create-better-t-stack 2.50.0-canary.dd7000f2 → 2.50.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 (92) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/index.d.ts +2 -2
  3. package/dist/index.js +1 -1
  4. package/dist/{src-dv6H37db.js → src-B8TD9m4n.js} +228 -518
  5. package/package.json +1 -2
  6. package/templates/api/orpc/server/{src → base/src/lib}/context.ts.hbs +6 -6
  7. package/templates/api/orpc/server/next/src/app/rpc/[...all]/route.ts.hbs +52 -0
  8. package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +1 -1
  9. package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +1 -1
  10. package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +1 -1
  11. package/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs +1 -1
  12. package/templates/api/trpc/server/{src → base/src/lib}/context.ts.hbs +6 -6
  13. package/templates/api/trpc/server/next/src/app/trpc/[trpc]/route.ts +14 -0
  14. package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +2 -2
  15. package/templates/auth/better-auth/server/base/src/{index.ts.hbs → lib/auth.ts.hbs} +7 -7
  16. package/templates/auth/better-auth/server/next/src/app/api/auth/[...all]/route.ts +4 -0
  17. package/templates/backend/server/elysia/src/index.ts.hbs +6 -6
  18. package/templates/backend/server/express/src/index.ts.hbs +6 -6
  19. package/templates/backend/server/fastify/src/index.ts.hbs +6 -6
  20. package/templates/backend/server/hono/src/index.ts.hbs +7 -7
  21. package/templates/backend/server/next/next-env.d.ts +5 -0
  22. package/templates/backend/server/next/next.config.ts +7 -0
  23. package/templates/backend/server/next/package.json.hbs +27 -0
  24. package/templates/backend/server/next/src/app/route.ts +5 -0
  25. package/templates/backend/server/next/src/middleware.ts +19 -0
  26. package/templates/backend/server/next/tsconfig.json.hbs +33 -0
  27. package/templates/backend/server/{base → server-base}/package.json.hbs +1 -0
  28. package/templates/{api/trpc/server → backend/server/server-base}/src/routers/index.ts.hbs +2 -2
  29. package/templates/backend/server/{base → server-base}/tsconfig.json.hbs +10 -5
  30. package/templates/base/_gitignore +1 -47
  31. package/templates/base/package.json.hbs +3 -1
  32. package/templates/db/drizzle/mysql/drizzle.config.ts.hbs +2 -7
  33. package/templates/db/drizzle/mysql/src/{index.ts.hbs → db/index.ts.hbs} +1 -1
  34. package/templates/db/drizzle/postgres/drizzle.config.ts.hbs +2 -7
  35. package/templates/db/drizzle/postgres/src/{index.ts.hbs → db/index.ts.hbs} +1 -1
  36. package/templates/db/drizzle/sqlite/drizzle.config.ts.hbs +2 -7
  37. package/templates/db/drizzle/sqlite/src/{index.ts.hbs → db/index.ts.hbs} +1 -1
  38. package/templates/db/prisma/mongodb/prisma.config.ts.hbs +1 -5
  39. package/templates/db/prisma/mongodb/src/db/index.ts.hbs +5 -0
  40. package/templates/db/prisma/mysql/prisma.config.ts.hbs +1 -5
  41. package/templates/db/prisma/mysql/src/{index.ts.hbs → db/index.ts.hbs} +1 -1
  42. package/templates/db/prisma/postgres/prisma.config.ts.hbs +3 -7
  43. package/templates/db/prisma/postgres/src/{index.ts.hbs → db/index.ts.hbs} +1 -1
  44. package/templates/db/prisma/sqlite/prisma.config.ts.hbs +1 -5
  45. package/templates/db/prisma/sqlite/src/{index.ts.hbs → db/index.ts.hbs} +3 -3
  46. package/templates/examples/ai/server/next/src/app/ai/route.ts.hbs +15 -0
  47. package/templates/examples/todo/server/drizzle/base/src/routers/todo.ts.hbs +6 -6
  48. package/templates/examples/todo/server/mongoose/base/src/routers/todo.ts.hbs +4 -4
  49. package/templates/examples/todo/server/prisma/base/src/routers/todo.ts.hbs +4 -4
  50. package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +1 -1
  51. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +1 -1
  52. package/templates/api/orpc/server/_gitignore +0 -34
  53. package/templates/api/orpc/server/package.json.hbs +0 -24
  54. package/templates/api/orpc/server/src/routers/index.ts.hbs +0 -55
  55. package/templates/api/orpc/server/tsconfig.json.hbs +0 -10
  56. package/templates/api/orpc/server/tsdown.config.ts.hbs +0 -7
  57. package/templates/api/trpc/server/_gitignore +0 -34
  58. package/templates/api/trpc/server/package.json.hbs +0 -23
  59. package/templates/api/trpc/server/tsconfig.json.hbs +0 -13
  60. package/templates/api/trpc/server/tsdown.config.ts.hbs +0 -7
  61. package/templates/auth/better-auth/server/base/_gitignore +0 -34
  62. package/templates/auth/better-auth/server/base/package.json.hbs +0 -24
  63. package/templates/auth/better-auth/server/base/tsconfig.json.hbs +0 -13
  64. package/templates/auth/better-auth/server/base/tsdown.config.ts.hbs +0 -7
  65. package/templates/backend/server/base/tsdown.config.ts.hbs +0 -14
  66. package/templates/base/tsconfig.base.json +0 -23
  67. package/templates/db/base/_gitignore +0 -34
  68. package/templates/db/base/package.json.hbs +0 -23
  69. package/templates/db/base/tsconfig.json.hbs +0 -13
  70. package/templates/db/base/tsdown.config.ts.hbs +0 -7
  71. package/templates/db/prisma/mongodb/src/index.ts.hbs +0 -5
  72. /package/templates/api/orpc/server/{src/index.ts.hbs → base/src/lib/orpc.ts.hbs} +0 -0
  73. /package/templates/api/trpc/server/{src/index.ts.hbs → base/src/lib/trpc.ts.hbs} +0 -0
  74. /package/templates/auth/better-auth/server/db/drizzle/mysql/src/{schema/auth.ts.hbs → db/schema/auth.ts} +0 -0
  75. /package/templates/auth/better-auth/server/db/drizzle/postgres/src/{schema/auth.ts.hbs → db/schema/auth.ts} +0 -0
  76. /package/templates/auth/better-auth/server/db/drizzle/sqlite/src/{schema/auth.ts.hbs → db/schema/auth.ts} +0 -0
  77. /package/templates/auth/better-auth/server/db/mongoose/mongodb/src/{models/auth.model.ts.hbs → db/models/auth.model.ts} +0 -0
  78. /package/templates/auth/better-auth/server/db/prisma/mongodb/prisma/schema/{auth.prisma.hbs → auth.prisma} +0 -0
  79. /package/templates/auth/better-auth/server/db/prisma/mysql/prisma/schema/{auth.prisma.hbs → auth.prisma} +0 -0
  80. /package/templates/auth/better-auth/server/db/prisma/postgres/prisma/schema/{auth.prisma.hbs → auth.prisma} +0 -0
  81. /package/templates/auth/better-auth/server/db/prisma/sqlite/prisma/schema/{auth.prisma.hbs → auth.prisma} +0 -0
  82. /package/templates/auth/better-auth/web/nuxt/app/middleware/{auth.ts.hbs → auth.ts} +0 -0
  83. /package/templates/backend/server/{base → server-base}/_gitignore +0 -0
  84. /package/templates/db/mongoose/mongodb/src/{index.ts.hbs → db/index.ts.hbs} +0 -0
  85. /package/templates/examples/todo/server/drizzle/mysql/src/{schema → db/schema}/todo.ts +0 -0
  86. /package/templates/examples/todo/server/drizzle/postgres/src/{schema → db/schema}/todo.ts +0 -0
  87. /package/templates/examples/todo/server/drizzle/sqlite/src/{schema → db/schema}/todo.ts +0 -0
  88. /package/templates/examples/todo/server/mongoose/mongodb/src/{models/todo.model.ts.hbs → db/models/todo.model.ts} +0 -0
  89. /package/templates/examples/todo/server/prisma/mongodb/prisma/schema/{todo.prisma.hbs → todo.prisma} +0 -0
  90. /package/templates/examples/todo/server/prisma/mysql/prisma/schema/{todo.prisma.hbs → todo.prisma} +0 -0
  91. /package/templates/examples/todo/server/prisma/postgres/prisma/schema/{todo.prisma.hbs → todo.prisma} +0 -0
  92. /package/templates/examples/todo/server/prisma/sqlite/prisma/schema/{todo.prisma.hbs → todo.prisma} +0 -0
@@ -15,7 +15,6 @@ import { IndentationText, Node, Project, QuoteKind, SyntaxKind } from "ts-morph"
15
15
  import { glob } from "tinyglobby";
16
16
  import handlebars from "handlebars";
17
17
  import { Biome } from "@biomejs/js-api/nodejs";
18
- import yaml from "yaml";
19
18
  import os$1 from "node:os";
20
19
 
21
20
  //#region src/utils/get-package-manager.ts
@@ -72,7 +71,6 @@ const dependencyVersionMap = {
72
71
  "drizzle-kit": "^0.31.2",
73
72
  "@planetscale/database": "^1.19.0",
74
73
  "@libsql/client": "^0.15.9",
75
- libsql: "^0.5.22",
76
74
  "@neondatabase/serverless": "^1.0.1",
77
75
  pg: "^8.14.1",
78
76
  "@types/pg": "^8.11.11",
@@ -125,7 +123,6 @@ const dependencyVersionMap = {
125
123
  "@trpc/tanstack-react-query": "^11.5.0",
126
124
  "@trpc/server": "^11.5.0",
127
125
  "@trpc/client": "^11.5.0",
128
- next: "^15.1.0",
129
126
  convex: "^1.27.0",
130
127
  "@convex-dev/react-query": "^0.0.0-alpha.8",
131
128
  "convex-svelte": "^0.0.11",
@@ -149,9 +146,7 @@ const dependencyVersionMap = {
149
146
  "@cloudflare/workers-types": "^4.20250822.0",
150
147
  alchemy: "^0.70.0",
151
148
  nitropack: "^2.12.4",
152
- dotenv: "^17.2.2",
153
- tsdown: "^0.15.5",
154
- zod: "^4.1.11",
149
+ dotenv: "^17.2.1",
155
150
  "@polar-sh/better-auth": "^1.1.3",
156
151
  "@polar-sh/sdk": "^0.34.16"
157
152
  };
@@ -200,9 +195,9 @@ const BackendSchema = z.enum([
200
195
  "hono",
201
196
  "express",
202
197
  "fastify",
198
+ "next",
203
199
  "elysia",
204
200
  "convex",
205
- "self",
206
201
  "none"
207
202
  ]).describe("Backend framework");
208
203
  const RuntimeSchema = z.enum([
@@ -348,22 +343,6 @@ function ensureSingleWebAndNative(frontends) {
348
343
  if (web.length > 1) exitWithError("Cannot select multiple web frameworks. Choose only one of: tanstack-router, tanstack-start, react-router, next, nuxt, svelte, solid");
349
344
  if (native.length > 1) exitWithError("Cannot select multiple native frameworks. Choose only one of: native-nativewind, native-unistyles");
350
345
  }
351
- const FULLSTACK_FRONTENDS$1 = [
352
- "next",
353
- "nuxt",
354
- "svelte",
355
- "tanstack-start"
356
- ];
357
- function validateSelfBackendCompatibility(providedFlags, options, config) {
358
- const backend = config.backend || options.backend;
359
- const frontends = config.frontend || options.frontend || [];
360
- if (backend === "self") {
361
- if (!frontends.some((f) => FULLSTACK_FRONTENDS$1.includes(f))) exitWithError("Backend 'self' (fullstack) requires a fullstack-capable frontend. Please use --frontend with one of: next, nuxt, svelte, tanstack-start");
362
- if (frontends.length > 1) exitWithError("Backend 'self' (fullstack) can only be used with a single frontend framework.");
363
- }
364
- const hasFullstackFrontend = frontends.some((f) => FULLSTACK_FRONTENDS$1.includes(f));
365
- if (providedFlags.has("backend") && !hasFullstackFrontend && backend === "self") exitWithError("Backend 'self' (fullstack) is only compatible with fullstack-capable frontends: next, nuxt, svelte, tanstack-start. Please choose a different backend or use a fullstack frontend.");
366
- }
367
346
  function validateWorkersCompatibility(providedFlags, options, config) {
368
347
  if (providedFlags.has("runtime") && options.runtime === "workers" && config.backend && config.backend !== "hono") exitWithError(`Cloudflare Workers runtime (--runtime workers) is only supported with Hono backend (--backend hono). Current backend: ${config.backend}. Please use '--backend hono' or choose a different runtime.`);
369
348
  if (providedFlags.has("backend") && config.backend && config.backend !== "hono" && config.runtime === "workers") exitWithError(`Backend '${config.backend}' is not compatible with Cloudflare Workers runtime. Cloudflare Workers runtime is only supported with Hono backend. Please use '--backend hono' or choose a different runtime.`);
@@ -685,39 +664,36 @@ async function getAuthChoice(auth, hasDatabase, backend, frontend) {
685
664
 
686
665
  //#endregion
687
666
  //#region src/prompts/backend.ts
688
- const FULLSTACK_FRONTENDS = [
689
- "next",
690
- "nuxt",
691
- "svelte",
692
- "tanstack-start"
693
- ];
694
667
  async function getBackendFrameworkChoice(backendFramework, frontends) {
695
668
  if (backendFramework !== void 0) return backendFramework;
696
669
  const hasIncompatibleFrontend = frontends?.some((f) => f === "solid");
697
- const hasFullstackFrontend = frontends?.some((f) => FULLSTACK_FRONTENDS.includes(f));
698
- const backendOptions = [];
699
- if (hasFullstackFrontend) backendOptions.push({
700
- value: "self",
701
- label: "Self (Fullstack)",
702
- hint: "Use frontend's built-in backend capabilities"
703
- });
704
- backendOptions.push({
705
- value: "hono",
706
- label: "Hono",
707
- hint: "Lightweight, ultrafast web framework"
708
- }, {
709
- value: "express",
710
- label: "Express",
711
- hint: "Fast, unopinionated, minimalist web framework for Node.js"
712
- }, {
713
- value: "fastify",
714
- label: "Fastify",
715
- hint: "Fast, low-overhead web framework for Node.js"
716
- }, {
717
- value: "elysia",
718
- label: "Elysia",
719
- hint: "Ergonomic web framework for building backend servers"
720
- });
670
+ const backendOptions = [
671
+ {
672
+ value: "hono",
673
+ label: "Hono",
674
+ hint: "Lightweight, ultrafast web framework"
675
+ },
676
+ {
677
+ value: "next",
678
+ label: "Next.js",
679
+ hint: "separate api routes only backend"
680
+ },
681
+ {
682
+ value: "express",
683
+ label: "Express",
684
+ hint: "Fast, unopinionated, minimalist web framework for Node.js"
685
+ },
686
+ {
687
+ value: "fastify",
688
+ label: "Fastify",
689
+ hint: "Fast, low-overhead web framework for Node.js"
690
+ },
691
+ {
692
+ value: "elysia",
693
+ label: "Elysia",
694
+ hint: "Ergonomic web framework for building backend servers"
695
+ }
696
+ ];
721
697
  if (!hasIncompatibleFrontend) backendOptions.push({
722
698
  value: "convex",
723
699
  label: "Convex",
@@ -731,7 +707,7 @@ async function getBackendFrameworkChoice(backendFramework, frontends) {
731
707
  const response = await select({
732
708
  message: "Select backend",
733
709
  options: backendOptions,
734
- initialValue: hasFullstackFrontend ? "self" : DEFAULT_CONFIG.backend
710
+ initialValue: DEFAULT_CONFIG.backend
735
711
  });
736
712
  if (isCancel(response)) return exitCancelled("Operation cancelled");
737
713
  return response;
@@ -1110,8 +1086,9 @@ async function getPaymentsChoice(payments, auth, backend, frontends) {
1110
1086
  //#endregion
1111
1087
  //#region src/prompts/runtime.ts
1112
1088
  async function getRuntimeChoice(runtime, backend) {
1113
- if (backend === "convex" || backend === "none" || backend === "self") return "none";
1089
+ if (backend === "convex" || backend === "none") return "none";
1114
1090
  if (runtime !== void 0) return runtime;
1091
+ if (backend === "next") return "node";
1115
1092
  const runtimeOptions = [{
1116
1093
  value: "bun",
1117
1094
  label: "Bun",
@@ -1398,7 +1375,7 @@ const getLatestCLIVersion = () => {
1398
1375
  */
1399
1376
  function isTelemetryEnabled() {
1400
1377
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
1401
- const BTS_TELEMETRY = "0";
1378
+ const BTS_TELEMETRY = "1";
1402
1379
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
1403
1380
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
1404
1381
  return true;
@@ -1406,8 +1383,8 @@ function isTelemetryEnabled() {
1406
1383
 
1407
1384
  //#endregion
1408
1385
  //#region src/utils/analytics.ts
1409
- const POSTHOG_API_KEY = "random";
1410
- const POSTHOG_HOST = "random";
1386
+ const POSTHOG_API_KEY = "phc_8ZUxEwwfKMajJLvxz1daGd931dYbQrwKNficBmsdIrs";
1387
+ const POSTHOG_HOST = "https://us.i.posthog.com";
1411
1388
  function generateSessionId() {
1412
1389
  const rand = Math.random().toString(36).slice(2);
1413
1390
  return `cli_${Date.now().toString(36)}${rand}`;
@@ -1788,8 +1765,8 @@ function validateBackendConstraints(config, providedFlags, options) {
1788
1765
  ].includes(f));
1789
1766
  if (incompatibleFrontends.length > 0) exitWithError(`Clerk authentication is not compatible with the following frontends: ${incompatibleFrontends.join(", ")}. Please choose a different frontend or auth provider.`);
1790
1767
  }
1791
- if (providedFlags.has("backend") && backend && backend !== "convex" && backend !== "none" && backend !== "self") {
1792
- if (providedFlags.has("runtime") && options.runtime === "none") exitWithError("'--runtime none' is only supported with '--backend convex', '--backend none', or '--backend self'. Please choose 'bun', 'node', or remove the --runtime flag.");
1768
+ if (providedFlags.has("backend") && backend && backend !== "convex" && backend !== "none") {
1769
+ if (providedFlags.has("runtime") && options.runtime === "none") exitWithError("'--runtime none' is only supported with '--backend convex' or '--backend none'. Please choose 'bun', 'node', or remove the --runtime flag.");
1793
1770
  }
1794
1771
  if (backend === "convex" && providedFlags.has("frontend") && options.frontend) {
1795
1772
  const incompatibleFrontends = options.frontend.filter((f) => f === "solid");
@@ -1819,7 +1796,6 @@ function validateFullConfig(config, providedFlags, options) {
1819
1796
  validateFrontendConstraints(config, providedFlags);
1820
1797
  validateApiConstraints(config, options);
1821
1798
  validateServerDeployRequiresBackend(config.serverDeploy, config.backend);
1822
- validateSelfBackendCompatibility(providedFlags, options, config);
1823
1799
  validateWorkersCompatibility(providedFlags, options, config);
1824
1800
  if (config.runtime === "workers" && config.serverDeploy === "none") exitWithError("Cloudflare Workers runtime requires a server deployment. Please choose 'wrangler' or 'alchemy' for --server-deploy.");
1825
1801
  if (config.addons && config.addons.length > 0) {
@@ -1873,7 +1849,6 @@ const CORE_STACK_FLAGS = new Set([
1873
1849
  "examples",
1874
1850
  "auth",
1875
1851
  "dbSetup",
1876
- "payments",
1877
1852
  "api",
1878
1853
  "webDeploy",
1879
1854
  "serverDeploy"
@@ -2017,17 +1992,15 @@ const addPackageDependency = async (opts) => {
2017
1992
  if (!pkgJson.dependencies) pkgJson.dependencies = {};
2018
1993
  if (!pkgJson.devDependencies) pkgJson.devDependencies = {};
2019
1994
  for (const pkgName of dependencies) {
2020
- const version = dependencyVersionMap[pkgName];
1995
+ const version = customDependencies[pkgName] || dependencyVersionMap[pkgName];
2021
1996
  if (version) pkgJson.dependencies[pkgName] = version;
2022
1997
  else console.warn(`Warning: Dependency ${pkgName} not found in version map.`);
2023
1998
  }
2024
1999
  for (const pkgName of devDependencies) {
2025
- const version = dependencyVersionMap[pkgName];
2000
+ const version = customDevDependencies[pkgName] || dependencyVersionMap[pkgName];
2026
2001
  if (version) pkgJson.devDependencies[pkgName] = version;
2027
2002
  else console.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
2028
2003
  }
2029
- for (const [pkgName, version] of Object.entries(customDependencies)) pkgJson.dependencies[pkgName] = version;
2030
- for (const [pkgName, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[pkgName] = version;
2031
2004
  await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
2032
2005
  };
2033
2006
 
@@ -2682,12 +2655,8 @@ async function processTemplate(srcPath, destPath, context) {
2682
2655
  }
2683
2656
  handlebars.registerHelper("eq", (a, b) => a === b);
2684
2657
  handlebars.registerHelper("ne", (a, b) => a !== b);
2685
- handlebars.registerHelper("and", (...args) => {
2686
- return args.slice(0, -1).every((value) => value);
2687
- });
2688
- handlebars.registerHelper("or", (...args) => {
2689
- return args.slice(0, -1).some((value) => value);
2690
- });
2658
+ handlebars.registerHelper("and", (a, b) => a && b);
2659
+ handlebars.registerHelper("or", (a, b) => a || b);
2691
2660
  handlebars.registerHelper("includes", (array, value) => Array.isArray(array) && array.includes(value));
2692
2661
 
2693
2662
  //#endregion
@@ -2789,52 +2758,35 @@ async function setupFrontendTemplates(projectDir, context) {
2789
2758
  }
2790
2759
  }
2791
2760
  }
2792
- async function setupApiPackage(projectDir, context) {
2793
- if (context.api === "none") return;
2794
- const apiPackageDir = path.join(projectDir, "packages/api");
2795
- await fs.ensureDir(apiPackageDir);
2796
- const apiServerDir = path.join(PKG_ROOT, `templates/api/${context.api}/server`);
2797
- if (await fs.pathExists(apiServerDir)) await processAndCopyFiles("**/*", apiServerDir, apiPackageDir, context);
2798
- }
2799
- async function setupDbPackage(projectDir, context) {
2800
- if (context.database === "none" || context.orm === "none") return;
2801
- const dbPackageDir = path.join(projectDir, "packages/db");
2802
- await fs.ensureDir(dbPackageDir);
2803
- const dbBaseDir = path.join(PKG_ROOT, "templates/db/base");
2804
- if (await fs.pathExists(dbBaseDir)) await processAndCopyFiles("**/*", dbBaseDir, dbPackageDir, context);
2805
- const dbOrmSrcDir = path.join(PKG_ROOT, `templates/db/${context.orm}/${context.database}`);
2806
- if (await fs.pathExists(dbOrmSrcDir)) await processAndCopyFiles("**/*", dbOrmSrcDir, dbPackageDir, context);
2807
- }
2808
- async function setupConvexBackend(projectDir, context) {
2809
- const serverAppDir = path.join(projectDir, "apps/server");
2810
- if (await fs.pathExists(serverAppDir)) await fs.remove(serverAppDir);
2811
- const convexBackendDestDir = path.join(projectDir, "packages/backend");
2812
- const convexSrcDir = path.join(PKG_ROOT, "templates/backend/convex/packages/backend");
2813
- await fs.ensureDir(convexBackendDestDir);
2814
- if (await fs.pathExists(convexSrcDir)) await processAndCopyFiles("**/*", convexSrcDir, convexBackendDestDir, context);
2815
- }
2816
- async function setupServerApp(projectDir, context) {
2817
- const serverAppDir = path.join(projectDir, "apps/server");
2818
- await fs.ensureDir(serverAppDir);
2819
- const serverBaseDir = path.join(PKG_ROOT, "templates/backend/server/base");
2820
- if (await fs.pathExists(serverBaseDir)) await processAndCopyFiles("**/*", serverBaseDir, serverAppDir, context);
2821
- const frameworkSrcDir = path.join(PKG_ROOT, `templates/backend/server/${context.backend}`);
2822
- if (await fs.pathExists(frameworkSrcDir)) await processAndCopyFiles("**/*", frameworkSrcDir, serverAppDir, context, true);
2823
- }
2824
2761
  async function setupBackendFramework(projectDir, context) {
2825
2762
  if (context.backend === "none") return;
2763
+ const serverAppDir = path.join(projectDir, "apps/server");
2826
2764
  if (context.backend === "convex") {
2827
- await setupConvexBackend(projectDir, context);
2765
+ if (await fs.pathExists(serverAppDir)) await fs.remove(serverAppDir);
2766
+ const convexBackendDestDir = path.join(projectDir, "packages/backend");
2767
+ const convexSrcDir = path.join(PKG_ROOT, "templates/backend/convex/packages/backend");
2768
+ await fs.ensureDir(convexBackendDestDir);
2769
+ if (await fs.pathExists(convexSrcDir)) await processAndCopyFiles("**/*", convexSrcDir, convexBackendDestDir, context);
2828
2770
  return;
2829
2771
  }
2830
- if (context.backend === "self") {
2831
- await setupApiPackage(projectDir, context);
2832
- await setupDbPackage(projectDir, context);
2833
- return;
2772
+ await fs.ensureDir(serverAppDir);
2773
+ const serverBaseDir = path.join(PKG_ROOT, "templates/backend/server/server-base");
2774
+ if (await fs.pathExists(serverBaseDir)) await processAndCopyFiles("**/*", serverBaseDir, serverAppDir, context);
2775
+ const frameworkSrcDir = path.join(PKG_ROOT, `templates/backend/server/${context.backend}`);
2776
+ if (await fs.pathExists(frameworkSrcDir)) await processAndCopyFiles("**/*", frameworkSrcDir, serverAppDir, context, true);
2777
+ if (context.api !== "none") {
2778
+ const apiServerBaseDir = path.join(PKG_ROOT, `templates/api/${context.api}/server/base`);
2779
+ if (await fs.pathExists(apiServerBaseDir)) await processAndCopyFiles("**/*", apiServerBaseDir, serverAppDir, context, true);
2780
+ const apiServerFrameworkDir = path.join(PKG_ROOT, `templates/api/${context.api}/server/${context.backend}`);
2781
+ if (await fs.pathExists(apiServerFrameworkDir)) await processAndCopyFiles("**/*", apiServerFrameworkDir, serverAppDir, context, true);
2834
2782
  }
2835
- await setupServerApp(projectDir, context);
2836
- await setupApiPackage(projectDir, context);
2837
- await setupDbPackage(projectDir, context);
2783
+ }
2784
+ async function setupDbOrmTemplates(projectDir, context) {
2785
+ if (context.backend === "convex" || context.orm === "none" || context.database === "none") return;
2786
+ const serverAppDir = path.join(projectDir, "apps/server");
2787
+ await fs.ensureDir(serverAppDir);
2788
+ const dbOrmSrcDir = path.join(PKG_ROOT, `templates/db/${context.orm}/${context.database}`);
2789
+ if (await fs.pathExists(dbOrmSrcDir)) await processAndCopyFiles("**/*", dbOrmSrcDir, serverAppDir, context);
2838
2790
  }
2839
2791
  async function setupAuthTemplate(projectDir, context) {
2840
2792
  if (!context.auth || context.auth === "none") return;
@@ -2914,21 +2866,21 @@ async function setupAuthTemplate(projectDir, context) {
2914
2866
  }
2915
2867
  return;
2916
2868
  }
2917
- if ((serverAppDirExists || context.backend === "self") && context.backend !== "convex") {
2918
- const authPackageDir = path.join(projectDir, "packages/auth");
2919
- await fs.ensureDir(authPackageDir);
2869
+ if (serverAppDirExists && context.backend !== "convex") {
2920
2870
  const authServerBaseSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/base`);
2921
- if (await fs.pathExists(authServerBaseSrc)) await processAndCopyFiles("**/*", authServerBaseSrc, authPackageDir, context);
2871
+ if (await fs.pathExists(authServerBaseSrc)) await processAndCopyFiles("**/*", authServerBaseSrc, serverAppDir, context);
2872
+ if (context.backend === "next") {
2873
+ const authServerNextSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/next`);
2874
+ if (await fs.pathExists(authServerNextSrc)) await processAndCopyFiles("**/*", authServerNextSrc, serverAppDir, context);
2875
+ }
2922
2876
  if (context.orm !== "none" && context.database !== "none") {
2923
- const dbPackageDir = path.join(projectDir, "packages/db");
2924
- await fs.ensureDir(dbPackageDir);
2925
2877
  const orm = context.orm;
2926
2878
  const db = context.database;
2927
2879
  let authDbSrc = "";
2928
2880
  if (orm === "drizzle") authDbSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/db/drizzle/${db}`);
2929
2881
  else if (orm === "prisma") authDbSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/db/prisma/${db}`);
2930
2882
  else if (orm === "mongoose") authDbSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/db/mongoose/${db}`);
2931
- if (authDbSrc && await fs.pathExists(authDbSrc)) await processAndCopyFiles("**/*", authDbSrc, dbPackageDir, context);
2883
+ if (authDbSrc && await fs.pathExists(authDbSrc)) await processAndCopyFiles("**/*", authDbSrc, serverAppDir, context);
2932
2884
  }
2933
2885
  }
2934
2886
  if ((hasReactWeb || hasNuxtWeb || hasSvelteWeb || hasSolidWeb) && webAppDirExists) {
@@ -2974,11 +2926,9 @@ async function setupPaymentsTemplate(projectDir, context) {
2974
2926
  const webAppDir = path.join(projectDir, "apps/web");
2975
2927
  const serverAppDirExists = await fs.pathExists(serverAppDir);
2976
2928
  const webAppDirExists = await fs.pathExists(webAppDir);
2977
- if ((serverAppDirExists || context.backend === "self") && context.backend !== "convex") {
2978
- const authPackageDir = path.join(projectDir, "packages/auth");
2979
- await fs.ensureDir(authPackageDir);
2929
+ if (serverAppDirExists && context.backend !== "convex") {
2980
2930
  const paymentsServerSrc = path.join(PKG_ROOT, `templates/payments/${context.payments}/server/base`);
2981
- if (await fs.pathExists(paymentsServerSrc)) await processAndCopyFiles("**/*", paymentsServerSrc, authPackageDir, context);
2931
+ if (await fs.pathExists(paymentsServerSrc)) await processAndCopyFiles("**/*", paymentsServerSrc, serverAppDir, context);
2982
2932
  }
2983
2933
  const hasReactWeb = context.frontend.some((f) => [
2984
2934
  "tanstack-router",
@@ -3054,19 +3004,17 @@ async function setupExamplesTemplate(projectDir, context) {
3054
3004
  for (const example of context.examples) {
3055
3005
  if (example === "none") continue;
3056
3006
  const exampleBaseDir = path.join(PKG_ROOT, `templates/examples/${example}`);
3057
- if ((serverAppDirExists || context.backend === "self") && context.backend !== "convex" && context.backend !== "none") {
3007
+ if (serverAppDirExists && context.backend !== "convex" && context.backend !== "none") {
3058
3008
  const exampleServerSrc = path.join(exampleBaseDir, "server");
3059
- if (context.api !== "none") {
3060
- const apiPackageDir = path.join(projectDir, "packages/api");
3061
- await fs.ensureDir(apiPackageDir);
3062
- const exampleOrmBaseSrc = path.join(exampleServerSrc, context.orm, "base");
3063
- if (await fs.pathExists(exampleOrmBaseSrc)) await processAndCopyFiles("**/*", exampleOrmBaseSrc, apiPackageDir, context, false);
3009
+ if (example === "ai" && context.backend === "next") {
3010
+ const aiNextServerSrc = path.join(exampleServerSrc, "next");
3011
+ if (await fs.pathExists(aiNextServerSrc)) await processAndCopyFiles("**/*", aiNextServerSrc, serverAppDir, context, false);
3064
3012
  }
3065
3013
  if (context.orm !== "none" && context.database !== "none") {
3066
- const dbPackageDir = path.join(projectDir, "packages/db");
3067
- await fs.ensureDir(dbPackageDir);
3014
+ const exampleOrmBaseSrc = path.join(exampleServerSrc, context.orm, "base");
3015
+ if (await fs.pathExists(exampleOrmBaseSrc)) await processAndCopyFiles("**/*", exampleOrmBaseSrc, serverAppDir, context, false);
3068
3016
  const exampleDbSchemaSrc = path.join(exampleServerSrc, context.orm, context.database);
3069
- if (await fs.pathExists(exampleDbSchemaSrc)) await processAndCopyFiles("**/*", exampleDbSchemaSrc, dbPackageDir, context, false);
3017
+ if (await fs.pathExists(exampleDbSchemaSrc)) await processAndCopyFiles("**/*", exampleDbSchemaSrc, serverAppDir, context, false);
3070
3018
  }
3071
3019
  }
3072
3020
  if (webAppDirExists) {
@@ -3133,9 +3081,9 @@ async function handleExtras(projectDir, context) {
3133
3081
  }
3134
3082
  async function setupDockerComposeTemplates(projectDir, context) {
3135
3083
  if (context.dbSetup !== "docker" || context.database === "none") return;
3136
- const dbPackageDir = path.join(projectDir, "packages/db");
3084
+ const serverAppDir = path.join(projectDir, "apps/server");
3137
3085
  const dockerSrcDir = path.join(PKG_ROOT, `templates/db-setup/docker-compose/${context.database}`);
3138
- if (await fs.pathExists(dockerSrcDir)) await processAndCopyFiles("**/*", dockerSrcDir, dbPackageDir, context);
3086
+ if (await fs.pathExists(dockerSrcDir)) await processAndCopyFiles("**/*", dockerSrcDir, serverAppDir, context);
3139
3087
  }
3140
3088
  async function setupDeploymentTemplates(projectDir, context) {
3141
3089
  if (context.webDeploy === "alchemy" || context.serverDeploy === "alchemy") if (context.webDeploy === "alchemy" && context.serverDeploy === "alchemy") {
@@ -3953,110 +3901,6 @@ async function addDeploymentToProject(input) {
3953
3901
  }
3954
3902
  }
3955
3903
 
3956
- //#endregion
3957
- //#region src/utils/setup-catalogs.ts
3958
- async function setupCatalogs(projectDir, options) {
3959
- if (options.packageManager === "npm") return;
3960
- const packagePaths = [
3961
- "apps/server",
3962
- "apps/web",
3963
- "packages/api",
3964
- "packages/db",
3965
- "packages/auth",
3966
- "packages/backend"
3967
- ];
3968
- const packagesInfo = [];
3969
- for (const pkgPath of packagePaths) {
3970
- const fullPath = path.join(projectDir, pkgPath);
3971
- const pkgJsonPath = path.join(fullPath, "package.json");
3972
- if (await fs.pathExists(pkgJsonPath)) {
3973
- const pkgJson = await fs.readJson(pkgJsonPath);
3974
- packagesInfo.push({
3975
- path: fullPath,
3976
- dependencies: pkgJson.dependencies || {},
3977
- devDependencies: pkgJson.devDependencies || {}
3978
- });
3979
- }
3980
- }
3981
- const catalog = findDuplicateDependencies(packagesInfo, options.projectName);
3982
- if (Object.keys(catalog).length === 0) return;
3983
- if (options.packageManager === "bun") await setupBunCatalogs(projectDir, catalog);
3984
- else if (options.packageManager === "pnpm") await setupPnpmCatalogs(projectDir, catalog);
3985
- await updatePackageJsonsWithCatalogs(packagesInfo, catalog);
3986
- }
3987
- function findDuplicateDependencies(packagesInfo, projectName) {
3988
- const depCount = /* @__PURE__ */ new Map();
3989
- const projectScope = `@${projectName}/`;
3990
- for (const pkg of packagesInfo) {
3991
- const allDeps = {
3992
- ...pkg.dependencies,
3993
- ...pkg.devDependencies
3994
- };
3995
- for (const [depName, version] of Object.entries(allDeps)) {
3996
- if (depName.startsWith(projectScope)) continue;
3997
- if (version.startsWith("workspace:")) continue;
3998
- const existing = depCount.get(depName);
3999
- if (existing) existing.packages.push(pkg.path);
4000
- else depCount.set(depName, {
4001
- version,
4002
- packages: [pkg.path]
4003
- });
4004
- }
4005
- }
4006
- const catalog = {};
4007
- for (const [depName, info] of depCount.entries()) if (info.packages.length > 1) catalog[depName] = info.version;
4008
- return catalog;
4009
- }
4010
- async function setupBunCatalogs(projectDir, catalog) {
4011
- const rootPkgJsonPath = path.join(projectDir, "package.json");
4012
- const rootPkgJson = await fs.readJson(rootPkgJsonPath);
4013
- if (!rootPkgJson.workspaces) rootPkgJson.workspaces = {};
4014
- if (Array.isArray(rootPkgJson.workspaces)) rootPkgJson.workspaces = {
4015
- packages: rootPkgJson.workspaces,
4016
- catalog
4017
- };
4018
- else if (typeof rootPkgJson.workspaces === "object") {
4019
- if (!rootPkgJson.workspaces.catalog) rootPkgJson.workspaces.catalog = {};
4020
- rootPkgJson.workspaces.catalog = {
4021
- ...rootPkgJson.workspaces.catalog,
4022
- ...catalog
4023
- };
4024
- }
4025
- await fs.writeJson(rootPkgJsonPath, rootPkgJson, { spaces: 2 });
4026
- }
4027
- async function setupPnpmCatalogs(projectDir, catalog) {
4028
- const workspaceYamlPath = path.join(projectDir, "pnpm-workspace.yaml");
4029
- if (!await fs.pathExists(workspaceYamlPath)) return;
4030
- const workspaceContent = await fs.readFile(workspaceYamlPath, "utf-8");
4031
- const workspaceYaml = yaml.parse(workspaceContent);
4032
- if (!workspaceYaml.catalog) workspaceYaml.catalog = {};
4033
- workspaceYaml.catalog = {
4034
- ...workspaceYaml.catalog,
4035
- ...catalog
4036
- };
4037
- await fs.writeFile(workspaceYamlPath, yaml.stringify(workspaceYaml));
4038
- }
4039
- async function updatePackageJsonsWithCatalogs(packagesInfo, catalog) {
4040
- for (const pkg of packagesInfo) {
4041
- const pkgJsonPath = path.join(pkg.path, "package.json");
4042
- const pkgJson = await fs.readJson(pkgJsonPath);
4043
- let updated = false;
4044
- if (pkgJson.dependencies) {
4045
- for (const depName of Object.keys(pkgJson.dependencies)) if (catalog[depName]) {
4046
- pkgJson.dependencies[depName] = "catalog:";
4047
- updated = true;
4048
- }
4049
- }
4050
- if (pkgJson.devDependencies) {
4051
- for (const depName of Object.keys(pkgJson.devDependencies)) if (catalog[depName]) {
4052
- pkgJson.devDependencies[depName] = "catalog:";
4053
- updated = true;
4054
- }
4055
- }
4056
- if (updated) await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
4057
- }
4058
- }
4059
-
4060
3904
  //#endregion
4061
3905
  //#region src/helpers/addons/examples-setup.ts
4062
3906
  async function setupExamples(config) {
@@ -4065,10 +3909,10 @@ async function setupExamples(config) {
4065
3909
  if (examples.includes("ai")) {
4066
3910
  const webClientDir = path.join(projectDir, "apps/web");
4067
3911
  const nativeClientDir = path.join(projectDir, "apps/native");
4068
- const apiDir = path.join(projectDir, "packages/api");
3912
+ const serverDir = path.join(projectDir, "apps/server");
4069
3913
  const webClientDirExists = await fs.pathExists(webClientDir);
4070
3914
  const nativeClientDirExists = await fs.pathExists(nativeClientDir);
4071
- const apiDirExists = await fs.pathExists(apiDir);
3915
+ const serverDirExists = await fs.pathExists(serverDir);
4072
3916
  const hasNuxt = frontend.includes("nuxt");
4073
3917
  const hasSvelte = frontend.includes("svelte");
4074
3918
  const hasReactWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("next") || frontend.includes("tanstack-start");
@@ -4089,9 +3933,9 @@ async function setupExamples(config) {
4089
3933
  dependencies: ["ai", "@ai-sdk/react"],
4090
3934
  projectDir: nativeClientDir
4091
3935
  });
4092
- if (apiDirExists && backend !== "none") await addPackageDependency({
3936
+ if (serverDirExists && backend !== "none") await addPackageDependency({
4093
3937
  dependencies: ["ai", "@ai-sdk/google"],
4094
- projectDir: apiDir
3938
+ projectDir: serverDir
4095
3939
  });
4096
3940
  }
4097
3941
  }
@@ -4207,57 +4051,32 @@ function getConvexDependencies(frontend) {
4207
4051
  return deps;
4208
4052
  }
4209
4053
  async function setupApi(config) {
4210
- const { api, projectName, frontend, backend, packageManager, projectDir, auth } = config;
4054
+ const { api, projectName, frontend, backend, packageManager, projectDir } = config;
4211
4055
  const isConvex = backend === "convex";
4212
4056
  const webDir = path.join(projectDir, "apps/web");
4213
4057
  const nativeDir = path.join(projectDir, "apps/native");
4214
4058
  const serverDir = path.join(projectDir, "apps/server");
4215
4059
  const webDirExists = await fs.pathExists(webDir);
4216
4060
  const nativeDirExists = await fs.pathExists(nativeDir);
4217
- await fs.pathExists(serverDir);
4061
+ const serverDirExists = await fs.pathExists(serverDir);
4218
4062
  const frontendType = getFrontendType(frontend);
4219
4063
  if (!isConvex && api !== "none") {
4220
4064
  const apiDeps = getApiDependencies(api, frontendType);
4221
- const apiPackageDir = path.join(projectDir, "packages/api");
4222
- if (apiDeps.server) {
4065
+ if (serverDirExists && apiDeps.server) {
4223
4066
  await addPackageDependency({
4224
4067
  dependencies: apiDeps.server.dependencies,
4225
- projectDir: apiPackageDir
4226
- });
4227
- const frameworkDeps = [];
4228
- if (backend === "hono") frameworkDeps.push("hono");
4229
- else if (backend === "elysia") frameworkDeps.push("elysia");
4230
- else if (backend === "express") frameworkDeps.push("express", "@types/express");
4231
- else if (backend === "fastify") frameworkDeps.push("fastify");
4232
- else if (backend === "self") {
4233
- if (frontend.includes("next")) frameworkDeps.push("next");
4234
- }
4235
- if (frameworkDeps.length > 0) await addPackageDependency({
4236
- dependencies: frameworkDeps,
4237
- projectDir: apiPackageDir
4068
+ projectDir: serverDir
4238
4069
  });
4239
4070
  if (api === "trpc") {
4240
4071
  if (backend === "hono") await addPackageDependency({
4241
4072
  dependencies: ["@hono/trpc-server"],
4242
- projectDir: apiPackageDir
4073
+ projectDir: serverDir
4243
4074
  });
4244
4075
  else if (backend === "elysia") await addPackageDependency({
4245
4076
  dependencies: ["@elysiajs/trpc"],
4246
- projectDir: apiPackageDir
4247
- });
4248
- else if (backend === "express") await addPackageDependency({
4249
- dependencies: ["@trpc/server"],
4250
- projectDir: apiPackageDir
4251
- });
4252
- else if (backend === "fastify") await addPackageDependency({
4253
- dependencies: ["@trpc/server"],
4254
- projectDir: apiPackageDir
4077
+ projectDir: serverDir
4255
4078
  });
4256
4079
  }
4257
- if (auth === "better-auth") await addPackageDependency({
4258
- dependencies: ["better-auth"],
4259
- projectDir: apiPackageDir
4260
- });
4261
4080
  }
4262
4081
  if (webDirExists && apiDeps.web) await addPackageDependency({
4263
4082
  dependencies: apiDeps.web.dependencies,
@@ -4301,7 +4120,7 @@ async function setupApi(config) {
4301
4120
  //#endregion
4302
4121
  //#region src/helpers/core/backend-setup.ts
4303
4122
  async function setupBackendDependencies(config) {
4304
- const { backend, runtime, api, auth, examples, projectDir } = config;
4123
+ const { backend, runtime, api, projectDir } = config;
4305
4124
  if (backend === "convex") return;
4306
4125
  const framework = backend;
4307
4126
  const serverDir = path.join(projectDir, "apps/server");
@@ -4329,13 +4148,6 @@ async function setupBackendDependencies(config) {
4329
4148
  dependencies.push("fastify", "@fastify/cors");
4330
4149
  if (runtime === "node") devDependencies.push("tsx", "@types/node");
4331
4150
  }
4332
- if (api === "trpc") {
4333
- if (framework === "express") dependencies.push("@trpc/server");
4334
- else if (framework === "fastify") dependencies.push("@trpc/server");
4335
- else if (runtime === "workers") dependencies.push("@trpc/server");
4336
- } else if (api === "orpc") dependencies.push("@orpc/server", "@orpc/openapi", "@orpc/zod");
4337
- if (auth === "better-auth") dependencies.push("better-auth");
4338
- if (examples.includes("ai")) dependencies.push("ai", "@ai-sdk/google");
4339
4151
  if (runtime === "bun") devDependencies.push("@types/bun");
4340
4152
  if (dependencies.length > 0 || devDependencies.length > 0) await addPackageDependency({
4341
4153
  dependencies,
@@ -4354,7 +4166,7 @@ async function setupAuth(config) {
4354
4166
  const nativeDir = path.join(projectDir, "apps/native");
4355
4167
  const clientDirExists = await fs.pathExists(clientDir);
4356
4168
  const nativeDirExists = await fs.pathExists(nativeDir);
4357
- await fs.pathExists(serverDir);
4169
+ const serverDirExists = await fs.pathExists(serverDir);
4358
4170
  try {
4359
4171
  if (backend === "convex") {
4360
4172
  if (auth === "clerk" && clientDirExists) {
@@ -4410,11 +4222,9 @@ async function setupAuth(config) {
4410
4222
  });
4411
4223
  return;
4412
4224
  }
4413
- const authPackageDir = path.join(projectDir, "packages/auth");
4414
- const authPackageDirExists = await fs.pathExists(authPackageDir);
4415
- if (authPackageDirExists && auth === "better-auth") await addPackageDependency({
4225
+ if (serverDirExists && auth === "better-auth") await addPackageDependency({
4416
4226
  dependencies: ["better-auth"],
4417
- projectDir: authPackageDir
4227
+ projectDir: serverDir
4418
4228
  });
4419
4229
  if (frontend.some((f) => [
4420
4230
  "react-router",
@@ -4436,9 +4246,9 @@ async function setupAuth(config) {
4436
4246
  dependencies: ["better-auth", "@better-auth/expo"],
4437
4247
  projectDir: nativeDir
4438
4248
  });
4439
- if (authPackageDirExists) await addPackageDependency({
4249
+ if (serverDirExists) await addPackageDependency({
4440
4250
  dependencies: ["@better-auth/expo"],
4441
- projectDir: authPackageDir
4251
+ projectDir: serverDir
4442
4252
  });
4443
4253
  }
4444
4254
  }
@@ -4621,6 +4431,8 @@ async function setupEnvironmentVariables(config) {
4621
4431
  return;
4622
4432
  }
4623
4433
  const serverDir = path.join(projectDir, "apps/server");
4434
+ if (!await fs.pathExists(serverDir)) return;
4435
+ const envPath = path.join(serverDir, ".env");
4624
4436
  let corsOrigin = "http://localhost:3001";
4625
4437
  if (hasReactRouter || hasSvelte) corsOrigin = "http://localhost:5173";
4626
4438
  let databaseUrl = null;
@@ -4636,50 +4448,47 @@ async function setupEnvironmentVariables(config) {
4636
4448
  break;
4637
4449
  case "sqlite":
4638
4450
  if (config.runtime === "workers") databaseUrl = "http://127.0.0.1:8080";
4639
- else databaseUrl = `file:${path.join(config.projectDir, "apps/server", "local.db")}`;
4451
+ else databaseUrl = "file:./local.db";
4640
4452
  break;
4641
4453
  }
4642
- if (await fs.pathExists(serverDir)) {
4643
- const serverEnvPath = path.join(serverDir, ".env");
4644
- const serverVars = [
4645
- {
4646
- key: "BETTER_AUTH_SECRET",
4647
- value: generateAuthSecret(),
4648
- condition: !!auth
4649
- },
4650
- {
4651
- key: "BETTER_AUTH_URL",
4652
- value: "http://localhost:3000",
4653
- condition: !!auth
4654
- },
4655
- {
4656
- key: "POLAR_ACCESS_TOKEN",
4657
- value: "",
4658
- condition: config.payments === "polar"
4659
- },
4660
- {
4661
- key: "POLAR_SUCCESS_URL",
4662
- value: `${corsOrigin}/success?checkout_id={CHECKOUT_ID}`,
4663
- condition: config.payments === "polar"
4664
- },
4665
- {
4666
- key: "CORS_ORIGIN",
4667
- value: corsOrigin,
4668
- condition: true
4669
- },
4670
- {
4671
- key: "GOOGLE_GENERATIVE_AI_API_KEY",
4672
- value: "",
4673
- condition: examples?.includes("ai") || false
4674
- },
4675
- {
4676
- key: "DATABASE_URL",
4677
- value: databaseUrl,
4678
- condition: database !== "none" && dbSetup === "none"
4679
- }
4680
- ];
4681
- await addEnvVariablesToFile(serverEnvPath, serverVars);
4682
- }
4454
+ const serverVars = [
4455
+ {
4456
+ key: "CORS_ORIGIN",
4457
+ value: corsOrigin,
4458
+ condition: true
4459
+ },
4460
+ {
4461
+ key: "BETTER_AUTH_SECRET",
4462
+ value: generateAuthSecret(),
4463
+ condition: !!auth
4464
+ },
4465
+ {
4466
+ key: "BETTER_AUTH_URL",
4467
+ value: "http://localhost:3000",
4468
+ condition: !!auth
4469
+ },
4470
+ {
4471
+ key: "DATABASE_URL",
4472
+ value: databaseUrl,
4473
+ condition: database !== "none" && dbSetup === "none"
4474
+ },
4475
+ {
4476
+ key: "GOOGLE_GENERATIVE_AI_API_KEY",
4477
+ value: "",
4478
+ condition: examples?.includes("ai") || false
4479
+ },
4480
+ {
4481
+ key: "POLAR_ACCESS_TOKEN",
4482
+ value: "",
4483
+ condition: config.payments === "polar"
4484
+ },
4485
+ {
4486
+ key: "POLAR_SUCCESS_URL",
4487
+ value: `${corsOrigin}/success?checkout_id={CHECKOUT_ID}`,
4488
+ condition: config.payments === "polar"
4489
+ }
4490
+ ];
4491
+ await addEnvVariablesToFile(envPath, serverVars);
4683
4492
  const isUnifiedAlchemy = webDeploy === "alchemy" && serverDeploy === "alchemy";
4684
4493
  const isIndividualAlchemy = webDeploy === "alchemy" || serverDeploy === "alchemy";
4685
4494
  if (isUnifiedAlchemy) {
@@ -4698,11 +4507,14 @@ async function setupEnvironmentVariables(config) {
4698
4507
  condition: true
4699
4508
  }]);
4700
4509
  }
4701
- if (serverDeploy === "alchemy") await addEnvVariablesToFile(path.join(serverDir, ".env"), [{
4702
- key: "ALCHEMY_PASSWORD",
4703
- value: "please-change-this",
4704
- condition: true
4705
- }]);
4510
+ if (serverDeploy === "alchemy") {
4511
+ const serverDir$1 = path.join(projectDir, "apps/server");
4512
+ if (await fs.pathExists(serverDir$1)) await addEnvVariablesToFile(path.join(serverDir$1, ".env"), [{
4513
+ key: "ALCHEMY_PASSWORD",
4514
+ value: "please-change-this",
4515
+ condition: true
4516
+ }]);
4517
+ }
4706
4518
  }
4707
4519
  }
4708
4520
 
@@ -4737,7 +4549,7 @@ async function setupCloudflareD1(config) {
4737
4549
  const envPath = path.join(projectDir, "apps/server", ".env");
4738
4550
  const variables = [{
4739
4551
  key: "DATABASE_URL",
4740
- value: `file:${path.join(projectDir, "apps/server", "local.db")}`,
4552
+ value: "file:./local.db",
4741
4553
  condition: true
4742
4554
  }];
4743
4555
  try {
@@ -4794,14 +4606,13 @@ async function commandExists(command) {
4794
4606
  //#endregion
4795
4607
  //#region src/helpers/database-providers/mongodb-atlas-setup.ts
4796
4608
  async function checkAtlasCLI() {
4797
- const s = spinner();
4798
- s.start("Checking for MongoDB Atlas CLI...");
4799
4609
  try {
4800
4610
  const exists = await commandExists("atlas");
4801
- s.stop(exists ? "MongoDB Atlas CLI found" : pc.yellow("MongoDB Atlas CLI not found"));
4611
+ if (exists) log.info("MongoDB Atlas CLI found");
4612
+ else log.warn(pc.yellow("MongoDB Atlas CLI not found"));
4802
4613
  return exists;
4803
4614
  } catch (_error) {
4804
- s.stop(pc.red("Error checking MongoDB Atlas CLI"));
4615
+ log.error(pc.red("Error checking MongoDB Atlas CLI"));
4805
4616
  return false;
4806
4617
  }
4807
4618
  }
@@ -4812,12 +4623,13 @@ async function initMongoDBAtlas(serverDir) {
4812
4623
  log.info(pc.yellow("Please install it from: https://www.mongodb.com/docs/atlas/cli/current/install-atlas-cli/"));
4813
4624
  return null;
4814
4625
  }
4815
- log.info(pc.blue("Running MongoDB Atlas setup..."));
4626
+ log.info("Running MongoDB Atlas setup...");
4816
4627
  await execa("atlas", ["deployments", "setup"], {
4817
4628
  cwd: serverDir,
4629
+ shell: true,
4818
4630
  stdio: "inherit"
4819
4631
  });
4820
- log.info(pc.green("MongoDB Atlas deployment ready"));
4632
+ log.success("MongoDB Atlas deployment ready");
4821
4633
  const connectionString = await text({
4822
4634
  message: "Enter your MongoDB connection string:",
4823
4635
  placeholder: "mongodb+srv://username:password@cluster.mongodb.net/database",
@@ -4869,13 +4681,11 @@ ${pc.green("MongoDB Atlas Manual Setup Instructions:")}
4869
4681
  async function setupMongoDBAtlas(config, cliInput) {
4870
4682
  const { projectDir } = config;
4871
4683
  const manualDb = cliInput?.manualDb ?? false;
4872
- const mainSpinner = spinner();
4873
- mainSpinner.start("Setting up MongoDB Atlas...");
4874
4684
  const serverDir = path.join(projectDir, "apps/server");
4875
4685
  try {
4876
4686
  await fs.ensureDir(serverDir);
4877
4687
  if (manualDb) {
4878
- mainSpinner.stop("MongoDB Atlas manual setup selected");
4688
+ log.info("MongoDB Atlas manual setup selected");
4879
4689
  await writeEnvFile$3(projectDir);
4880
4690
  displayManualSetupInstructions$3();
4881
4691
  return;
@@ -4895,15 +4705,14 @@ async function setupMongoDBAtlas(config, cliInput) {
4895
4705
  });
4896
4706
  if (isCancel(mode)) return exitCancelled("Operation cancelled");
4897
4707
  if (mode === "manual") {
4898
- mainSpinner.stop("MongoDB Atlas manual setup selected");
4708
+ log.info("MongoDB Atlas manual setup selected");
4899
4709
  await writeEnvFile$3(projectDir);
4900
4710
  displayManualSetupInstructions$3();
4901
4711
  return;
4902
4712
  }
4903
- mainSpinner.stop("MongoDB Atlas setup ready");
4904
- const config$1 = await initMongoDBAtlas(serverDir);
4905
- if (config$1) {
4906
- await writeEnvFile$3(projectDir, config$1);
4713
+ const atlasConfig = await initMongoDBAtlas(serverDir);
4714
+ if (atlasConfig) {
4715
+ await writeEnvFile$3(projectDir, atlasConfig);
4907
4716
  log.success(pc.green("MongoDB Atlas setup complete! Connection saved to .env file."));
4908
4717
  } else {
4909
4718
  log.warn(pc.yellow("Falling back to local MongoDB configuration"));
@@ -4911,7 +4720,6 @@ async function setupMongoDBAtlas(config, cliInput) {
4911
4720
  displayManualSetupInstructions$3();
4912
4721
  }
4913
4722
  } catch (error) {
4914
- mainSpinner.stop(pc.red("MongoDB Atlas setup failed"));
4915
4723
  consola.error(pc.red(`Error during MongoDB Atlas setup: ${error instanceof Error ? error.message : String(error)}`));
4916
4724
  try {
4917
4725
  await writeEnvFile$3(projectDir);
@@ -5267,9 +5075,9 @@ async function writeEnvFile$1(projectDir, config) {
5267
5075
  }
5268
5076
  async function addDotenvImportToPrismaConfig(projectDir) {
5269
5077
  try {
5270
- const prismaConfigPath = path.join(projectDir, "packages/db/prisma.config.ts");
5078
+ const prismaConfigPath = path.join(projectDir, "apps/server/prisma.config.ts");
5271
5079
  let content = await fs.readFile(prismaConfigPath, "utf8");
5272
- content = `import dotenv from "dotenv";\ndotenv.config({ path: "../../apps/server/.env" });\n${content}`;
5080
+ content = `import "dotenv/config";\n${content}`;
5273
5081
  await fs.writeFile(prismaConfigPath, content);
5274
5082
  } catch (_error) {
5275
5083
  consola$1.error("Failed to update prisma.config.ts");
@@ -5285,12 +5093,11 @@ function displayManualSetupInstructions$1() {
5285
5093
 
5286
5094
  DATABASE_URL="your_database_url"`);
5287
5095
  }
5288
- async function addPrismaAccelerateExtension(projectDir) {
5096
+ async function addPrismaAccelerateExtension(serverDir) {
5289
5097
  try {
5290
- const dbPackageDir = path.join(projectDir, "packages/db");
5291
5098
  await addPackageDependency({
5292
5099
  dependencies: ["@prisma/extension-accelerate"],
5293
- projectDir: dbPackageDir
5100
+ projectDir: serverDir
5294
5101
  });
5295
5102
  return true;
5296
5103
  } catch (_error) {
@@ -5351,7 +5158,7 @@ async function setupPrismaPostgres(config, cliInput) {
5351
5158
  await writeEnvFile$1(projectDir, prismaConfig);
5352
5159
  if (orm === "prisma") {
5353
5160
  await addDotenvImportToPrismaConfig(projectDir);
5354
- await addPrismaAccelerateExtension(projectDir);
5161
+ await addPrismaAccelerateExtension(serverDir);
5355
5162
  }
5356
5163
  const connectionType = orm === "drizzle" ? "direct connection" : "Prisma Accelerate";
5357
5164
  log.success(pc.green(`Prisma Postgres database configured successfully with ${connectionType}!`));
@@ -5451,18 +5258,18 @@ function displayManualSupabaseInstructions(output) {
5451
5258
  log.info(`"Manual Supabase Setup Instructions:"
5452
5259
  1. Ensure Docker is installed and running.
5453
5260
  2. Install the Supabase CLI (e.g., \`npm install -g supabase\`).
5454
- 3. Run \`supabase init\` in your project's \`packages/db\` directory.
5455
- 4. Run \`supabase start\` in your project's \`packages/db\` directory.
5261
+ 3. Run \`supabase init\` in your project's \`apps/server\` directory.
5262
+ 4. Run \`supabase start\` in your project's \`apps/server\` directory.
5456
5263
  5. Copy the 'DB URL' from the output.${output ? `
5457
5264
  ${pc.bold("Relevant output from `supabase start`:")}
5458
5265
  ${pc.dim(output)}` : ""}
5459
- 6. Add the DB URL to the .env file in \`packages/db/.env\` as \`DATABASE_URL\`:
5266
+ 6. Add the DB URL to the .env file in \`apps/server/.env\` as \`DATABASE_URL\`:
5460
5267
  ${pc.gray("DATABASE_URL=\"your_supabase_db_url\"")}`);
5461
5268
  }
5462
5269
  async function setupSupabase(config, cliInput) {
5463
5270
  const { projectDir, packageManager } = config;
5464
5271
  const manualDb = cliInput?.manualDb ?? false;
5465
- const serverDir = path.join(projectDir, "packages", "db");
5272
+ const serverDir = path.join(projectDir, "apps", "server");
5466
5273
  try {
5467
5274
  await fs.ensureDir(serverDir);
5468
5275
  if (manualDb) {
@@ -5745,15 +5552,15 @@ async function setupDatabase(config, cliInput) {
5745
5552
  const { database, orm, dbSetup, backend, projectDir } = config;
5746
5553
  if (backend === "convex" || database === "none") {
5747
5554
  if (backend !== "convex") {
5748
- const serverDir = path.join(projectDir, "apps/server");
5749
- const serverDbDir = path.join(serverDir, "src/db");
5555
+ const serverDir$1 = path.join(projectDir, "apps/server");
5556
+ const serverDbDir = path.join(serverDir$1, "src/db");
5750
5557
  if (await fs.pathExists(serverDbDir)) await fs.remove(serverDbDir);
5751
5558
  }
5752
5559
  return;
5753
5560
  }
5754
5561
  const s = spinner();
5755
- const dbPackageDir = path.join(projectDir, "packages/db");
5756
- if (!await fs.pathExists(dbPackageDir)) return;
5562
+ const serverDir = path.join(projectDir, "apps/server");
5563
+ if (!await fs.pathExists(serverDir)) return;
5757
5564
  try {
5758
5565
  if (orm === "prisma") if (database === "mysql" && dbSetup === "planetscale") await addPackageDependency({
5759
5566
  dependencies: [
@@ -5762,27 +5569,23 @@ async function setupDatabase(config, cliInput) {
5762
5569
  "@planetscale/database"
5763
5570
  ],
5764
5571
  devDependencies: ["prisma"],
5765
- projectDir: dbPackageDir
5572
+ projectDir: serverDir
5766
5573
  });
5767
5574
  else if (database === "sqlite" && dbSetup === "turso") await addPackageDependency({
5768
5575
  dependencies: ["@prisma/client", "@prisma/adapter-libsql"],
5769
5576
  devDependencies: ["prisma"],
5770
- projectDir: dbPackageDir
5577
+ projectDir: serverDir
5771
5578
  });
5772
5579
  else await addPackageDependency({
5773
5580
  dependencies: ["@prisma/client"],
5774
5581
  devDependencies: ["prisma"],
5775
- projectDir: dbPackageDir
5582
+ projectDir: serverDir
5776
5583
  });
5777
5584
  else if (orm === "drizzle") {
5778
5585
  if (database === "sqlite") await addPackageDependency({
5779
- dependencies: [
5780
- "drizzle-orm",
5781
- "@libsql/client",
5782
- "libsql"
5783
- ],
5586
+ dependencies: ["drizzle-orm", "@libsql/client"],
5784
5587
  devDependencies: ["drizzle-kit"],
5785
- projectDir: dbPackageDir
5588
+ projectDir: serverDir
5786
5589
  });
5787
5590
  else if (database === "postgres") if (dbSetup === "neon") await addPackageDependency({
5788
5591
  dependencies: [
@@ -5791,32 +5594,32 @@ async function setupDatabase(config, cliInput) {
5791
5594
  "ws"
5792
5595
  ],
5793
5596
  devDependencies: ["drizzle-kit", "@types/ws"],
5794
- projectDir: dbPackageDir
5597
+ projectDir: serverDir
5795
5598
  });
5796
5599
  else if (dbSetup === "planetscale") await addPackageDependency({
5797
5600
  dependencies: ["drizzle-orm", "pg"],
5798
5601
  devDependencies: ["drizzle-kit", "@types/pg"],
5799
- projectDir: dbPackageDir
5602
+ projectDir: serverDir
5800
5603
  });
5801
5604
  else await addPackageDependency({
5802
5605
  dependencies: ["drizzle-orm", "pg"],
5803
5606
  devDependencies: ["drizzle-kit", "@types/pg"],
5804
- projectDir: dbPackageDir
5607
+ projectDir: serverDir
5805
5608
  });
5806
5609
  else if (database === "mysql") if (dbSetup === "planetscale") await addPackageDependency({
5807
5610
  dependencies: ["drizzle-orm", "@planetscale/database"],
5808
5611
  devDependencies: ["drizzle-kit"],
5809
- projectDir: dbPackageDir
5612
+ projectDir: serverDir
5810
5613
  });
5811
5614
  else await addPackageDependency({
5812
5615
  dependencies: ["drizzle-orm", "mysql2"],
5813
5616
  devDependencies: ["drizzle-kit"],
5814
- projectDir: dbPackageDir
5617
+ projectDir: serverDir
5815
5618
  });
5816
5619
  } else if (orm === "mongoose") await addPackageDependency({
5817
5620
  dependencies: ["mongoose"],
5818
5621
  devDependencies: [],
5819
- projectDir: dbPackageDir
5622
+ projectDir: serverDir
5820
5623
  });
5821
5624
  if (dbSetup === "docker") await setupDockerCompose(config);
5822
5625
  else if (database === "sqlite" && dbSetup === "turso") await setupTurso(config, cliInput);
@@ -5839,7 +5642,7 @@ async function setupDatabase(config, cliInput) {
5839
5642
  //#region src/helpers/core/runtime-setup.ts
5840
5643
  async function setupRuntime(config) {
5841
5644
  const { runtime, backend, projectDir } = config;
5842
- if (backend === "convex" || backend === "self" || runtime === "none") return;
5645
+ if (backend === "convex" || backend === "next" || runtime === "none") return;
5843
5646
  const serverDir = path.join(projectDir, "apps/server");
5844
5647
  if (!await fs.pathExists(serverDir)) return;
5845
5648
  if (runtime === "bun") await setupBunRuntime(serverDir, backend);
@@ -6359,7 +6162,7 @@ async function displayPostInstallInstructions(config) {
6359
6162
  else if (!hasNative && !addons?.includes("starlight")) output += `${pc.yellow("NOTE:")} You are creating a backend-only app\n (no frontend selected)\n`;
6360
6163
  if (!isConvex) {
6361
6164
  output += `${pc.cyan("•")} Backend API: http://localhost:3000\n`;
6362
- if (api === "orpc") if (backend === "self") output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/rpc/api\n`;
6165
+ if (api === "orpc") if (backend === "next") output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/rpc/api\n`;
6363
6166
  else output += `${pc.cyan("•")} OpenAPI (Scalar UI): http://localhost:3000/api\n`;
6364
6167
  }
6365
6168
  if (addons?.includes("starlight")) output += `${pc.cyan("•")} Docs: http://localhost:4321\n`;
@@ -6473,78 +6276,12 @@ function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy) {
6473
6276
  return instructions.length ? `\n${instructions.join("\n")}` : "";
6474
6277
  }
6475
6278
 
6476
- //#endregion
6477
- //#region src/helpers/core/workspace-setup.ts
6478
- async function setupWorkspaceDependencies(projectDir, options) {
6479
- const projectName = options.projectName;
6480
- const workspaceVersion = options.packageManager === "npm" ? "*" : "workspace:*";
6481
- const commonDeps = ["dotenv", "zod"];
6482
- const commonDevDeps = ["tsdown"];
6483
- const dbPackageDir = path.join(projectDir, "packages/db");
6484
- if (await fs.pathExists(dbPackageDir)) await addPackageDependency({
6485
- dependencies: commonDeps,
6486
- devDependencies: commonDevDeps,
6487
- projectDir: dbPackageDir
6488
- });
6489
- const authPackageDir = path.join(projectDir, "packages/auth");
6490
- if (await fs.pathExists(authPackageDir)) await addPackageDependency({
6491
- dependencies: commonDeps,
6492
- devDependencies: commonDevDeps,
6493
- customDependencies: { [`@${projectName}/db`]: workspaceVersion },
6494
- projectDir: authPackageDir
6495
- });
6496
- const apiPackageDir = path.join(projectDir, "packages/api");
6497
- if (await fs.pathExists(apiPackageDir)) await addPackageDependency({
6498
- dependencies: commonDeps,
6499
- devDependencies: commonDevDeps,
6500
- customDependencies: {
6501
- [`@${projectName}/auth`]: workspaceVersion,
6502
- [`@${projectName}/db`]: workspaceVersion
6503
- },
6504
- projectDir: apiPackageDir
6505
- });
6506
- const serverPackageDir = path.join(projectDir, "apps/server");
6507
- if (await fs.pathExists(serverPackageDir)) await addPackageDependency({
6508
- dependencies: commonDeps,
6509
- devDependencies: commonDevDeps,
6510
- customDependencies: {
6511
- [`@${projectName}/api`]: workspaceVersion,
6512
- [`@${projectName}/auth`]: workspaceVersion,
6513
- [`@${projectName}/db`]: workspaceVersion
6514
- },
6515
- projectDir: serverPackageDir
6516
- });
6517
- const needsApiDependency = options.api && options.api !== "none";
6518
- const webPackageDir = path.join(projectDir, "apps/web");
6519
- if (await fs.pathExists(webPackageDir)) {
6520
- const webDeps = {};
6521
- if (options.backend === "self") {
6522
- webDeps[`@${projectName}/api`] = workspaceVersion;
6523
- webDeps[`@${projectName}/auth`] = workspaceVersion;
6524
- webDeps[`@${projectName}/db`] = workspaceVersion;
6525
- } else if (needsApiDependency) webDeps[`@${projectName}/api`] = workspaceVersion;
6526
- if (Object.keys(webDeps).length > 0) await addPackageDependency({
6527
- customDependencies: webDeps,
6528
- projectDir: webPackageDir
6529
- });
6530
- }
6531
- }
6532
-
6533
6279
  //#endregion
6534
6280
  //#region src/helpers/core/project-config.ts
6535
6281
  async function updatePackageConfigurations(projectDir, options) {
6536
6282
  await updateRootPackageJson(projectDir, options);
6537
- if (options.backend === "convex") await updateConvexPackageJson(projectDir, options);
6538
- else if (options.backend === "self") {
6539
- await updateAuthPackageJson(projectDir, options);
6540
- await updateApiPackageJson(projectDir, options);
6541
- await setupWorkspaceDependencies(projectDir, options);
6542
- } else if (options.backend !== "none") {
6543
- await updateServerPackageJson(projectDir, options);
6544
- await updateAuthPackageJson(projectDir, options);
6545
- await updateApiPackageJson(projectDir, options);
6546
- await setupWorkspaceDependencies(projectDir, options);
6547
- }
6283
+ if (options.backend !== "convex") await updateServerPackageJson(projectDir, options);
6284
+ else await updateConvexPackageJson(projectDir, options);
6548
6285
  }
6549
6286
  async function updateRootPackageJson(projectDir, options) {
6550
6287
  const rootPackageJsonPath = path.join(projectDir, "package.json");
@@ -6554,7 +6291,6 @@ async function updateRootPackageJson(projectDir, options) {
6554
6291
  if (!packageJson.scripts) packageJson.scripts = {};
6555
6292
  const scripts = packageJson.scripts;
6556
6293
  const backendPackageName = options.backend === "convex" ? `@${options.projectName}/backend` : "server";
6557
- const dbPackageName = `@${options.projectName}/db`;
6558
6294
  let serverDevScript = "";
6559
6295
  if (options.addons.includes("turborepo")) serverDevScript = `turbo -F ${backendPackageName} dev`;
6560
6296
  else if (options.packageManager === "bun") serverDevScript = `bun run --filter ${backendPackageName} dev`;
@@ -6571,17 +6307,17 @@ async function updateRootPackageJson(projectDir, options) {
6571
6307
  scripts["check-types"] = "turbo check-types";
6572
6308
  scripts["dev:native"] = "turbo -F native dev";
6573
6309
  scripts["dev:web"] = "turbo -F web dev";
6574
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6310
+ scripts["dev:server"] = serverDevScript;
6575
6311
  if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`;
6576
6312
  if (needsDbScripts) {
6577
- scripts["db:push"] = `turbo -F ${dbPackageName} db:push`;
6578
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `turbo -F ${dbPackageName} db:studio`;
6313
+ scripts["db:push"] = `turbo -F ${backendPackageName} db:push`;
6314
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `turbo -F ${backendPackageName} db:studio`;
6579
6315
  if (options.orm === "prisma") {
6580
- scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
6581
- scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
6316
+ scripts["db:generate"] = `turbo -F ${backendPackageName} db:generate`;
6317
+ scripts["db:migrate"] = `turbo -F ${backendPackageName} db:migrate`;
6582
6318
  } else if (options.orm === "drizzle") {
6583
- scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
6584
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
6319
+ scripts["db:generate"] = `turbo -F ${backendPackageName} db:generate`;
6320
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `turbo -F ${backendPackageName} db:migrate`;
6585
6321
  }
6586
6322
  }
6587
6323
  if (options.dbSetup === "docker") {
@@ -6596,17 +6332,17 @@ async function updateRootPackageJson(projectDir, options) {
6596
6332
  scripts["check-types"] = "pnpm -r check-types";
6597
6333
  scripts["dev:native"] = "pnpm --filter native dev";
6598
6334
  scripts["dev:web"] = "pnpm --filter web dev";
6599
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6335
+ scripts["dev:server"] = serverDevScript;
6600
6336
  if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`;
6601
6337
  if (needsDbScripts) {
6602
- scripts["db:push"] = `pnpm --filter ${dbPackageName} db:push`;
6603
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `pnpm --filter ${dbPackageName} db:studio`;
6338
+ scripts["db:push"] = `pnpm --filter ${backendPackageName} db:push`;
6339
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `pnpm --filter ${backendPackageName} db:studio`;
6604
6340
  if (options.orm === "prisma") {
6605
- scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
6606
- scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
6341
+ scripts["db:generate"] = `pnpm --filter ${backendPackageName} db:generate`;
6342
+ scripts["db:migrate"] = `pnpm --filter ${backendPackageName} db:migrate`;
6607
6343
  } else if (options.orm === "drizzle") {
6608
- scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
6609
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
6344
+ scripts["db:generate"] = `pnpm --filter ${backendPackageName} db:generate`;
6345
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `pnpm --filter ${backendPackageName} db:migrate`;
6610
6346
  }
6611
6347
  }
6612
6348
  if (options.dbSetup === "docker") {
@@ -6621,17 +6357,17 @@ async function updateRootPackageJson(projectDir, options) {
6621
6357
  scripts["check-types"] = "npm run check-types --workspaces";
6622
6358
  scripts["dev:native"] = "npm run dev --workspace native";
6623
6359
  scripts["dev:web"] = "npm run dev --workspace web";
6624
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6360
+ scripts["dev:server"] = serverDevScript;
6625
6361
  if (options.backend === "convex") scripts["dev:setup"] = `npm run dev:setup --workspace ${backendPackageName}`;
6626
6362
  if (needsDbScripts) {
6627
- scripts["db:push"] = `npm run db:push --workspace ${dbPackageName}`;
6628
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `npm run db:studio --workspace ${dbPackageName}`;
6363
+ scripts["db:push"] = `npm run db:push --workspace ${backendPackageName}`;
6364
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `npm run db:studio --workspace ${backendPackageName}`;
6629
6365
  if (options.orm === "prisma") {
6630
- scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
6631
- scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
6366
+ scripts["db:generate"] = `npm run db:generate --workspace ${backendPackageName}`;
6367
+ scripts["db:migrate"] = `npm run db:migrate --workspace ${backendPackageName}`;
6632
6368
  } else if (options.orm === "drizzle") {
6633
- scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
6634
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
6369
+ scripts["db:generate"] = `npm run db:generate --workspace ${backendPackageName}`;
6370
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `npm run db:migrate --workspace ${backendPackageName}`;
6635
6371
  }
6636
6372
  }
6637
6373
  if (options.dbSetup === "docker") {
@@ -6646,17 +6382,17 @@ async function updateRootPackageJson(projectDir, options) {
6646
6382
  scripts["check-types"] = "bun run --filter '*' check-types";
6647
6383
  scripts["dev:native"] = "bun run --filter native dev";
6648
6384
  scripts["dev:web"] = "bun run --filter web dev";
6649
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6385
+ scripts["dev:server"] = serverDevScript;
6650
6386
  if (options.backend === "convex") scripts["dev:setup"] = `bun run --filter ${backendPackageName} dev:setup`;
6651
6387
  if (needsDbScripts) {
6652
- scripts["db:push"] = `bun run --filter ${dbPackageName} db:push`;
6653
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `bun run --filter ${dbPackageName} db:studio`;
6388
+ scripts["db:push"] = `bun run --filter ${backendPackageName} db:push`;
6389
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `bun run --filter ${backendPackageName} db:studio`;
6654
6390
  if (options.orm === "prisma") {
6655
- scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
6656
- scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
6391
+ scripts["db:generate"] = `bun run --filter ${backendPackageName} db:generate`;
6392
+ scripts["db:migrate"] = `bun run --filter ${backendPackageName} db:migrate`;
6657
6393
  } else if (options.orm === "drizzle") {
6658
- scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
6659
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
6394
+ scripts["db:generate"] = `bun run --filter ${backendPackageName} db:generate`;
6395
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `bun run --filter ${backendPackageName} db:migrate`;
6660
6396
  }
6661
6397
  }
6662
6398
  if (options.dbSetup === "docker") {
@@ -6689,22 +6425,6 @@ async function updateServerPackageJson(projectDir, options) {
6689
6425
  const serverPackageJson = await fs.readJson(serverPackageJsonPath);
6690
6426
  if (!serverPackageJson.scripts) serverPackageJson.scripts = {};
6691
6427
  const scripts = serverPackageJson.scripts;
6692
- if (options.dbSetup === "docker") {
6693
- scripts["db:start"] = "docker compose up -d";
6694
- scripts["db:watch"] = "docker compose up";
6695
- scripts["db:stop"] = "docker compose stop";
6696
- scripts["db:down"] = "docker compose down";
6697
- }
6698
- await fs.writeJson(serverPackageJsonPath, serverPackageJson, { spaces: 2 });
6699
- await updateDbPackageJson(projectDir, options);
6700
- }
6701
- async function updateDbPackageJson(projectDir, options) {
6702
- const dbPackageJsonPath = path.join(projectDir, "packages/db/package.json");
6703
- if (!await fs.pathExists(dbPackageJsonPath)) return;
6704
- const dbPackageJson = await fs.readJson(dbPackageJsonPath);
6705
- dbPackageJson.name = `@${options.projectName}/db`;
6706
- if (!dbPackageJson.scripts) dbPackageJson.scripts = {};
6707
- const scripts = dbPackageJson.scripts;
6708
6428
  if (options.database !== "none") {
6709
6429
  if (options.database === "sqlite" && options.orm === "drizzle" && options.dbSetup !== "d1") scripts["db:local"] = "turso dev --db-file local.db";
6710
6430
  if (options.orm === "prisma") {
@@ -6719,21 +6439,13 @@ async function updateDbPackageJson(projectDir, options) {
6719
6439
  if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = "drizzle-kit migrate";
6720
6440
  }
6721
6441
  }
6722
- await fs.writeJson(dbPackageJsonPath, dbPackageJson, { spaces: 2 });
6723
- }
6724
- async function updateAuthPackageJson(projectDir, options) {
6725
- const authPackageJsonPath = path.join(projectDir, "packages/auth/package.json");
6726
- if (!await fs.pathExists(authPackageJsonPath)) return;
6727
- const authPackageJson = await fs.readJson(authPackageJsonPath);
6728
- authPackageJson.name = `@${options.projectName}/auth`;
6729
- await fs.writeJson(authPackageJsonPath, authPackageJson, { spaces: 2 });
6730
- }
6731
- async function updateApiPackageJson(projectDir, options) {
6732
- const apiPackageJsonPath = path.join(projectDir, "packages/api/package.json");
6733
- if (!await fs.pathExists(apiPackageJsonPath)) return;
6734
- const apiPackageJson = await fs.readJson(apiPackageJsonPath);
6735
- apiPackageJson.name = `@${options.projectName}/api`;
6736
- await fs.writeJson(apiPackageJsonPath, apiPackageJson, { spaces: 2 });
6442
+ if (options.dbSetup === "docker") {
6443
+ scripts["db:start"] = "docker compose up -d";
6444
+ scripts["db:watch"] = "docker compose up";
6445
+ scripts["db:stop"] = "docker compose stop";
6446
+ scripts["db:down"] = "docker compose down";
6447
+ }
6448
+ await fs.writeJson(serverPackageJsonPath, serverPackageJson, { spaces: 2 });
6737
6449
  }
6738
6450
  async function updateConvexPackageJson(projectDir, options) {
6739
6451
  const convexPackageJsonPath = path.join(projectDir, "packages/backend/package.json");
@@ -6749,14 +6461,15 @@ async function updateConvexPackageJson(projectDir, options) {
6749
6461
  async function createProject(options, cliInput) {
6750
6462
  const projectDir = options.projectDir;
6751
6463
  const isConvex = options.backend === "convex";
6752
- const isSelfBackend = options.backend === "self";
6753
- const needsServerSetup = !isConvex && !isSelfBackend;
6754
6464
  try {
6755
6465
  await fs.ensureDir(projectDir);
6756
6466
  await copyBaseTemplate(projectDir, options);
6757
6467
  await setupFrontendTemplates(projectDir, options);
6758
6468
  await setupBackendFramework(projectDir, options);
6759
- if (needsServerSetup) await setupDockerComposeTemplates(projectDir, options);
6469
+ if (!isConvex) {
6470
+ await setupDbOrmTemplates(projectDir, options);
6471
+ await setupDockerComposeTemplates(projectDir, options);
6472
+ }
6760
6473
  await setupAuthTemplate(projectDir, options);
6761
6474
  if (options.payments && options.payments !== "none") await setupPaymentsTemplate(projectDir, options);
6762
6475
  if (options.examples.length > 0 && options.examples[0] !== "none") await setupExamplesTemplate(projectDir, options);
@@ -6764,11 +6477,9 @@ async function createProject(options, cliInput) {
6764
6477
  await setupDeploymentTemplates(projectDir, options);
6765
6478
  await setupApi(options);
6766
6479
  if (!isConvex) {
6767
- if (needsServerSetup) {
6768
- await setupBackendDependencies(options);
6769
- await setupRuntime(options);
6770
- }
6480
+ await setupBackendDependencies(options);
6771
6481
  await setupDatabase(options, cliInput);
6482
+ await setupRuntime(options);
6772
6483
  if (options.examples.length > 0 && options.examples[0] !== "none") await setupExamples(options);
6773
6484
  }
6774
6485
  if (options.addons.length > 0 && options.addons[0] !== "none") await setupAddons(options);
@@ -6777,7 +6488,6 @@ async function createProject(options, cliInput) {
6777
6488
  await handleExtras(projectDir, options);
6778
6489
  await setupEnvironmentVariables(options);
6779
6490
  await updatePackageConfigurations(projectDir, options);
6780
- await setupCatalogs(projectDir, options);
6781
6491
  await setupWebDeploy(options);
6782
6492
  await setupServerDeploy(options);
6783
6493
  await createReadme(projectDir, options);