create-better-t-stack 3.4.1 → 3.4.2-canary.281ca96d

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 (46) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +1 -1
  3. package/dist/index.d.ts +0 -6
  4. package/dist/index.js +1 -1
  5. package/dist/{src-_EdtPnBT.js → src-CFkY2F0Q.js} +97 -462
  6. package/package.json +1 -1
  7. package/templates/api/orpc/server/package.json.hbs +1 -5
  8. package/templates/api/orpc/server/tsconfig.json.hbs +1 -4
  9. package/templates/api/trpc/server/package.json.hbs +1 -5
  10. package/templates/api/trpc/server/tsconfig.json.hbs +1 -4
  11. package/templates/auth/better-auth/server/base/package.json.hbs +1 -5
  12. package/templates/auth/better-auth/server/base/tsconfig.json.hbs +1 -4
  13. package/templates/db/base/package.json.hbs +1 -5
  14. package/templates/db/base/tsconfig.json.hbs +1 -4
  15. package/templates/db/drizzle/sqlite/drizzle.config.ts.hbs +0 -7
  16. package/templates/db/prisma/mongodb/prisma/schema/schema.prisma.hbs +1 -1
  17. package/templates/db/prisma/mysql/prisma/schema/schema.prisma.hbs +8 -12
  18. package/templates/db/prisma/mysql/prisma.config.ts.hbs +17 -14
  19. package/templates/db/prisma/mysql/src/index.ts.hbs +20 -6
  20. package/templates/db/prisma/postgres/prisma/schema/schema.prisma.hbs +1 -5
  21. package/templates/db/prisma/postgres/prisma.config.ts.hbs +12 -9
  22. package/templates/db/prisma/postgres/src/index.ts.hbs +26 -4
  23. package/templates/db/prisma/sqlite/prisma/schema/schema.prisma.hbs +1 -12
  24. package/templates/db/prisma/sqlite/prisma.config.ts.hbs +12 -9
  25. package/templates/db/prisma/sqlite/src/index.ts.hbs +10 -14
  26. package/templates/deploy/alchemy/alchemy.run.ts.hbs +67 -5
  27. package/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs +2 -2
  28. package/templates/extras/_npmrc.hbs +2 -2
  29. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +21 -13
  30. package/templates/frontend/react/next/next.config.ts.hbs +5 -2
  31. package/templates/frontend/react/next/tsconfig.json.hbs +0 -3
  32. package/templates/frontend/react/tanstack-start/package.json.hbs +4 -4
  33. package/templates/packages/config/tsconfig.base.json.hbs +1 -1
  34. package/templates/api/orpc/server/tsdown.config.ts.hbs +0 -7
  35. package/templates/api/trpc/server/tsdown.config.ts.hbs +0 -7
  36. package/templates/auth/better-auth/server/base/tsdown.config.ts.hbs +0 -7
  37. package/templates/db/base/tsdown.config.ts.hbs +0 -7
  38. package/templates/deploy/wrangler/server/wrangler.jsonc.hbs +0 -39
  39. package/templates/deploy/wrangler/web/nuxt/wrangler.jsonc.hbs +0 -51
  40. package/templates/deploy/wrangler/web/react/next/open-next.config.ts +0 -6
  41. package/templates/deploy/wrangler/web/react/next/wrangler.jsonc.hbs +0 -22
  42. package/templates/deploy/wrangler/web/react/react-router/wrangler.jsonc.hbs +0 -8
  43. package/templates/deploy/wrangler/web/react/tanstack-router/wrangler.jsonc.hbs +0 -8
  44. package/templates/deploy/wrangler/web/react/tanstack-start/wrangler.jsonc.hbs +0 -20
  45. package/templates/deploy/wrangler/web/solid/wrangler.jsonc.hbs +0 -8
  46. package/templates/deploy/wrangler/web/svelte/wrangler.jsonc.hbs +0 -51
@@ -72,18 +72,22 @@ const dependencyVersionMap = {
72
72
  "drizzle-kit": "^0.31.2",
73
73
  "@planetscale/database": "^1.19.0",
74
74
  "@libsql/client": "^0.14.0",
75
+ libsql: "^0.5.22",
75
76
  "@neondatabase/serverless": "^1.0.1",
76
77
  pg: "^8.14.1",
77
78
  "@types/pg": "^8.11.11",
78
79
  "@types/ws": "^8.18.1",
79
80
  ws: "^8.18.3",
80
81
  mysql2: "^3.14.0",
81
- "@prisma/client": "^6.15.0",
82
- prisma: "^6.15.0",
83
- "@prisma/adapter-d1": "^6.15.0",
84
- "@prisma/extension-accelerate": "^2.0.2",
85
- "@prisma/adapter-libsql": "^6.15.0",
86
- "@prisma/adapter-planetscale": "^6.15.0",
82
+ "@prisma/client": "dev",
83
+ prisma: "dev",
84
+ "@prisma/adapter-d1": "dev",
85
+ "@prisma/adapter-neon": "dev",
86
+ "@prisma/adapter-mariadb": "dev",
87
+ "@prisma/adapter-libsql": "dev",
88
+ "@prisma/adapter-better-sqlite3": "dev",
89
+ "@prisma/adapter-pg": "dev",
90
+ "@prisma/adapter-planetscale": "dev",
87
91
  mongoose: "^8.14.0",
88
92
  "vite-plugin-pwa": "^1.0.1",
89
93
  "@vite-pwa/assets-generator": "^1.0.0",
@@ -148,7 +152,7 @@ const dependencyVersionMap = {
148
152
  "@cloudflare/workers-types": "^4.20250822.0",
149
153
  alchemy: "^0.77.0",
150
154
  dotenv: "^17.2.2",
151
- tsdown: "^0.15.5",
155
+ tsdown: "^0.16.5",
152
156
  zod: "^4.1.11",
153
157
  srvx: "0.8.15",
154
158
  "@polar-sh/better-auth": "^1.1.3",
@@ -279,16 +283,8 @@ const ProjectNameSchema = z.string().min(1, "Project name cannot be empty").max(
279
283
  "*"
280
284
  ].some((char) => name.includes(char));
281
285
  }, "Project name contains invalid characters").refine((name) => name.toLowerCase() !== "node_modules", "Project name is reserved").describe("Project name or path");
282
- const WebDeploySchema = z.enum([
283
- "wrangler",
284
- "alchemy",
285
- "none"
286
- ]).describe("Web deployment");
287
- const ServerDeploySchema = z.enum([
288
- "wrangler",
289
- "alchemy",
290
- "none"
291
- ]).describe("Server deployment");
286
+ const WebDeploySchema = z.enum(["alchemy", "none"]).describe("Web deployment");
287
+ const ServerDeploySchema = z.enum(["alchemy", "none"]).describe("Server deployment");
292
288
  const DirectoryConflictSchema = z.enum([
293
289
  "merge",
294
290
  "overwrite",
@@ -1132,10 +1128,6 @@ async function getRuntimeChoice(runtime, backend) {
1132
1128
  //#endregion
1133
1129
  //#region src/prompts/server-deploy.ts
1134
1130
  function getDeploymentDisplay$1(deployment) {
1135
- if (deployment === "wrangler") return {
1136
- label: "Wrangler",
1137
- hint: "Deploy to Cloudflare Workers using Wrangler"
1138
- };
1139
1131
  if (deployment === "alchemy") return {
1140
1132
  label: "Alchemy",
1141
1133
  hint: "Deploy to Cloudflare Workers using Alchemy"
@@ -1145,40 +1137,17 @@ function getDeploymentDisplay$1(deployment) {
1145
1137
  hint: `Add ${deployment} deployment`
1146
1138
  };
1147
1139
  }
1148
- async function getServerDeploymentChoice(deployment, runtime, backend, webDeploy) {
1140
+ async function getServerDeploymentChoice(deployment, runtime, backend, _webDeploy) {
1149
1141
  if (deployment !== void 0) return deployment;
1150
1142
  if (backend === "none" || backend === "convex") return "none";
1151
1143
  if (backend !== "hono") return "none";
1152
- const options = [];
1153
- if (runtime !== "workers") return "none";
1154
- ["alchemy", "wrangler"].forEach((deploy) => {
1155
- const { label, hint } = getDeploymentDisplay$1(deploy);
1156
- options.unshift({
1157
- value: deploy,
1158
- label,
1159
- hint
1160
- });
1161
- });
1162
- const response = await select({
1163
- message: "Select server deployment",
1164
- options,
1165
- initialValue: webDeploy === "alchemy" ? "alchemy" : runtime === "workers" ? "wrangler" : DEFAULT_CONFIG.serverDeploy
1166
- });
1167
- if (isCancel(response)) return exitCancelled("Operation cancelled");
1168
- return response;
1144
+ if (runtime === "workers") return "alchemy";
1145
+ return "none";
1169
1146
  }
1170
1147
  async function getServerDeploymentToAdd(runtime, existingDeployment, backend) {
1171
1148
  if (backend !== "hono") return "none";
1172
1149
  const options = [];
1173
1150
  if (runtime === "workers") {
1174
- if (existingDeployment !== "wrangler") {
1175
- const { label, hint } = getDeploymentDisplay$1("wrangler");
1176
- options.push({
1177
- value: "wrangler",
1178
- label,
1179
- hint
1180
- });
1181
- }
1182
1151
  if (existingDeployment !== "alchemy") {
1183
1152
  const { label, hint } = getDeploymentDisplay$1("alchemy");
1184
1153
  options.push({
@@ -1194,7 +1163,7 @@ async function getServerDeploymentToAdd(runtime, existingDeployment, backend) {
1194
1163
  const response = await select({
1195
1164
  message: "Select server deployment",
1196
1165
  options,
1197
- initialValue: runtime === "workers" ? "wrangler" : DEFAULT_CONFIG.serverDeploy
1166
+ initialValue: DEFAULT_CONFIG.serverDeploy
1198
1167
  });
1199
1168
  if (isCancel(response)) return exitCancelled("Operation cancelled");
1200
1169
  return response;
@@ -1206,10 +1175,6 @@ function hasWebFrontend(frontends) {
1206
1175
  return frontends.some((f) => WEB_FRAMEWORKS.includes(f));
1207
1176
  }
1208
1177
  function getDeploymentDisplay(deployment) {
1209
- if (deployment === "wrangler") return {
1210
- label: "Wrangler",
1211
- hint: "Deploy to Cloudflare Workers using Wrangler"
1212
- };
1213
1178
  if (deployment === "alchemy") return {
1214
1179
  label: "Alchemy",
1215
1180
  hint: "Deploy to Cloudflare Workers using Alchemy"
@@ -1224,11 +1189,7 @@ async function getDeploymentChoice(deployment, _runtime, _backend, frontend = []
1224
1189
  if (!hasWebFrontend(frontend)) return "none";
1225
1190
  const response = await select({
1226
1191
  message: "Select web deployment",
1227
- options: [
1228
- "wrangler",
1229
- "alchemy",
1230
- "none"
1231
- ].map((deploy) => {
1192
+ options: ["alchemy", "none"].map((deploy) => {
1232
1193
  const { label, hint } = getDeploymentDisplay(deploy);
1233
1194
  return {
1234
1195
  value: deploy,
@@ -1244,14 +1205,6 @@ async function getDeploymentChoice(deployment, _runtime, _backend, frontend = []
1244
1205
  async function getDeploymentToAdd(frontend, existingDeployment) {
1245
1206
  if (!hasWebFrontend(frontend)) return "none";
1246
1207
  const options = [];
1247
- if (existingDeployment !== "wrangler") {
1248
- const { label, hint } = getDeploymentDisplay("wrangler");
1249
- options.push({
1250
- value: "wrangler",
1251
- label,
1252
- hint
1253
- });
1254
- }
1255
1208
  if (existingDeployment !== "alchemy") {
1256
1209
  const { label, hint } = getDeploymentDisplay("alchemy");
1257
1210
  options.push({
@@ -1387,7 +1340,7 @@ const getLatestCLIVersion = () => {
1387
1340
  */
1388
1341
  function isTelemetryEnabled() {
1389
1342
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
1390
- const BTS_TELEMETRY = "1";
1343
+ const BTS_TELEMETRY = "0";
1391
1344
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
1392
1345
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
1393
1346
  return true;
@@ -1395,8 +1348,8 @@ function isTelemetryEnabled() {
1395
1348
 
1396
1349
  //#endregion
1397
1350
  //#region src/utils/analytics.ts
1398
- const POSTHOG_API_KEY = "phc_8ZUxEwwfKMajJLvxz1daGd931dYbQrwKNficBmsdIrs";
1399
- const POSTHOG_HOST = "https://us.i.posthog.com";
1351
+ const POSTHOG_API_KEY = "random";
1352
+ const POSTHOG_HOST = "random";
1400
1353
  function generateSessionId() {
1401
1354
  const rand = Math.random().toString(36).slice(2);
1402
1355
  return `cli_${Date.now().toString(36)}${rand}`;
@@ -1815,8 +1768,8 @@ function validateFullConfig(config, providedFlags, options) {
1815
1768
  validateServerDeployRequiresBackend(config.serverDeploy, config.backend);
1816
1769
  validateSelfBackendCompatibility(providedFlags, options, config);
1817
1770
  validateWorkersCompatibility(providedFlags, options, config);
1818
- if (config.runtime === "workers" && config.serverDeploy === "none") exitWithError("Cloudflare Workers runtime requires a server deployment. Please choose 'wrangler' or 'alchemy' for --server-deploy.");
1819
- if (providedFlags.has("serverDeploy") && (config.serverDeploy === "alchemy" || config.serverDeploy === "wrangler") && config.runtime !== "workers") exitWithError(`Server deployment '${config.serverDeploy}' requires '--runtime workers'. Please use '--runtime workers' or choose a different server deployment.`);
1771
+ if (config.runtime === "workers" && config.serverDeploy === "none") exitWithError("Cloudflare Workers runtime requires a server deployment. Please choose 'alchemy' for --server-deploy.");
1772
+ if (providedFlags.has("serverDeploy") && config.serverDeploy === "alchemy" && config.runtime !== "workers") exitWithError(`Server deployment '${config.serverDeploy}' requires '--runtime workers'. Please use '--runtime workers' or choose a different server deployment.`);
1820
1773
  if (config.addons && config.addons.length > 0) {
1821
1774
  validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth);
1822
1775
  config.addons = [...new Set(config.addons)];
@@ -3227,14 +3180,14 @@ async function setupDeploymentTemplates(projectDir, context) {
3227
3180
  if (await fs.pathExists(alchemyTemplateSrc)) {
3228
3181
  const webAppDir = path.join(projectDir, "apps/web");
3229
3182
  await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, isBackendSelf && await fs.pathExists(webAppDir) ? webAppDir : projectDir, context);
3230
- await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3183
+ if (!isBackendSelf) await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3231
3184
  }
3232
3185
  } else {
3233
3186
  if (context.webDeploy === "alchemy") {
3234
3187
  const webAppDir = path.join(projectDir, "apps/web");
3235
3188
  if (await fs.pathExists(alchemyTemplateSrc) && await fs.pathExists(webAppDir)) {
3236
3189
  await processAndCopyFiles("alchemy.run.ts.hbs", alchemyTemplateSrc, webAppDir, context);
3237
- await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3190
+ if (!isBackendSelf) await addEnvDtsToPackages(projectDir, context, alchemyTemplateSrc);
3238
3191
  }
3239
3192
  }
3240
3193
  if (context.serverDeploy === "alchemy" && !isBackendSelf) {
@@ -3338,54 +3291,13 @@ async function addAddonsToProject(input) {
3338
3291
  //#region src/helpers/deployment/server-deploy-setup.ts
3339
3292
  async function setupServerDeploy(config) {
3340
3293
  const { serverDeploy, webDeploy, projectDir } = config;
3341
- const { packageManager } = config;
3342
3294
  if (serverDeploy === "none") return;
3343
3295
  if (serverDeploy === "alchemy" && webDeploy === "alchemy") return;
3344
3296
  const serverDir = path.join(projectDir, "apps/server");
3345
3297
  if (!await fs.pathExists(serverDir)) return;
3346
- if (serverDeploy === "wrangler") {
3347
- await setupWorkersServerDeploy(serverDir, packageManager);
3348
- await generateCloudflareWorkerTypes({
3349
- serverDir,
3350
- packageManager
3351
- });
3352
- } else if (serverDeploy === "alchemy") await setupAlchemyServerDeploy(serverDir, packageManager, projectDir);
3298
+ if (serverDeploy === "alchemy") await setupAlchemyServerDeploy(serverDir, projectDir);
3353
3299
  }
3354
- async function setupWorkersServerDeploy(serverDir, _packageManager) {
3355
- const packageJsonPath = path.join(serverDir, "package.json");
3356
- if (!await fs.pathExists(packageJsonPath)) return;
3357
- const packageJson = await fs.readJson(packageJsonPath);
3358
- packageJson.scripts = {
3359
- ...packageJson.scripts,
3360
- dev: "wrangler dev --port=3000",
3361
- start: "wrangler dev",
3362
- deploy: "wrangler deploy",
3363
- build: "wrangler deploy --dry-run",
3364
- "cf-typegen": "wrangler types --env-interface CloudflareBindings"
3365
- };
3366
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
3367
- await addPackageDependency({
3368
- devDependencies: ["wrangler", "@types/node"],
3369
- projectDir: serverDir
3370
- });
3371
- }
3372
- async function generateCloudflareWorkerTypes({ serverDir, packageManager }) {
3373
- if (!await fs.pathExists(serverDir)) return;
3374
- const s = spinner();
3375
- try {
3376
- s.start("Generating Cloudflare Workers types...");
3377
- await execa(getPackageExecutionCommand(packageManager, "wrangler types --env-interface CloudflareBindings"), {
3378
- cwd: serverDir,
3379
- shell: true
3380
- });
3381
- s.stop("Cloudflare Workers types generated successfully!");
3382
- } catch {
3383
- s.stop(pc.yellow("Failed to generate Cloudflare Workers types"));
3384
- const managerCmd = `${packageManager} run`;
3385
- log.warn(`Note: You can manually run 'cd apps/server && ${managerCmd} cf-typegen' in the project directory later`);
3386
- }
3387
- }
3388
- async function setupAlchemyServerDeploy(serverDir, _packageManager, projectDir) {
3300
+ async function setupAlchemyServerDeploy(serverDir, projectDir) {
3389
3301
  if (!await fs.pathExists(serverDir)) return;
3390
3302
  await addPackageDependency({
3391
3303
  devDependencies: [
@@ -3720,7 +3632,7 @@ async function setupCombinedAlchemyDeploy(projectDir, packageManager, config) {
3720
3632
  await fs.writeJson(rootPkgPath, pkg, { spaces: 2 });
3721
3633
  }
3722
3634
  const serverDir = path.join(projectDir, "apps/server");
3723
- if (await fs.pathExists(serverDir)) await setupAlchemyServerDeploy(serverDir, packageManager, projectDir);
3635
+ if (await fs.pathExists(serverDir)) await setupAlchemyServerDeploy(serverDir, projectDir);
3724
3636
  const frontend = config.frontend;
3725
3637
  const isNext = frontend.includes("next");
3726
3638
  const isNuxt = frontend.includes("nuxt");
@@ -3738,219 +3650,13 @@ async function setupCombinedAlchemyDeploy(projectDir, packageManager, config) {
3738
3650
  else if (isSolid) await setupSolidAlchemyDeploy(projectDir, packageManager, { skipAppScripts: true });
3739
3651
  }
3740
3652
 
3741
- //#endregion
3742
- //#region src/helpers/deployment/workers/workers-next-setup.ts
3743
- async function setupNextWorkersDeploy(projectDir, _packageManager) {
3744
- const webAppDir = path.join(projectDir, "apps/web");
3745
- if (!await fs.pathExists(webAppDir)) return;
3746
- await addPackageDependency({
3747
- dependencies: ["@opennextjs/cloudflare"],
3748
- devDependencies: ["wrangler"],
3749
- projectDir: webAppDir
3750
- });
3751
- const packageJsonPath = path.join(webAppDir, "package.json");
3752
- if (await fs.pathExists(packageJsonPath)) {
3753
- const pkg = await fs.readJson(packageJsonPath);
3754
- pkg.scripts = {
3755
- ...pkg.scripts,
3756
- preview: "opennextjs-cloudflare build && opennextjs-cloudflare preview",
3757
- deploy: "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
3758
- upload: "opennextjs-cloudflare build && opennextjs-cloudflare upload",
3759
- "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
3760
- };
3761
- await fs.writeJson(packageJsonPath, pkg, { spaces: 2 });
3762
- }
3763
- }
3764
-
3765
- //#endregion
3766
- //#region src/helpers/deployment/workers/workers-nuxt-setup.ts
3767
- async function setupNuxtWorkersDeploy(projectDir, packageManager) {
3768
- const webAppDir = path.join(projectDir, "apps/web");
3769
- if (!await fs.pathExists(webAppDir)) return;
3770
- await addPackageDependency({
3771
- devDependencies: ["nitro-cloudflare-dev", "wrangler"],
3772
- projectDir: webAppDir
3773
- });
3774
- const pkgPath = path.join(webAppDir, "package.json");
3775
- if (await fs.pathExists(pkgPath)) {
3776
- const pkg = await fs.readJson(pkgPath);
3777
- pkg.scripts = {
3778
- ...pkg.scripts,
3779
- deploy: `${packageManager} run build && wrangler deploy`,
3780
- "cf-typegen": "wrangler types"
3781
- };
3782
- await fs.writeJson(pkgPath, pkg, { spaces: 2 });
3783
- }
3784
- const nuxtConfigPath = path.join(webAppDir, "nuxt.config.ts");
3785
- if (!await fs.pathExists(nuxtConfigPath)) return;
3786
- const sourceFile = tsProject.addSourceFileAtPathIfExists(nuxtConfigPath);
3787
- if (!sourceFile) return;
3788
- const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((expr) => {
3789
- const expression = expr.getExpression();
3790
- return Node.isIdentifier(expression) && expression.getText() === "defineNuxtConfig";
3791
- });
3792
- if (!defineCall) return;
3793
- const configObj = defineCall.getArguments()[0];
3794
- if (!configObj) return;
3795
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3796
- const compatProp = configObj.getProperty("compatibilityDate");
3797
- if (compatProp && compatProp.getKind() === SyntaxKind.PropertyAssignment) compatProp.setInitializer(`'${today}'`);
3798
- else configObj.addPropertyAssignment({
3799
- name: "compatibilityDate",
3800
- initializer: `'${today}'`
3801
- });
3802
- const nitroInitializer = `{
3803
- preset: "cloudflare_module",
3804
- cloudflare: {
3805
- deployConfig: true,
3806
- nodeCompat: true
3807
- }
3808
- }`;
3809
- const nitroProp = configObj.getProperty("nitro");
3810
- if (nitroProp && nitroProp.getKind() === SyntaxKind.PropertyAssignment) nitroProp.setInitializer(nitroInitializer);
3811
- else configObj.addPropertyAssignment({
3812
- name: "nitro",
3813
- initializer: nitroInitializer
3814
- });
3815
- const modulesProp = configObj.getProperty("modules");
3816
- if (modulesProp && modulesProp.getKind() === SyntaxKind.PropertyAssignment) {
3817
- const arrayExpr = modulesProp.getFirstDescendantByKind(SyntaxKind.ArrayLiteralExpression);
3818
- if (arrayExpr) {
3819
- if (!arrayExpr.getElements().some((el) => el.getText().replace(/['"`]/g, "") === "nitro-cloudflare-dev")) arrayExpr.addElement("'nitro-cloudflare-dev'");
3820
- }
3821
- } else configObj.addPropertyAssignment({
3822
- name: "modules",
3823
- initializer: "['nitro-cloudflare-dev']"
3824
- });
3825
- await tsProject.save();
3826
- }
3827
-
3828
- //#endregion
3829
- //#region src/helpers/deployment/workers/workers-svelte-setup.ts
3830
- async function setupSvelteWorkersDeploy(projectDir, packageManager) {
3831
- const webAppDir = path.join(projectDir, "apps/web");
3832
- if (!await fs.pathExists(webAppDir)) return;
3833
- await addPackageDependency({
3834
- devDependencies: ["@sveltejs/adapter-cloudflare", "wrangler"],
3835
- projectDir: webAppDir
3836
- });
3837
- const pkgPath = path.join(webAppDir, "package.json");
3838
- if (await fs.pathExists(pkgPath)) {
3839
- const pkg = await fs.readJson(pkgPath);
3840
- pkg.scripts = {
3841
- ...pkg.scripts,
3842
- deploy: `${packageManager} run build && wrangler deploy`,
3843
- "cf-typegen": "wrangler types ./src/worker-configuration.d.ts"
3844
- };
3845
- await fs.writeJson(pkgPath, pkg, { spaces: 2 });
3846
- }
3847
- const possibleConfigFiles = [path.join(webAppDir, "svelte.config.js"), path.join(webAppDir, "svelte.config.ts")];
3848
- const existingConfigPath = (await Promise.all(possibleConfigFiles.map(async (p) => await fs.pathExists(p) ? p : ""))).find((p) => p);
3849
- if (existingConfigPath) {
3850
- const sourceFile = tsProject.addSourceFileAtPathIfExists(existingConfigPath);
3851
- if (!sourceFile) return;
3852
- const adapterImport = sourceFile.getImportDeclarations().find((imp) => ["@sveltejs/adapter-auto", "@sveltejs/adapter-node"].includes(imp.getModuleSpecifierValue()));
3853
- if (adapterImport) adapterImport.setModuleSpecifier("@sveltejs/adapter-cloudflare");
3854
- else if (!sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === "@sveltejs/adapter-cloudflare")) sourceFile.insertImportDeclaration(0, {
3855
- defaultImport: "adapter",
3856
- moduleSpecifier: "@sveltejs/adapter-cloudflare"
3857
- });
3858
- await tsProject.save();
3859
- }
3860
- }
3861
-
3862
- //#endregion
3863
- //#region src/helpers/deployment/workers/workers-tanstack-start-setup.ts
3864
- async function setupTanstackStartWorkersDeploy(projectDir, packageManager) {
3865
- const webAppDir = path.join(projectDir, "apps/web");
3866
- if (!await fs.pathExists(webAppDir)) return;
3867
- await addPackageDependency({
3868
- devDependencies: ["wrangler", "@cloudflare/vite-plugin"],
3869
- projectDir: webAppDir
3870
- });
3871
- const pkgPath = path.join(webAppDir, "package.json");
3872
- if (await fs.pathExists(pkgPath)) {
3873
- const pkg = await fs.readJson(pkgPath);
3874
- pkg.scripts = {
3875
- ...pkg.scripts,
3876
- deploy: `${packageManager} run build && wrangler deploy`,
3877
- "cf-typegen": "wrangler types --env-interface Env"
3878
- };
3879
- await fs.writeJson(pkgPath, pkg, { spaces: 2 });
3880
- }
3881
- const viteConfigPath = path.join(webAppDir, "vite.config.ts");
3882
- if (!await fs.pathExists(viteConfigPath)) return;
3883
- const sourceFile = tsProject.addSourceFileAtPathIfExists(viteConfigPath);
3884
- if (!sourceFile) return;
3885
- const cfImport = sourceFile.getImportDeclaration("@cloudflare/vite-plugin");
3886
- if (!cfImport) sourceFile.addImportDeclaration({
3887
- moduleSpecifier: "@cloudflare/vite-plugin",
3888
- namedImports: [{ name: "cloudflare" }]
3889
- });
3890
- else if (!cfImport.getNamedImports().some((ni) => ni.getName() === "cloudflare")) cfImport.addNamedImport({ name: "cloudflare" });
3891
- const reactImport = sourceFile.getImportDeclaration("@vitejs/plugin-react");
3892
- let reactPluginIdentifier = "viteReact";
3893
- if (!reactImport) sourceFile.addImportDeclaration({
3894
- moduleSpecifier: "@vitejs/plugin-react",
3895
- defaultImport: "viteReact"
3896
- });
3897
- else {
3898
- const defaultImport = reactImport.getDefaultImport();
3899
- if (defaultImport) reactPluginIdentifier = defaultImport.getText();
3900
- else reactImport.setDefaultImport("viteReact");
3901
- }
3902
- const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((expr) => {
3903
- const expression = expr.getExpression();
3904
- return Node.isIdentifier(expression) && expression.getText() === "defineConfig";
3905
- });
3906
- if (!defineCall) return;
3907
- const configObj = defineCall.getArguments()[0];
3908
- if (!configObj) return;
3909
- const pluginsArray = ensureArrayProperty(configObj, "plugins");
3910
- if (!pluginsArray.getElements().some((el) => el.getText().includes("cloudflare("))) pluginsArray.insertElement(0, "cloudflare({ viteEnvironment: { name: 'ssr' } })");
3911
- if (!pluginsArray.getElements().some((el) => Node.isCallExpression(el) && el.getExpression().getText() === reactPluginIdentifier)) {
3912
- const nextIndex = pluginsArray.getElements().findIndex((el) => el.getText().includes("tanstackStart(")) + 1;
3913
- if (nextIndex > 0) pluginsArray.insertElement(nextIndex, `${reactPluginIdentifier}()`);
3914
- else pluginsArray.addElement(`${reactPluginIdentifier}()`);
3915
- }
3916
- await tsProject.save();
3917
- }
3918
-
3919
- //#endregion
3920
- //#region src/helpers/deployment/workers/workers-vite-setup.ts
3921
- async function setupWorkersVitePlugin(projectDir) {
3922
- const webAppDir = path.join(projectDir, "apps/web");
3923
- const viteConfigPath = path.join(webAppDir, "vite.config.ts");
3924
- if (!await fs.pathExists(viteConfigPath)) throw new Error("vite.config.ts not found in web app directory");
3925
- await addPackageDependency({
3926
- devDependencies: ["@cloudflare/vite-plugin", "wrangler"],
3927
- projectDir: webAppDir
3928
- });
3929
- const sourceFile = tsProject.addSourceFileAtPathIfExists(viteConfigPath);
3930
- if (!sourceFile) throw new Error("vite.config.ts not found in web app directory");
3931
- if (!sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === "@cloudflare/vite-plugin")) sourceFile.insertImportDeclaration(0, {
3932
- namedImports: ["cloudflare"],
3933
- moduleSpecifier: "@cloudflare/vite-plugin"
3934
- });
3935
- const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((expr) => {
3936
- const expression = expr.getExpression();
3937
- return Node.isIdentifier(expression) && expression.getText() === "defineConfig";
3938
- });
3939
- if (!defineCall) throw new Error("Could not find defineConfig call in vite config");
3940
- const configObject = defineCall.getArguments()[0];
3941
- if (!configObject) throw new Error("defineConfig argument is not an object literal");
3942
- const pluginsArray = ensureArrayProperty(configObject, "plugins");
3943
- if (!pluginsArray.getElements().some((el) => el.getText().includes("cloudflare("))) pluginsArray.addElement("cloudflare()");
3944
- await tsProject.save();
3945
- }
3946
-
3947
3653
  //#endregion
3948
3654
  //#region src/helpers/deployment/web-deploy-setup.ts
3949
3655
  async function setupWebDeploy(config) {
3950
3656
  const { webDeploy, serverDeploy, frontend, projectDir } = config;
3951
3657
  const { packageManager } = config;
3952
3658
  if (webDeploy === "none") return;
3953
- if (webDeploy !== "wrangler" && webDeploy !== "alchemy") return;
3659
+ if (webDeploy !== "alchemy") return;
3954
3660
  if (webDeploy === "alchemy" && serverDeploy === "alchemy") {
3955
3661
  await setupCombinedAlchemyDeploy(projectDir, packageManager, config);
3956
3662
  await addAlchemyPackagesDependencies(projectDir);
@@ -3963,37 +3669,14 @@ async function setupWebDeploy(config) {
3963
3669
  const isTanstackStart = frontend.includes("tanstack-start");
3964
3670
  const isReactRouter = frontend.includes("react-router");
3965
3671
  const isSolid = frontend.includes("solid");
3966
- if (webDeploy === "wrangler") {
3967
- if (isNext) await setupNextWorkersDeploy(projectDir, packageManager);
3968
- else if (isNuxt) await setupNuxtWorkersDeploy(projectDir, packageManager);
3969
- else if (isSvelte) await setupSvelteWorkersDeploy(projectDir, packageManager);
3970
- else if (isTanstackStart) await setupTanstackStartWorkersDeploy(projectDir, packageManager);
3971
- else if (isTanstackRouter || isReactRouter || isSolid) await setupWorkersWebDeploy(projectDir, packageManager);
3972
- } else if (webDeploy === "alchemy") {
3973
- if (isNext) await setupNextAlchemyDeploy(projectDir, packageManager);
3974
- else if (isNuxt) await setupNuxtAlchemyDeploy(projectDir, packageManager);
3975
- else if (isSvelte) await setupSvelteAlchemyDeploy(projectDir, packageManager);
3976
- else if (isTanstackStart) await setupTanStackStartAlchemyDeploy(projectDir, packageManager);
3977
- else if (isTanstackRouter) await setupTanStackRouterAlchemyDeploy(projectDir, packageManager);
3978
- else if (isReactRouter) await setupReactRouterAlchemyDeploy(projectDir, packageManager);
3979
- else if (isSolid) await setupSolidAlchemyDeploy(projectDir, packageManager);
3980
- await addAlchemyPackagesDependencies(projectDir);
3981
- }
3982
- }
3983
- async function setupWorkersWebDeploy(projectDir, pkgManager) {
3984
- const webAppDir = path.join(projectDir, "apps/web");
3985
- if (!await fs.pathExists(webAppDir)) return;
3986
- const packageJsonPath = path.join(webAppDir, "package.json");
3987
- if (await fs.pathExists(packageJsonPath)) {
3988
- const packageJson = await fs.readJson(packageJsonPath);
3989
- packageJson.scripts = {
3990
- ...packageJson.scripts,
3991
- "wrangler:dev": "wrangler dev --port=3001",
3992
- deploy: `${pkgManager} run build && wrangler deploy`
3993
- };
3994
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
3995
- }
3996
- await setupWorkersVitePlugin(projectDir);
3672
+ if (isNext) await setupNextAlchemyDeploy(projectDir, packageManager);
3673
+ else if (isNuxt) await setupNuxtAlchemyDeploy(projectDir, packageManager);
3674
+ else if (isSvelte) await setupSvelteAlchemyDeploy(projectDir, packageManager);
3675
+ else if (isTanstackStart) await setupTanStackStartAlchemyDeploy(projectDir, packageManager);
3676
+ else if (isTanstackRouter) await setupTanStackRouterAlchemyDeploy(projectDir, packageManager);
3677
+ else if (isReactRouter) await setupReactRouterAlchemyDeploy(projectDir, packageManager);
3678
+ else if (isSolid) await setupSolidAlchemyDeploy(projectDir, packageManager);
3679
+ await addAlchemyPackagesDependencies(projectDir);
3997
3680
  }
3998
3681
  async function addAlchemyPackagesDependencies(projectDir) {
3999
3682
  await addPackageDependency({
@@ -4854,7 +4537,7 @@ ${hasWeb ? "# npx convex env set SITE_URL http://localhost:3001\n" : ""}
4854
4537
  databaseUrl = "mongodb://localhost:27017/mydatabase";
4855
4538
  break;
4856
4539
  case "sqlite":
4857
- if (config.runtime === "workers" || webDeploy === "wrangler" || serverDeploy === "wrangler" || webDeploy === "alchemy" || serverDeploy === "alchemy") databaseUrl = "http://127.0.0.1:8080";
4540
+ if (config.runtime === "workers" || webDeploy === "alchemy" || serverDeploy === "alchemy") databaseUrl = "http://127.0.0.1:8080";
4858
4541
  else {
4859
4542
  const dbAppDir = backend === "self" ? "apps/web" : "apps/server";
4860
4543
  databaseUrl = `file:${path.join(config.projectDir, dbAppDir, "local.db")}`;
@@ -4936,31 +4619,7 @@ ${hasWeb ? "# npx convex env set SITE_URL http://localhost:3001\n" : ""}
4936
4619
  //#region src/helpers/database-providers/d1-setup.ts
4937
4620
  async function setupCloudflareD1(config) {
4938
4621
  const { projectDir, serverDeploy, orm, backend } = config;
4939
- if (serverDeploy === "wrangler") {
4940
- const targetApp = backend === "self" ? "apps/web" : "apps/server";
4941
- const envPath = path.join(projectDir, targetApp, ".env");
4942
- const variables = [
4943
- {
4944
- key: "CLOUDFLARE_ACCOUNT_ID",
4945
- value: "",
4946
- condition: true
4947
- },
4948
- {
4949
- key: "CLOUDFLARE_DATABASE_ID",
4950
- value: "",
4951
- condition: true
4952
- },
4953
- {
4954
- key: "CLOUDFLARE_D1_TOKEN",
4955
- value: "",
4956
- condition: true
4957
- }
4958
- ];
4959
- try {
4960
- await addEnvVariablesToFile(envPath, variables);
4961
- } catch (_err) {}
4962
- }
4963
- if ((serverDeploy === "wrangler" || serverDeploy === "alchemy") && orm === "prisma") {
4622
+ if (serverDeploy === "alchemy" && orm === "prisma") {
4964
4623
  const targetApp2 = backend === "self" ? "apps/web" : "apps/server";
4965
4624
  const envPath = path.join(projectDir, targetApp2, ".env");
4966
4625
  const variables = [{
@@ -5407,7 +5066,7 @@ const AVAILABLE_REGIONS = [
5407
5066
  label: "US West (N. California)"
5408
5067
  }
5409
5068
  ];
5410
- async function setupWithCreateDb(serverDir, packageManager, orm) {
5069
+ async function setupWithCreateDb(serverDir, packageManager) {
5411
5070
  try {
5412
5071
  log.info("Starting Prisma Postgres setup with create-db.");
5413
5072
  const selectedRegion = await select({
@@ -5432,7 +5091,7 @@ async function setupWithCreateDb(serverDir, packageManager, orm) {
5432
5091
  return null;
5433
5092
  }
5434
5093
  return {
5435
- databaseUrl: orm === "drizzle" ? createDbResponse.directConnectionString : createDbResponse.connectionString,
5094
+ databaseUrl: createDbResponse.connectionString,
5436
5095
  claimUrl: createDbResponse.claimUrl
5437
5096
  };
5438
5097
  } catch (error) {
@@ -5450,12 +5109,12 @@ async function initPrismaDatabase(serverDir, packageManager) {
5450
5109
  stdio: "inherit",
5451
5110
  shell: true
5452
5111
  });
5453
- log.info(pc.yellow("Please copy the Prisma Postgres URL from the output above.\nIt looks like: prisma+postgres://accelerate.prisma-data.net/?api_key=..."));
5112
+ log.info(pc.yellow("Please copy the Prisma Postgres URL.\nIt looks like: postgresql://user:password@host:5432/db?sslmode=require"));
5454
5113
  const databaseUrl = await text({
5455
5114
  message: "Paste your Prisma Postgres database URL:",
5456
5115
  validate(value) {
5457
5116
  if (!value) return "Please enter a database URL";
5458
- if (!value.startsWith("prisma+postgres://")) return "URL should start with prisma+postgres://";
5117
+ if (!value.startsWith("postgresql://")) return "URL should start with postgresql://";
5459
5118
  }
5460
5119
  });
5461
5120
  if (isCancel(databaseUrl)) return null;
@@ -5504,18 +5163,6 @@ function displayManualSetupInstructions$1(target) {
5504
5163
 
5505
5164
  DATABASE_URL="your_database_url"`);
5506
5165
  }
5507
- async function addPrismaAccelerateExtension(projectDir) {
5508
- try {
5509
- await addPackageDependency({
5510
- dependencies: ["@prisma/extension-accelerate"],
5511
- projectDir: path.join(projectDir, "packages/db")
5512
- });
5513
- return true;
5514
- } catch (_error) {
5515
- log.warn(pc.yellow("Could not add Prisma Accelerate extension automatically"));
5516
- return false;
5517
- }
5518
- }
5519
5166
  async function setupPrismaPostgres(config, cliInput) {
5520
5167
  const { packageManager, projectDir, orm, backend } = config;
5521
5168
  const manualDb = cliInput?.manualDb ?? false;
@@ -5563,16 +5210,12 @@ async function setupPrismaPostgres(config, cliInput) {
5563
5210
  });
5564
5211
  if (isCancel(setupMethod)) return exitCancelled("Operation cancelled");
5565
5212
  let prismaConfig = null;
5566
- if (setupMethod === "create-db") prismaConfig = await setupWithCreateDb(dbDir, packageManager, orm);
5213
+ if (setupMethod === "create-db") prismaConfig = await setupWithCreateDb(dbDir, packageManager);
5567
5214
  else prismaConfig = await initPrismaDatabase(dbDir, packageManager);
5568
5215
  if (prismaConfig) {
5569
5216
  await writeEnvFile$1(projectDir, backend, prismaConfig);
5570
- if (orm === "prisma") {
5571
- await addDotenvImportToPrismaConfig(projectDir, backend);
5572
- await addPrismaAccelerateExtension(projectDir);
5573
- }
5574
- const connectionType = orm === "drizzle" ? "direct connection" : "Prisma Accelerate";
5575
- log.success(pc.green(`Prisma Postgres database configured successfully with ${connectionType}!`));
5217
+ if (orm === "prisma") await addDotenvImportToPrismaConfig(projectDir, backend);
5218
+ log.success(pc.green("Prisma Postgres database configured successfully!"));
5576
5219
  if (prismaConfig.claimUrl) log.info(pc.blue(`Claim URL saved to .env: ${prismaConfig.claimUrl}`));
5577
5220
  } else {
5578
5221
  await writeEnvFile$1(projectDir, backend);
@@ -5968,40 +5611,57 @@ async function setupDatabase(config, cliInput) {
5968
5611
  }
5969
5612
  const s = spinner();
5970
5613
  const dbPackageDir = path.join(projectDir, "packages/db");
5614
+ const webDir = path.join(projectDir, "apps/web");
5971
5615
  if (!await fs.pathExists(dbPackageDir)) return;
5972
5616
  try {
5973
5617
  if (orm === "prisma") {
5974
- if (database === "mysql" && dbSetup === "planetscale") await addPackageDependency({
5975
- dependencies: [
5976
- "@prisma/client",
5977
- "@prisma/adapter-planetscale",
5978
- "@planetscale/database"
5979
- ],
5980
- devDependencies: ["prisma"],
5618
+ if (database === "mongodb") await addPackageDependency({
5619
+ customDependencies: { "@prisma/client": "6.19.0" },
5620
+ customDevDependencies: { prisma: "6.19.0" },
5981
5621
  projectDir: dbPackageDir
5982
5622
  });
5983
- else if (database === "sqlite" && dbSetup === "turso") await addPackageDependency({
5984
- dependencies: ["@prisma/client", "@prisma/adapter-libsql"],
5985
- devDependencies: ["prisma"],
5986
- projectDir: dbPackageDir
5623
+ else {
5624
+ const prismaDependencies = ["@prisma/client"];
5625
+ const prismaDevDependencies = ["prisma"];
5626
+ if (database === "mysql" && dbSetup === "planetscale") prismaDependencies.push("@prisma/adapter-planetscale", "@planetscale/database");
5627
+ else if (database === "mysql") prismaDependencies.push("@prisma/adapter-mariadb");
5628
+ else if (database === "sqlite") prismaDependencies.push("@prisma/adapter-libsql");
5629
+ else if (database === "postgres") if (dbSetup === "neon") prismaDependencies.push("@prisma/adapter-neon");
5630
+ else {
5631
+ prismaDependencies.push("@prisma/adapter-pg");
5632
+ prismaDependencies.push("pg");
5633
+ prismaDevDependencies.push("@types/pg");
5634
+ }
5635
+ await addPackageDependency({
5636
+ dependencies: prismaDependencies,
5637
+ devDependencies: prismaDevDependencies,
5638
+ projectDir: dbPackageDir
5639
+ });
5640
+ }
5641
+ if (await fs.pathExists(webDir)) if (database === "mongodb") await addPackageDependency({
5642
+ customDependencies: { "@prisma/client": "6.19.0" },
5643
+ projectDir: webDir
5987
5644
  });
5988
5645
  else await addPackageDependency({
5989
- dependencies: ["@prisma/client"],
5990
- devDependencies: ["prisma"],
5991
- projectDir: dbPackageDir
5992
- });
5993
- const webDir = path.join(projectDir, "apps/web");
5994
- if (await fs.pathExists(webDir)) await addPackageDependency({
5995
5646
  dependencies: ["@prisma/client"],
5996
5647
  projectDir: webDir
5997
5648
  });
5998
5649
  } else if (orm === "drizzle") {
5999
- if (database === "sqlite") await addPackageDependency({
6000
- dependencies: ["drizzle-orm", "@libsql/client"],
6001
- devDependencies: ["drizzle-kit"],
6002
- projectDir: dbPackageDir
6003
- });
6004
- else if (database === "postgres") if (dbSetup === "neon") await addPackageDependency({
5650
+ if (database === "sqlite") {
5651
+ await addPackageDependency({
5652
+ dependencies: [
5653
+ "drizzle-orm",
5654
+ "@libsql/client",
5655
+ "libsql"
5656
+ ],
5657
+ devDependencies: ["drizzle-kit"],
5658
+ projectDir: dbPackageDir
5659
+ });
5660
+ await addPackageDependency({
5661
+ dependencies: ["@libsql/client", "libsql"],
5662
+ projectDir: webDir
5663
+ });
5664
+ } else if (database === "postgres") if (dbSetup === "neon") await addPackageDependency({
6005
5665
  dependencies: [
6006
5666
  "drizzle-orm",
6007
5667
  "@neondatabase/serverless",
@@ -6320,7 +5980,7 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
6320
5980
  else if (addon === "turborepo") addonsList.push("- **Turborepo** - Optimized monorepo build system");
6321
5981
  return addonsList.join("\n");
6322
5982
  }
6323
- function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm, dbSetup, serverDeploy, backend) {
5983
+ function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm, dbSetup, _serverDeploy, backend) {
6324
5984
  if (database === "none") return "";
6325
5985
  const isBackendSelf = backend === "self";
6326
5986
  const envPath = isBackendSelf ? "apps/web/.env" : "apps/server/.env";
@@ -6329,7 +5989,7 @@ function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm, dbSet
6329
5989
  if (database === "sqlite") setup += `This project uses SQLite${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
6330
5990
 
6331
5991
  1. Start the local SQLite database:
6332
- ${dbSetup === "d1" ? serverDeploy === "alchemy" ? "D1 local development and migrations are handled automatically by Alchemy during dev and deploy." : "Local development for a Cloudflare D1 database will already be running as part of the `wrangler dev` command." : `\`\`\`bash
5992
+ ${dbSetup === "d1" ? "D1 local development and migrations are handled automatically by Alchemy during dev and deploy." : `\`\`\`bash
6333
5993
  cd ${dbLocalPath} && ${packageManagerRunCmd} db:local
6334
5994
  \`\`\`
6335
5995
  `}
@@ -6427,11 +6087,6 @@ function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeplo
6427
6087
  if (serverDeploy === "alchemy" && webDeploy !== "alchemy") lines.push(`- Server dev: cd apps/server && ${packageManagerRunCmd} dev`, `- Server deploy: cd apps/server && ${packageManagerRunCmd} deploy`, `- Server destroy: cd apps/server && ${packageManagerRunCmd} destroy`);
6428
6088
  if (webDeploy === "alchemy" && serverDeploy === "alchemy") lines.push(`- Dev: ${packageManagerRunCmd} dev`, `- Deploy: ${packageManagerRunCmd} deploy`, `- Destroy: ${packageManagerRunCmd} destroy`);
6429
6089
  }
6430
- if (webDeploy === "wrangler" || serverDeploy === "wrangler") {
6431
- lines.push("\n## Deployment (Cloudflare Wrangler)");
6432
- if (webDeploy === "wrangler") lines.push(`- Web deploy: cd apps/web && ${packageManagerRunCmd} deploy`);
6433
- if (serverDeploy === "wrangler") lines.push(`- Server dev: cd apps/server && ${packageManagerRunCmd} dev`, `- Server deploy: cd apps/server && ${packageManagerRunCmd} deploy`);
6434
- }
6435
6090
  return lines.length ? `\n${lines.join("\n")}\n` : "";
6436
6091
  }
6437
6092
 
@@ -6555,7 +6210,6 @@ async function displayPostInstallInstructions(config) {
6555
6210
  const starlightInstructions = addons?.includes("starlight") ? getStarlightInstructions(runCmd) : "";
6556
6211
  const clerkInstructions = isConvex && config.auth === "clerk" ? getClerkInstructions() : "";
6557
6212
  const polarInstructions = config.payments === "polar" && config.auth === "better-auth" ? getPolarInstructions(backend) : "";
6558
- const wranglerDeployInstructions = getWranglerDeployInstructions(runCmd, webDeploy, serverDeploy, backend);
6559
6213
  const alchemyDeployInstructions = getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend);
6560
6214
  const hasWeb = frontend?.some((f) => [
6561
6215
  "tanstack-router",
@@ -6575,7 +6229,7 @@ async function displayPostInstallInstructions(config) {
6575
6229
  let output = `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
6576
6230
  let stepCounter = 2;
6577
6231
  if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} ${packageManager} install\n`;
6578
- if (database === "sqlite" && dbSetup === "none" && (serverDeploy === "wrangler" || serverDeploy === "alchemy" || webDeploy === "wrangler" || webDeploy === "alchemy")) output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} db:local\n${pc.dim(" (starts local SQLite server for Workers compatibility)")}\n`;
6232
+ if (database === "sqlite" && dbSetup === "none" && (serverDeploy === "alchemy" || webDeploy === "alchemy")) output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} db:local\n${pc.dim(" (starts local SQLite server for Workers compatibility)")}\n`;
6579
6233
  if (isConvex) {
6580
6234
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup\n${pc.dim(" (this will guide you through Convex project setup)")}\n`;
6581
6235
  output += `${pc.cyan(`${stepCounter++}.`)} Copy environment variables from\n${pc.white(" packages/backend/.env.local")} to ${pc.white("apps/*/.env")}\n`;
@@ -6586,7 +6240,6 @@ async function displayPostInstallInstructions(config) {
6586
6240
  if (runtime === "workers") {
6587
6241
  if (dbSetup === "d1") output += `${pc.yellow("IMPORTANT:")} Complete D1 database setup first\n (see Database commands below)\n`;
6588
6242
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
6589
- if (serverDeploy === "wrangler") output += `${pc.cyan(`${stepCounter++}.`)} cd apps/server && ${runCmd} cf-typegen\n`;
6590
6243
  }
6591
6244
  }
6592
6245
  output += `${pc.bold("Your project will be available at:")}\n`;
@@ -6604,7 +6257,6 @@ async function displayPostInstallInstructions(config) {
6604
6257
  if (tauriInstructions) output += `\n${tauriInstructions.trim()}\n`;
6605
6258
  if (lintingInstructions) output += `\n${lintingInstructions.trim()}\n`;
6606
6259
  if (pwaInstructions) output += `\n${pwaInstructions.trim()}\n`;
6607
- if (wranglerDeployInstructions) output += `\n${wranglerDeployInstructions.trim()}\n`;
6608
6260
  if (alchemyDeployInstructions) output += `\n${alchemyDeployInstructions.trim()}\n`;
6609
6261
  if (starlightInstructions) output += `\n${starlightInstructions.trim()}\n`;
6610
6262
  if (clerkInstructions) output += `\n${clerkInstructions.trim()}\n`;
@@ -6627,7 +6279,7 @@ function getNativeInstructions(isConvex, isBackendSelf, _frontend) {
6627
6279
  function getLintingInstructions(runCmd) {
6628
6280
  return `${pc.bold("Linting and formatting:")}\n${pc.cyan("•")} Format and lint fix: ${`${runCmd} check`}\n`;
6629
6281
  }
6630
- async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup, serverDeploy, backend) {
6282
+ async function getDatabaseInstructions(database, orm, runCmd, _runtime, dbSetup, serverDeploy, _backend) {
6631
6283
  const instructions = [];
6632
6284
  if (dbSetup === "docker") {
6633
6285
  const dockerStatus = await getDockerStatus(database);
@@ -6636,17 +6288,6 @@ async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup,
6636
6288
  instructions.push("");
6637
6289
  }
6638
6290
  }
6639
- if (serverDeploy === "wrangler" && dbSetup === "d1") {
6640
- if (orm === "prisma" && runtime === "workers") instructions.push(`\n${pc.yellow("WARNING:")} Prisma + D1 on Workers with Wrangler has migration issues.\n Consider using Alchemy deploy instead of Wrangler for D1 projects.\n`);
6641
- const packageManager = runCmd === "npm run" ? "npm" : runCmd || "npm";
6642
- instructions.push(`${pc.cyan("1.")} Login to Cloudflare: ${pc.white(`${packageManager} wrangler login`)}`);
6643
- instructions.push(`${pc.cyan("2.")} Create D1 database: ${pc.white(`${packageManager} wrangler d1 create your-database-name`)}`);
6644
- const wranglerPath = backend === "self" ? "apps/web" : "apps/server";
6645
- instructions.push(`${pc.cyan("3.")} Update ${wranglerPath}/wrangler.jsonc with database_id and database_name`);
6646
- instructions.push(`${pc.cyan("4.")} Generate migrations: ${pc.white(`cd ${wranglerPath} && ${runCmd} db:generate`)}`);
6647
- instructions.push(`${pc.cyan("5.")} Apply migrations locally: ${pc.white(`${packageManager} wrangler d1 migrations apply YOUR_DB_NAME --local`)}`);
6648
- instructions.push(`${pc.cyan("6.")} Apply migrations to production: ${pc.white(`${packageManager} wrangler d1 migrations apply YOUR_DB_NAME`)}`);
6649
- }
6650
6291
  if (dbSetup === "d1" && serverDeploy === "alchemy") {
6651
6292
  if (orm === "drizzle") instructions.push(`${pc.yellow("NOTE:")} D1 migrations are automatically handled by Alchemy`);
6652
6293
  else if (orm === "prisma") {
@@ -6661,7 +6302,10 @@ async function getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup,
6661
6302
  if (orm === "prisma") {
6662
6303
  if (database === "mongodb" && dbSetup === "docker") instructions.push(`${pc.yellow("WARNING:")} Prisma + MongoDB + Docker combination\n may not work.`);
6663
6304
  if (dbSetup === "docker") instructions.push(`${pc.cyan("•")} Start docker container: ${`${runCmd} db:start`}`);
6664
- if (!(dbSetup === "d1" && serverDeploy === "alchemy")) instructions.push(`${pc.cyan("•")} Apply schema: ${`${runCmd} db:push`}`);
6305
+ if (!(dbSetup === "d1" && serverDeploy === "alchemy")) {
6306
+ instructions.push(`${pc.cyan("•")} Generate Prisma Client: ${`${runCmd} db:generate`}`);
6307
+ instructions.push(`${pc.cyan("•")} Apply schema: ${`${runCmd} db:push`}`);
6308
+ }
6665
6309
  if (!(dbSetup === "d1" && serverDeploy === "alchemy")) instructions.push(`${pc.cyan("•")} Database UI: ${`${runCmd} db:studio`}`);
6666
6310
  } else if (orm === "drizzle") {
6667
6311
  if (dbSetup === "docker") instructions.push(`${pc.cyan("•")} Start docker container: ${`${runCmd} db:start`}`);
@@ -6687,15 +6331,6 @@ function getNoOrmWarning() {
6687
6331
  function getBunWebNativeWarning() {
6688
6332
  return `\n${pc.yellow("WARNING:")} 'bun' might cause issues with web + native apps in a monorepo.\n Use 'pnpm' if problems arise.`;
6689
6333
  }
6690
- function getWranglerDeployInstructions(runCmd, webDeploy, serverDeploy, backend) {
6691
- const instructions = [];
6692
- if (webDeploy === "wrangler") {
6693
- const deployPath = backend === "self" ? "apps/web" : "apps/web";
6694
- instructions.push(`${pc.bold("Deploy web to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd ${deployPath} && ${runCmd} deploy`}`);
6695
- }
6696
- if (serverDeploy === "wrangler" && backend !== "self") instructions.push(`${pc.bold("Deploy server to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} deploy`}`);
6697
- return instructions.length ? `\n${instructions.join("\n")}` : "";
6698
- }
6699
6334
  function getClerkInstructions() {
6700
6335
  return `${pc.bold("Clerk Authentication Setup:")}\n${pc.cyan("•")} Follow the guide: ${pc.underline("https://docs.convex.dev/auth/clerk")}\n${pc.cyan("•")} Set CLERK_JWT_ISSUER_DOMAIN in Convex Dashboard\n${pc.cyan("•")} Set CLERK_PUBLISHABLE_KEY in apps/*/.env`;
6701
6336
  }
@@ -6706,7 +6341,7 @@ function getPolarInstructions(backend) {
6706
6341
  function getAlchemyDeployInstructions(runCmd, webDeploy, serverDeploy, backend) {
6707
6342
  const instructions = [];
6708
6343
  const isBackendSelf = backend === "self";
6709
- if (webDeploy === "alchemy" && serverDeploy !== "alchemy") instructions.push(`${pc.bold("Deploy web with Alchemy:")}\n${pc.cyan("•")} Dev: ${`cd apps/web && ${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`cd apps/web && ${runCmd} destroy`}`);
6344
+ if (webDeploy === "alchemy" && serverDeploy !== "alchemy") instructions.push(`${pc.bold("Deploy web with Alchemy:")}\n${pc.cyan("•")} Dev: ${`cd apps/web && ${runCmd} alchemy dev`}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`cd apps/web && ${runCmd} destroy`}`);
6710
6345
  else if (serverDeploy === "alchemy" && webDeploy !== "alchemy" && !isBackendSelf) instructions.push(`${pc.bold("Deploy server with Alchemy:")}\n${pc.cyan("•")} Dev: ${`cd apps/server && ${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`cd apps/server && ${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`cd apps/server && ${runCmd} destroy`}`);
6711
6346
  else if (webDeploy === "alchemy" && (serverDeploy === "alchemy" || isBackendSelf)) instructions.push(`${pc.bold("Deploy with Alchemy:")}\n${pc.cyan("•")} Dev: ${`${runCmd} dev`}\n${pc.cyan("•")} Deploy: ${`${runCmd} deploy`}\n${pc.cyan("•")} Destroy: ${`${runCmd} destroy`}`);
6712
6347
  return instructions.length ? `\n${instructions.join("\n")}` : "";
@@ -6718,7 +6353,7 @@ async function setupWorkspaceDependencies(projectDir, options) {
6718
6353
  const projectName = options.projectName;
6719
6354
  const workspaceVersion = options.packageManager === "npm" ? "*" : "workspace:*";
6720
6355
  const commonDeps = ["dotenv", "zod"];
6721
- const commonDevDeps = ["tsdown"];
6356
+ const commonDevDeps = [];
6722
6357
  const configPackageDir = path.join(projectDir, "packages/config");
6723
6358
  const configDep = {};
6724
6359
  if (await fs.pathExists(configPackageDir)) configDep[`@${projectName}/config`] = workspaceVersion;
@@ -6762,7 +6397,7 @@ async function setupWorkspaceDependencies(projectDir, options) {
6762
6397
  if (options.database !== "none" && await fs.pathExists(dbPackageDir)) serverDeps[`@${projectName}/db`] = workspaceVersion;
6763
6398
  await addPackageDependency({
6764
6399
  dependencies: commonDeps,
6765
- devDependencies: commonDevDeps,
6400
+ devDependencies: [...commonDevDeps, "tsdown"],
6766
6401
  customDependencies: serverDeps,
6767
6402
  customDevDependencies: configDep,
6768
6403
  projectDir: serverPackageDir