@luxkit/cli 1.1.2 → 1.1.4
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 +137 -40
- package/README_zh.md +238 -0
- package/dist/index.js +365 -64
- package/dist/skills/lux/references/custom-preset-setting.md +222 -41
- package/dist/skills/lux/skill.md +36 -12
- package/package.json +14 -3
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { program } from "commander";
|
|
|
6
6
|
// src/commands/fmt.ts
|
|
7
7
|
import fs3 from "fs";
|
|
8
8
|
import path5 from "path";
|
|
9
|
+
import chalk2 from "chalk";
|
|
9
10
|
|
|
10
11
|
// src/presets/fmt/electron-vue.ts
|
|
11
12
|
var electronVueFmt = {
|
|
@@ -112,14 +113,25 @@ trim_trailing_whitespace = false
|
|
|
112
113
|
"@stylistic/stylelint-plugin",
|
|
113
114
|
"postcss-html",
|
|
114
115
|
"postcss-scss",
|
|
115
|
-
"cspell"
|
|
116
|
+
"cspell",
|
|
117
|
+
"husky",
|
|
118
|
+
"lint-staged"
|
|
116
119
|
]
|
|
117
120
|
},
|
|
118
121
|
scripts: {
|
|
119
122
|
lint: 'eslint . --cache --cache-location node_modules/.cache/eslint && cspell --cache --cache-location node_modules/.cache/cspell --gitignore "src/**/*" && vue-tsc --noEmit && stylelint "src/**/*.{css,scss,vue}" --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
120
123
|
"lint:fix": 'eslint . --cache --cache-location node_modules/.cache/eslint --fix && stylelint "src/**/*.{css,scss,vue}" --fix --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
121
|
-
format: 'prettier --write "src/**/*.{ts,js,json,vue,css,scss}"'
|
|
122
|
-
|
|
124
|
+
format: 'prettier --write "src/**/*.{ts,js,json,vue,css,scss}"',
|
|
125
|
+
"lint-staged": "lint-staged"
|
|
126
|
+
},
|
|
127
|
+
lintStaged: () => JSON.stringify(
|
|
128
|
+
{
|
|
129
|
+
"*.{ts,js,vue}": ["eslint --fix", "prettier --write"],
|
|
130
|
+
"*.{css,scss,vue}": ["stylelint --fix", "prettier --write"]
|
|
131
|
+
},
|
|
132
|
+
null,
|
|
133
|
+
2
|
|
134
|
+
) + "\n"
|
|
123
135
|
};
|
|
124
136
|
|
|
125
137
|
// src/presets/fmt/nest.ts
|
|
@@ -175,13 +187,21 @@ trim_trailing_whitespace = true
|
|
|
175
187
|
trim_trailing_whitespace = false
|
|
176
188
|
`,
|
|
177
189
|
dependencies: {
|
|
178
|
-
dev: ["prettier", "cspell"]
|
|
190
|
+
dev: ["prettier", "cspell", "husky", "lint-staged"]
|
|
179
191
|
},
|
|
180
192
|
scripts: {
|
|
181
193
|
lint: 'eslint "{src,apps,libs,test}/**/*.ts" --cache --cache-location node_modules/.cache/eslint && cspell --cache --cache-location node_modules/.cache/cspell --gitignore "src/**/*" && tsc --noEmit',
|
|
182
194
|
"lint:fix": 'eslint "{src,apps,libs,test}/**/*.ts" --cache --cache-location node_modules/.cache/eslint --fix',
|
|
183
|
-
format: 'prettier --write "src/**/*.{ts,js,json}"'
|
|
184
|
-
|
|
195
|
+
format: 'prettier --write "src/**/*.{ts,js,json}"',
|
|
196
|
+
"lint-staged": "lint-staged"
|
|
197
|
+
},
|
|
198
|
+
lintStaged: () => JSON.stringify(
|
|
199
|
+
{
|
|
200
|
+
"*.{ts,js}": ["eslint --fix", "prettier --write"]
|
|
201
|
+
},
|
|
202
|
+
null,
|
|
203
|
+
2
|
|
204
|
+
) + "\n"
|
|
185
205
|
};
|
|
186
206
|
|
|
187
207
|
// src/presets/fmt/node.ts
|
|
@@ -286,14 +306,24 @@ trim_trailing_whitespace = false
|
|
|
286
306
|
"eslint-plugin-prettier",
|
|
287
307
|
"eslint-config-prettier",
|
|
288
308
|
"prettier",
|
|
289
|
-
"cspell"
|
|
309
|
+
"cspell",
|
|
310
|
+
"husky",
|
|
311
|
+
"lint-staged"
|
|
290
312
|
]
|
|
291
313
|
},
|
|
292
314
|
scripts: {
|
|
293
315
|
lint: 'eslint . --cache --cache-location node_modules/.cache/eslint && cspell --cache --cache-location node_modules/.cache/cspell --gitignore "src/**/*" && tsc --noEmit',
|
|
294
316
|
"lint:fix": "eslint . --cache --cache-location node_modules/.cache/eslint --fix",
|
|
295
|
-
format: 'prettier --write "src/**/*.{ts,js,json}"'
|
|
296
|
-
|
|
317
|
+
format: 'prettier --write "src/**/*.{ts,js,json}"',
|
|
318
|
+
"lint-staged": "lint-staged"
|
|
319
|
+
},
|
|
320
|
+
lintStaged: () => JSON.stringify(
|
|
321
|
+
{
|
|
322
|
+
"*.{ts,js}": ["eslint --fix", "prettier --write"]
|
|
323
|
+
},
|
|
324
|
+
null,
|
|
325
|
+
2
|
|
326
|
+
) + "\n"
|
|
297
327
|
};
|
|
298
328
|
|
|
299
329
|
// src/presets/fmt/uniapp.ts
|
|
@@ -399,14 +429,25 @@ trim_trailing_whitespace = false
|
|
|
399
429
|
"@stylistic/stylelint-plugin",
|
|
400
430
|
"postcss-html",
|
|
401
431
|
"postcss-scss",
|
|
402
|
-
"cspell"
|
|
432
|
+
"cspell",
|
|
433
|
+
"husky",
|
|
434
|
+
"lint-staged"
|
|
403
435
|
]
|
|
404
436
|
},
|
|
405
437
|
scripts: {
|
|
406
438
|
lint: 'eslint . --cache --cache-location node_modules/.cache/eslint && cspell --cache --cache-location node_modules/.cache/cspell --gitignore "src/**/*" && vue-tsc --noEmit && stylelint "src/**/*.{css,scss,vue}" --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
407
439
|
"lint:fix": 'eslint . --cache --cache-location node_modules/.cache/eslint --fix && stylelint "src/**/*.{css,scss,vue}" --fix --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
408
|
-
format: 'prettier --write "src/**/*.{ts,js,json,vue,css,scss}"'
|
|
409
|
-
|
|
440
|
+
format: 'prettier --write "src/**/*.{ts,js,json,vue,css,scss}"',
|
|
441
|
+
"lint-staged": "lint-staged"
|
|
442
|
+
},
|
|
443
|
+
lintStaged: () => JSON.stringify(
|
|
444
|
+
{
|
|
445
|
+
"*.{ts,js,vue}": ["eslint --fix", "prettier --write"],
|
|
446
|
+
"*.{css,scss,vue}": ["stylelint --fix", "prettier --write"]
|
|
447
|
+
},
|
|
448
|
+
null,
|
|
449
|
+
2
|
|
450
|
+
) + "\n"
|
|
410
451
|
};
|
|
411
452
|
|
|
412
453
|
// src/presets/fmt/web-react.ts
|
|
@@ -519,14 +560,25 @@ trim_trailing_whitespace = false
|
|
|
519
560
|
"stylelint-scss",
|
|
520
561
|
"@stylistic/stylelint-plugin",
|
|
521
562
|
"postcss-scss",
|
|
522
|
-
"cspell"
|
|
563
|
+
"cspell",
|
|
564
|
+
"husky",
|
|
565
|
+
"lint-staged"
|
|
523
566
|
]
|
|
524
567
|
},
|
|
525
568
|
scripts: {
|
|
526
569
|
lint: 'eslint . --cache --cache-location node_modules/.cache/eslint && cspell --cache --cache-location node_modules/.cache/cspell --gitignore "src/**/*" && tsc --noEmit && stylelint "src/**/*.{css,scss}" --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
527
570
|
"lint:fix": 'eslint . --cache --cache-location node_modules/.cache/eslint --fix && stylelint "src/**/*.{css,scss}" --fix --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
528
|
-
format: 'prettier --write "src/**/*.{ts,js,json,jsx,tsx,css,scss}"'
|
|
529
|
-
|
|
571
|
+
format: 'prettier --write "src/**/*.{ts,js,json,jsx,tsx,css,scss}"',
|
|
572
|
+
"lint-staged": "lint-staged"
|
|
573
|
+
},
|
|
574
|
+
lintStaged: () => JSON.stringify(
|
|
575
|
+
{
|
|
576
|
+
"*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
|
|
577
|
+
"*.{css,scss}": ["stylelint --fix", "prettier --write"]
|
|
578
|
+
},
|
|
579
|
+
null,
|
|
580
|
+
2
|
|
581
|
+
) + "\n"
|
|
530
582
|
};
|
|
531
583
|
|
|
532
584
|
// src/presets/fmt/web-vue.ts
|
|
@@ -630,14 +682,25 @@ trim_trailing_whitespace = false
|
|
|
630
682
|
"@stylistic/stylelint-plugin",
|
|
631
683
|
"postcss-html",
|
|
632
684
|
"postcss-scss",
|
|
633
|
-
"cspell"
|
|
685
|
+
"cspell",
|
|
686
|
+
"husky",
|
|
687
|
+
"lint-staged"
|
|
634
688
|
]
|
|
635
689
|
},
|
|
636
690
|
scripts: {
|
|
637
691
|
lint: 'eslint . --cache --cache-location node_modules/.cache/eslint && cspell --cache --cache-location node_modules/.cache/cspell --gitignore "src/**/*" && vue-tsc --noEmit && stylelint "src/**/*.{css,scss,vue}" --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
638
692
|
"lint:fix": 'eslint . --cache --cache-location node_modules/.cache/eslint --fix && stylelint "src/**/*.{css,scss,vue}" --fix --cache --cache-strategy content --cache-location node_modules/.cache/stylelint/',
|
|
639
|
-
format: 'prettier --write "src/**/*.{ts,js,json,vue,css,scss}"'
|
|
640
|
-
|
|
693
|
+
format: 'prettier --write "src/**/*.{ts,js,json,vue,css,scss}"',
|
|
694
|
+
"lint-staged": "lint-staged"
|
|
695
|
+
},
|
|
696
|
+
lintStaged: () => JSON.stringify(
|
|
697
|
+
{
|
|
698
|
+
"*.{ts,js,vue}": ["eslint --fix", "prettier --write"],
|
|
699
|
+
"*.{css,scss,vue}": ["stylelint --fix", "prettier --write"]
|
|
700
|
+
},
|
|
701
|
+
null,
|
|
702
|
+
2
|
|
703
|
+
) + "\n"
|
|
641
704
|
};
|
|
642
705
|
|
|
643
706
|
// src/presets/fmt/index.ts
|
|
@@ -668,7 +731,6 @@ var logger = {
|
|
|
668
731
|
};
|
|
669
732
|
|
|
670
733
|
// src/utils/errors.ts
|
|
671
|
-
import chalk2 from "chalk";
|
|
672
734
|
var CliError = class extends Error {
|
|
673
735
|
code;
|
|
674
736
|
suggestion;
|
|
@@ -714,14 +776,6 @@ function levenshtein(a, b) {
|
|
|
714
776
|
}
|
|
715
777
|
function resolvePreset(presets, name) {
|
|
716
778
|
const found = presets.find((p) => p.name === name);
|
|
717
|
-
if (!found) {
|
|
718
|
-
const err = new PresetNotFoundError(
|
|
719
|
-
name,
|
|
720
|
-
presets.map((p) => p.name)
|
|
721
|
-
);
|
|
722
|
-
console.error(chalk2.red(err.message));
|
|
723
|
-
process.exit(1);
|
|
724
|
-
}
|
|
725
779
|
return found;
|
|
726
780
|
}
|
|
727
781
|
|
|
@@ -784,7 +838,8 @@ var CONFIG_FILES = [
|
|
|
784
838
|
{ filename: "stylelint.config.mjs", getContent: (p) => p.stylelint?.() },
|
|
785
839
|
{ filename: ".stylelintignore", getContent: (p) => p.stylelintIgnore?.() },
|
|
786
840
|
{ filename: "cspell.json", getContent: (p) => p.cspell?.() },
|
|
787
|
-
{ filename: ".editorconfig", getContent: (p) => p.editorconfig?.() }
|
|
841
|
+
{ filename: ".editorconfig", getContent: (p) => p.editorconfig?.() },
|
|
842
|
+
{ filename: ".lintstagedrc.json", getContent: (p) => p.lintStaged?.() }
|
|
788
843
|
];
|
|
789
844
|
function generateConfigFile(preset, filename, content, opts) {
|
|
790
845
|
const filepath = path2.join(opts.cwd, filename);
|
|
@@ -807,6 +862,8 @@ function generateAllFmt(preset, opts) {
|
|
|
807
862
|
for (const { filename, getContent } of CONFIG_FILES) {
|
|
808
863
|
if (opts.noStylelint && filename.includes("stylelint")) continue;
|
|
809
864
|
if (opts.noEditorconfig && filename === ".editorconfig") continue;
|
|
865
|
+
if (opts.noCspell && filename.includes("cspell")) continue;
|
|
866
|
+
if (opts.noLintStaged && filename === ".lintstagedrc.json") continue;
|
|
810
867
|
const content = getContent(preset);
|
|
811
868
|
if (content === void 0) continue;
|
|
812
869
|
const action = generateConfigFile(preset, filename, content, opts);
|
|
@@ -999,10 +1056,13 @@ var CONFIG_GETTERS = [
|
|
|
999
1056
|
{ filename: "stylelint.config.mjs", getContent: (p) => p.stylelint?.() },
|
|
1000
1057
|
{ filename: ".stylelintignore", getContent: (p) => p.stylelintIgnore?.() },
|
|
1001
1058
|
{ filename: "cspell.json", getContent: (p) => p.cspell?.() },
|
|
1002
|
-
{ filename: ".editorconfig", getContent: (p) => p.editorconfig?.() }
|
|
1059
|
+
{ filename: ".editorconfig", getContent: (p) => p.editorconfig?.() },
|
|
1060
|
+
{ filename: ".lintstagedrc.json", getContent: (p) => p.lintStaged?.() }
|
|
1003
1061
|
];
|
|
1004
1062
|
var STYLELINT_FILES = /* @__PURE__ */ new Set(["stylelint.config.mjs", ".stylelintignore"]);
|
|
1005
1063
|
var EDITORCONFIG_FILE = ".editorconfig";
|
|
1064
|
+
var CSPELL_FILE = "cspell.json";
|
|
1065
|
+
var LINTSTAGED_FILE = ".lintstagedrc.json";
|
|
1006
1066
|
var STYLELINT_SETTINGS_PREFIXES = [
|
|
1007
1067
|
"stylelint.",
|
|
1008
1068
|
"css.validate",
|
|
@@ -1019,6 +1079,8 @@ var STYLELINT_DEPS = /* @__PURE__ */ new Set([
|
|
|
1019
1079
|
"postcss-scss"
|
|
1020
1080
|
]);
|
|
1021
1081
|
var STYLELINT_EXTENSION = "stylelint.vscode-stylelint";
|
|
1082
|
+
var HUSKY_DEPS = /* @__PURE__ */ new Set(["husky"]);
|
|
1083
|
+
var LINTSTAGED_DEPS = /* @__PURE__ */ new Set(["lint-staged"]);
|
|
1022
1084
|
function getLuxDir() {
|
|
1023
1085
|
return process.env.LUX_HOME || path4.join(os.homedir(), ".lux");
|
|
1024
1086
|
}
|
|
@@ -1031,6 +1093,28 @@ function getLocalPresetDir(type, presetName) {
|
|
|
1031
1093
|
function isValidPresetName(name) {
|
|
1032
1094
|
return name.length > 0 && !name.includes("/") && !name.includes("\\") && !name.includes("..");
|
|
1033
1095
|
}
|
|
1096
|
+
function listCustomPresets() {
|
|
1097
|
+
const fmtDir = path4.join(getLuxDir(), "preset", "fmt");
|
|
1098
|
+
if (!fs2.existsSync(fmtDir)) return [];
|
|
1099
|
+
const entries = fs2.readdirSync(fmtDir, { withFileTypes: true });
|
|
1100
|
+
const result = [];
|
|
1101
|
+
for (const entry of entries) {
|
|
1102
|
+
if (!entry.isDirectory()) continue;
|
|
1103
|
+
if (!isValidPresetName(entry.name)) continue;
|
|
1104
|
+
const pkgPath = path4.join(fmtDir, entry.name, "package.json");
|
|
1105
|
+
if (fs2.existsSync(pkgPath)) {
|
|
1106
|
+
result.push(entry.name);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
return result;
|
|
1110
|
+
}
|
|
1111
|
+
function isValidCustomPreset(name) {
|
|
1112
|
+
if (!isValidPresetName(name)) return false;
|
|
1113
|
+
const presetDir = path4.join(getLuxDir(), "preset", "fmt", name);
|
|
1114
|
+
if (!fs2.existsSync(presetDir)) return false;
|
|
1115
|
+
const pkgPath = path4.join(presetDir, "package.json");
|
|
1116
|
+
return fs2.existsSync(pkgPath);
|
|
1117
|
+
}
|
|
1034
1118
|
function localPresetExists(type, presetName) {
|
|
1035
1119
|
const dir = getLocalPresetDir(type, presetName);
|
|
1036
1120
|
return fs2.existsSync(dir);
|
|
@@ -1115,6 +1199,8 @@ function applyLocalFmtPreset(cwd, presetName, opts) {
|
|
|
1115
1199
|
for (const filename of entries) {
|
|
1116
1200
|
if (opts.noStylelint && STYLELINT_FILES.has(filename)) continue;
|
|
1117
1201
|
if (opts.noEditorconfig && filename === EDITORCONFIG_FILE) continue;
|
|
1202
|
+
if (opts.noCspell && filename === CSPELL_FILE) continue;
|
|
1203
|
+
if (opts.noLintStaged && filename === LINTSTAGED_FILE) continue;
|
|
1118
1204
|
const destPath = path4.join(cwd, filename);
|
|
1119
1205
|
const exists = fileExists(destPath);
|
|
1120
1206
|
if (exists && !opts.force) {
|
|
@@ -1235,6 +1321,9 @@ function mergeTemplateIntoProject(templatePkg, projectPkg, pm, opts, result) {
|
|
|
1235
1321
|
for (const [dep, version] of Object.entries(templatePkg.devDependencies)) {
|
|
1236
1322
|
if (opts.noStylelint && STYLELINT_DEPS.has(dep)) continue;
|
|
1237
1323
|
if (opts.noEditorconfig && dep.includes("editorconfig")) continue;
|
|
1324
|
+
if (opts.noCspell && dep === "cspell") continue;
|
|
1325
|
+
if (opts.noHusky && HUSKY_DEPS.has(dep)) continue;
|
|
1326
|
+
if (opts.noLintStaged && LINTSTAGED_DEPS.has(dep)) continue;
|
|
1238
1327
|
if (existingDeps[dep] === void 0 && version !== "<latest>") {
|
|
1239
1328
|
newDeps[dep] = version;
|
|
1240
1329
|
}
|
|
@@ -1244,11 +1333,15 @@ function mergeTemplateIntoProject(templatePkg, projectPkg, pm, opts, result) {
|
|
|
1244
1333
|
if (templatePkg.scripts) {
|
|
1245
1334
|
const existingScripts = merged.scripts ?? {};
|
|
1246
1335
|
const newScripts = { ...existingScripts };
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1336
|
+
const filteredScripts = filterScripts(
|
|
1337
|
+
templatePkg.scripts,
|
|
1338
|
+
opts.noStylelint,
|
|
1339
|
+
opts.noEditorconfig,
|
|
1340
|
+
opts.noCspell,
|
|
1341
|
+
opts.noLintStaged
|
|
1342
|
+
);
|
|
1343
|
+
for (const [key, value] of Object.entries(filteredScripts)) {
|
|
1344
|
+
const resolved = value.replace(/<pm>/g, prefix);
|
|
1252
1345
|
if (existingScripts[key] !== void 0 && !opts.force) {
|
|
1253
1346
|
result.scriptsSkipped++;
|
|
1254
1347
|
if (opts.dryRun) {
|
|
@@ -1283,6 +1376,57 @@ function filterStylelintSettings(settings) {
|
|
|
1283
1376
|
}
|
|
1284
1377
|
return filtered;
|
|
1285
1378
|
}
|
|
1379
|
+
function filterScripts(scripts, noStylelint, noEditorconfig, noCspell, noLintStaged = false) {
|
|
1380
|
+
const filtered = {};
|
|
1381
|
+
for (const [key, value] of Object.entries(scripts)) {
|
|
1382
|
+
if (noStylelint && key.includes("stylelint")) continue;
|
|
1383
|
+
if (noEditorconfig && key.includes("editorconfig")) continue;
|
|
1384
|
+
if (noCspell && key.includes("cspell")) continue;
|
|
1385
|
+
if (noLintStaged && key.includes("lint-staged")) continue;
|
|
1386
|
+
let resolved = value;
|
|
1387
|
+
if (noStylelint) {
|
|
1388
|
+
resolved = resolved.replace(/\s*&&\s*stylelint\s+"[^"]*".*/g, "");
|
|
1389
|
+
}
|
|
1390
|
+
if (noCspell) {
|
|
1391
|
+
resolved = resolved.replace(/\s*&&\s*cspell\s+[^&]*/g, "");
|
|
1392
|
+
resolved = resolved.replace(/(\S)&&/g, "$1 &&");
|
|
1393
|
+
}
|
|
1394
|
+
filtered[key] = resolved;
|
|
1395
|
+
}
|
|
1396
|
+
return filtered;
|
|
1397
|
+
}
|
|
1398
|
+
function detectPresetCapabilities(presetName) {
|
|
1399
|
+
const presetDir = path4.join(getLuxDir(), "preset", "fmt", presetName);
|
|
1400
|
+
const entries = fs2.readdirSync(presetDir);
|
|
1401
|
+
const hasStylelintFile = entries.some((f) => STYLELINT_FILES.has(f));
|
|
1402
|
+
const pkg = readJson(
|
|
1403
|
+
path4.join(presetDir, "package.json")
|
|
1404
|
+
);
|
|
1405
|
+
const hasStylelintDep = pkg?.devDependencies ? Object.keys(pkg.devDependencies).some((d) => isNotStylelintDep(d) === false) : false;
|
|
1406
|
+
const hasEditorconfigFile = entries.includes(EDITORCONFIG_FILE);
|
|
1407
|
+
const hasEditorconfigDep = pkg?.devDependencies ? Object.keys(pkg.devDependencies).some((d) => !isNotEditorconfigDep(d)) : false;
|
|
1408
|
+
const hasCspellFile = entries.includes(CSPELL_FILE);
|
|
1409
|
+
const hasCspellDep = pkg?.devDependencies ? Object.keys(pkg.devDependencies).some((d) => d === "cspell") : false;
|
|
1410
|
+
const hasLintStagedFile = entries.includes(LINTSTAGED_FILE);
|
|
1411
|
+
const hasLintStagedDep = pkg?.devDependencies ? Object.keys(pkg.devDependencies).some((d) => isNotLintStagedDep(d) === false) : false;
|
|
1412
|
+
return {
|
|
1413
|
+
hasStylelint: hasStylelintFile || hasStylelintDep,
|
|
1414
|
+
hasEditorconfig: hasEditorconfigFile || hasEditorconfigDep,
|
|
1415
|
+
hasCspell: hasCspellFile || hasCspellDep,
|
|
1416
|
+
hasLintStaged: hasLintStagedFile || hasLintStagedDep
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
function isNotStylelintDep(dep) {
|
|
1420
|
+
if (dep.includes("stylelint")) return false;
|
|
1421
|
+
if (dep === "postcss-html" || dep === "postcss-scss") return false;
|
|
1422
|
+
return true;
|
|
1423
|
+
}
|
|
1424
|
+
function isNotEditorconfigDep(dep) {
|
|
1425
|
+
return !dep.includes("editorconfig");
|
|
1426
|
+
}
|
|
1427
|
+
function isNotLintStagedDep(dep) {
|
|
1428
|
+
return dep !== "lint-staged";
|
|
1429
|
+
}
|
|
1286
1430
|
function resolveLocalDeps(deps) {
|
|
1287
1431
|
const packages = [];
|
|
1288
1432
|
for (const [name, version] of Object.entries(deps)) {
|
|
@@ -1296,27 +1440,33 @@ function resolveLocalDeps(deps) {
|
|
|
1296
1440
|
}
|
|
1297
1441
|
|
|
1298
1442
|
// src/commands/fmt.ts
|
|
1299
|
-
function
|
|
1300
|
-
const filtered = {};
|
|
1301
|
-
for (const [key, value] of Object.entries(scripts)) {
|
|
1302
|
-
filtered[key] = value.replace(/\s*&&\s*stylelint\s+"[^"]*".*/g, "");
|
|
1303
|
-
}
|
|
1304
|
-
return filtered;
|
|
1305
|
-
}
|
|
1306
|
-
function isNotStylelintDep(dep) {
|
|
1443
|
+
function isNotStylelintDep2(dep) {
|
|
1307
1444
|
if (dep.includes("stylelint")) return false;
|
|
1308
1445
|
if (dep === "postcss-html" || dep === "postcss-scss") return false;
|
|
1309
1446
|
return true;
|
|
1310
1447
|
}
|
|
1311
|
-
function
|
|
1448
|
+
function isNotEditorconfigDep2(dep) {
|
|
1312
1449
|
return !dep.includes("editorconfig");
|
|
1313
1450
|
}
|
|
1451
|
+
function isNotCspellDep(dep) {
|
|
1452
|
+
return dep !== "cspell";
|
|
1453
|
+
}
|
|
1454
|
+
function isNotHuskyDep(dep) {
|
|
1455
|
+
return dep !== "husky";
|
|
1456
|
+
}
|
|
1457
|
+
function isNotLintStagedDep2(dep) {
|
|
1458
|
+
return dep !== "lint-staged";
|
|
1459
|
+
}
|
|
1314
1460
|
function registerFmtCommand(program2) {
|
|
1315
1461
|
const fmt = program2.command("fmt").description("Initialize formatting config with preset");
|
|
1316
|
-
fmt.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--no-install", "Skip dependency installation").option("--dry-run", "Preview without writing files").option("--stylelint", "Include Stylelint config generation").option("--editorconfig", "Include EditorConfig config generation").option("--reset", "Reset local preset and re-materialize from built-in").action(
|
|
1462
|
+
fmt.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--no-install", "Skip dependency installation").option("--dry-run", "Preview without writing files").option("--stylelint", "Include Stylelint config generation").option("--editorconfig", "Include EditorConfig config generation").option("--cspell", "Include CSpell config generation").option("--husky", "Initialize husky for Git hooks").option("--lint-staged", "Set up lint-staged (implies --husky)").option("--reset", "Reset local preset and re-materialize from built-in").action(
|
|
1317
1463
|
async (presetName, options) => {
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1464
|
+
const builtinPreset = FMT_PRESETS.find((p) => p.name === presetName);
|
|
1465
|
+
const isBuiltin = builtinPreset !== void 0;
|
|
1466
|
+
if (options.reset && !isBuiltin) {
|
|
1467
|
+
logger.warn(`"${presetName}" is a custom preset, --reset has no builtin to restore`);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1320
1470
|
const cwd = process.cwd();
|
|
1321
1471
|
const pkgPath = path5.join(cwd, "package.json");
|
|
1322
1472
|
if (fileExists(pkgPath)) {
|
|
@@ -1329,31 +1479,73 @@ function registerFmtCommand(program2) {
|
|
|
1329
1479
|
return;
|
|
1330
1480
|
}
|
|
1331
1481
|
}
|
|
1332
|
-
if (
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1482
|
+
if (isBuiltin) {
|
|
1483
|
+
if (options.reset) {
|
|
1484
|
+
resetLocalPreset("fmt", presetName);
|
|
1485
|
+
}
|
|
1486
|
+
const useLocal = localPresetExists("fmt", presetName);
|
|
1487
|
+
if (useLocal) {
|
|
1488
|
+
await executeLocalPath(cwd, presetName, options);
|
|
1489
|
+
} else {
|
|
1490
|
+
await executeBuiltinPath(cwd, presetName, builtinPreset, options);
|
|
1491
|
+
}
|
|
1492
|
+
} else if (isValidCustomPreset(presetName)) {
|
|
1337
1493
|
await executeLocalPath(cwd, presetName, options);
|
|
1338
1494
|
} else {
|
|
1339
|
-
|
|
1495
|
+
const builtinNames = new Set(FMT_PRESETS.map((p) => p.name));
|
|
1496
|
+
const customNames = listCustomPresets().filter((n) => !builtinNames.has(n));
|
|
1497
|
+
const allNames = [...builtinNames, ...customNames];
|
|
1498
|
+
const err = new PresetNotFoundError(presetName, allNames);
|
|
1499
|
+
logger.error(err.message);
|
|
1500
|
+
process.exitCode = 1;
|
|
1340
1501
|
}
|
|
1341
1502
|
}
|
|
1342
1503
|
);
|
|
1343
1504
|
fmt.command("list").description("List available fmt presets").action(() => {
|
|
1505
|
+
const builtinNames = new Set(FMT_PRESETS.map((p) => p.name));
|
|
1344
1506
|
for (const p of FMT_PRESETS) {
|
|
1345
1507
|
console.log(`${p.name.padEnd(12)} ${p.description}`);
|
|
1346
1508
|
}
|
|
1509
|
+
const customs = listCustomPresets().filter((name) => !builtinNames.has(name));
|
|
1510
|
+
for (const name of customs) {
|
|
1511
|
+
console.log(`${name.padEnd(12)} ${chalk2.yellow("(custom)")}`);
|
|
1512
|
+
}
|
|
1347
1513
|
});
|
|
1348
1514
|
}
|
|
1349
1515
|
async function executeLocalPath(cwd, presetName, options) {
|
|
1350
1516
|
logger.log("Using local custom preset");
|
|
1517
|
+
const caps = detectPresetCapabilities(presetName);
|
|
1518
|
+
if (options.stylelint && !caps.hasStylelint) {
|
|
1519
|
+
logger.warn(
|
|
1520
|
+
"--stylelint has no effect: this custom preset has no stylelint config or dependencies"
|
|
1521
|
+
);
|
|
1522
|
+
}
|
|
1523
|
+
if (options.editorconfig && !caps.hasEditorconfig) {
|
|
1524
|
+
logger.warn(
|
|
1525
|
+
"--editorconfig has no effect: this custom preset has no editorconfig config or dependencies"
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
if (options.cspell && !caps.hasCspell) {
|
|
1529
|
+
logger.warn(
|
|
1530
|
+
"--cspell has no effect: this custom preset has no cspell config or dependencies"
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
if (options.lintStaged && !caps.hasLintStaged) {
|
|
1534
|
+
logger.warn(
|
|
1535
|
+
"--lint-staged has no effect: this custom preset has no lint-staged config or dependencies"
|
|
1536
|
+
);
|
|
1537
|
+
}
|
|
1538
|
+
const noHusky = options.husky !== true && options.lintStaged !== true;
|
|
1539
|
+
const noLintStaged = options.lintStaged !== true;
|
|
1351
1540
|
const opts = {
|
|
1352
1541
|
cwd,
|
|
1353
1542
|
force: options.force ?? false,
|
|
1354
1543
|
dryRun: options.dryRun ?? false,
|
|
1355
1544
|
noStylelint: options.stylelint !== true,
|
|
1356
|
-
noEditorconfig: options.editorconfig !== true
|
|
1545
|
+
noEditorconfig: options.editorconfig !== true,
|
|
1546
|
+
noCspell: options.cspell !== true,
|
|
1547
|
+
noHusky,
|
|
1548
|
+
noLintStaged
|
|
1357
1549
|
};
|
|
1358
1550
|
let result;
|
|
1359
1551
|
try {
|
|
@@ -1384,7 +1576,10 @@ async function executeLocalPath(cwd, presetName, options) {
|
|
|
1384
1576
|
const depsToInstall = filterDeps(
|
|
1385
1577
|
Object.keys(templatePkg.devDependencies),
|
|
1386
1578
|
opts.noStylelint,
|
|
1387
|
-
opts.noEditorconfig
|
|
1579
|
+
opts.noEditorconfig,
|
|
1580
|
+
opts.noCspell,
|
|
1581
|
+
opts.noHusky,
|
|
1582
|
+
opts.noLintStaged
|
|
1388
1583
|
);
|
|
1389
1584
|
const projectPkgPath = path5.join(cwd, "package.json");
|
|
1390
1585
|
const projectPkg = readJson(projectPkgPath);
|
|
@@ -1394,6 +1589,9 @@ async function executeLocalPath(cwd, presetName, options) {
|
|
|
1394
1589
|
if (missing.length === 0) return;
|
|
1395
1590
|
if (opts.dryRun) {
|
|
1396
1591
|
logger.log(`[dry-run] Would add to package.json: ${missing.join(", ")}`);
|
|
1592
|
+
if (!opts.noHusky) {
|
|
1593
|
+
await initHusky(cwd, pm, opts);
|
|
1594
|
+
}
|
|
1397
1595
|
return;
|
|
1398
1596
|
}
|
|
1399
1597
|
if (options.install === false) {
|
|
@@ -1412,6 +1610,9 @@ async function executeLocalPath(cwd, presetName, options) {
|
|
|
1412
1610
|
const message = error instanceof Error ? error.message : String(error);
|
|
1413
1611
|
logger.warn(`Failed to fetch versions: ${message}. You can add dependencies manually.`);
|
|
1414
1612
|
}
|
|
1613
|
+
if (!opts.noHusky) {
|
|
1614
|
+
await initHusky(cwd, pm, opts);
|
|
1615
|
+
}
|
|
1415
1616
|
return;
|
|
1416
1617
|
}
|
|
1417
1618
|
try {
|
|
@@ -1427,15 +1628,23 @@ async function executeLocalPath(cwd, presetName, options) {
|
|
|
1427
1628
|
const message = error instanceof Error ? error.message : String(error);
|
|
1428
1629
|
logger.warn(`Dependency installation failed: ${message}. You can install manually.`);
|
|
1429
1630
|
}
|
|
1631
|
+
if (!opts.noHusky) {
|
|
1632
|
+
await initHusky(cwd, pm, opts);
|
|
1633
|
+
}
|
|
1430
1634
|
}
|
|
1431
1635
|
async function executeBuiltinPath(cwd, presetName, preset, options) {
|
|
1432
1636
|
const pm = fileExists(path5.join(cwd, "package.json")) ? detectPackageManager(cwd) : void 0;
|
|
1637
|
+
const noHusky = options.husky !== true && options.lintStaged !== true;
|
|
1638
|
+
const noLintStaged = options.lintStaged !== true;
|
|
1433
1639
|
const opts = {
|
|
1434
1640
|
cwd,
|
|
1435
1641
|
force: options.force ?? false,
|
|
1436
1642
|
dryRun: options.dryRun ?? false,
|
|
1437
1643
|
noStylelint: options.stylelint !== true,
|
|
1438
1644
|
noEditorconfig: options.editorconfig !== true,
|
|
1645
|
+
noCspell: options.cspell !== true,
|
|
1646
|
+
noHusky,
|
|
1647
|
+
noLintStaged,
|
|
1439
1648
|
lockfile: pm ? getLockfileName(pm) : void 0
|
|
1440
1649
|
};
|
|
1441
1650
|
const result = generateAllFmt(preset, opts);
|
|
@@ -1452,15 +1661,27 @@ async function executeBuiltinPath(cwd, presetName, preset, options) {
|
|
|
1452
1661
|
warnMissingPackageJson(preset, options.install !== false);
|
|
1453
1662
|
return;
|
|
1454
1663
|
}
|
|
1455
|
-
const scripts =
|
|
1664
|
+
const scripts = preset.scripts ? filterScripts(
|
|
1665
|
+
preset.scripts,
|
|
1666
|
+
opts.noStylelint,
|
|
1667
|
+
opts.noEditorconfig,
|
|
1668
|
+
opts.noCspell,
|
|
1669
|
+
opts.noLintStaged
|
|
1670
|
+
) : void 0;
|
|
1456
1671
|
if (scripts) {
|
|
1457
1672
|
await injectScripts(scripts, opts, pm);
|
|
1458
1673
|
}
|
|
1459
1674
|
if (!preset.dependencies?.dev) return;
|
|
1460
|
-
const devDeps = opts.noStylelint ? preset.dependencies.dev.filter(
|
|
1461
|
-
const
|
|
1675
|
+
const devDeps = opts.noStylelint ? preset.dependencies.dev.filter(isNotStylelintDep2) : preset.dependencies.dev;
|
|
1676
|
+
const noEditorconfigDeps = opts.noEditorconfig ? devDeps.filter(isNotEditorconfigDep2) : devDeps;
|
|
1677
|
+
const noCspellDeps = opts.noCspell ? noEditorconfigDeps.filter(isNotCspellDep) : noEditorconfigDeps;
|
|
1678
|
+
const noHuskyDeps = opts.noHusky ? noCspellDeps.filter(isNotHuskyDep) : noCspellDeps;
|
|
1679
|
+
const finalDeps = opts.noLintStaged ? noHuskyDeps.filter(isNotLintStagedDep2) : noHuskyDeps;
|
|
1462
1680
|
if (opts.dryRun) {
|
|
1463
1681
|
logger.log(`[dry-run] Would add to package.json: ${finalDeps.join(", ")}`);
|
|
1682
|
+
if (!opts.noHusky) {
|
|
1683
|
+
await initHusky(cwd, pm, opts);
|
|
1684
|
+
}
|
|
1464
1685
|
return;
|
|
1465
1686
|
}
|
|
1466
1687
|
if (options.install === false) {
|
|
@@ -1475,6 +1696,9 @@ async function executeBuiltinPath(cwd, presetName, preset, options) {
|
|
|
1475
1696
|
const message = error instanceof Error ? error.message : String(error);
|
|
1476
1697
|
logger.warn(`Failed to fetch versions: ${message}. You can add dependencies manually.`);
|
|
1477
1698
|
}
|
|
1699
|
+
if (!opts.noHusky) {
|
|
1700
|
+
await initHusky(cwd, pm, opts);
|
|
1701
|
+
}
|
|
1478
1702
|
return;
|
|
1479
1703
|
}
|
|
1480
1704
|
try {
|
|
@@ -1485,11 +1709,17 @@ async function executeBuiltinPath(cwd, presetName, preset, options) {
|
|
|
1485
1709
|
const message = error instanceof Error ? error.message : String(error);
|
|
1486
1710
|
logger.warn(`Dependency installation failed: ${message}. You can install manually.`);
|
|
1487
1711
|
}
|
|
1712
|
+
if (!opts.noHusky) {
|
|
1713
|
+
await initHusky(cwd, pm, opts);
|
|
1714
|
+
}
|
|
1488
1715
|
}
|
|
1489
|
-
function filterDeps(deps, noStylelint, noEditorconfig) {
|
|
1716
|
+
function filterDeps(deps, noStylelint, noEditorconfig, noCspell, noHusky, noLintStaged) {
|
|
1490
1717
|
let filtered = deps;
|
|
1491
|
-
if (noStylelint) filtered = filtered.filter(
|
|
1492
|
-
if (noEditorconfig) filtered = filtered.filter(
|
|
1718
|
+
if (noStylelint) filtered = filtered.filter(isNotStylelintDep2);
|
|
1719
|
+
if (noEditorconfig) filtered = filtered.filter(isNotEditorconfigDep2);
|
|
1720
|
+
if (noCspell) filtered = filtered.filter(isNotCspellDep);
|
|
1721
|
+
if (noHusky) filtered = filtered.filter(isNotHuskyDep);
|
|
1722
|
+
if (noLintStaged) filtered = filtered.filter(isNotLintStagedDep2);
|
|
1493
1723
|
return filtered;
|
|
1494
1724
|
}
|
|
1495
1725
|
function logGenerationResult(result, dryRun) {
|
|
@@ -1552,6 +1782,8 @@ function summarizeFiles(filenames) {
|
|
|
1552
1782
|
else if (name.includes("stylelint")) categories.add("stylelint");
|
|
1553
1783
|
else if (name.includes("cspell")) categories.add("cspell");
|
|
1554
1784
|
else if (name.includes("editorconfig")) categories.add("editorconfig");
|
|
1785
|
+
else if (name.includes("husky")) categories.add("husky");
|
|
1786
|
+
else if (name.includes("lintstagedrc")) categories.add("lint-staged");
|
|
1555
1787
|
}
|
|
1556
1788
|
return [...categories].join(", ");
|
|
1557
1789
|
}
|
|
@@ -1590,6 +1822,58 @@ async function injectScripts(scripts, opts, pm) {
|
|
|
1590
1822
|
);
|
|
1591
1823
|
}
|
|
1592
1824
|
}
|
|
1825
|
+
async function initHusky(cwd, pm, opts) {
|
|
1826
|
+
const pkgPath = path5.join(cwd, "package.json");
|
|
1827
|
+
const pkg = readJson(pkgPath);
|
|
1828
|
+
if (!pkg) {
|
|
1829
|
+
logger.warn("package.json not found, skipping husky setup");
|
|
1830
|
+
return;
|
|
1831
|
+
}
|
|
1832
|
+
const prefix = getRunPrefix(pm);
|
|
1833
|
+
const isYarn = pm === "yarn";
|
|
1834
|
+
const initScriptName = isYarn ? "postinstall" : "prepare";
|
|
1835
|
+
const hookCommand = opts.noLintStaged ? `${prefix} lint` : `${prefix} lint-staged`;
|
|
1836
|
+
const huskyDir = path5.join(cwd, ".husky");
|
|
1837
|
+
const preCommitPath = path5.join(huskyDir, "pre-commit");
|
|
1838
|
+
if (opts.dryRun) {
|
|
1839
|
+
logger.log(`[dry-run] Would create .husky/pre-commit with: ${hookCommand}`);
|
|
1840
|
+
logger.log(`[dry-run] Would inject "${initScriptName}": "husky" script`);
|
|
1841
|
+
logger.log(`[dry-run] Would run ${prefix} ${initScriptName}`);
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1844
|
+
if (fileExists(preCommitPath) && !opts.force) {
|
|
1845
|
+
logger.log("Skipped .husky/pre-commit (already exists)");
|
|
1846
|
+
} else {
|
|
1847
|
+
ensureDir(huskyDir);
|
|
1848
|
+
writeFile(preCommitPath, `${hookCommand}
|
|
1849
|
+
`);
|
|
1850
|
+
fs3.chmodSync(preCommitPath, 493);
|
|
1851
|
+
}
|
|
1852
|
+
const scripts = pkg.scripts ?? {};
|
|
1853
|
+
if (scripts[initScriptName] !== void 0 && !opts.force) {
|
|
1854
|
+
logger.log(`Skipped script "${initScriptName}" (already exists)`);
|
|
1855
|
+
} else {
|
|
1856
|
+
scripts[initScriptName] = "husky";
|
|
1857
|
+
pkg.scripts = scripts;
|
|
1858
|
+
writeJson(pkgPath, pkg);
|
|
1859
|
+
logger.log(`Injected "${initScriptName}" script for husky`);
|
|
1860
|
+
}
|
|
1861
|
+
logger.log(`Running ${prefix} ${initScriptName} to initialize git hooks...`);
|
|
1862
|
+
try {
|
|
1863
|
+
const args = isYarn ? ["postinstall"] : ["run", initScriptName];
|
|
1864
|
+
const { exitCode } = await execFileNoThrow(pm, args, { cwd });
|
|
1865
|
+
if (exitCode === 0) {
|
|
1866
|
+
logger.success("Husky initialized successfully");
|
|
1867
|
+
} else {
|
|
1868
|
+
logger.warn(`Husky init script exited with code ${exitCode}`);
|
|
1869
|
+
}
|
|
1870
|
+
} catch (error) {
|
|
1871
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1872
|
+
logger.warn(
|
|
1873
|
+
`Husky init failed: ${message}. You can run "${prefix} ${initScriptName}" manually.`
|
|
1874
|
+
);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1593
1877
|
|
|
1594
1878
|
// src/commands/init.ts
|
|
1595
1879
|
import { select, isCancel, cancel, outro } from "@clack/prompts";
|
|
@@ -2448,7 +2732,10 @@ function materializeAllPresets() {
|
|
|
2448
2732
|
force: false,
|
|
2449
2733
|
dryRun: false,
|
|
2450
2734
|
noStylelint: false,
|
|
2451
|
-
noEditorconfig: false
|
|
2735
|
+
noEditorconfig: false,
|
|
2736
|
+
noCspell: false,
|
|
2737
|
+
noHusky: false,
|
|
2738
|
+
noLintStaged: false
|
|
2452
2739
|
};
|
|
2453
2740
|
for (const preset of FMT_PRESETS) {
|
|
2454
2741
|
materializeFmtPreset(preset.name, preset, opts);
|
|
@@ -2676,7 +2963,15 @@ function registerVscodeCommand(program2) {
|
|
|
2676
2963
|
vscode.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--dry-run", "Preview without writing files").option("--stylelint", "Include Stylelint settings and extension").option("--reset", "Reset local preset and re-materialize from built-in").action(
|
|
2677
2964
|
async (presetName, options) => {
|
|
2678
2965
|
const preset = resolvePreset(VSCODE_PRESETS, presetName);
|
|
2679
|
-
if (!preset)
|
|
2966
|
+
if (!preset) {
|
|
2967
|
+
const err = new PresetNotFoundError(
|
|
2968
|
+
presetName,
|
|
2969
|
+
VSCODE_PRESETS.map((p) => p.name)
|
|
2970
|
+
);
|
|
2971
|
+
logger.error(err.message);
|
|
2972
|
+
process.exitCode = 1;
|
|
2973
|
+
return;
|
|
2974
|
+
}
|
|
2680
2975
|
const cwd = process.cwd();
|
|
2681
2976
|
if (options.reset) {
|
|
2682
2977
|
resetLocalPreset("vscode", presetName);
|
|
@@ -2702,7 +2997,10 @@ function executeVscodeLocalPath(cwd, presetName, options) {
|
|
|
2702
2997
|
force: options.force ?? false,
|
|
2703
2998
|
dryRun: options.dryRun ?? false,
|
|
2704
2999
|
noStylelint: options.stylelint !== true,
|
|
2705
|
-
noEditorconfig: false
|
|
3000
|
+
noEditorconfig: false,
|
|
3001
|
+
noCspell: false,
|
|
3002
|
+
noHusky: true,
|
|
3003
|
+
noLintStaged: true
|
|
2706
3004
|
};
|
|
2707
3005
|
const result = applyLocalVscodePreset(cwd, presetName, opts);
|
|
2708
3006
|
const files = [...result.created, ...result.overwritten];
|
|
@@ -2722,7 +3020,10 @@ function executeVscodeBuiltinPath(cwd, presetName, preset, options) {
|
|
|
2722
3020
|
force: options.force ?? false,
|
|
2723
3021
|
dryRun: options.dryRun ?? false,
|
|
2724
3022
|
noStylelint: options.stylelint !== true,
|
|
2725
|
-
noEditorconfig: false
|
|
3023
|
+
noEditorconfig: false,
|
|
3024
|
+
noCspell: false,
|
|
3025
|
+
noHusky: true,
|
|
3026
|
+
noLintStaged: true
|
|
2726
3027
|
};
|
|
2727
3028
|
const result = generateAllVscode(preset, opts);
|
|
2728
3029
|
const files = [...result.created, ...result.overwritten];
|