Skip to content

Commit 4d8e743

Browse files
chimericdreamljharb
authored andcommitted
starting point for adding allow/deny list options to no-namespace
1 parent 9fa6bc9 commit 4d8e743

File tree

2 files changed

+119
-4
lines changed

2 files changed

+119
-4
lines changed

src/rules/no-namespace.js

+48-4
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,50 @@ module.exports = {
1717
url: docsUrl('no-namespace'),
1818
},
1919
fixable: 'code',
20-
schema: [],
20+
schema: [
21+
{
22+
oneOf: [
23+
{
24+
type: 'object',
25+
properties: {
26+
allowList: {
27+
type: 'array',
28+
},
29+
},
30+
additionalProperties: false,
31+
},
32+
{
33+
type: 'object',
34+
properties: {
35+
denyList: {
36+
type: 'array',
37+
},
38+
},
39+
additionalProperties: false,
40+
},
41+
],
42+
},
43+
],
2144
},
2245

2346
create: function (context) {
2447
return {
2548
'ImportNamespaceSpecifier': function (node) {
49+
const options = context.options[0] || {};
50+
const [mode, identifiers] = Array.isArray(options.denyList)
51+
? ['deny', options.denyList]
52+
: ['allow', options.allowList || []];
53+
2654
const scopeVariables = context.getScope().variables;
27-
const namespaceVariable = scopeVariables.find((variable) =>
28-
variable.defs[0].node === node
29-
);
55+
const namespaceVariable = scopeVariables.find((variable) => variable.defs[0].node === node);
3056
const namespaceReferences = namespaceVariable.references;
3157
const namespaceIdentifiers = namespaceReferences.map(reference => reference.identifier);
3258
const canFix = namespaceIdentifiers.length > 0 && !usesNamespaceAsObject(namespaceIdentifiers);
3359

60+
if (!shouldReport(mode, identifiers, namespaceIdentifiers)) {
61+
return;
62+
}
63+
3464
context.report({
3565
node,
3666
message: `Unexpected namespace import.`,
@@ -87,6 +117,20 @@ module.exports = {
87117
},
88118
};
89119

120+
/**
121+
*
122+
* @param {'deny' | 'allow'} mode
123+
* @param {string[]} list
124+
* @param {TSESTree.Identifier[]} namespaceIdentifiers
125+
*/
126+
function shouldReport(mode, list, identifiers) {
127+
for (const identifier of identifiers) {
128+
if (list.includes(identifier)) {
129+
return mode === 'deny';
130+
}
131+
}
132+
}
133+
90134
/**
91135
* @param {Identifier[]} namespaceIdentifiers
92136
* @returns {boolean} `true` if the namespace variable is more than just a glorified constant

tests/src/rules/no-namespace.js

+71
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,80 @@ ruleTester.run('no-namespace', require('rules/no-namespace'), {
7878
{ code: 'import { a, b } from \'./foo\';', parserOptions: { ecmaVersion: 2015, sourceType: 'module' } },
7979
{ code: 'import bar from \'bar\';', parserOptions: { ecmaVersion: 2015, sourceType: 'module' } },
8080
{ code: 'import bar from \'./bar\';', parserOptions: { ecmaVersion: 2015, sourceType: 'module' } },
81+
{
82+
code: 'import * as foo from \'foo\';',
83+
options: [{
84+
denyList: ['bar'],
85+
}],
86+
parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
87+
},
88+
{
89+
code: 'import * as bar from \'foo\';',
90+
options: [{
91+
denyList: ['bar'],
92+
}],
93+
parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
94+
},
95+
{
96+
code: 'import * as foo from \'foo\';',
97+
options: [{
98+
allowList: ['foo'],
99+
}],
100+
parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
101+
},
102+
{
103+
code: 'import * as lib from \'some-lib\';',
104+
options: [{
105+
allowList: ['some-lib'],
106+
}],
107+
parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
108+
},
109+
{
110+
code: 'import * as scopedLib from \'@scoped/lib\';',
111+
options: [{
112+
allowList: ['@scoped/lib'],
113+
}],
114+
parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
115+
},
81116
],
82117

83118
invalid: [
119+
test({
120+
code: 'import * as foo from \'foo\';',
121+
output: 'import * as foo from \'foo\';',
122+
options: [{
123+
allowList: ['bar'],
124+
}],
125+
errors: [ {
126+
line: 1,
127+
column: 8,
128+
message: ERROR_MESSAGE,
129+
} ],
130+
}),
131+
test({
132+
code: 'import * as bar from \'foo\';',
133+
output: 'import * as bar from \'foo\';',
134+
options: [{
135+
allowList: ['bar'],
136+
}],
137+
errors: [ {
138+
line: 1,
139+
column: 8,
140+
message: ERROR_MESSAGE,
141+
} ],
142+
}),
143+
test({
144+
code: 'import * as foo from \'foo\';',
145+
output: 'import * as foo from \'foo\';',
146+
options: [{
147+
denyList: ['foo'],
148+
}],
149+
errors: [ {
150+
line: 1,
151+
column: 8,
152+
message: ERROR_MESSAGE,
153+
} ],
154+
}),
84155
test({
85156
code: 'import * as foo from \'foo\';',
86157
output: 'import * as foo from \'foo\';',

0 commit comments

Comments
 (0)