create-better-t-stack 3.7.3-canary.fe324be3 → 3.7.4

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.
@@ -3,12 +3,11 @@ 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 from "zod";
6
+ import z$1, { 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 "@better-t-stack/types";
12
11
  import gradient from "gradient-string";
13
12
  import * as JSONC from "jsonc-parser";
14
13
  import { $, execa } from "execa";
@@ -63,7 +62,6 @@ function getDefaultConfig() {
63
62
  }
64
63
  const DEFAULT_CONFIG = getDefaultConfig();
65
64
  const dependencyVersionMap = {
66
- typescript: "^5",
67
65
  "better-auth": "^1.4.5",
68
66
  "@better-auth/expo": "^1.4.5",
69
67
  "@clerk/nextjs": "^6.31.5",
@@ -100,7 +98,7 @@ const dependencyVersionMap = {
100
98
  "lint-staged": "^16.1.2",
101
99
  tsx: "^4.19.2",
102
100
  "@types/node": "^22.13.11",
103
- "@types/bun": "^1.3.4",
101
+ "@types/bun": "^1.2.6",
104
102
  "@elysiajs/node": "^1.3.1",
105
103
  "@elysiajs/cors": "^1.3.3",
106
104
  "@elysiajs/trpc": "^1.1.0",
@@ -120,17 +118,17 @@ const dependencyVersionMap = {
120
118
  "@ai-sdk/vue": "^2.0.49",
121
119
  "@ai-sdk/svelte": "^3.0.39",
122
120
  "@ai-sdk/react": "^2.0.39",
123
- streamdown: "^1.3.0",
121
+ streamdown: "^1.6.10",
124
122
  shiki: "^3.12.2",
125
- "@orpc/server": "^1.10.0",
126
- "@orpc/client": "^1.10.0",
127
- "@orpc/openapi": "^1.10.0",
128
- "@orpc/zod": "^1.10.0",
129
- "@orpc/tanstack-query": "^1.10.0",
130
- "@trpc/tanstack-react-query": "^11.5.0",
131
- "@trpc/server": "^11.5.0",
132
- "@trpc/client": "^11.5.0",
133
- next: "^16.0.7",
123
+ "@orpc/server": "^1.12.2",
124
+ "@orpc/client": "^1.12.2",
125
+ "@orpc/openapi": "^1.12.2",
126
+ "@orpc/zod": "^1.12.2",
127
+ "@orpc/tanstack-query": "^1.12.2",
128
+ "@trpc/tanstack-react-query": "^11.7.2",
129
+ "@trpc/server": "^11.7.2",
130
+ "@trpc/client": "^11.7.2",
131
+ next: "^16.0.10",
134
132
  convex: "^1.29.3",
135
133
  "@convex-dev/react-query": "^0.1.0",
136
134
  "convex-svelte": "^0.0.12",
@@ -141,8 +139,8 @@ const dependencyVersionMap = {
141
139
  "@tanstack/svelte-query-devtools": "^5.85.3",
142
140
  "@tanstack/vue-query-devtools": "^5.90.2",
143
141
  "@tanstack/vue-query": "^5.90.2",
144
- "@tanstack/react-query-devtools": "^5.85.5",
145
- "@tanstack/react-query": "^5.85.5",
142
+ "@tanstack/react-query-devtools": "^5.91.1",
143
+ "@tanstack/react-query": "^5.90.12",
146
144
  "@tanstack/solid-query": "^5.87.4",
147
145
  "@tanstack/solid-query-devtools": "^5.87.4",
148
146
  "@tanstack/solid-router-devtools": "^1.131.44",
@@ -186,6 +184,121 @@ const ADDON_COMPATIBILITY = {
186
184
  none: []
187
185
  };
188
186
 
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
+
189
302
  //#endregion
190
303
  //#region src/utils/compatibility.ts
191
304
  const WEB_FRAMEWORKS = [
@@ -1233,7 +1346,7 @@ const getLatestCLIVersion = () => {
1233
1346
  */
1234
1347
  function isTelemetryEnabled() {
1235
1348
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
1236
- const BTS_TELEMETRY = "0";
1349
+ const BTS_TELEMETRY = "1";
1237
1350
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
1238
1351
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
1239
1352
  return true;
@@ -3750,7 +3863,6 @@ async function addDeploymentToProject(input) {
3750
3863
  async function setupCatalogs(projectDir, options) {
3751
3864
  if (options.packageManager === "npm") return;
3752
3865
  const packagePaths = [
3753
- ".",
3754
3866
  "apps/server",
3755
3867
  "apps/web",
3756
3868
  "apps/native",
@@ -3759,8 +3871,7 @@ async function setupCatalogs(projectDir, options) {
3759
3871
  "packages/api",
3760
3872
  "packages/db",
3761
3873
  "packages/auth",
3762
- "packages/backend",
3763
- "packages/config"
3874
+ "packages/backend"
3764
3875
  ];
3765
3876
  const packagesInfo = [];
3766
3877
  for (const pkgPath of packagePaths) {
@@ -3859,18 +3970,15 @@ async function updatePackageJsonsWithCatalogs(packagesInfo, catalog) {
3859
3970
  //#endregion
3860
3971
  //#region src/helpers/addons/examples-setup.ts
3861
3972
  async function setupExamples(config) {
3862
- const { examples, frontend, backend, projectDir, orm, database } = config;
3973
+ const { examples, frontend, backend, projectDir, orm } = config;
3863
3974
  if (backend === "convex" || !examples || examples.length === 0 || examples[0] === "none") return;
3864
3975
  const apiDir = path.join(projectDir, "packages/api");
3865
3976
  if (await fs.pathExists(apiDir) && backend !== "none") {
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({
3977
+ if (orm === "drizzle") await addPackageDependency({
3978
+ dependencies: ["drizzle-orm", "@types/pg"],
3979
+ projectDir: apiDir
3980
+ });
3981
+ else if (orm === "prisma") await addPackageDependency({
3874
3982
  dependencies: ["@prisma/client"],
3875
3983
  projectDir: apiDir
3876
3984
  });
@@ -3919,6 +4027,15 @@ async function setupExamples(config) {
3919
4027
 
3920
4028
  //#endregion
3921
4029
  //#region src/helpers/core/api-setup.ts
4030
+ async function addBackendWorkspaceDependency(projectDir, backendPackageName, workspaceVersion) {
4031
+ const pkgJsonPath = path.join(projectDir, "package.json");
4032
+ try {
4033
+ const pkgJson = await fs.readJson(pkgJsonPath);
4034
+ if (!pkgJson.dependencies) pkgJson.dependencies = {};
4035
+ pkgJson.dependencies[backendPackageName] = workspaceVersion;
4036
+ await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
4037
+ } catch {}
4038
+ }
3922
4039
  function getFrontendType(frontend) {
3923
4040
  const reactBasedFrontends = [
3924
4041
  "tanstack-router",
@@ -4036,7 +4153,7 @@ function getConvexDependencies(frontend) {
4036
4153
  return deps;
4037
4154
  }
4038
4155
  async function setupApi(config) {
4039
- const { api, frontend, backend, projectDir } = config;
4156
+ const { api, projectName, frontend, backend, packageManager, projectDir } = config;
4040
4157
  const isConvex = backend === "convex";
4041
4158
  const webDir = path.join(projectDir, "apps/web");
4042
4159
  const nativeDir = path.join(projectDir, "apps/native");
@@ -4106,6 +4223,10 @@ async function setupApi(config) {
4106
4223
  dependencies: convexDeps.native.dependencies,
4107
4224
  projectDir: nativeDir
4108
4225
  });
4226
+ const backendPackageName = `@${projectName}/backend`;
4227
+ const backendWorkspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
4228
+ if (webDirExists) await addBackendWorkspaceDependency(webDir, backendPackageName, backendWorkspaceVersion);
4229
+ if (nativeDirExists) await addBackendWorkspaceDependency(nativeDir, backendPackageName, backendWorkspaceVersion);
4109
4230
  }
4110
4231
  }
4111
4232
 
@@ -6310,113 +6431,93 @@ function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend)
6310
6431
  //#endregion
6311
6432
  //#region src/helpers/core/workspace-setup.ts
6312
6433
  async function setupWorkspaceDependencies(projectDir, options) {
6313
- const { projectName, packageManager, database, auth, api, runtime, backend } = options;
6314
- const workspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
6434
+ const projectName = options.projectName;
6435
+ const workspaceVersion = options.packageManager === "npm" ? "*" : "workspace:*";
6315
6436
  const commonDeps = ["dotenv", "zod"];
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({
6437
+ const commonDevDeps = [];
6438
+ const configPackageDir = path.join(projectDir, "packages/config");
6439
+ const configDep = {};
6440
+ if (await fs.pathExists(configPackageDir)) configDep[`@${projectName}/config`] = workspaceVersion;
6441
+ const dbPackageDir = path.join(projectDir, "packages/db");
6442
+ if (await fs.pathExists(dbPackageDir)) await addPackageDependency({
6337
6443
  dependencies: commonDeps,
6338
6444
  devDependencies: commonDevDeps,
6339
6445
  customDevDependencies: configDep,
6340
- projectDir: dbDir
6446
+ projectDir: dbPackageDir
6341
6447
  });
6342
- if (authExists) {
6448
+ const authPackageDir = path.join(projectDir, "packages/auth");
6449
+ if (await fs.pathExists(authPackageDir)) {
6343
6450
  const authDeps = {};
6344
- if (database !== "none" && dbExists) authDeps[`@${projectName}/db`] = workspaceVersion;
6451
+ if (options.database !== "none" && await fs.pathExists(dbPackageDir)) authDeps[`@${projectName}/db`] = workspaceVersion;
6345
6452
  await addPackageDependency({
6346
6453
  dependencies: commonDeps,
6347
6454
  devDependencies: commonDevDeps,
6348
6455
  customDependencies: authDeps,
6349
6456
  customDevDependencies: configDep,
6350
- projectDir: authDir
6457
+ projectDir: authPackageDir
6351
6458
  });
6352
6459
  }
6353
- if (apiExists) {
6460
+ const apiPackageDir = path.join(projectDir, "packages/api");
6461
+ if (await fs.pathExists(apiPackageDir)) {
6354
6462
  const apiDeps = {};
6355
- if (auth !== "none" && authExists) apiDeps[`@${projectName}/auth`] = workspaceVersion;
6356
- if (database !== "none" && dbExists) apiDeps[`@${projectName}/db`] = workspaceVersion;
6463
+ if (options.auth !== "none" && await fs.pathExists(authPackageDir)) apiDeps[`@${projectName}/auth`] = workspaceVersion;
6464
+ if (options.database !== "none" && await fs.pathExists(dbPackageDir)) apiDeps[`@${projectName}/db`] = workspaceVersion;
6357
6465
  await addPackageDependency({
6358
6466
  dependencies: commonDeps,
6359
6467
  devDependencies: commonDevDeps,
6360
6468
  customDependencies: apiDeps,
6361
6469
  customDevDependencies: configDep,
6362
- projectDir: apiDir
6470
+ projectDir: apiPackageDir
6363
6471
  });
6364
6472
  }
6365
- if (backendExists) await addPackageDependency({
6366
- dependencies: commonDeps,
6367
- devDependencies: commonDevDeps,
6368
- customDevDependencies: configDep,
6369
- projectDir: backendDir
6370
- });
6371
- if (serverExists) {
6473
+ const serverPackageDir = path.join(projectDir, "apps/server");
6474
+ if (await fs.pathExists(serverPackageDir)) {
6372
6475
  const serverDeps = {};
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;
6476
+ if (options.api !== "none" && await fs.pathExists(apiPackageDir)) serverDeps[`@${projectName}/api`] = workspaceVersion;
6477
+ if (options.auth !== "none" && await fs.pathExists(authPackageDir)) serverDeps[`@${projectName}/auth`] = workspaceVersion;
6478
+ if (options.database !== "none" && await fs.pathExists(dbPackageDir)) serverDeps[`@${projectName}/db`] = workspaceVersion;
6376
6479
  await addPackageDependency({
6377
6480
  dependencies: commonDeps,
6378
6481
  devDependencies: [...commonDevDeps, "tsdown"],
6379
6482
  customDependencies: serverDeps,
6380
6483
  customDevDependencies: configDep,
6381
- projectDir: serverDir
6484
+ projectDir: serverPackageDir
6382
6485
  });
6383
6486
  }
6384
- if (webExists) {
6487
+ const webPackageDir = path.join(projectDir, "apps/web");
6488
+ if (await fs.pathExists(webPackageDir)) {
6385
6489
  const webDeps = {};
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,
6490
+ if (options.api !== "none" && await fs.pathExists(apiPackageDir)) webDeps[`@${projectName}/api`] = workspaceVersion;
6491
+ if (options.auth !== "none" && await fs.pathExists(authPackageDir)) webDeps[`@${projectName}/auth`] = workspaceVersion;
6492
+ if (Object.keys(webDeps).length > 0) await addPackageDependency({
6392
6493
  customDependencies: webDeps,
6393
6494
  customDevDependencies: configDep,
6394
- projectDir: webDir
6495
+ projectDir: webPackageDir
6395
6496
  });
6396
6497
  }
6397
- if (nativeExists) {
6498
+ const nativePackageDir = path.join(projectDir, "apps/native");
6499
+ if (await fs.pathExists(nativePackageDir)) {
6398
6500
  const nativeDeps = {};
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,
6501
+ if (options.api !== "none" && await fs.pathExists(apiPackageDir)) nativeDeps[`@${projectName}/api`] = workspaceVersion;
6502
+ if (Object.keys(nativeDeps).length > 0) await addPackageDependency({
6404
6503
  customDependencies: nativeDeps,
6405
6504
  customDevDependencies: configDep,
6406
- projectDir: nativeDir
6505
+ projectDir: nativePackageDir
6407
6506
  });
6408
6507
  }
6409
- const runtimeDevDeps = getRuntimeDevDeps(runtime, backend);
6508
+ const runtimeDevDeps = getRuntimeDevDeps(options);
6410
6509
  await addPackageDependency({
6411
6510
  dependencies: commonDeps,
6412
6511
  devDependencies: [...commonDevDeps, ...runtimeDevDeps],
6413
6512
  projectDir
6414
6513
  });
6415
6514
  }
6416
- function getRuntimeDevDeps(runtime, backend) {
6515
+ function getRuntimeDevDeps(options) {
6516
+ const { runtime, backend } = options;
6417
6517
  if (runtime === "none" && backend === "self") return ["@types/node"];
6418
- if (runtime === "node" || runtime === "workers") return ["@types/node"];
6518
+ if (runtime === "node") return ["@types/node"];
6419
6519
  if (runtime === "bun") return ["@types/bun"];
6520
+ if (runtime === "workers") return ["@types/node"];
6420
6521
  return [];
6421
6522
  }
6422
6523
 
@@ -6425,130 +6526,185 @@ function getRuntimeDevDeps(runtime, backend) {
6425
6526
  async function updatePackageConfigurations(projectDir, options) {
6426
6527
  await updateRootPackageJson(projectDir, options);
6427
6528
  if (options.backend === "convex") await updateConvexPackageJson(projectDir, options);
6428
- else if (options.backend !== "none") {
6529
+ else if (options.backend === "self") {
6429
6530
  await updateDbPackageJson(projectDir, options);
6430
6531
  await updateAuthPackageJson(projectDir, options);
6431
6532
  await updateApiPackageJson(projectDir, options);
6432
- if (options.backend !== "self") await updateServerPackageJson(projectDir, options);
6533
+ await setupWorkspaceDependencies(projectDir, options);
6534
+ } else if (options.backend !== "none") {
6535
+ await updateServerPackageJson(projectDir, options);
6536
+ await updateAuthPackageJson(projectDir, options);
6537
+ await updateApiPackageJson(projectDir, options);
6538
+ await setupWorkspaceDependencies(projectDir, options);
6433
6539
  }
6434
- await setupWorkspaceDependencies(projectDir, options);
6435
6540
  }
6436
6541
  async function updateRootPackageJson(projectDir, options) {
6437
6542
  const rootPackageJsonPath = path.join(projectDir, "package.json");
6438
6543
  if (!await fs.pathExists(rootPackageJsonPath)) return;
6439
6544
  const packageJson = await fs.readJson(rootPackageJsonPath);
6440
6545
  packageJson.name = options.projectName;
6441
- packageJson.scripts = packageJson.scripts || {};
6442
- packageJson.workspaces = packageJson.workspaces || [];
6546
+ if (!packageJson.scripts) packageJson.scripts = {};
6443
6547
  const scripts = packageJson.scripts;
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");
6548
+ const backendPackageName = options.backend === "convex" ? `@${options.projectName}/backend` : "server";
6549
+ const dbPackageName = `@${options.projectName}/db`;
6550
+ let serverDevScript = "";
6551
+ if (options.addons.includes("turborepo")) serverDevScript = `turbo -F ${backendPackageName} dev`;
6552
+ else if (options.packageManager === "bun") serverDevScript = `bun run --filter ${backendPackageName} dev`;
6553
+ else if (options.packageManager === "pnpm") serverDevScript = `pnpm --filter ${backendPackageName} dev`;
6554
+ else if (options.packageManager === "npm") serverDevScript = `npm run dev --workspace ${backendPackageName}`;
6555
+ let devScript = "";
6556
+ if (options.packageManager === "pnpm") devScript = "pnpm -r dev";
6557
+ else if (options.packageManager === "npm") devScript = "npm run dev --workspaces";
6558
+ else if (options.packageManager === "bun") devScript = "bun run --filter '*' dev";
6559
+ const needsDbScripts = options.backend !== "convex" && options.database !== "none" && options.orm !== "none" && options.orm !== "mongoose";
6560
+ if (options.addons.includes("turborepo")) {
6561
+ scripts.dev = "turbo dev";
6562
+ scripts.build = "turbo build";
6563
+ scripts["check-types"] = "turbo check-types";
6564
+ scripts["dev:native"] = "turbo -F native dev";
6565
+ scripts["dev:web"] = "turbo -F web dev";
6566
+ if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6567
+ if (options.backend === "convex") scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`;
6568
+ if (needsDbScripts) {
6569
+ scripts["db:push"] = `turbo -F ${dbPackageName} db:push`;
6570
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `turbo -F ${dbPackageName} db:studio`;
6571
+ if (options.orm === "prisma") {
6572
+ scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
6573
+ scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
6574
+ } else if (options.orm === "drizzle") {
6575
+ scripts["db:generate"] = `turbo -F ${dbPackageName} db:generate`;
6576
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `turbo -F ${dbPackageName} db:migrate`;
6577
+ }
6578
+ }
6579
+ if (options.dbSetup === "docker") {
6580
+ scripts["db:start"] = `turbo -F ${dbPackageName} db:start`;
6581
+ scripts["db:watch"] = `turbo -F ${dbPackageName} db:watch`;
6582
+ scripts["db:stop"] = `turbo -F ${dbPackageName} db:stop`;
6583
+ scripts["db:down"] = `turbo -F ${dbPackageName} db:down`;
6584
+ }
6585
+ } else if (options.packageManager === "pnpm") {
6586
+ scripts.dev = devScript;
6587
+ scripts.build = "pnpm -r build";
6588
+ scripts["check-types"] = "pnpm -r check-types";
6589
+ scripts["dev:native"] = "pnpm --filter native dev";
6590
+ scripts["dev:web"] = "pnpm --filter web dev";
6591
+ if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6592
+ if (options.backend === "convex") scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`;
6593
+ if (needsDbScripts) {
6594
+ scripts["db:push"] = `pnpm --filter ${dbPackageName} db:push`;
6595
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `pnpm --filter ${dbPackageName} db:studio`;
6596
+ if (options.orm === "prisma") {
6597
+ scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
6598
+ scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
6599
+ } else if (options.orm === "drizzle") {
6600
+ scripts["db:generate"] = `pnpm --filter ${dbPackageName} db:generate`;
6601
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `pnpm --filter ${dbPackageName} db:migrate`;
6602
+ }
6603
+ }
6604
+ if (options.dbSetup === "docker") {
6605
+ scripts["db:start"] = `pnpm --filter ${dbPackageName} db:start`;
6606
+ scripts["db:watch"] = `pnpm --filter ${dbPackageName} db:watch`;
6607
+ scripts["db:stop"] = `pnpm --filter ${dbPackageName} db:stop`;
6608
+ scripts["db:down"] = `pnpm --filter ${dbPackageName} db:down`;
6609
+ }
6610
+ } else if (options.packageManager === "npm") {
6611
+ scripts.dev = devScript;
6612
+ scripts.build = "npm run build --workspaces";
6613
+ scripts["check-types"] = "npm run check-types --workspaces";
6614
+ scripts["dev:native"] = "npm run dev --workspace native";
6615
+ scripts["dev:web"] = "npm run dev --workspace web";
6616
+ if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6617
+ if (options.backend === "convex") scripts["dev:setup"] = `npm run dev:setup --workspace ${backendPackageName}`;
6618
+ if (needsDbScripts) {
6619
+ scripts["db:push"] = `npm run db:push --workspace ${dbPackageName}`;
6620
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `npm run db:studio --workspace ${dbPackageName}`;
6621
+ if (options.orm === "prisma") {
6622
+ scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
6623
+ scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
6624
+ } else if (options.orm === "drizzle") {
6625
+ scripts["db:generate"] = `npm run db:generate --workspace ${dbPackageName}`;
6626
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `npm run db:migrate --workspace ${dbPackageName}`;
6627
+ }
6628
+ }
6629
+ if (options.dbSetup === "docker") {
6630
+ scripts["db:start"] = `npm run db:start --workspace ${dbPackageName}`;
6631
+ scripts["db:watch"] = `npm run db:watch --workspace ${dbPackageName}`;
6632
+ scripts["db:stop"] = `npm run db:stop --workspace ${dbPackageName}`;
6633
+ scripts["db:down"] = `npm run db:down --workspace ${dbPackageName}`;
6634
+ }
6635
+ } else if (options.packageManager === "bun") {
6636
+ scripts.dev = devScript;
6637
+ scripts.build = "bun run --filter '*' build";
6638
+ scripts["check-types"] = "bun run --filter '*' check-types";
6639
+ scripts["dev:native"] = "bun run --filter native dev";
6640
+ scripts["dev:web"] = "bun run --filter web dev";
6641
+ if (options.backend !== "self" && options.backend !== "none") scripts["dev:server"] = serverDevScript;
6642
+ if (options.backend === "convex") scripts["dev:setup"] = `bun run --filter ${backendPackageName} dev:setup`;
6643
+ if (needsDbScripts) {
6644
+ scripts["db:push"] = `bun run --filter ${dbPackageName} db:push`;
6645
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = `bun run --filter ${dbPackageName} db:studio`;
6646
+ if (options.orm === "prisma") {
6647
+ scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
6648
+ scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
6649
+ } else if (options.orm === "drizzle") {
6650
+ scripts["db:generate"] = `bun run --filter ${dbPackageName} db:generate`;
6651
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = `bun run --filter ${dbPackageName} db:migrate`;
6652
+ }
6653
+ }
6654
+ if (options.dbSetup === "docker") {
6655
+ scripts["db:start"] = `bun run --filter ${dbPackageName} db:start`;
6656
+ scripts["db:watch"] = `bun run --filter ${dbPackageName} db:watch`;
6657
+ scripts["db:stop"] = `bun run --filter ${dbPackageName} db:stop`;
6658
+ scripts["db:down"] = `bun run --filter ${dbPackageName} db:down`;
6468
6659
  }
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
6660
  }
6476
6661
  try {
6477
- const { stdout } = await execa(packageManager, ["-v"], { cwd: projectDir });
6478
- packageJson.packageManager = `${packageManager}@${stdout.trim()}`;
6662
+ const { stdout } = await execa(options.packageManager, ["-v"], { cwd: projectDir });
6663
+ packageJson.packageManager = `${options.packageManager}@${stdout.trim()}`;
6479
6664
  } catch {
6480
- log.warn(`Could not determine ${packageManager} version.`);
6665
+ log.warn(`Could not determine ${options.packageManager} version.`);
6481
6666
  }
6482
- if (backend === "convex") {
6667
+ if (!packageJson.workspaces) packageJson.workspaces = [];
6668
+ const workspaces = packageJson.workspaces;
6669
+ if (options.backend === "convex") {
6483
6670
  if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
6484
- if ((options.frontend.length > 0 || addons.includes("starlight")) && !workspaces.includes("apps/*")) workspaces.push("apps/*");
6671
+ if ((options.frontend.length > 0 || options.addons.includes("starlight")) && !workspaces.includes("apps/*")) workspaces.push("apps/*");
6485
6672
  } else {
6486
6673
  if (!workspaces.includes("apps/*")) workspaces.push("apps/*");
6487
6674
  if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
6488
6675
  }
6489
6676
  await fs.writeJson(rootPackageJsonPath, packageJson, { spaces: 2 });
6490
6677
  }
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) {
6678
+ async function updateServerPackageJson(projectDir, options) {
6520
6679
  const serverPackageJsonPath = path.join(projectDir, "apps/server/package.json");
6521
6680
  if (!await fs.pathExists(serverPackageJsonPath)) return;
6522
6681
  const serverPackageJson = await fs.readJson(serverPackageJsonPath);
6523
- serverPackageJson.scripts = serverPackageJson.scripts || {};
6682
+ if (!serverPackageJson.scripts) serverPackageJson.scripts = {};
6524
6683
  await fs.writeJson(serverPackageJsonPath, serverPackageJson, { spaces: 2 });
6684
+ await updateDbPackageJson(projectDir, options);
6525
6685
  }
6526
6686
  async function updateDbPackageJson(projectDir, options) {
6527
6687
  const dbPackageJsonPath = path.join(projectDir, "packages/db/package.json");
6528
6688
  if (!await fs.pathExists(dbPackageJsonPath)) return;
6529
6689
  const dbPackageJson = await fs.readJson(dbPackageJsonPath);
6530
6690
  dbPackageJson.name = `@${options.projectName}/db`;
6531
- dbPackageJson.scripts = dbPackageJson.scripts || {};
6691
+ if (!dbPackageJson.scripts) dbPackageJson.scripts = {};
6532
6692
  const scripts = dbPackageJson.scripts;
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") {
6693
+ if (options.database !== "none") {
6694
+ if (options.database === "sqlite" && options.orm === "drizzle" && options.dbSetup !== "d1") scripts["db:local"] = "turso dev --db-file local.db";
6695
+ if (options.orm === "prisma") {
6538
6696
  scripts["db:push"] = "prisma db push";
6697
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = "prisma studio";
6539
6698
  scripts["db:generate"] = "prisma generate";
6540
6699
  scripts["db:migrate"] = "prisma migrate dev";
6541
- if (!isD1Alchemy) scripts["db:studio"] = "prisma studio";
6542
- } else if (orm === "drizzle") {
6700
+ } else if (options.orm === "drizzle") {
6543
6701
  scripts["db:push"] = "drizzle-kit push";
6702
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:studio"] = "drizzle-kit studio";
6544
6703
  scripts["db:generate"] = "drizzle-kit generate";
6545
- if (!isD1Alchemy) {
6546
- scripts["db:studio"] = "drizzle-kit studio";
6547
- scripts["db:migrate"] = "drizzle-kit migrate";
6548
- }
6704
+ if (!(options.dbSetup === "d1" && options.serverDeploy === "alchemy")) scripts["db:migrate"] = "drizzle-kit migrate";
6549
6705
  }
6550
6706
  }
6551
- if (dbSetup === "docker") {
6707
+ if (options.dbSetup === "docker") {
6552
6708
  scripts["db:start"] = "docker compose up -d";
6553
6709
  scripts["db:watch"] = "docker compose up";
6554
6710
  scripts["db:stop"] = "docker compose stop";
@@ -6575,7 +6731,7 @@ async function updateConvexPackageJson(projectDir, options) {
6575
6731
  if (!await fs.pathExists(convexPackageJsonPath)) return;
6576
6732
  const convexPackageJson = await fs.readJson(convexPackageJsonPath);
6577
6733
  convexPackageJson.name = `@${options.projectName}/backend`;
6578
- convexPackageJson.scripts = convexPackageJson.scripts || {};
6734
+ if (!convexPackageJson.scripts) convexPackageJson.scripts = {};
6579
6735
  await fs.writeJson(convexPackageJsonPath, convexPackageJson, { spaces: 2 });
6580
6736
  }
6581
6737
 
@@ -6938,21 +7094,21 @@ const router = os.router({
6938
7094
  description: "Create a new Better-T-Stack project",
6939
7095
  default: true,
6940
7096
  negateBooleans: true
6941
- }).input(z.tuple([ProjectNameSchema.optional(), z.object({
7097
+ }).input(z$1.tuple([ProjectNameSchema.optional(), z$1.object({
6942
7098
  template: TemplateSchema.optional().describe("Use a predefined template"),
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"),
7099
+ yes: z$1.boolean().optional().default(false).describe("Use default configuration"),
7100
+ yolo: z$1.boolean().optional().default(false).describe("(WARNING - NOT RECOMMENDED) Bypass validations and compatibility checks"),
7101
+ verbose: z$1.boolean().optional().default(false).describe("Show detailed result information"),
6946
7102
  database: DatabaseSchema.optional(),
6947
7103
  orm: ORMSchema.optional(),
6948
7104
  auth: AuthSchema.optional(),
6949
7105
  payments: PaymentsSchema.optional(),
6950
- frontend: z.array(FrontendSchema).optional(),
6951
- addons: z.array(AddonsSchema).optional(),
6952
- examples: z.array(ExamplesSchema).optional(),
6953
- git: z.boolean().optional(),
7106
+ frontend: z$1.array(FrontendSchema).optional(),
7107
+ addons: z$1.array(AddonsSchema).optional(),
7108
+ examples: z$1.array(ExamplesSchema).optional(),
7109
+ git: z$1.boolean().optional(),
6954
7110
  packageManager: PackageManagerSchema.optional(),
6955
- install: z.boolean().optional(),
7111
+ install: z$1.boolean().optional(),
6956
7112
  dbSetup: DatabaseSetupSchema.optional(),
6957
7113
  backend: BackendSchema.optional(),
6958
7114
  runtime: RuntimeSchema.optional(),
@@ -6960,9 +7116,9 @@ const router = os.router({
6960
7116
  webDeploy: WebDeploySchema.optional(),
6961
7117
  serverDeploy: ServerDeploySchema.optional(),
6962
7118
  directoryConflict: DirectoryConflictSchema.optional(),
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")
7119
+ renderTitle: z$1.boolean().optional(),
7120
+ disableAnalytics: z$1.boolean().optional().default(false).describe("Disable analytics"),
7121
+ manualDb: z$1.boolean().optional().default(false).describe("Skip automatic/manual database setup prompt and use manual setup")
6966
7122
  })])).handler(async ({ input }) => {
6967
7123
  const [projectName, options] = input;
6968
7124
  const result = await createProjectHandler({
@@ -6971,12 +7127,12 @@ const router = os.router({
6971
7127
  });
6972
7128
  if (options.verbose) return result;
6973
7129
  }),
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([]),
7130
+ add: os.meta({ description: "Add addons or deployment configurations to an existing Better-T-Stack project" }).input(z$1.tuple([z$1.object({
7131
+ addons: z$1.array(AddonsSchema).optional().default([]),
6976
7132
  webDeploy: WebDeploySchema.optional(),
6977
7133
  serverDeploy: ServerDeploySchema.optional(),
6978
- projectDir: z.string().optional(),
6979
- install: z.boolean().optional().default(false).describe("Install dependencies after adding addons or deployment"),
7134
+ projectDir: z$1.string().optional(),
7135
+ install: z$1.boolean().optional().default(false).describe("Install dependencies after adding addons or deployment"),
6980
7136
  packageManager: PackageManagerSchema.optional()
6981
7137
  })])).handler(async ({ input }) => {
6982
7138
  const [options] = input;