Skip to content

Commit a457e33

Browse files
authored
Merge pull request #25 from noxify/cli-template-fetch
replace github api with our own template list
2 parents dab74de + 05c052a commit a457e33

File tree

5 files changed

+62
-52
lines changed

5 files changed

+62
-52
lines changed

.changeset/rude-candies-brush.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"create-vorsteh-queue": patch
3+
---
4+
5+
use static json list from our own website to fetch the available templates.
6+
7+
This solves the "Rate limit" problem which comes from the GitHub API.

apps/docs/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"class-variance-authority": "0.7.1",
3838
"clsx": "2.1.1",
3939
"date-fns": "^4.1.0",
40+
"globby": "14.1.0",
4041
"interweave": "13.1.1",
4142
"lucide-react": "0.542.0",
4243
"multimatch": "7.0.0",
@@ -45,6 +46,7 @@
4546
"p-map": "7.0.3",
4647
"react": "19.1.1",
4748
"react-dom": "19.1.1",
49+
"read-pkg": "^9.0.1",
4850
"rehype-mdx-import-media": "1.2.0",
4951
"remark-frontmatter": "5.0.0",
5052
"remark-gfm": "4.0.1",
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as path from "path"
2+
import { NextResponse } from "next/server"
3+
import { globby } from "globby"
4+
import pMap from "p-map"
5+
import { readPackage } from "read-pkg"
6+
7+
export const dynamic = "force-static"
8+
9+
export async function GET() {
10+
const examplePkgJson = await globby(["**/*/package.json"], {
11+
cwd: path.join(process.cwd(), "..", "..", "examples"),
12+
expandDirectories: true,
13+
absolute: true,
14+
deep: 2,
15+
gitignore: true,
16+
})
17+
18+
const parsedTemplates = await pMap(examplePkgJson, async (file) => {
19+
const content = await readPackage({ cwd: path.dirname(file) })
20+
return {
21+
name: content.name || path.basename(path.dirname(file)),
22+
alias: path.basename(path.dirname(file)),
23+
path: path.join("examples", path.basename(path.dirname(file))),
24+
description: content.description ?? "No description",
25+
}
26+
})
27+
28+
return NextResponse.json({ templates: parsedTemplates })
29+
}

packages/create-vorsteh-queue/src/index.ts

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,82 +11,48 @@ import terminalLink from "terminal-link"
1111

1212
interface Template {
1313
name: string
14+
alias: string
1415
description: string
1516
path: string
1617
}
1718

18-
interface GitHubContent {
19-
name: string
20-
type: string
21-
download_url?: string
22-
}
23-
24-
interface GitHubFile {
25-
content: string
26-
}
27-
2819
interface NpmPackageData {
2920
version: string
3021
}
3122

32-
type PackageJson = Awaited<ReturnType<typeof readPackage>>
33-
3423
async function fetchTemplates(): Promise<Template[]> {
3524
const s = spinner()
3625
s.start("Discovering templates...")
3726

3827
try {
3928
// Fetch examples directory contents
40-
const response = await fetch(
41-
"https://api.github.com/repos/noxify/vorsteh-queue/contents/examples",
42-
)
43-
if (!response.ok) throw new Error(`HTTP ${response.status}`)
29+
const response = await fetch("https://vorsteh-queue.dev/templates.json")
4430

45-
const contents = (await response.json()) as GitHubContent[]
46-
const templates: Template[] = []
47-
48-
// Process each directory in examples/
49-
for (const item of contents) {
50-
if (item.type === "dir") {
51-
try {
52-
// Fetch package.json for each example
53-
const pkgResponse = await fetch(
54-
`https://api.github.com/repos/noxify/vorsteh-queue/contents/examples/${item.name}/package.json`,
55-
)
56-
if (pkgResponse.ok) {
57-
const pkgData = (await pkgResponse.json()) as GitHubFile
58-
const pkgContent = JSON.parse(atob(pkgData.content)) as Partial<PackageJson>
59-
60-
templates.push({
61-
name: pkgContent.name ?? item.name,
62-
description: pkgContent.description ?? `${item.name} example`,
63-
path: `examples/${item.name}`,
64-
})
65-
}
66-
} catch (error) {
67-
// Skip directories without valid package.json
68-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
69-
console.warn(pc.yellow(`⚠️ Skipping ${item.name}: ${error}`))
70-
}
71-
}
31+
if (!response.ok) {
32+
throw new Error(`HTTP ${response.status}`)
7233
}
7334

74-
s.stop(`Found ${templates.length} templates`)
75-
return templates
76-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
77-
} catch (error) {
78-
s.stop("Failed to fetch templates")
35+
const responseBody = (await response.json()) as { templates: Template[] }
36+
37+
s.stop(`Found ${responseBody.templates.length} templates`)
38+
return responseBody.templates
39+
} catch (error: unknown) {
40+
s.stop(
41+
`Failed to fetch templates - ${error instanceof Error ? error.toString() : String(error)}`,
42+
)
7943
// Fallback to hardcoded templates
8044

8145
console.warn(pc.yellow("⚠️ Using fallback templates"))
8246
return [
8347
{
84-
name: "drizzle-postgres",
48+
name: "drizzle-postgres-example",
49+
alias: "drizzle-postgres",
8550
description: "Drizzle ORM + postgres.js",
8651
path: "examples/drizzle-postgres",
8752
},
8853
{
89-
name: "drizzle-pglite",
54+
name: "drizzle-pglite-example",
55+
alias: "drizzle-pglite",
9056
description: "Drizzle ORM + PGlite (Embedded)",
9157
path: "examples/drizzle-pglite",
9258
},

pnpm-lock.yaml

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)