@hublo/sentinel 1.5.1-alpha.1 → 1.5.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/sentinel.js +3 -3
- package/dist/{chunk-64H5HBPH.js → chunk-JHLNNIZC.js} +154 -119
- package/dist/{chunk-J2USE3KV.js → chunk-P7NYSMLS.js} +675 -2
- package/dist/index.js +2 -2
- package/dist/{validate-TIPIECG6.js → validate-5SD5CTTO.js} +1 -1
- package/docs/lint-adoption.md +16 -1
- package/docs/validating-a-change.md +42 -1
- package/package.json +1 -1
package/dist/bin/sentinel.js
CHANGED
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
presetNotInstalledYet,
|
|
12
12
|
registerAdapters,
|
|
13
13
|
resolve
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-JHLNNIZC.js";
|
|
15
15
|
import {
|
|
16
16
|
resolveContext
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-P7NYSMLS.js";
|
|
18
18
|
import {
|
|
19
19
|
ensureWorkspacePrep,
|
|
20
20
|
findWorkspaceRoot,
|
|
@@ -527,7 +527,7 @@ async function runValidate(ctx) {
|
|
|
527
527
|
);
|
|
528
528
|
}
|
|
529
529
|
if (!ctx.targets.includes("test")) return 1;
|
|
530
|
-
const { validateModuleTests } = await import("../validate-
|
|
530
|
+
const { validateModuleTests } = await import("../validate-5SD5CTTO.js");
|
|
531
531
|
const outcomes = modules.flatMap(
|
|
532
532
|
(module) => validateModuleTests(module.name, module.root)
|
|
533
533
|
);
|
|
@@ -20,7 +20,9 @@ import {
|
|
|
20
20
|
binFromOwnInstall,
|
|
21
21
|
binSearchPath,
|
|
22
22
|
canRunTypeAware,
|
|
23
|
+
canonicalRuleName,
|
|
23
24
|
describeHolds,
|
|
25
|
+
describeRuleKey,
|
|
24
26
|
extendsWithBaseline,
|
|
25
27
|
extendsWithPreset,
|
|
26
28
|
formatPresetFor,
|
|
@@ -57,7 +59,7 @@ import {
|
|
|
57
59
|
splitToolArgs,
|
|
58
60
|
walk,
|
|
59
61
|
writtenFileFormatter
|
|
60
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-P7NYSMLS.js";
|
|
61
63
|
import {
|
|
62
64
|
DEFAULT_MAX_DIAGNOSTICS,
|
|
63
65
|
WORKSPACE_ROOT_MARKER,
|
|
@@ -4587,6 +4589,19 @@ function validate(preset, rules) {
|
|
|
4587
4589
|
}
|
|
4588
4590
|
}
|
|
4589
4591
|
}
|
|
4592
|
+
function rejectTwoSpellings(label, rules) {
|
|
4593
|
+
const seen = /* @__PURE__ */ new Map();
|
|
4594
|
+
for (const rule of Object.keys(rules)) {
|
|
4595
|
+
const canonical = canonicalRuleName(rule);
|
|
4596
|
+
const other = seen.get(canonical);
|
|
4597
|
+
if (other !== void 0) {
|
|
4598
|
+
throw new Error(
|
|
4599
|
+
`${label}: "${other}" and "${rule}" are the same rule to oxlint (${canonical}). Configure it once, under one name: oxlint keeps both and picks one by hash order.`
|
|
4600
|
+
);
|
|
4601
|
+
}
|
|
4602
|
+
seen.set(canonical, rule);
|
|
4603
|
+
}
|
|
4604
|
+
}
|
|
4590
4605
|
function layered(preset) {
|
|
4591
4606
|
const base = sharedRules();
|
|
4592
4607
|
const layer = presetRules(preset);
|
|
@@ -4596,6 +4611,7 @@ function layered(preset) {
|
|
|
4596
4611
|
}
|
|
4597
4612
|
function toRuleMap(label, rules) {
|
|
4598
4613
|
validate(label, rules);
|
|
4614
|
+
rejectTwoSpellings(label, rules);
|
|
4599
4615
|
const entries = Object.entries(rules).map(([rule, value]) => {
|
|
4600
4616
|
if (!isDecision(value)) return [rule, value];
|
|
4601
4617
|
const options = value.options ?? [];
|
|
@@ -4663,6 +4679,110 @@ function committedExtendsList(cwd, configFile) {
|
|
|
4663
4679
|
}
|
|
4664
4680
|
}
|
|
4665
4681
|
|
|
4682
|
+
// src/roles/lint/module-own-config.ts
|
|
4683
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4684
|
+
function pluginKey(entry) {
|
|
4685
|
+
if (typeof entry === "string") return entry;
|
|
4686
|
+
if (isRecord(entry) && typeof entry.name === "string") return entry.name;
|
|
4687
|
+
if (isRecord(entry) && typeof entry.specifier === "string") return entry.specifier;
|
|
4688
|
+
return void 0;
|
|
4689
|
+
}
|
|
4690
|
+
function governedRuleNames(preset) {
|
|
4691
|
+
return /* @__PURE__ */ new Set([
|
|
4692
|
+
...Object.keys(preset.rules),
|
|
4693
|
+
...(preset.overrides ?? []).flatMap((override) => Object.keys(override.rules))
|
|
4694
|
+
]);
|
|
4695
|
+
}
|
|
4696
|
+
function governedRules(preset) {
|
|
4697
|
+
const governed = /* @__PURE__ */ new Map();
|
|
4698
|
+
for (const name of governedRuleNames(preset)) {
|
|
4699
|
+
const canonical = canonicalRuleName(name);
|
|
4700
|
+
if (!governed.has(canonical)) governed.set(canonical, name);
|
|
4701
|
+
}
|
|
4702
|
+
return governed;
|
|
4703
|
+
}
|
|
4704
|
+
function moduleOwnBlocks(committed, preset) {
|
|
4705
|
+
const blocks = {};
|
|
4706
|
+
const kept = [];
|
|
4707
|
+
const dropped = [];
|
|
4708
|
+
if (Array.isArray(committed.plugins)) {
|
|
4709
|
+
const own = committed.plugins.filter(
|
|
4710
|
+
(name) => typeof name === "string" && !preset.plugins.includes(name)
|
|
4711
|
+
);
|
|
4712
|
+
if (own.length > 0) {
|
|
4713
|
+
blocks.plugins = own;
|
|
4714
|
+
kept.push(
|
|
4715
|
+
`kept this module's own plugins (${own.join(", ")}): the preset does not enable them`
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4718
|
+
}
|
|
4719
|
+
if (Array.isArray(committed.jsPlugins)) {
|
|
4720
|
+
const presetKeys = new Set(preset.jsPlugins.map((entry) => pluginKey(entry)));
|
|
4721
|
+
const own = [];
|
|
4722
|
+
for (const entry of committed.jsPlugins) {
|
|
4723
|
+
const key = pluginKey(entry);
|
|
4724
|
+
if (key !== void 0 && presetKeys.has(key)) dropped.push(`jsPlugins ${key}`);
|
|
4725
|
+
else own.push(entry);
|
|
4726
|
+
}
|
|
4727
|
+
if (own.length > 0) {
|
|
4728
|
+
blocks.jsPlugins = own;
|
|
4729
|
+
kept.push(
|
|
4730
|
+
`kept ${own.length} jsPlugin(s) this module added (${own.map((entry) => pluginKey(entry) ?? "?").join(", ")})`
|
|
4731
|
+
);
|
|
4732
|
+
}
|
|
4733
|
+
}
|
|
4734
|
+
if (isRecord(committed.settings)) {
|
|
4735
|
+
const presetSettings = preset.settings ?? {};
|
|
4736
|
+
const own = {};
|
|
4737
|
+
for (const [key, value] of Object.entries(committed.settings)) {
|
|
4738
|
+
if (key in presetSettings) dropped.push(`settings.${key}`);
|
|
4739
|
+
else own[key] = value;
|
|
4740
|
+
}
|
|
4741
|
+
if (Object.keys(own).length > 0) {
|
|
4742
|
+
blocks.settings = own;
|
|
4743
|
+
kept.push(`kept this module's own settings (${Object.keys(own).join(", ")})`);
|
|
4744
|
+
}
|
|
4745
|
+
}
|
|
4746
|
+
if (Array.isArray(committed.overrides)) {
|
|
4747
|
+
const governed = governedRules(preset);
|
|
4748
|
+
const byFiles = /* @__PURE__ */ new Map();
|
|
4749
|
+
for (const block of committed.overrides) {
|
|
4750
|
+
if (!isRecord(block) || !Array.isArray(block.files)) continue;
|
|
4751
|
+
const files = JSON.stringify([...block.files].map(String).sort());
|
|
4752
|
+
const rules = {};
|
|
4753
|
+
for (const [rule, value] of Object.entries(isRecord(block.rules) ? block.rules : {})) {
|
|
4754
|
+
const presetSpelling = governed.get(canonicalRuleName(rule));
|
|
4755
|
+
if (presetSpelling === void 0) rules[rule] = value;
|
|
4756
|
+
else
|
|
4757
|
+
dropped.push(
|
|
4758
|
+
`overrides[${block.files.join(", ")}] ${describeRuleKey(rule, presetSpelling)}`
|
|
4759
|
+
);
|
|
4760
|
+
}
|
|
4761
|
+
const { rules: _rules, ...rest } = block;
|
|
4762
|
+
const merged = byFiles.get(files);
|
|
4763
|
+
if (merged === void 0) {
|
|
4764
|
+
byFiles.set(files, { ...rest, ...Object.keys(rules).length > 0 ? { rules } : {} });
|
|
4765
|
+
continue;
|
|
4766
|
+
}
|
|
4767
|
+
const { files: _sameFiles, ...others } = rest;
|
|
4768
|
+
const mergedRules = { ...isRecord(merged.rules) ? merged.rules : {}, ...rules };
|
|
4769
|
+
Object.assign(
|
|
4770
|
+
merged,
|
|
4771
|
+
others,
|
|
4772
|
+
Object.keys(mergedRules).length > 0 ? { rules: mergedRules } : {}
|
|
4773
|
+
);
|
|
4774
|
+
}
|
|
4775
|
+
const own = [...byFiles.values()].filter((block) => Object.keys(block).length > 1);
|
|
4776
|
+
if (own.length > 0) {
|
|
4777
|
+
blocks.overrides = own;
|
|
4778
|
+
kept.push(
|
|
4779
|
+
`kept ${own.length} override block(s) this module set (${own.map((block) => block.files.join(", ")).join("; ")})`
|
|
4780
|
+
);
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
return { blocks, kept, dropped };
|
|
4784
|
+
}
|
|
4785
|
+
|
|
4666
4786
|
// src/roles/lint/parse-diagnostics.ts
|
|
4667
4787
|
function ruleId(code) {
|
|
4668
4788
|
const inner = /\(([^)]+)\)/.exec(code);
|
|
@@ -4712,6 +4832,26 @@ function errorCountsByConfigRule(stdout) {
|
|
|
4712
4832
|
return counts;
|
|
4713
4833
|
}
|
|
4714
4834
|
|
|
4835
|
+
// src/roles/lint/presets.ts
|
|
4836
|
+
var hasRuleData = (name) => GENERATED_LINT_PRESETS.includes(name);
|
|
4837
|
+
function lintPresetFor(preset) {
|
|
4838
|
+
const file = presetFile(preset);
|
|
4839
|
+
const resolved = hasRuleData(preset) ? preset : "node";
|
|
4840
|
+
return {
|
|
4841
|
+
plugins: file.plugins,
|
|
4842
|
+
jsPlugins: file.jsPlugins,
|
|
4843
|
+
...file.settings === null ? {} : { settings: file.settings },
|
|
4844
|
+
...file.renames ? { renames: file.renames } : {},
|
|
4845
|
+
...file.overrides ? {
|
|
4846
|
+
overrides: file.overrides.map((override, index) => ({
|
|
4847
|
+
files: override.files,
|
|
4848
|
+
rules: toRuleMap(`${preset} override ${index}`, override.rules)
|
|
4849
|
+
}))
|
|
4850
|
+
} : {},
|
|
4851
|
+
rules: rulesFor(resolved)
|
|
4852
|
+
};
|
|
4853
|
+
}
|
|
4854
|
+
|
|
4715
4855
|
// src/roles/lint/adapters/oxlint/plan.ts
|
|
4716
4856
|
import { existsSync as existsSync11, readFileSync as readFileSync13 } from "node:fs";
|
|
4717
4857
|
import { join as join16 } from "node:path";
|
|
@@ -4804,118 +4944,6 @@ function keepsOtherCommands3(script) {
|
|
|
4804
4944
|
return keepsOtherCommands(script, SENTINEL_LINT_COMMAND);
|
|
4805
4945
|
}
|
|
4806
4946
|
|
|
4807
|
-
// src/roles/lint/module-own-config.ts
|
|
4808
|
-
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4809
|
-
function pluginKey(entry) {
|
|
4810
|
-
if (typeof entry === "string") return entry;
|
|
4811
|
-
if (isRecord(entry) && typeof entry.name === "string") return entry.name;
|
|
4812
|
-
if (isRecord(entry) && typeof entry.specifier === "string") return entry.specifier;
|
|
4813
|
-
return void 0;
|
|
4814
|
-
}
|
|
4815
|
-
function governedRuleNames(preset) {
|
|
4816
|
-
return /* @__PURE__ */ new Set([
|
|
4817
|
-
...Object.keys(preset.rules),
|
|
4818
|
-
...(preset.overrides ?? []).flatMap((override) => Object.keys(override.rules))
|
|
4819
|
-
]);
|
|
4820
|
-
}
|
|
4821
|
-
function moduleOwnBlocks(committed, preset) {
|
|
4822
|
-
const blocks = {};
|
|
4823
|
-
const kept = [];
|
|
4824
|
-
const dropped = [];
|
|
4825
|
-
if (Array.isArray(committed.plugins)) {
|
|
4826
|
-
const own = committed.plugins.filter(
|
|
4827
|
-
(name) => typeof name === "string" && !preset.plugins.includes(name)
|
|
4828
|
-
);
|
|
4829
|
-
if (own.length > 0) {
|
|
4830
|
-
blocks.plugins = own;
|
|
4831
|
-
kept.push(
|
|
4832
|
-
`kept this module's own plugins (${own.join(", ")}): the preset does not enable them`
|
|
4833
|
-
);
|
|
4834
|
-
}
|
|
4835
|
-
}
|
|
4836
|
-
if (Array.isArray(committed.jsPlugins)) {
|
|
4837
|
-
const presetKeys = new Set(preset.jsPlugins.map((entry) => pluginKey(entry)));
|
|
4838
|
-
const own = [];
|
|
4839
|
-
for (const entry of committed.jsPlugins) {
|
|
4840
|
-
const key = pluginKey(entry);
|
|
4841
|
-
if (key !== void 0 && presetKeys.has(key)) dropped.push(`jsPlugins ${key}`);
|
|
4842
|
-
else own.push(entry);
|
|
4843
|
-
}
|
|
4844
|
-
if (own.length > 0) {
|
|
4845
|
-
blocks.jsPlugins = own;
|
|
4846
|
-
kept.push(
|
|
4847
|
-
`kept ${own.length} jsPlugin(s) this module added (${own.map((entry) => pluginKey(entry) ?? "?").join(", ")})`
|
|
4848
|
-
);
|
|
4849
|
-
}
|
|
4850
|
-
}
|
|
4851
|
-
if (isRecord(committed.settings)) {
|
|
4852
|
-
const presetSettings = preset.settings ?? {};
|
|
4853
|
-
const own = {};
|
|
4854
|
-
for (const [key, value] of Object.entries(committed.settings)) {
|
|
4855
|
-
if (key in presetSettings) dropped.push(`settings.${key}`);
|
|
4856
|
-
else own[key] = value;
|
|
4857
|
-
}
|
|
4858
|
-
if (Object.keys(own).length > 0) {
|
|
4859
|
-
blocks.settings = own;
|
|
4860
|
-
kept.push(`kept this module's own settings (${Object.keys(own).join(", ")})`);
|
|
4861
|
-
}
|
|
4862
|
-
}
|
|
4863
|
-
if (Array.isArray(committed.overrides)) {
|
|
4864
|
-
const governed = governedRuleNames(preset);
|
|
4865
|
-
const byFiles = /* @__PURE__ */ new Map();
|
|
4866
|
-
for (const block of committed.overrides) {
|
|
4867
|
-
if (!isRecord(block) || !Array.isArray(block.files)) continue;
|
|
4868
|
-
const files = JSON.stringify([...block.files].map(String).sort());
|
|
4869
|
-
const rules = {};
|
|
4870
|
-
for (const [rule, value] of Object.entries(isRecord(block.rules) ? block.rules : {})) {
|
|
4871
|
-
if (governed.has(rule)) dropped.push(`overrides[${block.files.join(", ")}] ${rule}`);
|
|
4872
|
-
else rules[rule] = value;
|
|
4873
|
-
}
|
|
4874
|
-
const { rules: _rules, ...rest } = block;
|
|
4875
|
-
const merged = byFiles.get(files);
|
|
4876
|
-
if (merged === void 0) {
|
|
4877
|
-
byFiles.set(files, { ...rest, ...Object.keys(rules).length > 0 ? { rules } : {} });
|
|
4878
|
-
continue;
|
|
4879
|
-
}
|
|
4880
|
-
const { files: _sameFiles, ...others } = rest;
|
|
4881
|
-
const mergedRules = { ...isRecord(merged.rules) ? merged.rules : {}, ...rules };
|
|
4882
|
-
Object.assign(
|
|
4883
|
-
merged,
|
|
4884
|
-
others,
|
|
4885
|
-
Object.keys(mergedRules).length > 0 ? { rules: mergedRules } : {}
|
|
4886
|
-
);
|
|
4887
|
-
}
|
|
4888
|
-
const own = [...byFiles.values()].filter((block) => Object.keys(block).length > 1);
|
|
4889
|
-
if (own.length > 0) {
|
|
4890
|
-
blocks.overrides = own;
|
|
4891
|
-
kept.push(
|
|
4892
|
-
`kept ${own.length} override block(s) this module set (${own.map((block) => block.files.join(", ")).join("; ")})`
|
|
4893
|
-
);
|
|
4894
|
-
}
|
|
4895
|
-
}
|
|
4896
|
-
return { blocks, kept, dropped };
|
|
4897
|
-
}
|
|
4898
|
-
|
|
4899
|
-
// src/roles/lint/presets.ts
|
|
4900
|
-
var hasRuleData = (name) => GENERATED_LINT_PRESETS.includes(name);
|
|
4901
|
-
function lintPresetFor(preset) {
|
|
4902
|
-
const file = presetFile(preset);
|
|
4903
|
-
const resolved = hasRuleData(preset) ? preset : "node";
|
|
4904
|
-
return {
|
|
4905
|
-
plugins: file.plugins,
|
|
4906
|
-
jsPlugins: file.jsPlugins,
|
|
4907
|
-
...file.settings === null ? {} : { settings: file.settings },
|
|
4908
|
-
...file.renames ? { renames: file.renames } : {},
|
|
4909
|
-
...file.overrides ? {
|
|
4910
|
-
overrides: file.overrides.map((override, index) => ({
|
|
4911
|
-
files: override.files,
|
|
4912
|
-
rules: toRuleMap(`${preset} override ${index}`, override.rules)
|
|
4913
|
-
}))
|
|
4914
|
-
} : {},
|
|
4915
|
-
rules: rulesFor(resolved)
|
|
4916
|
-
};
|
|
4917
|
-
}
|
|
4918
|
-
|
|
4919
4947
|
// src/roles/lint/rename-suppressions.ts
|
|
4920
4948
|
import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
|
|
4921
4949
|
import { join as join15, relative as relative3 } from "node:path";
|
|
@@ -5172,7 +5200,7 @@ function plan2(context2) {
|
|
|
5172
5200
|
}
|
|
5173
5201
|
if (droppedRules.length > 0) {
|
|
5174
5202
|
notes.push(
|
|
5175
|
-
`dropped ${droppedRules.length} rule(s) this module set over the preset (${droppedRules.join(", ")}): the preset governs them`
|
|
5203
|
+
`dropped ${droppedRules.length} rule(s) this module set over the preset (${droppedRules.map((rule) => describeGoverned(rule, variant)).join(", ")}): the preset governs them`
|
|
5176
5204
|
);
|
|
5177
5205
|
}
|
|
5178
5206
|
notes.push(...teamBlocks.kept);
|
|
@@ -5266,15 +5294,18 @@ function committedConfig(cwd) {
|
|
|
5266
5294
|
}
|
|
5267
5295
|
}
|
|
5268
5296
|
function moduleOwnRules(committed, preset) {
|
|
5269
|
-
const governedNames =
|
|
5297
|
+
const governedNames = governedRules(preset);
|
|
5270
5298
|
const kept = {};
|
|
5271
5299
|
const governed = [];
|
|
5272
5300
|
for (const [rule, value] of Object.entries(committed)) {
|
|
5273
|
-
if (governedNames.has(rule)) governed.push(rule);
|
|
5301
|
+
if (governedNames.has(canonicalRuleName(rule))) governed.push(rule);
|
|
5274
5302
|
else kept[rule] = value;
|
|
5275
5303
|
}
|
|
5276
5304
|
return { kept, governed };
|
|
5277
5305
|
}
|
|
5306
|
+
function describeGoverned(rule, variant) {
|
|
5307
|
+
return describeRuleKey(rule, governedRules(lintPresetFor(variant)).get(canonicalRuleName(rule)));
|
|
5308
|
+
}
|
|
5278
5309
|
function committedIgnorePatterns(cwd) {
|
|
5279
5310
|
try {
|
|
5280
5311
|
const parsed = parseJsonc(
|
|
@@ -5516,7 +5547,10 @@ ${result.stderr ?? ""}`);
|
|
|
5516
5547
|
);
|
|
5517
5548
|
return;
|
|
5518
5549
|
}
|
|
5519
|
-
const holds = holdsFrom(
|
|
5550
|
+
const holds = holdsFrom(
|
|
5551
|
+
errorCountsByConfigRule(measured.stdout ?? ""),
|
|
5552
|
+
governedRules(lintPresetFor(presetVariant(ctx.preset, ctx.cwd)))
|
|
5553
|
+
);
|
|
5520
5554
|
const next = extendsWithBaseline(current, holds.length > 0);
|
|
5521
5555
|
if (holds.length > 0) {
|
|
5522
5556
|
writeFileSync3(baselinePath, renderBaseline(holds, readOwnPackage().version));
|
|
@@ -5672,7 +5706,8 @@ ${result.stderr ?? ""}`);
|
|
|
5672
5706
|
* exactly when something is broken.
|
|
5673
5707
|
*
|
|
5674
5708
|
* Counted as a SET of rule names, so the baseline re-stating a preset rule at `warn` is
|
|
5675
|
-
* the same rule, not a second one.
|
|
5709
|
+
* the same rule, not a second one. The rule oxlint RUNS (`canonicalRuleName`), so a layer
|
|
5710
|
+
* spelling it `no-unused-vars` beside the preset's `typescript/no-unused-vars` is one rule too.
|
|
5676
5711
|
*/
|
|
5677
5712
|
presetRuleCount(cwd) {
|
|
5678
5713
|
const target = this.unresolvedPreset(cwd);
|
|
@@ -5693,7 +5728,7 @@ ${result.stderr ?? ""}`);
|
|
|
5693
5728
|
readFileSync14(join17(cwd, entry), "utf8"),
|
|
5694
5729
|
entry
|
|
5695
5730
|
);
|
|
5696
|
-
for (const rule of Object.keys(preset.rules ?? {})) names.add(rule);
|
|
5731
|
+
for (const rule of Object.keys(preset.rules ?? {})) names.add(canonicalRuleName(rule));
|
|
5697
5732
|
} catch {
|
|
5698
5733
|
continue;
|
|
5699
5734
|
}
|
|
@@ -5940,11 +5940,682 @@ import { join as join30 } from "node:path";
|
|
|
5940
5940
|
// src/roles/lint/module-baseline.ts
|
|
5941
5941
|
import { existsSync as existsSync20, readFileSync as readFileSync22 } from "node:fs";
|
|
5942
5942
|
import { join as join26 } from "node:path";
|
|
5943
|
+
|
|
5944
|
+
// src/roles/lint/oxlint-rule-owners.json
|
|
5945
|
+
var oxlint_rule_owners_default = {
|
|
5946
|
+
"adjacent-overload-signatures": "typescript",
|
|
5947
|
+
"alt-text": "jsx_a11y",
|
|
5948
|
+
"always-return": "promise",
|
|
5949
|
+
"anchor-ambiguous-text": "jsx_a11y",
|
|
5950
|
+
"anchor-has-content": "jsx_a11y",
|
|
5951
|
+
"anchor-is-valid": "jsx_a11y",
|
|
5952
|
+
"approx-constant": "oxc",
|
|
5953
|
+
"aria-activedescendant-has-tabindex": "jsx_a11y",
|
|
5954
|
+
"aria-props": "jsx_a11y",
|
|
5955
|
+
"aria-proptypes": "jsx_a11y",
|
|
5956
|
+
"aria-role": "jsx_a11y",
|
|
5957
|
+
"aria-unsupported-elements": "jsx_a11y",
|
|
5958
|
+
"array-type": "typescript",
|
|
5959
|
+
"autocomplete-valid": "jsx_a11y",
|
|
5960
|
+
"avoid-new": "promise",
|
|
5961
|
+
"await-thenable": "typescript",
|
|
5962
|
+
"bad-array-method-on-arguments": "oxc",
|
|
5963
|
+
"bad-bitwise-operator": "oxc",
|
|
5964
|
+
"bad-char-at-comparison": "oxc",
|
|
5965
|
+
"bad-comparison-sequence": "oxc",
|
|
5966
|
+
"bad-match-all-arg": "oxc",
|
|
5967
|
+
"bad-min-max-func": "oxc",
|
|
5968
|
+
"bad-object-literal-comparison": "oxc",
|
|
5969
|
+
"bad-replace-all-arg": "oxc",
|
|
5970
|
+
"ban-ts-comment": "typescript",
|
|
5971
|
+
"ban-tslint-comment": "typescript",
|
|
5972
|
+
"ban-types": "typescript",
|
|
5973
|
+
"branches-sharing-code": "oxc",
|
|
5974
|
+
"button-has-type": "react",
|
|
5975
|
+
"callback-return": "node",
|
|
5976
|
+
"catch-error-name": "unicorn",
|
|
5977
|
+
"catch-or-return": "promise",
|
|
5978
|
+
"check-access": "jsdoc",
|
|
5979
|
+
"check-property-names": "jsdoc",
|
|
5980
|
+
"check-tag-names": "jsdoc",
|
|
5981
|
+
"checked-requires-onchange-or-readonly": "react",
|
|
5982
|
+
"class-literal-property-style": "typescript",
|
|
5983
|
+
"click-events-have-key-events": "jsx_a11y",
|
|
5984
|
+
"component-definition-name-casing": "vue",
|
|
5985
|
+
"consistent-assert": "unicorn",
|
|
5986
|
+
"consistent-date-clone": "unicorn",
|
|
5987
|
+
"consistent-each-for": "vitest",
|
|
5988
|
+
"consistent-empty-array-spread": "unicorn",
|
|
5989
|
+
"consistent-existence-index-check": "unicorn",
|
|
5990
|
+
"consistent-function-scoping": "unicorn",
|
|
5991
|
+
"consistent-generic-constructors": "typescript",
|
|
5992
|
+
"consistent-indexed-object-style": "typescript",
|
|
5993
|
+
"consistent-return": "typescript",
|
|
5994
|
+
"consistent-template-literal-escape": "unicorn",
|
|
5995
|
+
"consistent-test-filename": "vitest",
|
|
5996
|
+
"consistent-test-it": "jest",
|
|
5997
|
+
"consistent-type-assertions": "typescript",
|
|
5998
|
+
"consistent-type-definitions": "typescript",
|
|
5999
|
+
"consistent-type-exports": "typescript",
|
|
6000
|
+
"consistent-type-imports": "typescript",
|
|
6001
|
+
"consistent-type-specifier-style": "import",
|
|
6002
|
+
"consistent-vitest-vi": "vitest",
|
|
6003
|
+
"const-comparisons": "oxc",
|
|
6004
|
+
"control-has-associated-label": "jsx_a11y",
|
|
6005
|
+
"custom-error-definition": "unicorn",
|
|
6006
|
+
default: "import",
|
|
6007
|
+
"define-emits-declaration": "vue",
|
|
6008
|
+
"define-props-declaration": "vue",
|
|
6009
|
+
"define-props-destructuring": "vue",
|
|
6010
|
+
"display-name": "react",
|
|
6011
|
+
"dot-notation": "typescript",
|
|
6012
|
+
"double-comparisons": "oxc",
|
|
6013
|
+
"empty-brace-spaces": "unicorn",
|
|
6014
|
+
"empty-tags": "jsdoc",
|
|
6015
|
+
"erasing-op": "oxc",
|
|
6016
|
+
"error-message": "unicorn",
|
|
6017
|
+
"escape-case": "unicorn",
|
|
6018
|
+
"exhaustive-deps": "react",
|
|
6019
|
+
"expect-expect": "jest",
|
|
6020
|
+
"explicit-function-return-type": "typescript",
|
|
6021
|
+
"explicit-length-check": "unicorn",
|
|
6022
|
+
"explicit-member-accessibility": "typescript",
|
|
6023
|
+
"explicit-module-boundary-types": "typescript",
|
|
6024
|
+
"explicit-timer-delay": "unicorn",
|
|
6025
|
+
export: "import",
|
|
6026
|
+
"exports-last": "import",
|
|
6027
|
+
"exports-style": "node",
|
|
6028
|
+
extensions: "import",
|
|
6029
|
+
"filename-case": "unicorn",
|
|
6030
|
+
first: "import",
|
|
6031
|
+
"forbid-component-props": "react",
|
|
6032
|
+
"forbid-dom-props": "react",
|
|
6033
|
+
"forbid-elements": "react",
|
|
6034
|
+
"forward-ref-uses-ref": "react",
|
|
6035
|
+
"function-component-definition": "react",
|
|
6036
|
+
"global-require": "node",
|
|
6037
|
+
"google-font-display": "nextjs",
|
|
6038
|
+
"google-font-preconnect": "nextjs",
|
|
6039
|
+
"group-exports": "import",
|
|
6040
|
+
"handle-callback-err": "node",
|
|
6041
|
+
"heading-has-content": "jsx_a11y",
|
|
6042
|
+
"hoisted-apis-on-top": "vitest",
|
|
6043
|
+
"hook-use-state": "react",
|
|
6044
|
+
"html-has-lang": "jsx_a11y",
|
|
6045
|
+
"iframe-has-title": "jsx_a11y",
|
|
6046
|
+
"iframe-missing-sandbox": "react",
|
|
6047
|
+
"img-redundant-alt": "jsx_a11y",
|
|
6048
|
+
"implements-on-classes": "jsdoc",
|
|
6049
|
+
"import-style": "unicorn",
|
|
6050
|
+
"inline-script-id": "nextjs",
|
|
6051
|
+
"interactive-supports-focus": "jsx_a11y",
|
|
6052
|
+
"jsx-boolean-value": "react",
|
|
6053
|
+
"jsx-curly-brace-presence": "react",
|
|
6054
|
+
"jsx-filename-extension": "react",
|
|
6055
|
+
"jsx-fragments": "react",
|
|
6056
|
+
"jsx-handler-names": "react",
|
|
6057
|
+
"jsx-key": "react",
|
|
6058
|
+
"jsx-max-depth": "react",
|
|
6059
|
+
"jsx-no-comment-textnodes": "react",
|
|
6060
|
+
"jsx-no-constructed-context-values": "react",
|
|
6061
|
+
"jsx-no-duplicate-props": "react",
|
|
6062
|
+
"jsx-no-jsx-as-prop": "react_perf",
|
|
6063
|
+
"jsx-no-literals": "react",
|
|
6064
|
+
"jsx-no-new-array-as-prop": "react_perf",
|
|
6065
|
+
"jsx-no-new-function-as-prop": "react_perf",
|
|
6066
|
+
"jsx-no-new-object-as-prop": "react_perf",
|
|
6067
|
+
"jsx-no-script-url": "react",
|
|
6068
|
+
"jsx-no-target-blank": "react",
|
|
6069
|
+
"jsx-no-undef": "react",
|
|
6070
|
+
"jsx-no-useless-fragment": "react",
|
|
6071
|
+
"jsx-pascal-case": "react",
|
|
6072
|
+
"jsx-props-no-spread-multi": "react",
|
|
6073
|
+
"jsx-props-no-spreading": "react",
|
|
6074
|
+
"label-has-associated-control": "jsx_a11y",
|
|
6075
|
+
lang: "jsx_a11y",
|
|
6076
|
+
"max-dependencies": "import",
|
|
6077
|
+
"max-expects": "jest",
|
|
6078
|
+
"max-nested-calls": "unicorn",
|
|
6079
|
+
"max-nested-describe": "jest",
|
|
6080
|
+
"max-props": "vue",
|
|
6081
|
+
"media-has-caption": "jsx_a11y",
|
|
6082
|
+
"method-signature-style": "typescript",
|
|
6083
|
+
"misrefactored-assign-op": "oxc",
|
|
6084
|
+
"missing-throw": "oxc",
|
|
6085
|
+
"mouse-events-have-key-events": "jsx_a11y",
|
|
6086
|
+
named: "import",
|
|
6087
|
+
namespace: "import",
|
|
6088
|
+
"new-for-builtins": "unicorn",
|
|
6089
|
+
"newline-after-import": "import",
|
|
6090
|
+
"next-script-for-ga": "nextjs",
|
|
6091
|
+
"next-tick-style": "vue",
|
|
6092
|
+
"no-absolute-path": "import",
|
|
6093
|
+
"no-abusive-eslint-disable": "unicorn",
|
|
6094
|
+
"no-access-key": "jsx_a11y",
|
|
6095
|
+
"no-accessor-recursion": "unicorn",
|
|
6096
|
+
"no-accumulating-spread": "oxc",
|
|
6097
|
+
"no-alias-methods": "jest",
|
|
6098
|
+
"no-amd": "import",
|
|
6099
|
+
"no-anonymous-default-export": "import",
|
|
6100
|
+
"no-aria-hidden-on-focusable": "jsx_a11y",
|
|
6101
|
+
"no-array-callback-reference": "unicorn",
|
|
6102
|
+
"no-array-delete": "typescript",
|
|
6103
|
+
"no-array-fill-with-reference-type": "unicorn",
|
|
6104
|
+
"no-array-for-each": "unicorn",
|
|
6105
|
+
"no-array-index-key": "react",
|
|
6106
|
+
"no-array-method-this-argument": "unicorn",
|
|
6107
|
+
"no-array-reduce": "unicorn",
|
|
6108
|
+
"no-array-reverse": "unicorn",
|
|
6109
|
+
"no-array-sort": "unicorn",
|
|
6110
|
+
"no-arrow-functions-in-watch": "vue",
|
|
6111
|
+
"no-assign-module-variable": "nextjs",
|
|
6112
|
+
"no-async-await": "oxc",
|
|
6113
|
+
"no-async-client-component": "nextjs",
|
|
6114
|
+
"no-async-endpoint-handlers": "oxc",
|
|
6115
|
+
"no-async-in-computed-properties": "vue",
|
|
6116
|
+
"no-autofocus": "jsx_a11y",
|
|
6117
|
+
"no-await-expression-member": "unicorn",
|
|
6118
|
+
"no-await-in-promise-methods": "unicorn",
|
|
6119
|
+
"no-barrel-file": "oxc",
|
|
6120
|
+
"no-base-to-string": "typescript",
|
|
6121
|
+
"no-before-interactive-script-outside-document": "nextjs",
|
|
6122
|
+
"no-callback-in-promise": "promise",
|
|
6123
|
+
"no-children-prop": "react",
|
|
6124
|
+
"no-clone-element": "react",
|
|
6125
|
+
"no-commented-out-tests": "jest",
|
|
6126
|
+
"no-commonjs": "import",
|
|
6127
|
+
"no-computed-properties-in-data": "vue",
|
|
6128
|
+
"no-conditional-expect": "jest",
|
|
6129
|
+
"no-conditional-in-test": "jest",
|
|
6130
|
+
"no-conditional-tests": "vitest",
|
|
6131
|
+
"no-confusing-array-with": "unicorn",
|
|
6132
|
+
"no-confusing-non-null-assertion": "typescript",
|
|
6133
|
+
"no-confusing-set-timeout": "jest",
|
|
6134
|
+
"no-confusing-void-expression": "typescript",
|
|
6135
|
+
"no-console-spaces": "unicorn",
|
|
6136
|
+
"no-const-enum": "oxc",
|
|
6137
|
+
"no-css-tags": "nextjs",
|
|
6138
|
+
"no-cycle": "import",
|
|
6139
|
+
"no-danger": "react",
|
|
6140
|
+
"no-danger-with-children": "react",
|
|
6141
|
+
"no-default-export": "import",
|
|
6142
|
+
"no-defaults": "jsdoc",
|
|
6143
|
+
"no-deprecated": "typescript",
|
|
6144
|
+
"no-deprecated-data-object-declaration": "vue",
|
|
6145
|
+
"no-deprecated-delete-set": "vue",
|
|
6146
|
+
"no-deprecated-destroyed-lifecycle": "vue",
|
|
6147
|
+
"no-deprecated-events-api": "vue",
|
|
6148
|
+
"no-deprecated-functions": "jest",
|
|
6149
|
+
"no-deprecated-model-definition": "vue",
|
|
6150
|
+
"no-deprecated-props-default-this": "vue",
|
|
6151
|
+
"no-deprecated-vue-config-keycodes": "vue",
|
|
6152
|
+
"no-did-mount-set-state": "react",
|
|
6153
|
+
"no-did-update-set-state": "react",
|
|
6154
|
+
"no-direct-mutation-state": "react",
|
|
6155
|
+
"no-disabled-tests": "jest",
|
|
6156
|
+
"no-distracting-elements": "jsx_a11y",
|
|
6157
|
+
"no-document-cookie": "unicorn",
|
|
6158
|
+
"no-document-import-in-page": "nextjs",
|
|
6159
|
+
"no-done-callback": "jest",
|
|
6160
|
+
"no-duplicate-enum-values": "typescript",
|
|
6161
|
+
"no-duplicate-head": "nextjs",
|
|
6162
|
+
"no-duplicate-hooks": "jest",
|
|
6163
|
+
"no-duplicate-type-constituents": "typescript",
|
|
6164
|
+
"no-duplicates": "import",
|
|
6165
|
+
"no-dynamic-delete": "typescript",
|
|
6166
|
+
"no-dynamic-require": "import",
|
|
6167
|
+
"no-empty-file": "unicorn",
|
|
6168
|
+
"no-empty-interface": "typescript",
|
|
6169
|
+
"no-empty-named-blocks": "import",
|
|
6170
|
+
"no-empty-object-type": "typescript",
|
|
6171
|
+
"no-explicit-any": "typescript",
|
|
6172
|
+
"no-export": "jest",
|
|
6173
|
+
"no-export-in-script-setup": "vue",
|
|
6174
|
+
"no-exports-assign": "node",
|
|
6175
|
+
"no-expose-after-await": "vue",
|
|
6176
|
+
"no-extra-non-null-assertion": "typescript",
|
|
6177
|
+
"no-extraneous-class": "typescript",
|
|
6178
|
+
"no-find-dom-node": "react",
|
|
6179
|
+
"no-floating-promises": "typescript",
|
|
6180
|
+
"no-focused-tests": "jest",
|
|
6181
|
+
"no-for-in-array": "typescript",
|
|
6182
|
+
"no-head-element": "nextjs",
|
|
6183
|
+
"no-head-import-in-document": "nextjs",
|
|
6184
|
+
"no-hex-escape": "unicorn",
|
|
6185
|
+
"no-hooks": "jest",
|
|
6186
|
+
"no-html-link-for-pages": "nextjs",
|
|
6187
|
+
"no-identical-title": "jest",
|
|
6188
|
+
"no-img-element": "nextjs",
|
|
6189
|
+
"no-immediate-mutation": "unicorn",
|
|
6190
|
+
"no-import-compiler-macros": "vue",
|
|
6191
|
+
"no-import-node-test": "vitest",
|
|
6192
|
+
"no-import-type-side-effects": "typescript",
|
|
6193
|
+
"no-importing-vitest-globals": "vitest",
|
|
6194
|
+
"no-inferrable-types": "typescript",
|
|
6195
|
+
"no-instanceof-array": "unicorn",
|
|
6196
|
+
"no-instanceof-builtins": "unicorn",
|
|
6197
|
+
"no-interactive-element-to-noninteractive-role": "jsx_a11y",
|
|
6198
|
+
"no-interpolation-in-snapshots": "jest",
|
|
6199
|
+
"no-invalid-fetch-options": "unicorn",
|
|
6200
|
+
"no-invalid-remove-event-listener": "unicorn",
|
|
6201
|
+
"no-invalid-void-type": "typescript",
|
|
6202
|
+
"no-is-mounted": "react",
|
|
6203
|
+
"no-jasmine-globals": "jest",
|
|
6204
|
+
"no-large-snapshots": "jest",
|
|
6205
|
+
"no-length-as-slice-end": "unicorn",
|
|
6206
|
+
"no-lifecycle-after-await": "vue",
|
|
6207
|
+
"no-magic-array-flat-depth": "unicorn",
|
|
6208
|
+
"no-map-spread": "oxc",
|
|
6209
|
+
"no-meaningless-void-operator": "typescript",
|
|
6210
|
+
"no-misused-new": "typescript",
|
|
6211
|
+
"no-misused-promises": "typescript",
|
|
6212
|
+
"no-misused-spread": "typescript",
|
|
6213
|
+
"no-mixed-enums": "typescript",
|
|
6214
|
+
"no-mixed-requires": "node",
|
|
6215
|
+
"no-mocks-import": "jest",
|
|
6216
|
+
"no-multi-comp": "react",
|
|
6217
|
+
"no-multiple-resolved": "promise",
|
|
6218
|
+
"no-multiple-slot-args": "vue",
|
|
6219
|
+
"no-mutable-exports": "import",
|
|
6220
|
+
"no-named-as-default": "import",
|
|
6221
|
+
"no-named-as-default-member": "import",
|
|
6222
|
+
"no-named-default": "import",
|
|
6223
|
+
"no-named-export": "import",
|
|
6224
|
+
"no-namespace": "import",
|
|
6225
|
+
"no-negation-in-equality-check": "unicorn",
|
|
6226
|
+
"no-nesting": "promise",
|
|
6227
|
+
"no-new-array": "unicorn",
|
|
6228
|
+
"no-new-buffer": "unicorn",
|
|
6229
|
+
"no-new-require": "node",
|
|
6230
|
+
"no-new-statics": "promise",
|
|
6231
|
+
"no-nodejs-modules": "import",
|
|
6232
|
+
"no-non-null-asserted-nullish-coalescing": "typescript",
|
|
6233
|
+
"no-non-null-asserted-optional-chain": "typescript",
|
|
6234
|
+
"no-non-null-assertion": "typescript",
|
|
6235
|
+
"no-noninteractive-element-interactions": "jsx_a11y",
|
|
6236
|
+
"no-noninteractive-element-to-interactive-role": "jsx_a11y",
|
|
6237
|
+
"no-noninteractive-tabindex": "jsx_a11y",
|
|
6238
|
+
"no-null": "unicorn",
|
|
6239
|
+
"no-object-as-default-parameter": "unicorn",
|
|
6240
|
+
"no-object-type-as-default-prop": "react",
|
|
6241
|
+
"no-optional-chaining": "oxc",
|
|
6242
|
+
"no-page-custom-font": "nextjs",
|
|
6243
|
+
"no-path-concat": "node",
|
|
6244
|
+
"no-process-env": "node",
|
|
6245
|
+
"no-process-exit": "unicorn",
|
|
6246
|
+
"no-promise-in-callback": "promise",
|
|
6247
|
+
"no-react-children": "react",
|
|
6248
|
+
"no-redundant-roles": "jsx_a11y",
|
|
6249
|
+
"no-redundant-should-component-update": "react",
|
|
6250
|
+
"no-redundant-type-constituents": "typescript",
|
|
6251
|
+
"no-relative-parent-imports": "import",
|
|
6252
|
+
"no-render-return-value": "react",
|
|
6253
|
+
"no-require-imports": "typescript",
|
|
6254
|
+
"no-required-prop-with-default": "vue",
|
|
6255
|
+
"no-reserved-component-names": "vue",
|
|
6256
|
+
"no-reserved-keys": "vue",
|
|
6257
|
+
"no-reserved-props": "vue",
|
|
6258
|
+
"no-rest-spread-properties": "oxc",
|
|
6259
|
+
"no-restricted-jest-methods": "jest",
|
|
6260
|
+
"no-restricted-matchers": "jest",
|
|
6261
|
+
"no-restricted-types": "typescript",
|
|
6262
|
+
"no-restricted-vi-methods": "vitest",
|
|
6263
|
+
"no-return-in-finally": "promise",
|
|
6264
|
+
"no-return-wrap": "promise",
|
|
6265
|
+
"no-script-component-in-head": "nextjs",
|
|
6266
|
+
"no-self-import": "import",
|
|
6267
|
+
"no-set-state": "react",
|
|
6268
|
+
"no-shared-component-data": "vue",
|
|
6269
|
+
"no-side-effects-in-computed-properties": "vue",
|
|
6270
|
+
"no-single-promise-in-promise-methods": "unicorn",
|
|
6271
|
+
"no-standalone-expect": "jest",
|
|
6272
|
+
"no-static-element-interactions": "jsx_a11y",
|
|
6273
|
+
"no-static-only-class": "unicorn",
|
|
6274
|
+
"no-string-refs": "react",
|
|
6275
|
+
"no-styled-jsx-in-document": "nextjs",
|
|
6276
|
+
"no-sync": "node",
|
|
6277
|
+
"no-sync-scripts": "nextjs",
|
|
6278
|
+
"no-test-prefixes": "jest",
|
|
6279
|
+
"no-test-return-statement": "jest",
|
|
6280
|
+
"no-thenable": "unicorn",
|
|
6281
|
+
"no-this-alias": "typescript",
|
|
6282
|
+
"no-this-assignment": "unicorn",
|
|
6283
|
+
"no-this-in-before-route-enter": "vue",
|
|
6284
|
+
"no-this-in-exported-function": "oxc",
|
|
6285
|
+
"no-this-in-sfc": "react",
|
|
6286
|
+
"no-title-in-document-head": "nextjs",
|
|
6287
|
+
"no-top-level-await": "node",
|
|
6288
|
+
"no-typeof-undefined": "unicorn",
|
|
6289
|
+
"no-typos": "nextjs",
|
|
6290
|
+
"no-unassigned-import": "import",
|
|
6291
|
+
"no-unescaped-entities": "react",
|
|
6292
|
+
"no-unknown-property": "react",
|
|
6293
|
+
"no-unnecessary-array-flat-depth": "unicorn",
|
|
6294
|
+
"no-unnecessary-array-splice-count": "unicorn",
|
|
6295
|
+
"no-unnecessary-await": "unicorn",
|
|
6296
|
+
"no-unnecessary-boolean-literal-compare": "typescript",
|
|
6297
|
+
"no-unnecessary-condition": "typescript",
|
|
6298
|
+
"no-unnecessary-parameter-property-assignment": "typescript",
|
|
6299
|
+
"no-unnecessary-qualifier": "typescript",
|
|
6300
|
+
"no-unnecessary-slice-end": "unicorn",
|
|
6301
|
+
"no-unnecessary-template-expression": "typescript",
|
|
6302
|
+
"no-unnecessary-type-arguments": "typescript",
|
|
6303
|
+
"no-unnecessary-type-assertion": "typescript",
|
|
6304
|
+
"no-unnecessary-type-constraint": "typescript",
|
|
6305
|
+
"no-unnecessary-type-conversion": "typescript",
|
|
6306
|
+
"no-unnecessary-type-parameters": "typescript",
|
|
6307
|
+
"no-unneeded-async-expect-function": "jest",
|
|
6308
|
+
"no-unreadable-array-destructuring": "unicorn",
|
|
6309
|
+
"no-unreadable-iife": "unicorn",
|
|
6310
|
+
"no-unsafe": "react",
|
|
6311
|
+
"no-unsafe-argument": "typescript",
|
|
6312
|
+
"no-unsafe-assignment": "typescript",
|
|
6313
|
+
"no-unsafe-call": "typescript",
|
|
6314
|
+
"no-unsafe-declaration-merging": "typescript",
|
|
6315
|
+
"no-unsafe-enum-comparison": "typescript",
|
|
6316
|
+
"no-unsafe-function-type": "typescript",
|
|
6317
|
+
"no-unsafe-member-access": "typescript",
|
|
6318
|
+
"no-unsafe-return": "typescript",
|
|
6319
|
+
"no-unsafe-type-assertion": "typescript",
|
|
6320
|
+
"no-unsafe-unary-minus": "typescript",
|
|
6321
|
+
"no-unstable-nested-components": "react",
|
|
6322
|
+
"no-untyped-mock-factory": "jest",
|
|
6323
|
+
"no-unwanted-polyfillio": "nextjs",
|
|
6324
|
+
"no-useless-collection-argument": "unicorn",
|
|
6325
|
+
"no-useless-default-assignment": "typescript",
|
|
6326
|
+
"no-useless-empty-export": "typescript",
|
|
6327
|
+
"no-useless-error-capture-stack-trace": "unicorn",
|
|
6328
|
+
"no-useless-fallback-in-spread": "unicorn",
|
|
6329
|
+
"no-useless-iterator-to-array": "unicorn",
|
|
6330
|
+
"no-useless-length-check": "unicorn",
|
|
6331
|
+
"no-useless-promise-resolve-reject": "unicorn",
|
|
6332
|
+
"no-useless-spread": "unicorn",
|
|
6333
|
+
"no-useless-switch-case": "unicorn",
|
|
6334
|
+
"no-useless-undefined": "unicorn",
|
|
6335
|
+
"no-var-requires": "typescript",
|
|
6336
|
+
"no-watch-after-await": "vue",
|
|
6337
|
+
"no-webpack-loader-syntax": "import",
|
|
6338
|
+
"no-will-update-set-state": "react",
|
|
6339
|
+
"no-wrapper-object-types": "typescript",
|
|
6340
|
+
"no-zero-fractions": "unicorn",
|
|
6341
|
+
"non-nullable-type-assertion-style": "typescript",
|
|
6342
|
+
"number-arg-out-of-range": "oxc",
|
|
6343
|
+
"number-literal-case": "unicorn",
|
|
6344
|
+
"numeric-separators-style": "unicorn",
|
|
6345
|
+
"only-export-components": "react",
|
|
6346
|
+
"only-throw-error": "typescript",
|
|
6347
|
+
"only-used-in-recursion": "oxc",
|
|
6348
|
+
"padding-around-after-all-blocks": "jest",
|
|
6349
|
+
"padding-around-test-blocks": "jest",
|
|
6350
|
+
"param-names": "promise",
|
|
6351
|
+
"parameter-properties": "typescript",
|
|
6352
|
+
"prefer-add-event-listener": "unicorn",
|
|
6353
|
+
"prefer-array-find": "unicorn",
|
|
6354
|
+
"prefer-array-flat": "unicorn",
|
|
6355
|
+
"prefer-array-flat-map": "unicorn",
|
|
6356
|
+
"prefer-array-index-of": "unicorn",
|
|
6357
|
+
"prefer-array-some": "unicorn",
|
|
6358
|
+
"prefer-as-const": "typescript",
|
|
6359
|
+
"prefer-at": "unicorn",
|
|
6360
|
+
"prefer-await-to-callbacks": "promise",
|
|
6361
|
+
"prefer-await-to-then": "promise",
|
|
6362
|
+
"prefer-bigint-literals": "unicorn",
|
|
6363
|
+
"prefer-blob-reading-methods": "unicorn",
|
|
6364
|
+
"prefer-called-exactly-once-with": "vitest",
|
|
6365
|
+
"prefer-called-once": "vitest",
|
|
6366
|
+
"prefer-called-times": "vitest",
|
|
6367
|
+
"prefer-called-with": "jest",
|
|
6368
|
+
"prefer-catch": "promise",
|
|
6369
|
+
"prefer-class-fields": "unicorn",
|
|
6370
|
+
"prefer-classlist-toggle": "unicorn",
|
|
6371
|
+
"prefer-code-point": "unicorn",
|
|
6372
|
+
"prefer-comparison-matcher": "jest",
|
|
6373
|
+
"prefer-date-now": "unicorn",
|
|
6374
|
+
"prefer-default-export": "import",
|
|
6375
|
+
"prefer-default-parameters": "unicorn",
|
|
6376
|
+
"prefer-describe-function-title": "vitest",
|
|
6377
|
+
"prefer-dom-node-append": "unicorn",
|
|
6378
|
+
"prefer-dom-node-dataset": "unicorn",
|
|
6379
|
+
"prefer-dom-node-remove": "unicorn",
|
|
6380
|
+
"prefer-dom-node-text-content": "unicorn",
|
|
6381
|
+
"prefer-each": "jest",
|
|
6382
|
+
"prefer-ending-with-an-expect": "jest",
|
|
6383
|
+
"prefer-enum-initializers": "typescript",
|
|
6384
|
+
"prefer-equality-matcher": "jest",
|
|
6385
|
+
"prefer-es6-class": "react",
|
|
6386
|
+
"prefer-event-target": "unicorn",
|
|
6387
|
+
"prefer-expect-assertions": "jest",
|
|
6388
|
+
"prefer-expect-resolves": "jest",
|
|
6389
|
+
"prefer-expect-type-of": "vitest",
|
|
6390
|
+
"prefer-export-from": "unicorn",
|
|
6391
|
+
"prefer-find": "typescript",
|
|
6392
|
+
"prefer-for-of": "typescript",
|
|
6393
|
+
"prefer-function-component": "react",
|
|
6394
|
+
"prefer-function-type": "typescript",
|
|
6395
|
+
"prefer-global-this": "unicorn",
|
|
6396
|
+
"prefer-hooks-in-order": "jest",
|
|
6397
|
+
"prefer-hooks-on-top": "jest",
|
|
6398
|
+
"prefer-import-from-vue": "vue",
|
|
6399
|
+
"prefer-import-in-mock": "vitest",
|
|
6400
|
+
"prefer-import-meta-properties": "unicorn",
|
|
6401
|
+
"prefer-importing-jest-globals": "jest",
|
|
6402
|
+
"prefer-importing-vitest-globals": "vitest",
|
|
6403
|
+
"prefer-includes": "typescript",
|
|
6404
|
+
"prefer-jest-mocked": "jest",
|
|
6405
|
+
"prefer-keyboard-event-key": "unicorn",
|
|
6406
|
+
"prefer-literal-enum-member": "typescript",
|
|
6407
|
+
"prefer-logical-operator-over-ternary": "unicorn",
|
|
6408
|
+
"prefer-lowercase-title": "jest",
|
|
6409
|
+
"prefer-math-min-max": "unicorn",
|
|
6410
|
+
"prefer-math-trunc": "unicorn",
|
|
6411
|
+
"prefer-mock-promise-shorthand": "jest",
|
|
6412
|
+
"prefer-mock-return-shorthand": "jest",
|
|
6413
|
+
"prefer-modern-dom-apis": "unicorn",
|
|
6414
|
+
"prefer-modern-math-apis": "unicorn",
|
|
6415
|
+
"prefer-module": "unicorn",
|
|
6416
|
+
"prefer-namespace-keyword": "typescript",
|
|
6417
|
+
"prefer-native-coercion-functions": "unicorn",
|
|
6418
|
+
"prefer-negative-index": "unicorn",
|
|
6419
|
+
"prefer-node-protocol": "unicorn",
|
|
6420
|
+
"prefer-nullish-coalescing": "typescript",
|
|
6421
|
+
"prefer-number-coercion": "unicorn",
|
|
6422
|
+
"prefer-number-properties": "unicorn",
|
|
6423
|
+
"prefer-object-from-entries": "unicorn",
|
|
6424
|
+
"prefer-optional-catch-binding": "unicorn",
|
|
6425
|
+
"prefer-optional-chain": "typescript",
|
|
6426
|
+
"prefer-prototype-methods": "unicorn",
|
|
6427
|
+
"prefer-query-selector": "unicorn",
|
|
6428
|
+
"prefer-readonly": "typescript",
|
|
6429
|
+
"prefer-readonly-parameter-types": "typescript",
|
|
6430
|
+
"prefer-reduce-type-parameter": "typescript",
|
|
6431
|
+
"prefer-reflect-apply": "unicorn",
|
|
6432
|
+
"prefer-regexp-exec": "typescript",
|
|
6433
|
+
"prefer-regexp-test": "unicorn",
|
|
6434
|
+
"prefer-response-static-json": "unicorn",
|
|
6435
|
+
"prefer-return-this-type": "typescript",
|
|
6436
|
+
"prefer-set-has": "unicorn",
|
|
6437
|
+
"prefer-set-size": "unicorn",
|
|
6438
|
+
"prefer-single-call": "unicorn",
|
|
6439
|
+
"prefer-snapshot-hint": "jest",
|
|
6440
|
+
"prefer-spy-on": "jest",
|
|
6441
|
+
"prefer-strict-boolean-matchers": "vitest",
|
|
6442
|
+
"prefer-strict-equal": "jest",
|
|
6443
|
+
"prefer-string-raw": "unicorn",
|
|
6444
|
+
"prefer-string-replace-all": "unicorn",
|
|
6445
|
+
"prefer-string-slice": "unicorn",
|
|
6446
|
+
"prefer-string-starts-ends-with": "typescript",
|
|
6447
|
+
"prefer-string-trim-start-end": "unicorn",
|
|
6448
|
+
"prefer-structured-clone": "unicorn",
|
|
6449
|
+
"prefer-tag-over-role": "jsx_a11y",
|
|
6450
|
+
"prefer-ternary": "unicorn",
|
|
6451
|
+
"prefer-to-be": "jest",
|
|
6452
|
+
"prefer-to-be-falsy": "vitest",
|
|
6453
|
+
"prefer-to-be-object": "vitest",
|
|
6454
|
+
"prefer-to-be-truthy": "vitest",
|
|
6455
|
+
"prefer-to-contain": "jest",
|
|
6456
|
+
"prefer-to-have-been-called": "jest",
|
|
6457
|
+
"prefer-to-have-been-called-times": "jest",
|
|
6458
|
+
"prefer-to-have-length": "jest",
|
|
6459
|
+
"prefer-todo": "jest",
|
|
6460
|
+
"prefer-top-level-await": "unicorn",
|
|
6461
|
+
"prefer-ts-expect-error": "typescript",
|
|
6462
|
+
"prefer-type-error": "unicorn",
|
|
6463
|
+
"promise-function-async": "typescript",
|
|
6464
|
+
"prop-name-casing": "vue",
|
|
6465
|
+
"react-compiler": "react",
|
|
6466
|
+
"react-in-jsx-scope": "react",
|
|
6467
|
+
"related-getter-setter-pairs": "typescript",
|
|
6468
|
+
"relative-url-style": "unicorn",
|
|
6469
|
+
"require-array-join-separator": "unicorn",
|
|
6470
|
+
"require-array-sort-compare": "typescript",
|
|
6471
|
+
"require-awaited-expect-poll": "vitest",
|
|
6472
|
+
"require-default-export": "vue",
|
|
6473
|
+
"require-default-prop": "vue",
|
|
6474
|
+
"require-direct-export": "vue",
|
|
6475
|
+
"require-hook": "jest",
|
|
6476
|
+
"require-local-test-context-for-concurrent-snapshots": "vitest",
|
|
6477
|
+
"require-mock-type-parameters": "vitest",
|
|
6478
|
+
"require-module-attributes": "unicorn",
|
|
6479
|
+
"require-module-specifiers": "unicorn",
|
|
6480
|
+
"require-number-to-fixed-digits-argument": "unicorn",
|
|
6481
|
+
"require-param": "jsdoc",
|
|
6482
|
+
"require-param-description": "jsdoc",
|
|
6483
|
+
"require-param-name": "jsdoc",
|
|
6484
|
+
"require-param-type": "jsdoc",
|
|
6485
|
+
"require-post-message-target-origin": "unicorn",
|
|
6486
|
+
"require-prop-type-constructor": "vue",
|
|
6487
|
+
"require-prop-types": "vue",
|
|
6488
|
+
"require-property": "jsdoc",
|
|
6489
|
+
"require-property-description": "jsdoc",
|
|
6490
|
+
"require-property-name": "jsdoc",
|
|
6491
|
+
"require-property-type": "jsdoc",
|
|
6492
|
+
"require-render-return": "react",
|
|
6493
|
+
"require-returns": "jsdoc",
|
|
6494
|
+
"require-returns-description": "jsdoc",
|
|
6495
|
+
"require-returns-type": "jsdoc",
|
|
6496
|
+
"require-slots-as-functions": "vue",
|
|
6497
|
+
"require-test-timeout": "vitest",
|
|
6498
|
+
"require-throws-description": "jsdoc",
|
|
6499
|
+
"require-throws-type": "jsdoc",
|
|
6500
|
+
"require-to-throw-message": "jest",
|
|
6501
|
+
"require-top-level-describe": "jest",
|
|
6502
|
+
"require-typed-ref": "vue",
|
|
6503
|
+
"require-yields": "jsdoc",
|
|
6504
|
+
"require-yields-description": "jsdoc",
|
|
6505
|
+
"require-yields-type": "jsdoc",
|
|
6506
|
+
"restrict-plus-operands": "typescript",
|
|
6507
|
+
"restrict-template-expressions": "typescript",
|
|
6508
|
+
"return-await": "typescript",
|
|
6509
|
+
"return-in-computed-property": "vue",
|
|
6510
|
+
"return-in-emits-validator": "vue",
|
|
6511
|
+
"role-has-required-aria-props": "jsx_a11y",
|
|
6512
|
+
"role-supports-aria-props": "jsx_a11y",
|
|
6513
|
+
"rules-of-hooks": "react",
|
|
6514
|
+
scope: "jsx_a11y",
|
|
6515
|
+
"self-closing-comp": "react",
|
|
6516
|
+
"spec-only": "promise",
|
|
6517
|
+
"state-in-constructor": "react",
|
|
6518
|
+
"strict-boolean-expressions": "typescript",
|
|
6519
|
+
"strict-void-return": "typescript",
|
|
6520
|
+
"style-prop-object": "react",
|
|
6521
|
+
"switch-case-braces": "unicorn",
|
|
6522
|
+
"switch-case-break-position": "unicorn",
|
|
6523
|
+
"switch-exhaustiveness-check": "typescript",
|
|
6524
|
+
"tabindex-no-positive": "jsx_a11y",
|
|
6525
|
+
"text-encoding-identifier-case": "unicorn",
|
|
6526
|
+
"throw-new-error": "unicorn",
|
|
6527
|
+
"triple-slash-reference": "typescript",
|
|
6528
|
+
unambiguous: "import",
|
|
6529
|
+
"unbound-method": "typescript",
|
|
6530
|
+
"unified-signatures": "typescript",
|
|
6531
|
+
"uninvoked-array-callback": "oxc",
|
|
6532
|
+
"use-unknown-in-catch-callback-variable": "typescript",
|
|
6533
|
+
"valid-define-emits": "vue",
|
|
6534
|
+
"valid-define-options": "vue",
|
|
6535
|
+
"valid-define-props": "vue",
|
|
6536
|
+
"valid-describe-callback": "jest",
|
|
6537
|
+
"valid-expect": "jest",
|
|
6538
|
+
"valid-expect-in-promise": "jest",
|
|
6539
|
+
"valid-next-tick": "vue",
|
|
6540
|
+
"valid-params": "promise",
|
|
6541
|
+
"valid-title": "jest",
|
|
6542
|
+
"void-dom-elements-no-children": "react",
|
|
6543
|
+
"warn-todo": "vitest"
|
|
6544
|
+
};
|
|
6545
|
+
|
|
6546
|
+
// src/roles/lint/rule-name.ts
|
|
6547
|
+
var PLUGIN_ALIASES = {
|
|
6548
|
+
"@typescript-eslint": "typescript",
|
|
6549
|
+
"import-x": "import",
|
|
6550
|
+
"jsx-a11y": "jsx_a11y",
|
|
6551
|
+
"jsx-a11y-x": "jsx_a11y",
|
|
6552
|
+
"jsx_a11y-x": "jsx_a11y",
|
|
6553
|
+
"react-perf": "react_perf",
|
|
6554
|
+
"@next": "nextjs",
|
|
6555
|
+
"@next/next": "nextjs",
|
|
6556
|
+
"react-hooks": "react",
|
|
6557
|
+
deepscan: "oxc"
|
|
6558
|
+
};
|
|
6559
|
+
var TYPESCRIPT_COMPATIBLE_ESLINT_RULES = /* @__PURE__ */ new Set([
|
|
6560
|
+
"class-methods-use-this",
|
|
6561
|
+
"default-param-last",
|
|
6562
|
+
"init-declarations",
|
|
6563
|
+
"max-params",
|
|
6564
|
+
"no-array-constructor",
|
|
6565
|
+
"no-dupe-class-members",
|
|
6566
|
+
"no-empty-function",
|
|
6567
|
+
"no-invalid-this",
|
|
6568
|
+
"no-loop-func",
|
|
6569
|
+
"no-loss-of-precision",
|
|
6570
|
+
"no-magic-numbers",
|
|
6571
|
+
"no-redeclare",
|
|
6572
|
+
"no-restricted-imports",
|
|
6573
|
+
"no-shadow",
|
|
6574
|
+
"no-unused-expressions",
|
|
6575
|
+
"no-unused-vars",
|
|
6576
|
+
"no-use-before-define",
|
|
6577
|
+
"no-useless-constructor"
|
|
6578
|
+
]);
|
|
6579
|
+
var OWNERS = oxlint_rule_owners_default;
|
|
6580
|
+
var PLUGIN_PREFIXES = ["eslint-plugin", "oxlint-plugin"];
|
|
6581
|
+
function normalizePluginName(plugin) {
|
|
6582
|
+
const slash = plugin.indexOf("/");
|
|
6583
|
+
if (slash !== -1) {
|
|
6584
|
+
const scope = plugin.slice(0, slash);
|
|
6585
|
+
const rest = plugin.slice(slash + 1);
|
|
6586
|
+
for (const prefix of PLUGIN_PREFIXES) {
|
|
6587
|
+
if (rest === prefix) return scope;
|
|
6588
|
+
if (rest.startsWith(`${prefix}-`)) return `${scope}/${rest.slice(prefix.length + 1)}`;
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
for (const prefix of PLUGIN_PREFIXES) {
|
|
6592
|
+
if (plugin.startsWith(`${prefix}-`)) return plugin.slice(prefix.length + 1);
|
|
6593
|
+
}
|
|
6594
|
+
return plugin;
|
|
6595
|
+
}
|
|
6596
|
+
function canonicalRuleName(key) {
|
|
6597
|
+
const at = key.startsWith("@") ? key.lastIndexOf("/") : key.indexOf("/");
|
|
6598
|
+
if (at === -1) return `${OWNERS[key] ?? "eslint"}/${key}`;
|
|
6599
|
+
const normalized = normalizePluginName(key.slice(0, at));
|
|
6600
|
+
const rule = key.slice(at + 1);
|
|
6601
|
+
const plugin = PLUGIN_ALIASES[normalized] ?? normalized;
|
|
6602
|
+
return plugin === "typescript" && TYPESCRIPT_COMPATIBLE_ESLINT_RULES.has(rule) ? `eslint/${rule}` : `${plugin}/${rule}`;
|
|
6603
|
+
}
|
|
6604
|
+
function describeRuleKey(key, presetSpelling) {
|
|
6605
|
+
return presetSpelling === void 0 || presetSpelling === key ? key : `${key} (oxlint runs it as ${presetSpelling})`;
|
|
6606
|
+
}
|
|
6607
|
+
|
|
6608
|
+
// src/roles/lint/module-baseline.ts
|
|
5943
6609
|
var LINT_BASELINE_FILE = ".oxlintrc.baseline.json";
|
|
5944
6610
|
var LINT_MEASURE_FILE = ".oxlintrc.measure.json";
|
|
5945
6611
|
var LINT_BASELINE_SPECIFIER = `./${LINT_BASELINE_FILE}`;
|
|
5946
|
-
function holdsFrom(errorCounts) {
|
|
5947
|
-
|
|
6612
|
+
function holdsFrom(errorCounts, presetSpellings = /* @__PURE__ */ new Map()) {
|
|
6613
|
+
const counts = /* @__PURE__ */ new Map();
|
|
6614
|
+
for (const [id, count] of errorCounts) {
|
|
6615
|
+
const rule = presetSpellings.get(canonicalRuleName(id)) ?? id;
|
|
6616
|
+
counts.set(rule, (counts.get(rule) ?? 0) + count);
|
|
6617
|
+
}
|
|
6618
|
+
return [...counts].map(([rule, count]) => ({ rule, count })).sort((left, right) => right.count - left.count || left.rule.localeCompare(right.rule));
|
|
5948
6619
|
}
|
|
5949
6620
|
function renderBaseline(holds, version) {
|
|
5950
6621
|
const entries = holds.map(({ rule }) => ` ${JSON.stringify(rule)}: "warn"`).join(",\n");
|
|
@@ -6607,6 +7278,8 @@ export {
|
|
|
6607
7278
|
rewriteToolchainImports,
|
|
6608
7279
|
resolveOxfmt,
|
|
6609
7280
|
oxfmtRejects,
|
|
7281
|
+
canonicalRuleName,
|
|
7282
|
+
describeRuleKey,
|
|
6610
7283
|
LINT_BASELINE_FILE,
|
|
6611
7284
|
LINT_MEASURE_FILE,
|
|
6612
7285
|
LINT_BASELINE_SPECIFIER,
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
registerAdapters,
|
|
7
7
|
resolve,
|
|
8
8
|
setDefaultRunner
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JHLNNIZC.js";
|
|
10
10
|
import {
|
|
11
11
|
BaseAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-P7NYSMLS.js";
|
|
13
13
|
import "./chunk-JRZI5IIN.js";
|
|
14
14
|
import "./chunk-WBDBRGLV.js";
|
|
15
15
|
import "./chunk-O7REVMOC.js";
|
package/docs/lint-adoption.md
CHANGED
|
@@ -215,6 +215,16 @@ Two limits, both the preset's governance:
|
|
|
215
215
|
it and names it. That includes `no-console` and `no-restricted-imports` in the react preset. To
|
|
216
216
|
set one of those for your module, put it in an `extends` layer after the preset (above): a
|
|
217
217
|
layer is reviewed as yours and `--inspect` shows it.
|
|
218
|
+
- **"The same rule" is the rule oxlint runs, not the name you wrote** (since 1.5.1). Oxlint
|
|
219
|
+
accepts several names for one rule: `eslint/x` is `x`, `typescript/x` is the eslint rule `x`
|
|
220
|
+
for 18 rules that typescript-eslint extends (`no-restricted-imports`, `no-unused-vars`,
|
|
221
|
+
`no-unused-expressions`, ...), `@typescript-eslint/` is `typescript/`, `react-hooks/` is
|
|
222
|
+
`react/`, `jsx-a11y/` is `jsx_a11y/`, `import-x/` is `import/`, `eslint-plugin-` prefixes are
|
|
223
|
+
dropped, and a bare name belongs to the first built-in rule of that name. Measured on 1.77.0, a
|
|
224
|
+
react stub setting `typescript/no-restricted-imports` beside console's two rules linted with
|
|
225
|
+
its own patterns and none of the preset's, so `@nestjs/*` imports passed. A re-`init` now drops
|
|
226
|
+
an alias like the name it stands for, and says which preset rule it is:
|
|
227
|
+
`typescript/no-restricted-imports (oxlint runs it as no-restricted-imports)`.
|
|
218
228
|
- **Your `overrides` blocks are kept as written**, with their `files`, and their rules go through
|
|
219
229
|
the same filter. Two of your blocks with the same `files` are merged into one on re-`init`; a
|
|
220
230
|
block is never merged into a preset override, which lives behind `extends` where the stub
|
|
@@ -283,7 +293,12 @@ things follow, and they are the point:
|
|
|
283
293
|
- your own config stays `extends` + `ignorePatterns`, so a rule **you** change by hand is
|
|
284
294
|
still reported as drift and is never confused with a hold sentinel made;
|
|
285
295
|
- `--init` says what it held and how many violations each hold covers, so the debt is
|
|
286
|
-
announced rather than discovered
|
|
296
|
+
announced rather than discovered;
|
|
297
|
+
- a hold is written under the **preset's** name for the rule (since 1.5.1). Oxlint reports
|
|
298
|
+
`eslint(no-unused-expressions)` for a rule the nest preset configures as
|
|
299
|
+
`typescript/no-unused-expressions`, and a hold keyed `no-unused-expressions` did not hold:
|
|
300
|
+
measured on 1.77.0, the violation stayed an `error` on react and nest, because oxlint keeps the
|
|
301
|
+
two names side by side and picks one by hash order.
|
|
287
302
|
|
|
288
303
|
Do not edit `.oxlintrc.baseline.json` by hand. Commit it: it is part of the adoption, and it
|
|
289
304
|
is what makes the promise above true on the day you adopt rather than on the day the preset
|
|
@@ -137,7 +137,7 @@ majority of the migration, and only a sweep over every real module found it.
|
|
|
137
137
|
|
|
138
138
|
## The `--init` matrix for 1.5.1, 29 October 2026
|
|
139
139
|
|
|
140
|
-
Six fixes, found by re-initializing the monorepo's 63 adopted modules with 1.5.1-alpha.0. Every
|
|
140
|
+
Six fixes, then a seventh (below) found by the alpha.1 validation. Found by re-initializing the monorepo's 63 adopted modules with 1.5.1-alpha.0. Every
|
|
141
141
|
cell below is a test in this repo, against the built CLI unless it says unit, and every fix has a
|
|
142
142
|
negative control: the fix reverted in the source, the cells run again, and the cells that must
|
|
143
143
|
fail do. No existing cell changed: against the alpha, the test tree gains lines and loses none
|
|
@@ -240,6 +240,47 @@ Negative controls, one per block, each reverting one read-back: plugins 5 cells
|
|
|
240
240
|
6, settings 5, overrides 6, extends 5, rules 6, sortImports 7, format `ignorePatterns` 1. Each
|
|
241
241
|
fails its own cells plus the every-block cells, and nothing else.
|
|
242
242
|
|
|
243
|
+
### 7. an alias of a governed rule is governed (`init-drops-governed-aliases`, unit `lint-governed-aliases`, `lint-rule-name`)
|
|
244
|
+
|
|
245
|
+
Oxlint 1.77.0 runs several names as one rule, and sentinel compared names. Proven first, outside
|
|
246
|
+
sentinel, react preset, a file importing `@nestjs/common` and one importing `lodash`:
|
|
247
|
+
|
|
248
|
+
| stub `rules` beside the preset | what fires |
|
|
249
|
+
| ------------------------------------------------------------------------------------- | ------------------------------ |
|
|
250
|
+
| five unrelated rules (control) | the preset's `@nestjs/*` ban |
|
|
251
|
+
| the same, plus `typescript/no-restricted-imports` with a lodash pattern | the lodash ban only |
|
|
252
|
+
| `typescript/no-restricted-imports` alone | the preset's ban only |
|
|
253
|
+
| `eslint/no-restricted-imports` alone | the lodash ban only, every run |
|
|
254
|
+
| baseline `no-unused-expressions: warn` over nest's `typescript/no-unused-expressions` | still an `error` |
|
|
255
|
+
|
|
256
|
+
The `typescript/` outcome moves with the rest of the rule set because oxlint keeps both names
|
|
257
|
+
through the `extends` merge and picks one by hash order; `eslint/` collapses with the canonical
|
|
258
|
+
name in the merge, where the stub wins. The canonical form is ported from oxc at
|
|
259
|
+
`oxlint_v1.77.0` (`parse_rule_key`, `normalize_plugin_name`, `unalias_plugin_name`,
|
|
260
|
+
`TYPESCRIPT_COMPATIBLE_ESLINT_RULES`), with the bare-name owners taken from `oxlint --rules -f json`.
|
|
261
|
+
|
|
262
|
+
| cell | result |
|
|
263
|
+
| ----------------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
264
|
+
| re-init, react, console's rules + `typescript/no-restricted-imports` / `eslint/...` | alias dropped and named, the two team rules kept |
|
|
265
|
+
| the same, then a file importing `@nestjs/common`, `--run --lint` | fails on the preset's ban |
|
|
266
|
+
| control: the canonical `no-restricted-imports` | dropped, message unchanged |
|
|
267
|
+
| nest module violating `no-unused-expressions` at adoption | holds `typescript/no-unused-expressions`, lints green |
|
|
268
|
+
| team layer `no-unused-vars` over nest's `typescript/no-unused-vars`, `--inspect` | rule count unchanged |
|
|
269
|
+
| unit: `@typescript-eslint/`, bare `no-unused-vars`, `react/rules-of-hooks`, an override | dropped (override named with the preset rule) |
|
|
270
|
+
| unit: `typescript/require-await`, `unicorn/no-nested-ternary`, `typescript/no-namespace` | kept: different rules to oxlint too |
|
|
271
|
+
| every governed built-in rule of every preset, in every spelling, through `--print-config` | resolves where sentinel says |
|
|
272
|
+
| a preset rule set naming one rule twice | refused at build |
|
|
273
|
+
|
|
274
|
+
Negative control, `canonicalRuleName` made the identity: 31 of the 48 new cells fail, the 17 that
|
|
275
|
+
pass are the negative ones (the non-aliases, the preset-builds, the owners file, the canonical
|
|
276
|
+
control). With the source fix reverted (`git checkout` of the five files, new files kept), 6 of
|
|
277
|
+
the 7 e2e cells fail, the canonical control passes, and the `--run --lint` cell lints the
|
|
278
|
+
`@nestjs/common` import clean. No existing cell changed.
|
|
279
|
+
|
|
280
|
+
Checked in the monorepo at 7177eb86038: none of the 66 committed `.oxlintrc*.json` files and
|
|
281
|
+
team layers spells a governed rule under another name, so no adopted module carries the gap
|
|
282
|
+
today.
|
|
283
|
+
|
|
243
284
|
### against the consumer, the 63 adopted modules
|
|
244
285
|
|
|
245
286
|
The packed branch, through a pnpm `file:` override, on a fresh worktree of the monorepo at
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hublo/sentinel",
|
|
3
|
-
"version": "1.5.1-alpha.
|
|
3
|
+
"version": "1.5.1-alpha.2",
|
|
4
4
|
"description": "One CLI that guards code health across Hublo repos: shared lint/typescript/build/test presets, static & dynamic analysis, and architecture checks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|