eslint-plugin-import-next 2.3.14 → 2.3.16
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/package.json +9 -4
- package/src/files/foo.js +1 -6
- package/src/files/no-default.js +1 -4
- package/src/index.js +1 -326
- package/src/oxlint.js +1 -3
- package/src/rules/consistent-type-specifier-style.js +1 -109
- package/src/rules/default.js +1 -56
- package/src/rules/dynamic-import-chunkname.js +1 -115
- package/src/rules/enforce-dependency-direction.js +1 -213
- package/src/rules/enforce-import-order.js +1 -299
- package/src/rules/enforce-team-boundaries.js +1 -191
- package/src/rules/export.js +1 -111
- package/src/rules/exports-last.js +1 -67
- package/src/rules/extensions.js +1 -105
- package/src/rules/first.js +1 -53
- package/src/rules/group-exports.js +1 -69
- package/src/rules/max-dependencies.js +1 -241
- package/src/rules/named.js +1 -67
- package/src/rules/namespace.js +1 -64
- package/src/rules/newline-after-import.js +1 -57
- package/src/rules/no-absolute-path.js +1 -107
- package/src/rules/no-amd.js +1 -108
- package/src/rules/no-anonymous-default-export.js +1 -135
- package/src/rules/no-barrel-file.js +1 -194
- package/src/rules/no-barrel-import.js +1 -135
- package/src/rules/no-commonjs.js +1 -312
- package/src/rules/no-cross-domain-imports.js +1 -233
- package/src/rules/no-cycle.js +2 -396
- package/src/rules/no-default-export.js +2 -213
- package/src/rules/no-deprecated.js +1 -316
- package/src/rules/no-duplicates.js +1 -81
- package/src/rules/no-dynamic-require.js +1 -78
- package/src/rules/no-empty-named-blocks.js +1 -103
- package/src/rules/no-extraneous-dependencies.js +7 -385
- package/src/rules/no-full-package-import.js +1 -134
- package/src/rules/no-import-module-exports.js +1 -76
- package/src/rules/no-internal-modules.js +1 -256
- package/src/rules/no-legacy-imports.js +1 -125
- package/src/rules/no-mutable-exports.js +1 -146
- package/src/rules/no-named-as-default-member.js +1 -73
- package/src/rules/no-named-as-default.js +1 -90
- package/src/rules/no-named-default.js +1 -48
- package/src/rules/no-named-export.js +1 -174
- package/src/rules/no-namespace.js +1 -71
- package/src/rules/no-nodejs-modules.js +1 -229
- package/src/rules/no-relative-packages.js +1 -129
- package/src/rules/no-relative-parent-imports.js +1 -118
- package/src/rules/no-restricted-paths.js +1 -89
- package/src/rules/no-self-import.js +1 -113
- package/src/rules/no-unassigned-import.js +1 -115
- package/src/rules/no-unresolved.js +1 -189
- package/src/rules/no-unused-modules.js +1 -82
- package/src/rules/no-useless-path-segments.js +1 -107
- package/src/rules/prefer-default-export.js +1 -188
- package/src/rules/prefer-direct-import.js +1 -170
- package/src/rules/prefer-modern-api.js +1 -212
- package/src/rules/prefer-node-protocol.js +1 -174
- package/src/rules/prefer-tree-shakeable-imports.js +1 -134
- package/src/rules/require-import-approval.js +1 -174
- package/src/rules/unambiguous.js +1 -70
- package/src/types/index.js +1 -2
- package/src/utils/typescript-peer.js +1 -23
|
@@ -1,241 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.maxDependencies = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
exports.maxDependencies = (0, eslint_devkit_1.createRule)({
|
|
7
|
-
name: 'max-dependencies',
|
|
8
|
-
meta: {
|
|
9
|
-
type: 'suggestion',
|
|
10
|
-
docs: {
|
|
11
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/max-dependencies.md',
|
|
12
|
-
description: 'Enforce the maximum number of dependencies a module can have',
|
|
13
|
-
},
|
|
14
|
-
hasSuggestions: false,
|
|
15
|
-
messages: {
|
|
16
|
-
maxDependencies: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
18
|
-
issueName: 'Too Many Dependencies',
|
|
19
|
-
description: 'Module exceeds maximum dependency limit',
|
|
20
|
-
severity: 'MEDIUM',
|
|
21
|
-
fix: 'Refactor to reduce dependencies or increase limit for this module',
|
|
22
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md',
|
|
23
|
-
}),
|
|
24
|
-
suggestRefactor: (0, eslint_devkit_2.formatLLMMessage)({
|
|
25
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
26
|
-
issueName: 'Dependency Refactoring',
|
|
27
|
-
description: 'Consider breaking down module or creating barrel exports',
|
|
28
|
-
severity: 'LOW',
|
|
29
|
-
fix: 'Split module into smaller, focused modules',
|
|
30
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md',
|
|
31
|
-
}),
|
|
32
|
-
dependencyAnalysis: (0, eslint_devkit_2.formatLLMMessage)({
|
|
33
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
34
|
-
issueName: 'Dependency Analysis',
|
|
35
|
-
description: 'Review dependency usage and consider alternatives',
|
|
36
|
-
severity: 'LOW',
|
|
37
|
-
fix: 'Analyze if all dependencies are necessary',
|
|
38
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md',
|
|
39
|
-
}),
|
|
40
|
-
},
|
|
41
|
-
schema: [
|
|
42
|
-
{
|
|
43
|
-
type: 'object',
|
|
44
|
-
properties: {
|
|
45
|
-
max: {
|
|
46
|
-
type: 'number',
|
|
47
|
-
minimum: 1,
|
|
48
|
-
default: 10,
|
|
49
|
-
description: 'Maximum number of dependencies allowed.',
|
|
50
|
-
},
|
|
51
|
-
ignoreTypeImports: {
|
|
52
|
-
type: 'boolean',
|
|
53
|
-
default: true,
|
|
54
|
-
description: 'Ignore type-only imports.',
|
|
55
|
-
},
|
|
56
|
-
ignoreImports: {
|
|
57
|
-
type: 'array',
|
|
58
|
-
items: {
|
|
59
|
-
type: 'string',
|
|
60
|
-
},
|
|
61
|
-
description: 'Import sources to ignore.',
|
|
62
|
-
},
|
|
63
|
-
ignoreFiles: {
|
|
64
|
-
type: 'array',
|
|
65
|
-
items: {
|
|
66
|
-
type: 'string',
|
|
67
|
-
},
|
|
68
|
-
description: 'File patterns to ignore.',
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
additionalProperties: false,
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
defaultOptions: [
|
|
76
|
-
{
|
|
77
|
-
max: 10,
|
|
78
|
-
ignoreTypeImports: true,
|
|
79
|
-
ignoreImports: [],
|
|
80
|
-
ignoreFiles: [],
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
create(context) {
|
|
84
|
-
const [options] = context.options;
|
|
85
|
-
const { max = 10, ignoreTypeImports = true, ignoreImports = [], ignoreFiles = [], } = options || {};
|
|
86
|
-
const filename = context.filename;
|
|
87
|
-
if (!filename) {
|
|
88
|
-
return {};
|
|
89
|
-
}
|
|
90
|
-
const shouldIgnoreFile = ignoreFiles.some((pattern) => {
|
|
91
|
-
if (pattern.includes('*')) {
|
|
92
|
-
const regex = new RegExp(pattern.replace(/\*/g, '.*'));
|
|
93
|
-
return regex.test(filename);
|
|
94
|
-
}
|
|
95
|
-
return filename.includes(pattern);
|
|
96
|
-
});
|
|
97
|
-
if (shouldIgnoreFile) {
|
|
98
|
-
return {};
|
|
99
|
-
}
|
|
100
|
-
const dependencies = new Set();
|
|
101
|
-
function shouldCountImport(importPath, node) {
|
|
102
|
-
if (ignoreImports.includes(importPath)) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
if (ignoreTypeImports && node.importKind === 'type') {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
const nodeBuiltins = [
|
|
112
|
-
'assert',
|
|
113
|
-
'buffer',
|
|
114
|
-
'child_process',
|
|
115
|
-
'cluster',
|
|
116
|
-
'crypto',
|
|
117
|
-
'dgram',
|
|
118
|
-
'dns',
|
|
119
|
-
'domain',
|
|
120
|
-
'events',
|
|
121
|
-
'fs',
|
|
122
|
-
'http',
|
|
123
|
-
'https',
|
|
124
|
-
'net',
|
|
125
|
-
'os',
|
|
126
|
-
'path',
|
|
127
|
-
'punycode',
|
|
128
|
-
'querystring',
|
|
129
|
-
'readline',
|
|
130
|
-
'stream',
|
|
131
|
-
'string_decoder',
|
|
132
|
-
'timers',
|
|
133
|
-
'tls',
|
|
134
|
-
'tty',
|
|
135
|
-
'url',
|
|
136
|
-
'util',
|
|
137
|
-
'v8',
|
|
138
|
-
'vm',
|
|
139
|
-
'zlib',
|
|
140
|
-
];
|
|
141
|
-
if (nodeBuiltins.includes(importPath) || importPath.startsWith('node:')) {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
return true;
|
|
145
|
-
}
|
|
146
|
-
function shouldCountRequire(importPath) {
|
|
147
|
-
if (ignoreImports.includes(importPath)) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
const nodeBuiltins = [
|
|
154
|
-
'assert',
|
|
155
|
-
'buffer',
|
|
156
|
-
'child_process',
|
|
157
|
-
'cluster',
|
|
158
|
-
'crypto',
|
|
159
|
-
'dgram',
|
|
160
|
-
'dns',
|
|
161
|
-
'domain',
|
|
162
|
-
'events',
|
|
163
|
-
'fs',
|
|
164
|
-
'http',
|
|
165
|
-
'https',
|
|
166
|
-
'net',
|
|
167
|
-
'os',
|
|
168
|
-
'path',
|
|
169
|
-
'punycode',
|
|
170
|
-
'querystring',
|
|
171
|
-
'readline',
|
|
172
|
-
'stream',
|
|
173
|
-
'string_decoder',
|
|
174
|
-
'timers',
|
|
175
|
-
'tls',
|
|
176
|
-
'tty',
|
|
177
|
-
'url',
|
|
178
|
-
'util',
|
|
179
|
-
'v8',
|
|
180
|
-
'vm',
|
|
181
|
-
'zlib',
|
|
182
|
-
];
|
|
183
|
-
if (nodeBuiltins.includes(importPath) || importPath.startsWith('node:')) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
function addDependency(importPath) {
|
|
189
|
-
const packageName = importPath.startsWith('@')
|
|
190
|
-
? importPath.split('/').slice(0, 2).join('/')
|
|
191
|
-
: importPath.split('/')[0];
|
|
192
|
-
dependencies.add(packageName);
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
ImportDeclaration(node) {
|
|
196
|
-
const importPath = node.source.value;
|
|
197
|
-
if (typeof importPath === 'string' &&
|
|
198
|
-
shouldCountImport(importPath, node)) {
|
|
199
|
-
addDependency(importPath);
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
CallExpression(node) {
|
|
203
|
-
if (node.callee.type === 'Identifier' &&
|
|
204
|
-
node.callee.name === 'require' &&
|
|
205
|
-
node.arguments.length === 1) {
|
|
206
|
-
const arg = node.arguments[0];
|
|
207
|
-
if (arg.type === 'Literal' && typeof arg.value === 'string') {
|
|
208
|
-
if (shouldCountRequire(arg.value)) {
|
|
209
|
-
addDependency(arg.value);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
ImportExpression(node) {
|
|
215
|
-
const source = node.source;
|
|
216
|
-
if (source.type === 'Literal' && typeof source.value === 'string') {
|
|
217
|
-
if (shouldCountRequire(source.value)) {
|
|
218
|
-
addDependency(source.value);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
'Program:exit'(node) {
|
|
223
|
-
const dependencyCount = dependencies.size;
|
|
224
|
-
if (dependencyCount > max) {
|
|
225
|
-
const dependencyList = Array.from(dependencies).join(', ');
|
|
226
|
-
context.report({
|
|
227
|
-
node,
|
|
228
|
-
messageId: 'maxDependencies',
|
|
229
|
-
data: {
|
|
230
|
-
count: dependencyCount,
|
|
231
|
-
max,
|
|
232
|
-
dependencies: dependencyList,
|
|
233
|
-
filename,
|
|
234
|
-
overLimit: dependencyCount - max,
|
|
235
|
-
},
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
};
|
|
240
|
-
},
|
|
241
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.maxDependencies=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.maxDependencies=(0,eslint_devkit_1.createRule)({name:"max-dependencies",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/max-dependencies.md",description:"Enforce the maximum number of dependencies a module can have"},hasSuggestions:false,messages:{maxDependencies:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Too Many Dependencies",description:"Module exceeds maximum dependency limit",severity:"MEDIUM",fix:"Refactor to reduce dependencies or increase limit for this module",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md"}),suggestRefactor:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Dependency Refactoring",description:"Consider breaking down module or creating barrel exports",severity:"LOW",fix:"Split module into smaller, focused modules",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md"}),dependencyAnalysis:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Dependency Analysis",description:"Review dependency usage and consider alternatives",severity:"LOW",fix:"Analyze if all dependencies are necessary",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/max-dependencies.md"})},schema:[{type:"object",properties:{max:{type:"number",minimum:1,default:10,description:"Maximum number of dependencies allowed."},ignoreTypeImports:{type:"boolean",default:true,description:"Ignore type-only imports."},ignoreImports:{type:"array",items:{type:"string"},description:"Import sources to ignore."},ignoreFiles:{type:"array",items:{type:"string"},description:"File patterns to ignore."}},additionalProperties:false}]},defaultOptions:[{max:10,ignoreTypeImports:true,ignoreImports:[],ignoreFiles:[]}],create(context){const[options]=context.options;const{max=10,ignoreTypeImports=true,ignoreImports=[],ignoreFiles=[]}=options||{};const filename=context.filename;if(!filename){return{}}const shouldIgnoreFile=ignoreFiles.some(pattern=>{if(pattern.includes("*")){const regex=new RegExp(pattern.replace(/\*/g,".*"));return regex.test(filename)}return filename.includes(pattern)});if(shouldIgnoreFile){return{}}const dependencies=new Set;function shouldCountImport(importPath,node){if(ignoreImports.includes(importPath)){return false}if(ignoreTypeImports&&node.importKind==="type"){return false}if(importPath.startsWith("./")||importPath.startsWith("../")){return false}const nodeBuiltins=["assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","fs","http","https","net","os","path","punycode","querystring","readline","stream","string_decoder","timers","tls","tty","url","util","v8","vm","zlib"];if(nodeBuiltins.includes(importPath)||importPath.startsWith("node:")){return false}return true}function shouldCountRequire(importPath){if(ignoreImports.includes(importPath)){return false}if(importPath.startsWith("./")||importPath.startsWith("../")){return false}const nodeBuiltins=["assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","fs","http","https","net","os","path","punycode","querystring","readline","stream","string_decoder","timers","tls","tty","url","util","v8","vm","zlib"];if(nodeBuiltins.includes(importPath)||importPath.startsWith("node:")){return false}return true}function addDependency(importPath){const packageName=importPath.startsWith("@")?importPath.split("/").slice(0,2).join("/"):importPath.split("/")[0];dependencies.add(packageName)}return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath==="string"&&shouldCountImport(importPath,node)){addDependency(importPath)}},CallExpression(node){if(node.callee.type==="Identifier"&&node.callee.name==="require"&&node.arguments.length===1){const arg=node.arguments[0];if(arg.type==="Literal"&&typeof arg.value==="string"){if(shouldCountRequire(arg.value)){addDependency(arg.value)}}}},ImportExpression(node){const source=node.source;if(source.type==="Literal"&&typeof source.value==="string"){if(shouldCountRequire(source.value)){addDependency(source.value)}}},"Program:exit"(node){const dependencyCount=dependencies.size;if(dependencyCount>max){const dependencyList=Array.from(dependencies).join(", ");context.report({node,messageId:"maxDependencies",data:{count:dependencyCount,max,dependencies:dependencyList,filename,overLimit:dependencyCount-max}})}}}}});
|
package/src/rules/named.js
CHANGED
|
@@ -1,67 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.named = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
const typescript_peer_1 = require("../utils/typescript-peer");
|
|
7
|
-
exports.named = (0, eslint_devkit_1.createRule)({
|
|
8
|
-
name: 'named',
|
|
9
|
-
meta: {
|
|
10
|
-
type: 'problem',
|
|
11
|
-
docs: {
|
|
12
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/named.md',
|
|
13
|
-
description: 'Ensure named imports correspond to a named export in the remote file',
|
|
14
|
-
},
|
|
15
|
-
messages: {
|
|
16
|
-
named: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.SECURITY,
|
|
18
|
-
issueName: 'Missing Named Export',
|
|
19
|
-
description: 'Named export not found in module',
|
|
20
|
-
severity: 'HIGH',
|
|
21
|
-
fix: 'Verify the export name or use default import',
|
|
22
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/named.md',
|
|
23
|
-
}),
|
|
24
|
-
},
|
|
25
|
-
schema: [],
|
|
26
|
-
},
|
|
27
|
-
defaultOptions: [],
|
|
28
|
-
create(context) {
|
|
29
|
-
if (!(0, eslint_devkit_2.hasParserServices)(context))
|
|
30
|
-
return {};
|
|
31
|
-
const services = (0, eslint_devkit_2.getParserServices)(context);
|
|
32
|
-
const checker = services.program?.getTypeChecker?.();
|
|
33
|
-
return {
|
|
34
|
-
ImportSpecifier(node) {
|
|
35
|
-
if (node.parent.type === 'ImportDeclaration' &&
|
|
36
|
-
node.parent.importKind === 'type')
|
|
37
|
-
return;
|
|
38
|
-
const tsNode = services.esTreeNodeToTSNodeMap.get(node.imported);
|
|
39
|
-
let symbol = checker?.getSymbolAtLocation?.(tsNode);
|
|
40
|
-
if (symbol && (symbol.flags & (0, typescript_peer_1.aliasSymbolFlag)())) {
|
|
41
|
-
try {
|
|
42
|
-
symbol = checker?.getAliasedSymbol?.(symbol);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
symbol = undefined;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (symbol && symbol.escapedName === 'unknown') {
|
|
49
|
-
symbol = undefined;
|
|
50
|
-
}
|
|
51
|
-
if (!symbol) {
|
|
52
|
-
const source = node.parent.source;
|
|
53
|
-
if (!source)
|
|
54
|
-
return;
|
|
55
|
-
const moduleNode = services.esTreeNodeToTSNodeMap.get(source);
|
|
56
|
-
const moduleSymbol = checker?.getSymbolAtLocation?.(moduleNode);
|
|
57
|
-
if (!moduleSymbol)
|
|
58
|
-
return;
|
|
59
|
-
context.report({
|
|
60
|
-
node: node.imported,
|
|
61
|
-
messageId: 'named',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
},
|
|
67
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.named=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const typescript_peer_1=require("../utils/typescript-peer");exports.named=(0,eslint_devkit_1.createRule)({name:"named",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/named.md",description:"Ensure named imports correspond to a named export in the remote file"},messages:{named:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.SECURITY,issueName:"Missing Named Export",description:"Named export not found in module",severity:"HIGH",fix:"Verify the export name or use default import",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/named.md"})},schema:[]},defaultOptions:[],create(context){if(!(0,eslint_devkit_2.hasParserServices)(context))return{};const services=(0,eslint_devkit_2.getParserServices)(context);const checker=services.program?.getTypeChecker?.();return{ImportSpecifier(node){if(node.parent.type==="ImportDeclaration"&&node.parent.importKind==="type")return;const tsNode=services.esTreeNodeToTSNodeMap.get(node.imported);let symbol=checker?.getSymbolAtLocation?.(tsNode);if(symbol&&symbol.flags&(0,typescript_peer_1.aliasSymbolFlag)()){try{symbol=checker?.getAliasedSymbol?.(symbol)}catch{symbol=void 0}}if(symbol&&symbol.escapedName==="unknown"){symbol=void 0}if(!symbol){const source=node.parent.source;if(!source)return;const moduleNode=services.esTreeNodeToTSNodeMap.get(source);const moduleSymbol=checker?.getSymbolAtLocation?.(moduleNode);if(!moduleSymbol)return;context.report({node:node.imported,messageId:"named"})}}}}});
|
package/src/rules/namespace.js
CHANGED
|
@@ -1,64 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.namespace = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
const typescript_peer_1 = require("../utils/typescript-peer");
|
|
7
|
-
exports.namespace = (0, eslint_devkit_1.createRule)({
|
|
8
|
-
name: 'namespace',
|
|
9
|
-
meta: {
|
|
10
|
-
type: 'problem',
|
|
11
|
-
docs: {
|
|
12
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/namespace.md',
|
|
13
|
-
description: 'Ensure imported namespaces contain dereferenced properties as they are dereferenced',
|
|
14
|
-
},
|
|
15
|
-
messages: {
|
|
16
|
-
namespace: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.QUALITY,
|
|
18
|
-
issueName: 'Namespace Import Issue',
|
|
19
|
-
description: 'Namespace import usage issue',
|
|
20
|
-
severity: 'MEDIUM',
|
|
21
|
-
fix: 'Verify namespace member existence',
|
|
22
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/namespace.md',
|
|
23
|
-
}),
|
|
24
|
-
},
|
|
25
|
-
schema: [],
|
|
26
|
-
},
|
|
27
|
-
defaultOptions: [],
|
|
28
|
-
create(context) {
|
|
29
|
-
if (!(0, eslint_devkit_2.hasParserServices)(context))
|
|
30
|
-
return {};
|
|
31
|
-
const services = (0, eslint_devkit_2.getParserServices)(context);
|
|
32
|
-
const checker = services.program?.getTypeChecker?.();
|
|
33
|
-
return {
|
|
34
|
-
MemberExpression(node) {
|
|
35
|
-
const object = node.object;
|
|
36
|
-
if (object.type !== 'Identifier')
|
|
37
|
-
return;
|
|
38
|
-
const tsNode = services.esTreeNodeToTSNodeMap.get(object);
|
|
39
|
-
const symbol = checker?.getSymbolAtLocation?.(tsNode);
|
|
40
|
-
if (symbol && symbol.declarations && symbol.declarations.length > 0) {
|
|
41
|
-
const declaration = symbol.declarations[0];
|
|
42
|
-
if (declaration.kind === (0, typescript_peer_1.loadTypeScript)()?.SyntaxKind.NamespaceImport) {
|
|
43
|
-
if (node.property.type !== 'Identifier')
|
|
44
|
-
return;
|
|
45
|
-
const propertyName = node.property.name;
|
|
46
|
-
const type = checker?.getTypeAtLocation?.(tsNode);
|
|
47
|
-
if (!type)
|
|
48
|
-
return;
|
|
49
|
-
const propertySymbol = checker?.getPropertyOfType?.(type, propertyName);
|
|
50
|
-
if (!propertySymbol) {
|
|
51
|
-
context.report({
|
|
52
|
-
node: node.property,
|
|
53
|
-
messageId: 'namespace',
|
|
54
|
-
data: {
|
|
55
|
-
name: propertyName,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
},
|
|
64
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.namespace=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const typescript_peer_1=require("../utils/typescript-peer");exports.namespace=(0,eslint_devkit_1.createRule)({name:"namespace",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/namespace.md",description:"Ensure imported namespaces contain dereferenced properties as they are dereferenced"},messages:{namespace:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.QUALITY,issueName:"Namespace Import Issue",description:"Namespace import usage issue",severity:"MEDIUM",fix:"Verify namespace member existence",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/namespace.md"})},schema:[]},defaultOptions:[],create(context){if(!(0,eslint_devkit_2.hasParserServices)(context))return{};const services=(0,eslint_devkit_2.getParserServices)(context);const checker=services.program?.getTypeChecker?.();return{MemberExpression(node){const object=node.object;if(object.type!=="Identifier")return;const tsNode=services.esTreeNodeToTSNodeMap.get(object);const symbol=checker?.getSymbolAtLocation?.(tsNode);if(symbol&&symbol.declarations&&symbol.declarations.length>0){const declaration=symbol.declarations[0];if(declaration.kind===(0,typescript_peer_1.loadTypeScript)()?.SyntaxKind.NamespaceImport){if(node.property.type!=="Identifier")return;const propertyName=node.property.name;const type=checker?.getTypeAtLocation?.(tsNode);if(!type)return;const propertySymbol=checker?.getPropertyOfType?.(type,propertyName);if(!propertySymbol){context.report({node:node.property,messageId:"namespace",data:{name:propertyName}})}}}}}}});
|
|
@@ -1,57 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.newlineAfterImport = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
exports.newlineAfterImport = (0, eslint_devkit_1.createRule)({
|
|
7
|
-
name: 'newline-after-import',
|
|
8
|
-
meta: {
|
|
9
|
-
type: 'layout',
|
|
10
|
-
docs: {
|
|
11
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/newline-after-import.md',
|
|
12
|
-
description: 'Enforce a newline after import statements',
|
|
13
|
-
},
|
|
14
|
-
fixable: 'whitespace',
|
|
15
|
-
messages: {
|
|
16
|
-
newlineAfterImport: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.QUALITY,
|
|
18
|
-
issueName: 'Newline After Import',
|
|
19
|
-
description: 'Require a newline after the last import statement',
|
|
20
|
-
severity: 'LOW',
|
|
21
|
-
fix: 'Add a newline after the import block',
|
|
22
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/newline-after-import.md',
|
|
23
|
-
}),
|
|
24
|
-
},
|
|
25
|
-
schema: [],
|
|
26
|
-
},
|
|
27
|
-
defaultOptions: [],
|
|
28
|
-
create(context) {
|
|
29
|
-
return {
|
|
30
|
-
ImportDeclaration(node) {
|
|
31
|
-
const sourceCode = context.sourceCode;
|
|
32
|
-
const nextToken = sourceCode.getTokenAfter(node);
|
|
33
|
-
if (!nextToken)
|
|
34
|
-
return;
|
|
35
|
-
if (nextToken.loc.start.line === node.loc.end.line) {
|
|
36
|
-
}
|
|
37
|
-
const nextNode = sourceCode.getNodeByRangeIndex(nextToken.range[0]);
|
|
38
|
-
if (nextNode &&
|
|
39
|
-
(nextNode.type === 'ImportDeclaration' ||
|
|
40
|
-
nextNode.type === 'TSImportEqualsDeclaration')) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (nextToken.loc.start.line - node.loc.end.line < 2) {
|
|
44
|
-
context.report({
|
|
45
|
-
node,
|
|
46
|
-
messageId: 'newlineAfterImport',
|
|
47
|
-
fix(fixer) {
|
|
48
|
-
const linesBetween = nextToken.loc.start.line - node.loc.end.line;
|
|
49
|
-
const newlinesToAdd = 2 - linesBetween;
|
|
50
|
-
return fixer.insertTextAfter(node, '\n'.repeat(newlinesToAdd));
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.newlineAfterImport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.newlineAfterImport=(0,eslint_devkit_1.createRule)({name:"newline-after-import",meta:{type:"layout",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/newline-after-import.md",description:"Enforce a newline after import statements"},fixable:"whitespace",messages:{newlineAfterImport:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.QUALITY,issueName:"Newline After Import",description:"Require a newline after the last import statement",severity:"LOW",fix:"Add a newline after the import block",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/newline-after-import.md"})},schema:[]},defaultOptions:[],create(context){return{ImportDeclaration(node){const sourceCode=context.sourceCode;const nextToken=sourceCode.getTokenAfter(node);if(!nextToken)return;if(nextToken.loc.start.line===node.loc.end.line){}const nextNode=sourceCode.getNodeByRangeIndex(nextToken.range[0]);if(nextNode&&(nextNode.type==="ImportDeclaration"||nextNode.type==="TSImportEqualsDeclaration")){return}if(nextToken.loc.start.line-node.loc.end.line<2){context.report({node,messageId:"newlineAfterImport",fix(fixer){const linesBetween=nextToken.loc.start.line-node.loc.end.line;const newlinesToAdd=2-linesBetween;return fixer.insertTextAfter(node,"\n".repeat(newlinesToAdd))}})}}}}});
|
|
@@ -1,107 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noAbsolutePath = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
6
|
-
const path = tslib_1.__importStar(require("node:path"));
|
|
7
|
-
exports.noAbsolutePath = (0, eslint_devkit_1.createRule)({
|
|
8
|
-
name: 'no-absolute-path',
|
|
9
|
-
meta: {
|
|
10
|
-
type: 'suggestion',
|
|
11
|
-
docs: {
|
|
12
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-absolute-path.md',
|
|
13
|
-
description: 'Forbid import of modules using absolute paths',
|
|
14
|
-
cwe: 'CWE-426',
|
|
15
|
-
cvss: 5,
|
|
16
|
-
},
|
|
17
|
-
fixable: 'code',
|
|
18
|
-
messages: {
|
|
19
|
-
absolutePath: (0, eslint_devkit_1.formatLLMMessage)({
|
|
20
|
-
icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
|
|
21
|
-
issueName: 'Absolute Path Import',
|
|
22
|
-
cwe: 'CWE-426',
|
|
23
|
-
description: 'Import uses absolute path: {{importPath}}',
|
|
24
|
-
severity: 'MEDIUM',
|
|
25
|
-
fix: 'Use relative path instead: {{relativePath}}',
|
|
26
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-absolute-path.md',
|
|
27
|
-
}),
|
|
28
|
-
},
|
|
29
|
-
schema: [
|
|
30
|
-
{
|
|
31
|
-
type: 'object',
|
|
32
|
-
properties: {
|
|
33
|
-
esmodule: { type: 'boolean', default: true },
|
|
34
|
-
commonjs: { type: 'boolean', default: true },
|
|
35
|
-
amd: { type: 'boolean', default: false },
|
|
36
|
-
},
|
|
37
|
-
additionalProperties: false,
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
},
|
|
41
|
-
defaultOptions: [{ esmodule: true, commonjs: true, amd: false }],
|
|
42
|
-
create(context) {
|
|
43
|
-
const options = context.options[0] || {};
|
|
44
|
-
const { esmodule = true, commonjs = true, amd = false } = options;
|
|
45
|
-
const filename = context.filename;
|
|
46
|
-
function isAbsolutePath(importPath) {
|
|
47
|
-
return path.isAbsolute(importPath);
|
|
48
|
-
}
|
|
49
|
-
function getRelativePath(absolutePath) {
|
|
50
|
-
const currentDir = path.dirname(filename);
|
|
51
|
-
let relativePath = path.relative(currentDir, absolutePath);
|
|
52
|
-
if (!relativePath.startsWith('.')) {
|
|
53
|
-
relativePath = './' + relativePath;
|
|
54
|
-
}
|
|
55
|
-
return relativePath;
|
|
56
|
-
}
|
|
57
|
-
function checkImport(node, source) {
|
|
58
|
-
const importPath = source.value;
|
|
59
|
-
if (typeof importPath !== 'string')
|
|
60
|
-
return;
|
|
61
|
-
if (isAbsolutePath(importPath)) {
|
|
62
|
-
const relativePath = getRelativePath(importPath);
|
|
63
|
-
context.report({
|
|
64
|
-
node: source,
|
|
65
|
-
messageId: 'absolutePath',
|
|
66
|
-
data: {
|
|
67
|
-
importPath,
|
|
68
|
-
relativePath,
|
|
69
|
-
},
|
|
70
|
-
fix(fixer) {
|
|
71
|
-
return fixer.replaceText(source, `'${relativePath}'`);
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
ImportDeclaration(node) {
|
|
78
|
-
if (esmodule) {
|
|
79
|
-
checkImport(node, node.source);
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
ImportExpression(node) {
|
|
83
|
-
if (esmodule && node.source.type === 'Literal') {
|
|
84
|
-
checkImport(node, node.source);
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
CallExpression(node) {
|
|
88
|
-
if (node.callee.type !== 'Identifier')
|
|
89
|
-
return;
|
|
90
|
-
const calleeName = node.callee.name;
|
|
91
|
-
if (commonjs &&
|
|
92
|
-
calleeName === 'require' &&
|
|
93
|
-
node.arguments.length === 1 &&
|
|
94
|
-
node.arguments[0].type === 'Literal') {
|
|
95
|
-
checkImport(node, node.arguments[0]);
|
|
96
|
-
}
|
|
97
|
-
if (amd && (calleeName === 'define' || calleeName === 'require')) {
|
|
98
|
-
node.arguments.forEach((arg) => {
|
|
99
|
-
if (arg.type === 'Literal') {
|
|
100
|
-
checkImport(node, arg);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
});
|
|
1
|
+
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(o,m,k,k2){if(k2===void 0)k2=k;var desc=Object.getOwnPropertyDescriptor(m,k);if(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable)){desc={enumerable:true,get:function(){return m[k]}}}Object.defineProperty(o,k2,desc)}):(function(o,m,k,k2){if(k2===void 0)k2=k;o[k2]=m[k]}));var __setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(o,v){Object.defineProperty(o,"default",{enumerable:true,value:v})}):function(o,v){o["default"]=v});var __importStar=this&&this.__importStar||(function(){var ownKeys=function(o){ownKeys=Object.getOwnPropertyNames||function(o2){var ar=[];for(var k in o2)if(Object.prototype.hasOwnProperty.call(o2,k))ar[ar.length]=k;return ar};return ownKeys(o)};return function(mod){if(mod&&mod.__esModule)return mod;var result={};if(mod!=null){for(var k=ownKeys(mod),i=0;i<k.length;i++)if(k[i]!=="default")__createBinding(result,mod,k[i])}__setModuleDefault(result,mod);return result}})();Object.defineProperty(exports,"__esModule",{value:true});exports.noAbsolutePath=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const path=__importStar(require("node:path"));exports.noAbsolutePath=(0,eslint_devkit_1.createRule)({name:"no-absolute-path",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-absolute-path.md",description:"Forbid import of modules using absolute paths",cwe:"CWE-426",cvss:5},fixable:"code",messages:{absolutePath:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Absolute Path Import",cwe:"CWE-426",description:"Import uses absolute path: {{importPath}}",severity:"MEDIUM",fix:"Use relative path instead: {{relativePath}}",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-absolute-path.md"})},schema:[{type:"object",properties:{esmodule:{type:"boolean",default:true},commonjs:{type:"boolean",default:true},amd:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{esmodule:true,commonjs:true,amd:false}],create(context){const options=context.options[0]||{};const{esmodule=true,commonjs=true,amd=false}=options;const filename=context.filename;function isAbsolutePath(importPath){return path.isAbsolute(importPath)}function getRelativePath(absolutePath){const currentDir=path.dirname(filename);let relativePath=path.relative(currentDir,absolutePath);if(!relativePath.startsWith(".")){relativePath="./"+relativePath}return relativePath}function checkImport(node,source){const importPath=source.value;if(typeof importPath!=="string")return;if(isAbsolutePath(importPath)){const relativePath=getRelativePath(importPath);context.report({node:source,messageId:"absolutePath",data:{importPath,relativePath},fix(fixer){return fixer.replaceText(source,`'${relativePath}'`)}})}}return{ImportDeclaration(node){if(esmodule){checkImport(node,node.source)}},ImportExpression(node){if(esmodule&&node.source.type==="Literal"){checkImport(node,node.source)}},CallExpression(node){if(node.callee.type!=="Identifier")return;const calleeName=node.callee.name;if(commonjs&&calleeName==="require"&&node.arguments.length===1&&node.arguments[0].type==="Literal"){checkImport(node,node.arguments[0])}if(amd&&(calleeName==="define"||calleeName==="require")){node.arguments.forEach(arg=>{if(arg.type==="Literal"){checkImport(node,arg)}})}}}}});
|