better-ts-stack 0.1.1 → 1.1.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.
Files changed (118) hide show
  1. package/README.md +12 -6
  2. package/dist/builder/configGenerator.d.ts.map +1 -1
  3. package/dist/builder/configGenerator.js +30 -24
  4. package/dist/builder/configGenerator.js.map +1 -1
  5. package/dist/builder/dependencyInstaller.d.ts.map +1 -1
  6. package/dist/builder/dependencyInstaller.js +1 -10
  7. package/dist/builder/dependencyInstaller.js.map +1 -1
  8. package/dist/builder/index.d.ts.map +1 -1
  9. package/dist/builder/index.js +3 -7
  10. package/dist/builder/index.js.map +1 -1
  11. package/dist/builder/moduleSelector.d.ts.map +1 -1
  12. package/dist/builder/moduleSelector.js +1 -1
  13. package/dist/builder/moduleSelector.js.map +1 -1
  14. package/dist/builder/templateContext.d.ts +2 -2
  15. package/dist/builder/templateContext.d.ts.map +1 -1
  16. package/dist/builder/templateContext.js +1 -3
  17. package/dist/builder/templateContext.js.map +1 -1
  18. package/dist/modules/registry.d.ts.map +1 -1
  19. package/dist/modules/registry.js +2 -5
  20. package/dist/modules/registry.js.map +1 -1
  21. package/dist/output/nextSteps.d.ts.map +1 -1
  22. package/dist/output/nextSteps.js +7 -34
  23. package/dist/output/nextSteps.js.map +1 -1
  24. package/dist/prompts/index.d.ts.map +1 -1
  25. package/dist/prompts/index.js +3 -14
  26. package/dist/prompts/index.js.map +1 -1
  27. package/dist/prompts/stack.d.ts +3 -0
  28. package/dist/prompts/stack.d.ts.map +1 -0
  29. package/dist/prompts/stack.js +77 -0
  30. package/dist/prompts/stack.js.map +1 -0
  31. package/dist/types/index.d.ts +12 -10
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/types/index.js +6 -10
  34. package/dist/types/index.js.map +1 -1
  35. package/dist/validators/index.d.ts +1 -1
  36. package/dist/validators/index.d.ts.map +1 -1
  37. package/dist/validators/index.js +1 -1
  38. package/package.json +12 -12
  39. package/templates/backend/express/config.json +44 -42
  40. package/templates/backend/express/eslint.config.mjs +40 -31
  41. package/templates/backend/express/src/index.ts +61 -46
  42. package/templates/backend/express/src/routes/health.ts +12 -12
  43. package/templates/backend/express/tsconfig.json +25 -23
  44. package/templates/frontend/nextjs/config.json +33 -27
  45. package/templates/frontend/nextjs/eslint.config.mjs +11 -11
  46. package/templates/frontend/nextjs/proxy.ts.hbs +9 -8
  47. package/templates/frontend/nextjs/tsconfig.json +34 -21
  48. package/templates/frontend/tanstack/components.json +18 -0
  49. package/templates/frontend/tanstack/config.json +49 -0
  50. package/templates/frontend/tanstack/eslint.config.mjs +23 -0
  51. package/templates/frontend/tanstack/gitignore +38 -0
  52. package/templates/frontend/tanstack/public/favicon.svg +7 -0
  53. package/templates/frontend/tanstack/src/components/ui/button.tsx +51 -0
  54. package/templates/frontend/tanstack/src/components/ui/card.tsx +60 -0
  55. package/templates/frontend/tanstack/src/components/ui/field.tsx +67 -0
  56. package/templates/frontend/tanstack/src/components/ui/input.tsx +18 -0
  57. package/templates/frontend/tanstack/src/lib/utils.ts +6 -0
  58. package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -0
  59. package/templates/frontend/tanstack/src/router.tsx +32 -0
  60. package/templates/frontend/tanstack/src/routes/__root.tsx +70 -0
  61. package/templates/frontend/tanstack/src/routes/index.tsx.hbs +102 -0
  62. package/templates/frontend/tanstack/src/styles/app.css +85 -0
  63. package/templates/frontend/tanstack/tsconfig.json +22 -0
  64. package/templates/frontend/tanstack/vite.config.ts +14 -0
  65. package/templates/modules/auth/express/config.json +26 -1
  66. package/templates/modules/auth/express/src/routes/auth.ts.hbs +1 -1
  67. package/templates/modules/auth/express/src/services/userStore.ts.hbs +95 -107
  68. package/templates/modules/auth/nextjs/config.json +6 -6
  69. package/templates/modules/auth/nextjs/lib/auth.ts.hbs +34 -32
  70. package/templates/modules/auth/tanstack/config.json +33 -0
  71. package/templates/modules/auth/tanstack/src/components/auth/sign-in-form.tsx +135 -0
  72. package/templates/modules/auth/tanstack/src/components/auth/sign-out-button.tsx +49 -0
  73. package/templates/modules/auth/tanstack/src/components/auth/sign-up-form.tsx +153 -0
  74. package/templates/modules/auth/tanstack/src/lib/auth-client.ts +3 -0
  75. package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +12 -0
  76. package/templates/modules/auth/tanstack/src/lib/auth-schema.ts +39 -0
  77. package/templates/modules/auth/tanstack/src/lib/auth.ts.hbs +38 -0
  78. package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -0
  79. package/templates/modules/auth/tanstack/src/routes/api/auth/$.ts +16 -0
  80. package/templates/modules/auth/tanstack/src/routes/dashboard.tsx +111 -0
  81. package/templates/modules/auth/tanstack/src/routes/sign-in.tsx +37 -0
  82. package/templates/modules/auth/tanstack/src/routes/sign-up.tsx +37 -0
  83. package/templates/modules/docker/.dockerignore +14 -13
  84. package/templates/modules/docker/Dockerfile.hbs +64 -9
  85. package/templates/modules/docker/config.json +19 -16
  86. package/templates/modules/docker/docker-compose.yml.hbs +9 -9
  87. package/templates/modules/drizzle/express/config.json +27 -0
  88. package/templates/modules/drizzle/express/drizzle.config.ts +13 -0
  89. package/templates/modules/drizzle/express/src/lib/db.ts +13 -0
  90. package/templates/modules/drizzle/express/src/lib/schema.ts +10 -0
  91. package/templates/modules/drizzle/nextjs/config.json +27 -19
  92. package/templates/modules/drizzle/nextjs/lib/db.ts +3 -1
  93. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
  94. package/templates/modules/drizzle/tanstack/config.json +26 -0
  95. package/templates/modules/drizzle/tanstack/drizzle.config.ts +13 -0
  96. package/templates/modules/drizzle/tanstack/src/lib/db.ts +13 -0
  97. package/templates/modules/drizzle/tanstack/src/lib/schema.ts.hbs +84 -0
  98. package/templates/modules/mongoose/config.json +16 -16
  99. package/templates/modules/mongoose/src/lib/db.ts.hbs +0 -13
  100. package/templates/modules/mongoose/src/models/User.ts +48 -47
  101. package/templates/modules/prisma/express/config.json +27 -21
  102. package/templates/modules/prisma/express/prisma/schema.prisma +3 -2
  103. package/templates/modules/prisma/express/prisma.config.ts +12 -13
  104. package/templates/modules/prisma/express/src/lib/prisma.ts +24 -37
  105. package/templates/modules/prisma/nextjs/config.json +28 -23
  106. package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -90
  107. package/templates/modules/prisma/tanstack/config.json +28 -0
  108. package/templates/modules/prisma/tanstack/prisma/schema.prisma.hbs +91 -0
  109. package/templates/modules/prisma/tanstack/prisma.config.ts +12 -0
  110. package/templates/modules/prisma/tanstack/src/lib/prisma.ts +18 -0
  111. package/dist/prompts/backend/index.d.ts +0 -3
  112. package/dist/prompts/backend/index.d.ts.map +0 -1
  113. package/dist/prompts/backend/index.js +0 -128
  114. package/dist/prompts/backend/index.js.map +0 -1
  115. package/dist/prompts/frontend/index.d.ts +0 -3
  116. package/dist/prompts/frontend/index.d.ts.map +0 -1
  117. package/dist/prompts/frontend/index.js +0 -111
  118. package/dist/prompts/frontend/index.js.map +0 -1
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.collectStackChoices = collectStackChoices;
7
+ const prompts_1 = require("@clack/prompts");
8
+ const consola_1 = __importDefault(require("consola"));
9
+ const types_1 = require("../types");
10
+ async function collectStackChoices(applicationType) {
11
+ return (0, prompts_1.group)({
12
+ framework: async () => {
13
+ if (applicationType === "backend") {
14
+ while (true) {
15
+ const selection = await (0, prompts_1.select)({
16
+ message: "Select a backend framework:",
17
+ options: types_1.backendFrameworkOptions,
18
+ initialValue: "express",
19
+ });
20
+ if ((0, prompts_1.isCancel)(selection) || selection !== "nestjs")
21
+ return selection;
22
+ consola_1.default.warn("This framework is coming soon! Please select another option.");
23
+ }
24
+ }
25
+ return (0, prompts_1.select)({
26
+ message: "Select a frontend framework:",
27
+ options: types_1.frontendFrameworkOptions,
28
+ initialValue: "nextjs",
29
+ });
30
+ },
31
+ databaseType: () => (0, prompts_1.select)({
32
+ message: "Select a database:",
33
+ options: types_1.databaseTypeOptions,
34
+ initialValue: "none",
35
+ }),
36
+ orm: async ({ results }) => {
37
+ if (results.databaseType === "none")
38
+ return "none";
39
+ const options = results.databaseType === "mongodb"
40
+ ? types_1.mongodbOrmOptions
41
+ : types_1.postgresqlOrmOptions;
42
+ return (0, prompts_1.select)({
43
+ message: `Select an ORM for ${results.databaseType}:`,
44
+ options,
45
+ initialValue: options[0].value,
46
+ });
47
+ },
48
+ packageManager: () => (0, prompts_1.select)({
49
+ message: "Select a package manager:",
50
+ options: types_1.packageManagerOptions,
51
+ initialValue: "npm",
52
+ }),
53
+ useDocker: () => (0, prompts_1.confirm)({ message: "Use Docker?", initialValue: false }),
54
+ useAuth: async ({ results }) => {
55
+ if (applicationType === "fullstack" && results.databaseType === "none")
56
+ return false;
57
+ return (0, prompts_1.select)({
58
+ message: applicationType === "fullstack"
59
+ ? "Add Better Auth?"
60
+ : "Add authentication?",
61
+ options: types_1.authOptions,
62
+ initialValue: false,
63
+ });
64
+ },
65
+ initGit: () => (0, prompts_1.confirm)({
66
+ message: "Initialize a git repository?",
67
+ initialValue: true,
68
+ }),
69
+ installDeps: () => (0, prompts_1.confirm)({ message: "Install dependencies now?", initialValue: false }),
70
+ }, {
71
+ onCancel: () => {
72
+ (0, prompts_1.cancel)("Operation cancelled.");
73
+ process.exit(0);
74
+ },
75
+ });
76
+ }
77
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/prompts/stack.ts"],"names":[],"mappings":";;;;;AAoBA,kDA+EC;AAnGD,4CAA0E;AAC1E,sDAA8B;AAE9B,oCAekB;AAEX,KAAK,UAAU,mBAAmB,CACvC,eAAgC;IAEhC,OAAO,IAAA,eAAK,EACV;QACE,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,IAAI,EAAE,CAAC;oBACZ,MAAM,SAAS,GAAG,MAAM,IAAA,gBAAM,EAAmB;wBAC/C,OAAO,EAAE,6BAA6B;wBACtC,OAAO,EAAE,+BAAuB;wBAChC,YAAY,EAAE,SAAS;qBACxB,CAAC,CAAC;oBACH,IAAI,IAAA,kBAAQ,EAAC,SAAS,CAAC,IAAI,SAAS,KAAK,QAAQ;wBAC/C,OAAO,SAAS,CAAC;oBACnB,iBAAO,CAAC,IAAI,CACV,8DAA8D,CAC/D,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO,IAAA,gBAAM,EAAoB;gBAC/B,OAAO,EAAE,8BAA8B;gBACvC,OAAO,EAAE,gCAAwB;gBACjC,YAAY,EAAE,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC;QACD,YAAY,EAAE,GAAG,EAAE,CACjB,IAAA,gBAAM,EAAe;YACnB,OAAO,EAAE,oBAAoB;YAC7B,OAAO,EAAE,2BAAmB;YAC5B,YAAY,EAAE,MAAM;SACrB,CAAC;QACJ,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAA+B,EAAE;YACtD,IAAI,OAAO,CAAC,YAAY,KAAK,MAAM;gBAAE,OAAO,MAAe,CAAC;YAC5D,MAAM,OAAO,GACX,OAAO,CAAC,YAAY,KAAK,SAAS;gBAChC,CAAC,CAAC,yBAAiB;gBACnB,CAAC,CAAC,4BAAoB,CAAC;YAC3B,OAAO,IAAA,gBAAM,EAAY;gBACvB,OAAO,EAAE,qBAAqB,OAAO,CAAC,YAAY,GAAG;gBACrD,OAAO;gBACP,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK;aAC/B,CAAC,CAAC;QACL,CAAC;QACD,cAAc,EAAE,GAAG,EAAE,CACnB,IAAA,gBAAM,EAAiB;YACrB,OAAO,EAAE,2BAA2B;YACpC,OAAO,EAAE,6BAAqB;YAC9B,YAAY,EAAE,KAAK;SACpB,CAAC;QACJ,SAAS,EAAE,GAAG,EAAE,CAAC,IAAA,iBAAO,EAAC,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;QACzE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAA6B,EAAE;YACxD,IAAI,eAAe,KAAK,WAAW,IAAI,OAAO,CAAC,YAAY,KAAK,MAAM;gBACpE,OAAO,KAAK,CAAC;YACf,OAAO,IAAA,gBAAM,EAAC;gBACZ,OAAO,EACL,eAAe,KAAK,WAAW;oBAC7B,CAAC,CAAC,kBAAkB;oBACpB,CAAC,CAAC,qBAAqB;gBAC3B,OAAO,EAAE,mBAAW;gBACpB,YAAY,EAAE,KAAK;aACpB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,CACZ,IAAA,iBAAO,EAAC;YACN,OAAO,EAAE,8BAA8B;YACvC,YAAY,EAAE,IAAI;SACnB,CAAC;QACJ,WAAW,EAAE,GAAG,EAAE,CAChB,IAAA,iBAAO,EAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;KACzE,EACD;QACE,QAAQ,EAAE,GAAG,EAAE;YACb,IAAA,gBAAM,EAAC,sBAAsB,CAAC,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;KACF,CACF,CAAC;AACJ,CAAC"}
@@ -8,7 +8,7 @@ export interface Dependencies {
8
8
  [packageName: string]: string;
9
9
  }
10
10
  export type BackendFramework = "express" | "nestjs";
11
- export type FrontendFramework = "nextjs";
11
+ export type FrontendFramework = "nextjs" | "tanstack";
12
12
  export interface ProjectConfig {
13
13
  projectName: string;
14
14
  applicationType: ApplicationType;
@@ -27,8 +27,6 @@ export interface ProjectConfig {
27
27
  * This is essentially ProjectConfig without the derived/initial fields.
28
28
  */
29
29
  export type PromptChoices = Omit<ProjectConfig, "projectName" | "applicationType" | "database">;
30
- /** Type guard to validate OrmOption values */
31
- export declare function isValidOrmOption(value: unknown): value is OrmOption;
32
30
  /**
33
31
  * Derives the database option from database type and ORM selection.
34
32
  * Returns "none" if either is "none", otherwise returns the ORM which
@@ -42,6 +40,7 @@ export interface ModuleConfig {
42
40
  type: ModuleType;
43
41
  dependencies: Dependencies;
44
42
  devDependencies: Dependencies;
43
+ overrides: Dependencies;
45
44
  scripts: Record<string, string>;
46
45
  envVars: Record<string, string>;
47
46
  templateFiles: string[];
@@ -53,6 +52,7 @@ export interface Module {
53
52
  export interface MergedConfig {
54
53
  dependencies: Dependencies;
55
54
  devDependencies: Dependencies;
55
+ overrides: Dependencies;
56
56
  scripts: Record<string, string>;
57
57
  envVars: Record<string, string>;
58
58
  }
@@ -96,10 +96,15 @@ export declare const backendFrameworkOptions: ({
96
96
  label: string;
97
97
  hint: string;
98
98
  })[];
99
- export declare const frontendFrameworkOptions: {
99
+ export declare const frontendFrameworkOptions: ({
100
100
  value: "nextjs";
101
101
  label: string;
102
- }[];
102
+ hint?: undefined;
103
+ } | {
104
+ value: "tanstack";
105
+ label: string;
106
+ hint: string;
107
+ })[];
103
108
  export declare const databaseTypeOptions: ({
104
109
  value: "none";
105
110
  label: string;
@@ -110,13 +115,10 @@ export declare const databaseTypeOptions: ({
110
115
  value: "postgresql";
111
116
  label: string;
112
117
  })[];
113
- export declare const mongodbOrmOptions: ({
114
- value: "prisma";
115
- label: string;
116
- } | {
118
+ export declare const mongodbOrmOptions: {
117
119
  value: "mongoose";
118
120
  label: string;
119
- })[];
121
+ }[];
120
122
  export declare const postgresqlOrmOptions: ({
121
123
  value: "prisma";
122
124
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -2,16 +2,8 @@
2
2
  // Core type definitions for the CLI builder
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.authOptions = exports.packageManagerOptions = exports.databaseOptions = exports.postgresqlOrmOptions = exports.mongodbOrmOptions = exports.databaseTypeOptions = exports.frontendFrameworkOptions = exports.backendFrameworkOptions = exports.applicationTypeOptions = void 0;
5
- exports.isValidOrmOption = isValidOrmOption;
6
5
  exports.deriveDatabase = deriveDatabase;
7
6
  exports.buildError = buildError;
8
- /** Type guard to validate OrmOption values */
9
- function isValidOrmOption(value) {
10
- return (value === "prisma" ||
11
- value === "mongoose" ||
12
- value === "drizzle" ||
13
- value === "none");
14
- }
15
7
  /**
16
8
  * Derives the database option from database type and ORM selection.
17
9
  * Returns "none" if either is "none", otherwise returns the ORM which
@@ -37,7 +29,7 @@ function buildError(errorOrMessage, code, context, exitCode = 1) {
37
29
  // Type-safe option definitions
38
30
  exports.applicationTypeOptions = [
39
31
  { value: "backend", label: "Backend API (Express/NestJS)" },
40
- { value: "fullstack", label: "Full-stack App (Next.js)" },
32
+ { value: "fullstack", label: "Full-stack App (Next.js/TanStack)" },
41
33
  ];
42
34
  exports.backendFrameworkOptions = [
43
35
  { value: "express", label: "Express" },
@@ -45,6 +37,11 @@ exports.backendFrameworkOptions = [
45
37
  ];
46
38
  exports.frontendFrameworkOptions = [
47
39
  { value: "nextjs", label: "Next.js 16 (App Router)" },
40
+ {
41
+ value: "tanstack",
42
+ label: "TanStack Start (React)",
43
+ hint: "(Release Candidate)",
44
+ },
48
45
  ];
49
46
  // Database type options (what database system)
50
47
  exports.databaseTypeOptions = [
@@ -54,7 +51,6 @@ exports.databaseTypeOptions = [
54
51
  ];
55
52
  // ORM options for MongoDB
56
53
  exports.mongodbOrmOptions = [
57
- { value: "prisma", label: "Prisma (Type-safe ORM)" },
58
54
  { value: "mongoose", label: "Mongoose (MongoDB ODM)" },
59
55
  ];
60
56
  // ORM options for PostgreSQL
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- export declare const projectNameSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>;
2
+ export declare const projectNameSchema: z.ZodString;
3
3
  export declare function validateProjectName(name: string): string | undefined;
4
4
  export declare function validateDirectoryEmpty(dirPath: string): Promise<string | null>;
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,iBAAiB,uGAc3B,CAAC;AAGJ,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUpE;AAGD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,0BAgB3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,iBAAiB,aAc3B,CAAC;AAGJ,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUpE;AAGD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,0BAgB3D"}
@@ -53,7 +53,7 @@ function validateProjectName(name) {
53
53
  return undefined;
54
54
  }
55
55
  // Return the first error message
56
- const firstError = result.error.errors[0];
56
+ const firstError = result.error.issues[0];
57
57
  return firstError.message;
58
58
  }
59
59
  // Ensures a directory is empty or does not exist before starting build
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-ts-stack",
3
- "version": "0.1.1",
3
+ "version": "1.1.0",
4
4
  "description": "A powerful CLI tool that generates fully configured TypeScript projects with backend, frontend, database integration, Docker support, and more--all through an interactive setup.",
5
5
  "keywords": [
6
6
  "cli",
@@ -43,24 +43,24 @@
43
43
  "type:check": "tsc --noEmit"
44
44
  },
45
45
  "dependencies": {
46
- "@clack/prompts": "^0.11.0",
47
- "consola": "^3.2.3",
48
- "fs-extra": "^11.1.1",
49
- "handlebars": "^4.7.8",
50
- "zod": "^3.22.4"
46
+ "@clack/prompts": "^1.7.0",
47
+ "consola": "^3.4.2",
48
+ "fs-extra": "^11.4.0",
49
+ "handlebars": "^4.7.9",
50
+ "zod": "^4.5.4"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@better-ts-stack/eslint-config": "*",
54
54
  "@better-ts-stack/prettier-config": "*",
55
55
  "@types/fs-extra": "^11.0.4",
56
- "@types/node": "^20.10.5",
57
- "eslint": "^9.17.0",
58
- "prettier": "^3.1.1",
59
- "tsx": "^4.7.0",
60
- "typescript": "^5.3.3"
56
+ "@types/node": "^24.13.3",
57
+ "eslint": "^10.10.0",
58
+ "prettier": "^3.9.6",
59
+ "tsx": "^4.23.13",
60
+ "typescript": "^6.0.3"
61
61
  },
62
62
  "engines": {
63
- "node": ">=18.0.0"
63
+ "node": ">=24.0.0"
64
64
  },
65
65
  "prettier": "@better-ts-stack/prettier-config"
66
66
  }
@@ -1,42 +1,44 @@
1
- {
2
- "id": "express",
3
- "name": "Express Base",
4
- "description": "Base Express server with TypeScript, middleware, and best practices",
5
- "type": "base",
6
- "scripts": {
7
- "dev": "{{#if (eq packageManager 'bun')}}bun --watch src/index.ts{{else}}tsx watch src/index.ts{{/if}}",
8
- "build": "tsc",
9
- "start": "{{runner}} dist/index.js",
10
- "lint": "eslint src",
11
- "lint:fix": "eslint src --fix",
12
- "format": "prettier --write \"src/**/*.ts\"",
13
- "type:check": "tsc --noEmit"
14
- },
15
- "dependencies": {
16
- "express": "^4.18.2",
17
- "dotenv": "^16.3.1",
18
- "cors": "^2.8.5",
19
- "helmet": "^7.1.0",
20
- "morgan": "^1.10.0"
21
- },
22
- "devDependencies": {
23
- "@eslint/js": "^9.39.2",
24
- "@trivago/prettier-plugin-sort-imports": "^6.0.2",
25
- "@types/cors": "^2.8.17",
26
- "@types/express": "^4.17.21",
27
- "@types/morgan": "^1.9.9",
28
- "@types/node": "^20.10.6",
29
- "eslint": "^9.39.2",
30
- "eslint-config-prettier": "^10.1.8",
31
- "prettier": "^3.8.1",
32
- "prettier-plugin-tailwindcss": "^0.7.2",
33
- "tsx": "^4.7.0",
34
- "typescript": "^5.3.3",
35
- "typescript-eslint": "^8.54.0"
36
- },
37
- "envVars": {
38
- "NODE_ENV": "development",
39
- "PORT": "3000"
40
- },
41
- "templateFiles": ["src/index.ts"]
42
- }
1
+ {
2
+ "id": "express",
3
+ "name": "Express Base",
4
+ "description": "Base Express server with TypeScript, middleware, and best practices",
5
+ "type": "base",
6
+ "scripts": {
7
+ "dev": "{{#if (eq packageManager 'bun')}}bun --watch src/index.ts{{else}}tsx watch src/index.ts{{/if}}",
8
+ "build": "tsc",
9
+ "start": "{{runner}} dist/index.js",
10
+ "lint": "eslint src",
11
+ "lint:fix": "eslint src --fix",
12
+ "format": "prettier --write \"src/**/*.ts\"",
13
+ "type:check": "tsc --noEmit"
14
+ },
15
+ "dependencies": {
16
+ "express": "^5.2.1",
17
+ "dotenv": "^17.4.2",
18
+ "cors": "^2.8.6",
19
+ "helmet": "^8.3.0",
20
+ "morgan": "^1.12.0"
21
+ },
22
+ "devDependencies": {
23
+ "@eslint/js": "^10.0.1",
24
+ "@trivago/prettier-plugin-sort-imports": "^6.0.2",
25
+ "@types/cors": "^2.8.19",
26
+ "@types/express": "^5.0.6",
27
+ "@types/morgan": "^1.9.10",
28
+ "@types/node": "^24.13.3",
29
+ "eslint": "^10.10.0",
30
+ "eslint-config-prettier": "^10.1.8",
31
+ "prettier": "^3.9.6",
32
+ "prettier-plugin-tailwindcss": "^0.8.1",
33
+ "tsx": "^4.23.13",
34
+ "typescript": "^6.0.3",
35
+ "typescript-eslint": "^8.69.0"
36
+ },
37
+ "envVars": {
38
+ "NODE_ENV": "development",
39
+ "PORT": "3000"
40
+ },
41
+ "templateFiles": [
42
+ "src/index.ts"
43
+ ]
44
+ }
@@ -1,31 +1,40 @@
1
- import path from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import eslint from '@eslint/js';
4
- import tseslint from 'typescript-eslint';
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- export default tseslint.config(
10
- {
11
- ignores: ['dist', 'node_modules', 'templates/**/*', 'bin/**/*'],
12
- },
13
- eslint.configs.recommended,
14
- ...tseslint.configs.recommended,
15
- ...tseslint.configs.recommendedTypeChecked,
16
- {
17
- languageOptions: {
18
- parserOptions: {
19
- project: './tsconfig.eslint.json',
20
- tsconfigRootDir: __dirname,
21
- },
22
- },
23
- rules: {
24
- '@typescript-eslint/explicit-function-return-type': 'off',
25
- '@typescript-eslint/no-explicit-any': 'warn',
26
- '@typescript-eslint/no-unused-vars': ['error'],
27
- '@typescript-eslint/no-floating-promises': 'error',
28
- 'no-console': 'off',
29
- },
30
- }
31
- );
1
+ import eslint from "@eslint/js";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import tseslint from "typescript-eslint";
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ export default tseslint.config(
10
+ {
11
+ ignores: [
12
+ "dist",
13
+ "node_modules",
14
+ "templates/**/*",
15
+ "bin/**/*",
16
+ "src/generated/**",
17
+ ],
18
+ },
19
+ eslint.configs.recommended,
20
+ ...tseslint.configs.recommended,
21
+ ...tseslint.configs.recommendedTypeChecked,
22
+ {
23
+ languageOptions: {
24
+ parserOptions: {
25
+ project: "./tsconfig.eslint.json",
26
+ tsconfigRootDir: __dirname,
27
+ },
28
+ },
29
+ rules: {
30
+ "@typescript-eslint/explicit-function-return-type": "off",
31
+ "@typescript-eslint/no-explicit-any": "warn",
32
+ "@typescript-eslint/no-unused-vars": [
33
+ "error",
34
+ { argsIgnorePattern: "^_" },
35
+ ],
36
+ "@typescript-eslint/no-floating-promises": "error",
37
+ "no-console": "off",
38
+ },
39
+ }
40
+ );
@@ -1,46 +1,61 @@
1
- import express, { Express, Request, Response } from 'express';
2
- import cors from 'cors';
3
- import helmet from 'helmet';
4
- import morgan from 'morgan';
5
- import dotenv from 'dotenv';
6
- import healthRouter from './routes/health';
7
- {{#if useAuth}}
8
- import authRouter from './routes/auth';
9
- {{/if}}
10
-
11
- dotenv.config();
12
-
13
- const app: Express = express();
14
- const port = process.env.PORT || 3000;
15
-
16
- // Middleware
17
- app.use(helmet());
18
- app.use(cors());
19
- app.use(morgan('dev'));
20
- app.use(express.json());
21
- app.use(express.urlencoded({ extended: true }));
22
-
23
- // Routes
24
- app.use('/health', healthRouter);
25
- {{#if useAuth}}
26
- app.use('/auth', authRouter);
27
- {{/if}}
28
-
29
- // 404 handler
30
- app.use((_req: Request, res: Response) => {
31
- res.status(404).json({ error: 'Not Found' });
32
- });
33
-
34
- // Error handler
35
- app.use((err: Error, _req: Request, res: Response) => {
36
- console.error(err.stack);
37
- res.status(500).json({ error: 'Internal Server Error' });
38
- });
39
-
40
- app.listen(port, () => {
41
- console.log(`Server is running on http://localhost:${port}
42
- Health: http://localhost:${port}/health
43
- `);
44
- });
45
-
46
- export default app;
1
+ import 'dotenv/config';
2
+ import express, { Express, Request, Response, NextFunction } from 'express';
3
+ import cors from 'cors';
4
+ import helmet from 'helmet';
5
+ import morgan from 'morgan';
6
+ {{#if (eq database 'mongoose')}}
7
+ import { connectDB } from './lib/db';
8
+ {{/if}}
9
+ import healthRouter from './routes/health';
10
+ {{#if useAuth}}
11
+ import authRouter from './routes/auth';
12
+ {{/if}}
13
+
14
+
15
+
16
+ const app: Express = express();
17
+ const port = process.env.PORT || 3000;
18
+
19
+ // Middleware
20
+ app.use(helmet());
21
+ app.use(cors());
22
+ app.use(morgan('dev'));
23
+ app.use(express.json());
24
+ app.use(express.urlencoded({ extended: true }));
25
+
26
+ // Routes
27
+ app.use('/health', healthRouter);
28
+ {{#if useAuth}}
29
+ app.use('/auth', authRouter);
30
+ {{/if}}
31
+
32
+ // 404 handler
33
+ app.use((_req: Request, res: Response) => {
34
+ res.status(404).json({ error: 'Not Found' });
35
+ });
36
+
37
+ // Error handler
38
+ app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {
39
+ console.error(err.stack);
40
+ res.status(500).json({ error: 'Internal Server Error' });
41
+ });
42
+
43
+ {{#if (eq database 'mongoose')}}
44
+ void awaitDatabase().catch((error: unknown) => {
45
+ console.error(error);
46
+ process.exitCode = 1;
47
+ });
48
+ async function awaitDatabase(): Promise<void> {
49
+ await connectDB();
50
+ app.listen(port);
51
+ }
52
+ {{else}}
53
+ app.listen(port, () => {
54
+ console.log(`Server is running on http://localhost:${port}
55
+ Health: http://localhost:${port}/health
56
+ `);
57
+ });
58
+
59
+ {{/if}}
60
+
61
+ export default app;
@@ -1,12 +1,12 @@
1
- import { Router, Request, Response } from 'express';
2
-
3
- const router = Router();
4
-
5
- router.get('/', (_req: Request, res: Response) => {
6
- res.status(200).json({
7
- status: 'ok',
8
- timestamp: new Date().toISOString(),
9
- });
10
- });
11
-
12
- export default router;
1
+ import { Request, Response, Router } from "express";
2
+
3
+ const router: Router = Router();
4
+
5
+ router.get("/", (_req: Request, res: Response) => {
6
+ res.status(200).json({
7
+ status: "ok",
8
+ timestamp: new Date().toISOString(),
9
+ });
10
+ });
11
+
12
+ export default router;
@@ -1,23 +1,25 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "resolveJsonModule": true,
13
- "declaration": true,
14
- "declarationMap": true,
15
- "sourceMap": true,
16
- "noUnusedLocals": true,
17
- "noUnusedParameters": true,
18
- "noImplicitReturns": true,
19
- "noFallthroughCasesInSwitch": true
20
- },
21
- "include": ["src/**/*"],
22
- "exclude": ["node_modules", "dist"]
23
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "NodeNext",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "noUnusedLocals": true,
17
+ "noUnusedParameters": true,
18
+ "noImplicitReturns": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "moduleResolution": "NodeNext",
21
+ "types": ["node"]
22
+ },
23
+ "include": ["src/**/*"],
24
+ "exclude": ["node_modules", "dist"]
25
+ }