better-ts-stack 0.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 (134) hide show
  1. package/README.md +83 -0
  2. package/dist/builder/configGenerator.d.ts +6 -0
  3. package/dist/builder/configGenerator.d.ts.map +1 -0
  4. package/dist/builder/configGenerator.js +110 -0
  5. package/dist/builder/configGenerator.js.map +1 -0
  6. package/dist/builder/dependencyInstaller.d.ts +3 -0
  7. package/dist/builder/dependencyInstaller.d.ts.map +1 -0
  8. package/dist/builder/dependencyInstaller.js +39 -0
  9. package/dist/builder/dependencyInstaller.js.map +1 -0
  10. package/dist/builder/fileProcessor.d.ts +6 -0
  11. package/dist/builder/fileProcessor.d.ts.map +1 -0
  12. package/dist/builder/fileProcessor.js +108 -0
  13. package/dist/builder/fileProcessor.js.map +1 -0
  14. package/dist/builder/gitInitializer.d.ts +2 -0
  15. package/dist/builder/gitInitializer.d.ts.map +1 -0
  16. package/dist/builder/gitInitializer.js +52 -0
  17. package/dist/builder/gitInitializer.js.map +1 -0
  18. package/dist/builder/index.d.ts +3 -0
  19. package/dist/builder/index.d.ts.map +1 -0
  20. package/dist/builder/index.js +126 -0
  21. package/dist/builder/index.js.map +1 -0
  22. package/dist/builder/moduleSelector.d.ts +9 -0
  23. package/dist/builder/moduleSelector.d.ts.map +1 -0
  24. package/dist/builder/moduleSelector.js +29 -0
  25. package/dist/builder/moduleSelector.js.map +1 -0
  26. package/dist/builder/templateContext.d.ts +21 -0
  27. package/dist/builder/templateContext.d.ts.map +1 -0
  28. package/dist/builder/templateContext.js +47 -0
  29. package/dist/builder/templateContext.js.map +1 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +34 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/intro.d.ts +2 -0
  35. package/dist/intro.d.ts.map +1 -0
  36. package/dist/intro.js +27 -0
  37. package/dist/intro.js.map +1 -0
  38. package/dist/modules/registry.d.ts +6 -0
  39. package/dist/modules/registry.d.ts.map +1 -0
  40. package/dist/modules/registry.js +64 -0
  41. package/dist/modules/registry.js.map +1 -0
  42. package/dist/output/nextSteps.d.ts +4 -0
  43. package/dist/output/nextSteps.d.ts.map +1 -0
  44. package/dist/output/nextSteps.js +87 -0
  45. package/dist/output/nextSteps.js.map +1 -0
  46. package/dist/prompts/backend/index.d.ts +3 -0
  47. package/dist/prompts/backend/index.d.ts.map +1 -0
  48. package/dist/prompts/backend/index.js +128 -0
  49. package/dist/prompts/backend/index.js.map +1 -0
  50. package/dist/prompts/frontend/index.d.ts +3 -0
  51. package/dist/prompts/frontend/index.d.ts.map +1 -0
  52. package/dist/prompts/frontend/index.js +111 -0
  53. package/dist/prompts/frontend/index.js.map +1 -0
  54. package/dist/prompts/index.d.ts +4 -0
  55. package/dist/prompts/index.d.ts.map +1 -0
  56. package/dist/prompts/index.js +82 -0
  57. package/dist/prompts/index.js.map +1 -0
  58. package/dist/types/index.d.ts +157 -0
  59. package/dist/types/index.d.ts.map +1 -0
  60. package/dist/types/index.js +81 -0
  61. package/dist/types/index.js.map +1 -0
  62. package/dist/validators/index.d.ts +5 -0
  63. package/dist/validators/index.d.ts.map +1 -0
  64. package/dist/validators/index.js +73 -0
  65. package/dist/validators/index.js.map +1 -0
  66. package/package.json +66 -0
  67. package/templates/backend/express/.eslintrc.js +24 -0
  68. package/templates/backend/express/.prettierignore +52 -0
  69. package/templates/backend/express/.prettierrc +16 -0
  70. package/templates/backend/express/config.json +42 -0
  71. package/templates/backend/express/eslint.config.mjs +31 -0
  72. package/templates/backend/express/gitignore +39 -0
  73. package/templates/backend/express/src/index.ts +46 -0
  74. package/templates/backend/express/src/routes/health.ts +12 -0
  75. package/templates/backend/express/tsconfig.eslint.json +9 -0
  76. package/templates/backend/express/tsconfig.json +23 -0
  77. package/templates/frontend/nextjs/app/globals.css +99 -0
  78. package/templates/frontend/nextjs/app/layout.tsx +34 -0
  79. package/templates/frontend/nextjs/app/page.tsx.hbs +98 -0
  80. package/templates/frontend/nextjs/components/ui/button.tsx +51 -0
  81. package/templates/frontend/nextjs/components/ui/card.tsx +60 -0
  82. package/templates/frontend/nextjs/components/ui/field.tsx +67 -0
  83. package/templates/frontend/nextjs/components/ui/input.tsx +18 -0
  84. package/templates/frontend/nextjs/components.json +19 -0
  85. package/templates/frontend/nextjs/config.json +33 -0
  86. package/templates/frontend/nextjs/eslint.config.mjs +11 -0
  87. package/templates/frontend/nextjs/gitignore +41 -0
  88. package/templates/frontend/nextjs/lib/utils.ts +6 -0
  89. package/templates/frontend/nextjs/next.config.ts +8 -0
  90. package/templates/frontend/nextjs/postcss.config.mjs +7 -0
  91. package/templates/frontend/nextjs/proxy.ts.hbs +23 -0
  92. package/templates/frontend/nextjs/public/file.svg +1 -0
  93. package/templates/frontend/nextjs/public/globe.svg +1 -0
  94. package/templates/frontend/nextjs/public/next.svg +1 -0
  95. package/templates/frontend/nextjs/public/vercel.svg +1 -0
  96. package/templates/frontend/nextjs/public/window.svg +1 -0
  97. package/templates/frontend/nextjs/tsconfig.json +21 -0
  98. package/templates/modules/auth/express/config.json +1 -0
  99. package/templates/modules/auth/express/src/controllers/authController.ts.hbs +81 -0
  100. package/templates/modules/auth/express/src/lib/jwt.ts.hbs +27 -0
  101. package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +26 -0
  102. package/templates/modules/auth/express/src/routes/auth.ts.hbs +19 -0
  103. package/templates/modules/auth/express/src/services/userStore.ts.hbs +107 -0
  104. package/templates/modules/auth/nextjs/app/api/auth/[...all]/route.ts +4 -0
  105. package/templates/modules/auth/nextjs/app/dashboard/page.tsx +96 -0
  106. package/templates/modules/auth/nextjs/app/sign-in/page.tsx +35 -0
  107. package/templates/modules/auth/nextjs/app/sign-up/page.tsx +35 -0
  108. package/templates/modules/auth/nextjs/components/auth/sign-in-form.tsx +132 -0
  109. package/templates/modules/auth/nextjs/components/auth/sign-out-button.tsx +50 -0
  110. package/templates/modules/auth/nextjs/components/auth/sign-up-form.tsx +152 -0
  111. package/templates/modules/auth/nextjs/config.json +31 -0
  112. package/templates/modules/auth/nextjs/lib/auth-client.ts +3 -0
  113. package/templates/modules/auth/nextjs/lib/auth-schema.ts +39 -0
  114. package/templates/modules/auth/nextjs/lib/auth.ts.hbs +35 -0
  115. package/templates/modules/docker/.dockerignore +13 -0
  116. package/templates/modules/docker/Dockerfile.hbs +71 -0
  117. package/templates/modules/docker/config.json +16 -0
  118. package/templates/modules/docker/docker-compose.yml.hbs +10 -0
  119. package/templates/modules/drizzle/nextjs/config.json +21 -0
  120. package/templates/modules/drizzle/nextjs/drizzle.config.ts +13 -0
  121. package/templates/modules/drizzle/nextjs/lib/db.ts +11 -0
  122. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -0
  123. package/templates/modules/mongoose/config.json +16 -0
  124. package/templates/modules/mongoose/src/lib/db.ts +43 -0
  125. package/templates/modules/mongoose/src/lib/db.ts.hbs +56 -0
  126. package/templates/modules/mongoose/src/models/User.ts +47 -0
  127. package/templates/modules/prisma/express/config.json +21 -0
  128. package/templates/modules/prisma/express/prisma/schema.prisma +23 -0
  129. package/templates/modules/prisma/express/prisma.config.ts +13 -0
  130. package/templates/modules/prisma/express/src/lib/prisma.ts +37 -0
  131. package/templates/modules/prisma/nextjs/config.json +23 -0
  132. package/templates/modules/prisma/nextjs/lib/prisma.ts +18 -0
  133. package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +90 -0
  134. package/templates/modules/prisma/nextjs/prisma.config.ts +12 -0
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectFrontendChoices = void 0;
4
+ const prompts_1 = require("@clack/prompts");
5
+ const types_1 = require("../../types");
6
+ const collectFrontendChoices = async () => {
7
+ const project = await (0, prompts_1.group)({
8
+ framework: async () => {
9
+ // Auto-select Next.js since it's the only option
10
+ return Promise.resolve("nextjs");
11
+ },
12
+ databaseType: async () => {
13
+ const selection = await (0, prompts_1.select)({
14
+ message: "Select a database:",
15
+ options: types_1.databaseTypeOptions,
16
+ initialValue: "none",
17
+ });
18
+ if ((0, prompts_1.isCancel)(selection)) {
19
+ (0, prompts_1.cancel)("Operation cancelled.");
20
+ process.exit(0);
21
+ }
22
+ return selection;
23
+ },
24
+ orm: async ({ results }) => {
25
+ // Type guard to narrow the databaseType from unknown to DatabaseType
26
+ const dbType = results.databaseType;
27
+ // Skip ORM selection if no database type was selected
28
+ if (dbType === "none") {
29
+ return "none";
30
+ }
31
+ // Select ORM based on database type
32
+ if (dbType !== "mongodb" && dbType !== "postgresql") {
33
+ return "none";
34
+ }
35
+ const ormOptions = dbType === "mongodb" ? types_1.mongodbOrmOptions : types_1.postgresqlOrmOptions;
36
+ const selection = await (0, prompts_1.select)({
37
+ message: `Select an ORM for ${dbType}:`,
38
+ options: ormOptions,
39
+ initialValue: "prisma",
40
+ });
41
+ if ((0, prompts_1.isCancel)(selection)) {
42
+ (0, prompts_1.cancel)("Operation cancelled.");
43
+ process.exit(0);
44
+ }
45
+ return selection;
46
+ },
47
+ packageManager: async () => {
48
+ const selection = await (0, prompts_1.select)({
49
+ message: "Select a package manager:",
50
+ options: types_1.packageManagerOptions,
51
+ initialValue: "npm",
52
+ });
53
+ if ((0, prompts_1.isCancel)(selection)) {
54
+ (0, prompts_1.cancel)("Operation cancelled.");
55
+ process.exit(0);
56
+ }
57
+ return selection;
58
+ },
59
+ useDocker: () => (0, prompts_1.confirm)({
60
+ message: "Use Docker?",
61
+ initialValue: false,
62
+ }),
63
+ useAuth: async ({ results }) => {
64
+ // Better Auth template requires a database-backed adapter
65
+ if (results.databaseType === "none") {
66
+ return false;
67
+ }
68
+ const selection = await (0, prompts_1.select)({
69
+ message: "Add Better Auth?",
70
+ options: types_1.authOptions,
71
+ initialValue: false,
72
+ });
73
+ if ((0, prompts_1.isCancel)(selection)) {
74
+ (0, prompts_1.cancel)("Operation cancelled.");
75
+ process.exit(0);
76
+ }
77
+ return selection;
78
+ },
79
+ initGit: () => (0, prompts_1.confirm)({
80
+ message: "Initialize a git repository?",
81
+ initialValue: true,
82
+ }),
83
+ installDeps: () => (0, prompts_1.confirm)({
84
+ message: "Install dependencies now?",
85
+ initialValue: false,
86
+ }),
87
+ }, {
88
+ onCancel: () => {
89
+ (0, prompts_1.cancel)("Operation cancelled.");
90
+ process.exit(0);
91
+ },
92
+ });
93
+ // Transform the group result into the proper typed object
94
+ // Validate orm using type guard
95
+ if (!(0, types_1.isValidOrmOption)(project.orm)) {
96
+ throw new Error(`Invalid ORM option: ${String(project.orm)}`);
97
+ }
98
+ const result = {
99
+ framework: project.framework,
100
+ databaseType: project.databaseType,
101
+ orm: project.orm,
102
+ packageManager: project.packageManager,
103
+ useDocker: Boolean(project.useDocker),
104
+ useAuth: Boolean(project.useAuth),
105
+ initGit: Boolean(project.initGit),
106
+ installDeps: Boolean(project.installDeps),
107
+ };
108
+ return result;
109
+ };
110
+ exports.collectFrontendChoices = collectFrontendChoices;
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/prompts/frontend/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { ProjectConfig } from "../types";
2
+ export declare function collectUserChoices(): Promise<ProjectConfig>;
3
+ export declare function confirmBuild(config: ProjectConfig, targetDir: string): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,aAAa,EACd,MAAM,UAAU,CAAC;AAMlB,wBAAsB,kBAAkB,2BA4CvC;AAGD,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAiC1E"}
@@ -0,0 +1,82 @@
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.collectUserChoices = collectUserChoices;
7
+ exports.confirmBuild = confirmBuild;
8
+ const prompts_1 = require("@clack/prompts");
9
+ const consola_1 = __importDefault(require("consola"));
10
+ const types_1 = require("../types");
11
+ const validators_1 = require("../validators");
12
+ const backend_1 = require("./backend");
13
+ const frontend_1 = require("./frontend");
14
+ // Collects user input via interactive prompts
15
+ async function collectUserChoices() {
16
+ const projectName = await (0, prompts_1.text)({
17
+ message: "Project name:",
18
+ placeholder: "my-awesome-project",
19
+ validate: (value) => (0, validators_1.validateProjectName)(value),
20
+ });
21
+ if ((0, prompts_1.isCancel)(projectName)) {
22
+ (0, prompts_1.cancel)("Operation cancelled.");
23
+ process.exit(0);
24
+ }
25
+ const applicationType = await (0, prompts_1.select)({
26
+ message: "Application type:",
27
+ options: types_1.applicationTypeOptions,
28
+ initialValue: "backend",
29
+ });
30
+ if ((0, prompts_1.isCancel)(applicationType)) {
31
+ (0, prompts_1.cancel)("Operation cancelled.");
32
+ process.exit(0);
33
+ }
34
+ let userChoices;
35
+ if (applicationType === "backend") {
36
+ userChoices = await (0, backend_1.collectBackendChoices)();
37
+ }
38
+ else if (applicationType === "fullstack") {
39
+ userChoices = await (0, frontend_1.collectFrontendChoices)();
40
+ }
41
+ else {
42
+ (0, prompts_1.cancel)("Invalid application type selected.");
43
+ process.exit(0);
44
+ }
45
+ // Derive database field from databaseType + orm for backward compatibility
46
+ const database = (0, types_1.deriveDatabase)(userChoices.databaseType, userChoices.orm);
47
+ const choices = {
48
+ projectName,
49
+ applicationType,
50
+ ...userChoices,
51
+ database,
52
+ };
53
+ return choices;
54
+ }
55
+ // Displays a summary and asks for final confirmation before building
56
+ async function confirmBuild(config, targetDir) {
57
+ consola_1.default.info("Project Summary:");
58
+ const appTypeLabel = config.applicationType === "backend" ? "Backend API" : "Full-stack App";
59
+ consola_1.default.box(`Project Name: ${config.projectName}\n` +
60
+ `Target Dir: ${targetDir}\n` +
61
+ `App Type: ${appTypeLabel}\n` +
62
+ `Framework: ${config.framework}\n` +
63
+ `Database: ${config.database}\n` +
64
+ `Auth: ${config.useAuth ? "Yes" : "No"}\n` +
65
+ `Docker: ${config.useDocker ? "Yes" : "No"}\n` +
66
+ `Package Mgr: ${config.packageManager}\n` +
67
+ `Git Init: ${config.initGit ? "Yes" : "No"}\n` +
68
+ `Install Deps: ${config.installDeps ? "Yes" : "No"}`);
69
+ const shouldContinue = await (0, prompts_1.confirm)({
70
+ message: "Looks good? Ready to build?",
71
+ initialValue: true,
72
+ });
73
+ if ((0, prompts_1.isCancel)(shouldContinue)) {
74
+ (0, prompts_1.cancel)("Operation cancelled.");
75
+ process.exit(0);
76
+ }
77
+ if (!shouldContinue) {
78
+ (0, prompts_1.cancel)("Building cancelled by user.");
79
+ process.exit(0);
80
+ }
81
+ }
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ export type PackageManager = "npm" | "pnpm" | "bun";
2
+ export type DatabaseType = "mongodb" | "postgresql" | "none";
3
+ export type OrmOption = "prisma" | "mongoose" | "drizzle" | "none";
4
+ export type DatabaseOption = "none" | "prisma" | "mongoose" | "drizzle";
5
+ export type ApplicationType = "backend" | "fullstack";
6
+ export type ModuleType = "base" | "database" | "feature";
7
+ export interface Dependencies {
8
+ [packageName: string]: string;
9
+ }
10
+ export type BackendFramework = "express" | "nestjs";
11
+ export type FrontendFramework = "nextjs";
12
+ export interface ProjectConfig {
13
+ projectName: string;
14
+ applicationType: ApplicationType;
15
+ framework: BackendFramework | FrontendFramework;
16
+ databaseType: DatabaseType;
17
+ orm: OrmOption;
18
+ database: DatabaseOption;
19
+ useDocker: boolean;
20
+ useAuth: boolean;
21
+ packageManager: PackageManager;
22
+ initGit: boolean;
23
+ installDeps: boolean;
24
+ }
25
+ /**
26
+ * Shared type for prompt choices (used by both frontend and backend collectors).
27
+ * This is essentially ProjectConfig without the derived/initial fields.
28
+ */
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
+ /**
33
+ * Derives the database option from database type and ORM selection.
34
+ * Returns "none" if either is "none", otherwise returns the ORM which
35
+ * must be a valid DatabaseOption (prisma, mongoose, or drizzle).
36
+ */
37
+ export declare function deriveDatabase(databaseType: DatabaseType, orm: OrmOption): DatabaseOption;
38
+ export interface ModuleConfig {
39
+ id: string;
40
+ name: string;
41
+ description: string;
42
+ type: ModuleType;
43
+ dependencies: Dependencies;
44
+ devDependencies: Dependencies;
45
+ scripts: Record<string, string>;
46
+ envVars: Record<string, string>;
47
+ templateFiles: string[];
48
+ }
49
+ export interface Module {
50
+ config: ModuleConfig;
51
+ path: string;
52
+ }
53
+ export interface MergedConfig {
54
+ dependencies: Dependencies;
55
+ devDependencies: Dependencies;
56
+ scripts: Record<string, string>;
57
+ envVars: Record<string, string>;
58
+ }
59
+ export interface BuildResult {
60
+ success: boolean;
61
+ projectPath: string;
62
+ nextSteps: string[];
63
+ }
64
+ export interface BuildError extends Error {
65
+ code: string;
66
+ exitCode: number;
67
+ }
68
+ export declare function buildError(errorOrMessage: unknown, code: string, context?: string, exitCode?: number): BuildError;
69
+ export interface TemplateContext {
70
+ projectName: string;
71
+ packageManager: string;
72
+ database: string;
73
+ framework: string;
74
+ port: number;
75
+ useDocker: boolean;
76
+ useAuth: boolean;
77
+ helpers: {
78
+ lowercase: (str: string) => string;
79
+ uppercase: (str: string) => string;
80
+ kebabCase: (str: string) => string;
81
+ };
82
+ }
83
+ export declare const applicationTypeOptions: ({
84
+ value: "backend";
85
+ label: string;
86
+ } | {
87
+ value: "fullstack";
88
+ label: string;
89
+ })[];
90
+ export declare const backendFrameworkOptions: ({
91
+ value: "express";
92
+ label: string;
93
+ hint?: undefined;
94
+ } | {
95
+ value: "nestjs";
96
+ label: string;
97
+ hint: string;
98
+ })[];
99
+ export declare const frontendFrameworkOptions: {
100
+ value: "nextjs";
101
+ label: string;
102
+ }[];
103
+ export declare const databaseTypeOptions: ({
104
+ value: "none";
105
+ label: string;
106
+ } | {
107
+ value: "mongodb";
108
+ label: string;
109
+ } | {
110
+ value: "postgresql";
111
+ label: string;
112
+ })[];
113
+ export declare const mongodbOrmOptions: ({
114
+ value: "prisma";
115
+ label: string;
116
+ } | {
117
+ value: "mongoose";
118
+ label: string;
119
+ })[];
120
+ export declare const postgresqlOrmOptions: ({
121
+ value: "prisma";
122
+ label: string;
123
+ } | {
124
+ value: "drizzle";
125
+ label: string;
126
+ })[];
127
+ export declare const databaseOptions: ({
128
+ value: "none";
129
+ label: string;
130
+ } | {
131
+ value: "prisma";
132
+ label: string;
133
+ } | {
134
+ value: "mongoose";
135
+ label: string;
136
+ } | {
137
+ value: "drizzle";
138
+ label: string;
139
+ })[];
140
+ export declare const packageManagerOptions: ({
141
+ value: "npm";
142
+ label: string;
143
+ } | {
144
+ value: "pnpm";
145
+ label: string;
146
+ } | {
147
+ value: "bun";
148
+ label: string;
149
+ })[];
150
+ export declare const authOptions: ({
151
+ value: false;
152
+ label: string;
153
+ } | {
154
+ value: true;
155
+ label: string;
156
+ })[];
157
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ // Core type definitions for the CLI builder
3
+ Object.defineProperty(exports, "__esModule", { value: true });
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
+ exports.deriveDatabase = deriveDatabase;
7
+ 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
+ /**
16
+ * Derives the database option from database type and ORM selection.
17
+ * Returns "none" if either is "none", otherwise returns the ORM which
18
+ * must be a valid DatabaseOption (prisma, mongoose, or drizzle).
19
+ */
20
+ function deriveDatabase(databaseType, orm) {
21
+ if (databaseType === "none" || orm === "none") {
22
+ return "none";
23
+ }
24
+ // At this point, orm must be one of: prisma, mongoose, drizzle
25
+ // which are all valid DatabaseOption values
26
+ return orm;
27
+ }
28
+ // Unified error creation function
29
+ function buildError(errorOrMessage, code, context, exitCode = 1) {
30
+ const message = errorOrMessage instanceof Error
31
+ ? errorOrMessage.message
32
+ : String(errorOrMessage);
33
+ const fullMessage = context ? `${context}: ${message}` : message;
34
+ const error = new Error(fullMessage);
35
+ return Object.assign(error, { code, exitCode });
36
+ }
37
+ // Type-safe option definitions
38
+ exports.applicationTypeOptions = [
39
+ { value: "backend", label: "Backend API (Express/NestJS)" },
40
+ { value: "fullstack", label: "Full-stack App (Next.js)" },
41
+ ];
42
+ exports.backendFrameworkOptions = [
43
+ { value: "express", label: "Express" },
44
+ { value: "nestjs", label: "NestJS", hint: "(Coming Soon)" },
45
+ ];
46
+ exports.frontendFrameworkOptions = [
47
+ { value: "nextjs", label: "Next.js 16 (App Router)" },
48
+ ];
49
+ // Database type options (what database system)
50
+ exports.databaseTypeOptions = [
51
+ { value: "none", label: "None (Skip database setup)" },
52
+ { value: "mongodb", label: "MongoDB" },
53
+ { value: "postgresql", label: "PostgreSQL" },
54
+ ];
55
+ // ORM options for MongoDB
56
+ exports.mongodbOrmOptions = [
57
+ { value: "prisma", label: "Prisma (Type-safe ORM)" },
58
+ { value: "mongoose", label: "Mongoose (MongoDB ODM)" },
59
+ ];
60
+ // ORM options for PostgreSQL
61
+ exports.postgresqlOrmOptions = [
62
+ { value: "prisma", label: "Prisma (Type-safe ORM)" },
63
+ { value: "drizzle", label: "Drizzle (Lightweight ORM)" },
64
+ ];
65
+ // Legacy database options (for backward compatibility)
66
+ exports.databaseOptions = [
67
+ { value: "none", label: "None (Skip database setup)" },
68
+ { value: "prisma", label: "Prisma (Type-safe ORM)" },
69
+ { value: "mongoose", label: "Mongoose (Standard MongoDB ODM)" },
70
+ { value: "drizzle", label: "Drizzle (Lightweight ORM)" },
71
+ ];
72
+ exports.packageManagerOptions = [
73
+ { value: "npm", label: "npm" },
74
+ { value: "pnpm", label: "pnpm" },
75
+ { value: "bun", label: "bun" },
76
+ ];
77
+ exports.authOptions = [
78
+ { value: false, label: "No" },
79
+ { value: true, label: "Yes" },
80
+ ];
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;AA+D5C,4CAOC;AAOD,wCAUC;AA2CD,gCAaC;AAjFD,8CAA8C;AAC9C,SAAgB,gBAAgB,CAAC,KAAc;IAC7C,OAAO,CACL,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,MAAM,CACjB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAC5B,YAA0B,EAC1B,GAAc;IAEd,IAAI,YAAY,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,+DAA+D;IAC/D,4CAA4C;IAC5C,OAAO,GAAG,CAAC;AACb,CAAC;AA0CD,kCAAkC;AAClC,SAAgB,UAAU,CACxB,cAAuB,EACvB,IAAY,EACZ,OAAgB,EAChB,WAAmB,CAAC;IAEpB,MAAM,OAAO,GACX,cAAc,YAAY,KAAK;QAC7B,CAAC,CAAC,cAAc,CAAC,OAAO;QACxB,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAClD,CAAC;AAmBD,+BAA+B;AAClB,QAAA,sBAAsB,GAAG;IACpC,EAAE,KAAK,EAAE,SAAkB,EAAE,KAAK,EAAE,8BAA8B,EAAE;IACpE,EAAE,KAAK,EAAE,WAAoB,EAAE,KAAK,EAAE,0BAA0B,EAAE;CACnE,CAAC;AAEW,QAAA,uBAAuB,GAAG;IACrC,EAAE,KAAK,EAAE,SAAkB,EAAE,KAAK,EAAE,SAAS,EAAE;IAC/C,EAAE,KAAK,EAAE,QAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE;CACrE,CAAC;AAEW,QAAA,wBAAwB,GAAG;IACtC,EAAE,KAAK,EAAE,QAAiB,EAAE,KAAK,EAAE,yBAAyB,EAAE;CAC/D,CAAC;AAEF,+CAA+C;AAClC,QAAA,mBAAmB,GAAG;IACjC,EAAE,KAAK,EAAE,MAAe,EAAE,KAAK,EAAE,4BAA4B,EAAE;IAC/D,EAAE,KAAK,EAAE,SAAkB,EAAE,KAAK,EAAE,SAAS,EAAE;IAC/C,EAAE,KAAK,EAAE,YAAqB,EAAE,KAAK,EAAE,YAAY,EAAE;CACtD,CAAC;AAEF,0BAA0B;AACb,QAAA,iBAAiB,GAAG;IAC/B,EAAE,KAAK,EAAE,QAAiB,EAAE,KAAK,EAAE,wBAAwB,EAAE;IAC7D,EAAE,KAAK,EAAE,UAAmB,EAAE,KAAK,EAAE,wBAAwB,EAAE;CAChE,CAAC;AAEF,6BAA6B;AAChB,QAAA,oBAAoB,GAAG;IAClC,EAAE,KAAK,EAAE,QAAiB,EAAE,KAAK,EAAE,wBAAwB,EAAE;IAC7D,EAAE,KAAK,EAAE,SAAkB,EAAE,KAAK,EAAE,2BAA2B,EAAE;CAClE,CAAC;AAEF,uDAAuD;AAC1C,QAAA,eAAe,GAAG;IAC7B,EAAE,KAAK,EAAE,MAAe,EAAE,KAAK,EAAE,4BAA4B,EAAE;IAC/D,EAAE,KAAK,EAAE,QAAiB,EAAE,KAAK,EAAE,wBAAwB,EAAE;IAC7D,EAAE,KAAK,EAAE,UAAmB,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACxE,EAAE,KAAK,EAAE,SAAkB,EAAE,KAAK,EAAE,2BAA2B,EAAE;CAClE,CAAC;AAEW,QAAA,qBAAqB,GAAG;IACnC,EAAE,KAAK,EAAE,KAAc,EAAE,KAAK,EAAE,KAAK,EAAE;IACvC,EAAE,KAAK,EAAE,MAAe,EAAE,KAAK,EAAE,MAAM,EAAE;IACzC,EAAE,KAAK,EAAE,KAAc,EAAE,KAAK,EAAE,KAAK,EAAE;CACxC,CAAC;AAEW,QAAA,WAAW,GAAG;IACzB,EAAE,KAAK,EAAE,KAAc,EAAE,KAAK,EAAE,IAAI,EAAE;IACtC,EAAE,KAAK,EAAE,IAAa,EAAE,KAAK,EAAE,KAAK,EAAE;CACvC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ export declare const projectNameSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>;
3
+ export declare function validateProjectName(name: string): string | undefined;
4
+ export declare function validateDirectoryEmpty(dirPath: string): Promise<string | null>;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.projectNameSchema = void 0;
37
+ exports.validateProjectName = validateProjectName;
38
+ exports.validateDirectoryEmpty = validateDirectoryEmpty;
39
+ const fs = __importStar(require("fs-extra"));
40
+ const path = __importStar(require("path"));
41
+ const zod_1 = require("zod");
42
+ // Validates project name: lowercase letters, numbers, and hyphens
43
+ exports.projectNameSchema = zod_1.z
44
+ .string()
45
+ .min(1, "Project name is required")
46
+ .refine((name) => /^[a-z0-9-]+$/.test(name), "Project name must be lowercase and can contain only letters, numbers, and hyphens")
47
+ .refine((name) => !name.startsWith("-") && !name.endsWith("-"), "Project name cannot start or end with a hyphen")
48
+ .refine((name) => name.length <= 214, "Project name must be 214 characters or less (npm package name limit)");
49
+ // Checks if a project name follows npm naming conventions
50
+ function validateProjectName(name) {
51
+ const result = exports.projectNameSchema.safeParse(name);
52
+ if (result.success) {
53
+ return undefined;
54
+ }
55
+ // Return the first error message
56
+ const firstError = result.error.errors[0];
57
+ return firstError.message;
58
+ }
59
+ // Ensures a directory is empty or does not exist before starting build
60
+ async function validateDirectoryEmpty(dirPath) {
61
+ const exists = await fs.pathExists(dirPath);
62
+ if (!exists)
63
+ return null;
64
+ const stats = await fs.stat(dirPath);
65
+ if (!stats.isDirectory()) {
66
+ return `Path "${dirPath}" exists but is not a directory`;
67
+ }
68
+ const files = await fs.readdir(dirPath);
69
+ if (files.length === 0)
70
+ return null;
71
+ return `Directory "${path.basename(dirPath)}" already exists and is not empty`;
72
+ }
73
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,kDAUC;AAGD,wDAgBC;AAnDD,6CAA+B;AAC/B,2CAA6B;AAC7B,6BAAwB;AAExB,kEAAkE;AACrD,QAAA,iBAAiB,GAAG,OAAC;KAC/B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,0BAA0B,CAAC;KAClC,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EACnC,mFAAmF,CACpF;KACA,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EACtD,gDAAgD,CACjD;KACA,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,EAC5B,sEAAsE,CACvE,CAAC;AAEJ,0DAA0D;AAC1D,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,MAAM,MAAM,GAAG,yBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEjD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iCAAiC;IACjC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,UAAU,CAAC,OAAO,CAAC;AAC5B,CAAC;AAED,uEAAuE;AAChE,KAAK,UAAU,sBAAsB,CAAC,OAAe;IAC1D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE5C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAErC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,OAAO,SAAS,OAAO,iCAAiC,CAAC;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,OAAO,cAAc,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,mCAAmC,CAAC;AACjF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "better-ts-stack",
3
+ "version": "0.1.0",
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
+ "keywords": [
6
+ "cli",
7
+ "builder",
8
+ "backend",
9
+ "typescript",
10
+ "express",
11
+ "prisma",
12
+ "template"
13
+ ],
14
+ "homepage": "https://better-ts-stack.abdullahtech.me",
15
+ "bugs": {
16
+ "url": "https://github.com/Abdullah-dev0/better-ts-stack/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Abdullah-dev0/better-ts-stack.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Abdullah",
24
+ "type": "commonjs",
25
+ "main": "dist/index.js",
26
+ "bin": {
27
+ "better-ts-stack": "dist/index.js"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "templates"
32
+ ],
33
+ "scripts": {
34
+ "dev": "tsx src/index.ts",
35
+ "build": "tsc",
36
+ "postbuild": "node -e \"const fs=require('fs');const p='dist/index.js';fs.writeFileSync(p,'#!/usr/bin/env node\\n'+fs.readFileSync(p,'utf8'))\"",
37
+ "prepack": "npm run build",
38
+ "start": "node dist/index.js",
39
+ "lint": "eslint src",
40
+ "lint:fix": "eslint src --fix",
41
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md,mdx,css}\"",
42
+ "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,mdx,css}\"",
43
+ "type:check": "tsc --noEmit"
44
+ },
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"
51
+ },
52
+ "devDependencies": {
53
+ "@better-ts-stack/eslint-config": "*",
54
+ "@better-ts-stack/prettier-config": "*",
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"
61
+ },
62
+ "engines": {
63
+ "node": ">=18.0.0"
64
+ },
65
+ "prettier": "@better-ts-stack/prettier-config"
66
+ }
@@ -0,0 +1,24 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ parserOptions: {
4
+ ecmaVersion: 2020,
5
+ sourceType: 'module',
6
+ project: './tsconfig.json',
7
+ },
8
+ extends: [
9
+ 'eslint:recommended',
10
+ 'plugin:@typescript-eslint/recommended',
11
+ 'plugin:@typescript-eslint/recommended-requiring-type-checking',
12
+ 'prettier',
13
+ ],
14
+ plugins: ['@typescript-eslint'],
15
+ env: {
16
+ node: true,
17
+ es2020: true,
18
+ },
19
+ rules: {
20
+ '@typescript-eslint/explicit-function-return-type': 'off',
21
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
22
+ '@typescript-eslint/no-explicit-any': 'error',
23
+ },
24
+ };