diff --git a/.changeset/rude-candies-brush.md b/.changeset/rude-candies-brush.md new file mode 100644 index 0000000..5eec8a1 --- /dev/null +++ b/.changeset/rude-candies-brush.md @@ -0,0 +1,7 @@ +--- +"create-vorsteh-queue": patch +--- + +use static json list from our own website to fetch the available templates. + +This solves the "Rate limit" problem which comes from the GitHub API. diff --git a/apps/docs/package.json b/apps/docs/package.json index 44e13bd..18fbd62 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -37,6 +37,7 @@ "class-variance-authority": "0.7.1", "clsx": "2.1.1", "date-fns": "^4.1.0", + "globby": "14.1.0", "interweave": "13.1.1", "lucide-react": "0.542.0", "multimatch": "7.0.0", @@ -45,6 +46,7 @@ "p-map": "7.0.3", "react": "19.1.1", "react-dom": "19.1.1", + "read-pkg": "^9.0.1", "rehype-mdx-import-media": "1.2.0", "remark-frontmatter": "5.0.0", "remark-gfm": "4.0.1", diff --git a/apps/docs/src/app/templates.json/route.ts b/apps/docs/src/app/templates.json/route.ts new file mode 100644 index 0000000..5e4041a --- /dev/null +++ b/apps/docs/src/app/templates.json/route.ts @@ -0,0 +1,29 @@ +import * as path from "path" +import { NextResponse } from "next/server" +import { globby } from "globby" +import pMap from "p-map" +import { readPackage } from "read-pkg" + +export const dynamic = "force-static" + +export async function GET() { + const examplePkgJson = await globby(["**/*/package.json"], { + cwd: path.join(process.cwd(), "..", "..", "examples"), + expandDirectories: true, + absolute: true, + deep: 2, + gitignore: true, + }) + + const parsedTemplates = await pMap(examplePkgJson, async (file) => { + const content = await readPackage({ cwd: path.dirname(file) }) + return { + name: content.name || path.basename(path.dirname(file)), + alias: path.basename(path.dirname(file)), + path: path.join("examples", path.basename(path.dirname(file))), + description: content.description ?? "No description", + } + }) + + return NextResponse.json({ templates: parsedTemplates }) +} diff --git a/packages/create-vorsteh-queue/src/index.ts b/packages/create-vorsteh-queue/src/index.ts index 8472864..f6a2dc8 100644 --- a/packages/create-vorsteh-queue/src/index.ts +++ b/packages/create-vorsteh-queue/src/index.ts @@ -11,82 +11,48 @@ import terminalLink from "terminal-link" interface Template { name: string + alias: string description: string path: string } -interface GitHubContent { - name: string - type: string - download_url?: string -} - -interface GitHubFile { - content: string -} - interface NpmPackageData { version: string } -type PackageJson = Awaited> - async function fetchTemplates(): Promise { const s = spinner() s.start("Discovering templates...") try { // Fetch examples directory contents - const response = await fetch( - "https://api.github.com/repos/noxify/vorsteh-queue/contents/examples", - ) - if (!response.ok) throw new Error(`HTTP ${response.status}`) + const response = await fetch("https://vorsteh-queue.dev/templates.json") - const contents = (await response.json()) as GitHubContent[] - const templates: Template[] = [] - - // Process each directory in examples/ - for (const item of contents) { - if (item.type === "dir") { - try { - // Fetch package.json for each example - const pkgResponse = await fetch( - `https://api.github.com/repos/noxify/vorsteh-queue/contents/examples/${item.name}/package.json`, - ) - if (pkgResponse.ok) { - const pkgData = (await pkgResponse.json()) as GitHubFile - const pkgContent = JSON.parse(atob(pkgData.content)) as Partial - - templates.push({ - name: pkgContent.name ?? item.name, - description: pkgContent.description ?? `${item.name} example`, - path: `examples/${item.name}`, - }) - } - } catch (error) { - // Skip directories without valid package.json - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - console.warn(pc.yellow(`⚠️ Skipping ${item.name}: ${error}`)) - } - } + if (!response.ok) { + throw new Error(`HTTP ${response.status}`) } - s.stop(`Found ${templates.length} templates`) - return templates - // eslint-disable-next-line @typescript-eslint/no-unused-vars - } catch (error) { - s.stop("Failed to fetch templates") + const responseBody = (await response.json()) as { templates: Template[] } + + s.stop(`Found ${responseBody.templates.length} templates`) + return responseBody.templates + } catch (error: unknown) { + s.stop( + `Failed to fetch templates - ${error instanceof Error ? error.toString() : String(error)}`, + ) // Fallback to hardcoded templates console.warn(pc.yellow("⚠️ Using fallback templates")) return [ { - name: "drizzle-postgres", + name: "drizzle-postgres-example", + alias: "drizzle-postgres", description: "Drizzle ORM + postgres.js", path: "examples/drizzle-postgres", }, { - name: "drizzle-pglite", + name: "drizzle-pglite-example", + alias: "drizzle-pglite", description: "Drizzle ORM + PGlite (Embedded)", path: "examples/drizzle-pglite", }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c202d7..7813782 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.29.6(@types/node@24.3.0) '@vitest/coverage-v8': specifier: 3.2.4 - version: 3.2.4(vitest@3.2.4) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(@vitest/ui@3.2.4)(jiti@2.5.1)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.3.0)(typescript@5.9.2))(tsx@4.20.5)(yaml@2.8.1)) '@vitest/ui': specifier: 3.2.4 version: 3.2.4(vitest@3.2.4) @@ -98,6 +98,9 @@ importers: date-fns: specifier: ^4.1.0 version: 4.1.0 + globby: + specifier: 14.1.0 + version: 14.1.0 interweave: specifier: 13.1.1 version: 13.1.1(react@19.1.1) @@ -122,6 +125,9 @@ importers: react-dom: specifier: 19.1.1 version: 19.1.1(react@19.1.1) + read-pkg: + specifier: ^9.0.1 + version: 9.0.1 rehype-mdx-import-media: specifier: 1.2.0 version: 1.2.0 @@ -9198,7 +9204,7 @@ snapshots: '@resvg/resvg-wasm': 2.4.0 satori: 0.16.0 - '@vitest/coverage-v8@3.2.4(vitest@3.2.4)': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(@vitest/ui@3.2.4)(jiti@2.5.1)(lightningcss@1.30.1)(msw@2.10.4(@types/node@24.3.0)(typescript@5.9.2))(tsx@4.20.5)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2