@hublo/sentinel 1.1.6 → 1.2.0-alpha.0
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/README.md +5 -4
- package/dist/bin/sentinel.js +20 -4
- package/dist/{chunk-RGIEWANO.js → chunk-TWL6T237.js} +875 -292
- package/dist/chunk-XSCDJZDY.js +26 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/roles/build/react-app.d.ts +116 -0
- package/dist/roles/build/react-app.js +111 -0
- package/lint/nest.json +358 -0
- package/lint/node.json +52 -0
- package/lint/react-lib.json +376 -0
- package/lint/react.json +474 -0
- package/lint/svelte.json +209 -0
- package/lint/tools.json +197 -0
- package/oxlint/nest.json +2 -355
- package/oxlint/node.json +3 -50
- package/oxlint/react-lib.json +2 -373
- package/oxlint/react.json +2 -471
- package/oxlint/svelte.json +3 -207
- package/oxlint/tools.json +3 -195
- package/package.json +21 -2
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
REACT_APP_DEFAULTS,
|
|
3
|
+
isPlainObject
|
|
4
|
+
} from "./chunk-XSCDJZDY.js";
|
|
5
|
+
|
|
1
6
|
// src/core/registry.ts
|
|
2
7
|
var adapters = [];
|
|
8
|
+
var PresetUnsupportedError = class extends Error {
|
|
9
|
+
constructor(target, preset) {
|
|
10
|
+
super(`No adapter for target "${target}" handles preset "${preset}".`);
|
|
11
|
+
this.target = target;
|
|
12
|
+
this.preset = preset;
|
|
13
|
+
this.name = "PresetUnsupportedError";
|
|
14
|
+
}
|
|
15
|
+
target;
|
|
16
|
+
preset;
|
|
17
|
+
};
|
|
3
18
|
var defaultRunner = {
|
|
4
19
|
// Filled in by tool branches, e.g. lint: 'eslint', typescript: 'tsc'.
|
|
5
20
|
};
|
|
@@ -12,6 +27,14 @@ function setDefaultRunner(target, runner) {
|
|
|
12
27
|
function all() {
|
|
13
28
|
return adapters;
|
|
14
29
|
}
|
|
30
|
+
function declaredPresetFor(target, cwd) {
|
|
31
|
+
for (const adapter of adapters) {
|
|
32
|
+
if (adapter.target !== target) continue;
|
|
33
|
+
const declared = adapter.declaredPreset?.(cwd);
|
|
34
|
+
if (declared !== void 0) return declared;
|
|
35
|
+
}
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
15
38
|
function availableTargets() {
|
|
16
39
|
return [...new Set(adapters.map((a) => a.target))];
|
|
17
40
|
}
|
|
@@ -24,7 +47,7 @@ function resolve(target, preset, runner) {
|
|
|
24
47
|
}
|
|
25
48
|
const candidates = preset ? forTarget.filter((a) => a.appliesTo(preset)) : forTarget;
|
|
26
49
|
if (candidates.length === 0) {
|
|
27
|
-
throw new
|
|
50
|
+
throw new PresetUnsupportedError(target, preset);
|
|
28
51
|
}
|
|
29
52
|
const wanted = runner ?? defaultRunner[target];
|
|
30
53
|
const available = candidates.map((a) => a.runner).join(", ");
|
|
@@ -131,21 +154,79 @@ var TARGETS = [
|
|
|
131
154
|
"format",
|
|
132
155
|
"typescript",
|
|
133
156
|
"build",
|
|
157
|
+
"dev",
|
|
134
158
|
"test",
|
|
135
159
|
"static-analysis",
|
|
136
160
|
"runtime-analysis",
|
|
137
161
|
"arch"
|
|
138
162
|
];
|
|
163
|
+
var LONG_RUNNING_TARGETS = ["dev"];
|
|
164
|
+
var SWEEPABLE_TARGETS = TARGETS.filter(
|
|
165
|
+
(target) => !LONG_RUNNING_TARGETS.includes(target)
|
|
166
|
+
);
|
|
139
167
|
var PRESET_NAMES = ["react", "nest", "svelte", "node", "tools"];
|
|
140
168
|
|
|
141
|
-
// src/roles/
|
|
169
|
+
// src/roles/build/adapters/vite/vite-dev.adapter.ts
|
|
142
170
|
import { spawnSync } from "child_process";
|
|
143
|
-
|
|
144
|
-
|
|
171
|
+
|
|
172
|
+
// src/core/config/tool-args.ts
|
|
173
|
+
import { existsSync as existsSync2 } from "fs";
|
|
174
|
+
import { isAbsolute, resolve as resolve2 } from "path";
|
|
175
|
+
function splitToolArgs(cwd, toolArgs = [], { valueFlags = [] } = {}) {
|
|
176
|
+
const takesValue = new Set(valueFlags);
|
|
177
|
+
const options = [];
|
|
178
|
+
const paths = [];
|
|
179
|
+
let previousTakesValue = false;
|
|
180
|
+
for (const arg of toolArgs) {
|
|
181
|
+
const looksLikeOption = arg.startsWith("-");
|
|
182
|
+
const target = isAbsolute(arg) ? arg : resolve2(cwd, arg);
|
|
183
|
+
if (!previousTakesValue && !looksLikeOption && existsSync2(target)) paths.push(arg);
|
|
184
|
+
else options.push(arg);
|
|
185
|
+
previousTakesValue = !arg.includes("=") && takesValue.has(arg);
|
|
186
|
+
}
|
|
187
|
+
return { options, paths };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/shared/resolve-bin.ts
|
|
191
|
+
import { existsSync as existsSync3 } from "fs";
|
|
192
|
+
import { createRequire } from "module";
|
|
193
|
+
import { delimiter, dirname as dirname2, join as join2 } from "path";
|
|
194
|
+
var require2 = createRequire(import.meta.url);
|
|
195
|
+
function resolveBin(fromDir, name) {
|
|
196
|
+
let dir = fromDir;
|
|
197
|
+
for (; ; ) {
|
|
198
|
+
const candidate = join2(dir, "node_modules", ".bin", name);
|
|
199
|
+
if (existsSync3(candidate)) return candidate;
|
|
200
|
+
const parent = dirname2(dir);
|
|
201
|
+
if (parent === dir) return void 0;
|
|
202
|
+
dir = parent;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function binFromOwnInstall(packageName, binName) {
|
|
206
|
+
try {
|
|
207
|
+
const manifest = require2.resolve(`${packageName}/package.json`);
|
|
208
|
+
const bin = require2(manifest).bin;
|
|
209
|
+
const relative3 = typeof bin === "string" ? bin : bin?.[binName];
|
|
210
|
+
if (!relative3) return void 0;
|
|
211
|
+
const executable = join2(dirname2(manifest), relative3);
|
|
212
|
+
return existsSync3(executable) ? executable : void 0;
|
|
213
|
+
} catch {
|
|
214
|
+
return void 0;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function binSearchPath(cwd) {
|
|
218
|
+
return [`${cwd}${delimiter}node_modules/.bin (and parents)`, "sentinel's own install"].join(
|
|
219
|
+
" then "
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/roles/build/plan.ts
|
|
224
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
225
|
+
import { join as join7 } from "path";
|
|
145
226
|
|
|
146
227
|
// src/core/config/existing-command.ts
|
|
147
228
|
import { readFileSync as readFileSync3 } from "fs";
|
|
148
|
-
import { join as
|
|
229
|
+
import { join as join4 } from "path";
|
|
149
230
|
|
|
150
231
|
// src/shared/jsonc.ts
|
|
151
232
|
import { parse, printParseErrorCode } from "jsonc-parser";
|
|
@@ -160,11 +241,11 @@ function parseJsonc(text, source = "config") {
|
|
|
160
241
|
}
|
|
161
242
|
|
|
162
243
|
// src/core/config/manifest.ts
|
|
163
|
-
import { existsSync as
|
|
164
|
-
import { basename, join as
|
|
244
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
245
|
+
import { basename, join as join3 } from "path";
|
|
165
246
|
function moduleScripts(cwd) {
|
|
166
247
|
try {
|
|
167
|
-
const pkg = JSON.parse(readFileSync2(
|
|
248
|
+
const pkg = JSON.parse(readFileSync2(join3(cwd, "package.json"), "utf8"));
|
|
168
249
|
return pkg.scripts ?? {};
|
|
169
250
|
} catch {
|
|
170
251
|
return {};
|
|
@@ -172,7 +253,7 @@ function moduleScripts(cwd) {
|
|
|
172
253
|
}
|
|
173
254
|
function moduleName(cwd) {
|
|
174
255
|
try {
|
|
175
|
-
const pkg = JSON.parse(readFileSync2(
|
|
256
|
+
const pkg = JSON.parse(readFileSync2(join3(cwd, "package.json"), "utf8"));
|
|
176
257
|
return pkg.name;
|
|
177
258
|
} catch {
|
|
178
259
|
return void 0;
|
|
@@ -192,7 +273,7 @@ function manifestOperation(cwd, scripts) {
|
|
|
192
273
|
scripts,
|
|
193
274
|
devDependencies: { [own.name]: isSelfAdoption(cwd) ? "link:." : own.version }
|
|
194
275
|
};
|
|
195
|
-
if (
|
|
276
|
+
if (existsSync4(join3(cwd, "package.json"))) {
|
|
196
277
|
return { kind: "merge-json", path: "package.json", value };
|
|
197
278
|
}
|
|
198
279
|
return {
|
|
@@ -207,7 +288,7 @@ function nxTargetCommand(cwd, target) {
|
|
|
207
288
|
let project;
|
|
208
289
|
try {
|
|
209
290
|
project = parseJsonc(
|
|
210
|
-
readFileSync3(
|
|
291
|
+
readFileSync3(join4(cwd, "project.json"), "utf8"),
|
|
211
292
|
"project.json"
|
|
212
293
|
);
|
|
213
294
|
} catch {
|
|
@@ -237,9 +318,630 @@ function existingCommand(cwd, target) {
|
|
|
237
318
|
return fromTarget.ranInModule ? fromTarget.command : rootedForScript(fromTarget.command);
|
|
238
319
|
}
|
|
239
320
|
|
|
321
|
+
// src/core/config/nx-target.ts
|
|
322
|
+
import { existsSync as existsSync5 } from "fs";
|
|
323
|
+
import { join as join5 } from "path";
|
|
324
|
+
function nxTargetOperations(options) {
|
|
325
|
+
const { cwd, targets } = options;
|
|
326
|
+
const names = Object.keys(targets);
|
|
327
|
+
if (names.length === 0) return [];
|
|
328
|
+
const operations = [];
|
|
329
|
+
if (existsSync5(join5(cwd, "project.json"))) {
|
|
330
|
+
operations.push({
|
|
331
|
+
kind: "remove-json-keys",
|
|
332
|
+
path: "project.json",
|
|
333
|
+
keys: names.map((name) => ["targets", name])
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
operations.push({
|
|
337
|
+
kind: "merge-json",
|
|
338
|
+
path: "package.json",
|
|
339
|
+
value: { nx: { targets } }
|
|
340
|
+
});
|
|
341
|
+
return operations;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// src/core/config/tool-script.ts
|
|
345
|
+
var SEGMENT_SEPARATOR = /(\s*(?:&&|\|\||;|&|\|)\s*)/;
|
|
346
|
+
function isSeparatorAt(index) {
|
|
347
|
+
return index % 2 === 1;
|
|
348
|
+
}
|
|
349
|
+
function invokes(segment, binary) {
|
|
350
|
+
return new RegExp(String.raw`(^|[\s/])${binary}(\s|$)`).test(segment.trim());
|
|
351
|
+
}
|
|
352
|
+
function isSentinelSegment(segment, roleFlag) {
|
|
353
|
+
const runsSentinel = invokes(segment, "sentinel") || segment.includes("bin/sentinel.js");
|
|
354
|
+
return runsSentinel && new RegExp(String.raw`(^|\s)${roleFlag}(\s|$)`).test(segment);
|
|
355
|
+
}
|
|
356
|
+
function composeToolScript(existing, options) {
|
|
357
|
+
const { command } = options;
|
|
358
|
+
if (!existing || existing.trim() === "") return command;
|
|
359
|
+
const { roleFlag } = options;
|
|
360
|
+
const isReplaceable = (segment) => options.replaces(segment) || roleFlag !== void 0 && isSentinelSegment(segment, roleFlag);
|
|
361
|
+
const parts = existing.split(SEGMENT_SEPARATOR);
|
|
362
|
+
const commands = parts.filter((_, index) => !isSeparatorAt(index));
|
|
363
|
+
if (!commands.some(isReplaceable)) return existing;
|
|
364
|
+
let replacedOnce = false;
|
|
365
|
+
const rebuilt = parts.map((part, index) => {
|
|
366
|
+
if (isSeparatorAt(index) || !isReplaceable(part)) return part;
|
|
367
|
+
if (replacedOnce) return null;
|
|
368
|
+
replacedOnce = true;
|
|
369
|
+
return options.keepFix && /(^|\s)--fix(\s|$)/.test(part) ? `${command} --fix` : command;
|
|
370
|
+
});
|
|
371
|
+
const kept = [];
|
|
372
|
+
for (let index = 0; index < rebuilt.length; index += 1) {
|
|
373
|
+
const part = rebuilt[index];
|
|
374
|
+
if (part === null) {
|
|
375
|
+
if (kept.length > 0) kept.pop();
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
kept.push(part);
|
|
379
|
+
}
|
|
380
|
+
return kept.join("").trim();
|
|
381
|
+
}
|
|
382
|
+
function keepsOtherCommands(script, sentinelCommand) {
|
|
383
|
+
return script.split(SEGMENT_SEPARATOR).filter((_, index) => !isSeparatorAt(index)).some((segment) => segment.trim() !== "" && segment.trim() !== sentinelCommand);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// src/roles/build/config-policy.ts
|
|
387
|
+
var BUILD_CONFIG_FILES = [
|
|
388
|
+
"vite.config.ts",
|
|
389
|
+
"vite.config.mts",
|
|
390
|
+
"vite.config.js",
|
|
391
|
+
"vite.config.mjs"
|
|
392
|
+
];
|
|
393
|
+
var BUILD_PRESET_SPECIFIER = "@hublo/sentinel/build/react";
|
|
394
|
+
var BUILD_SCRIPT_NAME = "build";
|
|
395
|
+
var SENTINEL_BUILD_COMMAND = "sentinel --run --build";
|
|
396
|
+
var DEV_SCRIPT_NAME = "serve";
|
|
397
|
+
var SENTINEL_DEV_COMMAND = "sentinel --run --dev";
|
|
398
|
+
function buildTarget() {
|
|
399
|
+
return {
|
|
400
|
+
[BUILD_SCRIPT_NAME]: {
|
|
401
|
+
cache: true,
|
|
402
|
+
inputs: ["default", "^default", `{projectRoot}/${BUILD_CONFIG_FILES[0]}`]
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
var SENTINEL_OWNED_BUILD_PACKAGES = [
|
|
407
|
+
"vite",
|
|
408
|
+
"@vitejs/plugin-react",
|
|
409
|
+
"@tailwindcss/vite",
|
|
410
|
+
"vite-plugin-svgr",
|
|
411
|
+
"nitro"
|
|
412
|
+
];
|
|
413
|
+
|
|
414
|
+
// src/roles/build/dev-script.ts
|
|
415
|
+
var CHAIN = " -- ";
|
|
416
|
+
var VITE_TOKEN = /(^|\s|\/)vite(\s|$)/;
|
|
417
|
+
var DEV_SUBCOMMANDS = /* @__PURE__ */ new Set(["dev", "serve"]);
|
|
418
|
+
function appOptions(rest) {
|
|
419
|
+
const tokens = (rest ?? "").trim().split(/\s+/).filter(Boolean);
|
|
420
|
+
const kept = tokens.filter((token, at) => !(at === 0 && DEV_SUBCOMMANDS.has(token)));
|
|
421
|
+
return kept.join(" ");
|
|
422
|
+
}
|
|
423
|
+
function composeDevScript(existing, command) {
|
|
424
|
+
if (existing === void 0 || existing.trim() === "") return command;
|
|
425
|
+
const chunks = existing.trim().split(CHAIN);
|
|
426
|
+
const at = chunks.map((chunk) => VITE_TOKEN.test(chunk)).lastIndexOf(true);
|
|
427
|
+
if (at === -1) return existing;
|
|
428
|
+
const rest = (chunks[at] ?? "").replace(/^.*?(^|\s|\/)vite(\s|$)/, "");
|
|
429
|
+
const options = appOptions(rest);
|
|
430
|
+
chunks[at] = options === "" ? command : `${command} -- ${options}`;
|
|
431
|
+
return chunks.join(CHAIN);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// src/roles/build/read-adoption.ts
|
|
435
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
436
|
+
import { join as join6 } from "path";
|
|
437
|
+
var NOT_ADOPTED = (configFile, unreadable = null) => ({
|
|
438
|
+
configFile,
|
|
439
|
+
preset: null,
|
|
440
|
+
adopted: false,
|
|
441
|
+
conformant: false,
|
|
442
|
+
drift: [],
|
|
443
|
+
ownDeclarations: [],
|
|
444
|
+
unreadable
|
|
445
|
+
});
|
|
446
|
+
function buildConfigFile(cwd) {
|
|
447
|
+
return BUILD_CONFIG_FILES.find((name) => existsSync6(join6(cwd, name)));
|
|
448
|
+
}
|
|
449
|
+
function importsPreset(source) {
|
|
450
|
+
const specifier = BUILD_PRESET_SPECIFIER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
451
|
+
return new RegExp(`(?:from|import)\\s*\\(?\\s*['"\`]${specifier}['"\`]`).test(source);
|
|
452
|
+
}
|
|
453
|
+
var REACT_PLUGIN_SPECIFIERS = ["@vitejs/plugin-react", "@tanstack/react-start"];
|
|
454
|
+
function declaredBuildPreset(cwd) {
|
|
455
|
+
const configFile = buildConfigFile(cwd);
|
|
456
|
+
if (!configFile) return void 0;
|
|
457
|
+
try {
|
|
458
|
+
const source = readFileSync4(join6(cwd, configFile), "utf8");
|
|
459
|
+
return REACT_PLUGIN_SPECIFIERS.some((specifier) => source.includes(specifier)) ? "react" : void 0;
|
|
460
|
+
} catch {
|
|
461
|
+
return void 0;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function readBuildAdoption(cwd) {
|
|
465
|
+
const configFile = buildConfigFile(cwd);
|
|
466
|
+
if (!configFile) return NOT_ADOPTED(null);
|
|
467
|
+
let source;
|
|
468
|
+
try {
|
|
469
|
+
source = readFileSync4(join6(cwd, configFile), "utf8");
|
|
470
|
+
} catch (error) {
|
|
471
|
+
return NOT_ADOPTED(configFile, error instanceof Error ? error.message : String(error));
|
|
472
|
+
}
|
|
473
|
+
if (!importsPreset(source)) return NOT_ADOPTED(configFile);
|
|
474
|
+
const manifest = readProjectPackageJson(cwd);
|
|
475
|
+
const declared = { ...manifest.dependencies, ...manifest.devDependencies };
|
|
476
|
+
const ownDeclarations = SENTINEL_OWNED_BUILD_PACKAGES.filter((name) => name in declared).map(
|
|
477
|
+
(name) => ({ name, version: declared[name] })
|
|
478
|
+
);
|
|
479
|
+
return {
|
|
480
|
+
configFile,
|
|
481
|
+
preset: "react",
|
|
482
|
+
adopted: true,
|
|
483
|
+
conformant: ownDeclarations.length === 0,
|
|
484
|
+
drift: ownDeclarations.map(
|
|
485
|
+
({ name, version }) => `declares ${name}@${version} of its own; sentinel owns it, and two copies in one build give the plugins a different Vite than the one running them`
|
|
486
|
+
),
|
|
487
|
+
ownDeclarations,
|
|
488
|
+
unreadable: null
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// src/roles/build/plan.ts
|
|
493
|
+
function scaffold() {
|
|
494
|
+
return `import { defineConfig, reactApp } from '${BUILD_PRESET_SPECIFIER}'
|
|
495
|
+
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
|
496
|
+
import { tanstackRouter } from '@tanstack/router-plugin/vite'
|
|
497
|
+
import path from 'node:path'
|
|
498
|
+
|
|
499
|
+
/*
|
|
500
|
+
* Composition comes from sentinel: how the env is loaded, which plugins run under test and
|
|
501
|
+
* which under a real build, the order they run in. The values below are this app's own.
|
|
502
|
+
*
|
|
503
|
+
* TanStack is passed IN rather than imported by sentinel, because the app codes against it
|
|
504
|
+
* directly. \`alias\` is passed through verbatim and never read, so nothing in it can be lost.
|
|
505
|
+
* Anything sentinel does not set goes in \`overrides\`, which merges over the preset last.
|
|
506
|
+
*/
|
|
507
|
+
export default defineConfig(({ mode }) =>
|
|
508
|
+
reactApp({
|
|
509
|
+
root: __dirname,
|
|
510
|
+
mode,
|
|
511
|
+
base: '/',
|
|
512
|
+
port: 3000,
|
|
513
|
+
// Explicit, NOT port + 1: the three apps in this repo disagree, one of them goes down.
|
|
514
|
+
hmrPort: 3001,
|
|
515
|
+
router: {
|
|
516
|
+
routesDirectory: path.resolve(__dirname, 'src/routes'),
|
|
517
|
+
generatedRouteTree: path.resolve(__dirname, 'src/routeTree.gen.ts'),
|
|
518
|
+
},
|
|
519
|
+
tanstack: { start: tanstackStart, router: tanstackRouter },
|
|
520
|
+
alias: [],
|
|
521
|
+
}),
|
|
522
|
+
)
|
|
523
|
+
`;
|
|
524
|
+
}
|
|
525
|
+
function ownedBuildDependencies(cwd) {
|
|
526
|
+
const manifest = readProjectPackageJson(cwd);
|
|
527
|
+
const keys = [];
|
|
528
|
+
for (const section of ["dependencies", "devDependencies"]) {
|
|
529
|
+
const declared = manifest[section];
|
|
530
|
+
if (!declared) continue;
|
|
531
|
+
for (const name of SENTINEL_OWNED_BUILD_PACKAGES) {
|
|
532
|
+
if (name in declared) keys.push([section, name]);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return keys;
|
|
536
|
+
}
|
|
537
|
+
function invokesVite(segment) {
|
|
538
|
+
return /(^|\s|\/)vite(\s|$)/.test(segment.trim());
|
|
539
|
+
}
|
|
540
|
+
function buildScripts(cwd) {
|
|
541
|
+
const own = selfCommand(cwd, "--run --build");
|
|
542
|
+
const scripts = {
|
|
543
|
+
[BUILD_SCRIPT_NAME]: composeToolScript(existingCommand(cwd, BUILD_SCRIPT_NAME), {
|
|
544
|
+
command: own ?? SENTINEL_BUILD_COMMAND,
|
|
545
|
+
replaces: invokesVite,
|
|
546
|
+
// Only meaningful for the self case: it lets a re-init correct a sentinel invocation
|
|
547
|
+
// whose FORM is wrong, without matching another role's script.
|
|
548
|
+
roleFlag: own === void 0 ? void 0 : "--build"
|
|
549
|
+
})
|
|
550
|
+
};
|
|
551
|
+
const existingDev = existingCommand(cwd, DEV_SCRIPT_NAME);
|
|
552
|
+
if (existingDev !== void 0) {
|
|
553
|
+
scripts[DEV_SCRIPT_NAME] = composeDevScript(
|
|
554
|
+
existingDev,
|
|
555
|
+
selfCommand(cwd, "--run --dev") ?? SENTINEL_DEV_COMMAND
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
return scripts;
|
|
559
|
+
}
|
|
560
|
+
function plan(context) {
|
|
561
|
+
if (declaredBuildPreset(context.cwd) === void 0 && buildConfigFile(context.cwd) !== void 0) {
|
|
562
|
+
return {
|
|
563
|
+
operations: [],
|
|
564
|
+
skipped: `this module has a Vite config, but it does not build a React app (no @vitejs/plugin-react or @tanstack/react-start in it). The build role ships a React preset only; the two SvelteKit configs in this repo share nothing with it.`
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
const notes = [];
|
|
568
|
+
const operations = [];
|
|
569
|
+
const configFile = buildConfigFile(context.cwd);
|
|
570
|
+
if (configFile === void 0) {
|
|
571
|
+
operations.push({ kind: "write", path: BUILD_CONFIG_FILES[0], contents: scaffold() });
|
|
572
|
+
notes.push(
|
|
573
|
+
`wrote ${BUILD_CONFIG_FILES[0]} as a starting point. Fill in this app's own values (base, ports, routes); sentinel owns the composition, not the data.`
|
|
574
|
+
);
|
|
575
|
+
} else if (!readsPreset(context.cwd, configFile)) {
|
|
576
|
+
notes.push(
|
|
577
|
+
`${configFile} is this app's own, so it was left alone. To adopt: import \`reactApp\` from \`${BUILD_PRESET_SPECIFIER}\` and pass it this app's values, keeping \`alias\` and your own plugins verbatim. \`sentinel --inspect --build\` reports what the resolved config departs from and what it adds, before and after.`
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
operations.push(manifestOperation(context.cwd, buildScripts(context.cwd)));
|
|
581
|
+
operations.push(...nxTargetOperations({ cwd: context.cwd, targets: buildTarget() }));
|
|
582
|
+
const owned = ownedBuildDependencies(context.cwd);
|
|
583
|
+
if (owned.length > 0) {
|
|
584
|
+
operations.push({ kind: "remove-json-keys", path: "package.json", keys: owned });
|
|
585
|
+
notes.push(
|
|
586
|
+
`removed ${owned.map(([, name]) => name).join(", ")} from this module: sentinel owns them now, and two copies of Vite in one build give the plugins a different Vite than the one running them.`
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
return { operations, notes };
|
|
590
|
+
}
|
|
591
|
+
function readsPreset(cwd, configFile) {
|
|
592
|
+
if (!existsSync7(join7(cwd, configFile))) return false;
|
|
593
|
+
try {
|
|
594
|
+
return readFileSync5(join7(cwd, configFile), "utf8").includes(BUILD_PRESET_SPECIFIER);
|
|
595
|
+
} catch {
|
|
596
|
+
return false;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// src/roles/build/resolve-vite.ts
|
|
601
|
+
function resolveVite(cwd) {
|
|
602
|
+
return binFromOwnInstall("vite", "vite") ?? resolveBin(cwd, "vite");
|
|
603
|
+
}
|
|
604
|
+
function viteOrigin(cwd) {
|
|
605
|
+
if (binFromOwnInstall("vite", "vite")) return "sentinel";
|
|
606
|
+
return resolveBin(cwd, "vite") ? "module" : "none";
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// src/roles/build/adapters/vite/vite-dev.adapter.ts
|
|
610
|
+
var ViteDevAdapter = class extends BaseAdapter {
|
|
611
|
+
target = "dev";
|
|
612
|
+
runner = "vite";
|
|
613
|
+
appliesTo(preset) {
|
|
614
|
+
return preset === "react";
|
|
615
|
+
}
|
|
616
|
+
declaredPreset(cwd) {
|
|
617
|
+
return declaredBuildPreset(cwd);
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* The same plan as `--build`, deliberately.
|
|
621
|
+
*
|
|
622
|
+
* `build` and `serve` are one app's two calls into one toolchain, so adopting one without
|
|
623
|
+
* the other leaves the module half-migrated in a way nothing reports. The operations are
|
|
624
|
+
* idempotent, so `--init --build` and `--init --dev` are interchangeable rather than
|
|
625
|
+
* additive.
|
|
626
|
+
*/
|
|
627
|
+
plan(context) {
|
|
628
|
+
return plan(context);
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Start the dev server. It does not return until stopped, so there is no verdict to report
|
|
632
|
+
* beyond the exit code the developer's own Ctrl-C produces.
|
|
633
|
+
*
|
|
634
|
+
* No `prebuild` here, unlike `--run --build`: the artefact this repo generates before a build
|
|
635
|
+
* is produced by the watcher that WRAPS this command (`run-with-runtime-artifact-watch`), and
|
|
636
|
+
* running it again would race the watcher that is about to own the file.
|
|
637
|
+
*/
|
|
638
|
+
async run(ctx) {
|
|
639
|
+
if (!readBuildAdoption(ctx.cwd).adopted) {
|
|
640
|
+
process.stderr.write(
|
|
641
|
+
`sentinel dev(vite): no sentinel preset in this module's Vite config; run \`sentinel --init --build\` to adopt.
|
|
642
|
+
`
|
|
643
|
+
);
|
|
644
|
+
return { ok: true, code: 0 };
|
|
645
|
+
}
|
|
646
|
+
const vite = resolveVite(ctx.cwd);
|
|
647
|
+
if (!vite) {
|
|
648
|
+
process.stderr.write(
|
|
649
|
+
`sentinel dev(vite): could not find the vite binary (looked in ${binSearchPath(ctx.cwd)}). Run \`pnpm install\` in the module.
|
|
650
|
+
`
|
|
651
|
+
);
|
|
652
|
+
return { ok: false, code: 1 };
|
|
653
|
+
}
|
|
654
|
+
if (viteOrigin(ctx.cwd) === "module") {
|
|
655
|
+
process.stderr.write(
|
|
656
|
+
`sentinel dev(vite): serving with the MODULE's vite, not sentinel's. An adopted config gets its plugins from sentinel, and two copies of Vite in one process fail in ways that never mention a version. Remove vite from this module's package.json.
|
|
657
|
+
`
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
const { options, paths } = splitToolArgs(ctx.cwd, ctx.toolArgs, { valueFlags: [] });
|
|
661
|
+
const result = spawnSync(vite, [...options, ...paths], { cwd: ctx.cwd, stdio: "inherit" });
|
|
662
|
+
if (result.error) {
|
|
663
|
+
process.stderr.write(`sentinel dev(vite): could not run vite (${result.error.message})
|
|
664
|
+
`);
|
|
665
|
+
return { ok: false, code: 1 };
|
|
666
|
+
}
|
|
667
|
+
const code = result.status ?? 0;
|
|
668
|
+
return { ok: code === 0, code };
|
|
669
|
+
}
|
|
670
|
+
async status(ctx) {
|
|
671
|
+
const { adopted, preset, conformant, drift, unreadable } = readBuildAdoption(ctx.cwd);
|
|
672
|
+
return { adopted, preset, conformant, drift, unreadable };
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
// src/roles/build/adapters/vite/vite.adapter.ts
|
|
677
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
678
|
+
|
|
679
|
+
// src/roles/build/owned-paths.ts
|
|
680
|
+
var PRESET_OWNED_KEYS = [
|
|
681
|
+
"base",
|
|
682
|
+
"root",
|
|
683
|
+
"define",
|
|
684
|
+
"server",
|
|
685
|
+
"build",
|
|
686
|
+
"resolve",
|
|
687
|
+
"plugins"
|
|
688
|
+
];
|
|
689
|
+
function describeDepartures(config, defaults) {
|
|
690
|
+
const departures = [];
|
|
691
|
+
const build = asRecord(config.build);
|
|
692
|
+
const target = build?.target;
|
|
693
|
+
if (typeof target === "string" && target !== defaults.target) {
|
|
694
|
+
departures.push({
|
|
695
|
+
rule: "build.target",
|
|
696
|
+
reason: `${target}, where the convention is ${defaults.target}`
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
const server = asRecord(config.server);
|
|
700
|
+
const hosts = server?.allowedHosts;
|
|
701
|
+
if (Array.isArray(hosts) && !sameStrings(hosts, defaults.allowedHosts)) {
|
|
702
|
+
departures.push({
|
|
703
|
+
rule: "server.allowedHosts",
|
|
704
|
+
reason: `${JSON.stringify(hosts)}, where the convention is ${JSON.stringify(defaults.allowedHosts)}`
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
return departures;
|
|
708
|
+
}
|
|
709
|
+
function appAdditions(config) {
|
|
710
|
+
const owned = new Set(PRESET_OWNED_KEYS);
|
|
711
|
+
return Object.keys(config).filter((key) => !owned.has(key)).sort();
|
|
712
|
+
}
|
|
713
|
+
function asRecord(value) {
|
|
714
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
715
|
+
}
|
|
716
|
+
function sameStrings(a, b) {
|
|
717
|
+
return a.length === b.length && a.every((value, at) => value === b[at]);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// src/roles/build/prerequisite.ts
|
|
721
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
722
|
+
var PREBUILD_SCRIPT_NAME = `pre${BUILD_SCRIPT_NAME}`;
|
|
723
|
+
function insideBuildScript(env = process.env) {
|
|
724
|
+
return env.npm_lifecycle_event === BUILD_SCRIPT_NAME;
|
|
725
|
+
}
|
|
726
|
+
function runPrerequisite(cwd, env = process.env) {
|
|
727
|
+
const scripts = moduleScripts(cwd);
|
|
728
|
+
const script = scripts[PREBUILD_SCRIPT_NAME];
|
|
729
|
+
if (script === void 0 || script.trim() === "") return { kind: "none" };
|
|
730
|
+
if (insideBuildScript(env)) return { kind: "already-run" };
|
|
731
|
+
const result = spawnSync2("pnpm", ["run", PREBUILD_SCRIPT_NAME], { cwd, stdio: "inherit" });
|
|
732
|
+
if (result.error) {
|
|
733
|
+
return { kind: "failed", code: 1, reason: result.error.message };
|
|
734
|
+
}
|
|
735
|
+
const code = result.status ?? 1;
|
|
736
|
+
if (code !== 0) {
|
|
737
|
+
return {
|
|
738
|
+
kind: "failed",
|
|
739
|
+
code,
|
|
740
|
+
reason: `\`pnpm run ${PREBUILD_SCRIPT_NAME}\` exited ${code}`
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
return { kind: "ran" };
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// src/roles/build/resolve-config.ts
|
|
747
|
+
async function resolveBuildConfig(cwd) {
|
|
748
|
+
try {
|
|
749
|
+
const { loadConfigFromFile } = await import("vite");
|
|
750
|
+
const loaded = await loadConfigFromFile(
|
|
751
|
+
{ command: "build", mode: "production" },
|
|
752
|
+
void 0,
|
|
753
|
+
cwd,
|
|
754
|
+
"silent"
|
|
755
|
+
);
|
|
756
|
+
if (!loaded) return { kind: "failed", reason: "Vite found no config file in this module" };
|
|
757
|
+
return { kind: "loaded", config: loaded.config, from: loaded.path };
|
|
758
|
+
} catch (error) {
|
|
759
|
+
return { kind: "failed", reason: error instanceof Error ? error.message : String(error) };
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// src/roles/build/adapters/vite/vite.adapter.ts
|
|
764
|
+
var VITE_VALUE_FLAGS = ["--config", "-c", "--mode", "-m", "--outDir", "--logLevel", "--base"];
|
|
765
|
+
var ViteAdapter = class extends BaseAdapter {
|
|
766
|
+
target = "build";
|
|
767
|
+
runner = "vite";
|
|
768
|
+
/**
|
|
769
|
+
* React only. The two SvelteKit configs in this repo are 34 and 21 lines and share nothing
|
|
770
|
+
* with the React three; claiming them would mean a preset that fits neither.
|
|
771
|
+
*/
|
|
772
|
+
appliesTo(preset) {
|
|
773
|
+
return preset === "react";
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* `react`, read from the module's Vite config rather than from its dependencies.
|
|
777
|
+
*
|
|
778
|
+
* Without this the role is unreachable in practice: the toolchain is declared at the ROOT,
|
|
779
|
+
* so every front app detects as `node` and `appliesTo` filters the adapter out — including
|
|
780
|
+
* during `sentinel --inspect` with no target, which never passes `--preset`.
|
|
781
|
+
*/
|
|
782
|
+
declaredPreset(cwd) {
|
|
783
|
+
return declaredBuildPreset(cwd);
|
|
784
|
+
}
|
|
785
|
+
plan(context) {
|
|
786
|
+
return plan(context);
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Build the module.
|
|
790
|
+
*
|
|
791
|
+
* A module that has not adopted is reported and passes, the same stance every other role
|
|
792
|
+
* takes: `--run` with no named target sweeps every wired target across the workspace, so
|
|
793
|
+
* failing here would exit non-zero on every module that has not migrated, which is most of
|
|
794
|
+
* them.
|
|
795
|
+
*/
|
|
796
|
+
async run(ctx) {
|
|
797
|
+
const adoption = readBuildAdoption(ctx.cwd);
|
|
798
|
+
if (!adoption.adopted) {
|
|
799
|
+
process.stderr.write(
|
|
800
|
+
`sentinel build(vite): no sentinel preset in this module's Vite config; run \`sentinel --init --build\` to adopt.
|
|
801
|
+
`
|
|
802
|
+
);
|
|
803
|
+
return { ok: true, code: 0 };
|
|
804
|
+
}
|
|
805
|
+
const prerequisite = runPrerequisite(ctx.cwd);
|
|
806
|
+
if (prerequisite.kind === "failed") {
|
|
807
|
+
process.stderr.write(
|
|
808
|
+
`sentinel build(vite): the ${PREBUILD_SCRIPT_NAME} step failed, so the build was not started: ${prerequisite.reason}
|
|
809
|
+
`
|
|
810
|
+
);
|
|
811
|
+
return { ok: false, code: prerequisite.code };
|
|
812
|
+
}
|
|
813
|
+
const vite = resolveVite(ctx.cwd);
|
|
814
|
+
if (!vite) {
|
|
815
|
+
process.stderr.write(
|
|
816
|
+
`sentinel build(vite): could not find the vite binary (looked in ${binSearchPath(ctx.cwd)}). Run \`pnpm install\` in the module.
|
|
817
|
+
`
|
|
818
|
+
);
|
|
819
|
+
return { ok: false, code: 1 };
|
|
820
|
+
}
|
|
821
|
+
if (viteOrigin(ctx.cwd) === "module") {
|
|
822
|
+
process.stderr.write(
|
|
823
|
+
`sentinel build(vite): building with the MODULE's vite, not sentinel's. An adopted config gets its plugins from sentinel, and two copies of Vite in one build fail in ways that never mention a version. Remove vite from this module's package.json.
|
|
824
|
+
`
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
const { options, paths } = splitToolArgs(ctx.cwd, ctx.toolArgs, {
|
|
828
|
+
valueFlags: VITE_VALUE_FLAGS
|
|
829
|
+
});
|
|
830
|
+
const result = spawnSync3(vite, ["build", ...options, ...paths], {
|
|
831
|
+
cwd: ctx.cwd,
|
|
832
|
+
stdio: "inherit"
|
|
833
|
+
});
|
|
834
|
+
if (result.error) {
|
|
835
|
+
process.stderr.write(`sentinel build(vite): could not run vite (${result.error.message})
|
|
836
|
+
`);
|
|
837
|
+
return { ok: false, code: 1 };
|
|
838
|
+
}
|
|
839
|
+
const code = result.status ?? 1;
|
|
840
|
+
return { ok: code === 0, code };
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* What this module builds with, without building it.
|
|
844
|
+
*
|
|
845
|
+
* `--inspect` reads the committed config for every role, and the moment `--build` was wired
|
|
846
|
+
* it joined the sweep — so leaving this to throw would have broken `sentinel --inspect` on
|
|
847
|
+
* every React module, for a role that had only just arrived. Cheap and honest is the bar.
|
|
848
|
+
*
|
|
849
|
+
* `vite` is the interesting field and the one nothing else reports: an adopted config takes
|
|
850
|
+
* its plugins from sentinel, so a module answering `module` here is one build away from the
|
|
851
|
+
* two-copies failure, and this is where that is visible before it happens.
|
|
852
|
+
*
|
|
853
|
+
* The resolved config comes from Vite's own loader rather than from parsing the file. See
|
|
854
|
+
* `resolve-config` for why that is the only honest answer here, and what it costs.
|
|
855
|
+
*/
|
|
856
|
+
async inspect(ctx) {
|
|
857
|
+
const adoption = readBuildAdoption(ctx.cwd);
|
|
858
|
+
const base = {
|
|
859
|
+
runner: "vite",
|
|
860
|
+
configFile: adoption.configFile,
|
|
861
|
+
...adoption.unreadable ? { unreadable: adoption.unreadable } : {},
|
|
862
|
+
vite: viteOrigin(ctx.cwd),
|
|
863
|
+
// Rendered as a labelled block by the shared renderer, the same shape the lint role's
|
|
864
|
+
// parked rules and the format role's overrides already use.
|
|
865
|
+
overrides: adoption.ownDeclarations.map(({ name, version }) => ({
|
|
866
|
+
rule: name,
|
|
867
|
+
reason: `declared by this module at ${version}, where sentinel owns it`
|
|
868
|
+
})),
|
|
869
|
+
prerequisite: moduleScripts(ctx.cwd)[PREBUILD_SCRIPT_NAME] ?? null
|
|
870
|
+
};
|
|
871
|
+
if (adoption.configFile === null) return base;
|
|
872
|
+
const resolved = await resolveBuildConfig(ctx.cwd);
|
|
873
|
+
if (resolved.kind === "failed") {
|
|
874
|
+
return { ...base, configError: resolved.reason };
|
|
875
|
+
}
|
|
876
|
+
const config = resolved.config;
|
|
877
|
+
return {
|
|
878
|
+
...base,
|
|
879
|
+
// What the app departs from, and what it adds, are different facts. A DEPARTURE is a
|
|
880
|
+
// disagreement with an opinion the preset holds; an ADDITION is the app needing
|
|
881
|
+
// something the preset never claimed, which is the preset working rather than being
|
|
882
|
+
// worked around.
|
|
883
|
+
departures: describeDepartures(config, REACT_APP_DEFAULTS),
|
|
884
|
+
additions: appAdditions(config),
|
|
885
|
+
resolved: {
|
|
886
|
+
base: config.base ?? null,
|
|
887
|
+
target: config.build?.target ?? null,
|
|
888
|
+
sourcemap: config.build?.sourcemap ?? null,
|
|
889
|
+
port: config.server?.port ?? null,
|
|
890
|
+
// The one number nothing else reports and that no formula predicts: career goes DOWN
|
|
891
|
+
// to 9998 where the others go up, which is why it is data rather than `port + 1`.
|
|
892
|
+
hmrPort: config.server?.hmr?.port ?? null,
|
|
893
|
+
// Counted, not listed. It is 56-67% of every config today, and printing 296 entries
|
|
894
|
+
// would bury everything above it. The count is what tells you whether it moved.
|
|
895
|
+
aliases: Array.isArray(config.resolve?.alias) ? config.resolve.alias.length : 0,
|
|
896
|
+
plugins: Array.isArray(config.plugins) ? config.plugins.flat(9).length : 0
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Adoption as data, WITHOUT building.
|
|
902
|
+
*
|
|
903
|
+
* Deliberately not "run the build and attach metrics". `--report` is what a migration
|
|
904
|
+
* dashboard calls across the whole workspace, and a bundler is the one tool here where doing
|
|
905
|
+
* the real work costs minutes per module rather than seconds. A report that nobody can
|
|
906
|
+
* afford to run is a report nobody runs.
|
|
907
|
+
*
|
|
908
|
+
* Bundle size is the metric this will eventually want, and it needs a build to produce. It
|
|
909
|
+
* belongs behind an explicit opt-in rather than in the default sweep, and the ticket parks
|
|
910
|
+
* it for exactly that reason.
|
|
911
|
+
*/
|
|
912
|
+
async report(ctx) {
|
|
913
|
+
const adoption = readBuildAdoption(ctx.cwd);
|
|
914
|
+
return {
|
|
915
|
+
ok: true,
|
|
916
|
+
code: 0,
|
|
917
|
+
metrics: {
|
|
918
|
+
vite: viteOrigin(ctx.cwd),
|
|
919
|
+
ownBuildDependencies: adoption.ownDeclarations.length
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
async status(ctx) {
|
|
924
|
+
const { adopted, preset, conformant, drift, unreadable } = readBuildAdoption(ctx.cwd);
|
|
925
|
+
return { adopted, preset, conformant, drift, unreadable };
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
// src/roles/build/register.ts
|
|
930
|
+
function registerBuild() {
|
|
931
|
+
register(new ViteAdapter());
|
|
932
|
+
setDefaultRunner("build", "vite");
|
|
933
|
+
register(new ViteDevAdapter());
|
|
934
|
+
setDefaultRunner("dev", "vite");
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
// src/roles/format/adapters/oxfmt/oxfmt.adapter.ts
|
|
938
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
939
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
|
|
940
|
+
import { join as join14 } from "path";
|
|
941
|
+
|
|
240
942
|
// src/core/config/has-source.ts
|
|
241
943
|
import { readdirSync } from "fs";
|
|
242
|
-
import { extname, join as
|
|
944
|
+
import { extname, join as join8 } from "path";
|
|
243
945
|
var SKIP_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
244
946
|
"node_modules",
|
|
245
947
|
"dist",
|
|
@@ -290,7 +992,7 @@ function hasSourceFiles(cwd, extensions) {
|
|
|
290
992
|
}
|
|
291
993
|
for (const entry of entries) {
|
|
292
994
|
if (entry.isDirectory()) {
|
|
293
|
-
if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(
|
|
995
|
+
if (!SKIP_DIRECTORIES.has(entry.name)) queue.push(join8(dir, entry.name));
|
|
294
996
|
continue;
|
|
295
997
|
}
|
|
296
998
|
if (wanted.has(extname(entry.name))) return true;
|
|
@@ -299,54 +1001,13 @@ function hasSourceFiles(cwd, extensions) {
|
|
|
299
1001
|
return false;
|
|
300
1002
|
}
|
|
301
1003
|
|
|
302
|
-
// src/core/config/nx-target.ts
|
|
303
|
-
import { existsSync as existsSync3 } from "fs";
|
|
304
|
-
import { join as join5 } from "path";
|
|
305
|
-
function nxTargetOperations(options) {
|
|
306
|
-
const { cwd, targets } = options;
|
|
307
|
-
const names = Object.keys(targets);
|
|
308
|
-
if (names.length === 0) return [];
|
|
309
|
-
const operations = [];
|
|
310
|
-
if (existsSync3(join5(cwd, "project.json"))) {
|
|
311
|
-
operations.push({
|
|
312
|
-
kind: "remove-json-keys",
|
|
313
|
-
path: "project.json",
|
|
314
|
-
keys: names.map((name) => ["targets", name])
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
operations.push({
|
|
318
|
-
kind: "merge-json",
|
|
319
|
-
path: "package.json",
|
|
320
|
-
value: { nx: { targets } }
|
|
321
|
-
});
|
|
322
|
-
return operations;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// src/core/config/tool-args.ts
|
|
326
|
-
import { existsSync as existsSync4 } from "fs";
|
|
327
|
-
import { isAbsolute, resolve as resolve2 } from "path";
|
|
328
|
-
function splitToolArgs(cwd, toolArgs = [], { valueFlags = [] } = {}) {
|
|
329
|
-
const takesValue = new Set(valueFlags);
|
|
330
|
-
const options = [];
|
|
331
|
-
const paths = [];
|
|
332
|
-
let previousTakesValue = false;
|
|
333
|
-
for (const arg of toolArgs) {
|
|
334
|
-
const looksLikeOption = arg.startsWith("-");
|
|
335
|
-
const target = isAbsolute(arg) ? arg : resolve2(cwd, arg);
|
|
336
|
-
if (!previousTakesValue && !looksLikeOption && existsSync4(target)) paths.push(arg);
|
|
337
|
-
else options.push(arg);
|
|
338
|
-
previousTakesValue = !arg.includes("=") && takesValue.has(arg);
|
|
339
|
-
}
|
|
340
|
-
return { options, paths };
|
|
341
|
-
}
|
|
342
|
-
|
|
343
1004
|
// src/core/settings.ts
|
|
344
1005
|
var WORKSPACE_ROOT_MARKER = "nx.json";
|
|
345
1006
|
var DEFAULT_MAX_DIAGNOSTICS = 100;
|
|
346
1007
|
|
|
347
1008
|
// src/core/workspace-prep.ts
|
|
348
|
-
import { existsSync as
|
|
349
|
-
import { dirname as
|
|
1009
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync } from "fs";
|
|
1010
|
+
import { dirname as dirname3, join as join9, relative } from "path";
|
|
350
1011
|
var OVERRIDE_KEY = "i18next>typescript";
|
|
351
1012
|
var NATIVE_TS_ALIAS = "@typescript/native";
|
|
352
1013
|
var WORKSPACE_YAML = "pnpm-workspace.yaml";
|
|
@@ -355,8 +1016,8 @@ var LIST_ITEM = /^(\s*)-\s+(.*?)\s*$/;
|
|
|
355
1016
|
function findWorkspaceRoot(startDir) {
|
|
356
1017
|
let dir = startDir;
|
|
357
1018
|
for (; ; ) {
|
|
358
|
-
if (
|
|
359
|
-
const parent =
|
|
1019
|
+
if (existsSync8(join9(dir, WORKSPACE_ROOT_MARKER))) return dir;
|
|
1020
|
+
const parent = dirname3(dir);
|
|
360
1021
|
if (parent === dir) return void 0;
|
|
361
1022
|
dir = parent;
|
|
362
1023
|
}
|
|
@@ -368,9 +1029,9 @@ function declaredNativeTs(pkg) {
|
|
|
368
1029
|
return version || void 0;
|
|
369
1030
|
}
|
|
370
1031
|
function ensureI18nextSingleton(root, dryRun) {
|
|
371
|
-
const pkgPath =
|
|
372
|
-
if (!
|
|
373
|
-
const pkg = JSON.parse(
|
|
1032
|
+
const pkgPath = join9(root, "package.json");
|
|
1033
|
+
if (!existsSync8(pkgPath)) return void 0;
|
|
1034
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf8"));
|
|
374
1035
|
const want = declaredNativeTs(pkg);
|
|
375
1036
|
if (!want) return void 0;
|
|
376
1037
|
const have = pkg.pnpm?.overrides?.[OVERRIDE_KEY];
|
|
@@ -383,10 +1044,10 @@ function ensureI18nextSingleton(root, dryRun) {
|
|
|
383
1044
|
return `pinned ${OVERRIDE_KEY} to ${want} in package.json (i18next singleton)`;
|
|
384
1045
|
}
|
|
385
1046
|
function ensureReleaseAgeAllowList(root, dryRun) {
|
|
386
|
-
const yamlPath =
|
|
387
|
-
if (!
|
|
1047
|
+
const yamlPath = join9(root, WORKSPACE_YAML);
|
|
1048
|
+
if (!existsSync8(yamlPath)) return void 0;
|
|
388
1049
|
const own = readOwnPackage().name;
|
|
389
|
-
const lines =
|
|
1050
|
+
const lines = readFileSync6(yamlPath, "utf8").split("\n");
|
|
390
1051
|
const keyIdx = lines.findIndex((line) => line.replace(/\s+$/, "") === `${RELEASE_AGE_KEY}:`);
|
|
391
1052
|
if (keyIdx === -1) return void 0;
|
|
392
1053
|
let lastItemIdx = keyIdx;
|
|
@@ -421,11 +1082,11 @@ var ROOT_PRETTIER_CONFIGS = [
|
|
|
421
1082
|
function ensureFormatterExclusion(root, moduleDir, dryRun) {
|
|
422
1083
|
const rel = relative(root, moduleDir).replaceAll("\\", "/");
|
|
423
1084
|
if (rel === "" || rel.startsWith("..")) return void 0;
|
|
424
|
-
const ignorePath =
|
|
425
|
-
const hasPrettier =
|
|
1085
|
+
const ignorePath = join9(root, PRETTIER_IGNORE);
|
|
1086
|
+
const hasPrettier = existsSync8(ignorePath) || ROOT_PRETTIER_CONFIGS.some((name) => existsSync8(join9(root, name)));
|
|
426
1087
|
if (!hasPrettier) return void 0;
|
|
427
1088
|
const pattern = `/${rel}/`;
|
|
428
|
-
const existing =
|
|
1089
|
+
const existing = existsSync8(ignorePath) ? readFileSync6(ignorePath, "utf8") : "";
|
|
429
1090
|
const lines = existing.split("\n");
|
|
430
1091
|
if (lines.some((line) => line.trim().replace(/\/$/, "") === pattern.replace(/\/$/, ""))) {
|
|
431
1092
|
return void 0;
|
|
@@ -461,10 +1122,10 @@ function ensureWorkspacePrep(opts) {
|
|
|
461
1122
|
function inspectWorkspacePrep(root) {
|
|
462
1123
|
const entries = [];
|
|
463
1124
|
let pkg = {};
|
|
464
|
-
const pkgPath =
|
|
465
|
-
if (
|
|
1125
|
+
const pkgPath = join9(root, "package.json");
|
|
1126
|
+
if (existsSync8(pkgPath)) {
|
|
466
1127
|
try {
|
|
467
|
-
pkg = JSON.parse(
|
|
1128
|
+
pkg = JSON.parse(readFileSync6(pkgPath, "utf8"));
|
|
468
1129
|
} catch {
|
|
469
1130
|
pkg = {};
|
|
470
1131
|
}
|
|
@@ -478,9 +1139,9 @@ function inspectWorkspacePrep(root) {
|
|
|
478
1139
|
});
|
|
479
1140
|
}
|
|
480
1141
|
const own = readOwnPackage().name;
|
|
481
|
-
const yamlPath =
|
|
482
|
-
if (
|
|
483
|
-
const yaml =
|
|
1142
|
+
const yamlPath = join9(root, WORKSPACE_YAML);
|
|
1143
|
+
if (existsSync8(yamlPath)) {
|
|
1144
|
+
const yaml = readFileSync6(yamlPath, "utf8");
|
|
484
1145
|
const listed = new RegExp(`^\\s*-\\s*['"]?${own.replace("/", "\\/")}['"]?\\s*$`, "m").test(yaml);
|
|
485
1146
|
if (listed) {
|
|
486
1147
|
const gated = new RegExp(`^\\s*minimumReleaseAge\\s*:`, "m").test(yaml);
|
|
@@ -493,39 +1154,6 @@ function inspectWorkspacePrep(root) {
|
|
|
493
1154
|
return entries;
|
|
494
1155
|
}
|
|
495
1156
|
|
|
496
|
-
// src/shared/resolve-bin.ts
|
|
497
|
-
import { existsSync as existsSync6 } from "fs";
|
|
498
|
-
import { createRequire } from "module";
|
|
499
|
-
import { delimiter, dirname as dirname3, join as join7 } from "path";
|
|
500
|
-
var require2 = createRequire(import.meta.url);
|
|
501
|
-
function resolveBin(fromDir, name) {
|
|
502
|
-
let dir = fromDir;
|
|
503
|
-
for (; ; ) {
|
|
504
|
-
const candidate = join7(dir, "node_modules", ".bin", name);
|
|
505
|
-
if (existsSync6(candidate)) return candidate;
|
|
506
|
-
const parent = dirname3(dir);
|
|
507
|
-
if (parent === dir) return void 0;
|
|
508
|
-
dir = parent;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
function binFromOwnInstall(packageName, binName) {
|
|
512
|
-
try {
|
|
513
|
-
const manifest = require2.resolve(`${packageName}/package.json`);
|
|
514
|
-
const bin = require2(manifest).bin;
|
|
515
|
-
const relative3 = typeof bin === "string" ? bin : bin?.[binName];
|
|
516
|
-
if (!relative3) return void 0;
|
|
517
|
-
const executable = join7(dirname3(manifest), relative3);
|
|
518
|
-
return existsSync6(executable) ? executable : void 0;
|
|
519
|
-
} catch {
|
|
520
|
-
return void 0;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
function binSearchPath(cwd) {
|
|
524
|
-
return [`${cwd}${delimiter}node_modules/.bin (and parents)`, "sentinel's own install"].join(
|
|
525
|
-
" then "
|
|
526
|
-
);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
1157
|
// src/roles/format/config-policy.ts
|
|
530
1158
|
var FORMAT_CONFIG_FILE = ".oxfmtrc.json";
|
|
531
1159
|
var FORMAT_SCRIPT_NAME = "format";
|
|
@@ -572,48 +1200,6 @@ function formatTargets() {
|
|
|
572
1200
|
};
|
|
573
1201
|
}
|
|
574
1202
|
|
|
575
|
-
// src/core/config/tool-script.ts
|
|
576
|
-
var SEGMENT_SEPARATOR = /(\s*(?:&&|\|\||;|&|\|)\s*)/;
|
|
577
|
-
function isSeparatorAt(index) {
|
|
578
|
-
return index % 2 === 1;
|
|
579
|
-
}
|
|
580
|
-
function invokes(segment, binary) {
|
|
581
|
-
return new RegExp(String.raw`(^|[\s/])${binary}(\s|$)`).test(segment.trim());
|
|
582
|
-
}
|
|
583
|
-
function isSentinelSegment(segment, roleFlag) {
|
|
584
|
-
const runsSentinel = invokes(segment, "sentinel") || segment.includes("bin/sentinel.js");
|
|
585
|
-
return runsSentinel && new RegExp(String.raw`(^|\s)${roleFlag}(\s|$)`).test(segment);
|
|
586
|
-
}
|
|
587
|
-
function composeToolScript(existing, options) {
|
|
588
|
-
const { command } = options;
|
|
589
|
-
if (!existing || existing.trim() === "") return command;
|
|
590
|
-
const { roleFlag } = options;
|
|
591
|
-
const isReplaceable = (segment) => options.replaces(segment) || roleFlag !== void 0 && isSentinelSegment(segment, roleFlag);
|
|
592
|
-
const parts = existing.split(SEGMENT_SEPARATOR);
|
|
593
|
-
const commands = parts.filter((_, index) => !isSeparatorAt(index));
|
|
594
|
-
if (!commands.some(isReplaceable)) return existing;
|
|
595
|
-
let replacedOnce = false;
|
|
596
|
-
const rebuilt = parts.map((part, index) => {
|
|
597
|
-
if (isSeparatorAt(index) || !isReplaceable(part)) return part;
|
|
598
|
-
if (replacedOnce) return null;
|
|
599
|
-
replacedOnce = true;
|
|
600
|
-
return options.keepFix && /(^|\s)--fix(\s|$)/.test(part) ? `${command} --fix` : command;
|
|
601
|
-
});
|
|
602
|
-
const kept = [];
|
|
603
|
-
for (let index = 0; index < rebuilt.length; index += 1) {
|
|
604
|
-
const part = rebuilt[index];
|
|
605
|
-
if (part === null) {
|
|
606
|
-
if (kept.length > 0) kept.pop();
|
|
607
|
-
continue;
|
|
608
|
-
}
|
|
609
|
-
kept.push(part);
|
|
610
|
-
}
|
|
611
|
-
return kept.join("").trim();
|
|
612
|
-
}
|
|
613
|
-
function keepsOtherCommands(script, sentinelCommand) {
|
|
614
|
-
return script.split(SEGMENT_SEPARATOR).filter((_, index) => !isSeparatorAt(index)).some((segment) => segment.trim() !== "" && segment.trim() !== sentinelCommand);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
1203
|
// src/roles/format/format-script.ts
|
|
618
1204
|
var SENTINEL_FORMAT_COMMAND = "sentinel --run --format";
|
|
619
1205
|
function isPrettierSegment(segment) {
|
|
@@ -642,8 +1228,8 @@ function writesWhenRewritten(name, command) {
|
|
|
642
1228
|
var CHECK_SCRIPT_NAMES = /* @__PURE__ */ new Set(["lint", "format", "check", "test", "typecheck", "verify"]);
|
|
643
1229
|
|
|
644
1230
|
// src/roles/format/inherited-ignores.ts
|
|
645
|
-
import { existsSync as
|
|
646
|
-
import { join as
|
|
1231
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
|
|
1232
|
+
import { join as join10 } from "path";
|
|
647
1233
|
var ROOT_IGNORE_FILE = ".prettierignore";
|
|
648
1234
|
function isPattern(line) {
|
|
649
1235
|
const trimmed = line.trim();
|
|
@@ -658,11 +1244,11 @@ function toModulePattern(pattern) {
|
|
|
658
1244
|
}
|
|
659
1245
|
function inheritedIgnorePatterns(workspaceRoot) {
|
|
660
1246
|
if (!workspaceRoot) return [];
|
|
661
|
-
const path =
|
|
662
|
-
if (!
|
|
1247
|
+
const path = join10(workspaceRoot, ROOT_IGNORE_FILE);
|
|
1248
|
+
if (!existsSync9(path)) return [];
|
|
663
1249
|
let contents;
|
|
664
1250
|
try {
|
|
665
|
-
contents =
|
|
1251
|
+
contents = readFileSync7(path, "utf8");
|
|
666
1252
|
} catch {
|
|
667
1253
|
return [];
|
|
668
1254
|
}
|
|
@@ -749,13 +1335,13 @@ function formatPresetFor(preset) {
|
|
|
749
1335
|
}
|
|
750
1336
|
|
|
751
1337
|
// src/roles/format/prettier-config.ts
|
|
752
|
-
import { existsSync as
|
|
753
|
-
import { join as
|
|
1338
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
|
|
1339
|
+
import { join as join12 } from "path";
|
|
754
1340
|
|
|
755
1341
|
// src/roles/format/resolve-oxfmt.ts
|
|
756
|
-
import { readFileSync as
|
|
1342
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
757
1343
|
import { createRequire as createRequire2 } from "module";
|
|
758
|
-
import { dirname as dirname4, join as
|
|
1344
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
759
1345
|
function resolveOxfmt(cwd) {
|
|
760
1346
|
return resolveBin(cwd, "oxfmt") ?? binFromOwnInstall("oxfmt", "oxfmt");
|
|
761
1347
|
}
|
|
@@ -784,8 +1370,8 @@ function configSchema() {
|
|
|
784
1370
|
function readConfigSchema() {
|
|
785
1371
|
try {
|
|
786
1372
|
const manifest = createRequire2(import.meta.url).resolve("oxfmt/package.json");
|
|
787
|
-
const schemaPath =
|
|
788
|
-
return JSON.parse(
|
|
1373
|
+
const schemaPath = join11(dirname4(manifest), "configuration_schema.json");
|
|
1374
|
+
return JSON.parse(readFileSync8(schemaPath, "utf8"));
|
|
789
1375
|
} catch {
|
|
790
1376
|
return void 0;
|
|
791
1377
|
}
|
|
@@ -816,14 +1402,14 @@ function toOxfmtOverrides(value) {
|
|
|
816
1402
|
return { overrides, unresolved };
|
|
817
1403
|
}
|
|
818
1404
|
function readPrettierSettings(cwd) {
|
|
819
|
-
const file = PRETTIER_CONFIG_FILES.find((name) =>
|
|
1405
|
+
const file = PRETTIER_CONFIG_FILES.find((name) => existsSync10(join12(cwd, name)));
|
|
820
1406
|
if (!file) return { options: {}, unresolved: [] };
|
|
821
1407
|
if (/\.(js|cjs|mjs)$/.test(file)) {
|
|
822
1408
|
return { options: {}, file, unresolved: [`${file} is JavaScript, so it was not executed`] };
|
|
823
1409
|
}
|
|
824
1410
|
let parsed;
|
|
825
1411
|
try {
|
|
826
|
-
parsed = parseJsonc(
|
|
1412
|
+
parsed = parseJsonc(readFileSync9(join12(cwd, file), "utf8"), file);
|
|
827
1413
|
} catch {
|
|
828
1414
|
return { options: {}, file, unresolved: [`${file} could not be parsed`] };
|
|
829
1415
|
}
|
|
@@ -853,9 +1439,9 @@ function readPrettierSettings(cwd) {
|
|
|
853
1439
|
}
|
|
854
1440
|
|
|
855
1441
|
// src/roles/format/read-adoption.ts
|
|
856
|
-
import { existsSync as
|
|
857
|
-
import { join as
|
|
858
|
-
var
|
|
1442
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
1443
|
+
import { join as join13 } from "path";
|
|
1444
|
+
var NOT_ADOPTED2 = (configFile, unreadable = null) => ({
|
|
859
1445
|
configFile,
|
|
860
1446
|
preset: null,
|
|
861
1447
|
adopted: false,
|
|
@@ -870,19 +1456,19 @@ function sameValue(a, b) {
|
|
|
870
1456
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
871
1457
|
}
|
|
872
1458
|
function readFormatAdoption(cwd) {
|
|
873
|
-
const path =
|
|
874
|
-
if (!
|
|
1459
|
+
const path = join13(cwd, FORMAT_CONFIG_FILE);
|
|
1460
|
+
if (!existsSync11(path)) return NOT_ADOPTED2(null);
|
|
875
1461
|
let parsed;
|
|
876
1462
|
try {
|
|
877
|
-
parsed = parseJsonc(
|
|
1463
|
+
parsed = parseJsonc(readFileSync10(path, "utf8"), FORMAT_CONFIG_FILE);
|
|
878
1464
|
} catch (error) {
|
|
879
1465
|
const reason = error instanceof Error ? error.message : String(error);
|
|
880
|
-
return
|
|
1466
|
+
return NOT_ADOPTED2(FORMAT_CONFIG_FILE, `${FORMAT_CONFIG_FILE} could not be parsed (${reason})`);
|
|
881
1467
|
}
|
|
882
1468
|
const provenance = parsed[PROVENANCE_KEY];
|
|
883
|
-
if (!provenance || typeof provenance.preset !== "string") return
|
|
1469
|
+
if (!provenance || typeof provenance.preset !== "string") return NOT_ADOPTED2(FORMAT_CONFIG_FILE);
|
|
884
1470
|
if (!hasFormatPreset(provenance.preset)) {
|
|
885
|
-
return
|
|
1471
|
+
return NOT_ADOPTED2(
|
|
886
1472
|
FORMAT_CONFIG_FILE,
|
|
887
1473
|
`${FORMAT_CONFIG_FILE} declares the format preset "${provenance.preset}", which sentinel does not ship (shipped: ${FORMAT_PRESETS.join(", ")}). Re-run \`sentinel --init --format\`.`
|
|
888
1474
|
);
|
|
@@ -983,7 +1569,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
983
1569
|
manifestOperation(context.cwd, this.formatScripts(context.cwd))
|
|
984
1570
|
];
|
|
985
1571
|
const prettierConfigs = PRETTIER_CONFIG_FILES.filter(
|
|
986
|
-
(name) =>
|
|
1572
|
+
(name) => existsSync12(join14(context.cwd, name))
|
|
987
1573
|
);
|
|
988
1574
|
for (const name of prettierConfigs) operations.push({ kind: "delete", path: name });
|
|
989
1575
|
const removableDeps = this.modulePrettierDependencies(context.cwd);
|
|
@@ -1042,7 +1628,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
1042
1628
|
async afterInit(ctx) {
|
|
1043
1629
|
const oxfmt = resolveOxfmt(ctx.cwd);
|
|
1044
1630
|
if (!oxfmt) return;
|
|
1045
|
-
const pass =
|
|
1631
|
+
const pass = spawnSync4(oxfmt, ["--write", "."], { cwd: ctx.cwd, encoding: "utf8" });
|
|
1046
1632
|
process.stderr.write(` ${palette(process.stderr).dim(FORMATTER_DIFFERENCES)}
|
|
1047
1633
|
`);
|
|
1048
1634
|
if (pass.status === 0) return;
|
|
@@ -1105,7 +1691,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
1105
1691
|
const { options, paths } = splitToolArgs(ctx.cwd, ctx.toolArgs, {
|
|
1106
1692
|
valueFlags: OXFMT_VALUE_FLAGS
|
|
1107
1693
|
});
|
|
1108
|
-
const result =
|
|
1694
|
+
const result = spawnSync4(oxfmt, [mode, ...options, ...paths.length > 0 ? paths : ["."]], {
|
|
1109
1695
|
cwd: ctx.cwd,
|
|
1110
1696
|
stdio: "inherit"
|
|
1111
1697
|
});
|
|
@@ -1183,7 +1769,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
1183
1769
|
);
|
|
1184
1770
|
return { ok: false, code: 1, metrics: { ...base, unformatted: null } };
|
|
1185
1771
|
}
|
|
1186
|
-
const result =
|
|
1772
|
+
const result = spawnSync4(oxfmt, ["--list-different", "."], { cwd: ctx.cwd, encoding: "utf8" });
|
|
1187
1773
|
if (result.error) {
|
|
1188
1774
|
process.stderr.write(
|
|
1189
1775
|
`sentinel format(oxfmt): could not run oxfmt (${result.error.message})
|
|
@@ -1219,7 +1805,7 @@ var OxfmtAdapter = class extends BaseAdapter {
|
|
|
1219
1805
|
modulePrettierDependencies(cwd) {
|
|
1220
1806
|
const isPrettierPackage = (name) => name === "prettier" || name.startsWith("prettier-plugin-") || name.startsWith("@prettier/");
|
|
1221
1807
|
try {
|
|
1222
|
-
const manifest = JSON.parse(
|
|
1808
|
+
const manifest = JSON.parse(readFileSync11(join14(cwd, "package.json"), "utf8"));
|
|
1223
1809
|
return Object.keys(manifest.devDependencies ?? {}).filter(isPrettierPackage).map((name) => ["devDependencies", name]);
|
|
1224
1810
|
} catch {
|
|
1225
1811
|
return [];
|
|
@@ -1300,9 +1886,9 @@ function registerFormat() {
|
|
|
1300
1886
|
}
|
|
1301
1887
|
|
|
1302
1888
|
// src/roles/lint/adapters/oxlint/oxlint.adapter.ts
|
|
1303
|
-
import { spawnSync as
|
|
1304
|
-
import { existsSync as
|
|
1305
|
-
import { join as
|
|
1889
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
1890
|
+
import { existsSync as existsSync19, readFileSync as readFileSync18, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1891
|
+
import { join as join22 } from "path";
|
|
1306
1892
|
|
|
1307
1893
|
// src/core/config/deferred-rules.ts
|
|
1308
1894
|
function deferredRuleNames(rules) {
|
|
@@ -1312,12 +1898,12 @@ function deferredRuleNames(rules) {
|
|
|
1312
1898
|
// src/roles/lint/config-policy.ts
|
|
1313
1899
|
var LINT_CONFIG_FILE = ".oxlintrc.json";
|
|
1314
1900
|
var LINT_SCRIPT_NAME = "lint";
|
|
1315
|
-
var PRESET_DIR = "./node_modules/@hublo/sentinel/
|
|
1901
|
+
var PRESET_DIR = "./node_modules/@hublo/sentinel/lint";
|
|
1316
1902
|
function presetPath(preset) {
|
|
1317
1903
|
return `${PRESET_DIR}/${preset}.json`;
|
|
1318
1904
|
}
|
|
1319
1905
|
function isSentinelPreset(entry) {
|
|
1320
|
-
return
|
|
1906
|
+
return /@hublo\/sentinel\/(lint|oxlint)\//.test(entry);
|
|
1321
1907
|
}
|
|
1322
1908
|
function extendsWithPreset(current, variant) {
|
|
1323
1909
|
const own = presetPath(variant);
|
|
@@ -1331,7 +1917,7 @@ function presetVariant(preset, cwd) {
|
|
|
1331
1917
|
function presetOfVariant(variant) {
|
|
1332
1918
|
return variant === "react-lib" ? "react" : variant;
|
|
1333
1919
|
}
|
|
1334
|
-
var SENTINEL_LINT_PRESET = /@hublo\/sentinel\/oxlint\/([a-z-]+)\.json$/;
|
|
1920
|
+
var SENTINEL_LINT_PRESET = /@hublo\/sentinel\/(?:lint|oxlint)\/([a-z-]+)\.json$/;
|
|
1335
1921
|
function presetNameFromPath(preset) {
|
|
1336
1922
|
return preset ? SENTINEL_LINT_PRESET.exec(preset)?.[1] ?? void 0 : void 0;
|
|
1337
1923
|
}
|
|
@@ -3116,8 +3702,8 @@ function downgradedRulesFor(preset) {
|
|
|
3116
3702
|
}
|
|
3117
3703
|
|
|
3118
3704
|
// src/roles/lint/extra-layers.ts
|
|
3119
|
-
import { existsSync as
|
|
3120
|
-
import { isAbsolute as isAbsolute2, join as
|
|
3705
|
+
import { existsSync as existsSync13, readFileSync as readFileSync12 } from "fs";
|
|
3706
|
+
import { isAbsolute as isAbsolute2, join as join15, resolve as resolve3 } from "path";
|
|
3121
3707
|
|
|
3122
3708
|
// src/roles/lint/module-baseline.ts
|
|
3123
3709
|
var LINT_BASELINE_FILE = ".oxlintrc.baseline.json";
|
|
@@ -3164,15 +3750,12 @@ function describeHolds(holds) {
|
|
|
3164
3750
|
}
|
|
3165
3751
|
|
|
3166
3752
|
// src/roles/lint/extra-layers.ts
|
|
3167
|
-
function isSentinelPreset2(entry) {
|
|
3168
|
-
return entry.includes("@hublo/sentinel/oxlint/");
|
|
3169
|
-
}
|
|
3170
3753
|
function ruleCount(cwd, specifier) {
|
|
3171
3754
|
const path = isAbsolute2(specifier) ? specifier : resolve3(cwd, specifier);
|
|
3172
|
-
if (!
|
|
3755
|
+
if (!existsSync13(path)) return void 0;
|
|
3173
3756
|
try {
|
|
3174
3757
|
const parsed = parseJsonc(
|
|
3175
|
-
|
|
3758
|
+
readFileSync12(path, "utf8"),
|
|
3176
3759
|
specifier
|
|
3177
3760
|
);
|
|
3178
3761
|
return Object.keys(parsed.rules ?? {}).length;
|
|
@@ -3181,7 +3764,7 @@ function ruleCount(cwd, specifier) {
|
|
|
3181
3764
|
}
|
|
3182
3765
|
}
|
|
3183
3766
|
function extraLayers(cwd, extendsList) {
|
|
3184
|
-
return extendsList.filter((entry) => !
|
|
3767
|
+
return extendsList.filter((entry) => !isSentinelPreset(entry) && entry !== LINT_BASELINE_SPECIFIER).map((entry) => {
|
|
3185
3768
|
const count = ruleCount(cwd, entry);
|
|
3186
3769
|
return {
|
|
3187
3770
|
rule: entry,
|
|
@@ -3192,7 +3775,7 @@ function extraLayers(cwd, extendsList) {
|
|
|
3192
3775
|
function committedExtendsList(cwd, configFile) {
|
|
3193
3776
|
try {
|
|
3194
3777
|
const parsed = parseJsonc(
|
|
3195
|
-
|
|
3778
|
+
readFileSync12(join15(cwd, configFile), "utf8"),
|
|
3196
3779
|
configFile
|
|
3197
3780
|
);
|
|
3198
3781
|
return Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : [];
|
|
@@ -3251,8 +3834,8 @@ function errorCountsByConfigRule(stdout) {
|
|
|
3251
3834
|
}
|
|
3252
3835
|
|
|
3253
3836
|
// src/core/config/read-adoption.ts
|
|
3254
|
-
import { existsSync as
|
|
3255
|
-
import { join as
|
|
3837
|
+
import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
|
|
3838
|
+
import { join as join17 } from "path";
|
|
3256
3839
|
|
|
3257
3840
|
// src/core/config/owned-keys.ts
|
|
3258
3841
|
function presetOwnedKeys(config, permitted, presetSets) {
|
|
@@ -3267,12 +3850,12 @@ function localOnlyKeys(config, permitted, presetSets) {
|
|
|
3267
3850
|
}
|
|
3268
3851
|
|
|
3269
3852
|
// src/core/config/resolve-config-target.ts
|
|
3270
|
-
import { existsSync as
|
|
3271
|
-
import { join as
|
|
3853
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13 } from "fs";
|
|
3854
|
+
import { join as join16 } from "path";
|
|
3272
3855
|
function readExtends(absolutePath) {
|
|
3273
3856
|
let parsed;
|
|
3274
3857
|
try {
|
|
3275
|
-
parsed = parseJsonc(
|
|
3858
|
+
parsed = parseJsonc(readFileSync13(absolutePath, "utf8"), absolutePath);
|
|
3276
3859
|
} catch {
|
|
3277
3860
|
return [];
|
|
3278
3861
|
}
|
|
@@ -3286,8 +3869,8 @@ function resolveConfigTarget(moduleDir, { candidates, markers, fallback }) {
|
|
|
3286
3869
|
let existing;
|
|
3287
3870
|
let existingExtendsSomething = false;
|
|
3288
3871
|
for (const candidate of candidates) {
|
|
3289
|
-
const absolutePath =
|
|
3290
|
-
if (!
|
|
3872
|
+
const absolutePath = join16(moduleDir, candidate);
|
|
3873
|
+
if (!existsSync14(absolutePath)) continue;
|
|
3291
3874
|
const chain = readExtends(absolutePath);
|
|
3292
3875
|
if (existing === void 0) {
|
|
3293
3876
|
existing = candidate;
|
|
@@ -3310,7 +3893,7 @@ function normaliseExtends(value) {
|
|
|
3310
3893
|
}
|
|
3311
3894
|
return [];
|
|
3312
3895
|
}
|
|
3313
|
-
var
|
|
3896
|
+
var NOT_ADOPTED3 = (configFile, unreadable = null) => ({
|
|
3314
3897
|
configFile,
|
|
3315
3898
|
preset: null,
|
|
3316
3899
|
adopted: false,
|
|
@@ -3320,18 +3903,18 @@ var NOT_ADOPTED2 = (configFile, unreadable = null) => ({
|
|
|
3320
3903
|
});
|
|
3321
3904
|
function readAdoption(cwd, options) {
|
|
3322
3905
|
const target = resolveConfigTarget(cwd, options);
|
|
3323
|
-
if (target.reason === "none" || !
|
|
3324
|
-
return
|
|
3906
|
+
if (target.reason === "none" || !existsSync15(join17(cwd, target.path))) {
|
|
3907
|
+
return NOT_ADOPTED3(target.reason === "none" ? null : target.path);
|
|
3325
3908
|
}
|
|
3326
3909
|
let parsed;
|
|
3327
3910
|
try {
|
|
3328
|
-
parsed = parseJsonc(
|
|
3911
|
+
parsed = parseJsonc(readFileSync14(join17(cwd, target.path), "utf8"), target.path);
|
|
3329
3912
|
} catch (error) {
|
|
3330
3913
|
const reason = error instanceof Error ? error.message : String(error);
|
|
3331
|
-
return
|
|
3914
|
+
return NOT_ADOPTED3(target.path, `${target.path} could not be parsed (${reason})`);
|
|
3332
3915
|
}
|
|
3333
3916
|
const preset = normaliseExtends(parsed.extends).find((entry) => options.presetPattern.test(entry)) ?? null;
|
|
3334
|
-
if (preset === null) return
|
|
3917
|
+
if (preset === null) return NOT_ADOPTED3(target.path);
|
|
3335
3918
|
const settings = options.settingsKey === null ? parsed : parsed[options.settingsKey];
|
|
3336
3919
|
const drift = presetOwnedKeys(settings, options.permitted, options.presetOwns?.(preset));
|
|
3337
3920
|
return {
|
|
@@ -3359,9 +3942,9 @@ function readLintAdoption(cwd) {
|
|
|
3359
3942
|
}
|
|
3360
3943
|
|
|
3361
3944
|
// src/roles/lint/resolve-oxlint.ts
|
|
3362
|
-
import { existsSync as
|
|
3945
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3363
3946
|
import { createRequire as createRequire3 } from "module";
|
|
3364
|
-
import { delimiter as delimiter2, dirname as dirname5, join as
|
|
3947
|
+
import { delimiter as delimiter2, dirname as dirname5, join as join18 } from "path";
|
|
3365
3948
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3366
3949
|
var PACKAGE_OF = {
|
|
3367
3950
|
oxlint: "oxlint",
|
|
@@ -3386,30 +3969,30 @@ function tsgolintShim(cwd) {
|
|
|
3386
3969
|
for (const owner of ["oxlint-tsgolint", "oxlint"]) {
|
|
3387
3970
|
try {
|
|
3388
3971
|
const packageDir = dirname5(require3.resolve(`${owner}/package.json`));
|
|
3389
|
-
candidates.push(
|
|
3390
|
-
candidates.push(
|
|
3972
|
+
candidates.push(join18(packageDir, "node_modules", ".bin", "tsgolint"));
|
|
3973
|
+
candidates.push(join18(packageDir, "..", ".bin", "tsgolint"));
|
|
3391
3974
|
} catch {
|
|
3392
3975
|
}
|
|
3393
3976
|
}
|
|
3394
3977
|
try {
|
|
3395
3978
|
const ownRoot = dirname5(require3.resolve("@hublo/sentinel/package.json"));
|
|
3396
|
-
candidates.push(
|
|
3979
|
+
candidates.push(join18(ownRoot, "node_modules", ".bin", "tsgolint"));
|
|
3397
3980
|
} catch {
|
|
3398
3981
|
candidates.push(resolveBin(dirname5(fileURLToPath2(import.meta.url)), "tsgolint") ?? "");
|
|
3399
3982
|
}
|
|
3400
|
-
return candidates.find((candidate) => candidate !== "" &&
|
|
3983
|
+
return candidates.find((candidate) => candidate !== "" && existsSync16(candidate));
|
|
3401
3984
|
}
|
|
3402
3985
|
function oxlintSearchPath(cwd) {
|
|
3403
3986
|
return binSearchPath(cwd);
|
|
3404
3987
|
}
|
|
3405
3988
|
|
|
3406
3989
|
// src/roles/lint/adapters/oxlint/plan.ts
|
|
3407
|
-
import { existsSync as
|
|
3408
|
-
import { join as
|
|
3990
|
+
import { existsSync as existsSync18, readFileSync as readFileSync17 } from "fs";
|
|
3991
|
+
import { join as join21 } from "path";
|
|
3409
3992
|
|
|
3410
3993
|
// src/roles/lint/eslint-ignores.ts
|
|
3411
|
-
import { existsSync as
|
|
3412
|
-
import { join as
|
|
3994
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
3995
|
+
import { join as join19 } from "path";
|
|
3413
3996
|
var IGNORE_BLOCKS = [/\bignores\s*:\s*\[([^\]]*)\]/g, /\bglobalIgnores\s*\(\s*\[([^\]]*)\]/g];
|
|
3414
3997
|
var STRING_LITERAL = /['"`]([^'"`]+)['"`]/g;
|
|
3415
3998
|
var OPAQUE_SOURCE = /\b(includeIgnoreFile)\s*\([^)]*\)/g;
|
|
@@ -3422,11 +4005,11 @@ function readRootEslintIgnores(root) {
|
|
|
3422
4005
|
return { patterns: patterns.filter((pattern) => pattern.startsWith("**/")), unresolved };
|
|
3423
4006
|
}
|
|
3424
4007
|
function readEslintIgnores(cwd) {
|
|
3425
|
-
const config = ESLINT_CONFIG_FILES.map((name) =>
|
|
4008
|
+
const config = ESLINT_CONFIG_FILES.map((name) => join19(cwd, name)).find((path) => existsSync17(path));
|
|
3426
4009
|
if (!config) return { patterns: [], unresolved: [] };
|
|
3427
4010
|
let source;
|
|
3428
4011
|
try {
|
|
3429
|
-
source =
|
|
4012
|
+
source = readFileSync15(config, "utf8");
|
|
3430
4013
|
} catch {
|
|
3431
4014
|
return { patterns: [], unresolved: [] };
|
|
3432
4015
|
}
|
|
@@ -3480,8 +4063,8 @@ function lintPresetFor(preset) {
|
|
|
3480
4063
|
}
|
|
3481
4064
|
|
|
3482
4065
|
// src/roles/lint/rename-suppressions.ts
|
|
3483
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
3484
|
-
import { join as
|
|
4066
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync16, statSync } from "fs";
|
|
4067
|
+
import { join as join20, relative as relative2 } from "path";
|
|
3485
4068
|
var SOURCE_EXTENSIONS = [
|
|
3486
4069
|
".ts",
|
|
3487
4070
|
".tsx",
|
|
@@ -3528,7 +4111,7 @@ function* sourceFiles(dir) {
|
|
|
3528
4111
|
return;
|
|
3529
4112
|
}
|
|
3530
4113
|
for (const entry of entries) {
|
|
3531
|
-
const full =
|
|
4114
|
+
const full = join20(dir, entry);
|
|
3532
4115
|
let isDirectory;
|
|
3533
4116
|
try {
|
|
3534
4117
|
isDirectory = statSync(full).isDirectory();
|
|
@@ -3548,7 +4131,7 @@ function findSuppressionRenames(cwd, renames) {
|
|
|
3548
4131
|
for (const file of sourceFiles(cwd)) {
|
|
3549
4132
|
let content;
|
|
3550
4133
|
try {
|
|
3551
|
-
content =
|
|
4134
|
+
content = readFileSync16(file, "utf8");
|
|
3552
4135
|
} catch {
|
|
3553
4136
|
continue;
|
|
3554
4137
|
}
|
|
@@ -3627,7 +4210,7 @@ function summariseByPlugin(rules) {
|
|
|
3627
4210
|
}
|
|
3628
4211
|
return [...counts.entries()].sort((left, right) => right[1] - left[1]).map(([plugin, count]) => `${count} ${plugin}`).join(", ");
|
|
3629
4212
|
}
|
|
3630
|
-
function
|
|
4213
|
+
function plan2(context) {
|
|
3631
4214
|
if (!hasLintPreset(context.preset)) {
|
|
3632
4215
|
return {
|
|
3633
4216
|
operations: [],
|
|
@@ -3676,7 +4259,7 @@ function plan(context) {
|
|
|
3676
4259
|
keys: removableDeps
|
|
3677
4260
|
});
|
|
3678
4261
|
}
|
|
3679
|
-
const eslintConfigs = ESLINT_CONFIG_FILES.filter((name) =>
|
|
4262
|
+
const eslintConfigs = ESLINT_CONFIG_FILES.filter((name) => existsSync18(join21(context.cwd, name)));
|
|
3680
4263
|
for (const name of eslintConfigs) operations.push({ kind: "delete", path: name });
|
|
3681
4264
|
operations.push(
|
|
3682
4265
|
...nxTargetOperations({
|
|
@@ -3774,7 +4357,7 @@ function lintScripts(cwd) {
|
|
|
3774
4357
|
function committedExtends(cwd) {
|
|
3775
4358
|
try {
|
|
3776
4359
|
const parsed = parseJsonc(
|
|
3777
|
-
|
|
4360
|
+
readFileSync17(join21(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
3778
4361
|
LINT_CONFIG_FILE
|
|
3779
4362
|
);
|
|
3780
4363
|
return Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : [];
|
|
@@ -3785,7 +4368,7 @@ function committedExtends(cwd) {
|
|
|
3785
4368
|
function committedIgnorePatterns(cwd) {
|
|
3786
4369
|
try {
|
|
3787
4370
|
const parsed = parseJsonc(
|
|
3788
|
-
|
|
4371
|
+
readFileSync17(join21(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
3789
4372
|
LINT_CONFIG_FILE
|
|
3790
4373
|
);
|
|
3791
4374
|
return Array.isArray(parsed.ignorePatterns) ? parsed.ignorePatterns.filter((entry) => typeof entry === "string") : [];
|
|
@@ -3797,7 +4380,7 @@ function moduleEslintDependencies(cwd) {
|
|
|
3797
4380
|
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/");
|
|
3798
4381
|
let manifest;
|
|
3799
4382
|
try {
|
|
3800
|
-
manifest = JSON.parse(
|
|
4383
|
+
manifest = JSON.parse(readFileSync17(join21(cwd, "package.json"), "utf8"));
|
|
3801
4384
|
} catch {
|
|
3802
4385
|
return [];
|
|
3803
4386
|
}
|
|
@@ -3856,7 +4439,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
3856
4439
|
* lines. The adapter stays the contract with the engine.
|
|
3857
4440
|
*/
|
|
3858
4441
|
plan(context) {
|
|
3859
|
-
return
|
|
4442
|
+
return plan2(context);
|
|
3860
4443
|
}
|
|
3861
4444
|
declaredPreset(cwd) {
|
|
3862
4445
|
return presetOfVariant(presetNameFromPath(readLintAdoption(cwd).preset));
|
|
@@ -3866,7 +4449,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
3866
4449
|
* verification run that follows is the one a developer reads.
|
|
3867
4450
|
*/
|
|
3868
4451
|
fixPass(ctx, oxlint, env) {
|
|
3869
|
-
const result =
|
|
4452
|
+
const result = spawnSync5(oxlint, ["-c", LINT_CONFIG_FILE, "--fix", "."], {
|
|
3870
4453
|
cwd: ctx.cwd,
|
|
3871
4454
|
encoding: "utf8",
|
|
3872
4455
|
env,
|
|
@@ -3916,20 +4499,20 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
3916
4499
|
* build the developer can see, rather than a silent half-adoption they cannot.
|
|
3917
4500
|
*/
|
|
3918
4501
|
writeModuleBaseline(ctx, oxlint, env) {
|
|
3919
|
-
const configPath =
|
|
3920
|
-
const baselinePath =
|
|
3921
|
-
if (!
|
|
4502
|
+
const configPath = join22(ctx.cwd, LINT_CONFIG_FILE);
|
|
4503
|
+
const baselinePath = join22(ctx.cwd, LINT_BASELINE_FILE);
|
|
4504
|
+
if (!existsSync19(configPath)) return;
|
|
3922
4505
|
let config;
|
|
3923
4506
|
try {
|
|
3924
4507
|
config = parseJsonc(
|
|
3925
|
-
|
|
4508
|
+
readFileSync18(configPath, "utf8"),
|
|
3926
4509
|
LINT_CONFIG_FILE
|
|
3927
4510
|
);
|
|
3928
4511
|
} catch {
|
|
3929
4512
|
return;
|
|
3930
4513
|
}
|
|
3931
4514
|
const current = Array.isArray(config.extends) ? config.extends : [];
|
|
3932
|
-
const measurePath =
|
|
4515
|
+
const measurePath = join22(ctx.cwd, LINT_MEASURE_FILE);
|
|
3933
4516
|
let measured;
|
|
3934
4517
|
try {
|
|
3935
4518
|
writeFileSync2(
|
|
@@ -3937,7 +4520,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
3937
4520
|
`${JSON.stringify({ ...config, extends: extendsWithBaseline(current, false) }, null, 2)}
|
|
3938
4521
|
`
|
|
3939
4522
|
);
|
|
3940
|
-
measured =
|
|
4523
|
+
measured = spawnSync5(
|
|
3941
4524
|
oxlint,
|
|
3942
4525
|
[
|
|
3943
4526
|
"-c",
|
|
@@ -3977,7 +4560,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
3977
4560
|
}
|
|
3978
4561
|
}
|
|
3979
4562
|
async run(ctx) {
|
|
3980
|
-
if (!
|
|
4563
|
+
if (!existsSync19(join22(ctx.cwd, LINT_CONFIG_FILE))) {
|
|
3981
4564
|
process.stderr.write(
|
|
3982
4565
|
`sentinel lint(oxlint): no ${LINT_CONFIG_FILE} in this module; run \`sentinel --init --lint\` to adopt.
|
|
3983
4566
|
`
|
|
@@ -4024,7 +4607,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
4024
4607
|
const targets = paths.length > 0 ? paths : ["."];
|
|
4025
4608
|
const lint = (extra) => {
|
|
4026
4609
|
const passed = [...extra, ...passedOptions];
|
|
4027
|
-
const result =
|
|
4610
|
+
const result = spawnSync5(oxlint, ["-c", LINT_CONFIG_FILE, ...passed, ...targets], {
|
|
4028
4611
|
cwd: ctx.cwd,
|
|
4029
4612
|
stdio: "inherit",
|
|
4030
4613
|
env
|
|
@@ -4097,7 +4680,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
4097
4680
|
let stub;
|
|
4098
4681
|
try {
|
|
4099
4682
|
stub = parseJsonc(
|
|
4100
|
-
|
|
4683
|
+
readFileSync18(join22(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
4101
4684
|
LINT_CONFIG_FILE
|
|
4102
4685
|
);
|
|
4103
4686
|
} catch {
|
|
@@ -4107,7 +4690,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
4107
4690
|
for (const entry of stub.extends ?? []) {
|
|
4108
4691
|
try {
|
|
4109
4692
|
const preset = parseJsonc(
|
|
4110
|
-
|
|
4693
|
+
readFileSync18(join22(cwd, entry), "utf8"),
|
|
4111
4694
|
entry
|
|
4112
4695
|
);
|
|
4113
4696
|
for (const rule of Object.keys(preset.rules ?? {})) names.add(rule);
|
|
@@ -4124,7 +4707,7 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
4124
4707
|
const oxlint = resolveOxlint(ctx.cwd);
|
|
4125
4708
|
if (!oxlint) return { ok: false, code: 1, metrics: { error: "oxlint not found" } };
|
|
4126
4709
|
const typeAware = canRunTypeAware(ctx.cwd) ? ["--type-aware"] : [];
|
|
4127
|
-
const result =
|
|
4710
|
+
const result = spawnSync5(oxlint, ["-c", LINT_CONFIG_FILE, ...typeAware, "-f", "json", "."], {
|
|
4128
4711
|
cwd: ctx.cwd,
|
|
4129
4712
|
encoding: "utf8",
|
|
4130
4713
|
env: { ...process.env, PATH: oxlintPath(ctx.cwd, process.env) },
|
|
@@ -4177,14 +4760,14 @@ var OxlintAdapter = class extends BaseAdapter {
|
|
|
4177
4760
|
let parsed;
|
|
4178
4761
|
try {
|
|
4179
4762
|
parsed = parseJsonc(
|
|
4180
|
-
|
|
4763
|
+
readFileSync18(join22(cwd, LINT_CONFIG_FILE), "utf8"),
|
|
4181
4764
|
LINT_CONFIG_FILE
|
|
4182
4765
|
);
|
|
4183
4766
|
} catch {
|
|
4184
4767
|
return void 0;
|
|
4185
4768
|
}
|
|
4186
4769
|
const targets = Array.isArray(parsed.extends) ? parsed.extends.filter((entry) => typeof entry === "string") : typeof parsed.extends === "string" ? [parsed.extends] : [];
|
|
4187
|
-
return targets.find((target) => !
|
|
4770
|
+
return targets.find((target) => !existsSync19(join22(cwd, target)));
|
|
4188
4771
|
}
|
|
4189
4772
|
/** Announce what is not enforced, so reduced coverage is never silent. */
|
|
4190
4773
|
announceDisabled(preset) {
|
|
@@ -4215,10 +4798,10 @@ function registerLint() {
|
|
|
4215
4798
|
}
|
|
4216
4799
|
|
|
4217
4800
|
// src/roles/typescript/adapters/tsc/tsc.adapter.ts
|
|
4218
|
-
import { spawnSync as
|
|
4219
|
-
import { existsSync as
|
|
4801
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
4802
|
+
import { existsSync as existsSync20, readFileSync as readFileSync20 } from "fs";
|
|
4220
4803
|
import { createRequire as createRequire4 } from "module";
|
|
4221
|
-
import { join as
|
|
4804
|
+
import { join as join24 } from "path";
|
|
4222
4805
|
|
|
4223
4806
|
// src/roles/typescript/presets/base.json
|
|
4224
4807
|
var base_default3 = {
|
|
@@ -4382,7 +4965,7 @@ function resolveTsconfigTarget(moduleDir) {
|
|
|
4382
4965
|
}
|
|
4383
4966
|
|
|
4384
4967
|
// src/roles/typescript/read-adoption.ts
|
|
4385
|
-
var SENTINEL_PRESET = /^@hublo\/sentinel\/tsconfig\/[a-z-]+$/;
|
|
4968
|
+
var SENTINEL_PRESET = /^@hublo\/sentinel\/(?:typescript|tsconfig)\/[a-z-]+$/;
|
|
4386
4969
|
function readTsconfigAdoption(cwd) {
|
|
4387
4970
|
return readAdoption(cwd, {
|
|
4388
4971
|
candidates: TSCONFIG_CANDIDATES,
|
|
@@ -4399,8 +4982,8 @@ function readTsconfigAdoption(cwd) {
|
|
|
4399
4982
|
}
|
|
4400
4983
|
|
|
4401
4984
|
// src/roles/typescript/adapters/tsc/plan.ts
|
|
4402
|
-
import { readFileSync as
|
|
4403
|
-
import { join as
|
|
4985
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
4986
|
+
import { join as join23 } from "path";
|
|
4404
4987
|
|
|
4405
4988
|
// src/roles/typescript/typecheck-script.ts
|
|
4406
4989
|
var SENTINEL_TYPECHECK_COMMAND = "sentinel --run --typescript";
|
|
@@ -4434,9 +5017,11 @@ function typecheckScripts(cwd) {
|
|
|
4434
5017
|
[TYPECHECK_SCRIPT_NAME]: composeTypecheckScript(existingCommand(cwd, TYPECHECK_SCRIPT_NAME))
|
|
4435
5018
|
};
|
|
4436
5019
|
}
|
|
5020
|
+
var SENTINEL_TS_PRESET = /@hublo\/sentinel\/(?:typescript|tsconfig)\//;
|
|
4437
5021
|
function composeExtends(current, preset) {
|
|
4438
5022
|
const chain = typeof current === "string" ? [current] : Array.isArray(current) ? current.filter((entry) => typeof entry === "string") : [];
|
|
4439
|
-
|
|
5023
|
+
const withoutOwn = chain.filter((entry) => entry !== preset && !SENTINEL_TS_PRESET.test(entry));
|
|
5024
|
+
return [...withoutOwn, preset];
|
|
4440
5025
|
}
|
|
4441
5026
|
function declaredPreset(cwd) {
|
|
4442
5027
|
const { preset } = readTsconfigAdoption(cwd);
|
|
@@ -4465,7 +5050,7 @@ function planAdoption(context) {
|
|
|
4465
5050
|
};
|
|
4466
5051
|
}
|
|
4467
5052
|
const target = resolveTsconfigTarget(context.cwd);
|
|
4468
|
-
const preset = `@hublo/sentinel/
|
|
5053
|
+
const preset = `@hublo/sentinel/typescript/${context.preset}`;
|
|
4469
5054
|
const addScript = manifestOperation(context.cwd, typecheckScripts(context.cwd));
|
|
4470
5055
|
const nxTargets = nxTargetOperations({
|
|
4471
5056
|
cwd: context.cwd,
|
|
@@ -4491,7 +5076,7 @@ function planAdoption(context) {
|
|
|
4491
5076
|
};
|
|
4492
5077
|
}
|
|
4493
5078
|
const existing = parseJsonc(
|
|
4494
|
-
|
|
5079
|
+
readFileSync19(join23(context.cwd, target.path), "utf8"),
|
|
4495
5080
|
target.path
|
|
4496
5081
|
);
|
|
4497
5082
|
const extendsChain = composeExtends(existing.extends, preset);
|
|
@@ -4529,7 +5114,7 @@ function planAdoption(context) {
|
|
|
4529
5114
|
|
|
4530
5115
|
// src/roles/typescript/adapters/tsc/tsc.adapter.ts
|
|
4531
5116
|
var SENTINEL_PACKAGE = "@hublo/sentinel";
|
|
4532
|
-
var
|
|
5117
|
+
var SENTINEL_PRESET_SCOPES = [`${SENTINEL_PACKAGE}/typescript/`, `${SENTINEL_PACKAGE}/tsconfig/`];
|
|
4533
5118
|
var DIAGNOSTIC_RE = /^(.+?)\((\d+),(\d+)\): error (TS\d+): (.+)$/;
|
|
4534
5119
|
function parseDiagnostics(output) {
|
|
4535
5120
|
const diagnostics = [];
|
|
@@ -4629,7 +5214,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4629
5214
|
let chain;
|
|
4630
5215
|
try {
|
|
4631
5216
|
const parsed = parseJsonc(
|
|
4632
|
-
|
|
5217
|
+
readFileSync20(join24(cwd, target.path), "utf8"),
|
|
4633
5218
|
target.path
|
|
4634
5219
|
);
|
|
4635
5220
|
chain = parsed.extends;
|
|
@@ -4638,11 +5223,11 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4638
5223
|
}
|
|
4639
5224
|
const entries = typeof chain === "string" ? [chain] : Array.isArray(chain) ? chain : [];
|
|
4640
5225
|
const preset = entries.find(
|
|
4641
|
-
(entry) => typeof entry === "string" && entry.startsWith(
|
|
5226
|
+
(entry) => typeof entry === "string" && SENTINEL_PRESET_SCOPES.some((scope) => entry.startsWith(scope))
|
|
4642
5227
|
);
|
|
4643
5228
|
if (preset === void 0) return void 0;
|
|
4644
5229
|
try {
|
|
4645
|
-
createRequire4(
|
|
5230
|
+
createRequire4(join24(cwd, "noop.js")).resolve(preset);
|
|
4646
5231
|
return void 0;
|
|
4647
5232
|
} catch {
|
|
4648
5233
|
return preset;
|
|
@@ -4683,7 +5268,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4683
5268
|
return { ok: false, code: 1 };
|
|
4684
5269
|
}
|
|
4685
5270
|
if (options.length > 0) return this.runWithOptions(ctx, tsc, config);
|
|
4686
|
-
const result =
|
|
5271
|
+
const result = spawnSync6(tsc, ["-b", config], { cwd: ctx.cwd, stdio: "inherit" });
|
|
4687
5272
|
if (result.error) {
|
|
4688
5273
|
process.stderr.write(
|
|
4689
5274
|
`sentinel typescript(tsc): could not run tsc (${result.error.message}); is TypeScript installed in the module?
|
|
@@ -4718,7 +5303,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4718
5303
|
let worst = 0;
|
|
4719
5304
|
for (const project of this.referencedProjects(ctx.cwd, config)) {
|
|
4720
5305
|
const args = ["-p", project, "--noEmit", "--composite", "false", ...ctx.toolArgs ?? []];
|
|
4721
|
-
const result =
|
|
5306
|
+
const result = spawnSync6(tsc, args, { cwd: ctx.cwd, stdio: "inherit" });
|
|
4722
5307
|
if (result.error) {
|
|
4723
5308
|
process.stderr.write(
|
|
4724
5309
|
`sentinel typescript(tsc): could not run tsc (${result.error.message}); is TypeScript installed in the module?
|
|
@@ -4738,7 +5323,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4738
5323
|
referencedProjects(cwd, config) {
|
|
4739
5324
|
try {
|
|
4740
5325
|
const parsed = parseJsonc(
|
|
4741
|
-
|
|
5326
|
+
readFileSync20(join24(cwd, config), "utf8"),
|
|
4742
5327
|
config
|
|
4743
5328
|
);
|
|
4744
5329
|
const referenced = (parsed.references ?? []).map((reference) => reference.path).filter((path) => typeof path === "string" && path.length > 0);
|
|
@@ -4754,7 +5339,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4754
5339
|
* check.
|
|
4755
5340
|
*/
|
|
4756
5341
|
typecheckTarget(cwd) {
|
|
4757
|
-
if (
|
|
5342
|
+
if (existsSync20(join24(cwd, "tsconfig.json"))) return "tsconfig.json";
|
|
4758
5343
|
const target = resolveTsconfigTarget(cwd);
|
|
4759
5344
|
return target.reason === "none" ? null : target.path;
|
|
4760
5345
|
}
|
|
@@ -4807,7 +5392,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4807
5392
|
return { ok: true, code: 0, metrics: _TscAdapter.NOTHING_TO_REPORT };
|
|
4808
5393
|
}
|
|
4809
5394
|
const tsc = resolveBin(ctx.cwd, "tsc") ?? "tsc";
|
|
4810
|
-
const result =
|
|
5395
|
+
const result = spawnSync6(tsc, ["-b", config], { cwd: ctx.cwd, encoding: "utf8" });
|
|
4811
5396
|
if (result.error) {
|
|
4812
5397
|
process.stderr.write(
|
|
4813
5398
|
`sentinel typescript(tsc): could not run tsc (${result.error.message}); is TypeScript installed in the module?
|
|
@@ -4850,7 +5435,7 @@ var TscAdapter = class _TscAdapter extends BaseAdapter {
|
|
|
4850
5435
|
* errors in the output mean the rule must be on.
|
|
4851
5436
|
*/
|
|
4852
5437
|
noImplicitAnyEnabled(cwd, tsc, config, mainOutput) {
|
|
4853
|
-
const shown =
|
|
5438
|
+
const shown = spawnSync6(tsc, ["-p", config, "--showConfig"], { cwd, encoding: "utf8" });
|
|
4854
5439
|
if (shown.status === 0 && shown.stdout) {
|
|
4855
5440
|
try {
|
|
4856
5441
|
const co = parseJsonc(
|
|
@@ -4876,6 +5461,7 @@ function registerAdapters() {
|
|
|
4876
5461
|
registerTypescript();
|
|
4877
5462
|
registerLint();
|
|
4878
5463
|
registerFormat();
|
|
5464
|
+
registerBuild();
|
|
4879
5465
|
}
|
|
4880
5466
|
|
|
4881
5467
|
// src/core/detect-framework.ts
|
|
@@ -4957,16 +5543,9 @@ function replaceLines(current, replacements) {
|
|
|
4957
5543
|
}
|
|
4958
5544
|
|
|
4959
5545
|
// src/core/apply-plan.ts
|
|
4960
|
-
import { existsSync as
|
|
5546
|
+
import { existsSync as existsSync21, readFileSync as readFileSync21, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
4961
5547
|
import { resolve as resolve4, sep } from "path";
|
|
4962
5548
|
import { applyEdits, findNodeAtLocation, modify, parseTree } from "jsonc-parser";
|
|
4963
|
-
|
|
4964
|
-
// src/shared/deep-merge.ts
|
|
4965
|
-
function isPlainObject(value) {
|
|
4966
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4967
|
-
}
|
|
4968
|
-
|
|
4969
|
-
// src/core/apply-plan.ts
|
|
4970
5549
|
function resolveWithinRoot(cwd, relativePath) {
|
|
4971
5550
|
const root = resolve4(cwd);
|
|
4972
5551
|
const absolutePath = resolve4(root, relativePath);
|
|
@@ -4976,7 +5555,7 @@ function resolveWithinRoot(cwd, relativePath) {
|
|
|
4976
5555
|
return absolutePath;
|
|
4977
5556
|
}
|
|
4978
5557
|
function readIfExists(absolutePath) {
|
|
4979
|
-
return
|
|
5558
|
+
return existsSync21(absolutePath) ? readFileSync21(absolutePath, "utf8") : void 0;
|
|
4980
5559
|
}
|
|
4981
5560
|
function* leaves(value, prefix = []) {
|
|
4982
5561
|
for (const [key, keyValue] of Object.entries(value)) {
|
|
@@ -5057,9 +5636,9 @@ function applyOperationTo(current, operation) {
|
|
|
5057
5636
|
}
|
|
5058
5637
|
}
|
|
5059
5638
|
}
|
|
5060
|
-
function preparePlan(cwd,
|
|
5639
|
+
function preparePlan(cwd, plan3) {
|
|
5061
5640
|
const prepared = /* @__PURE__ */ new Map();
|
|
5062
|
-
for (const operation of
|
|
5641
|
+
for (const operation of plan3.operations) {
|
|
5063
5642
|
const absolutePath = resolveWithinRoot(cwd, operation.path);
|
|
5064
5643
|
const existing = prepared.get(operation.path);
|
|
5065
5644
|
const before = existing?.before ?? readIfExists(absolutePath) ?? "";
|
|
@@ -5081,8 +5660,8 @@ function writeFileAtomic(absolutePath, contents) {
|
|
|
5081
5660
|
writeFileSync3(tempPath, contents);
|
|
5082
5661
|
renameSync(tempPath, absolutePath);
|
|
5083
5662
|
}
|
|
5084
|
-
function applyPlan(cwd,
|
|
5085
|
-
const changed = preparePlan(cwd,
|
|
5663
|
+
function applyPlan(cwd, plan3) {
|
|
5664
|
+
const changed = preparePlan(cwd, plan3).filter((file) => file.before !== file.after);
|
|
5086
5665
|
for (const file of changed) {
|
|
5087
5666
|
if (file.deleted) {
|
|
5088
5667
|
rmSync2(file.absolutePath, { force: true });
|
|
@@ -5094,8 +5673,8 @@ function applyPlan(cwd, plan2) {
|
|
|
5094
5673
|
}
|
|
5095
5674
|
|
|
5096
5675
|
// src/core/config/preset-evidence.ts
|
|
5097
|
-
import { existsSync as
|
|
5098
|
-
import { join as
|
|
5676
|
+
import { existsSync as existsSync22, readdirSync as readdirSync3, readFileSync as readFileSync22 } from "fs";
|
|
5677
|
+
import { join as join25 } from "path";
|
|
5099
5678
|
var PATH_SIGNALS = [
|
|
5100
5679
|
{
|
|
5101
5680
|
preset: "nest",
|
|
@@ -5109,11 +5688,11 @@ var DEPENDENCY_SIGNALS = [
|
|
|
5109
5688
|
{ preset: "nest", pattern: /^@nestjs\// }
|
|
5110
5689
|
];
|
|
5111
5690
|
function dependencyNames(cwd) {
|
|
5112
|
-
const path =
|
|
5113
|
-
if (!
|
|
5691
|
+
const path = join25(cwd, "package.json");
|
|
5692
|
+
if (!existsSync22(path)) return [];
|
|
5114
5693
|
try {
|
|
5115
5694
|
const manifest = parseJsonc(
|
|
5116
|
-
|
|
5695
|
+
readFileSync22(path, "utf8"),
|
|
5117
5696
|
path
|
|
5118
5697
|
);
|
|
5119
5698
|
return [
|
|
@@ -5136,7 +5715,7 @@ function declaresJsx(cwd) {
|
|
|
5136
5715
|
for (const name of entries) {
|
|
5137
5716
|
try {
|
|
5138
5717
|
const config = parseJsonc(
|
|
5139
|
-
|
|
5718
|
+
readFileSync22(join25(cwd, name), "utf8"),
|
|
5140
5719
|
name
|
|
5141
5720
|
);
|
|
5142
5721
|
if (config.compilerOptions?.jsx !== void 0) return true;
|
|
@@ -5187,14 +5766,14 @@ function resolveFlavour(opts) {
|
|
|
5187
5766
|
}
|
|
5188
5767
|
return detection.preset;
|
|
5189
5768
|
}
|
|
5190
|
-
function previewPlan(opts,
|
|
5191
|
-
const changed = preparePlan(opts.cwd,
|
|
5769
|
+
function previewPlan(opts, plan3) {
|
|
5770
|
+
const changed = preparePlan(opts.cwd, plan3).filter((file) => file.before !== file.after);
|
|
5192
5771
|
if (opts.json) {
|
|
5193
5772
|
process.stdout.write(
|
|
5194
5773
|
JSON.stringify(
|
|
5195
5774
|
{
|
|
5196
5775
|
dryRun: true,
|
|
5197
|
-
notes:
|
|
5776
|
+
notes: plan3.notes ?? [],
|
|
5198
5777
|
files: changed.map(({ path, before, after, deleted }) => ({
|
|
5199
5778
|
path,
|
|
5200
5779
|
action: deleted ? "delete" : before.length === 0 ? "create" : "update",
|
|
@@ -5209,7 +5788,7 @@ function previewPlan(opts, plan2) {
|
|
|
5209
5788
|
return 0;
|
|
5210
5789
|
}
|
|
5211
5790
|
process.stderr.write(" dry run: no files written\n");
|
|
5212
|
-
for (const note of
|
|
5791
|
+
for (const note of plan3.notes ?? []) process.stderr.write(` ${note}
|
|
5213
5792
|
`);
|
|
5214
5793
|
if (changed.length === 0) {
|
|
5215
5794
|
process.stderr.write(" nothing to change\n");
|
|
@@ -5230,7 +5809,8 @@ async function dispatch(opts) {
|
|
|
5230
5809
|
throw new Error(`dispatch handles --init only; --${opts.verb} routes through analyse()`);
|
|
5231
5810
|
}
|
|
5232
5811
|
const detected = resolveFlavour(opts);
|
|
5233
|
-
const
|
|
5812
|
+
const resolutionPreset = opts.preset ?? declaredPresetFor(opts.target, opts.cwd) ?? detected;
|
|
5813
|
+
const adapter = resolve(opts.target, resolutionPreset, opts.runner);
|
|
5234
5814
|
const preset = opts.preset ?? adapter.declaredPreset?.(opts.cwd) ?? detected;
|
|
5235
5815
|
const contradiction = presetContradiction(preset, opts.cwd);
|
|
5236
5816
|
if (contradiction !== void 0) {
|
|
@@ -5239,25 +5819,25 @@ async function dispatch(opts) {
|
|
|
5239
5819
|
return 1;
|
|
5240
5820
|
}
|
|
5241
5821
|
const context = { cwd: opts.cwd, preset };
|
|
5242
|
-
const
|
|
5243
|
-
if (
|
|
5244
|
-
process.stderr.write(`sentinel (${opts.target}): ${
|
|
5822
|
+
const plan3 = await adapter.plan(context);
|
|
5823
|
+
if (plan3.blocked) {
|
|
5824
|
+
process.stderr.write(`sentinel (${opts.target}): ${plan3.blocked}
|
|
5245
5825
|
`);
|
|
5246
5826
|
return 1;
|
|
5247
5827
|
}
|
|
5248
|
-
if (
|
|
5249
|
-
process.stderr.write(` ${palette(process.stderr).dim(`${opts.target}: ${
|
|
5828
|
+
if (plan3.skipped) {
|
|
5829
|
+
process.stderr.write(` ${palette(process.stderr).dim(`${opts.target}: ${plan3.skipped}`)}
|
|
5250
5830
|
`);
|
|
5251
5831
|
return 0;
|
|
5252
5832
|
}
|
|
5253
5833
|
if (opts.dryRun) {
|
|
5254
|
-
return previewPlan(opts,
|
|
5834
|
+
return previewPlan(opts, plan3);
|
|
5255
5835
|
}
|
|
5256
|
-
for (const change of applyPlan(opts.cwd,
|
|
5836
|
+
for (const change of applyPlan(opts.cwd, plan3)) {
|
|
5257
5837
|
process.stderr.write(` ${change.deleted ? "removed" : "wrote"} ${change.path}
|
|
5258
5838
|
`);
|
|
5259
5839
|
}
|
|
5260
|
-
for (const note of
|
|
5840
|
+
for (const note of plan3.notes ?? []) process.stderr.write(` ${note}
|
|
5261
5841
|
`);
|
|
5262
5842
|
if (adapter.afterInit) {
|
|
5263
5843
|
process.stderr.write(` fixing what ${opts.target} can fix automatically...
|
|
@@ -5274,12 +5854,15 @@ async function dispatch(opts) {
|
|
|
5274
5854
|
}
|
|
5275
5855
|
|
|
5276
5856
|
export {
|
|
5857
|
+
PresetUnsupportedError,
|
|
5277
5858
|
register,
|
|
5278
5859
|
setDefaultRunner,
|
|
5279
5860
|
all,
|
|
5861
|
+
declaredPresetFor,
|
|
5280
5862
|
availableTargets,
|
|
5281
5863
|
resolve,
|
|
5282
5864
|
BaseAdapter,
|
|
5865
|
+
resolveBin,
|
|
5283
5866
|
readOwnVersion,
|
|
5284
5867
|
readProjectPackageJson,
|
|
5285
5868
|
readNxProjectName,
|
|
@@ -5288,13 +5871,13 @@ export {
|
|
|
5288
5871
|
ensureWorkspacePrep,
|
|
5289
5872
|
inspectWorkspacePrep,
|
|
5290
5873
|
palette,
|
|
5291
|
-
resolveBin,
|
|
5292
5874
|
VERBS,
|
|
5293
5875
|
TARGETS,
|
|
5876
|
+
SWEEPABLE_TARGETS,
|
|
5294
5877
|
PRESET_NAMES,
|
|
5295
5878
|
registerAdapters,
|
|
5296
5879
|
describeFramework,
|
|
5297
5880
|
detectFramework,
|
|
5298
5881
|
dispatch
|
|
5299
5882
|
};
|
|
5300
|
-
//# sourceMappingURL=chunk-
|
|
5883
|
+
//# sourceMappingURL=chunk-TWL6T237.js.map
|