@better-t-stack/template-generator 3.27.4 → 3.28.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.mjs CHANGED
@@ -694,8 +694,8 @@ function renameDevScriptsForAlchemy(vfs, config) {
694
694
  //#region src/utils/add-deps.ts
695
695
  const dependencyVersionMap = {
696
696
  typescript: "^6",
697
- "better-auth": "1.5.5",
698
- "@better-auth/expo": "1.5.5",
697
+ "better-auth": "1.6.9",
698
+ "@better-auth/expo": "1.6.9",
699
699
  "@clerk/backend": "^3.2.1",
700
700
  "@clerk/express": "^2.0.5",
701
701
  "@clerk/fastify": "^3.1.3",
@@ -737,10 +737,11 @@ const dependencyVersionMap = {
737
737
  tsx: "^4.19.2",
738
738
  "@types/node": "^22.13.14",
739
739
  "@types/bun": "^1.3.4",
740
- "@elysiajs/node": "^1.3.1",
740
+ "@elysiajs/node": "^1.4.5",
741
741
  "@elysiajs/cors": "^1.4.1",
742
742
  "@elysiajs/trpc": "^1.1.0",
743
- elysia: "^1.4.21",
743
+ elysia: "^1.4.28",
744
+ "@sinclair/typebox": "^0.34.49",
744
745
  "@hono/node-server": "^1.14.4",
745
746
  "@hono/trpc-server": "^0.4.0",
746
747
  hono: "^4.8.2",
@@ -769,13 +770,14 @@ const dependencyVersionMap = {
769
770
  "@trpc/server": "^11.16.0",
770
771
  "@trpc/client": "^11.16.0",
771
772
  next: "^16.2.0",
773
+ nitro: "^3.0.260429-beta",
772
774
  convex: "^1.33.1",
773
775
  "@convex-dev/react-query": "^0.1.0",
774
776
  "@convex-dev/agent": "^0.3.2",
775
777
  "convex-svelte": "^0.0.12",
776
778
  "convex-nuxt": "0.1.5",
777
779
  "convex-vue": "^0.1.5",
778
- "@convex-dev/better-auth": "^0.11.4",
780
+ "@convex-dev/better-auth": "^0.12.1",
779
781
  "@tanstack/svelte-query": "^5.85.3",
780
782
  "@tanstack/svelte-query-devtools": "^5.85.3",
781
783
  "@tanstack/vue-query-devtools": "^6.1.5",
@@ -805,7 +807,8 @@ const dependencyVersionMap = {
805
807
  "@t3-oss/env-nextjs": "^0.13.1",
806
808
  "@t3-oss/env-nuxt": "^0.13.1",
807
809
  "@polar-sh/better-auth": "^1.8.3",
808
- "@polar-sh/sdk": "^0.42.2"
810
+ "@polar-sh/sdk": "^0.42.2",
811
+ evlog: "^2.14.1"
809
812
  };
810
813
  /**
811
814
  * Add dependencies to a package.json file in the VFS
@@ -837,6 +840,13 @@ function processAddonsDeps(vfs, config) {
837
840
  const hasViteReactFrontend = config.frontend.includes("react-router") || config.frontend.includes("tanstack-router");
838
841
  const hasSolidFrontend = config.frontend.includes("solid");
839
842
  const hasPwaCompatibleFrontend = hasViteReactFrontend || hasSolidFrontend;
843
+ const hasEvlogWebServer = config.frontend.some((frontend) => [
844
+ "next",
845
+ "nuxt",
846
+ "svelte",
847
+ "tanstack-start",
848
+ "astro"
849
+ ].includes(frontend));
840
850
  if (config.addons.includes("turborepo")) addPackageDependency({
841
851
  vfs,
842
852
  packagePath: "package.json",
@@ -847,6 +857,20 @@ function processAddonsDeps(vfs, config) {
847
857
  packagePath: "package.json",
848
858
  devDependencies: ["nx"]
849
859
  });
860
+ if (config.addons.includes("evlog")) {
861
+ const serverPkgPath = "apps/server/package.json";
862
+ if (vfs.exists(serverPkgPath) && config.backend !== "self" && config.backend !== "none") addPackageDependency({
863
+ vfs,
864
+ packagePath: serverPkgPath,
865
+ dependencies: ["evlog"]
866
+ });
867
+ const webPkgPath = "apps/web/package.json";
868
+ if (vfs.exists(webPkgPath) && hasEvlogWebServer) addPackageDependency({
869
+ vfs,
870
+ packagePath: webPkgPath,
871
+ dependencies: config.frontend.includes("tanstack-start") ? ["evlog", "nitro"] : ["evlog"]
872
+ });
873
+ }
850
874
  if (config.addons.includes("pwa") && hasPwaCompatibleFrontend) {
851
875
  const webPkgPath = "apps/web/package.json";
852
876
  if (vfs.exists(webPkgPath)) {
@@ -934,6 +958,49 @@ function processNuxtAlchemy(vfs) {
934
958
  moduleSpecifier: "alchemy/cloudflare/nuxt",
935
959
  defaultImport: "alchemy"
936
960
  });
961
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:fs")) sourceFile.addImportDeclaration({
962
+ moduleSpecifier: "node:fs",
963
+ namedImports: ["existsSync"]
964
+ });
965
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:url")) sourceFile.addImportDeclaration({
966
+ moduleSpecifier: "node:url",
967
+ namedImports: ["fileURLToPath"]
968
+ });
969
+ if (!sourceFile.getVariableDeclaration("alchemyConfigPath")) {
970
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
971
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const alchemyConfigPath = fileURLToPath(new URL("./.alchemy/local/wrangler.jsonc", import.meta.url));
972
+ const hasAlchemyConfig = existsSync(alchemyConfigPath);`);
973
+ }
974
+ if (!sourceFile.getVariableDeclaration("cloudflareWorkersShimPath")) {
975
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
976
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const cloudflareWorkersShimPath = fileURLToPath(new URL("../../packages/env/src/cloudflare-local.ts", import.meta.url));`);
977
+ }
978
+ if (!sourceFile.getVariableDeclaration("isNuxtPrepare")) {
979
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
980
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const isNuxtPrepare =
981
+ process.env.npm_lifecycle_event === "postinstall" ||
982
+ process.env.npm_lifecycle_script === "nuxt prepare" ||
983
+ process.argv.includes("prepare");`);
984
+ }
985
+ if (!sourceFile.getVariableDeclaration("shouldUseAlchemy")) {
986
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
987
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const shouldUseAlchemy = !isNuxtPrepare && hasAlchemyConfig;`);
988
+ }
989
+ if (!sourceFile.getVariableDeclaration("cloudflareWorkersAlias")) {
990
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
991
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const cloudflareWorkersAlias = shouldUseAlchemy
992
+ ? {}
993
+ : {
994
+ "cloudflare:workers": cloudflareWorkersShimPath,
995
+ };`);
996
+ }
997
+ if (!sourceFile.getVariableDeclaration("isNuxtDev")) {
998
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
999
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const isNuxtDev =
1000
+ !isNuxtPrepare &&
1001
+ process.env.NODE_ENV !== "production" &&
1002
+ !process.argv.some((arg) => arg === "build" || arg === "generate");`);
1003
+ }
937
1004
  const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());
938
1005
  if (!exportAssignment) return;
939
1006
  const defineConfigCall = exportAssignment.getExpression();
@@ -945,11 +1012,20 @@ function processNuxtAlchemy(vfs) {
945
1012
  name: "nitro",
946
1013
  initializer: `{
947
1014
  preset: "cloudflare-module",
948
- cloudflare: alchemy(),
1015
+ ...(shouldUseAlchemy ? { cloudflare: alchemy({ dev: { configPath: alchemyConfigPath } }) } : {}),
1016
+ alias: cloudflareWorkersAlias,
949
1017
  prerender: {
950
1018
  routes: ["/"],
951
1019
  autoSubfolderIndex: false,
952
1020
  },
1021
+ }`
1022
+ });
1023
+ if (!configObject.getProperty("vite")) configObject.addPropertyAssignment({
1024
+ name: "vite",
1025
+ initializer: `{
1026
+ resolve: {
1027
+ alias: cloudflareWorkersAlias,
1028
+ },
953
1029
  }`
954
1030
  });
955
1031
  const modulesProperty = configObject.getProperty("modules");
@@ -976,15 +1052,27 @@ function processSvelteAlchemy(vfs) {
976
1052
  quoteKind: QuoteKind.Single
977
1053
  }
978
1054
  }).createSourceFile("svelte.config.js", content);
979
- const adapterImport = sourceFile.getImportDeclarations().find((imp) => imp.getModuleSpecifierValue().includes("@sveltejs/adapter"));
980
- if (adapterImport) {
981
- adapterImport.setModuleSpecifier("alchemy/cloudflare/sveltekit");
982
- adapterImport.removeDefaultImport();
983
- adapterImport.setDefaultImport("alchemy");
984
- } else sourceFile.insertImportDeclaration(0, {
1055
+ if (!sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === "alchemy/cloudflare/sveltekit")) sourceFile.insertImportDeclaration(0, {
985
1056
  moduleSpecifier: "alchemy/cloudflare/sveltekit",
986
1057
  defaultImport: "alchemy"
987
1058
  });
1059
+ if (!sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === "@sveltejs/adapter-auto")) sourceFile.insertImportDeclaration(0, {
1060
+ moduleSpecifier: "@sveltejs/adapter-auto",
1061
+ defaultImport: "adapter"
1062
+ });
1063
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:fs")) sourceFile.insertImportDeclaration(0, {
1064
+ moduleSpecifier: "node:fs",
1065
+ namedImports: ["existsSync"]
1066
+ });
1067
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:url")) sourceFile.insertImportDeclaration(0, {
1068
+ moduleSpecifier: "node:url",
1069
+ namedImports: ["fileURLToPath"]
1070
+ });
1071
+ if (!sourceFile.getVariableDeclaration("alchemyConfigPath")) {
1072
+ const configVariableIndex = sourceFile.getStatements().findIndex((statement) => Node.isVariableStatement(statement) && statement.getDeclarationList().getDeclarations().some((decl) => decl.getName() === "config"));
1073
+ sourceFile.insertStatements(configVariableIndex === -1 ? sourceFile.getStatements().length : configVariableIndex, `const alchemyConfigPath = fileURLToPath(new URL("./.alchemy/local/wrangler.jsonc", import.meta.url));
1074
+ const shouldUseAlchemy = existsSync(alchemyConfigPath);`);
1075
+ }
988
1076
  const configVariable = sourceFile.getVariableDeclaration("config");
989
1077
  if (configVariable) {
990
1078
  const initializer = configVariable.getInitializer();
@@ -994,13 +1082,7 @@ function processSvelteAlchemy(vfs) {
994
1082
  const kitInitializer = kitProperty.getInitializer();
995
1083
  if (Node.isObjectLiteralExpression(kitInitializer)) {
996
1084
  const adapterProperty = kitInitializer.getProperty("adapter");
997
- if (adapterProperty && Node.isPropertyAssignment(adapterProperty)) {
998
- const adapterInitializer = adapterProperty.getInitializer();
999
- if (Node.isCallExpression(adapterInitializer)) {
1000
- const expression = adapterInitializer.getExpression();
1001
- if (Node.isIdentifier(expression) && expression.getText() === "adapter") expression.replaceWithText("alchemy");
1002
- }
1003
- }
1085
+ if (adapterProperty && Node.isPropertyAssignment(adapterProperty)) adapterProperty.setInitializer("shouldUseAlchemy ? alchemy({ platformProxy: { configPath: alchemyConfigPath } }) : adapter()");
1004
1086
  }
1005
1087
  }
1006
1088
  }
@@ -1022,6 +1104,31 @@ function processTanStackStartAlchemy(vfs) {
1022
1104
  moduleSpecifier: "alchemy/cloudflare/tanstack-start",
1023
1105
  defaultImport: "alchemy"
1024
1106
  });
1107
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:fs")) sourceFile.addImportDeclaration({
1108
+ moduleSpecifier: "node:fs",
1109
+ namedImports: ["existsSync"]
1110
+ });
1111
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:url")) sourceFile.addImportDeclaration({
1112
+ moduleSpecifier: "node:url",
1113
+ namedImports: ["fileURLToPath"]
1114
+ });
1115
+ if (!sourceFile.getVariableDeclaration("alchemyConfigPath")) {
1116
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
1117
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const alchemyConfigPath = fileURLToPath(new URL("./.alchemy/local/wrangler.jsonc", import.meta.url));
1118
+ const shouldUseAlchemy = existsSync(alchemyConfigPath);`);
1119
+ }
1120
+ if (!sourceFile.getVariableDeclaration("cloudflareWorkersShimPath")) {
1121
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
1122
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const cloudflareWorkersShimPath = fileURLToPath(new URL("../../packages/env/src/cloudflare-local.ts", import.meta.url));`);
1123
+ }
1124
+ if (!sourceFile.getVariableDeclaration("cloudflareWorkersAlias")) {
1125
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
1126
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const cloudflareWorkersAlias = shouldUseAlchemy
1127
+ ? {}
1128
+ : {
1129
+ "cloudflare:workers": cloudflareWorkersShimPath,
1130
+ };`);
1131
+ }
1025
1132
  const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());
1026
1133
  if (!exportAssignment) return;
1027
1134
  const defineConfigCall = exportAssignment.getExpression();
@@ -1033,11 +1140,22 @@ function processTanStackStartAlchemy(vfs) {
1033
1140
  if (pluginsProperty && Node.isPropertyAssignment(pluginsProperty)) {
1034
1141
  const initializer = pluginsProperty.getInitializer();
1035
1142
  if (Node.isArrayLiteralExpression(initializer)) {
1036
- if (!initializer.getElements().some((el) => el.getText().includes("alchemy("))) initializer.addElement("alchemy()");
1143
+ if (!initializer.getElements().some((el) => el.getText().includes("alchemy("))) initializer.addElement("...(shouldUseAlchemy ? [alchemy({ configPath: alchemyConfigPath })] : [])");
1037
1144
  }
1038
1145
  } else configObject.addPropertyAssignment({
1039
1146
  name: "plugins",
1040
- initializer: "[alchemy()]"
1147
+ initializer: "[...(shouldUseAlchemy ? [alchemy({ configPath: alchemyConfigPath })] : [])]"
1148
+ });
1149
+ const resolveProperty = configObject.getProperty("resolve");
1150
+ if (resolveProperty && Node.isPropertyAssignment(resolveProperty)) {
1151
+ const initializer = resolveProperty.getInitializer();
1152
+ if (Node.isObjectLiteralExpression(initializer) && !initializer.getProperty("alias")) initializer.addPropertyAssignment({
1153
+ name: "alias",
1154
+ initializer: "cloudflareWorkersAlias"
1155
+ });
1156
+ } else if (!resolveProperty) configObject.addPropertyAssignment({
1157
+ name: "resolve",
1158
+ initializer: "{ alias: cloudflareWorkersAlias }"
1041
1159
  });
1042
1160
  }
1043
1161
  vfs.writeFile(viteConfigPath, sourceFile.getFullText());
@@ -1053,15 +1171,39 @@ function processAstroAlchemy(vfs) {
1053
1171
  quoteKind: QuoteKind.Double
1054
1172
  }
1055
1173
  }).createSourceFile("astro.config.mjs", content);
1056
- const nodeAdapterImport = sourceFile.getImportDeclarations().find((imp) => imp.getModuleSpecifierValue() === "@astrojs/node");
1057
- if (nodeAdapterImport) {
1058
- nodeAdapterImport.setModuleSpecifier("alchemy/cloudflare/astro");
1059
- nodeAdapterImport.removeDefaultImport();
1060
- nodeAdapterImport.setDefaultImport("alchemy");
1061
- } else sourceFile.insertImportDeclaration(0, {
1174
+ if (!sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === "alchemy/cloudflare/astro")) sourceFile.insertImportDeclaration(0, {
1062
1175
  moduleSpecifier: "alchemy/cloudflare/astro",
1063
1176
  defaultImport: "alchemy"
1064
1177
  });
1178
+ if (!sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === "@astrojs/node")) sourceFile.insertImportDeclaration(0, {
1179
+ moduleSpecifier: "@astrojs/node",
1180
+ defaultImport: "node"
1181
+ });
1182
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:fs")) sourceFile.insertImportDeclaration(0, {
1183
+ moduleSpecifier: "node:fs",
1184
+ namedImports: ["existsSync"]
1185
+ });
1186
+ if (!sourceFile.getImportDeclarations().some((decl) => decl.getModuleSpecifierValue() === "node:url")) sourceFile.insertImportDeclaration(0, {
1187
+ moduleSpecifier: "node:url",
1188
+ namedImports: ["fileURLToPath"]
1189
+ });
1190
+ if (!sourceFile.getVariableDeclaration("alchemyConfigPath")) {
1191
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
1192
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const alchemyConfigPath = fileURLToPath(new URL("./.alchemy/local/wrangler.jsonc", import.meta.url));
1193
+ const shouldUseAlchemy = existsSync(alchemyConfigPath);`);
1194
+ }
1195
+ if (!sourceFile.getVariableDeclaration("cloudflareWorkersShimPath")) {
1196
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
1197
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const cloudflareWorkersShimPath = fileURLToPath(new URL("../../packages/env/src/cloudflare-local.ts", import.meta.url));`);
1198
+ }
1199
+ if (!sourceFile.getVariableDeclaration("cloudflareWorkersAlias")) {
1200
+ const firstExport = sourceFile.getStatements().findIndex((statement) => Node.isExportAssignment(statement));
1201
+ sourceFile.insertStatements(firstExport === -1 ? sourceFile.getStatements().length : firstExport, `const cloudflareWorkersAlias = shouldUseAlchemy
1202
+ ? {}
1203
+ : {
1204
+ "cloudflare:workers": cloudflareWorkersShimPath,
1205
+ };`);
1206
+ }
1065
1207
  const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());
1066
1208
  if (exportAssignment) {
1067
1209
  const defineConfigCall = exportAssignment.getExpression();
@@ -1069,7 +1211,27 @@ function processAstroAlchemy(vfs) {
1069
1211
  const configObject = defineConfigCall.getArguments()[0];
1070
1212
  if (Node.isObjectLiteralExpression(configObject)) {
1071
1213
  const adapterProperty = configObject.getProperty("adapter");
1072
- if (adapterProperty && Node.isPropertyAssignment(adapterProperty)) adapterProperty.setInitializer("alchemy()");
1214
+ if (adapterProperty && Node.isPropertyAssignment(adapterProperty)) adapterProperty.setInitializer("shouldUseAlchemy ? alchemy({ platformProxy: { configPath: alchemyConfigPath } }) : node({ mode: \"standalone\" })");
1215
+ const viteProperty = configObject.getProperty("vite");
1216
+ if (viteProperty && Node.isPropertyAssignment(viteProperty)) {
1217
+ const viteInitializer = viteProperty.getInitializer();
1218
+ if (Node.isObjectLiteralExpression(viteInitializer)) {
1219
+ const resolveProperty = viteInitializer.getProperty("resolve");
1220
+ if (resolveProperty && Node.isPropertyAssignment(resolveProperty)) {
1221
+ const resolveInitializer = resolveProperty.getInitializer();
1222
+ if (Node.isObjectLiteralExpression(resolveInitializer) && !resolveInitializer.getProperty("alias")) resolveInitializer.addPropertyAssignment({
1223
+ name: "alias",
1224
+ initializer: "cloudflareWorkersAlias"
1225
+ });
1226
+ } else if (!resolveProperty) viteInitializer.addPropertyAssignment({
1227
+ name: "resolve",
1228
+ initializer: "{ alias: cloudflareWorkersAlias }"
1229
+ });
1230
+ }
1231
+ } else if (!viteProperty) configObject.addPropertyAssignment({
1232
+ name: "vite",
1233
+ initializer: "{ resolve: { alias: cloudflareWorkersAlias } }"
1234
+ });
1073
1235
  }
1074
1236
  }
1075
1237
  }
@@ -1326,7 +1488,7 @@ function addConvexDeps(vfs, frontend, frontendType) {
1326
1488
  }
1327
1489
  //#endregion
1328
1490
  //#region src/processors/auth-deps.ts
1329
- const CONVEX_BETTER_AUTH_VERSION = "1.5.3";
1491
+ const CONVEX_BETTER_AUTH_VERSION = "1.6.9";
1330
1492
  function processAuthDeps(vfs, config) {
1331
1493
  const { auth, backend } = config;
1332
1494
  if (!auth || auth === "none") return;
@@ -1665,7 +1827,7 @@ function processBackendDeps(vfs, config) {
1665
1827
  deps.push("hono");
1666
1828
  if (runtime === "node") deps.push("@hono/node-server");
1667
1829
  } else if (backend === "elysia") {
1668
- deps.push("elysia", "@elysiajs/cors");
1830
+ deps.push("elysia", "@elysiajs/cors", "@sinclair/typebox");
1669
1831
  if (runtime === "node") deps.push("@elysiajs/node");
1670
1832
  } else if (backend === "express") {
1671
1833
  deps.push("express", "cors");
@@ -1694,9 +1856,9 @@ function processDatabaseDeps(vfs, config) {
1694
1856
  const dbPkgPath = "packages/db/package.json";
1695
1857
  const webPkgPath = "apps/web/package.json";
1696
1858
  if (!vfs.exists(dbPkgPath)) return;
1697
- const webExists = vfs.exists(webPkgPath);
1698
- if (orm === "prisma") processPrismaDeps(vfs, config, dbPkgPath, webPkgPath, webExists);
1699
- else if (orm === "drizzle") processDrizzleDeps(vfs, config, dbPkgPath, webPkgPath, webExists);
1859
+ const webNeedsDbRuntime = backend === "self" && vfs.exists(webPkgPath);
1860
+ if (orm === "prisma") processPrismaDeps(vfs, config, dbPkgPath, webPkgPath, webNeedsDbRuntime);
1861
+ else if (orm === "drizzle") processDrizzleDeps(vfs, config, dbPkgPath, webPkgPath, webNeedsDbRuntime);
1700
1862
  else if (orm === "mongoose") addPackageDependency({
1701
1863
  vfs,
1702
1864
  packagePath: dbPkgPath,
@@ -1848,6 +2010,7 @@ function processDeployDeps(vfs, config) {
1848
2010
  else if (frontend.includes("astro")) addPackageDependency({
1849
2011
  vfs,
1850
2012
  packagePath: webPkgPath,
2013
+ dependencies: ["@astrojs/node"],
1851
2014
  devDependencies: [
1852
2015
  "alchemy",
1853
2016
  "@astrojs/cloudflare",
@@ -2019,9 +2182,10 @@ function buildClientVars(frontend, backend, auth) {
2019
2182
  }
2020
2183
  function buildNativeVars(frontend, backend, auth) {
2021
2184
  const hasAstro = frontend.includes("astro");
2185
+ const hasSvelte = frontend.includes("svelte");
2022
2186
  let envVarName = "EXPO_PUBLIC_SERVER_URL";
2023
2187
  let serverUrl = "http://localhost:3000";
2024
- if (backend === "self") serverUrl = hasAstro ? "http://localhost:4321" : "http://localhost:3001";
2188
+ if (backend === "self") serverUrl = hasSvelte ? "http://localhost:5173" : hasAstro ? "http://localhost:4321" : "http://localhost:3001";
2025
2189
  if (backend === "convex") {
2026
2190
  envVarName = "EXPO_PUBLIC_CONVEX_URL";
2027
2191
  serverUrl = "https://<YOUR_CONVEX_URL>";
@@ -2134,7 +2298,7 @@ function buildServerVars(backend, frontend, auth, api, database, dbSetup, runtim
2134
2298
  },
2135
2299
  {
2136
2300
  key: "BETTER_AUTH_URL",
2137
- value: backend === "self" ? hasAstro ? "http://localhost:4321" : "http://localhost:3001" : "http://localhost:3000",
2301
+ value: backend === "self" ? hasSvelte ? "http://localhost:5173" : hasAstro ? "http://localhost:4321" : "http://localhost:3001" : "http://localhost:3000",
2138
2302
  condition: hasBetterAuth
2139
2303
  },
2140
2304
  {
@@ -2664,7 +2828,7 @@ ${packageManagerRunCmd} dev
2664
2828
  ${generateRunningInstructions(frontend, backend, webPort, hasNative, isConvex)}
2665
2829
  ${generateReactUiSection(hasReactWeb, projectName)}
2666
2830
  ${addons.includes("pwa") && hasReactRouter ? "\n## PWA Support with React Router v7\n\nThere is a known compatibility issue between VitePWA and React Router v7.\nSee: https://github.com/vite-pwa/vite-plugin-pwa/issues/809\n" : ""}
2667
- ${generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy)}
2831
+ ${generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy, backend)}
2668
2832
  ${generateGitHooksSection(packageManagerRunCmd, addons)}
2669
2833
 
2670
2834
  ## Project Structure
@@ -2962,12 +3126,11 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
2962
3126
  - \`cd apps/docs && ${packageManagerRunCmd} build\`: Build documentation site`;
2963
3127
  return scripts;
2964
3128
  }
2965
- function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy) {
3129
+ function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy, backend) {
2966
3130
  if (webDeploy !== "cloudflare" && serverDeploy !== "cloudflare") return "";
2967
3131
  const lines = ["## Deployment (Cloudflare via Alchemy)"];
2968
- if (webDeploy === "cloudflare" && serverDeploy !== "cloudflare") lines.push(`- Dev: cd apps/web && ${packageManagerRunCmd} alchemy dev`, `- Deploy: cd apps/web && ${packageManagerRunCmd} deploy`, `- Destroy: cd apps/web && ${packageManagerRunCmd} destroy`);
2969
- if (serverDeploy === "cloudflare" && webDeploy !== "cloudflare") lines.push(`- Dev: cd apps/server && ${packageManagerRunCmd} dev`, `- Deploy: cd apps/server && ${packageManagerRunCmd} deploy`, `- Destroy: cd apps/server && ${packageManagerRunCmd} destroy`);
2970
- if (webDeploy === "cloudflare" && serverDeploy === "cloudflare") lines.push(`- Dev: ${packageManagerRunCmd} dev`, `- Deploy: ${packageManagerRunCmd} deploy`, `- Destroy: ${packageManagerRunCmd} destroy`);
3132
+ const targetLabel = webDeploy === "cloudflare" && (serverDeploy === "cloudflare" || backend === "self") ? "web + server" : webDeploy === "cloudflare" ? "web" : "server";
3133
+ lines.push(`- Target: ${targetLabel}`, `- Dev: ${packageManagerRunCmd} dev`, `- Deploy: ${packageManagerRunCmd} deploy`, `- Destroy: ${packageManagerRunCmd} destroy`);
2971
3134
  lines.push("", "For more details, see the guide on [Deploying to Cloudflare with Alchemy](https://www.better-t-stack.dev/docs/guides/cloudflare-alchemy).");
2972
3135
  return `${lines.join("\n")}\n`;
2973
3136
  }
@@ -3112,6 +3275,7 @@ function getDeployTasks() {
3112
3275
  }
3113
3276
  //#endregion
3114
3277
  //#region src/processors/workspace-deps.ts
3278
+ const NATIVE_TYPESCRIPT_VERSION = "~5.9.2";
3115
3279
  function processWorkspaceDeps(vfs, config) {
3116
3280
  const { projectName, packageManager, runtime, backend, database, auth, api, serverDeploy, webDeploy } = config;
3117
3281
  const workspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
@@ -3221,7 +3385,7 @@ function processWorkspaceDeps(vfs, config) {
3221
3385
  ...uiDep
3222
3386
  };
3223
3387
  if (api !== "none" && packages.api) webPackageDeps[`@${projectName}/api`] = workspaceVersion;
3224
- if (auth !== "none" && packages.auth) webPackageDeps[`@${projectName}/auth`] = workspaceVersion;
3388
+ if (backend === "self" && auth !== "none" && packages.auth) webPackageDeps[`@${projectName}/auth`] = workspaceVersion;
3225
3389
  if (backend === "convex" && packages.backend) webPackageDeps[`@${projectName}/backend`] = workspaceVersion;
3226
3390
  addPackageDependency({
3227
3391
  vfs,
@@ -3246,9 +3410,11 @@ function processWorkspaceDeps(vfs, config) {
3246
3410
  vfs,
3247
3411
  packagePath: "apps/native/package.json",
3248
3412
  dependencies: commonDeps,
3249
- devDependencies: ["typescript"],
3250
3413
  customDependencies: nativeDeps,
3251
- customDevDependencies: configDep
3414
+ customDevDependencies: {
3415
+ ...configDep,
3416
+ typescript: NATIVE_TYPESCRIPT_VERSION
3417
+ }
3252
3418
  });
3253
3419
  }
3254
3420
  }
@@ -3405,8 +3571,13 @@ async function processApiTemplates(vfs, templates, config) {
3405
3571
  processTemplatesFromPrefix(vfs, templates, `api/${config.api}/fullstack/nuxt`, "apps/web", config);
3406
3572
  processSingleTemplate(vfs, templates, `api/${config.api}/web/nuxt/app/plugins/vue-query.ts`, "apps/web/app/plugins/vue-query.ts", config);
3407
3573
  } else processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/nuxt`, "apps/web", config);
3408
- else if (hasSvelteWeb && config.api === "orpc") processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/svelte`, "apps/web", config);
3409
- else if (hasSolidWeb && config.api === "orpc") processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/solid`, "apps/web", config);
3574
+ else if (hasSvelteWeb && config.api === "orpc") {
3575
+ processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/svelte`, "apps/web", config);
3576
+ if (config.backend === "self") {
3577
+ processTemplatesFromPrefix(vfs, templates, `api/${config.api}/fullstack/svelte`, "apps/web", config);
3578
+ if (config.auth !== "better-auth") vfs.writeFile("apps/web/src/hooks.server.ts", "import \"./lib/orpc.server\";\n");
3579
+ }
3580
+ } else if (hasSolidWeb && config.api === "orpc") processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/solid`, "apps/web", config);
3410
3581
  else if (hasAstroWeb && config.api === "orpc") {
3411
3582
  processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/astro`, "apps/web", config);
3412
3583
  if (config.backend === "self") processTemplatesFromPrefix(vfs, templates, `api/${config.api}/fullstack/astro`, "apps/web", config);
@@ -3438,7 +3609,10 @@ async function processEnvPackage(vfs, templates, config) {
3438
3609
  processSingleTemplate(vfs, templates, "packages/env/tsconfig.json", "packages/env/tsconfig.json", config);
3439
3610
  if (hasWebFrontend) processSingleTemplate(vfs, templates, "packages/env/src/web.ts", "packages/env/src/web.ts", config);
3440
3611
  if (hasNative) processSingleTemplate(vfs, templates, "packages/env/src/native.ts", "packages/env/src/native.ts", config);
3441
- if (config.backend !== "none" && config.backend !== "convex") processSingleTemplate(vfs, templates, "packages/env/src/server.ts", "packages/env/src/server.ts", config);
3612
+ if (config.backend !== "none" && config.backend !== "convex") {
3613
+ processSingleTemplate(vfs, templates, "packages/env/src/server.ts", "packages/env/src/server.ts", config);
3614
+ if (config.serverDeploy === "cloudflare" || config.backend === "self" && config.webDeploy === "cloudflare") processSingleTemplate(vfs, templates, "packages/env/src/cloudflare-local.ts", "packages/env/src/cloudflare-local.ts", config);
3615
+ }
3442
3616
  }
3443
3617
  async function processUiPackage(vfs, templates, config) {
3444
3618
  if (!config.frontend.some((f) => [
@@ -3530,8 +3704,10 @@ async function processAuthTemplates(vfs, templates, config) {
3530
3704
  } else if (hasNuxtWeb) {
3531
3705
  if (config.backend === "self") processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/fullstack/nuxt`, "apps/web", config);
3532
3706
  processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/nuxt`, "apps/web", config);
3533
- } else if (hasSvelteWeb) processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/svelte`, "apps/web", config);
3534
- else if (hasSolidWeb) processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/solid`, "apps/web", config);
3707
+ } else if (hasSvelteWeb) {
3708
+ if (config.backend === "self" && authProvider === "better-auth") processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/fullstack/svelte`, "apps/web", config);
3709
+ processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/svelte`, "apps/web", config);
3710
+ } else if (hasSolidWeb) processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/solid`, "apps/web", config);
3535
3711
  else if (hasAstroWeb) {
3536
3712
  if (config.backend === "self" && authProvider === "better-auth") processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/fullstack/astro`, "apps/web", config);
3537
3713
  processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/astro`, "apps/web", config);
@@ -3630,8 +3806,10 @@ async function processExampleTemplates(vfs, templates, config) {
3630
3806
  } else if (hasNuxtWeb) {
3631
3807
  if (config.backend === "self") processTemplatesFromPrefix(vfs, templates, `examples/${example}/fullstack/nuxt`, "apps/web", config);
3632
3808
  processTemplatesFromPrefix(vfs, templates, `examples/${example}/web/nuxt`, "apps/web", config);
3633
- } else if (hasSvelteWeb) processTemplatesFromPrefix(vfs, templates, `examples/${example}/web/svelte`, "apps/web", config);
3634
- else if (hasSolidWeb) processTemplatesFromPrefix(vfs, templates, `examples/${example}/web/solid`, "apps/web", config);
3809
+ } else if (hasSvelteWeb) {
3810
+ if (config.backend === "self") processTemplatesFromPrefix(vfs, templates, `examples/${example}/fullstack/svelte`, "apps/web", config);
3811
+ processTemplatesFromPrefix(vfs, templates, `examples/${example}/web/svelte`, "apps/web", config);
3812
+ } else if (hasSolidWeb) processTemplatesFromPrefix(vfs, templates, `examples/${example}/web/solid`, "apps/web", config);
3635
3813
  else if (hasAstroWeb) processTemplatesFromPrefix(vfs, templates, `examples/${example}/web/astro`, "apps/web", config);
3636
3814
  if (hasNative) {
3637
3815
  let nativeFramework = "";
@@ -4094,6 +4272,9 @@ export default defineConfig({
4094
4272
  });
4095
4273
  `],
4096
4274
  ["api/orpc/fullstack/astro/src/pages/rpc/[...rest].ts.hbs", `import type { APIRoute } from "astro";
4275
+ import { OpenAPIHandler } from "@orpc/openapi/fetch";
4276
+ import { OpenAPIReferencePlugin } from "@orpc/openapi/plugins";
4277
+ import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
4097
4278
  import { RPCHandler } from "@orpc/server/fetch";
4098
4279
  import { onError } from "@orpc/server";
4099
4280
  import { appRouter } from "@{{projectName}}/api/routers/index";
@@ -4107,17 +4288,37 @@ const handler = new RPCHandler(appRouter, {
4107
4288
  ],
4108
4289
  });
4109
4290
 
4291
+ const apiHandler = new OpenAPIHandler(appRouter, {
4292
+ plugins: [
4293
+ new OpenAPIReferencePlugin({
4294
+ schemaConverters: [new ZodToJsonSchemaConverter()],
4295
+ }),
4296
+ ],
4297
+ interceptors: [
4298
+ onError((error) => {
4299
+ console.error(error);
4300
+ }),
4301
+ ],
4302
+ });
4303
+
4110
4304
  export const prerender = false;
4111
4305
 
4112
4306
  export const ALL: APIRoute = async ({ request }) => {
4113
4307
  const context = await createContext({ headers: request.headers });
4114
4308
 
4115
- const { response } = await handler.handle(request, {
4309
+ const rpcResult = await handler.handle(request, {
4116
4310
  prefix: "/rpc",
4117
4311
  context,
4118
4312
  });
4313
+ if (rpcResult.response) return rpcResult.response;
4314
+
4315
+ const apiResult = await apiHandler.handle(request, {
4316
+ prefix: "/rpc/api-reference",
4317
+ context,
4318
+ });
4319
+ if (apiResult.response) return apiResult.response;
4119
4320
 
4120
- return response ?? new Response("Not found", { status: 404 });
4321
+ return new Response("Not found", { status: 404 });
4121
4322
  };
4122
4323
  `],
4123
4324
  ["api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs", `import { createContext } from "@{{projectName}}/api/context";
@@ -4275,6 +4476,105 @@ export default defineEventHandler(async (event) => {
4275
4476
  });
4276
4477
  `],
4277
4478
  ["api/orpc/fullstack/nuxt/server/routes/rpc/index.ts.hbs", `export { default } from "./[...]";
4479
+ `],
4480
+ ["api/orpc/fullstack/svelte/src/lib/orpc.server.ts.hbs", `import { getRequestEvent } from "$app/server";
4481
+ import { createContext } from "@{{projectName}}/api/context";
4482
+ import { appRouter, type AppRouterClient } from "@{{projectName}}/api/routers/index";
4483
+ {{#if (eq webDeploy "cloudflare")}}
4484
+ import { env as localEnv } from "@{{projectName}}/env/server";
4485
+ {{/if}}
4486
+ import { createRouterClient } from "@orpc/server";
4487
+
4488
+ if (typeof window !== "undefined") {
4489
+ throw new Error("This file should only be imported on the server.");
4490
+ }
4491
+
4492
+ const serverClient: AppRouterClient = createRouterClient(appRouter, {
4493
+ context: async () => {
4494
+ const event = getRequestEvent();
4495
+ {{#if (eq webDeploy "cloudflare")}}
4496
+ const env = event.platform?.env ?? localEnv;
4497
+
4498
+ {{/if}}
4499
+ return createContext({
4500
+ headers: event.request.headers,
4501
+ {{#if (eq webDeploy "cloudflare")}}
4502
+ env,
4503
+ {{/if}}
4504
+ });
4505
+ },
4506
+ });
4507
+
4508
+ // oRPC's SvelteKit SSR setup loads this from hooks.server.ts so $lib/orpc can
4509
+ // reuse the in-process server client during SSR and fall back to HTTP in the browser.
4510
+ globalThis.$client = serverClient;
4511
+ `],
4512
+ ["api/orpc/fullstack/svelte/src/routes/rpc/[...rest]/+server.ts.hbs", `import { createContext } from "@{{projectName}}/api/context";
4513
+ import { appRouter } from "@{{projectName}}/api/routers/index";
4514
+ {{#if (eq webDeploy "cloudflare")}}
4515
+ import { env as localEnv } from "@{{projectName}}/env/server";
4516
+ {{/if}}
4517
+ import { OpenAPIHandler } from "@orpc/openapi/fetch";
4518
+ import { OpenAPIReferencePlugin } from "@orpc/openapi/plugins";
4519
+ import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
4520
+ import { onError } from "@orpc/server";
4521
+ import { RPCHandler } from "@orpc/server/fetch";
4522
+ import type { RequestHandler } from "@sveltejs/kit";
4523
+
4524
+ const rpcHandler = new RPCHandler(appRouter, {
4525
+ interceptors: [
4526
+ onError((error) => {
4527
+ console.error(error);
4528
+ }),
4529
+ ],
4530
+ });
4531
+
4532
+ const apiHandler = new OpenAPIHandler(appRouter, {
4533
+ plugins: [
4534
+ new OpenAPIReferencePlugin({
4535
+ schemaConverters: [new ZodToJsonSchemaConverter()],
4536
+ }),
4537
+ ],
4538
+ interceptors: [
4539
+ onError((error) => {
4540
+ console.error(error);
4541
+ }),
4542
+ ],
4543
+ });
4544
+
4545
+ const handle: RequestHandler = async ({ request{{#if (eq webDeploy "cloudflare")}}, platform{{/if}} }) => {
4546
+ {{#if (eq webDeploy "cloudflare")}}
4547
+ const env = platform?.env ?? localEnv;
4548
+
4549
+ {{/if}}
4550
+ const context = await createContext({
4551
+ headers: request.headers,
4552
+ {{#if (eq webDeploy "cloudflare")}}
4553
+ env,
4554
+ {{/if}}
4555
+ });
4556
+
4557
+ const rpcResult = await rpcHandler.handle(request, {
4558
+ prefix: "/rpc",
4559
+ context,
4560
+ });
4561
+ if (rpcResult.response) return rpcResult.response;
4562
+
4563
+ const apiResult = await apiHandler.handle(request, {
4564
+ prefix: "/rpc/api-reference",
4565
+ context,
4566
+ });
4567
+ if (apiResult.response) return apiResult.response;
4568
+
4569
+ return new Response("Not found", { status: 404 });
4570
+ };
4571
+
4572
+ export const HEAD = handle;
4573
+ export const GET = handle;
4574
+ export const POST = handle;
4575
+ export const PUT = handle;
4576
+ export const PATCH = handle;
4577
+ export const DELETE = handle;
4278
4578
  `],
4279
4579
  ["api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbs", `import { createContext } from "@{{projectName}}/api/context";
4280
4580
  import { appRouter } from "@{{projectName}}/api/routers/index";
@@ -4463,6 +4763,8 @@ function toClerkContextAuth(auth: { userId: string | null } | null): ClerkContex
4463
4763
  {{/if}}
4464
4764
 
4465
4765
  {{#if (and (eq auth "clerk") (or (eq backend 'self') (eq backend 'hono') (eq backend 'elysia')))}}
4766
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
4767
+ {{else}}
4466
4768
  import { createClerkClient } from "@clerk/backend";
4467
4769
  import { env } from "@{{projectName}}/env/server";
4468
4770
 
@@ -4478,6 +4780,7 @@ async function authenticateClerkRequest(request: Request): Promise<ClerkContextA
4478
4780
  return toClerkContextAuth(requestState.toAuth());
4479
4781
  }
4480
4782
  {{/if}}
4783
+ {{/if}}
4481
4784
 
4482
4785
  {{#if (and (eq backend 'self') (includes frontend "next"))}}
4483
4786
  import type { NextRequest } from "next/server";
@@ -4572,6 +4875,46 @@ export async function createContext({ headers }: CreateContextOptions) {
4572
4875
  {{/if}}
4573
4876
  }
4574
4877
 
4878
+ {{else if (and (eq backend 'self') (includes frontend "svelte"))}}
4879
+ {{#if (eq auth "better-auth")}}
4880
+ {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
4881
+ import { createAuth } from "@{{projectName}}/auth";
4882
+ {{else}}
4883
+ import { auth } from "@{{projectName}}/auth";
4884
+ {{/if}}
4885
+ {{/if}}
4886
+ {{#if (eq webDeploy "cloudflare")}}
4887
+ import type {} from "@{{projectName}}/env/server";
4888
+ {{/if}}
4889
+
4890
+ export type CreateContextOptions = {
4891
+ headers: Headers;
4892
+ {{#if (eq webDeploy "cloudflare")}}
4893
+ env: Env;
4894
+ {{/if}}
4895
+ };
4896
+
4897
+ export async function createContext({ headers{{#if (eq webDeploy "cloudflare")}}, env{{/if}} }: CreateContextOptions) {
4898
+ {{#if (eq auth "better-auth")}}
4899
+ const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth({{#if (eq webDeploy "cloudflare")}}env{{/if}}){{else}}auth{{/if}}.api.getSession({ headers });
4900
+ return {
4901
+ auth: null,
4902
+ session,
4903
+ {{#if (eq webDeploy "cloudflare")}}
4904
+ env,
4905
+ {{/if}}
4906
+ };
4907
+ {{else}}
4908
+ return {
4909
+ auth: null,
4910
+ session: null,
4911
+ {{#if (eq webDeploy "cloudflare")}}
4912
+ env,
4913
+ {{/if}}
4914
+ };
4915
+ {{/if}}
4916
+ }
4917
+
4575
4918
  {{else if (and (eq backend 'self') (includes frontend "astro"))}}
4576
4919
  {{#if (eq auth "better-auth")}}
4577
4920
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
@@ -5140,7 +5483,9 @@ export const client: AppRouterClient = createORPCClient(link);
5140
5483
 
5141
5484
  export const orpc = createTanstackQueryUtils(client);
5142
5485
  `],
5143
- ["api/orpc/web/svelte/src/lib/orpc.ts.hbs", `import { PUBLIC_SERVER_URL } from "$env/static/public";
5486
+ ["api/orpc/web/svelte/src/lib/orpc.ts.hbs", `{{#unless (eq backend "self")}}
5487
+ import { PUBLIC_SERVER_URL } from "$env/static/public";
5488
+ {{/unless}}
5144
5489
  import { createORPCClient } from "@orpc/client";
5145
5490
  import { RPCLink } from "@orpc/client/fetch";
5146
5491
  import { createTanstackQueryUtils } from "@orpc/tanstack-query";
@@ -5156,7 +5501,17 @@ export const queryClient = new QueryClient({
5156
5501
  });
5157
5502
 
5158
5503
  export const link = new RPCLink({
5504
+ {{#if (eq backend "self")}}
5505
+ url: () => {
5506
+ if (typeof window === "undefined") {
5507
+ throw new Error("This link is not allowed on the server side.");
5508
+ }
5509
+
5510
+ return \`\${window.location.origin}/rpc\`;
5511
+ },
5512
+ {{else}}
5159
5513
  url: \`\${PUBLIC_SERVER_URL}/rpc\`,
5514
+ {{/if}}
5160
5515
  {{#if (eq auth "better-auth")}}
5161
5516
  fetch(url, options) {
5162
5517
  return fetch(url, {
@@ -5167,7 +5522,11 @@ export const link = new RPCLink({
5167
5522
  {{/if}}
5168
5523
  });
5169
5524
 
5525
+ {{#if (eq backend "self")}}
5526
+ export const client: AppRouterClient = globalThis.$client ?? createORPCClient(link);
5527
+ {{else}}
5170
5528
  export const client: AppRouterClient = createORPCClient(link);
5529
+ {{/if}}
5171
5530
 
5172
5531
  export const orpc = createTanstackQueryUtils(client);
5173
5532
  `],
@@ -8896,6 +9255,45 @@ export default defineEventHandler((event) => {
8896
9255
  {{/if}}
8897
9256
  return auth.handler(toWebRequest(event));
8898
9257
  });
9258
+ `],
9259
+ ["auth/better-auth/fullstack/svelte/src/hooks.server.ts.hbs", `{{#if (eq api "orpc")}}
9260
+ import "./lib/orpc.server";
9261
+ {{/if}}
9262
+ import { building } from "$app/environment";
9263
+ {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
9264
+ import { createAuth } from "@{{projectName}}/auth";
9265
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
9266
+ import { env as localEnv } from "@{{projectName}}/env/server";
9267
+ {{/if}}
9268
+ {{else}}
9269
+ import { auth } from "@{{projectName}}/auth";
9270
+ {{/if}}
9271
+ import { svelteKitHandler } from "better-auth/svelte-kit";
9272
+ import type { Handle } from "@sveltejs/kit";
9273
+
9274
+ export const handle: Handle = async ({ event, resolve }) => {
9275
+ {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
9276
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
9277
+ if (building) {
9278
+ return resolve(event);
9279
+ }
9280
+
9281
+ const authEnv = event.platform?.env ?? localEnv;
9282
+ const authInstance = createAuth(authEnv);
9283
+ {{else}}
9284
+ const authInstance = createAuth();
9285
+ {{/if}}
9286
+ {{else}}
9287
+ const authInstance = auth;
9288
+ {{/if}}
9289
+
9290
+ return svelteKitHandler({
9291
+ event,
9292
+ resolve,
9293
+ auth: authInstance,
9294
+ building,
9295
+ });
9296
+ };
8899
9297
  `],
8900
9298
  ["auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs", `{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
8901
9299
  import { createAuth } from '@{{projectName}}/auth'
@@ -10831,15 +11229,23 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
10831
11229
  ["auth/better-auth/server/base/src/index.ts.hbs", `{{#if (eq orm "prisma")}}
10832
11230
  import { betterAuth } from "better-auth";
10833
11231
  import { prismaAdapter } from "better-auth/adapters/prisma";
11232
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11233
+ import type {} from "@{{projectName}}/env/server";
11234
+ {{else}}
10834
11235
  import { env } from "@{{projectName}}/env/server";
11236
+ {{/if}}
10835
11237
  {{#if (eq payments "polar")}}
10836
11238
  import { polar, checkout, portal } from "@polar-sh/better-auth";
11239
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11240
+ import { createPolarClient } from "./lib/payments";
11241
+ {{else}}
10837
11242
  import { polarClient } from "./lib/payments";
10838
11243
  {{/if}}
11244
+ {{/if}}
10839
11245
  import { createPrismaClient } from "@{{projectName}}/db";
10840
11246
 
10841
- export function createAuth() {
10842
- const prisma = createPrismaClient();
11247
+ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
11248
+ const prisma = createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env{{/if}});
10843
11249
 
10844
11250
  return betterAuth({
10845
11251
  database: prismaAdapter(prisma, {
@@ -10880,7 +11286,7 @@ export function createAuth() {
10880
11286
  plugins: [
10881
11287
  {{#if (eq payments "polar")}}
10882
11288
  polar({
10883
- client: polarClient,
11289
+ client: {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}createPolarClient(env){{else}}polarClient{{/if}},
10884
11290
  createCustomerOnSignUp: true,
10885
11291
  enableCustomerPortal: true,
10886
11292
  use: [
@@ -10911,17 +11317,25 @@ export const auth = createAuth();
10911
11317
  {{#if (or (eq runtime "bun") (eq runtime "node") (eq runtime "none"))}}
10912
11318
  import { betterAuth } from "better-auth";
10913
11319
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
11320
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11321
+ import type {} from "@{{projectName}}/env/server";
11322
+ {{else}}
10914
11323
  import { env } from "@{{projectName}}/env/server";
11324
+ {{/if}}
10915
11325
  {{#if (eq payments "polar")}}
10916
11326
  import { polar, checkout, portal } from "@polar-sh/better-auth";
11327
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11328
+ import { createPolarClient } from "./lib/payments";
11329
+ {{else}}
10917
11330
  import { polarClient } from "./lib/payments";
10918
11331
  {{/if}}
11332
+ {{/if}}
10919
11333
  import { createDb } from "@{{projectName}}/db";
10920
11334
  import * as schema from "@{{projectName}}/db/schema/auth";
10921
11335
 
10922
11336
 
10923
- export function createAuth() {
10924
- const db = createDb();
11337
+ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
11338
+ const db = createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env{{/if}});
10925
11339
 
10926
11340
  return betterAuth({
10927
11341
  database: drizzleAdapter(db, {
@@ -10961,7 +11375,7 @@ export function createAuth() {
10961
11375
  plugins: [
10962
11376
  {{#if (eq payments "polar")}}
10963
11377
  polar({
10964
- client: polarClient,
11378
+ client: {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}createPolarClient(env){{else}}polarClient{{/if}},
10965
11379
  createCustomerOnSignUp: true,
10966
11380
  enableCustomerPortal: true,
10967
11381
  use: [
@@ -11079,14 +11493,22 @@ export function createAuth() {
11079
11493
  {{#if (eq orm "mongoose")}}
11080
11494
  import { betterAuth } from "better-auth";
11081
11495
  import { mongodbAdapter } from "better-auth/adapters/mongodb";
11496
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11497
+ import type {} from "@{{projectName}}/env/server";
11498
+ {{else}}
11082
11499
  import { env } from "@{{projectName}}/env/server";
11500
+ {{/if}}
11083
11501
  {{#if (eq payments "polar")}}
11084
11502
  import { polar, checkout, portal } from "@polar-sh/better-auth";
11503
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11504
+ import { createPolarClient } from "./lib/payments";
11505
+ {{else}}
11085
11506
  import { polarClient } from "./lib/payments";
11086
11507
  {{/if}}
11508
+ {{/if}}
11087
11509
  import { client } from "@{{projectName}}/db";
11088
11510
 
11089
- export function createAuth() {
11511
+ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
11090
11512
  return betterAuth({
11091
11513
  database: mongodbAdapter(client),
11092
11514
  trustedOrigins: [
@@ -11120,7 +11542,7 @@ export function createAuth() {
11120
11542
  {{#if (eq payments "polar")}}
11121
11543
  plugins: [
11122
11544
  polar({
11123
- client: polarClient,
11545
+ client: {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}createPolarClient(env){{else}}polarClient{{/if}},
11124
11546
  createCustomerOnSignUp: true,
11125
11547
  enableCustomerPortal: true,
11126
11548
  use: [
@@ -11149,14 +11571,22 @@ export const auth = createAuth();
11149
11571
 
11150
11572
  {{#if (eq orm "none")}}
11151
11573
  import { betterAuth } from "better-auth";
11574
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11575
+ import type {} from "@{{projectName}}/env/server";
11576
+ {{else}}
11152
11577
  import { env } from "@{{projectName}}/env/server";
11578
+ {{/if}}
11153
11579
  {{#if (eq payments "polar")}}
11154
11580
  import { polar, checkout, portal } from "@polar-sh/better-auth";
11581
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
11582
+ import { createPolarClient } from "./lib/payments";
11583
+ {{else}}
11155
11584
  import { polarClient } from "./lib/payments";
11156
11585
  {{/if}}
11586
+ {{/if}}
11157
11587
 
11158
11588
 
11159
- export function createAuth() {
11589
+ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
11160
11590
  return betterAuth({
11161
11591
  database: "", // Invalid configuration
11162
11592
  trustedOrigins: [
@@ -11190,7 +11620,7 @@ export function createAuth() {
11190
11620
  {{#if (eq payments "polar")}}
11191
11621
  plugins: [
11192
11622
  polar({
11193
- client: polarClient,
11623
+ client: {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}createPolarClient(env){{else}}polarClient{{/if}},
11194
11624
  createCustomerOnSignUp: true,
11195
11625
  enableCustomerPortal: true,
11196
11626
  use: [
@@ -12593,10 +13023,14 @@ import { polarClient } from "@polar-sh/better-auth";
12593
13023
  {{/if}}
12594
13024
 
12595
13025
  export default defineNuxtPlugin(() => {
13026
+ {{#if (ne backend "self")}}
12596
13027
  const config = useRuntimeConfig();
13028
+ {{/if}}
12597
13029
 
12598
13030
  const authClient = createAuthClient({
13031
+ {{#if (ne backend "self")}}
12599
13032
  baseURL: config.public.serverUrl,
13033
+ {{/if}}
12600
13034
  {{#if (eq payments "polar")}}
12601
13035
  plugins: [polarClient()],
12602
13036
  {{/if}}
@@ -14991,6 +15425,8 @@ function RouteComponent() {
14991
15425
  onSubmit: validationSchema,
14992
15426
  },
14993
15427
  }));
15428
+
15429
+ type SubmitState = Pick<typeof form.state, 'canSubmit' | 'isSubmitting'>;
14994
15430
  <\/script>
14995
15431
 
14996
15432
  <div class="mx-auto mt-10 w-full max-w-md p-6">
@@ -15054,8 +15490,8 @@ function RouteComponent() {
15054
15490
  {/snippet}
15055
15491
  </form.Field>
15056
15492
 
15057
- <form.Subscribe selector={(state) => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>
15058
- {#snippet children(state)}
15493
+ <form.Subscribe selector={(state: typeof form.state): SubmitState => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>
15494
+ {#snippet children(state: SubmitState)}
15059
15495
  <button type="submit" class="w-full" disabled={!state.canSubmit || state.isSubmitting}>
15060
15496
  {state.isSubmitting ? 'Submitting...' : 'Sign In'}
15061
15497
  </button>
@@ -15109,6 +15545,8 @@ function RouteComponent() {
15109
15545
  onSubmit: validationSchema,
15110
15546
  },
15111
15547
  }));
15548
+
15549
+ type SubmitState = Pick<typeof form.state, 'canSubmit' | 'isSubmitting'>;
15112
15550
  <\/script>
15113
15551
 
15114
15552
  <div class="mx-auto mt-10 w-full max-w-md p-6">
@@ -15197,8 +15635,8 @@ function RouteComponent() {
15197
15635
  {/snippet}
15198
15636
  </form.Field>
15199
15637
 
15200
- <form.Subscribe selector={(state) => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>
15201
- {#snippet children(state)}
15638
+ <form.Subscribe selector={(state: typeof form.state): SubmitState => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>
15639
+ {#snippet children(state: SubmitState)}
15202
15640
  <button type="submit" class="w-full" disabled={!state.canSubmit || state.isSubmitting}>
15203
15641
  {state.isSubmitting ? 'Submitting...' : 'Sign Up'}
15204
15642
  </button>
@@ -15266,14 +15704,18 @@ function RouteComponent() {
15266
15704
  {/if}
15267
15705
  </div>
15268
15706
  `],
15269
- ["auth/better-auth/web/svelte/src/lib/auth-client.ts.hbs", `import { PUBLIC_SERVER_URL } from "$env/static/public";
15707
+ ["auth/better-auth/web/svelte/src/lib/auth-client.ts.hbs", `{{#unless (eq backend "self")}}
15708
+ import { PUBLIC_SERVER_URL } from "$env/static/public";
15709
+ {{/unless}}
15270
15710
  import { createAuthClient } from "better-auth/svelte";
15271
15711
  {{#if (eq payments "polar")}}
15272
15712
  import { polarClient } from "@polar-sh/better-auth";
15273
15713
  {{/if}}
15274
15714
 
15275
15715
  export const authClient = createAuthClient({
15716
+ {{#unless (eq backend "self")}}
15276
15717
  baseURL: PUBLIC_SERVER_URL,
15718
+ {{/unless}}
15277
15719
  {{#if (eq payments "polar")}}
15278
15720
  plugins: [polarClient()]
15279
15721
  {{/if}}
@@ -17128,7 +17570,7 @@ import { Elysia } from "elysia";
17128
17570
  import { cors } from "@elysiajs/cors";
17129
17571
  {{#if (includes examples "ai")}}
17130
17572
  import { google } from "@ai-sdk/google";
17131
- import { convertToModelMessages, streamText, wrapLanguageModel } from "ai";
17573
+ import { convertToModelMessages, streamText, type UIMessage, wrapLanguageModel } from "ai";
17132
17574
  import { devToolsMiddleware } from "@ai-sdk/devtools";
17133
17575
  {{/if}}
17134
17576
  {{#if (eq api "trpc")}}
@@ -17172,9 +17614,9 @@ const apiHandler = new OpenAPIHandler(appRouter, {
17172
17614
  {{/if}}
17173
17615
 
17174
17616
  {{#if (eq runtime "node")}}
17175
- const app = new Elysia({ adapter: node() })
17617
+ new Elysia({ adapter: node() })
17176
17618
  {{else}}
17177
- const app = new Elysia()
17619
+ new Elysia()
17178
17620
  {{/if}}
17179
17621
  .use(
17180
17622
  cors({
@@ -17238,7 +17680,7 @@ const app = new Elysia()
17238
17680
  {{/if}}
17239
17681
  {{#if (includes examples "ai")}}
17240
17682
  .post("/ai", async (context) => {
17241
- const body = await context.request.json();
17683
+ const body = (await context.request.json()) as { messages?: UIMessage[] };
17242
17684
  const uiMessages = body.messages || [];
17243
17685
  const model = wrapLanguageModel({
17244
17686
  model: google("gemini-2.5-flash"),
@@ -17246,7 +17688,7 @@ const app = new Elysia()
17246
17688
  });
17247
17689
  const result = streamText({
17248
17690
  model,
17249
- messages: await convertToModelMessages(uiMessages)
17691
+ messages: await convertToModelMessages(uiMessages),
17250
17692
  });
17251
17693
 
17252
17694
  return result.toUIMessageStreamResponse();
@@ -17994,13 +18436,17 @@ export default defineConfig({
17994
18436
  });
17995
18437
  `],
17996
18438
  ["db/drizzle/mysql/src/index.ts.hbs", `{{#if (or (eq runtime "bun") (eq runtime "node") (eq runtime "none"))}}
18439
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
18440
+ import type {} from "@{{projectName}}/env/server";
18441
+ {{else}}
17997
18442
  import { env } from "@{{projectName}}/env/server";
18443
+ {{/if}}
17998
18444
  import * as schema from "./schema";
17999
18445
 
18000
18446
  {{#if (eq dbSetup "planetscale")}}
18001
18447
  import { drizzle } from "drizzle-orm/planetscale-serverless";
18002
18448
 
18003
- export function createDb() {
18449
+ export function createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18004
18450
  return drizzle({
18005
18451
  connection: {
18006
18452
  host: env.DATABASE_HOST,
@@ -18013,7 +18459,7 @@ export function createDb() {
18013
18459
  {{else}}
18014
18460
  import { drizzle } from "drizzle-orm/mysql2";
18015
18461
 
18016
- export function createDb() {
18462
+ export function createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18017
18463
  return drizzle({
18018
18464
  connection: {
18019
18465
  uri: env.DATABASE_URL,
@@ -18081,14 +18527,18 @@ export default defineConfig({
18081
18527
  });
18082
18528
  `],
18083
18529
  ["db/drizzle/postgres/src/index.ts.hbs", `{{#if (or (eq runtime "bun") (eq runtime "node") (eq runtime "none"))}}
18530
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
18531
+ import type {} from "@{{projectName}}/env/server";
18532
+ {{else}}
18084
18533
  import { env } from "@{{projectName}}/env/server";
18534
+ {{/if}}
18085
18535
  import * as schema from "./schema";
18086
18536
 
18087
18537
  {{#if (eq dbSetup "neon")}}
18088
18538
  import { neon } from '@neondatabase/serverless';
18089
18539
  import { drizzle } from 'drizzle-orm/neon-http';
18090
18540
 
18091
- export function createDb() {
18541
+ export function createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18092
18542
  const sql = neon(env.DATABASE_URL);
18093
18543
  return drizzle(sql, { schema });
18094
18544
  }
@@ -18098,7 +18548,7 @@ import { drizzle } from "drizzle-orm/node-postgres";
18098
18548
  import { Pool } from "pg";
18099
18549
  {{/if}}
18100
18550
 
18101
- export function createDb() {
18551
+ export function createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18102
18552
  {{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
18103
18553
  const pool = new Pool({
18104
18554
  connectionString: env.DATABASE_URL,
@@ -18177,18 +18627,26 @@ export default defineConfig({
18177
18627
  ["db/drizzle/sqlite/src/index.ts.hbs", `{{#if (eq dbSetup "d1")}}
18178
18628
  import * as schema from "./schema";
18179
18629
  import { drizzle } from "drizzle-orm/d1";
18630
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
18631
+ import type {} from "@{{projectName}}/env/server";
18632
+ {{else}}
18180
18633
  import { env } from "@{{projectName}}/env/server";
18634
+ {{/if}}
18181
18635
 
18182
- export function createDb() {
18636
+ export function createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18183
18637
  return drizzle(env.DB, { schema });
18184
18638
  }
18185
18639
  {{else if (or (eq runtime "bun") (eq runtime "node") (eq runtime "none"))}}
18640
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
18641
+ import type {} from "@{{projectName}}/env/server";
18642
+ {{else}}
18186
18643
  import { env } from "@{{projectName}}/env/server";
18644
+ {{/if}}
18187
18645
  import * as schema from "./schema";
18188
18646
  import { drizzle } from "drizzle-orm/libsql";
18189
18647
  import { createClient } from "@libsql/client";
18190
18648
 
18191
- export function createDb() {
18649
+ export function createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18192
18650
  const client = createClient({
18193
18651
  url: env.DATABASE_URL,
18194
18652
  {{#if (eq dbSetup "turso")}}
@@ -18349,19 +18807,23 @@ export function createPrismaClient() {
18349
18807
  {{/if}}
18350
18808
  {{else}}
18351
18809
  import { PrismaClient } from "../prisma/generated/client";
18810
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
18811
+ import type {} from "@{{projectName}}/env/server";
18812
+ {{else}}
18352
18813
  import { env } from "@{{projectName}}/env/server";
18814
+ {{/if}}
18353
18815
 
18354
18816
  {{#if (eq dbSetup "planetscale")}}
18355
18817
  import { PrismaPlanetScale } from "@prisma/adapter-planetscale";
18356
18818
 
18357
- export function createPrismaClient() {
18819
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18358
18820
  const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });
18359
18821
  return new PrismaClient({ adapter });
18360
18822
  }
18361
18823
  {{else}}
18362
18824
  import { PrismaMariaDb } from "@prisma/adapter-mariadb";
18363
18825
 
18364
- export function createPrismaClient() {
18826
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18365
18827
  const databaseUrl: string = env.DATABASE_URL;
18366
18828
  const url: URL = new URL(databaseUrl);
18367
18829
  const connectionConfig = {
@@ -18470,11 +18932,15 @@ export function createPrismaClient() {
18470
18932
  {{/if}}
18471
18933
  {{else}}
18472
18934
  import { PrismaClient } from "../prisma/generated/client";
18935
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
18936
+ import type {} from "@{{projectName}}/env/server";
18937
+ {{else}}
18473
18938
  import { env } from "@{{projectName}}/env/server";
18939
+ {{/if}}
18474
18940
  {{#if (eq dbSetup "neon")}}
18475
18941
  import { PrismaNeon } from "@prisma/adapter-neon";
18476
18942
 
18477
- export function createPrismaClient() {
18943
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18478
18944
  const adapter = new PrismaNeon({
18479
18945
  connectionString: env.DATABASE_URL,
18480
18946
  });
@@ -18485,7 +18951,7 @@ export function createPrismaClient() {
18485
18951
  {{else if (eq dbSetup "prisma-postgres")}}
18486
18952
  import { PrismaPg } from "@prisma/adapter-pg";
18487
18953
 
18488
- export function createPrismaClient() {
18954
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18489
18955
  const adapter = new PrismaPg({
18490
18956
  connectionString: env.DATABASE_URL,
18491
18957
  {{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
@@ -18499,7 +18965,7 @@ export function createPrismaClient() {
18499
18965
  {{else}}
18500
18966
  import { PrismaPg } from "@prisma/adapter-pg";
18501
18967
 
18502
- export function createPrismaClient() {
18968
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18503
18969
  const adapter = new PrismaPg({
18504
18970
  connectionString: env.DATABASE_URL,
18505
18971
  {{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
@@ -18564,9 +19030,13 @@ datasource db {
18564
19030
 
18565
19031
  {{#if (eq dbSetup "d1")}}
18566
19032
  import { PrismaD1 } from "@prisma/adapter-d1";
19033
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
19034
+ import type {} from "@{{projectName}}/env/server";
19035
+ {{else}}
18567
19036
  import { env } from "@{{projectName}}/env/server";
19037
+ {{/if}}
18568
19038
 
18569
- export function createPrismaClient() {
19039
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18570
19040
  const adapter = new PrismaD1(env.DB);
18571
19041
  return new PrismaClient({ adapter });
18572
19042
  }
@@ -18577,9 +19047,13 @@ export default prisma;
18577
19047
  {{/if}}
18578
19048
  {{else}}
18579
19049
  import { PrismaLibSql } from "@prisma/adapter-libsql";
19050
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
19051
+ import type {} from "@{{projectName}}/env/server";
19052
+ {{else}}
18580
19053
  import { env } from "@{{projectName}}/env/server";
19054
+ {{/if}}
18581
19055
 
18582
- export function createPrismaClient() {
19056
+ export function createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
18583
19057
  const adapter = new PrismaLibSql({
18584
19058
  url: env.DATABASE_URL,
18585
19059
  {{#if (eq dbSetup "turso")}}
@@ -18715,6 +19189,26 @@ export default defineEventHandler(async (event) => {
18715
19189
 
18716
19190
  return result.toUIMessageStreamResponse();
18717
19191
  });
19192
+ `],
19193
+ ["examples/ai/fullstack/svelte/src/routes/api/ai/+server.ts.hbs", `import { devToolsMiddleware } from "@ai-sdk/devtools";
19194
+ import { google } from "@ai-sdk/google";
19195
+ import { convertToModelMessages, streamText, type UIMessage, wrapLanguageModel } from "ai";
19196
+ import type { RequestHandler } from "@sveltejs/kit";
19197
+
19198
+ export const POST: RequestHandler = async ({ request }) => {
19199
+ const { messages }: { messages: UIMessage[] } = await request.json();
19200
+
19201
+ const model = wrapLanguageModel({
19202
+ model: google("gemini-2.5-flash"),
19203
+ middleware: devToolsMiddleware(),
19204
+ });
19205
+ const result = streamText({
19206
+ model,
19207
+ messages: await convertToModelMessages(messages),
19208
+ });
19209
+
19210
+ return result.toUIMessageStreamResponse();
19211
+ };
18718
19212
  `],
18719
19213
  ["examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs", `import { createFileRoute } from "@tanstack/react-router";
18720
19214
  import { google } from "@ai-sdk/google";
@@ -21485,14 +21979,20 @@ function RouteComponent() {
21485
21979
  {{/if}}
21486
21980
  `],
21487
21981
  ["examples/ai/web/svelte/src/routes/ai/+page.svelte.hbs", `<script lang="ts">
21982
+ {{#unless (eq backend "self")}}
21488
21983
  import { PUBLIC_SERVER_URL } from "$env/static/public";
21984
+ {{/unless}}
21489
21985
  import { Chat } from "@ai-sdk/svelte";
21490
21986
  import { DefaultChatTransport } from "ai";
21491
21987
 
21492
21988
  let input = $state("");
21493
21989
  const chat = new Chat({
21494
21990
  transport: new DefaultChatTransport({
21991
+ {{#if (eq backend "self")}}
21992
+ api: "/api/ai",
21993
+ {{else}}
21495
21994
  api: \`\${PUBLIC_SERVER_URL}/ai\`,
21995
+ {{/if}}
21496
21996
  }),
21497
21997
  });
21498
21998
 
@@ -22790,18 +23290,18 @@ import { todo } from "@{{projectName}}/db/schema/todo";
22790
23290
  import { publicProcedure } from "../index";
22791
23291
 
22792
23292
  export const todoRouter = {
22793
- getAll: publicProcedure.handler(async () => {
23293
+ getAll: publicProcedure.handler(async ({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}{ context }{{/if}}) => {
22794
23294
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
22795
- const db = createDb();
23295
+ const db = createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
22796
23296
  {{/if}}
22797
23297
  return await db.select().from(todo);
22798
23298
  }),
22799
23299
 
22800
23300
  create: publicProcedure
22801
23301
  .input(z.object({ text: z.string().min(1) }))
22802
- .handler(async ({ input }) => {
23302
+ .handler(async ({ input{{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}, context{{/if}} }) => {
22803
23303
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
22804
- const db = createDb();
23304
+ const db = createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
22805
23305
  {{/if}}
22806
23306
  return await db
22807
23307
  .insert(todo)
@@ -22812,9 +23312,9 @@ export const todoRouter = {
22812
23312
 
22813
23313
  toggle: publicProcedure
22814
23314
  .input(z.object({ id: z.number(), completed: z.boolean() }))
22815
- .handler(async ({ input }) => {
23315
+ .handler(async ({ input{{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}, context{{/if}} }) => {
22816
23316
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
22817
- const db = createDb();
23317
+ const db = createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
22818
23318
  {{/if}}
22819
23319
  return await db
22820
23320
  .update(todo)
@@ -22824,9 +23324,9 @@ export const todoRouter = {
22824
23324
 
22825
23325
  delete: publicProcedure
22826
23326
  .input(z.object({ id: z.number() }))
22827
- .handler(async ({ input }) => {
23327
+ .handler(async ({ input{{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}, context{{/if}} }) => {
22828
23328
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
22829
- const db = createDb();
23329
+ const db = createDb({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
22830
23330
  {{/if}}
22831
23331
  return await db.delete(todo).where(eq(todo.id, input.id));
22832
23332
  }),
@@ -23012,9 +23512,9 @@ import prisma from "@{{projectName}}/db";
23012
23512
  import { publicProcedure } from "../index";
23013
23513
 
23014
23514
  export const todoRouter = {
23015
- getAll: publicProcedure.handler(async () => {
23515
+ getAll: publicProcedure.handler(async ({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}{ context }{{/if}}) => {
23016
23516
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
23017
- const prisma = createPrismaClient();
23517
+ const prisma = createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
23018
23518
  {{/if}}
23019
23519
  return await prisma.todo.findMany({
23020
23520
  orderBy: {
@@ -23025,9 +23525,9 @@ export const todoRouter = {
23025
23525
 
23026
23526
  create: publicProcedure
23027
23527
  .input(z.object({ text: z.string().min(1) }))
23028
- .handler(async ({ input }) => {
23528
+ .handler(async ({ input{{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}, context{{/if}} }) => {
23029
23529
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
23030
- const prisma = createPrismaClient();
23530
+ const prisma = createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
23031
23531
  {{/if}}
23032
23532
  return await prisma.todo.create({
23033
23533
  data: {
@@ -23042,9 +23542,9 @@ export const todoRouter = {
23042
23542
  {{else}}
23043
23543
  .input(z.object({ id: z.number(), completed: z.boolean() }))
23044
23544
  {{/if}}
23045
- .handler(async ({ input }) => {
23545
+ .handler(async ({ input{{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}, context{{/if}} }) => {
23046
23546
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
23047
- const prisma = createPrismaClient();
23547
+ const prisma = createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
23048
23548
  {{/if}}
23049
23549
  return await prisma.todo.update({
23050
23550
  where: { id: input.id },
@@ -23058,9 +23558,9 @@ export const todoRouter = {
23058
23558
  {{else}}
23059
23559
  .input(z.object({ id: z.number() }))
23060
23560
  {{/if}}
23061
- .handler(async ({ input }) => {
23561
+ .handler(async ({ input{{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}, context{{/if}} }) => {
23062
23562
  {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
23063
- const prisma = createPrismaClient();
23563
+ const prisma = createPrismaClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}context.env{{/if}});
23064
23564
  {{/if}}
23065
23565
  return await prisma.todo.delete({
23066
23566
  where: { id: input.id },
@@ -26341,40 +26841,41 @@ module.exports = config;
26341
26841
  "web": "expo start --web"
26342
26842
  },
26343
26843
  "dependencies": {
26344
- "@expo/vector-icons": "^15.0.2",
26345
- "@react-navigation/bottom-tabs": "^7.2.0",
26346
- "@react-navigation/drawer": "^7.1.1",
26347
- "@react-navigation/native": "^7.0.14",
26348
- "@tanstack/react-query": "^5.85.5",
26844
+ "@expo/vector-icons": "^15.1.1",
26845
+ "@react-navigation/bottom-tabs": "^7.15.9",
26846
+ "@react-navigation/drawer": "^7.9.4",
26847
+ "@react-navigation/native": "^7.2.2",
26848
+ "@tanstack/react-query": "^5.99.2",
26349
26849
  {{#if (includes examples "ai")}}
26350
26850
  "@stardazed/streams-text-encoding": "^1.0.2",
26351
26851
  "@ungap/structured-clone": "^1.3.0",
26352
26852
  {{/if}}
26353
- "expo": "^55.0.0",
26354
- "expo-constants": "~55.0.7",
26355
- "expo-crypto": "~55.0.8",
26356
- "expo-font": "~55.0.4",
26357
- "expo-linking": "~55.0.7",
26358
- "expo-network": "~55.0.8",
26359
- "expo-router": "~55.0.2",
26360
- "expo-secure-store": "~55.0.8",
26361
- "expo-splash-screen": "~55.0.9",
26362
- "expo-status-bar": "~55.0.4",
26363
- "expo-system-ui": "~55.0.9",
26364
- "expo-web-browser": "~55.0.9",
26853
+ "expo": "^55.0.17",
26854
+ "expo-constants": "~55.0.15",
26855
+ "expo-crypto": "~55.0.14",
26856
+ "expo-font": "~55.0.6",
26857
+ "expo-linking": "~55.0.14",
26858
+ "expo-network": "~55.0.13",
26859
+ "expo-router": "~55.0.13",
26860
+ "expo-secure-store": "~55.0.13",
26861
+ "expo-splash-screen": "~55.0.19",
26862
+ "expo-status-bar": "~55.0.5",
26863
+ "expo-system-ui": "~55.0.16",
26864
+ "expo-web-browser": "~55.0.14",
26365
26865
  "react": "19.2.0",
26366
26866
  "react-dom": "19.2.0",
26367
- "react-native": "0.83.2",
26867
+ "react-native": "0.83.6",
26368
26868
  "react-native-gesture-handler": "~2.30.0",
26369
26869
  "react-native-reanimated": "4.2.1",
26370
- "react-native-safe-area-context": "~5.6.0",
26870
+ "react-native-safe-area-context": "~5.6.2",
26371
26871
  "react-native-screens": "~4.23.0",
26372
- "react-native-web": "^0.21.0",
26373
- "react-native-worklets": "0.7.2"
26872
+ "react-native-web": "~0.21.0",
26873
+ "react-native-worklets": "0.7.4"
26374
26874
  },
26375
26875
  "devDependencies": {
26376
- "@babel/core": "^7.26.10",
26377
- "@types/react": "~19.2.10"
26876
+ "@babel/core": "^7.28.0",
26877
+ "@types/react": "~19.2.10",
26878
+ "typescript": "~5.9.2"
26378
26879
  },
26379
26880
  "private": true
26380
26881
  }
@@ -27544,45 +28045,46 @@ module.exports = config;
27544
28045
  "web": "expo start --web"
27545
28046
  },
27546
28047
  "dependencies": {
27547
- "@expo/vector-icons": "^15.0.3",
27548
- "@react-navigation/bottom-tabs": "^7.4.0",
27549
- "@react-navigation/drawer": "^7.5.0",
27550
- "@react-navigation/native": "^7.1.8",
28048
+ "@expo/vector-icons": "^15.1.1",
28049
+ "@react-navigation/bottom-tabs": "^7.15.9",
28050
+ "@react-navigation/drawer": "^7.9.4",
28051
+ "@react-navigation/native": "^7.2.2",
27551
28052
  {{#if (includes examples "ai")}}
27552
28053
  "@stardazed/streams-text-encoding": "^1.0.2",
27553
28054
  "@ungap/structured-clone": "^1.3.0",
27554
28055
  {{/if}}
27555
- "babel-preset-expo": "~55.0.8",
27556
- "expo": "^55.0.0",
27557
- "expo-constants": "~55.0.7",
27558
- "expo-crypto": "~55.0.8",
27559
- "expo-dev-client": "~55.0.9",
27560
- "expo-font": "~55.0.4",
27561
- "expo-linking": "~55.0.7",
27562
- "expo-network": "~55.0.8",
27563
- "expo-router": "~55.0.2",
27564
- "expo-secure-store": "~55.0.8",
27565
- "expo-splash-screen": "~55.0.9",
27566
- "expo-status-bar": "~55.0.4",
27567
- "expo-system-ui": "~55.0.9",
27568
- "expo-web-browser": "~55.0.9",
28056
+ "babel-preset-expo": "~55.0.18",
28057
+ "expo": "^55.0.17",
28058
+ "expo-constants": "~55.0.15",
28059
+ "expo-crypto": "~55.0.14",
28060
+ "expo-dev-client": "~55.0.28",
28061
+ "expo-font": "~55.0.6",
28062
+ "expo-linking": "~55.0.14",
28063
+ "expo-network": "~55.0.13",
28064
+ "expo-router": "~55.0.13",
28065
+ "expo-secure-store": "~55.0.13",
28066
+ "expo-splash-screen": "~55.0.19",
28067
+ "expo-status-bar": "~55.0.5",
28068
+ "expo-system-ui": "~55.0.16",
28069
+ "expo-web-browser": "~55.0.14",
27569
28070
  "react": "19.2.0",
27570
28071
  "react-dom": "19.2.0",
27571
- "react-native": "0.83.2",
27572
- "react-native-edge-to-edge": "^1.7.0",
28072
+ "react-native": "0.83.6",
28073
+ "react-native-edge-to-edge": "^1.8.1",
27573
28074
  "react-native-gesture-handler": "~2.30.0",
27574
- "react-native-nitro-modules": "^0.33.2",
28075
+ "react-native-nitro-modules": "^0.35.4",
27575
28076
  "react-native-reanimated": "4.2.1",
27576
- "react-native-safe-area-context": "~5.6.0",
28077
+ "react-native-safe-area-context": "~5.6.2",
27577
28078
  "react-native-screens": "~4.23.0",
27578
- "react-native-unistyles": "^3.0.22",
27579
- "react-native-web": "^0.21.2",
27580
- "react-native-worklets": "0.7.2"
28079
+ "react-native-unistyles": "^3.2.3",
28080
+ "react-native-web": "~0.21.0",
28081
+ "react-native-worklets": "0.7.4"
27581
28082
  },
27582
28083
  "devDependencies": {
27583
28084
  "ajv": "^8.17.1",
27584
28085
  "@babel/core": "^7.28.0",
27585
- "@types/react": "~19.2.10"
28086
+ "@types/react": "~19.2.10",
28087
+ "typescript": "~5.9.2"
27586
28088
  }
27587
28089
  }
27588
28090
  `],
@@ -28604,45 +29106,46 @@ module.exports = uniwindConfig;
28604
29106
  "web": "expo start --web"
28605
29107
  },
28606
29108
  "dependencies": {
28607
- "@expo/metro-runtime": "~55.0.6",
28608
- "@expo/vector-icons": "^15.0.3",
28609
- "@gorhom/bottom-sheet": "^5",
28610
- "@react-navigation/drawer": "^7.3.9",
28611
- "@react-navigation/elements": "^2.8.1",
29109
+ "@expo/metro-runtime": "~55.0.10",
29110
+ "@expo/vector-icons": "^15.1.1",
29111
+ "@gorhom/bottom-sheet": "^5.2.10",
29112
+ "@react-navigation/drawer": "^7.9.4",
29113
+ "@react-navigation/elements": "^2.9.14",
28612
29114
  {{#if (includes examples "ai")}}
28613
29115
  "@stardazed/streams-text-encoding": "^1.0.2",
28614
29116
  "@ungap/structured-clone": "^1.3.0",
28615
29117
  {{/if}}
28616
- "expo": "^55.0.0",
28617
- "expo-constants": "~55.0.7",
28618
- "expo-font": "~55.0.4",
28619
- "expo-haptics": "~55.0.8",
28620
- "expo-linking": "~55.0.7",
28621
- "expo-network": "~55.0.8",
28622
- "expo-router": "~55.0.2",
28623
- "expo-secure-store": "~55.0.8",
28624
- "expo-status-bar": "~55.0.4",
28625
- "expo-web-browser": "~55.0.9",
28626
- "heroui-native": "^1.0.0",
29118
+ "expo": "^55.0.17",
29119
+ "expo-constants": "~55.0.15",
29120
+ "expo-font": "~55.0.6",
29121
+ "expo-haptics": "~55.0.14",
29122
+ "expo-linking": "~55.0.14",
29123
+ "expo-network": "~55.0.13",
29124
+ "expo-router": "~55.0.13",
29125
+ "expo-secure-store": "~55.0.13",
29126
+ "expo-status-bar": "~55.0.5",
29127
+ "expo-web-browser": "~55.0.14",
29128
+ "heroui-native": "^1.0.2",
28627
29129
  "react": "19.2.0",
28628
29130
  "react-dom": "19.2.0",
28629
- "react-native": "0.83.2",
29131
+ "react-native": "0.83.6",
28630
29132
  "react-native-gesture-handler": "~2.30.0",
28631
29133
  "react-native-keyboard-controller": "1.20.7",
28632
29134
  "react-native-reanimated": "4.2.1",
28633
- "react-native-safe-area-context": "~5.6.0",
29135
+ "react-native-safe-area-context": "~5.6.2",
28634
29136
  "react-native-screens": "~4.23.0",
28635
29137
  "react-native-svg": "15.15.3",
28636
- "react-native-web": "^0.21.0",
28637
- "react-native-worklets": "0.7.2",
28638
- "tailwind-merge": "^3.4.0",
29138
+ "react-native-web": "~0.21.0",
29139
+ "react-native-worklets": "0.7.4",
29140
+ "tailwind-merge": "^3.5.0",
28639
29141
  "tailwind-variants": "^3.2.2",
28640
- "tailwindcss": "^4.2.2",
28641
- "uniwind": "^1.6.0"
29142
+ "tailwindcss": "^4.2.4",
29143
+ "uniwind": "^1.6.3"
28642
29144
  },
28643
29145
  "devDependencies": {
28644
29146
  "@types/node": "^24.10.0",
28645
- "@types/react": "~19.2.10"
29147
+ "@types/react": "~19.2.10",
29148
+ "typescript": "~5.9.2"
28646
29149
  }
28647
29150
  }
28648
29151
  `],
@@ -28656,7 +29159,9 @@ module.exports = uniwindConfig;
28656
29159
  },
28657
29160
  "include": [
28658
29161
  "**/*.ts",
28659
- "**/*.tsx"
29162
+ "**/*.tsx",
29163
+ ".expo/types/**/*.ts",
29164
+ "expo-env.d.ts"
28660
29165
  ]
28661
29166
  }`],
28662
29167
  ["frontend/native/uniwind/uniwind-env.d.ts", `/// <reference types="uniwind/types" />
@@ -28903,7 +29408,7 @@ export default defineNuxtConfig({
28903
29408
  {{else if (and (ne backend "self") (ne backend "none"))}}
28904
29409
  runtimeConfig: {
28905
29410
  public: {
28906
- serverUrl: process.env.NUXT_PUBLIC_SERVER_URL,
29411
+ serverUrl: process.env.NUXT_PUBLIC_SERVER_URL ?? "",
28907
29412
  }
28908
29413
  },
28909
29414
  {{/if}}
@@ -28922,7 +29427,7 @@ export default defineNuxtConfig({
28922
29427
  },
28923
29428
  "dependencies": {
28924
29429
  "@nuxt/ui": "^4.5.1",
28925
- "nuxt": "^4.4.2"
29430
+ "nuxt": "^4.4.4"
28926
29431
  },
28927
29432
  "devDependencies": {
28928
29433
  "tailwindcss": "^4.2.1",
@@ -28975,7 +29480,7 @@ const nextConfig: NextConfig = {
28975
29480
  {{#if (includes examples "ai")}}
28976
29481
  transpilePackages: ["shiki"],
28977
29482
  {{/if}}
28978
- {{#if (eq dbSetup "turso")}}
29483
+ {{#if (and (eq backend "self") (eq dbSetup "turso"))}}
28979
29484
  serverExternalPackages: ["libsql", "@libsql/client"],
28980
29485
  {{/if}}
28981
29486
  };
@@ -31498,13 +32003,13 @@ vite.config.ts.timestamp-*
31498
32003
  },
31499
32004
  "devDependencies": {
31500
32005
  "@sveltejs/adapter-auto": "^7.0.1",
31501
- "@sveltejs/kit": "^2.57.1",
32006
+ "@sveltejs/kit": "^2.58.0",
31502
32007
  "@sveltejs/vite-plugin-svelte": "^7.0.0",
31503
- "@tailwindcss/vite": "^4.2.2",
31504
- "svelte": "^5.55.4",
32008
+ "@tailwindcss/vite": "^4.2.4",
32009
+ "svelte": "^5.55.5",
31505
32010
  "svelte-check": "^4.4.6",
31506
- "tailwindcss": "^4.2.2",
31507
- "vite": "^8.0.8"
32011
+ "tailwindcss": "^4.2.4",
32012
+ "vite": "^8.0.10"
31508
32013
  },
31509
32014
  "dependencies": {}
31510
32015
  }
@@ -31515,16 +32020,36 @@ body {
31515
32020
  @apply bg-neutral-950 text-neutral-100;
31516
32021
  }
31517
32022
  `],
31518
- ["frontend/svelte/src/app.d.ts", `// See https://svelte.dev/docs/kit/types#app.d.ts
32023
+ ["frontend/svelte/src/app.d.ts.hbs", `{{#if (eq webDeploy "cloudflare")}}
32024
+ /// <reference path="../../../packages/env/env.d.ts" />
32025
+ {{/if}}
32026
+ {{#if (and (eq backend "self") (eq api "orpc"))}}
32027
+ import type { AppRouterClient } from "@{{projectName}}/api/routers/index";
32028
+
32029
+ {{/if}}
32030
+ // See https://svelte.dev/docs/kit/types#app.d.ts
31519
32031
  // for information about these interfaces
31520
32032
  declare global {
31521
- namespace App {
31522
- // interface Error {}
31523
- // interface Locals {}
31524
- // interface PageData {}
31525
- // interface PageState {}
31526
- // interface Platform {}
31527
- }
32033
+ {{#if (and (eq backend "self") (eq api "orpc"))}}
32034
+ var $client: AppRouterClient | undefined;
32035
+
32036
+ {{/if}}
32037
+ namespace App {
32038
+ // interface Error {}
32039
+ // interface Locals {}
32040
+ // interface PageData {}
32041
+ // interface PageState {}
32042
+ {{#if (eq webDeploy "cloudflare")}}
32043
+ interface Platform {
32044
+ env: Env;
32045
+ ctx: ExecutionContext;
32046
+ caches: CacheStorage;
32047
+ cf: IncomingRequestCfProperties;
32048
+ }
32049
+ {{else}}
32050
+ // interface Platform {}
32051
+ {{/if}}
32052
+ }
31528
32053
  }
31529
32054
 
31530
32055
  export {};
@@ -31547,32 +32072,22 @@ export {};
31547
32072
  {{#if (eq auth "better-auth")}}
31548
32073
  import UserMenu from './UserMenu.svelte';
31549
32074
  {{/if}}
31550
- const links = [
31551
- { to: "/", label: "Home" },
31552
- {{#if (eq auth "better-auth")}}
31553
- { to: "/dashboard", label: "Dashboard" },
31554
- {{/if}}
31555
- {{#if (includes examples "todo")}}
31556
- { to: "/todos", label: "Todos" },
31557
- {{/if}}
31558
- {{#if (includes examples "ai")}}
31559
- { to: "/ai", label: "AI Chat" },
31560
- {{/if}}
31561
- ];
31562
32075
 
31563
32076
  <\/script>
31564
32077
 
31565
32078
  <div>
31566
32079
  <div class="flex flex-row items-center justify-between px-4 py-2 md:px-6">
31567
32080
  <nav class="flex gap-4 text-lg">
31568
- {#each links as link (link.to)}
31569
- <a
31570
- href={link.to}
31571
- class="hover:text-neutral-400 transition-colors"
31572
- >
31573
- {link.label}
31574
- </a>
31575
- {/each}
32081
+ <a href="/" class="hover:text-neutral-400 transition-colors">Home</a>
32082
+ {{#if (eq auth "better-auth")}}
32083
+ <a href="/dashboard" class="hover:text-neutral-400 transition-colors">Dashboard</a>
32084
+ {{/if}}
32085
+ {{#if (includes examples "todo")}}
32086
+ <a href="/todos" class="hover:text-neutral-400 transition-colors">Todos</a>
32087
+ {{/if}}
32088
+ {{#if (includes examples "ai")}}
32089
+ <a href="/ai" class="hover:text-neutral-400 transition-colors">AI Chat</a>
32090
+ {{/if}}
31576
32091
  </nav>
31577
32092
  <div class="flex items-center gap-2">
31578
32093
  {{#if (eq auth "better-auth")}}
@@ -31735,7 +32250,11 @@ const TITLE_TEXT = \`
31735
32250
  {{/if}}
31736
32251
  `],
31737
32252
  ["frontend/svelte/static/favicon.png", `[Binary file]`],
31738
- ["frontend/svelte/svelte.config.js.hbs", `import adapter from '@sveltejs/adapter-auto';
32253
+ ["frontend/svelte/svelte.config.js.hbs", `{{#if (eq webDeploy "cloudflare")}}
32254
+ import alchemy from 'alchemy/cloudflare/sveltekit';
32255
+ {{else}}
32256
+ import adapter from '@sveltejs/adapter-auto';
32257
+ {{/if}}
31739
32258
  import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
31740
32259
 
31741
32260
  /** @type {import('@sveltejs/kit').Config} */
@@ -31745,10 +32264,15 @@ const config = {
31745
32264
  preprocess: vitePreprocess(),
31746
32265
 
31747
32266
  kit: {
32267
+ {{#if (eq webDeploy "cloudflare")}}
32268
+ // Alchemy's adapter wraps SvelteKit's Cloudflare adapter for local platform.env and Worker builds.
32269
+ adapter: alchemy()
32270
+ {{else}}
31748
32271
  // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
31749
32272
  // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
31750
32273
  // See https://svelte.dev/docs/kit/adapters for more information about adapters.
31751
32274
  adapter: adapter()
32275
+ {{/if}}
31752
32276
  }
31753
32277
  };
31754
32278
 
@@ -31765,7 +32289,8 @@ export default config;
31765
32289
  "skipLibCheck": true,
31766
32290
  "sourceMap": true,
31767
32291
  "strict": true,
31768
- "moduleResolution": "bundler"
32292
+ "moduleResolution": "bundler"{{#if (eq webDeploy "cloudflare")}},
32293
+ "types": ["@cloudflare/workers-types"]{{/if}}
31769
32294
  }
31770
32295
  // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
31771
32296
  // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
@@ -31828,6 +32353,24 @@ export default defineConfig({
31828
32353
  "type": "module",
31829
32354
  "exports": {}
31830
32355
  }`],
32356
+ ["packages/env/src/cloudflare-local.ts.hbs", `import { config } from "dotenv";
32357
+ import { fileURLToPath } from "node:url";
32358
+
32359
+ config({ path: fileURLToPath(new URL("../../../.env", import.meta.url)) });
32360
+ config();
32361
+
32362
+ const runtimeEnv = typeof process === "undefined" ? {} : process.env;
32363
+
32364
+ export const env = new Proxy({} as Env, {
32365
+ get(_target, prop) {
32366
+ if (typeof prop !== "string") {
32367
+ return undefined;
32368
+ }
32369
+
32370
+ return runtimeEnv[prop];
32371
+ },
32372
+ });
32373
+ `],
31831
32374
  ["packages/env/src/native.ts.hbs", `import { createEnv } from "@t3-oss/env-core";
31832
32375
  import { z } from "zod";
31833
32376
 
@@ -31850,7 +32393,8 @@ export const env = createEnv({
31850
32393
  emptyStringAsUndefined: true,
31851
32394
  });
31852
32395
  `],
31853
- ["packages/env/src/server.ts.hbs", `{{#if (eq serverDeploy "cloudflare")}}
32396
+ ["packages/env/src/server.ts.hbs", `{{#if (and (eq serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
32397
+ /// <reference types="@cloudflare/workers-types" />
31854
32398
  /// <reference path="../env.d.ts" />
31855
32399
  // For Cloudflare Workers, env is accessed via cloudflare:workers module
31856
32400
  // Types are defined in env.d.ts based on your alchemy.run.ts bindings
@@ -31860,6 +32404,10 @@ export { env } from "cloudflare:workers";
31860
32404
  import { getCloudflareContext } from "@opennextjs/cloudflare";
31861
32405
 
31862
32406
  function getNodeEnvValue(key: string) {
32407
+ if (key === "DB") {
32408
+ return undefined;
32409
+ }
32410
+
31863
32411
  return process.env[key];
31864
32412
  }
31865
32413
 
@@ -31912,7 +32460,27 @@ export async function getEnvAsync() {
31912
32460
  }
31913
32461
 
31914
32462
  export const env = createEnvProxy(resolveEnvValue);
32463
+ {{else if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
32464
+ /// <reference path="../env.d.ts" />
32465
+ import { config } from "dotenv";
32466
+ import { fileURLToPath } from "node:url";
32467
+
32468
+ config({ path: fileURLToPath(new URL("../../../.env", import.meta.url)) });
32469
+ config();
32470
+
32471
+ const runtimeEnv = typeof process === "undefined" ? {} : process.env;
32472
+
32473
+ export const env = new Proxy({} as Env, {
32474
+ get(_target, prop) {
32475
+ if (typeof prop !== "string") {
32476
+ return undefined;
32477
+ }
32478
+
32479
+ return runtimeEnv[prop];
32480
+ },
32481
+ });
31915
32482
  {{else if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
32483
+ /// <reference types="@cloudflare/workers-types" />
31916
32484
  /// <reference path="../env.d.ts" />
31917
32485
  // For Cloudflare Workers, env is accessed via cloudflare:workers module
31918
32486
  // Types are defined in env.d.ts based on your alchemy.run.ts bindings
@@ -32256,7 +32824,39 @@ export const web = await SvelteKit("web", {
32256
32824
  {{else if (ne backend "self")}}
32257
32825
  PUBLIC_SERVER_URL: alchemy.env.PUBLIC_SERVER_URL!,
32258
32826
  {{/if}}
32259
- }
32827
+ {{#if (eq backend "self")}}
32828
+ {{#if (eq dbSetup "d1")}}
32829
+ DB: db,
32830
+ {{else if (ne database "none")}}
32831
+ DATABASE_URL: alchemy.secret.env.DATABASE_URL!,
32832
+ {{/if}}
32833
+ CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,
32834
+ {{#if (eq auth "better-auth")}}
32835
+ BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,
32836
+ BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,
32837
+ {{/if}}
32838
+ {{#if (and (includes examples "ai") (ne backend "convex"))}}
32839
+ GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,
32840
+ {{/if}}
32841
+ {{#if (eq payments "polar")}}
32842
+ POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,
32843
+ POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,
32844
+ {{/if}}
32845
+ {{#if (eq dbSetup "turso")}}
32846
+ DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,
32847
+ {{/if}}
32848
+ {{#if (eq database "mysql")}}
32849
+ {{#if (eq orm "drizzle")}}
32850
+ DATABASE_HOST: alchemy.env.DATABASE_HOST!,
32851
+ DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,
32852
+ DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,
32853
+ {{/if}}
32854
+ {{/if}}
32855
+ {{/if}}
32856
+ },
32857
+ dev: {
32858
+ domain: "localhost:5173",
32859
+ },
32260
32860
  });
32261
32861
  {{else if (includes frontend "tanstack-start")}}
32262
32862
  export const web = await TanStackStart("web", {
@@ -33248,12 +33848,25 @@ export function cn(...inputs: ClassValue[]) {
33248
33848
  }
33249
33849
  `],
33250
33850
  ["payments/polar/server/base/src/lib/payments.ts.hbs", `import { Polar } from "@polar-sh/sdk";
33851
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
33852
+ import type {} from "@{{projectName}}/env/server";
33853
+ {{else}}
33251
33854
  import { env } from "@{{projectName}}/env/server";
33855
+ {{/if}}
33252
33856
 
33857
+ {{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}
33858
+ export function createPolarClient({{#if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "svelte"))}}env: Env{{/if}}) {
33859
+ return new Polar({
33860
+ accessToken: env.POLAR_ACCESS_TOKEN,
33861
+ server: "sandbox",
33862
+ });
33863
+ }
33864
+ {{else}}
33253
33865
  export const polarClient = new Polar({
33254
33866
  accessToken: env.POLAR_ACCESS_TOKEN,
33255
33867
  server: "sandbox",
33256
33868
  });
33869
+ {{/if}}
33257
33870
  `],
33258
33871
  ["payments/polar/web/nuxt/app/pages/success.vue.hbs", `<script setup lang="ts">
33259
33872
  const route = useRoute()
@@ -33391,7 +34004,7 @@ function SuccessPage() {
33391
34004
  </div>
33392
34005
  `]
33393
34006
  ]);
33394
- const TEMPLATE_COUNT = 462;
34007
+ const TEMPLATE_COUNT = 467;
33395
34008
  //#endregion
33396
34009
  export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };
33397
34010