create-apollo-monorepo 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.mjs +118 -1
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -325,9 +325,47 @@ function writeRootPackageJson(targetDir, dirName) {
325
325
  "backend:setup": "pnpm --filter ./apps/backend setup",
326
326
  },
327
327
  engines: { node: ">=20", pnpm: ">=9" },
328
- packageManager: "pnpm@9.0.0",
328
+ pnpm: {
329
+ // apollo-cms transitively pulls multiple esbuild versions (0.18, 0.25, 0.27).
330
+ // pnpm's binary symlink can pick the wrong platform binary for esbuild's
331
+ // postinstall version check, failing with "Expected X.Y.Z but got A.B.C".
332
+ // Allow listed packages to run their build/postinstall scripts; the rest
333
+ // are skipped (pnpm 10 default is empty allow-list).
334
+ onlyBuiltDependencies: [
335
+ "@swc/core",
336
+ "@swc/core-darwin-arm64",
337
+ "@swc/core-darwin-x64",
338
+ "@swc/core-linux-arm64-gnu",
339
+ "@swc/core-linux-x64-gnu",
340
+ "esbuild",
341
+ "msw",
342
+ "sharp",
343
+ "unrs-resolver",
344
+ "@rolldown/binding-darwin-arm64",
345
+ "@rolldown/binding-linux-x64-gnu",
346
+ "@rolldown/binding-linux-arm64-gnu",
347
+ "better-sqlite3",
348
+ "core-js",
349
+ "core-js-pure",
350
+ ],
351
+ },
329
352
  };
330
353
  writeFileSync(resolve(targetDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
354
+
355
+ // .npmrc — keep peer-deps lenient and hoist esbuild's platform binaries so
356
+ // its postinstall version check resolves the correct one across nested
357
+ // dependency trees.
358
+ writeFileSync(
359
+ resolve(targetDir, ".npmrc"),
360
+ [
361
+ "auto-install-peers=true",
362
+ "strict-peer-dependencies=false",
363
+ "public-hoist-pattern[]=*esbuild*",
364
+ "public-hoist-pattern[]=*types*",
365
+ "shell-emulator=true",
366
+ "",
367
+ ].join("\n"),
368
+ );
331
369
  }
332
370
 
333
371
  function writePnpmWorkspace(targetDir) {
@@ -540,6 +578,20 @@ export default config;
540
578
  resolve(dir, ".gitignore"),
541
579
  ["node_modules", ".next", "dist", ".env.local", ""].join("\n"),
542
580
  );
581
+
582
+ // Vercel project config for the frontend. Skip cron + region pinning is
583
+ // optional; configure Root Directory + "Include all submodules" in the
584
+ // Vercel UI when linking the project.
585
+ const vercelJson = {
586
+ $schema: "https://openapi.vercel.sh/vercel.json",
587
+ regions: ["sin1"],
588
+ };
589
+ writeFileSync(resolve(dir, "vercel.json"), JSON.stringify(vercelJson, null, 2) + "\n");
590
+
591
+ writeFileSync(
592
+ resolve(dir, ".vercelignore"),
593
+ ["node_modules", ".next", ".env.local", ""].join("\n"),
594
+ );
543
595
  }
544
596
 
545
597
  function writeReadme(targetDir, dirName, frontendName, assetPrefix) {
@@ -629,6 +681,71 @@ Do **not** edit files inside \`apps/backend\`. Open issues / PRs in the
629
681
 
630
682
  Shared dev env lives in the root \`.env.local\`. The backend reads its own
631
683
  \`apps/backend/.env.local\` (already populated by the installer).
684
+
685
+ ## Deploy on Vercel
686
+
687
+ Two Vercel projects, one repo. Each project picks up its own Root Directory.
688
+
689
+ ### 1) Backend project
690
+
691
+ - **Import** this repo into Vercel as a new project.
692
+ - **Root Directory**: \`apps/backend\`
693
+ - **Build Command**: \`cd ../.. && pnpm install --frozen-lockfile && pnpm --filter ./apps/backend build\`
694
+ - **Install Command**: leave empty (handled in build)
695
+ - **Settings → Git → Include all submodules: ON** (Vercel checks out an empty \`apps/backend\` otherwise)
696
+ - **Environment variables**:
697
+ \`\`\`
698
+ DATABASE_URL=postgresql://…
699
+ APOLLO_SECRET=<openssl rand -hex 32>
700
+ NEXT_PUBLIC_SITE_URL=https://yourdomain.com # the PUBLIC origin
701
+ NEXT_PUBLIC_DEFAULT_LOCALE=en
702
+ ${singleOrigin ? `APOLLO_ASSET_PREFIX=${assetPrefix}` : "# APOLLO_ASSET_PREFIX=/cms-assets # only when single-origin"}
703
+ CRON_SECRET=<random> # protects /api/cron
704
+ # Storage on Vercel cannot use local FS — pick one:
705
+ # Vercel Blob: BLOB_READ_WRITE_TOKEN=…
706
+ # S3 / R2 / Spaces: S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_BUCKET, S3_REGION, S3_ENDPOINT
707
+ APOLLO_DISABLE_LOCAL_STORAGE=1
708
+ \`\`\`
709
+ - **Cron**: \`apps/backend/vercel.json\` declares \`/api/cron\` on a 5-minute schedule (from apollo-cms upstream).
710
+
711
+ ### 2) Frontend project
712
+
713
+ - **Import the same repo** as a separate Vercel project.
714
+ - **Root Directory**: \`apps/frontend\`
715
+ - **Build Command**: \`cd ../.. && pnpm install --frozen-lockfile && pnpm --filter ./apps/frontend build\`
716
+ - **Install Command**: leave empty
717
+ - **Settings → Git → Include all submodules: ON**
718
+ - **Environment variables**:
719
+ \`\`\`
720
+ NEXT_PUBLIC_SITE_URL=https://yourdomain.com
721
+ ${singleOrigin
722
+ ? ` BACKEND_INTERNAL_URL=https://<your-backend>.vercel.app\n NEXT_PUBLIC_APOLLO_ASSET_PREFIX=${assetPrefix}`
723
+ : ` NEXT_PUBLIC_BACKEND_URL=https://<your-backend>.vercel.app`
724
+ }
725
+ \`\`\`
726
+
727
+ ### 3) Custom domain
728
+
729
+ Attach \`yourdomain.com\` to the **frontend** project${singleOrigin ? " (in single-origin mode it's the public entry point)" : ""}. The backend stays on its \`*.vercel.app\` URL${singleOrigin ? " — that's what the rewrite proxies to" : ""}.
730
+
731
+ ### 4) Skip duplicate builds (optional)
732
+
733
+ Each push triggers both projects to rebuild. Add an **Ignored Build Step** in
734
+ each project's Settings → Git:
735
+
736
+ - **Backend**: \`git diff HEAD^ HEAD --quiet -- apps/backend\` (exits 0 → skip build)
737
+ - **Frontend**: \`git diff HEAD^ HEAD --quiet -- apps/frontend\`
738
+
739
+ ### Gotchas
740
+
741
+ - **Submodule must be initialized** on Vercel — the "Include all submodules"
742
+ toggle is the most common reason builds fail with a missing \`apps/backend\`.
743
+ - **OAuth callbacks** for email providers must use the public domain:
744
+ \`https://yourdomain.com/api/email/oauth/callback\`.${singleOrigin ? " The frontend rewrite forwards it to the backend." : ""}
745
+ - **Cron** runs on the backend project only. Vercel sends \`Authorization:
746
+ Bearer $CRON_SECRET\` automatically when \`CRON_SECRET\` is set.${singleOrigin ? `
747
+ - **Better Auth** uses \`trustedProxyHeaders: true\` so the rewrite proxy's
748
+ \`x-forwarded-host\` lands cookies at the public origin without extra config.` : ""}
632
749
  `;
633
750
  writeFileSync(resolve(targetDir, "README.md"), readme);
634
751
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-apollo-monorepo",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Scaffold a monorepo with a frontend app and Apollo CMS as a git submodule backend (single-origin via Next.js rewrites + assetPrefix)",
5
5
  "bin": {
6
6
  "create-apollo-monorepo": "index.mjs"