diff --git a/apps/web/package.json b/apps/web/package.json index fc35203..c469017 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "dev": "next dev", - "build": "next build", + "build": "node scripts/copy-registry.mjs && next build", "start": "next start", "lint": "eslint .", "typecheck": "tsc --noEmit", diff --git a/apps/web/scripts/copy-registry.mjs b/apps/web/scripts/copy-registry.mjs new file mode 100644 index 0000000..3546570 --- /dev/null +++ b/apps/web/scripts/copy-registry.mjs @@ -0,0 +1,40 @@ +#!/usr/bin/env node + +/** + * Copies the built registry JSON from packages/registry/public/r/ into + * apps/web/public/r/ so Next.js can serve them at /r/*.json. + * + * Running this as part of web:build (instead of registry:build) means the + * files land in web:build's turbo cache outputs and get restored on cache + * hit — otherwise apps/web/public/r/ is empty on Vercel when registry:build + * hits the remote cache and its script doesn't re-execute. + */ +import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const WEB_DIR = join(__dirname, ".."); +const REGISTRY_R = join( + WEB_DIR, + "..", + "..", + "packages", + "registry", + "public", + "r", +); +const WEB_R = join(WEB_DIR, "public", "r"); + +if (!existsSync(REGISTRY_R)) { + console.error( + "No packages/registry/public/r/ found. Did registry:build run?", + ); + process.exit(1); +} + +rmSync(WEB_R, { recursive: true, force: true }); +mkdirSync(WEB_R, { recursive: true }); +cpSync(REGISTRY_R, WEB_R, { recursive: true }); + +console.log("Registry output copied to apps/web/public/r/"); diff --git a/packages/registry/scripts/copy-to-web.mjs b/packages/registry/scripts/copy-to-web.mjs index 5bf823e..dbbe0f7 100644 --- a/packages/registry/scripts/copy-to-web.mjs +++ b/packages/registry/scripts/copy-to-web.mjs @@ -1,9 +1,11 @@ #!/usr/bin/env node /** - * Copies the shadcn build output from dist/public/r/ to: - * - packages/registry/public/r/ (canonical location) - * - apps/web/public/r/ (served by Next.js) + * Copies the shadcn build output from dist/public/r/ to + * packages/registry/public/r/ (the canonical registry output location). + * + * apps/web copies from here during its own build so the JSON files become + * part of web:build's turbo cache — see apps/web/scripts/copy-registry.mjs. */ import { cpSync, existsSync, mkdirSync } from "node:fs"; import { dirname, join } from "node:path"; @@ -13,16 +15,13 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); const ROOT_DIR = join(__dirname, ".."); const DIST_R = join(ROOT_DIR, "dist", "public", "r"); const LOCAL_R = join(ROOT_DIR, "public", "r"); -const WEB_R = join(ROOT_DIR, "..", "..", "apps", "web", "public", "r"); if (!existsSync(DIST_R)) { console.error("No dist/public/r/ found. Did shadcn build run?"); process.exit(1); } -for (const dest of [LOCAL_R, WEB_R]) { - mkdirSync(dest, { recursive: true }); - cpSync(DIST_R, dest, { recursive: true }); -} +mkdirSync(LOCAL_R, { recursive: true }); +cpSync(DIST_R, LOCAL_R, { recursive: true }); -console.log("Registry output copied to public/r/ and apps/web/public/r/"); +console.log("Registry output copied to public/r/"); diff --git a/turbo.json b/turbo.json index 548c39c..667c2e6 100644 --- a/turbo.json +++ b/turbo.json @@ -3,7 +3,7 @@ "tasks": { "build": { "dependsOn": ["^build", "^registry:build"], - "outputs": [".next/**", "!.next/cache/**"] + "outputs": [".next/**", "!.next/cache/**", "public/r/**"] }, "registry:build": { "outputs": ["public/r/**"]