@blumintinc/eslint-plugin-blumint 1.12.4 → 1.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js
CHANGED
|
@@ -105,10 +105,11 @@ const no_margin_properties_1 = require("./rules/no-margin-properties");
|
|
|
105
105
|
const enforce_boolean_naming_prefixes_1 = require("./rules/enforce-boolean-naming-prefixes");
|
|
106
106
|
const prefer_block_comments_for_declarations_1 = require("./rules/prefer-block-comments-for-declarations");
|
|
107
107
|
const no_undefined_null_passthrough_1 = require("./rules/no-undefined-null-passthrough");
|
|
108
|
+
const no_restricted_imports_dynamic_1 = __importDefault(require("./rules/no-restricted-imports-dynamic"));
|
|
108
109
|
module.exports = {
|
|
109
110
|
meta: {
|
|
110
111
|
name: '@blumintinc/eslint-plugin-blumint',
|
|
111
|
-
version: '1.12.
|
|
112
|
+
version: '1.12.5',
|
|
112
113
|
},
|
|
113
114
|
parseOptions: {
|
|
114
115
|
ecmaVersion: 2020,
|
|
@@ -225,6 +226,7 @@ module.exports = {
|
|
|
225
226
|
'@blumintinc/blumint/no-margin-properties': 'error',
|
|
226
227
|
'@blumintinc/blumint/enforce-boolean-naming-prefixes': 'error',
|
|
227
228
|
'@blumintinc/blumint/no-undefined-null-passthrough': 'error',
|
|
229
|
+
'@blumintinc/blumint/no-restricted-imports-dynamic': 'error',
|
|
228
230
|
},
|
|
229
231
|
},
|
|
230
232
|
},
|
|
@@ -331,6 +333,7 @@ module.exports = {
|
|
|
331
333
|
'no-margin-properties': no_margin_properties_1.noMarginProperties,
|
|
332
334
|
'enforce-boolean-naming-prefixes': enforce_boolean_naming_prefixes_1.enforceBooleanNamingPrefixes,
|
|
333
335
|
'no-undefined-null-passthrough': no_undefined_null_passthrough_1.noUndefinedNullPassthrough,
|
|
336
|
+
'no-restricted-imports-dynamic': no_restricted_imports_dynamic_1.default,
|
|
334
337
|
},
|
|
335
338
|
};
|
|
336
339
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const RULE_NAME = "no-restricted-imports-dynamic";
|
|
2
|
+
type Options = [
|
|
3
|
+
{
|
|
4
|
+
paths?: (string | {
|
|
5
|
+
name: string;
|
|
6
|
+
message?: string;
|
|
7
|
+
allowTypeImports?: boolean;
|
|
8
|
+
allowDynamicImports?: boolean;
|
|
9
|
+
})[];
|
|
10
|
+
patterns?: (string | {
|
|
11
|
+
group: string[];
|
|
12
|
+
message?: string;
|
|
13
|
+
caseSensitive?: boolean;
|
|
14
|
+
allowTypeImports?: boolean;
|
|
15
|
+
allowDynamicImports?: boolean;
|
|
16
|
+
})[];
|
|
17
|
+
} | (string | {
|
|
18
|
+
name: string;
|
|
19
|
+
message?: string;
|
|
20
|
+
allowTypeImports?: boolean;
|
|
21
|
+
allowDynamicImports?: boolean;
|
|
22
|
+
})[]
|
|
23
|
+
];
|
|
24
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"restrictedImport" | "restrictedImportPattern", Options, import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RULE_NAME = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const createRule_1 = require("../utils/createRule");
|
|
9
|
+
exports.RULE_NAME = 'no-restricted-imports-dynamic';
|
|
10
|
+
exports.default = (0, createRule_1.createRule)({
|
|
11
|
+
name: exports.RULE_NAME,
|
|
12
|
+
meta: {
|
|
13
|
+
type: 'suggestion',
|
|
14
|
+
docs: {
|
|
15
|
+
description: 'Disallow specified modules when loaded by `import`, with special handling for .dynamic.tsx files',
|
|
16
|
+
recommended: 'error',
|
|
17
|
+
},
|
|
18
|
+
schema: [
|
|
19
|
+
{
|
|
20
|
+
oneOf: [
|
|
21
|
+
{
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
paths: {
|
|
25
|
+
type: 'array',
|
|
26
|
+
items: {
|
|
27
|
+
oneOf: [
|
|
28
|
+
{ type: 'string' },
|
|
29
|
+
{
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
name: { type: 'string' },
|
|
33
|
+
message: { type: 'string' },
|
|
34
|
+
allowTypeImports: { type: 'boolean' },
|
|
35
|
+
allowDynamicImports: { type: 'boolean' },
|
|
36
|
+
},
|
|
37
|
+
additionalProperties: false,
|
|
38
|
+
required: ['name'],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
patterns: {
|
|
44
|
+
type: 'array',
|
|
45
|
+
items: {
|
|
46
|
+
oneOf: [
|
|
47
|
+
{ type: 'string' },
|
|
48
|
+
{
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
group: {
|
|
52
|
+
type: 'array',
|
|
53
|
+
items: { type: 'string' },
|
|
54
|
+
minItems: 1,
|
|
55
|
+
},
|
|
56
|
+
message: { type: 'string' },
|
|
57
|
+
caseSensitive: { type: 'boolean' },
|
|
58
|
+
allowTypeImports: { type: 'boolean' },
|
|
59
|
+
allowDynamicImports: { type: 'boolean' },
|
|
60
|
+
},
|
|
61
|
+
additionalProperties: false,
|
|
62
|
+
required: ['group'],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
additionalProperties: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'array',
|
|
72
|
+
items: {
|
|
73
|
+
oneOf: [
|
|
74
|
+
{ type: 'string' },
|
|
75
|
+
{
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: {
|
|
78
|
+
name: { type: 'string' },
|
|
79
|
+
message: { type: 'string' },
|
|
80
|
+
allowTypeImports: { type: 'boolean' },
|
|
81
|
+
allowDynamicImports: { type: 'boolean' },
|
|
82
|
+
},
|
|
83
|
+
additionalProperties: false,
|
|
84
|
+
required: ['name'],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
messages: {
|
|
93
|
+
restrictedImport: "import '{{importSource}}' is restricted from being used{{customMessage}}",
|
|
94
|
+
restrictedImportPattern: "import '{{importSource}}' is restricted from being used by a pattern{{customMessage}}",
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
defaultOptions: [{ paths: [], patterns: [] }],
|
|
98
|
+
create(context, [options]) {
|
|
99
|
+
// Get the file path and name
|
|
100
|
+
const filePath = context.getFilename();
|
|
101
|
+
const fileName = path_1.default.basename(filePath);
|
|
102
|
+
// Check if the file has .dynamic.ts or .dynamic.tsx extension
|
|
103
|
+
const isDynamicFile = /\.dynamic\.tsx?$/.test(fileName);
|
|
104
|
+
// If this is a dynamic file, we'll allow imports from other dynamic files
|
|
105
|
+
if (isDynamicFile) {
|
|
106
|
+
return {};
|
|
107
|
+
}
|
|
108
|
+
// Process options
|
|
109
|
+
const restrictedPaths = [];
|
|
110
|
+
const restrictedPatterns = [];
|
|
111
|
+
if (Array.isArray(options)) {
|
|
112
|
+
// Handle array format
|
|
113
|
+
for (const item of options) {
|
|
114
|
+
if (typeof item === 'string') {
|
|
115
|
+
restrictedPaths.push({ name: item });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
restrictedPaths.push(item);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (options && typeof options === 'object') {
|
|
123
|
+
// Handle object format
|
|
124
|
+
if (options.paths) {
|
|
125
|
+
for (const item of options.paths) {
|
|
126
|
+
if (typeof item === 'string') {
|
|
127
|
+
restrictedPaths.push({ name: item });
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
restrictedPaths.push(item);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (options.patterns) {
|
|
135
|
+
for (const item of options.patterns) {
|
|
136
|
+
if (typeof item === 'string') {
|
|
137
|
+
restrictedPatterns.push({ group: [item] });
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
restrictedPatterns.push(item);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
ImportDeclaration(node) {
|
|
147
|
+
const importSource = node.source.value;
|
|
148
|
+
const importKind = node.importKind;
|
|
149
|
+
// Check against restricted paths
|
|
150
|
+
for (const restrictedPath of restrictedPaths) {
|
|
151
|
+
if (importSource === restrictedPath.name) {
|
|
152
|
+
// Skip if it's a type import and type imports are allowed
|
|
153
|
+
if (importKind === 'type' &&
|
|
154
|
+
restrictedPath.allowTypeImports === true) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Skip if it's a dynamic import and dynamic imports are allowed
|
|
158
|
+
if (importSource.endsWith('.dynamic') &&
|
|
159
|
+
restrictedPath.allowDynamicImports === true) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
context.report({
|
|
163
|
+
node,
|
|
164
|
+
messageId: 'restrictedImport',
|
|
165
|
+
data: {
|
|
166
|
+
importSource,
|
|
167
|
+
customMessage: restrictedPath.message
|
|
168
|
+
? `: ${restrictedPath.message}`
|
|
169
|
+
: '',
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Check against restricted patterns
|
|
175
|
+
for (const restrictedPattern of restrictedPatterns) {
|
|
176
|
+
const { group, caseSensitive = false } = restrictedPattern;
|
|
177
|
+
const matched = group.some((pattern) => {
|
|
178
|
+
if (pattern.includes('*')) {
|
|
179
|
+
const regex = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`, caseSensitive ? '' : 'i');
|
|
180
|
+
return regex.test(importSource);
|
|
181
|
+
}
|
|
182
|
+
return caseSensitive
|
|
183
|
+
? importSource === pattern
|
|
184
|
+
: importSource.toLowerCase() === pattern.toLowerCase();
|
|
185
|
+
});
|
|
186
|
+
if (matched) {
|
|
187
|
+
// Skip if it's a type import and type imports are allowed
|
|
188
|
+
if (importKind === 'type' &&
|
|
189
|
+
restrictedPattern.allowTypeImports === true) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
// Skip if it's a dynamic import and dynamic imports are allowed
|
|
193
|
+
if (importSource.endsWith('.dynamic') &&
|
|
194
|
+
restrictedPattern.allowDynamicImports === true) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
context.report({
|
|
198
|
+
node,
|
|
199
|
+
messageId: 'restrictedImportPattern',
|
|
200
|
+
data: {
|
|
201
|
+
importSource,
|
|
202
|
+
customMessage: restrictedPattern.message
|
|
203
|
+
? `: ${restrictedPattern.message}`
|
|
204
|
+
: '',
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
//# sourceMappingURL=no-restricted-imports-dynamic.js.map
|
|
@@ -28,6 +28,12 @@ function isTypePredicate(node) {
|
|
|
28
28
|
function isInsideReturnStatement(node) {
|
|
29
29
|
let current = node;
|
|
30
30
|
while (current?.parent) {
|
|
31
|
+
// If we encounter a variable declaration before a return statement,
|
|
32
|
+
// then the node is not directly inside a return statement
|
|
33
|
+
if (current.parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator ||
|
|
34
|
+
current.parent.type === utils_1.AST_NODE_TYPES.VariableDeclaration) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
31
37
|
if (current.parent.type === utils_1.AST_NODE_TYPES.ReturnStatement) {
|
|
32
38
|
return true;
|
|
33
39
|
}
|