@expressots/cli 3.0.0 → 4.0.0-preview.3

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 (194) hide show
  1. package/README.md +41 -95
  2. package/bin/cicd/cli.d.ts +6 -0
  3. package/bin/cicd/cli.js +128 -0
  4. package/bin/cicd/form.d.ts +29 -0
  5. package/bin/cicd/form.js +346 -0
  6. package/bin/cicd/generators/azure-devops.d.ts +2 -0
  7. package/bin/cicd/generators/azure-devops.js +370 -0
  8. package/bin/cicd/generators/bitbucket.d.ts +2 -0
  9. package/bin/cicd/generators/bitbucket.js +217 -0
  10. package/bin/cicd/generators/circleci.d.ts +2 -0
  11. package/bin/cicd/generators/circleci.js +274 -0
  12. package/bin/cicd/generators/github-actions.d.ts +14 -0
  13. package/bin/cicd/generators/github-actions.js +426 -0
  14. package/bin/cicd/generators/gitlab-ci.d.ts +2 -0
  15. package/bin/cicd/generators/gitlab-ci.js +237 -0
  16. package/bin/cicd/generators/index.d.ts +6 -0
  17. package/bin/cicd/generators/index.js +15 -0
  18. package/bin/cicd/generators/jenkins.d.ts +2 -0
  19. package/bin/cicd/generators/jenkins.js +248 -0
  20. package/bin/cicd/generators/template-loader.d.ts +17 -0
  21. package/bin/cicd/generators/template-loader.js +128 -0
  22. package/bin/cicd/index.d.ts +1 -0
  23. package/bin/cicd/index.js +5 -0
  24. package/bin/cli.d.ts +1 -5
  25. package/bin/cli.js +72 -7
  26. package/bin/commands/project.commands.d.ts +19 -6
  27. package/bin/commands/project.commands.js +602 -66
  28. package/bin/config/index.d.ts +5 -0
  29. package/bin/config/index.js +10 -0
  30. package/bin/config/manager.d.ts +98 -0
  31. package/bin/config/manager.js +222 -0
  32. package/bin/containerize/analyzers/bootstrap-analyzer.d.ts +46 -0
  33. package/bin/containerize/analyzers/bootstrap-analyzer.js +187 -0
  34. package/bin/containerize/analyzers/project-analyzer.d.ts +20 -0
  35. package/bin/containerize/analyzers/project-analyzer.js +150 -0
  36. package/bin/containerize/cli.d.ts +4 -0
  37. package/bin/containerize/cli.js +113 -0
  38. package/bin/containerize/form.d.ts +15 -0
  39. package/bin/containerize/form.js +152 -0
  40. package/bin/containerize/generators/ci-generator.d.ts +31 -0
  41. package/bin/containerize/generators/ci-generator.js +940 -0
  42. package/bin/containerize/generators/docker-compose-generator.d.ts +8 -0
  43. package/bin/containerize/generators/docker-compose-generator.js +187 -0
  44. package/bin/containerize/generators/dockerfile-generator.d.ts +8 -0
  45. package/bin/containerize/generators/dockerfile-generator.js +657 -0
  46. package/bin/containerize/generators/kubernetes-generator.d.ts +8 -0
  47. package/bin/containerize/generators/kubernetes-generator.js +134 -0
  48. package/bin/containerize/generators/template-loader.d.ts +36 -0
  49. package/bin/containerize/generators/template-loader.js +129 -0
  50. package/bin/containerize/index.d.ts +4 -0
  51. package/bin/containerize/index.js +13 -0
  52. package/bin/containerize/presets/preset-registry.d.ts +20 -0
  53. package/bin/containerize/presets/preset-registry.js +102 -0
  54. package/bin/costs/cli.d.ts +5 -0
  55. package/bin/costs/cli.js +185 -0
  56. package/bin/costs/form.d.ts +44 -0
  57. package/bin/costs/form.js +412 -0
  58. package/bin/costs/index.d.ts +4 -0
  59. package/bin/costs/index.js +25 -0
  60. package/bin/costs/pricing-manager.d.ts +84 -0
  61. package/bin/costs/pricing-manager.js +342 -0
  62. package/bin/costs/providers/index.d.ts +32 -0
  63. package/bin/costs/providers/index.js +153 -0
  64. package/bin/costs/sources/api-source.d.ts +10 -0
  65. package/bin/costs/sources/api-source.js +32 -0
  66. package/bin/costs/sources/index.d.ts +6 -0
  67. package/bin/costs/sources/index.js +15 -0
  68. package/bin/costs/sources/local-json-source.d.ts +23 -0
  69. package/bin/costs/sources/local-json-source.js +59 -0
  70. package/bin/costs/sources/remote-json-source.d.ts +11 -0
  71. package/bin/costs/sources/remote-json-source.js +53 -0
  72. package/bin/costs/types.d.ts +53 -0
  73. package/bin/costs/types.js +5 -0
  74. package/bin/dev/cli.d.ts +4 -0
  75. package/bin/dev/cli.js +136 -0
  76. package/bin/dev/form.d.ts +36 -0
  77. package/bin/dev/form.js +254 -0
  78. package/bin/dev/index.d.ts +1 -0
  79. package/bin/dev/index.js +5 -0
  80. package/bin/generate/cli.d.ts +1 -1
  81. package/bin/generate/cli.js +29 -2
  82. package/bin/generate/form.d.ts +5 -1
  83. package/bin/generate/form.js +3 -3
  84. package/bin/generate/templates/nonopinionated/config.tpl +12 -0
  85. package/bin/generate/templates/nonopinionated/event.tpl +10 -0
  86. package/bin/generate/templates/nonopinionated/guard.tpl +18 -0
  87. package/bin/generate/templates/nonopinionated/handler.tpl +12 -0
  88. package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -0
  89. package/bin/generate/templates/opinionated/config.tpl +47 -0
  90. package/bin/generate/templates/opinionated/entity.tpl +1 -8
  91. package/bin/generate/templates/opinionated/event.tpl +15 -0
  92. package/bin/generate/templates/opinionated/guard.tpl +41 -0
  93. package/bin/generate/templates/opinionated/handler.tpl +23 -0
  94. package/bin/generate/templates/opinionated/interceptor.tpl +50 -0
  95. package/bin/generate/utils/command-utils.d.ts +20 -5
  96. package/bin/generate/utils/command-utils.js +145 -48
  97. package/bin/generate/utils/nonopininated-cmd.d.ts +10 -1
  98. package/bin/generate/utils/nonopininated-cmd.js +100 -1
  99. package/bin/generate/utils/opinionated-cmd.d.ts +10 -1
  100. package/bin/generate/utils/opinionated-cmd.js +128 -16
  101. package/bin/generate/utils/string-utils.d.ts +6 -0
  102. package/bin/generate/utils/string-utils.js +13 -1
  103. package/bin/help/cli.d.ts +1 -1
  104. package/bin/help/command-help-registry.d.ts +23 -0
  105. package/bin/help/command-help-registry.js +303 -0
  106. package/bin/help/command-help.d.ts +36 -0
  107. package/bin/help/command-help.js +56 -0
  108. package/bin/help/form.js +127 -22
  109. package/bin/help/main-help.d.ts +8 -0
  110. package/bin/help/main-help.js +126 -0
  111. package/bin/help/render.d.ts +32 -0
  112. package/bin/help/render.js +46 -0
  113. package/bin/info/cli.d.ts +1 -1
  114. package/bin/info/form.d.ts +1 -1
  115. package/bin/info/form.js +11 -11
  116. package/bin/migrate/analyzers/platform-detector.d.ts +14 -0
  117. package/bin/migrate/analyzers/platform-detector.js +116 -0
  118. package/bin/migrate/cli.d.ts +6 -0
  119. package/bin/migrate/cli.js +98 -0
  120. package/bin/migrate/form.d.ts +25 -0
  121. package/bin/migrate/form.js +348 -0
  122. package/bin/migrate/generators/compose-to-k8s.d.ts +2 -0
  123. package/bin/migrate/generators/compose-to-k8s.js +324 -0
  124. package/bin/migrate/generators/compose-to-railway.d.ts +2 -0
  125. package/bin/migrate/generators/compose-to-railway.js +138 -0
  126. package/bin/migrate/generators/compose-to-render.d.ts +2 -0
  127. package/bin/migrate/generators/compose-to-render.js +148 -0
  128. package/bin/migrate/generators/generic-migration.d.ts +9 -0
  129. package/bin/migrate/generators/generic-migration.js +221 -0
  130. package/bin/migrate/generators/heroku-to-fly.d.ts +2 -0
  131. package/bin/migrate/generators/heroku-to-fly.js +291 -0
  132. package/bin/migrate/generators/heroku-to-railway.d.ts +2 -0
  133. package/bin/migrate/generators/heroku-to-railway.js +283 -0
  134. package/bin/migrate/generators/heroku-to-render.d.ts +2 -0
  135. package/bin/migrate/generators/heroku-to-render.js +148 -0
  136. package/bin/migrate/generators/index.d.ts +7 -0
  137. package/bin/migrate/generators/index.js +17 -0
  138. package/bin/migrate/generators/template-loader.d.ts +21 -0
  139. package/bin/migrate/generators/template-loader.js +59 -0
  140. package/bin/migrate/index.d.ts +1 -0
  141. package/bin/migrate/index.js +5 -0
  142. package/bin/new/cli.d.ts +5 -1
  143. package/bin/new/cli.js +77 -14
  144. package/bin/new/form.d.ts +27 -4
  145. package/bin/new/form.js +605 -75
  146. package/bin/profile/analyzers/dockerfile-analyzer.d.ts +27 -0
  147. package/bin/profile/analyzers/dockerfile-analyzer.js +122 -0
  148. package/bin/profile/analyzers/image-analyzer.d.ts +19 -0
  149. package/bin/profile/analyzers/image-analyzer.js +85 -0
  150. package/bin/profile/cli.d.ts +4 -0
  151. package/bin/profile/cli.js +94 -0
  152. package/bin/profile/form.d.ts +56 -0
  153. package/bin/profile/form.js +401 -0
  154. package/bin/profile/index.d.ts +1 -0
  155. package/bin/profile/index.js +5 -0
  156. package/bin/profile/optimizers/index.d.ts +19 -0
  157. package/bin/profile/optimizers/index.js +137 -0
  158. package/bin/providers/add/form.d.ts +1 -1
  159. package/bin/providers/add/form.js +27 -6
  160. package/bin/providers/create/form.js +53 -3
  161. package/bin/scripts/form.js +27 -5
  162. package/bin/studio/cli.d.ts +15 -0
  163. package/bin/studio/cli.js +172 -0
  164. package/bin/studio/index.d.ts +5 -0
  165. package/bin/studio/index.js +9 -0
  166. package/bin/templates/cache.d.ts +54 -0
  167. package/bin/templates/cache.js +180 -0
  168. package/bin/templates/cli.d.ts +8 -0
  169. package/bin/templates/cli.js +294 -0
  170. package/bin/templates/fetcher.d.ts +49 -0
  171. package/bin/templates/fetcher.js +208 -0
  172. package/bin/templates/index.d.ts +11 -0
  173. package/bin/templates/index.js +37 -0
  174. package/bin/templates/manager.d.ts +116 -0
  175. package/bin/templates/manager.js +323 -0
  176. package/bin/templates/renderer.d.ts +49 -0
  177. package/bin/templates/renderer.js +204 -0
  178. package/bin/templates/types.d.ts +51 -0
  179. package/bin/templates/types.js +5 -0
  180. package/bin/utils/add-module-to-container.d.ts +14 -3
  181. package/bin/utils/add-module-to-container.js +327 -98
  182. package/bin/utils/cli-ui.d.ts +49 -3
  183. package/bin/utils/cli-ui.js +133 -13
  184. package/bin/utils/index.d.ts +4 -0
  185. package/bin/utils/index.js +4 -0
  186. package/bin/utils/input-validation.d.ts +50 -0
  187. package/bin/utils/input-validation.js +143 -0
  188. package/bin/utils/package-manager-commands.d.ts +24 -0
  189. package/bin/utils/package-manager-commands.js +50 -0
  190. package/bin/utils/safe-spawn.d.ts +35 -0
  191. package/bin/utils/safe-spawn.js +51 -0
  192. package/bin/utils/update-tsconfig-paths.d.ts +35 -0
  193. package/bin/utils/update-tsconfig-paths.js +326 -0
  194. package/package.json +165 -156
@@ -0,0 +1,326 @@
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.validateTsconfigPaths = exports.getPathAliasForFolder = exports.updateTsconfigPaths = exports.generatePathAlias = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const cli_ui_1 = require("./cli-ui");
10
+ /**
11
+ * Default path alias mappings for opinionated scaffolding
12
+ * Maps folder names to their corresponding path aliases
13
+ */
14
+ const DEFAULT_PATH_ALIASES = {
15
+ controllers: "@controllers",
16
+ useCases: "@useCases",
17
+ providers: "@providers",
18
+ entities: "@entities",
19
+ middleware: "@middleware",
20
+ interceptors: "@interceptors",
21
+ events: "@events",
22
+ guards: "@guards",
23
+ config: "@config",
24
+ };
25
+ /**
26
+ * Generate path alias from folder name
27
+ * Handles both default mappings and custom folder names
28
+ *
29
+ * @param folderName - The folder name (e.g., "useCases", "my-custom-folder")
30
+ * @returns The path alias (e.g., "@useCases", "@myCustomFolder")
31
+ */
32
+ function generatePathAlias(folderName) {
33
+ // Check if we have a default mapping
34
+ if (DEFAULT_PATH_ALIASES[folderName]) {
35
+ return DEFAULT_PATH_ALIASES[folderName];
36
+ }
37
+ // For custom folder names, convert to camelCase and add @ prefix
38
+ // Handles: kebab-case, snake_case, PascalCase, camelCase
39
+ const camelCase = folderName
40
+ .split(/[-_]/)
41
+ .map((word, index) => {
42
+ if (index === 0) {
43
+ // First word: keep original case for already camelCase names
44
+ return word.charAt(0).toLowerCase() + word.slice(1);
45
+ }
46
+ // Subsequent words: capitalize first letter
47
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
48
+ })
49
+ .join("");
50
+ return `@${camelCase}`;
51
+ }
52
+ exports.generatePathAlias = generatePathAlias;
53
+ /**
54
+ * Parse JSONC (JSON with Comments) by stripping comments and trailing commas.
55
+ *
56
+ * Implemented as a small character scanner so we are correctly string-aware:
57
+ * comment-delimiter sequences (slash-star and star-slash) inside a JSON
58
+ * string literal — e.g. the very common "src" double-star slash "*.ts"
59
+ * include glob — must NOT be treated as comments. The previous regex-based
60
+ * stripper silently corrupted such globs into `src*.ts`, which then got
61
+ * persisted to disk by the structured rewriter.
62
+ *
63
+ * Handles:
64
+ * - Line comments (`//` to end of line)
65
+ * - Block comments (may span lines, may also be empty)
66
+ * - Trailing commas before `}` / `]`
67
+ * - JSON string escapes (`\"`, `\\`, etc.)
68
+ *
69
+ * @param content - The JSONC content
70
+ * @returns Cleaned JSON string that can be parsed by JSON.parse
71
+ */
72
+ function stripJsonComments(content) {
73
+ let out = "";
74
+ let inString = false;
75
+ let escape = false;
76
+ for (let i = 0; i < content.length; i++) {
77
+ const ch = content[i];
78
+ const next = content[i + 1];
79
+ if (inString) {
80
+ out += ch;
81
+ if (escape) {
82
+ escape = false;
83
+ }
84
+ else if (ch === "\\") {
85
+ escape = true;
86
+ }
87
+ else if (ch === '"') {
88
+ inString = false;
89
+ }
90
+ continue;
91
+ }
92
+ if (ch === '"') {
93
+ inString = true;
94
+ out += ch;
95
+ continue;
96
+ }
97
+ if (ch === "/" && next === "/") {
98
+ // Line comment — skip until newline (newline is preserved).
99
+ i += 2;
100
+ while (i < content.length && content[i] !== "\n")
101
+ i++;
102
+ i--; // Loop will increment past this position.
103
+ continue;
104
+ }
105
+ if (ch === "/" && next === "*") {
106
+ // Block comment — skip until closing */. Replace with a single
107
+ // space so adjacent tokens don't fuse (e.g. `a/*x*/b` -> `a b`).
108
+ i += 2;
109
+ while (i < content.length &&
110
+ !(content[i] === "*" && content[i + 1] === "/")) {
111
+ i++;
112
+ }
113
+ i++; // Consume the closing '*' (loop increments past '/').
114
+ out += " ";
115
+ continue;
116
+ }
117
+ out += ch;
118
+ }
119
+ // Strip trailing commas before `}` / `]` (legal in JSONC, not in JSON).
120
+ return out.replace(/,(\s*[}\]])/g, "$1");
121
+ }
122
+ /**
123
+ * Try to parse JSONC content, first stripping comments then parsing
124
+ * @param content - Raw file content
125
+ * @returns Parsed config object or null if parsing fails
126
+ */
127
+ function parseJsonc(content) {
128
+ // Always try to strip comments first for consistency
129
+ const stripped = stripJsonComments(content);
130
+ try {
131
+ return JSON.parse(stripped);
132
+ }
133
+ catch {
134
+ // If stripping didn't help, try the original (unlikely but safe)
135
+ try {
136
+ return JSON.parse(content);
137
+ }
138
+ catch {
139
+ return null;
140
+ }
141
+ }
142
+ }
143
+ /**
144
+ * Text-based fallback to add path alias when JSON parsing fails
145
+ * This preserves the original file format (comments, etc.)
146
+ *
147
+ * @param content - Original file content
148
+ * @param aliasKey - The path alias key (e.g., "@config/*")
149
+ * @param aliasValue - The path alias value (e.g., ["./src/config/*"])
150
+ * @returns Modified content or null if update failed
151
+ */
152
+ function addPathAliasTextBased(content, aliasKey, aliasValue) {
153
+ // Check if the alias already exists
154
+ if (content.includes(`"${aliasKey}"`)) {
155
+ return null; // Already exists, no update needed
156
+ }
157
+ // Find the "paths" object
158
+ const pathsMatch = content.match(/"paths"\s*:\s*\{/);
159
+ if (pathsMatch && pathsMatch.index !== undefined) {
160
+ // Insert new path alias after "paths": {
161
+ const insertPos = pathsMatch.index + pathsMatch[0].length;
162
+ const aliasEntry = `\n\t\t\t"${aliasKey}": ${JSON.stringify(aliasValue)},`;
163
+ return (content.slice(0, insertPos) + aliasEntry + content.slice(insertPos));
164
+ }
165
+ // Find compilerOptions to add paths object
166
+ const compilerOptionsMatch = content.match(/"compilerOptions"\s*:\s*\{/);
167
+ if (compilerOptionsMatch && compilerOptionsMatch.index !== undefined) {
168
+ // Find the end of compilerOptions opening brace.
169
+ // We don't inject `baseUrl` here on purpose — `paths` resolve
170
+ // relative to the tsconfig file when `baseUrl` is absent (TS 5+),
171
+ // which matches the v4 template convention.
172
+ const insertPos = compilerOptionsMatch.index + compilerOptionsMatch[0].length;
173
+ const insertion = "\n" +
174
+ `\t\t"paths": {\n\t\t\t"${aliasKey}": ${JSON.stringify(aliasValue)}\n\t\t},`;
175
+ return (content.slice(0, insertPos) + insertion + content.slice(insertPos));
176
+ }
177
+ // Can't find compilerOptions, give up
178
+ return null;
179
+ }
180
+ /**
181
+ * Update tsconfig.json paths to include missing aliases for opinionated scaffolding
182
+ * Handles both default folders and custom scaffoldSchematics overrides
183
+ *
184
+ * @param folderName - The folder name where the schematic is being created
185
+ * @param sourceRoot - The source root directory (default: "src")
186
+ */
187
+ async function updateTsconfigPaths(folderName, sourceRoot = "src") {
188
+ if (!folderName) {
189
+ return; // No folder specified
190
+ }
191
+ const tsconfigPath = node_path_1.default.join(process.cwd(), "tsconfig.json");
192
+ const tsconfigBuildPath = node_path_1.default.join(process.cwd(), "tsconfig.build.json");
193
+ // Generate alias from folder name (handles custom names)
194
+ const alias = generatePathAlias(folderName);
195
+ const aliasKey = `${alias}/*`;
196
+ // Track if we updated any config
197
+ let updated = false;
198
+ // Update both tsconfig files if they exist
199
+ for (const configPath of [tsconfigPath, tsconfigBuildPath]) {
200
+ if (!node_fs_1.default.existsSync(configPath)) {
201
+ continue;
202
+ }
203
+ try {
204
+ const configContent = node_fs_1.default.readFileSync(configPath, "utf-8");
205
+ // Try JSON parsing first
206
+ const config = parseJsonc(configContent);
207
+ if (config) {
208
+ // JSON parsing succeeded - use structured approach
209
+ // Ensure compilerOptions exists
210
+ if (!config.compilerOptions) {
211
+ config.compilerOptions = {};
212
+ }
213
+ const compilerOptions = config.compilerOptions;
214
+ // Determine the correct path value based on baseUrl. When
215
+ // `baseUrl` is absent (the TS 7-friendly default the v4
216
+ // templates ship) `paths` resolve relative to the tsconfig
217
+ // file itself — same effective behaviour as `baseUrl: "."`.
218
+ // We deliberately do NOT inject `baseUrl` here; doing so
219
+ // would silently undo the template's intentional removal.
220
+ const baseUrl = compilerOptions.baseUrl || ".";
221
+ const isBaseUrlSrc = baseUrl === `./${sourceRoot}` || baseUrl === sourceRoot;
222
+ const aliasValue = isBaseUrlSrc
223
+ ? [`./${folderName}/*`]
224
+ : [`./${sourceRoot}/${folderName}/*`];
225
+ // Ensure paths object exists
226
+ if (!compilerOptions.paths) {
227
+ compilerOptions.paths = {};
228
+ }
229
+ const paths = compilerOptions.paths;
230
+ // Only add if it doesn't exist
231
+ if (!paths[aliasKey]) {
232
+ paths[aliasKey] = aliasValue;
233
+ // Write back to file with proper formatting (tab indent)
234
+ node_fs_1.default.writeFileSync(configPath, JSON.stringify(config, null, "\t") + "\n", "utf-8");
235
+ updated = true;
236
+ }
237
+ }
238
+ else {
239
+ // JSON parsing failed - use text-based fallback
240
+ // This preserves comments and formatting
241
+ // Try to detect baseUrl from content
242
+ const baseUrlMatch = configContent.match(/"baseUrl"\s*:\s*"([^"]+)"/);
243
+ const baseUrl = baseUrlMatch ? baseUrlMatch[1] : ".";
244
+ const isBaseUrlSrc = baseUrl === `./${sourceRoot}` || baseUrl === sourceRoot;
245
+ const aliasValue = isBaseUrlSrc
246
+ ? [`./${folderName}/*`]
247
+ : [`./${sourceRoot}/${folderName}/*`];
248
+ const modifiedContent = addPathAliasTextBased(configContent, aliasKey, aliasValue);
249
+ if (modifiedContent) {
250
+ node_fs_1.default.writeFileSync(configPath, modifiedContent, "utf-8");
251
+ updated = true;
252
+ }
253
+ else if (!configContent.includes(`"${aliasKey}"`)) {
254
+ // Couldn't update and alias doesn't exist
255
+ (0, cli_ui_1.printWarning)(`Could not update ${node_path_1.default.basename(configPath)}. Please add "${aliasKey}" path alias manually`, "tsconfig");
256
+ }
257
+ }
258
+ }
259
+ catch (error) {
260
+ // Log warning but don't fail the scaffolding process
261
+ (0, cli_ui_1.printWarning)(`Could not update ${node_path_1.default.basename(configPath)}: ${error instanceof Error ? error.message : "Unknown error"}`, "tsconfig");
262
+ }
263
+ }
264
+ // Print success message only if we updated something
265
+ if (updated) {
266
+ (0, cli_ui_1.printInfo)(`Path alias ${aliasKey} added`, "tsconfig");
267
+ }
268
+ }
269
+ exports.updateTsconfigPaths = updateTsconfigPaths;
270
+ /**
271
+ * Get the path alias for a given folder name
272
+ * Used by other utilities to determine the correct import path
273
+ *
274
+ * @param folderName - The folder name
275
+ * @returns The path alias (e.g., "@useCases")
276
+ */
277
+ function getPathAliasForFolder(folderName) {
278
+ return generatePathAlias(folderName);
279
+ }
280
+ exports.getPathAliasForFolder = getPathAliasForFolder;
281
+ /**
282
+ * Check if tsconfig already has all required path aliases for opinionated mode
283
+ * This can be used to validate project setup
284
+ *
285
+ * @param requiredFolders - List of folder names that need path aliases
286
+ * @returns Object with missing aliases and whether all are present
287
+ */
288
+ function validateTsconfigPaths(requiredFolders) {
289
+ const tsconfigPath = node_path_1.default.join(process.cwd(), "tsconfig.json");
290
+ if (!node_fs_1.default.existsSync(tsconfigPath)) {
291
+ return {
292
+ valid: false,
293
+ missingAliases: requiredFolders.map((f) => generatePathAlias(f)),
294
+ };
295
+ }
296
+ try {
297
+ const configContent = node_fs_1.default.readFileSync(tsconfigPath, "utf-8");
298
+ let config;
299
+ try {
300
+ config = JSON.parse(configContent);
301
+ }
302
+ catch {
303
+ config = JSON.parse(stripJsonComments(configContent));
304
+ }
305
+ const paths = config.compilerOptions
306
+ ?.paths || {};
307
+ const missingAliases = [];
308
+ for (const folder of requiredFolders) {
309
+ const aliasKey = `${generatePathAlias(folder)}/*`;
310
+ if (!paths[aliasKey]) {
311
+ missingAliases.push(aliasKey);
312
+ }
313
+ }
314
+ return {
315
+ valid: missingAliases.length === 0,
316
+ missingAliases,
317
+ };
318
+ }
319
+ catch {
320
+ return {
321
+ valid: false,
322
+ missingAliases: requiredFolders.map((f) => generatePathAlias(f)),
323
+ };
324
+ }
325
+ }
326
+ exports.validateTsconfigPaths = validateTsconfigPaths;
package/package.json CHANGED
@@ -1,158 +1,167 @@
1
1
  {
2
- "name": "@expressots/cli",
3
- "version": "3.0.0",
4
- "description": "Expressots CLI - modern, fast, lightweight nodejs web framework (@cli)",
5
- "author": "Richard Zampieri",
6
- "license": "MIT",
7
- "bugs": {
8
- "url": "https://github.com/expressots/expressots-cli/issues"
9
- },
10
- "bin": {
11
- "expressots": "bin/cli.js",
12
- "ex": "bin/cli.js"
13
- },
14
- "engines": {
15
- "node": ">=20.18.0"
16
- },
17
- "funding": {
18
- "type": "github",
19
- "url": "https://github.com/sponsors/expressots"
20
- },
21
- "repository": {
22
- "type": "git",
23
- "url": "https://github.com/expressots/expressots-cli"
24
- },
25
- "homepage": "https://expresso-ts.com",
26
- "publishConfig": {
27
- "access": "public"
28
- },
29
- "keywords": [
30
- "ExpressoTS",
31
- "CLI",
32
- "Scaffolding"
33
- ],
34
- "scripts": {
35
- "prepare": "husky",
36
- "start:build": "npm run build && npm run start",
37
- "start": "node ./bin/cli.js",
38
- "start:dev": "tsx ./src/cli.ts",
39
- "build": "npm run clean && tsc -p tsconfig.json && npm run cp:templates && node scripts/chmod.js ./bin/cli.js",
40
- "cp:templates": "node scripts/cp.js ./src/generate/templates ./bin/generate/",
41
- "clean": "node scripts/rm.js bin",
42
- "prepublish": "npm run build && npm pack",
43
- "format": "prettier --write \"./src/**/*.ts\" --cache",
44
- "lint": "eslint \"./src/**/*.ts\"",
45
- "lint:fix": "eslint \"./src/**/*.ts\" --fix",
46
- "release": "release-it",
47
- "test": "jest",
48
- "coverage": "jest --coverage",
49
- "test:watch": "jest --watch"
50
- },
51
- "dependencies": {
52
- "axios": "1.7.7",
53
- "chalk-animation": "2.0.3",
54
- "cli-progress": "3.12.0",
55
- "cli-table3": "0.6.5",
56
- "degit": "2.8.4",
57
- "glob": "10.4.5",
58
- "inquirer": "8.2.6",
59
- "mustache": "4.2.0",
60
- "semver": "7.6.3",
61
- "ts-node": "10.9.2",
62
- "yargs": "17.7.2"
63
- },
64
- "devDependencies": {
65
- "@codecov/vite-plugin": "0.0.1-beta.9",
66
- "@commitlint/cli": "19.2.1",
67
- "@commitlint/config-conventional": "19.1.0",
68
- "@expressots/shared": "3.0.0",
69
- "@release-it/conventional-changelog": "7.0.2",
70
- "@types/chalk-animation": "1.6.1",
71
- "@types/cli-progress": "3.11.0",
72
- "@types/degit": "2.8.3",
73
- "@types/inquirer": "9.0.3",
74
- "@types/jest": "^29.5.14",
75
- "@types/mustache": "4.2.2",
76
- "@types/node": "20.12.7",
77
- "@types/yargs": "17.0.22",
78
- "@typescript-eslint/eslint-plugin": "7.6.0",
79
- "@typescript-eslint/parser": "7.6.0",
80
- "chalk": "4.1.2",
81
- "eslint": "8.57.0",
82
- "eslint-config-prettier": "9.1.0",
83
- "husky": "9.0.11",
84
- "jest": "^29.7.0",
85
- "prettier": "3.2.5",
86
- "reflect-metadata": "0.2.2",
87
- "release-it": "16.3.0",
88
- "shx": "0.3.4",
89
- "ts-jest": "^29.2.5",
90
- "tsx": "^4.19.2",
91
- "typescript": "5.2.2"
92
- },
93
- "release-it": {
94
- "git": {
95
- "commitMessage": "chore: release ${version}"
96
- },
97
- "github": {
98
- "release": true
99
- },
100
- "npm": {
101
- "publish": false
102
- },
103
- "plugins": {
104
- "@release-it/conventional-changelog": {
105
- "infile": "CHANGELOG.md",
106
- "preset": {
107
- "name": "conventionalcommits",
108
- "types": [
109
- {
110
- "type": "feat",
111
- "section": "Features"
112
- },
113
- {
114
- "type": "fix",
115
- "section": "Bug Fixes"
116
- },
117
- {
118
- "type": "perf",
119
- "section": "Performance Improvements"
120
- },
121
- {
122
- "type": "revert",
123
- "section": "Reverts"
124
- },
125
- {
126
- "type": "docs",
127
- "section": "Documentation"
128
- },
129
- {
130
- "type": "style",
131
- "section": "Styles"
132
- },
133
- {
134
- "type": "refactor",
135
- "section": "Code Refactoring"
136
- },
137
- {
138
- "type": "test",
139
- "section": "Tests"
140
- },
141
- {
142
- "type": "build",
143
- "section": "Build System"
144
- },
145
- {
146
- "type": "ci",
147
- "section": "Continuous Integrations"
148
- },
149
- {
150
- "type": "chore",
151
- "hidden": true
152
- }
153
- ]
154
- }
155
- }
156
- }
157
- }
2
+ "name": "@expressots/cli",
3
+ "version": "4.0.0-preview.3",
4
+ "description": "Expressots CLI - modern, fast, lightweight nodejs web framework (@cli)",
5
+ "author": "Richard Zampieri",
6
+ "license": "MIT",
7
+ "bugs": {
8
+ "url": "https://github.com/expressots/expressots-cli/issues"
9
+ },
10
+ "bin": {
11
+ "expressots": "bin/cli.js",
12
+ "ex": "bin/cli.js"
13
+ },
14
+ "engines": {
15
+ "node": ">=20.18.0"
16
+ },
17
+ "funding": {
18
+ "type": "github",
19
+ "url": "https://github.com/sponsors/expressots"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/expressots/expressots-cli"
24
+ },
25
+ "homepage": "https://expresso-ts.com",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "keywords": [
30
+ "ExpressoTS",
31
+ "CLI",
32
+ "Scaffolding"
33
+ ],
34
+ "scripts": {
35
+ "prepare": "husky",
36
+ "start:build": "npm run build && npm run start",
37
+ "start": "node ./bin/cli.js",
38
+ "start:dev": "tsx ./src/cli.ts",
39
+ "build": "npm run clean && tsc -p tsconfig.json && npm run cp:templates && node scripts/chmod.js ./bin/cli.js",
40
+ "cp:templates": "node scripts/cp.js ./src/generate/templates ./bin/generate/",
41
+ "clean": "node scripts/rm.js bin",
42
+ "prepublish": "npm run build && npm pack",
43
+ "format": "prettier --write \"./src/**/*.ts\" --cache",
44
+ "lint": "eslint \"./src/**/*.ts\" --cache --cache-location node_modules/.cache/eslint/",
45
+ "lint:fix": "eslint \"./src/**/*.ts\" --fix --cache --cache-location node_modules/.cache/eslint/",
46
+ "release": "release-it",
47
+ "release:prepare": "node scripts/release/prepare-publish.mjs",
48
+ "release:restore": "node scripts/release/restore-package-json.mjs",
49
+ "release:publish": "npm run build && npm run release:prepare && npm publish --tag next --access public && npm run release:restore",
50
+ "test": "jest",
51
+ "coverage": "jest --coverage",
52
+ "test:watch": "jest --watch"
53
+ },
54
+ "dependencies": {
55
+ "@expressots/shared": "^4.0.0-preview.3",
56
+ "chalk": "4.1.2",
57
+ "cli-progress": "3.12.0",
58
+ "cross-spawn": "7.0.6",
59
+ "degit": "2.8.4",
60
+ "glob": "13.0.6",
61
+ "inquirer": "^8.2.7",
62
+ "mustache": "4.2.0",
63
+ "ora": "5.4.1",
64
+ "semver": "7.6.3",
65
+ "ts-node": "10.9.2",
66
+ "yargs": "17.7.2"
67
+ },
68
+ "devDependencies": {
69
+ "@codecov/vite-plugin": "^2.0.1",
70
+ "@commitlint/cli": "19.2.1",
71
+ "@commitlint/config-conventional": "19.1.0",
72
+ "@release-it/conventional-changelog": "^11.0.0",
73
+ "@types/cli-progress": "3.11.0",
74
+ "@types/cross-spawn": "6.0.6",
75
+ "@types/degit": "2.8.3",
76
+ "@types/inquirer": "9.0.3",
77
+ "@types/jest": "^29.5.14",
78
+ "@types/mustache": "4.2.2",
79
+ "@types/node": "20.12.7",
80
+ "@types/yargs": "17.0.22",
81
+ "@typescript-eslint/eslint-plugin": "7.6.0",
82
+ "@typescript-eslint/parser": "7.6.0",
83
+ "eslint": "8.57.0",
84
+ "eslint-config-prettier": "9.1.0",
85
+ "husky": "9.0.11",
86
+ "jest": "^29.7.0",
87
+ "lint-staged": "^15.2.10",
88
+ "prettier": "3.2.5",
89
+ "reflect-metadata": "0.2.2",
90
+ "release-it": "^20.0.1",
91
+ "shx": "0.3.4",
92
+ "ts-jest": "^29.2.5",
93
+ "tsx": "^4.19.2",
94
+ "typescript": "5.2.2"
95
+ },
96
+ "lint-staged": {
97
+ "src/**/*.ts": [
98
+ "eslint --cache --cache-location node_modules/.cache/eslint/ --fix",
99
+ "prettier --write --cache"
100
+ ]
101
+ },
102
+ "release-it": {
103
+ "git": {
104
+ "commitMessage": "chore: release ${version}"
105
+ },
106
+ "github": {
107
+ "release": true
108
+ },
109
+ "npm": {
110
+ "publish": false
111
+ },
112
+ "plugins": {
113
+ "@release-it/conventional-changelog": {
114
+ "infile": "CHANGELOG.md",
115
+ "preset": {
116
+ "name": "conventionalcommits",
117
+ "types": [
118
+ {
119
+ "type": "feat",
120
+ "section": "Features"
121
+ },
122
+ {
123
+ "type": "fix",
124
+ "section": "Bug Fixes"
125
+ },
126
+ {
127
+ "type": "perf",
128
+ "section": "Performance Improvements"
129
+ },
130
+ {
131
+ "type": "revert",
132
+ "section": "Reverts"
133
+ },
134
+ {
135
+ "type": "docs",
136
+ "section": "Documentation"
137
+ },
138
+ {
139
+ "type": "style",
140
+ "section": "Styles"
141
+ },
142
+ {
143
+ "type": "refactor",
144
+ "section": "Code Refactoring"
145
+ },
146
+ {
147
+ "type": "test",
148
+ "section": "Tests"
149
+ },
150
+ {
151
+ "type": "build",
152
+ "section": "Build System"
153
+ },
154
+ {
155
+ "type": "ci",
156
+ "section": "Continuous Integrations"
157
+ },
158
+ {
159
+ "type": "chore",
160
+ "hidden": true
161
+ }
162
+ ]
163
+ }
164
+ }
165
+ }
166
+ }
158
167
  }