@better-t-stack/template-generator 3.31.1 → 3.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -380,6 +380,156 @@ function updatePackageJsonsWithCatalogs(vfs, packagesInfo, catalog) {
380
380
  }
381
381
  }
382
382
  //#endregion
383
+ //#region src/utils/add-deps.ts
384
+ const dependencyVersionMap = {
385
+ typescript: "^6",
386
+ "better-auth": "1.6.11",
387
+ "@better-auth/expo": "1.6.11",
388
+ "@clerk/backend": "^3.2.1",
389
+ "@clerk/express": "^2.0.5",
390
+ "@clerk/fastify": "^3.1.3",
391
+ "@clerk/nextjs": "^7.0.5",
392
+ "@clerk/react": "^6.1.1",
393
+ "@clerk/react-router": "^3.0.5",
394
+ "@clerk/tanstack-react-start": "^1.1.3",
395
+ "@clerk/expo": "^3.1.3",
396
+ "drizzle-orm": "^0.45.1",
397
+ "drizzle-kit": "^0.31.8",
398
+ "@planetscale/database": "^1.19.0",
399
+ "@libsql/client": "0.15.15",
400
+ libsql: "0.5.22",
401
+ "@neondatabase/serverless": "^1.0.2",
402
+ pg: "^8.17.1",
403
+ "@types/pg": "^8.16.0",
404
+ "@types/ws": "^8.18.1",
405
+ ws: "^8.18.3",
406
+ mysql2: "^3.14.0",
407
+ "@prisma/client": "^7.8.0",
408
+ prisma: "^7.8.0",
409
+ "@prisma/adapter-d1": "^7.8.0",
410
+ "@prisma/adapter-neon": "^7.8.0",
411
+ "@prisma/adapter-mariadb": "^7.8.0",
412
+ "@prisma/adapter-libsql": "^7.8.0",
413
+ "@prisma/adapter-better-sqlite3": "^7.8.0",
414
+ "@prisma/adapter-pg": "^7.8.0",
415
+ "@prisma/adapter-planetscale": "^7.8.0",
416
+ mongoose: "^9.6.2",
417
+ mongodb: "^7.2.0",
418
+ "vite-plugin-pwa": "^1.3.0",
419
+ "@vite-pwa/assets-generator": "^1.0.2",
420
+ "@tauri-apps/cli": "^2.11.2",
421
+ "@biomejs/biome": "^2.4.16",
422
+ oxlint: "^1.68.0",
423
+ oxfmt: "^0.53.0",
424
+ husky: "^9.1.7",
425
+ lefthook: "^2.1.9",
426
+ "lint-staged": "^17.0.7",
427
+ tsx: "^4.19.2",
428
+ "@types/node": "^22.13.14",
429
+ "@types/bun": "^1.3.4",
430
+ "@elysiajs/node": "^1.4.5",
431
+ "@elysiajs/cors": "^1.4.1",
432
+ "@elysiajs/trpc": "^1.1.0",
433
+ elysia: "^1.4.28",
434
+ "@sinclair/typebox": "^0.34.49",
435
+ "@hono/node-server": "^1.14.4",
436
+ "@hono/trpc-server": "^0.4.0",
437
+ hono: "^4.8.2",
438
+ cors: "^2.8.5",
439
+ express: "^5.1.0",
440
+ "@types/express": "^5.0.1",
441
+ "@types/cors": "^2.8.17",
442
+ fastify: "^5.3.3",
443
+ "@fastify/cors": "^11.0.1",
444
+ turbo: "^2.9.16",
445
+ nx: "^22.7.5",
446
+ "vite-plus": "0.1.24",
447
+ rolldown: "1.1.0",
448
+ ai: "^6.0.3",
449
+ "@ai-sdk/google": "^3.0.1",
450
+ "@ai-sdk/vue": "^3.0.3",
451
+ "@ai-sdk/svelte": "^4.0.3",
452
+ "@ai-sdk/react": "^3.0.3",
453
+ "@ai-sdk/devtools": "^0.0.2",
454
+ streamdown: "^1.6.10",
455
+ shiki: "^3.20.0",
456
+ "@orpc/server": "^1.13.14",
457
+ "@orpc/client": "^1.13.14",
458
+ "@orpc/openapi": "^1.13.14",
459
+ "@orpc/zod": "^1.13.14",
460
+ "@orpc/tanstack-query": "^1.13.14",
461
+ "@trpc/tanstack-react-query": "^11.16.0",
462
+ "@trpc/server": "^11.16.0",
463
+ "@trpc/client": "^11.16.0",
464
+ next: "^16.2.0",
465
+ nitro: "^3.0.260429-beta",
466
+ convex: "^1.33.1",
467
+ "@convex-dev/react-query": "^0.1.0",
468
+ "@convex-dev/agent": "^0.3.2",
469
+ "@convex-dev/polar": "^0.9.1",
470
+ "convex-svelte": "^0.0.12",
471
+ "convex-nuxt": "0.1.5",
472
+ "convex-vue": "^0.1.5",
473
+ "@convex-dev/better-auth": "^0.12.2",
474
+ "@tanstack/svelte-query": "^5.85.3",
475
+ "@tanstack/svelte-query-devtools": "^5.85.3",
476
+ "@tanstack/vue-query-devtools": "^6.1.5",
477
+ "@tanstack/vue-query": "^5.92.9",
478
+ "@tanstack/react-query-devtools": "^5.91.1",
479
+ "@tanstack/react-query": "^5.90.12",
480
+ "@tanstack/react-form": "^1.28.0",
481
+ "@tanstack/react-router-ssr-query": "^1.166.11",
482
+ "@tanstack/solid-form": "^1.28.0",
483
+ "@tanstack/svelte-form": "^1.28.0",
484
+ "@tanstack/solid-query": "^5.99.1",
485
+ "@tanstack/solid-query-devtools": "^5.99.1",
486
+ "@tanstack/solid-router-devtools": "^1.166.13",
487
+ wrangler: "^4.77.0",
488
+ "@cloudflare/vite-plugin": "^1.17.1",
489
+ "@opennextjs/cloudflare": "^1.17.3",
490
+ "nitro-cloudflare-dev": "^0.2.2",
491
+ "@sveltejs/adapter-cloudflare": "^7.2.8",
492
+ "@cloudflare/workers-types": "^4.20251213.0",
493
+ "@astrojs/cloudflare": "^13.0.1",
494
+ "@astrojs/node": "^10.0.0-beta.9",
495
+ alchemy: "^0.91.2",
496
+ dotenv: "^17.2.2",
497
+ tsdown: "^0.21.9",
498
+ zod: "^4.1.13",
499
+ "@t3-oss/env-core": "^0.13.1",
500
+ "@t3-oss/env-nextjs": "^0.13.1",
501
+ "@t3-oss/env-nuxt": "^0.13.1",
502
+ "@polar-sh/better-auth": "^1.8.4",
503
+ "@polar-sh/checkout": "^0.2.1",
504
+ "@polar-sh/sdk": "^0.47.1",
505
+ "@stripe/react-stripe-js": "^4.0.2",
506
+ "@stripe/stripe-js": "^7.9.0",
507
+ evlog: "^2.18.1"
508
+ };
509
+ /**
510
+ * Add dependencies to a package.json file in the VFS
511
+ */
512
+ function addPackageDependency(options) {
513
+ const { vfs, packagePath, dependencies = [], devDependencies = [], customDependencies = {}, customDevDependencies = {} } = options;
514
+ const pkgJson = vfs.readJson(packagePath);
515
+ if (!pkgJson) return;
516
+ pkgJson.dependencies = pkgJson.dependencies || {};
517
+ pkgJson.devDependencies = pkgJson.devDependencies || {};
518
+ for (const dep of dependencies) if (!pkgJson.dependencies[dep]) {
519
+ const version = dependencyVersionMap[dep];
520
+ if (!version) throw new Error(`Missing version for dependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
521
+ pkgJson.dependencies[dep] = version;
522
+ }
523
+ for (const dep of devDependencies) if (!pkgJson.devDependencies[dep]) {
524
+ const version = dependencyVersionMap[dep];
525
+ if (!version) throw new Error(`Missing version for devDependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`);
526
+ pkgJson.devDependencies[dep] = version;
527
+ }
528
+ for (const [dep, version] of Object.entries(customDependencies)) pkgJson.dependencies[dep] = version;
529
+ for (const [dep, version] of Object.entries(customDevDependencies)) pkgJson.devDependencies[dep] = version;
530
+ vfs.writeJson(packagePath, pkgJson);
531
+ }
532
+ //#endregion
383
533
  //#region src/utils/db-scripts.ts
384
534
  function getDbScriptSupport(config) {
385
535
  const isD1Alchemy = config.dbSetup === "d1" && (config.serverDeploy === "cloudflare" || config.backend === "self" && config.webDeploy === "cloudflare");
@@ -406,6 +556,7 @@ function getDbScriptSupport(config) {
406
556
  * Package.json configuration post-processor
407
557
  * Updates package names, scripts, and workspaces after template generation
408
558
  */
559
+ const VITE_PLUS_VERSION = dependencyVersionMap["vite-plus"];
409
560
  /**
410
561
  * Update all package.json files with proper names, scripts, and workspaces
411
562
  */
@@ -417,6 +568,7 @@ function processPackageConfigs(vfs, config) {
417
568
  updateInfraPackageJson(vfs, config);
418
569
  updateDesktopPackageJson(vfs, config);
419
570
  renameDevScriptsForAlchemy(vfs, config);
571
+ updateVitePlusPackageScripts(vfs, config);
420
572
  if (config.backend === "convex") updateConvexPackageJson(vfs, config);
421
573
  else if (config.backend !== "none") {
422
574
  updateDbPackageJson(vfs, config);
@@ -429,10 +581,8 @@ function updateRootPackageJson(vfs, config) {
429
581
  if (!pkgJson) return;
430
582
  pkgJson.name = config.projectName;
431
583
  pkgJson.scripts = pkgJson.scripts || {};
432
- let workspaces = [];
433
- if (Array.isArray(pkgJson.workspaces)) workspaces = pkgJson.workspaces;
434
- else if (pkgJson.workspaces && typeof pkgJson.workspaces === "object" && pkgJson.workspaces.packages) workspaces = pkgJson.workspaces.packages;
435
- pkgJson.workspaces = workspaces;
584
+ const existingWorkspaces = pkgJson.workspaces;
585
+ const workspaces = getWorkspacePackages(existingWorkspaces);
436
586
  const scripts = pkgJson.scripts;
437
587
  const { projectName, packageManager, backend, database, orm, dbSetup, addons, frontend } = config;
438
588
  const hasWebApp = frontend.some((item) => desktopWebFrontends.includes(item));
@@ -445,16 +595,27 @@ function updateRootPackageJson(vfs, config) {
445
595
  const dbPackageName = `@${projectName}/db`;
446
596
  const hasTurborepo = addons.includes("turborepo");
447
597
  const hasNx = addons.includes("nx");
598
+ const hasVitePlus = addons.includes("vite-plus");
599
+ const hasVitePlusNativeHooks = hasVitePlus && !addons.includes("husky") && !addons.includes("lefthook");
448
600
  const dbSupport = getDbScriptSupport(config);
449
601
  const needsDbScripts = dbSupport.hasDbScripts;
450
602
  const isD1Alchemy = dbSupport.isD1Alchemy;
451
603
  const pmConfig = getPackageManagerConfig(packageManager, {
452
604
  hasTurborepo,
453
- hasNx
605
+ hasNx,
606
+ hasVitePlus
454
607
  });
455
608
  scripts.dev = pmConfig.dev;
456
609
  scripts.build = pmConfig.build;
457
610
  scripts["check-types"] = pmConfig.checkTypes;
611
+ if (hasVitePlus) {
612
+ scripts.check = "vp check && vp run -r check-types";
613
+ scripts.lint = "vp lint";
614
+ scripts.format = "vp fmt";
615
+ scripts.staged = "vp staged";
616
+ if (hasVitePlusNativeHooks) scripts["hooks:setup"] = "vp config";
617
+ else delete scripts["hooks:setup"];
618
+ }
458
619
  if (hasNativeApp) scripts["dev:native"] = pmConfig.filter("native", "dev");
459
620
  if (hasWebApp) scripts["dev:web"] = pmConfig.filter("web", "dev");
460
621
  if (addons.includes("electrobun")) {
@@ -493,6 +654,11 @@ function updateRootPackageJson(vfs, config) {
493
654
  ...pkgJson.overrides,
494
655
  "@vue/devtools-api": "^8.0.7"
495
656
  };
657
+ if (hasVitePlus) pkgJson.overrides = {
658
+ ...pkgJson.overrides,
659
+ vite: `npm:@voidzero-dev/vite-plus-core@${VITE_PLUS_VERSION}`,
660
+ vitest: `npm:@voidzero-dev/vite-plus-test@${VITE_PLUS_VERSION}`
661
+ };
496
662
  if (backend === "convex") {
497
663
  if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
498
664
  if ((config.frontend.length > 0 || addons.includes("starlight")) && !workspaces.includes("apps/*")) workspaces.push("apps/*");
@@ -500,8 +666,21 @@ function updateRootPackageJson(vfs, config) {
500
666
  if (!workspaces.includes("apps/*")) workspaces.push("apps/*");
501
667
  if (!workspaces.includes("packages/*")) workspaces.push("packages/*");
502
668
  }
669
+ pkgJson.workspaces = getUpdatedWorkspaces(existingWorkspaces, workspaces);
503
670
  vfs.writeJson("package.json", pkgJson);
504
671
  }
672
+ function getWorkspacePackages(workspaces) {
673
+ if (Array.isArray(workspaces)) return workspaces;
674
+ if (workspaces && typeof workspaces === "object" && workspaces.packages) return workspaces.packages;
675
+ return [];
676
+ }
677
+ function getUpdatedWorkspaces(existingWorkspaces, packages) {
678
+ if (existingWorkspaces && !Array.isArray(existingWorkspaces) && typeof existingWorkspaces === "object" && existingWorkspaces.catalog) return {
679
+ ...existingWorkspaces,
680
+ packages
681
+ };
682
+ return packages;
683
+ }
505
684
  function getPackageManagerConfig(packageManager, options) {
506
685
  if (options.hasTurborepo) return {
507
686
  dev: "turbo dev",
@@ -515,6 +694,12 @@ function getPackageManagerConfig(packageManager, options) {
515
694
  checkTypes: "nx run-many -t check-types",
516
695
  filter: (workspace, script) => `nx run-many -t ${script} --projects=${workspace}`
517
696
  };
697
+ if (options.hasVitePlus) return {
698
+ dev: "vp run -r dev",
699
+ build: "vp run -r build",
700
+ checkTypes: "vp run -r check-types",
701
+ filter: (workspace, script) => `vp run --filter ${workspace} ${script}`
702
+ };
518
703
  switch (packageManager) {
519
704
  case "pnpm": return {
520
705
  dev: "pnpm -r dev",
@@ -542,14 +727,17 @@ function updateDesktopPackageJson(vfs, config) {
542
727
  const { packageManager, addons, frontend } = config;
543
728
  const hasTurborepo = addons.includes("turborepo");
544
729
  const hasNx = addons.includes("nx");
730
+ const hasVitePlus = addons.includes("vite-plus");
545
731
  const desktopBuildScript = frontend.includes("nuxt") ? "generate" : "build";
546
732
  const webBuildCommand = getDesktopWebCommand(packageManager, {
547
733
  hasTurborepo,
548
- hasNx
734
+ hasNx,
735
+ hasVitePlus
549
736
  }, desktopBuildScript);
550
737
  const webDevCommand = getDesktopWebCommand(packageManager, {
551
738
  hasTurborepo,
552
- hasNx
739
+ hasNx,
740
+ hasVitePlus
553
741
  }, "dev");
554
742
  const localRunCommand = getLocalRunCommand(packageManager);
555
743
  pkgJson.scripts = {
@@ -568,6 +756,7 @@ function updateDesktopPackageJson(vfs, config) {
568
756
  function getDesktopWebCommand(packageManager, options, script) {
569
757
  if (options.hasTurborepo) return `turbo -F web ${script}`;
570
758
  if (options.hasNx) return `nx run-many -t ${script} --projects=web`;
759
+ if (options.hasVitePlus) return `vp run --filter web ${script}`;
571
760
  switch (packageManager) {
572
761
  case "npm": return `npm run ${script} --workspace web`;
573
762
  case "pnpm": return `pnpm -w --filter web ${script}`;
@@ -691,153 +880,21 @@ function renameDevScriptsForAlchemy(vfs, config) {
691
880
  }
692
881
  }
693
882
  }
694
- //#endregion
695
- //#region src/utils/add-deps.ts
696
- const dependencyVersionMap = {
697
- typescript: "^6",
698
- "better-auth": "1.6.11",
699
- "@better-auth/expo": "1.6.11",
700
- "@clerk/backend": "^3.2.1",
701
- "@clerk/express": "^2.0.5",
702
- "@clerk/fastify": "^3.1.3",
703
- "@clerk/nextjs": "^7.0.5",
704
- "@clerk/react": "^6.1.1",
705
- "@clerk/react-router": "^3.0.5",
706
- "@clerk/tanstack-react-start": "^1.1.3",
707
- "@clerk/expo": "^3.1.3",
708
- "drizzle-orm": "^0.45.1",
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);
883
+ function updateVitePlusPackageScripts(vfs, config) {
884
+ if (!config.addons.includes("vite-plus")) return;
885
+ const webPkgPath = "apps/web/package.json";
886
+ const webPkg = vfs.readJson(webPkgPath);
887
+ if (!webPkg?.scripts) return;
888
+ const viteScriptReplacements = {
889
+ vite: "vp dev",
890
+ "vite dev": "vp dev",
891
+ "vite build": "vp build",
892
+ "vite preview": "vp preview",
893
+ "vitest run": "vp test",
894
+ "vite build && tsc --noEmit": "vp build && tsc --noEmit"
895
+ };
896
+ for (const [scriptName, command] of Object.entries(webPkg.scripts)) webPkg.scripts[scriptName] = viteScriptReplacements[command] ?? command;
897
+ vfs.writeJson(webPkgPath, webPkg);
841
898
  }
842
899
  //#endregion
843
900
  //#region src/processors/addons-deps.ts
@@ -863,6 +920,11 @@ function processAddonsDeps(vfs, config) {
863
920
  packagePath: "package.json",
864
921
  devDependencies: ["nx"]
865
922
  });
923
+ if (config.addons.includes("vite-plus")) addPackageDependency({
924
+ vfs,
925
+ packagePath: "package.json",
926
+ devDependencies: ["vite-plus", "rolldown"]
927
+ });
866
928
  if (config.addons.includes("evlog")) {
867
929
  const serverPkgPath = "apps/server/package.json";
868
930
  if (vfs.exists(serverPkgPath) && config.backend !== "self" && config.backend !== "none") addPackageDependency({
@@ -2568,6 +2630,86 @@ function processInfraDeps(vfs, config) {
2568
2630
  });
2569
2631
  }
2570
2632
  //#endregion
2633
+ //#region src/utils/generated-ignore-patterns.ts
2634
+ const FRONTEND_GENERATED_PATTERNS = {
2635
+ "tanstack-router": [
2636
+ "apps/web/dist/**",
2637
+ "apps/web/.tanstack/**",
2638
+ "apps/web/src/routeTree.gen.ts"
2639
+ ],
2640
+ "react-router": ["apps/web/build/**", "apps/web/.react-router/**"],
2641
+ "tanstack-start": [
2642
+ "apps/web/dist/**",
2643
+ "apps/web/.vinxi/**",
2644
+ "apps/web/.tanstack/**",
2645
+ "apps/web/src/routeTree.gen.ts"
2646
+ ],
2647
+ next: ["apps/web/.next/**", "apps/web/out/**"],
2648
+ nuxt: [
2649
+ "apps/web/.nuxt/**",
2650
+ "apps/web/.output/**",
2651
+ "apps/web/.data/**",
2652
+ "apps/web/.nitro/**"
2653
+ ],
2654
+ svelte: [
2655
+ "apps/web/.svelte-kit/**",
2656
+ "apps/web/build/**",
2657
+ "apps/web/.output/**"
2658
+ ],
2659
+ solid: [
2660
+ "apps/web/dist/**",
2661
+ "apps/web/.tanstack/**",
2662
+ "apps/web/src/routeTree.gen.ts"
2663
+ ],
2664
+ astro: ["apps/web/dist/**", "apps/web/.astro/**"],
2665
+ "native-bare": [
2666
+ "apps/native/.expo/**",
2667
+ "apps/native/dist/**",
2668
+ "apps/native/web-build/**"
2669
+ ],
2670
+ "native-uniwind": [
2671
+ "apps/native/.expo/**",
2672
+ "apps/native/dist/**",
2673
+ "apps/native/web-build/**"
2674
+ ],
2675
+ "native-unistyles": [
2676
+ "apps/native/.expo/**",
2677
+ "apps/native/dist/**",
2678
+ "apps/native/web-build/**",
2679
+ "apps/native/ios/**",
2680
+ "apps/native/android/**"
2681
+ ]
2682
+ };
2683
+ const SERVER_BUILD_BACKENDS = [
2684
+ "hono",
2685
+ "express",
2686
+ "fastify",
2687
+ "elysia"
2688
+ ];
2689
+ function getStackGeneratedIgnorePatterns(config) {
2690
+ const patterns = /* @__PURE__ */ new Set();
2691
+ for (const frontend of config.frontend) {
2692
+ const frontendPatterns = FRONTEND_GENERATED_PATTERNS[frontend];
2693
+ if (!frontendPatterns) continue;
2694
+ for (const pattern of frontendPatterns) patterns.add(pattern);
2695
+ }
2696
+ if (SERVER_BUILD_BACKENDS.includes(config.backend)) patterns.add("apps/server/dist/**");
2697
+ if (config.database !== "none" && config.orm !== "none") patterns.add("packages/db/dist/**");
2698
+ if (config.database === "sqlite" && config.dbSetup !== "d1" && config.orm !== "none") patterns.add("packages/db/local.db*");
2699
+ if (config.orm === "prisma") {
2700
+ patterns.add("packages/db/prisma/generated/**");
2701
+ if (config.database === "sqlite" && config.dbSetup === "turso") patterns.add("packages/db/prisma/**/*.db*");
2702
+ }
2703
+ if (config.backend === "convex") patterns.add("packages/backend/convex/_generated/**");
2704
+ if (config.runtime === "workers" || config.dbSetup === "d1" || config.webDeploy === "cloudflare" || config.serverDeploy === "cloudflare") {
2705
+ patterns.add(".alchemy/**");
2706
+ patterns.add(".wrangler/**");
2707
+ patterns.add("**/.wrangler/**");
2708
+ if (config.frontend.includes("next")) patterns.add("apps/web/.open-next/**");
2709
+ }
2710
+ return [...patterns];
2711
+ }
2712
+ //#endregion
2571
2713
  //#region src/processors/nx-generator.ts
2572
2714
  function processNxConfig(vfs, config) {
2573
2715
  if (!config.addons.includes("nx")) return;
@@ -2582,35 +2724,40 @@ function generateNxConfig(config) {
2582
2724
  const isDocker = dbSetup === "docker";
2583
2725
  const isSqliteLocal = database === "sqlite" && dbSetup !== "d1" && hasDatabase;
2584
2726
  const hasCloudflare = webDeploy === "cloudflare" || serverDeploy === "cloudflare";
2727
+ const targetDefaults = {
2728
+ build: {
2729
+ dependsOn: ["^build"],
2730
+ inputs: ["production", "^production"]
2731
+ },
2732
+ "check-types": {
2733
+ dependsOn: ["^check-types"],
2734
+ inputs: ["default", "^default"]
2735
+ },
2736
+ dev: { cache: false },
2737
+ ...isConvex ? getConvexTargets() : {},
2738
+ ...!isConvex && hasDatabase ? getDatabaseTargets(dbSupport) : {},
2739
+ ...isDocker ? getDockerTargets() : {},
2740
+ ...isSqliteLocal ? getSqliteLocalTarget() : {},
2741
+ ...hasCloudflare ? getDeployTargets() : {}
2742
+ };
2585
2743
  return {
2586
2744
  $schema: "./node_modules/nx/schemas/nx-schema.json",
2587
2745
  namedInputs: {
2588
2746
  default: ["{projectRoot}/**/*", "sharedGlobals"],
2589
2747
  production: [
2590
2748
  "default",
2749
+ ...getNxProductionInputExclusions(config),
2591
2750
  "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
2592
2751
  "!{projectRoot}/tsconfig.spec.json"
2593
2752
  ],
2594
2753
  sharedGlobals: []
2595
2754
  },
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
- }
2755
+ targetDefaults
2612
2756
  };
2613
2757
  }
2758
+ function getNxProductionInputExclusions(config) {
2759
+ return getStackGeneratedIgnorePatterns(config).map((pattern) => `!{workspaceRoot}/${pattern}`);
2760
+ }
2614
2761
  function getConvexTargets() {
2615
2762
  return { "dev:setup": { cache: false } };
2616
2763
  }
@@ -3102,7 +3249,8 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
3102
3249
  husky: "- **Husky** - Git hooks for code quality",
3103
3250
  starlight: "- **Starlight** - Documentation site with Astro",
3104
3251
  turborepo: "- **Turborepo** - Optimized monorepo build system",
3105
- nx: "- **Nx** - Smart monorepo task orchestration and caching"
3252
+ nx: "- **Nx** - Smart monorepo task orchestration and caching",
3253
+ "vite-plus": "- **Vite+** - Unified Vite toolchain, workspace task runner, linting, and formatting"
3106
3254
  };
3107
3255
  for (const addon of addons) if (addonFeatures[addon]) features.push(addonFeatures[addon]);
3108
3256
  return features.join("\n");
@@ -3201,8 +3349,15 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
3201
3349
  if (dbSupport.hasDbStudio) scripts += `\n- \`${packageManagerRunCmd} db:studio\`: Open database studio UI`;
3202
3350
  }
3203
3351
  if (database === "sqlite" && dbSetup !== "d1" && dbSupport.hasDbScripts) scripts += `\n- \`${packageManagerRunCmd} db:local\`: Start the local SQLite database`;
3204
- if (addons.includes("biome")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
3205
- if (addons.includes("oxlint")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Oxlint and Oxfmt`;
3352
+ if (addons.includes("vite-plus")) {
3353
+ const hasVitePlusNativeHooks = !addons.includes("husky") && !addons.includes("lefthook");
3354
+ scripts += `\n- \`${packageManagerRunCmd} check\`: Run Vite+ format/lint checks and workspace TypeScript checks
3355
+ - \`${packageManagerRunCmd} lint\`: Run Vite+ lint checks
3356
+ - \`${packageManagerRunCmd} format\`: Run Vite+ formatting
3357
+ - \`${packageManagerRunCmd} staged\`: Run Vite+ checks against staged files`;
3358
+ if (hasVitePlusNativeHooks) scripts += `\n- \`${packageManagerRunCmd} hooks:setup\`: Install Vite+ native Git hooks with \`vp config\``;
3359
+ } else if (addons.includes("biome")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
3360
+ else if (addons.includes("oxlint")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Oxlint and Oxfmt`;
3206
3361
  if (addons.includes("pwa")) scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} generate-pwa-assets\`: Generate PWA assets`;
3207
3362
  if (addons.includes("tauri")) {
3208
3363
  scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} desktop:dev\`: Start Tauri desktop app in development
@@ -3231,11 +3386,15 @@ function generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeplo
3231
3386
  }
3232
3387
  function generateGitHooksSection(packageManagerRunCmd, addons) {
3233
3388
  const hasHusky = addons.includes("husky");
3234
- const hasLinting = addons.includes("biome") || addons.includes("oxlint");
3389
+ const hasLefthook = addons.includes("lefthook");
3390
+ const hasVitePlus = addons.includes("vite-plus");
3391
+ const hasVitePlusNativeHooks = hasVitePlus && !hasHusky && !hasLefthook;
3392
+ const hasLinting = addons.includes("biome") || addons.includes("oxlint") || hasVitePlus;
3235
3393
  if (!hasHusky && !hasLinting) return "";
3236
3394
  const lines = ["## Git Hooks and Formatting", ""];
3237
3395
  if (hasHusky) lines.push(`- Initialize hooks: \`${packageManagerRunCmd} prepare\``);
3238
- if (hasLinting) lines.push(`- Format and lint fix: \`${packageManagerRunCmd} check\``);
3396
+ if (hasVitePlusNativeHooks) lines.push(`- Optional native Vite+ hooks: \`${packageManagerRunCmd} hooks:setup\``, "- Docs: [Vite+ commit hooks](https://viteplus.dev/guide/commit-hooks)");
3397
+ if (hasLinting) lines.push(`- Run checks: \`${packageManagerRunCmd} check\``);
3239
3398
  return `${lines.join("\n")}\n\n`;
3240
3399
  }
3241
3400
  //#endregion
@@ -3369,6 +3528,51 @@ function getDeployTasks() {
3369
3528
  };
3370
3529
  }
3371
3530
  //#endregion
3531
+ //#region src/processors/vite-plus-generator.ts
3532
+ const BASE_IGNORE_PATTERNS = ["node_modules/**", "**/node_modules/**"];
3533
+ const STAGED_PATTERN = "*.{js,ts,jsx,tsx,vue,svelte,json,jsonc,css,md}";
3534
+ function processVitePlusConfig(vfs, config) {
3535
+ if (!config.addons.includes("vite-plus")) return;
3536
+ vfs.writeFile("vite.config.ts", generateVitePlusConfig(config));
3537
+ }
3538
+ function formatStringArray(values, indent = 4) {
3539
+ const spaces = " ".repeat(indent);
3540
+ return values.map((value) => `${spaces}${JSON.stringify(value)},`).join("\n");
3541
+ }
3542
+ function getVitePlusIgnorePatterns(config) {
3543
+ const patterns = new Set(BASE_IGNORE_PATTERNS);
3544
+ for (const pattern of getStackGeneratedIgnorePatterns(config)) patterns.add(pattern);
3545
+ return [...patterns];
3546
+ }
3547
+ function generateVitePlusConfig(config) {
3548
+ const ignorePatterns = formatStringArray(getVitePlusIgnorePatterns(config), 6);
3549
+ return `import { defineConfig } from "vite-plus";
3550
+
3551
+ export default defineConfig({
3552
+ lint: {
3553
+ ignorePatterns: [
3554
+ ${ignorePatterns}
3555
+ ],
3556
+ options: {
3557
+ typeAware: false,
3558
+ typeCheck: false,
3559
+ },
3560
+ },
3561
+ fmt: {
3562
+ ignorePatterns: [
3563
+ ${ignorePatterns}
3564
+ ],
3565
+ singleQuote: false,
3566
+ semi: true,
3567
+ sortPackageJson: true,
3568
+ },
3569
+ staged: {
3570
+ ${JSON.stringify(STAGED_PATTERN)}: "vp check --fix",
3571
+ },
3572
+ });
3573
+ `;
3574
+ }
3575
+ //#endregion
3372
3576
  //#region src/processors/workspace-deps.ts
3373
3577
  function processWorkspaceDeps(vfs, config) {
3374
3578
  const { projectName, packageManager, runtime, backend, database, auth, api, serverDeploy, webDeploy } = config;
@@ -3533,6 +3737,7 @@ function processDependencies(vfs, config) {
3533
3737
  processExamplesDeps(vfs, config);
3534
3738
  processTurboConfig(vfs, config);
3535
3739
  processNxConfig(vfs, config);
3740
+ processVitePlusConfig(vfs, config);
3536
3741
  }
3537
3742
  //#endregion
3538
3743
  //#region src/template-handlers/utils.ts
@@ -3842,7 +4047,7 @@ async function processAddonTemplates(vfs, templates, config) {
3842
4047
  if (!config.addons || config.addons.length === 0) return;
3843
4048
  for (const addon of config.addons) {
3844
4049
  if (addon === "none") continue;
3845
- if (addon === "turborepo" || addon === "nx") continue;
4050
+ if (addon === "turborepo" || addon === "nx" || addon === "vite-plus") continue;
3846
4051
  if (addon === "pwa") {
3847
4052
  if (config.frontend.includes("next")) processTemplatesFromPrefix(vfs, templates, "addons/pwa/apps/web/next", "apps/web", config);
3848
4053
  else if (config.frontend.some((f) => [
@@ -4195,11 +4400,11 @@ export default {
4195
4400
  "type": "module",
4196
4401
  "scripts": {},
4197
4402
  "dependencies": {
4198
- "electrobun": "^1.15.1"
4403
+ "electrobun": "^1.18.1"
4199
4404
  },
4200
4405
  "devDependencies": {
4201
- "@types/bun": "^1.3.4",
4202
- "concurrently": "^9.1.0",
4406
+ "@types/bun": "^1.3.14",
4407
+ "concurrently": "^10.0.3",
4203
4408
  "typescript": "^6"
4204
4409
  }
4205
4410
  }
@@ -4277,6 +4482,10 @@ pre-commit:
4277
4482
  - name: oxfmt
4278
4483
  run: {{packageManager}} oxfmt --write {staged_files}
4279
4484
  stage_fixed: true
4485
+ {{else if (includes addons "vite-plus")}}
4486
+ - name: vite-plus
4487
+ run: {{packageManager}} vp staged
4488
+ stage_fixed: true
4280
4489
  {{else}}
4281
4490
  # Add your pre-commit commands here
4282
4491
  # Example:
@@ -19028,6 +19237,9 @@ dist
19028
19237
  build
19029
19238
  *.tsbuildinfo
19030
19239
 
19240
+ # Generated files
19241
+ apps/web/src/routeTree.gen.ts
19242
+
19031
19243
  # Environment variables
19032
19244
  .env
19033
19245
  .env*.local
@@ -31603,7 +31815,7 @@ export default function Home() {
31603
31815
  `],
31604
31816
  ["frontend/react/react-router/vite.config.ts.hbs", `import { reactRouter } from "@react-router/dev/vite";
31605
31817
  import tailwindcss from "@tailwindcss/vite";
31606
- import { defineConfig } from "vite";
31818
+ import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
31607
31819
  import tsconfigPaths from "vite-tsconfig-paths";
31608
31820
 
31609
31821
  export default defineConfig({
@@ -31612,7 +31824,8 @@ export default defineConfig({
31612
31824
  reactRouter(),
31613
31825
  tsconfigPaths(),
31614
31826
  ],
31615
- });`],
31827
+ });
31828
+ `],
31616
31829
  ["frontend/react/tanstack-router/index.html.hbs", `<!DOCTYPE html>
31617
31830
  <html lang="en">
31618
31831
  <head>
@@ -32055,7 +32268,7 @@ function HomeComponent() {
32055
32268
  ["frontend/react/tanstack-router/vite.config.ts.hbs", `import tailwindcss from "@tailwindcss/vite";
32056
32269
  import { tanstackRouter } from "@tanstack/router-plugin/vite";
32057
32270
  import react from "@vitejs/plugin-react";
32058
- import { defineConfig } from "vite";
32271
+ import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
32059
32272
 
32060
32273
  export default defineConfig({
32061
32274
  server: {
@@ -32643,7 +32856,7 @@ function HomeComponent() {
32643
32856
  }
32644
32857
  }
32645
32858
  `],
32646
- ["frontend/react/tanstack-start/vite.config.ts.hbs", `import { defineConfig } from "vite";
32859
+ ["frontend/react/tanstack-start/vite.config.ts.hbs", `import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
32647
32860
  import { tanstackStart } from "@tanstack/react-start/plugin/vite";
32648
32861
  import tailwindcss from "@tailwindcss/vite";
32649
32862
  import viteReact from "@vitejs/plugin-react";
@@ -33134,7 +33347,7 @@ body {
33134
33347
  }
33135
33348
  }
33136
33349
  `],
33137
- ["frontend/solid/vite.config.ts.hbs", `import { defineConfig } from "vite";
33350
+ ["frontend/solid/vite.config.ts.hbs", `import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
33138
33351
  import { tanstackRouter } from "@tanstack/router-plugin/vite";
33139
33352
  import solidPlugin from "vite-plugin-solid";
33140
33353
  import tailwindcss from "@tailwindcss/vite";
@@ -33154,7 +33367,8 @@ export default defineConfig({
33154
33367
  server: {
33155
33368
  port: 3001,
33156
33369
  },
33157
- });`],
33370
+ });
33371
+ `],
33158
33372
  ["frontend/svelte/_gitignore", `node_modules
33159
33373
 
33160
33374
  # Output
@@ -33495,7 +33709,7 @@ export default config;
33495
33709
  `],
33496
33710
  ["frontend/svelte/vite.config.ts.hbs", `import tailwindcss from "@tailwindcss/vite";
33497
33711
  import { sveltekit } from "@sveltejs/kit/vite";
33498
- import { defineConfig } from "vite";
33712
+ import { defineConfig } from "{{#if (includes addons "vite-plus")}}vite-plus{{else}}vite{{/if}}";
33499
33713
 
33500
33714
  export default defineConfig({
33501
33715
  plugins: [tailwindcss(), sveltekit()],
@@ -35299,6 +35513,6 @@ function SuccessPage() {
35299
35513
  ]);
35300
35514
  const TEMPLATE_COUNT = 483;
35301
35515
  //#endregion
35302
- export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };
35516
+ export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processNxConfig, processPackageConfigs, processTemplateString, processTurboConfig, processVitePlusConfig, transformFilename, writeBtsConfigToVfs };
35303
35517
 
35304
35518
  //# sourceMappingURL=index.mjs.map