@hublo/sentinel 1.4.0-alpha.40 → 1.4.0-alpha.42
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-BF5SF6HQ.js";
|
|
19
19
|
import {
|
|
20
20
|
resolveContext
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-YHNQONE2.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-AUKAA6EG.js");
|
|
149
149
|
const outcomes = modules.flatMap(
|
|
150
150
|
(module) => validateModuleTests(module.name, module.root)
|
|
151
151
|
);
|
|
@@ -747,7 +747,8 @@ function resolveVitest(cwd) {
|
|
|
747
747
|
|
|
748
748
|
// src/roles/test/adapters/vitest/vitest.adapter.ts
|
|
749
749
|
import { spawnSync } from "node:child_process";
|
|
750
|
-
import {
|
|
750
|
+
import { readFileSync as readFileSync24, writeFileSync as writeFileSync2 } from "node:fs";
|
|
751
|
+
import { isAbsolute as isAbsolute2, join as join30, resolve as resolve9 } from "node:path";
|
|
751
752
|
|
|
752
753
|
// src/core/config/tool-args.ts
|
|
753
754
|
import { existsSync as existsSync6 } from "node:fs";
|
|
@@ -767,6 +768,25 @@ function splitToolArgs(cwd, toolArgs = [], { valueFlags = [] } = {}) {
|
|
|
767
768
|
return { options, paths };
|
|
768
769
|
}
|
|
769
770
|
|
|
771
|
+
// src/roles/test/ordering-is-a-permutation.ts
|
|
772
|
+
function lineCounts(source) {
|
|
773
|
+
const counts = /* @__PURE__ */ new Map();
|
|
774
|
+
for (const line of source.split("\n")) {
|
|
775
|
+
const trimmed = line.trim();
|
|
776
|
+
if (trimmed === "") continue;
|
|
777
|
+
counts.set(trimmed, (counts.get(trimmed) ?? 0) + 1);
|
|
778
|
+
}
|
|
779
|
+
return counts;
|
|
780
|
+
}
|
|
781
|
+
function lineLostByTheFixer(before, after) {
|
|
782
|
+
const had = lineCounts(before);
|
|
783
|
+
const has = lineCounts(after);
|
|
784
|
+
for (const [line, count] of had) {
|
|
785
|
+
if ((has.get(line) ?? 0) < count) return line;
|
|
786
|
+
}
|
|
787
|
+
return void 0;
|
|
788
|
+
}
|
|
789
|
+
|
|
770
790
|
// src/core/config/nx-target.ts
|
|
771
791
|
import { existsSync as existsSync7 } from "node:fs";
|
|
772
792
|
import { join as join7 } from "node:path";
|
|
@@ -1963,6 +1983,25 @@ function rewriteHookReturnValue(source, program) {
|
|
|
1963
1983
|
return { source: result, rewritten: edits.length };
|
|
1964
1984
|
}
|
|
1965
1985
|
|
|
1986
|
+
// src/roles/test/codemod/asyncify.ts
|
|
1987
|
+
function alreadyAPromise(text) {
|
|
1988
|
+
return /^(?:Promise|PromiseLike)\s*</.test(text.trim());
|
|
1989
|
+
}
|
|
1990
|
+
function asyncifyEdits(source, fn) {
|
|
1991
|
+
const edits = [{ start: fn.start, end: fn.start, text: "async " }];
|
|
1992
|
+
const annotation = fn.returnType;
|
|
1993
|
+
const declared = annotation?.typeAnnotation;
|
|
1994
|
+
if (declared?.start === void 0 || declared.end === void 0) return edits;
|
|
1995
|
+
const text = source.slice(declared.start, declared.end);
|
|
1996
|
+
if (alreadyAPromise(text)) return edits;
|
|
1997
|
+
edits.push({
|
|
1998
|
+
start: declared.start,
|
|
1999
|
+
end: declared.end,
|
|
2000
|
+
text: `Promise<${text}>`
|
|
2001
|
+
});
|
|
2002
|
+
return edits;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
1966
2005
|
// src/roles/test/codemod/named-rules.ts
|
|
1967
2006
|
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "node:fs";
|
|
1968
2007
|
import { createRequire as createRequire2 } from "node:module";
|
|
@@ -2474,7 +2513,7 @@ function applyNamedRules(source, program, fileName = "") {
|
|
|
2474
2513
|
}
|
|
2475
2514
|
});
|
|
2476
2515
|
for (const fn of asyncify) {
|
|
2477
|
-
edits.push(
|
|
2516
|
+
edits.push(...asyncifyEdits(source, fn));
|
|
2478
2517
|
}
|
|
2479
2518
|
const namespaceLines = namespaces.planned().map(
|
|
2480
2519
|
({ specifier, binding }) => `import * as ${binding} from '${specifier}'${fileUsesSemicolons(source) ? ";" : ""}`
|
|
@@ -2545,6 +2584,12 @@ function rewriteIsolateModules(source, program) {
|
|
|
2545
2584
|
const refusals = [];
|
|
2546
2585
|
const asyncify = /* @__PURE__ */ new Set();
|
|
2547
2586
|
let rewritten = 0;
|
|
2587
|
+
const awaitedCall = /* @__PURE__ */ new Map();
|
|
2588
|
+
walkWithEnclosingFunction(program, void 0, (node) => {
|
|
2589
|
+
if (node.type !== "AwaitExpression") return;
|
|
2590
|
+
const argument = node.argument;
|
|
2591
|
+
if (argument !== void 0) awaitedCall.set(argument, node);
|
|
2592
|
+
});
|
|
2548
2593
|
walkWithEnclosingFunction(program, void 0, (node, enclosing) => {
|
|
2549
2594
|
const unusable = unusableIsolatingCall(node);
|
|
2550
2595
|
if (unusable !== void 0) {
|
|
@@ -2558,10 +2603,11 @@ function rewriteIsolateModules(source, program) {
|
|
|
2558
2603
|
if (found === void 0) return;
|
|
2559
2604
|
const callbackText = source.slice(found.callback.start, found.callback.end);
|
|
2560
2605
|
const callback = found.callback.async === true ? callbackText : `async ${callbackText}`;
|
|
2561
|
-
const
|
|
2606
|
+
const replaced = awaitedCall.get(found.call) ?? found.call;
|
|
2607
|
+
const indent = indentationAt(source, replaced.start);
|
|
2562
2608
|
edits.push({
|
|
2563
|
-
start:
|
|
2564
|
-
end:
|
|
2609
|
+
start: replaced.start,
|
|
2610
|
+
end: replaced.end,
|
|
2565
2611
|
text: `vi.resetModules()
|
|
2566
2612
|
${indent}await (${callback})()`
|
|
2567
2613
|
});
|
|
@@ -2569,7 +2615,7 @@ ${indent}await (${callback})()`
|
|
|
2569
2615
|
if (enclosing !== void 0 && enclosing.async !== true) asyncify.add(enclosing);
|
|
2570
2616
|
});
|
|
2571
2617
|
for (const fn of asyncify) {
|
|
2572
|
-
edits.push(
|
|
2618
|
+
edits.push(...asyncifyEdits(source, fn));
|
|
2573
2619
|
}
|
|
2574
2620
|
const result = applyEdits(source, edits);
|
|
2575
2621
|
return { source: result, rewritten, refusals };
|
|
@@ -5329,6 +5375,13 @@ function writtenFileLinter(cwd) {
|
|
|
5329
5375
|
// src/roles/test/adapters/vitest/vitest.adapter.ts
|
|
5330
5376
|
var FORMATTABLE = /\.(m|c)?(j|t)sx?$|\.json$/;
|
|
5331
5377
|
var FORMAT_BATCH = 25;
|
|
5378
|
+
function readIfPossible(path) {
|
|
5379
|
+
try {
|
|
5380
|
+
return readFileSync24(path, "utf8");
|
|
5381
|
+
} catch {
|
|
5382
|
+
return void 0;
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5332
5385
|
var VitestAdapter = class extends BaseAdapter {
|
|
5333
5386
|
target = "test";
|
|
5334
5387
|
runner = "vitest";
|
|
@@ -5450,13 +5503,30 @@ var VitestAdapter = class extends BaseAdapter {
|
|
|
5450
5503
|
const linter = writtenFileLinter(ctx.cwd);
|
|
5451
5504
|
if (linter === void 0) return;
|
|
5452
5505
|
let unsettled = 0;
|
|
5506
|
+
const reverted = [];
|
|
5453
5507
|
for (let at = 0; at < written.length; at += FORMAT_BATCH) {
|
|
5454
5508
|
const batch = written.slice(at, at + FORMAT_BATCH);
|
|
5509
|
+
const before = new Map(batch.map((file) => [file, readIfPossible(join30(ctx.cwd, file))]));
|
|
5455
5510
|
const pass = spawnSync(linter.bin, [...linter.args, ...batch], {
|
|
5456
5511
|
cwd: ctx.cwd,
|
|
5457
5512
|
encoding: "utf8"
|
|
5458
5513
|
});
|
|
5459
5514
|
if (pass.status !== 0) unsettled += 1;
|
|
5515
|
+
for (const file of batch) {
|
|
5516
|
+
const was = before.get(file);
|
|
5517
|
+
if (was === void 0) continue;
|
|
5518
|
+
const now = readIfPossible(join30(ctx.cwd, file));
|
|
5519
|
+
if (now === void 0 || now === was) continue;
|
|
5520
|
+
const lost = lineLostByTheFixer(was, now);
|
|
5521
|
+
if (lost === void 0) continue;
|
|
5522
|
+
writeFileSync2(join30(ctx.cwd, file), was);
|
|
5523
|
+
reverted.push(`${file}: \`${lost.slice(0, 80)}\``);
|
|
5524
|
+
}
|
|
5525
|
+
}
|
|
5526
|
+
if (reverted.length > 0) {
|
|
5527
|
+
this.say(
|
|
5528
|
+
`${linter.origin} did not only reorder: it removed ${reverted.length} line(s) it was given, so those file(s) were restored to what this migration wrote and their imports are left for your own lint to order. Reordering imports moves lines, it does not delete them. Measured on this repository, the rules that do this are \`prefer-arrow-callback\`, which un-does the function expression a mocked CLASS needs to be constructible, and unused-directive removal, which deletes a suppression for a rule your real lint target does run. First: ${reverted.slice(0, 3).join("; ")}`
|
|
5529
|
+
);
|
|
5460
5530
|
}
|
|
5461
5531
|
this.say(
|
|
5462
5532
|
unsettled === 0 ? `ran ${linter.origin} with its fixer over the ${written.length} file(s) this wrote, so the import this migration adds is ordered the way your rules ask. Without it, \`import/order\` alone put 19 modules of this repository in the red.` : `ran ${linter.origin} with its fixer over the ${written.length} file(s) this wrote, and it still reports something it cannot fix. Adoption itself is applied. Run your own lint to see what: it may be rules this module already failed, which are not this migration's to settle.`
|
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-BF5SF6HQ.js";
|
|
10
10
|
import {
|
|
11
11
|
BaseAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YHNQONE2.js";
|
|
13
13
|
import "./chunk-O7REVMOC.js";
|
|
14
14
|
import "./chunk-QXFCZON7.js";
|
|
15
15
|
import "./chunk-NW6UHNYX.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.42",
|
|
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",
|