create-apollo-monorepo 0.5.0 → 0.5.2

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 (3) hide show
  1. package/README.md +17 -7
  2. package/index.mjs +26 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -44,19 +44,29 @@ collide:
44
44
  | Browser path | Goes to |
45
45
  | ------------------------------------ | -------------------- |
46
46
  | `/`, your custom routes | `apps/frontend` |
47
- | `/admin/*` | `apps/backend` |
47
+ | `/admin/*` | `apps/backend` (admin pages **and** their JS chunks) |
48
48
  | `/api/auth/*`, `/api/v1/*`, `/api/admin/*`, `/api/email/*`, `/api/cron`, `/api/health`, `/api/mcp`, `/api/editing-presence/*` | `apps/backend` |
49
49
  | `/uploads/*` | `apps/backend` (media) |
50
- | `/cms-assets/*` | `apps/backend` chunks (via `APOLLO_ASSET_PREFIX`) |
51
50
  | `/monitoring` | `apps/backend` (Sentry tunnel, no-op without DSN) |
52
51
 
53
- Apollo CMS picks up `APOLLO_ASSET_PREFIX=/cms-assets` and serves its built JS
54
- under that namespace, sidestepping the `/_next/*` collision. The frontend
55
- **must not** define routes at `/admin`, `/api/auth`, `/api/v1`, etc.
52
+ Apollo CMS reads `APOLLO_ASSET_PREFIX` (default `/admin`) and serves its built
53
+ JS under `<prefix>/_next/static/`. Because the prefix coincides with the admin
54
+ path, a single `/admin/:path*` rewrite covers both pages and chunks — no
55
+ separate asset rewrite is emitted. The frontend **must not** define routes at
56
+ `/admin`, `/api/auth`, `/api/v1`, etc.
57
+
58
+ You can override the prefix:
59
+
60
+ ```bash
61
+ npx create-apollo-monorepo my-app --admin-prefix /cms
62
+ ```
63
+
64
+ When the prefix is anything other than `/admin`, the scaffold also emits a
65
+ matching `<prefix>/:path*` rewrite for backend chunks.
56
66
 
57
67
  ### Separate origins (fallback)
58
68
 
59
- Pass `--asset-prefix none` (or `off`/`false`/`disabled`) to skip the rewrite
69
+ Pass `--admin-prefix none` (or `off`/`false`/`disabled`) to skip the rewrite
60
70
  wiring. The backend runs at `http://localhost:3000` and the frontend at
61
71
  `http://localhost:3001`. Useful when you'd rather deploy them on separate
62
72
  subdomains (e.g. `cms.example.com` + `example.com`).
@@ -71,7 +81,7 @@ subdomains (e.g. `cms.example.com` + `example.com`).
71
81
  | `-d, --db <url>` | _(prompted)_ | `DATABASE_URL` for backend |
72
82
  | `-u, --url <url>` | `:3001` single-origin / `:3000` separate | `NEXT_PUBLIC_SITE_URL` |
73
83
  | `-l, --locale <code>` | `en` | `NEXT_PUBLIC_DEFAULT_LOCALE` |
74
- | `--asset-prefix <path>` | `/cms-assets` | Single-origin asset namespace; `none` to disable |
84
+ | `--admin-prefix <path>` | `/admin` | Single-origin admin/asset namespace; `none` to disable. Alias: `--asset-prefix` |
75
85
  | `--skip-install` | off | Don't run `pnpm install` |
76
86
  | `--skip-submodule` | off | Don't add the git submodule |
77
87
  | `-h, --help` | — | Show help |
package/index.mjs CHANGED
@@ -57,7 +57,7 @@ ${COLORS.bold}Flags:${COLORS.reset}
57
57
  -u, --url <url> NEXT_PUBLIC_SITE_URL (default: http://localhost:3001 single-origin / 3000 separate)
58
58
  -l, --locale <code> NEXT_PUBLIC_DEFAULT_LOCALE (default: en)
59
59
  --admin-prefix <path> Backend prefix in single-origin mode — sets Next.js
60
- adminPrefix on the backend AND the path the frontend
60
+ assetPrefix on the backend AND the path the frontend
61
61
  rewrites to it. Defaults to /admin so backend chunks
62
62
  sit alongside admin pages under one rewrite.
63
63
  Pass "none" to disable single-origin (separate origins).
@@ -69,10 +69,9 @@ ${COLORS.bold}Flags:${COLORS.reset}
69
69
  ${COLORS.bold}Single-origin model:${COLORS.reset}
70
70
  The frontend is the public entry point. It rewrites these paths to the
71
71
  backend so both apps live under one domain without /_next/* collisions:
72
- /admin/* → backend
72
+ /admin/* → backend (admin pages + chunks via APOLLO_ASSET_PREFIX=/admin)
73
73
  /api/* → backend (REST API + auth)
74
74
  /uploads/* → backend (media)
75
- <asset-prefix>/* → backend (Next.js chunks via APOLLO_ASSET_PREFIX)
76
75
  Frontend MUST NOT define routes at /admin or /api/auth or /api/v1.
77
76
  `;
78
77
 
@@ -326,14 +325,24 @@ function writeRootPackageJson(targetDir, dirName) {
326
325
  private: true,
327
326
  description: `${dirName} monorepo (frontend + apollo-cms backend submodule)`,
328
327
  scripts: {
329
- dev: "pnpm cms-plugins:build && pnpm -r --parallel dev",
328
+ // We bypass apollo-cms's own `dev` script ("bun install && bun run
329
+ // plugins:build && next dev & bun run scripts/dev-cron.ts") because the
330
+ // bash-`&`-then-foreground pattern exits with SIGHUP (129) under pnpm's
331
+ // parallel runner. Instead we explicitly run plugins:build (both ours
332
+ // and apollo-cms's) and `next dev` directly. Cron is optional in dev —
333
+ // run `pnpm dev:cron` in a separate terminal if you need scheduled jobs
334
+ // (production uses Vercel Cron via apps/backend/vercel.json).
335
+ "predev:setup":
336
+ "pnpm cms-plugins:build && pnpm --filter ./apps/backend exec bun run plugins:build",
337
+ dev:
338
+ "pnpm predev:setup && concurrently -k -n FE,BE -c blue,magenta \"pnpm --filter ./apps/frontend dev\" \"pnpm --filter ./apps/backend exec next dev\"",
330
339
  "dev:frontend": "pnpm --filter ./apps/frontend dev",
331
- "dev:backend": "pnpm cms-plugins:build && pnpm --filter ./apps/backend dev",
332
- // cms-plugins must compile to dist/ before the backend boots, otherwise
333
- // the loader falls back to index.ts which only works under Bun and
334
- // emits a warning. Build them sequentially: cms-plugins → backend → frontend.
340
+ "dev:backend":
341
+ "pnpm predev:setup && pnpm --filter ./apps/backend exec next dev",
342
+ "dev:cron": "pnpm --filter ./apps/backend exec bun scripts/dev-cron.ts",
343
+ // Build pipeline: cms-plugins → apollo-cms's own plugins → backend → frontend.
335
344
  build:
336
- "pnpm cms-plugins:build && pnpm --filter ./apps/backend build && pnpm --filter ./apps/frontend build",
345
+ "pnpm cms-plugins:build && pnpm --filter ./apps/backend exec bun run plugins:build && pnpm --filter ./apps/backend build && pnpm --filter ./apps/frontend build",
337
346
  "cms-plugins:build":
338
347
  "pnpm --filter './apps/cms-plugins/*' --parallel --if-present build",
339
348
  "cms-plugin:new": "node scripts/new-cms-plugin.mjs",
@@ -342,6 +351,9 @@ function writeRootPackageJson(targetDir, dirName) {
342
351
  "backend:update": "git submodule update --remote --merge apps/backend",
343
352
  "backend:setup": "pnpm --filter ./apps/backend setup",
344
353
  },
354
+ devDependencies: {
355
+ concurrently: "^9.0.0",
356
+ },
345
357
  engines: { node: ">=20", pnpm: ">=9" },
346
358
  pnpm: {
347
359
  // apollo-cms transitively pulls multiple esbuild versions (0.18, 0.25, 0.27).
@@ -950,7 +962,7 @@ Two Vercel projects, one repo. Each project picks up its own Root Directory.
950
962
 
951
963
  - **Import** this repo into Vercel as a new project.
952
964
  - **Root Directory**: \`apps/backend\`
953
- - **Build Command**: \`cd ../.. && pnpm install --frozen-lockfile && pnpm --filter ./apps/backend build\`
965
+ - **Build Command**: \`cd ../.. && pnpm install --frozen-lockfile && pnpm cms-plugins:build && cp -r ../cms-plugins/* apps/backend/plugins/ 2>/dev/null || true && pnpm --filter ./apps/backend build\`
954
966
  - **Install Command**: leave empty (handled in build)
955
967
  - **Settings → Git → Include all submodules: ON** (Vercel checks out an empty \`apps/backend\` otherwise)
956
968
  - **Environment variables**:
@@ -959,14 +971,16 @@ Two Vercel projects, one repo. Each project picks up its own Root Directory.
959
971
  APOLLO_SECRET=<openssl rand -hex 32>
960
972
  NEXT_PUBLIC_SITE_URL=https://yourdomain.com # the PUBLIC origin
961
973
  NEXT_PUBLIC_DEFAULT_LOCALE=en
962
- ${singleOrigin ? `APOLLO_ASSET_PREFIX=${adminPrefix}` : "# APOLLO_ASSET_PREFIX=/cms-assets # only when single-origin"}
974
+ ${singleOrigin ? `APOLLO_ASSET_PREFIX=${adminPrefix}` : "# APOLLO_ASSET_PREFIX=/admin # only when single-origin"}
963
975
  CRON_SECRET=<random> # protects /api/cron
976
+ APOLLO_EXTRA_PLUGINS_DIR=./plugins # picks up copied cms-plugins (see Build Command)
964
977
  # Storage on Vercel cannot use local FS — pick one:
965
978
  # Vercel Blob: BLOB_READ_WRITE_TOKEN=…
966
979
  # S3 / R2 / Spaces: S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_BUCKET, S3_REGION, S3_ENDPOINT
967
980
  APOLLO_DISABLE_LOCAL_STORAGE=1
968
981
  \`\`\`
969
982
  - **Cron**: \`apps/backend/vercel.json\` declares \`/api/cron\` on a 5-minute schedule (from apollo-cms upstream).
983
+ - **About the \`cp\` step**: Turbopack rejects \`outputFileTracingIncludes\` globs that walk above the project root, so the Build Command copies built \`apps/cms-plugins/*/dist\` into \`apps/backend/plugins/\` before \`next build\`. NFT then traces them normally as if they were built-in plugins. Locally this isn't needed because \`APOLLO_EXTRA_PLUGINS_DIR=../cms-plugins\` reads them directly.
970
984
 
971
985
  ### 2) Frontend project
972
986
 
@@ -1043,7 +1057,7 @@ async function main() {
1043
1057
  const cronSecret = randomBytes(24).toString("hex");
1044
1058
  const backendInternalUrl = "http://localhost:3000";
1045
1059
  success(`Frontend pkg name: ${frontendName}`);
1046
- success(`Asset prefix: ${adminPrefix || "(disabled — separate origins)"}`);
1060
+ success(`Admin prefix: ${adminPrefix || "(disabled — separate origins)"}`);
1047
1061
 
1048
1062
  // ── Step 3: Scaffold root ──
1049
1063
  step(3, "Scaffolding monorepo root");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-apollo-monorepo",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
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"