mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-04-29 10:21:47 +00:00
connection github enhancements
This commit is contained in:
parent
5a6c0e5f90
commit
fd98059cfe
@ -8,11 +8,34 @@ interface GitHubUserResponse {
|
||||
login: string;
|
||||
avatar_url: string;
|
||||
html_url: string;
|
||||
name: string;
|
||||
bio: string;
|
||||
public_repos: number;
|
||||
followers: number;
|
||||
following: number;
|
||||
}
|
||||
|
||||
interface GitHubRepoInfo {
|
||||
name: string;
|
||||
full_name: string;
|
||||
html_url: string;
|
||||
description: string;
|
||||
stargazers_count: number;
|
||||
forks_count: number;
|
||||
default_branch: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
interface GitHubStats {
|
||||
repos: GitHubRepoInfo[];
|
||||
totalStars: number;
|
||||
totalForks: number;
|
||||
}
|
||||
|
||||
interface GitHubConnection {
|
||||
user: GitHubUserResponse | null;
|
||||
token: string;
|
||||
stats?: GitHubStats;
|
||||
}
|
||||
|
||||
export default function ConnectionsTab() {
|
||||
@ -22,18 +45,59 @@ export default function ConnectionsTab() {
|
||||
});
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const [isFetchingStats, setIsFetchingStats] = useState(false);
|
||||
|
||||
// Load saved connection on mount
|
||||
useEffect(() => {
|
||||
const savedConnection = localStorage.getItem('github_connection');
|
||||
|
||||
if (savedConnection) {
|
||||
setConnection(JSON.parse(savedConnection));
|
||||
const parsed = JSON.parse(savedConnection);
|
||||
setConnection(parsed);
|
||||
if (parsed.user && parsed.token) {
|
||||
fetchGitHubStats(parsed.token);
|
||||
}
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
}, []);
|
||||
|
||||
const fetchGitHubStats = async (token: string) => {
|
||||
try {
|
||||
setIsFetchingStats(true);
|
||||
|
||||
// Fetch repositories
|
||||
const reposResponse = await fetch('https://api.github.com/user/repos?sort=updated&per_page=10', {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!reposResponse.ok) throw new Error('Failed to fetch repositories');
|
||||
|
||||
const repos = await reposResponse.json() as GitHubRepoInfo[];
|
||||
|
||||
// Calculate total stats
|
||||
const totalStars = repos.reduce((acc, repo) => acc + repo.stargazers_count, 0);
|
||||
const totalForks = repos.reduce((acc, repo) => acc + repo.forks_count, 0);
|
||||
|
||||
setConnection(prev => ({
|
||||
...prev,
|
||||
stats: {
|
||||
repos,
|
||||
totalStars,
|
||||
totalForks,
|
||||
},
|
||||
}));
|
||||
|
||||
} catch (error) {
|
||||
logStore.logError('Failed to fetch GitHub stats', { error });
|
||||
toast.error('Failed to fetch GitHub statistics');
|
||||
} finally {
|
||||
setIsFetchingStats(false);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchGithubUser = async (token: string) => {
|
||||
try {
|
||||
setIsConnecting(true);
|
||||
@ -44,16 +108,18 @@ export default function ConnectionsTab() {
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Invalid token or unauthorized');
|
||||
}
|
||||
if (!response.ok) throw new Error('Invalid token or unauthorized');
|
||||
|
||||
const data = (await response.json()) as GitHubUserResponse;
|
||||
const data = await response.json() as GitHubUserResponse;
|
||||
const newConnection = { user: data, token };
|
||||
|
||||
// Save connection
|
||||
localStorage.setItem('github_connection', JSON.stringify(newConnection));
|
||||
setConnection(newConnection);
|
||||
|
||||
// Fetch additional stats
|
||||
await fetchGitHubStats(token);
|
||||
|
||||
toast.success('Successfully connected to GitHub');
|
||||
} catch (error) {
|
||||
logStore.logError('Failed to authenticate with GitHub', { error });
|
||||
@ -75,16 +141,7 @@ export default function ConnectionsTab() {
|
||||
toast.success('Disconnected from GitHub');
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="i-ph:spinner-gap-bold animate-spin w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (isLoading) return <LoadingSpinner />;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
@ -200,9 +257,92 @@ export default function ConnectionsTab() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{connection.user && connection.stats && (
|
||||
<div className="mt-6 border-t border-[#E5E5E5] dark:border-[#1A1A1A] pt-6">
|
||||
<div className="flex items-center gap-4 mb-6">
|
||||
<img
|
||||
src={connection.user.avatar_url}
|
||||
alt={connection.user.login}
|
||||
className="w-16 h-16 rounded-full"
|
||||
/>
|
||||
<div>
|
||||
<h3 className="text-lg font-medium text-bolt-elements-textPrimary">
|
||||
{connection.user.name || connection.user.login}
|
||||
</h3>
|
||||
{connection.user.bio && (
|
||||
<p className="text-sm text-bolt-elements-textSecondary">{connection.user.bio}</p>
|
||||
)}
|
||||
<div className="flex gap-4 mt-2 text-sm text-bolt-elements-textSecondary">
|
||||
<span className="flex items-center gap-1">
|
||||
<div className="i-ph:users w-4 h-4" />
|
||||
{connection.user.followers} followers
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<div className="i-ph:star w-4 h-4" />
|
||||
{connection.stats.totalStars} stars
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<div className="i-ph:git-fork w-4 h-4" />
|
||||
{connection.stats.totalForks} forks
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="text-sm font-medium text-bolt-elements-textPrimary mb-3">
|
||||
Recent Repositories
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
{connection.stats.repos.map((repo) => (
|
||||
<a
|
||||
key={repo.full_name}
|
||||
href={repo.html_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block p-3 rounded-lg bg-[#F8F8F8] dark:bg-[#1A1A1A] hover:bg-[#F0F0F0] dark:hover:bg-[#252525] transition-colors"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h5 className="text-sm font-medium text-bolt-elements-textPrimary">
|
||||
{repo.name}
|
||||
</h5>
|
||||
{repo.description && (
|
||||
<p className="text-xs text-bolt-elements-textSecondary mt-1">
|
||||
{repo.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-3 text-xs text-bolt-elements-textSecondary">
|
||||
<span className="flex items-center gap-1">
|
||||
<div className="i-ph:star w-3 h-3" />
|
||||
{repo.stargazers_count}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<div className="i-ph:git-fork w-3 h-3" />
|
||||
{repo.forks_count}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LoadingSpinner() {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="i-ph:spinner-gap-bold animate-spin w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ interface SystemInfo {
|
||||
}
|
||||
|
||||
interface WebAppInfo {
|
||||
// Local WebApp Info
|
||||
name: string;
|
||||
version: string;
|
||||
description: string;
|
||||
@ -91,6 +92,33 @@ interface WebAppInfo {
|
||||
nodeVersion: string;
|
||||
dependencies: { [key: string]: string };
|
||||
devDependencies: { [key: string]: string };
|
||||
// Build Info
|
||||
buildTime?: string;
|
||||
buildNumber?: string;
|
||||
environment?: string;
|
||||
// Git Info
|
||||
gitInfo?: {
|
||||
branch: string;
|
||||
commit: string;
|
||||
commitTime: string;
|
||||
author: string;
|
||||
remoteUrl: string;
|
||||
};
|
||||
// GitHub Repository Info
|
||||
repoInfo?: {
|
||||
name: string;
|
||||
fullName: string;
|
||||
description: string;
|
||||
stars: number;
|
||||
forks: number;
|
||||
openIssues: number;
|
||||
defaultBranch: string;
|
||||
lastUpdate: string;
|
||||
owner: {
|
||||
login: string;
|
||||
avatarUrl: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default function DebugTab() {
|
||||
@ -298,14 +326,54 @@ export default function DebugTab() {
|
||||
try {
|
||||
setLoading((prev) => ({ ...prev, webAppInfo: true }));
|
||||
|
||||
const response = await fetch('/api/system/app-info');
|
||||
|
||||
if (!response.ok) {
|
||||
// Fetch local app info
|
||||
const appInfoResponse = await fetch('/api/system/app-info');
|
||||
if (!appInfoResponse.ok) {
|
||||
throw new Error('Failed to fetch webapp info');
|
||||
}
|
||||
const appData = await appInfoResponse.json();
|
||||
|
||||
const data = await response.json();
|
||||
setWebAppInfo(data as WebAppInfo);
|
||||
// Fetch git info
|
||||
const gitInfoResponse = await fetch('/api/system/git-info');
|
||||
let gitInfo = null;
|
||||
if (gitInfoResponse.ok) {
|
||||
gitInfo = await gitInfoResponse.json();
|
||||
}
|
||||
|
||||
// Fetch GitHub repository info
|
||||
const repoInfoResponse = await fetch('https://api.github.com/repos/stackblitz-labs/bolt.diy');
|
||||
let repoInfo = null;
|
||||
if (repoInfoResponse.ok) {
|
||||
const repoData = await repoInfoResponse.json();
|
||||
repoInfo = {
|
||||
name: repoData.name,
|
||||
fullName: repoData.full_name,
|
||||
description: repoData.description,
|
||||
stars: repoData.stargazers_count,
|
||||
forks: repoData.forks_count,
|
||||
openIssues: repoData.open_issues_count,
|
||||
defaultBranch: repoData.default_branch,
|
||||
lastUpdate: repoData.updated_at,
|
||||
owner: {
|
||||
login: repoData.owner.login,
|
||||
avatarUrl: repoData.owner.avatar_url,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Get build info from environment variables or config
|
||||
const buildInfo = {
|
||||
buildTime: process.env.NEXT_PUBLIC_BUILD_TIME || new Date().toISOString(),
|
||||
buildNumber: process.env.NEXT_PUBLIC_BUILD_NUMBER || 'development',
|
||||
environment: process.env.NEXT_PUBLIC_ENV || 'development',
|
||||
};
|
||||
|
||||
setWebAppInfo({
|
||||
...appData,
|
||||
...buildInfo,
|
||||
gitInfo,
|
||||
repoInfo,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch webapp info:', error);
|
||||
toast.error('Failed to fetch webapp information');
|
||||
@ -895,6 +963,27 @@ export default function DebugTab() {
|
||||
<span className="text-bolt-elements-textSecondary">Node Version: </span>
|
||||
<span className="text-bolt-elements-textPrimary">{webAppInfo.nodeVersion}</span>
|
||||
</div>
|
||||
{webAppInfo.buildTime && (
|
||||
<div className="text-sm flex items-center gap-2">
|
||||
<div className="i-ph:calendar text-bolt-elements-textSecondary w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">Build Time: </span>
|
||||
<span className="text-bolt-elements-textPrimary">{webAppInfo.buildTime}</span>
|
||||
</div>
|
||||
)}
|
||||
{webAppInfo.buildNumber && (
|
||||
<div className="text-sm flex items-center gap-2">
|
||||
<div className="i-ph:hash text-bolt-elements-textSecondary w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">Build Number: </span>
|
||||
<span className="text-bolt-elements-textPrimary">{webAppInfo.buildNumber}</span>
|
||||
</div>
|
||||
)}
|
||||
{webAppInfo.environment && (
|
||||
<div className="text-sm flex items-center gap-2">
|
||||
<div className="i-ph:cloud text-bolt-elements-textSecondary w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">Environment: </span>
|
||||
<span className="text-bolt-elements-textPrimary">{webAppInfo.environment}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm">
|
||||
@ -912,6 +1001,71 @@ export default function DebugTab() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{webAppInfo.gitInfo && (
|
||||
<div className="text-sm">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<div className="i-ph:git-branch text-bolt-elements-textSecondary w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">Git Info:</span>
|
||||
</div>
|
||||
<div className="pl-6 space-y-1">
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Branch: {webAppInfo.gitInfo.branch}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Commit: {webAppInfo.gitInfo.commit}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Commit Time: {webAppInfo.gitInfo.commitTime}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Author: {webAppInfo.gitInfo.author}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Remote URL: {webAppInfo.gitInfo.remoteUrl}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{webAppInfo.repoInfo && (
|
||||
<div className="text-sm">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<div className="i-ph:github text-bolt-elements-textSecondary w-4 h-4" />
|
||||
<span className="text-bolt-elements-textSecondary">GitHub Repository:</span>
|
||||
</div>
|
||||
<div className="pl-6 space-y-1">
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Name: {webAppInfo.repoInfo.name}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Full Name: {webAppInfo.repoInfo.fullName}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Description: {webAppInfo.repoInfo.description}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Stars: {webAppInfo.repoInfo.stars}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Forks: {webAppInfo.repoInfo.forks}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Open Issues: {webAppInfo.repoInfo.openIssues}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Default Branch: {webAppInfo.repoInfo.defaultBranch}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Last Update: {webAppInfo.repoInfo.lastUpdate}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Owner: {webAppInfo.repoInfo.owner.login}
|
||||
</div>
|
||||
<div className="text-xs text-bolt-elements-textPrimary">
|
||||
Avatar URL: {webAppInfo.repoInfo.owner.avatarUrl}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
26
app/routes/api.system.git-info.ts
Normal file
26
app/routes/api.system.git-info.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { json } from '@remix-run/node';
|
||||
import type { LoaderFunctionArgs } from '@remix-run/node';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
try {
|
||||
const branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
|
||||
const commit = execSync('git rev-parse --short HEAD').toString().trim();
|
||||
const lastCommitMessage = execSync('git log -1 --pretty=%B').toString().trim();
|
||||
|
||||
return json({
|
||||
branch,
|
||||
commit,
|
||||
lastCommitMessage,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
} catch (error) {
|
||||
return json(
|
||||
{
|
||||
error: 'Failed to fetch git information',
|
||||
details: error instanceof Error ? error.message : 'Unknown error',
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
@ -67,6 +67,7 @@
|
||||
"@radix-ui/react-tooltip": "^1.1.4",
|
||||
"@remix-run/cloudflare": "^2.15.0",
|
||||
"@remix-run/cloudflare-pages": "^2.15.0",
|
||||
"@remix-run/node": "^2.15.2",
|
||||
"@remix-run/react": "^2.15.0",
|
||||
"@uiw/codemirror-theme-vscode": "^4.23.6",
|
||||
"@unocss/reset": "^0.61.9",
|
||||
|
30
pages/api/system/git-info.ts
Normal file
30
pages/api/system/git-info.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== 'GET') {
|
||||
return res.status(405).json({ message: 'Method not allowed' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Get git information using git commands
|
||||
const branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD').toString().trim();
|
||||
const commitTime = execSync('git log -1 --format=%cd').toString().trim();
|
||||
const author = execSync('git log -1 --format=%an').toString().trim();
|
||||
const remoteUrl = execSync('git config --get remote.origin.url').toString().trim();
|
||||
|
||||
const gitInfo = {
|
||||
branch,
|
||||
commit,
|
||||
commitTime,
|
||||
author,
|
||||
remoteUrl,
|
||||
};
|
||||
|
||||
res.status(200).json(gitInfo);
|
||||
} catch (error) {
|
||||
console.error('Failed to get git information:', error);
|
||||
res.status(500).json({ message: 'Failed to get git information' });
|
||||
}
|
||||
}
|
@ -122,6 +122,9 @@ importers:
|
||||
'@remix-run/cloudflare-pages':
|
||||
specifier: ^2.15.0
|
||||
version: 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2)
|
||||
'@remix-run/node':
|
||||
specifier: ^2.15.2
|
||||
version: 2.15.2(typescript@5.7.2)
|
||||
'@remix-run/react':
|
||||
specifier: ^2.15.0
|
||||
version: 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)
|
||||
@ -241,10 +244,10 @@ importers:
|
||||
version: 4.0.0
|
||||
remix-island:
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/server-runtime@2.15.0(typescript@5.7.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 0.2.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/server-runtime@2.15.2(typescript@5.7.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
remix-utils:
|
||||
specifier: ^7.7.0
|
||||
version: 7.7.0(@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.0(typescript@5.7.2))(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/router@1.21.0)(react@18.3.1)(zod@3.23.8)
|
||||
version: 7.7.0(@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.2(typescript@5.7.2))(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/router@1.21.0)(react@18.3.1)(zod@3.23.8)
|
||||
shiki:
|
||||
specifier: ^1.24.0
|
||||
version: 1.24.0
|
||||
@ -2294,6 +2297,15 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@remix-run/node@2.15.2':
|
||||
resolution: {integrity: sha512-NS/h5uxje7DYCNgcKqKAiUhf0r2HVnoYUBWLyIIMmCUP1ddWurBP6xTPcWzGhEvV/EvguniYi1wJZ5+X8sonWw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
typescript: ^5.1.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@remix-run/react@2.15.0':
|
||||
resolution: {integrity: sha512-puqDbi9N/WfaUhzDnw2pACXtCB7ukrtFJ9ILwpEuhlaTBpjefifJ89igokW+tt1ePphIFMivAm/YspcbZdCQsA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
@ -2318,6 +2330,15 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@remix-run/server-runtime@2.15.2':
|
||||
resolution: {integrity: sha512-OqiPcvEnnU88B8b1LIWHHkQ3Tz2GDAmQ1RihFNQsbrFKpDsQLkw0lJlnfgKA/uHd0CEEacpfV7C9qqJT3V6Z2g==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
typescript: ^5.1.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
'@remix-run/web-blob@3.1.0':
|
||||
resolution: {integrity: sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g==}
|
||||
|
||||
@ -8640,6 +8661,18 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
|
||||
'@remix-run/node@2.15.2(typescript@5.7.2)':
|
||||
dependencies:
|
||||
'@remix-run/server-runtime': 2.15.2(typescript@5.7.2)
|
||||
'@remix-run/web-fetch': 4.4.2
|
||||
'@web3-storage/multipart-parser': 1.0.0
|
||||
cookie-signature: 1.2.2
|
||||
source-map-support: 0.5.21
|
||||
stream-slice: 0.1.2
|
||||
undici: 6.21.0
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
|
||||
'@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)':
|
||||
dependencies:
|
||||
'@remix-run/router': 1.21.0
|
||||
@ -8666,6 +8699,18 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
|
||||
'@remix-run/server-runtime@2.15.2(typescript@5.7.2)':
|
||||
dependencies:
|
||||
'@remix-run/router': 1.21.0
|
||||
'@types/cookie': 0.6.0
|
||||
'@web3-storage/multipart-parser': 1.0.0
|
||||
cookie: 0.6.0
|
||||
set-cookie-parser: 2.7.1
|
||||
source-map: 0.7.4
|
||||
turbo-stream: 2.4.0
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
|
||||
'@remix-run/web-blob@3.1.0':
|
||||
dependencies:
|
||||
'@remix-run/web-stream': 1.1.0
|
||||
@ -12680,19 +12725,19 @@ snapshots:
|
||||
mdast-util-to-markdown: 2.1.2
|
||||
unified: 11.0.5
|
||||
|
||||
remix-island@0.2.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/server-runtime@2.15.0(typescript@5.7.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
remix-island@0.2.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/server-runtime@2.15.2(typescript@5.7.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@remix-run/react': 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)
|
||||
'@remix-run/server-runtime': 2.15.0(typescript@5.7.2)
|
||||
'@remix-run/server-runtime': 2.15.2(typescript@5.7.2)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
remix-utils@7.7.0(@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.0(typescript@5.7.2))(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/router@1.21.0)(react@18.3.1)(zod@3.23.8):
|
||||
remix-utils@7.7.0(@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.2(typescript@5.7.2))(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/router@1.21.0)(react@18.3.1)(zod@3.23.8):
|
||||
dependencies:
|
||||
type-fest: 4.30.0
|
||||
optionalDependencies:
|
||||
'@remix-run/cloudflare': 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2)
|
||||
'@remix-run/node': 2.15.0(typescript@5.7.2)
|
||||
'@remix-run/node': 2.15.2(typescript@5.7.2)
|
||||
'@remix-run/react': 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)
|
||||
'@remix-run/router': 1.21.0
|
||||
react: 18.3.1
|
||||
|
Loading…
Reference in New Issue
Block a user