uilint 0.2.23 → 0.2.26
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/chunk-P4I4RKBY.js +126 -0
- package/dist/chunk-P4I4RKBY.js.map +1 -0
- package/dist/{chunk-PBEKMDUH.js → chunk-TWUDB36F.js} +62 -54
- package/dist/chunk-TWUDB36F.js.map +1 -0
- package/dist/{chunk-PB5DLLVC.js → chunk-VNANPKR2.js} +256 -30
- package/dist/chunk-VNANPKR2.js.map +1 -0
- package/dist/index.js +481 -20
- package/dist/index.js.map +1 -1
- package/dist/{install-ui-TXV7A34M.js → install-ui-CCZ3XJDE.js} +263 -41
- package/dist/install-ui-CCZ3XJDE.js.map +1 -0
- package/dist/{plan-SIXVCXCK.js → plan-5WHKVACB.js} +95 -40
- package/dist/plan-5WHKVACB.js.map +1 -0
- package/package.json +9 -4
- package/dist/chunk-PB5DLLVC.js.map +0 -1
- package/dist/chunk-PBEKMDUH.js.map +0 -1
- package/dist/install-ui-TXV7A34M.js.map +0 -1
- package/dist/plan-SIXVCXCK.js.map +0 -1
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
detectPackageManager,
|
|
4
|
+
installDependencies,
|
|
5
|
+
runTestsWithCoverage
|
|
6
|
+
} from "./chunk-P4I4RKBY.js";
|
|
2
7
|
|
|
3
8
|
// src/utils/prompts.ts
|
|
4
9
|
import * as p from "@clack/prompts";
|
|
@@ -94,38 +99,125 @@ async function multiselect2(options) {
|
|
|
94
99
|
return handleCancel(result);
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
// src/utils/
|
|
98
|
-
import { existsSync,
|
|
102
|
+
// src/utils/coverage-detect.ts
|
|
103
|
+
import { existsSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
99
104
|
import { join as join2 } from "path";
|
|
105
|
+
var VITEST_CONFIG_FILES = [
|
|
106
|
+
"vitest.config.ts",
|
|
107
|
+
"vitest.config.js",
|
|
108
|
+
"vitest.config.mts",
|
|
109
|
+
"vitest.config.mjs"
|
|
110
|
+
];
|
|
111
|
+
function checkPackageDeps(projectPath) {
|
|
112
|
+
try {
|
|
113
|
+
const pkgPath = join2(projectPath, "package.json");
|
|
114
|
+
if (!existsSync(pkgPath)) return { hasVitest: false, hasCoveragePackage: false };
|
|
115
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
116
|
+
const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
117
|
+
const hasVitest = "vitest" in deps;
|
|
118
|
+
const hasCoveragePackage = "@vitest/coverage-v8" in deps || "@vitest/coverage-istanbul" in deps;
|
|
119
|
+
return { hasVitest, hasCoveragePackage };
|
|
120
|
+
} catch {
|
|
121
|
+
return { hasVitest: false, hasCoveragePackage: false };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function findVitestConfig(projectPath) {
|
|
125
|
+
for (const configFile of VITEST_CONFIG_FILES) {
|
|
126
|
+
const configPath = join2(projectPath, configFile);
|
|
127
|
+
if (existsSync(configPath)) {
|
|
128
|
+
return configPath;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
function parseCoverageConfig(configPath) {
|
|
134
|
+
try {
|
|
135
|
+
const content = readFileSync2(configPath, "utf-8");
|
|
136
|
+
const hasCoverageConfig = /coverage\s*:\s*\{/.test(content);
|
|
137
|
+
if (!hasCoverageConfig) {
|
|
138
|
+
return { hasCoverageConfig: false, coverageProvider: null };
|
|
139
|
+
}
|
|
140
|
+
const providerMatch = content.match(/provider\s*:\s*["']?(v8|istanbul)["']?/);
|
|
141
|
+
const coverageProvider = providerMatch ? providerMatch[1] : null;
|
|
142
|
+
return { hasCoverageConfig, coverageProvider };
|
|
143
|
+
} catch {
|
|
144
|
+
return { hasCoverageConfig: false, coverageProvider: null };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function findCoverageData(projectPath) {
|
|
148
|
+
const coverageDataPath = join2(projectPath, "coverage", "coverage-final.json");
|
|
149
|
+
if (existsSync(coverageDataPath)) {
|
|
150
|
+
try {
|
|
151
|
+
const stats = statSync(coverageDataPath);
|
|
152
|
+
const age = Date.now() - stats.mtimeMs;
|
|
153
|
+
return { path: coverageDataPath, age };
|
|
154
|
+
} catch {
|
|
155
|
+
return { path: coverageDataPath, age: null };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { path: null, age: null };
|
|
159
|
+
}
|
|
160
|
+
function detectCoverageSetup(projectPath) {
|
|
161
|
+
const { hasVitest, hasCoveragePackage } = checkPackageDeps(projectPath);
|
|
162
|
+
const vitestConfigPath = findVitestConfig(projectPath);
|
|
163
|
+
const hasVitestConfig = vitestConfigPath !== null;
|
|
164
|
+
let hasCoverageConfig = false;
|
|
165
|
+
let coverageProvider = null;
|
|
166
|
+
if (vitestConfigPath) {
|
|
167
|
+
const coverageInfo = parseCoverageConfig(vitestConfigPath);
|
|
168
|
+
hasCoverageConfig = coverageInfo.hasCoverageConfig;
|
|
169
|
+
coverageProvider = coverageInfo.coverageProvider;
|
|
170
|
+
}
|
|
171
|
+
const coverageData = findCoverageData(projectPath);
|
|
172
|
+
const hasCoverageData = coverageData.path !== null;
|
|
173
|
+
const needsCoveragePackage = hasVitest && !hasCoveragePackage;
|
|
174
|
+
const needsCoverageConfig = hasVitest && hasVitestConfig && !hasCoverageConfig;
|
|
175
|
+
return {
|
|
176
|
+
hasVitest,
|
|
177
|
+
hasVitestConfig,
|
|
178
|
+
vitestConfigPath,
|
|
179
|
+
hasCoverageConfig,
|
|
180
|
+
coverageProvider,
|
|
181
|
+
hasCoverageData,
|
|
182
|
+
coverageDataPath: coverageData.path,
|
|
183
|
+
needsCoveragePackage,
|
|
184
|
+
needsCoverageConfig,
|
|
185
|
+
coverageDataAge: coverageData.age
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/utils/next-detect.ts
|
|
190
|
+
import { existsSync as existsSync2, readdirSync } from "fs";
|
|
191
|
+
import { join as join3 } from "path";
|
|
100
192
|
function fileExists(projectPath, relPath) {
|
|
101
|
-
return
|
|
193
|
+
return existsSync2(join3(projectPath, relPath));
|
|
102
194
|
}
|
|
103
195
|
function detectNextAppRouter(projectPath) {
|
|
104
|
-
const roots = ["app",
|
|
196
|
+
const roots = ["app", join3("src", "app")];
|
|
105
197
|
const candidates = [];
|
|
106
198
|
let chosenRoot = null;
|
|
107
199
|
for (const root of roots) {
|
|
108
|
-
if (
|
|
200
|
+
if (existsSync2(join3(projectPath, root))) {
|
|
109
201
|
chosenRoot = root;
|
|
110
202
|
break;
|
|
111
203
|
}
|
|
112
204
|
}
|
|
113
205
|
if (!chosenRoot) return null;
|
|
114
206
|
const entryCandidates = [
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
207
|
+
join3(chosenRoot, "layout.tsx"),
|
|
208
|
+
join3(chosenRoot, "layout.jsx"),
|
|
209
|
+
join3(chosenRoot, "layout.ts"),
|
|
210
|
+
join3(chosenRoot, "layout.js"),
|
|
119
211
|
// Fallbacks (less ideal, but can work):
|
|
120
|
-
|
|
121
|
-
|
|
212
|
+
join3(chosenRoot, "page.tsx"),
|
|
213
|
+
join3(chosenRoot, "page.jsx")
|
|
122
214
|
];
|
|
123
215
|
for (const rel of entryCandidates) {
|
|
124
216
|
if (fileExists(projectPath, rel)) candidates.push(rel);
|
|
125
217
|
}
|
|
126
218
|
return {
|
|
127
219
|
appRoot: chosenRoot,
|
|
128
|
-
appRootAbs:
|
|
220
|
+
appRootAbs: join3(projectPath, chosenRoot),
|
|
129
221
|
candidates
|
|
130
222
|
};
|
|
131
223
|
}
|
|
@@ -169,7 +261,7 @@ function findNextAppRouterProjects(rootDir, options) {
|
|
|
169
261
|
if (!ent.isDirectory) continue;
|
|
170
262
|
if (ignoreDirs.has(ent.name)) continue;
|
|
171
263
|
if (ent.name.startsWith(".") && ent.name !== ".") continue;
|
|
172
|
-
walk(
|
|
264
|
+
walk(join3(dir, ent.name), depth + 1);
|
|
173
265
|
}
|
|
174
266
|
}
|
|
175
267
|
walk(rootDir, 0);
|
|
@@ -177,15 +269,15 @@ function findNextAppRouterProjects(rootDir, options) {
|
|
|
177
269
|
}
|
|
178
270
|
|
|
179
271
|
// src/utils/eslint-config-inject.ts
|
|
180
|
-
import { existsSync as
|
|
181
|
-
import { join as
|
|
272
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
273
|
+
import { join as join4, relative, dirname as dirname2 } from "path";
|
|
182
274
|
import { parseExpression, parseModule, generateCode } from "magicast";
|
|
183
275
|
import { findWorkspaceRoot } from "uilint-core/node";
|
|
184
276
|
var CONFIG_EXTENSIONS = [".ts", ".mjs", ".js", ".cjs"];
|
|
185
277
|
function findEslintConfigFile(projectPath) {
|
|
186
278
|
for (const ext of CONFIG_EXTENSIONS) {
|
|
187
|
-
const configPath =
|
|
188
|
-
if (
|
|
279
|
+
const configPath = join4(projectPath, `eslint.config${ext}`);
|
|
280
|
+
if (existsSync3(configPath)) {
|
|
189
281
|
return configPath;
|
|
190
282
|
}
|
|
191
283
|
}
|
|
@@ -384,6 +476,15 @@ function collectTopLevelBindings(program) {
|
|
|
384
476
|
const names = /* @__PURE__ */ new Set();
|
|
385
477
|
if (!program || program.type !== "Program") return names;
|
|
386
478
|
for (const stmt of program.body ?? []) {
|
|
479
|
+
if (stmt?.type === "ImportDeclaration") {
|
|
480
|
+
for (const spec of stmt.specifiers ?? []) {
|
|
481
|
+
const local = spec?.local;
|
|
482
|
+
if (local?.type === "Identifier" && typeof local.name === "string") {
|
|
483
|
+
names.add(local.name);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
387
488
|
if (stmt?.type === "VariableDeclaration") {
|
|
388
489
|
for (const decl of stmt.declarations ?? []) {
|
|
389
490
|
const id = decl?.id;
|
|
@@ -405,22 +506,45 @@ function chooseUniqueIdentifier(base, used) {
|
|
|
405
506
|
while (used.has(`${base}${i}`)) i++;
|
|
406
507
|
return `${base}${i}`;
|
|
407
508
|
}
|
|
509
|
+
function findExistingDefaultImportLocalName(program, from) {
|
|
510
|
+
if (!program || program.type !== "Program") return null;
|
|
511
|
+
for (const stmt of program.body ?? []) {
|
|
512
|
+
if (stmt?.type !== "ImportDeclaration") continue;
|
|
513
|
+
const src = stmt.source?.value;
|
|
514
|
+
if (typeof src !== "string" || src !== from) continue;
|
|
515
|
+
for (const spec of stmt.specifiers ?? []) {
|
|
516
|
+
if (spec?.type === "ImportDefaultSpecifier") {
|
|
517
|
+
const local = spec.local;
|
|
518
|
+
if (local?.type === "Identifier" && typeof local.name === "string") {
|
|
519
|
+
return local.name;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
408
526
|
function addLocalRuleImportsAst(mod, selectedRules, configPath, rulesRoot, fileExtension = ".js") {
|
|
409
527
|
const importNames = /* @__PURE__ */ new Map();
|
|
410
528
|
let changed = false;
|
|
411
529
|
const configDir = dirname2(configPath);
|
|
412
|
-
const rulesDir =
|
|
530
|
+
const rulesDir = join4(rulesRoot, ".uilint", "rules");
|
|
413
531
|
const relativeRulesPath = relative(configDir, rulesDir).replace(/\\/g, "/");
|
|
414
532
|
const normalizedRulesPath = relativeRulesPath.startsWith("./") || relativeRulesPath.startsWith("../") ? relativeRulesPath : `./${relativeRulesPath}`;
|
|
415
533
|
const used = collectTopLevelBindings(mod.$ast);
|
|
416
534
|
for (const rule of selectedRules) {
|
|
535
|
+
const rulePath = `${normalizedRulesPath}/${rule.id}${fileExtension}`;
|
|
536
|
+
const existingLocal = findExistingDefaultImportLocalName(mod.$ast, rulePath);
|
|
537
|
+
if (existingLocal) {
|
|
538
|
+
importNames.set(rule.id, existingLocal);
|
|
539
|
+
used.add(existingLocal);
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
417
542
|
const importName = chooseUniqueIdentifier(
|
|
418
543
|
`${rule.id.replace(/-([a-z])/g, (_, c) => c.toUpperCase()).replace(/^./, (c) => c.toUpperCase())}Rule`,
|
|
419
544
|
used
|
|
420
545
|
);
|
|
421
546
|
importNames.set(rule.id, importName);
|
|
422
547
|
used.add(importName);
|
|
423
|
-
const rulePath = `${normalizedRulesPath}/${rule.id}${fileExtension}`;
|
|
424
548
|
mod.imports.$add({
|
|
425
549
|
imported: "default",
|
|
426
550
|
local: importName,
|
|
@@ -437,7 +561,7 @@ function addLocalRuleRequiresAst(program, selectedRules, configPath, rulesRoot,
|
|
|
437
561
|
return { importNames, changed };
|
|
438
562
|
}
|
|
439
563
|
const configDir = dirname2(configPath);
|
|
440
|
-
const rulesDir =
|
|
564
|
+
const rulesDir = join4(rulesRoot, ".uilint", "rules");
|
|
441
565
|
const relativeRulesPath = relative(configDir, rulesDir).replace(/\\/g, "/");
|
|
442
566
|
const normalizedRulesPath = relativeRulesPath.startsWith("./") || relativeRulesPath.startsWith("../") ? relativeRulesPath : `./${relativeRulesPath}`;
|
|
443
567
|
const used = collectTopLevelBindings(program);
|
|
@@ -596,7 +720,7 @@ async function installEslintPlugin(opts) {
|
|
|
596
720
|
};
|
|
597
721
|
}
|
|
598
722
|
const configFilename = getEslintConfigFilename(configPath);
|
|
599
|
-
const original =
|
|
723
|
+
const original = readFileSync3(configPath, "utf-8");
|
|
600
724
|
const isCommonJS = configPath.endsWith(".cjs");
|
|
601
725
|
const ast = getUilintEslintConfigInfoFromSourceAst(original);
|
|
602
726
|
if ("error" in ast) {
|
|
@@ -648,10 +772,10 @@ async function installEslintPlugin(opts) {
|
|
|
648
772
|
};
|
|
649
773
|
}
|
|
650
774
|
let modifiedAst = false;
|
|
651
|
-
const localRulesDir =
|
|
775
|
+
const localRulesDir = join4(opts.projectPath, ".uilint", "rules");
|
|
652
776
|
const workspaceRoot = findWorkspaceRoot(opts.projectPath);
|
|
653
|
-
const workspaceRulesDir =
|
|
654
|
-
const rulesRoot =
|
|
777
|
+
const workspaceRulesDir = join4(workspaceRoot, ".uilint", "rules");
|
|
778
|
+
const rulesRoot = existsSync3(localRulesDir) ? opts.projectPath : workspaceRoot;
|
|
655
779
|
const isTypeScriptConfig = configPath.endsWith(".ts");
|
|
656
780
|
let fileExtension = isTypeScriptConfig ? "" : ".js";
|
|
657
781
|
let ruleImportNames;
|
|
@@ -732,7 +856,7 @@ async function uninstallEslintPlugin(options) {
|
|
|
732
856
|
};
|
|
733
857
|
}
|
|
734
858
|
try {
|
|
735
|
-
const original =
|
|
859
|
+
const original = readFileSync3(configPath, "utf-8");
|
|
736
860
|
let updated = original.replace(
|
|
737
861
|
/^import\s+\{[^}]*\}\s+from\s+["'][^"']*\.uilint\/rules[^"']*["'];?\s*$/gm,
|
|
738
862
|
""
|
|
@@ -846,7 +970,7 @@ function extractOptionsFromValueNode(valueNode) {
|
|
|
846
970
|
function readRuleConfigsFromConfig(configPath) {
|
|
847
971
|
const configs = /* @__PURE__ */ new Map();
|
|
848
972
|
try {
|
|
849
|
-
const source =
|
|
973
|
+
const source = readFileSync3(configPath, "utf-8");
|
|
850
974
|
const mod = parseModule(source);
|
|
851
975
|
const found = findExportedConfigArrayExpression(mod);
|
|
852
976
|
if (!found) {
|
|
@@ -887,7 +1011,7 @@ function findRulePropertyInConfigArray(arrayExpr, ruleId) {
|
|
|
887
1011
|
}
|
|
888
1012
|
function updateRuleSeverityInConfig(configPath, ruleId, severity) {
|
|
889
1013
|
try {
|
|
890
|
-
const source =
|
|
1014
|
+
const source = readFileSync3(configPath, "utf-8");
|
|
891
1015
|
const mod = parseModule(source);
|
|
892
1016
|
const found = findExportedConfigArrayExpression(mod);
|
|
893
1017
|
if (!found) {
|
|
@@ -938,7 +1062,7 @@ function updateRuleSeverityInConfig(configPath, ruleId, severity) {
|
|
|
938
1062
|
}
|
|
939
1063
|
function updateRuleConfigInConfig(configPath, ruleId, severity, options) {
|
|
940
1064
|
try {
|
|
941
|
-
const source =
|
|
1065
|
+
const source = readFileSync3(configPath, "utf-8");
|
|
942
1066
|
const mod = parseModule(source);
|
|
943
1067
|
const found = findExportedConfigArrayExpression(mod);
|
|
944
1068
|
if (!found) {
|
|
@@ -971,6 +1095,104 @@ function updateRuleConfigInConfig(configPath, ruleId, severity, options) {
|
|
|
971
1095
|
}
|
|
972
1096
|
}
|
|
973
1097
|
|
|
1098
|
+
// src/utils/coverage-prepare.ts
|
|
1099
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
1100
|
+
function injectCoverageConfig(vitestConfigPath) {
|
|
1101
|
+
try {
|
|
1102
|
+
const content = readFileSync4(vitestConfigPath, "utf-8");
|
|
1103
|
+
if (/coverage\s*:\s*\{/.test(content)) {
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1106
|
+
const testBlockRegex = /(test\s*:\s*\{)/;
|
|
1107
|
+
const match = content.match(testBlockRegex);
|
|
1108
|
+
if (!match) {
|
|
1109
|
+
return false;
|
|
1110
|
+
}
|
|
1111
|
+
const coverageConfig = `
|
|
1112
|
+
coverage: {
|
|
1113
|
+
provider: "v8",
|
|
1114
|
+
reporter: ["text", "json"],
|
|
1115
|
+
reportsDirectory: "./coverage",
|
|
1116
|
+
},`;
|
|
1117
|
+
const newContent = content.replace(
|
|
1118
|
+
testBlockRegex,
|
|
1119
|
+
`$1${coverageConfig}`
|
|
1120
|
+
);
|
|
1121
|
+
writeFileSync2(vitestConfigPath, newContent, "utf-8");
|
|
1122
|
+
return true;
|
|
1123
|
+
} catch {
|
|
1124
|
+
return false;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
async function prepareCoverage(options) {
|
|
1128
|
+
const { appRoot, onProgress, skipPackageInstall, skipTests } = options;
|
|
1129
|
+
const start = Date.now();
|
|
1130
|
+
const result = {
|
|
1131
|
+
packageAdded: false,
|
|
1132
|
+
configModified: false,
|
|
1133
|
+
testsRan: false,
|
|
1134
|
+
coverageGenerated: false,
|
|
1135
|
+
duration: 0
|
|
1136
|
+
};
|
|
1137
|
+
try {
|
|
1138
|
+
onProgress?.("Detecting coverage setup...", "detect");
|
|
1139
|
+
const setup = detectCoverageSetup(appRoot);
|
|
1140
|
+
if (!setup.hasVitest) {
|
|
1141
|
+
result.error = "Vitest not found in dependencies";
|
|
1142
|
+
result.duration = Date.now() - start;
|
|
1143
|
+
return result;
|
|
1144
|
+
}
|
|
1145
|
+
if (setup.needsCoveragePackage && !skipPackageInstall) {
|
|
1146
|
+
onProgress?.("Installing @vitest/coverage-v8...", "install");
|
|
1147
|
+
const pm = detectPackageManager(appRoot);
|
|
1148
|
+
try {
|
|
1149
|
+
await installDependencies(pm, appRoot, ["@vitest/coverage-v8"]);
|
|
1150
|
+
result.packageAdded = true;
|
|
1151
|
+
} catch (err) {
|
|
1152
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1153
|
+
result.error = `Failed to install coverage package: ${msg}`;
|
|
1154
|
+
result.duration = Date.now() - start;
|
|
1155
|
+
return result;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
if (setup.needsCoverageConfig && setup.vitestConfigPath) {
|
|
1159
|
+
onProgress?.("Adding coverage configuration...", "config");
|
|
1160
|
+
result.configModified = injectCoverageConfig(setup.vitestConfigPath);
|
|
1161
|
+
}
|
|
1162
|
+
if (!skipTests) {
|
|
1163
|
+
const updatedSetup = detectCoverageSetup(appRoot);
|
|
1164
|
+
if (!updatedSetup.hasCoverageData || result.configModified) {
|
|
1165
|
+
onProgress?.("Running tests with coverage...", "test");
|
|
1166
|
+
const pm = detectPackageManager(appRoot);
|
|
1167
|
+
try {
|
|
1168
|
+
await runTestsWithCoverage(pm, appRoot);
|
|
1169
|
+
result.testsRan = true;
|
|
1170
|
+
} catch (err) {
|
|
1171
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1172
|
+
result.error = `Tests failed: ${msg}`;
|
|
1173
|
+
}
|
|
1174
|
+
const finalSetup = detectCoverageSetup(appRoot);
|
|
1175
|
+
result.coverageGenerated = finalSetup.hasCoverageData;
|
|
1176
|
+
}
|
|
1177
|
+
} else {
|
|
1178
|
+
onProgress?.("Skipping tests (skipTests=true)", "skip");
|
|
1179
|
+
}
|
|
1180
|
+
result.duration = Date.now() - start;
|
|
1181
|
+
return result;
|
|
1182
|
+
} catch (err) {
|
|
1183
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1184
|
+
result.error = `Coverage preparation failed: ${msg}`;
|
|
1185
|
+
result.duration = Date.now() - start;
|
|
1186
|
+
return result;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function needsCoveragePreparation(setup) {
|
|
1190
|
+
if (!setup.hasVitest) {
|
|
1191
|
+
return false;
|
|
1192
|
+
}
|
|
1193
|
+
return setup.needsCoveragePackage || setup.needsCoverageConfig || !setup.hasCoverageData;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
974
1196
|
export {
|
|
975
1197
|
pc,
|
|
976
1198
|
intro2 as intro,
|
|
@@ -995,6 +1217,10 @@ export {
|
|
|
995
1217
|
uninstallEslintPlugin,
|
|
996
1218
|
readRuleConfigsFromConfig,
|
|
997
1219
|
updateRuleSeverityInConfig,
|
|
998
|
-
updateRuleConfigInConfig
|
|
1220
|
+
updateRuleConfigInConfig,
|
|
1221
|
+
detectCoverageSetup,
|
|
1222
|
+
injectCoverageConfig,
|
|
1223
|
+
prepareCoverage,
|
|
1224
|
+
needsCoveragePreparation
|
|
999
1225
|
};
|
|
1000
|
-
//# sourceMappingURL=chunk-
|
|
1226
|
+
//# sourceMappingURL=chunk-VNANPKR2.js.map
|