Skip to content

Commit

Permalink
feat: add allowed option (#25)
Browse files Browse the repository at this point in the history
Adds an `allowed` option to allow certain modules to be used even if they are in the chosen preset/modules list
  • Loading branch information
zloirock authored Jun 27, 2024
1 parent a906d24 commit ab4718d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 6 deletions.
23 changes: 22 additions & 1 deletion docs/rules/ban-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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.
Expand All @@ -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
Expand Down
22 changes: 17 additions & 5 deletions src/rules/ban-dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {createReplacementListener} from '../util/imports.js';
interface BanDependenciesOptions {
presets?: string[];
modules?: string[];
allowed?: string[];
}

const availablePresets: Record<string, ModuleReplacement[]> = {
Expand Down Expand Up @@ -43,6 +44,12 @@ export const rule: Rule.RuleModule = {
items: {
type: 'string'
}
},
allowed: {
type: 'array',
items: {
type: 'string'
}
}
},
additionalProperties: false
Expand All @@ -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
});
}
}
}

Expand Down
58 changes: 58 additions & 0 deletions src/test/rules/ban-dependencies_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -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": {
Expand Down

0 comments on commit ab4718d

Please sign in to comment.