@hublo/sentinel 1.4.0-alpha.53 → 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.
@@ -15,10 +15,10 @@ import {
15
15
  palette,
16
16
  registerAdapters,
17
17
  resolve
18
- } from "../chunk-N5HLS3BX.js";
18
+ } from "../chunk-DEDLGEHF.js";
19
19
  import {
20
20
  resolveContext
21
- } from "../chunk-GAM4KIPA.js";
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-KQCFKTXU.js");
148
+ const { validateModuleTests } = await import("../validate-T2YQFHJA.js");
149
149
  const outcomes = modules.flatMap(
150
150
  (module) => validateModuleTests(module.name, module.root)
151
151
  );
@@ -53,7 +53,7 @@ import {
53
53
  selfCommand,
54
54
  splitToolArgs,
55
55
  walk
56
- } from "./chunk-GAM4KIPA.js";
56
+ } from "./chunk-WE2AU6M2.js";
57
57
  import {
58
58
  parseJsonc
59
59
  } from "./chunk-QXFCZON7.js";
@@ -980,15 +980,6 @@ 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
984
  function bareModuleCalls(program, method) {
994
985
  const found = [];
@@ -1009,7 +1000,7 @@ function bareModuleCalls(program, method) {
1009
1000
  });
1010
1001
  return found;
1011
1002
  }
1012
- function inheritedAutomocks(cwd, setupFiles, parse5) {
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,42 +1012,27 @@ function inheritedAutomocks(cwd, setupFiles, parse5) {
1021
1012
  } catch {
1022
1013
  continue;
1023
1014
  }
1024
- const program = parse5(path, source);
1015
+ const program = parse6(path, source);
1025
1016
  if (program === void 0) continue;
1026
1017
  for (const specifier of bareModuleCalls(program, "mock")) found.add(specifier);
1027
1018
  }
1028
1019
  return [...found].sort();
1029
1020
  }
1030
- function importsSpecifier(program, specifier) {
1031
- for (const statement2 of program.body ?? []) {
1032
- if (statement2.type !== "ImportDeclaration") continue;
1033
- const source = statement2.source;
1034
- if (source !== void 0 && String(source.value) === specifier) return true;
1035
- }
1036
- return false;
1037
- }
1038
- function declareInheritedAutomocks(source, program, specifiers) {
1039
- const alreadyMocked = new Set(bareModuleCalls(program, "mock"));
1040
- const refused = new Set(bareModuleCalls(program, "unmock"));
1041
- const missing = specifiers.filter(
1042
- (specifier) => !alreadyMocked.has(specifier) && !refused.has(specifier) && importsSpecifier(program, specifier)
1043
- );
1044
- if (missing.length === 0) return source;
1045
- const imports = (program.body ?? []).filter(
1046
- (node) => node.type === "ImportDeclaration"
1047
- );
1048
- const last = imports[imports.length - 1];
1049
- const at = last === void 0 ? 0 : last.end;
1050
- const semi = /^import\s[^\n]*;\s*$/m.test(source) ? ";" : "";
1051
- const block = missing.map((specifier) => `vi.mock('${specifier}')${semi}`).join("\n");
1052
- const edits = [
1053
- { start: at, end: at, text: last === void 0 ? `${block}
1054
-
1055
- ` : `
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'
1056
1033
 
1057
- ${block}` }
1058
- ];
1059
- return applyEdits(source, edits);
1034
+ ${lines.join("\n")}
1035
+ `;
1060
1036
  }
1061
1037
 
1062
1038
  // src/roles/test/codemod/inject-type-import.ts
@@ -1249,6 +1225,15 @@ ${source}`;
1249
1225
  import { dirname as dirname8 } from "node:path";
1250
1226
  import { parseSync as parseSync8 } from "oxc-parser";
1251
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
+
1252
1237
  // src/roles/test/codemod/assertion-return-value.ts
1253
1238
  function rootedAtExpect(node) {
1254
1239
  let current = node;
@@ -4391,11 +4376,6 @@ function defaultImportedSpecifiers(cwd) {
4391
4376
  walk2(cwd);
4392
4377
  return found;
4393
4378
  }
4394
- function declaredInheritedMocks(fileName, source, inherited) {
4395
- if (inherited.length === 0) return source;
4396
- const program = parse4(fileName, source);
4397
- return program === void 0 ? source : declareInheritedAutomocks(source, program, inherited);
4398
- }
4399
4379
  function migrateModuleTests(cwd, setupFiles = []) {
4400
4380
  const modulesOwnMsw = ownsMswLifecycle(cwd, setupFiles);
4401
4381
  const inherited = inheritedAutomocks(cwd, setupFiles, parse4);
@@ -4473,12 +4453,14 @@ function migrateModuleTests(cwd, setupFiles = []) {
4473
4453
  files++;
4474
4454
  renamed += migrated.renamed;
4475
4455
  if (migrated.hoisted.length > 0) hoisted++;
4476
- const withInheritedMocks = declaredInheritedMocks(
4477
- join18(cwd, relative8),
4478
- migrated.source,
4479
- inherited
4480
- );
4481
- operations.push({ kind: "write", path: relative8, contents: withInheritedMocks });
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
+ });
4482
4464
  }
4483
4465
  const warnings = [...new Set(collected)];
4484
4466
  return blockers.length > 0 ? { operations: [], files, renamed, hoisted, blockers, warnings } : { operations, files, renamed, hoisted, blockers: [], warnings };
@@ -4487,6 +4469,7 @@ function migrateModuleTests(cwd, setupFiles = []) {
4487
4469
  // src/roles/test/nest/generate-config.ts
4488
4470
  import { readdirSync as readdirSync5, readFileSync as readFileSync17, statSync as statSync6 } from "node:fs";
4489
4471
  import { join as join19, relative as relative5 } from "node:path";
4472
+ import { parseSync as parseSync10 } from "oxc-parser";
4490
4473
  var NEST_TEST_PRESET_SPECIFIER = "@hublo/sentinel/test/nest";
4491
4474
  var REACT_TEST_PRESET_SPECIFIER = "@hublo/sentinel/test/react";
4492
4475
  function flavourOf(reading) {
@@ -4566,16 +4549,22 @@ var withoutRootDir = (value) => value.replaceAll("<rootDir>/", "./").replaceAll(
4566
4549
  function ownsMswLifecycle2(cwd, reading) {
4567
4550
  return ownsMswLifecycle(cwd, [...reading.setupFiles ?? [], ...reading.setupFilesAfterEnv ?? []]);
4568
4551
  }
4552
+ function parse5(fileName, source) {
4553
+ const { program, errors } = parseSync10(fileName, source, { sourceType: "module" });
4554
+ return errors.length > 0 ? void 0 : program;
4555
+ }
4569
4556
  function setupBlock(cwd, reading, msw) {
4570
4557
  const dom = flavourOf(reading) === "react";
4571
4558
  const declared = [...reading.setupFiles ?? [], ...reading.setupFilesAfterEnv ?? []];
4572
4559
  const namedTheRootSetup = declared.some((file) => file.endsWith("jest.setup.after.env.js"));
4573
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}'`] : [];
4574
4562
  const sentinel = [
4575
4563
  `'${SENTINEL_TEST_SETUP}'`,
4576
4564
  ...dom ? [`'${SENTINEL_A11Y_SETUP}'`, `'${SENTINEL_W3C_SETUP}'`] : [],
4577
4565
  ...namedTheRootSetup ? [`'${SENTINEL_WORKSPACE_SETUP}'`] : [],
4578
- ...msw && namedTheRootSetup && !ownsMswLifecycle2(cwd, reading) ? [`'${SENTINEL_MSW_SETUP}'`] : []
4566
+ ...msw && namedTheRootSetup && !ownsMswLifecycle2(cwd, reading) ? [`'${SENTINEL_MSW_SETUP}'`] : [],
4567
+ ...inheritedMocks
4579
4568
  ];
4580
4569
  return ` setupFiles: [${[...sentinel, ...own].join(", ")}],`;
4581
4570
  }
package/dist/index.js CHANGED
@@ -6,10 +6,10 @@ import {
6
6
  registerAdapters,
7
7
  resolve,
8
8
  setDefaultRunner
9
- } from "./chunk-N5HLS3BX.js";
9
+ } from "./chunk-DEDLGEHF.js";
10
10
  import {
11
11
  BaseAdapter
12
- } from "./chunk-GAM4KIPA.js";
12
+ } from "./chunk-WE2AU6M2.js";
13
13
  import "./chunk-O7REVMOC.js";
14
14
  import "./chunk-QXFCZON7.js";
15
15
  import "./chunk-KMKQDGI6.js";
@@ -7,7 +7,7 @@ import {
7
7
  readTestAdoption,
8
8
  resolveVitest,
9
9
  suiteOf
10
- } from "./chunk-GAM4KIPA.js";
10
+ } from "./chunk-WE2AU6M2.js";
11
11
  import "./chunk-O7REVMOC.js";
12
12
  import "./chunk-QXFCZON7.js";
13
13
  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.53",
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",