@rpcbase/test 0.326.0 → 0.327.0
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/package.json +1 -1
- package/dist/clearDatabase.d.ts +0 -2
- package/dist/clearDatabase.d.ts.map +0 -1
- package/dist/clearDatabase.js +0 -12
- package/dist/clearDatabase.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -799
- package/dist/cli.js.map +0 -1
- package/dist/coverage/collect.d.ts +0 -5
- package/dist/coverage/collect.d.ts.map +0 -1
- package/dist/coverage/collect.js +0 -113
- package/dist/coverage/collect.js.map +0 -1
- package/dist/coverage/config-loader.d.ts +0 -10
- package/dist/coverage/config-loader.d.ts.map +0 -1
- package/dist/coverage/config-loader.js +0 -286
- package/dist/coverage/config-loader.js.map +0 -1
- package/dist/coverage/config.d.ts +0 -3
- package/dist/coverage/config.d.ts.map +0 -1
- package/dist/coverage/config.js +0 -101
- package/dist/coverage/config.js.map +0 -1
- package/dist/coverage/console-text-report.d.ts +0 -5
- package/dist/coverage/console-text-report.d.ts.map +0 -1
- package/dist/coverage/console-text-report.js +0 -240
- package/dist/coverage/console-text-report.js.map +0 -1
- package/dist/coverage/files.d.ts +0 -4
- package/dist/coverage/files.d.ts.map +0 -1
- package/dist/coverage/files.js +0 -68
- package/dist/coverage/files.js.map +0 -1
- package/dist/coverage/fixtures.d.ts +0 -5
- package/dist/coverage/fixtures.d.ts.map +0 -1
- package/dist/coverage/fixtures.js +0 -45
- package/dist/coverage/fixtures.js.map +0 -1
- package/dist/coverage/global-setup.d.ts +0 -3
- package/dist/coverage/global-setup.d.ts.map +0 -1
- package/dist/coverage/global-setup.js +0 -18
- package/dist/coverage/global-setup.js.map +0 -1
- package/dist/coverage/index.d.ts +0 -10
- package/dist/coverage/index.d.ts.map +0 -1
- package/dist/coverage/index.js +0 -62
- package/dist/coverage/index.js.map +0 -1
- package/dist/coverage/report.d.ts +0 -7
- package/dist/coverage/report.d.ts.map +0 -1
- package/dist/coverage/report.js +0 -529
- package/dist/coverage/report.js.map +0 -1
- package/dist/coverage/reporter.d.ts +0 -16
- package/dist/coverage/reporter.d.ts.map +0 -1
- package/dist/coverage/reporter.js +0 -61
- package/dist/coverage/reporter.js.map +0 -1
- package/dist/coverage/types.d.ts +0 -45
- package/dist/coverage/types.d.ts.map +0 -1
- package/dist/coverage/v8-tracker.d.ts +0 -6
- package/dist/coverage/v8-tracker.d.ts.map +0 -1
- package/dist/coverage/v8-tracker.js +0 -168
- package/dist/coverage/v8-tracker.js.map +0 -1
- package/dist/defineConfig.d.ts +0 -3
- package/dist/defineConfig.d.ts.map +0 -1
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -80
- package/dist/index.js.map +0 -1
- package/dist/register-tty.cjs +0 -33
- package/dist/serverCoverage.d.ts +0 -8
- package/dist/serverCoverage.d.ts.map +0 -1
- package/dist/serverCoverage.js +0 -42
- package/dist/serverCoverage.js.map +0 -1
- package/dist/vitest.config.d.ts +0 -3
- package/dist/vitest.config.d.ts.map +0 -1
- package/dist/vitest.config.js +0 -83
- package/dist/vitest.config.js.map +0 -1
package/dist/coverage/index.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
|
-
import { createCoverageConfig } from "./config.js";
|
|
5
|
-
import { createCoverageGlobalSetup } from "./global-setup.js";
|
|
6
|
-
import { createCoverageFixtures } from "./fixtures.js";
|
|
7
|
-
import "node:fs/promises";
|
|
8
|
-
import "node:url";
|
|
9
|
-
import "istanbul-lib-coverage";
|
|
10
|
-
import "istanbul-lib-instrument";
|
|
11
|
-
import "fast-glob";
|
|
12
|
-
import "picomatch";
|
|
13
|
-
import "v8-to-istanbul";
|
|
14
|
-
function createCoverageHarness(options) {
|
|
15
|
-
const config = createCoverageConfig(options);
|
|
16
|
-
const globalSetup = createCoverageGlobalSetup(config);
|
|
17
|
-
const reporterPath = resolveReporterPath();
|
|
18
|
-
return {
|
|
19
|
-
config,
|
|
20
|
-
globalSetup,
|
|
21
|
-
extendTest(baseTest) {
|
|
22
|
-
return createCoverageFixtures(baseTest, config);
|
|
23
|
-
},
|
|
24
|
-
reporterEntry() {
|
|
25
|
-
return [reporterPath, { coverageConfig: config }];
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function resolveReporterPath() {
|
|
30
|
-
const require2 = createRequire(path.join(process.cwd(), "package.json"));
|
|
31
|
-
const entryPath = require2.resolve("@rpcbase/test");
|
|
32
|
-
const pkgDir = findPackageRoot(entryPath) ?? path.resolve(path.dirname(entryPath), "..", "..");
|
|
33
|
-
const distReporter = path.join(pkgDir, "dist", "coverage", "reporter.js");
|
|
34
|
-
if (fs.existsSync(distReporter)) {
|
|
35
|
-
return distReporter;
|
|
36
|
-
}
|
|
37
|
-
const srcReporter = path.join(pkgDir, "src", "coverage", "reporter.ts");
|
|
38
|
-
if (fs.existsSync(srcReporter)) {
|
|
39
|
-
return srcReporter;
|
|
40
|
-
}
|
|
41
|
-
return distReporter;
|
|
42
|
-
}
|
|
43
|
-
function findPackageRoot(entryPath) {
|
|
44
|
-
let dir = path.dirname(entryPath);
|
|
45
|
-
while (true) {
|
|
46
|
-
if (fs.existsSync(path.join(dir, "package.json"))) {
|
|
47
|
-
return dir;
|
|
48
|
-
}
|
|
49
|
-
const parent = path.dirname(dir);
|
|
50
|
-
if (parent === dir) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
dir = parent;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
export {
|
|
57
|
-
createCoverageConfig,
|
|
58
|
-
createCoverageFixtures,
|
|
59
|
-
createCoverageGlobalSetup,
|
|
60
|
-
createCoverageHarness
|
|
61
|
-
};
|
|
62
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/coverage/index.ts"],"sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { createRequire } from \"node:module\"\n\nimport { createCoverageConfig } from \"./config\"\nimport { createCoverageGlobalSetup } from \"./global-setup\"\nimport { createCoverageFixtures } from \"./fixtures\"\nimport type { CoverageHarness, CoverageHarnessOptions } from \"./types\"\n\n\nexport function createCoverageHarness(options: CoverageHarnessOptions): CoverageHarness {\n const config = createCoverageConfig(options)\n const globalSetup = createCoverageGlobalSetup(config)\n\n const reporterPath = resolveReporterPath()\n\n return {\n config,\n globalSetup,\n extendTest<T extends { extend: (fixtures: any) => unknown }>(baseTest: T): T {\n return createCoverageFixtures(baseTest, config)\n },\n reporterEntry() {\n return [reporterPath, { coverageConfig: config }]\n },\n }\n}\n\nfunction resolveReporterPath(): string {\n const require = createRequire(path.join(process.cwd(), \"package.json\"))\n const entryPath = require.resolve(\"@rpcbase/test\")\n const pkgDir = findPackageRoot(entryPath) ?? path.resolve(path.dirname(entryPath), \"..\", \"..\")\n\n const distReporter = path.join(pkgDir, \"dist\", \"coverage\", \"reporter.js\")\n if (fs.existsSync(distReporter)) {\n return distReporter\n }\n\n const srcReporter = path.join(pkgDir, \"src\", \"coverage\", \"reporter.ts\")\n if (fs.existsSync(srcReporter)) {\n return srcReporter\n }\n\n return distReporter\n}\n\nfunction findPackageRoot(entryPath: string): string | null {\n let dir = path.dirname(entryPath)\n while (true) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) {\n return dir\n }\n const parent = path.dirname(dir)\n if (parent === dir) {\n return null\n }\n dir = parent\n }\n}\n\nexport { CoverageReporter } from \"./reporter\"\nexport { createCoverageConfig } from \"./config\"\nexport { generateCoverageReport } from \"./report\"\nexport { createCoverageFixtures } from \"./fixtures\"\nexport { createCoverageGlobalSetup } from \"./global-setup\"\nexport { findCoverageFiles, removeCoverageFiles } from \"./files\"\nexport type * from \"./types\"\n"],"names":["require"],"mappings":";;;;;;;;;;;;;AAUO,SAAS,sBAAsB,SAAkD;AACtF,QAAM,SAAS,qBAAqB,OAAO;AAC3C,QAAM,cAAc,0BAA0B,MAAM;AAEpD,QAAM,eAAe,oBAAA;AAErB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAA6D,UAAgB;AAC3E,aAAO,uBAAuB,UAAU,MAAM;AAAA,IAChD;AAAA,IACA,gBAAgB;AACd,aAAO,CAAC,cAAc,EAAE,gBAAgB,QAAQ;AAAA,IAClD;AAAA,EAAA;AAEJ;AAEA,SAAS,sBAA8B;AACrC,QAAMA,WAAU,cAAc,KAAK,KAAK,QAAQ,IAAA,GAAO,cAAc,CAAC;AACtE,QAAM,YAAYA,SAAQ,QAAQ,eAAe;AACjD,QAAM,SAAS,gBAAgB,SAAS,KAAK,KAAK,QAAQ,KAAK,QAAQ,SAAS,GAAG,MAAM,IAAI;AAE7F,QAAM,eAAe,KAAK,KAAK,QAAQ,QAAQ,YAAY,aAAa;AACxE,MAAI,GAAG,WAAW,YAAY,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,KAAK,KAAK,QAAQ,OAAO,YAAY,aAAa;AACtE,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,WAAkC;AACzD,MAAI,MAAM,KAAK,QAAQ,SAAS;AAChC,SAAO,MAAM;AACX,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,cAAc,CAAC,GAAG;AACjD,aAAO;AAAA,IACT;AACA,UAAM,SAAS,KAAK,QAAQ,GAAG;AAC/B,QAAI,WAAW,KAAK;AAClB,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { CoverageConfig } from './types';
|
|
2
|
-
export declare class CoverageThresholdError extends Error {
|
|
3
|
-
constructor(message: string);
|
|
4
|
-
}
|
|
5
|
-
export declare function generateCoverageReport(config: CoverageConfig): Promise<void>;
|
|
6
|
-
export declare function collectCoveredFiles(config: CoverageConfig): Promise<string[]>;
|
|
7
|
-
//# sourceMappingURL=report.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/coverage/report.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAA+C,MAAM,SAAS,CAAA;AAK1F,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoElF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsBnF"}
|
package/dist/coverage/report.js
DELETED
|
@@ -1,529 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import * as libCoverage from "istanbul-lib-coverage";
|
|
5
|
-
import * as libInstrument from "istanbul-lib-instrument";
|
|
6
|
-
import fg from "fast-glob";
|
|
7
|
-
import picomatch from "picomatch";
|
|
8
|
-
import v8ToIstanbul from "v8-to-istanbul";
|
|
9
|
-
import { createCollectCoverageMatcher, toPosix } from "./collect.js";
|
|
10
|
-
import { generateConsoleTextCoverageReport } from "./console-text-report.js";
|
|
11
|
-
import { findCoverageFiles } from "./files.js";
|
|
12
|
-
const TEXT_REPORT_FILENAME = "coverage.txt";
|
|
13
|
-
class CoverageThresholdError extends Error {
|
|
14
|
-
constructor(message) {
|
|
15
|
-
super(message);
|
|
16
|
-
this.name = "CoverageThresholdError";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
async function generateCoverageReport(config) {
|
|
20
|
-
const coverageFiles = await findCoverageFiles(config);
|
|
21
|
-
if (coverageFiles.length === 0) {
|
|
22
|
-
console.warn("[coverage] no V8 coverage artifacts were generated");
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const coverageLib = resolveCoverageLib();
|
|
26
|
-
const coverageMap = coverageLib.createCoverageMap({});
|
|
27
|
-
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir);
|
|
28
|
-
for (const file of coverageFiles) {
|
|
29
|
-
const payload = await readCoverageFile(file);
|
|
30
|
-
if (!payload) {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
for (const script of payload.scripts) {
|
|
34
|
-
await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (config.includeAllFiles) {
|
|
38
|
-
await includeUntestedFiles(coverageMap, config, matchesCollectCoverageFrom);
|
|
39
|
-
}
|
|
40
|
-
if (coverageMap.files().length === 0) {
|
|
41
|
-
console.warn("[coverage] no library files matched the coverage filters");
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
await fs.rm(config.coverageReportDir, { recursive: true, force: true });
|
|
45
|
-
await fs.mkdir(config.coverageReportDir, { recursive: true });
|
|
46
|
-
const { createContext, reports } = await loadIstanbulModules();
|
|
47
|
-
const context = createContext({
|
|
48
|
-
dir: config.coverageReportDir,
|
|
49
|
-
coverageMap,
|
|
50
|
-
defaultSummarizer: "pkg"
|
|
51
|
-
});
|
|
52
|
-
const { output: reportOutput, summarizer } = generateConsoleTextCoverageReport(reports, context);
|
|
53
|
-
process.stdout.write(reportOutput);
|
|
54
|
-
reports.create("text", { file: TEXT_REPORT_FILENAME, summarizer }).execute(context);
|
|
55
|
-
console.log(`[coverage] Full text report saved to ${path.join(config.coverageReportDir, TEXT_REPORT_FILENAME)}`);
|
|
56
|
-
const summary = coverageMap.getCoverageSummary();
|
|
57
|
-
enforceThresholds(summary, config.thresholds, "global");
|
|
58
|
-
const targets = Array.isArray(config.thresholdTargets) ? config.thresholdTargets : [];
|
|
59
|
-
if (targets.length > 0) {
|
|
60
|
-
const fileSummaries = buildFileSummaries(coverageMap, config.rootDir);
|
|
61
|
-
for (const target of targets) {
|
|
62
|
-
const matcher = createGlobMatcher(target.pattern);
|
|
63
|
-
const matchResult = collectTargetSummary(fileSummaries, matcher, coverageLib);
|
|
64
|
-
if (matchResult.matched === 0) {
|
|
65
|
-
console.warn(
|
|
66
|
-
`[coverage] threshold pattern "${target.pattern}" did not match any files — skipping`
|
|
67
|
-
);
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
enforceThresholds(matchResult.summary, target.thresholds, target.pattern);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
async function collectCoveredFiles(config) {
|
|
75
|
-
const coverageFiles = await findCoverageFiles(config);
|
|
76
|
-
if (coverageFiles.length === 0) {
|
|
77
|
-
return [];
|
|
78
|
-
}
|
|
79
|
-
const coverageLib = resolveCoverageLib();
|
|
80
|
-
const coverageMap = coverageLib.createCoverageMap({});
|
|
81
|
-
const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir);
|
|
82
|
-
for (const file of coverageFiles) {
|
|
83
|
-
const payload = await readCoverageFile(file);
|
|
84
|
-
if (!payload) {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
for (const script of payload.scripts) {
|
|
88
|
-
await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return coverageMap.files().sort();
|
|
92
|
-
}
|
|
93
|
-
async function loadIstanbulModules() {
|
|
94
|
-
maybeForceColor();
|
|
95
|
-
const [libReportMod, reportsMod] = await Promise.all([
|
|
96
|
-
import("istanbul-lib-report"),
|
|
97
|
-
import("istanbul-reports")
|
|
98
|
-
]);
|
|
99
|
-
const createContext = typeof libReportMod.createContext === "function" ? libReportMod.createContext : libReportMod.default?.createContext;
|
|
100
|
-
if (typeof createContext !== "function") {
|
|
101
|
-
throw new Error("istanbul-lib-report exports are unavailable");
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
createContext,
|
|
105
|
-
reports: reportsMod.default ?? reportsMod
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
function maybeForceColor() {
|
|
109
|
-
if (process.stdout.isTTY) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
if (process.env.FORCE_COLOR !== void 0) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
if (process.env.NO_COLOR !== void 0 || process.env.NODE_DISABLE_COLORS !== void 0) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (process.env.CI !== void 0) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
process.env.FORCE_COLOR = "1";
|
|
122
|
-
}
|
|
123
|
-
async function mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom) {
|
|
124
|
-
const scriptPath = script.absolutePath;
|
|
125
|
-
if (!scriptPath) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
if (isNodeModulesPath(scriptPath)) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (isViteVirtualModulePath(scriptPath)) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
let source = script.source && script.source.length > 0 ? script.source : "";
|
|
135
|
-
if (!source) {
|
|
136
|
-
try {
|
|
137
|
-
source = await fs.readFile(scriptPath, "utf8");
|
|
138
|
-
} catch (error) {
|
|
139
|
-
const base = path.basename(scriptPath);
|
|
140
|
-
if (error?.code === "ENOENT" && base && !base.includes(".")) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
if (error?.code === "ENOENT" && !matchesCollectCoverageFrom(scriptPath)) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const sourceMap = await loadSourceMapForScript(scriptPath, source);
|
|
150
|
-
const converter = v8ToIstanbul(
|
|
151
|
-
scriptPath,
|
|
152
|
-
0,
|
|
153
|
-
sourceMap ? { source, sourceMap: { sourcemap: sourceMap } } : { source }
|
|
154
|
-
);
|
|
155
|
-
await converter.load();
|
|
156
|
-
converter.applyCoverage(script.functions);
|
|
157
|
-
const filtered = filterCoverageMap(converter.toIstanbul(), config, matchesCollectCoverageFrom);
|
|
158
|
-
if (Object.keys(filtered).length > 0) {
|
|
159
|
-
coverageMap.merge(filtered);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
async function readCoverageFile(file) {
|
|
163
|
-
try {
|
|
164
|
-
const raw = await fs.readFile(file, "utf8");
|
|
165
|
-
return JSON.parse(raw);
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.warn(`[coverage] failed to parse ${file}:`, error);
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function enforceThresholds(summary, thresholds, label = "global") {
|
|
172
|
-
const failures = [];
|
|
173
|
-
for (const metric of Object.keys(thresholds)) {
|
|
174
|
-
const minimum = thresholds[metric];
|
|
175
|
-
const actual = summary[metric]?.pct ?? 0;
|
|
176
|
-
if (actual < minimum) {
|
|
177
|
-
failures.push({ metric, actual, minimum });
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (failures.length === 0) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
const details = failures.map(({ metric, actual, minimum }) => `${metric}: ${actual.toFixed(2)}% < ${minimum}%`).join("; ");
|
|
184
|
-
throw new CoverageThresholdError(`[coverage] thresholds not met (target: ${label}) — ${details}`);
|
|
185
|
-
}
|
|
186
|
-
function resolveCoverageLib() {
|
|
187
|
-
const candidate = libCoverage;
|
|
188
|
-
if (typeof candidate.createCoverageMap === "function") {
|
|
189
|
-
return candidate;
|
|
190
|
-
}
|
|
191
|
-
if (candidate.default && typeof candidate.default.createCoverageMap === "function") {
|
|
192
|
-
return candidate.default;
|
|
193
|
-
}
|
|
194
|
-
throw new Error("istanbul-lib-coverage exports are unavailable");
|
|
195
|
-
}
|
|
196
|
-
function resolveInstrumentLib() {
|
|
197
|
-
const candidate = libInstrument;
|
|
198
|
-
if (typeof candidate.createInstrumenter === "function") {
|
|
199
|
-
return candidate;
|
|
200
|
-
}
|
|
201
|
-
if (candidate.default && typeof candidate.default.createInstrumenter === "function") {
|
|
202
|
-
return candidate.default;
|
|
203
|
-
}
|
|
204
|
-
throw new Error("istanbul-lib-instrument exports are unavailable");
|
|
205
|
-
}
|
|
206
|
-
async function includeUntestedFiles(coverageMap, config, matchesCollectCoverageFrom) {
|
|
207
|
-
const existing = new Set(
|
|
208
|
-
coverageMap.files().map((filePath) => path.resolve(String(filePath ?? "")))
|
|
209
|
-
);
|
|
210
|
-
const candidates = await findCollectCoverageFiles(config, matchesCollectCoverageFrom);
|
|
211
|
-
if (candidates.length === 0) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
const instrumentLib = resolveInstrumentLib();
|
|
215
|
-
const instrumenter = instrumentLib.createInstrumenter({
|
|
216
|
-
esModules: true,
|
|
217
|
-
parserPlugins: [
|
|
218
|
-
"typescript",
|
|
219
|
-
"jsx",
|
|
220
|
-
"classProperties",
|
|
221
|
-
"classPrivateProperties",
|
|
222
|
-
"classPrivateMethods",
|
|
223
|
-
"decorators-legacy",
|
|
224
|
-
"importMeta",
|
|
225
|
-
"topLevelAwait"
|
|
226
|
-
]
|
|
227
|
-
});
|
|
228
|
-
for (const filePath of candidates) {
|
|
229
|
-
const normalized = path.resolve(filePath);
|
|
230
|
-
if (existing.has(normalized)) {
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
const source = await fs.readFile(normalized, "utf8").catch(() => null);
|
|
234
|
-
if (source === null) {
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
try {
|
|
238
|
-
instrumenter.instrumentSync(source, normalized);
|
|
239
|
-
const fileCoverage = instrumenter.lastFileCoverage();
|
|
240
|
-
if (!fileCoverage) {
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
coverageMap.addFileCoverage(fileCoverage);
|
|
244
|
-
existing.add(normalized);
|
|
245
|
-
} catch (error) {
|
|
246
|
-
const relative = path.relative(config.rootDir, normalized);
|
|
247
|
-
console.warn(
|
|
248
|
-
`[coverage] failed to instrument ${relative && !relative.startsWith("..") ? relative : normalized}:`,
|
|
249
|
-
error
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
const DEFAULT_COLLECT_COVERAGE_IGNORES = [
|
|
255
|
-
"**/.git/**",
|
|
256
|
-
"**/.next/**",
|
|
257
|
-
"**/.turbo/**",
|
|
258
|
-
"**/.vite/**",
|
|
259
|
-
"**/.vitest/**",
|
|
260
|
-
"**/build/**",
|
|
261
|
-
"**/coverage/**",
|
|
262
|
-
"**/dist/**",
|
|
263
|
-
"**/node_modules/**",
|
|
264
|
-
"**/playwright-report/**",
|
|
265
|
-
"**/spec/**",
|
|
266
|
-
"**/test/**",
|
|
267
|
-
"**/test-results/**",
|
|
268
|
-
"**/tests/**",
|
|
269
|
-
"**/__tests__/**",
|
|
270
|
-
"**/*.d.ts",
|
|
271
|
-
"**/*.map"
|
|
272
|
-
];
|
|
273
|
-
async function findCollectCoverageFiles(config, matchesCollectCoverageFrom) {
|
|
274
|
-
const patterns = Array.isArray(config.collectCoverageFrom) ? config.collectCoverageFrom : [];
|
|
275
|
-
if (patterns.length === 0) {
|
|
276
|
-
return [];
|
|
277
|
-
}
|
|
278
|
-
const rawFiles = await fg(patterns, {
|
|
279
|
-
cwd: config.rootDir,
|
|
280
|
-
absolute: true,
|
|
281
|
-
dot: true,
|
|
282
|
-
onlyFiles: true,
|
|
283
|
-
unique: true,
|
|
284
|
-
followSymbolicLinks: false,
|
|
285
|
-
ignore: DEFAULT_COLLECT_COVERAGE_IGNORES
|
|
286
|
-
}).catch(() => []);
|
|
287
|
-
const collected = /* @__PURE__ */ new Set();
|
|
288
|
-
for (const file of rawFiles) {
|
|
289
|
-
const normalized = path.resolve(String(file ?? ""));
|
|
290
|
-
if (!normalized) {
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
if (normalized.endsWith(".d.ts") || normalized.endsWith(".map")) {
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
if (isNodeModulesPath(normalized)) {
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
if (isViteVirtualModulePath(normalized)) {
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
if (!matchesCollectCoverageFrom(normalized)) {
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
collected.add(normalized);
|
|
306
|
-
}
|
|
307
|
-
return Array.from(collected).sort();
|
|
308
|
-
}
|
|
309
|
-
function buildFileSummaries(coverageMap, rootDir) {
|
|
310
|
-
const normalizedRoot = path.resolve(rootDir);
|
|
311
|
-
return coverageMap.files().map((filePath) => {
|
|
312
|
-
const normalizedAbsolute = path.resolve(filePath);
|
|
313
|
-
const summary = coverageMap.fileCoverageFor(filePath).toSummary();
|
|
314
|
-
const relativePath = path.relative(normalizedRoot, normalizedAbsolute);
|
|
315
|
-
const candidates = /* @__PURE__ */ new Set();
|
|
316
|
-
if (relativePath) {
|
|
317
|
-
const relativePosix = toPosix(relativePath);
|
|
318
|
-
candidates.add(relativePosix);
|
|
319
|
-
candidates.add(`./${relativePosix}`);
|
|
320
|
-
} else {
|
|
321
|
-
candidates.add(toPosix(path.basename(normalizedAbsolute)));
|
|
322
|
-
}
|
|
323
|
-
return {
|
|
324
|
-
summary,
|
|
325
|
-
candidates: Array.from(candidates)
|
|
326
|
-
};
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
function collectTargetSummary(fileSummaries, matcher, coverageLib) {
|
|
330
|
-
const summary = coverageLib.createCoverageSummary();
|
|
331
|
-
let matched = 0;
|
|
332
|
-
for (const file of fileSummaries) {
|
|
333
|
-
if (file.candidates.some((candidate) => matcher(candidate))) {
|
|
334
|
-
summary.merge(file.summary);
|
|
335
|
-
matched += 1;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
return { summary, matched };
|
|
339
|
-
}
|
|
340
|
-
function createGlobMatcher(pattern) {
|
|
341
|
-
const normalized = toPosix(String(pattern ?? "")).trim();
|
|
342
|
-
if (!normalized) {
|
|
343
|
-
return () => false;
|
|
344
|
-
}
|
|
345
|
-
if (isAbsoluteGlobPattern(normalized)) {
|
|
346
|
-
throw new Error(`[coverage] threshold patterns must be relative (absolute paths are not supported): "${pattern}"`);
|
|
347
|
-
}
|
|
348
|
-
return picomatch(normalized, { dot: true });
|
|
349
|
-
}
|
|
350
|
-
function isAbsoluteGlobPattern(pattern) {
|
|
351
|
-
const normalized = String(pattern ?? "").trim();
|
|
352
|
-
if (!normalized) {
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
if (normalized.startsWith("/")) {
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
if (normalized.startsWith("file://")) {
|
|
359
|
-
return true;
|
|
360
|
-
}
|
|
361
|
-
return /^[A-Za-z]:\//.test(normalized);
|
|
362
|
-
}
|
|
363
|
-
function stripQuery(url) {
|
|
364
|
-
const queryIndex = url.indexOf("?");
|
|
365
|
-
const hashIndex = url.indexOf("#");
|
|
366
|
-
const endIndex = Math.min(
|
|
367
|
-
queryIndex === -1 ? Number.POSITIVE_INFINITY : queryIndex,
|
|
368
|
-
hashIndex === -1 ? Number.POSITIVE_INFINITY : hashIndex
|
|
369
|
-
);
|
|
370
|
-
if (!Number.isFinite(endIndex)) {
|
|
371
|
-
return url;
|
|
372
|
-
}
|
|
373
|
-
return url.slice(0, endIndex);
|
|
374
|
-
}
|
|
375
|
-
function extractSourceMappingUrl(source) {
|
|
376
|
-
const regex = /\/\/[#@]\s*sourceMappingURL=([^\s]+)/g;
|
|
377
|
-
let last = null;
|
|
378
|
-
let match = null;
|
|
379
|
-
while ((match = regex.exec(source)) !== null) {
|
|
380
|
-
last = match[1];
|
|
381
|
-
}
|
|
382
|
-
return typeof last === "string" && last.length > 0 ? last : null;
|
|
383
|
-
}
|
|
384
|
-
function resolveSourceMapPath(scriptPath, mappingUrl) {
|
|
385
|
-
const cleaned = stripQuery(mappingUrl);
|
|
386
|
-
if (cleaned.startsWith("file://")) {
|
|
387
|
-
return fileURLToPath(cleaned);
|
|
388
|
-
}
|
|
389
|
-
if (path.isAbsolute(cleaned)) {
|
|
390
|
-
return cleaned;
|
|
391
|
-
}
|
|
392
|
-
return path.resolve(path.dirname(scriptPath), cleaned);
|
|
393
|
-
}
|
|
394
|
-
function filterCoverageMap(map, config, matchesCollectCoverageFrom) {
|
|
395
|
-
if (!map || typeof map !== "object") {
|
|
396
|
-
return {};
|
|
397
|
-
}
|
|
398
|
-
const filtered = {};
|
|
399
|
-
for (const [filePath, fileCoverage] of Object.entries(map)) {
|
|
400
|
-
const absolutePath = resolveCoveragePath(filePath, config.rootDir);
|
|
401
|
-
if (!absolutePath) {
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
if (absolutePath.endsWith(".d.ts") || absolutePath.endsWith(".map")) {
|
|
405
|
-
continue;
|
|
406
|
-
}
|
|
407
|
-
if (isNodeModulesPath(absolutePath)) {
|
|
408
|
-
continue;
|
|
409
|
-
}
|
|
410
|
-
if (isViteVirtualModulePath(absolutePath)) {
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
|
-
if (!matchesCollectCoverageFrom(absolutePath)) {
|
|
414
|
-
continue;
|
|
415
|
-
}
|
|
416
|
-
if (fileCoverage && typeof fileCoverage === "object") {
|
|
417
|
-
filtered[absolutePath] = { ...fileCoverage, path: absolutePath };
|
|
418
|
-
} else {
|
|
419
|
-
filtered[absolutePath] = fileCoverage;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
return filtered;
|
|
423
|
-
}
|
|
424
|
-
function resolveCoveragePath(filePath, rootDir) {
|
|
425
|
-
const raw = String(filePath ?? "").trim();
|
|
426
|
-
if (!raw) {
|
|
427
|
-
return null;
|
|
428
|
-
}
|
|
429
|
-
const cleaned = stripQuery(raw);
|
|
430
|
-
if (cleaned.startsWith("file://")) {
|
|
431
|
-
try {
|
|
432
|
-
return path.normalize(fileURLToPath(cleaned));
|
|
433
|
-
} catch {
|
|
434
|
-
return null;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
if (path.isAbsolute(cleaned)) {
|
|
438
|
-
return path.normalize(cleaned);
|
|
439
|
-
}
|
|
440
|
-
if (cleaned.includes("://")) {
|
|
441
|
-
return null;
|
|
442
|
-
}
|
|
443
|
-
return path.normalize(path.resolve(rootDir, cleaned));
|
|
444
|
-
}
|
|
445
|
-
function isNodeModulesPath(filePath) {
|
|
446
|
-
return path.normalize(String(filePath ?? "")).split(path.sep).includes("node_modules");
|
|
447
|
-
}
|
|
448
|
-
function isViteVirtualModulePath(filePath) {
|
|
449
|
-
const normalized = path.normalize(String(filePath ?? ""));
|
|
450
|
-
const baseName = path.basename(normalized);
|
|
451
|
-
return baseName === "__vite-browser-external" || baseName.startsWith("__vite-browser-external:") || baseName.startsWith("__vite-");
|
|
452
|
-
}
|
|
453
|
-
function parseSourceMapPayload(raw) {
|
|
454
|
-
if (!raw || typeof raw !== "object") {
|
|
455
|
-
return null;
|
|
456
|
-
}
|
|
457
|
-
const sources = raw.sources;
|
|
458
|
-
if (!Array.isArray(sources) || sources.length === 0) {
|
|
459
|
-
return null;
|
|
460
|
-
}
|
|
461
|
-
return raw;
|
|
462
|
-
}
|
|
463
|
-
function normalizeSourceMap(sourceMap, scriptPath) {
|
|
464
|
-
const root = typeof sourceMap.sourceRoot === "string" ? sourceMap.sourceRoot.replace("file://", "") : "";
|
|
465
|
-
const dir = path.dirname(scriptPath);
|
|
466
|
-
const fixedSources = sourceMap.sources.map((source) => {
|
|
467
|
-
const raw = String(source ?? "");
|
|
468
|
-
const cleaned = stripQuery(raw);
|
|
469
|
-
if (cleaned.startsWith("file://")) {
|
|
470
|
-
try {
|
|
471
|
-
return path.normalize(fileURLToPath(cleaned));
|
|
472
|
-
} catch {
|
|
473
|
-
return cleaned;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
const withoutWebpack = cleaned.replace(/^webpack:\/\//, "");
|
|
477
|
-
const candidate = path.join(root, withoutWebpack);
|
|
478
|
-
if (path.isAbsolute(candidate)) {
|
|
479
|
-
return path.normalize(candidate);
|
|
480
|
-
}
|
|
481
|
-
const normalizedCandidate = candidate.split("/").join(path.sep);
|
|
482
|
-
if (dir.endsWith(`${path.sep}dist`) && !normalizedCandidate.startsWith(`..${path.sep}`)) {
|
|
483
|
-
if (normalizedCandidate.startsWith(`src${path.sep}`) || normalizedCandidate.startsWith(`lib${path.sep}`)) {
|
|
484
|
-
return path.normalize(path.resolve(dir, "..", normalizedCandidate));
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return path.normalize(path.resolve(dir, normalizedCandidate));
|
|
488
|
-
});
|
|
489
|
-
return {
|
|
490
|
-
...sourceMap,
|
|
491
|
-
sources: fixedSources
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
async function loadSourceMapForScript(scriptPath, source) {
|
|
495
|
-
const mappingUrl = extractSourceMappingUrl(source);
|
|
496
|
-
if (!mappingUrl) {
|
|
497
|
-
return null;
|
|
498
|
-
}
|
|
499
|
-
const cleaned = stripQuery(mappingUrl);
|
|
500
|
-
if (cleaned.startsWith("data:")) {
|
|
501
|
-
const commaIndex = cleaned.indexOf(",");
|
|
502
|
-
if (commaIndex === -1) {
|
|
503
|
-
return null;
|
|
504
|
-
}
|
|
505
|
-
const meta = cleaned.slice(0, commaIndex);
|
|
506
|
-
const payload = cleaned.slice(commaIndex + 1);
|
|
507
|
-
const raw = meta.includes(";base64") ? Buffer.from(payload, "base64").toString("utf8") : decodeURIComponent(payload);
|
|
508
|
-
try {
|
|
509
|
-
const parsed = parseSourceMapPayload(JSON.parse(raw));
|
|
510
|
-
return parsed ? normalizeSourceMap(parsed, scriptPath) : null;
|
|
511
|
-
} catch {
|
|
512
|
-
return null;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
try {
|
|
516
|
-
const mapPath = resolveSourceMapPath(scriptPath, cleaned);
|
|
517
|
-
const raw = await fs.readFile(mapPath, "utf8");
|
|
518
|
-
const parsed = parseSourceMapPayload(JSON.parse(raw));
|
|
519
|
-
return parsed ? normalizeSourceMap(parsed, scriptPath) : null;
|
|
520
|
-
} catch {
|
|
521
|
-
return null;
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
export {
|
|
525
|
-
CoverageThresholdError,
|
|
526
|
-
collectCoveredFiles,
|
|
527
|
-
generateCoverageReport
|
|
528
|
-
};
|
|
529
|
-
//# sourceMappingURL=report.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sources":["../../src/coverage/report.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\n\nimport * as libCoverage from \"istanbul-lib-coverage\"\nimport * as libInstrument from \"istanbul-lib-instrument\"\nimport fg from \"fast-glob\"\nimport picomatch from \"picomatch\"\nimport v8ToIstanbul from \"v8-to-istanbul\"\n\nimport { createCollectCoverageMatcher, toPosix } from \"./collect\"\nimport { generateConsoleTextCoverageReport } from \"./console-text-report\"\nimport { findCoverageFiles } from \"./files\"\nimport type { CoverageConfig, CoverageThresholdTarget, CoverageThresholds } from \"./types\"\n\n\nconst TEXT_REPORT_FILENAME = \"coverage.txt\"\n\nexport class CoverageThresholdError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"CoverageThresholdError\"\n }\n}\n\nexport async function generateCoverageReport(config: CoverageConfig): Promise<void> {\n const coverageFiles = await findCoverageFiles(config)\n\n if (coverageFiles.length === 0) {\n console.warn(\"[coverage] no V8 coverage artifacts were generated\")\n return\n }\n\n const coverageLib = resolveCoverageLib()\n const coverageMap = coverageLib.createCoverageMap({})\n const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir)\n\n for (const file of coverageFiles) {\n const payload = await readCoverageFile(file)\n if (!payload) {\n continue\n }\n\n for (const script of payload.scripts as any[]) {\n await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom)\n }\n }\n\n if (config.includeAllFiles) {\n await includeUntestedFiles(coverageMap, config, matchesCollectCoverageFrom)\n }\n\n if (coverageMap.files().length === 0) {\n console.warn(\"[coverage] no library files matched the coverage filters\")\n return\n }\n\n await fs.rm(config.coverageReportDir, { recursive: true, force: true })\n await fs.mkdir(config.coverageReportDir, { recursive: true })\n\n const { createContext, reports } = await loadIstanbulModules()\n const context = createContext({\n dir: config.coverageReportDir,\n coverageMap,\n defaultSummarizer: \"pkg\",\n })\n\n const { output: reportOutput, summarizer } = generateConsoleTextCoverageReport(reports, context)\n process.stdout.write(reportOutput)\n reports.create(\"text\", { file: TEXT_REPORT_FILENAME, summarizer }).execute(context)\n\n console.log(`[coverage] Full text report saved to ${path.join(config.coverageReportDir, TEXT_REPORT_FILENAME)}`)\n\n const summary = coverageMap.getCoverageSummary()\n enforceThresholds(summary, config.thresholds, \"global\")\n\n const targets: CoverageThresholdTarget[] = Array.isArray(config.thresholdTargets) ? config.thresholdTargets : []\n if (targets.length > 0) {\n const fileSummaries = buildFileSummaries(coverageMap, config.rootDir)\n for (const target of targets) {\n const matcher = createGlobMatcher(target.pattern)\n const matchResult = collectTargetSummary(fileSummaries, matcher, coverageLib)\n\n if (matchResult.matched === 0) {\n console.warn(\n `[coverage] threshold pattern \"${target.pattern}\" did not match any files — skipping`,\n )\n continue\n }\n\n enforceThresholds(matchResult.summary, target.thresholds, target.pattern)\n }\n }\n}\n\nexport async function collectCoveredFiles(config: CoverageConfig): Promise<string[]> {\n const coverageFiles = await findCoverageFiles(config)\n if (coverageFiles.length === 0) {\n return []\n }\n\n const coverageLib = resolveCoverageLib()\n const coverageMap = coverageLib.createCoverageMap({})\n const matchesCollectCoverageFrom = createCollectCoverageMatcher(config.collectCoverageFrom, config.rootDir)\n\n for (const file of coverageFiles) {\n const payload = await readCoverageFile(file)\n if (!payload) {\n continue\n }\n\n for (const script of payload.scripts as any[]) {\n await mergeScriptCoverage(coverageMap, script, config, matchesCollectCoverageFrom)\n }\n }\n\n return coverageMap.files().sort()\n}\n\nasync function loadIstanbulModules(): Promise<{ createContext: (opts: any) => any; reports: any }> {\n maybeForceColor()\n const [libReportMod, reportsMod]: any[] = await Promise.all([\n import(\"istanbul-lib-report\"),\n import(\"istanbul-reports\"),\n ])\n\n const createContext = typeof libReportMod.createContext === \"function\"\n ? libReportMod.createContext\n : libReportMod.default?.createContext\n\n if (typeof createContext !== \"function\") {\n throw new Error(\"istanbul-lib-report exports are unavailable\")\n }\n\n return {\n createContext,\n reports: reportsMod.default ?? reportsMod,\n }\n}\n\nfunction maybeForceColor(): void {\n if (process.stdout.isTTY) {\n return\n }\n\n if (process.env.FORCE_COLOR !== undefined) {\n return\n }\n\n if (process.env.NO_COLOR !== undefined || process.env.NODE_DISABLE_COLORS !== undefined) {\n return\n }\n\n if (process.env.CI !== undefined) {\n return\n }\n\n process.env.FORCE_COLOR = \"1\"\n}\n\nasync function mergeScriptCoverage(\n coverageMap: any,\n script: any,\n config: CoverageConfig,\n matchesCollectCoverageFrom: (absolutePath: string) => boolean,\n): Promise<void> {\n const scriptPath = script.absolutePath\n if (!scriptPath) {\n return\n }\n\n if (isNodeModulesPath(scriptPath)) {\n return\n }\n\n if (isViteVirtualModulePath(scriptPath)) {\n return\n }\n\n let source = script.source && script.source.length > 0\n ? script.source\n : \"\"\n\n if (!source) {\n try {\n source = await fs.readFile(scriptPath, \"utf8\")\n } catch (error: any) {\n const base = path.basename(scriptPath)\n if (error?.code === \"ENOENT\" && base && !base.includes(\".\")) {\n return\n }\n if (error?.code === \"ENOENT\" && !matchesCollectCoverageFrom(scriptPath)) {\n return\n }\n throw error\n }\n }\n\n const sourceMap = await loadSourceMapForScript(scriptPath, source)\n const converter = v8ToIstanbul(\n scriptPath,\n 0,\n sourceMap ? { source, sourceMap: { sourcemap: sourceMap } } : { source },\n )\n await converter.load()\n converter.applyCoverage(script.functions)\n\n const filtered = filterCoverageMap(converter.toIstanbul(), config, matchesCollectCoverageFrom)\n if (Object.keys(filtered).length > 0) {\n coverageMap.merge(filtered)\n }\n}\n\nasync function readCoverageFile(file: string): Promise<any | null> {\n try {\n const raw = await fs.readFile(file, \"utf8\")\n return JSON.parse(raw)\n } catch (error) {\n console.warn(`[coverage] failed to parse ${file}:`, error)\n return null\n }\n}\n\nfunction enforceThresholds(summary: any, thresholds: CoverageThresholds, label = \"global\"): void {\n const failures = []\n\n for (const metric of Object.keys(thresholds) as Array<keyof CoverageThresholds>) {\n const minimum = thresholds[metric]\n const actual = summary[metric]?.pct ?? 0\n if (actual < minimum) {\n failures.push({ metric, actual, minimum })\n }\n }\n\n if (failures.length === 0) {\n return\n }\n\n const details = failures\n .map(({ metric, actual, minimum }) => `${metric}: ${actual.toFixed(2)}% < ${minimum}%`)\n .join(\"; \")\n\n throw new CoverageThresholdError(`[coverage] thresholds not met (target: ${label}) — ${details}`)\n}\n\nfunction resolveCoverageLib(): any {\n const candidate: any = libCoverage as any\n if (typeof candidate.createCoverageMap === \"function\") {\n return candidate\n }\n\n if (candidate.default && typeof candidate.default.createCoverageMap === \"function\") {\n return candidate.default\n }\n\n throw new Error(\"istanbul-lib-coverage exports are unavailable\")\n}\n\nfunction resolveInstrumentLib(): any {\n const candidate: any = libInstrument as any\n if (typeof candidate.createInstrumenter === \"function\") {\n return candidate\n }\n\n if (candidate.default && typeof candidate.default.createInstrumenter === \"function\") {\n return candidate.default\n }\n\n throw new Error(\"istanbul-lib-instrument exports are unavailable\")\n}\n\nasync function includeUntestedFiles(\n coverageMap: any,\n config: CoverageConfig,\n matchesCollectCoverageFrom: (absolutePath: string) => boolean,\n): Promise<void> {\n const existing = new Set(\n coverageMap.files().map((filePath: unknown) => path.resolve(String(filePath ?? \"\"))),\n )\n\n const candidates = await findCollectCoverageFiles(config, matchesCollectCoverageFrom)\n if (candidates.length === 0) {\n return\n }\n\n const instrumentLib = resolveInstrumentLib()\n const instrumenter = instrumentLib.createInstrumenter({\n esModules: true,\n parserPlugins: [\n \"typescript\",\n \"jsx\",\n \"classProperties\",\n \"classPrivateProperties\",\n \"classPrivateMethods\",\n \"decorators-legacy\",\n \"importMeta\",\n \"topLevelAwait\",\n ],\n })\n\n for (const filePath of candidates) {\n const normalized = path.resolve(filePath)\n if (existing.has(normalized)) {\n continue\n }\n\n const source = await fs.readFile(normalized, \"utf8\").catch(() => null)\n if (source === null) {\n continue\n }\n\n try {\n instrumenter.instrumentSync(source, normalized)\n const fileCoverage = instrumenter.lastFileCoverage()\n if (!fileCoverage) {\n continue\n }\n coverageMap.addFileCoverage(fileCoverage)\n existing.add(normalized)\n } catch (error) {\n const relative = path.relative(config.rootDir, normalized)\n console.warn(\n `[coverage] failed to instrument ${relative && !relative.startsWith(\"..\") ? relative : normalized}:`,\n error,\n )\n }\n }\n}\n\nconst DEFAULT_COLLECT_COVERAGE_IGNORES = [\n \"**/.git/**\",\n \"**/.next/**\",\n \"**/.turbo/**\",\n \"**/.vite/**\",\n \"**/.vitest/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/dist/**\",\n \"**/node_modules/**\",\n \"**/playwright-report/**\",\n \"**/spec/**\",\n \"**/test/**\",\n \"**/test-results/**\",\n \"**/tests/**\",\n \"**/__tests__/**\",\n \"**/*.d.ts\",\n \"**/*.map\",\n]\n\nasync function findCollectCoverageFiles(\n config: CoverageConfig,\n matchesCollectCoverageFrom: (absolutePath: string) => boolean,\n): Promise<string[]> {\n const patterns = Array.isArray(config.collectCoverageFrom)\n ? config.collectCoverageFrom\n : []\n\n if (patterns.length === 0) {\n return []\n }\n\n const rawFiles = await fg(patterns, {\n cwd: config.rootDir,\n absolute: true,\n dot: true,\n onlyFiles: true,\n unique: true,\n followSymbolicLinks: false,\n ignore: DEFAULT_COLLECT_COVERAGE_IGNORES,\n }).catch(() => [])\n\n const collected = new Set<string>()\n\n for (const file of rawFiles) {\n const normalized = path.resolve(String(file ?? \"\"))\n if (!normalized) {\n continue\n }\n\n if (normalized.endsWith(\".d.ts\") || normalized.endsWith(\".map\")) {\n continue\n }\n\n if (isNodeModulesPath(normalized)) {\n continue\n }\n\n if (isViteVirtualModulePath(normalized)) {\n continue\n }\n\n if (!matchesCollectCoverageFrom(normalized)) {\n continue\n }\n\n collected.add(normalized)\n }\n\n return Array.from(collected).sort()\n}\n\nfunction buildFileSummaries(\n coverageMap: any,\n rootDir: string,\n): Array<{ summary: any; candidates: string[] }> {\n const normalizedRoot = path.resolve(rootDir)\n return coverageMap.files().map((filePath: string) => {\n const normalizedAbsolute = path.resolve(filePath)\n const summary = coverageMap.fileCoverageFor(filePath).toSummary()\n const relativePath = path.relative(normalizedRoot, normalizedAbsolute)\n const candidates = new Set<string>()\n\n if (relativePath) {\n const relativePosix = toPosix(relativePath)\n candidates.add(relativePosix)\n candidates.add(`./${relativePosix}`)\n } else {\n candidates.add(toPosix(path.basename(normalizedAbsolute)))\n }\n\n return {\n summary,\n candidates: Array.from(candidates),\n }\n })\n}\n\nfunction collectTargetSummary(\n fileSummaries: Array<{ summary: any; candidates: string[] }>,\n matcher: (candidate: string) => boolean,\n coverageLib: any,\n): { summary: any; matched: number } {\n const summary = coverageLib.createCoverageSummary()\n let matched = 0\n\n for (const file of fileSummaries) {\n if (file.candidates.some((candidate) => matcher(candidate))) {\n summary.merge(file.summary)\n matched += 1\n }\n }\n\n return { summary, matched }\n}\n\nfunction createGlobMatcher(pattern: string): (candidate: string) => boolean {\n const normalized = toPosix(String(pattern ?? \"\")).trim()\n if (!normalized) {\n return () => false\n }\n if (isAbsoluteGlobPattern(normalized)) {\n throw new Error(`[coverage] threshold patterns must be relative (absolute paths are not supported): \"${pattern}\"`)\n }\n return picomatch(normalized, { dot: true })\n}\n\nfunction isAbsoluteGlobPattern(pattern: string): boolean {\n const normalized = String(pattern ?? \"\").trim()\n if (!normalized) {\n return false\n }\n\n if (normalized.startsWith(\"/\")) {\n return true\n }\n\n if (normalized.startsWith(\"file://\")) {\n return true\n }\n\n return /^[A-Za-z]:\\//.test(normalized)\n}\n\nfunction stripQuery(url: string): string {\n const queryIndex = url.indexOf(\"?\")\n const hashIndex = url.indexOf(\"#\")\n\n const endIndex = Math.min(\n queryIndex === -1 ? Number.POSITIVE_INFINITY : queryIndex,\n hashIndex === -1 ? Number.POSITIVE_INFINITY : hashIndex,\n )\n\n if (!Number.isFinite(endIndex)) {\n return url\n }\n\n return url.slice(0, endIndex)\n}\n\nfunction extractSourceMappingUrl(source: string): string | null {\n const regex = /\\/\\/[#@]\\s*sourceMappingURL=([^\\s]+)/g\n\n let last = null\n let match = null\n\n while ((match = regex.exec(source)) !== null) {\n last = match[1]\n }\n\n return typeof last === \"string\" && last.length > 0 ? last : null\n}\n\nfunction resolveSourceMapPath(scriptPath: string, mappingUrl: string): string {\n const cleaned = stripQuery(mappingUrl)\n\n if (cleaned.startsWith(\"file://\")) {\n return fileURLToPath(cleaned)\n }\n\n if (path.isAbsolute(cleaned)) {\n return cleaned\n }\n\n return path.resolve(path.dirname(scriptPath), cleaned)\n}\n\nfunction filterCoverageMap(\n map: any,\n config: CoverageConfig,\n matchesCollectCoverageFrom: (absolutePath: string) => boolean,\n): Record<string, any> {\n if (!map || typeof map !== \"object\") {\n return {}\n }\n\n const filtered: Record<string, any> = {}\n\n for (const [filePath, fileCoverage] of Object.entries(map)) {\n const absolutePath = resolveCoveragePath(filePath, config.rootDir)\n if (!absolutePath) {\n continue\n }\n\n if (absolutePath.endsWith(\".d.ts\") || absolutePath.endsWith(\".map\")) {\n continue\n }\n\n if (isNodeModulesPath(absolutePath)) {\n continue\n }\n\n if (isViteVirtualModulePath(absolutePath)) {\n continue\n }\n\n if (!matchesCollectCoverageFrom(absolutePath)) {\n continue\n }\n\n if (fileCoverage && typeof fileCoverage === \"object\") {\n filtered[absolutePath] = { ...fileCoverage, path: absolutePath }\n } else {\n filtered[absolutePath] = fileCoverage\n }\n }\n\n return filtered\n}\n\nfunction resolveCoveragePath(filePath: string, rootDir: string): string | null {\n const raw = String(filePath ?? \"\").trim()\n if (!raw) {\n return null\n }\n\n const cleaned = stripQuery(raw)\n\n if (cleaned.startsWith(\"file://\")) {\n try {\n return path.normalize(fileURLToPath(cleaned))\n } catch {\n return null\n }\n }\n\n if (path.isAbsolute(cleaned)) {\n return path.normalize(cleaned)\n }\n\n if (cleaned.includes(\"://\")) {\n return null\n }\n\n return path.normalize(path.resolve(rootDir, cleaned))\n}\n\nfunction isNodeModulesPath(filePath: string): boolean {\n return path\n .normalize(String(filePath ?? \"\"))\n .split(path.sep)\n .includes(\"node_modules\")\n}\n\nfunction isViteVirtualModulePath(filePath: string): boolean {\n const normalized = path.normalize(String(filePath ?? \"\"))\n const baseName = path.basename(normalized)\n return baseName === \"__vite-browser-external\"\n || baseName.startsWith(\"__vite-browser-external:\")\n || baseName.startsWith(\"__vite-\")\n}\n\nfunction parseSourceMapPayload(raw: any): any | null {\n if (!raw || typeof raw !== \"object\") {\n return null\n }\n\n const sources = raw.sources\n if (!Array.isArray(sources) || sources.length === 0) {\n return null\n }\n\n return raw\n}\n\nfunction normalizeSourceMap(sourceMap: any, scriptPath: string): any {\n const root = typeof sourceMap.sourceRoot === \"string\"\n ? sourceMap.sourceRoot.replace(\"file://\", \"\")\n : \"\"\n\n const dir = path.dirname(scriptPath)\n const fixedSources = sourceMap.sources.map((source: unknown) => {\n const raw = String(source ?? \"\")\n const cleaned = stripQuery(raw)\n\n if (cleaned.startsWith(\"file://\")) {\n try {\n return path.normalize(fileURLToPath(cleaned))\n } catch {\n return cleaned\n }\n }\n\n const withoutWebpack = cleaned.replace(/^webpack:\\/\\//, \"\")\n const candidate = path.join(root, withoutWebpack)\n\n if (path.isAbsolute(candidate)) {\n return path.normalize(candidate)\n }\n\n const normalizedCandidate = candidate.split(\"/\").join(path.sep)\n\n if (dir.endsWith(`${path.sep}dist`) && !normalizedCandidate.startsWith(`..${path.sep}`)) {\n if (normalizedCandidate.startsWith(`src${path.sep}`) || normalizedCandidate.startsWith(`lib${path.sep}`)) {\n return path.normalize(path.resolve(dir, \"..\", normalizedCandidate))\n }\n }\n\n return path.normalize(path.resolve(dir, normalizedCandidate))\n })\n\n return {\n ...sourceMap,\n sources: fixedSources,\n }\n}\n\nasync function loadSourceMapForScript(scriptPath: string, source: string): Promise<any | null> {\n const mappingUrl = extractSourceMappingUrl(source)\n if (!mappingUrl) {\n return null\n }\n\n const cleaned = stripQuery(mappingUrl)\n\n if (cleaned.startsWith(\"data:\")) {\n const commaIndex = cleaned.indexOf(\",\")\n if (commaIndex === -1) {\n return null\n }\n\n const meta = cleaned.slice(0, commaIndex)\n const payload = cleaned.slice(commaIndex + 1)\n const raw = meta.includes(\";base64\")\n ? Buffer.from(payload, \"base64\").toString(\"utf8\")\n : decodeURIComponent(payload)\n\n try {\n const parsed = parseSourceMapPayload(JSON.parse(raw))\n return parsed ? normalizeSourceMap(parsed, scriptPath) : null\n } catch {\n return null\n }\n }\n\n try {\n const mapPath = resolveSourceMapPath(scriptPath, cleaned)\n const raw = await fs.readFile(mapPath, \"utf8\")\n const parsed = parseSourceMapPayload(JSON.parse(raw))\n return parsed ? normalizeSourceMap(parsed, scriptPath) : null\n } catch {\n return null\n }\n}\n"],"names":[],"mappings":"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"}
|