create-better-t-stack 2.50.0-canary.08568a05 → 2.50.0-canary.5b25d7db

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 (31) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/index.js +1 -1
  3. package/dist/{src-DfbhNFZ9.js → src-Vtq3I-LI.js} +165 -119
  4. package/package.json +1 -1
  5. package/templates/api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs +45 -16
  6. package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +1 -1
  7. package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +2 -2
  8. package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +1 -1
  9. package/templates/api/orpc/web/svelte/src/lib/orpc.ts.hbs +1 -1
  10. package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +2 -2
  11. package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
  12. package/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs +2 -0
  13. package/templates/auth/better-auth/web/react/next/src/app/dashboard/page.tsx.hbs +31 -0
  14. package/templates/db/drizzle/mysql/drizzle.config.ts.hbs +5 -1
  15. package/templates/db/drizzle/postgres/drizzle.config.ts.hbs +5 -1
  16. package/templates/db/drizzle/sqlite/drizzle.config.ts.hbs +5 -1
  17. package/templates/db/prisma/mongodb/prisma.config.ts.hbs +5 -1
  18. package/templates/db/prisma/mysql/prisma.config.ts.hbs +5 -1
  19. package/templates/db/prisma/postgres/prisma.config.ts.hbs +5 -1
  20. package/templates/db/prisma/sqlite/prisma.config.ts.hbs +5 -1
  21. package/templates/frontend/native/nativewind/tsconfig.json.hbs +1 -6
  22. package/templates/frontend/native/unistyles/tsconfig.json.hbs +1 -6
  23. package/templates/frontend/nuxt/tsconfig.json.hbs +0 -4
  24. package/templates/frontend/react/next/tsconfig.json.hbs +0 -7
  25. package/templates/frontend/react/react-router/tsconfig.json.hbs +1 -6
  26. package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +1 -1
  27. package/templates/frontend/react/tanstack-router/tsconfig.json.hbs +1 -6
  28. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +1 -1
  29. package/templates/frontend/react/tanstack-start/tsconfig.json.hbs +1 -6
  30. package/templates/frontend/solid/tsconfig.json.hbs +1 -6
  31. package/templates/frontend/svelte/tsconfig.json.hbs +1 -6
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createBtsCli } from "./src-DfbhNFZ9.js";
2
+ import { createBtsCli } from "./src-Vtq3I-LI.js";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { builder, createBtsCli, docs, init, router, sponsors } from "./src-DfbhNFZ9.js";
2
+ import { builder, createBtsCli, docs, init, router, sponsors } from "./src-Vtq3I-LI.js";
3
3
 
4
4
  export { builder, createBtsCli, docs, init, router, sponsors };
@@ -125,7 +125,7 @@ const dependencyVersionMap = {
125
125
  "@trpc/tanstack-react-query": "^11.5.0",
126
126
  "@trpc/server": "^11.5.0",
127
127
  "@trpc/client": "^11.5.0",
128
- "next": "15.5.4",
128
+ next: "15.5.4",
129
129
  convex: "^1.27.0",
130
130
  "@convex-dev/react-query": "^0.0.0-alpha.8",
131
131
  "convex-svelte": "^0.0.11",
@@ -699,7 +699,7 @@ async function getBackendFrameworkChoice(backendFramework, frontends) {
699
699
  if (hasFullstackFrontend) backendOptions.push({
700
700
  value: "self",
701
701
  label: "Self (Fullstack)",
702
- hint: "Use frontend's built-in backend capabilities"
702
+ hint: "Use frontend's built-in api routes"
703
703
  });
704
704
  backendOptions.push({
705
705
  value: "hono",
@@ -4120,6 +4120,10 @@ async function setupExamples(config) {
4120
4120
  dependencies: ["ai", "@ai-sdk/google"],
4121
4121
  projectDir: apiDir$1
4122
4122
  });
4123
+ if (backend === "self" && webClientDirExists) await addPackageDependency({
4124
+ dependencies: ["ai", "@ai-sdk/google"],
4125
+ projectDir: webClientDir
4126
+ });
4123
4127
  }
4124
4128
  }
4125
4129
 
@@ -4251,6 +4255,10 @@ async function setupApi(config) {
4251
4255
  dependencies: apiDeps.server.dependencies,
4252
4256
  projectDir: apiPackageDir
4253
4257
  });
4258
+ if (backend === "self" && webDirExists) await addPackageDependency({
4259
+ dependencies: apiDeps.server.dependencies,
4260
+ projectDir: webDir
4261
+ });
4254
4262
  const frameworkDeps = [];
4255
4263
  if (backend === "hono") frameworkDeps.push("hono");
4256
4264
  else if (backend === "elysia") frameworkDeps.push("elysia");
@@ -4484,6 +4492,34 @@ function generateAuthSecret(length = 32) {
4484
4492
 
4485
4493
  //#endregion
4486
4494
  //#region src/helpers/core/env-setup.ts
4495
+ function getClientServerVar(frontend, backend) {
4496
+ const hasNextJs = frontend.includes("next");
4497
+ const hasNuxt = frontend.includes("nuxt");
4498
+ const hasSvelte = frontend.includes("svelte");
4499
+ if (backend === "self") return {
4500
+ key: "",
4501
+ value: "",
4502
+ write: false
4503
+ };
4504
+ let key = "VITE_SERVER_URL";
4505
+ if (hasNextJs) key = "NEXT_PUBLIC_SERVER_URL";
4506
+ else if (hasNuxt) key = "NUXT_PUBLIC_SERVER_URL";
4507
+ else if (hasSvelte) key = "PUBLIC_SERVER_URL";
4508
+ return {
4509
+ key,
4510
+ value: "http://localhost:3000",
4511
+ write: true
4512
+ };
4513
+ }
4514
+ function getConvexVar(frontend) {
4515
+ const hasNextJs = frontend.includes("next");
4516
+ const hasNuxt = frontend.includes("nuxt");
4517
+ const hasSvelte = frontend.includes("svelte");
4518
+ if (hasNextJs) return "NEXT_PUBLIC_CONVEX_URL";
4519
+ if (hasNuxt) return "NUXT_PUBLIC_CONVEX_URL";
4520
+ if (hasSvelte) return "PUBLIC_CONVEX_URL";
4521
+ return "VITE_CONVEX_URL";
4522
+ }
4487
4523
  async function addEnvVariablesToFile(filePath, variables) {
4488
4524
  await fs.ensureDir(path.dirname(filePath));
4489
4525
  let envContent = "";
@@ -4542,22 +4578,13 @@ async function setupEnvironmentVariables(config) {
4542
4578
  if (hasReactRouter || hasTanStackRouter || hasTanStackStart || hasNextJs || hasNuxt || hasSolid || hasSvelte) {
4543
4579
  const clientDir = path.join(projectDir, "apps/web");
4544
4580
  if (await fs.pathExists(clientDir)) {
4545
- let envVarName = "VITE_SERVER_URL";
4546
- let serverUrl = "http://localhost:3000";
4547
- if (hasNextJs) envVarName = "NEXT_PUBLIC_SERVER_URL";
4548
- else if (hasNuxt) envVarName = "NUXT_PUBLIC_SERVER_URL";
4549
- else if (hasSvelte) envVarName = "PUBLIC_SERVER_URL";
4550
- if (backend === "convex") {
4551
- if (hasNextJs) envVarName = "NEXT_PUBLIC_CONVEX_URL";
4552
- else if (hasNuxt) envVarName = "NUXT_PUBLIC_CONVEX_URL";
4553
- else if (hasSvelte) envVarName = "PUBLIC_CONVEX_URL";
4554
- else envVarName = "VITE_CONVEX_URL";
4555
- serverUrl = "https://<YOUR_CONVEX_URL>";
4556
- }
4581
+ const baseVar = getClientServerVar(frontend, backend);
4582
+ const envVarName = backend === "convex" ? getConvexVar(frontend) : baseVar.key;
4583
+ const serverUrl = backend === "convex" ? "https://<YOUR_CONVEX_URL>" : baseVar.value;
4557
4584
  const clientVars = [{
4558
4585
  key: envVarName,
4559
4586
  value: serverUrl,
4560
- condition: backend !== "self"
4587
+ condition: backend === "convex" ? true : baseVar.write
4561
4588
  }];
4562
4589
  if (backend === "convex" && auth === "clerk") {
4563
4590
  if (hasNextJs) clientVars.push({
@@ -4649,7 +4676,8 @@ async function setupEnvironmentVariables(config) {
4649
4676
  }
4650
4677
  const serverDir = path.join(projectDir, "apps/server");
4651
4678
  let corsOrigin = "http://localhost:3001";
4652
- if (hasReactRouter || hasSvelte) corsOrigin = "http://localhost:5173";
4679
+ if (backend === "self") corsOrigin = "http://localhost:3001";
4680
+ else if (hasReactRouter || hasSvelte) corsOrigin = "http://localhost:5173";
4653
4681
  let databaseUrl = null;
4654
4682
  if (database !== "none" && dbSetup === "none") switch (database) {
4655
4683
  case "postgres":
@@ -4663,7 +4691,10 @@ async function setupEnvironmentVariables(config) {
4663
4691
  break;
4664
4692
  case "sqlite":
4665
4693
  if (config.runtime === "workers") databaseUrl = "http://127.0.0.1:8080";
4666
- else databaseUrl = `file:${path.join(config.projectDir, "apps/server", "local.db")}`;
4694
+ else {
4695
+ const dbAppDir = backend === "self" ? "apps/web" : "apps/server";
4696
+ databaseUrl = `file:${path.join(config.projectDir, dbAppDir, "local.db")}`;
4697
+ }
4667
4698
  break;
4668
4699
  }
4669
4700
  const serverVars = [
@@ -4674,7 +4705,7 @@ async function setupEnvironmentVariables(config) {
4674
4705
  },
4675
4706
  {
4676
4707
  key: "BETTER_AUTH_URL",
4677
- value: "http://localhost:3000",
4708
+ value: backend === "self" ? "http://localhost:3001" : "http://localhost:3000",
4678
4709
  condition: !!auth
4679
4710
  },
4680
4711
  {
@@ -4742,9 +4773,10 @@ async function setupEnvironmentVariables(config) {
4742
4773
  //#endregion
4743
4774
  //#region src/helpers/database-providers/d1-setup.ts
4744
4775
  async function setupCloudflareD1(config) {
4745
- const { projectDir, serverDeploy, orm } = config;
4776
+ const { projectDir, serverDeploy, orm, backend } = config;
4746
4777
  if (serverDeploy === "wrangler") {
4747
- const envPath = path.join(projectDir, "apps/server", ".env");
4778
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
4779
+ const envPath = path.join(projectDir, targetApp, ".env");
4748
4780
  const variables = [
4749
4781
  {
4750
4782
  key: "CLOUDFLARE_ACCOUNT_ID",
@@ -4767,7 +4799,8 @@ async function setupCloudflareD1(config) {
4767
4799
  } catch (_err) {}
4768
4800
  }
4769
4801
  if ((serverDeploy === "wrangler" || serverDeploy === "alchemy") && orm === "prisma") {
4770
- const envPath = path.join(projectDir, "apps/server", ".env");
4802
+ const targetApp2 = backend === "self" ? "apps/web" : "apps/server";
4803
+ const envPath = path.join(projectDir, targetApp2, ".env");
4771
4804
  const variables = [{
4772
4805
  key: "DATABASE_URL",
4773
4806
  value: `file:${path.join(projectDir, "apps/server", "local.db")}`,
@@ -4776,7 +4809,7 @@ async function setupCloudflareD1(config) {
4776
4809
  try {
4777
4810
  await addEnvVariablesToFile(envPath, variables);
4778
4811
  } catch (_err) {}
4779
- const serverDir = path.join(projectDir, "apps/server");
4812
+ const serverDir = path.join(projectDir, backend === "self" ? "apps/web" : "apps/server");
4780
4813
  await addPackageDependency({
4781
4814
  dependencies: ["@prisma/adapter-d1"],
4782
4815
  projectDir: serverDir
@@ -4869,9 +4902,10 @@ async function initMongoDBAtlas(serverDir) {
4869
4902
  return null;
4870
4903
  }
4871
4904
  }
4872
- async function writeEnvFile$3(projectDir, config) {
4905
+ async function writeEnvFile$3(projectDir, backend, config) {
4873
4906
  try {
4874
- const envPath = path.join(projectDir, "apps/server", ".env");
4907
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
4908
+ const envPath = path.join(projectDir, targetApp, ".env");
4875
4909
  const variables = [{
4876
4910
  key: "DATABASE_URL",
4877
4911
  value: config?.connectionString ?? "mongodb://localhost:27017/mydb",
@@ -4900,16 +4934,16 @@ ${pc.green("MongoDB Atlas Manual Setup Instructions:")}
4900
4934
  `);
4901
4935
  }
4902
4936
  async function setupMongoDBAtlas(config, cliInput) {
4903
- const { projectDir } = config;
4937
+ const { projectDir, backend } = config;
4904
4938
  const manualDb = cliInput?.manualDb ?? false;
4905
4939
  const mainSpinner = spinner();
4906
4940
  mainSpinner.start("Setting up MongoDB Atlas...");
4907
- const serverDir = path.join(projectDir, "apps/server");
4941
+ const serverDir = path.join(projectDir, "packages/db");
4908
4942
  try {
4909
4943
  await fs.ensureDir(serverDir);
4910
4944
  if (manualDb) {
4911
4945
  mainSpinner.stop("MongoDB Atlas manual setup selected");
4912
- await writeEnvFile$3(projectDir);
4946
+ await writeEnvFile$3(projectDir, backend);
4913
4947
  displayManualSetupInstructions$3();
4914
4948
  return;
4915
4949
  }
@@ -4929,25 +4963,25 @@ async function setupMongoDBAtlas(config, cliInput) {
4929
4963
  if (isCancel(mode)) return exitCancelled("Operation cancelled");
4930
4964
  if (mode === "manual") {
4931
4965
  mainSpinner.stop("MongoDB Atlas manual setup selected");
4932
- await writeEnvFile$3(projectDir);
4966
+ await writeEnvFile$3(projectDir, backend);
4933
4967
  displayManualSetupInstructions$3();
4934
4968
  return;
4935
4969
  }
4936
4970
  mainSpinner.stop("MongoDB Atlas setup ready");
4937
4971
  const config$1 = await initMongoDBAtlas(serverDir);
4938
4972
  if (config$1) {
4939
- await writeEnvFile$3(projectDir, config$1);
4973
+ await writeEnvFile$3(projectDir, backend, config$1);
4940
4974
  log.success(pc.green("MongoDB Atlas setup complete! Connection saved to .env file."));
4941
4975
  } else {
4942
4976
  log.warn(pc.yellow("Falling back to local MongoDB configuration"));
4943
- await writeEnvFile$3(projectDir);
4977
+ await writeEnvFile$3(projectDir, backend);
4944
4978
  displayManualSetupInstructions$3();
4945
4979
  }
4946
4980
  } catch (error) {
4947
4981
  mainSpinner.stop(pc.red("MongoDB Atlas setup failed"));
4948
4982
  consola.error(pc.red(`Error during MongoDB Atlas setup: ${error instanceof Error ? error.message : String(error)}`));
4949
4983
  try {
4950
- await writeEnvFile$3(projectDir);
4984
+ await writeEnvFile$3(projectDir, backend);
4951
4985
  displayManualSetupInstructions$3();
4952
4986
  } catch {}
4953
4987
  }
@@ -5004,7 +5038,7 @@ async function executeNeonCommand(packageManager, commandArgsString, spinnerText
5004
5038
  }
5005
5039
  async function createNeonProject(projectName, regionId, packageManager) {
5006
5040
  try {
5007
- const commandArgsString = `neonctl projects create --name ${projectName} --region-id ${regionId} --output json`;
5041
+ const commandArgsString = `neonctl@latest projects create --name ${projectName} --region-id ${regionId} --output json`;
5008
5042
  const { stdout } = await executeNeonCommand(packageManager, commandArgsString, `Creating Neon project "${projectName}"...`);
5009
5043
  const response = JSON.parse(stdout);
5010
5044
  if (response.project && response.connection_uris && response.connection_uris.length > 0) {
@@ -5024,8 +5058,9 @@ async function createNeonProject(projectName, regionId, packageManager) {
5024
5058
  consola$1.error(pc.red("Failed to create Neon project"));
5025
5059
  }
5026
5060
  }
5027
- async function writeEnvFile$2(projectDir, config) {
5028
- const envPath = path.join(projectDir, "apps/server", ".env");
5061
+ async function writeEnvFile$2(projectDir, backend, config) {
5062
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
5063
+ const envPath = path.join(projectDir, targetApp, ".env");
5029
5064
  const variables = [{
5030
5065
  key: "DATABASE_URL",
5031
5066
  value: config?.connectionString ?? "postgresql://postgres:postgres@localhost:5432/mydb?schema=public",
@@ -5034,16 +5069,17 @@ async function writeEnvFile$2(projectDir, config) {
5034
5069
  await addEnvVariablesToFile(envPath, variables);
5035
5070
  return true;
5036
5071
  }
5037
- async function setupWithNeonDb(projectDir, packageManager) {
5072
+ async function setupWithNeonDb(projectDir, packageManager, backend) {
5038
5073
  try {
5039
5074
  const s = spinner();
5040
5075
  s.start("Creating Neon database using neondb...");
5041
- const serverDir = path.join(projectDir, "apps/server");
5042
- await fs.ensureDir(serverDir);
5043
- const packageCmd = getPackageExecutionCommand(packageManager, "neondb --yes");
5076
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
5077
+ const targetDir = path.join(projectDir, targetApp);
5078
+ await fs.ensureDir(targetDir);
5079
+ const packageCmd = getPackageExecutionCommand(packageManager, "neondb@latest --yes");
5044
5080
  await execa(packageCmd, {
5045
5081
  shell: true,
5046
- cwd: serverDir
5082
+ cwd: targetDir
5047
5083
  });
5048
5084
  s.stop(pc.green("Neon database created successfully!"));
5049
5085
  return true;
@@ -5052,23 +5088,23 @@ async function setupWithNeonDb(projectDir, packageManager) {
5052
5088
  throw error;
5053
5089
  }
5054
5090
  }
5055
- function displayManualSetupInstructions$2() {
5091
+ function displayManualSetupInstructions$2(target) {
5056
5092
  log.info(`Manual Neon PostgreSQL Setup Instructions:
5057
5093
 
5058
5094
  1. Visit https://neon.tech and create an account
5059
5095
  2. Create a new project from the dashboard
5060
5096
  3. Get your connection string
5061
- 4. Add the database URL to the .env file in apps/server/.env
5097
+ 4. Add the database URL to the .env file in ${target}/.env
5062
5098
 
5063
5099
  DATABASE_URL="your_connection_string"`);
5064
5100
  }
5065
5101
  async function setupNeonPostgres(config, cliInput) {
5066
- const { packageManager, projectDir } = config;
5102
+ const { packageManager, projectDir, backend } = config;
5067
5103
  const manualDb = cliInput?.manualDb ?? false;
5068
5104
  try {
5069
5105
  if (manualDb) {
5070
- await writeEnvFile$2(projectDir);
5071
- displayManualSetupInstructions$2();
5106
+ await writeEnvFile$2(projectDir, backend);
5107
+ displayManualSetupInstructions$2(backend === "self" ? "apps/web" : "apps/server");
5072
5108
  return;
5073
5109
  }
5074
5110
  const mode = await select({
@@ -5086,8 +5122,8 @@ async function setupNeonPostgres(config, cliInput) {
5086
5122
  });
5087
5123
  if (isCancel(mode)) return exitCancelled("Operation cancelled");
5088
5124
  if (mode === "manual") {
5089
- await writeEnvFile$2(projectDir);
5090
- displayManualSetupInstructions$2();
5125
+ await writeEnvFile$2(projectDir, backend);
5126
+ displayManualSetupInstructions$2(backend === "self" ? "apps/web" : "apps/server");
5091
5127
  return;
5092
5128
  }
5093
5129
  const setupMethod = await select({
@@ -5104,7 +5140,7 @@ async function setupNeonPostgres(config, cliInput) {
5104
5140
  initialValue: "neondb"
5105
5141
  });
5106
5142
  if (isCancel(setupMethod)) return exitCancelled("Operation cancelled");
5107
- if (setupMethod === "neondb") await setupWithNeonDb(projectDir, packageManager);
5143
+ if (setupMethod === "neondb") await setupWithNeonDb(projectDir, packageManager, backend);
5108
5144
  else {
5109
5145
  const suggestedProjectName = path.basename(projectDir);
5110
5146
  const projectName = await text({
@@ -5122,22 +5158,22 @@ async function setupNeonPostgres(config, cliInput) {
5122
5158
  if (!neonConfig) throw new Error("Failed to create project - couldn't get connection information");
5123
5159
  const finalSpinner = spinner();
5124
5160
  finalSpinner.start("Configuring database connection");
5125
- await fs.ensureDir(path.join(projectDir, "apps/server"));
5126
- await writeEnvFile$2(projectDir, neonConfig);
5161
+ await writeEnvFile$2(projectDir, backend, neonConfig);
5127
5162
  finalSpinner.stop("Neon database configured!");
5128
5163
  }
5129
5164
  } catch (error) {
5130
5165
  if (error instanceof Error) consola$1.error(pc.red(error.message));
5131
- await writeEnvFile$2(projectDir);
5132
- displayManualSetupInstructions$2();
5166
+ await writeEnvFile$2(projectDir, backend);
5167
+ displayManualSetupInstructions$2(backend === "self" ? "apps/web" : "apps/server");
5133
5168
  }
5134
5169
  }
5135
5170
 
5136
5171
  //#endregion
5137
5172
  //#region src/helpers/database-providers/planetscale-setup.ts
5138
5173
  async function setupPlanetScale(config) {
5139
- const { projectDir, database, orm } = config;
5140
- const envPath = path.join(projectDir, "apps/server", ".env");
5174
+ const { projectDir, database, orm, backend } = config;
5175
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
5176
+ const envPath = path.join(projectDir, targetApp, ".env");
5141
5177
  if (database === "mysql" && orm === "drizzle") {
5142
5178
  const variables = [
5143
5179
  {
@@ -5161,7 +5197,7 @@ async function setupPlanetScale(config) {
5161
5197
  condition: true
5162
5198
  }
5163
5199
  ];
5164
- await fs.ensureDir(path.join(projectDir, "apps/server"));
5200
+ await fs.ensureDir(path.join(projectDir, targetApp));
5165
5201
  await addEnvVariablesToFile(envPath, variables);
5166
5202
  }
5167
5203
  if (database === "postgres" && orm === "prisma") {
@@ -5170,7 +5206,7 @@ async function setupPlanetScale(config) {
5170
5206
  value: "postgresql://username:password@host/database?sslaccept=strict",
5171
5207
  condition: true
5172
5208
  }];
5173
- await fs.ensureDir(path.join(projectDir, "apps/server"));
5209
+ await fs.ensureDir(path.join(projectDir, targetApp));
5174
5210
  await addEnvVariablesToFile(envPath, variables);
5175
5211
  }
5176
5212
  if (database === "postgres" && orm === "drizzle") {
@@ -5179,7 +5215,7 @@ async function setupPlanetScale(config) {
5179
5215
  value: "postgresql://username:password@host/database?sslmode=verify-full",
5180
5216
  condition: true
5181
5217
  }];
5182
- await fs.ensureDir(path.join(projectDir, "apps/server"));
5218
+ await fs.ensureDir(path.join(projectDir, targetApp));
5183
5219
  await addEnvVariablesToFile(envPath, variables);
5184
5220
  }
5185
5221
  if (database === "mysql" && orm === "prisma") {
@@ -5188,7 +5224,7 @@ async function setupPlanetScale(config) {
5188
5224
  value: "mysql://username:password@host/database?sslaccept=strict",
5189
5225
  condition: true
5190
5226
  }];
5191
- await fs.ensureDir(path.join(projectDir, "apps/server"));
5227
+ await fs.ensureDir(path.join(projectDir, targetApp));
5192
5228
  await addEnvVariablesToFile(envPath, variables);
5193
5229
  }
5194
5230
  }
@@ -5258,7 +5294,7 @@ async function initPrismaDatabase(serverDir, packageManager) {
5258
5294
  try {
5259
5295
  const prismaDir = path.join(serverDir, "prisma");
5260
5296
  await fs.ensureDir(prismaDir);
5261
- log.info("Starting Prisma PostgreSQL setup. Please follow the instructions below:");
5297
+ log.info("Starting Prisma PostgreSQL setup.");
5262
5298
  const prismaInitCommand = getPackageExecutionCommand(packageManager, "prisma init --db");
5263
5299
  await execa(prismaInitCommand, {
5264
5300
  cwd: serverDir,
@@ -5280,9 +5316,10 @@ async function initPrismaDatabase(serverDir, packageManager) {
5280
5316
  return null;
5281
5317
  }
5282
5318
  }
5283
- async function writeEnvFile$1(projectDir, config) {
5319
+ async function writeEnvFile$1(projectDir, backend, config) {
5284
5320
  try {
5285
- const envPath = path.join(projectDir, "apps/server", ".env");
5321
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
5322
+ const envPath = path.join(projectDir, targetApp, ".env");
5286
5323
  const variables = [{
5287
5324
  key: "DATABASE_URL",
5288
5325
  value: config?.databaseUrl ?? "postgresql://postgres:postgres@localhost:5432/mydb?schema=public",
@@ -5298,23 +5335,23 @@ async function writeEnvFile$1(projectDir, config) {
5298
5335
  consola$1.error("Failed to update environment configuration");
5299
5336
  }
5300
5337
  }
5301
- async function addDotenvImportToPrismaConfig(projectDir) {
5338
+ async function addDotenvImportToPrismaConfig(projectDir, backend) {
5302
5339
  try {
5303
5340
  const prismaConfigPath = path.join(projectDir, "packages/db/prisma.config.ts");
5304
5341
  let content = await fs.readFile(prismaConfigPath, "utf8");
5305
- content = `import dotenv from "dotenv";\ndotenv.config({ path: "../../apps/server/.env" });\n${content}`;
5342
+ content = `import dotenv from "dotenv";\ndotenv.config({ path: "${backend === "self" ? "../../apps/web/.env" : "../../apps/server/.env"}" });\n${content}`;
5306
5343
  await fs.writeFile(prismaConfigPath, content);
5307
5344
  } catch (_error) {
5308
5345
  consola$1.error("Failed to update prisma.config.ts");
5309
5346
  }
5310
5347
  }
5311
- function displayManualSetupInstructions$1() {
5348
+ function displayManualSetupInstructions$1(target) {
5312
5349
  log.info(`Manual Prisma PostgreSQL Setup Instructions:
5313
5350
 
5314
5351
  1. Visit https://console.prisma.io and create an account
5315
5352
  2. Create a new PostgreSQL database from the dashboard
5316
5353
  3. Get your database URL
5317
- 4. Add the database URL to the .env file in apps/server/.env
5354
+ 4. Add the database URL to the .env file in ${target}/.env
5318
5355
 
5319
5356
  DATABASE_URL="your_database_url"`);
5320
5357
  }
@@ -5332,14 +5369,14 @@ async function addPrismaAccelerateExtension(projectDir) {
5332
5369
  }
5333
5370
  }
5334
5371
  async function setupPrismaPostgres(config, cliInput) {
5335
- const { packageManager, projectDir, orm } = config;
5372
+ const { packageManager, projectDir, orm, backend } = config;
5336
5373
  const manualDb = cliInput?.manualDb ?? false;
5337
- const serverDir = path.join(projectDir, "apps/server");
5374
+ const dbDir = path.join(projectDir, "packages/db");
5338
5375
  try {
5339
- await fs.ensureDir(serverDir);
5376
+ await fs.ensureDir(dbDir);
5340
5377
  if (manualDb) {
5341
- await writeEnvFile$1(projectDir);
5342
- displayManualSetupInstructions$1();
5378
+ await writeEnvFile$1(projectDir, backend);
5379
+ displayManualSetupInstructions$1(backend === "self" ? "apps/web" : "apps/server");
5343
5380
  return;
5344
5381
  }
5345
5382
  const mode = await select({
@@ -5357,8 +5394,8 @@ async function setupPrismaPostgres(config, cliInput) {
5357
5394
  });
5358
5395
  if (isCancel(mode)) return exitCancelled("Operation cancelled");
5359
5396
  if (mode === "manual") {
5360
- await writeEnvFile$1(projectDir);
5361
- displayManualSetupInstructions$1();
5397
+ await writeEnvFile$1(projectDir, backend);
5398
+ displayManualSetupInstructions$1(backend === "self" ? "apps/web" : "apps/server");
5362
5399
  return;
5363
5400
  }
5364
5401
  const setupOptions = [{
@@ -5378,26 +5415,26 @@ async function setupPrismaPostgres(config, cliInput) {
5378
5415
  });
5379
5416
  if (isCancel(setupMethod)) return exitCancelled("Operation cancelled");
5380
5417
  let prismaConfig = null;
5381
- if (setupMethod === "create-db") prismaConfig = await setupWithCreateDb(serverDir, packageManager, orm);
5382
- else prismaConfig = await initPrismaDatabase(serverDir, packageManager);
5418
+ if (setupMethod === "create-db") prismaConfig = await setupWithCreateDb(dbDir, packageManager, orm);
5419
+ else prismaConfig = await initPrismaDatabase(dbDir, packageManager);
5383
5420
  if (prismaConfig) {
5384
- await writeEnvFile$1(projectDir, prismaConfig);
5421
+ await writeEnvFile$1(projectDir, backend, prismaConfig);
5385
5422
  if (orm === "prisma") {
5386
- await addDotenvImportToPrismaConfig(projectDir);
5423
+ await addDotenvImportToPrismaConfig(projectDir, backend);
5387
5424
  await addPrismaAccelerateExtension(projectDir);
5388
5425
  }
5389
5426
  const connectionType = orm === "drizzle" ? "direct connection" : "Prisma Accelerate";
5390
5427
  log.success(pc.green(`Prisma Postgres database configured successfully with ${connectionType}!`));
5391
5428
  if (prismaConfig.claimUrl) log.info(pc.blue(`Claim URL saved to .env: ${prismaConfig.claimUrl}`));
5392
5429
  } else {
5393
- await writeEnvFile$1(projectDir);
5394
- displayManualSetupInstructions$1();
5430
+ await writeEnvFile$1(projectDir, backend);
5431
+ displayManualSetupInstructions$1(backend === "self" ? "apps/web" : "apps/server");
5395
5432
  }
5396
5433
  } catch (error) {
5397
5434
  consola$1.error(pc.red(`Error during Prisma Postgres setup: ${error instanceof Error ? error.message : String(error)}`));
5398
5435
  try {
5399
- await writeEnvFile$1(projectDir);
5400
- displayManualSetupInstructions$1();
5436
+ await writeEnvFile$1(projectDir, backend);
5437
+ displayManualSetupInstructions$1(backend === "self" ? "apps/web" : "apps/server");
5401
5438
  } catch {}
5402
5439
  log.info("Setup completed with manual configuration required.");
5403
5440
  }
@@ -5405,9 +5442,10 @@ async function setupPrismaPostgres(config, cliInput) {
5405
5442
 
5406
5443
  //#endregion
5407
5444
  //#region src/helpers/database-providers/supabase-setup.ts
5408
- async function writeSupabaseEnvFile(projectDir, databaseUrl) {
5445
+ async function writeSupabaseEnvFile(projectDir, backend, databaseUrl) {
5409
5446
  try {
5410
- const envPath = path.join(projectDir, "apps/server", ".env");
5447
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
5448
+ const envPath = path.join(projectDir, targetApp, ".env");
5411
5449
  const dbUrlToUse = databaseUrl || "postgresql://postgres:postgres@127.0.0.1:54322/postgres";
5412
5450
  await addEnvVariablesToFile(envPath, [{
5413
5451
  key: "DATABASE_URL",
@@ -5493,14 +5531,14 @@ ${pc.dim(output)}` : ""}
5493
5531
  ${pc.gray("DATABASE_URL=\"your_supabase_db_url\"")}`);
5494
5532
  }
5495
5533
  async function setupSupabase(config, cliInput) {
5496
- const { projectDir, packageManager } = config;
5534
+ const { projectDir, packageManager, backend } = config;
5497
5535
  const manualDb = cliInput?.manualDb ?? false;
5498
5536
  const serverDir = path.join(projectDir, "packages", "db");
5499
5537
  try {
5500
5538
  await fs.ensureDir(serverDir);
5501
5539
  if (manualDb) {
5502
5540
  displayManualSupabaseInstructions();
5503
- await writeSupabaseEnvFile(projectDir, "");
5541
+ await writeSupabaseEnvFile(projectDir, backend, "");
5504
5542
  return;
5505
5543
  }
5506
5544
  const mode = await select({
@@ -5519,7 +5557,7 @@ async function setupSupabase(config, cliInput) {
5519
5557
  if (isCancel(mode)) return exitCancelled("Operation cancelled");
5520
5558
  if (mode === "manual") {
5521
5559
  displayManualSupabaseInstructions();
5522
- await writeSupabaseEnvFile(projectDir, "");
5560
+ await writeSupabaseEnvFile(projectDir, backend, "");
5523
5561
  return;
5524
5562
  }
5525
5563
  if (!await initializeSupabase(serverDir, packageManager)) {
@@ -5532,7 +5570,7 @@ async function setupSupabase(config, cliInput) {
5532
5570
  return;
5533
5571
  }
5534
5572
  const dbUrl = extractDbUrl(supabaseOutput);
5535
- if (dbUrl) if (await writeSupabaseEnvFile(projectDir, dbUrl)) log.success(pc.green("Supabase local development setup ready!"));
5573
+ if (dbUrl) if (await writeSupabaseEnvFile(projectDir, backend, dbUrl)) log.success(pc.green("Supabase local development setup ready!"));
5536
5574
  else {
5537
5575
  log.error(pc.red("Supabase setup completed, but failed to update .env automatically."));
5538
5576
  displayManualSupabaseInstructions(supabaseOutput);
@@ -5660,8 +5698,9 @@ async function createTursoDatabase(dbName, groupName) {
5660
5698
  s.stop(pc.red("Failed to retrieve database connection details"));
5661
5699
  }
5662
5700
  }
5663
- async function writeEnvFile(projectDir, config) {
5664
- const envPath = path.join(projectDir, "apps/server", ".env");
5701
+ async function writeEnvFile(projectDir, backend, config) {
5702
+ const targetApp = backend === "self" ? "apps/web" : "apps/server";
5703
+ const envPath = path.join(projectDir, targetApp, ".env");
5665
5704
  const variables = [{
5666
5705
  key: "DATABASE_URL",
5667
5706
  value: config?.dbUrl ?? "",
@@ -5685,12 +5724,12 @@ DATABASE_URL=your_database_url
5685
5724
  DATABASE_AUTH_TOKEN=your_auth_token`);
5686
5725
  }
5687
5726
  async function setupTurso(config, cliInput) {
5688
- const { orm, projectDir } = config;
5727
+ const { orm, projectDir, backend } = config;
5689
5728
  const manualDb = cliInput?.manualDb ?? false;
5690
5729
  const setupSpinner = spinner();
5691
5730
  try {
5692
5731
  if (manualDb) {
5693
- await writeEnvFile(projectDir);
5732
+ await writeEnvFile(projectDir, backend);
5694
5733
  displayManualSetupInstructions();
5695
5734
  return;
5696
5735
  }
@@ -5709,7 +5748,7 @@ async function setupTurso(config, cliInput) {
5709
5748
  });
5710
5749
  if (isCancel(mode)) return exitCancelled("Operation cancelled");
5711
5750
  if (mode === "manual") {
5712
- await writeEnvFile(projectDir);
5751
+ await writeEnvFile(projectDir, backend);
5713
5752
  displayManualSetupInstructions();
5714
5753
  return;
5715
5754
  }
@@ -5719,7 +5758,7 @@ async function setupTurso(config, cliInput) {
5719
5758
  if (platform === "win32") {
5720
5759
  if (setupSpinner) setupSpinner.stop(pc.yellow("Turso setup not supported on Windows"));
5721
5760
  log.warn(pc.yellow("Automatic Turso setup is not supported on Windows."));
5722
- await writeEnvFile(projectDir);
5761
+ await writeEnvFile(projectDir, backend);
5723
5762
  displayManualSetupInstructions();
5724
5763
  return;
5725
5764
  }
@@ -5731,7 +5770,7 @@ async function setupTurso(config, cliInput) {
5731
5770
  });
5732
5771
  if (isCancel(shouldInstall)) return exitCancelled("Operation cancelled");
5733
5772
  if (!shouldInstall) {
5734
- await writeEnvFile(projectDir);
5773
+ await writeEnvFile(projectDir, backend);
5735
5774
  displayManualSetupInstructions();
5736
5775
  return;
5737
5776
  }
@@ -5753,7 +5792,7 @@ async function setupTurso(config, cliInput) {
5753
5792
  dbName = dbNameResponse;
5754
5793
  try {
5755
5794
  const config$1 = await createTursoDatabase(dbName, selectedGroup);
5756
- await writeEnvFile(projectDir, config$1);
5795
+ await writeEnvFile(projectDir, backend, config$1);
5757
5796
  success = true;
5758
5797
  } catch (error) {
5759
5798
  if (error instanceof Error && error.message === "DATABASE_EXISTS") {
@@ -5766,7 +5805,7 @@ async function setupTurso(config, cliInput) {
5766
5805
  } catch (error) {
5767
5806
  if (setupSpinner) setupSpinner.stop(pc.red("Turso CLI availability check failed"));
5768
5807
  consola.error(pc.red(`Error during Turso setup: ${error instanceof Error ? error.message : String(error)}`));
5769
- await writeEnvFile(projectDir);
5808
+ await writeEnvFile(projectDir, backend);
5770
5809
  displayManualSetupInstructions();
5771
5810
  log.success("Setup completed with manual configuration required.");
5772
5811
  }
@@ -5788,26 +5827,34 @@ async function setupDatabase(config, cliInput) {
5788
5827
  const dbPackageDir = path.join(projectDir, "packages/db");
5789
5828
  if (!await fs.pathExists(dbPackageDir)) return;
5790
5829
  try {
5791
- if (orm === "prisma") if (database === "mysql" && dbSetup === "planetscale") await addPackageDependency({
5792
- dependencies: [
5793
- "@prisma/client",
5794
- "@prisma/adapter-planetscale",
5795
- "@planetscale/database"
5796
- ],
5797
- devDependencies: ["prisma"],
5798
- projectDir: dbPackageDir
5799
- });
5800
- else if (database === "sqlite" && dbSetup === "turso") await addPackageDependency({
5801
- dependencies: ["@prisma/client", "@prisma/adapter-libsql"],
5802
- devDependencies: ["prisma"],
5803
- projectDir: dbPackageDir
5804
- });
5805
- else await addPackageDependency({
5806
- dependencies: ["@prisma/client"],
5807
- devDependencies: ["prisma"],
5808
- projectDir: dbPackageDir
5809
- });
5810
- else if (orm === "drizzle") {
5830
+ if (orm === "prisma") {
5831
+ if (database === "mysql" && dbSetup === "planetscale") await addPackageDependency({
5832
+ dependencies: [
5833
+ "@prisma/client",
5834
+ "@prisma/adapter-planetscale",
5835
+ "@planetscale/database"
5836
+ ],
5837
+ devDependencies: ["prisma"],
5838
+ projectDir: dbPackageDir
5839
+ });
5840
+ else if (database === "sqlite" && dbSetup === "turso") await addPackageDependency({
5841
+ dependencies: ["@prisma/client", "@prisma/adapter-libsql"],
5842
+ devDependencies: ["prisma"],
5843
+ projectDir: dbPackageDir
5844
+ });
5845
+ else await addPackageDependency({
5846
+ dependencies: ["@prisma/client"],
5847
+ devDependencies: ["prisma"],
5848
+ projectDir: dbPackageDir
5849
+ });
5850
+ if (backend === "self") {
5851
+ const webDir = path.join(projectDir, "apps/web");
5852
+ if (await fs.pathExists(webDir)) await addPackageDependency({
5853
+ dependencies: ["@prisma/client"],
5854
+ projectDir: webDir
5855
+ });
5856
+ }
5857
+ } else if (orm === "drizzle") {
5811
5858
  if (database === "sqlite") await addPackageDependency({
5812
5859
  dependencies: [
5813
5860
  "drizzle-orm",
@@ -6261,15 +6308,14 @@ async function initializeGit(projectDir, useGit) {
6261
6308
  async function setupPayments(config) {
6262
6309
  const { payments, projectDir, frontend } = config;
6263
6310
  if (!payments || payments === "none") return;
6264
- const serverDir = path.join(projectDir, "apps/server");
6265
6311
  const clientDir = path.join(projectDir, "apps/web");
6266
- const serverDirExists = await fs.pathExists(serverDir);
6312
+ const authDir = path.join(projectDir, "packages/auth");
6267
6313
  const clientDirExists = await fs.pathExists(clientDir);
6268
- if (!serverDirExists) return;
6314
+ const authDirExists = await fs.pathExists(authDir);
6269
6315
  if (payments === "polar") {
6270
- await addPackageDependency({
6316
+ if (authDirExists) await addPackageDependency({
6271
6317
  dependencies: ["@polar-sh/better-auth", "@polar-sh/sdk"],
6272
- projectDir: serverDir
6318
+ projectDir: authDir
6273
6319
  });
6274
6320
  if (clientDirExists) {
6275
6321
  if (frontend.some((f) => [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "2.50.0-canary.08568a05",
3
+ "version": "2.50.0-canary.5b25d7db",
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",
@@ -1,21 +1,50 @@
1
- import { RPCHandler } from '@orpc/server/fetch'
2
- import { createContext } from '@{{projectName}}/api/context'
3
- import { appRouter } from '@{{projectName}}/api/routers/index'
1
+ import { createContext } from "@{{projectName}}/api/context";
2
+ import { appRouter } from "@{{projectName}}/api/routers/index";
3
+ import { OpenAPIHandler } from "@orpc/openapi/fetch";
4
+ import { OpenAPIReferencePlugin } from "@orpc/openapi/plugins";
5
+ import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
6
+ import { RPCHandler } from "@orpc/server/fetch";
7
+ import { onError } from "@orpc/server";
8
+ import { NextRequest } from "next/server";
4
9
 
5
- const handler = new RPCHandler(appRouter)
10
+ const rpcHandler = new RPCHandler(appRouter, {
11
+ interceptors: [
12
+ onError((error) => {
13
+ console.error(error);
14
+ }),
15
+ ],
16
+ });
17
+ const apiHandler = new OpenAPIHandler(appRouter, {
18
+ plugins: [
19
+ new OpenAPIReferencePlugin({
20
+ schemaConverters: [new ZodToJsonSchemaConverter()],
21
+ }),
22
+ ],
23
+ interceptors: [
24
+ onError((error) => {
25
+ console.error(error);
26
+ }),
27
+ ],
28
+ });
6
29
 
7
- async function handleRequest(request: Request) {
8
- const { response } = await handler.handle(request, {
9
- prefix: '/api/rpc',
10
- context: createContext(request)
11
- })
30
+ async function handleRequest(req: NextRequest) {
31
+ const rpcResult = await rpcHandler.handle(req, {
32
+ prefix: "/api/rpc",
33
+ context: await createContext(req),
34
+ });
35
+ if (rpcResult.response) return rpcResult.response;
12
36
 
13
- return response ?? new Response('Not found', { status: 404 })
37
+ const apiResult = await apiHandler.handle(req, {
38
+ prefix: "/api/rpc/api",
39
+ context: await createContext(req),
40
+ });
41
+ if (apiResult.response) return apiResult.response;
42
+
43
+ return new Response("Not found", { status: 404 });
14
44
  }
15
45
 
16
- export const HEAD = handleRequest
17
- export const GET = handleRequest
18
- export const POST = handleRequest
19
- export const PUT = handleRequest
20
- export const PATCH = handleRequest
21
- export const DELETE = handleRequest
46
+ export const GET = handleRequest;
47
+ export const POST = handleRequest;
48
+ export const PUT = handleRequest;
49
+ export const PATCH = handleRequest;
50
+ export const DELETE = handleRequest;
@@ -1,5 +1,5 @@
1
1
  import { defineNuxtPlugin, useRuntimeConfig } from '#app'
2
- import type { AppRouterClient } from "@{{projectName}}/api/src/routers/index";
2
+ import type { AppRouterClient } from "@{{projectName}}/api/routers/index";
3
3
  import { createORPCClient } from '@orpc/client'
4
4
  import { RPCLink } from '@orpc/client/fetch'
5
5
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
@@ -3,7 +3,7 @@ import { RPCLink } from "@orpc/client/fetch";
3
3
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
4
4
  import { QueryCache, QueryClient } from "@tanstack/react-query";
5
5
  import { toast } from "sonner";
6
- import type { AppRouterClient } from "@{{projectName}}/api/src/routers/index";
6
+ import type { AppRouterClient } from "@{{projectName}}/api/routers/index";
7
7
 
8
8
  export const queryClient = new QueryClient({
9
9
  queryCache: new QueryCache({
@@ -22,7 +22,7 @@ export const queryClient = new QueryClient({
22
22
 
23
23
  export const link = new RPCLink({
24
24
  {{#if (and (eq backend "self") (includes frontend "next"))}}
25
- url: "/api/rpc",
25
+ url: `${typeof window !== "undefined" ? window.location.origin : "http://localhost:3001"}/api/rpc`,
26
26
  {{else if (includes frontend "next")}}
27
27
  url: `${process.env.NEXT_PUBLIC_SERVER_URL}/rpc`,
28
28
  {{else}}
@@ -2,7 +2,7 @@ import { createORPCClient } from "@orpc/client";
2
2
  import { RPCLink } from "@orpc/client/fetch";
3
3
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
4
4
  import { QueryCache, QueryClient } from "@tanstack/solid-query";
5
- import type { AppRouterClient } from "@{{projectName}}/api/src/routers/index";
5
+ import type { AppRouterClient } from "@{{projectName}}/api/routers/index";
6
6
 
7
7
  export const queryClient = new QueryClient({
8
8
  queryCache: new QueryCache({
@@ -3,7 +3,7 @@ import { createORPCClient } from "@orpc/client";
3
3
  import { RPCLink } from "@orpc/client/fetch";
4
4
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
5
5
  import { QueryCache, QueryClient } from "@tanstack/svelte-query";
6
- import type { AppRouterClient } from "@{{projectName}}/api/src/routers/index";
6
+ import type { AppRouterClient } from "@{{projectName}}/api/routers/index";
7
7
 
8
8
  export const queryClient = new QueryClient({
9
9
  queryCache: new QueryCache({
@@ -49,13 +49,13 @@ export const trpc = createTRPCOptionsProxy<AppRouter>({
49
49
 
50
50
  {{else if (includes frontend 'tanstack-start')}}
51
51
  import { createTRPCContext } from "@trpc/tanstack-react-query";
52
- import type { AppRouter } from "@{{projectName}}/api/src/routers/index";
52
+ import type { AppRouter } from "@{{projectName}}/api/routers/index";
53
53
 
54
54
  export const { TRPCProvider, useTRPC, useTRPCClient } =
55
55
  createTRPCContext<AppRouter>();
56
56
 
57
57
  {{else}}
58
- import type { AppRouter } from "@{{projectName}}/api/src/routers/index";
58
+ import type { AppRouter } from "@{{projectName}}/api/routers/index";
59
59
  import { QueryCache, QueryClient } from "@tanstack/react-query";
60
60
  import { createTRPCClient, httpBatchLink } from "@trpc/client";
61
61
  import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
@@ -6,7 +6,7 @@ import { expo } from "@better-auth/expo";
6
6
  {{/if}}
7
7
  {{#if (eq payments "polar")}}
8
8
  import { polar, checkout, portal } from "@polar-sh/better-auth";
9
- import { polarClient } from "./payments";
9
+ import { polarClient } from "./lib/payments";
10
10
  {{/if}}
11
11
  import prisma from "@{{projectName}}/db";
12
12
 
@@ -74,7 +74,7 @@ import { expo } from "@better-auth/expo";
74
74
  {{/if}}
75
75
  {{#if (eq payments "polar")}}
76
76
  import { polar, checkout, portal } from "@polar-sh/better-auth";
77
- import { polarClient } from "./payments";
77
+ import { polarClient } from "./lib/payments";
78
78
  {{/if}}
79
79
  import { db } from "@{{projectName}}/db";
80
80
  import * as schema from "@{{projectName}}/db/schema/auth";
@@ -142,7 +142,7 @@ import { expo } from "@better-auth/expo";
142
142
  {{/if}}
143
143
  {{#if (eq payments "polar")}}
144
144
  import { polar, checkout, portal } from "@polar-sh/better-auth";
145
- import { polarClient } from "./payments";
145
+ import { polarClient } from "./lib/payments";
146
146
  {{/if}}
147
147
  import { db } from "@{{projectName}}/db";
148
148
  import * as schema from "@{{projectName}}/db/schema/auth";
@@ -224,7 +224,7 @@ import { expo } from "@better-auth/expo";
224
224
  {{/if}}
225
225
  {{#if (eq payments "polar")}}
226
226
  import { polar, checkout, portal } from "@polar-sh/better-auth";
227
- import { polarClient } from "./payments";
227
+ import { polarClient } from "./lib/payments";
228
228
  {{/if}}
229
229
  import { client } from "@{{projectName}}/db";
230
230
 
@@ -285,7 +285,7 @@ import { expo } from "@better-auth/expo";
285
285
  {{/if}}
286
286
  {{#if (eq payments "polar")}}
287
287
  import { polar, checkout, portal } from "@polar-sh/better-auth";
288
- import { polarClient } from "./payments";
288
+ import { polarClient } from "./lib/payments";
289
289
  {{/if}}
290
290
 
291
291
  export const auth = betterAuth<BetterAuthOptions>({
@@ -4,12 +4,14 @@ import { polarClient } from "@polar-sh/better-auth";
4
4
  {{/if}}
5
5
 
6
6
  export const authClient = createAuthClient({
7
+ {{#unless (eq backend "self")}}
7
8
  baseURL:
8
9
  {{#if (includes frontend "next")}}
9
10
  process.env.NEXT_PUBLIC_SERVER_URL,
10
11
  {{else}}
11
12
  import.meta.env.VITE_SERVER_URL,
12
13
  {{/if}}
14
+ {{/unless}}
13
15
  {{#if (eq payments "polar")}}
14
16
  plugins: [polarClient()]
15
17
  {{/if}}
@@ -1,3 +1,33 @@
1
+ {{#if (eq backend "self")}}
2
+ import { redirect } from "next/navigation";
3
+ import Dashboard from "./dashboard";
4
+ import { headers } from "next/headers";
5
+ import { auth } from "@{{projectName}}/auth";
6
+
7
+ export default async function DashboardPage() {
8
+ const session = await auth.api.getSession({
9
+ headers: await headers(),
10
+ });
11
+
12
+ if (!session?.user) {
13
+ redirect("/login");
14
+ }
15
+
16
+ {{#if (eq payments "polar")}}
17
+ const { data: customerState } = await auth.api.customer.state({
18
+ headers: await headers(),
19
+ });
20
+ {{/if}}
21
+
22
+ return (
23
+ <div>
24
+ <h1>Dashboard</h1>
25
+ <p>Welcome {session.user.name}</p>
26
+ <Dashboard session={session} {{#if (eq payments "polar")}}customerState={customerState}{{/if}} />
27
+ </div>
28
+ );
29
+ }
30
+ {{else}}
1
31
  import { authClient } from "@/lib/auth-client";
2
32
  import { redirect } from "next/navigation";
3
33
  import Dashboard from "./dashboard";
@@ -35,3 +65,4 @@ export default async function DashboardPage() {
35
65
  </div>
36
66
  );
37
67
  }
68
+ {{/if}}
@@ -2,7 +2,11 @@ import { defineConfig } from "drizzle-kit";
2
2
  import dotenv from "dotenv";
3
3
 
4
4
  dotenv.config({
5
- path: "../../apps/server/.env",
5
+ {{#if (eq backend "self")}}
6
+ path: "../../apps/web/.env",
7
+ {{else}}
8
+ path: "../../apps/server/.env",
9
+ {{/if}}
6
10
  });
7
11
 
8
12
  export default defineConfig({
@@ -2,7 +2,11 @@ import { defineConfig } from "drizzle-kit";
2
2
  import dotenv from "dotenv";
3
3
 
4
4
  dotenv.config({
5
- path: "../../apps/server/.env",
5
+ {{#if (eq backend "self")}}
6
+ path: "../../apps/web/.env",
7
+ {{else}}
8
+ path: "../../apps/server/.env",
9
+ {{/if}}
6
10
  });
7
11
 
8
12
  export default defineConfig({
@@ -2,7 +2,11 @@ import { defineConfig } from "drizzle-kit";
2
2
  import dotenv from "dotenv";
3
3
 
4
4
  dotenv.config({
5
- path: "../../apps/server/.env",
5
+ {{#if (eq backend "self")}}
6
+ path: "../../apps/web/.env",
7
+ {{else}}
8
+ path: "../../apps/server/.env",
9
+ {{/if}}
6
10
  });
7
11
 
8
12
  export default defineConfig({
@@ -3,7 +3,11 @@ import type { PrismaConfig } from "prisma";
3
3
  import dotenv from "dotenv";
4
4
 
5
5
  dotenv.config({
6
- path: "../../apps/server/.env",
6
+ {{#if (eq backend "self")}}
7
+ path: "../../apps/web/.env",
8
+ {{else}}
9
+ path: "../../apps/server/.env",
10
+ {{/if}}
7
11
  });
8
12
 
9
13
  export default {
@@ -3,7 +3,11 @@ import type { PrismaConfig } from "prisma";
3
3
  import dotenv from "dotenv";
4
4
 
5
5
  dotenv.config({
6
- path: "../../apps/server/.env",
6
+ {{#if (eq backend "self")}}
7
+ path: "../../apps/web/.env",
8
+ {{else}}
9
+ path: "../../apps/server/.env",
10
+ {{/if}}
7
11
  });
8
12
 
9
13
  export default {
@@ -4,7 +4,11 @@ import type { PrismaConfig } from "prisma";
4
4
  import dotenv from "dotenv";
5
5
 
6
6
  dotenv.config({
7
- path: "../../apps/server/.env",
7
+ {{#if (eq backend "self")}}
8
+ path: "../../apps/web/.env",
9
+ {{else}}
10
+ path: "../../apps/server/.env",
11
+ {{/if}}
8
12
  });
9
13
  {{/unless}}
10
14
 
@@ -3,7 +3,11 @@ import type { PrismaConfig } from "prisma";
3
3
  import dotenv from "dotenv";
4
4
 
5
5
  dotenv.config({
6
- path: "../../apps/server/.env",
6
+ {{#if (eq backend "self")}}
7
+ path: "../../apps/web/.env",
8
+ {{else}}
9
+ path: "../../apps/server/.env",
10
+ {{/if}}
7
11
  });
8
12
 
9
13
  export default {
@@ -14,10 +14,5 @@
14
14
  ".expo/types/**/*.ts",
15
15
  "expo-env.d.ts",
16
16
  "nativewind-env.d.ts"
17
- ],
18
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
19
- "references": [{
20
- "path": "../server"
21
- }]
22
- {{/unless}}
17
+ ]
23
18
  }
@@ -8,10 +8,5 @@
8
8
  "@/*": ["*"]
9
9
  }
10
10
  },
11
- "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"],
12
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
13
- "references": [{
14
- "path": "../server"
15
- }]
16
- {{/unless}}
11
+ "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
17
12
  }
@@ -13,10 +13,6 @@
13
13
  },
14
14
  {
15
15
  "path": "./.nuxt/tsconfig.node.json"
16
- }{{#unless (or (eq backend "convex") (eq backend "none"))}},
17
- {
18
- "path": "../server"
19
16
  }
20
- {{/unless}}
21
17
  ]
22
18
  }
@@ -40,12 +40,5 @@
40
40
  ],
41
41
  "exclude": [
42
42
  "./node_modules"
43
- ],
44
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
45
- "references": [
46
- {
47
- "path": "../server"
48
- }
49
43
  ]
50
- {{/unless}}
51
44
  }
@@ -23,10 +23,5 @@
23
23
  "resolveJsonModule": true,
24
24
  "skipLibCheck": true,
25
25
  "strict": true
26
- },
27
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
28
- "references": [{
29
- "path": "../server"
30
- }]
31
- {{/unless}}
26
+ }
32
27
  }
@@ -8,7 +8,7 @@ import type { QueryClient } from "@tanstack/react-query";
8
8
  import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
9
9
  import { useState } from "react";
10
10
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
11
- import type { AppRouterClient } from "@{{projectName}}/api/src/routers/index";
11
+ import type { AppRouterClient } from "@{{projectName}}/api/routers/index";
12
12
  import { createORPCClient } from "@orpc/client";
13
13
  {{/if}}
14
14
  {{#if (eq api "trpc")}}
@@ -14,10 +14,5 @@
14
14
  "paths": {
15
15
  "@/*": ["./src/*"]
16
16
  }
17
- },
18
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
19
- "references": [{
20
- "path": "../server"
21
- }]
22
- {{/unless}}
17
+ }
23
18
  }
@@ -66,7 +66,7 @@ export interface RouterAppContext {
66
66
  {{else}}
67
67
  {{#if (eq api "trpc")}}
68
68
  import type { TRPCOptionsProxy } from "@trpc/tanstack-react-query";
69
- import type { AppRouter } from "@{{projectName}}/api/src/routers/index";
69
+ import type { AppRouter } from "@{{projectName}}/api/routers/index";
70
70
  export interface RouterAppContext {
71
71
  trpc: TRPCOptionsProxy<AppRouter>;
72
72
  queryClient: QueryClient;
@@ -24,10 +24,5 @@
24
24
  "paths": {
25
25
  "@/*": ["./src/*"]
26
26
  }
27
- },
28
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
29
- "references": [{
30
- "path": "../server"
31
- }]
32
- {{/unless}}
27
+ }
33
28
  }
@@ -25,10 +25,5 @@
25
25
  "paths": {
26
26
  "@/*": ["./src/*"]
27
27
  }
28
- },
29
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
30
- "references": [{
31
- "path": "../server"
32
- }]
33
- {{/unless}}
28
+ }
34
29
  }
@@ -10,12 +10,7 @@
10
10
  "sourceMap": true,
11
11
  "strict": true,
12
12
  "moduleResolution": "bundler"
13
- },
14
- {{#unless (or (eq backend "convex") (eq backend "none"))}}
15
- "references": [{
16
- "path": "../server"
17
- }]
18
- {{/unless}}
13
+ }
19
14
  // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
20
15
  // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
21
16
  //