Skip to content

Commit f078fef

Browse files
authored
fix: handle non-array deprecated rule replacements (#20825)
* fix: handle non-array deprecated rule replacements * handle invalid replacement metadata entries
1 parent 5b817d6 commit f078fef

2 files changed

Lines changed: 103 additions & 6 deletions

File tree

‎lib/eslint/eslint.js‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,34 @@ function createRulesMeta(rules) {
107107
}, {});
108108
}
109109

110+
/**
111+
* Gets the replacement rule names from a deprecated rule's metadata.
112+
* @param {RulesMeta} meta The rule metadata.
113+
* @returns {string[]} Replacement rule names.
114+
*/
115+
function getDeprecatedRuleReplacements(meta) {
116+
if (typeof meta.deprecated !== "object") {
117+
return meta.replacedBy || [];
118+
}
119+
120+
const { replacedBy } = meta.deprecated;
121+
122+
if (!Array.isArray(replacedBy)) {
123+
return [];
124+
}
125+
126+
return replacedBy.map(replacement => {
127+
if (typeof replacement !== "object" || replacement === null) {
128+
return "";
129+
}
130+
131+
const pluginName = replacement.plugin?.name;
132+
const ruleName = replacement.rule?.name;
133+
134+
return `${typeof pluginName === "string" ? `${getShorthandName(pluginName, "eslint-plugin")}/` : ""}${typeof ruleName === "string" ? ruleName : ""}`;
135+
});
136+
}
137+
110138
/** @type {WeakMap<CalculatedConfig, DeprecatedRuleInfo[]>} */
111139
const usedDeprecatedRulesCache = new WeakMap();
112140

@@ -144,12 +172,7 @@ function getOrFindUsedDeprecatedRules(eslint, maybeFilePath) {
144172

145173
retv.push({
146174
ruleId,
147-
replacedBy: usesNewFormat
148-
? (meta.deprecated.replacedBy?.map(
149-
replacement =>
150-
`${replacement.plugin?.name !== void 0 ? `${getShorthandName(replacement.plugin.name, "eslint-plugin")}/` : ""}${replacement.rule?.name ?? ""}`,
151-
) ?? [])
152-
: meta.replacedBy || [],
175+
replacedBy: getDeprecatedRuleReplacements(meta),
153176
info: usesNewFormat ? meta.deprecated : void 0,
154177
});
155178
}

‎tests/lib/eslint/eslint.js‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4354,6 +4354,80 @@ describe("ESLint", () => {
43544354
},
43554355
]);
43564356
});
4357+
4358+
it("should ignore replacement metadata that is not an array", async () => {
4359+
const deprecated = {
4360+
replacedBy: "replacement",
4361+
};
4362+
4363+
eslint = new ESLint({
4364+
cwd: originalDir,
4365+
overrideConfigFile: true,
4366+
overrideConfig: {
4367+
plugins: {
4368+
test: {
4369+
rules: {
4370+
deprecated: {
4371+
meta: { deprecated },
4372+
create: () => ({}),
4373+
},
4374+
},
4375+
},
4376+
},
4377+
rules: {
4378+
"test/deprecated": "error",
4379+
},
4380+
},
4381+
});
4382+
const results = await eslint.lintFiles(["lib/cli*.js"]);
4383+
4384+
assert.deepStrictEqual(results[0].usedDeprecatedRules, [
4385+
{
4386+
ruleId: "test/deprecated",
4387+
replacedBy: [],
4388+
info: deprecated,
4389+
},
4390+
]);
4391+
});
4392+
4393+
it("should handle invalid replacement metadata entries", async () => {
4394+
const deprecated = {
4395+
replacedBy: [
4396+
null,
4397+
{ plugin: { name: null } },
4398+
{ plugin: { name: null }, rule: { name: "name" } },
4399+
],
4400+
};
4401+
4402+
eslint = new ESLint({
4403+
cwd: originalDir,
4404+
overrideConfigFile: true,
4405+
overrideConfig: {
4406+
plugins: {
4407+
test: {
4408+
rules: {
4409+
deprecated: {
4410+
meta: { deprecated },
4411+
create: () => ({}),
4412+
},
4413+
},
4414+
},
4415+
},
4416+
rules: {
4417+
"test/deprecated": "error",
4418+
},
4419+
},
4420+
});
4421+
const results = await eslint.lintFiles(["lib/cli*.js"]);
4422+
4423+
assert.deepStrictEqual(results[0].usedDeprecatedRules, [
4424+
{
4425+
ruleId: "test/deprecated",
4426+
replacedBy: ["", "", "name"],
4427+
info: deprecated,
4428+
},
4429+
]);
4430+
});
43574431
});
43584432

43594433
// working

0 commit comments

Comments
 (0)