@hublo/sentinel 1.4.0-alpha.52 → 1.4.0-alpha.54
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/bin/sentinel.js
CHANGED
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
palette,
|
|
16
16
|
registerAdapters,
|
|
17
17
|
resolve
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-DEDLGEHF.js";
|
|
19
19
|
import {
|
|
20
20
|
resolveContext
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-WE2AU6M2.js";
|
|
22
22
|
import "../chunk-O7REVMOC.js";
|
|
23
23
|
import "../chunk-QXFCZON7.js";
|
|
24
24
|
import {
|
|
@@ -145,7 +145,7 @@ async function runValidate(ctx) {
|
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
if (!ctx.targets.includes("test")) return 1;
|
|
148
|
-
const { validateModuleTests } = await import("../validate-
|
|
148
|
+
const { validateModuleTests } = await import("../validate-T2YQFHJA.js");
|
|
149
149
|
const outcomes = modules.flatMap(
|
|
150
150
|
(module) => validateModuleTests(module.name, module.root)
|
|
151
151
|
);
|
|
@@ -980,17 +980,8 @@ function walk(node, visit) {
|
|
|
980
980
|
}
|
|
981
981
|
var MEMBER_TYPES = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
|
|
982
982
|
|
|
983
|
-
// src/roles/test/codemod/edits.ts
|
|
984
|
-
function applyEdits(source, edits) {
|
|
985
|
-
let result = source;
|
|
986
|
-
for (const edit of [...edits].sort((left, right) => right.start - left.start)) {
|
|
987
|
-
result = `${result.slice(0, edit.start)}${edit.text}${result.slice(edit.end)}`;
|
|
988
|
-
}
|
|
989
|
-
return result;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
983
|
// src/roles/test/codemod/inherited-automocks.ts
|
|
993
|
-
function
|
|
984
|
+
function bareModuleCalls(program, method) {
|
|
994
985
|
const found = [];
|
|
995
986
|
walk(program, (node) => {
|
|
996
987
|
if (node.type !== "CallExpression") return;
|
|
@@ -999,7 +990,7 @@ function bareModuleMocks(program) {
|
|
|
999
990
|
const object = callee.object;
|
|
1000
991
|
const property = callee.property;
|
|
1001
992
|
if (object?.type !== "Identifier" || object.name !== "jest" && object.name !== "vi") return;
|
|
1002
|
-
if (property?.type !== "Identifier" || property.name !==
|
|
993
|
+
if (property?.type !== "Identifier" || property.name !== method) return;
|
|
1003
994
|
const args = node.arguments ?? [];
|
|
1004
995
|
if (args.length !== 1) return;
|
|
1005
996
|
const [specifier] = args;
|
|
@@ -1009,7 +1000,7 @@ function bareModuleMocks(program) {
|
|
|
1009
1000
|
});
|
|
1010
1001
|
return found;
|
|
1011
1002
|
}
|
|
1012
|
-
function inheritedAutomocks(cwd, setupFiles,
|
|
1003
|
+
function inheritedAutomocks(cwd, setupFiles, parse6) {
|
|
1013
1004
|
const found = /* @__PURE__ */ new Set();
|
|
1014
1005
|
for (const named of setupFiles) {
|
|
1015
1006
|
const path = resolve3(cwd, named.replace("<rootDir>/", "./"));
|
|
@@ -1021,41 +1012,27 @@ function inheritedAutomocks(cwd, setupFiles, parse5) {
|
|
|
1021
1012
|
} catch {
|
|
1022
1013
|
continue;
|
|
1023
1014
|
}
|
|
1024
|
-
const program =
|
|
1015
|
+
const program = parse6(path, source);
|
|
1025
1016
|
if (program === void 0) continue;
|
|
1026
|
-
for (const specifier of
|
|
1017
|
+
for (const specifier of bareModuleCalls(program, "mock")) found.add(specifier);
|
|
1027
1018
|
}
|
|
1028
1019
|
return [...found].sort();
|
|
1029
1020
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
);
|
|
1043
|
-
if (missing.length === 0) return source;
|
|
1044
|
-
const imports = (program.body ?? []).filter(
|
|
1045
|
-
(node) => node.type === "ImportDeclaration"
|
|
1046
|
-
);
|
|
1047
|
-
const last = imports[imports.length - 1];
|
|
1048
|
-
const at = last === void 0 ? 0 : last.end;
|
|
1049
|
-
const semi = /^import\s[^\n]*;\s*$/m.test(source) ? ";" : "";
|
|
1050
|
-
const block = missing.map((specifier) => `vi.mock('${specifier}')${semi}`).join("\n");
|
|
1051
|
-
const edits = [
|
|
1052
|
-
{ start: at, end: at, text: last === void 0 ? `${block}
|
|
1053
|
-
|
|
1054
|
-
` : `
|
|
1021
|
+
var INHERITED_MOCKS_SETUP = "vitest.setup.inherited-mocks.mts";
|
|
1022
|
+
function inheritedMocksSetup(specifiers) {
|
|
1023
|
+
const lines = specifiers.map((specifier) => `vi.mock('${specifier}')`);
|
|
1024
|
+
return `/**
|
|
1025
|
+
* Module mocks the workspace's jest setup made for every suite, declared where you can see
|
|
1026
|
+
* them.
|
|
1027
|
+
*
|
|
1028
|
+
* The root setup mocked these for every file of every module that named it, and this
|
|
1029
|
+
* migration cuts that reach on purpose. A spec that wants the real module says
|
|
1030
|
+
* \`vi.unmock('<specifier>')\`: a file beats a setup.
|
|
1031
|
+
*/
|
|
1032
|
+
import { vi } from 'vitest'
|
|
1055
1033
|
|
|
1056
|
-
${
|
|
1057
|
-
|
|
1058
|
-
return applyEdits(source, edits);
|
|
1034
|
+
${lines.join("\n")}
|
|
1035
|
+
`;
|
|
1059
1036
|
}
|
|
1060
1037
|
|
|
1061
1038
|
// src/roles/test/codemod/inject-type-import.ts
|
|
@@ -1248,6 +1225,15 @@ ${source}`;
|
|
|
1248
1225
|
import { dirname as dirname8 } from "node:path";
|
|
1249
1226
|
import { parseSync as parseSync8 } from "oxc-parser";
|
|
1250
1227
|
|
|
1228
|
+
// src/roles/test/codemod/edits.ts
|
|
1229
|
+
function applyEdits(source, edits) {
|
|
1230
|
+
let result = source;
|
|
1231
|
+
for (const edit of [...edits].sort((left, right) => right.start - left.start)) {
|
|
1232
|
+
result = `${result.slice(0, edit.start)}${edit.text}${result.slice(edit.end)}`;
|
|
1233
|
+
}
|
|
1234
|
+
return result;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1251
1237
|
// src/roles/test/codemod/assertion-return-value.ts
|
|
1252
1238
|
function rootedAtExpect(node) {
|
|
1253
1239
|
let current = node;
|
|
@@ -4390,11 +4376,6 @@ function defaultImportedSpecifiers(cwd) {
|
|
|
4390
4376
|
walk2(cwd);
|
|
4391
4377
|
return found;
|
|
4392
4378
|
}
|
|
4393
|
-
function declaredInheritedMocks(fileName, source, inherited) {
|
|
4394
|
-
if (inherited.length === 0) return source;
|
|
4395
|
-
const program = parse4(fileName, source);
|
|
4396
|
-
return program === void 0 ? source : declareInheritedAutomocks(source, program, inherited);
|
|
4397
|
-
}
|
|
4398
4379
|
function migrateModuleTests(cwd, setupFiles = []) {
|
|
4399
4380
|
const modulesOwnMsw = ownsMswLifecycle(cwd, setupFiles);
|
|
4400
4381
|
const inherited = inheritedAutomocks(cwd, setupFiles, parse4);
|
|
@@ -4472,12 +4453,14 @@ function migrateModuleTests(cwd, setupFiles = []) {
|
|
|
4472
4453
|
files++;
|
|
4473
4454
|
renamed += migrated.renamed;
|
|
4474
4455
|
if (migrated.hoisted.length > 0) hoisted++;
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4456
|
+
operations.push({ kind: "write", path: relative8, contents: migrated.source });
|
|
4457
|
+
}
|
|
4458
|
+
if (inherited.length > 0) {
|
|
4459
|
+
operations.push({
|
|
4460
|
+
kind: "write",
|
|
4461
|
+
path: INHERITED_MOCKS_SETUP,
|
|
4462
|
+
contents: inheritedMocksSetup(inherited)
|
|
4463
|
+
});
|
|
4481
4464
|
}
|
|
4482
4465
|
const warnings = [...new Set(collected)];
|
|
4483
4466
|
return blockers.length > 0 ? { operations: [], files, renamed, hoisted, blockers, warnings } : { operations, files, renamed, hoisted, blockers: [], warnings };
|
|
@@ -4486,6 +4469,7 @@ function migrateModuleTests(cwd, setupFiles = []) {
|
|
|
4486
4469
|
// src/roles/test/nest/generate-config.ts
|
|
4487
4470
|
import { readdirSync as readdirSync5, readFileSync as readFileSync17, statSync as statSync6 } from "node:fs";
|
|
4488
4471
|
import { join as join19, relative as relative5 } from "node:path";
|
|
4472
|
+
import { parseSync as parseSync10 } from "oxc-parser";
|
|
4489
4473
|
var NEST_TEST_PRESET_SPECIFIER = "@hublo/sentinel/test/nest";
|
|
4490
4474
|
var REACT_TEST_PRESET_SPECIFIER = "@hublo/sentinel/test/react";
|
|
4491
4475
|
function flavourOf(reading) {
|
|
@@ -4565,16 +4549,22 @@ var withoutRootDir = (value) => value.replaceAll("<rootDir>/", "./").replaceAll(
|
|
|
4565
4549
|
function ownsMswLifecycle2(cwd, reading) {
|
|
4566
4550
|
return ownsMswLifecycle(cwd, [...reading.setupFiles ?? [], ...reading.setupFilesAfterEnv ?? []]);
|
|
4567
4551
|
}
|
|
4552
|
+
function parse5(fileName, source) {
|
|
4553
|
+
const { program, errors } = parseSync10(fileName, source, { sourceType: "module" });
|
|
4554
|
+
return errors.length > 0 ? void 0 : program;
|
|
4555
|
+
}
|
|
4568
4556
|
function setupBlock(cwd, reading, msw) {
|
|
4569
4557
|
const dom = flavourOf(reading) === "react";
|
|
4570
4558
|
const declared = [...reading.setupFiles ?? [], ...reading.setupFilesAfterEnv ?? []];
|
|
4571
4559
|
const namedTheRootSetup = declared.some((file) => file.endsWith("jest.setup.after.env.js"));
|
|
4572
4560
|
const own = declared.filter((file) => !file.endsWith("jest.setup.after.env.js")).map((file) => `'${vitestSupportName(withoutRootDir(file))}'`);
|
|
4561
|
+
const inheritedMocks = namedTheRootSetup && inheritedAutomocks(cwd, declared, parse5).length > 0 ? [`'./${INHERITED_MOCKS_SETUP}'`] : [];
|
|
4573
4562
|
const sentinel = [
|
|
4574
4563
|
`'${SENTINEL_TEST_SETUP}'`,
|
|
4575
4564
|
...dom ? [`'${SENTINEL_A11Y_SETUP}'`, `'${SENTINEL_W3C_SETUP}'`] : [],
|
|
4576
4565
|
...namedTheRootSetup ? [`'${SENTINEL_WORKSPACE_SETUP}'`] : [],
|
|
4577
|
-
...msw && namedTheRootSetup && !ownsMswLifecycle2(cwd, reading) ? [`'${SENTINEL_MSW_SETUP}'`] : []
|
|
4566
|
+
...msw && namedTheRootSetup && !ownsMswLifecycle2(cwd, reading) ? [`'${SENTINEL_MSW_SETUP}'`] : [],
|
|
4567
|
+
...inheritedMocks
|
|
4578
4568
|
];
|
|
4579
4569
|
return ` setupFiles: [${[...sentinel, ...own].join(", ")}],`;
|
|
4580
4570
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
registerAdapters,
|
|
7
7
|
resolve,
|
|
8
8
|
setDefaultRunner
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DEDLGEHF.js";
|
|
10
10
|
import {
|
|
11
11
|
BaseAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WE2AU6M2.js";
|
|
13
13
|
import "./chunk-O7REVMOC.js";
|
|
14
14
|
import "./chunk-QXFCZON7.js";
|
|
15
15
|
import "./chunk-KMKQDGI6.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hublo/sentinel",
|
|
3
|
-
"version": "1.4.0-alpha.
|
|
3
|
+
"version": "1.4.0-alpha.54",
|
|
4
4
|
"description": "One CLI that guards code health across Hublo repos: shared lint/typescript/build/test presets, static & dynamic analysis, and architecture checks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|