From ef3849f068262bb61e21cfa547da3881b52dcf14 Mon Sep 17 00:00:00 2001 From: Andrew Hariri Date: Tue, 23 Sep 2025 10:02:38 -0700 Subject: [PATCH] [tables] Create table generator and modify README.md --- .github/workflows/ci.yml | 3 + README.md | 78 +++-- apps/web/package.json | 1 + package.json | 4 +- packages/table-generator/package.json | 40 +++ packages/table-generator/src/cli.ts | 96 ++++++ packages/table-generator/src/generator.ts | 39 +++ packages/table-generator/src/index.ts | 63 ++++ .../table-generator/src/readme-updater.ts | 65 ++++ packages/table-generator/src/scanner.ts | 91 +++++ packages/table-generator/src/types.ts | 30 ++ packages/table-generator/tsconfig.json | 21 ++ packages/ui/package.json | 1 + pnpm-lock.yaml | 313 ++++++++++++++++++ 14 files changed, 815 insertions(+), 30 deletions(-) create mode 100644 packages/table-generator/package.json create mode 100644 packages/table-generator/src/cli.ts create mode 100644 packages/table-generator/src/generator.ts create mode 100644 packages/table-generator/src/index.ts create mode 100644 packages/table-generator/src/readme-updater.ts create mode 100644 packages/table-generator/src/scanner.ts create mode 100644 packages/table-generator/src/types.ts create mode 100644 packages/table-generator/tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecce69d..94993bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,9 @@ jobs: - name: Setup Node and pnpm uses: ./.github/actions/setup-node + - name: Check Apps Table + run: pnpm check-table + - name: Lint run: pnpm lint diff --git a/README.md b/README.md index fcdfd40..bdd3365 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,38 @@ -# Shelby Protocol Examples +

+ + Shelby Logo +

Shelby Examples

+ +

+ +

+ 🌐 Website: shelby.xyz +  |  + šŸ“š Documentation: docs.shelby.xyz +  |  + šŸ™ GitHub: github.com/shelby +  |  + 🐦 Twitter: @shelbyserves +

+ +A collection of examples demonstrating various features and capabilities of the Shelby ecosystem. This repository is modeled after [Vercel's examples repository](https://github.com/vercel/examples) and serves as a comprehensive resource for developers building with Shelby. -
- Shelby Protocol Logo -
- -A collection of examples demonstrating various features and capabilities of the Shelby Protocol ecosystem. This repository is modeled after [Vercel's examples repository](https://github.com/vercel/examples) and serves as a comprehensive resource for developers building with Shelby Protocol. - -## About Shelby Protocol +## What's Inside -Shelby Protocol is a decentralized infrastructure platform designed to simplify the development and deployment of distributed applications. Learn more about us: +This Turborepo includes the following example applications: -- 🌐 **Website**: [shelby.xyz](https://shelby.xyz/) -- šŸ“š **Documentation**: [docs.shelby.xyz](https://docs.shelby.xyz/) -- šŸ™ **GitHub**: [github.com/shelby](https://github.com/shelby) -- 🐦 **Twitter**: [@shelbyserves](https://x.com/shelbyserves) + + -## What's Inside +### Applications -This Turborepo includes the following packages and applications: +| Name | Description | Path & Links | +| --- | --- | --- | +| `@shelby-protocol/web` | A Next.js application showcasing Shelby integrations | [`apps/web`](./apps/web) | -### Apps and Packages + -- `@shelby-protocol/web`: A [Next.js](https://nextjs.org/) application showcasing Shelby Protocol integrations -- `@shelby-protocol/ui`: A React component library shared across applications - -Each package/app is 100% [TypeScript](https://www.typescriptlang.org/) and follows Shelby Protocol's development standards. +Each application is 100% [TypeScript](https://www.typescriptlang.org/) and follows Shelby's development standards. ### Development Tools @@ -57,13 +65,13 @@ pnpm install ### Development -To develop all apps and packages: +To develop all applications: ```bash pnpm dev ``` -To develop a specific package: +To develop a specific application: ```bash # Develop the web application @@ -72,13 +80,13 @@ pnpm dev --filter=@shelby-protocol/web ### Building -To build all apps and packages: +To build all applications: ```bash pnpm build ``` -To build a specific package: +To build a specific application: ```bash # Build the web application @@ -102,14 +110,26 @@ Run tests: pnpm test:once ``` -## Contributing +### Table Maintenance + +The applications table above is automatically maintained by the `@shelby-protocol/table-generator` package: -We welcome contributions to the Shelby Protocol examples repository! Please read our contributing guidelines and feel free to submit issues and pull requests. +Update the table: +```bash +pnpm update-table +``` -## License +Check if table is up to date: +```bash +pnpm check-table +``` + +The table generator scans all applications in the `apps/` directory and automatically updates the README with current information including names, descriptions, and links. This ensures the documentation stays synchronized with the actual codebase. + +## Contributing -This repository is open source and available under the [MIT License](LICENSE). +We welcome contributions to the Shelby examples repository! Please read our contributing guidelines and feel free to submit issues and pull requests. --- -Built with ā¤ļø by the [Shelby Protocol team](https://github.com/shelby) \ No newline at end of file +Built with ā¤ļø by the [Shelby team](https://github.com/shelby) diff --git a/apps/web/package.json b/apps/web/package.json index be1eec2..7f3538f 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,7 @@ { "name": "@shelby-protocol/web", "version": "0.1.0", + "description": "A Next.js application showcasing Shelby integrations", "type": "module", "private": true, "scripts": { diff --git a/package.json b/package.json index 6425b3b..6a22f03 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "fmt": "turbo run fmt", "build": "turbo run build", "test:once": "turbo run test:once", - "generate": "turbo run generate" + "generate": "turbo run generate", + "update-table": "pnpm --filter @shelby-protocol/table-generator update-table", + "check-table": "pnpm --filter @shelby-protocol/table-generator check-table" }, "devDependencies": { "@biomejs/biome": "2.0.6", diff --git a/packages/table-generator/package.json b/packages/table-generator/package.json new file mode 100644 index 0000000..73e1e9e --- /dev/null +++ b/packages/table-generator/package.json @@ -0,0 +1,40 @@ +{ + "name": "@shelby-protocol/table-generator", + "version": "0.0.1", + "private": true, + "description": "Automatically generates and maintains the applications table in README.md", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "bin": { + "update-apps-table": "./dist/cli.js" + }, + "scripts": { + "build": "tsc", + "dev": "tsx src/cli.ts", + "lint": "biome check .", + "fmt": "biome check . --write", + "test:once": "echo 'No tests configured'", + "update-table": "tsx src/cli.ts", + "check-table": "tsx src/cli.ts --check" + }, + "dependencies": { + "tsx": "^4.19.2" + }, + "devDependencies": { + "@types/node": "^22.15.3", + "typescript": "5.8.2" + }, + "keywords": [ + "monorepo", + "documentation", + "automation", + "table-generation" + ] +} diff --git a/packages/table-generator/src/cli.ts b/packages/table-generator/src/cli.ts new file mode 100644 index 0000000..aa74232 --- /dev/null +++ b/packages/table-generator/src/cli.ts @@ -0,0 +1,96 @@ +#!/usr/bin/env tsx + +import { resolve } from "node:path"; +import { updateAppsTable } from "./index.js"; + +/** + * Parse command line arguments + */ +function parseArgs() { + const args = process.argv.slice(2); + return { + check: args.includes("--check"), + verbose: args.includes("--verbose") || args.includes("-v"), + help: args.includes("--help") || args.includes("-h"), + }; +} + +/** + * Show help message + */ +function showHelp() { + console.log(` +@shelby-protocol/table-generator + +Automatically generates and maintains the apps table in README.md + +USAGE: + tsx src/cli.ts [options] + pnpm update-table [options] + pnpm check-table + +OPTIONS: + --check Check if table is up to date (exits with code 1 if not) + --verbose, -v Show verbose output + --help, -h Show this help message + +EXAMPLES: + tsx src/cli.ts # Update the table + tsx src/cli.ts --check # Check if table is up to date + tsx src/cli.ts --verbose # Update with verbose output + pnpm update-table # Update using npm script + pnpm check-table # Check using npm script +`); +} + +/** + * Main CLI function + */ +function main() { + const { check, help } = parseArgs(); + + if (help) { + showHelp(); + return; + } + + try { + // Find the monorepo root (2 levels up from this package) + const rootDir = resolve(import.meta.dirname, "../../../"); + + const wasUpdated = updateAppsTable({ + rootDir, + checkOnly: check, + verbose: true, // Always verbose in CLI + }); + + if (check) { + console.log("āœ… README.md table is up to date"); + process.exit(0); + } else if (wasUpdated) { + console.log("šŸ“ README.md has been updated"); + process.exit(0); + } else { + console.log("āœ… No changes needed"); + process.exit(0); + } + } catch (error) { + console.error("āŒ Error:", (error as Error).message); + + if (check && (error as Error).message.includes("out of sync")) { + console.error("\nšŸ’” Run 'pnpm update-table' to fix this"); + } + + process.exit(1); + } +} + +// Run if this script is executed directly +if (import.meta.url === `file://${process.argv[1]}`) { + try { + main(); + } catch (error) { + console.error("Unexpected error:", error); + process.exit(1); + } +} diff --git a/packages/table-generator/src/generator.ts b/packages/table-generator/src/generator.ts new file mode 100644 index 0000000..6c8f989 --- /dev/null +++ b/packages/table-generator/src/generator.ts @@ -0,0 +1,39 @@ +import type { MonorepoItem } from "./types.js"; + +/** + * Generate markdown table for apps and packages + */ +export function generateTable(items: MonorepoItem[], title: string): string { + if (items.length === 0) { + return `### ${title}\n\nNo ${title.toLowerCase()} found.\n`; + } + + const headers = ["Name", "Description", "Path & Links"]; + const separator = headers.map(() => "---").join(" | "); + + let table = `### ${title}\n\n| ${headers.join(" | ")} |\n| ${separator} |\n`; + + for (const item of items) { + const links: string[] = []; + + // Add source link with path + links.push(`[\`${item.path}\`](./${item.path})`); + + // Add homepage link if available + if (item.homepage) { + links.push(`[Live Demo](${item.homepage})`); + } + + // Add repository link if different from homepage + if (item.repository && item.repository !== item.homepage) { + links.push(`[Repository](${item.repository})`); + } + + const pathAndLinks = links.join(" • "); + const escapedDescription = item.description.replace(/\|/g, "\\|"); + + table += `| \`${item.name}\` | ${escapedDescription} | ${pathAndLinks} |\n`; + } + + return `${table}\n`; +} diff --git a/packages/table-generator/src/index.ts b/packages/table-generator/src/index.ts new file mode 100644 index 0000000..99602c6 --- /dev/null +++ b/packages/table-generator/src/index.ts @@ -0,0 +1,63 @@ +import { resolve } from "node:path"; +import { generateTable } from "./generator.js"; +import { updateReadme } from "./readme-updater.js"; +import { getMonorepoApps } from "./scanner.js"; +import type { TableGeneratorOptions } from "./types.js"; + +/** + * Main function to update the apps table in README.md + */ +export function updateAppsTable(options: TableGeneratorOptions = {}) { + const { + rootDir = process.cwd(), + readmePath = resolve(rootDir, "README.md"), + checkOnly = false, + verbose = false, + } = options; + + if (verbose) { + console.log("šŸ” Scanning monorepo for apps..."); + } + + // Scan for apps only + const { apps } = getMonorepoApps(rootDir); + + if (verbose) { + console.log(`Found ${apps.length} apps`); + } + + // Generate apps table only + const appsTable = generateTable(apps, "Applications"); + + // Update README + const result = updateReadme(readmePath, appsTable, ""); + + if (result.error) { + throw new Error(result.error); + } + + if (checkOnly) { + if (result.wasUpdated) { + throw new Error("README.md table is out of sync"); + } + if (verbose) console.log("āœ… README.md table is up to date"); + return false; + } + + if (result.wasUpdated) { + if (verbose) console.log("āœ… Updated README.md with latest apps table"); + return true; + } + if (verbose) console.log("āœ… Table is already up to date"); + return false; +} + +export { generateTable } from "./generator.js"; +export { updateReadme } from "./readme-updater.js"; +export { getMonorepoApps } from "./scanner.js"; +// Re-export types and functions for library usage +export type { + MonorepoApps, + MonorepoItem, + TableGeneratorOptions, +} from "./types.js"; diff --git a/packages/table-generator/src/readme-updater.ts b/packages/table-generator/src/readme-updater.ts new file mode 100644 index 0000000..b589c90 --- /dev/null +++ b/packages/table-generator/src/readme-updater.ts @@ -0,0 +1,65 @@ +import { readFileSync, writeFileSync } from "node:fs"; + +const START_MARKER = ""; +const END_MARKER = ""; + +/** + * Update README.md with the generated table + */ +export function updateReadme( + readmePath: string, + appsTable: string, + packagesTable: string, +): { wasUpdated: boolean; error?: string } { + let readmeContent: string; + + try { + readmeContent = readFileSync(readmePath, "utf-8"); + } catch (error) { + return { + wasUpdated: false, + error: `Could not read README.md: ${(error as Error).message}`, + }; + } + + const startIndex = readmeContent.indexOf(START_MARKER); + const endIndex = readmeContent.indexOf(END_MARKER); + + if (startIndex === -1 || endIndex === -1) { + return { + wasUpdated: false, + error: `Could not find table markers in README.md. Please add:\n${START_MARKER}\n${END_MARKER}`, + }; + } + + const beforeTable = readmeContent.substring( + 0, + startIndex + START_MARKER.length, + ); + const afterTable = readmeContent.substring(endIndex); + + const tableContent = [ + "", + "", + "", + appsTable.trimEnd(), + packagesTable.trimEnd(), + "", + ].join("\n"); + + const newReadmeContent = beforeTable + tableContent + afterTable; + + if (newReadmeContent === readmeContent) { + return { wasUpdated: false }; + } + + try { + writeFileSync(readmePath, newReadmeContent, "utf-8"); + return { wasUpdated: true }; + } catch (error) { + return { + wasUpdated: false, + error: `Could not write README.md: ${(error as Error).message}`, + }; + } +} diff --git a/packages/table-generator/src/scanner.ts b/packages/table-generator/src/scanner.ts new file mode 100644 index 0000000..92925a5 --- /dev/null +++ b/packages/table-generator/src/scanner.ts @@ -0,0 +1,91 @@ +import { readdirSync, readFileSync, statSync } from "node:fs"; +import { join } from "node:path"; +import type { MonorepoApps, MonorepoItem, PackageInfo } from "./types.js"; + +/** + * Get package.json content for a given path + */ +function getPackageInfo(packagePath: string): PackageInfo | null { + try { + const pkgJsonPath = join(packagePath, "package.json"); + const pkgJson = JSON.parse( + readFileSync(pkgJsonPath, "utf-8"), + ) as PackageInfo; + return pkgJson; + } catch (error) { + console.warn( + `Could not read package.json for ${packagePath}:`, + (error as Error).message, + ); + return null; + } +} + +/** + * Scan a directory for packages/apps + */ +function scanDirectory( + dirPath: string, + type: "app" | "package", + relativePath: string, +): MonorepoItem[] { + const items: MonorepoItem[] = []; + + try { + const dirs = readdirSync(dirPath); + for (const dir of dirs) { + const fullPath = join(dirPath, dir); + if (statSync(fullPath).isDirectory()) { + const pkgInfo = getPackageInfo(fullPath); + if (pkgInfo) { + let repository: string | undefined; + if (typeof pkgInfo.repository === "string") { + repository = pkgInfo.repository; + } else if ( + typeof pkgInfo.repository === "object" && + pkgInfo.repository?.url + ) { + repository = pkgInfo.repository.url; + } + + if (repository) { + // Clean up git URLs + repository = repository.replace(/^git\+/, "").replace(/\.git$/, ""); + } + + items.push({ + name: pkgInfo.name, + description: pkgInfo.description || "No description provided", + path: `${relativePath}/${dir}`, + type, + private: pkgInfo.private || false, + homepage: pkgInfo.homepage, + repository, + }); + } + } + } + } catch (error) { + console.warn( + `Could not scan ${relativePath} directory:`, + (error as Error).message, + ); + } + + return items; +} + +/** + * Get all apps and packages from the monorepo + */ +export function getMonorepoApps(rootDir: string): MonorepoApps { + const appsDir = join(rootDir, "apps"); + const packagesDir = join(rootDir, "packages"); + + const apps = scanDirectory(appsDir, "app", "apps"); + const packages = scanDirectory(packagesDir, "package", "packages") + // Filter out the table-generator package itself + .filter((pkg) => !pkg.name.includes("table-generator")); + + return { apps, packages }; +} diff --git a/packages/table-generator/src/types.ts b/packages/table-generator/src/types.ts new file mode 100644 index 0000000..4b01d03 --- /dev/null +++ b/packages/table-generator/src/types.ts @@ -0,0 +1,30 @@ +export interface PackageInfo { + name: string; + description?: string; + homepage?: string; + repository?: string | { url: string }; + private?: boolean; + [key: string]: unknown; +} + +export interface MonorepoItem { + name: string; + description: string; + path: string; + type: "app" | "package"; + private: boolean; + homepage?: string; + repository?: string; +} + +export interface MonorepoApps { + apps: MonorepoItem[]; + packages: MonorepoItem[]; +} + +export interface TableGeneratorOptions { + rootDir?: string; + readmePath?: string; + checkOnly?: boolean; + verbose?: boolean; +} diff --git a/packages/table-generator/tsconfig.json b/packages/table-generator/tsconfig.json new file mode 100644 index 0000000..a9163d9 --- /dev/null +++ b/packages/table-generator/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "ESNext", + "moduleResolution": "bundler", + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": false, + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/ui/package.json b/packages/ui/package.json index 5e89b5b..799270b 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,7 @@ { "name": "@shelby-protocol/ui", "version": "0.0.0", + "description": "A React component library shared across applications", "private": true, "exports": { "./*": "./src/*.tsx" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d37483c..9ca7bc4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,6 +52,19 @@ importers: specifier: 5.8.2 version: 5.8.2 + packages/table-generator: + dependencies: + tsx: + specifier: ^4.19.2 + version: 4.20.5 + devDependencies: + '@types/node': + specifier: ^22.15.3 + version: 22.18.6 + typescript: + specifier: 5.8.2 + version: 5.8.2 + packages/ui: dependencies: react: @@ -132,6 +145,162 @@ packages: '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + '@esbuild/aix-ppc64@0.25.10': + resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.10': + resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.10': + resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.10': + resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.10': + resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.10': + resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.10': + resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.10': + resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.10': + resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.10': + resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.10': + resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.10': + resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.10': + resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.10': + resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.10': + resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.10': + resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.10': + resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.10': + resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.10': + resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.10': + resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.10': + resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.10': + resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.10': + resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.10': + resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.10': + resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.10': + resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@img/sharp-darwin-arm64@0.34.3': resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -352,6 +521,19 @@ packages: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} + esbuild@0.25.10: + resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} + engines: {node: '>=18'} + hasBin: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -404,6 +586,9 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -439,6 +624,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.5: + resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} + engines: {node: '>=18.0.0'} + hasBin: true + turbo-darwin-64@2.5.7: resolution: {integrity: sha512-c7QvEnTuBjKcw7HvVIoAe0qrmKlUgF2xYGnewICfvwruOpjGcKMKhDLiqZqbkYytr4eCgXTku4UCarVABsM9KA==} cpu: [x64] @@ -523,6 +713,84 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.25.10': + optional: true + + '@esbuild/android-arm64@0.25.10': + optional: true + + '@esbuild/android-arm@0.25.10': + optional: true + + '@esbuild/android-x64@0.25.10': + optional: true + + '@esbuild/darwin-arm64@0.25.10': + optional: true + + '@esbuild/darwin-x64@0.25.10': + optional: true + + '@esbuild/freebsd-arm64@0.25.10': + optional: true + + '@esbuild/freebsd-x64@0.25.10': + optional: true + + '@esbuild/linux-arm64@0.25.10': + optional: true + + '@esbuild/linux-arm@0.25.10': + optional: true + + '@esbuild/linux-ia32@0.25.10': + optional: true + + '@esbuild/linux-loong64@0.25.10': + optional: true + + '@esbuild/linux-mips64el@0.25.10': + optional: true + + '@esbuild/linux-ppc64@0.25.10': + optional: true + + '@esbuild/linux-riscv64@0.25.10': + optional: true + + '@esbuild/linux-s390x@0.25.10': + optional: true + + '@esbuild/linux-x64@0.25.10': + optional: true + + '@esbuild/netbsd-arm64@0.25.10': + optional: true + + '@esbuild/netbsd-x64@0.25.10': + optional: true + + '@esbuild/openbsd-arm64@0.25.10': + optional: true + + '@esbuild/openbsd-x64@0.25.10': + optional: true + + '@esbuild/openharmony-arm64@0.25.10': + optional: true + + '@esbuild/sunos-x64@0.25.10': + optional: true + + '@esbuild/win32-arm64@0.25.10': + optional: true + + '@esbuild/win32-ia32@0.25.10': + optional: true + + '@esbuild/win32-x64@0.25.10': + optional: true + '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.2.0 @@ -687,6 +955,42 @@ snapshots: detect-libc@2.0.4: optional: true + esbuild@0.25.10: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.10 + '@esbuild/android-arm': 0.25.10 + '@esbuild/android-arm64': 0.25.10 + '@esbuild/android-x64': 0.25.10 + '@esbuild/darwin-arm64': 0.25.10 + '@esbuild/darwin-x64': 0.25.10 + '@esbuild/freebsd-arm64': 0.25.10 + '@esbuild/freebsd-x64': 0.25.10 + '@esbuild/linux-arm': 0.25.10 + '@esbuild/linux-arm64': 0.25.10 + '@esbuild/linux-ia32': 0.25.10 + '@esbuild/linux-loong64': 0.25.10 + '@esbuild/linux-mips64el': 0.25.10 + '@esbuild/linux-ppc64': 0.25.10 + '@esbuild/linux-riscv64': 0.25.10 + '@esbuild/linux-s390x': 0.25.10 + '@esbuild/linux-x64': 0.25.10 + '@esbuild/netbsd-arm64': 0.25.10 + '@esbuild/netbsd-x64': 0.25.10 + '@esbuild/openbsd-arm64': 0.25.10 + '@esbuild/openbsd-x64': 0.25.10 + '@esbuild/openharmony-arm64': 0.25.10 + '@esbuild/sunos-x64': 0.25.10 + '@esbuild/win32-arm64': 0.25.10 + '@esbuild/win32-ia32': 0.25.10 + '@esbuild/win32-x64': 0.25.10 + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + is-arrayish@0.3.2: optional: true @@ -739,6 +1043,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + resolve-pkg-maps@1.0.0: {} + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -790,6 +1096,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.5: + dependencies: + esbuild: 0.25.10 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + turbo-darwin-64@2.5.7: optional: true