create-better-t-stack 3.7.1 → 3.7.3-canary.53fc0031

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 (47) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/index.d.ts +108 -250
  3. package/dist/index.js +1 -1
  4. package/dist/{src-BmyCNYPk.js → src-B1ogWZqk.js} +205 -368
  5. package/package.json +3 -3
  6. package/templates/api/orpc/server/package.json.hbs +0 -3
  7. package/templates/api/trpc/server/package.json.hbs +1 -4
  8. package/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs +0 -2
  9. package/templates/auth/better-auth/server/base/package.json.hbs +1 -4
  10. package/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs +6 -2
  11. package/templates/auth/better-auth/web/react/tanstack-router/src/components/sign-in-form.tsx +117 -121
  12. package/templates/auth/better-auth/web/react/tanstack-router/src/components/sign-up-form.tsx +141 -145
  13. package/templates/auth/better-auth/web/react/tanstack-start/src/components/sign-in-form.tsx +117 -121
  14. package/templates/auth/better-auth/web/react/tanstack-start/src/components/sign-up-form.tsx +141 -145
  15. package/templates/auth/better-auth/web/solid/src/components/sign-in-form.tsx +3 -11
  16. package/templates/auth/better-auth/web/solid/src/components/sign-up-form.tsx +4 -14
  17. package/templates/backend/convex/packages/backend/convex/healthCheck.ts +2 -2
  18. package/templates/backend/convex/packages/backend/package.json.hbs +1 -2
  19. package/templates/backend/server/base/package.json.hbs +1 -3
  20. package/templates/db/base/package.json.hbs +1 -4
  21. package/templates/examples/ai/native/bare/polyfills.js +3 -7
  22. package/templates/examples/ai/native/unistyles/polyfills.js +3 -6
  23. package/templates/examples/ai/native/uniwind/polyfills.js +3 -7
  24. package/templates/examples/todo/server/drizzle/postgres/src/schema/todo.ts +1 -1
  25. package/templates/frontend/native/bare/package.json.hbs +1 -2
  26. package/templates/frontend/native/unistyles/package.json.hbs +1 -2
  27. package/templates/frontend/native/uniwind/package.json.hbs +1 -2
  28. package/templates/frontend/nuxt/package.json.hbs +1 -3
  29. package/templates/frontend/react/next/package.json.hbs +1 -3
  30. package/templates/frontend/react/react-router/package.json.hbs +1 -3
  31. package/templates/frontend/react/react-router/src/components/mode-toggle.tsx +3 -9
  32. package/templates/frontend/react/tanstack-router/package.json.hbs +1 -3
  33. package/templates/frontend/react/tanstack-router/src/components/mode-toggle.tsx +3 -9
  34. package/templates/frontend/react/tanstack-start/package.json.hbs +1 -3
  35. package/templates/frontend/react/web-base/src/components/ui/button.tsx +13 -16
  36. package/templates/frontend/react/web-base/src/components/ui/card.tsx +13 -30
  37. package/templates/frontend/react/web-base/src/components/ui/checkbox.tsx +8 -11
  38. package/templates/frontend/react/web-base/src/components/ui/dropdown-menu.tsx +37 -66
  39. package/templates/frontend/react/web-base/src/components/ui/input.tsx +5 -5
  40. package/templates/frontend/react/web-base/src/components/ui/label.tsx +7 -10
  41. package/templates/frontend/react/web-base/src/components/ui/skeleton.tsx +3 -3
  42. package/templates/frontend/react/web-base/src/lib/utils.ts +3 -3
  43. package/templates/frontend/solid/package.json.hbs +1 -3
  44. package/templates/frontend/svelte/package.json.hbs +1 -3
  45. package/templates/frontend/svelte/src/app.d.ts +7 -7
  46. package/templates/frontend/svelte/src/lib/index.ts +1 -0
  47. package/templates/frontend/svelte/vite.config.ts +4 -4
@@ -3,11 +3,12 @@ import { autocompleteMultiselect, cancel, confirm, group, groupMultiselect, intr
3
3
  import { createRouterClient, os } from "@orpc/server";
4
4
  import pc from "picocolors";
5
5
  import { createCli } from "trpc-cli";
6
- import z$1, { z } from "zod";
6
+ import z from "zod";
7
7
  import path from "node:path";
8
8
  import consola, { consola as consola$1 } from "consola";
9
9
  import fs from "fs-extra";
10
10
  import { fileURLToPath } from "node:url";
11
+ import { APISchema, AddonsSchema, AuthSchema, BackendSchema, DatabaseSchema, DatabaseSetupSchema, DirectoryConflictSchema, ExamplesSchema, FrontendSchema, ORMSchema, PackageManagerSchema, PaymentsSchema, ProjectNameSchema, RuntimeSchema, ServerDeploySchema, TemplateSchema, WebDeploySchema } from "@create-better-t-stack/types";
11
12
  import gradient from "gradient-string";
12
13
  import * as JSONC from "jsonc-parser";
13
14
  import { $, execa } from "execa";
@@ -62,20 +63,21 @@ function getDefaultConfig() {
62
63
  }
63
64
  const DEFAULT_CONFIG = getDefaultConfig();
64
65
  const dependencyVersionMap = {
66
+ typescript: "^5",
65
67
  "better-auth": "^1.4.5",
66
68
  "@better-auth/expo": "^1.4.5",
67
69
  "@clerk/nextjs": "^6.31.5",
68
70
  "@clerk/clerk-react": "^5.45.0",
69
71
  "@clerk/tanstack-react-start": "^0.26.3",
70
72
  "@clerk/clerk-expo": "^2.14.25",
71
- "drizzle-orm": "^0.44.2",
72
- "drizzle-kit": "^0.31.2",
73
+ "drizzle-orm": "^0.45.0",
74
+ "drizzle-kit": "^0.31.8",
73
75
  "@planetscale/database": "^1.19.0",
74
76
  "@libsql/client": "^0.14.0",
75
77
  libsql: "^0.5.22",
76
78
  "@neondatabase/serverless": "^1.0.2",
77
- pg: "^8.14.1",
78
- "@types/pg": "^8.11.11",
79
+ pg: "^8.16.3",
80
+ "@types/pg": "^8.15.6",
79
81
  "@types/ws": "^8.18.1",
80
82
  ws: "^8.18.3",
81
83
  mysql2: "^3.14.0",
@@ -98,7 +100,7 @@ const dependencyVersionMap = {
98
100
  "lint-staged": "^16.1.2",
99
101
  tsx: "^4.19.2",
100
102
  "@types/node": "^22.13.11",
101
- "@types/bun": "^1.2.6",
103
+ "@types/bun": "^1.3.4",
102
104
  "@elysiajs/node": "^1.3.1",
103
105
  "@elysiajs/cors": "^1.3.3",
104
106
  "@elysiajs/trpc": "^1.1.0",
@@ -128,7 +130,7 @@ const dependencyVersionMap = {
128
130
  "@trpc/tanstack-react-query": "^11.5.0",
129
131
  "@trpc/server": "^11.5.0",
130
132
  "@trpc/client": "^11.5.0",
131
- next: "15.5.4",
133
+ next: "^16.0.7",
132
134
  convex: "^1.29.3",
133
135
  "@convex-dev/react-query": "^0.1.0",
134
136
  "convex-svelte": "^0.0.12",
@@ -153,7 +155,7 @@ const dependencyVersionMap = {
153
155
  alchemy: "^0.77.0",
154
156
  dotenv: "^17.2.2",
155
157
  tsdown: "^0.16.5",
156
- zod: "^4.1.11",
158
+ zod: "^4.1.13",
157
159
  srvx: "0.8.15",
158
160
  "@polar-sh/better-auth": "^1.1.3",
159
161
  "@polar-sh/sdk": "^0.34.16"
@@ -184,121 +186,6 @@ const ADDON_COMPATIBILITY = {
184
186
  none: []
185
187
  };
186
188
 
187
- //#endregion
188
- //#region src/types.ts
189
- const DatabaseSchema = z.enum([
190
- "none",
191
- "sqlite",
192
- "postgres",
193
- "mysql",
194
- "mongodb"
195
- ]).describe("Database type");
196
- const ORMSchema = z.enum([
197
- "drizzle",
198
- "prisma",
199
- "mongoose",
200
- "none"
201
- ]).describe("ORM type");
202
- const BackendSchema = z.enum([
203
- "hono",
204
- "express",
205
- "fastify",
206
- "elysia",
207
- "convex",
208
- "self",
209
- "none"
210
- ]).describe("Backend framework");
211
- const RuntimeSchema = z.enum([
212
- "bun",
213
- "node",
214
- "workers",
215
- "none"
216
- ]).describe("Runtime environment");
217
- const FrontendSchema = z.enum([
218
- "tanstack-router",
219
- "react-router",
220
- "tanstack-start",
221
- "next",
222
- "nuxt",
223
- "native-bare",
224
- "native-uniwind",
225
- "native-unistyles",
226
- "svelte",
227
- "solid",
228
- "none"
229
- ]).describe("Frontend framework");
230
- const AddonsSchema = z.enum([
231
- "pwa",
232
- "tauri",
233
- "starlight",
234
- "biome",
235
- "husky",
236
- "ruler",
237
- "turborepo",
238
- "fumadocs",
239
- "ultracite",
240
- "oxlint",
241
- "none"
242
- ]).describe("Additional addons");
243
- const ExamplesSchema = z.enum([
244
- "todo",
245
- "ai",
246
- "none"
247
- ]).describe("Example templates to include");
248
- const PackageManagerSchema = z.enum([
249
- "npm",
250
- "pnpm",
251
- "bun"
252
- ]).describe("Package manager");
253
- const DatabaseSetupSchema = z.enum([
254
- "turso",
255
- "neon",
256
- "prisma-postgres",
257
- "planetscale",
258
- "mongodb-atlas",
259
- "supabase",
260
- "d1",
261
- "docker",
262
- "none"
263
- ]).describe("Database hosting setup");
264
- const APISchema = z.enum([
265
- "trpc",
266
- "orpc",
267
- "none"
268
- ]).describe("API type");
269
- const AuthSchema = z.enum([
270
- "better-auth",
271
- "clerk",
272
- "none"
273
- ]).describe("Authentication provider");
274
- const PaymentsSchema = z.enum(["polar", "none"]).describe("Payments provider");
275
- const ProjectNameSchema = z.string().min(1, "Project name cannot be empty").max(255, "Project name must be less than 255 characters").refine((name) => name === "." || !name.startsWith("."), "Project name cannot start with a dot (except for '.')").refine((name) => name === "." || !name.startsWith("-"), "Project name cannot start with a dash").refine((name) => {
276
- return ![
277
- "<",
278
- ">",
279
- ":",
280
- "\"",
281
- "|",
282
- "?",
283
- "*"
284
- ].some((char) => name.includes(char));
285
- }, "Project name contains invalid characters").refine((name) => name.toLowerCase() !== "node_modules", "Project name is reserved").describe("Project name or path");
286
- const WebDeploySchema = z.enum(["alchemy", "none"]).describe("Web deployment");
287
- const ServerDeploySchema = z.enum(["alchemy", "none"]).describe("Server deployment");
288
- const DirectoryConflictSchema = z.enum([
289
- "merge",
290
- "overwrite",
291
- "increment",
292
- "error"
293
- ]).describe("How to handle existing directory conflicts");
294
- const TemplateSchema = z.enum([
295
- "mern",
296
- "pern",
297
- "t3",
298
- "uniwind",
299
- "none"
300
- ]).describe("Predefined project template");
301
-
302
189
  //#endregion
303
190
  //#region src/utils/compatibility.ts
304
191
  const WEB_FRAMEWORKS = [
@@ -1045,7 +932,7 @@ async function getORMChoice(orm, hasDatabase, database, backend, runtime) {
1045
932
  if (orm !== void 0) return orm;
1046
933
  const response = await select({
1047
934
  message: "Select ORM",
1048
- options: [...database === "mongodb" ? [ormOptions.prisma, ormOptions.mongoose] : [ormOptions.drizzle, ormOptions.prisma]],
935
+ options: database === "mongodb" ? [ormOptions.prisma, ormOptions.mongoose] : [ormOptions.drizzle, ormOptions.prisma],
1049
936
  initialValue: database === "mongodb" ? "prisma" : runtime === "workers" ? "drizzle" : DEFAULT_CONFIG.orm
1050
937
  });
1051
938
  if (isCancel(response)) return exitCancelled("Operation cancelled");
@@ -1165,7 +1052,6 @@ async function getServerDeploymentToAdd(runtime, existingDeployment, backend) {
1165
1052
  }
1166
1053
  }
1167
1054
  if (existingDeployment && existingDeployment !== "none") return "none";
1168
- if (options.length > 0) {}
1169
1055
  if (options.length === 0) return "none";
1170
1056
  const response = await select({
1171
1057
  message: "Select server deployment",
@@ -1347,7 +1233,7 @@ const getLatestCLIVersion = () => {
1347
1233
  */
1348
1234
  function isTelemetryEnabled() {
1349
1235
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
1350
- const BTS_TELEMETRY = "1";
1236
+ const BTS_TELEMETRY = "0";
1351
1237
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
1352
1238
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
1353
1239
  return true;
@@ -1363,20 +1249,19 @@ async function sendConvexEvent(payload) {
1363
1249
  headers: { "Content-Type": "application/json" },
1364
1250
  body: JSON.stringify(payload)
1365
1251
  });
1366
- } catch (_error) {}
1252
+ } catch {}
1367
1253
  }
1368
1254
  async function trackProjectCreation(config, disableAnalytics = false) {
1369
1255
  if (!isTelemetryEnabled() || disableAnalytics) return;
1370
- const { projectName, projectDir, relativePath,...safeConfig } = config;
1256
+ const { projectName: _projectName, projectDir: _projectDir, relativePath: _relativePath,...safeConfig } = config;
1371
1257
  try {
1372
1258
  await sendConvexEvent({
1373
- event: "project_created",
1374
1259
  ...safeConfig,
1375
1260
  cli_version: getLatestCLIVersion(),
1376
1261
  node_version: typeof process !== "undefined" ? process.version : "",
1377
1262
  platform: typeof process !== "undefined" ? process.platform : ""
1378
1263
  });
1379
- } catch (_error) {}
1264
+ } catch {}
1380
1265
  }
1381
1266
 
1382
1267
  //#endregion
@@ -1980,6 +1865,7 @@ async function writeBtsConfig(projectConfig) {
1980
1865
  addons: btsConfig.addons,
1981
1866
  examples: btsConfig.examples,
1982
1867
  auth: btsConfig.auth,
1868
+ payments: btsConfig.payments,
1983
1869
  packageManager: btsConfig.packageManager,
1984
1870
  dbSetup: btsConfig.dbSetup,
1985
1871
  api: btsConfig.api,
@@ -2015,7 +1901,7 @@ async function readBtsConfig(projectDir) {
2015
1901
  return null;
2016
1902
  }
2017
1903
  return config;
2018
- } catch (_error) {
1904
+ } catch {
2019
1905
  return null;
2020
1906
  }
2021
1907
  }
@@ -2033,7 +1919,7 @@ async function updateBtsConfig(projectDir, updates) {
2033
1919
  modifiedContent = JSONC.applyEdits(modifiedContent, editResult);
2034
1920
  }
2035
1921
  await fs.writeFile(configPath, modifiedContent, "utf-8");
2036
- } catch (_error) {}
1922
+ } catch {}
2037
1923
  }
2038
1924
 
2039
1925
  //#endregion
@@ -2212,7 +2098,7 @@ async function setupRuler(config) {
2212
2098
  shell: true
2213
2099
  });
2214
2100
  s.stop("Applied rules with Ruler");
2215
- } catch (_error) {
2101
+ } catch {
2216
2102
  s.stop(pc.red("Failed to apply rules"));
2217
2103
  }
2218
2104
  } catch (error) {
@@ -2636,14 +2522,14 @@ async function detectProjectConfig(projectDir) {
2636
2522
  serverDeploy: btsConfig.serverDeploy
2637
2523
  };
2638
2524
  return null;
2639
- } catch (_error) {
2525
+ } catch {
2640
2526
  return null;
2641
2527
  }
2642
2528
  }
2643
2529
  async function isBetterTStackProject(projectDir) {
2644
2530
  try {
2645
2531
  return await fs.pathExists(path.join(projectDir, "bts.jsonc"));
2646
- } catch (_error) {
2532
+ } catch {
2647
2533
  return false;
2648
2534
  }
2649
2535
  }
@@ -2686,7 +2572,7 @@ function initializeBiome() {
2686
2572
  biome,
2687
2573
  projectKey
2688
2574
  };
2689
- } catch (_error) {
2575
+ } catch {
2690
2576
  return null;
2691
2577
  }
2692
2578
  }
@@ -2721,7 +2607,7 @@ function formatFileWithBiome(filePath, content) {
2721
2607
  const result = biome.formatContent(projectKey, content, { filePath: path.basename(filePath) });
2722
2608
  if (result.diagnostics && result.diagnostics.length > 0) consola.debug(`Biome formatting diagnostics for ${filePath}:`, result.diagnostics);
2723
2609
  return result.content;
2724
- } catch (_error) {
2610
+ } catch {
2725
2611
  return null;
2726
2612
  }
2727
2613
  }
@@ -3864,6 +3750,7 @@ async function addDeploymentToProject(input) {
3864
3750
  async function setupCatalogs(projectDir, options) {
3865
3751
  if (options.packageManager === "npm") return;
3866
3752
  const packagePaths = [
3753
+ ".",
3867
3754
  "apps/server",
3868
3755
  "apps/web",
3869
3756
  "apps/native",
@@ -3872,7 +3759,8 @@ async function setupCatalogs(projectDir, options) {
3872
3759
  "packages/api",
3873
3760
  "packages/db",
3874
3761
  "packages/auth",
3875
- "packages/backend"
3762
+ "packages/backend",
3763
+ "packages/config"
3876
3764
  ];
3877
3765
  const packagesInfo = [];
3878
3766
  for (const pkgPath of packagePaths) {
@@ -3971,15 +3859,18 @@ async function updatePackageJsonsWithCatalogs(packagesInfo, catalog) {
3971
3859
  //#endregion
3972
3860
  //#region src/helpers/addons/examples-setup.ts
3973
3861
  async function setupExamples(config) {
3974
- const { examples, frontend, backend, projectDir, orm } = config;
3862
+ const { examples, frontend, backend, projectDir, orm, database } = config;
3975
3863
  if (backend === "convex" || !examples || examples.length === 0 || examples[0] === "none") return;
3976
3864
  const apiDir = path.join(projectDir, "packages/api");
3977
3865
  if (await fs.pathExists(apiDir) && backend !== "none") {
3978
- if (orm === "drizzle") await addPackageDependency({
3979
- dependencies: ["drizzle-orm"],
3980
- projectDir: apiDir
3981
- });
3982
- else if (orm === "prisma") await addPackageDependency({
3866
+ if (orm === "drizzle") {
3867
+ const dependencies = ["drizzle-orm"];
3868
+ if (database === "postgres") dependencies.push("@types/pg");
3869
+ await addPackageDependency({
3870
+ dependencies,
3871
+ projectDir: apiDir
3872
+ });
3873
+ } else if (orm === "prisma") await addPackageDependency({
3983
3874
  dependencies: ["@prisma/client"],
3984
3875
  projectDir: apiDir
3985
3876
  });
@@ -4028,15 +3919,6 @@ async function setupExamples(config) {
4028
3919
 
4029
3920
  //#endregion
4030
3921
  //#region src/helpers/core/api-setup.ts
4031
- async function addBackendWorkspaceDependency(projectDir, backendPackageName, workspaceVersion) {
4032
- const pkgJsonPath = path.join(projectDir, "package.json");
4033
- try {
4034
- const pkgJson = await fs.readJson(pkgJsonPath);
4035
- if (!pkgJson.dependencies) pkgJson.dependencies = {};
4036
- pkgJson.dependencies[backendPackageName] = workspaceVersion;
4037
- await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
4038
- } catch (_error) {}
4039
- }
4040
3922
  function getFrontendType(frontend) {
4041
3923
  const reactBasedFrontends = [
4042
3924
  "tanstack-router",
@@ -4154,7 +4036,7 @@ function getConvexDependencies(frontend) {
4154
4036
  return deps;
4155
4037
  }
4156
4038
  async function setupApi(config) {
4157
- const { api, projectName, frontend, backend, packageManager, projectDir } = config;
4039
+ const { api, frontend, backend, projectDir } = config;
4158
4040
  const isConvex = backend === "convex";
4159
4041
  const webDir = path.join(projectDir, "apps/web");
4160
4042
  const nativeDir = path.join(projectDir, "apps/native");
@@ -4224,10 +4106,6 @@ async function setupApi(config) {
4224
4106
  dependencies: convexDeps.native.dependencies,
4225
4107
  projectDir: nativeDir
4226
4108
  });
4227
- const backendPackageName = `@${projectName}/backend`;
4228
- const backendWorkspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
4229
- if (webDirExists) await addBackendWorkspaceDependency(webDir, backendPackageName, backendWorkspaceVersion);
4230
- if (nativeDirExists) await addBackendWorkspaceDependency(nativeDir, backendPackageName, backendWorkspaceVersion);
4231
4109
  }
4232
4110
  }
4233
4111
 
@@ -4754,15 +4632,11 @@ async function setupCloudflareD1(config) {
4754
4632
  const { projectDir, serverDeploy, orm, backend } = config;
4755
4633
  if (serverDeploy === "alchemy" && orm === "prisma") {
4756
4634
  const targetApp2 = backend === "self" ? "apps/web" : "apps/server";
4757
- const envPath = path.join(projectDir, targetApp2, ".env");
4758
- const variables = [{
4635
+ await addEnvVariablesToFile(path.join(projectDir, targetApp2, ".env"), [{
4759
4636
  key: "DATABASE_URL",
4760
4637
  value: `file:${path.join(projectDir, "apps/server", "local.db")}`,
4761
4638
  condition: true
4762
- }];
4763
- try {
4764
- await addEnvVariablesToFile(envPath, variables);
4765
- } catch (_err) {}
4639
+ }]);
4766
4640
  await addPackageDependency({
4767
4641
  dependencies: ["@prisma/adapter-d1"],
4768
4642
  projectDir: path.join(projectDir, backend === "self" ? "apps/web" : "apps/server")
@@ -4817,7 +4691,7 @@ async function checkAtlasCLI() {
4817
4691
  if (exists) log.info("MongoDB Atlas CLI found");
4818
4692
  else log.warn(pc.yellow("MongoDB Atlas CLI not found"));
4819
4693
  return exists;
4820
- } catch (_error) {
4694
+ } catch {
4821
4695
  log.error(pc.red("Error checking MongoDB Atlas CLI"));
4822
4696
  return false;
4823
4697
  }
@@ -4862,7 +4736,7 @@ async function writeEnvFile$3(projectDir, backend, config) {
4862
4736
  value: config?.connectionString ?? "mongodb://localhost:27017/mydb",
4863
4737
  condition: true
4864
4738
  }]);
4865
- } catch (_error) {
4739
+ } catch {
4866
4740
  consola.error("Failed to update environment configuration");
4867
4741
  }
4868
4742
  }
@@ -4999,7 +4873,7 @@ async function createNeonProject(projectName, regionId, packageManager) {
4999
4873
  }
5000
4874
  consola$1.error(pc.red("Failed to extract connection information from response"));
5001
4875
  return null;
5002
- } catch (_error) {
4876
+ } catch {
5003
4877
  consola$1.error(pc.red("Failed to create Neon project"));
5004
4878
  }
5005
4879
  }
@@ -5247,7 +5121,7 @@ async function writeEnvFile$1(projectDir, backend, config) {
5247
5121
  condition: true
5248
5122
  });
5249
5123
  await addEnvVariablesToFile(envPath, variables);
5250
- } catch (_error) {
5124
+ } catch {
5251
5125
  consola$1.error("Failed to update environment configuration");
5252
5126
  }
5253
5127
  }
@@ -5474,7 +5348,7 @@ async function loginToTurso() {
5474
5348
  await $`turso auth login`;
5475
5349
  s.stop("Logged into Turso");
5476
5350
  return true;
5477
- } catch (_error) {
5351
+ } catch {
5478
5352
  s.stop(pc.red("Failed to log in to Turso"));
5479
5353
  }
5480
5354
  }
@@ -5562,7 +5436,7 @@ async function createTursoDatabase(dbName, groupName) {
5562
5436
  dbUrl: dbUrl.trim(),
5563
5437
  authToken: authToken.trim()
5564
5438
  };
5565
- } catch (_error) {
5439
+ } catch {
5566
5440
  s.stop(pc.red("Failed to retrieve database connection details"));
5567
5441
  }
5568
5442
  }
@@ -5688,7 +5562,6 @@ async function setupDatabase(config, cliInput) {
5688
5562
  }
5689
5563
  return;
5690
5564
  }
5691
- const s = spinner();
5692
5565
  const dbPackageDir = path.join(projectDir, "packages/db");
5693
5566
  const webDir = path.join(projectDir, "apps/web");
5694
5567
  const webDirExists = await fs.pathExists(webDir);
@@ -5791,7 +5664,6 @@ async function setupDatabase(config, cliInput) {
5791
5664
  if (dbSetup === "planetscale") await setupPlanetScale(config);
5792
5665
  } else if (database === "mongodb" && dbSetup === "mongodb-atlas") await setupMongoDBAtlas(config, cliInput);
5793
5666
  } catch (error) {
5794
- s.stop(pc.red("Failed to set up database"));
5795
5667
  if (error instanceof Error) consola.error(pc.red(error.message));
5796
5668
  }
5797
5669
  }
@@ -6438,93 +6310,113 @@ function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend)
6438
6310
  //#endregion
6439
6311
  //#region src/helpers/core/workspace-setup.ts
6440
6312
  async function setupWorkspaceDependencies(projectDir, options) {
6441
- const projectName = options.projectName;
6442
- const workspaceVersion = options.packageManager === "npm" ? "*" : "workspace:*";
6313
+ const { projectName, packageManager, database, auth, api, runtime, backend } = options;
6314
+ const workspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
6443
6315
  const commonDeps = ["dotenv", "zod"];
6444
- const commonDevDeps = [];
6445
- const configPackageDir = path.join(projectDir, "packages/config");
6446
- const configDep = {};
6447
- if (await fs.pathExists(configPackageDir)) configDep[`@${projectName}/config`] = workspaceVersion;
6448
- const dbPackageDir = path.join(projectDir, "packages/db");
6449
- if (await fs.pathExists(dbPackageDir)) await addPackageDependency({
6316
+ const commonDevDeps = ["typescript"];
6317
+ const configDir = path.join(projectDir, "packages/config");
6318
+ const dbDir = path.join(projectDir, "packages/db");
6319
+ const authDir = path.join(projectDir, "packages/auth");
6320
+ const apiDir = path.join(projectDir, "packages/api");
6321
+ const backendDir = path.join(projectDir, "packages/backend");
6322
+ const serverDir = path.join(projectDir, "apps/server");
6323
+ const webDir = path.join(projectDir, "apps/web");
6324
+ const nativeDir = path.join(projectDir, "apps/native");
6325
+ const [configExists, dbExists, authExists, apiExists, backendExists, serverExists, webExists, nativeExists] = await Promise.all([
6326
+ fs.pathExists(configDir),
6327
+ fs.pathExists(dbDir),
6328
+ fs.pathExists(authDir),
6329
+ fs.pathExists(apiDir),
6330
+ fs.pathExists(backendDir),
6331
+ fs.pathExists(serverDir),
6332
+ fs.pathExists(webDir),
6333
+ fs.pathExists(nativeDir)
6334
+ ]);
6335
+ const configDep = configExists ? { [`@${projectName}/config`]: workspaceVersion } : {};
6336
+ if (dbExists) await addPackageDependency({
6450
6337
  dependencies: commonDeps,
6451
6338
  devDependencies: commonDevDeps,
6452
6339
  customDevDependencies: configDep,
6453
- projectDir: dbPackageDir
6340
+ projectDir: dbDir
6454
6341
  });
6455
- const authPackageDir = path.join(projectDir, "packages/auth");
6456
- if (await fs.pathExists(authPackageDir)) {
6342
+ if (authExists) {
6457
6343
  const authDeps = {};
6458
- if (options.database !== "none" && await fs.pathExists(dbPackageDir)) authDeps[`@${projectName}/db`] = workspaceVersion;
6344
+ if (database !== "none" && dbExists) authDeps[`@${projectName}/db`] = workspaceVersion;
6459
6345
  await addPackageDependency({
6460
6346
  dependencies: commonDeps,
6461
6347
  devDependencies: commonDevDeps,
6462
6348
  customDependencies: authDeps,
6463
6349
  customDevDependencies: configDep,
6464
- projectDir: authPackageDir
6350
+ projectDir: authDir
6465
6351
  });
6466
6352
  }
6467
- const apiPackageDir = path.join(projectDir, "packages/api");
6468
- if (await fs.pathExists(apiPackageDir)) {
6353
+ if (apiExists) {
6469
6354
  const apiDeps = {};
6470
- if (options.auth !== "none" && await fs.pathExists(authPackageDir)) apiDeps[`@${projectName}/auth`] = workspaceVersion;
6471
- if (options.database !== "none" && await fs.pathExists(dbPackageDir)) apiDeps[`@${projectName}/db`] = workspaceVersion;
6355
+ if (auth !== "none" && authExists) apiDeps[`@${projectName}/auth`] = workspaceVersion;
6356
+ if (database !== "none" && dbExists) apiDeps[`@${projectName}/db`] = workspaceVersion;
6472
6357
  await addPackageDependency({
6473
6358
  dependencies: commonDeps,
6474
6359
  devDependencies: commonDevDeps,
6475
6360
  customDependencies: apiDeps,
6476
6361
  customDevDependencies: configDep,
6477
- projectDir: apiPackageDir
6362
+ projectDir: apiDir
6478
6363
  });
6479
6364
  }
6480
- const serverPackageDir = path.join(projectDir, "apps/server");
6481
- if (await fs.pathExists(serverPackageDir)) {
6365
+ if (backendExists) await addPackageDependency({
6366
+ dependencies: commonDeps,
6367
+ devDependencies: commonDevDeps,
6368
+ customDevDependencies: configDep,
6369
+ projectDir: backendDir
6370
+ });
6371
+ if (serverExists) {
6482
6372
  const serverDeps = {};
6483
- if (options.api !== "none" && await fs.pathExists(apiPackageDir)) serverDeps[`@${projectName}/api`] = workspaceVersion;
6484
- if (options.auth !== "none" && await fs.pathExists(authPackageDir)) serverDeps[`@${projectName}/auth`] = workspaceVersion;
6485
- if (options.database !== "none" && await fs.pathExists(dbPackageDir)) serverDeps[`@${projectName}/db`] = workspaceVersion;
6373
+ if (api !== "none" && apiExists) serverDeps[`@${projectName}/api`] = workspaceVersion;
6374
+ if (auth !== "none" && authExists) serverDeps[`@${projectName}/auth`] = workspaceVersion;
6375
+ if (database !== "none" && dbExists) serverDeps[`@${projectName}/db`] = workspaceVersion;
6486
6376
  await addPackageDependency({
6487
6377
  dependencies: commonDeps,
6488
6378
  devDependencies: [...commonDevDeps, "tsdown"],
6489
6379
  customDependencies: serverDeps,
6490
6380
  customDevDependencies: configDep,
6491
- projectDir: serverPackageDir
6381
+ projectDir: serverDir
6492
6382
  });
6493
6383
  }
6494
- const webPackageDir = path.join(projectDir, "apps/web");
6495
- if (await fs.pathExists(webPackageDir)) {
6384
+ if (webExists) {
6496
6385
  const webDeps = {};
6497
- if (options.api !== "none" && await fs.pathExists(apiPackageDir)) webDeps[`@${projectName}/api`] = workspaceVersion;
6498
- if (options.auth !== "none" && await fs.pathExists(authPackageDir)) webDeps[`@${projectName}/auth`] = workspaceVersion;
6499
- if (Object.keys(webDeps).length > 0) await addPackageDependency({
6386
+ if (api !== "none" && apiExists) webDeps[`@${projectName}/api`] = workspaceVersion;
6387
+ if (auth !== "none" && authExists) webDeps[`@${projectName}/auth`] = workspaceVersion;
6388
+ if (backend === "convex" && backendExists) webDeps[`@${projectName}/backend`] = workspaceVersion;
6389
+ await addPackageDependency({
6390
+ dependencies: commonDeps,
6391
+ devDependencies: commonDevDeps,
6500
6392
  customDependencies: webDeps,
6501
6393
  customDevDependencies: configDep,
6502
- projectDir: webPackageDir
6394
+ projectDir: webDir
6503
6395
  });
6504
6396
  }
6505
- const nativePackageDir = path.join(projectDir, "apps/native");
6506
- if (await fs.pathExists(nativePackageDir)) {
6397
+ if (nativeExists) {
6507
6398
  const nativeDeps = {};
6508
- if (options.api !== "none" && await fs.pathExists(apiPackageDir)) nativeDeps[`@${projectName}/api`] = workspaceVersion;
6509
- if (Object.keys(nativeDeps).length > 0) await addPackageDependency({
6399
+ if (api !== "none" && apiExists) nativeDeps[`@${projectName}/api`] = workspaceVersion;
6400
+ if (backend === "convex" && backendExists) nativeDeps[`@${projectName}/backend`] = workspaceVersion;
6401
+ await addPackageDependency({
6402
+ dependencies: commonDeps,
6403
+ devDependencies: commonDevDeps,
6510
6404
  customDependencies: nativeDeps,
6511
6405
  customDevDependencies: configDep,
6512
- projectDir: nativePackageDir
6406
+ projectDir: nativeDir
6513
6407
  });
6514
6408
  }
6515
- const runtimeDevDeps = getRuntimeDevDeps(options);
6409
+ const runtimeDevDeps = getRuntimeDevDeps(runtime, backend);
6516
6410
  await addPackageDependency({
6517
6411
  dependencies: commonDeps,
6518
6412
  devDependencies: [...commonDevDeps, ...runtimeDevDeps],
6519
6413
  projectDir
6520
6414
  });
6521
6415
  }
6522
- function getRuntimeDevDeps(options) {
6523
- const { runtime, backend } = options;
6416
+ function getRuntimeDevDeps(runtime, backend) {
6524
6417
  if (runtime === "none" && backend === "self") return ["@types/node"];
6525
- if (runtime === "node") return ["@types/node"];
6418
+ if (runtime === "node" || runtime === "workers") return ["@types/node"];
6526
6419
  if (runtime === "bun") return ["@types/bun"];
6527
- if (runtime === "workers") return ["@types/node"];
6528
6420
  return [];
6529
6421
  }
6530
6422
 
@@ -6533,185 +6425,130 @@ function getRuntimeDevDeps(options) {
6533
6425
  async function updatePackageConfigurations(projectDir, options) {
6534
6426
  await updateRootPackageJson(projectDir, options);
6535
6427
  if (options.backend === "convex") await updateConvexPackageJson(projectDir, options);
6536
- else if (options.backend === "self") {
6428
+ else if (options.backend !== "none") {
6537
6429
  await updateDbPackageJson(projectDir, options);
6538
6430
  await updateAuthPackageJson(projectDir, options);
6539
6431
  await updateApiPackageJson(projectDir, options);
6540
- await setupWorkspaceDependencies(projectDir, options);
6541
- } else if (options.backend !== "none") {
6542
- await updateServerPackageJson(projectDir, options);
6543
- await updateAuthPackageJson(projectDir, options);
6544
- await updateApiPackageJson(projectDir, options);
6545
- await setupWorkspaceDependencies(projectDir, options);
6432
+ if (options.backend !== "self") await updateServerPackageJson(projectDir, options);
6546
6433
  }
6434
+ await setupWorkspaceDependencies(projectDir, options);
6547
6435
  }
6548
6436
  async function updateRootPackageJson(projectDir, options) {
6549
6437
  const rootPackageJsonPath = path.join(projectDir, "package.json");
6550
6438
  if (!await fs.pathExists(rootPackageJsonPath)) return;
6551
6439
  const packageJson = await fs.readJson(rootPackageJsonPath);
6552
6440
  packageJson.name = options.projectName;
6553
- if (!packageJson.scripts) packageJson.scripts = {};
6441
+ packageJson.scripts = packageJson.scripts || {};
6442
+ packageJson.workspaces = packageJson.workspaces || [];
6554
6443
  const scripts = packageJson.scripts;
6555
- const backendPackageName = options.backend === "convex" ? `@${options.projectName}/backend` : "server";
6556
- const dbPackageName = `@${options.projectName}/db`;
6557
- let serverDevScript = "";
6558
- if (options.addons.includes("turborepo")) serverDevScript = `turbo -F ${backendPackageName} dev`;
6559
- else if (options.packageManager === "bun") serverDevScript = `bun run --filter ${backendPackageName} dev`;
6560
- else if (options.packageManager === "pnpm") serverDevScript = `pnpm --filter ${backendPackageName} dev`;
6561
- else if (options.packageManager === "npm") serverDevScript = `npm run dev --workspace ${backendPackageName}`;
6562
- let devScript = "";
6563
- if (options.packageManager === "pnpm") devScript = "pnpm -r dev";
6564
- else if (options.packageManager === "npm") devScript = "npm run dev --workspaces";
6565
- else if (options.packageManager === "bun") devScript = "bun run --filter '*' dev";
6566
- const needsDbScripts = options.backend !== "convex" && options.database !== "none" && options.orm !== "none" && options.orm !== "mongoose";
6567
- if (options.addons.includes("turborepo")) {
6568
- scripts.dev = "turbo dev";
6569
- scripts.build = "turbo build";
6570
- scripts["check-types"] = "turbo check-types";
6571
- scripts["dev:native"] = "turbo -F native dev";
6572
- scripts["dev:web"] = "turbo -F web dev";
6573
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6574
- if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`;
6575
- if (needsDbScripts) {
6576
- scripts["db:push"] = `turbo -F ${dbPackageName} db:push`;
6577
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `turbo -F ${dbPackageName} db:studio`;
6578
- if (options.orm === "prisma") {
6579
- scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
6580
- scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
6581
- } else if (options.orm === "drizzle") {
6582
- scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
6583
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
6584
- }
6585
- }
6586
- if (options.dbSetup === "docker") {
6587
- scripts["db:start"] = `turbo -F ${dbPackageName} db:start`;
6588
- scripts["db:watch"] = `turbo -F ${dbPackageName} db:watch`;
6589
- scripts["db:stop"] = `turbo -F ${dbPackageName} db:stop`;
6590
- scripts["db:down"] = `turbo -F ${dbPackageName} db:down`;
6591
- }
6592
- } else if (options.packageManager === "pnpm") {
6593
- scripts.dev = devScript;
6594
- scripts.build = "pnpm -r build";
6595
- scripts["check-types"] = "pnpm -r check-types";
6596
- scripts["dev:native"] = "pnpm --filter native dev";
6597
- scripts["dev:web"] = "pnpm --filter web dev";
6598
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6599
- if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`;
6600
- if (needsDbScripts) {
6601
- scripts["db:push"] = `pnpm --filter ${dbPackageName} db:push`;
6602
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `pnpm --filter ${dbPackageName} db:studio`;
6603
- if (options.orm === "prisma") {
6604
- scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
6605
- scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
6606
- } else if (options.orm === "drizzle") {
6607
- scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
6608
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
6609
- }
6610
- }
6611
- if (options.dbSetup === "docker") {
6612
- scripts["db:start"] = `pnpm --filter ${dbPackageName} db:start`;
6613
- scripts["db:watch"] = `pnpm --filter ${dbPackageName} db:watch`;
6614
- scripts["db:stop"] = `pnpm --filter ${dbPackageName} db:stop`;
6615
- scripts["db:down"] = `pnpm --filter ${dbPackageName} db:down`;
6616
- }
6617
- } else if (options.packageManager === "npm") {
6618
- scripts.dev = devScript;
6619
- scripts.build = "npm run build --workspaces";
6620
- scripts["check-types"] = "npm run check-types --workspaces";
6621
- scripts["dev:native"] = "npm run dev --workspace native";
6622
- scripts["dev:web"] = "npm run dev --workspace web";
6623
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6624
- if (options.backend === "convex") scripts["dev:setup"] = `npm run dev:setup --workspace ${backendPackageName}`;
6625
- if (needsDbScripts) {
6626
- scripts["db:push"] = `npm run db:push --workspace ${dbPackageName}`;
6627
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `npm run db:studio --workspace ${dbPackageName}`;
6628
- if (options.orm === "prisma") {
6629
- scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
6630
- scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
6631
- } else if (options.orm === "drizzle") {
6632
- scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
6633
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
6634
- }
6635
- }
6636
- if (options.dbSetup === "docker") {
6637
- scripts["db:start"] = `npm run db:start --workspace ${dbPackageName}`;
6638
- scripts["db:watch"] = `npm run db:watch --workspace ${dbPackageName}`;
6639
- scripts["db:stop"] = `npm run db:stop --workspace ${dbPackageName}`;
6640
- scripts["db:down"] = `npm run db:down --workspace ${dbPackageName}`;
6641
- }
6642
- } else if (options.packageManager === "bun") {
6643
- scripts.dev = devScript;
6644
- scripts.build = "bun run --filter '*' build";
6645
- scripts["check-types"] = "bun run --filter '*' check-types";
6646
- scripts["dev:native"] = "bun run --filter native dev";
6647
- scripts["dev:web"] = "bun run --filter web dev";
6648
- if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6649
- if (options.backend === "convex") scripts["dev:setup"] = `bun run --filter ${backendPackageName} dev:setup`;
6650
- if (needsDbScripts) {
6651
- scripts["db:push"] = `bun run --filter ${dbPackageName} db:push`;
6652
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `bun run --filter ${dbPackageName} db:studio`;
6653
- if (options.orm === "prisma") {
6654
- scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
6655
- scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
6656
- } else if (options.orm === "drizzle") {
6657
- scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
6658
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
6659
- }
6660
- }
6661
- if (options.dbSetup === "docker") {
6662
- scripts["db:start"] = `bun run --filter ${dbPackageName} db:start`;
6663
- scripts["db:watch"] = `bun run --filter ${dbPackageName} db:watch`;
6664
- scripts["db:stop"] = `bun run --filter ${dbPackageName} db:stop`;
6665
- scripts["db:down"] = `bun run --filter ${dbPackageName} db:down`;
6444
+ const workspaces = packageJson.workspaces;
6445
+ const { projectName, packageManager, backend, database, orm, dbSetup, serverDeploy, addons } = options;
6446
+ const backendPackageName = backend === "convex" ? `@${projectName}/backend` : "server";
6447
+ const dbPackageName = `@${projectName}/db`;
6448
+ const hasTurborepo = addons.includes("turborepo");
6449
+ const needsDbScripts = backend !== "convex" && database !== "none" && orm !== "none" && orm !== "mongoose";
6450
+ const isD1Alchemy = dbSetup === "d1" && serverDeploy === "alchemy";
6451
+ const pmConfig = getPackageManagerConfig(packageManager, hasTurborepo);
6452
+ scripts.dev = pmConfig.dev;
6453
+ scripts.build = pmConfig.build;
6454
+ scripts["check-types"] = pmConfig.checkTypes;
6455
+ scripts["dev:native"] = pmConfig.filter("native", "dev");
6456
+ scripts["dev:web"] = pmConfig.filter("web", "dev");
6457
+ if (backend !== "self" && backend !== "none") scripts["dev:server"] = pmConfig.filter(backendPackageName, "dev");
6458
+ if (backend === "convex") scripts["dev:setup"] = pmConfig.filter(backendPackageName, "dev:setup");
6459
+ if (needsDbScripts) {
6460
+ scripts["db:push"] = pmConfig.filter(dbPackageName, "db:push");
6461
+ if (!isD1Alchemy) scripts["db:studio"] = pmConfig.filter(dbPackageName, "db:studio");
6462
+ if (orm === "prisma") {
6463
+ scripts["db:generate"] = pmConfig.filter(dbPackageName, "db:generate");
6464
+ scripts["db:migrate"] = pmConfig.filter(dbPackageName, "db:migrate");
6465
+ } else if (orm === "drizzle") {
6466
+ scripts["db:generate"] = pmConfig.filter(dbPackageName, "db:generate");
6467
+ if (!isD1Alchemy) scripts["db:migrate"] = pmConfig.filter(dbPackageName, "db:migrate");
6666
6468
  }
6667
6469
  }
6470
+ if (dbSetup === "docker") {
6471
+ scripts["db:start"] = pmConfig.filter(dbPackageName, "db:start");
6472
+ scripts["db:watch"] = pmConfig.filter(dbPackageName, "db:watch");
6473
+ scripts["db:stop"] = pmConfig.filter(dbPackageName, "db:stop");
6474
+ scripts["db:down"] = pmConfig.filter(dbPackageName, "db:down");
6475
+ }
6668
6476
  try {
6669
- const { stdout } = await execa(options.packageManager, ["-v"], { cwd: projectDir });
6670
- packageJson.packageManager = `${options.packageManager}@${stdout.trim()}`;
6671
- } catch (_e) {
6672
- log.warn(`Could not determine ${options.packageManager} version.`);
6477
+ const { stdout } = await execa(packageManager, ["-v"], { cwd: projectDir });
6478
+ packageJson.packageManager = `${packageManager}@${stdout.trim()}`;
6479
+ } catch {
6480
+ log.warn(`Could not determine ${packageManager} version.`);
6673
6481
  }
6674
- if (!packageJson.workspaces) packageJson.workspaces = [];
6675
- const workspaces = packageJson.workspaces;
6676
- if (options.backend === "convex") {
6482
+ if (backend === "convex") {
6677
6483
  if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
6678
- if ((options.frontend.length > 0 || options.addons.includes("starlight")) && !workspaces.includes("apps/*")) workspaces.push("apps/*");
6484
+ if ((options.frontend.length > 0 || addons.includes("starlight")) && !workspaces.includes("apps/*")) workspaces.push("apps/*");
6679
6485
  } else {
6680
6486
  if (!workspaces.includes("apps/*")) workspaces.push("apps/*");
6681
6487
  if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
6682
6488
  }
6683
6489
  await fs.writeJson(rootPackageJsonPath, packageJson, { spaces: 2 });
6684
6490
  }
6685
- async function updateServerPackageJson(projectDir, options) {
6491
+ function getPackageManagerConfig(packageManager, hasTurborepo) {
6492
+ if (hasTurborepo) return {
6493
+ dev: "turbo dev",
6494
+ build: "turbo build",
6495
+ checkTypes: "turbo check-types",
6496
+ filter: (workspace, script) => `turbo -F ${workspace} ${script}`
6497
+ };
6498
+ switch (packageManager) {
6499
+ case "pnpm": return {
6500
+ dev: "pnpm -r dev",
6501
+ build: "pnpm -r build",
6502
+ checkTypes: "pnpm -r check-types",
6503
+ filter: (workspace, script) => `pnpm --filter ${workspace} ${script}`
6504
+ };
6505
+ case "npm": return {
6506
+ dev: "npm run dev --workspaces",
6507
+ build: "npm run build --workspaces",
6508
+ checkTypes: "npm run check-types --workspaces",
6509
+ filter: (workspace, script) => `npm run ${script} --workspace ${workspace}`
6510
+ };
6511
+ case "bun": return {
6512
+ dev: "bun run --filter '*' dev",
6513
+ build: "bun run --filter '*' build",
6514
+ checkTypes: "bun run --filter '*' check-types",
6515
+ filter: (workspace, script) => `bun run --filter ${workspace} ${script}`
6516
+ };
6517
+ }
6518
+ }
6519
+ async function updateServerPackageJson(projectDir, _options) {
6686
6520
  const serverPackageJsonPath = path.join(projectDir, "apps/server/package.json");
6687
6521
  if (!await fs.pathExists(serverPackageJsonPath)) return;
6688
6522
  const serverPackageJson = await fs.readJson(serverPackageJsonPath);
6689
- if (!serverPackageJson.scripts) serverPackageJson.scripts = {};
6523
+ serverPackageJson.scripts = serverPackageJson.scripts || {};
6690
6524
  await fs.writeJson(serverPackageJsonPath, serverPackageJson, { spaces: 2 });
6691
- await updateDbPackageJson(projectDir, options);
6692
6525
  }
6693
6526
  async function updateDbPackageJson(projectDir, options) {
6694
6527
  const dbPackageJsonPath = path.join(projectDir, "packages/db/package.json");
6695
6528
  if (!await fs.pathExists(dbPackageJsonPath)) return;
6696
6529
  const dbPackageJson = await fs.readJson(dbPackageJsonPath);
6697
6530
  dbPackageJson.name = `@${options.projectName}/db`;
6698
- if (!dbPackageJson.scripts) dbPackageJson.scripts = {};
6531
+ dbPackageJson.scripts = dbPackageJson.scripts || {};
6699
6532
  const scripts = dbPackageJson.scripts;
6700
- if (options.database !== "none") {
6701
- if (options.database === "sqlite" && options.orm === "drizzle" && options.dbSetup !== "d1") scripts["db:local"] = "turso dev --db-file local.db";
6702
- if (options.orm === "prisma") {
6533
+ const { database, orm, dbSetup, serverDeploy } = options;
6534
+ const isD1Alchemy = dbSetup === "d1" && serverDeploy === "alchemy";
6535
+ if (database !== "none") {
6536
+ if (database === "sqlite" && orm === "drizzle" && dbSetup !== "d1") scripts["db:local"] = "turso dev --db-file local.db";
6537
+ if (orm === "prisma") {
6703
6538
  scripts["db:push"] = "prisma db push";
6704
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = "prisma studio";
6705
6539
  scripts["db:generate"] = "prisma generate";
6706
6540
  scripts["db:migrate"] = "prisma migrate dev";
6707
- } else if (options.orm === "drizzle") {
6541
+ if (!isD1Alchemy) scripts["db:studio"] = "prisma studio";
6542
+ } else if (orm === "drizzle") {
6708
6543
  scripts["db:push"] = "drizzle-kit push";
6709
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = "drizzle-kit studio";
6710
6544
  scripts["db:generate"] = "drizzle-kit generate";
6711
- if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = "drizzle-kit migrate";
6545
+ if (!isD1Alchemy) {
6546
+ scripts["db:studio"] = "drizzle-kit studio";
6547
+ scripts["db:migrate"] = "drizzle-kit migrate";
6548
+ }
6712
6549
  }
6713
6550
  }
6714
- if (options.dbSetup === "docker") {
6551
+ if (dbSetup === "docker") {
6715
6552
  scripts["db:start"] = "docker compose up -d";
6716
6553
  scripts["db:watch"] = "docker compose up";
6717
6554
  scripts["db:stop"] = "docker compose stop";
@@ -6738,7 +6575,7 @@ async function updateConvexPackageJson(projectDir, options) {
6738
6575
  if (!await fs.pathExists(convexPackageJsonPath)) return;
6739
6576
  const convexPackageJson = await fs.readJson(convexPackageJsonPath);
6740
6577
  convexPackageJson.name = `@${options.projectName}/backend`;
6741
- if (!convexPackageJson.scripts) convexPackageJson.scripts = {};
6578
+ convexPackageJson.scripts = convexPackageJson.scripts || {};
6742
6579
  await fs.writeJson(convexPackageJsonPath, convexPackageJson, { spaces: 2 });
6743
6580
  }
6744
6581
 
@@ -7101,21 +6938,21 @@ const router = os.router({
7101
6938
  description: "Create a new Better-T-Stack project",
7102
6939
  default: true,
7103
6940
  negateBooleans: true
7104
- }).input(z$1.tuple([ProjectNameSchema.optional(), z$1.object({
6941
+ }).input(z.tuple([ProjectNameSchema.optional(), z.object({
7105
6942
  template: TemplateSchema.optional().describe("Use a predefined template"),
7106
- yes: z$1.boolean().optional().default(false).describe("Use default configuration"),
7107
- yolo: z$1.boolean().optional().default(false).describe("(WARNING - NOT RECOMMENDED) Bypass validations and compatibility checks"),
7108
- verbose: z$1.boolean().optional().default(false).describe("Show detailed result information"),
6943
+ yes: z.boolean().optional().default(false).describe("Use default configuration"),
6944
+ yolo: z.boolean().optional().default(false).describe("(WARNING - NOT RECOMMENDED) Bypass validations and compatibility checks"),
6945
+ verbose: z.boolean().optional().default(false).describe("Show detailed result information"),
7109
6946
  database: DatabaseSchema.optional(),
7110
6947
  orm: ORMSchema.optional(),
7111
6948
  auth: AuthSchema.optional(),
7112
6949
  payments: PaymentsSchema.optional(),
7113
- frontend: z$1.array(FrontendSchema).optional(),
7114
- addons: z$1.array(AddonsSchema).optional(),
7115
- examples: z$1.array(ExamplesSchema).optional(),
7116
- git: z$1.boolean().optional(),
6950
+ frontend: z.array(FrontendSchema).optional(),
6951
+ addons: z.array(AddonsSchema).optional(),
6952
+ examples: z.array(ExamplesSchema).optional(),
6953
+ git: z.boolean().optional(),
7117
6954
  packageManager: PackageManagerSchema.optional(),
7118
- install: z$1.boolean().optional(),
6955
+ install: z.boolean().optional(),
7119
6956
  dbSetup: DatabaseSetupSchema.optional(),
7120
6957
  backend: BackendSchema.optional(),
7121
6958
  runtime: RuntimeSchema.optional(),
@@ -7123,9 +6960,9 @@ const router = os.router({
7123
6960
  webDeploy: WebDeploySchema.optional(),
7124
6961
  serverDeploy: ServerDeploySchema.optional(),
7125
6962
  directoryConflict: DirectoryConflictSchema.optional(),
7126
- renderTitle: z$1.boolean().optional(),
7127
- disableAnalytics: z$1.boolean().optional().default(false).describe("Disable analytics"),
7128
- manualDb: z$1.boolean().optional().default(false).describe("Skip automatic/manual database setup prompt and use manual setup")
6963
+ renderTitle: z.boolean().optional(),
6964
+ disableAnalytics: z.boolean().optional().default(false).describe("Disable analytics"),
6965
+ manualDb: z.boolean().optional().default(false).describe("Skip automatic/manual database setup prompt and use manual setup")
7129
6966
  })])).handler(async ({ input }) => {
7130
6967
  const [projectName, options] = input;
7131
6968
  const result = await createProjectHandler({
@@ -7134,12 +6971,12 @@ const router = os.router({
7134
6971
  });
7135
6972
  if (options.verbose) return result;
7136
6973
  }),
7137
- add: os.meta({ description: "Add addons or deployment configurations to an existing Better-T-Stack project" }).input(z$1.tuple([z$1.object({
7138
- addons: z$1.array(AddonsSchema).optional().default([]),
6974
+ add: os.meta({ description: "Add addons or deployment configurations to an existing Better-T-Stack project" }).input(z.tuple([z.object({
6975
+ addons: z.array(AddonsSchema).optional().default([]),
7139
6976
  webDeploy: WebDeploySchema.optional(),
7140
6977
  serverDeploy: ServerDeploySchema.optional(),
7141
- projectDir: z$1.string().optional(),
7142
- install: z$1.boolean().optional().default(false).describe("Install dependencies after adding addons or deployment"),
6978
+ projectDir: z.string().optional(),
6979
+ install: z.boolean().optional().default(false).describe("Install dependencies after adding addons or deployment"),
7143
6980
  packageManager: PackageManagerSchema.optional()
7144
6981
  })])).handler(async ({ input }) => {
7145
6982
  const [options] = input;