From b018558a704a996ee1a62ef3ee06e0be255f8461 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Thu, 27 Jun 2024 03:08:48 +0700 Subject: [PATCH 1/2] add `allowed` option --- docs/rules/ban-dependencies.md | 23 ++++++++++++++++++++++- src/rules/ban-dependencies.ts | 22 +++++++++++++++++----- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/docs/rules/ban-dependencies.md b/docs/rules/ban-dependencies.md index bfe402c..dc6fc87 100644 --- a/docs/rules/ban-dependencies.md +++ b/docs/rules/ban-dependencies.md @@ -36,7 +36,7 @@ The **default** is `['native', 'microutilities', 'preferred']`. ### `modules` -You may also specify your own list of packages which will be disallowed +You may specify your own list of packages which will be disallowed in code. For example: @@ -51,6 +51,23 @@ For example: } ``` +### `allowed` + +You may specify your own list of packages that will be allowed in code +even if they are in presets. + +For example: + +```json +{ + "rules": { + "depend/ban-dependencies": ["error", { + "allowed": ["is-nan"] + }] + } +} +``` + ## Rule Details This rule bans certain dependencies from being used. @@ -68,6 +85,10 @@ The following patterns are not warnings: ```ts // with `presets: ['native']` Number.isNaN(v); + +// with `presets: ['native'], allowed: ['is-nan']` +const isNaN = require('is-nan'); +isNaN(v); ``` ## When Not To Use It diff --git a/src/rules/ban-dependencies.ts b/src/rules/ban-dependencies.ts index 95e170e..4073d60 100644 --- a/src/rules/ban-dependencies.ts +++ b/src/rules/ban-dependencies.ts @@ -11,6 +11,7 @@ import {createReplacementListener} from '../util/imports.js'; interface BanDependenciesOptions { presets?: string[]; modules?: string[]; + allowed?: string[]; } const availablePresets: Record = { @@ -43,6 +44,12 @@ export const rule: Rule.RuleModule = { items: { type: 'string' } + }, + allowed: { + type: 'array', + items: { + type: 'string' + } } }, additionalProperties: false @@ -67,22 +74,27 @@ export const rule: Rule.RuleModule = { const replacements: ModuleReplacement[] = []; const presets = options?.presets ?? defaultPresets; const modules = options?.modules; + const allowed = new Set(options?.allowed ?? []); for (const preset of presets) { const presetReplacements = availablePresets[preset]; if (presetReplacements) { for (const rep of presetReplacements) { - replacements.push(rep); + if (!allowed.has(rep.moduleName)) { + replacements.push(rep); + } } } } if (modules) { for (const mod of modules) { - replacements.push({ - type: 'none', - moduleName: mod - }); + if (!allowed.has(mod)) { + replacements.push({ + type: 'none', + moduleName: mod + }); + } } } From 211cf045005565b69927ef093934ae2958175b63 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Thu, 27 Jun 2024 18:10:24 +0700 Subject: [PATCH 2/2] add some tests --- src/test/rules/ban-dependencies_test.ts | 58 +++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/test/rules/ban-dependencies_test.ts b/src/test/rules/ban-dependencies_test.ts index 4245522..f1ad931 100644 --- a/src/test/rules/ban-dependencies_test.ts +++ b/src/test/rules/ban-dependencies_test.ts @@ -45,6 +45,24 @@ ruleTester.run('ban-dependencies', rule, { } ] }, + { + code: `import foo from 'is-nan';`, + options: [ + { + presets: ['native'], + allowed: ['is-nan'] + } + ] + }, + { + code: `import foo from 'oogabooga';`, + options: [ + { + modules: ['oogabooga'], + allowed: ['oogabooga'] + } + ] + }, { code: `{ "dependencies": { @@ -179,6 +197,46 @@ ruleTester.run('ban-dependencies', rule, { } ] }, + { + code: `import foo from 'object-is';`, + options: [ + { + presets: ['native'], + allowed: ['is-nan'] + } + ], + errors: [ + { + line: 1, + column: 1, + messageId: 'nativeReplacement', + data: { + name: 'object-is', + replacement: 'Object.is', + url: getMdnUrl('Global_Objects/Object/is') + } + } + ] + }, + { + code: `import foo from 'oogabooga';`, + options: [ + { + modules: ['oogabooga'], + allowed: ['foo'] + } + ], + errors: [ + { + line: 1, + column: 1, + messageId: 'noneReplacement', + data: { + name: 'oogabooga' + } + } + ] + }, { code: `{ "dependencies": {