@better-t-stack/template-generator 3.31.1 → 3.33.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 +30 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1196 -206
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -187,6 +187,7 @@ Handlebars.registerHelper("eq", (a, b) => a === b);
|
|
|
187
187
|
Handlebars.registerHelper("ne", (a, b) => a !== b);
|
|
188
188
|
Handlebars.registerHelper("and", (...args) => args.slice(0, -1).every(Boolean));
|
|
189
189
|
Handlebars.registerHelper("or", (...args) => args.slice(0, -1).some(Boolean));
|
|
190
|
+
Handlebars.registerHelper("not", (a) => !a);
|
|
190
191
|
Handlebars.registerHelper("includes", (arr, val) => Array.isArray(arr) && arr.includes(val));
|
|
191
192
|
function processTemplateString(content, context) {
|
|
192
193
|
return Handlebars.compile(content)(context);
|
|
@@ -199,6 +200,7 @@ function transformFilename(filename) {
|
|
|
199
200
|
const basename = result.split("/").pop() || result;
|
|
200
201
|
if (basename === "_gitignore") result = result.replace(/_gitignore$/, ".gitignore");
|
|
201
202
|
else if (basename === "_npmrc") result = result.replace(/_npmrc$/, ".npmrc");
|
|
203
|
+
else if (basename === "_dockerignore") result = result.replace(/_dockerignore$/, ".dockerignore");
|
|
202
204
|
return result;
|
|
203
205
|
}
|
|
204
206
|
function processFileContent(filePath, content, context) {
|
|
@@ -380,6 +382,157 @@ function updatePackageJsonsWithCatalogs(vfs, packagesInfo, catalog) {
|
|
|
380
382
|
}
|
|
381
383
|
}
|
|
382
384
|
//#endregion
|
|
385
|
+
//#region src/utils/add-deps.ts
|
|
386
|
+
const dependencyVersionMap = {
|
|
387
|
+
typescript: "^6",
|
|
388
|
+
"better-auth": "1.6.11",
|
|
389
|
+
"@better-auth/expo": "1.6.11",
|
|
390
|
+
"@clerk/backend": "^3.2.1",
|
|
391
|
+
"@clerk/express": "^2.0.5",
|
|
392
|
+
"@clerk/fastify": "^3.1.3",
|
|
393
|
+
"@clerk/nextjs": "^7.0.5",
|
|
394
|
+
"@clerk/react": "^6.1.1",
|
|
395
|
+
"@clerk/react-router": "^3.0.5",
|
|
396
|
+
"@clerk/tanstack-react-start": "^1.1.3",
|
|
397
|
+
"@clerk/expo": "^3.1.3",
|
|
398
|
+
"drizzle-orm": "^0.45.1",
|
|
399
|
+
"drizzle-kit": "^0.31.8",
|
|
400
|
+
"@planetscale/database": "^1.19.0",
|
|
401
|
+
"@libsql/client": "0.15.15",
|
|
402
|
+
libsql: "0.5.22",
|
|
403
|
+
"@neondatabase/serverless": "^1.0.2",
|
|
404
|
+
pg: "^8.17.1",
|
|
405
|
+
"@types/pg": "^8.16.0",
|
|
406
|
+
"@types/ws": "^8.18.1",
|
|
407
|
+
ws: "^8.18.3",
|
|
408
|
+
mysql2: "^3.14.0",
|
|
409
|
+
"@prisma/client": "^7.8.0",
|
|
410
|
+
prisma: "^7.8.0",
|
|
411
|
+
"@prisma/adapter-d1": "^7.8.0",
|
|
412
|
+
"@prisma/adapter-neon": "^7.8.0",
|
|
413
|
+
"@prisma/adapter-mariadb": "^7.8.0",
|
|
414
|
+
"@prisma/adapter-libsql": "^7.8.0",
|
|
415
|
+
"@prisma/adapter-better-sqlite3": "^7.8.0",
|
|
416
|
+
"@prisma/adapter-pg": "^7.8.0",
|
|
417
|
+
"@prisma/adapter-planetscale": "^7.8.0",
|
|
418
|
+
mongoose: "^9.6.2",
|
|
419
|
+
mongodb: "^7.2.0",
|
|
420
|
+
"vite-plugin-pwa": "^1.3.0",
|
|
421
|
+
"@vite-pwa/assets-generator": "^1.0.2",
|
|
422
|
+
"@tauri-apps/cli": "^2.11.2",
|
|
423
|
+
"@biomejs/biome": "^2.4.16",
|
|
424
|
+
oxlint: "^1.68.0",
|
|
425
|
+
oxfmt: "^0.53.0",
|
|
426
|
+
husky: "^9.1.7",
|
|
427
|
+
lefthook: "^2.1.9",
|
|
428
|
+
"lint-staged": "^17.0.7",
|
|
429
|
+
tsx: "^4.19.2",
|
|
430
|
+
"@types/node": "^22.13.14",
|
|
431
|
+
"@types/bun": "^1.3.4",
|
|
432
|
+
"@elysiajs/node": "^1.4.5",
|
|
433
|
+
"@elysiajs/cors": "^1.4.1",
|
|
434
|
+
"@elysiajs/trpc": "^1.1.0",
|
|
435
|
+
elysia: "^1.4.28",
|
|
436
|
+
"@sinclair/typebox": "^0.34.49",
|
|
437
|
+
"@hono/node-server": "^1.14.4",
|
|
438
|
+
"@hono/trpc-server": "^0.4.0",
|
|
439
|
+
hono: "^4.8.2",
|
|
440
|
+
cors: "^2.8.5",
|
|
441
|
+
express: "^5.1.0",
|
|
442
|
+
"@types/express": "^5.0.1",
|
|
443
|
+
"@types/cors": "^2.8.17",
|
|
444
|
+
fastify: "^5.3.3",
|
|
445
|
+
"@fastify/cors": "^11.0.1",
|
|
446
|
+
turbo: "^2.9.16",
|
|
447
|
+
nx: "^22.7.5",
|
|
448
|
+
"vite-plus": "0.1.24",
|
|
449
|
+
rolldown: "1.1.0",
|
|
450
|
+
ai: "^6.0.3",
|
|
451
|
+
"@ai-sdk/google": "^3.0.1",
|
|
452
|
+
"@ai-sdk/vue": "^3.0.3",
|
|
453
|
+
"@ai-sdk/svelte": "^4.0.3",
|
|
454
|
+
"@ai-sdk/react": "^3.0.3",
|
|
455
|
+
"@ai-sdk/devtools": "^0.0.2",
|
|
456
|
+
streamdown: "^1.6.10",
|
|
457
|
+
shiki: "^3.20.0",
|
|
458
|
+
"@orpc/server": "^1.13.14",
|
|
459
|
+
"@orpc/client": "^1.13.14",
|
|
460
|
+
"@orpc/openapi": "^1.13.14",
|
|
461
|
+
"@orpc/zod": "^1.13.14",
|
|
462
|
+
"@orpc/tanstack-query": "^1.13.14",
|
|
463
|
+
"@trpc/tanstack-react-query": "^11.16.0",
|
|
464
|
+
"@trpc/server": "^11.16.0",
|
|
465
|
+
"@trpc/client": "^11.16.0",
|
|
466
|
+
next: "^16.2.0",
|
|
467
|
+
nitro: "^3.0.260429-beta",
|
|
468
|
+
convex: "^1.33.1",
|
|
469
|
+
"@convex-dev/react-query": "^0.1.0",
|
|
470
|
+
"@convex-dev/agent": "^0.3.2",
|
|
471
|
+
"@convex-dev/polar": "^0.9.1",
|
|
472
|
+
"convex-svelte": "^0.0.12",
|
|
473
|
+
"convex-nuxt": "0.1.5",
|
|
474
|
+
"convex-vue": "^0.1.5",
|
|
475
|
+
"@convex-dev/better-auth": "^0.12.2",
|
|
476
|
+
"@tanstack/svelte-query": "^5.85.3",
|
|
477
|
+
"@tanstack/svelte-query-devtools": "^5.85.3",
|
|
478
|
+
"@tanstack/vue-query-devtools": "^6.1.5",
|
|
479
|
+
"@tanstack/vue-query": "^5.92.9",
|
|
480
|
+
"@tanstack/react-query-devtools": "^5.91.1",
|
|
481
|
+
"@tanstack/react-query": "^5.90.12",
|
|
482
|
+
"@tanstack/react-form": "^1.28.0",
|
|
483
|
+
"@tanstack/react-router-ssr-query": "^1.166.11",
|
|
484
|
+
"@tanstack/solid-form": "^1.28.0",
|
|
485
|
+
"@tanstack/svelte-form": "^1.28.0",
|
|
486
|
+
"@tanstack/solid-query": "^5.99.1",
|
|
487
|
+
"@tanstack/solid-query-devtools": "^5.99.1",
|
|
488
|
+
"@tanstack/solid-router-devtools": "^1.166.13",
|
|
489
|
+
wrangler: "^4.77.0",
|
|
490
|
+
"@cloudflare/vite-plugin": "^1.17.1",
|
|
491
|
+
"@opennextjs/cloudflare": "^1.17.3",
|
|
492
|
+
"nitro-cloudflare-dev": "^0.2.2",
|
|
493
|
+
"@sveltejs/adapter-cloudflare": "^7.2.8",
|
|
494
|
+
"@sveltejs/adapter-node": "^5.5.4",
|
|
495
|
+
"@cloudflare/workers-types": "^4.20251213.0",
|
|
496
|
+
"@astrojs/cloudflare": "^13.0.1",
|
|
497
|
+
"@astrojs/node": "^10.0.0-beta.9",
|
|
498
|
+
alchemy: "^0.91.2",
|
|
499
|
+
dotenv: "^17.2.2",
|
|
500
|
+
tsdown: "^0.21.9",
|
|
501
|
+
zod: "^4.1.13",
|
|
502
|
+
"@t3-oss/env-core": "^0.13.1",
|
|
503
|
+
"@t3-oss/env-nextjs": "^0.13.1",
|
|
504
|
+
"@t3-oss/env-nuxt": "^0.13.1",
|
|
505
|
+
"@polar-sh/better-auth": "^1.8.4",
|
|
506
|
+
"@polar-sh/checkout": "^0.2.1",
|
|
507
|
+
"@polar-sh/sdk": "^0.47.1",
|
|
508
|
+
"@stripe/react-stripe-js": "^4.0.2",
|
|
509
|
+
"@stripe/stripe-js": "^7.9.0",
|
|
510
|
+
evlog: "^2.18.1"
|
|
511
|
+
};
|
|
512
|
+
/**
|
|
513
|
+
* Add dependencies to a package.json file in the VFS
|
|
514
|
+
*/
|
|
515
|
+
function addPackageDependency(options) {
|
|
516
|
+
const { vfs, packagePath, dependencies = [], devDependencies = [], customDependencies = {}, customDevDependencies = {} } = options;
|
|
517
|
+
const pkgJson = vfs.readJson(packagePath);
|
|
518
|
+
if (!pkgJson) return;
|
|
519
|
+
pkgJson.dependencies = pkgJson.dependencies || {};
|
|
520
|
+
pkgJson.devDependencies = pkgJson.devDependencies || {};
|
|
521
|
+
for (const dep of dependencies) if (!pkgJson.dependencies[dep]) {
|
|
522
|
+
const version = dependencyVersionMap[dep];
|
|
523
|
+
if (!version) throw new Error(`Missing version for dependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
|
|
524
|
+
pkgJson.dependencies[dep] = version;
|
|
525
|
+
}
|
|
526
|
+
for (const dep of devDependencies) if (!pkgJson.devDependencies[dep]) {
|
|
527
|
+
const version = dependencyVersionMap[dep];
|
|
528
|
+
if (!version) throw new Error(`Missing version for devDependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
|
|
529
|
+
pkgJson.devDependencies[dep] = version;
|
|
530
|
+
}
|
|
531
|
+
for (const [dep, version] of Object.entries(customDependencies)) pkgJson.dependencies[dep] = version;
|
|
532
|
+
for (const [dep, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[dep] = version;
|
|
533
|
+
vfs.writeJson(packagePath, pkgJson);
|
|
534
|
+
}
|
|
535
|
+
//#endregion
|
|
383
536
|
//#region src/utils/db-scripts.ts
|
|
384
537
|
function getDbScriptSupport(config) {
|
|
385
538
|
const isD1Alchemy = config.dbSetup === "d1" && (config.serverDeploy === "cloudflare" || config.backend === "self" && config.webDeploy === "cloudflare");
|
|
@@ -406,6 +559,7 @@ function getDbScriptSupport(config) {
|
|
|
406
559
|
* Package.json configuration post-processor
|
|
407
560
|
* Updates package names, scripts, and workspaces after template generation
|
|
408
561
|
*/
|
|
562
|
+
const VITE_PLUS_VERSION = dependencyVersionMap["vite-plus"];
|
|
409
563
|
/**
|
|
410
564
|
* Update all package.json files with proper names, scripts, and workspaces
|
|
411
565
|
*/
|
|
@@ -417,6 +571,7 @@ function processPackageConfigs(vfs, config) {
|
|
|
417
571
|
updateInfraPackageJson(vfs, config);
|
|
418
572
|
updateDesktopPackageJson(vfs, config);
|
|
419
573
|
renameDevScriptsForAlchemy(vfs, config);
|
|
574
|
+
updateVitePlusPackageScripts(vfs, config);
|
|
420
575
|
if (config.backend === "convex") updateConvexPackageJson(vfs, config);
|
|
421
576
|
else if (config.backend !== "none") {
|
|
422
577
|
updateDbPackageJson(vfs, config);
|
|
@@ -429,10 +584,8 @@ function updateRootPackageJson(vfs, config) {
|
|
|
429
584
|
if (!pkgJson) return;
|
|
430
585
|
pkgJson.name = config.projectName;
|
|
431
586
|
pkgJson.scripts = pkgJson.scripts || {};
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
else if (pkgJson.workspaces && typeof pkgJson.workspaces === "object" && pkgJson.workspaces.packages) workspaces = pkgJson.workspaces.packages;
|
|
435
|
-
pkgJson.workspaces = workspaces;
|
|
587
|
+
const existingWorkspaces = pkgJson.workspaces;
|
|
588
|
+
const workspaces = getWorkspacePackages(existingWorkspaces);
|
|
436
589
|
const scripts = pkgJson.scripts;
|
|
437
590
|
const { projectName, packageManager, backend, database, orm, dbSetup, addons, frontend } = config;
|
|
438
591
|
const hasWebApp = frontend.some((item) => desktopWebFrontends.includes(item));
|
|
@@ -445,16 +598,27 @@ function updateRootPackageJson(vfs, config) {
|
|
|
445
598
|
const dbPackageName = `@${projectName}/db`;
|
|
446
599
|
const hasTurborepo = addons.includes("turborepo");
|
|
447
600
|
const hasNx = addons.includes("nx");
|
|
601
|
+
const hasVitePlus = addons.includes("vite-plus");
|
|
602
|
+
const hasVitePlusNativeHooks = hasVitePlus && !addons.includes("husky") && !addons.includes("lefthook");
|
|
448
603
|
const dbSupport = getDbScriptSupport(config);
|
|
449
604
|
const needsDbScripts = dbSupport.hasDbScripts;
|
|
450
605
|
const isD1Alchemy = dbSupport.isD1Alchemy;
|
|
451
606
|
const pmConfig = getPackageManagerConfig(packageManager, {
|
|
452
607
|
hasTurborepo,
|
|
453
|
-
hasNx
|
|
608
|
+
hasNx,
|
|
609
|
+
hasVitePlus
|
|
454
610
|
});
|
|
455
611
|
scripts.dev = pmConfig.dev;
|
|
456
612
|
scripts.build = pmConfig.build;
|
|
457
613
|
scripts["check-types"] = pmConfig.checkTypes;
|
|
614
|
+
if (hasVitePlus) {
|
|
615
|
+
scripts.check = "vp check && vp run -r check-types";
|
|
616
|
+
scripts.lint = "vp lint";
|
|
617
|
+
scripts.format = "vp fmt";
|
|
618
|
+
scripts.staged = "vp staged";
|
|
619
|
+
if (hasVitePlusNativeHooks) scripts["hooks:setup"] = "vp config";
|
|
620
|
+
else delete scripts["hooks:setup"];
|
|
621
|
+
}
|
|
458
622
|
if (hasNativeApp) scripts["dev:native"] = pmConfig.filter("native", "dev");
|
|
459
623
|
if (hasWebApp) scripts["dev:web"] = pmConfig.filter("web", "dev");
|
|
460
624
|
if (addons.includes("electrobun")) {
|
|
@@ -477,7 +641,13 @@ function updateRootPackageJson(vfs, config) {
|
|
|
477
641
|
}
|
|
478
642
|
}
|
|
479
643
|
if (database === "sqlite" && dbSetup !== "d1") scripts["db:local"] = pmConfig.filter(dbPackageName, "db:local");
|
|
480
|
-
|
|
644
|
+
const hasDockerDeployScripts = config.webDeploy === "docker" || config.serverDeploy === "docker";
|
|
645
|
+
if (dbSetup === "docker") if (hasDockerDeployScripts) {
|
|
646
|
+
scripts["db:start"] = `docker compose up -d ${database}`;
|
|
647
|
+
scripts["db:watch"] = `docker compose up ${database}`;
|
|
648
|
+
scripts["db:stop"] = `docker compose stop ${database}`;
|
|
649
|
+
scripts["db:down"] = `docker compose down ${database}`;
|
|
650
|
+
} else {
|
|
481
651
|
scripts["db:start"] = pmConfig.filter(dbPackageName, "db:start");
|
|
482
652
|
scripts["db:watch"] = pmConfig.filter(dbPackageName, "db:watch");
|
|
483
653
|
scripts["db:stop"] = pmConfig.filter(dbPackageName, "db:stop");
|
|
@@ -488,11 +658,22 @@ function updateRootPackageJson(vfs, config) {
|
|
|
488
658
|
scripts.deploy = pmConfig.filter(infraPackageName, "deploy");
|
|
489
659
|
scripts.destroy = pmConfig.filter(infraPackageName, "destroy");
|
|
490
660
|
}
|
|
661
|
+
if (config.webDeploy === "docker" || config.serverDeploy === "docker") {
|
|
662
|
+
scripts["docker:build"] = "docker compose build";
|
|
663
|
+
scripts["docker:up"] = "docker compose up -d --build";
|
|
664
|
+
scripts["docker:down"] = "docker compose down";
|
|
665
|
+
scripts["docker:logs"] = "docker compose logs -f";
|
|
666
|
+
}
|
|
491
667
|
pkgJson.packageManager = `${packageManager}@latest`;
|
|
492
668
|
if (config.api === "orpc" && config.frontend.includes("nuxt")) pkgJson.overrides = {
|
|
493
669
|
...pkgJson.overrides,
|
|
494
670
|
"@vue/devtools-api": "^8.0.7"
|
|
495
671
|
};
|
|
672
|
+
if (hasVitePlus) pkgJson.overrides = {
|
|
673
|
+
...pkgJson.overrides,
|
|
674
|
+
vite: `npm:@voidzero-dev/vite-plus-core@${VITE_PLUS_VERSION}`,
|
|
675
|
+
vitest: `npm:@voidzero-dev/vite-plus-test@${VITE_PLUS_VERSION}`
|
|
676
|
+
};
|
|
496
677
|
if (backend === "convex") {
|
|
497
678
|
if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
|
|
498
679
|
if ((config.frontend.length > 0 || addons.includes("starlight")) && !workspaces.includes("apps/*")) workspaces.push("apps/*");
|
|
@@ -500,8 +681,21 @@ function updateRootPackageJson(vfs, config) {
|
|
|
500
681
|
if (!workspaces.includes("apps/*")) workspaces.push("apps/*");
|
|
501
682
|
if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
|
|
502
683
|
}
|
|
684
|
+
pkgJson.workspaces = getUpdatedWorkspaces(existingWorkspaces, workspaces);
|
|
503
685
|
vfs.writeJson("package.json", pkgJson);
|
|
504
686
|
}
|
|
687
|
+
function getWorkspacePackages(workspaces) {
|
|
688
|
+
if (Array.isArray(workspaces)) return workspaces;
|
|
689
|
+
if (workspaces && typeof workspaces === "object" && workspaces.packages) return workspaces.packages;
|
|
690
|
+
return [];
|
|
691
|
+
}
|
|
692
|
+
function getUpdatedWorkspaces(existingWorkspaces, packages) {
|
|
693
|
+
if (existingWorkspaces && !Array.isArray(existingWorkspaces) && typeof existingWorkspaces === "object" && existingWorkspaces.catalog) return {
|
|
694
|
+
...existingWorkspaces,
|
|
695
|
+
packages
|
|
696
|
+
};
|
|
697
|
+
return packages;
|
|
698
|
+
}
|
|
505
699
|
function getPackageManagerConfig(packageManager, options) {
|
|
506
700
|
if (options.hasTurborepo) return {
|
|
507
701
|
dev: "turbo dev",
|
|
@@ -515,6 +709,12 @@ function getPackageManagerConfig(packageManager, options) {
|
|
|
515
709
|
checkTypes: "nx run-many -t check-types",
|
|
516
710
|
filter: (workspace, script) => `nx run-many -t ${script} --projects=${workspace}`
|
|
517
711
|
};
|
|
712
|
+
if (options.hasVitePlus) return {
|
|
713
|
+
dev: "vp run -r dev",
|
|
714
|
+
build: "vp run -r build",
|
|
715
|
+
checkTypes: "vp run -r check-types",
|
|
716
|
+
filter: (workspace, script) => `vp run --filter ${workspace} ${script}`
|
|
717
|
+
};
|
|
518
718
|
switch (packageManager) {
|
|
519
719
|
case "pnpm": return {
|
|
520
720
|
dev: "pnpm -r dev",
|
|
@@ -542,14 +742,17 @@ function updateDesktopPackageJson(vfs, config) {
|
|
|
542
742
|
const { packageManager, addons, frontend } = config;
|
|
543
743
|
const hasTurborepo = addons.includes("turborepo");
|
|
544
744
|
const hasNx = addons.includes("nx");
|
|
745
|
+
const hasVitePlus = addons.includes("vite-plus");
|
|
545
746
|
const desktopBuildScript = frontend.includes("nuxt") ? "generate" : "build";
|
|
546
747
|
const webBuildCommand = getDesktopWebCommand(packageManager, {
|
|
547
748
|
hasTurborepo,
|
|
548
|
-
hasNx
|
|
749
|
+
hasNx,
|
|
750
|
+
hasVitePlus
|
|
549
751
|
}, desktopBuildScript);
|
|
550
752
|
const webDevCommand = getDesktopWebCommand(packageManager, {
|
|
551
753
|
hasTurborepo,
|
|
552
|
-
hasNx
|
|
754
|
+
hasNx,
|
|
755
|
+
hasVitePlus
|
|
553
756
|
}, "dev");
|
|
554
757
|
const localRunCommand = getLocalRunCommand(packageManager);
|
|
555
758
|
pkgJson.scripts = {
|
|
@@ -568,6 +771,7 @@ function updateDesktopPackageJson(vfs, config) {
|
|
|
568
771
|
function getDesktopWebCommand(packageManager, options, script) {
|
|
569
772
|
if (options.hasTurborepo) return `turbo -F web ${script}`;
|
|
570
773
|
if (options.hasNx) return `nx run-many -t ${script} --projects=web`;
|
|
774
|
+
if (options.hasVitePlus) return `vp run --filter web ${script}`;
|
|
571
775
|
switch (packageManager) {
|
|
572
776
|
case "npm": return `npm run ${script} --workspace web`;
|
|
573
777
|
case "pnpm": return `pnpm -w --filter web ${script}`;
|
|
@@ -607,7 +811,8 @@ function updateDbPackageJson(vfs, config) {
|
|
|
607
811
|
}
|
|
608
812
|
}
|
|
609
813
|
}
|
|
610
|
-
|
|
814
|
+
const hasDockerDeploy = config.webDeploy === "docker" || config.serverDeploy === "docker";
|
|
815
|
+
if (dbSetup === "docker" && !hasDockerDeploy) {
|
|
611
816
|
scripts["db:start"] = "docker compose up -d";
|
|
612
817
|
scripts["db:watch"] = "docker compose up";
|
|
613
818
|
scripts["db:stop"] = "docker compose stop";
|
|
@@ -691,153 +896,21 @@ function renameDevScriptsForAlchemy(vfs, config) {
|
|
|
691
896
|
}
|
|
692
897
|
}
|
|
693
898
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
"drizzle-kit": "^0.31.8",
|
|
710
|
-
"@planetscale/database": "^1.19.0",
|
|
711
|
-
"@libsql/client": "0.15.15",
|
|
712
|
-
libsql: "0.5.22",
|
|
713
|
-
"@neondatabase/serverless": "^1.0.2",
|
|
714
|
-
pg: "^8.17.1",
|
|
715
|
-
"@types/pg": "^8.16.0",
|
|
716
|
-
"@types/ws": "^8.18.1",
|
|
717
|
-
ws: "^8.18.3",
|
|
718
|
-
mysql2: "^3.14.0",
|
|
719
|
-
"@prisma/client": "^7.8.0",
|
|
720
|
-
prisma: "^7.8.0",
|
|
721
|
-
"@prisma/adapter-d1": "^7.8.0",
|
|
722
|
-
"@prisma/adapter-neon": "^7.8.0",
|
|
723
|
-
"@prisma/adapter-mariadb": "^7.8.0",
|
|
724
|
-
"@prisma/adapter-libsql": "^7.8.0",
|
|
725
|
-
"@prisma/adapter-better-sqlite3": "^7.8.0",
|
|
726
|
-
"@prisma/adapter-pg": "^7.8.0",
|
|
727
|
-
"@prisma/adapter-planetscale": "^7.8.0",
|
|
728
|
-
mongoose: "^9.6.2",
|
|
729
|
-
mongodb: "^7.2.0",
|
|
730
|
-
"vite-plugin-pwa": "^1.2.0",
|
|
731
|
-
"@vite-pwa/assets-generator": "^1.0.2",
|
|
732
|
-
"@tauri-apps/cli": "^2.4.0",
|
|
733
|
-
"@biomejs/biome": "^2.2.0",
|
|
734
|
-
oxlint: "^1.61.0",
|
|
735
|
-
oxfmt: "^0.46.0",
|
|
736
|
-
husky: "^9.1.7",
|
|
737
|
-
lefthook: "^2.0.13",
|
|
738
|
-
"lint-staged": "^16.1.2",
|
|
739
|
-
tsx: "^4.19.2",
|
|
740
|
-
"@types/node": "^22.13.14",
|
|
741
|
-
"@types/bun": "^1.3.4",
|
|
742
|
-
"@elysiajs/node": "^1.4.5",
|
|
743
|
-
"@elysiajs/cors": "^1.4.1",
|
|
744
|
-
"@elysiajs/trpc": "^1.1.0",
|
|
745
|
-
elysia: "^1.4.28",
|
|
746
|
-
"@sinclair/typebox": "^0.34.49",
|
|
747
|
-
"@hono/node-server": "^1.14.4",
|
|
748
|
-
"@hono/trpc-server": "^0.4.0",
|
|
749
|
-
hono: "^4.8.2",
|
|
750
|
-
cors: "^2.8.5",
|
|
751
|
-
express: "^5.1.0",
|
|
752
|
-
"@types/express": "^5.0.1",
|
|
753
|
-
"@types/cors": "^2.8.17",
|
|
754
|
-
fastify: "^5.3.3",
|
|
755
|
-
"@fastify/cors": "^11.0.1",
|
|
756
|
-
turbo: "^2.8.12",
|
|
757
|
-
nx: "^21.5.2",
|
|
758
|
-
ai: "^6.0.3",
|
|
759
|
-
"@ai-sdk/google": "^3.0.1",
|
|
760
|
-
"@ai-sdk/vue": "^3.0.3",
|
|
761
|
-
"@ai-sdk/svelte": "^4.0.3",
|
|
762
|
-
"@ai-sdk/react": "^3.0.3",
|
|
763
|
-
"@ai-sdk/devtools": "^0.0.2",
|
|
764
|
-
streamdown: "^1.6.10",
|
|
765
|
-
shiki: "^3.20.0",
|
|
766
|
-
"@orpc/server": "^1.13.14",
|
|
767
|
-
"@orpc/client": "^1.13.14",
|
|
768
|
-
"@orpc/openapi": "^1.13.14",
|
|
769
|
-
"@orpc/zod": "^1.13.14",
|
|
770
|
-
"@orpc/tanstack-query": "^1.13.14",
|
|
771
|
-
"@trpc/tanstack-react-query": "^11.16.0",
|
|
772
|
-
"@trpc/server": "^11.16.0",
|
|
773
|
-
"@trpc/client": "^11.16.0",
|
|
774
|
-
next: "^16.2.0",
|
|
775
|
-
nitro: "^3.0.260429-beta",
|
|
776
|
-
convex: "^1.33.1",
|
|
777
|
-
"@convex-dev/react-query": "^0.1.0",
|
|
778
|
-
"@convex-dev/agent": "^0.3.2",
|
|
779
|
-
"@convex-dev/polar": "^0.9.1",
|
|
780
|
-
"convex-svelte": "^0.0.12",
|
|
781
|
-
"convex-nuxt": "0.1.5",
|
|
782
|
-
"convex-vue": "^0.1.5",
|
|
783
|
-
"@convex-dev/better-auth": "^0.12.2",
|
|
784
|
-
"@tanstack/svelte-query": "^5.85.3",
|
|
785
|
-
"@tanstack/svelte-query-devtools": "^5.85.3",
|
|
786
|
-
"@tanstack/vue-query-devtools": "^6.1.5",
|
|
787
|
-
"@tanstack/vue-query": "^5.92.9",
|
|
788
|
-
"@tanstack/react-query-devtools": "^5.91.1",
|
|
789
|
-
"@tanstack/react-query": "^5.90.12",
|
|
790
|
-
"@tanstack/react-form": "^1.28.0",
|
|
791
|
-
"@tanstack/react-router-ssr-query": "^1.166.11",
|
|
792
|
-
"@tanstack/solid-form": "^1.28.0",
|
|
793
|
-
"@tanstack/svelte-form": "^1.28.0",
|
|
794
|
-
"@tanstack/solid-query": "^5.99.1",
|
|
795
|
-
"@tanstack/solid-query-devtools": "^5.99.1",
|
|
796
|
-
"@tanstack/solid-router-devtools": "^1.166.13",
|
|
797
|
-
wrangler: "^4.77.0",
|
|
798
|
-
"@cloudflare/vite-plugin": "^1.17.1",
|
|
799
|
-
"@opennextjs/cloudflare": "^1.17.3",
|
|
800
|
-
"nitro-cloudflare-dev": "^0.2.2",
|
|
801
|
-
"@sveltejs/adapter-cloudflare": "^7.2.8",
|
|
802
|
-
"@cloudflare/workers-types": "^4.20251213.0",
|
|
803
|
-
"@astrojs/cloudflare": "^13.0.1",
|
|
804
|
-
"@astrojs/node": "^10.0.0-beta.9",
|
|
805
|
-
alchemy: "^0.91.2",
|
|
806
|
-
dotenv: "^17.2.2",
|
|
807
|
-
tsdown: "^0.21.9",
|
|
808
|
-
zod: "^4.1.13",
|
|
809
|
-
"@t3-oss/env-core": "^0.13.1",
|
|
810
|
-
"@t3-oss/env-nextjs": "^0.13.1",
|
|
811
|
-
"@t3-oss/env-nuxt": "^0.13.1",
|
|
812
|
-
"@polar-sh/better-auth": "^1.8.4",
|
|
813
|
-
"@polar-sh/checkout": "^0.2.1",
|
|
814
|
-
"@polar-sh/sdk": "^0.47.1",
|
|
815
|
-
"@stripe/react-stripe-js": "^4.0.2",
|
|
816
|
-
"@stripe/stripe-js": "^7.9.0",
|
|
817
|
-
evlog: "^2.14.1"
|
|
818
|
-
};
|
|
819
|
-
/**
|
|
820
|
-
* Add dependencies to a package.json file in the VFS
|
|
821
|
-
*/
|
|
822
|
-
function addPackageDependency(options) {
|
|
823
|
-
const { vfs, packagePath, dependencies = [], devDependencies = [], customDependencies = {}, customDevDependencies = {} } = options;
|
|
824
|
-
const pkgJson = vfs.readJson(packagePath);
|
|
825
|
-
if (!pkgJson) return;
|
|
826
|
-
pkgJson.dependencies = pkgJson.dependencies || {};
|
|
827
|
-
pkgJson.devDependencies = pkgJson.devDependencies || {};
|
|
828
|
-
for (const dep of dependencies) if (!pkgJson.dependencies[dep]) {
|
|
829
|
-
const version = dependencyVersionMap[dep];
|
|
830
|
-
if (!version) throw new Error(`Missing version for dependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
|
|
831
|
-
pkgJson.dependencies[dep] = version;
|
|
832
|
-
}
|
|
833
|
-
for (const dep of devDependencies) if (!pkgJson.devDependencies[dep]) {
|
|
834
|
-
const version = dependencyVersionMap[dep];
|
|
835
|
-
if (!version) throw new Error(`Missing version for devDependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
|
|
836
|
-
pkgJson.devDependencies[dep] = version;
|
|
837
|
-
}
|
|
838
|
-
for (const [dep, version] of Object.entries(customDependencies)) pkgJson.dependencies[dep] = version;
|
|
839
|
-
for (const [dep, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[dep] = version;
|
|
840
|
-
vfs.writeJson(packagePath, pkgJson);
|
|
899
|
+
function updateVitePlusPackageScripts(vfs, config) {
|
|
900
|
+
if (!config.addons.includes("vite-plus")) return;
|
|
901
|
+
const webPkgPath = "apps/web/package.json";
|
|
902
|
+
const webPkg = vfs.readJson(webPkgPath);
|
|
903
|
+
if (!webPkg?.scripts) return;
|
|
904
|
+
const viteScriptReplacements = {
|
|
905
|
+
vite: "vp dev",
|
|
906
|
+
"vite dev": "vp dev",
|
|
907
|
+
"vite build": "vp build",
|
|
908
|
+
"vite preview": "vp preview",
|
|
909
|
+
"vitest run": "vp test",
|
|
910
|
+
"vite build && tsc --noEmit": "vp build && tsc --noEmit"
|
|
911
|
+
};
|
|
912
|
+
for (const [scriptName, command] of Object.entries(webPkg.scripts)) webPkg.scripts[scriptName] = viteScriptReplacements[command] ?? command;
|
|
913
|
+
vfs.writeJson(webPkgPath, webPkg);
|
|
841
914
|
}
|
|
842
915
|
//#endregion
|
|
843
916
|
//#region src/processors/addons-deps.ts
|
|
@@ -863,6 +936,11 @@ function processAddonsDeps(vfs, config) {
|
|
|
863
936
|
packagePath: "package.json",
|
|
864
937
|
devDependencies: ["nx"]
|
|
865
938
|
});
|
|
939
|
+
if (config.addons.includes("vite-plus")) addPackageDependency({
|
|
940
|
+
vfs,
|
|
941
|
+
packagePath: "package.json",
|
|
942
|
+
devDependencies: ["vite-plus", "rolldown"]
|
|
943
|
+
});
|
|
866
944
|
if (config.addons.includes("evlog")) {
|
|
867
945
|
const serverPkgPath = "apps/server/package.json";
|
|
868
946
|
if (vfs.exists(serverPkgPath) && config.backend !== "self" && config.backend !== "none") addPackageDependency({
|
|
@@ -1959,8 +2037,24 @@ function processDeployDeps(vfs, config) {
|
|
|
1959
2037
|
const { webDeploy, serverDeploy, frontend, backend } = config;
|
|
1960
2038
|
const isCloudflareWeb = webDeploy === "cloudflare";
|
|
1961
2039
|
const isCloudflareServer = serverDeploy === "cloudflare";
|
|
2040
|
+
const isDockerWeb = webDeploy === "docker";
|
|
1962
2041
|
const isBackendSelf = backend === "self";
|
|
1963
|
-
if (!isCloudflareWeb && !isCloudflareServer) return;
|
|
2042
|
+
if (!isCloudflareWeb && !isCloudflareServer && !isDockerWeb) return;
|
|
2043
|
+
if (isDockerWeb) {
|
|
2044
|
+
const webPkgPath = "apps/web/package.json";
|
|
2045
|
+
if (vfs.exists(webPkgPath)) {
|
|
2046
|
+
if (frontend.includes("svelte")) addPackageDependency({
|
|
2047
|
+
vfs,
|
|
2048
|
+
packagePath: webPkgPath,
|
|
2049
|
+
devDependencies: ["@sveltejs/adapter-node"]
|
|
2050
|
+
});
|
|
2051
|
+
else if (frontend.includes("tanstack-start")) addPackageDependency({
|
|
2052
|
+
vfs,
|
|
2053
|
+
packagePath: webPkgPath,
|
|
2054
|
+
dependencies: ["nitro"]
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
1964
2058
|
if (isCloudflareWeb || isCloudflareServer) addPackageDependency({
|
|
1965
2059
|
vfs,
|
|
1966
2060
|
packagePath: "package.json",
|
|
@@ -2568,6 +2662,86 @@ function processInfraDeps(vfs, config) {
|
|
|
2568
2662
|
});
|
|
2569
2663
|
}
|
|
2570
2664
|
//#endregion
|
|
2665
|
+
//#region src/utils/generated-ignore-patterns.ts
|
|
2666
|
+
const FRONTEND_GENERATED_PATTERNS = {
|
|
2667
|
+
"tanstack-router": [
|
|
2668
|
+
"apps/web/dist/**",
|
|
2669
|
+
"apps/web/.tanstack/**",
|
|
2670
|
+
"apps/web/src/routeTree.gen.ts"
|
|
2671
|
+
],
|
|
2672
|
+
"react-router": ["apps/web/build/**", "apps/web/.react-router/**"],
|
|
2673
|
+
"tanstack-start": [
|
|
2674
|
+
"apps/web/dist/**",
|
|
2675
|
+
"apps/web/.vinxi/**",
|
|
2676
|
+
"apps/web/.tanstack/**",
|
|
2677
|
+
"apps/web/src/routeTree.gen.ts"
|
|
2678
|
+
],
|
|
2679
|
+
next: ["apps/web/.next/**", "apps/web/out/**"],
|
|
2680
|
+
nuxt: [
|
|
2681
|
+
"apps/web/.nuxt/**",
|
|
2682
|
+
"apps/web/.output/**",
|
|
2683
|
+
"apps/web/.data/**",
|
|
2684
|
+
"apps/web/.nitro/**"
|
|
2685
|
+
],
|
|
2686
|
+
svelte: [
|
|
2687
|
+
"apps/web/.svelte-kit/**",
|
|
2688
|
+
"apps/web/build/**",
|
|
2689
|
+
"apps/web/.output/**"
|
|
2690
|
+
],
|
|
2691
|
+
solid: [
|
|
2692
|
+
"apps/web/dist/**",
|
|
2693
|
+
"apps/web/.tanstack/**",
|
|
2694
|
+
"apps/web/src/routeTree.gen.ts"
|
|
2695
|
+
],
|
|
2696
|
+
astro: ["apps/web/dist/**", "apps/web/.astro/**"],
|
|
2697
|
+
"native-bare": [
|
|
2698
|
+
"apps/native/.expo/**",
|
|
2699
|
+
"apps/native/dist/**",
|
|
2700
|
+
"apps/native/web-build/**"
|
|
2701
|
+
],
|
|
2702
|
+
"native-uniwind": [
|
|
2703
|
+
"apps/native/.expo/**",
|
|
2704
|
+
"apps/native/dist/**",
|
|
2705
|
+
"apps/native/web-build/**"
|
|
2706
|
+
],
|
|
2707
|
+
"native-unistyles": [
|
|
2708
|
+
"apps/native/.expo/**",
|
|
2709
|
+
"apps/native/dist/**",
|
|
2710
|
+
"apps/native/web-build/**",
|
|
2711
|
+
"apps/native/ios/**",
|
|
2712
|
+
"apps/native/android/**"
|
|
2713
|
+
]
|
|
2714
|
+
};
|
|
2715
|
+
const SERVER_BUILD_BACKENDS = [
|
|
2716
|
+
"hono",
|
|
2717
|
+
"express",
|
|
2718
|
+
"fastify",
|
|
2719
|
+
"elysia"
|
|
2720
|
+
];
|
|
2721
|
+
function getStackGeneratedIgnorePatterns(config) {
|
|
2722
|
+
const patterns = /* @__PURE__ */ new Set();
|
|
2723
|
+
for (const frontend of config.frontend) {
|
|
2724
|
+
const frontendPatterns = FRONTEND_GENERATED_PATTERNS[frontend];
|
|
2725
|
+
if (!frontendPatterns) continue;
|
|
2726
|
+
for (const pattern of frontendPatterns) patterns.add(pattern);
|
|
2727
|
+
}
|
|
2728
|
+
if (SERVER_BUILD_BACKENDS.includes(config.backend)) patterns.add("apps/server/dist/**");
|
|
2729
|
+
if (config.database !== "none" && config.orm !== "none") patterns.add("packages/db/dist/**");
|
|
2730
|
+
if (config.database === "sqlite" && config.dbSetup !== "d1" && config.orm !== "none") patterns.add("packages/db/local.db*");
|
|
2731
|
+
if (config.orm === "prisma") {
|
|
2732
|
+
patterns.add("packages/db/prisma/generated/**");
|
|
2733
|
+
if (config.database === "sqlite" && config.dbSetup === "turso") patterns.add("packages/db/prisma/**/*.db*");
|
|
2734
|
+
}
|
|
2735
|
+
if (config.backend === "convex") patterns.add("packages/backend/convex/_generated/**");
|
|
2736
|
+
if (config.runtime === "workers" || config.dbSetup === "d1" || config.webDeploy === "cloudflare" || config.serverDeploy === "cloudflare") {
|
|
2737
|
+
patterns.add(".alchemy/**");
|
|
2738
|
+
patterns.add(".wrangler/**");
|
|
2739
|
+
patterns.add("**/.wrangler/**");
|
|
2740
|
+
if (config.frontend.includes("next")) patterns.add("apps/web/.open-next/**");
|
|
2741
|
+
}
|
|
2742
|
+
return [...patterns];
|
|
2743
|
+
}
|
|
2744
|
+
//#endregion
|
|
2571
2745
|
//#region src/processors/nx-generator.ts
|
|
2572
2746
|
function processNxConfig(vfs, config) {
|
|
2573
2747
|
if (!config.addons.includes("nx")) return;
|
|
@@ -2582,35 +2756,40 @@ function generateNxConfig(config) {
|
|
|
2582
2756
|
const isDocker = dbSetup === "docker";
|
|
2583
2757
|
const isSqliteLocal = database === "sqlite" && dbSetup !== "d1" && hasDatabase;
|
|
2584
2758
|
const hasCloudflare = webDeploy === "cloudflare" || serverDeploy === "cloudflare";
|
|
2759
|
+
const targetDefaults = {
|
|
2760
|
+
build: {
|
|
2761
|
+
dependsOn: ["^build"],
|
|
2762
|
+
inputs: ["production", "^production"]
|
|
2763
|
+
},
|
|
2764
|
+
"check-types": {
|
|
2765
|
+
dependsOn: ["^check-types"],
|
|
2766
|
+
inputs: ["default", "^default"]
|
|
2767
|
+
},
|
|
2768
|
+
dev: { cache: false },
|
|
2769
|
+
...isConvex ? getConvexTargets() : {},
|
|
2770
|
+
...!isConvex && hasDatabase ? getDatabaseTargets(dbSupport) : {},
|
|
2771
|
+
...isDocker ? getDockerTargets() : {},
|
|
2772
|
+
...isSqliteLocal ? getSqliteLocalTarget() : {},
|
|
2773
|
+
...hasCloudflare ? getDeployTargets() : {}
|
|
2774
|
+
};
|
|
2585
2775
|
return {
|
|
2586
2776
|
$schema: "./node_modules/nx/schemas/nx-schema.json",
|
|
2587
2777
|
namedInputs: {
|
|
2588
2778
|
default: ["{projectRoot}/**/*", "sharedGlobals"],
|
|
2589
2779
|
production: [
|
|
2590
2780
|
"default",
|
|
2781
|
+
...getNxProductionInputExclusions(config),
|
|
2591
2782
|
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
|
|
2592
2783
|
"!{projectRoot}/tsconfig.spec.json"
|
|
2593
2784
|
],
|
|
2594
2785
|
sharedGlobals: []
|
|
2595
2786
|
},
|
|
2596
|
-
targetDefaults
|
|
2597
|
-
build: {
|
|
2598
|
-
dependsOn: ["^build"],
|
|
2599
|
-
inputs: ["production", "^production"]
|
|
2600
|
-
},
|
|
2601
|
-
"check-types": {
|
|
2602
|
-
dependsOn: ["^check-types"],
|
|
2603
|
-
inputs: ["default", "^default"]
|
|
2604
|
-
},
|
|
2605
|
-
dev: { cache: false },
|
|
2606
|
-
...isConvex ? getConvexTargets() : {},
|
|
2607
|
-
...!isConvex && hasDatabase ? getDatabaseTargets(dbSupport) : {},
|
|
2608
|
-
...isDocker ? getDockerTargets() : {},
|
|
2609
|
-
...isSqliteLocal ? getSqliteLocalTarget() : {},
|
|
2610
|
-
...hasCloudflare ? getDeployTargets() : {}
|
|
2611
|
-
}
|
|
2787
|
+
targetDefaults
|
|
2612
2788
|
};
|
|
2613
2789
|
}
|
|
2790
|
+
function getNxProductionInputExclusions(config) {
|
|
2791
|
+
return getStackGeneratedIgnorePatterns(config).map((pattern) => `!{workspaceRoot}/${pattern}`);
|
|
2792
|
+
}
|
|
2614
2793
|
function getConvexTargets() {
|
|
2615
2794
|
return { "dev:setup": { cache: false } };
|
|
2616
2795
|
}
|
|
@@ -3102,7 +3281,8 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
|
|
|
3102
3281
|
husky: "- **Husky** - Git hooks for code quality",
|
|
3103
3282
|
starlight: "- **Starlight** - Documentation site with Astro",
|
|
3104
3283
|
turborepo: "- **Turborepo** - Optimized monorepo build system",
|
|
3105
|
-
nx: "- **Nx** - Smart monorepo task orchestration and caching"
|
|
3284
|
+
nx: "- **Nx** - Smart monorepo task orchestration and caching",
|
|
3285
|
+
"vite-plus": "- **Vite+** - Unified Vite toolchain, workspace task runner, linting, and formatting"
|
|
3106
3286
|
};
|
|
3107
3287
|
for (const addon of addons) if (addonFeatures[addon]) features.push(addonFeatures[addon]);
|
|
3108
3288
|
return features.join("\n");
|
|
@@ -3173,7 +3353,7 @@ ${packageManagerRunCmd} db:push
|
|
|
3173
3353
|
return setup;
|
|
3174
3354
|
}
|
|
3175
3355
|
function generateScriptsList(packageManagerRunCmd, config, hasNative) {
|
|
3176
|
-
const { database, addons, backend, dbSetup, frontend } = config;
|
|
3356
|
+
const { database, addons, backend, dbSetup, frontend, webDeploy, serverDeploy } = config;
|
|
3177
3357
|
const isConvex = backend === "convex";
|
|
3178
3358
|
const isBackendSelf = backend === "self";
|
|
3179
3359
|
const hasWeb = frontend.some((f) => [
|
|
@@ -3201,8 +3381,15 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
|
|
|
3201
3381
|
if (dbSupport.hasDbStudio) scripts += `\n- \`${packageManagerRunCmd} db:studio\`: Open database studio UI`;
|
|
3202
3382
|
}
|
|
3203
3383
|
if (database === "sqlite" && dbSetup !== "d1" && dbSupport.hasDbScripts) scripts += `\n- \`${packageManagerRunCmd} db:local\`: Start the local SQLite database`;
|
|
3204
|
-
if (addons.includes("
|
|
3205
|
-
|
|
3384
|
+
if (addons.includes("vite-plus")) {
|
|
3385
|
+
const hasVitePlusNativeHooks = !addons.includes("husky") && !addons.includes("lefthook");
|
|
3386
|
+
scripts += `\n- \`${packageManagerRunCmd} check\`: Run Vite+ format/lint checks and workspace TypeScript checks
|
|
3387
|
+
- \`${packageManagerRunCmd} lint\`: Run Vite+ lint checks
|
|
3388
|
+
- \`${packageManagerRunCmd} format\`: Run Vite+ formatting
|
|
3389
|
+
- \`${packageManagerRunCmd} staged\`: Run Vite+ checks against staged files`;
|
|
3390
|
+
if (hasVitePlusNativeHooks) scripts += `\n- \`${packageManagerRunCmd} hooks:setup\`: Install Vite+ native Git hooks with \`vp config\``;
|
|
3391
|
+
} else if (addons.includes("biome")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
|
|
3392
|
+
else if (addons.includes("oxlint")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Oxlint and Oxfmt`;
|
|
3206
3393
|
if (addons.includes("pwa")) scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} generate-pwa-assets\`: Generate PWA assets`;
|
|
3207
3394
|
if (addons.includes("tauri")) {
|
|
3208
3395
|
scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} desktop:dev\`: Start Tauri desktop app in development
|
|
@@ -3219,23 +3406,38 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
|
|
|
3219
3406
|
}
|
|
3220
3407
|
if (addons.includes("starlight")) scripts += `\n- \`cd apps/docs && ${packageManagerRunCmd} dev\`: Start documentation site
|
|
3221
3408
|
- \`cd apps/docs && ${packageManagerRunCmd} build\`: Build documentation site`;
|
|
3409
|
+
if (webDeploy === "docker" || serverDeploy === "docker") scripts += `\n- \`${packageManagerRunCmd} docker:build\`: Build the Docker Compose images
|
|
3410
|
+
- \`${packageManagerRunCmd} docker:up\`: Build and start the Docker Compose stack
|
|
3411
|
+
- \`${packageManagerRunCmd} docker:logs\`: Tail logs from the Docker Compose stack
|
|
3412
|
+
- \`${packageManagerRunCmd} docker:down\`: Stop the Docker Compose stack`;
|
|
3222
3413
|
return scripts;
|
|
3223
3414
|
}
|
|
3224
3415
|
function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy, backend) {
|
|
3225
|
-
|
|
3226
|
-
const
|
|
3227
|
-
|
|
3228
|
-
lines
|
|
3229
|
-
|
|
3416
|
+
const hasCloudflare = webDeploy === "cloudflare" || serverDeploy === "cloudflare";
|
|
3417
|
+
const hasDocker = webDeploy === "docker" || serverDeploy === "docker";
|
|
3418
|
+
if (!hasCloudflare && !hasDocker) return "";
|
|
3419
|
+
const lines = ["## Deployment"];
|
|
3420
|
+
if (hasCloudflare) {
|
|
3421
|
+
const targetLabel = webDeploy === "cloudflare" && (serverDeploy === "cloudflare" || backend === "self") ? "web + server" : webDeploy === "cloudflare" ? "web" : "server";
|
|
3422
|
+
lines.push("", "### Cloudflare via Alchemy", "", `- Target: ${targetLabel}`, `- Dev: ${packageManagerRunCmd} dev`, `- Deploy: ${packageManagerRunCmd} deploy`, `- 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).");
|
|
3423
|
+
}
|
|
3424
|
+
if (hasDocker) {
|
|
3425
|
+
const targetLabel = webDeploy === "docker" && (serverDeploy === "docker" || backend === "self") ? "web + server" : webDeploy === "docker" ? "web" : "server";
|
|
3426
|
+
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.");
|
|
3427
|
+
}
|
|
3230
3428
|
return `${lines.join("\n")}\n`;
|
|
3231
3429
|
}
|
|
3232
3430
|
function generateGitHooksSection(packageManagerRunCmd, addons) {
|
|
3233
3431
|
const hasHusky = addons.includes("husky");
|
|
3234
|
-
const
|
|
3432
|
+
const hasLefthook = addons.includes("lefthook");
|
|
3433
|
+
const hasVitePlus = addons.includes("vite-plus");
|
|
3434
|
+
const hasVitePlusNativeHooks = hasVitePlus && !hasHusky && !hasLefthook;
|
|
3435
|
+
const hasLinting = addons.includes("biome") || addons.includes("oxlint") || hasVitePlus;
|
|
3235
3436
|
if (!hasHusky && !hasLinting) return "";
|
|
3236
3437
|
const lines = ["## Git Hooks and Formatting", ""];
|
|
3237
3438
|
if (hasHusky) lines.push(`- Initialize hooks: \`${packageManagerRunCmd} prepare\``);
|
|
3238
|
-
if (
|
|
3439
|
+
if (hasVitePlusNativeHooks) lines.push(`- Optional native Vite+ hooks: \`${packageManagerRunCmd} hooks:setup\``, "- Docs: [Vite+ commit hooks](https://viteplus.dev/guide/commit-hooks)");
|
|
3440
|
+
if (hasLinting) lines.push(`- Run checks: \`${packageManagerRunCmd} check\``);
|
|
3239
3441
|
return `${lines.join("\n")}\n\n`;
|
|
3240
3442
|
}
|
|
3241
3443
|
//#endregion
|
|
@@ -3369,6 +3571,51 @@ function getDeployTasks() {
|
|
|
3369
3571
|
};
|
|
3370
3572
|
}
|
|
3371
3573
|
//#endregion
|
|
3574
|
+
//#region src/processors/vite-plus-generator.ts
|
|
3575
|
+
const BASE_IGNORE_PATTERNS = ["node_modules/**", "**/node_modules/**"];
|
|
3576
|
+
const STAGED_PATTERN = "*.{js,ts,jsx,tsx,vue,svelte,json,jsonc,css,md}";
|
|
3577
|
+
function processVitePlusConfig(vfs, config) {
|
|
3578
|
+
if (!config.addons.includes("vite-plus")) return;
|
|
3579
|
+
vfs.writeFile("vite.config.ts", generateVitePlusConfig(config));
|
|
3580
|
+
}
|
|
3581
|
+
function formatStringArray(values, indent = 4) {
|
|
3582
|
+
const spaces = " ".repeat(indent);
|
|
3583
|
+
return values.map((value) => `${spaces}${JSON.stringify(value)},`).join("\n");
|
|
3584
|
+
}
|
|
3585
|
+
function getVitePlusIgnorePatterns(config) {
|
|
3586
|
+
const patterns = new Set(BASE_IGNORE_PATTERNS);
|
|
3587
|
+
for (const pattern of getStackGeneratedIgnorePatterns(config)) patterns.add(pattern);
|
|
3588
|
+
return [...patterns];
|
|
3589
|
+
}
|
|
3590
|
+
function generateVitePlusConfig(config) {
|
|
3591
|
+
const ignorePatterns = formatStringArray(getVitePlusIgnorePatterns(config), 6);
|
|
3592
|
+
return `import { defineConfig } from "vite-plus";
|
|
3593
|
+
|
|
3594
|
+
export default defineConfig({
|
|
3595
|
+
lint: {
|
|
3596
|
+
ignorePatterns: [
|
|
3597
|
+
${ignorePatterns}
|
|
3598
|
+
],
|
|
3599
|
+
options: {
|
|
3600
|
+
typeAware: false,
|
|
3601
|
+
typeCheck: false,
|
|
3602
|
+
},
|
|
3603
|
+
},
|
|
3604
|
+
fmt: {
|
|
3605
|
+
ignorePatterns: [
|
|
3606
|
+
${ignorePatterns}
|
|
3607
|
+
],
|
|
3608
|
+
singleQuote: false,
|
|
3609
|
+
semi: true,
|
|
3610
|
+
sortPackageJson: true,
|
|
3611
|
+
},
|
|
3612
|
+
staged: {
|
|
3613
|
+
${JSON.stringify(STAGED_PATTERN)}: "vp check --fix",
|
|
3614
|
+
},
|
|
3615
|
+
});
|
|
3616
|
+
`;
|
|
3617
|
+
}
|
|
3618
|
+
//#endregion
|
|
3372
3619
|
//#region src/processors/workspace-deps.ts
|
|
3373
3620
|
function processWorkspaceDeps(vfs, config) {
|
|
3374
3621
|
const { projectName, packageManager, runtime, backend, database, auth, api, serverDeploy, webDeploy } = config;
|
|
@@ -3533,6 +3780,7 @@ function processDependencies(vfs, config) {
|
|
|
3533
3780
|
processExamplesDeps(vfs, config);
|
|
3534
3781
|
processTurboConfig(vfs, config);
|
|
3535
3782
|
processNxConfig(vfs, config);
|
|
3783
|
+
processVitePlusConfig(vfs, config);
|
|
3536
3784
|
}
|
|
3537
3785
|
//#endregion
|
|
3538
3786
|
//#region src/template-handlers/utils.ts
|
|
@@ -3626,7 +3874,8 @@ async function processDbTemplates(vfs, templates, config) {
|
|
|
3626
3874
|
processTemplatesFromPrefix(vfs, templates, "db/base", "packages/db", config);
|
|
3627
3875
|
processTemplatesFromPrefix(vfs, templates, `db/${config.orm}/base`, "packages/db", config);
|
|
3628
3876
|
processTemplatesFromPrefix(vfs, templates, `db/${config.orm}/${config.database}`, "packages/db", config);
|
|
3629
|
-
|
|
3877
|
+
const hasDockerDeploy = config.webDeploy === "docker" || config.serverDeploy === "docker";
|
|
3878
|
+
if (config.dbSetup === "docker" && !hasDockerDeploy) processTemplatesFromPrefix(vfs, templates, `db-setup/docker-compose/${config.database}`, "packages/db", config);
|
|
3630
3879
|
}
|
|
3631
3880
|
//#endregion
|
|
3632
3881
|
//#region src/template-handlers/api.ts
|
|
@@ -3842,7 +4091,7 @@ async function processAddonTemplates(vfs, templates, config) {
|
|
|
3842
4091
|
if (!config.addons || config.addons.length === 0) return;
|
|
3843
4092
|
for (const addon of config.addons) {
|
|
3844
4093
|
if (addon === "none") continue;
|
|
3845
|
-
if (addon === "turborepo" || addon === "nx") continue;
|
|
4094
|
+
if (addon === "turborepo" || addon === "nx" || addon === "vite-plus") continue;
|
|
3846
4095
|
if (addon === "pwa") {
|
|
3847
4096
|
if (config.frontend.includes("next")) processTemplatesFromPrefix(vfs, templates, "addons/pwa/apps/web/next", "apps/web", config);
|
|
3848
4097
|
else if (config.frontend.some((f) => [
|
|
@@ -3927,6 +4176,7 @@ async function processExtrasTemplates(vfs, templates, config) {
|
|
|
3927
4176
|
async function processDeployTemplates(vfs, templates, config) {
|
|
3928
4177
|
const isBackendSelf = config.backend === "self";
|
|
3929
4178
|
if (config.webDeploy === "cloudflare" || config.serverDeploy === "cloudflare") processTemplatesFromPrefix(vfs, templates, "packages/infra", "packages/infra", config);
|
|
4179
|
+
if (config.webDeploy === "docker" || config.serverDeploy === "docker") processTemplatesFromPrefix(vfs, templates, "deploy/docker/compose", "", config);
|
|
3930
4180
|
if (config.webDeploy !== "none" && config.webDeploy !== "cloudflare") {
|
|
3931
4181
|
const templateMap = {
|
|
3932
4182
|
"tanstack-router": "react/tanstack-router",
|
|
@@ -3935,7 +4185,8 @@ async function processDeployTemplates(vfs, templates, config) {
|
|
|
3935
4185
|
solid: "solid",
|
|
3936
4186
|
next: "react/next",
|
|
3937
4187
|
nuxt: "nuxt",
|
|
3938
|
-
svelte: "svelte"
|
|
4188
|
+
svelte: "svelte",
|
|
4189
|
+
astro: "astro"
|
|
3939
4190
|
};
|
|
3940
4191
|
for (const f of config.frontend) if (templateMap[f]) processTemplatesFromPrefix(vfs, templates, `deploy/${config.webDeploy}/web/${templateMap[f]}`, "apps/web", config);
|
|
3941
4192
|
}
|
|
@@ -4195,11 +4446,11 @@ export default {
|
|
|
4195
4446
|
"type": "module",
|
|
4196
4447
|
"scripts": {},
|
|
4197
4448
|
"dependencies": {
|
|
4198
|
-
"electrobun": "^1.
|
|
4449
|
+
"electrobun": "^1.18.1"
|
|
4199
4450
|
},
|
|
4200
4451
|
"devDependencies": {
|
|
4201
|
-
"@types/bun": "^1.3.
|
|
4202
|
-
"concurrently": "^
|
|
4452
|
+
"@types/bun": "^1.3.14",
|
|
4453
|
+
"concurrently": "^10.0.3",
|
|
4203
4454
|
"typescript": "^6"
|
|
4204
4455
|
}
|
|
4205
4456
|
}
|
|
@@ -4277,6 +4528,10 @@ pre-commit:
|
|
|
4277
4528
|
- name: oxfmt
|
|
4278
4529
|
run: {{packageManager}} oxfmt --write {staged_files}
|
|
4279
4530
|
stage_fixed: true
|
|
4531
|
+
{{else if (includes addons "vite-plus")}}
|
|
4532
|
+
- name: vite-plus
|
|
4533
|
+
run: {{packageManager}} vp staged
|
|
4534
|
+
stage_fixed: true
|
|
4280
4535
|
{{else}}
|
|
4281
4536
|
# Add your pre-commit commands here
|
|
4282
4537
|
# Example:
|
|
@@ -5319,7 +5574,9 @@ import { createTanstackQueryUtils } from "@orpc/tanstack-query";
|
|
|
5319
5574
|
|
|
5320
5575
|
export default defineNuxtPlugin(() => {
|
|
5321
5576
|
const config = useRuntimeConfig();
|
|
5322
|
-
const
|
|
5577
|
+
const serverUrl =
|
|
5578
|
+
(import.meta.server && config.serverUrl) || config.public.serverUrl;
|
|
5579
|
+
const rpcUrl = \`\${serverUrl}/rpc\`;
|
|
5323
5580
|
|
|
5324
5581
|
const rpcLink = new RPCLink({
|
|
5325
5582
|
url: rpcUrl,
|
|
@@ -13565,7 +13822,7 @@ export default defineNuxtPlugin(() => {
|
|
|
13565
13822
|
|
|
13566
13823
|
const authClient = createAuthClient({
|
|
13567
13824
|
{{#if (ne backend "self")}}
|
|
13568
|
-
baseURL: config.public.serverUrl,
|
|
13825
|
+
baseURL: (import.meta.server && config.serverUrl) || config.public.serverUrl,
|
|
13569
13826
|
{{/if}}
|
|
13570
13827
|
{{#if (eq payments "polar")}}
|
|
13571
13828
|
plugins: [polarClient()],
|
|
@@ -18800,7 +19057,7 @@ fastify.get('/', async () => {
|
|
|
18800
19057
|
return 'OK';
|
|
18801
19058
|
});
|
|
18802
19059
|
|
|
18803
|
-
fastify.listen({ port: 3000 }, (err) => {
|
|
19060
|
+
fastify.listen({ port: 3000{{#if (eq serverDeploy "docker")}}, host: "0.0.0.0"{{/if}} }, (err) => {
|
|
18804
19061
|
if (err) {
|
|
18805
19062
|
fastify.log.error(err);
|
|
18806
19063
|
process.exit(1);
|
|
@@ -19028,6 +19285,9 @@ dist
|
|
|
19028
19285
|
build
|
|
19029
19286
|
*.tsbuildinfo
|
|
19030
19287
|
|
|
19288
|
+
# Generated files
|
|
19289
|
+
apps/web/src/routeTree.gen.ts
|
|
19290
|
+
|
|
19031
19291
|
# Environment variables
|
|
19032
19292
|
.env
|
|
19033
19293
|
.env*.local
|
|
@@ -19876,6 +20136,710 @@ const prisma = createPrismaClient();
|
|
|
19876
20136
|
export default prisma;
|
|
19877
20137
|
{{/if}}
|
|
19878
20138
|
{{/if}}
|
|
20139
|
+
`],
|
|
20140
|
+
["deploy/docker/compose/_dockerignore", `**/node_modules
|
|
20141
|
+
.git
|
|
20142
|
+
|
|
20143
|
+
**/dist
|
|
20144
|
+
**/build
|
|
20145
|
+
**/.next
|
|
20146
|
+
**/.nuxt
|
|
20147
|
+
**/.output
|
|
20148
|
+
**/.svelte-kit
|
|
20149
|
+
**/.astro
|
|
20150
|
+
**/.turbo
|
|
20151
|
+
.turbo
|
|
20152
|
+
|
|
20153
|
+
**/.wrangler
|
|
20154
|
+
**/.alchemy
|
|
20155
|
+
**/.expo
|
|
20156
|
+
**/.vercel
|
|
20157
|
+
*.log
|
|
20158
|
+
|
|
20159
|
+
Dockerfile
|
|
20160
|
+
**/Dockerfile
|
|
20161
|
+
docker-compose.yml
|
|
20162
|
+
|
|
20163
|
+
# Secrets stay out of image layers; runtime env comes from compose env_file,
|
|
20164
|
+
# build-time public values come from compose build args
|
|
20165
|
+
**/.env
|
|
20166
|
+
**/.env.*
|
|
20167
|
+
!**/.env.example
|
|
20168
|
+
`],
|
|
20169
|
+
["deploy/docker/compose/docker-compose.yml.hbs", `name: {{projectName}}
|
|
20170
|
+
|
|
20171
|
+
services:
|
|
20172
|
+
{{#if (eq webDeploy "docker")}}
|
|
20173
|
+
web:
|
|
20174
|
+
build:
|
|
20175
|
+
context: .
|
|
20176
|
+
dockerfile: apps/web/Dockerfile
|
|
20177
|
+
{{#if (and (not (includes frontend "nuxt")) (or (and (ne backend "self") (ne backend "none") (ne backend "convex")) (eq backend "convex") (and (eq auth "clerk") (or (includes frontend "next") (includes frontend "react-router") (includes frontend "tanstack-router") (includes frontend "tanstack-start")))))}}
|
|
20178
|
+
args:
|
|
20179
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20180
|
+
{{#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
|
|
20181
|
+
{{/if}}
|
|
20182
|
+
{{#if (eq backend "convex")}}
|
|
20183
|
+
{{#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}}: \${CONVEX_URL:-}
|
|
20184
|
+
{{/if}}
|
|
20185
|
+
{{#if (and (eq auth "clerk") (or (includes frontend "next") (includes frontend "react-router") (includes frontend "tanstack-router") (includes frontend "tanstack-start")))}}
|
|
20186
|
+
{{#if (includes frontend "next")}}NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY{{else}}VITE_CLERK_PUBLISHABLE_KEY{{/if}}: \${CLERK_PUBLISHABLE_KEY:-}
|
|
20187
|
+
{{/if}}
|
|
20188
|
+
{{/if}}
|
|
20189
|
+
init: true
|
|
20190
|
+
ports:
|
|
20191
|
+
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "solid"))}}
|
|
20192
|
+
- "3001:80"
|
|
20193
|
+
{{else}}
|
|
20194
|
+
- "3001:3001"
|
|
20195
|
+
{{/if}}
|
|
20196
|
+
env_file:
|
|
20197
|
+
- path: apps/web/.env
|
|
20198
|
+
required: false
|
|
20199
|
+
{{#if (eq backend "self")}}
|
|
20200
|
+
{{#if (or (eq dbSetup "docker") (eq auth "better-auth"))}}
|
|
20201
|
+
environment:
|
|
20202
|
+
{{#if (eq auth "better-auth")}}
|
|
20203
|
+
BETTER_AUTH_URL: http://localhost:3001
|
|
20204
|
+
CORS_ORIGIN: http://localhost:3001
|
|
20205
|
+
{{/if}}
|
|
20206
|
+
{{#if (and (eq dbSetup "docker") (eq database "postgres"))}}
|
|
20207
|
+
DATABASE_URL: postgresql://postgres:\${POSTGRES_PASSWORD:-password}@postgres:5432/{{projectName}}
|
|
20208
|
+
{{/if}}
|
|
20209
|
+
{{#if (and (eq dbSetup "docker") (eq database "mysql"))}}
|
|
20210
|
+
DATABASE_URL: mysql://user:\${MYSQL_PASSWORD:-password}@mysql:3306/{{projectName}}
|
|
20211
|
+
{{/if}}
|
|
20212
|
+
{{#if (and (eq dbSetup "docker") (eq database "mongodb"))}}
|
|
20213
|
+
DATABASE_URL: mongodb://root:\${MONGO_PASSWORD:-password}@mongodb:27017/{{projectName}}?authSource=admin
|
|
20214
|
+
{{/if}}
|
|
20215
|
+
{{/if}}
|
|
20216
|
+
{{#if (eq dbSetup "docker")}}
|
|
20217
|
+
depends_on:
|
|
20218
|
+
{{database}}:
|
|
20219
|
+
condition: service_healthy
|
|
20220
|
+
{{/if}}
|
|
20221
|
+
{{else}}
|
|
20222
|
+
{{#if (eq serverDeploy "docker")}}
|
|
20223
|
+
{{#if (or (includes frontend "next") (includes frontend "nuxt"))}}
|
|
20224
|
+
environment:
|
|
20225
|
+
{{#if (includes frontend "next")}}
|
|
20226
|
+
NEXT_PUBLIC_SERVER_URL: http://server:3000
|
|
20227
|
+
{{/if}}
|
|
20228
|
+
{{#if (includes frontend "nuxt")}}
|
|
20229
|
+
NUXT_SERVER_URL: http://server:3000
|
|
20230
|
+
{{/if}}
|
|
20231
|
+
{{/if}}
|
|
20232
|
+
depends_on:
|
|
20233
|
+
server:
|
|
20234
|
+
condition: service_healthy
|
|
20235
|
+
{{/if}}
|
|
20236
|
+
{{/if}}
|
|
20237
|
+
restart: unless-stopped
|
|
20238
|
+
|
|
20239
|
+
{{/if}}
|
|
20240
|
+
{{#if (and (eq serverDeploy "docker") (ne backend "self"))}}
|
|
20241
|
+
server:
|
|
20242
|
+
build:
|
|
20243
|
+
context: .
|
|
20244
|
+
dockerfile: apps/server/Dockerfile
|
|
20245
|
+
init: true
|
|
20246
|
+
ports:
|
|
20247
|
+
- "3000:3000"
|
|
20248
|
+
env_file:
|
|
20249
|
+
- path: apps/server/.env
|
|
20250
|
+
required: false
|
|
20251
|
+
{{#if (or (eq webDeploy "docker") (eq dbSetup "docker"))}}
|
|
20252
|
+
environment:
|
|
20253
|
+
{{#if (eq webDeploy "docker")}}
|
|
20254
|
+
CORS_ORIGIN: http://localhost:3001
|
|
20255
|
+
{{/if}}
|
|
20256
|
+
{{#if (and (eq dbSetup "docker") (eq database "postgres"))}}
|
|
20257
|
+
DATABASE_URL: postgresql://postgres:\${POSTGRES_PASSWORD:-password}@postgres:5432/{{projectName}}
|
|
20258
|
+
{{/if}}
|
|
20259
|
+
{{#if (and (eq dbSetup "docker") (eq database "mysql"))}}
|
|
20260
|
+
DATABASE_URL: mysql://user:\${MYSQL_PASSWORD:-password}@mysql:3306/{{projectName}}
|
|
20261
|
+
{{/if}}
|
|
20262
|
+
{{#if (and (eq dbSetup "docker") (eq database "mongodb"))}}
|
|
20263
|
+
DATABASE_URL: mongodb://root:\${MONGO_PASSWORD:-password}@mongodb:27017/{{projectName}}?authSource=admin
|
|
20264
|
+
{{/if}}
|
|
20265
|
+
{{/if}}
|
|
20266
|
+
healthcheck:
|
|
20267
|
+
test:
|
|
20268
|
+
[
|
|
20269
|
+
"CMD",
|
|
20270
|
+
"node",
|
|
20271
|
+
"-e",
|
|
20272
|
+
"fetch('http://localhost:3000/').then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))",
|
|
20273
|
+
]
|
|
20274
|
+
interval: 10s
|
|
20275
|
+
timeout: 5s
|
|
20276
|
+
retries: 5
|
|
20277
|
+
start_period: 10s
|
|
20278
|
+
{{#if (eq dbSetup "docker")}}
|
|
20279
|
+
depends_on:
|
|
20280
|
+
{{database}}:
|
|
20281
|
+
condition: service_healthy
|
|
20282
|
+
{{/if}}
|
|
20283
|
+
restart: unless-stopped
|
|
20284
|
+
|
|
20285
|
+
{{/if}}
|
|
20286
|
+
{{#if (eq dbSetup "docker")}}
|
|
20287
|
+
{{#if (eq database "postgres")}}
|
|
20288
|
+
postgres:
|
|
20289
|
+
image: postgres
|
|
20290
|
+
container_name: {{projectName}}-postgres
|
|
20291
|
+
environment:
|
|
20292
|
+
POSTGRES_DB: {{projectName}}
|
|
20293
|
+
POSTGRES_USER: postgres
|
|
20294
|
+
POSTGRES_PASSWORD: \${POSTGRES_PASSWORD:-password}
|
|
20295
|
+
ports:
|
|
20296
|
+
- "5432:5432"
|
|
20297
|
+
volumes:
|
|
20298
|
+
- {{projectName}}_postgres_data:/var/lib/postgresql
|
|
20299
|
+
healthcheck:
|
|
20300
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
20301
|
+
interval: 10s
|
|
20302
|
+
timeout: 5s
|
|
20303
|
+
retries: 5
|
|
20304
|
+
restart: unless-stopped
|
|
20305
|
+
{{/if}}
|
|
20306
|
+
{{#if (eq database "mysql")}}
|
|
20307
|
+
mysql:
|
|
20308
|
+
image: mysql
|
|
20309
|
+
container_name: {{projectName}}-mysql
|
|
20310
|
+
environment:
|
|
20311
|
+
MYSQL_ROOT_PASSWORD: \${MYSQL_ROOT_PASSWORD:-password}
|
|
20312
|
+
MYSQL_DATABASE: {{projectName}}
|
|
20313
|
+
MYSQL_USER: user
|
|
20314
|
+
MYSQL_PASSWORD: \${MYSQL_PASSWORD:-password}
|
|
20315
|
+
ports:
|
|
20316
|
+
- "3306:3306"
|
|
20317
|
+
volumes:
|
|
20318
|
+
- {{projectName}}_mysql_data:/var/lib/mysql
|
|
20319
|
+
healthcheck:
|
|
20320
|
+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
20321
|
+
interval: 10s
|
|
20322
|
+
timeout: 5s
|
|
20323
|
+
retries: 5
|
|
20324
|
+
restart: unless-stopped
|
|
20325
|
+
{{/if}}
|
|
20326
|
+
{{#if (eq database "mongodb")}}
|
|
20327
|
+
mongodb:
|
|
20328
|
+
image: mongo
|
|
20329
|
+
container_name: {{projectName}}-mongodb
|
|
20330
|
+
environment:
|
|
20331
|
+
MONGO_INITDB_ROOT_USERNAME: root
|
|
20332
|
+
MONGO_INITDB_ROOT_PASSWORD: \${MONGO_PASSWORD:-password}
|
|
20333
|
+
MONGO_INITDB_DATABASE: {{projectName}}
|
|
20334
|
+
ports:
|
|
20335
|
+
- "27017:27017"
|
|
20336
|
+
volumes:
|
|
20337
|
+
- {{projectName}}_mongodb_data:/data/db
|
|
20338
|
+
healthcheck:
|
|
20339
|
+
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
|
20340
|
+
interval: 10s
|
|
20341
|
+
timeout: 5s
|
|
20342
|
+
retries: 5
|
|
20343
|
+
restart: unless-stopped
|
|
20344
|
+
{{/if}}
|
|
20345
|
+
|
|
20346
|
+
volumes:
|
|
20347
|
+
{{projectName}}_{{database}}_data:
|
|
20348
|
+
{{/if}}
|
|
20349
|
+
`],
|
|
20350
|
+
["deploy/docker/server/Dockerfile.hbs", `FROM node:24-slim AS base
|
|
20351
|
+
{{#if (or (eq packageManager "bun") (eq runtime "bun"))}}
|
|
20352
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20353
|
+
{{/if}}
|
|
20354
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20355
|
+
RUN npm install -g pnpm
|
|
20356
|
+
{{/if}}
|
|
20357
|
+
WORKDIR /app
|
|
20358
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20359
|
+
{{#if (eq orm "prisma")}}
|
|
20360
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20361
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20362
|
+
{{/if}}
|
|
20363
|
+
|
|
20364
|
+
COPY . .
|
|
20365
|
+
{{#if (eq packageManager "bun")}}
|
|
20366
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20367
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20368
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20369
|
+
{{else}}
|
|
20370
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20371
|
+
{{/if}}
|
|
20372
|
+
|
|
20373
|
+
ENV NODE_ENV=production
|
|
20374
|
+
RUN cd apps/server && {{packageManager}} run build
|
|
20375
|
+
ENV SKIP_ENV_VALIDATION=
|
|
20376
|
+
{{#if (eq orm "prisma")}}
|
|
20377
|
+
ENV DATABASE_URL=
|
|
20378
|
+
{{/if}}
|
|
20379
|
+
|
|
20380
|
+
EXPOSE 3000
|
|
20381
|
+
|
|
20382
|
+
WORKDIR /app/apps/server
|
|
20383
|
+
{{#if (eq runtime "bun")}}
|
|
20384
|
+
CMD ["bun", "dist/index.mjs"]
|
|
20385
|
+
{{else}}
|
|
20386
|
+
CMD ["node", "dist/index.mjs"]
|
|
20387
|
+
{{/if}}
|
|
20388
|
+
`],
|
|
20389
|
+
["deploy/docker/web/astro/Dockerfile.hbs", `FROM node:24-slim AS base
|
|
20390
|
+
{{#if (eq packageManager "bun")}}
|
|
20391
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20392
|
+
{{/if}}
|
|
20393
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20394
|
+
RUN npm install -g pnpm
|
|
20395
|
+
{{/if}}
|
|
20396
|
+
WORKDIR /app
|
|
20397
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20398
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20399
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20400
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20401
|
+
{{/if}}
|
|
20402
|
+
{{#if (eq orm "prisma")}}
|
|
20403
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20404
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20405
|
+
{{/if}}
|
|
20406
|
+
|
|
20407
|
+
COPY . .
|
|
20408
|
+
{{#if (eq packageManager "bun")}}
|
|
20409
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20410
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20411
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20412
|
+
{{else}}
|
|
20413
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20414
|
+
{{/if}}
|
|
20415
|
+
|
|
20416
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20417
|
+
ARG PUBLIC_SERVER_URL
|
|
20418
|
+
ENV PUBLIC_SERVER_URL=\${PUBLIC_SERVER_URL}
|
|
20419
|
+
{{/if}}
|
|
20420
|
+
{{#if (eq backend "convex")}}
|
|
20421
|
+
ARG PUBLIC_CONVEX_URL
|
|
20422
|
+
ENV PUBLIC_CONVEX_URL=\${PUBLIC_CONVEX_URL}
|
|
20423
|
+
{{/if}}
|
|
20424
|
+
ENV NODE_ENV=production
|
|
20425
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20426
|
+
ENV SKIP_ENV_VALIDATION=
|
|
20427
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20428
|
+
ENV BETTER_AUTH_SECRET=
|
|
20429
|
+
{{/if}}
|
|
20430
|
+
{{#if (eq orm "prisma")}}
|
|
20431
|
+
ENV DATABASE_URL=
|
|
20432
|
+
{{/if}}
|
|
20433
|
+
|
|
20434
|
+
ENV HOST=0.0.0.0
|
|
20435
|
+
ENV PORT=3001
|
|
20436
|
+
EXPOSE 3001
|
|
20437
|
+
|
|
20438
|
+
WORKDIR /app/apps/web
|
|
20439
|
+
CMD ["node", "dist/server/entry.mjs"]
|
|
20440
|
+
`],
|
|
20441
|
+
["deploy/docker/web/nuxt/Dockerfile.hbs", `FROM node:24-slim AS builder
|
|
20442
|
+
{{#if (eq packageManager "bun")}}
|
|
20443
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20444
|
+
{{/if}}
|
|
20445
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20446
|
+
RUN npm install -g pnpm
|
|
20447
|
+
{{/if}}
|
|
20448
|
+
WORKDIR /app
|
|
20449
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20450
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20451
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20452
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20453
|
+
{{/if}}
|
|
20454
|
+
{{#if (eq orm "prisma")}}
|
|
20455
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20456
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20457
|
+
{{/if}}
|
|
20458
|
+
|
|
20459
|
+
COPY . .
|
|
20460
|
+
{{#if (eq packageManager "bun")}}
|
|
20461
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20462
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20463
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20464
|
+
{{else}}
|
|
20465
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20466
|
+
{{/if}}
|
|
20467
|
+
|
|
20468
|
+
ENV NODE_ENV=production
|
|
20469
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20470
|
+
|
|
20471
|
+
FROM node:24-slim AS runner
|
|
20472
|
+
WORKDIR /app
|
|
20473
|
+
ENV NODE_ENV=production
|
|
20474
|
+
|
|
20475
|
+
COPY --from=builder /app/apps/web/.output ./
|
|
20476
|
+
|
|
20477
|
+
ENV HOST=0.0.0.0
|
|
20478
|
+
ENV PORT=3001
|
|
20479
|
+
EXPOSE 3001
|
|
20480
|
+
|
|
20481
|
+
CMD ["node", "server/index.mjs"]
|
|
20482
|
+
`],
|
|
20483
|
+
["deploy/docker/web/react/next/Dockerfile.hbs", `FROM node:24-slim AS builder
|
|
20484
|
+
{{#if (eq packageManager "bun")}}
|
|
20485
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20486
|
+
{{/if}}
|
|
20487
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20488
|
+
RUN npm install -g pnpm
|
|
20489
|
+
{{/if}}
|
|
20490
|
+
WORKDIR /app
|
|
20491
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20492
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20493
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20494
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20495
|
+
{{/if}}
|
|
20496
|
+
{{#if (eq orm "prisma")}}
|
|
20497
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20498
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20499
|
+
{{/if}}
|
|
20500
|
+
|
|
20501
|
+
COPY . .
|
|
20502
|
+
{{#if (eq packageManager "bun")}}
|
|
20503
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20504
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20505
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20506
|
+
{{else}}
|
|
20507
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20508
|
+
{{/if}}
|
|
20509
|
+
|
|
20510
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20511
|
+
ARG NEXT_PUBLIC_SERVER_URL
|
|
20512
|
+
ENV NEXT_PUBLIC_SERVER_URL=\${NEXT_PUBLIC_SERVER_URL}
|
|
20513
|
+
{{/if}}
|
|
20514
|
+
{{#if (eq backend "convex")}}
|
|
20515
|
+
ARG NEXT_PUBLIC_CONVEX_URL
|
|
20516
|
+
ENV NEXT_PUBLIC_CONVEX_URL=\${NEXT_PUBLIC_CONVEX_URL}
|
|
20517
|
+
{{/if}}
|
|
20518
|
+
{{#if (eq auth "clerk")}}
|
|
20519
|
+
ARG NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
|
|
20520
|
+
ENV NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=\${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
|
|
20521
|
+
{{/if}}
|
|
20522
|
+
ENV NODE_ENV=production
|
|
20523
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20524
|
+
|
|
20525
|
+
FROM node:24-slim AS runner
|
|
20526
|
+
WORKDIR /app
|
|
20527
|
+
ENV NODE_ENV=production
|
|
20528
|
+
|
|
20529
|
+
COPY --from=builder /app/apps/web/.next/standalone ./
|
|
20530
|
+
COPY --from=builder /app/apps/web/.next/static ./apps/web/.next/static
|
|
20531
|
+
|
|
20532
|
+
ENV HOSTNAME=0.0.0.0
|
|
20533
|
+
ENV PORT=3001
|
|
20534
|
+
EXPOSE 3001
|
|
20535
|
+
|
|
20536
|
+
CMD ["node", "apps/web/server.js"]
|
|
20537
|
+
`],
|
|
20538
|
+
["deploy/docker/web/react/react-router/Dockerfile.hbs", `FROM node:24-slim AS builder
|
|
20539
|
+
{{#if (eq packageManager "bun")}}
|
|
20540
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20541
|
+
{{/if}}
|
|
20542
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20543
|
+
RUN npm install -g pnpm
|
|
20544
|
+
{{/if}}
|
|
20545
|
+
WORKDIR /app
|
|
20546
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20547
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20548
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20549
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20550
|
+
{{/if}}
|
|
20551
|
+
{{#if (eq orm "prisma")}}
|
|
20552
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20553
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20554
|
+
{{/if}}
|
|
20555
|
+
|
|
20556
|
+
COPY . .
|
|
20557
|
+
{{#if (eq packageManager "bun")}}
|
|
20558
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20559
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20560
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20561
|
+
{{else}}
|
|
20562
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20563
|
+
{{/if}}
|
|
20564
|
+
|
|
20565
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20566
|
+
ARG VITE_SERVER_URL
|
|
20567
|
+
ENV VITE_SERVER_URL=\${VITE_SERVER_URL}
|
|
20568
|
+
{{/if}}
|
|
20569
|
+
{{#if (eq backend "convex")}}
|
|
20570
|
+
ARG VITE_CONVEX_URL
|
|
20571
|
+
ENV VITE_CONVEX_URL=\${VITE_CONVEX_URL}
|
|
20572
|
+
{{/if}}
|
|
20573
|
+
{{#if (eq auth "clerk")}}
|
|
20574
|
+
ARG VITE_CLERK_PUBLISHABLE_KEY
|
|
20575
|
+
ENV VITE_CLERK_PUBLISHABLE_KEY=\${VITE_CLERK_PUBLISHABLE_KEY}
|
|
20576
|
+
{{/if}}
|
|
20577
|
+
ENV NODE_ENV=production
|
|
20578
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20579
|
+
|
|
20580
|
+
FROM nginx:alpine AS runner
|
|
20581
|
+
COPY --from=builder /app/apps/web/build/client /usr/share/nginx/html
|
|
20582
|
+
COPY apps/web/nginx.conf /etc/nginx/conf.d/default.conf
|
|
20583
|
+
EXPOSE 80
|
|
20584
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
20585
|
+
`],
|
|
20586
|
+
["deploy/docker/web/react/react-router/nginx.conf", `server {
|
|
20587
|
+
listen 80;
|
|
20588
|
+
server_name _;
|
|
20589
|
+
root /usr/share/nginx/html;
|
|
20590
|
+
index index.html;
|
|
20591
|
+
|
|
20592
|
+
gzip on;
|
|
20593
|
+
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
|
|
20594
|
+
|
|
20595
|
+
location /assets/ {
|
|
20596
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
20597
|
+
}
|
|
20598
|
+
|
|
20599
|
+
# SPA fallback
|
|
20600
|
+
location / {
|
|
20601
|
+
try_files $uri $uri/ /index.html;
|
|
20602
|
+
}
|
|
20603
|
+
}
|
|
20604
|
+
`],
|
|
20605
|
+
["deploy/docker/web/react/tanstack-router/Dockerfile.hbs", `FROM node:24-slim AS builder
|
|
20606
|
+
{{#if (eq packageManager "bun")}}
|
|
20607
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20608
|
+
{{/if}}
|
|
20609
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20610
|
+
RUN npm install -g pnpm
|
|
20611
|
+
{{/if}}
|
|
20612
|
+
WORKDIR /app
|
|
20613
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20614
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20615
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20616
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20617
|
+
{{/if}}
|
|
20618
|
+
{{#if (eq orm "prisma")}}
|
|
20619
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20620
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20621
|
+
{{/if}}
|
|
20622
|
+
|
|
20623
|
+
COPY . .
|
|
20624
|
+
{{#if (eq packageManager "bun")}}
|
|
20625
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20626
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20627
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20628
|
+
{{else}}
|
|
20629
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20630
|
+
{{/if}}
|
|
20631
|
+
|
|
20632
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20633
|
+
ARG VITE_SERVER_URL
|
|
20634
|
+
ENV VITE_SERVER_URL=\${VITE_SERVER_URL}
|
|
20635
|
+
{{/if}}
|
|
20636
|
+
{{#if (eq backend "convex")}}
|
|
20637
|
+
ARG VITE_CONVEX_URL
|
|
20638
|
+
ENV VITE_CONVEX_URL=\${VITE_CONVEX_URL}
|
|
20639
|
+
{{/if}}
|
|
20640
|
+
{{#if (eq auth "clerk")}}
|
|
20641
|
+
ARG VITE_CLERK_PUBLISHABLE_KEY
|
|
20642
|
+
ENV VITE_CLERK_PUBLISHABLE_KEY=\${VITE_CLERK_PUBLISHABLE_KEY}
|
|
20643
|
+
{{/if}}
|
|
20644
|
+
ENV NODE_ENV=production
|
|
20645
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20646
|
+
|
|
20647
|
+
FROM nginx:alpine AS runner
|
|
20648
|
+
COPY --from=builder /app/apps/web/dist /usr/share/nginx/html
|
|
20649
|
+
COPY apps/web/nginx.conf /etc/nginx/conf.d/default.conf
|
|
20650
|
+
EXPOSE 80
|
|
20651
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
20652
|
+
`],
|
|
20653
|
+
["deploy/docker/web/react/tanstack-router/nginx.conf", `server {
|
|
20654
|
+
listen 80;
|
|
20655
|
+
server_name _;
|
|
20656
|
+
root /usr/share/nginx/html;
|
|
20657
|
+
index index.html;
|
|
20658
|
+
|
|
20659
|
+
gzip on;
|
|
20660
|
+
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
|
|
20661
|
+
|
|
20662
|
+
location /assets/ {
|
|
20663
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
20664
|
+
}
|
|
20665
|
+
|
|
20666
|
+
# SPA fallback
|
|
20667
|
+
location / {
|
|
20668
|
+
try_files $uri $uri/ /index.html;
|
|
20669
|
+
}
|
|
20670
|
+
}
|
|
20671
|
+
`],
|
|
20672
|
+
["deploy/docker/web/react/tanstack-start/Dockerfile.hbs", `FROM node:24-slim AS base
|
|
20673
|
+
{{#if (eq packageManager "bun")}}
|
|
20674
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20675
|
+
{{/if}}
|
|
20676
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20677
|
+
RUN npm install -g pnpm
|
|
20678
|
+
{{/if}}
|
|
20679
|
+
WORKDIR /app
|
|
20680
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20681
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20682
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20683
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20684
|
+
{{/if}}
|
|
20685
|
+
{{#if (eq orm "prisma")}}
|
|
20686
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20687
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20688
|
+
{{/if}}
|
|
20689
|
+
|
|
20690
|
+
COPY . .
|
|
20691
|
+
{{#if (eq packageManager "bun")}}
|
|
20692
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20693
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20694
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20695
|
+
{{else}}
|
|
20696
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20697
|
+
{{/if}}
|
|
20698
|
+
|
|
20699
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20700
|
+
ARG VITE_SERVER_URL
|
|
20701
|
+
ENV VITE_SERVER_URL=\${VITE_SERVER_URL}
|
|
20702
|
+
{{/if}}
|
|
20703
|
+
{{#if (eq backend "convex")}}
|
|
20704
|
+
ARG VITE_CONVEX_URL
|
|
20705
|
+
ENV VITE_CONVEX_URL=\${VITE_CONVEX_URL}
|
|
20706
|
+
{{/if}}
|
|
20707
|
+
{{#if (eq auth "clerk")}}
|
|
20708
|
+
ARG VITE_CLERK_PUBLISHABLE_KEY
|
|
20709
|
+
ENV VITE_CLERK_PUBLISHABLE_KEY=\${VITE_CLERK_PUBLISHABLE_KEY}
|
|
20710
|
+
{{/if}}
|
|
20711
|
+
ENV NODE_ENV=production
|
|
20712
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20713
|
+
ENV SKIP_ENV_VALIDATION=
|
|
20714
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20715
|
+
ENV BETTER_AUTH_SECRET=
|
|
20716
|
+
{{/if}}
|
|
20717
|
+
{{#if (eq orm "prisma")}}
|
|
20718
|
+
ENV DATABASE_URL=
|
|
20719
|
+
{{/if}}
|
|
20720
|
+
|
|
20721
|
+
ENV HOST=0.0.0.0
|
|
20722
|
+
ENV PORT=3001
|
|
20723
|
+
EXPOSE 3001
|
|
20724
|
+
|
|
20725
|
+
# SSR chunks require() externals at runtime; must run from the workspace
|
|
20726
|
+
WORKDIR /app/apps/web
|
|
20727
|
+
CMD ["node", ".output/server/index.mjs"]
|
|
20728
|
+
`],
|
|
20729
|
+
["deploy/docker/web/solid/Dockerfile.hbs", `FROM node:24-slim AS builder
|
|
20730
|
+
{{#if (eq packageManager "bun")}}
|
|
20731
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20732
|
+
{{/if}}
|
|
20733
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20734
|
+
RUN npm install -g pnpm
|
|
20735
|
+
{{/if}}
|
|
20736
|
+
WORKDIR /app
|
|
20737
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20738
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20739
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20740
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20741
|
+
{{/if}}
|
|
20742
|
+
{{#if (eq orm "prisma")}}
|
|
20743
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20744
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20745
|
+
{{/if}}
|
|
20746
|
+
|
|
20747
|
+
COPY . .
|
|
20748
|
+
{{#if (eq packageManager "bun")}}
|
|
20749
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20750
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20751
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20752
|
+
{{else}}
|
|
20753
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20754
|
+
{{/if}}
|
|
20755
|
+
|
|
20756
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20757
|
+
ARG VITE_SERVER_URL
|
|
20758
|
+
ENV VITE_SERVER_URL=\${VITE_SERVER_URL}
|
|
20759
|
+
{{/if}}
|
|
20760
|
+
{{#if (eq backend "convex")}}
|
|
20761
|
+
ARG VITE_CONVEX_URL
|
|
20762
|
+
ENV VITE_CONVEX_URL=\${VITE_CONVEX_URL}
|
|
20763
|
+
{{/if}}
|
|
20764
|
+
ENV NODE_ENV=production
|
|
20765
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20766
|
+
|
|
20767
|
+
FROM nginx:alpine AS runner
|
|
20768
|
+
COPY --from=builder /app/apps/web/dist /usr/share/nginx/html
|
|
20769
|
+
COPY apps/web/nginx.conf /etc/nginx/conf.d/default.conf
|
|
20770
|
+
EXPOSE 80
|
|
20771
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
20772
|
+
`],
|
|
20773
|
+
["deploy/docker/web/solid/nginx.conf", `server {
|
|
20774
|
+
listen 80;
|
|
20775
|
+
server_name _;
|
|
20776
|
+
root /usr/share/nginx/html;
|
|
20777
|
+
index index.html;
|
|
20778
|
+
|
|
20779
|
+
gzip on;
|
|
20780
|
+
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
|
|
20781
|
+
|
|
20782
|
+
location /assets/ {
|
|
20783
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
20784
|
+
}
|
|
20785
|
+
|
|
20786
|
+
# SPA fallback
|
|
20787
|
+
location / {
|
|
20788
|
+
try_files $uri $uri/ /index.html;
|
|
20789
|
+
}
|
|
20790
|
+
}
|
|
20791
|
+
`],
|
|
20792
|
+
["deploy/docker/web/svelte/Dockerfile.hbs", `FROM node:24-slim AS base
|
|
20793
|
+
{{#if (eq packageManager "bun")}}
|
|
20794
|
+
COPY --from=oven/bun:1 /usr/local/bin/bun /usr/local/bin/bun
|
|
20795
|
+
{{/if}}
|
|
20796
|
+
{{#if (eq packageManager "pnpm")}}
|
|
20797
|
+
RUN npm install -g pnpm
|
|
20798
|
+
{{/if}}
|
|
20799
|
+
WORKDIR /app
|
|
20800
|
+
ENV SKIP_ENV_VALIDATION=1
|
|
20801
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20802
|
+
# the build evaluates the auth config; the real secret comes from compose at runtime
|
|
20803
|
+
ENV BETTER_AUTH_SECRET=build-time-placeholder-secret-not-used-at-runtime
|
|
20804
|
+
{{/if}}
|
|
20805
|
+
{{#if (eq orm "prisma")}}
|
|
20806
|
+
# prisma generate resolves DATABASE_URL at install time; the real value comes from compose at runtime
|
|
20807
|
+
ENV DATABASE_URL={{#if (eq database "mysql")}}mysql://build:build@localhost:3306/build{{else if (eq database "mongodb")}}mongodb://localhost:27017/build{{else if (eq database "sqlite")}}file:./build.db{{else}}postgresql://build:build@localhost:5432/build{{/if}}
|
|
20808
|
+
{{/if}}
|
|
20809
|
+
|
|
20810
|
+
COPY . .
|
|
20811
|
+
{{#if (eq packageManager "bun")}}
|
|
20812
|
+
RUN --mount=type=cache,target=/root/.bun/install/cache bun install
|
|
20813
|
+
{{else if (eq packageManager "pnpm")}}
|
|
20814
|
+
RUN --mount=type=cache,target=/pnpm-store pnpm install --store-dir /pnpm-store
|
|
20815
|
+
{{else}}
|
|
20816
|
+
RUN --mount=type=cache,target=/root/.npm npm install
|
|
20817
|
+
{{/if}}
|
|
20818
|
+
|
|
20819
|
+
{{#if (and (ne backend "self") (ne backend "none") (ne backend "convex"))}}
|
|
20820
|
+
ARG PUBLIC_SERVER_URL
|
|
20821
|
+
ENV PUBLIC_SERVER_URL=\${PUBLIC_SERVER_URL}
|
|
20822
|
+
{{/if}}
|
|
20823
|
+
{{#if (eq backend "convex")}}
|
|
20824
|
+
ARG PUBLIC_CONVEX_URL
|
|
20825
|
+
ENV PUBLIC_CONVEX_URL=\${PUBLIC_CONVEX_URL}
|
|
20826
|
+
{{/if}}
|
|
20827
|
+
ENV NODE_ENV=production
|
|
20828
|
+
RUN cd apps/web && {{packageManager}} run build
|
|
20829
|
+
ENV SKIP_ENV_VALIDATION=
|
|
20830
|
+
{{#if (and (eq backend "self") (eq auth "better-auth"))}}
|
|
20831
|
+
ENV BETTER_AUTH_SECRET=
|
|
20832
|
+
{{/if}}
|
|
20833
|
+
{{#if (eq orm "prisma")}}
|
|
20834
|
+
ENV DATABASE_URL=
|
|
20835
|
+
{{/if}}
|
|
20836
|
+
|
|
20837
|
+
ENV HOST=0.0.0.0
|
|
20838
|
+
ENV PORT=3001
|
|
20839
|
+
EXPOSE 3001
|
|
20840
|
+
|
|
20841
|
+
WORKDIR /app/apps/web
|
|
20842
|
+
CMD ["node", "build/index.js"]
|
|
19879
20843
|
`],
|
|
19880
20844
|
["examples/ai/convex/packages/backend/convex/agent.ts.hbs", `import { Agent } from "@convex-dev/agent";
|
|
19881
20845
|
import { google } from "@ai-sdk/google";
|
|
@@ -26408,12 +27372,12 @@ declare module "cloudflare:workers" {
|
|
|
26408
27372
|
["extras/pnpm-workspace.yaml.hbs", `packages:
|
|
26409
27373
|
- "apps/*"
|
|
26410
27374
|
- "packages/*"
|
|
26411
|
-
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq orm "prisma") (includes addons "lefthook") (includes addons "nx") (includes addons "pwa") (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
27375
|
+
{{#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 frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "nuxt") (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
26412
27376
|
|
|
26413
27377
|
# pnpm 11 blocks dependency lifecycle scripts unless they are approved here.
|
|
26414
27378
|
# Entries are scoped to packages this generated stack can pull in.
|
|
26415
27379
|
allowBuilds:
|
|
26416
|
-
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (includes frontend "tanstack-start"))}}
|
|
27380
|
+
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (eq serverDeploy "docker") (includes frontend "tanstack-start"))}}
|
|
26417
27381
|
esbuild: true
|
|
26418
27382
|
{{/if}}
|
|
26419
27383
|
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
@@ -26422,7 +27386,11 @@ allowBuilds:
|
|
|
26422
27386
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
26423
27387
|
msgpackr-extract: true
|
|
26424
27388
|
{{/if}}
|
|
26425
|
-
{{#if (
|
|
27389
|
+
{{#if (includes frontend "nuxt")}}
|
|
27390
|
+
"@parcel/watcher": true
|
|
27391
|
+
vue-demi: true
|
|
27392
|
+
{{/if}}
|
|
27393
|
+
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq webDeploy "docker") (includes addons "pwa"))}}
|
|
26426
27394
|
sharp: true
|
|
26427
27395
|
{{/if}}
|
|
26428
27396
|
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
|
|
@@ -30606,6 +31574,8 @@ export default defineNuxtConfig({
|
|
|
30606
31574
|
},
|
|
30607
31575
|
{{else if (and (ne backend "self") (ne backend "none"))}}
|
|
30608
31576
|
runtimeConfig: {
|
|
31577
|
+
// server-side override for SSR fetches (NUXT_SERVER_URL); falls back to the public URL
|
|
31578
|
+
serverUrl: "",
|
|
30609
31579
|
public: {
|
|
30610
31580
|
serverUrl: process.env.NUXT_PUBLIC_SERVER_URL ?? "",
|
|
30611
31581
|
}
|
|
@@ -30626,7 +31596,8 @@ export default defineNuxtConfig({
|
|
|
30626
31596
|
},
|
|
30627
31597
|
"dependencies": {
|
|
30628
31598
|
"@nuxt/ui": "^4.5.1",
|
|
30629
|
-
"nuxt": "^4.4.4"
|
|
31599
|
+
"nuxt": "^4.4.4",
|
|
31600
|
+
"vue": "^3.5.38"
|
|
30630
31601
|
},
|
|
30631
31602
|
"devDependencies": {
|
|
30632
31603
|
"tailwindcss": "^4.2.1",
|
|
@@ -30676,6 +31647,9 @@ import type { NextConfig } from "next";
|
|
|
30676
31647
|
const nextConfig: NextConfig = {
|
|
30677
31648
|
typedRoutes: true,
|
|
30678
31649
|
reactCompiler: true,
|
|
31650
|
+
{{#if (eq webDeploy "docker")}}
|
|
31651
|
+
output: "standalone",
|
|
31652
|
+
{{/if}}
|
|
30679
31653
|
{{#if (includes examples "ai")}}
|
|
30680
31654
|
transpilePackages: ["shiki"],
|
|
30681
31655
|
{{/if}}
|
|
@@ -31603,7 +32577,7 @@ export default function Home() {
|
|
|
31603
32577
|
`],
|
|
31604
32578
|
["frontend/react/react-router/vite.config.ts.hbs", `import { reactRouter } from "@react-router/dev/vite";
|
|
31605
32579
|
import tailwindcss from "@tailwindcss/vite";
|
|
31606
|
-
import { defineConfig } from "vite";
|
|
32580
|
+
import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
|
|
31607
32581
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
31608
32582
|
|
|
31609
32583
|
export default defineConfig({
|
|
@@ -31612,7 +32586,8 @@ export default defineConfig({
|
|
|
31612
32586
|
reactRouter(),
|
|
31613
32587
|
tsconfigPaths(),
|
|
31614
32588
|
],
|
|
31615
|
-
})
|
|
32589
|
+
});
|
|
32590
|
+
`],
|
|
31616
32591
|
["frontend/react/tanstack-router/index.html.hbs", `<!DOCTYPE html>
|
|
31617
32592
|
<html lang="en">
|
|
31618
32593
|
<head>
|
|
@@ -32055,7 +33030,7 @@ function HomeComponent() {
|
|
|
32055
33030
|
["frontend/react/tanstack-router/vite.config.ts.hbs", `import tailwindcss from "@tailwindcss/vite";
|
|
32056
33031
|
import { tanstackRouter } from "@tanstack/router-plugin/vite";
|
|
32057
33032
|
import react from "@vitejs/plugin-react";
|
|
32058
|
-
import { defineConfig } from "vite";
|
|
33033
|
+
import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
|
|
32059
33034
|
|
|
32060
33035
|
export default defineConfig({
|
|
32061
33036
|
server: {
|
|
@@ -32643,8 +33618,11 @@ function HomeComponent() {
|
|
|
32643
33618
|
}
|
|
32644
33619
|
}
|
|
32645
33620
|
`],
|
|
32646
|
-
["frontend/react/tanstack-start/vite.config.ts.hbs", `import { defineConfig } from "vite";
|
|
33621
|
+
["frontend/react/tanstack-start/vite.config.ts.hbs", `import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
|
|
32647
33622
|
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
33623
|
+
{{#if (eq webDeploy "docker")}}
|
|
33624
|
+
import { nitro } from "nitro/vite";
|
|
33625
|
+
{{/if}}
|
|
32648
33626
|
import tailwindcss from "@tailwindcss/vite";
|
|
32649
33627
|
import viteReact from "@vitejs/plugin-react";
|
|
32650
33628
|
|
|
@@ -32658,6 +33636,9 @@ export default defineConfig({
|
|
|
32658
33636
|
plugins: [
|
|
32659
33637
|
tailwindcss(),
|
|
32660
33638
|
tanstackStart(),
|
|
33639
|
+
{{#if (eq webDeploy "docker")}}
|
|
33640
|
+
nitro(),
|
|
33641
|
+
{{/if}}
|
|
32661
33642
|
viteReact(),
|
|
32662
33643
|
],
|
|
32663
33644
|
{{#if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
@@ -32891,6 +33872,7 @@ dist-ssr
|
|
|
32891
33872
|
"tailwindcss": "^4.2.2"
|
|
32892
33873
|
},
|
|
32893
33874
|
"devDependencies": {
|
|
33875
|
+
"@tanstack/solid-router-devtools": "^1.166.13",
|
|
32894
33876
|
"vite": "^8.0.8",
|
|
32895
33877
|
"vite-plugin-solid": "^2.11.12"
|
|
32896
33878
|
}
|
|
@@ -33134,7 +34116,7 @@ body {
|
|
|
33134
34116
|
}
|
|
33135
34117
|
}
|
|
33136
34118
|
`],
|
|
33137
|
-
["frontend/solid/vite.config.ts.hbs", `import { defineConfig } from "vite";
|
|
34119
|
+
["frontend/solid/vite.config.ts.hbs", `import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
|
|
33138
34120
|
import { tanstackRouter } from "@tanstack/router-plugin/vite";
|
|
33139
34121
|
import solidPlugin from "vite-plugin-solid";
|
|
33140
34122
|
import tailwindcss from "@tailwindcss/vite";
|
|
@@ -33154,7 +34136,8 @@ export default defineConfig({
|
|
|
33154
34136
|
server: {
|
|
33155
34137
|
port: 3001,
|
|
33156
34138
|
},
|
|
33157
|
-
})
|
|
34139
|
+
});
|
|
34140
|
+
`],
|
|
33158
34141
|
["frontend/svelte/_gitignore", `node_modules
|
|
33159
34142
|
|
|
33160
34143
|
# Output
|
|
@@ -33446,6 +34429,8 @@ const TITLE_TEXT = \`
|
|
|
33446
34429
|
["frontend/svelte/static/favicon.png", `[Binary file]`],
|
|
33447
34430
|
["frontend/svelte/svelte.config.js.hbs", `{{#if (eq webDeploy "cloudflare")}}
|
|
33448
34431
|
import alchemy from 'alchemy/cloudflare/sveltekit';
|
|
34432
|
+
{{else if (eq webDeploy "docker")}}
|
|
34433
|
+
import adapter from '@sveltejs/adapter-node';
|
|
33449
34434
|
{{else}}
|
|
33450
34435
|
import adapter from '@sveltejs/adapter-auto';
|
|
33451
34436
|
{{/if}}
|
|
@@ -33461,6 +34446,9 @@ const config = {
|
|
|
33461
34446
|
{{#if (eq webDeploy "cloudflare")}}
|
|
33462
34447
|
// Alchemy's adapter wraps SvelteKit's Cloudflare adapter for local platform.env and Worker builds.
|
|
33463
34448
|
adapter: alchemy()
|
|
34449
|
+
{{else if (eq webDeploy "docker")}}
|
|
34450
|
+
// adapter-node builds a standalone Node server (run with \`node build/index.js\`).
|
|
34451
|
+
adapter: adapter()
|
|
33464
34452
|
{{else}}
|
|
33465
34453
|
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
|
33466
34454
|
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
|
@@ -33495,7 +34483,7 @@ export default config;
|
|
|
33495
34483
|
`],
|
|
33496
34484
|
["frontend/svelte/vite.config.ts.hbs", `import tailwindcss from "@tailwindcss/vite";
|
|
33497
34485
|
import { sveltekit } from "@sveltejs/kit/vite";
|
|
33498
|
-
import { defineConfig } from "vite";
|
|
34486
|
+
import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
|
|
33499
34487
|
|
|
33500
34488
|
export default defineConfig({
|
|
33501
34489
|
plugins: [tailwindcss(), sveltekit()],
|
|
@@ -33716,6 +34704,7 @@ export const env = createEnv({
|
|
|
33716
34704
|
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
|
33717
34705
|
},
|
|
33718
34706
|
runtimeEnv: process.env,
|
|
34707
|
+
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
|
|
33719
34708
|
emptyStringAsUndefined: true,
|
|
33720
34709
|
});
|
|
33721
34710
|
{{/if}}
|
|
@@ -33841,6 +34830,7 @@ export const env = createEnv({
|
|
|
33841
34830
|
runtimeEnv: (import.meta as any).env,
|
|
33842
34831
|
{{/if}}
|
|
33843
34832
|
{{/if}}
|
|
34833
|
+
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
|
|
33844
34834
|
emptyStringAsUndefined: true,
|
|
33845
34835
|
});
|
|
33846
34836
|
`],
|
|
@@ -35297,8 +36287,8 @@ function SuccessPage() {
|
|
|
35297
36287
|
</div>
|
|
35298
36288
|
`]
|
|
35299
36289
|
]);
|
|
35300
|
-
const TEMPLATE_COUNT =
|
|
36290
|
+
const TEMPLATE_COUNT = 497;
|
|
35301
36291
|
//#endregion
|
|
35302
|
-
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };
|
|
36292
|
+
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processNxConfig, processPackageConfigs, processTemplateString, processTurboConfig, processVitePlusConfig, transformFilename, writeBtsConfigToVfs };
|
|
35303
36293
|
|
|
35304
36294
|
//# sourceMappingURL=index.mjs.map
|