@hublo/sentinel 1.4.0-alpha.26 → 1.4.0-alpha.27

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.
@@ -16,7 +16,7 @@ import {
16
16
  registerAdapters,
17
17
  resolve,
18
18
  resolveContext
19
- } from "../chunk-ATDETQX5.js";
19
+ } from "../chunk-ABFNJZ6C.js";
20
20
  import {
21
21
  ensureWorkspacePrep,
22
22
  findWorkspaceRoot,
@@ -5774,12 +5774,38 @@ function rewriteAssertionReturnValue(source, program) {
5774
5774
  return { source: result, rewritten: captures.length - refusals.length, refusals };
5775
5775
  }
5776
5776
 
5777
- // src/roles/test/codemod/constructible-mocks.ts
5777
+ // src/roles/test/codemod/bare-mock-factory.ts
5778
5778
  var MEMBER_TYPES2 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5779
+ function isMockFactory(node) {
5780
+ if (node === void 0 || !MEMBER_TYPES2.has(node.type)) return false;
5781
+ const object = node.object;
5782
+ const property = node.property;
5783
+ if (object?.type !== "Identifier") return false;
5784
+ if (object.name !== "vi" && object.name !== "jest") return false;
5785
+ return property?.type === "Identifier" && property.name === "fn";
5786
+ }
5787
+ function invokeBareMockFactories(source, program) {
5788
+ const edits = [];
5789
+ walk(program, (node) => {
5790
+ if (node.type !== "CallExpression") return;
5791
+ for (const argument of node.arguments ?? []) {
5792
+ if (isMockFactory(argument)) edits.push(argument.end);
5793
+ }
5794
+ });
5795
+ if (edits.length === 0) return { source, rewritten: 0 };
5796
+ let result = source;
5797
+ for (const end of [...edits].sort((left, right) => right - left)) {
5798
+ result = `${result.slice(0, end)}()${result.slice(end)}`;
5799
+ }
5800
+ return { source: result, rewritten: edits.length };
5801
+ }
5802
+
5803
+ // src/roles/test/codemod/constructible-mocks.ts
5804
+ var MEMBER_TYPES3 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5779
5805
  function mockImplementationArrow(node) {
5780
5806
  if (node.type !== "CallExpression") return void 0;
5781
5807
  const callee = node.callee;
5782
- if (callee === void 0 || !MEMBER_TYPES2.has(callee.type)) return void 0;
5808
+ if (callee === void 0 || !MEMBER_TYPES3.has(callee.type)) return void 0;
5783
5809
  const property = callee.property;
5784
5810
  if (property?.type !== "Identifier" || property.name !== "mockImplementation") return void 0;
5785
5811
  const [argument] = node.arguments ?? [];
@@ -5788,7 +5814,7 @@ function mockImplementationArrow(node) {
5788
5814
  function assertedMockedClass(source, node) {
5789
5815
  if (node.type !== "CallExpression") return false;
5790
5816
  const callee = node.callee;
5791
- if (callee === void 0 || !MEMBER_TYPES2.has(callee.type)) return false;
5817
+ if (callee === void 0 || !MEMBER_TYPES3.has(callee.type)) return false;
5792
5818
  const object = callee.object;
5793
5819
  if (object === void 0) return false;
5794
5820
  return /\bMockedClass\b/.test(source.slice(object.start, object.end));
@@ -5864,16 +5890,16 @@ function normaliseDeepImports(source) {
5864
5890
  }
5865
5891
 
5866
5892
  // src/roles/test/codemod/each-table-rows.ts
5867
- var MEMBER_TYPES3 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5893
+ var MEMBER_TYPES4 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5868
5894
  var RUNNERS = /* @__PURE__ */ new Set(["it", "test", "describe"]);
5869
5895
  function eachTable(node) {
5870
5896
  if (node.type !== "CallExpression") return void 0;
5871
5897
  const callee = node.callee;
5872
- if (callee === void 0 || !MEMBER_TYPES3.has(callee.type)) return void 0;
5898
+ if (callee === void 0 || !MEMBER_TYPES4.has(callee.type)) return void 0;
5873
5899
  const property = callee.property;
5874
5900
  if (property?.type !== "Identifier" || property.name !== "each") return void 0;
5875
5901
  let object = callee.object;
5876
- while (object !== void 0 && MEMBER_TYPES3.has(object.type)) {
5902
+ while (object !== void 0 && MEMBER_TYPES4.has(object.type)) {
5877
5903
  object = object.object;
5878
5904
  }
5879
5905
  if (object?.type !== "Identifier" || !RUNNERS.has(object.name)) return void 0;
@@ -5900,13 +5926,13 @@ function rewriteEachTableRows(source, program) {
5900
5926
  }
5901
5927
 
5902
5928
  // src/roles/test/codemod/each-title.ts
5903
- var MEMBER_TYPES4 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5929
+ var MEMBER_TYPES5 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5904
5930
  function eachTitle(node) {
5905
5931
  if (node.type !== "CallExpression") return void 0;
5906
5932
  const inner = node.callee;
5907
5933
  if (inner?.type !== "CallExpression") return void 0;
5908
5934
  const member = inner.callee;
5909
- if (member === void 0 || !MEMBER_TYPES4.has(member.type)) return void 0;
5935
+ if (member === void 0 || !MEMBER_TYPES5.has(member.type)) return void 0;
5910
5936
  const property = member.property;
5911
5937
  if (property?.type !== "Identifier" || property.name !== "each") return void 0;
5912
5938
  const [title] = node.arguments ?? [];
@@ -5959,14 +5985,14 @@ function rewriteEachTitles(source, program) {
5959
5985
 
5960
5986
  // src/roles/test/codemod/empty-mock-implementation.ts
5961
5987
  var METHODS = /* @__PURE__ */ new Set(["mockImplementation", "mockImplementationOnce"]);
5962
- var MEMBER_TYPES5 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5988
+ var MEMBER_TYPES6 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5963
5989
  function rewriteEmptyMockImplementation(source, program) {
5964
5990
  const insertAt = [];
5965
5991
  walk(program, (node) => {
5966
5992
  if (node.type !== "CallExpression") return;
5967
5993
  if ((node.arguments ?? []).length > 0) return;
5968
5994
  const callee = node.callee;
5969
- if (callee === void 0 || !MEMBER_TYPES5.has(callee.type)) return;
5995
+ if (callee === void 0 || !MEMBER_TYPES6.has(callee.type)) return;
5970
5996
  const property = callee.property;
5971
5997
  if (property?.type !== "Identifier" || !METHODS.has(property.name)) return;
5972
5998
  insertAt.push(node.end - 1);
@@ -5979,12 +6005,12 @@ function rewriteEmptyMockImplementation(source, program) {
5979
6005
  }
5980
6006
 
5981
6007
  // src/roles/test/codemod/fake-timer-options.ts
5982
- var MEMBER_TYPES6 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6008
+ var MEMBER_TYPES7 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
5983
6009
  var TIMER_CALLS = /* @__PURE__ */ new Set(["useFakeTimers"]);
5984
6010
  function timerOptions(node) {
5985
6011
  if (node.type !== "CallExpression") return void 0;
5986
6012
  const callee = node.callee;
5987
- if (callee === void 0 || !MEMBER_TYPES6.has(callee.type)) return void 0;
6013
+ if (callee === void 0 || !MEMBER_TYPES7.has(callee.type)) return void 0;
5988
6014
  const object = callee.object;
5989
6015
  const property = callee.property;
5990
6016
  if (object?.type !== "Identifier") return void 0;
@@ -6328,7 +6354,7 @@ function hoistCapturedBindings(source, program, factories, bindings, imported) {
6328
6354
 
6329
6355
  // src/roles/test/codemod/hook-return-value.ts
6330
6356
  var HOOKS = /* @__PURE__ */ new Set(["beforeEach", "afterEach", "beforeAll", "afterAll"]);
6331
- var MEMBER_TYPES7 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6357
+ var MEMBER_TYPES8 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6332
6358
  function hookCallback(node) {
6333
6359
  if (node.type !== "CallExpression") return void 0;
6334
6360
  const callee = node.callee;
@@ -6339,7 +6365,7 @@ function hookCallback(node) {
6339
6365
  function configuresAMock(body) {
6340
6366
  if (body.type !== "CallExpression") return false;
6341
6367
  const callee = body.callee;
6342
- if (callee === void 0 || !MEMBER_TYPES7.has(callee.type)) return false;
6368
+ if (callee === void 0 || !MEMBER_TYPES8.has(callee.type)) return false;
6343
6369
  const property = callee.property;
6344
6370
  return property?.type === "Identifier" && /^mock[A-Z]/.test(property.name);
6345
6371
  }
@@ -6554,7 +6580,7 @@ function isCommonJsPackage(fromFile, specifier) {
6554
6580
  }
6555
6581
  return false;
6556
6582
  }
6557
- var MEMBER_TYPES8 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6583
+ var MEMBER_TYPES9 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6558
6584
  var ASYNC_REPLACEMENTS = {
6559
6585
  requireActual: "importActual",
6560
6586
  requireMock: "importMock"
@@ -6564,7 +6590,7 @@ function mockedSpecifiers(program) {
6564
6590
  walk(program, (node) => {
6565
6591
  if (node.type !== "CallExpression") return;
6566
6592
  const callee = node.callee;
6567
- if (callee === void 0 || !MEMBER_TYPES8.has(callee.type)) return;
6593
+ if (callee === void 0 || !MEMBER_TYPES9.has(callee.type)) return;
6568
6594
  const object = callee.object;
6569
6595
  const property = callee.property;
6570
6596
  if (object?.type !== "Identifier") return;
@@ -6601,7 +6627,7 @@ function bareRequire(node) {
6601
6627
  function mockFactoryReturn(node) {
6602
6628
  if (node.type !== "CallExpression") return void 0;
6603
6629
  const callee = node.callee;
6604
- if (callee === void 0 || !MEMBER_TYPES8.has(callee.type)) return void 0;
6630
+ if (callee === void 0 || !MEMBER_TYPES9.has(callee.type)) return void 0;
6605
6631
  const object = callee.object;
6606
6632
  const property = callee.property;
6607
6633
  if (object?.type !== "Identifier") return void 0;
@@ -6711,7 +6737,7 @@ function applyNamedRules(source, program, fileName = "") {
6711
6737
  }
6712
6738
  return;
6713
6739
  }
6714
- if (!MEMBER_TYPES8.has(node.type)) return;
6740
+ if (!MEMBER_TYPES9.has(node.type)) return;
6715
6741
  const object = node.object;
6716
6742
  if (object !== void 0) readsANameOffIt.add(object);
6717
6743
  });
@@ -6782,13 +6808,13 @@ function applyNamedRules(source, program, fileName = "") {
6782
6808
  }
6783
6809
 
6784
6810
  // src/roles/test/codemod/isolate-modules.ts
6785
- var MEMBER_TYPES9 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6811
+ var MEMBER_TYPES10 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6786
6812
  var ISOLATORS = /* @__PURE__ */ new Set(["isolateModules", "isolateModulesAsync"]);
6787
6813
  var FUNCTIONS2 = /* @__PURE__ */ new Set(["ArrowFunctionExpression", "FunctionExpression"]);
6788
6814
  function isolatingCall(node) {
6789
6815
  if (node.type !== "CallExpression") return void 0;
6790
6816
  const callee = node.callee;
6791
- if (callee === void 0 || !MEMBER_TYPES9.has(callee.type)) return void 0;
6817
+ if (callee === void 0 || !MEMBER_TYPES10.has(callee.type)) return void 0;
6792
6818
  const object = callee.object;
6793
6819
  const property = callee.property;
6794
6820
  if (object?.type !== "Identifier" || object.name !== "jest") return void 0;
@@ -6799,7 +6825,7 @@ function isolatingCall(node) {
6799
6825
  function unusableIsolatingCall(node) {
6800
6826
  if (node.type !== "CallExpression") return void 0;
6801
6827
  const callee = node.callee;
6802
- if (callee === void 0 || !MEMBER_TYPES9.has(callee.type)) return void 0;
6828
+ if (callee === void 0 || !MEMBER_TYPES10.has(callee.type)) return void 0;
6803
6829
  const object = callee.object;
6804
6830
  const property = callee.property;
6805
6831
  if (object?.type !== "Identifier" || object.name !== "jest") return void 0;
@@ -6850,11 +6876,11 @@ ${indent}await (${callback})()`
6850
6876
  }
6851
6877
 
6852
6878
  // src/roles/test/codemod/mock-as-value.ts
6853
- var MEMBER_TYPES10 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6879
+ var MEMBER_TYPES11 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6854
6880
  function isViMockCall(node) {
6855
6881
  if (node?.type !== "CallExpression") return false;
6856
6882
  const callee = node.callee;
6857
- if (callee === void 0 || !MEMBER_TYPES10.has(callee.type)) return false;
6883
+ if (callee === void 0 || !MEMBER_TYPES11.has(callee.type)) return false;
6858
6884
  const object = callee.object;
6859
6885
  const property = callee.property;
6860
6886
  return object?.type === "Identifier" && object.name === "vi" && property?.type === "Identifier" && (property.name === "mock" || property.name === "doMock");
@@ -6879,7 +6905,7 @@ function rewriteMockAsValue(source, program) {
6879
6905
  const memberUses = /* @__PURE__ */ new Map();
6880
6906
  const otherUses = /* @__PURE__ */ new Map();
6881
6907
  walk(program, (node) => {
6882
- if (MEMBER_TYPES10.has(node.type)) {
6908
+ if (MEMBER_TYPES11.has(node.type)) {
6883
6909
  const object = node.object;
6884
6910
  if (object?.type === "Identifier" && bindings.has(object.name)) {
6885
6911
  const list = memberUses.get(object.name) ?? [];
@@ -6925,12 +6951,12 @@ function rewriteMockAsValue(source, program) {
6925
6951
  }
6926
6952
 
6927
6953
  // src/roles/test/codemod/mock-factory-default.ts
6928
- var MEMBER_TYPES11 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6954
+ var MEMBER_TYPES12 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
6929
6955
  var BINDING = "sentinelMockedModule";
6930
6956
  function mockCall(node) {
6931
6957
  if (node.type !== "CallExpression") return void 0;
6932
6958
  const callee = node.callee;
6933
- if (callee === void 0 || !MEMBER_TYPES11.has(callee.type)) return void 0;
6959
+ if (callee === void 0 || !MEMBER_TYPES12.has(callee.type)) return void 0;
6934
6960
  const property = callee.property;
6935
6961
  if (property?.type !== "Identifier" || property.name !== "mock") return void 0;
6936
6962
  const object = callee.object;
@@ -7043,7 +7069,7 @@ function rewriteMockFactoryDefault(source, program, defaultImported) {
7043
7069
 
7044
7070
  // src/roles/test/codemod/mock-promise-resolve.ts
7045
7071
  var MOCK_FACTORY = /* @__PURE__ */ new Set(["fn", "spyOn"]);
7046
- function isMockFactory(source, node) {
7072
+ function isMockFactory2(source, node) {
7047
7073
  if (node.type !== "CallExpression") return false;
7048
7074
  const callee = node.callee;
7049
7075
  if (callee?.type !== "MemberExpression") return false;
@@ -7086,7 +7112,7 @@ function resolvedValue(source, executor) {
7086
7112
  function rewriteMockPromiseResolve(source, program) {
7087
7113
  const edits = [];
7088
7114
  walk(program, (node) => {
7089
- if (!isMockFactory(source, node)) return;
7115
+ if (!isMockFactory2(source, node)) return;
7090
7116
  for (const argument of node.arguments ?? []) {
7091
7117
  walk(argument, (inner) => {
7092
7118
  if (inner.type !== "NewExpression") return;
@@ -7114,11 +7140,11 @@ function rewriteMockPromiseResolve(source, program) {
7114
7140
  }
7115
7141
 
7116
7142
  // src/roles/test/codemod/mocked-module-binding.ts
7117
- var MEMBER_TYPES12 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
7143
+ var MEMBER_TYPES13 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
7118
7144
  function mockedSpecifier(source, node) {
7119
7145
  if (node.type !== "CallExpression") return void 0;
7120
7146
  const callee = node.callee;
7121
- if (callee === void 0 || !MEMBER_TYPES12.has(callee.type)) return void 0;
7147
+ if (callee === void 0 || !MEMBER_TYPES13.has(callee.type)) return void 0;
7122
7148
  const object = callee.object;
7123
7149
  const property = callee.property;
7124
7150
  if (object?.type !== "Identifier") return void 0;
@@ -7176,7 +7202,7 @@ function annotateMockedBindings(source, program) {
7176
7202
  // src/roles/test/codemod/propagate-await.ts
7177
7203
  import { parseSync as parseSync5 } from "oxc-parser";
7178
7204
  var FUNCTIONS3 = /* @__PURE__ */ new Set(["ArrowFunctionExpression", "FunctionExpression", "FunctionDeclaration"]);
7179
- var MEMBER_TYPES13 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
7205
+ var MEMBER_TYPES14 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
7180
7206
  var ALREADY_A_PROMISE = /* @__PURE__ */ new Set(["then", "catch", "finally"]);
7181
7207
  function asyncFunctionNames(program) {
7182
7208
  const names = /* @__PURE__ */ new Set();
@@ -7250,7 +7276,7 @@ function alreadyHandled(call, parent) {
7250
7276
  if (parent === void 0) return false;
7251
7277
  if (parent.type === "AwaitExpression") return true;
7252
7278
  if (parent.type === "ReturnStatement" || parent.type === "ArrowFunctionExpression") return true;
7253
- if (MEMBER_TYPES13.has(parent.type) && parent.object === call) {
7279
+ if (MEMBER_TYPES14.has(parent.type) && parent.object === call) {
7254
7280
  const property = parent.property;
7255
7281
  return property?.type === "Identifier" && ALREADY_A_PROMISE.has(property.name);
7256
7282
  }
@@ -7303,7 +7329,7 @@ function propagateAwait(fileName, source, original, elsewhere = /* @__PURE__ */
7303
7329
  import { readFileSync as readFileSync24, readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
7304
7330
  import { createRequire as createRequire5 } from "node:module";
7305
7331
  import { dirname as dirname5, join as join30 } from "node:path";
7306
- var MEMBER_TYPES14 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
7332
+ var MEMBER_TYPES15 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
7307
7333
  var PACKAGE_SUBPATH = /^(@[^/]+\/[^/]+|[^@.][^/]*)\/(.+)$/;
7308
7334
  var PURE_REEXPORT = /^module\.exports\s*=\s*require\(\s*(['"])([^'"]+)\1\s*\)\s*;?$/;
7309
7335
  function mockCalls(program) {
@@ -7311,7 +7337,7 @@ function mockCalls(program) {
7311
7337
  walk(program, (node) => {
7312
7338
  if (node.type !== "CallExpression") return;
7313
7339
  const callee = node.callee;
7314
- if (callee === void 0 || !MEMBER_TYPES14.has(callee.type)) return;
7340
+ if (callee === void 0 || !MEMBER_TYPES15.has(callee.type)) return;
7315
7341
  const object = callee.object;
7316
7342
  const property = callee.property;
7317
7343
  if (object?.type !== "Identifier") return;
@@ -7804,7 +7830,10 @@ function migrateTestFile(fileName, source, defaultImported = /* @__PURE__ */ new
7804
7830
  const afterHoist = parse2(fileName, hoist.source);
7805
7831
  if (afterHoist === void 0) return unparsable("hoisting captured bindings");
7806
7832
  const mockedBindings = annotateMockedBindings(hoist.source, afterHoist);
7807
- const withImport = injectTypeImport(fileName, mockedBindings.source, [
7833
+ const afterBindings = parse2(fileName, mockedBindings.source);
7834
+ if (afterBindings === void 0) return unparsable("mocked module bindings");
7835
+ const bareFactories = invokeBareMockFactories(mockedBindings.source, afterBindings);
7836
+ const withImport = injectTypeImport(fileName, bareFactories.source, [
7808
7837
  ...renamed.typeImports,
7809
7838
  ...spyTypes.typeImports,
7810
7839
  ...mockedBindings.typeImports
@@ -7831,6 +7860,7 @@ function migrateTestFile(fileName, source, defaultImported = /* @__PURE__ */ new
7831
7860
  ...hooks.rewritten > 0 ? ["hook body, so it does not return its mock"] : [],
7832
7861
  ...spyTypes.rewritten > 0 ? ["SpyInstance<T> as a signature, not a return type"] : [],
7833
7862
  ...mockedBindings.rewritten > 0 ? ["a mocked module binding, typed as mocked"] : [],
7863
+ ...bareFactories.rewritten > 0 ? ["vi.fn passed as a value, invoked"] : [],
7834
7864
  ...awaited.rewritten > 0 ? ["await propagated to a helper that became async"] : [],
7835
7865
  ...barrels.added.map((alias) => `mock carried to ${alias}, which re-exports the mocked file`),
7836
7866
  ...fakeTimers.translated
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  registerAdapters,
8
8
  resolve,
9
9
  setDefaultRunner
10
- } from "./chunk-ATDETQX5.js";
10
+ } from "./chunk-ABFNJZ6C.js";
11
11
  import "./chunk-NW6UHNYX.js";
12
12
  export {
13
13
  BaseAdapter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hublo/sentinel",
3
- "version": "1.4.0-alpha.26",
3
+ "version": "1.4.0-alpha.27",
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",