@rpcbase/test 0.357.0 → 0.359.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/dist/clearDatabase.js +12 -10
- package/dist/clearDatabase.js.map +1 -1
- package/dist/cli.js +556 -439
- package/dist/cli.js.map +1 -1
- package/dist/coverage/collect.js +101 -63
- package/dist/coverage/collect.js.map +1 -1
- package/dist/coverage/config-loader.js +230 -180
- package/dist/coverage/config-loader.js.map +1 -1
- package/dist/coverage/config.js +100 -76
- package/dist/coverage/config.js.map +1 -1
- package/dist/coverage/console-text-report.js +220 -175
- package/dist/coverage/console-text-report.js.map +1 -1
- package/dist/coverage/files.js +58 -45
- package/dist/coverage/files.js.map +1 -1
- package/dist/coverage/fixtures.js +38 -27
- package/dist/coverage/fixtures.js.map +1 -1
- package/dist/coverage/global-setup.js +18 -15
- package/dist/coverage/global-setup.js.map +1 -1
- package/dist/coverage/index.js +55 -38
- package/dist/coverage/index.js.map +1 -1
- package/dist/coverage/report.js +466 -341
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/reporter.js +60 -47
- package/dist/coverage/reporter.js.map +1 -1
- package/dist/coverage/v8-tracker.js +147 -115
- package/dist/coverage/v8-tracker.js.map +1 -1
- package/dist/index.js +75 -46
- package/dist/index.js.map +1 -1
- package/dist/runners/playwright.js +563 -438
- package/dist/runners/playwright.js.map +1 -1
- package/dist/runners/process.d.ts.map +1 -1
- package/dist/runners/process.js +183 -125
- package/dist/runners/process.js.map +1 -1
- package/dist/runners/vitest.js +171 -124
- package/dist/runners/vitest.js.map +1 -1
- package/dist/serverCoverage.js +42 -28
- package/dist/serverCoverage.js.map +1 -1
- package/dist/vitest.config.d.ts +1 -1
- package/dist/vitest.config.js +74 -62
- package/dist/vitest.config.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,220 +1,270 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs$1 from "node:fs/promises";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import crypto from "node:crypto";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
8
|
+
import { buildSync, build } from "esbuild";
|
|
9
|
+
const require$1 = createRequire(import.meta.url);
|
|
10
|
+
const DEFAULT_COVERAGE_CANDIDATES = ["spec/coverage.config.ts", "spec/coverage.config.js", "spec/coverage.config.mjs", "spec/coverage.config.cjs", "spec/coverage.config.json"];
|
|
11
|
+
const LEGACY_COVERAGE_CANDIDATES = ["spec/coverage.ts", "spec/coverage.js", "spec/coverage.mjs", "spec/coverage.cjs", "spec/coverage.json"];
|
|
12
|
+
async function loadCoverageOptions({
|
|
13
|
+
optional = false,
|
|
14
|
+
candidates = DEFAULT_COVERAGE_CANDIDATES
|
|
15
|
+
} = {}) {
|
|
16
|
+
const projectRoot = process.cwd();
|
|
17
|
+
const legacy = await findCoverageFile(projectRoot, LEGACY_COVERAGE_CANDIDATES);
|
|
18
|
+
if (legacy) {
|
|
19
|
+
const ext = path.extname(legacy);
|
|
20
|
+
const suggested = path.join("spec", `coverage.config${ext}`);
|
|
21
|
+
throw new Error(`Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`);
|
|
22
|
+
}
|
|
23
|
+
const resolved = await findCoverageFile(projectRoot, candidates);
|
|
24
|
+
if (!resolved) {
|
|
25
|
+
if (optional) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
throw new Error("Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.");
|
|
29
|
+
}
|
|
30
|
+
const raw = await importCoverageModule(resolved);
|
|
31
|
+
if (!raw || typeof raw !== "object") {
|
|
32
|
+
throw new Error(`Coverage config at ${resolved} must export an object.`);
|
|
33
|
+
}
|
|
34
|
+
return await normalizeOptions(raw, resolved);
|
|
35
|
+
}
|
|
36
|
+
function loadCoverageOptionsSync({
|
|
37
|
+
optional = false,
|
|
38
|
+
candidates = DEFAULT_COVERAGE_CANDIDATES
|
|
39
|
+
} = {}) {
|
|
40
|
+
const projectRoot = process.cwd();
|
|
41
|
+
const legacy = findCoverageFileSync(projectRoot, LEGACY_COVERAGE_CANDIDATES);
|
|
42
|
+
if (legacy) {
|
|
43
|
+
const ext = path.extname(legacy);
|
|
44
|
+
const suggested = path.join("spec", `coverage.config${ext}`);
|
|
45
|
+
throw new Error(`Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`);
|
|
46
|
+
}
|
|
47
|
+
const resolved = findCoverageFileSync(projectRoot, candidates);
|
|
48
|
+
if (!resolved) {
|
|
49
|
+
if (optional) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
throw new Error("Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.");
|
|
53
|
+
}
|
|
54
|
+
const raw = importCoverageModuleSync(resolved);
|
|
55
|
+
if (!raw || typeof raw !== "object") {
|
|
56
|
+
throw new Error(`Coverage config at ${resolved} must export an object.`);
|
|
57
|
+
}
|
|
58
|
+
return normalizeOptionsSync(raw, resolved);
|
|
58
59
|
}
|
|
59
60
|
async function findCoverageFile(root, candidates) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
for (const relative of candidates) {
|
|
62
|
+
const candidate = path.resolve(root, relative);
|
|
63
|
+
try {
|
|
64
|
+
await fs$1.access(candidate);
|
|
65
|
+
return candidate;
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
68
70
|
}
|
|
69
71
|
function findCoverageFileSync(root, candidates) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
for (const relative of candidates) {
|
|
73
|
+
const candidate = path.resolve(root, relative);
|
|
74
|
+
try {
|
|
75
|
+
fs.accessSync(candidate);
|
|
76
|
+
return candidate;
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
78
81
|
}
|
|
79
82
|
async function importCoverageModule(filePath) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
const ext = path.extname(filePath);
|
|
84
|
+
if (ext === ".json") {
|
|
85
|
+
const raw = await fs$1.readFile(filePath, "utf8");
|
|
86
|
+
return JSON.parse(raw);
|
|
87
|
+
}
|
|
88
|
+
if (ext === ".ts") {
|
|
89
|
+
const compiledUrl = await compileTsModule(filePath);
|
|
90
|
+
return loadModule(compiledUrl);
|
|
91
|
+
}
|
|
92
|
+
const moduleUrl = pathToFileURL(filePath).href;
|
|
93
|
+
return loadModule(moduleUrl);
|
|
88
94
|
}
|
|
89
95
|
function importCoverageModuleSync(filePath) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
const ext = path.extname(filePath);
|
|
97
|
+
if (ext === ".json") {
|
|
98
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
99
|
+
return JSON.parse(raw);
|
|
100
|
+
}
|
|
101
|
+
if (ext === ".cjs") {
|
|
102
|
+
return loadModuleSync(filePath);
|
|
103
|
+
}
|
|
104
|
+
const compiledPath = compileCjsModuleSync(filePath);
|
|
105
|
+
return loadModuleSync(compiledPath);
|
|
97
106
|
}
|
|
98
107
|
async function compileTsModule(filePath) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
const stat = await fs$1.stat(filePath);
|
|
109
|
+
const hash = crypto.createHash("sha1").update(filePath).update(String(stat.mtimeMs)).digest("hex");
|
|
110
|
+
const outDir = path.join(os.tmpdir(), "rpcbase-test");
|
|
111
|
+
await fs$1.mkdir(outDir, {
|
|
112
|
+
recursive: true
|
|
113
|
+
});
|
|
114
|
+
const outfile = path.join(outDir, `coverage-${hash}.mjs`);
|
|
115
|
+
await build({
|
|
116
|
+
entryPoints: [filePath],
|
|
117
|
+
outfile,
|
|
118
|
+
platform: "node",
|
|
119
|
+
format: "esm",
|
|
120
|
+
bundle: false,
|
|
121
|
+
sourcemap: "inline",
|
|
122
|
+
logLevel: "silent"
|
|
123
|
+
});
|
|
124
|
+
return pathToFileURL(outfile).href;
|
|
114
125
|
}
|
|
115
126
|
function compileCjsModuleSync(filePath) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
const stat = fs.statSync(filePath);
|
|
128
|
+
const hash = crypto.createHash("sha1").update(filePath).update(String(stat.mtimeMs)).digest("hex");
|
|
129
|
+
const outDir = path.join(os.tmpdir(), "rpcbase-test");
|
|
130
|
+
fs.mkdirSync(outDir, {
|
|
131
|
+
recursive: true
|
|
132
|
+
});
|
|
133
|
+
const outfile = path.join(outDir, `coverage-${hash}.cjs`);
|
|
134
|
+
buildSync({
|
|
135
|
+
entryPoints: [filePath],
|
|
136
|
+
outfile,
|
|
137
|
+
platform: "node",
|
|
138
|
+
format: "cjs",
|
|
139
|
+
bundle: false,
|
|
140
|
+
sourcemap: "inline",
|
|
141
|
+
logLevel: "silent"
|
|
142
|
+
});
|
|
143
|
+
return outfile;
|
|
131
144
|
}
|
|
132
145
|
async function loadModule(url) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
146
|
+
const imported = await import(url);
|
|
147
|
+
if (imported && typeof imported.default === "object") {
|
|
148
|
+
return imported.default;
|
|
149
|
+
}
|
|
150
|
+
return imported;
|
|
136
151
|
}
|
|
137
152
|
function loadModuleSync(modulePath) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
const imported = require$1(modulePath);
|
|
154
|
+
if (imported && typeof imported.default === "object") {
|
|
155
|
+
return imported.default;
|
|
156
|
+
}
|
|
157
|
+
return imported;
|
|
141
158
|
}
|
|
142
|
-
|
|
143
|
-
|
|
159
|
+
const DEFAULT_COLLECT_COVERAGE_EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs";
|
|
160
|
+
const DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE = `!**/*.test.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`;
|
|
144
161
|
async function resolveCollectCoverageFrom(rawPatterns, rootDir) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
162
|
+
const resolvedRootDir = path.resolve(String(rootDir ?? ""));
|
|
163
|
+
const normalized = Array.isArray(rawPatterns) ? rawPatterns.map((pattern) => String(pattern ?? "").trim()).filter((pattern) => pattern.length > 0) : [];
|
|
164
|
+
const excludes = normalized.filter((pattern) => pattern.startsWith("!"));
|
|
165
|
+
const hasIncludes = normalized.some((pattern) => !pattern.startsWith("!"));
|
|
166
|
+
if (hasIncludes) {
|
|
167
|
+
return withDefaultExcludes(normalized);
|
|
168
|
+
}
|
|
169
|
+
const defaults = await inferDefaultCollectCoverageFrom(resolvedRootDir);
|
|
170
|
+
if (defaults.length === 0) {
|
|
171
|
+
throw new Error("Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.");
|
|
172
|
+
}
|
|
173
|
+
return withDefaultExcludes([...defaults, ...excludes]);
|
|
152
174
|
}
|
|
153
175
|
function resolveCollectCoverageFromSync(rawPatterns, rootDir) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
176
|
+
const resolvedRootDir = path.resolve(String(rootDir ?? ""));
|
|
177
|
+
const normalized = Array.isArray(rawPatterns) ? rawPatterns.map((pattern) => String(pattern ?? "").trim()).filter((pattern) => pattern.length > 0) : [];
|
|
178
|
+
const excludes = normalized.filter((pattern) => pattern.startsWith("!"));
|
|
179
|
+
const hasIncludes = normalized.some((pattern) => !pattern.startsWith("!"));
|
|
180
|
+
if (hasIncludes) {
|
|
181
|
+
return withDefaultExcludes(normalized);
|
|
182
|
+
}
|
|
183
|
+
const defaults = inferDefaultCollectCoverageFromSync(resolvedRootDir);
|
|
184
|
+
if (defaults.length === 0) {
|
|
185
|
+
throw new Error("Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.");
|
|
186
|
+
}
|
|
187
|
+
return withDefaultExcludes([...defaults, ...excludes]);
|
|
161
188
|
}
|
|
162
189
|
async function inferDefaultCollectCoverageFrom(rootDir) {
|
|
163
|
-
|
|
164
|
-
|
|
190
|
+
const srcDir = path.join(rootDir, "src");
|
|
191
|
+
if (await isDirectory(srcDir)) {
|
|
192
|
+
return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`];
|
|
193
|
+
}
|
|
194
|
+
return [];
|
|
165
195
|
}
|
|
166
196
|
function inferDefaultCollectCoverageFromSync(rootDir) {
|
|
167
|
-
|
|
168
|
-
|
|
197
|
+
const srcDir = path.join(rootDir, "src");
|
|
198
|
+
if (isDirectorySync(srcDir)) {
|
|
199
|
+
return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`];
|
|
200
|
+
}
|
|
201
|
+
return [];
|
|
169
202
|
}
|
|
170
203
|
function withDefaultExcludes(patterns) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
204
|
+
if (!Array.isArray(patterns) || patterns.length === 0) {
|
|
205
|
+
return patterns;
|
|
206
|
+
}
|
|
207
|
+
const hasTestExclude = patterns.some((pattern) => {
|
|
208
|
+
const raw = String(pattern ?? "");
|
|
209
|
+
if (!raw.startsWith("!")) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
return /\.test(?:\.|\{|$)/.test(raw.slice(1));
|
|
213
|
+
});
|
|
214
|
+
if (hasTestExclude) {
|
|
215
|
+
return patterns;
|
|
216
|
+
}
|
|
217
|
+
return [...patterns, DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE];
|
|
178
218
|
}
|
|
179
219
|
async function isDirectory(filePath) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
220
|
+
try {
|
|
221
|
+
const stat = await fs$1.stat(filePath);
|
|
222
|
+
return stat.isDirectory();
|
|
223
|
+
} catch {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
185
226
|
}
|
|
186
227
|
function isDirectorySync(filePath) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
228
|
+
try {
|
|
229
|
+
const stat = fs.statSync(filePath);
|
|
230
|
+
return stat.isDirectory();
|
|
231
|
+
} catch {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
192
234
|
}
|
|
193
235
|
async function normalizeOptions(rawOptions, filePath) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
236
|
+
const options = {
|
|
237
|
+
...rawOptions
|
|
238
|
+
};
|
|
239
|
+
const configDir = path.dirname(filePath);
|
|
240
|
+
const rootDir = path.resolve(configDir, "..");
|
|
241
|
+
const collectCoverageFrom = await resolveCollectCoverageFrom(options.collectCoverageFrom, rootDir);
|
|
242
|
+
return {
|
|
243
|
+
rootDir,
|
|
244
|
+
collectCoverageFrom,
|
|
245
|
+
coverageFileName: options.coverageFileName ?? "v8-coverage.json",
|
|
246
|
+
includeAllFiles: options.includeAllFiles,
|
|
247
|
+
thresholds: options.thresholds ?? {}
|
|
248
|
+
};
|
|
204
249
|
}
|
|
205
250
|
function normalizeOptionsSync(rawOptions, filePath) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
251
|
+
const options = {
|
|
252
|
+
...rawOptions
|
|
253
|
+
};
|
|
254
|
+
const configDir = path.dirname(filePath);
|
|
255
|
+
const rootDir = path.resolve(configDir, "..");
|
|
256
|
+
const collectCoverageFrom = resolveCollectCoverageFromSync(options.collectCoverageFrom, rootDir);
|
|
257
|
+
return {
|
|
258
|
+
rootDir,
|
|
259
|
+
collectCoverageFrom,
|
|
260
|
+
coverageFileName: options.coverageFileName ?? "v8-coverage.json",
|
|
261
|
+
includeAllFiles: options.includeAllFiles,
|
|
262
|
+
thresholds: options.thresholds ?? {}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
export {
|
|
266
|
+
DEFAULT_COVERAGE_CANDIDATES,
|
|
267
|
+
loadCoverageOptions,
|
|
268
|
+
loadCoverageOptionsSync
|
|
269
|
+
};
|
|
270
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.js","names":["fs","fsSync","path","os","crypto","createRequire","pathToFileURL","build","buildSync","CoverageHarnessOptions","require","import","meta","url","LoadCoverageOptionsArgs","optional","candidates","DEFAULT_COVERAGE_CANDIDATES","LEGACY_COVERAGE_CANDIDATES","loadCoverageOptions","Promise","projectRoot","process","cwd","legacy","findCoverageFile","ext","extname","suggested","join","Error","relative","resolved","raw","importCoverageModule","normalizeOptions","loadCoverageOptionsSync","findCoverageFileSync","importCoverageModuleSync","normalizeOptionsSync","root","candidate","resolve","access","accessSync","filePath","readFile","JSON","parse","compiledUrl","compileTsModule","loadModule","moduleUrl","href","readFileSync","loadModuleSync","compiledPath","compileCjsModuleSync","stat","hash","createHash","update","String","mtimeMs","digest","outDir","tmpdir","mkdir","recursive","outfile","entryPoints","platform","format","bundle","sourcemap","logLevel","statSync","mkdirSync","imported","default","modulePath","DEFAULT_COLLECT_COVERAGE_EXTENSIONS","DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE","resolveCollectCoverageFrom","rawPatterns","rootDir","resolvedRootDir","normalized","Array","isArray","map","pattern","trim","filter","length","excludes","startsWith","hasIncludes","some","withDefaultExcludes","defaults","inferDefaultCollectCoverageFrom","resolveCollectCoverageFromSync","inferDefaultCollectCoverageFromSync","srcDir","isDirectory","isDirectorySync","patterns","hasTestExclude","test","slice","rawOptions","options","configDir","dirname","collectCoverageFrom","coverageFileName","includeAllFiles","thresholds"],"sources":["../../src/coverage/config-loader.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport fsSync from \"node:fs\"\nimport path from \"node:path\"\nimport os from \"node:os\"\nimport crypto from \"node:crypto\"\nimport { createRequire } from \"node:module\"\nimport { pathToFileURL } from \"node:url\"\n\nimport { build, buildSync } from \"esbuild\"\n\nimport type { CoverageHarnessOptions } from \"./types\"\n\n\nconst require = createRequire(import.meta.url)\n\ntype LoadCoverageOptionsArgs = {\n optional?: boolean\n candidates?: string[]\n}\n\nconst DEFAULT_COVERAGE_CANDIDATES = [\n \"spec/coverage.config.ts\",\n \"spec/coverage.config.js\",\n \"spec/coverage.config.mjs\",\n \"spec/coverage.config.cjs\",\n \"spec/coverage.config.json\",\n]\n\nconst LEGACY_COVERAGE_CANDIDATES = [\n \"spec/coverage.ts\",\n \"spec/coverage.js\",\n \"spec/coverage.mjs\",\n \"spec/coverage.cjs\",\n \"spec/coverage.json\",\n]\n\nexport async function loadCoverageOptions({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): Promise<CoverageHarnessOptions | null> {\n const projectRoot = process.cwd()\n const legacy = await findCoverageFile(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = await findCoverageFile(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = await importCoverageModule(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return await normalizeOptions(raw, resolved)\n}\n\nexport function loadCoverageOptionsSync({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): CoverageHarnessOptions | null {\n const projectRoot = process.cwd()\n const legacy = findCoverageFileSync(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = findCoverageFileSync(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = importCoverageModuleSync(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return normalizeOptionsSync(raw, resolved)\n}\n\nasync function findCoverageFile(root: string, candidates: string[]): Promise<string | null> {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n await fs.access(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nfunction findCoverageFileSync(root: string, candidates: string[]): string | null {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n fsSync.accessSync(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nasync function importCoverageModule(filePath: string): Promise<unknown> {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = await fs.readFile(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".ts\") {\n const compiledUrl = await compileTsModule(filePath)\n return loadModule(compiledUrl)\n }\n\n const moduleUrl = pathToFileURL(filePath).href\n return loadModule(moduleUrl)\n}\n\nfunction importCoverageModuleSync(filePath: string): unknown {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = fsSync.readFileSync(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".cjs\") {\n return loadModuleSync(filePath)\n }\n\n const compiledPath = compileCjsModuleSync(filePath)\n return loadModuleSync(compiledPath)\n}\n\nasync function compileTsModule(filePath: string): Promise<string> {\n const stat = await fs.stat(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n await fs.mkdir(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.mjs`)\n\n await build({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"esm\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return pathToFileURL(outfile).href\n}\n\nfunction compileCjsModuleSync(filePath: string): string {\n const stat = fsSync.statSync(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n fsSync.mkdirSync(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.cjs`)\n\n buildSync({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"cjs\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return outfile\n}\n\nasync function loadModule(url: string): Promise<unknown> {\n const imported = await import(url)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nfunction loadModuleSync(modulePath: string): unknown {\n const imported = require(modulePath)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nconst DEFAULT_COLLECT_COVERAGE_EXTENSIONS = \"ts,tsx,js,jsx,mjs,cjs\"\nconst DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE = `!**/*.test.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`\n\nasync function resolveCollectCoverageFrom(rawPatterns: unknown, rootDir: string): Promise<string[]> {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = await inferDefaultCollectCoverageFrom(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nfunction resolveCollectCoverageFromSync(rawPatterns: unknown, rootDir: string): string[] {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = inferDefaultCollectCoverageFromSync(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nasync function inferDefaultCollectCoverageFrom(rootDir: string): Promise<string[]> {\n const srcDir = path.join(rootDir, \"src\")\n if (await isDirectory(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction inferDefaultCollectCoverageFromSync(rootDir: string): string[] {\n const srcDir = path.join(rootDir, \"src\")\n if (isDirectorySync(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction withDefaultExcludes(patterns: string[]): string[] {\n if (!Array.isArray(patterns) || patterns.length === 0) {\n return patterns\n }\n\n const hasTestExclude = patterns.some((pattern) => {\n const raw = String(pattern ?? \"\")\n if (!raw.startsWith(\"!\")) {\n return false\n }\n return /\\.test(?:\\.|\\{|$)/.test(raw.slice(1))\n })\n if (hasTestExclude) {\n return patterns\n }\n\n return [...patterns, DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE]\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nfunction isDirectorySync(filePath: string): boolean {\n try {\n const stat = fsSync.statSync(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nasync function normalizeOptions(\n rawOptions: any,\n filePath: string,\n): Promise<CoverageHarnessOptions> {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = await resolveCollectCoverageFrom(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nfunction normalizeOptionsSync(\n rawOptions: any,\n filePath: string,\n): CoverageHarnessOptions {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = resolveCollectCoverageFromSync(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nexport { DEFAULT_COVERAGE_CANDIDATES }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config-loader.js","sources":["../../src/coverage/config-loader.ts"],"sourcesContent":["import fs from \"node:fs/promises\"\nimport fsSync from \"node:fs\"\nimport path from \"node:path\"\nimport os from \"node:os\"\nimport crypto from \"node:crypto\"\nimport { createRequire } from \"node:module\"\nimport { pathToFileURL } from \"node:url\"\n\nimport { build, buildSync } from \"esbuild\"\n\nimport type { CoverageHarnessOptions } from \"./types\"\n\n\nconst require = createRequire(import.meta.url)\n\ntype LoadCoverageOptionsArgs = {\n optional?: boolean\n candidates?: string[]\n}\n\nconst DEFAULT_COVERAGE_CANDIDATES = [\n \"spec/coverage.config.ts\",\n \"spec/coverage.config.js\",\n \"spec/coverage.config.mjs\",\n \"spec/coverage.config.cjs\",\n \"spec/coverage.config.json\",\n]\n\nconst LEGACY_COVERAGE_CANDIDATES = [\n \"spec/coverage.ts\",\n \"spec/coverage.js\",\n \"spec/coverage.mjs\",\n \"spec/coverage.cjs\",\n \"spec/coverage.json\",\n]\n\nexport async function loadCoverageOptions({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): Promise<CoverageHarnessOptions | null> {\n const projectRoot = process.cwd()\n const legacy = await findCoverageFile(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = await findCoverageFile(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = await importCoverageModule(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return await normalizeOptions(raw, resolved)\n}\n\nexport function loadCoverageOptionsSync({\n optional = false,\n candidates = DEFAULT_COVERAGE_CANDIDATES,\n}: LoadCoverageOptionsArgs = {}): CoverageHarnessOptions | null {\n const projectRoot = process.cwd()\n const legacy = findCoverageFileSync(projectRoot, LEGACY_COVERAGE_CANDIDATES)\n if (legacy) {\n const ext = path.extname(legacy)\n const suggested = path.join(\"spec\", `coverage.config${ext}`)\n throw new Error(\n `Legacy coverage config detected (${path.relative(projectRoot, legacy)}). Rename it to ${suggested}.`,\n )\n }\n\n const resolved = findCoverageFileSync(projectRoot, candidates)\n\n if (!resolved) {\n if (optional) {\n return null\n }\n throw new Error(\n \"Coverage config not found. Create `spec/coverage.config.{ts,js,json}` with your coverage settings.\",\n )\n }\n\n const raw = importCoverageModuleSync(resolved)\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`Coverage config at ${resolved} must export an object.`)\n }\n\n return normalizeOptionsSync(raw, resolved)\n}\n\nasync function findCoverageFile(root: string, candidates: string[]): Promise<string | null> {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n await fs.access(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nfunction findCoverageFileSync(root: string, candidates: string[]): string | null {\n for (const relative of candidates) {\n const candidate = path.resolve(root, relative)\n try {\n fsSync.accessSync(candidate)\n return candidate\n } catch {\n // continue\n }\n }\n return null\n}\n\nasync function importCoverageModule(filePath: string): Promise<unknown> {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = await fs.readFile(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".ts\") {\n const compiledUrl = await compileTsModule(filePath)\n return loadModule(compiledUrl)\n }\n\n const moduleUrl = pathToFileURL(filePath).href\n return loadModule(moduleUrl)\n}\n\nfunction importCoverageModuleSync(filePath: string): unknown {\n const ext = path.extname(filePath)\n\n if (ext === \".json\") {\n const raw = fsSync.readFileSync(filePath, \"utf8\")\n return JSON.parse(raw)\n }\n\n if (ext === \".cjs\") {\n return loadModuleSync(filePath)\n }\n\n const compiledPath = compileCjsModuleSync(filePath)\n return loadModuleSync(compiledPath)\n}\n\nasync function compileTsModule(filePath: string): Promise<string> {\n const stat = await fs.stat(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n await fs.mkdir(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.mjs`)\n\n await build({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"esm\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return pathToFileURL(outfile).href\n}\n\nfunction compileCjsModuleSync(filePath: string): string {\n const stat = fsSync.statSync(filePath)\n const hash = crypto\n .createHash(\"sha1\")\n .update(filePath)\n .update(String(stat.mtimeMs))\n .digest(\"hex\")\n\n const outDir = path.join(os.tmpdir(), \"rpcbase-test\")\n fsSync.mkdirSync(outDir, { recursive: true })\n const outfile = path.join(outDir, `coverage-${hash}.cjs`)\n\n buildSync({\n entryPoints: [filePath],\n outfile,\n platform: \"node\",\n format: \"cjs\",\n bundle: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n })\n\n return outfile\n}\n\nasync function loadModule(url: string): Promise<unknown> {\n const imported = await import(url)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nfunction loadModuleSync(modulePath: string): unknown {\n const imported = require(modulePath)\n if (imported && typeof imported.default === \"object\") {\n return imported.default\n }\n return imported\n}\n\nconst DEFAULT_COLLECT_COVERAGE_EXTENSIONS = \"ts,tsx,js,jsx,mjs,cjs\"\nconst DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE = `!**/*.test.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`\n\nasync function resolveCollectCoverageFrom(rawPatterns: unknown, rootDir: string): Promise<string[]> {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = await inferDefaultCollectCoverageFrom(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nfunction resolveCollectCoverageFromSync(rawPatterns: unknown, rootDir: string): string[] {\n const resolvedRootDir = path.resolve(String(rootDir ?? \"\"))\n\n const normalized = Array.isArray(rawPatterns)\n ? rawPatterns\n .map((pattern) => String(pattern ?? \"\").trim())\n .filter((pattern) => pattern.length > 0)\n : []\n\n const excludes = normalized.filter((pattern) => pattern.startsWith(\"!\"))\n const hasIncludes = normalized.some((pattern) => !pattern.startsWith(\"!\"))\n if (hasIncludes) {\n return withDefaultExcludes(normalized)\n }\n\n const defaults = inferDefaultCollectCoverageFromSync(resolvedRootDir)\n if (defaults.length === 0) {\n throw new Error(\n \"Coverage config: couldn't infer a default `collectCoverageFrom` (src/ directory missing). Provide `collectCoverageFrom` with at least one positive glob pattern.\",\n )\n }\n\n return withDefaultExcludes([...defaults, ...excludes])\n}\n\nasync function inferDefaultCollectCoverageFrom(rootDir: string): Promise<string[]> {\n const srcDir = path.join(rootDir, \"src\")\n if (await isDirectory(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction inferDefaultCollectCoverageFromSync(rootDir: string): string[] {\n const srcDir = path.join(rootDir, \"src\")\n if (isDirectorySync(srcDir)) {\n return [`src/**/*.{${DEFAULT_COLLECT_COVERAGE_EXTENSIONS}}`]\n }\n\n return []\n}\n\nfunction withDefaultExcludes(patterns: string[]): string[] {\n if (!Array.isArray(patterns) || patterns.length === 0) {\n return patterns\n }\n\n const hasTestExclude = patterns.some((pattern) => {\n const raw = String(pattern ?? \"\")\n if (!raw.startsWith(\"!\")) {\n return false\n }\n return /\\.test(?:\\.|\\{|$)/.test(raw.slice(1))\n })\n if (hasTestExclude) {\n return patterns\n }\n\n return [...patterns, DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE]\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nfunction isDirectorySync(filePath: string): boolean {\n try {\n const stat = fsSync.statSync(filePath)\n return stat.isDirectory()\n } catch {\n return false\n }\n}\n\nasync function normalizeOptions(\n rawOptions: any,\n filePath: string,\n): Promise<CoverageHarnessOptions> {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = await resolveCollectCoverageFrom(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nfunction normalizeOptionsSync(\n rawOptions: any,\n filePath: string,\n): CoverageHarnessOptions {\n const options = { ...rawOptions }\n const configDir = path.dirname(filePath)\n const rootDir = path.resolve(configDir, \"..\")\n\n const collectCoverageFrom = resolveCollectCoverageFromSync(options.collectCoverageFrom, rootDir)\n\n return {\n rootDir,\n collectCoverageFrom,\n coverageFileName: options.coverageFileName ?? \"v8-coverage.json\",\n includeAllFiles: options.includeAllFiles,\n thresholds: options.thresholds ?? {},\n }\n}\n\nexport { DEFAULT_COVERAGE_CANDIDATES }\n"],"names":["require","createRequire","import","url","DEFAULT_COVERAGE_CANDIDATES","LEGACY_COVERAGE_CANDIDATES","loadCoverageOptions","optional","candidates","projectRoot","process","cwd","legacy","findCoverageFile","ext","path","extname","suggested","join","Error","relative","resolved","raw","importCoverageModule","normalizeOptions","loadCoverageOptionsSync","findCoverageFileSync","importCoverageModuleSync","normalizeOptionsSync","root","candidate","resolve","fs","access","fsSync","accessSync","filePath","readFile","JSON","parse","compiledUrl","compileTsModule","loadModule","moduleUrl","pathToFileURL","href","readFileSync","loadModuleSync","compiledPath","compileCjsModuleSync","stat","hash","crypto","createHash","update","String","mtimeMs","digest","outDir","os","tmpdir","mkdir","recursive","outfile","build","entryPoints","platform","format","bundle","sourcemap","logLevel","statSync","mkdirSync","buildSync","imported","default","modulePath","DEFAULT_COLLECT_COVERAGE_EXTENSIONS","DEFAULT_COLLECT_COVERAGE_TEST_EXCLUDE","resolveCollectCoverageFrom","rawPatterns","rootDir","resolvedRootDir","normalized","Array","isArray","map","pattern","trim","filter","length","excludes","startsWith","hasIncludes","some","withDefaultExcludes","defaults","inferDefaultCollectCoverageFrom","resolveCollectCoverageFromSync","inferDefaultCollectCoverageFromSync","srcDir","isDirectory","isDirectorySync","patterns","hasTestExclude","test","slice","rawOptions","options","configDir","dirname","collectCoverageFrom","coverageFileName","includeAllFiles","thresholds"],"mappings":"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"}
|