@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.
- package/README.md +41 -95
- package/bin/cicd/cli.d.ts +6 -0
- package/bin/cicd/cli.js +128 -0
- package/bin/cicd/form.d.ts +29 -0
- package/bin/cicd/form.js +346 -0
- package/bin/cicd/generators/azure-devops.d.ts +2 -0
- package/bin/cicd/generators/azure-devops.js +370 -0
- package/bin/cicd/generators/bitbucket.d.ts +2 -0
- package/bin/cicd/generators/bitbucket.js +217 -0
- package/bin/cicd/generators/circleci.d.ts +2 -0
- package/bin/cicd/generators/circleci.js +274 -0
- package/bin/cicd/generators/github-actions.d.ts +14 -0
- package/bin/cicd/generators/github-actions.js +426 -0
- package/bin/cicd/generators/gitlab-ci.d.ts +2 -0
- package/bin/cicd/generators/gitlab-ci.js +237 -0
- package/bin/cicd/generators/index.d.ts +6 -0
- package/bin/cicd/generators/index.js +15 -0
- package/bin/cicd/generators/jenkins.d.ts +2 -0
- package/bin/cicd/generators/jenkins.js +248 -0
- package/bin/cicd/generators/template-loader.d.ts +17 -0
- package/bin/cicd/generators/template-loader.js +128 -0
- package/bin/cicd/index.d.ts +1 -0
- package/bin/cicd/index.js +5 -0
- package/bin/cli.d.ts +1 -5
- package/bin/cli.js +72 -7
- package/bin/commands/project.commands.d.ts +19 -6
- package/bin/commands/project.commands.js +602 -66
- package/bin/config/index.d.ts +5 -0
- package/bin/config/index.js +10 -0
- package/bin/config/manager.d.ts +98 -0
- package/bin/config/manager.js +222 -0
- package/bin/containerize/analyzers/bootstrap-analyzer.d.ts +46 -0
- package/bin/containerize/analyzers/bootstrap-analyzer.js +187 -0
- package/bin/containerize/analyzers/project-analyzer.d.ts +20 -0
- package/bin/containerize/analyzers/project-analyzer.js +150 -0
- package/bin/containerize/cli.d.ts +4 -0
- package/bin/containerize/cli.js +113 -0
- package/bin/containerize/form.d.ts +15 -0
- package/bin/containerize/form.js +152 -0
- package/bin/containerize/generators/ci-generator.d.ts +31 -0
- package/bin/containerize/generators/ci-generator.js +940 -0
- package/bin/containerize/generators/docker-compose-generator.d.ts +8 -0
- package/bin/containerize/generators/docker-compose-generator.js +187 -0
- package/bin/containerize/generators/dockerfile-generator.d.ts +8 -0
- package/bin/containerize/generators/dockerfile-generator.js +657 -0
- package/bin/containerize/generators/kubernetes-generator.d.ts +8 -0
- package/bin/containerize/generators/kubernetes-generator.js +134 -0
- package/bin/containerize/generators/template-loader.d.ts +36 -0
- package/bin/containerize/generators/template-loader.js +129 -0
- package/bin/containerize/index.d.ts +4 -0
- package/bin/containerize/index.js +13 -0
- package/bin/containerize/presets/preset-registry.d.ts +20 -0
- package/bin/containerize/presets/preset-registry.js +102 -0
- package/bin/costs/cli.d.ts +5 -0
- package/bin/costs/cli.js +185 -0
- package/bin/costs/form.d.ts +44 -0
- package/bin/costs/form.js +412 -0
- package/bin/costs/index.d.ts +4 -0
- package/bin/costs/index.js +25 -0
- package/bin/costs/pricing-manager.d.ts +84 -0
- package/bin/costs/pricing-manager.js +342 -0
- package/bin/costs/providers/index.d.ts +32 -0
- package/bin/costs/providers/index.js +153 -0
- package/bin/costs/sources/api-source.d.ts +10 -0
- package/bin/costs/sources/api-source.js +32 -0
- package/bin/costs/sources/index.d.ts +6 -0
- package/bin/costs/sources/index.js +15 -0
- package/bin/costs/sources/local-json-source.d.ts +23 -0
- package/bin/costs/sources/local-json-source.js +59 -0
- package/bin/costs/sources/remote-json-source.d.ts +11 -0
- package/bin/costs/sources/remote-json-source.js +53 -0
- package/bin/costs/types.d.ts +53 -0
- package/bin/costs/types.js +5 -0
- package/bin/dev/cli.d.ts +4 -0
- package/bin/dev/cli.js +136 -0
- package/bin/dev/form.d.ts +36 -0
- package/bin/dev/form.js +254 -0
- package/bin/dev/index.d.ts +1 -0
- package/bin/dev/index.js +5 -0
- package/bin/generate/cli.d.ts +1 -1
- package/bin/generate/cli.js +29 -2
- package/bin/generate/form.d.ts +5 -1
- package/bin/generate/form.js +3 -3
- package/bin/generate/templates/nonopinionated/config.tpl +12 -0
- package/bin/generate/templates/nonopinionated/event.tpl +10 -0
- package/bin/generate/templates/nonopinionated/guard.tpl +18 -0
- package/bin/generate/templates/nonopinionated/handler.tpl +12 -0
- package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -0
- package/bin/generate/templates/opinionated/config.tpl +47 -0
- package/bin/generate/templates/opinionated/entity.tpl +1 -8
- package/bin/generate/templates/opinionated/event.tpl +15 -0
- package/bin/generate/templates/opinionated/guard.tpl +41 -0
- package/bin/generate/templates/opinionated/handler.tpl +23 -0
- package/bin/generate/templates/opinionated/interceptor.tpl +50 -0
- package/bin/generate/utils/command-utils.d.ts +20 -5
- package/bin/generate/utils/command-utils.js +145 -48
- package/bin/generate/utils/nonopininated-cmd.d.ts +10 -1
- package/bin/generate/utils/nonopininated-cmd.js +100 -1
- package/bin/generate/utils/opinionated-cmd.d.ts +10 -1
- package/bin/generate/utils/opinionated-cmd.js +128 -16
- package/bin/generate/utils/string-utils.d.ts +6 -0
- package/bin/generate/utils/string-utils.js +13 -1
- package/bin/help/cli.d.ts +1 -1
- package/bin/help/command-help-registry.d.ts +23 -0
- package/bin/help/command-help-registry.js +303 -0
- package/bin/help/command-help.d.ts +36 -0
- package/bin/help/command-help.js +56 -0
- package/bin/help/form.js +127 -22
- package/bin/help/main-help.d.ts +8 -0
- package/bin/help/main-help.js +126 -0
- package/bin/help/render.d.ts +32 -0
- package/bin/help/render.js +46 -0
- package/bin/info/cli.d.ts +1 -1
- package/bin/info/form.d.ts +1 -1
- package/bin/info/form.js +11 -11
- package/bin/migrate/analyzers/platform-detector.d.ts +14 -0
- package/bin/migrate/analyzers/platform-detector.js +116 -0
- package/bin/migrate/cli.d.ts +6 -0
- package/bin/migrate/cli.js +98 -0
- package/bin/migrate/form.d.ts +25 -0
- package/bin/migrate/form.js +348 -0
- package/bin/migrate/generators/compose-to-k8s.d.ts +2 -0
- package/bin/migrate/generators/compose-to-k8s.js +324 -0
- package/bin/migrate/generators/compose-to-railway.d.ts +2 -0
- package/bin/migrate/generators/compose-to-railway.js +138 -0
- package/bin/migrate/generators/compose-to-render.d.ts +2 -0
- package/bin/migrate/generators/compose-to-render.js +148 -0
- package/bin/migrate/generators/generic-migration.d.ts +9 -0
- package/bin/migrate/generators/generic-migration.js +221 -0
- package/bin/migrate/generators/heroku-to-fly.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-fly.js +291 -0
- package/bin/migrate/generators/heroku-to-railway.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-railway.js +283 -0
- package/bin/migrate/generators/heroku-to-render.d.ts +2 -0
- package/bin/migrate/generators/heroku-to-render.js +148 -0
- package/bin/migrate/generators/index.d.ts +7 -0
- package/bin/migrate/generators/index.js +17 -0
- package/bin/migrate/generators/template-loader.d.ts +21 -0
- package/bin/migrate/generators/template-loader.js +59 -0
- package/bin/migrate/index.d.ts +1 -0
- package/bin/migrate/index.js +5 -0
- package/bin/new/cli.d.ts +5 -1
- package/bin/new/cli.js +77 -14
- package/bin/new/form.d.ts +27 -4
- package/bin/new/form.js +605 -75
- package/bin/profile/analyzers/dockerfile-analyzer.d.ts +27 -0
- package/bin/profile/analyzers/dockerfile-analyzer.js +122 -0
- package/bin/profile/analyzers/image-analyzer.d.ts +19 -0
- package/bin/profile/analyzers/image-analyzer.js +85 -0
- package/bin/profile/cli.d.ts +4 -0
- package/bin/profile/cli.js +94 -0
- package/bin/profile/form.d.ts +56 -0
- package/bin/profile/form.js +401 -0
- package/bin/profile/index.d.ts +1 -0
- package/bin/profile/index.js +5 -0
- package/bin/profile/optimizers/index.d.ts +19 -0
- package/bin/profile/optimizers/index.js +137 -0
- package/bin/providers/add/form.d.ts +1 -1
- package/bin/providers/add/form.js +27 -6
- package/bin/providers/create/form.js +53 -3
- package/bin/scripts/form.js +27 -5
- package/bin/studio/cli.d.ts +15 -0
- package/bin/studio/cli.js +172 -0
- package/bin/studio/index.d.ts +5 -0
- package/bin/studio/index.js +9 -0
- package/bin/templates/cache.d.ts +54 -0
- package/bin/templates/cache.js +180 -0
- package/bin/templates/cli.d.ts +8 -0
- package/bin/templates/cli.js +294 -0
- package/bin/templates/fetcher.d.ts +49 -0
- package/bin/templates/fetcher.js +208 -0
- package/bin/templates/index.d.ts +11 -0
- package/bin/templates/index.js +37 -0
- package/bin/templates/manager.d.ts +116 -0
- package/bin/templates/manager.js +323 -0
- package/bin/templates/renderer.d.ts +49 -0
- package/bin/templates/renderer.js +204 -0
- package/bin/templates/types.d.ts +51 -0
- package/bin/templates/types.js +5 -0
- package/bin/utils/add-module-to-container.d.ts +14 -3
- package/bin/utils/add-module-to-container.js +327 -98
- package/bin/utils/cli-ui.d.ts +49 -3
- package/bin/utils/cli-ui.js +133 -13
- package/bin/utils/index.d.ts +4 -0
- package/bin/utils/index.js +4 -0
- package/bin/utils/input-validation.d.ts +50 -0
- package/bin/utils/input-validation.js +143 -0
- package/bin/utils/package-manager-commands.d.ts +24 -0
- package/bin/utils/package-manager-commands.js +50 -0
- package/bin/utils/safe-spawn.d.ts +35 -0
- package/bin/utils/safe-spawn.js +51 -0
- package/bin/utils/update-tsconfig-paths.d.ts +35 -0
- package/bin/utils/update-tsconfig-paths.js +326 -0
- 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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
}
|