work in progress poc git import

This commit is contained in:
Anirban Kar 2024-11-25 19:53:54 +05:30
parent 7fc8e40c03
commit e6ed210d0d
5 changed files with 406 additions and 0 deletions

View File

@ -18,6 +18,8 @@ import Cookies from 'js-cookie';
import styles from './BaseChat.module.scss';
import type { ProviderInfo } from '~/utils/types';
import GitCloneButton from './GitCloneButton';
import * as Separator from '@radix-ui/react-separator';
const EXAMPLE_PROMPTS = [
{ text: 'Build a todo app in React using Tailwind' },
@ -208,6 +210,9 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
},
)}
>
<GitCloneButton />
<Separator.Root className="my-[15px] bg-gray6 data-[orientation=horizontal]:h-px data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px"/>
<div className="flex items-center gap-3"></div>
<ModelSelector
key={provider?.name + ':' + modelList.length}
model={model}

View File

@ -0,0 +1,24 @@
import { IconButton } from '../ui/IconButton'
import git from 'isomorphic-git'
import http from 'isomorphic-git/http/web'
import { useGit } from '~/lib/hooks/useGit'
export default function GitCloneButton() {
const {ready,gitClone} = useGit()
const onClick= async(e:any)=>{
if (!ready) return
let repoUrl=prompt("Enter the Git url")
if (repoUrl) {
await gitClone(repoUrl)
}
}
return (
<IconButton onClick={e=>{
onClick(e)
}} className="w-full justify-center" title="Clone A Git Repo">
<span className="mr-2 text-xs lg:text-sm">Clone A Git Repo</span>
<div className='i-ph:git-branch' />
</IconButton>
)
}

254
app/lib/hooks/useGit.ts Normal file
View File

@ -0,0 +1,254 @@
import type { WebContainer,FileSystemAPI } from "@webcontainer/api";
import { useCallback, useEffect, useState } from "react";
import { webcontainer as webcontainerPromise } from "~/lib/webcontainer";
import git, { type PromiseFsClient } from 'isomorphic-git'
import http from 'isomorphic-git/http/web'
import Cookies from 'js-cookie';
export function useGit() {
const [ready, setReady] = useState(false);
const [webcontainer, setWebcontainer] = useState<WebContainer>();
const [fs, setFs] = useState<PromiseFsClient>();
const lookupSavedPassword=(url:string)=>{
try {
// Save updated API keys to cookies with 30 day expiry and secure settings
let creds=Cookies.get(`git:${url}`);
if (creds) {
const parsedCreds = JSON.parse(creds);
if (typeof parsedCreds === 'object' && parsedCreds !== null) {
return parsedCreds
}
}
return;
} catch (error) {
console.error('Error saving API keys to cookies:', error);
return;
}
}
useEffect(()=>{
webcontainerPromise.then(container=>{
setWebcontainer(container);
setFs(getFs(container));
setReady(true);
})
},[])
const gitClone= useCallback(async (url:string)=>{
if (!webcontainer||!fs||!ready) {
return;
}
let repo = await git.clone({
fs,
http,
dir: webcontainer.workdir,
url: url,
depth: 1,
singleBranch: true,
corsProxy: 'https://cors.isomorphic-git.org',
onAuth: url => {
let auth = lookupSavedPassword(url)
if (auth) return auth
if (confirm('This repo is password protected. Ready to enter a username & password?')) {
auth = {
username: prompt('Enter username'),
password: prompt('Enter password'),
}
return auth
} else {
return { cancel: true }
}
}
})
console.log(repo)
}, [webcontainer])
return {ready,gitClone}
}
interface IFS{
promises:{
readFile: PromiseFsClient['promises']['readFile'];
writeFile: PromiseFsClient['promises']['writeFile'];
mkdir:FileSystemAPI['mkdir'];
readdir:FileSystemAPI['readdir'];
rm:FileSystemAPI['rm'];
unlink(path: string): Promise<void>;
stat(path: string): Promise<any>;
lstat(path: string): Promise<any>;
rmdir(path: string): Promise<void>;
readlink?(path: string): Promise<string>;
symlink?(target: string, path: string): Promise<void>;
chmod?(path: string, mode: number): Promise<void>;
}
}
const getFs: (c: WebContainer) => PromiseFsClient = (webcontainer: WebContainer)=> ({
promises:{
readFile: async (path: string, options: any) => {
let encoding = options.encoding;
let relativePath = pathUtils.relative(webcontainer.workdir,path);
console.log('readFile', relativePath, encoding);
return await webcontainer.fs.readFile(relativePath,encoding);
},
writeFile: async (path: string, data: any, options: any) => {
let encoding = options.encoding;
let relativePath = pathUtils.relative(webcontainer.workdir,path);
console.log('writeFile', {relativePath,data,encoding});
return await webcontainer.fs.writeFile(relativePath, data, { ...options,encoding});
},
mkdir: async (path: string, options: any) => {
let relativePath = pathUtils.relative(webcontainer.workdir, path);
console.log('mkdir', relativePath,options);
return await webcontainer.fs.mkdir(relativePath,{...options,recursive:true})
},
readdir: async (path: string,options:any) => {
let relativePath = pathUtils.relative(webcontainer.workdir, path);
console.log('readdir', relativePath,options);
return await webcontainer.fs.readdir(relativePath,options)
},
rm: async (path: string,options:any) => {
let relativePath = pathUtils.relative(webcontainer.workdir, path);
console.log('rm', relativePath,options);
return await webcontainer.fs.rm(relativePath, { ...options||{} })
},
rmdir: async (path: string,options:any) => {
let relativePath = pathUtils.relative(webcontainer.workdir, path);
console.log('rmdir', relativePath, options);
return await webcontainer.fs.rm(relativePath, { recursive: true,...options})
},
// Mock implementations for missing functions
unlink: async (path: string) => {
// unlink is just removing a single file
let relativePath = pathUtils.relative(webcontainer.workdir, path);
return await webcontainer.fs.rm(relativePath, { recursive: false });
},
stat: async (path: string) => {
try {
let relativePath = pathUtils.relative(webcontainer.workdir, path);
let resp = await webcontainer.fs.readdir(pathUtils.dirname(relativePath),{withFileTypes:true})
let name = pathUtils.basename(relativePath)
let fileInfo=resp.find(x=>x.name==name)
if(!fileInfo){
throw new Error(`ENOENT: no such file or directory, stat '${path}'`);
}
return {
isFile: () => fileInfo.isFile(),
isDirectory: () => fileInfo.isDirectory(),
isSymbolicLink: () => false,
size: 1,
mode: 0o666, // Default permissions
mtimeMs: Date.now(),
uid: 1000,
gid: 1000
};
} catch (error) {
const err = new Error(`ENOENT: no such file or directory, stat '${path}'`) as NodeJS.ErrnoException;
err.code = 'ENOENT';
err.errno = -2;
err.syscall = 'stat';
err.path = path;
throw err;
}
},
lstat: async (path: string) => {
// For basic usage, lstat can return the same as stat
// since we're not handling symbolic links
return await getFs(webcontainer).promises.stat(path);
},
readlink: async (path: string) => {
// Since WebContainer doesn't support symlinks,
// we'll throw a "not a symbolic link" error
throw new Error(`EINVAL: invalid argument, readlink '${path}'`);
},
symlink: async (target: string, path: string) => {
// Since WebContainer doesn't support symlinks,
// we'll throw a "operation not supported" error
throw new Error(`EPERM: operation not permitted, symlink '${target}' -> '${path}'`);
},
chmod: async (path: string, mode: number) => {
// WebContainer doesn't support changing permissions,
// but we can pretend it succeeded for compatibility
return await Promise.resolve();
}
}
})
const pathUtils = {
dirname: (path: string) => {
// Handle empty or just filename cases
if (!path || !path.includes('/')) return '.';
// Remove trailing slashes
path = path.replace(/\/+$/, '');
// Get directory part
return path.split('/').slice(0, -1).join('/') || '/';
},
basename: (path: string, ext?: string) => {
// Remove trailing slashes
path = path.replace(/\/+$/, '');
// Get the last part of the path
const base = path.split('/').pop() || '';
// If extension is provided, remove it from the result
if (ext && base.endsWith(ext)) {
return base.slice(0, -ext.length);
}
return base;
},
relative: (from: string, to: string): string => {
// Handle empty inputs
if (!from || !to) return '.';
// Normalize paths by removing trailing slashes and splitting
const normalizePathParts = (p: string) =>
p.replace(/\/+$/, '')
.split('/')
.filter(Boolean);
const fromParts = normalizePathParts(from);
const toParts = normalizePathParts(to);
// Find common parts at the start of both paths
let commonLength = 0;
const minLength = Math.min(fromParts.length, toParts.length);
for (let i = 0; i < minLength; i++) {
if (fromParts[i] !== toParts[i]) break;
commonLength++;
}
// Calculate the number of "../" needed
const upCount = fromParts.length - commonLength;
// Get the remaining path parts we need to append
const remainingPath = toParts.slice(commonLength);
// Construct the relative path
const relativeParts = [
...Array(upCount).fill('..'),
...remainingPath
];
// Handle empty result case
return relativeParts.length === 0 ? '.' : relativeParts.join('/');
}
}

View File

@ -55,6 +55,7 @@
"@openrouter/ai-sdk-provider": "^0.0.5",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.4",
"@remix-run/cloudflare": "^2.10.2",
"@remix-run/cloudflare-pages": "^2.10.2",
@ -71,6 +72,7 @@
"file-saver": "^2.0.5",
"framer-motion": "^11.2.12",
"isbot": "^4.1.0",
"isomorphic-git": "^1.27.1",
"istextorbinary": "^9.5.0",
"jose": "^5.6.3",
"js-cookie": "^3.0.5",
@ -103,6 +105,7 @@
"fast-glob": "^3.3.2",
"is-ci": "^3.0.1",
"node-fetch": "^3.3.2",
"pnpm": "9.4.0",
"prettier": "^3.3.2",
"sass-embedded": "^1.80.3",
"typescript": "^5.5.2",

View File

@ -98,6 +98,9 @@ importers:
'@radix-ui/react-dropdown-menu':
specifier: ^2.1.1
version: 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-separator':
specifier: ^1.1.0
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-tooltip':
specifier: ^1.1.4
version: 1.1.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -146,6 +149,9 @@ importers:
isbot:
specifier: ^4.1.0
version: 4.4.0
isomorphic-git:
specifier: ^1.27.1
version: 1.27.1
istextorbinary:
specifier: ^9.5.0
version: 9.5.0
@ -237,6 +243,9 @@ importers:
node-fetch:
specifier: ^3.3.2
version: 3.3.2
pnpm:
specifier: 9.4.0
version: 9.4.0
prettier:
specifier: ^3.3.2
version: 3.3.2
@ -1607,6 +1616,19 @@ packages:
'@types/react-dom':
optional: true
'@radix-ui/react-separator@1.1.0':
resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-slot@1.1.0':
resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==}
peerDependencies:
@ -2371,6 +2393,9 @@ packages:
resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==}
hasBin: true
async-lock@1.4.1:
resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==}
available-typed-arrays@1.0.7:
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
engines: {node: '>= 0.4'}
@ -2564,6 +2589,9 @@ packages:
cipher-base@1.0.4:
resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==}
clean-git-ref@2.0.1:
resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==}
clean-stack@2.2.0:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
@ -2673,6 +2701,11 @@ packages:
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
crc-32@1.2.2:
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
engines: {node: '>=0.8'}
hasBin: true
create-ecdh@4.0.4:
resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==}
@ -2745,6 +2778,10 @@ packages:
decode-named-character-reference@1.0.2:
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
dedent@1.5.3:
resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==}
peerDependencies:
@ -2812,6 +2849,9 @@ packages:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
diff3@0.0.3:
resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==}
diff@5.2.0:
resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
engines: {node: '>=0.3.1'}
@ -3545,6 +3585,11 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
isomorphic-git@1.27.1:
resolution: {integrity: sha512-X32ph5zIWfT75QAqW2l3JCIqnx9/GWd17bRRehmn3qmWc34OYbSXY6Cxv0o9bIIY+CWugoN4nQFHNA+2uYf2nA==}
engines: {node: '>=12'}
hasBin: true
isomorphic-timers-promises@1.0.1:
resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==}
engines: {node: '>=10'}
@ -4035,6 +4080,10 @@ packages:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
mimic-response@3.1.0:
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
engines: {node: '>=10'}
miniflare@3.20240701.0:
resolution: {integrity: sha512-m9+I+7JNyqDGftCMKp9cK9pCZkK72hAL2mM9IWwhct+ZmucLBA8Uu6+rHQqA5iod86cpwOkrB2PrPA3wx9YNgw==}
engines: {node: '>=16.13'}
@ -4056,6 +4105,9 @@ packages:
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
minimisted@2.0.1:
resolution: {integrity: sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==}
minipass-collect@1.0.2:
resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
engines: {node: '>= 8'}
@ -4380,6 +4432,10 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
pify@4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
pkg-dir@5.0.0:
resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
engines: {node: '>=10'}
@ -4387,6 +4443,11 @@ packages:
pkg-types@1.1.1:
resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
pnpm@9.4.0:
resolution: {integrity: sha512-9Um4pSydK4U2di+ZwHIiBe/Fr5E+d4NdvMw7CwssqefcgCK3gGLBcpHEjoh0nHDOiOtadPH6jEv14Yu0bIvYOg==}
engines: {node: '>=18.12'}
hasBin: true
possible-typed-array-names@1.0.0:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
@ -5006,6 +5067,12 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
simple-concat@1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
sirv@2.0.4:
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
engines: {node: '>= 10'}
@ -7043,6 +7110,15 @@ snapshots:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
'@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
'@radix-ui/react-slot@1.1.0(@types/react@18.3.3)(react@18.3.1)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1)
@ -8004,6 +8080,8 @@ snapshots:
astring@1.8.6: {}
async-lock@1.4.1: {}
available-typed-arrays@1.0.7:
dependencies:
possible-typed-array-names: 1.0.0
@ -8260,6 +8338,8 @@ snapshots:
inherits: 2.0.4
safe-buffer: 5.2.1
clean-git-ref@2.0.1: {}
clean-stack@2.2.0: {}
cli-cursor@3.1.0:
@ -8351,6 +8431,8 @@ snapshots:
core-util-is@1.0.3: {}
crc-32@1.2.2: {}
create-ecdh@4.0.4:
dependencies:
bn.js: 4.12.0
@ -8428,6 +8510,10 @@ snapshots:
dependencies:
character-entities: 2.0.2
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
dedent@1.5.3: {}
deep-eql@5.0.2: {}
@ -8479,6 +8565,8 @@ snapshots:
diff-sequences@29.6.3: {}
diff3@0.0.3: {}
diff@5.2.0: {}
diffie-hellman@5.0.3:
@ -9398,6 +9486,20 @@ snapshots:
isexe@2.0.0: {}
isomorphic-git@1.27.1:
dependencies:
async-lock: 1.4.1
clean-git-ref: 2.0.1
crc-32: 1.2.2
diff3: 0.0.3
ignore: 5.3.1
minimisted: 2.0.1
pako: 1.0.11
pify: 4.0.1
readable-stream: 3.6.2
sha.js: 2.4.11
simple-get: 4.0.1
isomorphic-timers-promises@1.0.1: {}
istextorbinary@9.5.0:
@ -10265,6 +10367,8 @@ snapshots:
mimic-fn@4.0.0: {}
mimic-response@3.1.0: {}
miniflare@3.20240701.0:
dependencies:
'@cspotcode/source-map-support': 0.8.1
@ -10298,6 +10402,10 @@ snapshots:
minimist@1.2.8: {}
minimisted@2.0.1:
dependencies:
minimist: 1.2.8
minipass-collect@1.0.2:
dependencies:
minipass: 3.3.6
@ -10639,6 +10747,8 @@ snapshots:
pidtree@0.6.0: {}
pify@4.0.1: {}
pkg-dir@5.0.0:
dependencies:
find-up: 5.0.0
@ -10649,6 +10759,8 @@ snapshots:
mlly: 1.7.1
pathe: 1.1.2
pnpm@9.4.0: {}
possible-typed-array-names@1.0.0: {}
postcss-discard-duplicates@5.1.0(postcss@8.4.38):
@ -11314,6 +11426,14 @@ snapshots:
signal-exit@4.1.0: {}
simple-concat@1.0.1: {}
simple-get@4.0.1:
dependencies:
decompress-response: 6.0.0
once: 1.4.0
simple-concat: 1.0.1
sirv@2.0.4:
dependencies:
'@polka/url': 1.0.0-next.25