@better-t-stack/template-generator 3.35.2 → 3.36.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.d.mts +93 -87
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +768 -294
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -189,6 +189,33 @@ Handlebars.registerHelper("and", (...args) => args.slice(0, -1).every(Boolean));
|
|
|
189
189
|
Handlebars.registerHelper("or", (...args) => args.slice(0, -1).some(Boolean));
|
|
190
190
|
Handlebars.registerHelper("not", (a) => !a);
|
|
191
191
|
Handlebars.registerHelper("includes", (arr, val) => Array.isArray(arr) && arr.includes(val));
|
|
192
|
+
const getServerUrlSource = `function getServerUrl(url: string) {
|
|
193
|
+
const normalized = url.endsWith("/") ? url.slice(0, -1) : url;
|
|
194
|
+
|
|
195
|
+
if (!normalized.startsWith("/")) {
|
|
196
|
+
return normalized;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (typeof window !== "undefined") {
|
|
200
|
+
return \`\${window.location.origin}\${normalized}\`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const processEnv = (globalThis as {
|
|
204
|
+
process?: { env?: Record<string, string | undefined> };
|
|
205
|
+
}).process?.env;
|
|
206
|
+
const vercelUrl =
|
|
207
|
+
processEnv?.VERCEL_ENV === "production"
|
|
208
|
+
? (processEnv?.VERCEL_PROJECT_PRODUCTION_URL ?? processEnv?.VERCEL_URL)
|
|
209
|
+
: (processEnv?.VERCEL_URL ?? processEnv?.VERCEL_PROJECT_PRODUCTION_URL);
|
|
210
|
+
if (vercelUrl) {
|
|
211
|
+
const origin = vercelUrl.startsWith("http") ? vercelUrl : \`https://\${vercelUrl}\`;
|
|
212
|
+
return \`\${origin}\${normalized}\`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return \`http://localhost:3000\${normalized}\`;
|
|
216
|
+
}`;
|
|
217
|
+
Handlebars.registerPartial("getServerUrl", getServerUrlSource);
|
|
218
|
+
Handlebars.registerPartial("getServerUrlSpaces", getServerUrlSource.replaceAll(" ", " "));
|
|
192
219
|
function processTemplateString(content, context) {
|
|
193
220
|
return Handlebars.compile(content)(context);
|
|
194
221
|
}
|
|
@@ -201,6 +228,7 @@ function transformFilename(filename) {
|
|
|
201
228
|
if (basename === "_gitignore") result = result.replace(/_gitignore$/, ".gitignore");
|
|
202
229
|
else if (basename === "_npmrc") result = result.replace(/_npmrc$/, ".npmrc");
|
|
203
230
|
else if (basename === "_dockerignore") result = result.replace(/_dockerignore$/, ".dockerignore");
|
|
231
|
+
else if (basename === "_vercelignore") result = result.replace(/_vercelignore$/, ".vercelignore");
|
|
204
232
|
return result;
|
|
205
233
|
}
|
|
206
234
|
function processFileContent(filePath, content, context) {
|
|
@@ -385,27 +413,27 @@ function updatePackageJsonsWithCatalogs(vfs, packagesInfo, catalog) {
|
|
|
385
413
|
//#region src/utils/add-deps.ts
|
|
386
414
|
const dependencyVersionMap = {
|
|
387
415
|
typescript: "^6",
|
|
388
|
-
"better-auth": "1.6.
|
|
389
|
-
"@better-auth/expo": "1.6.
|
|
390
|
-
"@clerk/backend": "^3.
|
|
391
|
-
"@clerk/express": "^2.
|
|
392
|
-
"@clerk/fastify": "^3.1.
|
|
393
|
-
"@clerk/nextjs": "^7.
|
|
394
|
-
"@clerk/react": "^6.
|
|
395
|
-
"@clerk/react-router": "^3.
|
|
396
|
-
"@clerk/tanstack-react-start": "^1.
|
|
397
|
-
"@clerk/expo": "^3.
|
|
398
|
-
"drizzle-orm": "^0.45.
|
|
399
|
-
"drizzle-kit": "^0.31.
|
|
400
|
-
"@planetscale/database": "^1.
|
|
401
|
-
"@libsql/client": "0.
|
|
402
|
-
libsql: "0.5.
|
|
403
|
-
"@neondatabase/serverless": "^1.0
|
|
404
|
-
pg: "^8.
|
|
405
|
-
"@types/pg": "^8.
|
|
416
|
+
"better-auth": "1.6.23",
|
|
417
|
+
"@better-auth/expo": "1.6.23",
|
|
418
|
+
"@clerk/backend": "^3.10.0",
|
|
419
|
+
"@clerk/express": "^2.1.35",
|
|
420
|
+
"@clerk/fastify": "^3.1.45",
|
|
421
|
+
"@clerk/nextjs": "^7.5.12",
|
|
422
|
+
"@clerk/react": "^6.11.3",
|
|
423
|
+
"@clerk/react-router": "^3.5.4",
|
|
424
|
+
"@clerk/tanstack-react-start": "^1.4.12",
|
|
425
|
+
"@clerk/expo": "^3.6.5",
|
|
426
|
+
"drizzle-orm": "^0.45.2",
|
|
427
|
+
"drizzle-kit": "^0.31.10",
|
|
428
|
+
"@planetscale/database": "^1.20.1",
|
|
429
|
+
"@libsql/client": "0.17.4",
|
|
430
|
+
libsql: "0.5.29",
|
|
431
|
+
"@neondatabase/serverless": "^1.1.0",
|
|
432
|
+
pg: "^8.22.0",
|
|
433
|
+
"@types/pg": "^8.20.0",
|
|
406
434
|
"@types/ws": "^8.18.1",
|
|
407
|
-
ws: "^8.
|
|
408
|
-
mysql2: "^3.
|
|
435
|
+
ws: "^8.21.0",
|
|
436
|
+
mysql2: "^3.22.5",
|
|
409
437
|
"@prisma/client": "^7.8.0",
|
|
410
438
|
prisma: "^7.8.0",
|
|
411
439
|
"@prisma/adapter-d1": "^7.8.0",
|
|
@@ -415,57 +443,57 @@ const dependencyVersionMap = {
|
|
|
415
443
|
"@prisma/adapter-better-sqlite3": "^7.8.0",
|
|
416
444
|
"@prisma/adapter-pg": "^7.8.0",
|
|
417
445
|
"@prisma/adapter-planetscale": "^7.8.0",
|
|
418
|
-
mongoose: "^9.
|
|
419
|
-
mongodb: "^7.
|
|
446
|
+
mongoose: "^9.7.3",
|
|
447
|
+
mongodb: "^7.4.0",
|
|
420
448
|
"vite-plugin-pwa": "^1.3.0",
|
|
421
449
|
"@vite-pwa/assets-generator": "^1.0.2",
|
|
422
|
-
"@tauri-apps/cli": "^2.11.
|
|
423
|
-
"@biomejs/biome": "^2.
|
|
424
|
-
oxlint: "^1.
|
|
425
|
-
oxfmt: "^0.
|
|
450
|
+
"@tauri-apps/cli": "^2.11.4",
|
|
451
|
+
"@biomejs/biome": "^2.5.2",
|
|
452
|
+
oxlint: "^1.72.0",
|
|
453
|
+
oxfmt: "^0.57.0",
|
|
426
454
|
husky: "^9.1.7",
|
|
427
455
|
lefthook: "^2.1.9",
|
|
428
456
|
"lint-staged": "^17.0.7",
|
|
429
|
-
tsx: "^4.
|
|
457
|
+
tsx: "^4.22.5",
|
|
430
458
|
"@types/node": "^22.13.14",
|
|
431
|
-
"@types/bun": "^1.3.
|
|
459
|
+
"@types/bun": "^1.3.14",
|
|
432
460
|
"@elysiajs/node": "^1.4.5",
|
|
433
|
-
"@elysiajs/cors": "^1.4.
|
|
461
|
+
"@elysiajs/cors": "^1.4.2",
|
|
434
462
|
"@elysiajs/trpc": "^1.1.0",
|
|
435
|
-
elysia: "^1.4.
|
|
463
|
+
elysia: "^1.4.29",
|
|
436
464
|
"@sinclair/typebox": "^0.34.49",
|
|
437
|
-
"@hono/node-server": "^
|
|
438
|
-
"@hono/trpc-server": "^0.4.
|
|
439
|
-
hono: "^4.
|
|
440
|
-
cors: "^2.8.
|
|
441
|
-
express: "^5.1
|
|
442
|
-
"@types/express": "^5.0.
|
|
443
|
-
"@types/cors": "^2.8.
|
|
444
|
-
fastify: "^5.
|
|
445
|
-
"@fastify/cors": "^11.0
|
|
465
|
+
"@hono/node-server": "^2.0.8",
|
|
466
|
+
"@hono/trpc-server": "^0.4.2",
|
|
467
|
+
hono: "^4.12.27",
|
|
468
|
+
cors: "^2.8.6",
|
|
469
|
+
express: "^5.2.1",
|
|
470
|
+
"@types/express": "^5.0.6",
|
|
471
|
+
"@types/cors": "^2.8.19",
|
|
472
|
+
fastify: "^5.9.0",
|
|
473
|
+
"@fastify/cors": "^11.2.0",
|
|
446
474
|
turbo: "^2.10.2",
|
|
447
|
-
nx: "^
|
|
448
|
-
"vite-plus": "0.
|
|
449
|
-
rolldown: "1.1.
|
|
450
|
-
ai: "^7.0.
|
|
451
|
-
"@ai-sdk/google": "^4.0.
|
|
452
|
-
"@ai-sdk/vue": "^4.0.
|
|
453
|
-
"@ai-sdk/svelte": "^5.0.
|
|
454
|
-
"@ai-sdk/react": "^4.0.
|
|
455
|
-
"@ai-sdk/devtools": "^1.0.
|
|
475
|
+
nx: "^23.0.1",
|
|
476
|
+
"vite-plus": "0.2.2",
|
|
477
|
+
rolldown: "1.1.4",
|
|
478
|
+
ai: "^7.0.13",
|
|
479
|
+
"@ai-sdk/google": "^4.0.7",
|
|
480
|
+
"@ai-sdk/vue": "^4.0.13",
|
|
481
|
+
"@ai-sdk/svelte": "^5.0.13",
|
|
482
|
+
"@ai-sdk/react": "^4.0.14",
|
|
483
|
+
"@ai-sdk/devtools": "^1.0.1",
|
|
456
484
|
streamdown: "^2.5.0",
|
|
457
|
-
shiki: "^3.
|
|
485
|
+
shiki: "^4.3.0",
|
|
458
486
|
"@orpc/server": "^1.14.6",
|
|
459
487
|
"@orpc/client": "^1.14.6",
|
|
460
488
|
"@orpc/openapi": "^1.14.6",
|
|
461
489
|
"@orpc/zod": "^1.14.6",
|
|
462
490
|
"@orpc/tanstack-query": "^1.14.6",
|
|
463
|
-
"@trpc/tanstack-react-query": "^11.
|
|
464
|
-
"@trpc/server": "^11.
|
|
465
|
-
"@trpc/client": "^11.
|
|
491
|
+
"@trpc/tanstack-react-query": "^11.18.0",
|
|
492
|
+
"@trpc/server": "^11.18.0",
|
|
493
|
+
"@trpc/client": "^11.18.0",
|
|
466
494
|
next: "^16.2.0",
|
|
467
|
-
nitro: "^3.0.
|
|
468
|
-
convex: "^1.42.
|
|
495
|
+
nitro: "^3.0.260610-beta",
|
|
496
|
+
convex: "^1.42.1",
|
|
469
497
|
"@convex-dev/react-query": "^0.1.0",
|
|
470
498
|
"@convex-dev/agent": "^0.6.4",
|
|
471
499
|
"@convex-dev/polar": "^0.9.2",
|
|
@@ -473,40 +501,43 @@ const dependencyVersionMap = {
|
|
|
473
501
|
"convex-nuxt": "0.1.5",
|
|
474
502
|
"convex-vue": "^0.1.5",
|
|
475
503
|
"@convex-dev/better-auth": "^0.12.5",
|
|
476
|
-
"@tanstack/svelte-query": "^
|
|
477
|
-
"@tanstack/svelte-query-devtools": "^
|
|
478
|
-
"@tanstack/vue-query-devtools": "^6.1.
|
|
479
|
-
"@tanstack/vue-query": "^5.
|
|
480
|
-
"@tanstack/react-query-devtools": "^5.
|
|
481
|
-
"@tanstack/react-query": "^5.
|
|
482
|
-
"@tanstack/react-form": "^1.
|
|
483
|
-
"@tanstack/react-router-ssr-query": "^1.
|
|
484
|
-
"@tanstack/solid-form": "^1.
|
|
485
|
-
"@tanstack/svelte-form": "^1.
|
|
486
|
-
"@tanstack/solid-query": "^5.
|
|
487
|
-
"@tanstack/solid-query-devtools": "^5.
|
|
488
|
-
"@tanstack/solid-router-devtools": "^1.
|
|
489
|
-
wrangler: "^4.
|
|
490
|
-
"@cloudflare/vite-plugin": "^1.
|
|
491
|
-
"@opennextjs/cloudflare": "^1.
|
|
504
|
+
"@tanstack/svelte-query": "^6.1.36",
|
|
505
|
+
"@tanstack/svelte-query-devtools": "^6.1.36",
|
|
506
|
+
"@tanstack/vue-query-devtools": "^6.1.36",
|
|
507
|
+
"@tanstack/vue-query": "^5.101.2",
|
|
508
|
+
"@tanstack/react-query-devtools": "^5.101.2",
|
|
509
|
+
"@tanstack/react-query": "^5.101.2",
|
|
510
|
+
"@tanstack/react-form": "^1.33.0",
|
|
511
|
+
"@tanstack/react-router-ssr-query": "^1.167.1",
|
|
512
|
+
"@tanstack/solid-form": "^1.33.0",
|
|
513
|
+
"@tanstack/svelte-form": "^1.33.0",
|
|
514
|
+
"@tanstack/solid-query": "^5.101.2",
|
|
515
|
+
"@tanstack/solid-query-devtools": "^5.101.2",
|
|
516
|
+
"@tanstack/solid-router-devtools": "^1.167.0",
|
|
517
|
+
wrangler: "^4.107.0",
|
|
518
|
+
"@cloudflare/vite-plugin": "^1.43.0",
|
|
519
|
+
"@opennextjs/cloudflare": "^1.20.1",
|
|
492
520
|
"nitro-cloudflare-dev": "^0.2.2",
|
|
493
|
-
"@sveltejs/adapter-cloudflare": "^7.2.
|
|
494
|
-
"@sveltejs/adapter-node": "^5.5.
|
|
495
|
-
"@
|
|
496
|
-
"@
|
|
497
|
-
"@astrojs/
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
521
|
+
"@sveltejs/adapter-cloudflare": "^7.2.9",
|
|
522
|
+
"@sveltejs/adapter-node": "^5.5.7",
|
|
523
|
+
"@sveltejs/adapter-vercel": "^6.3.4",
|
|
524
|
+
"@cloudflare/workers-types": "^4.20260702.1",
|
|
525
|
+
"@astrojs/cloudflare": "^14.1.0",
|
|
526
|
+
"@astrojs/node": "^11.0.1",
|
|
527
|
+
"@astrojs/vercel": "^11.0.1",
|
|
528
|
+
alchemy: "^0.93.12",
|
|
529
|
+
vercel: "^54.18.6",
|
|
530
|
+
dotenv: "^17.4.2",
|
|
531
|
+
tsdown: "^0.22.3",
|
|
532
|
+
zod: "^4.4.3",
|
|
533
|
+
"@t3-oss/env-core": "^0.13.11",
|
|
534
|
+
"@t3-oss/env-nextjs": "^0.13.11",
|
|
535
|
+
"@t3-oss/env-nuxt": "^0.13.11",
|
|
505
536
|
"@polar-sh/better-auth": "^1.8.4",
|
|
506
|
-
"@polar-sh/checkout": "^0.
|
|
537
|
+
"@polar-sh/checkout": "^0.4.0",
|
|
507
538
|
"@polar-sh/sdk": "^0.47.1",
|
|
508
|
-
"@stripe/react-stripe-js": "^
|
|
509
|
-
"@stripe/stripe-js": "^
|
|
539
|
+
"@stripe/react-stripe-js": "^5.6.1",
|
|
540
|
+
"@stripe/stripe-js": "^8.11.0",
|
|
510
541
|
evlog: "^2.19.2"
|
|
511
542
|
};
|
|
512
543
|
/**
|
|
@@ -522,8 +553,9 @@ function addPackageDependency(options) {
|
|
|
522
553
|
const version = dependencyVersionMap[dep];
|
|
523
554
|
if (!version) throw new Error(`Missing version for dependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
|
|
524
555
|
pkgJson.dependencies[dep] = version;
|
|
556
|
+
delete pkgJson.devDependencies[dep];
|
|
525
557
|
}
|
|
526
|
-
for (const dep of devDependencies) if (!pkgJson.devDependencies[dep]) {
|
|
558
|
+
for (const dep of devDependencies) if (!pkgJson.devDependencies[dep] && !pkgJson.dependencies[dep]) {
|
|
527
559
|
const version = dependencyVersionMap[dep];
|
|
528
560
|
if (!version) throw new Error(`Missing version for devDependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
|
|
529
561
|
pkgJson.devDependencies[dep] = version;
|
|
@@ -659,10 +691,25 @@ function updateRootPackageJson(vfs, config) {
|
|
|
659
691
|
scripts["db:down"] = pmConfig.filter(dbPackageName, "db:down");
|
|
660
692
|
}
|
|
661
693
|
const infraPackageName = `@${projectName}/infra`;
|
|
662
|
-
|
|
663
|
-
|
|
694
|
+
const hasCloudflareDeploy = config.webDeploy === "cloudflare" || config.serverDeploy === "cloudflare";
|
|
695
|
+
const hasVercelDeploy = config.webDeploy === "vercel" || config.serverDeploy === "vercel";
|
|
696
|
+
const isMixedCloud = hasCloudflareDeploy && hasVercelDeploy;
|
|
697
|
+
if (hasCloudflareDeploy) {
|
|
698
|
+
const cfDeployScript = isMixedCloud ? config.webDeploy === "cloudflare" ? "deploy:web" : "deploy:server" : "deploy";
|
|
699
|
+
scripts[cfDeployScript] = pmConfig.filter(infraPackageName, "deploy");
|
|
664
700
|
scripts.destroy = pmConfig.filter(infraPackageName, "destroy");
|
|
665
701
|
}
|
|
702
|
+
if (hasVercelDeploy) {
|
|
703
|
+
const vercelTarget = config.webDeploy === "vercel" ? "web" : "server";
|
|
704
|
+
const vercelDeploy = isMixedCloud ? `deploy:${vercelTarget}` : "deploy";
|
|
705
|
+
scripts["deploy:setup"] = "vercel link";
|
|
706
|
+
scripts["dev:vercel"] = "vercel dev -L";
|
|
707
|
+
scripts["env:preview"] = "tsx scripts/sync-vercel-env.ts preview";
|
|
708
|
+
scripts["env:production"] = "tsx scripts/sync-vercel-env.ts production";
|
|
709
|
+
scripts[vercelDeploy] = "vercel deploy";
|
|
710
|
+
scripts[`${vercelDeploy}:prod`] = "vercel deploy --prod";
|
|
711
|
+
scripts["deploy:check"] = "vercel deploy --dry";
|
|
712
|
+
}
|
|
666
713
|
if (config.webDeploy === "docker" || config.serverDeploy === "docker") {
|
|
667
714
|
scripts["docker:build"] = "docker compose build";
|
|
668
715
|
scripts["docker:up"] = "docker compose up -d --build";
|
|
@@ -676,8 +723,7 @@ function updateRootPackageJson(vfs, config) {
|
|
|
676
723
|
};
|
|
677
724
|
if (hasVitePlus) pkgJson.overrides = {
|
|
678
725
|
...pkgJson.overrides,
|
|
679
|
-
vite: `npm:@voidzero-dev/vite-plus-core@${VITE_PLUS_VERSION}
|
|
680
|
-
vitest: `npm:@voidzero-dev/vite-plus-test@${VITE_PLUS_VERSION}`
|
|
726
|
+
vite: `npm:@voidzero-dev/vite-plus-core@${VITE_PLUS_VERSION}`
|
|
681
727
|
};
|
|
682
728
|
if (backend === "convex") {
|
|
683
729
|
if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
|
|
@@ -942,6 +988,86 @@ function updateVitePlusPackageScripts(vfs, config) {
|
|
|
942
988
|
vfs.writeJson(webPkgPath, webPkg);
|
|
943
989
|
}
|
|
944
990
|
//#endregion
|
|
991
|
+
//#region src/post-process/vercel-config.ts
|
|
992
|
+
function getWebFramework(frontend, isDesktop) {
|
|
993
|
+
if (frontend.includes("next")) return "nextjs";
|
|
994
|
+
if (frontend.includes("nuxt")) return "nuxtjs";
|
|
995
|
+
if (frontend.includes("svelte")) return "sveltekit";
|
|
996
|
+
if (frontend.includes("astro")) return "astro";
|
|
997
|
+
if (frontend.includes("tanstack-start")) return "tanstack-start";
|
|
998
|
+
if (frontend.includes("react-router") && !isDesktop) return "react-router";
|
|
999
|
+
return "vite";
|
|
1000
|
+
}
|
|
1001
|
+
function getPublicServerUrlVar(frontend) {
|
|
1002
|
+
if (frontend.includes("next")) return "NEXT_PUBLIC_SERVER_URL";
|
|
1003
|
+
if (frontend.includes("nuxt")) return "NUXT_PUBLIC_SERVER_URL";
|
|
1004
|
+
if (frontend.includes("svelte") || frontend.includes("astro")) return "PUBLIC_SERVER_URL";
|
|
1005
|
+
return "VITE_SERVER_URL";
|
|
1006
|
+
}
|
|
1007
|
+
function processVercelConfig(vfs, config) {
|
|
1008
|
+
const { webDeploy, serverDeploy, backend, runtime, frontend, addons, packageManager } = config;
|
|
1009
|
+
if (webDeploy !== "vercel" && serverDeploy !== "vercel") return;
|
|
1010
|
+
const hasWeb = webDeploy === "vercel";
|
|
1011
|
+
const hasServer = serverDeploy === "vercel" && backend !== "self";
|
|
1012
|
+
const isDesktop = addons.includes("tauri") || addons.includes("electrobun");
|
|
1013
|
+
const isStaticSpa = frontend.includes("tanstack-router") || frontend.includes("solid") || frontend.includes("react-router") && isDesktop;
|
|
1014
|
+
const installCommand = `cd ../.. && ${packageManager} install`;
|
|
1015
|
+
const services = {};
|
|
1016
|
+
if (hasWeb) {
|
|
1017
|
+
const web = {
|
|
1018
|
+
root: "apps/web",
|
|
1019
|
+
framework: getWebFramework(frontend, isDesktop),
|
|
1020
|
+
installCommand
|
|
1021
|
+
};
|
|
1022
|
+
if (hasServer) web.buildCommand = `${getPublicServerUrlVar(frontend)}=/api ${packageManager} run build`;
|
|
1023
|
+
if (frontend.includes("react-router") && isDesktop) web.outputDirectory = "build/client";
|
|
1024
|
+
if (isStaticSpa) web.rewrites = [{
|
|
1025
|
+
source: "/(.*)",
|
|
1026
|
+
destination: "/index.html"
|
|
1027
|
+
}];
|
|
1028
|
+
services.web = web;
|
|
1029
|
+
}
|
|
1030
|
+
if (hasServer) {
|
|
1031
|
+
const server = {
|
|
1032
|
+
root: "apps/server",
|
|
1033
|
+
framework: backend,
|
|
1034
|
+
entrypoint: "src/index.ts",
|
|
1035
|
+
installCommand
|
|
1036
|
+
};
|
|
1037
|
+
if (hasWeb) server.routes = [{
|
|
1038
|
+
src: "/api/((?!auth(?:/|$)).*)",
|
|
1039
|
+
transforms: [{
|
|
1040
|
+
type: "request.path",
|
|
1041
|
+
op: "set",
|
|
1042
|
+
args: "/$1"
|
|
1043
|
+
}]
|
|
1044
|
+
}];
|
|
1045
|
+
services.server = server;
|
|
1046
|
+
}
|
|
1047
|
+
const rewrites = [];
|
|
1048
|
+
if (hasWeb && hasServer) rewrites.push({
|
|
1049
|
+
source: "/api/(.*)",
|
|
1050
|
+
destination: { service: "server" }
|
|
1051
|
+
}, {
|
|
1052
|
+
source: "/(.*)",
|
|
1053
|
+
destination: { service: "web" }
|
|
1054
|
+
});
|
|
1055
|
+
else if (hasWeb) rewrites.push({
|
|
1056
|
+
source: "/(.*)",
|
|
1057
|
+
destination: { service: "web" }
|
|
1058
|
+
});
|
|
1059
|
+
else if (hasServer) rewrites.push({
|
|
1060
|
+
source: "/(.*)",
|
|
1061
|
+
destination: { service: "server" }
|
|
1062
|
+
});
|
|
1063
|
+
vfs.writeJson("vercel.json", {
|
|
1064
|
+
$schema: "https://openapi.vercel.sh/vercel.json",
|
|
1065
|
+
...hasServer && runtime === "bun" ? { bunVersion: "1.x" } : {},
|
|
1066
|
+
services,
|
|
1067
|
+
rewrites
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
//#endregion
|
|
945
1071
|
//#region src/processors/addons-deps.ts
|
|
946
1072
|
function processAddonsDeps(vfs, config) {
|
|
947
1073
|
if (!config.addons || config.addons.length === 0) return;
|
|
@@ -2063,12 +2189,47 @@ function processDrizzleDeps(vfs, config, dbPkgPath, webPkgPath, webExists) {
|
|
|
2063
2189
|
//#endregion
|
|
2064
2190
|
//#region src/processors/deploy-deps.ts
|
|
2065
2191
|
function processDeployDeps(vfs, config) {
|
|
2066
|
-
const { webDeploy, serverDeploy, frontend, backend } = config;
|
|
2192
|
+
const { webDeploy, serverDeploy, frontend, backend, addons } = config;
|
|
2067
2193
|
const isCloudflareWeb = webDeploy === "cloudflare";
|
|
2068
2194
|
const isCloudflareServer = serverDeploy === "cloudflare";
|
|
2069
2195
|
const isDockerWeb = webDeploy === "docker";
|
|
2196
|
+
const isVercelWeb = webDeploy === "vercel";
|
|
2197
|
+
const isVercelServer = serverDeploy === "vercel";
|
|
2070
2198
|
const isBackendSelf = backend === "self";
|
|
2071
|
-
if (!isCloudflareWeb && !isCloudflareServer && !isDockerWeb) return;
|
|
2199
|
+
if (!isCloudflareWeb && !isCloudflareServer && !isDockerWeb && !isVercelWeb && !isVercelServer) return;
|
|
2200
|
+
if (isVercelWeb || isVercelServer) addPackageDependency({
|
|
2201
|
+
vfs,
|
|
2202
|
+
packagePath: "package.json",
|
|
2203
|
+
devDependencies: [
|
|
2204
|
+
"@types/node",
|
|
2205
|
+
"tsx",
|
|
2206
|
+
"vercel"
|
|
2207
|
+
]
|
|
2208
|
+
});
|
|
2209
|
+
if (isVercelWeb && frontend.includes("tanstack-start")) {
|
|
2210
|
+
const webPkgPath = "apps/web/package.json";
|
|
2211
|
+
if (vfs.exists(webPkgPath)) addPackageDependency({
|
|
2212
|
+
vfs,
|
|
2213
|
+
packagePath: webPkgPath,
|
|
2214
|
+
dependencies: ["nitro"]
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
if (isVercelWeb && frontend.includes("astro") && !addons.includes("electrobun") && !addons.includes("tauri")) {
|
|
2218
|
+
const webPkgPath = "apps/web/package.json";
|
|
2219
|
+
if (vfs.exists(webPkgPath)) addPackageDependency({
|
|
2220
|
+
vfs,
|
|
2221
|
+
packagePath: webPkgPath,
|
|
2222
|
+
dependencies: ["@astrojs/vercel"]
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
if (isVercelWeb && frontend.includes("svelte") && !addons.includes("electrobun") && !addons.includes("tauri")) {
|
|
2226
|
+
const webPkgPath = "apps/web/package.json";
|
|
2227
|
+
if (vfs.exists(webPkgPath)) addPackageDependency({
|
|
2228
|
+
vfs,
|
|
2229
|
+
packagePath: webPkgPath,
|
|
2230
|
+
devDependencies: ["@sveltejs/adapter-vercel"]
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2072
2233
|
if (isDockerWeb) {
|
|
2073
2234
|
const webPkgPath = "apps/web/package.json";
|
|
2074
2235
|
if (vfs.exists(webPkgPath)) {
|
|
@@ -2519,10 +2680,25 @@ function processEnvVariables(vfs, config) {
|
|
|
2519
2680
|
const hasSvelte = frontend.includes("svelte");
|
|
2520
2681
|
const hasSolid = frontend.includes("solid");
|
|
2521
2682
|
const hasAstro = frontend.includes("astro");
|
|
2522
|
-
|
|
2683
|
+
const hasWebFrontend = hasReactRouter || hasTanStackRouter || hasTanStackStart || hasNextJs || hasNuxt || hasSolid || hasSvelte || hasAstro;
|
|
2684
|
+
if (hasWebFrontend) {
|
|
2523
2685
|
const clientDir = "apps/web";
|
|
2524
2686
|
if (vfs.directoryExists(clientDir)) writeEnvFile(vfs, `${clientDir}/.env`, buildClientVars(frontend, backend, auth));
|
|
2525
2687
|
}
|
|
2688
|
+
if (webDeploy === "docker" && hasWebFrontend) {
|
|
2689
|
+
const rootComposeVars = [{
|
|
2690
|
+
key: hasNextJs ? "NEXT_PUBLIC_CONVEX_URL" : hasSvelte || hasAstro ? "PUBLIC_CONVEX_URL" : "VITE_CONVEX_URL",
|
|
2691
|
+
value: CONVEX_URL_PLACEHOLDER,
|
|
2692
|
+
condition: backend === "convex" && !hasNuxt,
|
|
2693
|
+
comment: "Baked into the web image at docker compose build time"
|
|
2694
|
+
}, {
|
|
2695
|
+
key: hasNextJs ? "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY" : "VITE_CLERK_PUBLISHABLE_KEY",
|
|
2696
|
+
value: "",
|
|
2697
|
+
condition: auth === "clerk" && (hasNextJs || hasReactRouter || hasTanStackRouter || hasTanStackStart),
|
|
2698
|
+
comment: "Baked into the web image at docker compose build time"
|
|
2699
|
+
}];
|
|
2700
|
+
if (rootComposeVars.some((v) => v.condition)) writeEnvFile(vfs, ".env", rootComposeVars);
|
|
2701
|
+
}
|
|
2526
2702
|
if (frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles")) {
|
|
2527
2703
|
const nativeDir = "apps/native";
|
|
2528
2704
|
if (vfs.directoryExists(nativeDir)) writeEnvFile(vfs, `${nativeDir}/.env`, buildNativeVars(frontend, backend, auth));
|
|
@@ -2672,7 +2848,7 @@ function setupAIDependencies(vfs, config) {
|
|
|
2672
2848
|
//#region src/processors/frontend-deps.ts
|
|
2673
2849
|
function processFrontendDeps(vfs, config) {
|
|
2674
2850
|
const { addons, frontend, webDeploy } = config;
|
|
2675
|
-
if (!frontend.includes("astro") || addons.includes("electrobun") || addons.includes("tauri") || webDeploy === "cloudflare") return;
|
|
2851
|
+
if (!frontend.includes("astro") || addons.includes("electrobun") || addons.includes("tauri") || webDeploy === "cloudflare" || webDeploy === "vercel") return;
|
|
2676
2852
|
const webPackagePath = "apps/web/package.json";
|
|
2677
2853
|
if (!vfs.exists(webPackagePath)) return;
|
|
2678
2854
|
addPackageDependency({
|
|
@@ -2772,6 +2948,7 @@ function getStackGeneratedIgnorePatterns(config) {
|
|
|
2772
2948
|
patterns.add("**/.wrangler/**");
|
|
2773
2949
|
if (config.frontend.includes("next")) patterns.add("apps/web/.open-next/**");
|
|
2774
2950
|
}
|
|
2951
|
+
if (config.webDeploy === "vercel" || config.serverDeploy === "vercel") patterns.add(".vercel/**");
|
|
2775
2952
|
return [...patterns];
|
|
2776
2953
|
}
|
|
2777
2954
|
//#endregion
|
|
@@ -3442,20 +3619,39 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
|
|
|
3442
3619
|
- \`${packageManagerRunCmd} docker:up\`: Build and start the Docker Compose stack
|
|
3443
3620
|
- \`${packageManagerRunCmd} docker:logs\`: Tail logs from the Docker Compose stack
|
|
3444
3621
|
- \`${packageManagerRunCmd} docker:down\`: Stop the Docker Compose stack`;
|
|
3622
|
+
if (webDeploy === "vercel" || serverDeploy === "vercel") {
|
|
3623
|
+
const v = getVercelScriptNames(webDeploy, serverDeploy);
|
|
3624
|
+
scripts += `\n- \`${packageManagerRunCmd} ${v.setup}\`: Link this repo to a Vercel project (first-time setup)
|
|
3625
|
+
- \`${packageManagerRunCmd} dev:vercel\`: Run the Vercel Services dev environment locally
|
|
3626
|
+
- \`${packageManagerRunCmd} ${v.envPreview}\`: Sync local env files to the Vercel preview environment
|
|
3627
|
+
- \`${packageManagerRunCmd} ${v.envProduction}\`: Sync local env files to the Vercel production environment
|
|
3628
|
+
- \`${packageManagerRunCmd} ${v.deploy}\`: Create a Vercel preview deployment
|
|
3629
|
+
- \`${packageManagerRunCmd} ${v.deployProd}\`: Deploy to Vercel production
|
|
3630
|
+
- \`${packageManagerRunCmd} ${v.deployCheck}\`: Dry-run a deploy to preview framework detection and included files without uploading`;
|
|
3631
|
+
}
|
|
3445
3632
|
return scripts;
|
|
3446
3633
|
}
|
|
3447
3634
|
function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy, backend) {
|
|
3448
3635
|
const hasCloudflare = webDeploy === "cloudflare" || serverDeploy === "cloudflare";
|
|
3449
3636
|
const hasDocker = webDeploy === "docker" || serverDeploy === "docker";
|
|
3450
|
-
|
|
3637
|
+
const hasVercel = webDeploy === "vercel" || serverDeploy === "vercel";
|
|
3638
|
+
if (!hasCloudflare && !hasDocker && !hasVercel) return "";
|
|
3451
3639
|
const lines = ["## Deployment"];
|
|
3452
3640
|
if (hasCloudflare) {
|
|
3453
3641
|
const targetLabel = webDeploy === "cloudflare" && (serverDeploy === "cloudflare" || backend === "self") ? "web + server" : webDeploy === "cloudflare" ? "web" : "server";
|
|
3454
|
-
|
|
3642
|
+
const cfDeployScript = hasVercel ? webDeploy === "cloudflare" ? "deploy:web" : "deploy:server" : "deploy";
|
|
3643
|
+
lines.push("", "### Cloudflare via Alchemy", "", `- Target: ${targetLabel}`, `- Dev: ${packageManagerRunCmd} dev`, `- Deploy: ${packageManagerRunCmd} ${cfDeployScript}`, `- Destroy: ${packageManagerRunCmd} destroy`, "", "For more details, see the guide on [Deploying to Cloudflare with Alchemy](https://www.better-t-stack.dev/docs/guides/cloudflare-alchemy).");
|
|
3455
3644
|
}
|
|
3456
3645
|
if (hasDocker) {
|
|
3457
3646
|
const targetLabel = webDeploy === "docker" && (serverDeploy === "docker" || backend === "self") ? "web + server" : webDeploy === "docker" ? "web" : "server";
|
|
3458
|
-
lines.push("", "### Docker Compose", "", `- Target: ${targetLabel}`, "- Config: `docker-compose.yml` (app Dockerfiles live in `apps/*/Dockerfile`)", `- Build images: ${packageManagerRunCmd} docker:build`, `- Start: ${packageManagerRunCmd} docker:up`, `- Logs: ${packageManagerRunCmd} docker:logs`, `- Stop: ${packageManagerRunCmd} docker:down`, "", "Environment variables are read from each app's `.env` file (baked into web builds for public variables) and overridden in `docker-compose.yml` for container networking.");
|
|
3647
|
+
lines.push("", "### Docker Compose", "", `- Target: ${targetLabel}`, "- Config: `docker-compose.yml` (app Dockerfiles live in `apps/*/Dockerfile`)", `- Build images: ${packageManagerRunCmd} docker:build`, `- Start: ${packageManagerRunCmd} docker:up`, `- Logs: ${packageManagerRunCmd} docker:logs`, `- Stop: ${packageManagerRunCmd} docker:down`, "", "Environment variables are read from each app's `.env` file (baked into web builds for public variables) and overridden in `docker-compose.yml` for container networking.", "", "For more details, see the guide on [Deploying with Docker Compose](https://www.better-t-stack.dev/docs/guides/docker).");
|
|
3648
|
+
}
|
|
3649
|
+
if (hasVercel) {
|
|
3650
|
+
const vercelNames = getVercelScriptNames(webDeploy, serverDeploy);
|
|
3651
|
+
const targetLabel = webDeploy === "vercel" && (serverDeploy === "vercel" || backend === "self") ? "web + server" : webDeploy === "vercel" ? "web" : "server";
|
|
3652
|
+
lines.push("", "### Vercel Services", "", `- Target: ${targetLabel}`, "- Config: `vercel.json`", `- Link the project first: ${packageManagerRunCmd} ${vercelNames.setup}`, `- Local Vercel dev: ${packageManagerRunCmd} dev:vercel`, `- Sync preview env: ${packageManagerRunCmd} ${vercelNames.envPreview}`, `- Sync production env: ${packageManagerRunCmd} ${vercelNames.envProduction}`, `- Dry-run check (no upload): ${packageManagerRunCmd} ${vercelNames.deployCheck}`, `- Preview deploy: ${packageManagerRunCmd} ${vercelNames.deploy}`, `- Production deploy: ${packageManagerRunCmd} ${vercelNames.deployProd}`);
|
|
3653
|
+
if (webDeploy === "vercel" && serverDeploy === "vercel" && backend !== "self") lines.push("- Web requests under `/api/*` route to the server service and are rewritten before reaching the backend.");
|
|
3654
|
+
lines.push("Vercel Services share project environment variables, but deploys do not upload local `.env` files automatically. Link the project with `vercel link`, then run the env sync command before your first deploy (otherwise the deployment starts with no env vars), or pass one-off envs with `vercel deploy -e KEY=value`.", `Pass Vercel CLI flags to the env sync command directly, for example: \`${packageManagerRunCmd} ${vercelNames.envProduction} --scope your-team\`.`, "", "For more details, see the guide on [Deploying to Vercel](https://www.better-t-stack.dev/docs/guides/vercel).");
|
|
3459
3655
|
}
|
|
3460
3656
|
return `${lines.join("\n")}\n`;
|
|
3461
3657
|
}
|
|
@@ -3472,6 +3668,17 @@ function generateGitHooksSection(packageManagerRunCmd, addons) {
|
|
|
3472
3668
|
if (hasLinting) lines.push(`- Run checks: \`${packageManagerRunCmd} check\``);
|
|
3473
3669
|
return `${lines.join("\n")}\n\n`;
|
|
3474
3670
|
}
|
|
3671
|
+
function getVercelScriptNames(webDeploy, serverDeploy) {
|
|
3672
|
+
const deploy = webDeploy === "cloudflare" || serverDeploy === "cloudflare" ? `deploy:${webDeploy === "vercel" ? "web" : "server"}` : "deploy";
|
|
3673
|
+
return {
|
|
3674
|
+
setup: "deploy:setup",
|
|
3675
|
+
envPreview: "env:preview",
|
|
3676
|
+
envProduction: "env:production",
|
|
3677
|
+
deploy,
|
|
3678
|
+
deployProd: `${deploy}:prod`,
|
|
3679
|
+
deployCheck: "deploy:check"
|
|
3680
|
+
};
|
|
3681
|
+
}
|
|
3475
3682
|
//#endregion
|
|
3476
3683
|
//#region src/processors/runtime-deps.ts
|
|
3477
3684
|
function processRuntimeDeps(vfs, config) {
|
|
@@ -4219,7 +4426,7 @@ async function processExtrasTemplates(vfs, templates, config) {
|
|
|
4219
4426
|
].includes(f));
|
|
4220
4427
|
const hasNuxt = config.frontend.includes("nuxt");
|
|
4221
4428
|
if (config.packageManager === "pnpm") processSingleTemplate(vfs, templates, "extras/pnpm-workspace.yaml", "pnpm-workspace.yaml", config);
|
|
4222
|
-
if (config.packageManager === "bun") processSingleTemplate(vfs, templates, "extras/bunfig.toml", "bunfig.toml", config);
|
|
4429
|
+
if (config.packageManager === "bun" && hasNative) processSingleTemplate(vfs, templates, "extras/bunfig.toml", "bunfig.toml", config);
|
|
4223
4430
|
if (config.packageManager === "pnpm" && (hasNative || hasNuxt)) processSingleTemplate(vfs, templates, "extras/_npmrc", ".npmrc", config);
|
|
4224
4431
|
if (config.serverDeploy === "cloudflare" || config.backend === "self" && config.webDeploy === "cloudflare") processSingleTemplate(vfs, templates, "extras/env.d.ts", "packages/env/env.d.ts", config);
|
|
4225
4432
|
}
|
|
@@ -4229,7 +4436,8 @@ async function processDeployTemplates(vfs, templates, config) {
|
|
|
4229
4436
|
const isBackendSelf = config.backend === "self";
|
|
4230
4437
|
if (config.webDeploy === "cloudflare" || config.serverDeploy === "cloudflare") processTemplatesFromPrefix(vfs, templates, "packages/infra", "packages/infra", config);
|
|
4231
4438
|
if (config.webDeploy === "docker" || config.serverDeploy === "docker") processTemplatesFromPrefix(vfs, templates, "deploy/docker/compose", "", config);
|
|
4232
|
-
if (config.webDeploy
|
|
4439
|
+
if (config.webDeploy === "vercel" || config.serverDeploy === "vercel") processTemplatesFromPrefix(vfs, templates, "deploy/vercel", "", config);
|
|
4440
|
+
if (config.webDeploy !== "none" && config.webDeploy !== "cloudflare" && config.webDeploy !== "vercel") {
|
|
4233
4441
|
const templateMap = {
|
|
4234
4442
|
"tanstack-router": "react/tanstack-router",
|
|
4235
4443
|
"tanstack-start": "react/tanstack-start",
|
|
@@ -4242,7 +4450,7 @@ async function processDeployTemplates(vfs, templates, config) {
|
|
|
4242
4450
|
};
|
|
4243
4451
|
for (const f of config.frontend) if (templateMap[f]) processTemplatesFromPrefix(vfs, templates, `deploy/${config.webDeploy}/web/${templateMap[f]}`, "apps/web", config);
|
|
4244
4452
|
}
|
|
4245
|
-
if (config.serverDeploy !== "none" && config.serverDeploy !== "cloudflare" && !isBackendSelf) processTemplatesFromPrefix(vfs, templates, `deploy/${config.serverDeploy}/server`, "apps/server", config);
|
|
4453
|
+
if (config.serverDeploy !== "none" && config.serverDeploy !== "cloudflare" && config.serverDeploy !== "vercel" && !isBackendSelf) processTemplatesFromPrefix(vfs, templates, `deploy/${config.serverDeploy}/server`, "apps/server", config);
|
|
4246
4454
|
}
|
|
4247
4455
|
//#endregion
|
|
4248
4456
|
//#region src/utils/reproducible-command.ts
|
|
@@ -4330,6 +4538,7 @@ async function generate(options) {
|
|
|
4330
4538
|
processAlchemyPlugins(vfs, config);
|
|
4331
4539
|
processPwaPlugins(vfs, config);
|
|
4332
4540
|
processCatalogs(vfs, config);
|
|
4541
|
+
processVercelConfig(vfs, config);
|
|
4333
4542
|
processReadme(vfs, config);
|
|
4334
4543
|
if (options.version) {
|
|
4335
4544
|
const reproducibleCommand = generateReproducibleCommand(config);
|
|
@@ -4502,7 +4711,6 @@ export default {
|
|
|
4502
4711
|
},
|
|
4503
4712
|
"devDependencies": {
|
|
4504
4713
|
"@types/bun": "^1.3.14",
|
|
4505
|
-
"@types/three": "^0.165.0",
|
|
4506
4714
|
"concurrently": "^10.0.3",
|
|
4507
4715
|
"typescript": "^6"
|
|
4508
4716
|
}
|
|
@@ -5612,13 +5820,16 @@ import { RPCLink } from "@orpc/client/fetch";
|
|
|
5612
5820
|
|
|
5613
5821
|
{{#if (eq backend "self")}}
|
|
5614
5822
|
export const link = new RPCLink({
|
|
5615
|
-
|
|
5823
|
+
// Lazy: this module is imported during SSR where window does not exist
|
|
5824
|
+
url: () => \`\${window.location.origin}/rpc\`,
|
|
5616
5825
|
});
|
|
5617
5826
|
{{else}}
|
|
5618
5827
|
import { PUBLIC_SERVER_URL } from "astro:env/client";
|
|
5619
5828
|
|
|
5829
|
+
{{> getServerUrlSpaces}}
|
|
5830
|
+
|
|
5620
5831
|
export const link = new RPCLink({
|
|
5621
|
-
url: \`\${PUBLIC_SERVER_URL}/rpc\`,
|
|
5832
|
+
url: \`\${getServerUrl(PUBLIC_SERVER_URL)}/rpc\`,
|
|
5622
5833
|
{{#if (eq auth "better-auth")}}
|
|
5623
5834
|
fetch(url, options) {
|
|
5624
5835
|
return fetch(url, {
|
|
@@ -5638,11 +5849,25 @@ import { createORPCClient } from '@orpc/client'
|
|
|
5638
5849
|
import { RPCLink } from '@orpc/client/fetch'
|
|
5639
5850
|
import { createTanstackQueryUtils } from "@orpc/tanstack-query";
|
|
5640
5851
|
|
|
5852
|
+
function getServerUrl(url: string) {
|
|
5853
|
+
const normalized = url.endsWith("/") ? url.slice(0, -1) : url;
|
|
5854
|
+
|
|
5855
|
+
if (!normalized.startsWith("/")) {
|
|
5856
|
+
return normalized;
|
|
5857
|
+
}
|
|
5858
|
+
|
|
5859
|
+
if (import.meta.server) {
|
|
5860
|
+
return \`\${useRequestURL().origin}\${normalized}\`;
|
|
5861
|
+
}
|
|
5862
|
+
|
|
5863
|
+
return \`\${window.location.origin}\${normalized}\`;
|
|
5864
|
+
}
|
|
5865
|
+
|
|
5641
5866
|
export default defineNuxtPlugin(() => {
|
|
5642
5867
|
const config = useRuntimeConfig();
|
|
5643
5868
|
const serverUrl =
|
|
5644
5869
|
(import.meta.server && config.serverUrl) || config.public.serverUrl;
|
|
5645
|
-
const rpcUrl = \`\${serverUrl}/rpc\`;
|
|
5870
|
+
const rpcUrl = \`\${getServerUrl(serverUrl)}/rpc\`;
|
|
5646
5871
|
|
|
5647
5872
|
const rpcLink = new RPCLink({
|
|
5648
5873
|
url: rpcUrl,
|
|
@@ -5770,6 +5995,10 @@ export function createQueryClient() {
|
|
|
5770
5995
|
export const queryClient = createQueryClient();
|
|
5771
5996
|
{{/unless}}
|
|
5772
5997
|
|
|
5998
|
+
{{#unless (eq backend "self")}}
|
|
5999
|
+
{{> getServerUrl}}
|
|
6000
|
+
|
|
6001
|
+
{{/unless}}
|
|
5773
6002
|
{{#if (and (includes frontend "tanstack-start") (eq backend "self"))}}
|
|
5774
6003
|
const getORPCClient = createIsomorphicFn()
|
|
5775
6004
|
.server(() =>
|
|
@@ -5798,7 +6027,7 @@ const getORPCClient = createIsomorphicFn()
|
|
|
5798
6027
|
export const client: RouterClient<typeof appRouter> = getORPCClient();
|
|
5799
6028
|
{{else if (includes frontend "tanstack-start")}}
|
|
5800
6029
|
const link = new RPCLink({
|
|
5801
|
-
url: \`\${env.VITE_SERVER_URL}/rpc\`,
|
|
6030
|
+
url: \`\${getServerUrl(env.VITE_SERVER_URL)}/rpc\`,
|
|
5802
6031
|
{{#if (eq auth "clerk")}}
|
|
5803
6032
|
headers: async () => {
|
|
5804
6033
|
const token = await getClerkAuthToken();
|
|
@@ -5825,9 +6054,9 @@ export const link = new RPCLink({
|
|
|
5825
6054
|
{{#if (and (eq backend "self") (includes frontend "next"))}}
|
|
5826
6055
|
url: \`\${typeof window !== "undefined" ? window.location.origin : "http://localhost:3001"}/api/rpc\`,
|
|
5827
6056
|
{{else if (includes frontend "next")}}
|
|
5828
|
-
url: \`\${env.NEXT_PUBLIC_SERVER_URL}/rpc\`,
|
|
6057
|
+
url: \`\${getServerUrl(env.NEXT_PUBLIC_SERVER_URL)}/rpc\`,
|
|
5829
6058
|
{{else}}
|
|
5830
|
-
url: \`\${env.VITE_SERVER_URL}/rpc\`,
|
|
6059
|
+
url: \`\${getServerUrl(env.VITE_SERVER_URL)}/rpc\`,
|
|
5831
6060
|
{{/if}}
|
|
5832
6061
|
{{#if (eq auth "clerk")}}
|
|
5833
6062
|
headers: async () => {
|
|
@@ -5888,8 +6117,10 @@ export const queryClient = new QueryClient({
|
|
|
5888
6117
|
}),
|
|
5889
6118
|
});
|
|
5890
6119
|
|
|
6120
|
+
{{> getServerUrl}}
|
|
6121
|
+
|
|
5891
6122
|
export const link = new RPCLink({
|
|
5892
|
-
url: \`\${env.VITE_SERVER_URL}/rpc\`,
|
|
6123
|
+
url: \`\${getServerUrl(env.VITE_SERVER_URL)}/rpc\`,
|
|
5893
6124
|
{{#if (eq auth "better-auth")}}
|
|
5894
6125
|
fetch(url, options) {
|
|
5895
6126
|
return fetch(url, {
|
|
@@ -5921,6 +6152,10 @@ export const queryClient = new QueryClient({
|
|
|
5921
6152
|
}),
|
|
5922
6153
|
});
|
|
5923
6154
|
|
|
6155
|
+
{{#unless (eq backend "self")}}
|
|
6156
|
+
{{> getServerUrl}}
|
|
6157
|
+
|
|
6158
|
+
{{/unless}}
|
|
5924
6159
|
export const link = new RPCLink({
|
|
5925
6160
|
{{#if (eq backend "self")}}
|
|
5926
6161
|
url: () => {
|
|
@@ -5931,7 +6166,7 @@ export const link = new RPCLink({
|
|
|
5931
6166
|
return \`\${window.location.origin}/rpc\`;
|
|
5932
6167
|
},
|
|
5933
6168
|
{{else}}
|
|
5934
|
-
url: \`\${PUBLIC_SERVER_URL}/rpc\`,
|
|
6169
|
+
url: \`\${getServerUrl(PUBLIC_SERVER_URL)}/rpc\`,
|
|
5935
6170
|
{{/if}}
|
|
5936
6171
|
{{#if (eq auth "better-auth")}}
|
|
5937
6172
|
fetch(url, options) {
|
|
@@ -6457,6 +6692,8 @@ import type { AppRouter } from "@{{projectName}}/api/routers/index";
|
|
|
6457
6692
|
import { toast } from 'sonner';
|
|
6458
6693
|
{{#unless (eq backend "self")}}
|
|
6459
6694
|
import { env } from "@{{projectName}}/env/web";
|
|
6695
|
+
|
|
6696
|
+
{{> getServerUrl}}
|
|
6460
6697
|
{{/unless}}
|
|
6461
6698
|
{{#if (eq auth "clerk")}}
|
|
6462
6699
|
import { getClerkAuthToken } from "@/utils/clerk-auth";
|
|
@@ -6483,7 +6720,7 @@ const trpcClient = createTRPCClient<AppRouter>({
|
|
|
6483
6720
|
{{#if (eq backend "self")}}
|
|
6484
6721
|
url: "/api/trpc",
|
|
6485
6722
|
{{else}}
|
|
6486
|
-
url: \`\${env.NEXT_PUBLIC_SERVER_URL}/trpc\`,
|
|
6723
|
+
url: \`\${getServerUrl(env.NEXT_PUBLIC_SERVER_URL)}/trpc\`,
|
|
6487
6724
|
{{/if}}
|
|
6488
6725
|
{{#if (eq auth "clerk")}}
|
|
6489
6726
|
headers: async () => {
|
|
@@ -6534,6 +6771,8 @@ import { env } from "@{{projectName}}/env/web";
|
|
|
6534
6771
|
import { getClerkAuthToken } from "@/utils/clerk-auth";
|
|
6535
6772
|
{{/if}}
|
|
6536
6773
|
|
|
6774
|
+
{{> getServerUrl}}
|
|
6775
|
+
|
|
6537
6776
|
export const queryClient = new QueryClient({
|
|
6538
6777
|
queryCache: new QueryCache({
|
|
6539
6778
|
onError: (error, query) => {
|
|
@@ -6552,7 +6791,7 @@ export const queryClient = new QueryClient({
|
|
|
6552
6791
|
export const trpcClient = createTRPCClient<AppRouter>({
|
|
6553
6792
|
links: [
|
|
6554
6793
|
httpBatchLink({
|
|
6555
|
-
url: \`\${env.VITE_SERVER_URL}/trpc\`,
|
|
6794
|
+
url: \`\${getServerUrl(env.VITE_SERVER_URL)}/trpc\`,
|
|
6556
6795
|
{{#if (eq auth "clerk")}}
|
|
6557
6796
|
headers: async () => {
|
|
6558
6797
|
const token = await getClerkAuthToken();
|
|
@@ -13348,9 +13587,15 @@ import { polarClient } from "@polar-sh/better-auth/client";
|
|
|
13348
13587
|
import { PUBLIC_SERVER_URL } from "astro:env/client";
|
|
13349
13588
|
{{/if}}
|
|
13350
13589
|
|
|
13590
|
+
{{#if (ne backend "self")}}
|
|
13591
|
+
{{> getServerUrlSpaces}}
|
|
13592
|
+
|
|
13593
|
+
{{/if}}
|
|
13351
13594
|
export const authClient = createAuthClient({
|
|
13352
13595
|
{{#if (ne backend "self")}}
|
|
13353
|
-
|
|
13596
|
+
// better-auth derives its route-matching base from this URL's path, so the
|
|
13597
|
+
// public auth path must equal the server-side mount (/api/auth everywhere)
|
|
13598
|
+
baseURL: new URL("/api/auth", getServerUrl(PUBLIC_SERVER_URL)).toString(),
|
|
13354
13599
|
{{/if}}
|
|
13355
13600
|
{{#if (eq payments "polar")}}
|
|
13356
13601
|
plugins: [polarClient()],
|
|
@@ -13884,11 +14129,17 @@ import { polarClient } from "@polar-sh/better-auth/client";
|
|
|
13884
14129
|
export default defineNuxtPlugin(() => {
|
|
13885
14130
|
{{#if (ne backend "self")}}
|
|
13886
14131
|
const config = useRuntimeConfig();
|
|
14132
|
+
const rawServerUrl = (import.meta.server && config.serverUrl) || config.public.serverUrl;
|
|
14133
|
+
// Same-origin paths like /api need an absolute base, and better-auth derives
|
|
14134
|
+
// its route matching from this URL's path, so it must be exactly /api/auth
|
|
14135
|
+
const serverOrigin = rawServerUrl.startsWith("/")
|
|
14136
|
+
? (import.meta.server ? useRequestURL() : window.location).origin + rawServerUrl
|
|
14137
|
+
: rawServerUrl;
|
|
13887
14138
|
{{/if}}
|
|
13888
14139
|
|
|
13889
14140
|
const authClient = createAuthClient({
|
|
13890
14141
|
{{#if (ne backend "self")}}
|
|
13891
|
-
baseURL: (
|
|
14142
|
+
baseURL: new URL("/api/auth", serverOrigin).toString(),
|
|
13892
14143
|
{{/if}}
|
|
13893
14144
|
{{#if (eq payments "polar")}}
|
|
13894
14145
|
plugins: [polarClient()],
|
|
@@ -13908,11 +14159,15 @@ import { polarClient } from "@polar-sh/better-auth/client";
|
|
|
13908
14159
|
{{/if}}
|
|
13909
14160
|
{{#unless (eq backend "self")}}
|
|
13910
14161
|
import { env } from "@{{projectName}}/env/web";
|
|
14162
|
+
|
|
14163
|
+
{{> getServerUrl}}
|
|
13911
14164
|
{{/unless}}
|
|
13912
14165
|
|
|
13913
14166
|
export const authClient = createAuthClient({
|
|
13914
14167
|
{{#unless (eq backend "self")}}
|
|
13915
|
-
|
|
14168
|
+
// better-auth derives its route-matching base from this URL's path, so the
|
|
14169
|
+
// public auth path must equal the server-side mount (/api/auth everywhere)
|
|
14170
|
+
baseURL: new URL("/api/auth", getServerUrl(env.{{#if (includes frontend "next")}}NEXT_PUBLIC_SERVER_URL{{else}}VITE_SERVER_URL{{/if}})).toString(),
|
|
13916
14171
|
{{/unless}}
|
|
13917
14172
|
{{#if (eq payments "polar")}}
|
|
13918
14173
|
plugins: [polarClient()]
|
|
@@ -16206,8 +16461,12 @@ import { polarClient } from "@polar-sh/better-auth/client";
|
|
|
16206
16461
|
{{/if}}
|
|
16207
16462
|
import { env } from "@{{projectName}}/env/web";
|
|
16208
16463
|
|
|
16464
|
+
{{> getServerUrl}}
|
|
16465
|
+
|
|
16209
16466
|
export const authClient = createAuthClient({
|
|
16210
|
-
|
|
16467
|
+
// better-auth derives its route-matching base from this URL's path, so the
|
|
16468
|
+
// public auth path must equal the server-side mount (/api/auth everywhere)
|
|
16469
|
+
baseURL: new URL("/api/auth", getServerUrl(env.VITE_SERVER_URL)).toString(),
|
|
16211
16470
|
{{#if (eq payments "polar")}}
|
|
16212
16471
|
plugins: [polarClient()]
|
|
16213
16472
|
{{/if}}
|
|
@@ -16623,9 +16882,15 @@ import { createAuthClient } from "better-auth/svelte";
|
|
|
16623
16882
|
import { polarClient } from "@polar-sh/better-auth/client";
|
|
16624
16883
|
{{/if}}
|
|
16625
16884
|
|
|
16885
|
+
{{#unless (eq backend "self")}}
|
|
16886
|
+
{{> getServerUrl}}
|
|
16887
|
+
|
|
16888
|
+
{{/unless}}
|
|
16626
16889
|
export const authClient = createAuthClient({
|
|
16627
16890
|
{{#unless (eq backend "self")}}
|
|
16628
|
-
|
|
16891
|
+
// better-auth derives its route-matching base from this URL's path, so the
|
|
16892
|
+
// public auth path must equal the server-side mount (/api/auth everywhere)
|
|
16893
|
+
baseURL: new URL("/api/auth", getServerUrl(PUBLIC_SERVER_URL)).toString(),
|
|
16629
16894
|
{{/unless}}
|
|
16630
16895
|
{{#if (eq payments "polar")}}
|
|
16631
16896
|
plugins: [polarClient()]
|
|
@@ -16646,7 +16911,7 @@ export const authClient = createAuthClient({
|
|
|
16646
16911
|
const sessionQuery = authClient.useSession();
|
|
16647
16912
|
|
|
16648
16913
|
{{#if (eq api "orpc")}}
|
|
16649
|
-
const privateDataQuery = createQuery(orpc.privateData.queryOptions());
|
|
16914
|
+
const privateDataQuery = createQuery(() => orpc.privateData.queryOptions());
|
|
16650
16915
|
{{/if}}
|
|
16651
16916
|
|
|
16652
16917
|
$effect(() => {
|
|
@@ -16675,7 +16940,7 @@ export const authClient = createAuthClient({
|
|
|
16675
16940
|
<h1>Dashboard</h1>
|
|
16676
16941
|
<p>Welcome {$sessionQuery.data.user.name}</p>
|
|
16677
16942
|
{{#if (eq api "orpc")}}
|
|
16678
|
-
<p>API: {
|
|
16943
|
+
<p>API: {privateDataQuery.data?.message}</p>
|
|
16679
16944
|
{{/if}}
|
|
16680
16945
|
{{#if (eq payments "polar")}}
|
|
16681
16946
|
<p>Plan: {customerState?.activeSubscriptions?.length > 0 ? "Pro" : "Free"}</p>
|
|
@@ -18651,11 +18916,7 @@ const apiHandler = new OpenAPIHandler(appRouter, {
|
|
|
18651
18916
|
});
|
|
18652
18917
|
{{/if}}
|
|
18653
18918
|
|
|
18654
|
-
{{#if (eq runtime "node")}}
|
|
18655
|
-
new Elysia({ adapter: node() })
|
|
18656
|
-
{{else}}
|
|
18657
|
-
new Elysia()
|
|
18658
|
-
{{/if}}
|
|
18919
|
+
const app = {{#if (eq runtime "node")}}new Elysia({ adapter: node() }){{else}}new Elysia(){{/if}}
|
|
18659
18920
|
.use(
|
|
18660
18921
|
cors({
|
|
18661
18922
|
origin: env.CORS_ORIGIN,
|
|
@@ -18761,9 +19022,22 @@ new Elysia()
|
|
|
18761
19022
|
})
|
|
18762
19023
|
{{/if}}
|
|
18763
19024
|
.get("/", () => "OK")
|
|
19025
|
+
{{#if (eq serverDeploy "vercel")}};
|
|
19026
|
+
|
|
19027
|
+
export default app;
|
|
19028
|
+
|
|
19029
|
+
// Elysia's default export is not auto-served by Bun or Node, so start a local
|
|
19030
|
+
// server outside Vercel while still exporting the app for Vercel functions.
|
|
19031
|
+
if (!process.env.VERCEL) {
|
|
19032
|
+
app.listen(3000, () => {
|
|
19033
|
+
console.log("Server is running on http://localhost:3000");
|
|
19034
|
+
});
|
|
19035
|
+
}
|
|
19036
|
+
{{else}}
|
|
18764
19037
|
.listen(3000, () => {
|
|
18765
19038
|
console.log("Server is running on http://localhost:3000");
|
|
18766
19039
|
});
|
|
19040
|
+
{{/if}}
|
|
18767
19041
|
`],
|
|
18768
19042
|
["backend/server/express/src/index.ts.hbs", `import { env } from "@{{projectName}}/env/server";
|
|
18769
19043
|
{{#if (eq api "trpc")}}
|
|
@@ -19334,15 +19608,23 @@ app.get("/", (c) => {
|
|
|
19334
19608
|
{{#if (eq runtime "node")}}
|
|
19335
19609
|
import { serve } from "@hono/node-server";
|
|
19336
19610
|
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
(
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19611
|
+
{{#if (eq serverDeploy "vercel")}}
|
|
19612
|
+
export default app;
|
|
19613
|
+
|
|
19614
|
+
if (!process.env.VERCEL) {
|
|
19615
|
+
{{/if}}
|
|
19616
|
+
serve(
|
|
19617
|
+
{
|
|
19618
|
+
fetch: app.fetch,
|
|
19619
|
+
port: 3000,
|
|
19620
|
+
},
|
|
19621
|
+
(info) => {
|
|
19622
|
+
console.log(\`Server is running on http://localhost:\${info.port}\`);
|
|
19623
|
+
}
|
|
19624
|
+
);
|
|
19625
|
+
{{#if (eq serverDeploy "vercel")}}
|
|
19626
|
+
}
|
|
19627
|
+
{{/if}}
|
|
19346
19628
|
{{else}}
|
|
19347
19629
|
{{#if (eq runtime "bun")}}
|
|
19348
19630
|
export default app;
|
|
@@ -19396,6 +19678,7 @@ lerna-debug.log*
|
|
|
19396
19678
|
|
|
19397
19679
|
# Better-T-Stack
|
|
19398
19680
|
.alchemy
|
|
19681
|
+
.vercel
|
|
19399
19682
|
|
|
19400
19683
|
# Testing
|
|
19401
19684
|
coverage
|
|
@@ -19426,7 +19709,7 @@ temp
|
|
|
19426
19709
|
|
|
19427
19710
|
services:
|
|
19428
19711
|
mongodb:
|
|
19429
|
-
image: mongo
|
|
19712
|
+
image: mongo:8
|
|
19430
19713
|
container_name: {{projectName}}-mongodb
|
|
19431
19714
|
environment:
|
|
19432
19715
|
MONGO_INITDB_ROOT_USERNAME: root
|
|
@@ -19449,7 +19732,7 @@ volumes:
|
|
|
19449
19732
|
|
|
19450
19733
|
services:
|
|
19451
19734
|
mysql:
|
|
19452
|
-
image: mysql
|
|
19735
|
+
image: mysql:8.4
|
|
19453
19736
|
container_name: {{projectName}}-mysql
|
|
19454
19737
|
environment:
|
|
19455
19738
|
MYSQL_ROOT_PASSWORD: password
|
|
@@ -19473,7 +19756,7 @@ volumes:
|
|
|
19473
19756
|
|
|
19474
19757
|
services:
|
|
19475
19758
|
postgres:
|
|
19476
|
-
image: postgres
|
|
19759
|
+
image: postgres:18
|
|
19477
19760
|
container_name: {{projectName}}-postgres
|
|
19478
19761
|
environment:
|
|
19479
19762
|
POSTGRES_DB: {{projectName}}
|
|
@@ -20257,15 +20540,15 @@ services:
|
|
|
20257
20540
|
{{#if (includes frontend "next")}}NEXT_PUBLIC_SERVER_URL{{else if (or (includes frontend "svelte") (includes frontend "astro"))}}PUBLIC_SERVER_URL{{else}}VITE_SERVER_URL{{/if}}: http://localhost:3000
|
|
20258
20541
|
{{/if}}
|
|
20259
20542
|
{{#if (eq backend "convex")}}
|
|
20260
|
-
{{#if (includes frontend "next")}}NEXT_PUBLIC_CONVEX_URL{{else if (or (includes frontend "svelte") (includes frontend "astro"))}}PUBLIC_CONVEX_URL{{else}}VITE_CONVEX_URL{{/if}}
|
|
20543
|
+
{{#if (includes frontend "next")}}NEXT_PUBLIC_CONVEX_URL: \${NEXT_PUBLIC_CONVEX_URL:-}{{else if (or (includes frontend "svelte") (includes frontend "astro"))}}PUBLIC_CONVEX_URL: \${PUBLIC_CONVEX_URL:-}{{else}}VITE_CONVEX_URL: \${VITE_CONVEX_URL:-}{{/if}}
|
|
20261
20544
|
{{/if}}
|
|
20262
20545
|
{{#if (and (eq auth "clerk") (or (includes frontend "next") (includes frontend "react-router") (includes frontend "tanstack-router") (includes frontend "tanstack-start")))}}
|
|
20263
|
-
{{#if (includes frontend "next")}}NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY{{else}}VITE_CLERK_PUBLISHABLE_KEY{{/if}}
|
|
20546
|
+
{{#if (includes frontend "next")}}NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: \${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:-}{{else}}VITE_CLERK_PUBLISHABLE_KEY: \${VITE_CLERK_PUBLISHABLE_KEY:-}{{/if}}
|
|
20264
20547
|
{{/if}}
|
|
20265
20548
|
{{/if}}
|
|
20266
20549
|
init: true
|
|
20267
20550
|
ports:
|
|
20268
|
-
{{#if (or (includes frontend "tanstack-router") (includes frontend "
|
|
20551
|
+
{{#if (or (includes frontend "tanstack-router") (includes frontend "solid"))}}
|
|
20269
20552
|
- "3001:80"
|
|
20270
20553
|
{{else}}
|
|
20271
20554
|
- "3001:3001"
|
|
@@ -20311,6 +20594,22 @@ services:
|
|
|
20311
20594
|
condition: service_healthy
|
|
20312
20595
|
{{/if}}
|
|
20313
20596
|
{{/if}}
|
|
20597
|
+
healthcheck:
|
|
20598
|
+
{{#if (or (includes frontend "tanstack-router") (includes frontend "solid"))}}
|
|
20599
|
+
test: ["CMD", "wget", "-q", "--spider", "http://localhost:80/"]
|
|
20600
|
+
{{else}}
|
|
20601
|
+
test:
|
|
20602
|
+
[
|
|
20603
|
+
"CMD",
|
|
20604
|
+
"node",
|
|
20605
|
+
"-e",
|
|
20606
|
+
"fetch('http://localhost:3001/').then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))",
|
|
20607
|
+
]
|
|
20608
|
+
{{/if}}
|
|
20609
|
+
interval: 10s
|
|
20610
|
+
timeout: 5s
|
|
20611
|
+
retries: 5
|
|
20612
|
+
start_period: 10s
|
|
20314
20613
|
restart: unless-stopped
|
|
20315
20614
|
|
|
20316
20615
|
{{/if}}
|
|
@@ -20363,7 +20662,7 @@ services:
|
|
|
20363
20662
|
{{#if (eq dbSetup "docker")}}
|
|
20364
20663
|
{{#if (eq database "postgres")}}
|
|
20365
20664
|
postgres:
|
|
20366
|
-
image: postgres
|
|
20665
|
+
image: postgres:18
|
|
20367
20666
|
container_name: {{projectName}}-postgres
|
|
20368
20667
|
environment:
|
|
20369
20668
|
POSTGRES_DB: {{projectName}}
|
|
@@ -20382,7 +20681,7 @@ services:
|
|
|
20382
20681
|
{{/if}}
|
|
20383
20682
|
{{#if (eq database "mysql")}}
|
|
20384
20683
|
mysql:
|
|
20385
|
-
image: mysql
|
|
20684
|
+
image: mysql:8.4
|
|
20386
20685
|
container_name: {{projectName}}-mysql
|
|
20387
20686
|
environment:
|
|
20388
20687
|
MYSQL_ROOT_PASSWORD: \${MYSQL_ROOT_PASSWORD:-password}
|
|
@@ -20402,7 +20701,7 @@ services:
|
|
|
20402
20701
|
{{/if}}
|
|
20403
20702
|
{{#if (eq database "mongodb")}}
|
|
20404
20703
|
mongodb:
|
|
20405
|
-
image: mongo
|
|
20704
|
+
image: mongo:8
|
|
20406
20705
|
container_name: {{projectName}}-mongodb
|
|
20407
20706
|
environment:
|
|
20408
20707
|
MONGO_INITDB_ROOT_USERNAME: root
|
|
@@ -20429,7 +20728,7 @@ volumes:
|
|
|
20429
20728
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20430
20729
|
{{/if}}
|
|
20431
20730
|
{{#if (eq packageManager "pnpm")}}
|
|
20432
|
-
RUN npm install -g pnpm
|
|
20731
|
+
RUN npm install -g pnpm@11
|
|
20433
20732
|
{{/if}}
|
|
20434
20733
|
WORKDIR /app
|
|
20435
20734
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20468,7 +20767,7 @@ CMD ["node", "dist/index.mjs"]
|
|
|
20468
20767
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20469
20768
|
{{/if}}
|
|
20470
20769
|
{{#if (eq packageManager "pnpm")}}
|
|
20471
|
-
RUN npm install -g pnpm
|
|
20770
|
+
RUN npm install -g pnpm@11
|
|
20472
20771
|
{{/if}}
|
|
20473
20772
|
WORKDIR /app
|
|
20474
20773
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20520,7 +20819,7 @@ CMD ["node", "dist/server/entry.mjs"]
|
|
|
20520
20819
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20521
20820
|
{{/if}}
|
|
20522
20821
|
{{#if (eq packageManager "pnpm")}}
|
|
20523
|
-
RUN npm install -g pnpm
|
|
20822
|
+
RUN npm install -g pnpm@11
|
|
20524
20823
|
{{/if}}
|
|
20525
20824
|
WORKDIR /app
|
|
20526
20825
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20562,7 +20861,7 @@ CMD ["node", "server/index.mjs"]
|
|
|
20562
20861
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20563
20862
|
{{/if}}
|
|
20564
20863
|
{{#if (eq packageManager "pnpm")}}
|
|
20565
|
-
RUN npm install -g pnpm
|
|
20864
|
+
RUN npm install -g pnpm@11
|
|
20566
20865
|
{{/if}}
|
|
20567
20866
|
WORKDIR /app
|
|
20568
20867
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20598,6 +20897,8 @@ ENV NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=\${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
|
|
|
20598
20897
|
{{/if}}
|
|
20599
20898
|
ENV NODE_ENV=production
|
|
20600
20899
|
RUN cd apps/web && {{packageManager}} run build
|
|
20900
|
+
# standalone output excludes public/; ensure it exists so the runner copy never fails
|
|
20901
|
+
RUN mkdir -p apps/web/public
|
|
20601
20902
|
|
|
20602
20903
|
FROM node:24-slim AS runner
|
|
20603
20904
|
WORKDIR /app
|
|
@@ -20605,6 +20906,7 @@ ENV NODE_ENV=production
|
|
|
20605
20906
|
|
|
20606
20907
|
COPY --from=builder /app/apps/web/.next/standalone ./
|
|
20607
20908
|
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
|
|
20909
|
+
COPY --from=builder /app/apps/web/public ./apps/web/public
|
|
20608
20910
|
|
|
20609
20911
|
ENV HOSTNAME=0.0.0.0
|
|
20610
20912
|
ENV PORT=3001
|
|
@@ -20617,7 +20919,7 @@ CMD ["node", "apps/web/server.js"]
|
|
|
20617
20919
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20618
20920
|
{{/if}}
|
|
20619
20921
|
{{#if (eq packageManager "pnpm")}}
|
|
20620
|
-
RUN npm install -g pnpm
|
|
20922
|
+
RUN npm install -g pnpm@11
|
|
20621
20923
|
{{/if}}
|
|
20622
20924
|
WORKDIR /app
|
|
20623
20925
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20654,37 +20956,21 @@ ENV VITE_CLERK_PUBLISHABLE_KEY=\${VITE_CLERK_PUBLISHABLE_KEY}
|
|
|
20654
20956
|
ENV NODE_ENV=production
|
|
20655
20957
|
RUN cd apps/web && {{packageManager}} run build
|
|
20656
20958
|
|
|
20657
|
-
FROM
|
|
20658
|
-
|
|
20659
|
-
COPY
|
|
20660
|
-
|
|
20661
|
-
|
|
20662
|
-
|
|
20663
|
-
|
|
20664
|
-
|
|
20665
|
-
server_name _;
|
|
20666
|
-
root /usr/share/nginx/html;
|
|
20667
|
-
index index.html;
|
|
20668
|
-
|
|
20669
|
-
gzip on;
|
|
20670
|
-
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
|
|
20671
|
-
|
|
20672
|
-
location /assets/ {
|
|
20673
|
-
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
20674
|
-
}
|
|
20675
|
-
|
|
20676
|
-
# SPA fallback
|
|
20677
|
-
location / {
|
|
20678
|
-
try_files $uri $uri/ /index.html;
|
|
20679
|
-
}
|
|
20680
|
-
}
|
|
20959
|
+
FROM node:24-slim AS runner
|
|
20960
|
+
WORKDIR /app
|
|
20961
|
+
COPY --from=builder /app .
|
|
20962
|
+
ENV NODE_ENV=production
|
|
20963
|
+
ENV PORT=3001
|
|
20964
|
+
ENV HOST=0.0.0.0
|
|
20965
|
+
EXPOSE 3001
|
|
20966
|
+
CMD ["sh", "-c", "cd apps/web && npm run start"]
|
|
20681
20967
|
`],
|
|
20682
20968
|
["deploy/docker/web/react/tanstack-router/Dockerfile.hbs", `FROM node:24{{#unless (includes addons "vite-plus")}}-slim{{/unless}} AS builder
|
|
20683
20969
|
{{#if (eq packageManager "bun")}}
|
|
20684
20970
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20685
20971
|
{{/if}}
|
|
20686
20972
|
{{#if (eq packageManager "pnpm")}}
|
|
20687
|
-
RUN npm install -g pnpm
|
|
20973
|
+
RUN npm install -g pnpm@11
|
|
20688
20974
|
{{/if}}
|
|
20689
20975
|
WORKDIR /app
|
|
20690
20976
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20751,7 +21037,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
|
|
20751
21037
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20752
21038
|
{{/if}}
|
|
20753
21039
|
{{#if (eq packageManager "pnpm")}}
|
|
20754
|
-
RUN npm install -g pnpm
|
|
21040
|
+
RUN npm install -g pnpm@11
|
|
20755
21041
|
{{/if}}
|
|
20756
21042
|
WORKDIR /app
|
|
20757
21043
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20808,7 +21094,7 @@ CMD ["node", ".output/server/index.mjs"]
|
|
|
20808
21094
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20809
21095
|
{{/if}}
|
|
20810
21096
|
{{#if (eq packageManager "pnpm")}}
|
|
20811
|
-
RUN npm install -g pnpm
|
|
21097
|
+
RUN npm install -g pnpm@11
|
|
20812
21098
|
{{/if}}
|
|
20813
21099
|
WORKDIR /app
|
|
20814
21100
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20871,7 +21157,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
|
|
20871
21157
|
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20872
21158
|
{{/if}}
|
|
20873
21159
|
{{#if (eq packageManager "pnpm")}}
|
|
20874
|
-
RUN npm install -g pnpm
|
|
21160
|
+
RUN npm install -g pnpm@11
|
|
20875
21161
|
{{/if}}
|
|
20876
21162
|
WORKDIR /app
|
|
20877
21163
|
ENV SKIP_ENV_VALIDATION=1
|
|
@@ -20917,6 +21203,143 @@ EXPOSE 3001
|
|
|
20917
21203
|
|
|
20918
21204
|
WORKDIR /app/apps/web
|
|
20919
21205
|
CMD ["node", "build/index.js"]
|
|
21206
|
+
`],
|
|
21207
|
+
["deploy/vercel/_vercelignore", `# Local env files must never ship in deployments: Vercel project env vars are
|
|
21208
|
+
# the source of truth (bun env:vercel:*), and frameworks like Next.js would
|
|
21209
|
+
# otherwise load these localhost values at runtime.
|
|
21210
|
+
.env
|
|
21211
|
+
.env.*
|
|
21212
|
+
**/.env
|
|
21213
|
+
**/.env.*
|
|
21214
|
+
!**/.env.example
|
|
21215
|
+
local.db
|
|
21216
|
+
local.db-*
|
|
21217
|
+
.alchemy/
|
|
21218
|
+
`],
|
|
21219
|
+
["deploy/vercel/scripts/sync-vercel-env.ts.hbs", `import { spawnSync } from "node:child_process";
|
|
21220
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
21221
|
+
import dotenv from "dotenv";
|
|
21222
|
+
|
|
21223
|
+
const DEFAULT_ENVIRONMENT = "preview";
|
|
21224
|
+
const VALID_ENVIRONMENTS = new Set(["development", "preview", "production"]);
|
|
21225
|
+
const VERCEL_COMMAND = [{{#if (eq packageManager "npm")}}"npx", "vercel"{{else if (eq packageManager "pnpm")}}"pnpm", "exec", "vercel"{{else}}"bunx", "vercel"{{/if}}] as const;
|
|
21226
|
+
const DEFAULT_FILES = [
|
|
21227
|
+
{{#if (eq webDeploy "vercel")}}
|
|
21228
|
+
"apps/web/.env",
|
|
21229
|
+
{{/if}}
|
|
21230
|
+
{{#if (and (eq serverDeploy "vercel") (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
21231
|
+
"apps/server/.env",
|
|
21232
|
+
{{/if}}
|
|
21233
|
+
];
|
|
21234
|
+
const SKIP_KEYS = new Set([
|
|
21235
|
+
{{#if (or (and (eq webDeploy "vercel") (eq serverDeploy "vercel") (ne backend "self") (ne backend "none") (ne backend "convex")) (and (eq webDeploy "vercel") (eq backend "self")))}}
|
|
21236
|
+
"BETTER_AUTH_URL",
|
|
21237
|
+
"CORS_ORIGIN",
|
|
21238
|
+
"NODE_ENV",
|
|
21239
|
+
{{/if}}
|
|
21240
|
+
]);
|
|
21241
|
+
const OVERRIDE_KEYS = new Map([
|
|
21242
|
+
{{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel") (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
21243
|
+
["NEXT_PUBLIC_SERVER_URL", "/api"],
|
|
21244
|
+
["NUXT_PUBLIC_SERVER_URL", "/api"],
|
|
21245
|
+
["PUBLIC_SERVER_URL", "/api"],
|
|
21246
|
+
["VITE_SERVER_URL", "/api"],
|
|
21247
|
+
{{/if}}
|
|
21248
|
+
]);
|
|
21249
|
+
|
|
21250
|
+
const args = process.argv.slice(2);
|
|
21251
|
+
const separatorIndex = args.indexOf("--");
|
|
21252
|
+
const scriptArgs = separatorIndex === -1 ? args : args.slice(0, separatorIndex);
|
|
21253
|
+
const forwardedArgs = separatorIndex === -1 ? [] : args.slice(separatorIndex + 1);
|
|
21254
|
+
|
|
21255
|
+
const environment =
|
|
21256
|
+
scriptArgs[0] && VALID_ENVIRONMENTS.has(scriptArgs[0]) ? scriptArgs[0] : DEFAULT_ENVIRONMENT;
|
|
21257
|
+
const remainingArgs = scriptArgs.slice(VALID_ENVIRONMENTS.has(scriptArgs[0] ?? "") ? 1 : 0);
|
|
21258
|
+
// Split remaining args into env-file paths and passthrough Vercel CLI flags.
|
|
21259
|
+
// A bare token counts as a file only when it exists on disk, so flags and their
|
|
21260
|
+
// values (e.g. \`--scope my-team\`) forward correctly regardless of argument order.
|
|
21261
|
+
const files: string[] = [];
|
|
21262
|
+
const passthroughArgs: string[] = [];
|
|
21263
|
+
for (const arg of remainingArgs) {
|
|
21264
|
+
if (!arg.startsWith("-") && existsSync(arg)) {
|
|
21265
|
+
files.push(arg);
|
|
21266
|
+
} else {
|
|
21267
|
+
passthroughArgs.push(arg);
|
|
21268
|
+
}
|
|
21269
|
+
}
|
|
21270
|
+
const vercelArgs = [...passthroughArgs, ...forwardedArgs];
|
|
21271
|
+
const envFiles = files.length > 0 ? files : DEFAULT_FILES;
|
|
21272
|
+
|
|
21273
|
+
if (envFiles.length === 0) {
|
|
21274
|
+
console.log("No env files configured for this Vercel stack.");
|
|
21275
|
+
process.exit(0);
|
|
21276
|
+
}
|
|
21277
|
+
|
|
21278
|
+
const env = new Map<string, string>();
|
|
21279
|
+
|
|
21280
|
+
for (const file of envFiles) {
|
|
21281
|
+
if (!existsSync(file)) {
|
|
21282
|
+
console.warn(\`Skipping missing env file: \${file}\`);
|
|
21283
|
+
continue;
|
|
21284
|
+
}
|
|
21285
|
+
|
|
21286
|
+
for (const [key, value] of Object.entries(dotenv.parse(readFileSync(file, "utf8")))) {
|
|
21287
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
21288
|
+
env.set(key, OVERRIDE_KEYS.get(key) ?? value);
|
|
21289
|
+
}
|
|
21290
|
+
}
|
|
21291
|
+
|
|
21292
|
+
if (env.size === 0) {
|
|
21293
|
+
console.log("No Vercel env vars found to sync.");
|
|
21294
|
+
process.exit(0);
|
|
21295
|
+
}
|
|
21296
|
+
|
|
21297
|
+
const LOCAL_VALUE_PATTERN = /localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|^file:/i;
|
|
21298
|
+
const localKeys = [...env.entries()]
|
|
21299
|
+
.filter(([, value]) => LOCAL_VALUE_PATTERN.test(value))
|
|
21300
|
+
.map(([key]) => key);
|
|
21301
|
+
if (localKeys.length > 0) {
|
|
21302
|
+
console.warn(
|
|
21303
|
+
\`Warning: \${localKeys.join(", ")} look\${localKeys.length === 1 ? "s" : ""} like local-only value(s). Update them in your .env file(s) and re-run this sync if your deployed app should not point at local endpoints.\`,
|
|
21304
|
+
);
|
|
21305
|
+
}
|
|
21306
|
+
|
|
21307
|
+
console.log(\`Syncing \${env.size} env var(s) to Vercel \${environment}.\`);
|
|
21308
|
+
for (const [key, value] of env.entries()) {
|
|
21309
|
+
const result = spawnSync(
|
|
21310
|
+
VERCEL_COMMAND[0],
|
|
21311
|
+
[
|
|
21312
|
+
...VERCEL_COMMAND.slice(1),
|
|
21313
|
+
"env",
|
|
21314
|
+
"add",
|
|
21315
|
+
key,
|
|
21316
|
+
environment,
|
|
21317
|
+
"--force",
|
|
21318
|
+
"--yes",
|
|
21319
|
+
"--non-interactive",
|
|
21320
|
+
...vercelArgs,
|
|
21321
|
+
],
|
|
21322
|
+
{
|
|
21323
|
+
input: \`\${value}\\n\`,
|
|
21324
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
21325
|
+
encoding: "utf8",
|
|
21326
|
+
// Windows resolves bunx/npx/pnpm via .cmd shims, which need a shell
|
|
21327
|
+
shell: process.platform === "win32",
|
|
21328
|
+
},
|
|
21329
|
+
);
|
|
21330
|
+
|
|
21331
|
+
if (result.error) {
|
|
21332
|
+
console.error(\`Failed to sync \${key}: \${result.error.message}\`);
|
|
21333
|
+
process.exit(1);
|
|
21334
|
+
}
|
|
21335
|
+
|
|
21336
|
+
if (result.status !== 0) {
|
|
21337
|
+
console.error(\`Failed to sync \${key}\`);
|
|
21338
|
+
process.exit(result.status ?? 1);
|
|
21339
|
+
}
|
|
21340
|
+
}
|
|
21341
|
+
|
|
21342
|
+
console.log("Vercel env sync complete. Redeploy for changes to take effect.");
|
|
20920
21343
|
`],
|
|
20921
21344
|
["examples/ai/convex/packages/backend/convex/agent.ts.hbs", `import { Agent } from "@convex-dev/agent";
|
|
20922
21345
|
import { google } from "@ai-sdk/google";
|
|
@@ -29460,12 +29883,12 @@ function TodosRoute() {
|
|
|
29460
29883
|
let newTodoText = $state('');
|
|
29461
29884
|
|
|
29462
29885
|
{{#if (eq api "orpc")}}
|
|
29463
|
-
const todosQuery = createQuery(orpc.todo.getAll.queryOptions());
|
|
29886
|
+
const todosQuery = createQuery(() => orpc.todo.getAll.queryOptions());
|
|
29464
29887
|
|
|
29465
|
-
const addMutation = createMutation(
|
|
29888
|
+
const addMutation = createMutation(() =>
|
|
29466
29889
|
orpc.todo.create.mutationOptions({
|
|
29467
29890
|
onSuccess: () => {
|
|
29468
|
-
|
|
29891
|
+
todosQuery.refetch();
|
|
29469
29892
|
newTodoText = '';
|
|
29470
29893
|
},
|
|
29471
29894
|
onError: (error) => {
|
|
@@ -29474,10 +29897,10 @@ function TodosRoute() {
|
|
|
29474
29897
|
})
|
|
29475
29898
|
);
|
|
29476
29899
|
|
|
29477
|
-
const toggleMutation = createMutation(
|
|
29900
|
+
const toggleMutation = createMutation(() =>
|
|
29478
29901
|
orpc.todo.toggle.mutationOptions({
|
|
29479
29902
|
onSuccess: () => {
|
|
29480
|
-
|
|
29903
|
+
todosQuery.refetch();
|
|
29481
29904
|
},
|
|
29482
29905
|
onError: (error) => {
|
|
29483
29906
|
console.error('Failed to toggle todo:', error?.message ?? error);
|
|
@@ -29485,10 +29908,10 @@ function TodosRoute() {
|
|
|
29485
29908
|
})
|
|
29486
29909
|
);
|
|
29487
29910
|
|
|
29488
|
-
const deleteMutation = createMutation(
|
|
29911
|
+
const deleteMutation = createMutation(() =>
|
|
29489
29912
|
orpc.todo.delete.mutationOptions({
|
|
29490
29913
|
onSuccess: () => {
|
|
29491
|
-
|
|
29914
|
+
todosQuery.refetch();
|
|
29492
29915
|
},
|
|
29493
29916
|
onError: (error) => {
|
|
29494
29917
|
console.error('Failed to delete todo:', error?.message ?? error);
|
|
@@ -29501,22 +29924,22 @@ function TodosRoute() {
|
|
|
29501
29924
|
event.preventDefault();
|
|
29502
29925
|
const text = newTodoText.trim();
|
|
29503
29926
|
if (text) {
|
|
29504
|
-
|
|
29927
|
+
addMutation.mutate({ text });
|
|
29505
29928
|
}
|
|
29506
29929
|
}
|
|
29507
29930
|
|
|
29508
29931
|
function handleToggleTodo(id: number, completed: boolean) {
|
|
29509
|
-
|
|
29932
|
+
toggleMutation.mutate({ id, completed: !completed });
|
|
29510
29933
|
}
|
|
29511
29934
|
|
|
29512
29935
|
function handleDeleteTodo(id: number) {
|
|
29513
|
-
|
|
29936
|
+
deleteMutation.mutate({ id });
|
|
29514
29937
|
}
|
|
29515
29938
|
|
|
29516
|
-
const isAdding = $derived(
|
|
29939
|
+
const isAdding = $derived(addMutation.isPending);
|
|
29517
29940
|
const canAdd = $derived(!isAdding && newTodoText.trim().length > 0);
|
|
29518
|
-
const isLoadingTodos = $derived(
|
|
29519
|
-
const todos = $derived(
|
|
29941
|
+
const isLoadingTodos = $derived(todosQuery.isLoading);
|
|
29942
|
+
const todos = $derived(todosQuery.data ?? []);
|
|
29520
29943
|
const hasTodos = $derived(todos.length > 0);
|
|
29521
29944
|
|
|
29522
29945
|
<\/script>
|
|
@@ -29548,8 +29971,8 @@ function TodosRoute() {
|
|
|
29548
29971
|
{:else}
|
|
29549
29972
|
<ul class="space-y-1">
|
|
29550
29973
|
{#each todos as todo (todo.id)}
|
|
29551
|
-
{@const isToggling =
|
|
29552
|
-
{@const isDeleting =
|
|
29974
|
+
{@const isToggling = toggleMutation.isPending && toggleMutation.variables?.id === todo.id}
|
|
29975
|
+
{@const isDeleting = deleteMutation.isPending && deleteMutation.variables?.id === todo.id}
|
|
29553
29976
|
{@const isDisabled = isToggling || isDeleting}
|
|
29554
29977
|
<li
|
|
29555
29978
|
class="flex items-center justify-between p-2 "
|
|
@@ -29584,24 +30007,24 @@ function TodosRoute() {
|
|
|
29584
30007
|
</ul>
|
|
29585
30008
|
{/if}
|
|
29586
30009
|
|
|
29587
|
-
{#if
|
|
30010
|
+
{#if todosQuery.isError}
|
|
29588
30011
|
<p class="mt-4 text-red-500">
|
|
29589
|
-
Error loading: {
|
|
30012
|
+
Error loading: {todosQuery.error?.message ?? 'Unknown error'}
|
|
29590
30013
|
</p>
|
|
29591
30014
|
{/if}
|
|
29592
|
-
{#if
|
|
30015
|
+
{#if addMutation.isError}
|
|
29593
30016
|
<p class="mt-4 text-red-500">
|
|
29594
|
-
Error adding: {
|
|
30017
|
+
Error adding: {addMutation.error?.message ?? 'Unknown error'}
|
|
29595
30018
|
</p>
|
|
29596
30019
|
{/if}
|
|
29597
|
-
{#if
|
|
30020
|
+
{#if toggleMutation.isError}
|
|
29598
30021
|
<p class="mt-4 text-red-500">
|
|
29599
|
-
Error updating: {
|
|
30022
|
+
Error updating: {toggleMutation.error?.message ?? 'Unknown error'}
|
|
29600
30023
|
</p>
|
|
29601
30024
|
{/if}
|
|
29602
|
-
{#if
|
|
30025
|
+
{#if deleteMutation.isError}
|
|
29603
30026
|
<p class="mt-4 text-red-500">
|
|
29604
|
-
Error deleting: {
|
|
30027
|
+
Error deleting: {deleteMutation.error?.message ?? 'Unknown error'}
|
|
29605
30028
|
</p>
|
|
29606
30029
|
{/if}
|
|
29607
30030
|
</div>
|
|
@@ -29613,14 +30036,7 @@ shamefully-hoist=true
|
|
|
29613
30036
|
strict-peer-dependencies=false
|
|
29614
30037
|
{{/if}}`],
|
|
29615
30038
|
["extras/bunfig.toml.hbs", `[install]
|
|
29616
|
-
{{#if (includes frontend "nuxt")}}
|
|
29617
|
-
linker = "hoisted" # Nuxt needs hoisting for its dependency resolver
|
|
29618
|
-
{{else}}
|
|
29619
|
-
linker = "isolated"
|
|
29620
|
-
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
29621
30039
|
peer = false # Expo native projects declare SDK peers explicitly; this keeps Bun isolated installs deduped for native modules
|
|
29622
|
-
{{/if}}
|
|
29623
|
-
{{/if}}
|
|
29624
30040
|
`],
|
|
29625
30041
|
["extras/env.d.ts.hbs", `{{#if (eq serverDeploy "cloudflare")}}
|
|
29626
30042
|
import { type server } from "@{{projectName}}/infra/alchemy.run";
|
|
@@ -29646,19 +30062,19 @@ declare module "cloudflare:workers" {
|
|
|
29646
30062
|
["extras/pnpm-workspace.yaml.hbs", `packages:
|
|
29647
30063
|
- "apps/*"
|
|
29648
30064
|
- "packages/*"
|
|
29649
|
-
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (eq serverDeploy "docker") (eq orm "prisma") (includes addons "lefthook") (includes addons "nx") (includes addons "pwa") (includes addons "turborepo") (includes addons "vite-plus") (includes frontend "react-router") (includes frontend "next") (includes frontend "nuxt"))}}
|
|
30065
|
+
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (eq serverDeploy "docker") (eq webDeploy "vercel") (eq serverDeploy "vercel") (eq orm "prisma") (includes addons "lefthook") (includes addons "nx") (includes addons "pwa") (includes addons "turborepo") (includes addons "vite-plus") (includes frontend "react-router") (includes frontend "next") (includes frontend "nuxt"))}}
|
|
29650
30066
|
|
|
29651
30067
|
# pnpm 11 blocks dependency lifecycle scripts unless they are approved here.
|
|
29652
30068
|
# Entries are scoped to packages this generated stack can pull in.
|
|
29653
30069
|
allowBuilds:
|
|
29654
|
-
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (eq serverDeploy "docker") (includes addons "turborepo") (includes addons "vite-plus") (includes frontend "react-router") (includes frontend "nuxt"))}}
|
|
30070
|
+
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (eq serverDeploy "docker") (eq webDeploy "vercel") (eq serverDeploy "vercel") (includes addons "turborepo") (includes addons "vite-plus") (includes frontend "react-router") (includes frontend "nuxt"))}}
|
|
29655
30071
|
esbuild: true
|
|
29656
30072
|
{{/if}}
|
|
29657
30073
|
{{#if (includes frontend "nuxt")}}
|
|
29658
30074
|
"@parcel/watcher": true
|
|
29659
30075
|
vue-demi: true
|
|
29660
30076
|
{{/if}}
|
|
29661
|
-
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (includes addons "pwa") (includes frontend "next"))}}
|
|
30077
|
+
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (eq webDeploy "vercel") (includes addons "pwa") (includes frontend "next"))}}
|
|
29662
30078
|
sharp: true
|
|
29663
30079
|
{{/if}}
|
|
29664
30080
|
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
|
|
@@ -29705,6 +30121,8 @@ pnpm-debug.log*
|
|
|
29705
30121
|
import tailwindcss from "@tailwindcss/vite";
|
|
29706
30122
|
import { defineConfig, envField } from "astro/config";
|
|
29707
30123
|
{{#if (or (includes addons "electrobun") (includes addons "tauri"))}}
|
|
30124
|
+
{{else if (eq webDeploy "vercel")}}
|
|
30125
|
+
import vercel from "@astrojs/vercel";
|
|
29708
30126
|
{{else}}
|
|
29709
30127
|
import node from "@astrojs/node";
|
|
29710
30128
|
{{/if}}
|
|
@@ -29713,6 +30131,9 @@ import node from "@astrojs/node";
|
|
|
29713
30131
|
export default defineConfig({
|
|
29714
30132
|
{{#if (or (includes addons "electrobun") (includes addons "tauri"))}}
|
|
29715
30133
|
output: "static",
|
|
30134
|
+
{{else if (eq webDeploy "vercel")}}
|
|
30135
|
+
output: "server",
|
|
30136
|
+
adapter: vercel(),
|
|
29716
30137
|
{{else}}
|
|
29717
30138
|
output: "server",
|
|
29718
30139
|
adapter: node({ mode: "standalone" }),
|
|
@@ -29745,11 +30166,11 @@ export default defineConfig({
|
|
|
29745
30166
|
"astro": "astro"
|
|
29746
30167
|
},
|
|
29747
30168
|
"dependencies": {
|
|
29748
|
-
"astro": "^7.0.
|
|
30169
|
+
"astro": "^7.0.5"
|
|
29749
30170
|
},
|
|
29750
30171
|
"devDependencies": {
|
|
29751
|
-
"@tailwindcss/vite": "^4.3.
|
|
29752
|
-
"tailwindcss": "^4.3.
|
|
30172
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
30173
|
+
"tailwindcss": "^4.3.2"
|
|
29753
30174
|
}
|
|
29754
30175
|
}
|
|
29755
30176
|
`],
|
|
@@ -29873,9 +30294,6 @@ const { title = "{{projectName}}" } = Astro.props;
|
|
|
29873
30294
|
`],
|
|
29874
30295
|
["frontend/astro/src/pages/index.astro.hbs", `---
|
|
29875
30296
|
import Layout from "../layouts/Layout.astro";
|
|
29876
|
-
{{#if (eq api "orpc")}}
|
|
29877
|
-
import { orpc } from "../lib/orpc";
|
|
29878
|
-
{{/if}}
|
|
29879
30297
|
|
|
29880
30298
|
const TITLE_TEXT = \`
|
|
29881
30299
|
██████╗ ███████╗████████╗████████╗███████╗██████╗
|
|
@@ -33582,7 +34000,7 @@ module.exports = uniwindConfig;
|
|
|
33582
34000
|
"expo-secure-store": "~57.0.0",
|
|
33583
34001
|
"expo-status-bar": "~57.0.0",
|
|
33584
34002
|
"expo-web-browser": "~57.0.0",
|
|
33585
|
-
"heroui-native": "^1.0.
|
|
34003
|
+
"heroui-native": "^1.0.5",
|
|
33586
34004
|
"react": "19.2.3",
|
|
33587
34005
|
"react-dom": "19.2.3",
|
|
33588
34006
|
"react-native": "0.86.0",
|
|
@@ -33597,7 +34015,7 @@ module.exports = uniwindConfig;
|
|
|
33597
34015
|
"tailwind-merge": "^3.6.0",
|
|
33598
34016
|
"tailwind-variants": "^3.2.2",
|
|
33599
34017
|
"tailwindcss": "^4.3.2",
|
|
33600
|
-
"uniwind": "^1.
|
|
34018
|
+
"uniwind": "^1.10.0"
|
|
33601
34019
|
},
|
|
33602
34020
|
"devDependencies": {
|
|
33603
34021
|
"@types/node": "^26.0.1",
|
|
@@ -33887,13 +34305,13 @@ export default defineNuxtConfig({
|
|
|
33887
34305
|
"postinstall": "nuxt prepare"
|
|
33888
34306
|
},
|
|
33889
34307
|
"dependencies": {
|
|
33890
|
-
"@nuxt/ui": "^4.
|
|
33891
|
-
"nuxt": "^4.4.
|
|
33892
|
-
"vue": "^3.5.
|
|
34308
|
+
"@nuxt/ui": "^4.9.0",
|
|
34309
|
+
"nuxt": "^4.4.8",
|
|
34310
|
+
"vue": "^3.5.39"
|
|
33893
34311
|
},
|
|
33894
34312
|
"devDependencies": {
|
|
33895
|
-
"tailwindcss": "^4.3.
|
|
33896
|
-
"@iconify-json/lucide": "^1.2.
|
|
34313
|
+
"tailwindcss": "^4.3.2",
|
|
34314
|
+
"@iconify-json/lucide": "^1.2.115"
|
|
33897
34315
|
}
|
|
33898
34316
|
}
|
|
33899
34317
|
`],
|
|
@@ -33970,7 +34388,7 @@ initOpenNextCloudflareForDev();
|
|
|
33970
34388
|
"dependencies": {
|
|
33971
34389
|
"@{{projectName}}/ui": "{{#if (eq packageManager "npm")}}*{{else}}workspace:*{{/if}}",
|
|
33972
34390
|
"@swc/helpers": "^0.5.23",
|
|
33973
|
-
"lucide-react": "^1.
|
|
34391
|
+
"lucide-react": "^1.23.0",
|
|
33974
34392
|
"next": "^16.2.0",
|
|
33975
34393
|
"next-themes": "^0.4.6",
|
|
33976
34394
|
"react": "^19.2.7",
|
|
@@ -33979,11 +34397,11 @@ initOpenNextCloudflareForDev();
|
|
|
33979
34397
|
"babel-plugin-react-compiler": "^1.0.0"
|
|
33980
34398
|
},
|
|
33981
34399
|
"devDependencies": {
|
|
33982
|
-
"@tailwindcss/postcss": "^4.3.
|
|
34400
|
+
"@tailwindcss/postcss": "^4.3.2",
|
|
33983
34401
|
"@types/node": "^20",
|
|
33984
34402
|
"@types/react": "^19.2.17",
|
|
33985
34403
|
"@types/react-dom": "^19.2.3",
|
|
33986
|
-
"tailwindcss": "^4.3.
|
|
34404
|
+
"tailwindcss": "^4.3.2"
|
|
33987
34405
|
}
|
|
33988
34406
|
}
|
|
33989
34407
|
`],
|
|
@@ -34372,39 +34790,42 @@ export function ThemeProvider({
|
|
|
34372
34790
|
},
|
|
34373
34791
|
"dependencies": {
|
|
34374
34792
|
"@{{projectName}}/ui": "{{#if (eq packageManager "npm")}}*{{else}}workspace:*{{/if}}",
|
|
34375
|
-
"@react-router/fs-routes": "^
|
|
34376
|
-
"@react-router/node": "^
|
|
34377
|
-
"@react-router/serve": "^
|
|
34378
|
-
"isbot": "^5.1.
|
|
34379
|
-
"lucide-react": "^1.
|
|
34793
|
+
"@react-router/fs-routes": "^8.1.0",
|
|
34794
|
+
"@react-router/node": "^8.1.0",
|
|
34795
|
+
"@react-router/serve": "^8.1.0",
|
|
34796
|
+
"isbot": "^5.1.44",
|
|
34797
|
+
"lucide-react": "^1.23.0",
|
|
34380
34798
|
"next-themes": "^0.4.6",
|
|
34381
34799
|
"react": "^19.2.7",
|
|
34382
34800
|
"react-dom": "^19.2.7",
|
|
34383
|
-
"react-router": "^
|
|
34801
|
+
"react-router": "^8.1.0",
|
|
34384
34802
|
"sonner": "^2.0.7"
|
|
34385
34803
|
},
|
|
34386
34804
|
"devDependencies": {
|
|
34387
|
-
"@react-router/dev": "^
|
|
34388
|
-
"@tailwindcss/vite": "^4.3.
|
|
34389
|
-
"@types/node": "^
|
|
34805
|
+
"@react-router/dev": "^8.1.0",
|
|
34806
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
34807
|
+
"@types/node": "^22.13.14",
|
|
34390
34808
|
"@types/react": "^19.2.17",
|
|
34391
34809
|
"@types/react-dom": "^19.2.3",
|
|
34392
|
-
"react-router-devtools": "^
|
|
34393
|
-
"tailwindcss": "^4.3.
|
|
34394
|
-
"vite": "^
|
|
34810
|
+
"react-router-devtools": "^6.2.1",
|
|
34811
|
+
"tailwindcss": "^4.3.2",
|
|
34812
|
+
"vite": "^7.3.6",
|
|
34395
34813
|
"vite-tsconfig-paths": "^6.1.1"
|
|
34396
34814
|
}
|
|
34397
34815
|
}
|
|
34398
34816
|
`],
|
|
34399
34817
|
["frontend/react/react-router/public/favicon.ico", `[Binary file]`],
|
|
34400
|
-
["frontend/react/react-router/react-router.config.ts", `import type { Config } from "@react-router/dev/config";
|
|
34818
|
+
["frontend/react/react-router/react-router.config.ts.hbs", `import type { Config } from "@react-router/dev/config";
|
|
34401
34819
|
|
|
34402
34820
|
export default {
|
|
34821
|
+
{{#if (and (eq webDeploy "vercel") (not (or (includes addons "tauri") (includes addons "electrobun"))))}}
|
|
34822
|
+
// Adopt vercelPreset() once @vercel/react-router supports RR8 (vercel/vercel#16730)
|
|
34823
|
+
{{/if}}
|
|
34824
|
+
{{#if (or (includes addons "tauri") (includes addons "electrobun"))}}
|
|
34825
|
+
// Desktop addons package static web assets; SSR output cannot be bundled
|
|
34403
34826
|
ssr: false,
|
|
34827
|
+
{{/if}}
|
|
34404
34828
|
appDirectory: "src",
|
|
34405
|
-
future: {
|
|
34406
|
-
v8_middleware: true,
|
|
34407
|
-
},
|
|
34408
34829
|
} satisfies Config;
|
|
34409
34830
|
`],
|
|
34410
34831
|
["frontend/react/react-router/src/components/mode-toggle.tsx.hbs", `import { Moon, Sun } from "lucide-react";
|
|
@@ -34881,6 +35302,12 @@ export default defineConfig({
|
|
|
34881
35302
|
reactRouter(),
|
|
34882
35303
|
tsconfigPaths(),
|
|
34883
35304
|
],
|
|
35305
|
+
{{#if (and (eq webDeploy "vercel") (not (or (includes addons "tauri") (includes addons "electrobun"))))}}
|
|
35306
|
+
ssr: {
|
|
35307
|
+
// Vercel functions have no node_modules; bundle all deps into the server build
|
|
35308
|
+
noExternal: true,
|
|
35309
|
+
},
|
|
35310
|
+
{{/if}}
|
|
34884
35311
|
});
|
|
34885
35312
|
`],
|
|
34886
35313
|
["frontend/react/tanstack-router/index.html.hbs", `<!DOCTYPE html>
|
|
@@ -34910,26 +35337,26 @@ export default defineConfig({
|
|
|
34910
35337
|
"check-types": "vite build && tsc --noEmit"
|
|
34911
35338
|
},
|
|
34912
35339
|
"dependencies": {
|
|
34913
|
-
"@hookform/resolvers": "^5.
|
|
35340
|
+
"@hookform/resolvers": "^5.4.0",
|
|
34914
35341
|
"@{{projectName}}/ui": "{{#if (eq packageManager "npm")}}*{{else}}workspace:*{{/if}}",
|
|
34915
|
-
"@tailwindcss/vite": "^4.3.
|
|
34916
|
-
"@tanstack/react-router": "^1.
|
|
34917
|
-
"lucide-react": "^1.
|
|
35342
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
35343
|
+
"@tanstack/react-router": "^1.170.17",
|
|
35344
|
+
"lucide-react": "^1.23.0",
|
|
34918
35345
|
"next-themes": "^0.4.6",
|
|
34919
35346
|
"react": "^19.2.7",
|
|
34920
35347
|
"react-dom": "^19.2.7",
|
|
34921
35348
|
"sonner": "^2.0.7"
|
|
34922
35349
|
},
|
|
34923
35350
|
"devDependencies": {
|
|
34924
|
-
"@tanstack/react-router-devtools": "^1.
|
|
34925
|
-
"@tanstack/router-plugin": "^1.
|
|
35351
|
+
"@tanstack/react-router-devtools": "^1.167.0",
|
|
35352
|
+
"@tanstack/router-plugin": "^1.168.19",
|
|
34926
35353
|
"@types/node": "^22.13.14",
|
|
34927
35354
|
"@types/react": "^19.2.17",
|
|
34928
35355
|
"@types/react-dom": "^19.2.3",
|
|
34929
|
-
"@vitejs/plugin-react": "^6.0.
|
|
34930
|
-
"postcss": "^8.5.
|
|
34931
|
-
"tailwindcss": "^4.3.
|
|
34932
|
-
"vite": "^8.
|
|
35356
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
35357
|
+
"postcss": "^8.5.16",
|
|
35358
|
+
"tailwindcss": "^4.3.2",
|
|
35359
|
+
"vite": "^8.1.3"
|
|
34933
35360
|
}
|
|
34934
35361
|
}
|
|
34935
35362
|
`],
|
|
@@ -35355,27 +35782,27 @@ export default defineConfig({
|
|
|
35355
35782
|
},
|
|
35356
35783
|
"dependencies": {
|
|
35357
35784
|
"@{{projectName}}/ui": "{{#if (eq packageManager "npm")}}*{{else}}workspace:*{{/if}}",
|
|
35358
|
-
"@tailwindcss/vite": "^4.3.
|
|
35359
|
-
"@tanstack/react-query": "^5.
|
|
35360
|
-
"@tanstack/react-router": "^1.
|
|
35361
|
-
"@tanstack/react-start": "^1.
|
|
35362
|
-
"lucide-react": "^1.
|
|
35785
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
35786
|
+
"@tanstack/react-query": "^5.101.2",
|
|
35787
|
+
"@tanstack/react-router": "^1.170.17",
|
|
35788
|
+
"@tanstack/react-start": "^1.168.27",
|
|
35789
|
+
"lucide-react": "^1.23.0",
|
|
35363
35790
|
"next-themes": "^0.4.6",
|
|
35364
35791
|
"react": "^19.2.7",
|
|
35365
35792
|
"react-dom": "^19.2.7",
|
|
35366
35793
|
"sonner": "^2.0.7",
|
|
35367
|
-
"tailwindcss": "^4.3.
|
|
35794
|
+
"tailwindcss": "^4.3.2"
|
|
35368
35795
|
},
|
|
35369
35796
|
"devDependencies": {
|
|
35370
|
-
"@tanstack/react-router-devtools": "^1.
|
|
35797
|
+
"@tanstack/react-router-devtools": "^1.167.0",
|
|
35371
35798
|
"@testing-library/dom": "^10.4.1",
|
|
35372
35799
|
"@testing-library/react": "^16.3.2",
|
|
35373
35800
|
"@types/react": "^19.2.17",
|
|
35374
35801
|
"@types/react-dom": "^19.2.3",
|
|
35375
|
-
"@vitejs/plugin-react": "^6.0.
|
|
35376
|
-
"jsdom": "^29.
|
|
35377
|
-
"vite": "^8.
|
|
35378
|
-
"web-vitals": "^5.
|
|
35802
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
35803
|
+
"jsdom": "^29.1.1",
|
|
35804
|
+
"vite": "^8.1.3",
|
|
35805
|
+
"web-vitals": "^5.3.0"
|
|
35379
35806
|
}
|
|
35380
35807
|
}
|
|
35381
35808
|
`],
|
|
@@ -35451,6 +35878,10 @@ export function getRouter() {
|
|
|
35451
35878
|
}
|
|
35452
35879
|
{{else}}
|
|
35453
35880
|
{{#if (eq api "trpc")}}
|
|
35881
|
+
{{#unless (eq backend "self")}}
|
|
35882
|
+
{{> getServerUrl}}
|
|
35883
|
+
|
|
35884
|
+
{{/unless}}
|
|
35454
35885
|
function createQueryClient() {
|
|
35455
35886
|
return new QueryClient({
|
|
35456
35887
|
queryCache: new QueryCache({
|
|
@@ -35472,7 +35903,7 @@ function createQueryClient() {
|
|
|
35472
35903
|
const trpcClient = createTRPCClient<AppRouter>({
|
|
35473
35904
|
links: [
|
|
35474
35905
|
httpBatchLink({
|
|
35475
|
-
url: {{#if (eq backend "self")}}"/api/trpc"{{else}}\`\${env.VITE_SERVER_URL}/trpc\`{{/if}},
|
|
35906
|
+
url: {{#if (eq backend "self")}}"/api/trpc"{{else}}\`\${getServerUrl(env.VITE_SERVER_URL)}/trpc\`{{/if}},
|
|
35476
35907
|
{{#if (eq auth "clerk")}}
|
|
35477
35908
|
headers: async () => {
|
|
35478
35909
|
const token = await getClerkAuthToken();
|
|
@@ -35915,7 +36346,7 @@ function HomeComponent() {
|
|
|
35915
36346
|
`],
|
|
35916
36347
|
["frontend/react/tanstack-start/vite.config.ts.hbs", `import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
|
|
35917
36348
|
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
35918
|
-
{{#if (eq webDeploy "docker")}}
|
|
36349
|
+
{{#if (or (eq webDeploy "docker") (eq webDeploy "vercel"))}}
|
|
35919
36350
|
import { nitro } from "nitro/vite";
|
|
35920
36351
|
{{/if}}
|
|
35921
36352
|
import tailwindcss from "@tailwindcss/vite";
|
|
@@ -35937,12 +36368,17 @@ export default defineConfig({
|
|
|
35937
36368
|
},
|
|
35938
36369
|
},
|
|
35939
36370
|
{{/if}}),
|
|
35940
|
-
{{#if (eq webDeploy "docker")}}
|
|
36371
|
+
{{#if (or (eq webDeploy "docker") (eq webDeploy "vercel"))}}
|
|
35941
36372
|
nitro(),
|
|
35942
36373
|
{{/if}}
|
|
35943
36374
|
viteReact(),
|
|
35944
36375
|
],
|
|
35945
|
-
{{#if (
|
|
36376
|
+
{{#if (eq webDeploy "vercel")}}
|
|
36377
|
+
// Bundle all SSR deps: Vercel functions have no node_modules at runtime
|
|
36378
|
+
ssr: {
|
|
36379
|
+
noExternal: true,
|
|
36380
|
+
},
|
|
36381
|
+
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
35946
36382
|
ssr: {
|
|
35947
36383
|
noExternal: ["@convex-dev/better-auth"],
|
|
35948
36384
|
},
|
|
@@ -36165,16 +36601,16 @@ dist-ssr
|
|
|
36165
36601
|
"test": "vitest run"
|
|
36166
36602
|
},
|
|
36167
36603
|
"dependencies": {
|
|
36168
|
-
"@tailwindcss/vite": "^4.3.
|
|
36169
|
-
"@tanstack/router-plugin": "^1.
|
|
36170
|
-
"@tanstack/solid-router": "^1.
|
|
36171
|
-
"lucide-solid": "^1.
|
|
36172
|
-
"solid-js": "^1.9.
|
|
36173
|
-
"tailwindcss": "^4.3.
|
|
36604
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
36605
|
+
"@tanstack/router-plugin": "^1.168.19",
|
|
36606
|
+
"@tanstack/solid-router": "^1.170.17",
|
|
36607
|
+
"lucide-solid": "^1.23.0",
|
|
36608
|
+
"solid-js": "^1.9.14",
|
|
36609
|
+
"tailwindcss": "^4.3.2"
|
|
36174
36610
|
},
|
|
36175
36611
|
"devDependencies": {
|
|
36176
|
-
"@tanstack/solid-router-devtools": "^1.
|
|
36177
|
-
"vite": "^8.
|
|
36612
|
+
"@tanstack/solid-router-devtools": "^1.167.0",
|
|
36613
|
+
"vite": "^8.1.3",
|
|
36178
36614
|
"vite-plugin-solid": "^2.11.12"
|
|
36179
36615
|
}
|
|
36180
36616
|
}
|
|
@@ -36485,13 +36921,13 @@ vite.config.ts.timestamp-*
|
|
|
36485
36921
|
{{else}}
|
|
36486
36922
|
"@sveltejs/adapter-auto": "^7.0.1",
|
|
36487
36923
|
{{/if}}
|
|
36488
|
-
"@sveltejs/kit": "^2.
|
|
36489
|
-
"@sveltejs/vite-plugin-svelte": "^7.
|
|
36490
|
-
"@tailwindcss/vite": "^4.3.
|
|
36491
|
-
"svelte": "^5.
|
|
36492
|
-
"svelte-check": "^4.
|
|
36493
|
-
"tailwindcss": "^4.3.
|
|
36494
|
-
"vite": "^8.
|
|
36924
|
+
"@sveltejs/kit": "^2.69.0",
|
|
36925
|
+
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
36926
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
36927
|
+
"svelte": "^5.56.4",
|
|
36928
|
+
"svelte-check": "^4.7.1",
|
|
36929
|
+
"tailwindcss": "^4.3.2",
|
|
36930
|
+
"vite": "^8.1.3"
|
|
36495
36931
|
},
|
|
36496
36932
|
"dependencies": {}
|
|
36497
36933
|
}
|
|
@@ -36687,7 +37123,7 @@ const TITLE_TEXT = \`
|
|
|
36687
37123
|
{{#if (eq api "orpc")}}
|
|
36688
37124
|
import { orpc } from "$lib/orpc";
|
|
36689
37125
|
import { createQuery } from "@tanstack/svelte-query";
|
|
36690
|
-
const healthCheck = createQuery(orpc.healthCheck.queryOptions());
|
|
37126
|
+
const healthCheck = createQuery(() => orpc.healthCheck.queryOptions());
|
|
36691
37127
|
{{/if}}
|
|
36692
37128
|
|
|
36693
37129
|
const TITLE_TEXT = \`
|
|
@@ -36715,12 +37151,12 @@ const TITLE_TEXT = \`
|
|
|
36715
37151
|
<h2 class="mb-2 font-medium">API Status</h2>
|
|
36716
37152
|
<div class="flex items-center gap-2">
|
|
36717
37153
|
<div
|
|
36718
|
-
class={\`h-2 w-2 rounded-full \${
|
|
37154
|
+
class={\`h-2 w-2 rounded-full \${healthCheck.data ? "bg-green-500" : "bg-red-500"}\`}
|
|
36719
37155
|
></div>
|
|
36720
37156
|
<span class="text-muted-foreground text-sm">
|
|
36721
|
-
{
|
|
37157
|
+
{healthCheck.isLoading
|
|
36722
37158
|
? "Checking..."
|
|
36723
|
-
:
|
|
37159
|
+
: healthCheck.data
|
|
36724
37160
|
? "Connected"
|
|
36725
37161
|
: "Disconnected"}
|
|
36726
37162
|
</span>
|
|
@@ -36738,6 +37174,8 @@ import adapter from '@sveltejs/adapter-static';
|
|
|
36738
37174
|
import alchemy from 'alchemy/cloudflare/sveltekit';
|
|
36739
37175
|
{{else if (eq webDeploy "docker")}}
|
|
36740
37176
|
import adapter from '@sveltejs/adapter-node';
|
|
37177
|
+
{{else if (eq webDeploy "vercel")}}
|
|
37178
|
+
import adapter from '@sveltejs/adapter-vercel';
|
|
36741
37179
|
{{else}}
|
|
36742
37180
|
import adapter from '@sveltejs/adapter-auto';
|
|
36743
37181
|
{{/if}}
|
|
@@ -36763,6 +37201,8 @@ const config = {
|
|
|
36763
37201
|
{{else if (eq webDeploy "docker")}}
|
|
36764
37202
|
// adapter-node builds a standalone Node server (run with \`node build/index.js\`).
|
|
36765
37203
|
adapter: adapter()
|
|
37204
|
+
{{else if (eq webDeploy "vercel")}}
|
|
37205
|
+
adapter: adapter()
|
|
36766
37206
|
{{else}}
|
|
36767
37207
|
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
|
36768
37208
|
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
|
@@ -36993,6 +37433,33 @@ import "dotenv/config";
|
|
|
36993
37433
|
import { createEnv } from "@t3-oss/env-core";
|
|
36994
37434
|
import { z } from "zod";
|
|
36995
37435
|
|
|
37436
|
+
{{#if (or (eq webDeploy "vercel") (eq serverDeploy "vercel"))}}
|
|
37437
|
+
function getVercelOrigin() {
|
|
37438
|
+
const vercelUrl =
|
|
37439
|
+
process.env.VERCEL_ENV === "production"
|
|
37440
|
+
? (process.env.VERCEL_PROJECT_PRODUCTION_URL ?? process.env.VERCEL_URL)
|
|
37441
|
+
: (process.env.VERCEL_URL ?? process.env.VERCEL_PROJECT_PRODUCTION_URL);
|
|
37442
|
+
if (!vercelUrl) return undefined;
|
|
37443
|
+
return vercelUrl.startsWith("http") ? vercelUrl : \`https://\${vercelUrl}\`;
|
|
37444
|
+
}
|
|
37445
|
+
|
|
37446
|
+
const vercelOrigin = getVercelOrigin();
|
|
37447
|
+
|
|
37448
|
+
const runtimeEnv = {
|
|
37449
|
+
...process.env,
|
|
37450
|
+
{{#if (eq auth "better-auth")}}
|
|
37451
|
+
{{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel") (ne backend "self"))}}
|
|
37452
|
+
// Public auth base: /api/auth bypasses the rewrite's path strip, so the
|
|
37453
|
+
// same URL works for incoming matching and generated callbacks
|
|
37454
|
+
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL ?? (vercelOrigin ? \`\${vercelOrigin}/api/auth\` : undefined),
|
|
37455
|
+
{{else}}
|
|
37456
|
+
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL ?? vercelOrigin,
|
|
37457
|
+
{{/if}}
|
|
37458
|
+
{{/if}}
|
|
37459
|
+
CORS_ORIGIN: process.env.CORS_ORIGIN ?? vercelOrigin,
|
|
37460
|
+
};
|
|
37461
|
+
|
|
37462
|
+
{{/if}}
|
|
36996
37463
|
export const env = createEnv({
|
|
36997
37464
|
server: {
|
|
36998
37465
|
{{#if (ne database "none")}}
|
|
@@ -37024,7 +37491,7 @@ export const env = createEnv({
|
|
|
37024
37491
|
CORS_ORIGIN: z.url(),
|
|
37025
37492
|
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
|
37026
37493
|
},
|
|
37027
|
-
runtimeEnv: process.env,
|
|
37494
|
+
runtimeEnv: {{#if (or (eq webDeploy "vercel") (eq serverDeploy "vercel"))}}runtimeEnv{{else}}process.env{{/if}},
|
|
37028
37495
|
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
|
|
37029
37496
|
emptyStringAsUndefined: true,
|
|
37030
37497
|
});
|
|
@@ -37041,6 +37508,13 @@ import { createEnv } from "@t3-oss/env-core";
|
|
|
37041
37508
|
{{/if}}
|
|
37042
37509
|
import { z } from "zod";
|
|
37043
37510
|
|
|
37511
|
+
{{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel") (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
37512
|
+
const serverUrlSchema = z.union([
|
|
37513
|
+
z.url(),
|
|
37514
|
+
z.string().regex(/^\\/(?!\\/)/, "Use an absolute URL or a same-origin path like /api"),
|
|
37515
|
+
]);
|
|
37516
|
+
|
|
37517
|
+
{{/if}}
|
|
37044
37518
|
{{#if (eq backend "convex")}}
|
|
37045
37519
|
const convexUrlSchema = (exampleHost: string) =>
|
|
37046
37520
|
z.url().refine((url) => new URL(url).hostname !== exampleHost, {
|
|
@@ -37126,7 +37600,7 @@ export const env = createEnv({
|
|
|
37126
37600
|
{{else if (ne backend "none")}}
|
|
37127
37601
|
{{#if (includes frontend "next")}}
|
|
37128
37602
|
client: {
|
|
37129
|
-
NEXT_PUBLIC_SERVER_URL: z.url(),
|
|
37603
|
+
NEXT_PUBLIC_SERVER_URL: {{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel"))}}serverUrlSchema{{else}}z.url(){{/if}},
|
|
37130
37604
|
{{#if (eq auth "clerk")}}
|
|
37131
37605
|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
|
|
37132
37606
|
{{/if}}
|
|
@@ -37139,18 +37613,18 @@ export const env = createEnv({
|
|
|
37139
37613
|
},
|
|
37140
37614
|
{{else if (includes frontend "nuxt")}}
|
|
37141
37615
|
client: {
|
|
37142
|
-
NUXT_PUBLIC_SERVER_URL: z.url(),
|
|
37616
|
+
NUXT_PUBLIC_SERVER_URL: {{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel"))}}serverUrlSchema{{else}}z.url(){{/if}},
|
|
37143
37617
|
},
|
|
37144
37618
|
{{else if (or (includes frontend "svelte") (includes frontend "astro"))}}
|
|
37145
37619
|
clientPrefix: "PUBLIC_",
|
|
37146
37620
|
client: {
|
|
37147
|
-
PUBLIC_SERVER_URL: z.url(),
|
|
37621
|
+
PUBLIC_SERVER_URL: {{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel"))}}serverUrlSchema{{else}}z.url(){{/if}},
|
|
37148
37622
|
},
|
|
37149
37623
|
runtimeEnv: (import.meta as any).env,
|
|
37150
37624
|
{{else}}
|
|
37151
37625
|
clientPrefix: "VITE_",
|
|
37152
37626
|
client: {
|
|
37153
|
-
VITE_SERVER_URL: z.url(),
|
|
37627
|
+
VITE_SERVER_URL: {{#if (and (eq webDeploy "vercel") (eq serverDeploy "vercel"))}}serverUrlSchema{{else}}z.url(){{/if}},
|
|
37154
37628
|
{{#if (eq auth "clerk")}}
|
|
37155
37629
|
VITE_CLERK_PUBLISHABLE_KEY: z.string().min(1),
|
|
37156
37630
|
{{/if}}
|
|
@@ -37646,11 +38120,11 @@ await app.finalize();
|
|
|
37646
38120
|
},
|
|
37647
38121
|
"dependencies": {
|
|
37648
38122
|
"@base-ui/react": "^1.6.0",
|
|
37649
|
-
"@shadcn/react": "^0.
|
|
38123
|
+
"@shadcn/react": "^0.2.0",
|
|
37650
38124
|
"shadcn": "^4.12.0",
|
|
37651
38125
|
"class-variance-authority": "^0.7.1",
|
|
37652
38126
|
"clsx": "^2.1.1",
|
|
37653
|
-
"lucide-react": "^1.
|
|
38127
|
+
"lucide-react": "^1.23.0",
|
|
37654
38128
|
"next-themes": "^0.4.6",
|
|
37655
38129
|
"react": "^19.2.7",
|
|
37656
38130
|
"react-dom": "^19.2.7",
|
|
@@ -37659,10 +38133,10 @@ await app.finalize();
|
|
|
37659
38133
|
"tw-animate-css": "^1.4.0"
|
|
37660
38134
|
},
|
|
37661
38135
|
"devDependencies": {
|
|
37662
|
-
"@tailwindcss/postcss": "^4.3.
|
|
38136
|
+
"@tailwindcss/postcss": "^4.3.2",
|
|
37663
38137
|
"@types/react": "^19.2.17",
|
|
37664
38138
|
"@types/react-dom": "^19.2.3",
|
|
37665
|
-
"tailwindcss": "^4.3.
|
|
38139
|
+
"tailwindcss": "^4.3.2"
|
|
37666
38140
|
},
|
|
37667
38141
|
"scripts": {
|
|
37668
38142
|
"check-types": "tsc --noEmit"
|
|
@@ -39613,8 +40087,8 @@ function SuccessPage() {
|
|
|
39613
40087
|
</div>
|
|
39614
40088
|
`]
|
|
39615
40089
|
]);
|
|
39616
|
-
const TEMPLATE_COUNT =
|
|
40090
|
+
const TEMPLATE_COUNT = 507;
|
|
39617
40091
|
//#endregion
|
|
39618
|
-
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processNxConfig, processPackageConfigs, processTemplateString, processTurboConfig, processVitePlusConfig, transformFilename, writeBtsConfigToVfs };
|
|
40092
|
+
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processNxConfig, processPackageConfigs, processTemplateString, processTurboConfig, processVercelConfig, processVitePlusConfig, transformFilename, writeBtsConfigToVfs };
|
|
39619
40093
|
|
|
39620
40094
|
//# sourceMappingURL=index.mjs.map
|