From 3ba45844ba2ef5d622804e4398e694427a4c7940 Mon Sep 17 00:00:00 2001 From: auvred Date: Thu, 21 Dec 2023 08:39:03 +0000 Subject: [PATCH 1/4] fix(eslint-plugin): [no-restricted-imports] prevent crash when patterns or paths are empty --- .../src/rules/no-restricted-imports.ts | 18 +++++++++++- .../tests/rules/no-restricted-imports.test.ts | 29 +++++++++++++++++++ .../eslint-plugin/typings/eslint-rules.d.ts | 13 +++++---- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 1fbd584a1206..7d21e8790fab 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -8,6 +8,7 @@ import type { import type { ArrayOfStringOrObject, ArrayOfStringOrObjectPatterns, + RuleListener, } from 'eslint/lib/rules/no-restricted-imports'; import type { Ignore } from 'ignore'; import ignore from 'ignore'; @@ -211,6 +212,21 @@ function getRestrictedPatterns( return []; } +function shouldCreateRule( + baseRules: RuleListener, + options: Options, +): baseRules is Exclude> { + if (!Object.keys(baseRules).length || options.length === 0) { + return false; + } + + if (!isOptionsArrayOfStringOrObject(options)) { + return !!(options[0].paths?.length || options[0].patterns?.length); + } + + return true; +} + export default createRule({ name: 'no-restricted-imports', meta: { @@ -228,7 +244,7 @@ export default createRule({ const rules = baseRule.create(context); const { options } = context; - if (options.length === 0) { + if (!shouldCreateRule(rules, options)) { return {}; } diff --git a/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts b/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts index fcbdcd625caa..0345cfa17eca 100644 --- a/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts @@ -322,6 +322,35 @@ import type { foo } from 'import2/private/bar'; }, ], }, + { + code: "import foo from 'foo';", + options: [], + }, + { + code: "import foo from 'foo';", + options: [ + { + paths: [], + }, + ], + }, + { + code: "import foo from 'foo';", + options: [ + { + patterns: [], + }, + ], + }, + { + code: "import foo from 'foo';", + options: [ + { + paths: [], + patterns: [], + }, + ], + }, ], invalid: [ { diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 4490df6104be..5d301e04f2b6 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -1057,6 +1057,13 @@ declare module 'eslint/lib/rules/no-restricted-imports' { allowTypeImports?: boolean; }[] | string[]; + export type RuleListener = + | Record + | { + ImportDeclaration(node: TSESTree.ImportDeclaration): void; + ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration): void; + ExportAllDeclaration(node: TSESTree.ExportAllDeclaration): void; + }; } interface ObjectOfPathsAndPatterns { @@ -1074,11 +1081,7 @@ declare module 'eslint/lib/rules/no-restricted-imports' { | 'patterns' | 'patternWithCustomMessage', rule.ArrayOfStringOrObject | [ObjectOfPathsAndPatterns], - { - ImportDeclaration(node: TSESTree.ImportDeclaration): void; - ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration): void; - ExportAllDeclaration(node: TSESTree.ExportAllDeclaration): void; - } + rule.RuleListener >; export = rule; } From 54e0f1b1e034e56be07571195d4dd58e144ff2e7 Mon Sep 17 00:00:00 2001 From: auvred <61150013+auvred@users.noreply.github.com> Date: Fri, 22 Dec 2023 11:27:58 +0300 Subject: [PATCH 2/4] Update packages/eslint-plugin/src/rules/no-restricted-imports.ts Co-authored-by: StyleShit <32631382+StyleShit@users.noreply.github.com> --- packages/eslint-plugin/src/rules/no-restricted-imports.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 7d21e8790fab..b1e2d229f6a7 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -216,7 +216,7 @@ function shouldCreateRule( baseRules: RuleListener, options: Options, ): baseRules is Exclude> { - if (!Object.keys(baseRules).length || options.length === 0) { + if (Object.keys(baseRules).length === 0 || options.length === 0) { return false; } From c10c3ffed7efde2928157336d3a3ca996f6abac7 Mon Sep 17 00:00:00 2001 From: auvred Date: Fri, 22 Dec 2023 08:31:10 +0000 Subject: [PATCH 3/4] refactor: explicit zero-length check --- packages/eslint-plugin/src/rules/no-restricted-imports.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index b1e2d229f6a7..7d8990740d91 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -221,7 +221,7 @@ function shouldCreateRule( } if (!isOptionsArrayOfStringOrObject(options)) { - return !!(options[0].paths?.length || options[0].patterns?.length); + return options[0].paths?.length !== 0 || options[0].patterns?.length !== 0; } return true; From 99a367873b21a3ff9c5cb5e7af5e230dca4e0939 Mon Sep 17 00:00:00 2001 From: auvred Date: Fri, 22 Dec 2023 08:33:42 +0000 Subject: [PATCH 4/4] revert: "refactor: explicit zero-length check" --- packages/eslint-plugin/src/rules/no-restricted-imports.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 7d8990740d91..b1e2d229f6a7 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -221,7 +221,7 @@ function shouldCreateRule( } if (!isOptionsArrayOfStringOrObject(options)) { - return options[0].paths?.length !== 0 || options[0].patterns?.length !== 0; + return !!(options[0].paths?.length || options[0].patterns?.length); } return true;