@hublo/sentinel 1.2.0-alpha.8 → 1.2.0-alpha.9
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 +28 -2
- package/dist/{chunk-A25QVPXF.js → chunk-6RH3LZQZ.js} +257 -131
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/bin/sentinel.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
VERBS,
|
|
9
9
|
WORKSPACE_ROOT_MARKER,
|
|
10
10
|
availableTargets,
|
|
11
|
+
buildConfigFile,
|
|
11
12
|
declaredPresetFor,
|
|
12
13
|
describeFramework,
|
|
13
14
|
dispatch,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
registerAdapters,
|
|
22
23
|
resolve,
|
|
23
24
|
resolveBin
|
|
24
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-6RH3LZQZ.js";
|
|
25
26
|
|
|
26
27
|
// bin/sentinel.ts
|
|
27
28
|
import { program } from "commander";
|
|
@@ -113,6 +114,30 @@ function resolveContext(cwd2, opts2) {
|
|
|
113
114
|
);
|
|
114
115
|
}
|
|
115
116
|
|
|
117
|
+
// src/roles/build/scope.ts
|
|
118
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
119
|
+
import { join as join3 } from "path";
|
|
120
|
+
var DEPRECATED_NX_BUILDER = "@nx/webpack:webpack";
|
|
121
|
+
function buildsWithDeprecatedExecutor(cwd2) {
|
|
122
|
+
const projectJson = join3(cwd2, "project.json");
|
|
123
|
+
if (!existsSync2(projectJson)) return false;
|
|
124
|
+
try {
|
|
125
|
+
const project = JSON.parse(readFileSync2(projectJson, "utf8"));
|
|
126
|
+
return project.targets?.build?.executor === DEPRECATED_NX_BUILDER;
|
|
127
|
+
} catch {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function explainBuildScope(cwd2) {
|
|
132
|
+
if (buildConfigFile(cwd2) !== void 0) {
|
|
133
|
+
return ` This module HAS a Vite config, so detection is the likely problem: the build toolchain is declared at the workspace root, which makes a front app detect as "node". Pass --preset to say what it is.`;
|
|
134
|
+
}
|
|
135
|
+
if (buildsWithDeprecatedExecutor(cwd2)) {
|
|
136
|
+
return ` This module still builds through ${DEPRECATED_NX_BUILDER}, which Nx v24 removes. It has no Vite config yet, so there is nothing for --build to adopt: add one that imports @hublo/sentinel/build/nest, then run this again. See docs/build-adoption.md.`;
|
|
137
|
+
}
|
|
138
|
+
return ` This module has neither a Vite config nor an Nx build target, so it builds nothing and --build is out of scope for it. Nothing was written, and nothing is wrong.`;
|
|
139
|
+
}
|
|
140
|
+
|
|
116
141
|
// src/cli/run-init.ts
|
|
117
142
|
function asMessage(error) {
|
|
118
143
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -151,9 +176,10 @@ async function runInit(ctx) {
|
|
|
151
176
|
} catch (error) {
|
|
152
177
|
if (error instanceof PresetUnsupportedError) {
|
|
153
178
|
if (ctx.targetsExplicit) {
|
|
179
|
+
const hint = type === "build" ? explainBuildScope(module.root) : ` Pass --preset if it was detected wrongly (hoisted dependencies make detection fall back to "node").`;
|
|
154
180
|
process.stderr.write(
|
|
155
181
|
`
|
|
156
|
-
sentinel (${type}): this module's preset is "${error.preset}", and --${type} has no adapter for it
|
|
182
|
+
sentinel (${type}): this module's preset is "${error.preset}", and --${type} has no adapter for it.${hint}
|
|
157
183
|
`
|
|
158
184
|
);
|
|
159
185
|
worst = Math.max(worst, 1);
|
|
@@ -205,9 +205,9 @@ function binFromOwnInstall(packageName, binName) {
|
|
|
205
205
|
try {
|
|
206
206
|
const manifest = require2.resolve(`${packageName}/package.json`);
|
|
207
207
|
const bin = require2(manifest).bin;
|
|
208
|
-
const
|
|
209
|
-
if (!
|
|
210
|
-
const executable = join2(dirname2(manifest),
|
|
208
|
+
const relative6 = typeof bin === "string" ? bin : bin?.[binName];
|
|
209
|
+
if (!relative6) return void 0;
|
|
210
|
+
const executable = join2(dirname2(manifest), relative6);
|
|
211
211
|
return existsSync3(executable) ? executable : void 0;
|
|
212
212
|
} catch {
|
|
213
213
|
return void 0;
|
|
@@ -220,8 +220,8 @@ function binSearchPath(cwd) {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
// src/roles/build/plan.ts
|
|
223
|
-
import { existsSync as
|
|
224
|
-
import { join as
|
|
223
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
|
|
224
|
+
import { join as join8 } from "path";
|
|
225
225
|
|
|
226
226
|
// src/core/config/existing-command.ts
|
|
227
227
|
import { readFileSync as readFileSync3 } from "fs";
|
|
@@ -508,9 +508,116 @@ function composeDevScript(existing, command) {
|
|
|
508
508
|
return chunks.join(CHAIN);
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
-
// src/roles/build/
|
|
511
|
+
// src/roles/build/nest/adopt.ts
|
|
512
|
+
import { relative as relative2 } from "path";
|
|
513
|
+
|
|
514
|
+
// src/roles/build/nest/nx-target.ts
|
|
512
515
|
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
513
|
-
import { join as join6 } from "path";
|
|
516
|
+
import { join as join6, relative } from "path";
|
|
517
|
+
var DEPRECATED_NX_BUILDER = "@nx/webpack:webpack";
|
|
518
|
+
var TRANSLATABLE_WEBPACK_CONFIG = "tools/webpack-configs/update.webpack.config.js";
|
|
519
|
+
var readProjectJson = (cwd) => {
|
|
520
|
+
const path = join6(cwd, "project.json");
|
|
521
|
+
if (!existsSync6(path)) return void 0;
|
|
522
|
+
try {
|
|
523
|
+
return JSON.parse(readFileSync4(path, "utf8"));
|
|
524
|
+
} catch {
|
|
525
|
+
return void 0;
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
function webpackBuildTarget(cwd) {
|
|
529
|
+
const project = readProjectJson(cwd);
|
|
530
|
+
const target = project?.targets?.build;
|
|
531
|
+
if (target?.executor !== DEPRECATED_NX_BUILDER) return void 0;
|
|
532
|
+
const { outputPath, main, webpackConfig } = target.options ?? {};
|
|
533
|
+
if (typeof project?.name !== "string" || typeof outputPath !== "string" || typeof main !== "string" || typeof webpackConfig !== "string") {
|
|
534
|
+
return void 0;
|
|
535
|
+
}
|
|
536
|
+
return {
|
|
537
|
+
project: project.name,
|
|
538
|
+
outputPath,
|
|
539
|
+
main,
|
|
540
|
+
webpackConfig,
|
|
541
|
+
configurations: target.configurations
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function refusalFor(cwd, target) {
|
|
545
|
+
if (target.webpackConfig !== TRANSLATABLE_WEBPACK_CONFIG) {
|
|
546
|
+
return `this service builds with ${target.webpackConfig}, not the shared ${TRANSLATABLE_WEBPACK_CONFIG} this preset reproduces. Its own config adds loaders or rules the preset has no equivalent for, and translating it anyway would produce a build that succeeds and a service that fails later. Read that file, decide what the Vite config needs, and write it by hand. Nothing was written.`;
|
|
547
|
+
}
|
|
548
|
+
const live = liveFileReplacements(cwd, target);
|
|
549
|
+
if (live.length > 0) {
|
|
550
|
+
return `this service's production configuration replaces ${live.join(", ")}, and those files exist. The preset has no equivalent, so translating the target would drop a real substitution. Nothing was written.`;
|
|
551
|
+
}
|
|
552
|
+
return void 0;
|
|
553
|
+
}
|
|
554
|
+
function liveFileReplacements(cwd, target) {
|
|
555
|
+
const workspaceRoot = workspaceRootFor(cwd, target);
|
|
556
|
+
const configurations = target.configurations ?? {};
|
|
557
|
+
const live = [];
|
|
558
|
+
for (const configuration of Object.values(configurations)) {
|
|
559
|
+
for (const replacement of configuration.fileReplacements ?? []) {
|
|
560
|
+
const exists = existsSync6(join6(workspaceRoot, replacement.replace)) || existsSync6(join6(workspaceRoot, replacement.with));
|
|
561
|
+
if (exists) live.push(replacement.replace);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return live;
|
|
565
|
+
}
|
|
566
|
+
function workspaceRootFor(cwd, target) {
|
|
567
|
+
const moduleRoot = target.main.replace(/\/src\/.*$/, "");
|
|
568
|
+
const suffix = cwd.endsWith(moduleRoot) ? moduleRoot : "";
|
|
569
|
+
return suffix === "" ? cwd : cwd.slice(0, cwd.length - suffix.length - 1);
|
|
570
|
+
}
|
|
571
|
+
function workspaceRootHops(cwd, target) {
|
|
572
|
+
const root = workspaceRootFor(cwd, target);
|
|
573
|
+
const rel = relative(root, cwd);
|
|
574
|
+
return rel === "" ? 0 : rel.split(/[\\/]/).length;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// src/roles/build/nest/adopt.ts
|
|
578
|
+
var NEST_CONFIG_FILE = "vite.config.mts";
|
|
579
|
+
function nestConfigSource(cwd, target) {
|
|
580
|
+
const hops = workspaceRootHops(cwd, target);
|
|
581
|
+
const up = Array.from({ length: hops }, () => "..").join("/");
|
|
582
|
+
return `import path from 'node:path'
|
|
583
|
+
|
|
584
|
+
import { nestService } from '${BUILD_PRESET_SPECIFIERS.nest}'
|
|
585
|
+
|
|
586
|
+
export default nestService({
|
|
587
|
+
project: '${target.project}',
|
|
588
|
+
root: __dirname,
|
|
589
|
+
workspaceRoot: path.resolve(__dirname, '${up}'),
|
|
590
|
+
outDir: '${target.outputPath}',
|
|
591
|
+
})
|
|
592
|
+
`;
|
|
593
|
+
}
|
|
594
|
+
function nestBuildTarget(cwd, target) {
|
|
595
|
+
const moduleRoot = relative2(workspaceRootFor(cwd, target), cwd);
|
|
596
|
+
return {
|
|
597
|
+
executor: "nx:run-commands",
|
|
598
|
+
outputs: [`{workspaceRoot}/${target.outputPath}`],
|
|
599
|
+
options: {
|
|
600
|
+
cwd: moduleRoot,
|
|
601
|
+
command: "pnpm exec sentinel --run --build",
|
|
602
|
+
forwardAllArgs: false
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function nestAdoptionOperations(cwd, target) {
|
|
607
|
+
return [
|
|
608
|
+
{ kind: "write", path: NEST_CONFIG_FILE, contents: nestConfigSource(cwd, target) },
|
|
609
|
+
{ kind: "remove-json-keys", path: "project.json", keys: [["targets", "build"]] },
|
|
610
|
+
{
|
|
611
|
+
kind: "merge-json",
|
|
612
|
+
path: "project.json",
|
|
613
|
+
value: { targets: { build: nestBuildTarget(cwd, target) } }
|
|
614
|
+
}
|
|
615
|
+
];
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/roles/build/read-adoption.ts
|
|
619
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
620
|
+
import { join as join7 } from "path";
|
|
514
621
|
var NOT_ADOPTED = (configFile, unreadable = null) => ({
|
|
515
622
|
configFile,
|
|
516
623
|
preset: null,
|
|
@@ -521,7 +628,7 @@ var NOT_ADOPTED = (configFile, unreadable = null) => ({
|
|
|
521
628
|
unreadable
|
|
522
629
|
});
|
|
523
630
|
function buildConfigFile(cwd) {
|
|
524
|
-
return BUILD_CONFIG_FILES.find((name) =>
|
|
631
|
+
return BUILD_CONFIG_FILES.find((name) => existsSync7(join7(cwd, name)));
|
|
525
632
|
}
|
|
526
633
|
function importsSpecifier(source, specifier) {
|
|
527
634
|
const escaped = specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -535,7 +642,9 @@ function importsPreset(source) {
|
|
|
535
642
|
var REACT_PLUGIN_SPECIFIERS = ["@vitejs/plugin-react", "@tanstack/react-start"];
|
|
536
643
|
function declaredBuildPreset(cwd) {
|
|
537
644
|
const source = readBuildConfigSource(cwd);
|
|
538
|
-
if (source === void 0)
|
|
645
|
+
if (source === void 0) {
|
|
646
|
+
return webpackBuildTarget(cwd) === void 0 ? void 0 : "nest";
|
|
647
|
+
}
|
|
539
648
|
if (importsSpecifier(source, BUILD_PRESET_SPECIFIERS.nest)) return "nest";
|
|
540
649
|
if (importsPreset(source)) return "react";
|
|
541
650
|
return REACT_PLUGIN_SPECIFIERS.some((specifier) => importsSpecifier(source, specifier)) ? "react" : void 0;
|
|
@@ -544,7 +653,7 @@ function readBuildConfigSource(cwd) {
|
|
|
544
653
|
const configFile = buildConfigFile(cwd);
|
|
545
654
|
if (!configFile) return void 0;
|
|
546
655
|
try {
|
|
547
|
-
return
|
|
656
|
+
return readFileSync5(join7(cwd, configFile), "utf8");
|
|
548
657
|
} catch {
|
|
549
658
|
return void 0;
|
|
550
659
|
}
|
|
@@ -554,7 +663,7 @@ function readBuildAdoption(cwd) {
|
|
|
554
663
|
if (!configFile) return NOT_ADOPTED(null);
|
|
555
664
|
let source;
|
|
556
665
|
try {
|
|
557
|
-
source =
|
|
666
|
+
source = readFileSync5(join7(cwd, configFile), "utf8");
|
|
558
667
|
} catch (error) {
|
|
559
668
|
return NOT_ADOPTED(configFile, error instanceof Error ? error.message : String(error));
|
|
560
669
|
}
|
|
@@ -760,6 +869,22 @@ function plan(context) {
|
|
|
760
869
|
const notes = [];
|
|
761
870
|
const operations = [];
|
|
762
871
|
const configFile = buildConfigFile(context.cwd);
|
|
872
|
+
const webpackTarget = webpackBuildTarget(context.cwd);
|
|
873
|
+
if (configFile === void 0 && webpackTarget !== void 0) {
|
|
874
|
+
const refusal = refusalFor(context.cwd, webpackTarget);
|
|
875
|
+
if (refusal !== void 0) return { operations: [], blocked: refusal };
|
|
876
|
+
const dropped = Object.keys(webpackTarget.configurations ?? {});
|
|
877
|
+
return {
|
|
878
|
+
operations: nestAdoptionOperations(context.cwd, webpackTarget),
|
|
879
|
+
notes: [
|
|
880
|
+
`wrote ${NEST_CONFIG_FILE} and pointed the nx build target at sentinel. The target stays \`nx:run-commands\` with \`forwardAllArgs: false\`, so the image's \`--generatePackageJson\` still works and the Dockerfile needs no change.`,
|
|
881
|
+
...dropped.length > 0 ? [
|
|
882
|
+
`dropped the \`${dropped.join("`, `")}\` configuration${dropped.length > 1 ? "s" : ""} from the build target: its fileReplacements point at files that do not exist, so it replaced nothing. A live one would have blocked this instead.`
|
|
883
|
+
] : [],
|
|
884
|
+
`verify with \`nx run ${webpackTarget.project}:generate-swagger-file\` and \`git diff --exit-code\`: it runs the built bundle, so it proves the service boots AND that its published contract did not move.`
|
|
885
|
+
]
|
|
886
|
+
};
|
|
887
|
+
}
|
|
763
888
|
if (configFile === void 0) {
|
|
764
889
|
return {
|
|
765
890
|
operations: [],
|
|
@@ -809,9 +934,9 @@ function plan(context) {
|
|
|
809
934
|
return { operations, notes };
|
|
810
935
|
}
|
|
811
936
|
function readConfigSource(cwd, configFile) {
|
|
812
|
-
if (!
|
|
937
|
+
if (!existsSync8(join8(cwd, configFile))) return "";
|
|
813
938
|
try {
|
|
814
|
-
return
|
|
939
|
+
return readFileSync6(join8(cwd, configFile), "utf8");
|
|
815
940
|
} catch {
|
|
816
941
|
return "";
|
|
817
942
|
}
|
|
@@ -1109,12 +1234,12 @@ function registerBuild() {
|
|
|
1109
1234
|
|
|
1110
1235
|
// src/roles/format/adapters/oxfmt/oxfmt.adapter.ts
|
|
1111
1236
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
1112
|
-
import { existsSync as
|
|
1113
|
-
import { join as
|
|
1237
|
+
import { existsSync as existsSync13, readFileSync as readFileSync12 } from "fs";
|
|
1238
|
+
import { join as join15 } from "path";
|
|
1114
1239
|
|
|
1115
1240
|
// src/core/config/has-source.ts
|
|
1116
1241
|
import { readdirSync } from "fs";
|
|
1117
|
-
import { extname, join as
|
|
1242
|
+
import { extname, join as join9, relative as relative3 } from "path";
|
|
1118
1243
|
var SKIP_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
1119
1244
|
"node_modules",
|
|
1120
1245
|
"dist",
|
|
@@ -1165,7 +1290,7 @@ function hasSourceFiles(cwd, extensions) {
|
|
|
1165
1290
|
}
|
|
1166
1291
|
for (const entry of entries) {
|
|
1167
1292
|
if (entry.isDirectory()) {
|
|
1168
|
-
if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(
|
|
1293
|
+
if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(join9(dir, entry.name));
|
|
1169
1294
|
continue;
|
|
1170
1295
|
}
|
|
1171
1296
|
if (wanted.has(extname(entry.name))) return true;
|
|
@@ -1186,12 +1311,12 @@ function listSourceFiles(cwd, extensions) {
|
|
|
1186
1311
|
continue;
|
|
1187
1312
|
}
|
|
1188
1313
|
for (const entry of entries) {
|
|
1189
|
-
const full =
|
|
1314
|
+
const full = join9(dir, entry.name);
|
|
1190
1315
|
if (entry.isDirectory()) {
|
|
1191
1316
|
if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(full);
|
|
1192
1317
|
continue;
|
|
1193
1318
|
}
|
|
1194
|
-
if (wanted.has(extname(entry.name))) found.push(
|
|
1319
|
+
if (wanted.has(extname(entry.name))) found.push(relative3(cwd, full));
|
|
1195
1320
|
}
|
|
1196
1321
|
}
|
|
1197
1322
|
return found;
|
|
@@ -1209,8 +1334,8 @@ var WORKSPACE_ROOT_MARKER = "nx.json";
|
|
|
1209
1334
|
var DEFAULT_MAX_DIAGNOSTICS = 100;
|
|
1210
1335
|
|
|
1211
1336
|
// src/core/workspace-prep.ts
|
|
1212
|
-
import { existsSync as
|
|
1213
|
-
import { dirname as dirname3, join as
|
|
1337
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync } from "fs";
|
|
1338
|
+
import { dirname as dirname3, join as join10, relative as relative4 } from "path";
|
|
1214
1339
|
var OVERRIDE_KEY = "i18next>typescript";
|
|
1215
1340
|
var NATIVE_TS_ALIAS = "@typescript/native";
|
|
1216
1341
|
var WORKSPACE_YAML = "pnpm-workspace.yaml";
|
|
@@ -1219,7 +1344,7 @@ var LIST_ITEM = /^(\s*)-\s+(.*?)\s*$/;
|
|
|
1219
1344
|
function findWorkspaceRoot(startDir) {
|
|
1220
1345
|
let dir = startDir;
|
|
1221
1346
|
for (; ; ) {
|
|
1222
|
-
if (
|
|
1347
|
+
if (existsSync9(join10(dir, WORKSPACE_ROOT_MARKER))) return dir;
|
|
1223
1348
|
const parent = dirname3(dir);
|
|
1224
1349
|
if (parent === dir) return void 0;
|
|
1225
1350
|
dir = parent;
|
|
@@ -1232,9 +1357,9 @@ function declaredNativeTs(pkg) {
|
|
|
1232
1357
|
return version || void 0;
|
|
1233
1358
|
}
|
|
1234
1359
|
function ensureI18nextSingleton(root, dryRun) {
|
|
1235
|
-
const pkgPath =
|
|
1236
|
-
if (!
|
|
1237
|
-
const pkg = JSON.parse(
|
|
1360
|
+
const pkgPath = join10(root, "package.json");
|
|
1361
|
+
if (!existsSync9(pkgPath)) return void 0;
|
|
1362
|
+
const pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
|
|
1238
1363
|
const want = declaredNativeTs(pkg);
|
|
1239
1364
|
if (!want) return void 0;
|
|
1240
1365
|
const have = pkg.pnpm?.overrides?.[OVERRIDE_KEY];
|
|
@@ -1247,10 +1372,10 @@ function ensureI18nextSingleton(root, dryRun) {
|
|
|
1247
1372
|
return `pinned ${OVERRIDE_KEY} to ${want} in package.json (i18next singleton)`;
|
|
1248
1373
|
}
|
|
1249
1374
|
function ensureReleaseAgeAllowList(root, dryRun) {
|
|
1250
|
-
const yamlPath =
|
|
1251
|
-
if (!
|
|
1375
|
+
const yamlPath = join10(root, WORKSPACE_YAML);
|
|
1376
|
+
if (!existsSync9(yamlPath)) return void 0;
|
|
1252
1377
|
const own = readOwnPackage().name;
|
|
1253
|
-
const lines =
|
|
1378
|
+
const lines = readFileSync7(yamlPath, "utf8").split("\n");
|
|
1254
1379
|
const keyIdx = lines.findIndex((line) => line.replace(/\s+$/, "") === `${RELEASE_AGE_KEY}:`);
|
|
1255
1380
|
if (keyIdx === -1) return void 0;
|
|
1256
1381
|
let lastItemIdx = keyIdx;
|
|
@@ -1283,13 +1408,13 @@ var ROOT_PRETTIER_CONFIGS = [
|
|
|
1283
1408
|
"prettier.config.mjs"
|
|
1284
1409
|
];
|
|
1285
1410
|
function ensureFormatterExclusion(root, moduleDir, dryRun) {
|
|
1286
|
-
const rel =
|
|
1411
|
+
const rel = relative4(root, moduleDir).replaceAll("\\", "/");
|
|
1287
1412
|
if (rel === "" || rel.startsWith("..")) return void 0;
|
|
1288
|
-
const ignorePath =
|
|
1289
|
-
const hasPrettier =
|
|
1413
|
+
const ignorePath = join10(root, PRETTIER_IGNORE);
|
|
1414
|
+
const hasPrettier = existsSync9(ignorePath) || ROOT_PRETTIER_CONFIGS.some((name) => existsSync9(join10(root, name)));
|
|
1290
1415
|
if (!hasPrettier) return void 0;
|
|
1291
1416
|
const pattern = `/${rel}/`;
|
|
1292
|
-
const existing =
|
|
1417
|
+
const existing = existsSync9(ignorePath) ? readFileSync7(ignorePath, "utf8") : "";
|
|
1293
1418
|
const lines = existing.split("\n");
|
|
1294
1419
|
if (lines.some((line) => line.trim().replace(/\/$/, "") === pattern.replace(/\/$/, ""))) {
|
|
1295
1420
|
return void 0;
|
|
@@ -1325,10 +1450,10 @@ function ensureWorkspacePrep(opts) {
|
|
|
1325
1450
|
function inspectWorkspacePrep(root) {
|
|
1326
1451
|
const entries = [];
|
|
1327
1452
|
let pkg = {};
|
|
1328
|
-
const pkgPath =
|
|
1329
|
-
if (
|
|
1453
|
+
const pkgPath = join10(root, "package.json");
|
|
1454
|
+
if (existsSync9(pkgPath)) {
|
|
1330
1455
|
try {
|
|
1331
|
-
pkg = JSON.parse(
|
|
1456
|
+
pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
|
|
1332
1457
|
} catch {
|
|
1333
1458
|
pkg = {};
|
|
1334
1459
|
}
|
|
@@ -1342,9 +1467,9 @@ function inspectWorkspacePrep(root) {
|
|
|
1342
1467
|
});
|
|
1343
1468
|
}
|
|
1344
1469
|
const own = readOwnPackage().name;
|
|
1345
|
-
const yamlPath =
|
|
1346
|
-
if (
|
|
1347
|
-
const yaml =
|
|
1470
|
+
const yamlPath = join10(root, WORKSPACE_YAML);
|
|
1471
|
+
if (existsSync9(yamlPath)) {
|
|
1472
|
+
const yaml = readFileSync7(yamlPath, "utf8");
|
|
1348
1473
|
const listed = new RegExp(`^\\s*-\\s*['"]?${own.replace("/", "\\/")}['"]?\\s*$`, "m").test(yaml);
|
|
1349
1474
|
if (listed) {
|
|
1350
1475
|
const gated = new RegExp(`^\\s*minimumReleaseAge\\s*:`, "m").test(yaml);
|
|
@@ -1431,8 +1556,8 @@ function writesWhenRewritten(name, command) {
|
|
|
1431
1556
|
var CHECK_SCRIPT_NAMES = /* @__PURE__ */ new Set(["lint", "format", "check", "test", "typecheck", "verify"]);
|
|
1432
1557
|
|
|
1433
1558
|
// src/roles/format/inherited-ignores.ts
|
|
1434
|
-
import { existsSync as
|
|
1435
|
-
import { join as
|
|
1559
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
1560
|
+
import { join as join11 } from "path";
|
|
1436
1561
|
var ROOT_IGNORE_FILE = ".prettierignore";
|
|
1437
1562
|
function isPattern(line) {
|
|
1438
1563
|
const trimmed = line.trim();
|
|
@@ -1447,11 +1572,11 @@ function toModulePattern(pattern) {
|
|
|
1447
1572
|
}
|
|
1448
1573
|
function inheritedIgnorePatterns(workspaceRoot) {
|
|
1449
1574
|
if (!workspaceRoot) return [];
|
|
1450
|
-
const path =
|
|
1451
|
-
if (!
|
|
1575
|
+
const path = join11(workspaceRoot, ROOT_IGNORE_FILE);
|
|
1576
|
+
if (!existsSync10(path)) return [];
|
|
1452
1577
|
let contents;
|
|
1453
1578
|
try {
|
|
1454
|
-
contents =
|
|
1579
|
+
contents = readFileSync8(path, "utf8");
|
|
1455
1580
|
} catch {
|
|
1456
1581
|
return [];
|
|
1457
1582
|
}
|
|
@@ -1538,13 +1663,13 @@ function formatPresetFor(preset) {
|
|
|
1538
1663
|
}
|
|
1539
1664
|
|
|
1540
1665
|
// src/roles/format/prettier-config.ts
|
|
1541
|
-
import { existsSync as
|
|
1542
|
-
import { join as
|
|
1666
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
1667
|
+
import { join as join13 } from "path";
|
|
1543
1668
|
|
|
1544
1669
|
// src/roles/format/resolve-oxfmt.ts
|
|
1545
|
-
import { readFileSync as
|
|
1670
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
1546
1671
|
import { createRequire as createRequire2 } from "module";
|
|
1547
|
-
import { dirname as dirname4, join as
|
|
1672
|
+
import { dirname as dirname4, join as join12 } from "path";
|
|
1548
1673
|
function resolveOxfmt(cwd) {
|
|
1549
1674
|
return resolveBin(cwd, "oxfmt") ?? binFromOwnInstall("oxfmt", "oxfmt");
|
|
1550
1675
|
}
|
|
@@ -1573,8 +1698,8 @@ function configSchema() {
|
|
|
1573
1698
|
function readConfigSchema() {
|
|
1574
1699
|
try {
|
|
1575
1700
|
const manifest = createRequire2(import.meta.url).resolve("oxfmt/package.json");
|
|
1576
|
-
const schemaPath =
|
|
1577
|
-
return JSON.parse(
|
|
1701
|
+
const schemaPath = join12(dirname4(manifest), "configuration_schema.json");
|
|
1702
|
+
return JSON.parse(readFileSync9(schemaPath, "utf8"));
|
|
1578
1703
|
} catch {
|
|
1579
1704
|
return void 0;
|
|
1580
1705
|
}
|
|
@@ -1605,14 +1730,14 @@ function toOxfmtOverrides(value) {
|
|
|
1605
1730
|
return { overrides, unresolved };
|
|
1606
1731
|
}
|
|
1607
1732
|
function readPrettierSettings(cwd) {
|
|
1608
|
-
const file = PRETTIER_CONFIG_FILES.find((name) =>
|
|
1733
|
+
const file = PRETTIER_CONFIG_FILES.find((name) => existsSync11(join13(cwd, name)));
|
|
1609
1734
|
if (!file) return { options: {}, unresolved: [] };
|
|
1610
1735
|
if (/\.(js|cjs|mjs)$/.test(file)) {
|
|
1611
1736
|
return { options: {}, file, unresolved: [`${file} is JavaScript, so it was not executed`] };
|
|
1612
1737
|
}
|
|
1613
1738
|
let parsed;
|
|
1614
1739
|
try {
|
|
1615
|
-
parsed = parseJsonc(
|
|
1740
|
+
parsed = parseJsonc(readFileSync10(join13(cwd, file), "utf8"), file);
|
|
1616
1741
|
} catch {
|
|
1617
1742
|
return { options: {}, file, unresolved: [`${file} could not be parsed`] };
|
|
1618
1743
|
}
|
|
@@ -1642,8 +1767,8 @@ function readPrettierSettings(cwd) {
|
|
|
1642
1767
|
}
|
|
1643
1768
|
|
|
1644
1769
|
// src/roles/format/read-adoption.ts
|
|
1645
|
-
import { existsSync as
|
|
1646
|
-
import { join as
|
|
1770
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
|
|
1771
|
+
import { join as join14 } from "path";
|
|
1647
1772
|
var NOT_ADOPTED2 = (configFile, unreadable = null) => ({
|
|
1648
1773
|
configFile,
|
|
1649
1774
|
preset: null,
|
|
@@ -1659,11 +1784,11 @@ function sameValue(a, b) {
|
|
|
1659
1784
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
1660
1785
|
}
|
|
1661
1786
|
function readFormatAdoption(cwd) {
|
|
1662
|
-
const path =
|
|
1663
|
-
if (!
|
|
1787
|
+
const path = join14(cwd, FORMAT_CONFIG_FILE);
|
|
1788
|
+
if (!existsSync12(path)) return NOT_ADOPTED2(null);
|
|
1664
1789
|
let parsed;
|
|
1665
1790
|
try {
|
|
1666
|
-
parsed = parseJsonc(
|
|
1791
|
+
parsed = parseJsonc(readFileSync11(path, "utf8"), FORMAT_CONFIG_FILE);
|
|
1667
1792
|
} catch (error) {
|
|
1668
1793
|
const reason = error instanceof Error ? error.message : String(error);
|
|
1669
1794
|
return NOT_ADOPTED2(FORMAT_CONFIG_FILE, `${FORMAT_CONFIG_FILE} could not be parsed (${reason})`);
|
|
@@ -1788,7 +1913,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
1788
1913
|
manifestOperation(context.cwd, this.formatScripts(context.cwd))
|
|
1789
1914
|
];
|
|
1790
1915
|
const prettierConfigs = PRETTIER_CONFIG_FILES.filter(
|
|
1791
|
-
(name) =>
|
|
1916
|
+
(name) => existsSync13(join15(context.cwd, name))
|
|
1792
1917
|
);
|
|
1793
1918
|
for (const name of prettierConfigs) operations.push({ kind: "delete", path: name });
|
|
1794
1919
|
const removableDeps = this.modulePrettierDependencies(context.cwd);
|
|
@@ -2028,7 +2153,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
2028
2153
|
modulePrettierDependencies(cwd) {
|
|
2029
2154
|
const isPrettierPackage = (name) => name === "prettier" || name.startsWith("prettier-plugin-") || name.startsWith("@prettier/");
|
|
2030
2155
|
try {
|
|
2031
|
-
const manifest = JSON.parse(
|
|
2156
|
+
const manifest = JSON.parse(readFileSync12(join15(cwd, "package.json"), "utf8"));
|
|
2032
2157
|
return Object.keys(manifest.devDependencies ?? {}).filter(isPrettierPackage).map((name) => ["devDependencies", name]);
|
|
2033
2158
|
} catch {
|
|
2034
2159
|
return [];
|
|
@@ -2110,8 +2235,8 @@ function registerFormat() {
|
|
|
2110
2235
|
|
|
2111
2236
|
// src/roles/lint/adapters/oxlint/oxlint.adapter.ts
|
|
2112
2237
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
2113
|
-
import { existsSync as
|
|
2114
|
-
import { join as
|
|
2238
|
+
import { existsSync as existsSync21, readFileSync as readFileSync20, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
2239
|
+
import { join as join25 } from "path";
|
|
2115
2240
|
|
|
2116
2241
|
// src/core/config/deferred-rules.ts
|
|
2117
2242
|
function deferredRuleNames(rules) {
|
|
@@ -2120,7 +2245,7 @@ function deferredRuleNames(rules) {
|
|
|
2120
2245
|
|
|
2121
2246
|
// src/core/fix-report.ts
|
|
2122
2247
|
import { statSync } from "fs";
|
|
2123
|
-
import { join as
|
|
2248
|
+
import { join as join16 } from "path";
|
|
2124
2249
|
var CONFIG_REFUSED = /failed to parse .*config|invalid config file/i;
|
|
2125
2250
|
function readFailure(output) {
|
|
2126
2251
|
const lines = output.split("\n").map((line2) => line2.trim());
|
|
@@ -2140,7 +2265,7 @@ function fingerprint(path) {
|
|
|
2140
2265
|
function snapshotFiles(cwd, extensions) {
|
|
2141
2266
|
const snapshot = /* @__PURE__ */ new Map();
|
|
2142
2267
|
for (const file of listSourceFiles(cwd, extensions)) {
|
|
2143
|
-
const mark = fingerprint(
|
|
2268
|
+
const mark = fingerprint(join16(cwd, file));
|
|
2144
2269
|
if (mark !== void 0) snapshot.set(file, mark);
|
|
2145
2270
|
}
|
|
2146
2271
|
return snapshot;
|
|
@@ -2148,7 +2273,7 @@ function snapshotFiles(cwd, extensions) {
|
|
|
2148
2273
|
function changedSince(cwd, before, extensions) {
|
|
2149
2274
|
const changed = [];
|
|
2150
2275
|
for (const file of listSourceFiles(cwd, extensions)) {
|
|
2151
|
-
const now = fingerprint(
|
|
2276
|
+
const now = fingerprint(join16(cwd, file));
|
|
2152
2277
|
if (now === void 0) continue;
|
|
2153
2278
|
if (before.get(file) !== now) changed.push(file);
|
|
2154
2279
|
}
|
|
@@ -2167,8 +2292,8 @@ function describeFixOutcome(outcome, toolLabel) {
|
|
|
2167
2292
|
}
|
|
2168
2293
|
|
|
2169
2294
|
// src/roles/lint/module-baseline.ts
|
|
2170
|
-
import { existsSync as
|
|
2171
|
-
import { join as
|
|
2295
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13 } from "fs";
|
|
2296
|
+
import { join as join17 } from "path";
|
|
2172
2297
|
var LINT_BASELINE_FILE = ".oxlintrc.baseline.json";
|
|
2173
2298
|
var LINT_MEASURE_FILE = ".oxlintrc.measure.json";
|
|
2174
2299
|
var LINT_BASELINE_SPECIFIER = `./${LINT_BASELINE_FILE}`;
|
|
@@ -2212,11 +2337,11 @@ function describeHolds(holds) {
|
|
|
2212
2337
|
return `held ${holds.length} rule(s) at \`warn\` for this module, covering ${total} violation(s) that were already there: ${listed}${rest}. They are written to ${LINT_BASELINE_FILE}, they still report, and they return to \`error\` once fixed and re-initialized`;
|
|
2213
2338
|
}
|
|
2214
2339
|
function heldRules(cwd) {
|
|
2215
|
-
const path =
|
|
2216
|
-
if (!
|
|
2340
|
+
const path = join17(cwd, LINT_BASELINE_FILE);
|
|
2341
|
+
if (!existsSync14(path)) return [];
|
|
2217
2342
|
try {
|
|
2218
2343
|
const parsed = parseJsonc(
|
|
2219
|
-
|
|
2344
|
+
readFileSync13(path, "utf8"),
|
|
2220
2345
|
LINT_BASELINE_FILE
|
|
2221
2346
|
);
|
|
2222
2347
|
return Object.keys(parsed.rules ?? {});
|
|
@@ -4039,14 +4164,14 @@ function downgradedRulesFor(preset) {
|
|
|
4039
4164
|
}
|
|
4040
4165
|
|
|
4041
4166
|
// src/roles/lint/extra-layers.ts
|
|
4042
|
-
import { existsSync as
|
|
4043
|
-
import { isAbsolute as isAbsolute2, join as
|
|
4167
|
+
import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
|
|
4168
|
+
import { isAbsolute as isAbsolute2, join as join18, resolve as resolve3 } from "path";
|
|
4044
4169
|
function ruleCount(cwd, specifier) {
|
|
4045
4170
|
const path = isAbsolute2(specifier) ? specifier : resolve3(cwd, specifier);
|
|
4046
|
-
if (!
|
|
4171
|
+
if (!existsSync15(path)) return void 0;
|
|
4047
4172
|
try {
|
|
4048
4173
|
const parsed = parseJsonc(
|
|
4049
|
-
|
|
4174
|
+
readFileSync14(path, "utf8"),
|
|
4050
4175
|
specifier
|
|
4051
4176
|
);
|
|
4052
4177
|
return Object.keys(parsed.rules ?? {}).length;
|
|
@@ -4066,7 +4191,7 @@ function extraLayers(cwd, extendsList) {
|
|
|
4066
4191
|
function committedExtendsList(cwd, configFile) {
|
|
4067
4192
|
try {
|
|
4068
4193
|
const parsed = parseJsonc(
|
|
4069
|
-
|
|
4194
|
+
readFileSync14(join18(cwd, configFile), "utf8"),
|
|
4070
4195
|
configFile
|
|
4071
4196
|
);
|
|
4072
4197
|
return Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : [];
|
|
@@ -4125,8 +4250,8 @@ function errorCountsByConfigRule(stdout) {
|
|
|
4125
4250
|
}
|
|
4126
4251
|
|
|
4127
4252
|
// src/core/config/read-adoption.ts
|
|
4128
|
-
import { existsSync as
|
|
4129
|
-
import { join as
|
|
4253
|
+
import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
|
|
4254
|
+
import { join as join20 } from "path";
|
|
4130
4255
|
|
|
4131
4256
|
// src/core/config/owned-keys.ts
|
|
4132
4257
|
function presetOwnedKeys(config, permitted, presetSets) {
|
|
@@ -4141,12 +4266,12 @@ function localOnlyKeys(config, permitted, presetSets) {
|
|
|
4141
4266
|
}
|
|
4142
4267
|
|
|
4143
4268
|
// src/core/config/resolve-config-target.ts
|
|
4144
|
-
import { existsSync as
|
|
4145
|
-
import { join as
|
|
4269
|
+
import { existsSync as existsSync16, readFileSync as readFileSync15 } from "fs";
|
|
4270
|
+
import { join as join19 } from "path";
|
|
4146
4271
|
function readExtends(absolutePath) {
|
|
4147
4272
|
let parsed;
|
|
4148
4273
|
try {
|
|
4149
|
-
parsed = parseJsonc(
|
|
4274
|
+
parsed = parseJsonc(readFileSync15(absolutePath, "utf8"), absolutePath);
|
|
4150
4275
|
} catch {
|
|
4151
4276
|
return [];
|
|
4152
4277
|
}
|
|
@@ -4160,8 +4285,8 @@ function resolveConfigTarget(moduleDir, { candidates, markers, fallback }) {
|
|
|
4160
4285
|
let existing;
|
|
4161
4286
|
let existingExtendsSomething = false;
|
|
4162
4287
|
for (const candidate of candidates) {
|
|
4163
|
-
const absolutePath =
|
|
4164
|
-
if (!
|
|
4288
|
+
const absolutePath = join19(moduleDir, candidate);
|
|
4289
|
+
if (!existsSync16(absolutePath)) continue;
|
|
4165
4290
|
const chain = readExtends(absolutePath);
|
|
4166
4291
|
if (existing === void 0) {
|
|
4167
4292
|
existing = candidate;
|
|
@@ -4194,12 +4319,12 @@ var NOT_ADOPTED3 = (configFile, unreadable = null) => ({
|
|
|
4194
4319
|
});
|
|
4195
4320
|
function readAdoption(cwd, options) {
|
|
4196
4321
|
const target = resolveConfigTarget(cwd, options);
|
|
4197
|
-
if (target.reason === "none" || !
|
|
4322
|
+
if (target.reason === "none" || !existsSync17(join20(cwd, target.path))) {
|
|
4198
4323
|
return NOT_ADOPTED3(target.reason === "none" ? null : target.path);
|
|
4199
4324
|
}
|
|
4200
4325
|
let parsed;
|
|
4201
4326
|
try {
|
|
4202
|
-
parsed = parseJsonc(
|
|
4327
|
+
parsed = parseJsonc(readFileSync16(join20(cwd, target.path), "utf8"), target.path);
|
|
4203
4328
|
} catch (error) {
|
|
4204
4329
|
const reason = error instanceof Error ? error.message : String(error);
|
|
4205
4330
|
return NOT_ADOPTED3(target.path, `${target.path} could not be parsed (${reason})`);
|
|
@@ -4233,9 +4358,9 @@ function readLintAdoption(cwd) {
|
|
|
4233
4358
|
}
|
|
4234
4359
|
|
|
4235
4360
|
// src/roles/lint/resolve-oxlint.ts
|
|
4236
|
-
import { existsSync as
|
|
4361
|
+
import { existsSync as existsSync18 } from "fs";
|
|
4237
4362
|
import { createRequire as createRequire3 } from "module";
|
|
4238
|
-
import { delimiter as delimiter2, dirname as dirname5, join as
|
|
4363
|
+
import { delimiter as delimiter2, dirname as dirname5, join as join21 } from "path";
|
|
4239
4364
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4240
4365
|
var PACKAGE_OF = {
|
|
4241
4366
|
oxlint: "oxlint",
|
|
@@ -4260,30 +4385,30 @@ function tsgolintShim(cwd) {
|
|
|
4260
4385
|
for (const owner of ["oxlint-tsgolint", "oxlint"]) {
|
|
4261
4386
|
try {
|
|
4262
4387
|
const packageDir = dirname5(require3.resolve(`${owner}/package.json`));
|
|
4263
|
-
candidates.push(
|
|
4264
|
-
candidates.push(
|
|
4388
|
+
candidates.push(join21(packageDir, "node_modules", ".bin", "tsgolint"));
|
|
4389
|
+
candidates.push(join21(packageDir, "..", ".bin", "tsgolint"));
|
|
4265
4390
|
} catch {
|
|
4266
4391
|
}
|
|
4267
4392
|
}
|
|
4268
4393
|
try {
|
|
4269
4394
|
const ownRoot = dirname5(require3.resolve("@hublo/sentinel/package.json"));
|
|
4270
|
-
candidates.push(
|
|
4395
|
+
candidates.push(join21(ownRoot, "node_modules", ".bin", "tsgolint"));
|
|
4271
4396
|
} catch {
|
|
4272
4397
|
candidates.push(resolveBin(dirname5(fileURLToPath2(import.meta.url)), "tsgolint") ?? "");
|
|
4273
4398
|
}
|
|
4274
|
-
return candidates.find((candidate) => candidate !== "" &&
|
|
4399
|
+
return candidates.find((candidate) => candidate !== "" && existsSync18(candidate));
|
|
4275
4400
|
}
|
|
4276
4401
|
function oxlintSearchPath(cwd) {
|
|
4277
4402
|
return binSearchPath(cwd);
|
|
4278
4403
|
}
|
|
4279
4404
|
|
|
4280
4405
|
// src/roles/lint/adapters/oxlint/plan.ts
|
|
4281
|
-
import { existsSync as
|
|
4282
|
-
import { join as
|
|
4406
|
+
import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
|
|
4407
|
+
import { join as join24 } from "path";
|
|
4283
4408
|
|
|
4284
4409
|
// src/roles/lint/eslint-ignores.ts
|
|
4285
|
-
import { existsSync as
|
|
4286
|
-
import { join as
|
|
4410
|
+
import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
|
|
4411
|
+
import { join as join22 } from "path";
|
|
4287
4412
|
import { parseSync as parseSync2 } from "oxc-parser";
|
|
4288
4413
|
var OPAQUE_SOURCE = /\b(includeIgnoreFile)\s*\([^)]*\)/g;
|
|
4289
4414
|
function toOxlintPattern(pattern) {
|
|
@@ -4295,11 +4420,11 @@ function readRootEslintIgnores(root) {
|
|
|
4295
4420
|
return { patterns: patterns.filter((pattern) => pattern.startsWith("**/")), unresolved };
|
|
4296
4421
|
}
|
|
4297
4422
|
function readEslintIgnores(cwd) {
|
|
4298
|
-
const config = ESLINT_CONFIG_FILES.map((name) =>
|
|
4423
|
+
const config = ESLINT_CONFIG_FILES.map((name) => join22(cwd, name)).find((path) => existsSync19(path));
|
|
4299
4424
|
if (!config) return { patterns: [], unresolved: [] };
|
|
4300
4425
|
let source;
|
|
4301
4426
|
try {
|
|
4302
|
-
source =
|
|
4427
|
+
source = readFileSync17(config, "utf8");
|
|
4303
4428
|
} catch {
|
|
4304
4429
|
return { patterns: [], unresolved: [] };
|
|
4305
4430
|
}
|
|
@@ -4400,8 +4525,8 @@ function lintPresetFor(preset) {
|
|
|
4400
4525
|
}
|
|
4401
4526
|
|
|
4402
4527
|
// src/roles/lint/rename-suppressions.ts
|
|
4403
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
4404
|
-
import { join as
|
|
4528
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync18, statSync as statSync2 } from "fs";
|
|
4529
|
+
import { join as join23, relative as relative5 } from "path";
|
|
4405
4530
|
var SOURCE_EXTENSIONS = [
|
|
4406
4531
|
".ts",
|
|
4407
4532
|
".tsx",
|
|
@@ -4448,7 +4573,7 @@ function* sourceFiles(dir) {
|
|
|
4448
4573
|
return;
|
|
4449
4574
|
}
|
|
4450
4575
|
for (const entry of entries) {
|
|
4451
|
-
const full =
|
|
4576
|
+
const full = join23(dir, entry);
|
|
4452
4577
|
let isDirectory;
|
|
4453
4578
|
try {
|
|
4454
4579
|
isDirectory = statSync2(full).isDirectory();
|
|
@@ -4468,7 +4593,7 @@ function findSuppressionRenames(cwd, renames) {
|
|
|
4468
4593
|
for (const file of sourceFiles(cwd)) {
|
|
4469
4594
|
let content;
|
|
4470
4595
|
try {
|
|
4471
|
-
content =
|
|
4596
|
+
content = readFileSync18(file, "utf8");
|
|
4472
4597
|
} catch {
|
|
4473
4598
|
continue;
|
|
4474
4599
|
}
|
|
@@ -4492,7 +4617,7 @@ function findSuppressionRenames(cwd, renames) {
|
|
|
4492
4617
|
}
|
|
4493
4618
|
if (hits.length === 0) return;
|
|
4494
4619
|
found.push({
|
|
4495
|
-
file:
|
|
4620
|
+
file: relative5(cwd, file),
|
|
4496
4621
|
line: index + 1,
|
|
4497
4622
|
from: line,
|
|
4498
4623
|
to: line.replace(rules, renamed.join(", ")),
|
|
@@ -4596,7 +4721,7 @@ function plan2(context) {
|
|
|
4596
4721
|
keys: removableDeps
|
|
4597
4722
|
});
|
|
4598
4723
|
}
|
|
4599
|
-
const eslintConfigs = ESLINT_CONFIG_FILES.filter((name) =>
|
|
4724
|
+
const eslintConfigs = ESLINT_CONFIG_FILES.filter((name) => existsSync20(join24(context.cwd, name)));
|
|
4600
4725
|
for (const name of eslintConfigs) operations.push({ kind: "delete", path: name });
|
|
4601
4726
|
operations.push(
|
|
4602
4727
|
...nxTargetOperations({
|
|
@@ -4694,7 +4819,7 @@ function lintScripts(cwd) {
|
|
|
4694
4819
|
function committedExtends(cwd) {
|
|
4695
4820
|
try {
|
|
4696
4821
|
const parsed = parseJsonc(
|
|
4697
|
-
|
|
4822
|
+
readFileSync19(join24(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
4698
4823
|
LINT_CONFIG_FILE
|
|
4699
4824
|
);
|
|
4700
4825
|
return Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : [];
|
|
@@ -4705,7 +4830,7 @@ function committedExtends(cwd) {
|
|
|
4705
4830
|
function committedIgnorePatterns(cwd) {
|
|
4706
4831
|
try {
|
|
4707
4832
|
const parsed = parseJsonc(
|
|
4708
|
-
|
|
4833
|
+
readFileSync19(join24(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
4709
4834
|
LINT_CONFIG_FILE
|
|
4710
4835
|
);
|
|
4711
4836
|
return Array.isArray(parsed.ignorePatterns) ? parsed.ignorePatterns.filter((entry) => typeof entry === "string") : [];
|
|
@@ -4717,7 +4842,7 @@ function moduleEslintDependencies(cwd) {
|
|
|
4717
4842
|
const isEslintPackage = (name) => name === "eslint" || name === "@types/eslint" || name === "typescript-eslint" || name.startsWith("@typescript-eslint/") || name.startsWith("eslint-plugin-") || name.startsWith("eslint-config-") || name.startsWith("@eslint/");
|
|
4718
4843
|
let manifest;
|
|
4719
4844
|
try {
|
|
4720
|
-
manifest = JSON.parse(
|
|
4845
|
+
manifest = JSON.parse(readFileSync19(join24(cwd, "package.json"), "utf8"));
|
|
4721
4846
|
} catch {
|
|
4722
4847
|
return [];
|
|
4723
4848
|
}
|
|
@@ -4851,20 +4976,20 @@ ${result.stderr ?? ""}`);
|
|
|
4851
4976
|
* build the developer can see, rather than a silent half-adoption they cannot.
|
|
4852
4977
|
*/
|
|
4853
4978
|
writeModuleBaseline(ctx, oxlint, env) {
|
|
4854
|
-
const configPath =
|
|
4855
|
-
const baselinePath =
|
|
4856
|
-
if (!
|
|
4979
|
+
const configPath = join25(ctx.cwd, LINT_CONFIG_FILE);
|
|
4980
|
+
const baselinePath = join25(ctx.cwd, LINT_BASELINE_FILE);
|
|
4981
|
+
if (!existsSync21(configPath)) return;
|
|
4857
4982
|
let config;
|
|
4858
4983
|
try {
|
|
4859
4984
|
config = parseJsonc(
|
|
4860
|
-
|
|
4985
|
+
readFileSync20(configPath, "utf8"),
|
|
4861
4986
|
LINT_CONFIG_FILE
|
|
4862
4987
|
);
|
|
4863
4988
|
} catch {
|
|
4864
4989
|
return;
|
|
4865
4990
|
}
|
|
4866
4991
|
const current = Array.isArray(config.extends) ? config.extends : [];
|
|
4867
|
-
const measurePath =
|
|
4992
|
+
const measurePath = join25(ctx.cwd, LINT_MEASURE_FILE);
|
|
4868
4993
|
let measured;
|
|
4869
4994
|
try {
|
|
4870
4995
|
writeFileSync2(
|
|
@@ -4912,7 +5037,7 @@ ${result.stderr ?? ""}`);
|
|
|
4912
5037
|
}
|
|
4913
5038
|
}
|
|
4914
5039
|
async run(ctx) {
|
|
4915
|
-
if (!
|
|
5040
|
+
if (!existsSync21(join25(ctx.cwd, LINT_CONFIG_FILE))) {
|
|
4916
5041
|
process.stderr.write(
|
|
4917
5042
|
`sentinel lint(oxlint): no ${LINT_CONFIG_FILE} in this module; run \`sentinel --init --lint\` to adopt.
|
|
4918
5043
|
`
|
|
@@ -5060,7 +5185,7 @@ ${result.stderr ?? ""}`);
|
|
|
5060
5185
|
let stub;
|
|
5061
5186
|
try {
|
|
5062
5187
|
stub = parseJsonc(
|
|
5063
|
-
|
|
5188
|
+
readFileSync20(join25(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
5064
5189
|
LINT_CONFIG_FILE
|
|
5065
5190
|
);
|
|
5066
5191
|
} catch {
|
|
@@ -5070,7 +5195,7 @@ ${result.stderr ?? ""}`);
|
|
|
5070
5195
|
for (const entry of stub.extends ?? []) {
|
|
5071
5196
|
try {
|
|
5072
5197
|
const preset = parseJsonc(
|
|
5073
|
-
|
|
5198
|
+
readFileSync20(join25(cwd, entry), "utf8"),
|
|
5074
5199
|
entry
|
|
5075
5200
|
);
|
|
5076
5201
|
for (const rule of Object.keys(preset.rules ?? {})) names.add(rule);
|
|
@@ -5140,14 +5265,14 @@ ${result.stderr ?? ""}`);
|
|
|
5140
5265
|
let parsed;
|
|
5141
5266
|
try {
|
|
5142
5267
|
parsed = parseJsonc(
|
|
5143
|
-
|
|
5268
|
+
readFileSync20(join25(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
5144
5269
|
LINT_CONFIG_FILE
|
|
5145
5270
|
);
|
|
5146
5271
|
} catch {
|
|
5147
5272
|
return void 0;
|
|
5148
5273
|
}
|
|
5149
5274
|
const targets = Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : typeof parsed.extends === "string" ? [parsed.extends] : [];
|
|
5150
|
-
return targets.find((target) => !
|
|
5275
|
+
return targets.find((target) => !existsSync21(join25(cwd, target)));
|
|
5151
5276
|
}
|
|
5152
5277
|
/** Announce what is not enforced, so reduced coverage is never silent. */
|
|
5153
5278
|
announceDisabled(preset) {
|
|
@@ -5179,9 +5304,9 @@ function registerLint() {
|
|
|
5179
5304
|
|
|
5180
5305
|
// src/roles/typescript/adapters/tsc/tsc.adapter.ts
|
|
5181
5306
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
5182
|
-
import { existsSync as
|
|
5307
|
+
import { existsSync as existsSync22, readFileSync as readFileSync22 } from "fs";
|
|
5183
5308
|
import { createRequire as createRequire4 } from "module";
|
|
5184
|
-
import { join as
|
|
5309
|
+
import { join as join27 } from "path";
|
|
5185
5310
|
|
|
5186
5311
|
// src/roles/typescript/presets/nest.json
|
|
5187
5312
|
var nest_default2 = {
|
|
@@ -5362,8 +5487,8 @@ function readTsconfigAdoption(cwd) {
|
|
|
5362
5487
|
}
|
|
5363
5488
|
|
|
5364
5489
|
// src/roles/typescript/adapters/tsc/plan.ts
|
|
5365
|
-
import { readFileSync as
|
|
5366
|
-
import { join as
|
|
5490
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
5491
|
+
import { join as join26 } from "path";
|
|
5367
5492
|
|
|
5368
5493
|
// src/roles/typescript/typecheck-script.ts
|
|
5369
5494
|
var SENTINEL_TYPECHECK_COMMAND = "sentinel --run --typescript";
|
|
@@ -5456,7 +5581,7 @@ function planAdoption(context) {
|
|
|
5456
5581
|
};
|
|
5457
5582
|
}
|
|
5458
5583
|
const existing = parseJsonc(
|
|
5459
|
-
|
|
5584
|
+
readFileSync21(join26(context.cwd, target.path), "utf8"),
|
|
5460
5585
|
target.path
|
|
5461
5586
|
);
|
|
5462
5587
|
const extendsChain = composeExtends(existing.extends, preset);
|
|
@@ -5594,7 +5719,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
5594
5719
|
let chain;
|
|
5595
5720
|
try {
|
|
5596
5721
|
const parsed = parseJsonc(
|
|
5597
|
-
|
|
5722
|
+
readFileSync22(join27(cwd, target.path), "utf8"),
|
|
5598
5723
|
target.path
|
|
5599
5724
|
);
|
|
5600
5725
|
chain = parsed.extends;
|
|
@@ -5607,7 +5732,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
5607
5732
|
);
|
|
5608
5733
|
if (preset === void 0) return void 0;
|
|
5609
5734
|
try {
|
|
5610
|
-
createRequire4(
|
|
5735
|
+
createRequire4(join27(cwd, "noop.js")).resolve(preset);
|
|
5611
5736
|
return void 0;
|
|
5612
5737
|
} catch {
|
|
5613
5738
|
return preset;
|
|
@@ -5703,7 +5828,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
5703
5828
|
referencedProjects(cwd, config) {
|
|
5704
5829
|
try {
|
|
5705
5830
|
const parsed = parseJsonc(
|
|
5706
|
-
|
|
5831
|
+
readFileSync22(join27(cwd, config), "utf8"),
|
|
5707
5832
|
config
|
|
5708
5833
|
);
|
|
5709
5834
|
const referenced = (parsed.references ?? []).map((reference) => reference.path).filter((path) => typeof path === "string" && path.length > 0);
|
|
@@ -5719,7 +5844,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
5719
5844
|
* check.
|
|
5720
5845
|
*/
|
|
5721
5846
|
typecheckTarget(cwd) {
|
|
5722
|
-
if (
|
|
5847
|
+
if (existsSync22(join27(cwd, "tsconfig.json"))) return "tsconfig.json";
|
|
5723
5848
|
const target = resolveTsconfigTarget(cwd);
|
|
5724
5849
|
return target.reason === "none" ? null : target.path;
|
|
5725
5850
|
}
|
|
@@ -5923,7 +6048,7 @@ function replaceLines(current, replacements) {
|
|
|
5923
6048
|
}
|
|
5924
6049
|
|
|
5925
6050
|
// src/core/apply-plan.ts
|
|
5926
|
-
import { existsSync as
|
|
6051
|
+
import { existsSync as existsSync23, readFileSync as readFileSync23, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
5927
6052
|
import { resolve as resolve4, sep } from "path";
|
|
5928
6053
|
import { applyEdits, findNodeAtLocation, modify, parseTree } from "jsonc-parser";
|
|
5929
6054
|
|
|
@@ -5942,7 +6067,7 @@ function resolveWithinRoot(cwd, relativePath) {
|
|
|
5942
6067
|
return absolutePath;
|
|
5943
6068
|
}
|
|
5944
6069
|
function readIfExists(absolutePath) {
|
|
5945
|
-
return
|
|
6070
|
+
return existsSync23(absolutePath) ? readFileSync23(absolutePath, "utf8") : void 0;
|
|
5946
6071
|
}
|
|
5947
6072
|
function* leaves(value, prefix = []) {
|
|
5948
6073
|
for (const [key, keyValue] of Object.entries(value)) {
|
|
@@ -6060,8 +6185,8 @@ function applyPlan(cwd, plan3) {
|
|
|
6060
6185
|
}
|
|
6061
6186
|
|
|
6062
6187
|
// src/core/config/preset-evidence.ts
|
|
6063
|
-
import { existsSync as
|
|
6064
|
-
import { join as
|
|
6188
|
+
import { existsSync as existsSync24, readdirSync as readdirSync3, readFileSync as readFileSync24 } from "fs";
|
|
6189
|
+
import { join as join28 } from "path";
|
|
6065
6190
|
var PATH_SIGNALS = [
|
|
6066
6191
|
{
|
|
6067
6192
|
preset: "nest",
|
|
@@ -6075,11 +6200,11 @@ var DEPENDENCY_SIGNALS = [
|
|
|
6075
6200
|
{ preset: "nest", pattern: /^@nestjs\// }
|
|
6076
6201
|
];
|
|
6077
6202
|
function dependencyNames(cwd) {
|
|
6078
|
-
const path =
|
|
6079
|
-
if (!
|
|
6203
|
+
const path = join28(cwd, "package.json");
|
|
6204
|
+
if (!existsSync24(path)) return [];
|
|
6080
6205
|
try {
|
|
6081
6206
|
const manifest = parseJsonc(
|
|
6082
|
-
|
|
6207
|
+
readFileSync24(path, "utf8"),
|
|
6083
6208
|
path
|
|
6084
6209
|
);
|
|
6085
6210
|
return [
|
|
@@ -6102,7 +6227,7 @@ function declaresJsx(cwd) {
|
|
|
6102
6227
|
for (const name of entries) {
|
|
6103
6228
|
try {
|
|
6104
6229
|
const config = parseJsonc(
|
|
6105
|
-
|
|
6230
|
+
readFileSync24(join28(cwd, name), "utf8"),
|
|
6106
6231
|
name
|
|
6107
6232
|
);
|
|
6108
6233
|
if (config.compilerOptions?.jsx !== void 0) return true;
|
|
@@ -6266,6 +6391,7 @@ export {
|
|
|
6266
6391
|
readOwnVersion,
|
|
6267
6392
|
readProjectPackageJson,
|
|
6268
6393
|
moduleName,
|
|
6394
|
+
buildConfigFile,
|
|
6269
6395
|
VERBS,
|
|
6270
6396
|
TARGETS,
|
|
6271
6397
|
LONG_RUNNING_TARGETS,
|
|
@@ -6281,4 +6407,4 @@ export {
|
|
|
6281
6407
|
detectFramework,
|
|
6282
6408
|
dispatch
|
|
6283
6409
|
};
|
|
6284
|
-
//# sourceMappingURL=chunk-
|
|
6410
|
+
//# sourceMappingURL=chunk-6RH3LZQZ.js.map
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hublo/sentinel",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.9",
|
|
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",
|