create-better-t-stack 2.23.0 → 2.24.0

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.
package/dist/index.js CHANGED
@@ -834,14 +834,6 @@ async function getRuntimeChoice(runtime, backend) {
834
834
 
835
835
  //#endregion
836
836
  //#region src/prompts/web-deploy.ts
837
- const WORKERS_COMPATIBLE_FRONTENDS = [
838
- "tanstack-router",
839
- "react-router",
840
- "solid",
841
- "next",
842
- "nuxt",
843
- "svelte"
844
- ];
845
837
  function getDeploymentDisplay(deployment) {
846
838
  if (deployment === "workers") return {
847
839
  label: "Cloudflare Workers",
@@ -852,10 +844,8 @@ function getDeploymentDisplay(deployment) {
852
844
  hint: `Add ${deployment} deployment`
853
845
  };
854
846
  }
855
- async function getDeploymentChoice(deployment, _runtime, _backend, frontend = []) {
847
+ async function getDeploymentChoice(deployment, _runtime, _backend, _frontend = []) {
856
848
  if (deployment !== void 0) return deployment;
857
- const hasCompatibleFrontend = frontend.some((f) => WORKERS_COMPATIBLE_FRONTENDS.includes(f));
858
- if (!hasCompatibleFrontend) return "none";
859
849
  const options = [{
860
850
  value: "workers",
861
851
  label: "Cloudflare Workers",
@@ -876,9 +866,9 @@ async function getDeploymentChoice(deployment, _runtime, _backend, frontend = []
876
866
  }
877
867
  return response;
878
868
  }
879
- async function getDeploymentToAdd(frontend, existingDeployment) {
869
+ async function getDeploymentToAdd(_frontend, existingDeployment) {
880
870
  const options = [];
881
- if (frontend.some((f) => WORKERS_COMPATIBLE_FRONTENDS.includes(f)) && existingDeployment !== "workers") {
871
+ if (existingDeployment !== "workers") {
882
872
  const { label, hint } = getDeploymentDisplay("workers");
883
873
  options.push({
884
874
  value: "workers",
@@ -1483,13 +1473,6 @@ function processAndValidateFlags(options, providedFlags, projectName) {
1483
1473
  consola$1.fatal("MongoDB database is not compatible with Cloudflare Workers runtime. MongoDB requires Prisma or Mongoose ORM, but Workers runtime only supports Drizzle ORM. Please use a different database or runtime.");
1484
1474
  process.exit(1);
1485
1475
  }
1486
- if (config.webDeploy === "workers" && config.frontend && config.frontend.length > 0) {
1487
- const incompatibleFrontends = config.frontend.filter((f) => f === "tanstack-start");
1488
- if (incompatibleFrontends.length > 0) {
1489
- consola$1.fatal(`The following frontends are not compatible with '--web-deploy workers': ${incompatibleFrontends.join(", ")}. Please choose a different frontend or remove '--web-deploy workers'.`);
1490
- process.exit(1);
1491
- }
1492
- }
1493
1476
  return config;
1494
1477
  }
1495
1478
  function getProvidedFlags(options) {
@@ -2283,6 +2266,7 @@ async function setupDeploymentTemplates(projectDir, context) {
2283
2266
  const frontends = context.frontend;
2284
2267
  const templateMap = {
2285
2268
  "tanstack-router": "react/tanstack-router",
2269
+ "tanstack-start": "react/tanstack-start",
2286
2270
  "react-router": "react/react-router",
2287
2271
  solid: "solid",
2288
2272
  next: "react/next",
@@ -2450,6 +2434,44 @@ async function setupSvelteWorkersDeploy(projectDir, packageManager) {
2450
2434
  }
2451
2435
  }
2452
2436
 
2437
+ //#endregion
2438
+ //#region src/helpers/setup/workers-tanstack-start-setup.ts
2439
+ async function setupTanstackStartWorkersDeploy(projectDir, packageManager) {
2440
+ const webAppDir = path.join(projectDir, "apps/web");
2441
+ if (!await fs.pathExists(webAppDir)) return;
2442
+ await addPackageDependency({
2443
+ devDependencies: ["wrangler"],
2444
+ projectDir: webAppDir
2445
+ });
2446
+ const pkgPath = path.join(webAppDir, "package.json");
2447
+ if (await fs.pathExists(pkgPath)) {
2448
+ const pkg = await fs.readJson(pkgPath);
2449
+ pkg.scripts = {
2450
+ ...pkg.scripts,
2451
+ deploy: `${packageManager} run build && wrangler deploy`,
2452
+ "cf-typegen": "wrangler types --env-interface Env"
2453
+ };
2454
+ await fs.writeJson(pkgPath, pkg, { spaces: 2 });
2455
+ }
2456
+ const viteConfigPath = path.join(webAppDir, "vite.config.ts");
2457
+ if (!await fs.pathExists(viteConfigPath)) return;
2458
+ const sourceFile = tsProject.addSourceFileAtPathIfExists(viteConfigPath);
2459
+ if (!sourceFile) return;
2460
+ const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((expr) => {
2461
+ const expression = expr.getExpression();
2462
+ return Node.isIdentifier(expression) && expression.getText() === "defineConfig";
2463
+ });
2464
+ if (!defineCall) return;
2465
+ const configObj = defineCall.getArguments()[0];
2466
+ if (!configObj) return;
2467
+ const pluginsArray = ensureArrayProperty(configObj, "plugins");
2468
+ const tanstackPluginIndex = pluginsArray.getElements().findIndex((el) => el.getText().includes("tanstackStart("));
2469
+ const tanstackPluginText = "tanstackStart({ target: \"cloudflare-module\" })";
2470
+ if (tanstackPluginIndex === -1) pluginsArray.addElement(tanstackPluginText);
2471
+ else pluginsArray.getElements()[tanstackPluginIndex].replaceWithText(tanstackPluginText);
2472
+ await tsProject.save();
2473
+ }
2474
+
2453
2475
  //#endregion
2454
2476
  //#region src/helpers/setup/workers-vite-setup.ts
2455
2477
  async function setupWorkersVitePlugin(projectDir) {
@@ -2492,11 +2514,13 @@ async function setupWebDeploy(config) {
2492
2514
  const isNuxt = frontend.includes("nuxt");
2493
2515
  const isSvelte = frontend.includes("svelte");
2494
2516
  const isTanstackRouter = frontend.includes("tanstack-router");
2517
+ const isTanstackStart = frontend.includes("tanstack-start");
2495
2518
  const isReactRouter = frontend.includes("react-router");
2496
2519
  const isSolid = frontend.includes("solid");
2497
2520
  if (isNext) await setupNextWorkersDeploy(projectDir, packageManager);
2498
2521
  else if (isNuxt) await setupNuxtWorkersDeploy(projectDir, packageManager);
2499
2522
  else if (isSvelte) await setupSvelteWorkersDeploy(projectDir, packageManager);
2523
+ else if (isTanstackStart) await setupTanstackStartWorkersDeploy(projectDir, packageManager);
2500
2524
  else if (isTanstackRouter || isReactRouter || isSolid) await setupWorkersWebDeploy(projectDir, packageManager);
2501
2525
  }
2502
2526
  async function setupWorkersWebDeploy(projectDir, pkgManager) {
@@ -2550,17 +2574,6 @@ async function addDeploymentToProject(input) {
2550
2574
  const detectedConfig = await detectProjectConfig(projectDir);
2551
2575
  if (!detectedConfig) exitWithError("Could not detect the project configuration. Please ensure this is a valid Better-T Stack project.");
2552
2576
  if (detectedConfig.webDeploy === input.webDeploy) exitWithError(`${input.webDeploy} deployment is already configured for this project.`);
2553
- if (input.webDeploy === "workers") {
2554
- const compatibleFrontends = [
2555
- "tanstack-router",
2556
- "react-router",
2557
- "solid",
2558
- "next",
2559
- "svelte"
2560
- ];
2561
- const hasCompatible = detectedConfig.frontend?.some((f) => compatibleFrontends.includes(f));
2562
- if (!hasCompatible) exitWithError("Cloudflare Workers deployment requires a compatible web frontend (tanstack-router, react-router, solid, next, or svelte).");
2563
- }
2564
2577
  const config = {
2565
2578
  projectName: detectedConfig.projectName || path.basename(projectDir),
2566
2579
  projectDir,
@@ -4285,7 +4298,7 @@ async function initializeGit(projectDir, useGit) {
4285
4298
  //#endregion
4286
4299
  //#region src/helpers/project-generation/post-installation.ts
4287
4300
  function displayPostInstallInstructions(config) {
4288
- const { database, relativePath, packageManager, depsInstalled, orm, addons, runtime, frontend, backend, dbSetup } = config;
4301
+ const { database, relativePath, packageManager, depsInstalled, orm, addons, runtime, frontend, backend, dbSetup, webDeploy } = config;
4289
4302
  const isConvex = backend === "convex";
4290
4303
  const runCmd = packageManager === "npm" ? "npm run" : packageManager;
4291
4304
  const cdCmd = `cd ${relativePath}`;
@@ -4296,6 +4309,7 @@ function displayPostInstallInstructions(config) {
4296
4309
  const nativeInstructions = frontend?.includes("native-nativewind") || frontend?.includes("native-unistyles") ? getNativeInstructions(isConvex) : "";
4297
4310
  const pwaInstructions = addons?.includes("pwa") && frontend?.includes("react-router") ? getPwaInstructions() : "";
4298
4311
  const starlightInstructions = addons?.includes("starlight") ? getStarlightInstructions(runCmd) : "";
4312
+ const workersDeployInstructions = webDeploy === "workers" ? getWorkersDeployInstructions(runCmd) : "";
4299
4313
  const hasWeb = frontend?.some((f) => [
4300
4314
  "tanstack-router",
4301
4315
  "react-router",
@@ -4337,6 +4351,7 @@ function displayPostInstallInstructions(config) {
4337
4351
  if (tauriInstructions) output += `\n${tauriInstructions.trim()}\n`;
4338
4352
  if (lintingInstructions) output += `\n${lintingInstructions.trim()}\n`;
4339
4353
  if (pwaInstructions) output += `\n${pwaInstructions.trim()}\n`;
4354
+ if (workersDeployInstructions) output += `\n${workersDeployInstructions.trim()}\n`;
4340
4355
  if (starlightInstructions) output += `\n${starlightInstructions.trim()}\n`;
4341
4356
  if (noOrmWarning) output += `\n${noOrmWarning.trim()}\n`;
4342
4357
  if (bunWebNativeWarning) output += `\n${bunWebNativeWarning.trim()}\n`;
@@ -4396,6 +4411,9 @@ function getNoOrmWarning() {
4396
4411
  function getBunWebNativeWarning() {
4397
4412
  return `\n${pc.yellow("WARNING:")} 'bun' might cause issues with web + native apps in a monorepo. Use 'pnpm' if problems arise.`;
4398
4413
  }
4414
+ function getWorkersDeployInstructions(runCmd) {
4415
+ return `\n${pc.bold("Deploy frontend to Cloudflare Workers:")}\n${pc.cyan("•")} Deploy: ${`cd apps/web && ${runCmd || "bun run"} deploy`}`;
4416
+ }
4399
4417
 
4400
4418
  //#endregion
4401
4419
  //#region src/helpers/project-generation/project-config.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "2.23.0",
3
+ "version": "2.24.0",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "../../node_modules/wrangler/config-schema.json",
3
+ "name": "{{projectName}}",
4
+ "main": ".output/server/index.mjs",
5
+ "compatibility_date": "2025-07-05",
6
+ "compatibility_flags": ["nodejs_compat"],
7
+ "assets": {
8
+ "directory": ".output/public",
9
+ },
10
+ "observability": {
11
+ "enabled": true,
12
+ },
13
+ // "kv_namespaces": [
14
+ // {
15
+ // "binding": "CACHE",
16
+ // "id": "<Your KV ID>",
17
+ // },
18
+ // ],
19
+ }
20
+
@@ -19,6 +19,8 @@
19
19
  .vinxi
20
20
  .output
21
21
  .react-router/
22
+ .tanstack/
23
+ .nitro/
22
24
 
23
25
  # Deployment
24
26
  .vercel