mirror of
https://github.com/stackblitz/bolt.new
synced 2025-03-12 14:58:30 +00:00
chore: fixed lock file
This commit is contained in:
parent
b499ee1f15
commit
bd236860f9
@ -2,15 +2,24 @@
|
|||||||
|
|
||||||
echo "🔍 Running pre-commit hook to check the code looks good... 🔍"
|
echo "🔍 Running pre-commit hook to check the code looks good... 🔍"
|
||||||
|
|
||||||
|
export NVM_DIR="$HOME/.nvm"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # Load nvm if you're using i
|
||||||
|
|
||||||
|
echo "Running typecheck..."
|
||||||
|
which pnpm
|
||||||
|
|
||||||
if ! pnpm typecheck; then
|
if ! pnpm typecheck; then
|
||||||
echo "❌ Type checking failed! Please review TypeScript types."
|
echo "❌ Type checking failed! Please review TypeScript types."
|
||||||
echo "Once you're done, don't forget to add your changes to the commit! 🚀"
|
echo "Once you're done, don't forget to add your changes to the commit! 🚀"
|
||||||
|
echo "Typecheck exit code: $?"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Running lint..."
|
||||||
if ! pnpm lint; then
|
if ! pnpm lint; then
|
||||||
echo "❌ Linting failed! 'pnpm lint:check' will help you fix the easy ones."
|
echo "❌ Linting failed! 'pnpm lint:check' will help you fix the easy ones."
|
||||||
echo "Once you're done, don't forget to add your beautification to the commit! 🤩"
|
echo "Once you're done, don't forget to add your beautification to the commit! 🤩"
|
||||||
|
echo "lint exit code: $?"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,24 +1,30 @@
|
|||||||
import { IconButton } from '../ui/IconButton'
|
import { IconButton } from '~/components/ui/IconButton';
|
||||||
import git from 'isomorphic-git'
|
import { useGit } from '~/lib/hooks/useGit';
|
||||||
import http from 'isomorphic-git/http/web'
|
|
||||||
import { useGit } from '~/lib/hooks/useGit'
|
|
||||||
|
|
||||||
export default function GitCloneButton() {
|
export default function GitCloneButton() {
|
||||||
const {ready,gitClone} = useGit()
|
const { ready, gitClone } = useGit();
|
||||||
const onClick= async(e:any)=>{
|
const onClick = async (_e: any) => {
|
||||||
if (!ready) return
|
if (!ready) {
|
||||||
let repoUrl=prompt("Enter the Git url")
|
return;
|
||||||
if (repoUrl) {
|
|
||||||
await gitClone(repoUrl)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return (
|
|
||||||
<IconButton onClick={e=>{
|
|
||||||
onClick(e)
|
|
||||||
|
|
||||||
}} className="w-full justify-center" title="Clone A Git Repo">
|
const repoUrl = prompt('Enter the Git url');
|
||||||
<span className="mr-2 text-xs lg:text-sm">Clone A Git Repo</span>
|
|
||||||
<div className='i-ph:git-branch' />
|
if (repoUrl) {
|
||||||
</IconButton>
|
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>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,147 +1,140 @@
|
|||||||
import type { WebContainer,FileSystemAPI } from "@webcontainer/api";
|
import type { WebContainer } from '@webcontainer/api';
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { webcontainer as webcontainerPromise } from "~/lib/webcontainer";
|
import { webcontainer as webcontainerPromise } from '~/lib/webcontainer';
|
||||||
import git, { type PromiseFsClient } from 'isomorphic-git'
|
import git, { type PromiseFsClient } from 'isomorphic-git';
|
||||||
import http from 'isomorphic-git/http/web'
|
import http from 'isomorphic-git/http/web';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function useGit() {
|
export function useGit() {
|
||||||
const [ready, setReady] = useState(false);
|
const [ready, setReady] = useState(false);
|
||||||
const [webcontainer, setWebcontainer] = useState<WebContainer>();
|
const [webcontainer, setWebcontainer] = useState<WebContainer>();
|
||||||
const [fs, setFs] = useState<PromiseFsClient>();
|
const [fs, setFs] = useState<PromiseFsClient>();
|
||||||
const lookupSavedPassword=(url:string)=>{
|
const lookupSavedPassword: (url: string) => any | null = (url: string) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Save updated API keys to cookies with 30 day expiry and secure settings
|
// Save updated API keys to cookies with 30 day expiry and secure settings
|
||||||
let creds=Cookies.get(`git:${url}`);
|
const creds = Cookies.get(`git:${url}`);
|
||||||
|
|
||||||
if (creds) {
|
if (creds) {
|
||||||
const parsedCreds = JSON.parse(creds);
|
const parsedCreds = JSON.parse(creds);
|
||||||
|
|
||||||
if (typeof parsedCreds === 'object' && parsedCreds !== null) {
|
if (typeof parsedCreds === 'object' && parsedCreds !== null) {
|
||||||
return parsedCreds
|
return parsedCreds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
|
return null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error saving API keys to cookies:', error);
|
console.error('Error saving API keys to cookies:', error);
|
||||||
return;
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
webcontainerPromise.then(container=>{
|
webcontainerPromise.then((container) => {
|
||||||
setWebcontainer(container);
|
setWebcontainer(container);
|
||||||
setFs(getFs(container));
|
setFs(getFs(container));
|
||||||
setReady(true);
|
setReady(true);
|
||||||
})
|
});
|
||||||
},[])
|
}, []);
|
||||||
|
|
||||||
const gitClone= useCallback(async (url:string)=>{
|
const gitClone = useCallback(
|
||||||
|
async (url: string) => {
|
||||||
if (!webcontainer || !fs || !ready) {
|
if (!webcontainer || !fs || !ready) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let repo = await git.clone({
|
|
||||||
|
const repo = await git.clone({
|
||||||
fs,
|
fs,
|
||||||
http,
|
http,
|
||||||
dir: webcontainer.workdir,
|
dir: webcontainer.workdir,
|
||||||
url: url,
|
url,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
singleBranch: true,
|
singleBranch: true,
|
||||||
corsProxy: 'https://cors.isomorphic-git.org',
|
corsProxy: 'https://cors.isomorphic-git.org',
|
||||||
onAuth: url => {
|
onAuth: (url) => {
|
||||||
let auth = lookupSavedPassword(url)
|
let auth = lookupSavedPassword(url);
|
||||||
if (auth) return auth
|
|
||||||
|
if (auth) {
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
if (confirm('This repo is password protected. Ready to enter a username & password?')) {
|
if (confirm('This repo is password protected. Ready to enter a username & password?')) {
|
||||||
auth = {
|
auth = {
|
||||||
username: prompt('Enter username'),
|
username: prompt('Enter username'),
|
||||||
password: prompt('Enter password'),
|
password: prompt('Enter password'),
|
||||||
}
|
};
|
||||||
return auth
|
return auth;
|
||||||
} else {
|
} else {
|
||||||
return { cancel: true }
|
return { cancel: true };
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
console.log(repo)
|
console.log(repo);
|
||||||
}, [webcontainer])
|
},
|
||||||
return {ready,gitClone}
|
[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) => ({
|
const getFs: (c: WebContainer) => PromiseFsClient = (webcontainer: WebContainer) => ({
|
||||||
promises: {
|
promises: {
|
||||||
readFile: async (path: string, options: any) => {
|
readFile: async (path: string, options: any) => {
|
||||||
let encoding = options.encoding;
|
const encoding = options.encoding;
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir,path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
console.log('readFile', relativePath, encoding);
|
console.log('readFile', relativePath, encoding);
|
||||||
|
|
||||||
return await webcontainer.fs.readFile(relativePath, encoding);
|
return await webcontainer.fs.readFile(relativePath, encoding);
|
||||||
},
|
},
|
||||||
writeFile: async (path: string, data: any, options: any) => {
|
writeFile: async (path: string, data: any, options: any) => {
|
||||||
let encoding = options.encoding;
|
const encoding = options.encoding;
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir,path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
console.log('writeFile', { relativePath, data, encoding });
|
console.log('writeFile', { relativePath, data, encoding });
|
||||||
|
|
||||||
return await webcontainer.fs.writeFile(relativePath, data, { ...options, encoding });
|
return await webcontainer.fs.writeFile(relativePath, data, { ...options, encoding });
|
||||||
},
|
},
|
||||||
mkdir: async (path: string, options: any) => {
|
mkdir: async (path: string, options: any) => {
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir, path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
console.log('mkdir', relativePath, options);
|
console.log('mkdir', relativePath, options);
|
||||||
return await webcontainer.fs.mkdir(relativePath,{...options,recursive:true})
|
|
||||||
|
return await webcontainer.fs.mkdir(relativePath, { ...options, recursive: true });
|
||||||
},
|
},
|
||||||
readdir: async (path: string, options: any) => {
|
readdir: async (path: string, options: any) => {
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir, path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
console.log('readdir', relativePath, options);
|
console.log('readdir', relativePath, options);
|
||||||
return await webcontainer.fs.readdir(relativePath,options)
|
|
||||||
|
return await webcontainer.fs.readdir(relativePath, options);
|
||||||
},
|
},
|
||||||
rm: async (path: string, options: any) => {
|
rm: async (path: string, options: any) => {
|
||||||
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir, path);
|
|
||||||
console.log('rm', relativePath, options);
|
console.log('rm', relativePath, options);
|
||||||
|
|
||||||
return await webcontainer.fs.rm(relativePath, { ...options||{} })
|
return await webcontainer.fs.rm(relativePath, { ...(options || {}) });
|
||||||
},
|
},
|
||||||
rmdir: async (path: string, options: any) => {
|
rmdir: async (path: string, options: any) => {
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir, path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
console.log('rmdir', relativePath, options);
|
console.log('rmdir', relativePath, options);
|
||||||
return await webcontainer.fs.rm(relativePath, { recursive: true,...options})
|
|
||||||
|
return await webcontainer.fs.rm(relativePath, { recursive: true, ...options });
|
||||||
},
|
},
|
||||||
|
|
||||||
// Mock implementations for missing functions
|
// Mock implementations for missing functions
|
||||||
unlink: async (path: string) => {
|
unlink: async (path: string) => {
|
||||||
// unlink is just removing a single file
|
// unlink is just removing a single file
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir, path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
return await webcontainer.fs.rm(relativePath, { recursive: false });
|
return await webcontainer.fs.rm(relativePath, { recursive: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
stat: async (path: string) => {
|
stat: async (path: string) => {
|
||||||
try {
|
try {
|
||||||
let relativePath = pathUtils.relative(webcontainer.workdir, path);
|
const relativePath = pathUtils.relative(webcontainer.workdir, path);
|
||||||
let resp = await webcontainer.fs.readdir(pathUtils.dirname(relativePath),{withFileTypes:true})
|
const resp = await webcontainer.fs.readdir(pathUtils.dirname(relativePath), { withFileTypes: true });
|
||||||
let name = pathUtils.basename(relativePath)
|
const name = pathUtils.basename(relativePath);
|
||||||
let fileInfo=resp.find(x=>x.name==name)
|
const fileInfo = resp.find((x) => x.name == name);
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
throw new Error(`ENOENT: no such file or directory, stat '${path}'`);
|
throw new Error(`ENOENT: no such file or directory, stat '${path}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isFile: () => fileInfo.isFile(),
|
isFile: () => fileInfo.isFile(),
|
||||||
isDirectory: () => fileInfo.isDirectory(),
|
isDirectory: () => fileInfo.isDirectory(),
|
||||||
@ -150,9 +143,11 @@ const getFs: (c: WebContainer) => PromiseFsClient = (webcontainer: WebContainer)
|
|||||||
mode: 0o666, // Default permissions
|
mode: 0o666, // Default permissions
|
||||||
mtimeMs: Date.now(),
|
mtimeMs: Date.now(),
|
||||||
uid: 1000,
|
uid: 1000,
|
||||||
gid: 1000
|
gid: 1000,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
|
console.log(error?.message);
|
||||||
|
|
||||||
const err = new Error(`ENOENT: no such file or directory, stat '${path}'`) as NodeJS.ErrnoException;
|
const err = new Error(`ENOENT: no such file or directory, stat '${path}'`) as NodeJS.ErrnoException;
|
||||||
err.code = 'ENOENT';
|
err.code = 'ENOENT';
|
||||||
err.errno = -2;
|
err.errno = -2;
|
||||||
@ -163,35 +158,45 @@ const getFs: (c: WebContainer) => PromiseFsClient = (webcontainer: WebContainer)
|
|||||||
},
|
},
|
||||||
|
|
||||||
lstat: async (path: string) => {
|
lstat: async (path: string) => {
|
||||||
// For basic usage, lstat can return the same as stat
|
/*
|
||||||
// since we're not handling symbolic links
|
* For basic usage, lstat can return the same as stat
|
||||||
|
* since we're not handling symbolic links
|
||||||
|
*/
|
||||||
return await getFs(webcontainer).promises.stat(path);
|
return await getFs(webcontainer).promises.stat(path);
|
||||||
},
|
},
|
||||||
|
|
||||||
readlink: async (path: string) => {
|
readlink: async (path: string) => {
|
||||||
// Since WebContainer doesn't support symlinks,
|
/*
|
||||||
// we'll throw a "not a symbolic link" error
|
* Since WebContainer doesn't support symlinks,
|
||||||
|
* we'll throw a "not a symbolic link" error
|
||||||
|
*/
|
||||||
throw new Error(`EINVAL: invalid argument, readlink '${path}'`);
|
throw new Error(`EINVAL: invalid argument, readlink '${path}'`);
|
||||||
},
|
},
|
||||||
|
|
||||||
symlink: async (target: string, path: string) => {
|
symlink: async (target: string, path: string) => {
|
||||||
// Since WebContainer doesn't support symlinks,
|
/*
|
||||||
// we'll throw a "operation not supported" error
|
* Since WebContainer doesn't support symlinks,
|
||||||
|
* we'll throw a "operation not supported" error
|
||||||
|
*/
|
||||||
throw new Error(`EPERM: operation not permitted, symlink '${target}' -> '${path}'`);
|
throw new Error(`EPERM: operation not permitted, symlink '${target}' -> '${path}'`);
|
||||||
},
|
},
|
||||||
|
|
||||||
chmod: async (path: string, mode: number) => {
|
chmod: async (_path: string, _mode: number) => {
|
||||||
// WebContainer doesn't support changing permissions,
|
/*
|
||||||
// but we can pretend it succeeded for compatibility
|
* WebContainer doesn't support changing permissions,
|
||||||
|
* but we can pretend it succeeded for compatibility
|
||||||
|
*/
|
||||||
return await Promise.resolve();
|
return await Promise.resolve();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const pathUtils = {
|
const pathUtils = {
|
||||||
dirname: (path: string) => {
|
dirname: (path: string) => {
|
||||||
// Handle empty or just filename cases
|
// Handle empty or just filename cases
|
||||||
if (!path || !path.includes('/')) return '.';
|
if (!path || !path.includes('/')) {
|
||||||
|
return '.';
|
||||||
|
}
|
||||||
|
|
||||||
// Remove trailing slashes
|
// Remove trailing slashes
|
||||||
path = path.replace(/\/+$/, '');
|
path = path.replace(/\/+$/, '');
|
||||||
@ -216,13 +221,12 @@ const pathUtils = {
|
|||||||
},
|
},
|
||||||
relative: (from: string, to: string): string => {
|
relative: (from: string, to: string): string => {
|
||||||
// Handle empty inputs
|
// Handle empty inputs
|
||||||
if (!from || !to) return '.';
|
if (!from || !to) {
|
||||||
|
return '.';
|
||||||
|
}
|
||||||
|
|
||||||
// Normalize paths by removing trailing slashes and splitting
|
// Normalize paths by removing trailing slashes and splitting
|
||||||
const normalizePathParts = (p: string) =>
|
const normalizePathParts = (p: string) => p.replace(/\/+$/, '').split('/').filter(Boolean);
|
||||||
p.replace(/\/+$/, '')
|
|
||||||
.split('/')
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
const fromParts = normalizePathParts(from);
|
const fromParts = normalizePathParts(from);
|
||||||
const toParts = normalizePathParts(to);
|
const toParts = normalizePathParts(to);
|
||||||
@ -232,7 +236,10 @@ const pathUtils = {
|
|||||||
const minLength = Math.min(fromParts.length, toParts.length);
|
const minLength = Math.min(fromParts.length, toParts.length);
|
||||||
|
|
||||||
for (let i = 0; i < minLength; i++) {
|
for (let i = 0; i < minLength; i++) {
|
||||||
if (fromParts[i] !== toParts[i]) break;
|
if (fromParts[i] !== toParts[i]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
commonLength++;
|
commonLength++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,12 +250,9 @@ const pathUtils = {
|
|||||||
const remainingPath = toParts.slice(commonLength);
|
const remainingPath = toParts.slice(commonLength);
|
||||||
|
|
||||||
// Construct the relative path
|
// Construct the relative path
|
||||||
const relativeParts = [
|
const relativeParts = [...Array(upCount).fill('..'), ...remainingPath];
|
||||||
...Array(upCount).fill('..'),
|
|
||||||
...remainingPath
|
|
||||||
];
|
|
||||||
|
|
||||||
// Handle empty result case
|
// Handle empty result case
|
||||||
return relativeParts.length === 0 ? '.' : relativeParts.join('/');
|
return relativeParts.length === 0 ? '.' : relativeParts.join('/');
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
25548
package-lock.json
generated
25548
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -58,6 +58,7 @@
|
|||||||
"@openrouter/ai-sdk-provider": "^0.0.5",
|
"@openrouter/ai-sdk-provider": "^0.0.5",
|
||||||
"@radix-ui/react-dialog": "^1.1.2",
|
"@radix-ui/react-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
||||||
|
"@radix-ui/react-separator": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.1.4",
|
"@radix-ui/react-tooltip": "^1.1.4",
|
||||||
"@remix-run/cloudflare": "^2.15.0",
|
"@remix-run/cloudflare": "^2.15.0",
|
||||||
"@remix-run/cloudflare-pages": "^2.15.0",
|
"@remix-run/cloudflare-pages": "^2.15.0",
|
||||||
@ -75,13 +76,13 @@
|
|||||||
"framer-motion": "^11.12.0",
|
"framer-motion": "^11.12.0",
|
||||||
"ignore": "^6.0.2",
|
"ignore": "^6.0.2",
|
||||||
"isbot": "^4.4.0",
|
"isbot": "^4.4.0",
|
||||||
|
"isomorphic-git": "^1.27.2",
|
||||||
"istextorbinary": "^9.5.0",
|
"istextorbinary": "^9.5.0",
|
||||||
"jose": "^5.9.6",
|
"jose": "^5.9.6",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"nanostores": "^0.10.3",
|
"nanostores": "^0.10.3",
|
||||||
"ollama-ai-provider": "^0.15.2",
|
"ollama-ai-provider": "^0.15.2",
|
||||||
"pnpm": "^9.14.4",
|
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-hotkeys-hook": "^4.6.1",
|
"react-hotkeys-hook": "^4.6.1",
|
||||||
@ -109,6 +110,7 @@
|
|||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"is-ci": "^3.0.1",
|
"is-ci": "^3.0.1",
|
||||||
"node-fetch": "^3.3.2",
|
"node-fetch": "^3.3.2",
|
||||||
|
"pnpm": "^9.14.4",
|
||||||
"prettier": "^3.4.1",
|
"prettier": "^3.4.1",
|
||||||
"sass-embedded": "^1.81.0",
|
"sass-embedded": "^1.81.0",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
|
13312
pnpm-lock.yaml
13312
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user