@dimensional-innovations/tool-config 5.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1812 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +401 -0
- package/dist/index.js +2644 -0
- package/dist/index.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,1812 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, rmSync, readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import pc from 'picocolors';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __esm = (fn, res) => function __init() {
|
|
11
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
|
+
};
|
|
13
|
+
var __export = (target, all) => {
|
|
14
|
+
for (var name in all)
|
|
15
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/core/types.ts
|
|
19
|
+
var ConfigError;
|
|
20
|
+
var init_types = __esm({
|
|
21
|
+
"src/core/types.ts"() {
|
|
22
|
+
ConfigError = class _ConfigError extends Error {
|
|
23
|
+
context;
|
|
24
|
+
constructor(message, context) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "ConfigError";
|
|
27
|
+
this.context = context;
|
|
28
|
+
if (Error.captureStackTrace) {
|
|
29
|
+
Error.captureStackTrace(this, _ConfigError);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
function detectTypeChecker(framework, preference = "auto", cwd = process.cwd()) {
|
|
36
|
+
if (preference === "legacy") {
|
|
37
|
+
return framework === "vue" ? "vue-tsc" : "tsc";
|
|
38
|
+
}
|
|
39
|
+
if (preference === "modern") {
|
|
40
|
+
return "tsgo";
|
|
41
|
+
}
|
|
42
|
+
if (preference === "auto") {
|
|
43
|
+
if (framework === "vue") {
|
|
44
|
+
const hasVueTsc = hasPackageInstalled("vue-tsc", cwd);
|
|
45
|
+
if (hasVueTsc) return "vue-tsc";
|
|
46
|
+
console.warn(
|
|
47
|
+
"\u26A0\uFE0F Vue project detected but vue-tsc not found.\n Install with: npm install -D vue-tsc\n Falling back to tsgo/tsc (won't check .vue files)"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const hasTsgo = hasPackageInstalled("@typescript/native-preview", cwd);
|
|
51
|
+
if (hasTsgo) {
|
|
52
|
+
return "tsgo";
|
|
53
|
+
}
|
|
54
|
+
return "tsc";
|
|
55
|
+
}
|
|
56
|
+
throw new ConfigError(`Unknown checker preference: "${preference}"`, {
|
|
57
|
+
received: preference,
|
|
58
|
+
validOptions: ["auto", "modern", "legacy"]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function hasPackageInstalled(packageName, cwd) {
|
|
62
|
+
try {
|
|
63
|
+
const packagePath = join(cwd, "node_modules", packageName, "package.json");
|
|
64
|
+
return existsSync(packagePath);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
+
console.warn(`Warning: Error checking for ${packageName}: ${message}`);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function getTypeCheckCommand(checker, options = {}) {
|
|
72
|
+
const { watch = false, noEmit = true, project = "." } = options;
|
|
73
|
+
const baseCmd = checker;
|
|
74
|
+
const flags = [];
|
|
75
|
+
if (noEmit) flags.push("--noEmit");
|
|
76
|
+
if (watch) flags.push("--watch");
|
|
77
|
+
if (project !== ".") flags.push(`-p ${project}`);
|
|
78
|
+
return `${baseCmd} ${flags.join(" ")}`.trim();
|
|
79
|
+
}
|
|
80
|
+
var init_checker_detection = __esm({
|
|
81
|
+
"src/tools/typescript/checker-detection.ts"() {
|
|
82
|
+
init_types();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// src/tools/typescript/presets/base.ts
|
|
87
|
+
var basePreset, base_default;
|
|
88
|
+
var init_base = __esm({
|
|
89
|
+
"src/tools/typescript/presets/base.ts"() {
|
|
90
|
+
basePreset = {
|
|
91
|
+
compilerOptions: {
|
|
92
|
+
// Language and Environment
|
|
93
|
+
target: "ES2022",
|
|
94
|
+
lib: ["ES2022"],
|
|
95
|
+
// Modules
|
|
96
|
+
module: "ESNext",
|
|
97
|
+
moduleResolution: "Bundler",
|
|
98
|
+
resolveJsonModule: true,
|
|
99
|
+
// Emit
|
|
100
|
+
declaration: true,
|
|
101
|
+
declarationMap: true,
|
|
102
|
+
sourceMap: true,
|
|
103
|
+
removeComments: false,
|
|
104
|
+
// Interop Constraints
|
|
105
|
+
esModuleInterop: true,
|
|
106
|
+
allowSyntheticDefaultImports: true,
|
|
107
|
+
forceConsistentCasingInFileNames: true,
|
|
108
|
+
isolatedModules: true,
|
|
109
|
+
// Type Checking (Strict Mode)
|
|
110
|
+
strict: true,
|
|
111
|
+
noImplicitAny: true,
|
|
112
|
+
strictNullChecks: true,
|
|
113
|
+
strictFunctionTypes: true,
|
|
114
|
+
strictBindCallApply: true,
|
|
115
|
+
strictPropertyInitialization: true,
|
|
116
|
+
noImplicitThis: true,
|
|
117
|
+
alwaysStrict: true,
|
|
118
|
+
// Additional Checks
|
|
119
|
+
noUnusedLocals: true,
|
|
120
|
+
noUnusedParameters: true,
|
|
121
|
+
noImplicitReturns: true,
|
|
122
|
+
noFallthroughCasesInSwitch: true,
|
|
123
|
+
noUncheckedIndexedAccess: true,
|
|
124
|
+
noImplicitOverride: true,
|
|
125
|
+
noPropertyAccessFromIndexSignature: false,
|
|
126
|
+
// Completeness
|
|
127
|
+
skipLibCheck: true,
|
|
128
|
+
// Faster, skip checking .d.ts files
|
|
129
|
+
// Advanced
|
|
130
|
+
allowUnusedLabels: false,
|
|
131
|
+
allowUnreachableCode: false
|
|
132
|
+
},
|
|
133
|
+
include: ["src/**/*"],
|
|
134
|
+
exclude: ["node_modules", "dist", "build", "out", "coverage", ".nyc_output"]
|
|
135
|
+
};
|
|
136
|
+
base_default = basePreset;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// src/tools/typescript/presets/environments/browser.ts
|
|
141
|
+
var browserPreset, browser_default;
|
|
142
|
+
var init_browser = __esm({
|
|
143
|
+
"src/tools/typescript/presets/environments/browser.ts"() {
|
|
144
|
+
browserPreset = {
|
|
145
|
+
compilerOptions: {
|
|
146
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"],
|
|
147
|
+
target: "ES2020"
|
|
148
|
+
// Good browser support
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
browser_default = browserPreset;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// src/tools/typescript/presets/environments/node.ts
|
|
156
|
+
var nodePreset, node_default;
|
|
157
|
+
var init_node = __esm({
|
|
158
|
+
"src/tools/typescript/presets/environments/node.ts"() {
|
|
159
|
+
nodePreset = {
|
|
160
|
+
compilerOptions: {
|
|
161
|
+
lib: ["ES2024"],
|
|
162
|
+
target: "ES2024",
|
|
163
|
+
module: "NodeNext",
|
|
164
|
+
moduleResolution: "NodeNext",
|
|
165
|
+
types: ["node"]
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
node_default = nodePreset;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// src/tools/typescript/presets/environments/universal.ts
|
|
173
|
+
var universalPreset, universal_default;
|
|
174
|
+
var init_universal = __esm({
|
|
175
|
+
"src/tools/typescript/presets/environments/universal.ts"() {
|
|
176
|
+
universalPreset = {
|
|
177
|
+
compilerOptions: {
|
|
178
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"],
|
|
179
|
+
target: "ES2022",
|
|
180
|
+
types: ["node"]
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
universal_default = universalPreset;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// src/tools/typescript/presets/frameworks/angular.ts
|
|
188
|
+
var angularPreset, angular_default;
|
|
189
|
+
var init_angular = __esm({
|
|
190
|
+
"src/tools/typescript/presets/frameworks/angular.ts"() {
|
|
191
|
+
angularPreset = {
|
|
192
|
+
compilerOptions: {
|
|
193
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"],
|
|
194
|
+
experimentalDecorators: true,
|
|
195
|
+
emitDecoratorMetadata: true
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
angular_default = angularPreset;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// src/tools/typescript/presets/frameworks/astro.ts
|
|
203
|
+
var astroPreset, astro_default;
|
|
204
|
+
var init_astro = __esm({
|
|
205
|
+
"src/tools/typescript/presets/frameworks/astro.ts"() {
|
|
206
|
+
astroPreset = {
|
|
207
|
+
compilerOptions: {
|
|
208
|
+
jsx: "react-jsx",
|
|
209
|
+
// Astro uses React-style JSX
|
|
210
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"],
|
|
211
|
+
types: ["astro/client"]
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
astro_default = astroPreset;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// src/tools/typescript/presets/frameworks/electron.ts
|
|
219
|
+
function createElectronPreset(renderer = "vue") {
|
|
220
|
+
const rendererExtensions = renderer === "vue" ? ["src/renderer/**/*.vue"] : [];
|
|
221
|
+
const root = {
|
|
222
|
+
files: [],
|
|
223
|
+
references: [{ path: "./tsconfig.node.json" }, { path: "./tsconfig.web.json" }]
|
|
224
|
+
};
|
|
225
|
+
const node = {
|
|
226
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
227
|
+
include: ["electron.vite.config.*", "package.json", "src/main/*", "src/preload/*"],
|
|
228
|
+
compilerOptions: {
|
|
229
|
+
composite: true,
|
|
230
|
+
target: "ES2024",
|
|
231
|
+
lib: ["ES2024", "ESNext"],
|
|
232
|
+
module: "NodeNext",
|
|
233
|
+
moduleResolution: "NodeNext",
|
|
234
|
+
types: ["electron-vite/node"],
|
|
235
|
+
baseUrl: ".",
|
|
236
|
+
paths: {
|
|
237
|
+
"@/*": ["src/*"],
|
|
238
|
+
"@main/*": ["src/main/*"],
|
|
239
|
+
"@preload/*": ["src/preload/*"]
|
|
240
|
+
},
|
|
241
|
+
resolveJsonModule: true
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
const web = {
|
|
245
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
246
|
+
include: [
|
|
247
|
+
"src/renderer/env.d.ts",
|
|
248
|
+
"src/renderer/**/*",
|
|
249
|
+
...rendererExtensions,
|
|
250
|
+
"src/preload/*.d.ts",
|
|
251
|
+
"package.json"
|
|
252
|
+
],
|
|
253
|
+
compilerOptions: {
|
|
254
|
+
composite: true,
|
|
255
|
+
target: "ES2024",
|
|
256
|
+
lib: ["ES2024", "ESNext", "DOM", "DOM.Iterable"],
|
|
257
|
+
baseUrl: ".",
|
|
258
|
+
paths: {
|
|
259
|
+
"@/*": ["src/*"],
|
|
260
|
+
"@renderer/*": ["src/renderer/*"],
|
|
261
|
+
"@main/*": ["src/main/*"],
|
|
262
|
+
"@preload/*": ["src/preload/*"]
|
|
263
|
+
},
|
|
264
|
+
strict: true,
|
|
265
|
+
noUnusedParameters: true,
|
|
266
|
+
noFallthroughCasesInSwitch: true,
|
|
267
|
+
noUncheckedIndexedAccess: true
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
const tests = {
|
|
271
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
272
|
+
include: ["tests/**/*", "src/renderer/**/*.vue", "src/renderer/env.d.ts"],
|
|
273
|
+
compilerOptions: {
|
|
274
|
+
composite: true,
|
|
275
|
+
baseUrl: ".",
|
|
276
|
+
paths: {
|
|
277
|
+
"@/*": ["src/*"],
|
|
278
|
+
"@renderer/*": ["src/renderer/*"],
|
|
279
|
+
"@main/*": ["src/main/*"],
|
|
280
|
+
"@preload/*": ["src/preload/*"],
|
|
281
|
+
"@tests/*": ["tests/*"],
|
|
282
|
+
"@unit/*": ["tests/unit/*"],
|
|
283
|
+
"@integration/*": ["tests/integration/*"],
|
|
284
|
+
"@fixtures/*": ["tests/fixtures/*"],
|
|
285
|
+
"@setup/*": ["tests/setup/*"]
|
|
286
|
+
},
|
|
287
|
+
types: ["vitest/globals", "@playwright/test"],
|
|
288
|
+
strict: false
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
return { root, node, web, tests };
|
|
292
|
+
}
|
|
293
|
+
var init_electron = __esm({
|
|
294
|
+
"src/tools/typescript/presets/frameworks/electron.ts"() {
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// src/tools/typescript/presets/frameworks/node.ts
|
|
299
|
+
var nodePreset2, node_default2;
|
|
300
|
+
var init_node2 = __esm({
|
|
301
|
+
"src/tools/typescript/presets/frameworks/node.ts"() {
|
|
302
|
+
nodePreset2 = {
|
|
303
|
+
compilerOptions: {
|
|
304
|
+
lib: ["ES2022"],
|
|
305
|
+
module: "NodeNext",
|
|
306
|
+
moduleResolution: "NodeNext",
|
|
307
|
+
types: ["node"]
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
node_default2 = nodePreset2;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// src/tools/typescript/presets/frameworks/react.ts
|
|
315
|
+
var reactPreset, react_default;
|
|
316
|
+
var init_react = __esm({
|
|
317
|
+
"src/tools/typescript/presets/frameworks/react.ts"() {
|
|
318
|
+
reactPreset = {
|
|
319
|
+
compilerOptions: {
|
|
320
|
+
jsx: "react-jsx",
|
|
321
|
+
// Modern React 17+ automatic runtime
|
|
322
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"]
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
react_default = reactPreset;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// src/tools/typescript/presets/frameworks/solid.ts
|
|
330
|
+
var solidPreset, solid_default;
|
|
331
|
+
var init_solid = __esm({
|
|
332
|
+
"src/tools/typescript/presets/frameworks/solid.ts"() {
|
|
333
|
+
solidPreset = {
|
|
334
|
+
compilerOptions: {
|
|
335
|
+
jsx: "preserve",
|
|
336
|
+
// Solid uses its own JSX transform
|
|
337
|
+
jsxImportSource: "solid-js",
|
|
338
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"]
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
solid_default = solidPreset;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// src/tools/typescript/presets/frameworks/svelte.ts
|
|
346
|
+
var sveltePreset, svelte_default;
|
|
347
|
+
var init_svelte = __esm({
|
|
348
|
+
"src/tools/typescript/presets/frameworks/svelte.ts"() {
|
|
349
|
+
sveltePreset = {
|
|
350
|
+
compilerOptions: {
|
|
351
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"],
|
|
352
|
+
types: ["svelte"]
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
svelte_default = sveltePreset;
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// src/tools/typescript/presets/frameworks/vanilla.ts
|
|
360
|
+
var vanillaPreset, vanilla_default;
|
|
361
|
+
var init_vanilla = __esm({
|
|
362
|
+
"src/tools/typescript/presets/frameworks/vanilla.ts"() {
|
|
363
|
+
vanillaPreset = {
|
|
364
|
+
compilerOptions: {
|
|
365
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"]
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
vanilla_default = vanillaPreset;
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// src/tools/typescript/presets/frameworks/vue.ts
|
|
373
|
+
var vuePreset, vue_default;
|
|
374
|
+
var init_vue = __esm({
|
|
375
|
+
"src/tools/typescript/presets/frameworks/vue.ts"() {
|
|
376
|
+
vuePreset = {
|
|
377
|
+
compilerOptions: {
|
|
378
|
+
jsx: "preserve",
|
|
379
|
+
// Vue compiler handles JSX transformation
|
|
380
|
+
jsxImportSource: "vue",
|
|
381
|
+
lib: ["ES2022", "DOM", "DOM.Iterable"],
|
|
382
|
+
types: ["vite/client"]
|
|
383
|
+
// Common for Vue + Vite projects
|
|
384
|
+
},
|
|
385
|
+
// Vue-specific options (for vue-tsc)
|
|
386
|
+
vueCompilerOptions: {
|
|
387
|
+
extensions: [".vue"],
|
|
388
|
+
vitePressExtensions: [".md"]
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
vue_default = vuePreset;
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
function readPackageJson(cwd) {
|
|
395
|
+
const packagePath = join(cwd, "package.json");
|
|
396
|
+
if (!existsSync(packagePath)) {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
const content = readFileSync(packagePath, "utf8");
|
|
401
|
+
return JSON.parse(content);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
404
|
+
console.warn(`Warning: Failed to read package.json: ${message}`);
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function getAllDependencies(pkg) {
|
|
409
|
+
if (!pkg) {
|
|
410
|
+
return {};
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
...pkg.dependencies,
|
|
414
|
+
...pkg.devDependencies
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
var init_package_reader = __esm({
|
|
418
|
+
"src/core/package-reader.ts"() {
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
function detectReactMetaFramework(deps) {
|
|
422
|
+
return !!(deps.next || deps["@next/core"] || deps.remix || deps["@remix-run/react"] || deps["@remix-run/node"] || deps.gatsby || deps["gatsby-link"]);
|
|
423
|
+
}
|
|
424
|
+
function detectVueMetaFramework(deps) {
|
|
425
|
+
return !!(deps.nuxt || deps["nuxt3"]);
|
|
426
|
+
}
|
|
427
|
+
function detectSvelteMetaFramework(deps) {
|
|
428
|
+
return !!deps["@sveltejs/kit"];
|
|
429
|
+
}
|
|
430
|
+
function detectBaseFramework(deps) {
|
|
431
|
+
if (deps.react || deps["react-dom"]) return "react";
|
|
432
|
+
if (deps.vue || deps["@vue/runtime-core"] || deps["vue-router"] || deps.pinia) return "vue";
|
|
433
|
+
if (deps["@angular/core"]) return "angular";
|
|
434
|
+
if (deps.svelte) return "svelte";
|
|
435
|
+
if (deps["solid-js"]) return "solid";
|
|
436
|
+
if (deps.astro) return "astro";
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
function isNodeBackend(pkg, deps, cwd) {
|
|
440
|
+
if (pkg.type !== "module") return false;
|
|
441
|
+
const hasNodeFramework = !!(deps.express || deps.fastify || deps.koa || deps["@hapi/hapi"]);
|
|
442
|
+
const hasServerFiles = existsSync(join(cwd, "server.js")) || existsSync(join(cwd, "app.js")) || existsSync(join(cwd, "index.js")) && existsSync(join(cwd, "routes"));
|
|
443
|
+
return hasNodeFramework || hasServerFiles;
|
|
444
|
+
}
|
|
445
|
+
function detectFramework(cwd = process.cwd()) {
|
|
446
|
+
const pkg = readPackageJson(cwd);
|
|
447
|
+
if (!pkg) {
|
|
448
|
+
console.warn("Could not find package.json, defaulting to vanilla JavaScript");
|
|
449
|
+
return "vanilla";
|
|
450
|
+
}
|
|
451
|
+
const deps = getAllDependencies(pkg);
|
|
452
|
+
if (detectReactMetaFramework(deps)) return "react";
|
|
453
|
+
if (detectVueMetaFramework(deps)) return "vue";
|
|
454
|
+
if (detectSvelteMetaFramework(deps)) return "svelte";
|
|
455
|
+
const baseFramework = detectBaseFramework(deps);
|
|
456
|
+
if (baseFramework) return baseFramework;
|
|
457
|
+
if (isNodeBackend(pkg, deps, cwd)) return "node";
|
|
458
|
+
return "vanilla";
|
|
459
|
+
}
|
|
460
|
+
function detectEnvironment(framework, cwd = process.cwd()) {
|
|
461
|
+
if (framework === "node") {
|
|
462
|
+
return "node";
|
|
463
|
+
}
|
|
464
|
+
if (["react", "vue", "svelte", "solid", "angular"].includes(framework)) {
|
|
465
|
+
return "browser";
|
|
466
|
+
}
|
|
467
|
+
if (framework === "astro") {
|
|
468
|
+
return "universal";
|
|
469
|
+
}
|
|
470
|
+
const hasServerCode = existsSync(join(cwd, "server")) || existsSync(join(cwd, "api")) || existsSync(join(cwd, "backend"));
|
|
471
|
+
if (hasServerCode) {
|
|
472
|
+
return "universal";
|
|
473
|
+
}
|
|
474
|
+
return "browser";
|
|
475
|
+
}
|
|
476
|
+
function detectTypeScript(cwd = process.cwd()) {
|
|
477
|
+
if (existsSync(join(cwd, "tsconfig.json"))) {
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
const pkg = readPackageJson(cwd);
|
|
481
|
+
if (!pkg) return false;
|
|
482
|
+
return !!(pkg.dependencies?.typescript || pkg.devDependencies?.typescript);
|
|
483
|
+
}
|
|
484
|
+
function detectGitProvider(cwd = process.cwd()) {
|
|
485
|
+
const pkg = readPackageJson(cwd);
|
|
486
|
+
if (pkg?.repository) {
|
|
487
|
+
const repoUrl = typeof pkg.repository === "string" ? pkg.repository : pkg.repository.url || "";
|
|
488
|
+
if (repoUrl.includes("gitlab.com")) return "gitlab";
|
|
489
|
+
if (repoUrl.includes("github.com")) return "github";
|
|
490
|
+
if (repoUrl.includes("bitbucket.org")) return "bitbucket";
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
try {
|
|
494
|
+
const remoteUrl = execSync("git remote get-url origin", {
|
|
495
|
+
cwd,
|
|
496
|
+
encoding: "utf8",
|
|
497
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
498
|
+
}).trim();
|
|
499
|
+
if (remoteUrl.includes("gitlab.com")) return "gitlab";
|
|
500
|
+
if (remoteUrl.includes("github.com")) return "github";
|
|
501
|
+
if (remoteUrl.includes("bitbucket.org")) return "bitbucket";
|
|
502
|
+
} catch (error) {
|
|
503
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
504
|
+
console.warn(`Warning: Could not detect git provider from remote: ${message}`);
|
|
505
|
+
}
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
function detectCssType(cwd = process.cwd()) {
|
|
509
|
+
const pkg = readPackageJson(cwd);
|
|
510
|
+
const results = {
|
|
511
|
+
preprocessor: null,
|
|
512
|
+
// 'scss', 'sass', 'less', null
|
|
513
|
+
tailwind: false,
|
|
514
|
+
modules: false,
|
|
515
|
+
postcss: false
|
|
516
|
+
};
|
|
517
|
+
const hasSass = pkg?.dependencies?.sass || pkg?.devDependencies?.sass || pkg?.dependencies?.["node-sass"] || pkg?.devDependencies?.["node-sass"] || pkg?.dependencies?.["sass-embedded"] || pkg?.devDependencies?.["sass-embedded"];
|
|
518
|
+
if (hasSass) {
|
|
519
|
+
results.preprocessor = "scss";
|
|
520
|
+
}
|
|
521
|
+
const hasLess = pkg?.dependencies?.less || pkg?.devDependencies?.less;
|
|
522
|
+
if (hasLess && !hasSass) {
|
|
523
|
+
results.preprocessor = "less";
|
|
524
|
+
}
|
|
525
|
+
const hasTailwind = pkg?.dependencies?.tailwindcss || pkg?.devDependencies?.tailwindcss;
|
|
526
|
+
if (hasTailwind) {
|
|
527
|
+
results.tailwind = existsSync(join(cwd, "tailwind.config.js")) || existsSync(join(cwd, "tailwind.config.ts")) || existsSync(join(cwd, "tailwind.config.mjs")) || existsSync(join(cwd, "tailwind.config.cjs"));
|
|
528
|
+
}
|
|
529
|
+
results.postcss = existsSync(join(cwd, "postcss.config.js")) || existsSync(join(cwd, "postcss.config.cjs")) || existsSync(join(cwd, "postcss.config.mjs")) || existsSync(join(cwd, ".postcssrc")) || existsSync(join(cwd, ".postcssrc.json"));
|
|
530
|
+
return results;
|
|
531
|
+
}
|
|
532
|
+
function detectElectron(cwd = process.cwd()) {
|
|
533
|
+
const pkg = readPackageJson(cwd);
|
|
534
|
+
if (!pkg) return false;
|
|
535
|
+
const deps = getAllDependencies(pkg);
|
|
536
|
+
return !!(deps.electron || deps["@electron-toolkit/utils"] || deps["@electron-toolkit/preload"]);
|
|
537
|
+
}
|
|
538
|
+
function autoDetect(cwd = process.cwd()) {
|
|
539
|
+
const framework = detectFramework(cwd);
|
|
540
|
+
const environment = detectEnvironment(framework, cwd);
|
|
541
|
+
const typescript = detectTypeScript(cwd);
|
|
542
|
+
const gitProvider = detectGitProvider(cwd);
|
|
543
|
+
const cssType = detectCssType(cwd);
|
|
544
|
+
const electron = detectElectron(cwd);
|
|
545
|
+
return {
|
|
546
|
+
framework,
|
|
547
|
+
environment,
|
|
548
|
+
typescript,
|
|
549
|
+
gitProvider,
|
|
550
|
+
cssType,
|
|
551
|
+
electron
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
var init_detectors = __esm({
|
|
555
|
+
"src/core/detectors.ts"() {
|
|
556
|
+
init_package_reader();
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// src/tools/typescript/index.ts
|
|
561
|
+
var typescript_exports = {};
|
|
562
|
+
__export(typescript_exports, {
|
|
563
|
+
createTypescriptConfig: () => createTypescriptConfig,
|
|
564
|
+
default: () => typescript_default
|
|
565
|
+
});
|
|
566
|
+
async function createTypescriptConfig(options = {}) {
|
|
567
|
+
const {
|
|
568
|
+
framework: frameworkOption = "auto",
|
|
569
|
+
environment: environmentOption = "auto",
|
|
570
|
+
checker: checkerPreference = "auto",
|
|
571
|
+
strict = true,
|
|
572
|
+
electron: electronOption,
|
|
573
|
+
renderer: rendererOption,
|
|
574
|
+
compilerOptions: userCompilerOptions = {},
|
|
575
|
+
cwd = process.cwd()
|
|
576
|
+
} = options;
|
|
577
|
+
const detected = frameworkOption === "auto" || environmentOption === "auto" || electronOption === void 0 ? autoDetect(cwd) : { framework: frameworkOption, environment: environmentOption, electron: electronOption };
|
|
578
|
+
const framework = frameworkOption === "auto" ? detected.framework : frameworkOption;
|
|
579
|
+
const environment = environmentOption === "auto" ? detected.environment : environmentOption;
|
|
580
|
+
const isElectron = electronOption !== void 0 ? electronOption : detected.electron;
|
|
581
|
+
if (isElectron) {
|
|
582
|
+
const renderer = rendererOption || framework;
|
|
583
|
+
if (!VALID_RENDERERS.includes(renderer)) {
|
|
584
|
+
throw new ConfigError(
|
|
585
|
+
`Invalid renderer option for Electron: "${renderer}". Must be one of: ${VALID_RENDERERS.join(", ")}`,
|
|
586
|
+
{
|
|
587
|
+
received: renderer,
|
|
588
|
+
validRenderers: VALID_RENDERERS
|
|
589
|
+
}
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
const checker2 = detectTypeChecker(
|
|
593
|
+
framework,
|
|
594
|
+
checkerPreference,
|
|
595
|
+
cwd
|
|
596
|
+
);
|
|
597
|
+
console.log(
|
|
598
|
+
`\u26A1 Electron TypeScript Config: ${renderer} renderer | Checker: ${checker2}${checker2 === "tsgo" ? " (10x faster!)" : ""}`
|
|
599
|
+
);
|
|
600
|
+
const configs = createElectronPreset(renderer);
|
|
601
|
+
return {
|
|
602
|
+
...configs,
|
|
603
|
+
_meta: {
|
|
604
|
+
framework: "electron",
|
|
605
|
+
renderer,
|
|
606
|
+
checker: checker2,
|
|
607
|
+
multiConfig: true,
|
|
608
|
+
experimental: checker2 === "tsgo",
|
|
609
|
+
generatedBy: "@dimensional-innovations/tool-config"
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
const checker = detectTypeChecker(
|
|
614
|
+
framework,
|
|
615
|
+
checkerPreference,
|
|
616
|
+
cwd
|
|
617
|
+
);
|
|
618
|
+
console.log(
|
|
619
|
+
`\u{1F50D} TypeScript Config: ${framework} | ${environment} | Checker: ${checker}${checker === "tsgo" ? " (10x faster!)" : ""}`
|
|
620
|
+
);
|
|
621
|
+
const config = loadPresets(framework, environment, strict);
|
|
622
|
+
if (userCompilerOptions && Object.keys(userCompilerOptions).length > 0) {
|
|
623
|
+
config.compilerOptions = {
|
|
624
|
+
...config.compilerOptions,
|
|
625
|
+
...userCompilerOptions
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
config._meta = {
|
|
629
|
+
framework,
|
|
630
|
+
environment,
|
|
631
|
+
checker,
|
|
632
|
+
experimental: checker === "tsgo",
|
|
633
|
+
generatedBy: "@dimensional-innovations/tool-config"
|
|
634
|
+
};
|
|
635
|
+
return config;
|
|
636
|
+
}
|
|
637
|
+
function loadPresets(framework, environment, strict) {
|
|
638
|
+
const config = structuredClone(base_default);
|
|
639
|
+
const envPreset = loadEnvironmentPreset(environment);
|
|
640
|
+
mergeConfig(config, envPreset);
|
|
641
|
+
const frameworkPreset = loadFrameworkPreset(framework);
|
|
642
|
+
mergeConfig(config, frameworkPreset);
|
|
643
|
+
if (!strict) {
|
|
644
|
+
config.compilerOptions = config.compilerOptions || {};
|
|
645
|
+
config.compilerOptions.strict = false;
|
|
646
|
+
config.compilerOptions.noImplicitAny = false;
|
|
647
|
+
}
|
|
648
|
+
return config;
|
|
649
|
+
}
|
|
650
|
+
function loadEnvironmentPreset(environment) {
|
|
651
|
+
switch (environment) {
|
|
652
|
+
case "browser":
|
|
653
|
+
return browser_default;
|
|
654
|
+
case "node":
|
|
655
|
+
return node_default;
|
|
656
|
+
case "universal":
|
|
657
|
+
return universal_default;
|
|
658
|
+
default:
|
|
659
|
+
return {};
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
function loadFrameworkPreset(framework) {
|
|
663
|
+
switch (framework) {
|
|
664
|
+
case "react":
|
|
665
|
+
return react_default;
|
|
666
|
+
case "vue":
|
|
667
|
+
return vue_default;
|
|
668
|
+
case "svelte":
|
|
669
|
+
return svelte_default;
|
|
670
|
+
case "solid":
|
|
671
|
+
return solid_default;
|
|
672
|
+
case "astro":
|
|
673
|
+
return astro_default;
|
|
674
|
+
case "angular":
|
|
675
|
+
return angular_default;
|
|
676
|
+
case "node":
|
|
677
|
+
return node_default2;
|
|
678
|
+
case "vanilla":
|
|
679
|
+
default:
|
|
680
|
+
return vanilla_default;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function mergeConfig(target, source) {
|
|
684
|
+
for (const key in source) {
|
|
685
|
+
const sourceKey = key;
|
|
686
|
+
if (key === "compilerOptions" && target.compilerOptions) {
|
|
687
|
+
Object.assign(target.compilerOptions, source.compilerOptions);
|
|
688
|
+
} else if (key === "include" && Array.isArray(source.include)) {
|
|
689
|
+
target.include = [.../* @__PURE__ */ new Set([...target.include || [], ...source.include])];
|
|
690
|
+
} else if (key === "exclude" && Array.isArray(source.exclude)) {
|
|
691
|
+
target.exclude = [.../* @__PURE__ */ new Set([...target.exclude || [], ...source.exclude])];
|
|
692
|
+
} else {
|
|
693
|
+
target[sourceKey] = source[sourceKey];
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
var VALID_RENDERERS, typescript_default;
|
|
698
|
+
var init_typescript = __esm({
|
|
699
|
+
"src/tools/typescript/index.ts"() {
|
|
700
|
+
init_checker_detection();
|
|
701
|
+
init_base();
|
|
702
|
+
init_browser();
|
|
703
|
+
init_node();
|
|
704
|
+
init_universal();
|
|
705
|
+
init_angular();
|
|
706
|
+
init_astro();
|
|
707
|
+
init_electron();
|
|
708
|
+
init_node2();
|
|
709
|
+
init_react();
|
|
710
|
+
init_solid();
|
|
711
|
+
init_svelte();
|
|
712
|
+
init_vanilla();
|
|
713
|
+
init_vue();
|
|
714
|
+
init_detectors();
|
|
715
|
+
init_types();
|
|
716
|
+
VALID_RENDERERS = [
|
|
717
|
+
"react",
|
|
718
|
+
"vue",
|
|
719
|
+
"svelte",
|
|
720
|
+
"solid",
|
|
721
|
+
"astro",
|
|
722
|
+
"angular",
|
|
723
|
+
"vanilla"
|
|
724
|
+
];
|
|
725
|
+
typescript_default = createTypescriptConfig;
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
// src/cli/formatting.ts
|
|
730
|
+
var formatting_exports = {};
|
|
731
|
+
__export(formatting_exports, {
|
|
732
|
+
BOX: () => BOX,
|
|
733
|
+
SYMBOLS: () => SYMBOLS,
|
|
734
|
+
colors: () => colors,
|
|
735
|
+
createBox: () => createBox,
|
|
736
|
+
createList: () => createList,
|
|
737
|
+
createProgress: () => createProgress,
|
|
738
|
+
createSeparator: () => createSeparator
|
|
739
|
+
});
|
|
740
|
+
function createBox(lines, title = "") {
|
|
741
|
+
const width = BOX.width;
|
|
742
|
+
const contentWidth = width - 4;
|
|
743
|
+
let top;
|
|
744
|
+
if (title) {
|
|
745
|
+
const titlePart = `\u2500 ${title} `;
|
|
746
|
+
const remaining = width - 2 - titlePart.length;
|
|
747
|
+
top = BOX.topLeft + titlePart + BOX.horizontal.repeat(remaining) + BOX.topRight;
|
|
748
|
+
} else {
|
|
749
|
+
top = BOX.topLeft + BOX.horizontal.repeat(width - 2) + BOX.topRight;
|
|
750
|
+
}
|
|
751
|
+
const content = lines.map((line) => {
|
|
752
|
+
const padded = line.slice(0, contentWidth).padEnd(contentWidth);
|
|
753
|
+
return `${BOX.vertical} ${padded} ${BOX.vertical}`;
|
|
754
|
+
});
|
|
755
|
+
const bottom = BOX.bottomLeft + BOX.horizontal.repeat(width - 2) + BOX.bottomRight;
|
|
756
|
+
return [top, ...content, bottom].join("\n");
|
|
757
|
+
}
|
|
758
|
+
function createSeparator() {
|
|
759
|
+
return BOX.separator.repeat(BOX.width);
|
|
760
|
+
}
|
|
761
|
+
function createList(items, bullet = "\u2022") {
|
|
762
|
+
return items.map((item) => ` ${bullet} ${item}`).join("\n");
|
|
763
|
+
}
|
|
764
|
+
function createProgress(current, total, label) {
|
|
765
|
+
return ` [${current}/${total}] ${label}`;
|
|
766
|
+
}
|
|
767
|
+
var BOX_WIDTH, BOX, SYMBOLS, colors;
|
|
768
|
+
var init_formatting = __esm({
|
|
769
|
+
"src/cli/formatting.ts"() {
|
|
770
|
+
BOX_WIDTH = 70;
|
|
771
|
+
BOX = {
|
|
772
|
+
topLeft: "\u250C",
|
|
773
|
+
topRight: "\u2510",
|
|
774
|
+
bottomLeft: "\u2514",
|
|
775
|
+
bottomRight: "\u2518",
|
|
776
|
+
vertical: "\u2502",
|
|
777
|
+
horizontal: "\u2500",
|
|
778
|
+
separator: "\u2501",
|
|
779
|
+
width: BOX_WIDTH
|
|
780
|
+
};
|
|
781
|
+
SYMBOLS = {
|
|
782
|
+
success: pc.green("\u2713"),
|
|
783
|
+
warning: pc.yellow("\u26A0"),
|
|
784
|
+
error: pc.red("\u2717"),
|
|
785
|
+
info: pc.blue("\u2139")
|
|
786
|
+
};
|
|
787
|
+
colors = {
|
|
788
|
+
success: pc.green,
|
|
789
|
+
warning: pc.yellow,
|
|
790
|
+
error: pc.red,
|
|
791
|
+
info: pc.blue,
|
|
792
|
+
dim: pc.dim,
|
|
793
|
+
bold: pc.bold,
|
|
794
|
+
cyan: pc.cyan
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
// src/cli/handlers/eslint.ts
|
|
800
|
+
var eslint_exports = {};
|
|
801
|
+
__export(eslint_exports, {
|
|
802
|
+
generateConfigContent: () => generateConfigContent,
|
|
803
|
+
getConfigFilename: () => getConfigFilename,
|
|
804
|
+
getScripts: () => getScripts,
|
|
805
|
+
writeConfig: () => writeConfig
|
|
806
|
+
});
|
|
807
|
+
function getConfigFilename() {
|
|
808
|
+
return "eslint.config.js";
|
|
809
|
+
}
|
|
810
|
+
function generateConfigContent(detected) {
|
|
811
|
+
return `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
812
|
+
|
|
813
|
+
export default await createConfig('eslint', {
|
|
814
|
+
// \u2500\u2500 Detected Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
815
|
+
framework: '${detected.framework}',
|
|
816
|
+
environment: '${detected.environment}',
|
|
817
|
+
typescript: ${detected.typescript},
|
|
818
|
+
|
|
819
|
+
// \u2500\u2500 Customization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
820
|
+
// ignorePaths: [],
|
|
821
|
+
// rules: {},
|
|
822
|
+
})
|
|
823
|
+
`;
|
|
824
|
+
}
|
|
825
|
+
function getScripts(_detected) {
|
|
826
|
+
return {
|
|
827
|
+
lint: "eslint .",
|
|
828
|
+
"lint:fix": "eslint --fix ."
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function writeConfig(cwd, detected, dryRun = false) {
|
|
832
|
+
const filename = getConfigFilename();
|
|
833
|
+
const filepath = join(cwd, filename);
|
|
834
|
+
const content = generateConfigContent(detected);
|
|
835
|
+
if (existsSync(filepath)) {
|
|
836
|
+
console.log(` \u26A0\uFE0F ${filename} already exists - skipping`);
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
if (dryRun) {
|
|
840
|
+
console.log(` \u{1F4C4} Would create: ${filename}`);
|
|
841
|
+
return true;
|
|
842
|
+
}
|
|
843
|
+
try {
|
|
844
|
+
writeFileSync(filepath, content, "utf8");
|
|
845
|
+
console.log(` \u2705 Created: ${filename}`);
|
|
846
|
+
return true;
|
|
847
|
+
} catch (error) {
|
|
848
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
849
|
+
console.error(` \u274C Failed to create ${filename}:`, errorMessage);
|
|
850
|
+
return false;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// src/cli/handlers/prettier.ts
|
|
855
|
+
var prettier_exports = {};
|
|
856
|
+
__export(prettier_exports, {
|
|
857
|
+
generateConfigContent: () => generateConfigContent2,
|
|
858
|
+
getConfigFilename: () => getConfigFilename2,
|
|
859
|
+
getScripts: () => getScripts2,
|
|
860
|
+
writeConfig: () => writeConfig2
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
// src/core/ignore-patterns.ts
|
|
864
|
+
var COMMON_IGNORE_DIRS = [
|
|
865
|
+
"node_modules",
|
|
866
|
+
"dist",
|
|
867
|
+
"build",
|
|
868
|
+
"out",
|
|
869
|
+
"coverage",
|
|
870
|
+
".nyc_output"
|
|
871
|
+
];
|
|
872
|
+
var FRAMEWORK_BUILD_DIRS = [
|
|
873
|
+
".next",
|
|
874
|
+
// Next.js
|
|
875
|
+
".nuxt",
|
|
876
|
+
// Nuxt
|
|
877
|
+
".output",
|
|
878
|
+
// Nitro/Nuxt3
|
|
879
|
+
".vercel",
|
|
880
|
+
// Vercel
|
|
881
|
+
".netlify",
|
|
882
|
+
// Netlify
|
|
883
|
+
".cache",
|
|
884
|
+
// Gatsby/Parcel
|
|
885
|
+
".parcel-cache",
|
|
886
|
+
// Parcel
|
|
887
|
+
".turbo",
|
|
888
|
+
// Turborepo
|
|
889
|
+
".vite",
|
|
890
|
+
// Vite
|
|
891
|
+
".vitepress",
|
|
892
|
+
// VitePress
|
|
893
|
+
".svelte-kit"
|
|
894
|
+
// SvelteKit
|
|
895
|
+
];
|
|
896
|
+
var GENERATED_FILES = [
|
|
897
|
+
"package-lock.json",
|
|
898
|
+
"pnpm-lock.yaml",
|
|
899
|
+
"yarn.lock",
|
|
900
|
+
"bun.lockb",
|
|
901
|
+
"CHANGELOG.md"
|
|
902
|
+
];
|
|
903
|
+
function getPrettierIgnoreContent() {
|
|
904
|
+
return `# Dependencies
|
|
905
|
+
node_modules/
|
|
906
|
+
.pnp/
|
|
907
|
+
.pnp.js
|
|
908
|
+
|
|
909
|
+
# Build outputs
|
|
910
|
+
${COMMON_IGNORE_DIRS.filter((dir) => dir !== "node_modules" && dir !== "coverage").map((dir) => `${dir}/`).join("\n")}
|
|
911
|
+
${FRAMEWORK_BUILD_DIRS.map((dir) => `${dir}/`).join("\n")}
|
|
912
|
+
|
|
913
|
+
# Coverage
|
|
914
|
+
coverage/
|
|
915
|
+
.nyc_output/
|
|
916
|
+
*.lcov
|
|
917
|
+
|
|
918
|
+
# Lock files
|
|
919
|
+
${GENERATED_FILES.filter((f) => f.includes("lock") || f.includes(".lock")).join("\n")}
|
|
920
|
+
|
|
921
|
+
# Generated files
|
|
922
|
+
CHANGELOG.md
|
|
923
|
+
|
|
924
|
+
# Cache directories
|
|
925
|
+
.cache/
|
|
926
|
+
.parcel-cache/
|
|
927
|
+
.turbo/
|
|
928
|
+
.vite/
|
|
929
|
+
|
|
930
|
+
# Environment files (may contain secrets)
|
|
931
|
+
.env
|
|
932
|
+
.env.local
|
|
933
|
+
.env.*.local
|
|
934
|
+
|
|
935
|
+
# IDE
|
|
936
|
+
.vscode/
|
|
937
|
+
.idea/
|
|
938
|
+
|
|
939
|
+
# OS files
|
|
940
|
+
.DS_Store
|
|
941
|
+
Thumbs.db
|
|
942
|
+
`;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// src/cli/handlers/prettier.ts
|
|
946
|
+
function getConfigFilename2() {
|
|
947
|
+
return "prettier.config.js";
|
|
948
|
+
}
|
|
949
|
+
function generateConfigContent2(detected) {
|
|
950
|
+
return `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
951
|
+
|
|
952
|
+
export default createConfig('prettier', {
|
|
953
|
+
// \u2500\u2500 Detected Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
954
|
+
framework: '${detected.framework}',
|
|
955
|
+
|
|
956
|
+
// \u2500\u2500 Customization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
957
|
+
// printWidth: 100,
|
|
958
|
+
// semi: false,
|
|
959
|
+
// singleQuote: true,
|
|
960
|
+
// overrides: [],
|
|
961
|
+
})
|
|
962
|
+
`;
|
|
963
|
+
}
|
|
964
|
+
function getScripts2(_detected) {
|
|
965
|
+
return {
|
|
966
|
+
"prettier:fix": "prettier --write .",
|
|
967
|
+
prettier: "prettier --check ."
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function writeConfig2(cwd, detected, dryRun = false) {
|
|
971
|
+
const filename = getConfigFilename2();
|
|
972
|
+
const filepath = join(cwd, filename);
|
|
973
|
+
const content = generateConfigContent2(detected);
|
|
974
|
+
if (existsSync(filepath)) {
|
|
975
|
+
console.log(` \u26A0\uFE0F ${filename} already exists - skipping`);
|
|
976
|
+
return false;
|
|
977
|
+
}
|
|
978
|
+
if (dryRun) {
|
|
979
|
+
console.log(` \u{1F4C4} Would create: ${filename}`);
|
|
980
|
+
const ignoreFile = ".prettierignore";
|
|
981
|
+
const ignoreExists = existsSync(join(cwd, ignoreFile));
|
|
982
|
+
if (!ignoreExists) {
|
|
983
|
+
console.log(` \u{1F4C4} Would create: ${ignoreFile}`);
|
|
984
|
+
}
|
|
985
|
+
return true;
|
|
986
|
+
}
|
|
987
|
+
try {
|
|
988
|
+
writeFileSync(filepath, content, "utf8");
|
|
989
|
+
console.log(` \u2705 Created: ${filename}`);
|
|
990
|
+
const ignoreFile = ".prettierignore";
|
|
991
|
+
const ignorePath = join(cwd, ignoreFile);
|
|
992
|
+
if (!existsSync(ignorePath)) {
|
|
993
|
+
writeFileSync(ignorePath, getPrettierIgnoreContent(), "utf8");
|
|
994
|
+
console.log(` \u2705 Created: ${ignoreFile}`);
|
|
995
|
+
} else {
|
|
996
|
+
console.log(` \u26A0\uFE0F ${ignoreFile} already exists - skipping`);
|
|
997
|
+
}
|
|
998
|
+
return true;
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1001
|
+
console.error(` \u274C Failed to create ${filename}:`, errorMessage);
|
|
1002
|
+
return false;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// src/cli/handlers/semantic-release.ts
|
|
1007
|
+
var semantic_release_exports = {};
|
|
1008
|
+
__export(semantic_release_exports, {
|
|
1009
|
+
generateConfigContent: () => generateConfigContent3,
|
|
1010
|
+
getConfigFilename: () => getConfigFilename3,
|
|
1011
|
+
getScripts: () => getScripts3,
|
|
1012
|
+
writeConfig: () => writeConfig3
|
|
1013
|
+
});
|
|
1014
|
+
function getConfigFilename3() {
|
|
1015
|
+
return "release.config.js";
|
|
1016
|
+
}
|
|
1017
|
+
function generateConfigContent3(detected) {
|
|
1018
|
+
const gitProviderValue = detected.gitProvider === null ? "null" : `'${detected.gitProvider}'`;
|
|
1019
|
+
return `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
1020
|
+
|
|
1021
|
+
export default createConfig('semantic-release', {
|
|
1022
|
+
// \u2500\u2500 Detected Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1023
|
+
preset: 'default',
|
|
1024
|
+
gitProvider: ${gitProviderValue},
|
|
1025
|
+
|
|
1026
|
+
// \u2500\u2500 Customization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1027
|
+
// branches: [],
|
|
1028
|
+
// plugins: [],
|
|
1029
|
+
})
|
|
1030
|
+
`;
|
|
1031
|
+
}
|
|
1032
|
+
function getScripts3(_detected) {
|
|
1033
|
+
return {
|
|
1034
|
+
release: "semantic-release"
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
function writeConfig3(cwd, detected, dryRun = false) {
|
|
1038
|
+
const filename = getConfigFilename3();
|
|
1039
|
+
const filepath = join(cwd, filename);
|
|
1040
|
+
const content = generateConfigContent3(detected);
|
|
1041
|
+
if (existsSync(filepath)) {
|
|
1042
|
+
console.log(` \u26A0\uFE0F ${filename} already exists - skipping`);
|
|
1043
|
+
return false;
|
|
1044
|
+
}
|
|
1045
|
+
if (dryRun) {
|
|
1046
|
+
console.log(` \u{1F4C4} Would create: ${filename}`);
|
|
1047
|
+
return true;
|
|
1048
|
+
}
|
|
1049
|
+
try {
|
|
1050
|
+
writeFileSync(filepath, content, "utf8");
|
|
1051
|
+
console.log(` \u2705 Created: ${filename}`);
|
|
1052
|
+
return true;
|
|
1053
|
+
} catch (error) {
|
|
1054
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1055
|
+
console.error(` \u274C Failed to create ${filename}:`, errorMessage);
|
|
1056
|
+
return false;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// src/cli/handlers/stylelint.ts
|
|
1061
|
+
var stylelint_exports = {};
|
|
1062
|
+
__export(stylelint_exports, {
|
|
1063
|
+
generateConfigContent: () => generateConfigContent4,
|
|
1064
|
+
getConfigFilename: () => getConfigFilename4,
|
|
1065
|
+
getScripts: () => getScripts4,
|
|
1066
|
+
writeConfig: () => writeConfig4
|
|
1067
|
+
});
|
|
1068
|
+
function getConfigFilename4() {
|
|
1069
|
+
return "stylelint.config.js";
|
|
1070
|
+
}
|
|
1071
|
+
function generateConfigContent4(detected) {
|
|
1072
|
+
return `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
1073
|
+
|
|
1074
|
+
export default createConfig('stylelint', {
|
|
1075
|
+
// \u2500\u2500 Detected Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1076
|
+
framework: '${detected.framework}',
|
|
1077
|
+
|
|
1078
|
+
// \u2500\u2500 Customization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1079
|
+
// extends: [],
|
|
1080
|
+
// rules: {},
|
|
1081
|
+
// overrides: [],
|
|
1082
|
+
})
|
|
1083
|
+
`;
|
|
1084
|
+
}
|
|
1085
|
+
function getStylelintExtensions(framework, cssType) {
|
|
1086
|
+
const extensions = ["css"];
|
|
1087
|
+
if (cssType.preprocessor === "scss") {
|
|
1088
|
+
extensions.push("scss");
|
|
1089
|
+
} else if (cssType.preprocessor === "less") {
|
|
1090
|
+
extensions.push("less");
|
|
1091
|
+
}
|
|
1092
|
+
if (framework === "vue") extensions.push("vue");
|
|
1093
|
+
if (framework === "svelte") extensions.push("svelte");
|
|
1094
|
+
return extensions;
|
|
1095
|
+
}
|
|
1096
|
+
function getScripts4(detected) {
|
|
1097
|
+
const extensions = getStylelintExtensions(detected.framework, detected.cssType);
|
|
1098
|
+
const pattern = extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
|
|
1099
|
+
return {
|
|
1100
|
+
style: `stylelint "${pattern}" --allow-empty-input`,
|
|
1101
|
+
"style:fix": `stylelint "${pattern}" --fix --allow-empty-input`
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
function writeConfig4(cwd, detected, dryRun = false) {
|
|
1105
|
+
const filename = getConfigFilename4();
|
|
1106
|
+
const filepath = join(cwd, filename);
|
|
1107
|
+
const content = generateConfigContent4(detected);
|
|
1108
|
+
if (existsSync(filepath)) {
|
|
1109
|
+
console.log(` \u26A0\uFE0F ${filename} already exists - skipping`);
|
|
1110
|
+
return false;
|
|
1111
|
+
}
|
|
1112
|
+
if (dryRun) {
|
|
1113
|
+
console.log(` \u{1F4C4} Would create: ${filename}`);
|
|
1114
|
+
return true;
|
|
1115
|
+
}
|
|
1116
|
+
try {
|
|
1117
|
+
writeFileSync(filepath, content, "utf8");
|
|
1118
|
+
console.log(` \u2705 Created: ${filename}`);
|
|
1119
|
+
return true;
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1122
|
+
console.error(` \u274C Failed to create ${filename}:`, errorMessage);
|
|
1123
|
+
return false;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// src/cli/handlers/typescript.ts
|
|
1128
|
+
var typescript_exports2 = {};
|
|
1129
|
+
__export(typescript_exports2, {
|
|
1130
|
+
generateConfigContent: () => generateConfigContent5,
|
|
1131
|
+
getConfigFilename: () => getConfigFilename5,
|
|
1132
|
+
getScripts: () => getScripts5,
|
|
1133
|
+
writeConfig: () => writeConfig5
|
|
1134
|
+
});
|
|
1135
|
+
init_checker_detection();
|
|
1136
|
+
function getConfigFilename5() {
|
|
1137
|
+
return "tsconfig.json";
|
|
1138
|
+
}
|
|
1139
|
+
function generateConfigContent5(_detected) {
|
|
1140
|
+
return JSON.stringify(
|
|
1141
|
+
{
|
|
1142
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
1143
|
+
compilerOptions: {
|
|
1144
|
+
target: "ES2022",
|
|
1145
|
+
lib: ["ES2022"],
|
|
1146
|
+
module: "ESNext",
|
|
1147
|
+
moduleResolution: "Bundler",
|
|
1148
|
+
strict: true,
|
|
1149
|
+
esModuleInterop: true,
|
|
1150
|
+
skipLibCheck: true,
|
|
1151
|
+
forceConsistentCasingInFileNames: true,
|
|
1152
|
+
resolveJsonModule: true
|
|
1153
|
+
},
|
|
1154
|
+
include: ["src/**/*"],
|
|
1155
|
+
exclude: ["node_modules", "dist", "build", "out", "coverage"]
|
|
1156
|
+
},
|
|
1157
|
+
null,
|
|
1158
|
+
2
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
function getScripts5(detected) {
|
|
1162
|
+
if (detected.electron) {
|
|
1163
|
+
return {
|
|
1164
|
+
typecheck: "tsc --build",
|
|
1165
|
+
"typecheck:watch": "tsc --build --watch"
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
const checker = detectTypeChecker(detected.framework, "auto");
|
|
1169
|
+
const cmd = getTypeCheckCommand(checker);
|
|
1170
|
+
const watchCmd = getTypeCheckCommand(checker, { watch: true });
|
|
1171
|
+
return {
|
|
1172
|
+
typecheck: cmd,
|
|
1173
|
+
"typecheck:watch": watchCmd
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
async function writeElectronConfigs(detected, cwd, dryRun = false) {
|
|
1177
|
+
const files = [
|
|
1178
|
+
{ name: "tsconfig.json", key: "root", desc: "root orchestrator" },
|
|
1179
|
+
{ name: "tsconfig.node.json", key: "node", desc: "main process" },
|
|
1180
|
+
{ name: "tsconfig.web.json", key: "web", desc: "renderer process" },
|
|
1181
|
+
{ name: "tsconfig.tests.json", key: "tests", desc: "test environment" }
|
|
1182
|
+
];
|
|
1183
|
+
if (dryRun) {
|
|
1184
|
+
for (const file of files) {
|
|
1185
|
+
console.log(` \u{1F4C4} Would create: ${file.name} (${file.desc})`);
|
|
1186
|
+
}
|
|
1187
|
+
return true;
|
|
1188
|
+
}
|
|
1189
|
+
try {
|
|
1190
|
+
const { createTypescriptConfig: createTypescriptConfig2 } = await Promise.resolve().then(() => (init_typescript(), typescript_exports));
|
|
1191
|
+
const configs = await createTypescriptConfig2({
|
|
1192
|
+
electron: true,
|
|
1193
|
+
renderer: detected.framework,
|
|
1194
|
+
cwd
|
|
1195
|
+
});
|
|
1196
|
+
let created = 0;
|
|
1197
|
+
for (const file of files) {
|
|
1198
|
+
const filepath = join(cwd, file.name);
|
|
1199
|
+
if (existsSync(filepath)) {
|
|
1200
|
+
console.log(` \u26A0\uFE0F ${file.name} already exists - skipping`);
|
|
1201
|
+
continue;
|
|
1202
|
+
}
|
|
1203
|
+
const content = JSON.stringify(configs[file.key], null, 2);
|
|
1204
|
+
writeFileSync(filepath, `${content}
|
|
1205
|
+
`, "utf8");
|
|
1206
|
+
console.log(` \u2705 Created: ${file.name} (${file.desc})`);
|
|
1207
|
+
created++;
|
|
1208
|
+
}
|
|
1209
|
+
return created > 0;
|
|
1210
|
+
} catch (error) {
|
|
1211
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1212
|
+
console.error(" \u274C Failed to create Electron configs:", errorMessage);
|
|
1213
|
+
return false;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
function writeConfig5(cwd, detected, dryRun = false) {
|
|
1217
|
+
if (!detected.typescript) {
|
|
1218
|
+
console.log(" \u26A0\uFE0F TypeScript not detected - skipping tsconfig generation");
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
if (detected.electron) {
|
|
1222
|
+
return writeElectronConfigs(detected, cwd, dryRun);
|
|
1223
|
+
}
|
|
1224
|
+
const filename = getConfigFilename5();
|
|
1225
|
+
const filepath = join(cwd, filename);
|
|
1226
|
+
const content = generateConfigContent5();
|
|
1227
|
+
if (existsSync(filepath)) {
|
|
1228
|
+
console.log(` \u26A0\uFE0F ${filename} already exists - skipping`);
|
|
1229
|
+
return false;
|
|
1230
|
+
}
|
|
1231
|
+
if (dryRun) {
|
|
1232
|
+
console.log(` \u{1F4C4} Would create: ${filename}`);
|
|
1233
|
+
return true;
|
|
1234
|
+
}
|
|
1235
|
+
try {
|
|
1236
|
+
writeFileSync(filepath, content, "utf8");
|
|
1237
|
+
console.log(` \u2705 Created: ${filename}`);
|
|
1238
|
+
console.log("");
|
|
1239
|
+
console.log(" To customize TypeScript options, add compilerOptions:");
|
|
1240
|
+
console.log("");
|
|
1241
|
+
console.log(" {");
|
|
1242
|
+
console.log(' "compilerOptions": {');
|
|
1243
|
+
console.log(' "baseUrl": "./src",');
|
|
1244
|
+
console.log(' "paths": { "@/*": ["*"] }');
|
|
1245
|
+
console.log(" }");
|
|
1246
|
+
console.log(" }");
|
|
1247
|
+
console.log("");
|
|
1248
|
+
return true;
|
|
1249
|
+
} catch (error) {
|
|
1250
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1251
|
+
console.error(` \u274C Failed to create ${filename}:`, errorMessage);
|
|
1252
|
+
return false;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
var CHECK_SCRIPT_MAP = {
|
|
1256
|
+
prettier: "prettier",
|
|
1257
|
+
stylelint: "style",
|
|
1258
|
+
eslint: "lint",
|
|
1259
|
+
typescript: "typecheck"
|
|
1260
|
+
};
|
|
1261
|
+
var CHECK_ORDER = ["prettier", "stylelint", "eslint", "typescript"];
|
|
1262
|
+
function generateCheckAllScript(installedTools) {
|
|
1263
|
+
const commands = CHECK_ORDER.filter((tool) => installedTools.includes(tool)).map((tool) => `yarn ${CHECK_SCRIPT_MAP[tool]}`).join(" && ");
|
|
1264
|
+
return commands || null;
|
|
1265
|
+
}
|
|
1266
|
+
function updatePackageJsonScripts(tools, getScriptsFn, context) {
|
|
1267
|
+
const { detected, cwd, dryRun = false } = context;
|
|
1268
|
+
const packageJsonPath = join(cwd, "package.json");
|
|
1269
|
+
if (!existsSync(packageJsonPath)) {
|
|
1270
|
+
console.log(" \u26A0\uFE0F No package.json found - skipping script injection");
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
try {
|
|
1274
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
1275
|
+
if (!packageJson.scripts) {
|
|
1276
|
+
packageJson.scripts = {};
|
|
1277
|
+
}
|
|
1278
|
+
const scriptsToAdd = {};
|
|
1279
|
+
for (const tool of tools) {
|
|
1280
|
+
const toolScripts = getScriptsFn(tool, detected);
|
|
1281
|
+
for (const [name, command] of Object.entries(toolScripts)) {
|
|
1282
|
+
if (!packageJson.scripts[name]) {
|
|
1283
|
+
scriptsToAdd[name] = command;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
const installedTools = [];
|
|
1288
|
+
if (packageJson.scripts.lint || scriptsToAdd.lint) installedTools.push("eslint");
|
|
1289
|
+
if (packageJson.scripts.prettier || scriptsToAdd.prettier) installedTools.push("prettier");
|
|
1290
|
+
if (packageJson.scripts.style || scriptsToAdd.style) installedTools.push("stylelint");
|
|
1291
|
+
if (packageJson.scripts.typecheck || scriptsToAdd.typecheck) installedTools.push("typescript");
|
|
1292
|
+
if (installedTools.length >= 2) {
|
|
1293
|
+
const checkAllCmd = generateCheckAllScript(installedTools);
|
|
1294
|
+
if (checkAllCmd) {
|
|
1295
|
+
const existingCheckAll = packageJson.scripts["check-all"];
|
|
1296
|
+
const isAutoGenerated = existingCheckAll && existingCheckAll.startsWith("yarn ") && existingCheckAll.includes(" && yarn ");
|
|
1297
|
+
if (!existingCheckAll || isAutoGenerated) {
|
|
1298
|
+
scriptsToAdd["check-all"] = checkAllCmd;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
if (Object.keys(scriptsToAdd).length === 0) {
|
|
1303
|
+
console.log(" \u2139\uFE0F All scripts already exist in package.json");
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
if (dryRun) {
|
|
1307
|
+
console.log(" \u{1F4DD} Would add scripts to package.json:");
|
|
1308
|
+
for (const [name, command] of Object.entries(scriptsToAdd)) {
|
|
1309
|
+
console.log(` "${name}": "${command}"`);
|
|
1310
|
+
}
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
Object.assign(packageJson.scripts, scriptsToAdd);
|
|
1314
|
+
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
1315
|
+
`, "utf8");
|
|
1316
|
+
console.log(" \u2705 Updated package.json with scripts:");
|
|
1317
|
+
for (const name of Object.keys(scriptsToAdd)) {
|
|
1318
|
+
console.log(` - ${name}`);
|
|
1319
|
+
}
|
|
1320
|
+
} catch (error) {
|
|
1321
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1322
|
+
console.error(" \u274C Failed to update package.json:", errorMessage);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
function removePackageJsonScripts(tools, getScriptsFn, context) {
|
|
1326
|
+
const { detected, cwd, dryRun = false } = context;
|
|
1327
|
+
const packageJsonPath = join(cwd, "package.json");
|
|
1328
|
+
if (!existsSync(packageJsonPath)) {
|
|
1329
|
+
console.log(" \u2139\uFE0F No package.json found - skipping script removal");
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
try {
|
|
1333
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
1334
|
+
if (!packageJson.scripts) {
|
|
1335
|
+
console.log(" \u2139\uFE0F No scripts section in package.json");
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
const scriptsToRemove = [];
|
|
1339
|
+
for (const tool of tools) {
|
|
1340
|
+
const toolScripts = getScriptsFn(tool, detected);
|
|
1341
|
+
for (const scriptName of Object.keys(toolScripts)) {
|
|
1342
|
+
const expectedCommand = toolScripts[scriptName];
|
|
1343
|
+
const actualCommand = packageJson.scripts[scriptName];
|
|
1344
|
+
if (actualCommand === expectedCommand) {
|
|
1345
|
+
scriptsToRemove.push(scriptName);
|
|
1346
|
+
} else if (actualCommand) {
|
|
1347
|
+
console.log(` \u26A0\uFE0F Script "${scriptName}" has been modified - skipping for safety`);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
const checkAllScript = packageJson.scripts["check-all"];
|
|
1352
|
+
if (checkAllScript) {
|
|
1353
|
+
const isAutoGenerated = checkAllScript.startsWith("yarn ") && checkAllScript.includes(" && yarn ");
|
|
1354
|
+
if (isAutoGenerated) {
|
|
1355
|
+
scriptsToRemove.push("check-all");
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
if (scriptsToRemove.length === 0) {
|
|
1359
|
+
console.log(" \u2139\uFE0F No scripts to remove from package.json");
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
if (dryRun) {
|
|
1363
|
+
console.log(" \u{1F4DD} Would remove scripts from package.json:");
|
|
1364
|
+
for (const name of scriptsToRemove) {
|
|
1365
|
+
console.log(` - ${name}`);
|
|
1366
|
+
}
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
for (const scriptName of scriptsToRemove) {
|
|
1370
|
+
delete packageJson.scripts[scriptName];
|
|
1371
|
+
}
|
|
1372
|
+
if (Object.keys(packageJson.scripts).length === 0) {
|
|
1373
|
+
delete packageJson.scripts;
|
|
1374
|
+
}
|
|
1375
|
+
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
1376
|
+
`, "utf8");
|
|
1377
|
+
console.log(" \u2705 Removed scripts from package.json:");
|
|
1378
|
+
for (const name of scriptsToRemove) {
|
|
1379
|
+
console.log(` - ${name}`);
|
|
1380
|
+
}
|
|
1381
|
+
} catch (error) {
|
|
1382
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1383
|
+
console.error(" \u274C Failed to update package.json:", errorMessage);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
// src/cli/ui.ts
|
|
1388
|
+
init_formatting();
|
|
1389
|
+
var VERSION = "0.0.0-development";
|
|
1390
|
+
function showHelp() {
|
|
1391
|
+
console.log(`
|
|
1392
|
+
\u{1F4E6} @dimensional-innovations/tool-config Setup Tool
|
|
1393
|
+
|
|
1394
|
+
Usage:
|
|
1395
|
+
setup-tool-config [tool] [options]
|
|
1396
|
+
|
|
1397
|
+
Tools:
|
|
1398
|
+
eslint Setup ESLint only
|
|
1399
|
+
prettier Setup Prettier only
|
|
1400
|
+
stylelint Setup Stylelint only
|
|
1401
|
+
typescript Setup TypeScript only
|
|
1402
|
+
semantic-release Setup semantic-release only
|
|
1403
|
+
|
|
1404
|
+
Options:
|
|
1405
|
+
--all, -a Setup all tools (non-interactive)
|
|
1406
|
+
--uninstall Remove tool configuration and scripts
|
|
1407
|
+
--dry-run, -d Preview changes without writing files
|
|
1408
|
+
--help, -h Show this help message
|
|
1409
|
+
--version, -v Show version number
|
|
1410
|
+
|
|
1411
|
+
Examples (Install):
|
|
1412
|
+
setup-tool-config # Interactive mode
|
|
1413
|
+
setup-tool-config eslint # Setup ESLint only
|
|
1414
|
+
setup-tool-config --all # Setup all tools
|
|
1415
|
+
setup-tool-config --dry-run # Preview without changes
|
|
1416
|
+
|
|
1417
|
+
Examples (Uninstall):
|
|
1418
|
+
setup-tool-config --uninstall # Interactive uninstall
|
|
1419
|
+
setup-tool-config --uninstall eslint # Remove ESLint only
|
|
1420
|
+
setup-tool-config --uninstall --all # Remove all detected tools
|
|
1421
|
+
setup-tool-config --uninstall --dry-run # Preview uninstall
|
|
1422
|
+
|
|
1423
|
+
For more information, visit:
|
|
1424
|
+
https://gitlab.com/dimensional-innovations/tool-config
|
|
1425
|
+
`);
|
|
1426
|
+
}
|
|
1427
|
+
function showVersion() {
|
|
1428
|
+
console.log(`@dimensional-innovations/tool-config v${VERSION}`);
|
|
1429
|
+
}
|
|
1430
|
+
function showBanner(detected) {
|
|
1431
|
+
console.log("");
|
|
1432
|
+
const welcome = [
|
|
1433
|
+
"\u{1F680} Welcome to @dimensional-innovations/tool-config",
|
|
1434
|
+
"",
|
|
1435
|
+
"Zero-config setup for ESLint, Prettier, Stylelint,",
|
|
1436
|
+
"TypeScript, and semantic-release.",
|
|
1437
|
+
"",
|
|
1438
|
+
"\u{1F4A1} Navigation: \u2191\u2193 to move, Space to select, Enter to continue"
|
|
1439
|
+
];
|
|
1440
|
+
console.log(createBox(welcome));
|
|
1441
|
+
console.log("");
|
|
1442
|
+
const detectedParts = [];
|
|
1443
|
+
if (detected.framework !== "vanilla") {
|
|
1444
|
+
detectedParts.push(detected.framework.charAt(0).toUpperCase() + detected.framework.slice(1));
|
|
1445
|
+
}
|
|
1446
|
+
if (detected.typescript) {
|
|
1447
|
+
detectedParts.push("TypeScript");
|
|
1448
|
+
}
|
|
1449
|
+
if (detected.environment) {
|
|
1450
|
+
detectedParts.push(detected.environment.charAt(0).toUpperCase() + detected.environment.slice(1));
|
|
1451
|
+
}
|
|
1452
|
+
const detectedStr = detectedParts.length > 0 ? detectedParts.join(" \u2022 ") : "JavaScript project";
|
|
1453
|
+
console.log(`\u{1F50D} Auto-detected: ${detectedStr}`);
|
|
1454
|
+
console.log("");
|
|
1455
|
+
console.log("\u{1F4A1} Recommended tools are pre-selected based on your project");
|
|
1456
|
+
console.log("");
|
|
1457
|
+
}
|
|
1458
|
+
function showSection(title) {
|
|
1459
|
+
console.log("");
|
|
1460
|
+
console.log(`${title}`);
|
|
1461
|
+
console.log("");
|
|
1462
|
+
}
|
|
1463
|
+
function showCompletion(dryRun, createdFiles = [], scripts = []) {
|
|
1464
|
+
console.log("");
|
|
1465
|
+
if (dryRun) {
|
|
1466
|
+
console.log(createSeparator());
|
|
1467
|
+
console.log("");
|
|
1468
|
+
const dryRunMsg = [
|
|
1469
|
+
`${SYMBOLS.info} DRY RUN MODE - Preview only, no files created`,
|
|
1470
|
+
"",
|
|
1471
|
+
"Run without --dry-run to create these files"
|
|
1472
|
+
];
|
|
1473
|
+
console.log(createBox(dryRunMsg));
|
|
1474
|
+
} else {
|
|
1475
|
+
console.log(createSeparator());
|
|
1476
|
+
console.log("");
|
|
1477
|
+
const completion = [colors.bold(colors.cyan("\u{1F389} All done! Your project is ready."))];
|
|
1478
|
+
if (createdFiles.length > 0) {
|
|
1479
|
+
completion.push("");
|
|
1480
|
+
completion.push(
|
|
1481
|
+
`\u{1F4C1} Created ${createdFiles.length} config file${createdFiles.length > 1 ? "s" : ""}:`
|
|
1482
|
+
);
|
|
1483
|
+
createdFiles.forEach((file) => {
|
|
1484
|
+
completion.push(` \u2022 ${file}`);
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1487
|
+
if (scripts.length > 0) {
|
|
1488
|
+
completion.push("");
|
|
1489
|
+
completion.push(`\u{1F4E6} Added ${scripts.length} npm script${scripts.length > 1 ? "s" : ""}:`);
|
|
1490
|
+
const checkAllIndex = scripts.indexOf("check-all");
|
|
1491
|
+
if (checkAllIndex !== -1) {
|
|
1492
|
+
completion.push(` \u2022 check-all \u2190 Run this to validate everything`);
|
|
1493
|
+
scripts.filter((s) => s !== "check-all").forEach((script) => {
|
|
1494
|
+
completion.push(` \u2022 ${script}`);
|
|
1495
|
+
});
|
|
1496
|
+
} else {
|
|
1497
|
+
scripts.forEach((script) => {
|
|
1498
|
+
completion.push(` \u2022 ${script}`);
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
completion.push("");
|
|
1503
|
+
completion.push("\u{1F680} Quick start:");
|
|
1504
|
+
if (scripts.includes("check-all")) {
|
|
1505
|
+
completion.push(" npm run check-all");
|
|
1506
|
+
} else if (scripts.length > 0) {
|
|
1507
|
+
completion.push(` npm run ${scripts[0]}`);
|
|
1508
|
+
}
|
|
1509
|
+
console.log(createBox(completion));
|
|
1510
|
+
}
|
|
1511
|
+
console.log("");
|
|
1512
|
+
}
|
|
1513
|
+
function showUninstallBanner(installedTools) {
|
|
1514
|
+
console.log("");
|
|
1515
|
+
console.log("\u{1F5D1}\uFE0F @dimensional-innovations/tool-config Uninstall");
|
|
1516
|
+
console.log("\u2501".repeat(50));
|
|
1517
|
+
console.log("");
|
|
1518
|
+
console.log("\u26A0\uFE0F WARNING: This will remove configuration files and scripts");
|
|
1519
|
+
console.log(" Make sure you have committed or backed up your changes first!");
|
|
1520
|
+
console.log("");
|
|
1521
|
+
if (installedTools.length > 0) {
|
|
1522
|
+
console.log("\u{1F4E6} Detected tools:");
|
|
1523
|
+
for (const tool of installedTools) {
|
|
1524
|
+
console.log(` - ${tool}`);
|
|
1525
|
+
}
|
|
1526
|
+
console.log("");
|
|
1527
|
+
} else {
|
|
1528
|
+
console.log("\u2139\uFE0F No tools detected");
|
|
1529
|
+
console.log("");
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
function showUninstallCompletion(dryRun, removedCount) {
|
|
1533
|
+
console.log("");
|
|
1534
|
+
if (dryRun) {
|
|
1535
|
+
console.log(`${SYMBOLS.info} Dry run mode - no files were modified`);
|
|
1536
|
+
console.log(" Run without --dry-run to apply changes");
|
|
1537
|
+
} else if (removedCount > 0) {
|
|
1538
|
+
console.log(`${SYMBOLS.success} Uninstall complete!`);
|
|
1539
|
+
console.log(` Removed ${removedCount} file(s) and their associated scripts`);
|
|
1540
|
+
} else {
|
|
1541
|
+
console.log(`${SYMBOLS.info} Nothing was removed`);
|
|
1542
|
+
}
|
|
1543
|
+
console.log("");
|
|
1544
|
+
}
|
|
1545
|
+
function detectInstalledTools(cwd) {
|
|
1546
|
+
const toolFiles = {
|
|
1547
|
+
eslint: "eslint.config.js",
|
|
1548
|
+
prettier: "prettier.config.js",
|
|
1549
|
+
stylelint: "stylelint.config.js",
|
|
1550
|
+
typescript: "tsconfig.json",
|
|
1551
|
+
"semantic-release": "release.config.js"
|
|
1552
|
+
};
|
|
1553
|
+
const installed = [];
|
|
1554
|
+
for (const [tool, filename] of Object.entries(toolFiles)) {
|
|
1555
|
+
if (existsSync(join(cwd, filename))) {
|
|
1556
|
+
installed.push(tool);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
return installed;
|
|
1560
|
+
}
|
|
1561
|
+
function contentMatches(filepath, expectedContent) {
|
|
1562
|
+
if (!existsSync(filepath)) {
|
|
1563
|
+
return false;
|
|
1564
|
+
}
|
|
1565
|
+
try {
|
|
1566
|
+
const actualContent = readFileSync(filepath, "utf8");
|
|
1567
|
+
return actualContent.trim() === expectedContent.trim();
|
|
1568
|
+
} catch {
|
|
1569
|
+
return false;
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
function uninstallTool(_tool, handler, detected, cwd, dryRun = false) {
|
|
1573
|
+
const filename = handler.getConfigFilename();
|
|
1574
|
+
const filepath = join(cwd, filename);
|
|
1575
|
+
if (!existsSync(filepath)) {
|
|
1576
|
+
console.log(` \u2139\uFE0F ${filename} not found - already uninstalled`);
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
const expectedContent = handler.generateConfigContent(detected);
|
|
1580
|
+
const isUnmodified = contentMatches(filepath, expectedContent);
|
|
1581
|
+
if (!isUnmodified) {
|
|
1582
|
+
console.log(` \u26A0\uFE0F ${filename} has been modified - skipping for safety`);
|
|
1583
|
+
console.log(" Remove manually if you want to delete it");
|
|
1584
|
+
return false;
|
|
1585
|
+
}
|
|
1586
|
+
if (dryRun) {
|
|
1587
|
+
console.log(` \u{1F5D1}\uFE0F Would remove: ${filename}`);
|
|
1588
|
+
return true;
|
|
1589
|
+
}
|
|
1590
|
+
try {
|
|
1591
|
+
rmSync(filepath);
|
|
1592
|
+
console.log(` \u2705 Removed: ${filename}`);
|
|
1593
|
+
return true;
|
|
1594
|
+
} catch (error) {
|
|
1595
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1596
|
+
console.error(` \u274C Failed to remove ${filename}:`, errorMessage);
|
|
1597
|
+
return false;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
// src/cli/validators.ts
|
|
1602
|
+
var VALID_TOOLS = [
|
|
1603
|
+
"eslint",
|
|
1604
|
+
"prettier",
|
|
1605
|
+
"stylelint",
|
|
1606
|
+
"typescript",
|
|
1607
|
+
"semantic-release"
|
|
1608
|
+
];
|
|
1609
|
+
function validateTool(tool) {
|
|
1610
|
+
if (!VALID_TOOLS.includes(tool)) {
|
|
1611
|
+
throw new Error(`Unknown tool: ${tool}. Valid tools: ${VALID_TOOLS.join(", ")}`);
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
// src/cli/index.ts
|
|
1616
|
+
init_detectors();
|
|
1617
|
+
var TOOL_HANDLERS = {
|
|
1618
|
+
eslint: eslint_exports,
|
|
1619
|
+
prettier: prettier_exports,
|
|
1620
|
+
stylelint: stylelint_exports,
|
|
1621
|
+
typescript: typescript_exports2,
|
|
1622
|
+
"semantic-release": semantic_release_exports
|
|
1623
|
+
};
|
|
1624
|
+
function getToolScripts(tool, detected) {
|
|
1625
|
+
const handler = TOOL_HANDLERS[tool];
|
|
1626
|
+
return handler.getScripts ? handler.getScripts(detected) : {};
|
|
1627
|
+
}
|
|
1628
|
+
async function setupTools(tools, detected, cwd, dryRun = false) {
|
|
1629
|
+
const { createProgress: createProgress2, SYMBOLS: SYMBOLS2, colors: colors2 } = await Promise.resolve().then(() => (init_formatting(), formatting_exports));
|
|
1630
|
+
console.log("");
|
|
1631
|
+
console.log("Creating configuration files...");
|
|
1632
|
+
console.log("");
|
|
1633
|
+
const successfulTools = [];
|
|
1634
|
+
const createdFiles = [];
|
|
1635
|
+
let current = 0;
|
|
1636
|
+
for (const tool of tools) {
|
|
1637
|
+
current++;
|
|
1638
|
+
const handler = TOOL_HANDLERS[tool];
|
|
1639
|
+
const filename = handler.getConfigFilename();
|
|
1640
|
+
const progressLine = colors2.dim(createProgress2(current, tools.length, filename));
|
|
1641
|
+
process.stdout.write(progressLine);
|
|
1642
|
+
const success = await handler.writeConfig(cwd, detected, dryRun);
|
|
1643
|
+
if (success) {
|
|
1644
|
+
successfulTools.push(tool);
|
|
1645
|
+
createdFiles.push(filename);
|
|
1646
|
+
console.log(` ${SYMBOLS2.success}`);
|
|
1647
|
+
} else {
|
|
1648
|
+
console.log(` ${SYMBOLS2.warning}`);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
const addedScripts = [];
|
|
1652
|
+
if (successfulTools.length > 0) {
|
|
1653
|
+
console.log("");
|
|
1654
|
+
console.log("Adding npm scripts...");
|
|
1655
|
+
console.log("");
|
|
1656
|
+
for (const tool of successfulTools) {
|
|
1657
|
+
const scripts = getToolScripts(tool, detected);
|
|
1658
|
+
addedScripts.push(...Object.keys(scripts));
|
|
1659
|
+
}
|
|
1660
|
+
updatePackageJsonScripts(successfulTools, getToolScripts, {
|
|
1661
|
+
detected,
|
|
1662
|
+
cwd,
|
|
1663
|
+
dryRun
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1666
|
+
return {
|
|
1667
|
+
files: createdFiles,
|
|
1668
|
+
scripts: addedScripts
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
function uninstallTools(tools, detected, cwd, dryRun = false) {
|
|
1672
|
+
showSection("\u{1F5D1}\uFE0F Removing configuration files...");
|
|
1673
|
+
let removedCount = 0;
|
|
1674
|
+
for (const tool of tools) {
|
|
1675
|
+
console.log(`${tool}:`);
|
|
1676
|
+
const handler = TOOL_HANDLERS[tool];
|
|
1677
|
+
const success = uninstallTool(tool, handler, detected, cwd, dryRun);
|
|
1678
|
+
if (success) {
|
|
1679
|
+
removedCount++;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
if (tools.length > 0) {
|
|
1683
|
+
showSection("\u{1F4E6} Removing package.json scripts...");
|
|
1684
|
+
removePackageJsonScripts(tools, getToolScripts, { detected, cwd, dryRun });
|
|
1685
|
+
}
|
|
1686
|
+
return removedCount;
|
|
1687
|
+
}
|
|
1688
|
+
async function main() {
|
|
1689
|
+
const args = process.argv.slice(2);
|
|
1690
|
+
const flags = {
|
|
1691
|
+
help: args.includes("--help") || args.includes("-h"),
|
|
1692
|
+
version: args.includes("--version") || args.includes("-v"),
|
|
1693
|
+
dryRun: args.includes("--dry-run") || args.includes("-d"),
|
|
1694
|
+
all: args.includes("--all") || args.includes("-a"),
|
|
1695
|
+
uninstall: args.includes("--uninstall")
|
|
1696
|
+
};
|
|
1697
|
+
const singleTool = args.find((arg) => !arg.startsWith("-"));
|
|
1698
|
+
if (flags.help) {
|
|
1699
|
+
showHelp();
|
|
1700
|
+
process.exit(0);
|
|
1701
|
+
}
|
|
1702
|
+
if (flags.version) {
|
|
1703
|
+
showVersion();
|
|
1704
|
+
process.exit(0);
|
|
1705
|
+
}
|
|
1706
|
+
const cwd = process.cwd();
|
|
1707
|
+
if (flags.uninstall) {
|
|
1708
|
+
const detected2 = autoDetect(cwd);
|
|
1709
|
+
const installedTools = detectInstalledTools(cwd);
|
|
1710
|
+
showUninstallBanner(installedTools);
|
|
1711
|
+
if (installedTools.length === 0) {
|
|
1712
|
+
console.log("Nothing to uninstall.");
|
|
1713
|
+
process.exit(0);
|
|
1714
|
+
}
|
|
1715
|
+
if (flags.all) {
|
|
1716
|
+
const removedCount2 = uninstallTools(installedTools, detected2, cwd, flags.dryRun);
|
|
1717
|
+
showUninstallCompletion(flags.dryRun, removedCount2);
|
|
1718
|
+
process.exit(0);
|
|
1719
|
+
}
|
|
1720
|
+
if (singleTool) {
|
|
1721
|
+
if (!installedTools.includes(singleTool)) {
|
|
1722
|
+
console.log(`\u26A0\uFE0F ${singleTool} is not installed`);
|
|
1723
|
+
process.exit(0);
|
|
1724
|
+
}
|
|
1725
|
+
const removedCount2 = uninstallTools([singleTool], detected2, cwd, flags.dryRun);
|
|
1726
|
+
showUninstallCompletion(flags.dryRun, removedCount2);
|
|
1727
|
+
process.exit(0);
|
|
1728
|
+
}
|
|
1729
|
+
const response2 = await prompts({
|
|
1730
|
+
type: "multiselect",
|
|
1731
|
+
name: "tools",
|
|
1732
|
+
message: "Which tools would you like to uninstall?",
|
|
1733
|
+
choices: installedTools.map((tool) => ({
|
|
1734
|
+
title: tool,
|
|
1735
|
+
value: tool,
|
|
1736
|
+
selected: false
|
|
1737
|
+
})),
|
|
1738
|
+
hint: "- Space to select. Return to submit"
|
|
1739
|
+
});
|
|
1740
|
+
if (!response2.tools || response2.tools.length === 0) {
|
|
1741
|
+
console.log("");
|
|
1742
|
+
console.log("\u274C No tools selected. Exiting.");
|
|
1743
|
+
process.exit(0);
|
|
1744
|
+
}
|
|
1745
|
+
const removedCount = uninstallTools(response2.tools, detected2, cwd, flags.dryRun);
|
|
1746
|
+
showUninstallCompletion(flags.dryRun, removedCount);
|
|
1747
|
+
process.exit(0);
|
|
1748
|
+
}
|
|
1749
|
+
const detected = autoDetect(cwd);
|
|
1750
|
+
showBanner(detected);
|
|
1751
|
+
if (flags.all) {
|
|
1752
|
+
const summary2 = await setupTools([...VALID_TOOLS], detected, cwd, flags.dryRun);
|
|
1753
|
+
showCompletion(flags.dryRun, summary2.files, summary2.scripts);
|
|
1754
|
+
process.exit(0);
|
|
1755
|
+
}
|
|
1756
|
+
if (singleTool) {
|
|
1757
|
+
validateTool(singleTool);
|
|
1758
|
+
const summary2 = await setupTools([singleTool], detected, cwd, flags.dryRun);
|
|
1759
|
+
showCompletion(flags.dryRun, summary2.files, summary2.scripts);
|
|
1760
|
+
process.exit(0);
|
|
1761
|
+
}
|
|
1762
|
+
const response = await prompts([
|
|
1763
|
+
{
|
|
1764
|
+
type: "multiselect",
|
|
1765
|
+
name: "tools",
|
|
1766
|
+
message: "Select development tools to configure:",
|
|
1767
|
+
choices: [
|
|
1768
|
+
{
|
|
1769
|
+
title: "ESLint Catch bugs and enforce standards",
|
|
1770
|
+
value: "eslint",
|
|
1771
|
+
selected: true
|
|
1772
|
+
},
|
|
1773
|
+
{
|
|
1774
|
+
title: "Prettier Auto-format code consistently",
|
|
1775
|
+
value: "prettier",
|
|
1776
|
+
selected: true
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
title: "Stylelint Lint CSS, SCSS, and style files",
|
|
1780
|
+
value: "stylelint",
|
|
1781
|
+
selected: false
|
|
1782
|
+
},
|
|
1783
|
+
{
|
|
1784
|
+
title: "TypeScript Type safety and better tooling",
|
|
1785
|
+
value: "typescript",
|
|
1786
|
+
selected: detected.typescript
|
|
1787
|
+
},
|
|
1788
|
+
{
|
|
1789
|
+
title: "semantic-release Automated versioning & releases",
|
|
1790
|
+
value: "semantic-release",
|
|
1791
|
+
selected: false
|
|
1792
|
+
}
|
|
1793
|
+
],
|
|
1794
|
+
hint: " (Recommended tools are pre-selected)"
|
|
1795
|
+
}
|
|
1796
|
+
]);
|
|
1797
|
+
if (!response.tools || response.tools.length === 0) {
|
|
1798
|
+
console.log("");
|
|
1799
|
+
console.log("\u274C No tools selected. Exiting.");
|
|
1800
|
+
process.exit(0);
|
|
1801
|
+
}
|
|
1802
|
+
const summary = await setupTools(response.tools, detected, cwd, flags.dryRun);
|
|
1803
|
+
showCompletion(flags.dryRun, summary.files, summary.scripts);
|
|
1804
|
+
}
|
|
1805
|
+
main().catch((error) => {
|
|
1806
|
+
console.error("");
|
|
1807
|
+
console.error("\u274C Error:", error.message);
|
|
1808
|
+
console.error("");
|
|
1809
|
+
process.exit(1);
|
|
1810
|
+
});
|
|
1811
|
+
//# sourceMappingURL=index.js.map
|
|
1812
|
+
//# sourceMappingURL=index.js.map
|