@vitest-agent/plugin 1.1.1 → 1.1.2
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/index.d.ts +5 -0
- package/package.json +2 -2
- package/plugin.js +30 -1
- package/utils/discover-projects.js +64 -4
- package/utils/is-benign-vite-source-map-warning.js +21 -0
package/index.d.ts
CHANGED
|
@@ -223,6 +223,11 @@ declare const CURRENT_PLUGIN_VERSION: string;
|
|
|
223
223
|
*/
|
|
224
224
|
declare function AgentPlugin(options?: AgentPluginConstructorOptions, _layer?: Layer.Layer<EnvironmentDetector>): {
|
|
225
225
|
name: "vitest-agent";
|
|
226
|
+
configResolved: (resolvedConfig: {
|
|
227
|
+
logger: {
|
|
228
|
+
warn: (msg: string, options?: unknown) => void;
|
|
229
|
+
};
|
|
230
|
+
}) => void;
|
|
226
231
|
configureVitest(ctx: VitestPluginContext): Promise<void>;
|
|
227
232
|
transform?: (code: string, id: string) => InjectTagsResult | null;
|
|
228
233
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/plugin",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vitest plugin for the vitest-agent ecosystem: owns persistence, classification, baselines, trends, and dispatches rendering to a configurable reporter.",
|
|
6
6
|
"keywords": [
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"@vitest-agent/cli": "1.0.2",
|
|
57
|
-
"@vitest-agent/mcp": "1.
|
|
57
|
+
"@vitest-agent/mcp": "1.3.0",
|
|
58
58
|
"@vitest/coverage-istanbul": "^4.1.0",
|
|
59
59
|
"@vitest/coverage-v8": "^4.1.0",
|
|
60
60
|
"vitest": "^4.1.0"
|
package/plugin.js
CHANGED
|
@@ -6,6 +6,7 @@ import { buildModuleInfo } from "./utils/build-module-info.js";
|
|
|
6
6
|
import { DefaultDiscoverStrategy } from "./utils/discover-strategy.js";
|
|
7
7
|
import { discoverProjects } from "./utils/discover-projects.js";
|
|
8
8
|
import { injectTags } from "./utils/inject-tags.js";
|
|
9
|
+
import { isBenignViteSourceMapWarning } from "./utils/is-benign-vite-source-map-warning.js";
|
|
9
10
|
import { stripConsoleReporters } from "./utils/strip-console-reporters.js";
|
|
10
11
|
import { execSync } from "node:child_process";
|
|
11
12
|
import { AgentConsoleMode, CiConsoleMode, CoverageLevel, EnvironmentDetector, EnvironmentDetectorLive, HumanConsoleMode, formatFatalError, resolveLogLevel } from "@vitest-agent/sdk";
|
|
@@ -97,7 +98,7 @@ const aggregatedReporterByVitest = /* @__PURE__ */ new WeakSet();
|
|
|
97
98
|
*
|
|
98
99
|
* @public
|
|
99
100
|
*/
|
|
100
|
-
const CURRENT_PLUGIN_VERSION = "1.1.
|
|
101
|
+
const CURRENT_PLUGIN_VERSION = "1.1.2";
|
|
101
102
|
const TEST_FILE_SUFFIX_RE = /\.(?:test|spec)\.(?:ts|tsx|js|jsx)$/;
|
|
102
103
|
const TEST_FILE_DIR_RE = /\/(?:src|__test__)\//;
|
|
103
104
|
const isTestFile = (id) => TEST_FILE_SUFFIX_RE.test(id) && TEST_FILE_DIR_RE.test(id);
|
|
@@ -115,6 +116,31 @@ function envToExecutor(env) {
|
|
|
115
116
|
return "ci";
|
|
116
117
|
}
|
|
117
118
|
/**
|
|
119
|
+
* Wraps `resolvedConfig.logger.warn` in place so the benign Vite
|
|
120
|
+
* "Failed to load source map" / ENOENT `.js.map` noise (GitHub issue #110)
|
|
121
|
+
* never reaches stdout, while every other warning still passes through
|
|
122
|
+
* untouched.
|
|
123
|
+
*
|
|
124
|
+
* Every Vite per-environment logger (`environment.logger`) delegates its
|
|
125
|
+
* `warn` calls to the single root `resolvedConfig.logger.warn` function
|
|
126
|
+
* reference (see Vite's `PartialEnvironment` constructor), so mutating that
|
|
127
|
+
* one function here intercepts the warning regardless of which environment
|
|
128
|
+
* (`client`, `ssr`, ...) triggered it. Wrapping happens in `configResolved`
|
|
129
|
+
* (rather than returning a `customLogger` from the plugin's `config` hook)
|
|
130
|
+
* because Vite's own config-resolution pipeline can construct or replace
|
|
131
|
+
* the logger between `config` and `configResolved` — mutating the already-
|
|
132
|
+
* resolved logger instance in place is the wiring that survives.
|
|
133
|
+
*
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
136
|
+
function installViteSourceMapWarningFilter(resolvedConfig) {
|
|
137
|
+
const originalWarn = resolvedConfig.logger.warn.bind(resolvedConfig.logger);
|
|
138
|
+
resolvedConfig.logger.warn = (msg, options) => {
|
|
139
|
+
if (isBenignViteSourceMapWarning(msg)) return;
|
|
140
|
+
originalWarn(msg, options);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
118
144
|
* Vitest plugin that injects `AgentReporter` into the reporter chain.
|
|
119
145
|
*
|
|
120
146
|
* @param options - Plugin configuration options
|
|
@@ -130,6 +156,9 @@ function AgentPlugin(options = {}, _layer) {
|
|
|
130
156
|
const discoverStrategyResolved = options.discoverStrategy === false ? null : options.discoverStrategy ?? new DefaultDiscoverStrategy();
|
|
131
157
|
const pluginObj = {
|
|
132
158
|
name: "vitest-agent",
|
|
159
|
+
configResolved(resolvedConfig) {
|
|
160
|
+
installViteSourceMapWarningFilter(resolvedConfig);
|
|
161
|
+
},
|
|
133
162
|
async configureVitest(ctx) {
|
|
134
163
|
try {
|
|
135
164
|
const { vitest, project } = ctx;
|
|
@@ -1,11 +1,65 @@
|
|
|
1
1
|
import { toPosixPath } from "./to-posix-path.js";
|
|
2
2
|
import { DefaultDiscoverStrategy } from "./discover-strategy.js";
|
|
3
3
|
import { isAbsolute, join, normalize, relative } from "node:path";
|
|
4
|
+
import { readdir, stat } from "node:fs/promises";
|
|
4
5
|
import { findWorkspaceRootSync, getWorkspacePackagesSync } from "workspaces-effect";
|
|
5
6
|
|
|
6
7
|
//#region src/utils/discover-projects.ts
|
|
8
|
+
const DISCOVERY_LAST_SCAN_SYMBOL = Symbol.for("vitest-agent:discovery:last-scan-at");
|
|
9
|
+
function recordDiscoveryScanTimestamp() {
|
|
10
|
+
globalThis[DISCOVERY_LAST_SCAN_SYMBOL] = (/* @__PURE__ */ new Date()).toISOString();
|
|
11
|
+
}
|
|
7
12
|
const _cache = /* @__PURE__ */ new Map();
|
|
8
13
|
/**
|
|
14
|
+
* Computes a cheap signature (relative path + mtimeMs pairs, sorted) for every
|
|
15
|
+
* file nested under `dirPath`. Used to detect added/removed/moved/renamed test
|
|
16
|
+
* files between `discoverProjects` calls without re-walking test-file globs.
|
|
17
|
+
* Returns an empty string when `dirPath` does not exist — this still produces
|
|
18
|
+
* a stable, comparable signature contribution.
|
|
19
|
+
*/
|
|
20
|
+
async function computeDirSignature(dirPath) {
|
|
21
|
+
let entries;
|
|
22
|
+
try {
|
|
23
|
+
entries = await readdir(dirPath, {
|
|
24
|
+
withFileTypes: true,
|
|
25
|
+
recursive: true
|
|
26
|
+
});
|
|
27
|
+
} catch {
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
const parts = [];
|
|
31
|
+
for (const ent of entries) {
|
|
32
|
+
if (!ent.isFile()) continue;
|
|
33
|
+
const fullPath = join(ent.parentPath ?? dirPath, ent.name);
|
|
34
|
+
let mtimeMs;
|
|
35
|
+
try {
|
|
36
|
+
mtimeMs = (await stat(fullPath)).mtimeMs;
|
|
37
|
+
} catch {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const relPath = toPosixPath(relative(dirPath, fullPath));
|
|
41
|
+
parts.push(`${relPath}:${mtimeMs}`);
|
|
42
|
+
}
|
|
43
|
+
parts.sort();
|
|
44
|
+
return parts.join("|");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Computes a cheap whole-workspace directory signature by combining each
|
|
48
|
+
* package's `src/` and `__test__/` signatures (issue #100). Only entries +
|
|
49
|
+
* mtimes are read — no file content — so this stays fast even for large
|
|
50
|
+
* monorepos. A changed signature means a test file was added, removed,
|
|
51
|
+
* moved, or renamed since the cached result was computed.
|
|
52
|
+
*/
|
|
53
|
+
async function computeWorkspaceSignature(packages) {
|
|
54
|
+
const parts = [];
|
|
55
|
+
for (const pkg of packages) {
|
|
56
|
+
const srcSig = await computeDirSignature(join(pkg.path, "src"));
|
|
57
|
+
const testDirSig = await computeDirSignature(join(pkg.path, "__test__"));
|
|
58
|
+
parts.push(`${pkg.path}::src=${srcSig}::__test__=${testDirSig}`);
|
|
59
|
+
}
|
|
60
|
+
return parts.join("\n");
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
9
63
|
* Scan all workspace packages and additional entries through the active strategy and return projects + tags.
|
|
10
64
|
* @param options - Optional strategy, working directory, and extra project entries
|
|
11
65
|
* @returns Resolved projects and tag definitions
|
|
@@ -18,12 +72,14 @@ async function discoverProjects(options) {
|
|
|
18
72
|
const root = findWorkspaceRootSync(cwd ?? process.cwd());
|
|
19
73
|
if (!root) throw new Error(`[vitest-agent] Could not find workspace root from ${cwd ?? process.cwd()}. Ensure a pnpm-workspace.yaml or package.json with "workspaces" exists.`);
|
|
20
74
|
const useCache = strategy === void 0 && additionalEntries.length === 0;
|
|
75
|
+
const resolvedStrategy = strategy ?? new DefaultDiscoverStrategy();
|
|
76
|
+
const packages = getWorkspacePackagesSync(root);
|
|
77
|
+
let signature;
|
|
21
78
|
if (useCache) {
|
|
79
|
+
signature = await computeWorkspaceSignature(packages);
|
|
22
80
|
const cached = _cache.get(root);
|
|
23
|
-
if (cached) return cached;
|
|
81
|
+
if (cached && cached.signature === signature) return cached.result;
|
|
24
82
|
}
|
|
25
|
-
const resolvedStrategy = strategy ?? new DefaultDiscoverStrategy();
|
|
26
|
-
const packages = getWorkspacePackagesSync(root);
|
|
27
83
|
const configs = [];
|
|
28
84
|
const workspaceNames = /* @__PURE__ */ new Set();
|
|
29
85
|
const workspacePaths = /* @__PURE__ */ new Set();
|
|
@@ -60,7 +116,11 @@ async function discoverProjects(options) {
|
|
|
60
116
|
projects: configs.length > 0 ? configs : void 0,
|
|
61
117
|
tags
|
|
62
118
|
};
|
|
63
|
-
if (useCache) _cache.set(root,
|
|
119
|
+
if (useCache && signature !== void 0) _cache.set(root, {
|
|
120
|
+
result,
|
|
121
|
+
signature
|
|
122
|
+
});
|
|
123
|
+
recordDiscoveryScanTimestamp();
|
|
64
124
|
return result;
|
|
65
125
|
}
|
|
66
126
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/utils/is-benign-vite-source-map-warning.ts
|
|
2
|
+
/**
|
|
3
|
+
* Matches the benign Vite core warning emitted when a dependency's shipped
|
|
4
|
+
* `.js` file references a `.js.map` sibling that was never published in the
|
|
5
|
+
* npm tarball (the canonical example: `typescript/lib/typescript.js` /
|
|
6
|
+
* `typescript.js.map`). Vite core's `loadAndTransform` logs this through
|
|
7
|
+
* `environment.logger.warn` — not through per-test console output — so it
|
|
8
|
+
* cannot be filtered by the console-leak path. See GitHub issue #110.
|
|
9
|
+
*
|
|
10
|
+
* Only matches the specific "Failed to load source map" + ENOENT `.js.map`
|
|
11
|
+
* shape; every other warning (including unrelated ENOENT errors against
|
|
12
|
+
* other file extensions) returns `false` so it still surfaces.
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
function isBenignViteSourceMapWarning(message) {
|
|
16
|
+
if (!message) return false;
|
|
17
|
+
return /Failed to load source map/.test(message) && /ENOENT:.*\.js\.map/.test(message);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { isBenignViteSourceMapWarning };
|