@hublo/sentinel 1.4.0-alpha.32 → 1.4.0-alpha.33
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-63NQP75B.js";
|
|
19
19
|
import {
|
|
20
20
|
resolveContext
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-UBXL567Z.js";
|
|
22
22
|
import "../chunk-O7REVMOC.js";
|
|
23
23
|
import {
|
|
24
24
|
ensureWorkspacePrep,
|
|
@@ -144,7 +144,7 @@ async function runValidate(ctx) {
|
|
|
144
144
|
);
|
|
145
145
|
}
|
|
146
146
|
if (!ctx.targets.includes("test")) return 1;
|
|
147
|
-
const { validateModuleTests } = await import("../validate-
|
|
147
|
+
const { validateModuleTests } = await import("../validate-JUNITP37.js");
|
|
148
148
|
const outcomes = modules.flatMap(
|
|
149
149
|
(module) => validateModuleTests(module.name, module.root)
|
|
150
150
|
);
|
|
@@ -723,7 +723,7 @@ function resolveVitest(cwd) {
|
|
|
723
723
|
|
|
724
724
|
// src/roles/test/adapters/vitest/vitest.adapter.ts
|
|
725
725
|
import { spawnSync } from "node:child_process";
|
|
726
|
-
import { isAbsolute as isAbsolute2, resolve as
|
|
726
|
+
import { isAbsolute as isAbsolute2, resolve as resolve8 } from "node:path";
|
|
727
727
|
|
|
728
728
|
// src/core/config/tool-args.ts
|
|
729
729
|
import { existsSync as existsSync6 } from "node:fs";
|
|
@@ -873,9 +873,9 @@ function rewriteToolchainImports(toolchain, source, fileName) {
|
|
|
873
873
|
}
|
|
874
874
|
|
|
875
875
|
// src/roles/test/jest-migration.ts
|
|
876
|
-
import { existsSync as
|
|
876
|
+
import { existsSync as existsSync19, readFileSync as readFileSync18, readdirSync as readdirSync6 } from "node:fs";
|
|
877
877
|
import { createRequire as createRequire5 } from "node:module";
|
|
878
|
-
import { dirname as
|
|
878
|
+
import { dirname as dirname11, join as join23, relative as relative5 } from "node:path";
|
|
879
879
|
|
|
880
880
|
// src/shared/jsonc.ts
|
|
881
881
|
import { parse as parse2, printParseErrorCode } from "jsonc-parser";
|
|
@@ -890,9 +890,9 @@ function parseJsonc(text, source = "config") {
|
|
|
890
890
|
}
|
|
891
891
|
|
|
892
892
|
// src/roles/test/codemod/migrate-module.ts
|
|
893
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
894
|
-
import { join as
|
|
895
|
-
import { parseSync as
|
|
893
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync13, statSync as statSync4 } from "node:fs";
|
|
894
|
+
import { join as join16 } from "node:path";
|
|
895
|
+
import { parseSync as parseSync8 } from "oxc-parser";
|
|
896
896
|
|
|
897
897
|
// src/roles/test/msw-lifecycle.ts
|
|
898
898
|
import { existsSync as existsSync9, readFileSync as readFileSync6 } from "node:fs";
|
|
@@ -1121,8 +1121,8 @@ ${source}`;
|
|
|
1121
1121
|
}
|
|
1122
1122
|
|
|
1123
1123
|
// src/roles/test/codemod/migrate-file.ts
|
|
1124
|
-
import { dirname as
|
|
1125
|
-
import { parseSync as
|
|
1124
|
+
import { dirname as dirname7 } from "node:path";
|
|
1125
|
+
import { parseSync as parseSync7 } from "oxc-parser";
|
|
1126
1126
|
|
|
1127
1127
|
// src/roles/test/codemod/assertion-return-value.ts
|
|
1128
1128
|
var MEMBER_TYPES = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
|
|
@@ -1881,9 +1881,165 @@ function rewriteHookReturnValue(source, program) {
|
|
|
1881
1881
|
}
|
|
1882
1882
|
|
|
1883
1883
|
// src/roles/test/codemod/named-rules.ts
|
|
1884
|
-
import { existsSync as
|
|
1884
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
|
|
1885
1885
|
import { createRequire as createRequire2 } from "node:module";
|
|
1886
|
-
import { dirname as
|
|
1886
|
+
import { dirname as dirname3, join as join10 } from "node:path";
|
|
1887
|
+
|
|
1888
|
+
// src/roles/test/codemod/static-import-for-require.ts
|
|
1889
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7, statSync } from "node:fs";
|
|
1890
|
+
import { dirname as dirname2, join as join9, resolve as resolve3 } from "node:path";
|
|
1891
|
+
import { parseSync as parseSync4 } from "oxc-parser";
|
|
1892
|
+
var EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
1893
|
+
function resolveRelative(fromFile, specifier) {
|
|
1894
|
+
const base = resolve3(dirname2(fromFile), specifier);
|
|
1895
|
+
const candidates = [
|
|
1896
|
+
base,
|
|
1897
|
+
...EXTENSIONS.map((extension) => `${base}${extension}`),
|
|
1898
|
+
...EXTENSIONS.map((extension) => join9(base, `index${extension}`))
|
|
1899
|
+
];
|
|
1900
|
+
for (const candidate of candidates) {
|
|
1901
|
+
try {
|
|
1902
|
+
if (statSync(candidate).isFile()) return candidate;
|
|
1903
|
+
} catch {
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
return void 0;
|
|
1907
|
+
}
|
|
1908
|
+
function relativeSpecifiers(source) {
|
|
1909
|
+
const found = [];
|
|
1910
|
+
const patterns = [
|
|
1911
|
+
/\bfrom\s+['"](\.[^'"]*)['"]/g,
|
|
1912
|
+
/\bimport\s+['"](\.[^'"]*)['"]/g,
|
|
1913
|
+
/\bimport\s*\(\s*['"](\.[^'"]*)['"]\s*\)/g,
|
|
1914
|
+
/\brequire\s*\(\s*['"](\.[^'"]*)['"]\s*\)/g
|
|
1915
|
+
];
|
|
1916
|
+
for (const pattern of patterns) {
|
|
1917
|
+
for (const match of source.matchAll(pattern)) found.push(match[1]);
|
|
1918
|
+
}
|
|
1919
|
+
return found;
|
|
1920
|
+
}
|
|
1921
|
+
function reachesBack(fromFile, specifier) {
|
|
1922
|
+
const entry = resolveRelative(fromFile, specifier);
|
|
1923
|
+
if (entry === void 0) return true;
|
|
1924
|
+
const target = resolve3(fromFile);
|
|
1925
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1926
|
+
const stack = [entry];
|
|
1927
|
+
while (stack.length > 0 && seen.size < 200) {
|
|
1928
|
+
const file = stack.pop();
|
|
1929
|
+
if (seen.has(file)) continue;
|
|
1930
|
+
seen.add(file);
|
|
1931
|
+
if (resolve3(file) === target) return true;
|
|
1932
|
+
let source;
|
|
1933
|
+
try {
|
|
1934
|
+
source = readFileSync7(file, "utf8");
|
|
1935
|
+
} catch {
|
|
1936
|
+
continue;
|
|
1937
|
+
}
|
|
1938
|
+
for (const relative6 of relativeSpecifiers(source)) {
|
|
1939
|
+
const next = resolveRelative(file, relative6);
|
|
1940
|
+
if (next !== void 0) stack.push(next);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
return seen.size >= 200;
|
|
1944
|
+
}
|
|
1945
|
+
function namedRequireDeclarations(program) {
|
|
1946
|
+
const found = /* @__PURE__ */ new Map();
|
|
1947
|
+
walk(program, (node) => {
|
|
1948
|
+
if (node.type !== "VariableDeclaration") return;
|
|
1949
|
+
const declarators = node.declarations ?? [];
|
|
1950
|
+
if (declarators.length !== 1) return;
|
|
1951
|
+
const declarator = declarators[0];
|
|
1952
|
+
const init = declarator.init;
|
|
1953
|
+
if (init?.type !== "CallExpression") return;
|
|
1954
|
+
const callee = init.callee;
|
|
1955
|
+
if (callee?.type !== "Identifier" || callee.name !== "require") return;
|
|
1956
|
+
const [argument] = init.arguments ?? [];
|
|
1957
|
+
if (argument?.type !== "StringLiteral" && argument?.type !== "Literal") return;
|
|
1958
|
+
const specifier = String(argument.value);
|
|
1959
|
+
if (!specifier.startsWith(".")) return;
|
|
1960
|
+
const id = declarator.id;
|
|
1961
|
+
if (id?.type !== "ObjectPattern") return;
|
|
1962
|
+
const names = [];
|
|
1963
|
+
for (const property of id.properties ?? []) {
|
|
1964
|
+
if (property.type !== "Property" && property.type !== "ObjectProperty") return;
|
|
1965
|
+
if (property.computed === true || property.shorthand !== true) return;
|
|
1966
|
+
const key = property.key;
|
|
1967
|
+
const value = property.value;
|
|
1968
|
+
if (key?.type !== "Identifier" || value?.type !== "Identifier") return;
|
|
1969
|
+
if (key.name !== value.name) return;
|
|
1970
|
+
names.push(key.name);
|
|
1971
|
+
}
|
|
1972
|
+
if (names.length === 0) return;
|
|
1973
|
+
found.set(init, { names, specifier, start: node.start, end: node.end });
|
|
1974
|
+
});
|
|
1975
|
+
return found;
|
|
1976
|
+
}
|
|
1977
|
+
function topLevelNames(program) {
|
|
1978
|
+
const names = /* @__PURE__ */ new Set();
|
|
1979
|
+
for (const node of program.body ?? []) {
|
|
1980
|
+
if (node.type === "ImportDeclaration") {
|
|
1981
|
+
for (const specifier of node.specifiers ?? []) {
|
|
1982
|
+
const local = specifier.local;
|
|
1983
|
+
if (local?.type === "Identifier") names.add(local.name);
|
|
1984
|
+
}
|
|
1985
|
+
continue;
|
|
1986
|
+
}
|
|
1987
|
+
if (node.type === "VariableDeclaration") {
|
|
1988
|
+
for (const declarator of node.declarations ?? []) {
|
|
1989
|
+
const id = declarator.id;
|
|
1990
|
+
if (id?.type === "Identifier") names.add(id.name);
|
|
1991
|
+
}
|
|
1992
|
+
continue;
|
|
1993
|
+
}
|
|
1994
|
+
if ((node.type === "FunctionDeclaration" || node.type === "ClassDeclaration") && node.id?.type === "Identifier") {
|
|
1995
|
+
names.add(node.id.name);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
return names;
|
|
1999
|
+
}
|
|
2000
|
+
function withLeadingComments(source, comments, start) {
|
|
2001
|
+
let from = start;
|
|
2002
|
+
for (; ; ) {
|
|
2003
|
+
const before = source.slice(0, from);
|
|
2004
|
+
const blank = before.length - before.trimEnd().length;
|
|
2005
|
+
const candidate = comments.find((comment) => comment.end === from - blank);
|
|
2006
|
+
if (candidate === void 0) break;
|
|
2007
|
+
const lineStart = source.lastIndexOf("\n", candidate.start) + 1;
|
|
2008
|
+
if (source.slice(lineStart, candidate.start).trim() !== "") break;
|
|
2009
|
+
from = lineStart;
|
|
2010
|
+
}
|
|
2011
|
+
return from;
|
|
2012
|
+
}
|
|
2013
|
+
function planStaticImport(fileName, source, program, requireCall2, semi) {
|
|
2014
|
+
const declaration = namedRequireDeclarations(program).get(requireCall2);
|
|
2015
|
+
if (declaration === void 0) return void 0;
|
|
2016
|
+
const bound = topLevelNames(program);
|
|
2017
|
+
if (declaration.names.some((name) => bound.has(name))) return void 0;
|
|
2018
|
+
if (reachesBack(fileName, declaration.specifier)) return void 0;
|
|
2019
|
+
const { comments } = parseSync4(fileName, source, { sourceType: "module" });
|
|
2020
|
+
const lineStart = source.lastIndexOf("\n", declaration.start - 1) + 1;
|
|
2021
|
+
const ownsItsLine = source.slice(lineStart, declaration.start).trim() === "";
|
|
2022
|
+
const start = withLeadingComments(
|
|
2023
|
+
source,
|
|
2024
|
+
comments,
|
|
2025
|
+
ownsItsLine ? lineStart : declaration.start
|
|
2026
|
+
);
|
|
2027
|
+
return {
|
|
2028
|
+
line: `import { ${declaration.names.join(", ")} } from '${declaration.specifier}'${semi ? ";" : ""}`,
|
|
2029
|
+
// To the end of the line, so the statement does not leave an empty one behind.
|
|
2030
|
+
remove: { start, end: endOfLine(source, declaration.end) }
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
function endOfLine(source, end) {
|
|
2034
|
+
let at = end;
|
|
2035
|
+
if (source[at] === ";") at += 1;
|
|
2036
|
+
while (source[at] === " " || source[at] === " ") at += 1;
|
|
2037
|
+
if (source[at] === "\r") at += 1;
|
|
2038
|
+
if (source[at] === "\n") at += 1;
|
|
2039
|
+
return at;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
// src/roles/test/codemod/named-rules.ts
|
|
1887
2043
|
function isCommonJsPackage(fromFile, specifier) {
|
|
1888
2044
|
if (specifier.startsWith(".") || specifier.startsWith("/")) return false;
|
|
1889
2045
|
let resolved;
|
|
@@ -1895,23 +2051,27 @@ function isCommonJsPackage(fromFile, specifier) {
|
|
|
1895
2051
|
if (!resolved.includes(`${"/"}node_modules${"/"}`)) return false;
|
|
1896
2052
|
if (resolved.endsWith(".mjs")) return false;
|
|
1897
2053
|
if (resolved.endsWith(".cjs")) return true;
|
|
1898
|
-
let dir =
|
|
2054
|
+
let dir = dirname3(resolved);
|
|
1899
2055
|
for (let depth = 0; depth < 12; depth += 1) {
|
|
1900
|
-
const manifest =
|
|
1901
|
-
if (
|
|
2056
|
+
const manifest = join10(dir, "package.json");
|
|
2057
|
+
if (existsSync11(manifest)) {
|
|
1902
2058
|
try {
|
|
1903
|
-
return JSON.parse(
|
|
2059
|
+
return JSON.parse(readFileSync8(manifest, "utf8")).type !== "module";
|
|
1904
2060
|
} catch {
|
|
1905
2061
|
return false;
|
|
1906
2062
|
}
|
|
1907
2063
|
}
|
|
1908
|
-
const parent =
|
|
2064
|
+
const parent = dirname3(dir);
|
|
1909
2065
|
if (parent === dir) break;
|
|
1910
2066
|
dir = parent;
|
|
1911
2067
|
}
|
|
1912
2068
|
return false;
|
|
1913
2069
|
}
|
|
1914
2070
|
var MEMBER_TYPES9 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
|
|
2071
|
+
function fileUsesSemicolons(source) {
|
|
2072
|
+
const first = /^import\s[^\n]*$/m.exec(source);
|
|
2073
|
+
return first !== null && first[0].trimEnd().endsWith(";");
|
|
2074
|
+
}
|
|
1915
2075
|
var ASYNC_REPLACEMENTS = {
|
|
1916
2076
|
requireActual: "importActual",
|
|
1917
2077
|
requireMock: "importMock"
|
|
@@ -1934,6 +2094,16 @@ function mockedSpecifiers(program) {
|
|
|
1934
2094
|
});
|
|
1935
2095
|
return found;
|
|
1936
2096
|
}
|
|
2097
|
+
function methodValues(program) {
|
|
2098
|
+
const found = /* @__PURE__ */ new Set();
|
|
2099
|
+
walk(program, (node) => {
|
|
2100
|
+
const isMethod = node.type === "MethodDefinition" || node.type === "ClassMethod" || node.type === "ObjectMethod" || (node.type === "Property" || node.type === "ObjectProperty") && (node.kind === "get" || node.kind === "set" || node.method === true);
|
|
2101
|
+
if (!isMethod) return;
|
|
2102
|
+
const value = node.value ?? node.body;
|
|
2103
|
+
if (value !== void 0) found.add(value);
|
|
2104
|
+
});
|
|
2105
|
+
return found;
|
|
2106
|
+
}
|
|
1937
2107
|
var FUNCTIONS = /* @__PURE__ */ new Set(["ArrowFunctionExpression", "FunctionExpression", "FunctionDeclaration"]);
|
|
1938
2108
|
function walkWithEnclosingFunction(node, enclosing, visit) {
|
|
1939
2109
|
if (node === null || typeof node !== "object") return;
|
|
@@ -2016,7 +2186,25 @@ function applyNamedRules(source, program, fileName = "") {
|
|
|
2016
2186
|
const edits = [];
|
|
2017
2187
|
const applied = /* @__PURE__ */ new Set();
|
|
2018
2188
|
const asyncify = /* @__PURE__ */ new Set();
|
|
2189
|
+
const refusals = [];
|
|
2190
|
+
const staticImports = [];
|
|
2019
2191
|
const mocked = mockedSpecifiers(program);
|
|
2192
|
+
const methods = methodValues(program);
|
|
2193
|
+
const cannotAwaitHere = (enclosing, what, call) => {
|
|
2194
|
+
if (enclosing === void 0 || !methods.has(enclosing)) return false;
|
|
2195
|
+
const plan2 = planStaticImport(fileName, source, program, call, fileUsesSemicolons(source));
|
|
2196
|
+
if (plan2 !== void 0) {
|
|
2197
|
+
edits.push({ start: plan2.remove.start, end: plan2.remove.end, text: "" });
|
|
2198
|
+
staticImports.push(plan2.line);
|
|
2199
|
+
applied.add(`${what} as a static import`);
|
|
2200
|
+
return true;
|
|
2201
|
+
}
|
|
2202
|
+
refusals.push({
|
|
2203
|
+
binding: what,
|
|
2204
|
+
reason: `\`${what}\` sits inside a class or object METHOD, which cannot become async here: \`async get\` is not valid, and making a method that returns void return a promise changes what every caller gets. Left as it was. Under Vitest \`require\` is Node's own resolver, which knows nothing of \`.ts\`, so this one needs a person: a static import, or the dynamic one kept on purpose.`
|
|
2205
|
+
});
|
|
2206
|
+
return true;
|
|
2207
|
+
};
|
|
2020
2208
|
const wholeStatement = /* @__PURE__ */ new Map();
|
|
2021
2209
|
walk(program, (node) => {
|
|
2022
2210
|
if (node.type !== "ExpressionStatement") return;
|
|
@@ -2084,6 +2272,7 @@ function applyNamedRules(source, program, fileName = "") {
|
|
|
2084
2272
|
const [specifier] = node.arguments ?? [];
|
|
2085
2273
|
const literal = specifier?.type === "StringLiteral" || specifier?.type === "Literal" ? String(specifier.value) : void 0;
|
|
2086
2274
|
if (literal !== void 0 && mocked.has(literal)) {
|
|
2275
|
+
if (cannotAwaitHere(enclosing, "jest.requireMock", node)) return;
|
|
2087
2276
|
edits.push({
|
|
2088
2277
|
start: node.start,
|
|
2089
2278
|
end: node.end,
|
|
@@ -2096,6 +2285,7 @@ function applyNamedRules(source, program, fileName = "") {
|
|
|
2096
2285
|
}
|
|
2097
2286
|
const asyncReplacement = member === void 0 ? void 0 : ASYNC_REPLACEMENTS[member];
|
|
2098
2287
|
if (asyncReplacement !== void 0) {
|
|
2288
|
+
if (cannotAwaitHere(enclosing, `jest.${member}`, node)) return;
|
|
2099
2289
|
edits.push({
|
|
2100
2290
|
start: node.start,
|
|
2101
2291
|
end: node.end,
|
|
@@ -2109,6 +2299,7 @@ function applyNamedRules(source, program, fileName = "") {
|
|
|
2109
2299
|
return;
|
|
2110
2300
|
}
|
|
2111
2301
|
if (bareRequire(node)) {
|
|
2302
|
+
if (cannotAwaitHere(enclosing, "require", node)) return;
|
|
2112
2303
|
const [specifier] = node.arguments ?? [];
|
|
2113
2304
|
const literal = specifier?.type === "StringLiteral" || specifier?.type === "Literal" ? String(specifier.value) : void 0;
|
|
2114
2305
|
const interop = literal !== void 0 && !readsANameOffIt.has(node) && !handedToTheRunnerAsAModule.has(node) && !wholeStatement.has(node) && isCommonJsPackage(fileName, literal) ? ".default" : "";
|
|
@@ -2143,7 +2334,27 @@ function applyNamedRules(source, program, fileName = "") {
|
|
|
2143
2334
|
for (const fn of asyncify) {
|
|
2144
2335
|
edits.push({ start: fn.start, end: fn.start, text: "async " });
|
|
2145
2336
|
}
|
|
2146
|
-
|
|
2337
|
+
if (staticImports.length > 0) {
|
|
2338
|
+
const first = (program.body ?? []).find(
|
|
2339
|
+
(node) => node.type === "ImportDeclaration"
|
|
2340
|
+
);
|
|
2341
|
+
const byModule = /* @__PURE__ */ new Map();
|
|
2342
|
+
for (const line of staticImports) {
|
|
2343
|
+
const parsed = /^import \{ (.+) \} from '(.+)'(;?)$/.exec(line);
|
|
2344
|
+
if (parsed === null) continue;
|
|
2345
|
+
const names = byModule.get(parsed[2]) ?? /* @__PURE__ */ new Set();
|
|
2346
|
+
for (const name of parsed[1].split(", ")) names.add(name);
|
|
2347
|
+
byModule.set(parsed[2], names);
|
|
2348
|
+
}
|
|
2349
|
+
const semi = staticImports[0]?.endsWith(";") === true ? ";" : "";
|
|
2350
|
+
const block = `${[...byModule].map(([specifier, names]) => `import { ${[...names].join(", ")} } from '${specifier}'${semi}`).join("\n")}
|
|
2351
|
+
`;
|
|
2352
|
+
edits.push(
|
|
2353
|
+
first === void 0 ? { start: 0, end: 0, text: `${block}
|
|
2354
|
+
` } : { start: first.start, end: first.start, text: block }
|
|
2355
|
+
);
|
|
2356
|
+
}
|
|
2357
|
+
return { source: applyEdits(source, edits), applied: [...applied].sort(), refusals };
|
|
2147
2358
|
}
|
|
2148
2359
|
|
|
2149
2360
|
// src/roles/test/codemod/isolate-modules.ts
|
|
@@ -2539,7 +2750,7 @@ function annotateMockedBindings(source, program) {
|
|
|
2539
2750
|
}
|
|
2540
2751
|
|
|
2541
2752
|
// src/roles/test/codemod/propagate-await.ts
|
|
2542
|
-
import { parseSync as
|
|
2753
|
+
import { parseSync as parseSync5 } from "oxc-parser";
|
|
2543
2754
|
var FUNCTIONS3 = /* @__PURE__ */ new Set(["ArrowFunctionExpression", "FunctionExpression", "FunctionDeclaration"]);
|
|
2544
2755
|
var MEMBER_TYPES14 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
|
|
2545
2756
|
var ALREADY_A_PROMISE = /* @__PURE__ */ new Set(["then", "catch", "finally"]);
|
|
@@ -2635,7 +2846,7 @@ function propagateAwait(fileName, source, original, elsewhere = /* @__PURE__ */
|
|
|
2635
2846
|
for (let round = 0; round < 12; round += 1) {
|
|
2636
2847
|
let parsed;
|
|
2637
2848
|
try {
|
|
2638
|
-
parsed =
|
|
2849
|
+
parsed = parseSync5(fileName, current);
|
|
2639
2850
|
} catch {
|
|
2640
2851
|
return { source: current, rewritten };
|
|
2641
2852
|
}
|
|
@@ -2665,9 +2876,9 @@ function propagateAwait(fileName, source, original, elsewhere = /* @__PURE__ */
|
|
|
2665
2876
|
}
|
|
2666
2877
|
|
|
2667
2878
|
// src/roles/test/codemod/reexport-barrel-mock.ts
|
|
2668
|
-
import { readFileSync as
|
|
2879
|
+
import { readFileSync as readFileSync9, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
2669
2880
|
import { createRequire as createRequire3 } from "node:module";
|
|
2670
|
-
import { dirname as
|
|
2881
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
2671
2882
|
var MEMBER_TYPES15 = /* @__PURE__ */ new Set(["MemberExpression", "StaticMemberExpression"]);
|
|
2672
2883
|
var PACKAGE_SUBPATH = /^(@[^/]+\/[^/]+|[^@.][^/]*)\/(.+)$/;
|
|
2673
2884
|
var PURE_REEXPORT = /^module\.exports\s*=\s*require\(\s*(['"])([^'"]+)\1\s*\)\s*;?$/;
|
|
@@ -2696,7 +2907,7 @@ function mockCalls(program) {
|
|
|
2696
2907
|
}
|
|
2697
2908
|
function packageRoot(fromFile, name) {
|
|
2698
2909
|
try {
|
|
2699
|
-
return
|
|
2910
|
+
return dirname4(createRequire3(fromFile).resolve(`${name}/package.json`));
|
|
2700
2911
|
} catch {
|
|
2701
2912
|
return void 0;
|
|
2702
2913
|
}
|
|
@@ -2720,11 +2931,11 @@ function barrelsFor(fromFile, name, target) {
|
|
|
2720
2931
|
const aliases = [];
|
|
2721
2932
|
for (const entry of entries) {
|
|
2722
2933
|
if (!entry.endsWith(".js")) continue;
|
|
2723
|
-
const path =
|
|
2934
|
+
const path = join11(root, entry);
|
|
2724
2935
|
let body;
|
|
2725
2936
|
try {
|
|
2726
|
-
if (!
|
|
2727
|
-
body =
|
|
2937
|
+
if (!statSync2(path).isFile()) continue;
|
|
2938
|
+
body = readFileSync9(path, "utf8");
|
|
2728
2939
|
} catch {
|
|
2729
2940
|
continue;
|
|
2730
2941
|
}
|
|
@@ -2764,7 +2975,7 @@ ${text}` });
|
|
|
2764
2975
|
}
|
|
2765
2976
|
|
|
2766
2977
|
// src/roles/test/codemod/repoint-msw.ts
|
|
2767
|
-
import { parseSync as
|
|
2978
|
+
import { parseSync as parseSync6 } from "oxc-parser";
|
|
2768
2979
|
var SENTINEL_MSW_SERVER = "@hublo/sentinel/test/msw";
|
|
2769
2980
|
var SENTINEL_MSW_API = "@hublo/sentinel/test/tools/msw";
|
|
2770
2981
|
var MSW_PACKAGE = /^msw$/;
|
|
@@ -2777,7 +2988,7 @@ function importsServer(declaration) {
|
|
|
2777
2988
|
});
|
|
2778
2989
|
}
|
|
2779
2990
|
function repointMswServer(fileName, source) {
|
|
2780
|
-
const { program, errors } =
|
|
2991
|
+
const { program, errors } = parseSync6(fileName, source, { sourceType: "module" });
|
|
2781
2992
|
if (errors.length > 0) return { source, repointed: false };
|
|
2782
2993
|
const edits = [];
|
|
2783
2994
|
walk(program, (node) => {
|
|
@@ -2803,17 +3014,17 @@ function repointMswServer(fileName, source) {
|
|
|
2803
3014
|
}
|
|
2804
3015
|
|
|
2805
3016
|
// src/roles/test/codemod/setup-static-imports.ts
|
|
2806
|
-
import { dirname as
|
|
3017
|
+
import { dirname as dirname6, resolve as resolve6 } from "node:path";
|
|
2807
3018
|
|
|
2808
3019
|
// src/core/context.ts
|
|
2809
|
-
import { existsSync as
|
|
2810
|
-
import { dirname as
|
|
3020
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
3021
|
+
import { dirname as dirname5, join as join13, resolve as resolve4 } from "node:path";
|
|
2811
3022
|
|
|
2812
3023
|
// src/core/discover-modules.ts
|
|
2813
3024
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
2814
|
-
import { mkdtempSync as mkdtempSync2, readFileSync as
|
|
3025
|
+
import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync10, rmSync as rmSync2 } from "node:fs";
|
|
2815
3026
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2816
|
-
import { join as
|
|
3027
|
+
import { join as join12 } from "node:path";
|
|
2817
3028
|
function runNx(cwd, args) {
|
|
2818
3029
|
const nx = resolveBin(cwd, "nx") ?? "nx";
|
|
2819
3030
|
try {
|
|
@@ -2831,11 +3042,11 @@ function runNx(cwd, args) {
|
|
|
2831
3042
|
}
|
|
2832
3043
|
}
|
|
2833
3044
|
function readGraph(cwd) {
|
|
2834
|
-
const dir = mkdtempSync2(
|
|
2835
|
-
const file =
|
|
3045
|
+
const dir = mkdtempSync2(join12(tmpdir2(), "sentinel-nx-"));
|
|
3046
|
+
const file = join12(dir, "graph.json");
|
|
2836
3047
|
try {
|
|
2837
3048
|
runNx(cwd, ["graph", "--file", file]);
|
|
2838
|
-
const parsed = JSON.parse(
|
|
3049
|
+
const parsed = JSON.parse(readFileSync10(file, "utf8"));
|
|
2839
3050
|
const nodes = parsed.graph?.nodes;
|
|
2840
3051
|
if (!nodes || typeof nodes !== "object") {
|
|
2841
3052
|
throw new Error(
|
|
@@ -2844,7 +3055,7 @@ function readGraph(cwd) {
|
|
|
2844
3055
|
}
|
|
2845
3056
|
return Object.entries(nodes).map(([name, node]) => ({
|
|
2846
3057
|
name,
|
|
2847
|
-
root:
|
|
3058
|
+
root: join12(cwd, node.data.root)
|
|
2848
3059
|
}));
|
|
2849
3060
|
} finally {
|
|
2850
3061
|
rmSync2(dir, { recursive: true, force: true });
|
|
@@ -2862,20 +3073,20 @@ function discoverModules(cwd, options = {}) {
|
|
|
2862
3073
|
// src/core/context.ts
|
|
2863
3074
|
var MODULE_MARKERS = ["package.json", "project.json"];
|
|
2864
3075
|
function isModuleDir(cwd) {
|
|
2865
|
-
return MODULE_MARKERS.some((marker) =>
|
|
3076
|
+
return MODULE_MARKERS.some((marker) => existsSync12(join13(cwd, marker)));
|
|
2866
3077
|
}
|
|
2867
3078
|
function findModuleRoot(startDir, workspaceRoot) {
|
|
2868
|
-
let dir =
|
|
3079
|
+
let dir = resolve4(startDir);
|
|
2869
3080
|
for (; ; ) {
|
|
2870
|
-
if (workspaceRoot !== void 0 && dir ===
|
|
3081
|
+
if (workspaceRoot !== void 0 && dir === resolve4(workspaceRoot)) return void 0;
|
|
2871
3082
|
if (isModuleDir(dir)) return dir;
|
|
2872
|
-
const parent =
|
|
3083
|
+
const parent = dirname5(dir);
|
|
2873
3084
|
if (parent === dir) return void 0;
|
|
2874
3085
|
dir = parent;
|
|
2875
3086
|
}
|
|
2876
3087
|
}
|
|
2877
3088
|
function resolveContext(cwd, opts) {
|
|
2878
|
-
const atRoot =
|
|
3089
|
+
const atRoot = existsSync12(join13(cwd, WORKSPACE_ROOT_MARKER));
|
|
2879
3090
|
if (!atRoot && isModuleDir(cwd)) {
|
|
2880
3091
|
if (opts.module) {
|
|
2881
3092
|
throw new Error(
|
|
@@ -2903,16 +3114,16 @@ function resolveContext(cwd, opts) {
|
|
|
2903
3114
|
}
|
|
2904
3115
|
|
|
2905
3116
|
// src/roles/test/codemod/workspace-specifier.ts
|
|
2906
|
-
import { existsSync as
|
|
2907
|
-
import { join as
|
|
2908
|
-
var
|
|
3117
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
|
|
3118
|
+
import { join as join14, relative as relative2, resolve as resolve5 } from "node:path";
|
|
3119
|
+
var EXTENSIONS2 = ["", ".ts", ".tsx", ".js", ".jsx", ".mts", ".cts", "/index.ts", "/index.js"];
|
|
2909
3120
|
function pathEntries(workspaceRoot) {
|
|
2910
|
-
const file =
|
|
2911
|
-
if (!
|
|
3121
|
+
const file = join14(workspaceRoot, "tsconfig.base.json");
|
|
3122
|
+
if (!existsSync13(file)) return [];
|
|
2912
3123
|
let paths;
|
|
2913
3124
|
try {
|
|
2914
3125
|
paths = parseJsonc(
|
|
2915
|
-
|
|
3126
|
+
readFileSync11(file, "utf8"),
|
|
2916
3127
|
"tsconfig.base.json"
|
|
2917
3128
|
)?.compilerOptions?.paths;
|
|
2918
3129
|
} catch {
|
|
@@ -2925,17 +3136,17 @@ function pathEntries(workspaceRoot) {
|
|
|
2925
3136
|
const wildcard = key.endsWith("/*") && target.endsWith("/*");
|
|
2926
3137
|
entries.push({
|
|
2927
3138
|
key: wildcard ? key.slice(0, -2) : key,
|
|
2928
|
-
target:
|
|
3139
|
+
target: resolve5(workspaceRoot, wildcard ? target.slice(0, -2) : target),
|
|
2929
3140
|
wildcard
|
|
2930
3141
|
});
|
|
2931
3142
|
}
|
|
2932
3143
|
return entries.sort((left, right) => right.target.length - left.target.length);
|
|
2933
3144
|
}
|
|
2934
3145
|
function workspaceSpecifier(workspaceRoot, file) {
|
|
2935
|
-
const absolute =
|
|
3146
|
+
const absolute = resolve5(file);
|
|
2936
3147
|
for (const entry of pathEntries(workspaceRoot)) {
|
|
2937
3148
|
if (!entry.wildcard) {
|
|
2938
|
-
if (
|
|
3149
|
+
if (EXTENSIONS2.some((extension) => `${entry.target}${extension}` === absolute)) {
|
|
2939
3150
|
return entry.key;
|
|
2940
3151
|
}
|
|
2941
3152
|
continue;
|
|
@@ -2961,9 +3172,9 @@ function requireCall(source, node) {
|
|
|
2961
3172
|
}
|
|
2962
3173
|
function importable(written, fileName, workspaceRoot) {
|
|
2963
3174
|
if (!written.startsWith(".")) return written;
|
|
2964
|
-
const fileDir =
|
|
3175
|
+
const fileDir = dirname6(fileName);
|
|
2965
3176
|
const moduleRoot = findModuleRoot(fileDir, workspaceRoot) ?? fileDir;
|
|
2966
|
-
const target =
|
|
3177
|
+
const target = resolve6(fileDir, written);
|
|
2967
3178
|
if (target.startsWith(`${moduleRoot}/`)) return written;
|
|
2968
3179
|
if (workspaceRoot === void 0) return void 0;
|
|
2969
3180
|
return workspaceSpecifier(workspaceRoot, target);
|
|
@@ -3104,7 +3315,7 @@ function mockFactories(program) {
|
|
|
3104
3315
|
return factories;
|
|
3105
3316
|
}
|
|
3106
3317
|
function parse3(fileName, source) {
|
|
3107
|
-
const { program, errors } =
|
|
3318
|
+
const { program, errors } = parseSync7(fileName, source, { sourceType: "module" });
|
|
3108
3319
|
return errors.length > 0 ? void 0 : program;
|
|
3109
3320
|
}
|
|
3110
3321
|
function migrateTestFile(fileName, source, defaultImported = /* @__PURE__ */ new Set(), asyncHelpers = /* @__PURE__ */ new Set(), modulesOwnMsw = false) {
|
|
@@ -3134,7 +3345,7 @@ function migrateTestFile(fileName, source, defaultImported = /* @__PURE__ */ new
|
|
|
3134
3345
|
fileName,
|
|
3135
3346
|
source,
|
|
3136
3347
|
beforeStatic,
|
|
3137
|
-
findWorkspaceRoot(
|
|
3348
|
+
findWorkspaceRoot(dirname7(fileName))
|
|
3138
3349
|
);
|
|
3139
3350
|
source = statics.source;
|
|
3140
3351
|
const original = statics.rewritten === 0 ? beforeStatic : parse3(fileName, source);
|
|
@@ -3249,7 +3460,8 @@ function migrateTestFile(fileName, source, defaultImported = /* @__PURE__ */ new
|
|
|
3249
3460
|
...hoist.refusals,
|
|
3250
3461
|
...mocks.refusals.map((refusal) => ({ binding: refusal.binding, reason: refusal.reason })),
|
|
3251
3462
|
...constructible.refusals,
|
|
3252
|
-
...isolated.refusals
|
|
3463
|
+
...isolated.refusals,
|
|
3464
|
+
...ruled.refusals
|
|
3253
3465
|
],
|
|
3254
3466
|
warnings: fakeTimers.warnings,
|
|
3255
3467
|
mswRepointed: repointed.repointed
|
|
@@ -3257,13 +3469,13 @@ function migrateTestFile(fileName, source, defaultImported = /* @__PURE__ */ new
|
|
|
3257
3469
|
}
|
|
3258
3470
|
|
|
3259
3471
|
// src/roles/test/codemod/test-support-files.ts
|
|
3260
|
-
import { existsSync as
|
|
3261
|
-
import { dirname as
|
|
3472
|
+
import { existsSync as existsSync14, readFileSync as readFileSync12, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
|
|
3473
|
+
import { dirname as dirname8, join as join15, relative as relative3, resolve as resolve7 } from "node:path";
|
|
3262
3474
|
var SKIPPED = /* @__PURE__ */ new Set(["node_modules", "dist", "coverage", ".git", ".vite"]);
|
|
3263
3475
|
var TEST_FILE2 = /\.(spec|test)\.[cm]?[jt]sx?$/;
|
|
3264
3476
|
var SOURCE_FILE = /\.[cm]?[jt]sx?$/;
|
|
3265
|
-
var
|
|
3266
|
-
function
|
|
3477
|
+
var EXTENSIONS3 = [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts"];
|
|
3478
|
+
function relativeSpecifiers2(source) {
|
|
3267
3479
|
const found = [];
|
|
3268
3480
|
const patterns = [
|
|
3269
3481
|
/\bfrom\s+['"](\.[^'"]*)['"]/g,
|
|
@@ -3277,14 +3489,14 @@ function relativeSpecifiers(source) {
|
|
|
3277
3489
|
return found;
|
|
3278
3490
|
}
|
|
3279
3491
|
function resolveSpecifier(fromFile, specifier) {
|
|
3280
|
-
const base =
|
|
3281
|
-
if (
|
|
3282
|
-
for (const extension of
|
|
3283
|
-
if (
|
|
3492
|
+
const base = resolve7(dirname8(fromFile), specifier);
|
|
3493
|
+
if (existsSync14(base) && statSync3(base).isFile()) return base;
|
|
3494
|
+
for (const extension of EXTENSIONS3) {
|
|
3495
|
+
if (existsSync14(`${base}${extension}`)) return `${base}${extension}`;
|
|
3284
3496
|
}
|
|
3285
|
-
for (const extension of
|
|
3286
|
-
const index =
|
|
3287
|
-
if (
|
|
3497
|
+
for (const extension of EXTENSIONS3) {
|
|
3498
|
+
const index = join15(base, `index${extension}`);
|
|
3499
|
+
if (existsSync14(index)) return index;
|
|
3288
3500
|
}
|
|
3289
3501
|
return void 0;
|
|
3290
3502
|
}
|
|
@@ -3301,9 +3513,9 @@ function moduleSources(cwd) {
|
|
|
3301
3513
|
}
|
|
3302
3514
|
for (const entry of entries) {
|
|
3303
3515
|
if (entry.isDirectory()) {
|
|
3304
|
-
if (!SKIPPED.has(entry.name)) stack.push(
|
|
3516
|
+
if (!SKIPPED.has(entry.name)) stack.push(join15(dir, entry.name));
|
|
3305
3517
|
} else if (SOURCE_FILE.test(entry.name)) {
|
|
3306
|
-
found.push(
|
|
3518
|
+
found.push(join15(dir, entry.name));
|
|
3307
3519
|
}
|
|
3308
3520
|
}
|
|
3309
3521
|
}
|
|
@@ -3311,7 +3523,7 @@ function moduleSources(cwd) {
|
|
|
3311
3523
|
}
|
|
3312
3524
|
function read(path) {
|
|
3313
3525
|
try {
|
|
3314
|
-
return
|
|
3526
|
+
return readFileSync12(path, "utf8");
|
|
3315
3527
|
} catch {
|
|
3316
3528
|
return void 0;
|
|
3317
3529
|
}
|
|
@@ -3320,10 +3532,10 @@ function setupFilesInside(cwd, named) {
|
|
|
3320
3532
|
const kept = [];
|
|
3321
3533
|
for (const raw of named) {
|
|
3322
3534
|
const withoutToken = raw.replaceAll("<rootDir>/", "").replaceAll("<rootDir>", ".");
|
|
3323
|
-
const full =
|
|
3535
|
+
const full = resolve7(cwd, withoutToken);
|
|
3324
3536
|
const inside = relative3(cwd, full);
|
|
3325
3537
|
if (inside.startsWith("..") || inside === "") continue;
|
|
3326
|
-
if (!
|
|
3538
|
+
if (!existsSync14(full)) continue;
|
|
3327
3539
|
kept.push(inside.replaceAll("\\", "/"));
|
|
3328
3540
|
}
|
|
3329
3541
|
return kept;
|
|
@@ -3337,7 +3549,7 @@ function listTestSupportFiles(cwd, setupFiles = []) {
|
|
|
3337
3549
|
}
|
|
3338
3550
|
const importedBy = /* @__PURE__ */ new Map();
|
|
3339
3551
|
for (const [file, source] of contents) {
|
|
3340
|
-
for (const specifier of
|
|
3552
|
+
for (const specifier of relativeSpecifiers2(source)) {
|
|
3341
3553
|
const target = resolveSpecifier(file, specifier);
|
|
3342
3554
|
if (target === void 0 || !contents.has(target)) continue;
|
|
3343
3555
|
importedBy.set(target, [...importedBy.get(target) ?? [], file]);
|
|
@@ -3350,7 +3562,7 @@ function listTestSupportFiles(cwd, setupFiles = []) {
|
|
|
3350
3562
|
);
|
|
3351
3563
|
while (queue.length > 0) {
|
|
3352
3564
|
const file = queue.shift();
|
|
3353
|
-
for (const specifier of
|
|
3565
|
+
for (const specifier of relativeSpecifiers2(contents.get(file) ?? "")) {
|
|
3354
3566
|
const target = resolveSpecifier(file, specifier);
|
|
3355
3567
|
if (target === void 0 || TEST_FILE2.test(target) || testOnly.has(target)) continue;
|
|
3356
3568
|
if (!isTestOnly(target)) continue;
|
|
@@ -3364,12 +3576,12 @@ function listTestSupportFiles(cwd, setupFiles = []) {
|
|
|
3364
3576
|
|
|
3365
3577
|
// src/roles/test/codemod/migrate-module.ts
|
|
3366
3578
|
function parse4(source) {
|
|
3367
|
-
const { program, errors } =
|
|
3579
|
+
const { program, errors } = parseSync8("file.ts", source, { sourceType: "module" });
|
|
3368
3580
|
return errors.length > 0 ? void 0 : program;
|
|
3369
3581
|
}
|
|
3370
3582
|
function read2(path) {
|
|
3371
3583
|
try {
|
|
3372
|
-
return
|
|
3584
|
+
return readFileSync13(path, "utf8");
|
|
3373
3585
|
} catch {
|
|
3374
3586
|
return void 0;
|
|
3375
3587
|
}
|
|
@@ -3387,10 +3599,10 @@ function defaultImportedSpecifiers(cwd) {
|
|
|
3387
3599
|
}
|
|
3388
3600
|
for (const entry of entries) {
|
|
3389
3601
|
if (SKIPPED2.has(entry)) continue;
|
|
3390
|
-
const path =
|
|
3602
|
+
const path = join16(dir, entry);
|
|
3391
3603
|
let directory;
|
|
3392
3604
|
try {
|
|
3393
|
-
directory =
|
|
3605
|
+
directory = statSync4(path).isDirectory();
|
|
3394
3606
|
} catch {
|
|
3395
3607
|
continue;
|
|
3396
3608
|
}
|
|
@@ -3418,18 +3630,28 @@ function migrateModuleTests(cwd, setupFiles = []) {
|
|
|
3418
3630
|
const defaultImported = defaultImportedSpecifiers(cwd);
|
|
3419
3631
|
const asyncHelpers = /* @__PURE__ */ new Set();
|
|
3420
3632
|
for (const relative6 of listTestSupportFiles(cwd, setupFiles)) {
|
|
3421
|
-
const source = read2(
|
|
3633
|
+
const source = read2(join16(cwd, relative6));
|
|
3422
3634
|
if (source === void 0) {
|
|
3423
3635
|
blockers.push({ file: relative6, reason: "this file could not be read" });
|
|
3424
3636
|
continue;
|
|
3425
3637
|
}
|
|
3426
3638
|
const migrated = migrateTestFile(
|
|
3427
|
-
|
|
3639
|
+
join16(cwd, relative6),
|
|
3428
3640
|
source,
|
|
3429
3641
|
defaultImported,
|
|
3430
3642
|
/* @__PURE__ */ new Set(),
|
|
3431
3643
|
modulesOwnMsw
|
|
3432
3644
|
);
|
|
3645
|
+
for (const member of migrated.unhandled) {
|
|
3646
|
+
blockers.push({
|
|
3647
|
+
file: `${relative6}:${member.line}`,
|
|
3648
|
+
reason: member.rule === void 0 ? `${member.member} has no rule, and guessing one is how a suite goes green for the wrong reason` : `${member.member} needs ${member.rule}`
|
|
3649
|
+
});
|
|
3650
|
+
}
|
|
3651
|
+
for (const refusal of migrated.refusals) {
|
|
3652
|
+
blockers.push({ file: relative6, reason: refusal.reason });
|
|
3653
|
+
}
|
|
3654
|
+
collected.push(...migrated.warnings);
|
|
3433
3655
|
const renamedTo = vitestSupportName(relative6);
|
|
3434
3656
|
if (!migrated.changed && renamedTo === relative6) continue;
|
|
3435
3657
|
if (renamedTo !== relative6) operations.push({ kind: "delete", path: relative6 });
|
|
@@ -3443,17 +3665,17 @@ function migrateModuleTests(cwd, setupFiles = []) {
|
|
|
3443
3665
|
}
|
|
3444
3666
|
files++;
|
|
3445
3667
|
renamed += migrated.renamed;
|
|
3446
|
-
const contents = /\bvi\./.test(migrated.source) ? injectViImport(
|
|
3668
|
+
const contents = /\bvi\./.test(migrated.source) ? injectViImport(join16(cwd, renamedTo), migrated.source) : migrated.source;
|
|
3447
3669
|
operations.push({ kind: "write", path: renamedTo, contents });
|
|
3448
3670
|
}
|
|
3449
3671
|
for (const relative6 of listTestFiles(cwd)) {
|
|
3450
|
-
const source = read2(
|
|
3672
|
+
const source = read2(join16(cwd, relative6));
|
|
3451
3673
|
if (source === void 0) {
|
|
3452
3674
|
blockers.push({ file: relative6, reason: "this file could not be read" });
|
|
3453
3675
|
continue;
|
|
3454
3676
|
}
|
|
3455
3677
|
const migrated = migrateTestFile(
|
|
3456
|
-
|
|
3678
|
+
join16(cwd, relative6),
|
|
3457
3679
|
source,
|
|
3458
3680
|
defaultImported,
|
|
3459
3681
|
asyncHelpers,
|
|
@@ -3480,8 +3702,8 @@ function migrateModuleTests(cwd, setupFiles = []) {
|
|
|
3480
3702
|
}
|
|
3481
3703
|
|
|
3482
3704
|
// src/roles/test/nest/generate-config.ts
|
|
3483
|
-
import { readdirSync as readdirSync5, readFileSync as
|
|
3484
|
-
import { join as
|
|
3705
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync14, statSync as statSync5 } from "node:fs";
|
|
3706
|
+
import { join as join17, relative as relative4 } from "node:path";
|
|
3485
3707
|
var NEST_TEST_PRESET_SPECIFIER = "@hublo/sentinel/test/nest";
|
|
3486
3708
|
var REACT_TEST_PRESET_SPECIFIER = "@hublo/sentinel/test/react";
|
|
3487
3709
|
function flavourOf(reading) {
|
|
@@ -3527,10 +3749,10 @@ function readModuleTraits(cwd) {
|
|
|
3527
3749
|
}
|
|
3528
3750
|
for (const entry of entries) {
|
|
3529
3751
|
if (SKIPPED3.has(entry)) continue;
|
|
3530
|
-
const path =
|
|
3752
|
+
const path = join17(dir, entry);
|
|
3531
3753
|
let directory;
|
|
3532
3754
|
try {
|
|
3533
|
-
directory =
|
|
3755
|
+
directory = statSync5(path).isDirectory();
|
|
3534
3756
|
} catch {
|
|
3535
3757
|
continue;
|
|
3536
3758
|
}
|
|
@@ -3541,7 +3763,7 @@ function readModuleTraits(cwd) {
|
|
|
3541
3763
|
if (!/\.tsx?$/.test(entry)) continue;
|
|
3542
3764
|
let source;
|
|
3543
3765
|
try {
|
|
3544
|
-
source =
|
|
3766
|
+
source = readFileSync14(path, "utf8");
|
|
3545
3767
|
} catch {
|
|
3546
3768
|
continue;
|
|
3547
3769
|
}
|
|
@@ -3674,8 +3896,8 @@ ${overrides.join("\n")}
|
|
|
3674
3896
|
}
|
|
3675
3897
|
|
|
3676
3898
|
// src/roles/test/nest/read-jest-config.ts
|
|
3677
|
-
import { existsSync as
|
|
3678
|
-
import { join as
|
|
3899
|
+
import { existsSync as existsSync15, readFileSync as readFileSync15 } from "node:fs";
|
|
3900
|
+
import { join as join18 } from "node:path";
|
|
3679
3901
|
var CARRIED = [
|
|
3680
3902
|
"testEnvironment",
|
|
3681
3903
|
"coverageDirectory",
|
|
@@ -3865,7 +4087,7 @@ function extendedConfig(source, cwd) {
|
|
|
3865
4087
|
(name) => name.replace(/^\.\//, "")
|
|
3866
4088
|
);
|
|
3867
4089
|
const file = candidates.find(
|
|
3868
|
-
(name) => /^jest[\w.-]*\.(ts|js)$/.test(name) &&
|
|
4090
|
+
(name) => /^jest[\w.-]*\.(ts|js)$/.test(name) && existsSync15(join18(cwd, name))
|
|
3869
4091
|
);
|
|
3870
4092
|
if (file === void 0) continue;
|
|
3871
4093
|
if (!new RegExp(String.raw`\{\s*\.\.\.${binding}\b`).test(source)) continue;
|
|
@@ -3892,11 +4114,11 @@ function sideEffects(source, extended) {
|
|
|
3892
4114
|
return found;
|
|
3893
4115
|
}
|
|
3894
4116
|
function readJestConfig(cwd, named) {
|
|
3895
|
-
const file = named ?? JEST_CONFIG_FILES.find((name) =>
|
|
3896
|
-
if (file === void 0 || !
|
|
4117
|
+
const file = named ?? JEST_CONFIG_FILES.find((name) => existsSync15(join18(cwd, name)));
|
|
4118
|
+
if (file === void 0 || !existsSync15(join18(cwd, file))) return void 0;
|
|
3897
4119
|
let source;
|
|
3898
4120
|
try {
|
|
3899
|
-
source =
|
|
4121
|
+
source = readFileSync15(join18(cwd, file), "utf8");
|
|
3900
4122
|
} catch {
|
|
3901
4123
|
return { file, refusals: [`${file} could not be read`], notes: [] };
|
|
3902
4124
|
}
|
|
@@ -3977,8 +4199,8 @@ function readJestConfig(cwd, named) {
|
|
|
3977
4199
|
}
|
|
3978
4200
|
|
|
3979
4201
|
// src/roles/test/nest/run-modes.ts
|
|
3980
|
-
import { existsSync as
|
|
3981
|
-
import { basename as basename2, join as
|
|
4202
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
4203
|
+
import { basename as basename2, join as join19 } from "node:path";
|
|
3982
4204
|
var JEST_EXECUTOR = "@nx/jest:jest";
|
|
3983
4205
|
var PRIMARY_CONFIG_FILE = "vitest.config.mts";
|
|
3984
4206
|
var PRIMARY_TARGET = "test";
|
|
@@ -3999,7 +4221,7 @@ function runModes(cwd, fallback) {
|
|
|
3999
4221
|
const jestConfig = entry.options?.jestConfig;
|
|
4000
4222
|
if (jestConfig === void 0) continue;
|
|
4001
4223
|
const name = configName(jestConfig);
|
|
4002
|
-
if (!
|
|
4224
|
+
if (!existsSync16(join19(cwd, name))) continue;
|
|
4003
4225
|
declared.push({
|
|
4004
4226
|
target,
|
|
4005
4227
|
jestConfig: name,
|
|
@@ -4024,12 +4246,12 @@ function runModes(cwd, fallback) {
|
|
|
4024
4246
|
}
|
|
4025
4247
|
|
|
4026
4248
|
// src/roles/test/written-file-formatter.ts
|
|
4027
|
-
import { existsSync as
|
|
4028
|
-
import { dirname as
|
|
4249
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
4250
|
+
import { dirname as dirname10, join as join22 } from "node:path";
|
|
4029
4251
|
|
|
4030
4252
|
// src/roles/format/read-adoption.ts
|
|
4031
|
-
import { existsSync as
|
|
4032
|
-
import { join as
|
|
4253
|
+
import { existsSync as existsSync17, readFileSync as readFileSync16 } from "node:fs";
|
|
4254
|
+
import { join as join20 } from "node:path";
|
|
4033
4255
|
|
|
4034
4256
|
// src/roles/format/config-policy.ts
|
|
4035
4257
|
var FORMAT_CONFIG_FILE = ".oxfmtrc.json";
|
|
@@ -4135,11 +4357,11 @@ function sameValue(a, b) {
|
|
|
4135
4357
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
4136
4358
|
}
|
|
4137
4359
|
function readFormatAdoption(cwd) {
|
|
4138
|
-
const path =
|
|
4139
|
-
if (!
|
|
4360
|
+
const path = join20(cwd, FORMAT_CONFIG_FILE);
|
|
4361
|
+
if (!existsSync17(path)) return NOT_ADOPTED(null);
|
|
4140
4362
|
let parsed;
|
|
4141
4363
|
try {
|
|
4142
|
-
parsed = parseJsonc(
|
|
4364
|
+
parsed = parseJsonc(readFileSync16(path, "utf8"), FORMAT_CONFIG_FILE);
|
|
4143
4365
|
} catch (error) {
|
|
4144
4366
|
const reason = error instanceof Error ? error.message : String(error);
|
|
4145
4367
|
return NOT_ADOPTED(FORMAT_CONFIG_FILE, `${FORMAT_CONFIG_FILE} could not be parsed (${reason})`);
|
|
@@ -4183,9 +4405,9 @@ function readFormatAdoption(cwd) {
|
|
|
4183
4405
|
}
|
|
4184
4406
|
|
|
4185
4407
|
// src/roles/format/resolve-oxfmt.ts
|
|
4186
|
-
import { readFileSync as
|
|
4408
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
4187
4409
|
import { createRequire as createRequire4 } from "node:module";
|
|
4188
|
-
import { dirname as
|
|
4410
|
+
import { dirname as dirname9, join as join21 } from "node:path";
|
|
4189
4411
|
function resolveOxfmt(cwd) {
|
|
4190
4412
|
return resolveBin(cwd, "oxfmt") ?? binFromOwnInstall("oxfmt", "oxfmt");
|
|
4191
4413
|
}
|
|
@@ -4214,8 +4436,8 @@ function configSchema() {
|
|
|
4214
4436
|
function readConfigSchema() {
|
|
4215
4437
|
try {
|
|
4216
4438
|
const manifest = createRequire4(import.meta.url).resolve("oxfmt/package.json");
|
|
4217
|
-
const schemaPath =
|
|
4218
|
-
return JSON.parse(
|
|
4439
|
+
const schemaPath = join21(dirname9(manifest), "configuration_schema.json");
|
|
4440
|
+
return JSON.parse(readFileSync17(schemaPath, "utf8"));
|
|
4219
4441
|
} catch {
|
|
4220
4442
|
return void 0;
|
|
4221
4443
|
}
|
|
@@ -4240,9 +4462,9 @@ function prettierConfigFrom(cwd) {
|
|
|
4240
4462
|
let dir = cwd;
|
|
4241
4463
|
for (; ; ) {
|
|
4242
4464
|
for (const name of PRETTIER_CONFIGS) {
|
|
4243
|
-
if (
|
|
4465
|
+
if (existsSync18(join22(dir, name))) return join22(dir, name);
|
|
4244
4466
|
}
|
|
4245
|
-
const parent =
|
|
4467
|
+
const parent = dirname10(dir);
|
|
4246
4468
|
if (parent === dir) return void 0;
|
|
4247
4469
|
dir = parent;
|
|
4248
4470
|
}
|
|
@@ -4270,12 +4492,12 @@ function writtenFileFormatter(cwd) {
|
|
|
4270
4492
|
var SPEC_TSCONFIG = "tsconfig.spec.json";
|
|
4271
4493
|
var VITEST_GLOBAL_TYPES = "vitest/globals";
|
|
4272
4494
|
function specTypesOperation(cwd) {
|
|
4273
|
-
const path =
|
|
4274
|
-
if (!
|
|
4495
|
+
const path = join23(cwd, SPEC_TSCONFIG);
|
|
4496
|
+
if (!existsSync19(path)) return void 0;
|
|
4275
4497
|
let config;
|
|
4276
4498
|
try {
|
|
4277
4499
|
config = parseJsonc(
|
|
4278
|
-
|
|
4500
|
+
readFileSync18(path, "utf8"),
|
|
4279
4501
|
SPEC_TSCONFIG
|
|
4280
4502
|
);
|
|
4281
4503
|
} catch {
|
|
@@ -4295,9 +4517,9 @@ function specTypesOperation(cwd) {
|
|
|
4295
4517
|
}
|
|
4296
4518
|
function shippedTypesPath(cwd, declaration) {
|
|
4297
4519
|
try {
|
|
4298
|
-
const manifest = createRequire5(
|
|
4299
|
-
const file =
|
|
4300
|
-
if (
|
|
4520
|
+
const manifest = createRequire5(join23(cwd, "noop.cjs")).resolve("@hublo/sentinel/package.json");
|
|
4521
|
+
const file = join23(dirname11(manifest), declaration);
|
|
4522
|
+
if (existsSync19(file)) {
|
|
4301
4523
|
const path = relative5(cwd, file);
|
|
4302
4524
|
return path.startsWith(".") ? path : `./${path}`;
|
|
4303
4525
|
}
|
|
@@ -4316,7 +4538,7 @@ function helpersStillCallingJest(cwd) {
|
|
|
4316
4538
|
return;
|
|
4317
4539
|
}
|
|
4318
4540
|
for (const entry of entries) {
|
|
4319
|
-
const path =
|
|
4541
|
+
const path = join23(dir, entry.name);
|
|
4320
4542
|
if (entry.isDirectory()) {
|
|
4321
4543
|
if (!skip.has(entry.name)) walk2(path);
|
|
4322
4544
|
continue;
|
|
@@ -4326,7 +4548,7 @@ function helpersStillCallingJest(cwd) {
|
|
|
4326
4548
|
if (/^(jest|vitest)\./.test(entry.name)) continue;
|
|
4327
4549
|
let source;
|
|
4328
4550
|
try {
|
|
4329
|
-
source =
|
|
4551
|
+
source = readFileSync18(path, "utf8");
|
|
4330
4552
|
} catch {
|
|
4331
4553
|
continue;
|
|
4332
4554
|
}
|
|
@@ -4362,7 +4584,7 @@ function tsconfigFileListOperations(cwd) {
|
|
|
4362
4584
|
let config;
|
|
4363
4585
|
try {
|
|
4364
4586
|
config = parseJsonc(
|
|
4365
|
-
|
|
4587
|
+
readFileSync18(join23(cwd, name), "utf8"),
|
|
4366
4588
|
name
|
|
4367
4589
|
);
|
|
4368
4590
|
} catch {
|
|
@@ -4830,7 +5052,7 @@ function fromWorkspaceRoot(moduleDir, options, paths) {
|
|
|
4830
5052
|
if (root === void 0 || root === moduleDir) {
|
|
4831
5053
|
return { cwd: moduleDir, options: [...options], paths: [...paths] };
|
|
4832
5054
|
}
|
|
4833
|
-
const absolute = (value) => isAbsolute2(value) ? value :
|
|
5055
|
+
const absolute = (value) => isAbsolute2(value) ? value : resolve8(moduleDir, value);
|
|
4834
5056
|
const moved = [];
|
|
4835
5057
|
let previousWasConfig = false;
|
|
4836
5058
|
for (const option of options) {
|
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-63NQP75B.js";
|
|
10
10
|
import {
|
|
11
11
|
BaseAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-UBXL567Z.js";
|
|
13
13
|
import "./chunk-O7REVMOC.js";
|
|
14
14
|
import "./chunk-NW6UHNYX.js";
|
|
15
15
|
export {
|
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.33",
|
|
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",
|