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,385 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
exports.noExtraneousDependencies = (0, eslint_devkit_1.createRule)({
|
|
9
|
-
name: 'no-extraneous-dependencies',
|
|
10
|
-
meta: {
|
|
11
|
-
type: 'problem',
|
|
12
|
-
docs: {
|
|
13
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-extraneous-dependencies.md',
|
|
14
|
-
description: 'Forbid the use of extraneous packages not listed in package.json',
|
|
15
|
-
},
|
|
16
|
-
hasSuggestions: true,
|
|
17
|
-
messages: {
|
|
18
|
-
extraneousDependency: (0, eslint_devkit_2.formatLLMMessage)({
|
|
19
|
-
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
20
|
-
issueName: 'Extraneous Dependency',
|
|
21
|
-
description: 'Package not listed in package.json dependencies',
|
|
22
|
-
severity: 'HIGH',
|
|
23
|
-
fix: 'Add package to package.json or remove the import',
|
|
24
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md',
|
|
25
|
-
}),
|
|
26
|
-
missingDependency: (0, eslint_devkit_2.formatLLMMessage)({
|
|
27
|
-
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
28
|
-
issueName: 'Missing Dependency',
|
|
29
|
-
description: 'Package used but not in package.json',
|
|
30
|
-
severity: 'HIGH',
|
|
31
|
-
fix: 'Add package to appropriate section in package.json',
|
|
32
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md',
|
|
33
|
-
}),
|
|
34
|
-
devDependencyInProduction: (0, eslint_devkit_2.formatLLMMessage)({
|
|
35
|
-
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
36
|
-
issueName: 'Dev Dependency in Production',
|
|
37
|
-
description: 'Dev dependency used in production code',
|
|
38
|
-
severity: 'MEDIUM',
|
|
39
|
-
fix: 'Move to dependencies or ensure this is only used in development',
|
|
40
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md',
|
|
41
|
-
}),
|
|
42
|
-
addToDependencies: (0, eslint_devkit_2.formatLLMMessage)({
|
|
43
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
44
|
-
issueName: 'Add to Dependencies',
|
|
45
|
-
description: 'Add package to dependencies in package.json',
|
|
46
|
-
severity: 'HIGH',
|
|
47
|
-
fix: 'Run: npm install <package>',
|
|
48
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md',
|
|
49
|
-
}),
|
|
50
|
-
addToDevDependencies: (0, eslint_devkit_2.formatLLMMessage)({
|
|
51
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
52
|
-
issueName: 'Add to Dev Dependencies',
|
|
53
|
-
description: 'Add package to devDependencies in package.json',
|
|
54
|
-
severity: 'HIGH',
|
|
55
|
-
fix: 'Run: npm install --save-dev <package>',
|
|
56
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md',
|
|
57
|
-
}),
|
|
58
|
-
moveToDependencies: (0, eslint_devkit_2.formatLLMMessage)({
|
|
59
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
60
|
-
issueName: 'Move to Dependencies',
|
|
61
|
-
description: 'Move package from devDependencies to dependencies',
|
|
62
|
-
severity: 'MEDIUM',
|
|
63
|
-
fix: 'Move package from devDependencies to dependencies in package.json',
|
|
64
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md',
|
|
65
|
-
}),
|
|
66
|
-
},
|
|
67
|
-
schema: [
|
|
68
|
-
{
|
|
69
|
-
type: 'object',
|
|
70
|
-
properties: {
|
|
71
|
-
devDependencies: {
|
|
72
|
-
type: 'boolean',
|
|
73
|
-
default: true,
|
|
74
|
-
description: 'Allow imports from devDependencies.',
|
|
75
|
-
},
|
|
76
|
-
optionalDependencies: {
|
|
77
|
-
type: 'boolean',
|
|
78
|
-
default: true,
|
|
79
|
-
description: 'Allow imports from optionalDependencies.',
|
|
80
|
-
},
|
|
81
|
-
peerDependencies: {
|
|
82
|
-
type: 'boolean',
|
|
83
|
-
default: true,
|
|
84
|
-
description: 'Allow imports from peerDependencies.',
|
|
85
|
-
},
|
|
86
|
-
bundledDependencies: {
|
|
87
|
-
type: 'boolean',
|
|
88
|
-
default: true,
|
|
89
|
-
description: 'Allow imports from bundledDependencies.',
|
|
90
|
-
},
|
|
91
|
-
packageJsonPath: {
|
|
92
|
-
type: 'string',
|
|
93
|
-
description: 'Path to package.json file to use.',
|
|
94
|
-
},
|
|
95
|
-
packageJson: {
|
|
96
|
-
type: 'object',
|
|
97
|
-
description: 'Direct package.json content for testing.',
|
|
98
|
-
},
|
|
99
|
-
resolutionStrategy: {
|
|
100
|
-
type: 'string',
|
|
101
|
-
enum: ['strict', 'workspace', 'monorepo'],
|
|
102
|
-
default: 'strict',
|
|
103
|
-
description: 'Dependency resolution strategy: strict (exact match), workspace (allow workspace packages), monorepo (cross-package resolution).',
|
|
104
|
-
},
|
|
105
|
-
allowPatterns: {
|
|
106
|
-
type: 'array',
|
|
107
|
-
items: { type: 'string' },
|
|
108
|
-
description: 'Regex patterns for packages to allow even if not in package.json.',
|
|
109
|
-
},
|
|
110
|
-
ignore: {
|
|
111
|
-
type: 'array',
|
|
112
|
-
items: { type: 'string' },
|
|
113
|
-
description: "Specific package names to ignore (don't report as missing).",
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
additionalProperties: false,
|
|
117
|
-
},
|
|
118
|
-
],
|
|
119
|
-
},
|
|
120
|
-
defaultOptions: [
|
|
121
|
-
{
|
|
122
|
-
devDependencies: true,
|
|
123
|
-
optionalDependencies: true,
|
|
124
|
-
peerDependencies: true,
|
|
125
|
-
bundledDependencies: true,
|
|
126
|
-
resolutionStrategy: 'strict',
|
|
127
|
-
allowPatterns: [],
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
create(context) {
|
|
131
|
-
const [options] = context.options;
|
|
132
|
-
const { devDependencies = true, optionalDependencies = true, peerDependencies = true, bundledDependencies = true, packageJsonPath, packageJson, resolutionStrategy = 'strict', allowPatterns = [], } = options || {};
|
|
133
|
-
const filename = context.filename;
|
|
134
|
-
if (!filename) {
|
|
135
|
-
return {};
|
|
136
|
-
}
|
|
137
|
-
let resolvedPackageJson = null;
|
|
138
|
-
if (packageJson) {
|
|
139
|
-
resolvedPackageJson = packageJson;
|
|
140
|
-
}
|
|
141
|
-
else if (packageJsonPath) {
|
|
142
|
-
resolvedPackageJson = (0, eslint_devkit_3.readJsonFileSync)(packageJsonPath);
|
|
143
|
-
if (!resolvedPackageJson) {
|
|
144
|
-
return {};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
const packageJsonFile = (0, eslint_devkit_3.findFileUpward)('package.json', (0, eslint_devkit_4.getDirname)(filename));
|
|
149
|
-
if (!packageJsonFile) {
|
|
150
|
-
return {};
|
|
151
|
-
}
|
|
152
|
-
resolvedPackageJson = (0, eslint_devkit_3.readJsonFileSync)(packageJsonFile);
|
|
153
|
-
if (!resolvedPackageJson) {
|
|
154
|
-
return {};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
const allowedPackages = new Set();
|
|
158
|
-
if (resolvedPackageJson?.dependencies) {
|
|
159
|
-
Object.keys(resolvedPackageJson.dependencies).forEach((pkg) => allowedPackages.add(pkg));
|
|
160
|
-
}
|
|
161
|
-
if (devDependencies && resolvedPackageJson?.devDependencies) {
|
|
162
|
-
Object.keys(resolvedPackageJson.devDependencies).forEach((pkg) => allowedPackages.add(pkg));
|
|
163
|
-
}
|
|
164
|
-
if (optionalDependencies && resolvedPackageJson?.optionalDependencies) {
|
|
165
|
-
Object.keys(resolvedPackageJson.optionalDependencies).forEach((pkg) => allowedPackages.add(pkg));
|
|
166
|
-
}
|
|
167
|
-
if (peerDependencies && resolvedPackageJson?.peerDependencies) {
|
|
168
|
-
Object.keys(resolvedPackageJson.peerDependencies).forEach((pkg) => allowedPackages.add(pkg));
|
|
169
|
-
}
|
|
170
|
-
if (bundledDependencies && resolvedPackageJson?.bundledDependencies) {
|
|
171
|
-
resolvedPackageJson.bundledDependencies.forEach((pkg) => allowedPackages.add(pkg));
|
|
172
|
-
}
|
|
173
|
-
function isExternalPackage(importPath) {
|
|
174
|
-
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
if (importPath.startsWith('/')) {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
const nodeBuiltins = [
|
|
181
|
-
'assert',
|
|
182
|
-
'buffer',
|
|
183
|
-
'child_process',
|
|
184
|
-
'cluster',
|
|
185
|
-
'crypto',
|
|
186
|
-
'dgram',
|
|
187
|
-
'dns',
|
|
188
|
-
'domain',
|
|
189
|
-
'events',
|
|
190
|
-
'fs',
|
|
191
|
-
'http',
|
|
192
|
-
'https',
|
|
193
|
-
'net',
|
|
194
|
-
'os',
|
|
195
|
-
'path',
|
|
196
|
-
'punycode',
|
|
197
|
-
'querystring',
|
|
198
|
-
'readline',
|
|
199
|
-
'stream',
|
|
200
|
-
'string_decoder',
|
|
201
|
-
'timers',
|
|
202
|
-
'tls',
|
|
203
|
-
'tty',
|
|
204
|
-
'url',
|
|
205
|
-
'util',
|
|
206
|
-
'v8',
|
|
207
|
-
'vm',
|
|
208
|
-
'zlib',
|
|
209
|
-
'node:assert',
|
|
210
|
-
'node:buffer',
|
|
211
|
-
'node:child_process',
|
|
212
|
-
'node:cluster',
|
|
213
|
-
'node:crypto',
|
|
214
|
-
'node:dgram',
|
|
215
|
-
'node:dns',
|
|
216
|
-
'node:domain',
|
|
217
|
-
'node:events',
|
|
218
|
-
'node:fs',
|
|
219
|
-
'node:http',
|
|
220
|
-
'node:https',
|
|
221
|
-
'node:net',
|
|
222
|
-
'node:os',
|
|
223
|
-
'node:path',
|
|
224
|
-
'node:punycode',
|
|
225
|
-
'node:querystring',
|
|
226
|
-
'node:readline',
|
|
227
|
-
'node:stream',
|
|
228
|
-
'node:string_decoder',
|
|
229
|
-
'node:timers',
|
|
230
|
-
'node:tls',
|
|
231
|
-
'node:tty',
|
|
232
|
-
'node:url',
|
|
233
|
-
'node:util',
|
|
234
|
-
'node:v8',
|
|
235
|
-
'node:vm',
|
|
236
|
-
'node:zlib',
|
|
237
|
-
];
|
|
238
|
-
if (nodeBuiltins.includes(importPath)) {
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
const packageName = importPath.startsWith('@')
|
|
242
|
-
? importPath.split('/').slice(0, 2).join('/')
|
|
243
|
-
: importPath.split('/')[0];
|
|
244
|
-
return packageName;
|
|
245
|
-
}
|
|
246
|
-
function isWorkspacePackage(packageName) {
|
|
247
|
-
return (packageName.startsWith('@workspace/') ||
|
|
248
|
-
packageName.startsWith('@company/'));
|
|
249
|
-
}
|
|
250
|
-
function checkImport(importPath, node) {
|
|
251
|
-
const packageName = isExternalPackage(importPath);
|
|
252
|
-
if (!packageName) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
const isAllowedByPattern = allowPatterns.some((pattern) => {
|
|
256
|
-
try {
|
|
257
|
-
const regex = new RegExp(pattern);
|
|
258
|
-
return regex.test(packageName);
|
|
259
|
-
}
|
|
260
|
-
catch {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
if (isAllowedByPattern) {
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
const shouldCheckDependency = () => {
|
|
268
|
-
switch (resolutionStrategy) {
|
|
269
|
-
case 'workspace':
|
|
270
|
-
return (!allowedPackages.has(packageName) &&
|
|
271
|
-
!isWorkspacePackage(packageName));
|
|
272
|
-
case 'monorepo':
|
|
273
|
-
return (!allowedPackages.has(packageName) &&
|
|
274
|
-
!isWorkspacePackage(packageName));
|
|
275
|
-
case 'strict':
|
|
276
|
-
default:
|
|
277
|
-
return !allowedPackages.has(packageName);
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
if (shouldCheckDependency()) {
|
|
281
|
-
const isInDevDeps = resolvedPackageJson?.devDependencies &&
|
|
282
|
-
resolvedPackageJson.devDependencies[packageName];
|
|
283
|
-
if (isInDevDeps && !devDependencies) {
|
|
284
|
-
context.report({
|
|
285
|
-
node,
|
|
286
|
-
messageId: 'devDependencyInProduction',
|
|
287
|
-
data: {
|
|
288
|
-
packageName,
|
|
289
|
-
importPath,
|
|
290
|
-
suggestion: 'Move to dependencies if used in production, or ensure this code is only executed in development',
|
|
291
|
-
},
|
|
292
|
-
suggest: [
|
|
293
|
-
{
|
|
294
|
-
messageId: 'moveToDependencies',
|
|
295
|
-
fix(fixer) {
|
|
296
|
-
let parentStatement = node;
|
|
297
|
-
while (parentStatement &&
|
|
298
|
-
parentStatement.type !== 'ImportDeclaration' &&
|
|
299
|
-
parentStatement.type !== 'VariableDeclaration' &&
|
|
300
|
-
parentStatement.type !== 'ExpressionStatement') {
|
|
301
|
-
parentStatement = parentStatement.parent;
|
|
302
|
-
}
|
|
303
|
-
if (parentStatement) {
|
|
304
|
-
return fixer.insertTextBefore(parentStatement, `// TODO: Move ${packageName} from devDependencies to dependencies in package.json\n`);
|
|
305
|
-
}
|
|
306
|
-
return fixer.insertTextBefore(node, `// TODO: Move ${packageName} from devDependencies to dependencies in package.json\n`);
|
|
307
|
-
},
|
|
308
|
-
},
|
|
309
|
-
],
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
context.report({
|
|
314
|
-
node,
|
|
315
|
-
messageId: 'missingDependency',
|
|
316
|
-
data: {
|
|
317
|
-
packageName,
|
|
318
|
-
importPath,
|
|
319
|
-
allowedPackages: Array.from(allowedPackages).slice(0, 5).join(', ') +
|
|
320
|
-
(allowedPackages.size > 5 ? '...' : ''),
|
|
321
|
-
suggestion: `Add "${packageName}" to package.json dependencies`,
|
|
322
|
-
},
|
|
323
|
-
suggest: [
|
|
324
|
-
{
|
|
325
|
-
messageId: 'addToDependencies',
|
|
326
|
-
fix(fixer) {
|
|
327
|
-
let parentStatement = node;
|
|
328
|
-
while (parentStatement &&
|
|
329
|
-
parentStatement.type !== 'ImportDeclaration' &&
|
|
330
|
-
parentStatement.type !== 'VariableDeclaration' &&
|
|
331
|
-
parentStatement.type !== 'ExpressionStatement') {
|
|
332
|
-
parentStatement = parentStatement.parent;
|
|
333
|
-
}
|
|
334
|
-
if (parentStatement) {
|
|
335
|
-
return fixer.insertTextBefore(parentStatement, `// TODO: Run: npm install ${packageName}\n`);
|
|
336
|
-
}
|
|
337
|
-
return fixer.insertTextBefore(node, `// TODO: Run: npm install ${packageName}\n`);
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
messageId: 'addToDevDependencies',
|
|
342
|
-
fix(fixer) {
|
|
343
|
-
let parentStatement = node;
|
|
344
|
-
while (parentStatement &&
|
|
345
|
-
parentStatement.type !== 'ImportDeclaration' &&
|
|
346
|
-
parentStatement.type !== 'VariableDeclaration' &&
|
|
347
|
-
parentStatement.type !== 'ExpressionStatement') {
|
|
348
|
-
parentStatement = parentStatement.parent;
|
|
349
|
-
}
|
|
350
|
-
if (parentStatement) {
|
|
351
|
-
return fixer.insertTextBefore(parentStatement, `// TODO: Run: npm install --save-dev ${packageName}\n`);
|
|
352
|
-
}
|
|
353
|
-
return fixer.insertTextBefore(node, `// TODO: Run: npm install --save-dev ${packageName}\n`);
|
|
354
|
-
},
|
|
355
|
-
},
|
|
356
|
-
],
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
return {
|
|
362
|
-
ImportDeclaration(node) {
|
|
363
|
-
if (node.source.value && typeof node.source.value === 'string') {
|
|
364
|
-
checkImport(node.source.value, node.source);
|
|
365
|
-
}
|
|
366
|
-
},
|
|
367
|
-
CallExpression(node) {
|
|
368
|
-
if (node.callee.type === 'Identifier' &&
|
|
369
|
-
node.callee.name === 'require' &&
|
|
370
|
-
node.arguments.length === 1) {
|
|
371
|
-
const arg = node.arguments[0];
|
|
372
|
-
if (arg.type === 'Literal' && typeof arg.value === 'string') {
|
|
373
|
-
checkImport(arg.value, arg);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
},
|
|
377
|
-
ImportExpression(node) {
|
|
378
|
-
if (node.source.type === 'Literal' &&
|
|
379
|
-
typeof node.source.value === 'string') {
|
|
380
|
-
checkImport(node.source.value, node.source);
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
};
|
|
384
|
-
},
|
|
385
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noExtraneousDependencies=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");const eslint_devkit_4=require("@interlace/eslint-devkit");exports.noExtraneousDependencies=(0,eslint_devkit_1.createRule)({name:"no-extraneous-dependencies",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-extraneous-dependencies.md",description:"Forbid the use of extraneous packages not listed in package.json"},hasSuggestions:true,messages:{extraneousDependency:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Extraneous Dependency",description:"Package not listed in package.json dependencies",severity:"HIGH",fix:"Add package to package.json or remove the import",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md"}),missingDependency:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Missing Dependency",description:"Package used but not in package.json",severity:"HIGH",fix:"Add package to appropriate section in package.json",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md"}),devDependencyInProduction:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Dev Dependency in Production",description:"Dev dependency used in production code",severity:"MEDIUM",fix:"Move to dependencies or ensure this is only used in development",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md"}),addToDependencies:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Add to Dependencies",description:"Add package to dependencies in package.json",severity:"HIGH",fix:"Run: npm install <package>",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md"}),addToDevDependencies:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Add to Dev Dependencies",description:"Add package to devDependencies in package.json",severity:"HIGH",fix:"Run: npm install --save-dev <package>",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md"}),moveToDependencies:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Move to Dependencies",description:"Move package from devDependencies to dependencies",severity:"MEDIUM",fix:"Move package from devDependencies to dependencies in package.json",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-extraneous-dependencies.md"})},schema:[{type:"object",properties:{devDependencies:{type:"boolean",default:true,description:"Allow imports from devDependencies."},optionalDependencies:{type:"boolean",default:true,description:"Allow imports from optionalDependencies."},peerDependencies:{type:"boolean",default:true,description:"Allow imports from peerDependencies."},bundledDependencies:{type:"boolean",default:true,description:"Allow imports from bundledDependencies."},packageJsonPath:{type:"string",description:"Path to package.json file to use."},packageJson:{type:"object",description:"Direct package.json content for testing."},resolutionStrategy:{type:"string",enum:["strict","workspace","monorepo"],default:"strict",description:"Dependency resolution strategy: strict (exact match), workspace (allow workspace packages), monorepo (cross-package resolution)."},allowPatterns:{type:"array",items:{type:"string"},description:"Regex patterns for packages to allow even if not in package.json."},ignore:{type:"array",items:{type:"string"},description:"Specific package names to ignore (don't report as missing)."}},additionalProperties:false}]},defaultOptions:[{devDependencies:true,optionalDependencies:true,peerDependencies:true,bundledDependencies:true,resolutionStrategy:"strict",allowPatterns:[]}],create(context){const[options]=context.options;const{devDependencies=true,optionalDependencies=true,peerDependencies=true,bundledDependencies=true,packageJsonPath,packageJson,resolutionStrategy="strict",allowPatterns=[]}=options||{};const filename=context.filename;if(!filename){return{}}let resolvedPackageJson=null;if(packageJson){resolvedPackageJson=packageJson}else if(packageJsonPath){resolvedPackageJson=(0,eslint_devkit_3.readJsonFileSync)(packageJsonPath);if(!resolvedPackageJson){return{}}}else{const packageJsonFile=(0,eslint_devkit_3.findFileUpward)("package.json",(0,eslint_devkit_4.getDirname)(filename));if(!packageJsonFile){return{}}resolvedPackageJson=(0,eslint_devkit_3.readJsonFileSync)(packageJsonFile);if(!resolvedPackageJson){return{}}}const allowedPackages=new Set;if(resolvedPackageJson?.dependencies){Object.keys(resolvedPackageJson.dependencies).forEach(pkg=>allowedPackages.add(pkg))}if(devDependencies&&resolvedPackageJson?.devDependencies){Object.keys(resolvedPackageJson.devDependencies).forEach(pkg=>allowedPackages.add(pkg))}if(optionalDependencies&&resolvedPackageJson?.optionalDependencies){Object.keys(resolvedPackageJson.optionalDependencies).forEach(pkg=>allowedPackages.add(pkg))}if(peerDependencies&&resolvedPackageJson?.peerDependencies){Object.keys(resolvedPackageJson.peerDependencies).forEach(pkg=>allowedPackages.add(pkg))}if(bundledDependencies&&resolvedPackageJson?.bundledDependencies){resolvedPackageJson.bundledDependencies.forEach(pkg=>allowedPackages.add(pkg))}function isExternalPackage(importPath){if(importPath.startsWith("./")||importPath.startsWith("../")){return null}if(importPath.startsWith("/")){return null}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","node:assert","node:buffer","node:child_process","node:cluster","node:crypto","node:dgram","node:dns","node:domain","node:events","node:fs","node:http","node:https","node:net","node:os","node:path","node:punycode","node:querystring","node:readline","node:stream","node:string_decoder","node:timers","node:tls","node:tty","node:url","node:util","node:v8","node:vm","node:zlib"];if(nodeBuiltins.includes(importPath)){return null}const packageName=importPath.startsWith("@")?importPath.split("/").slice(0,2).join("/"):importPath.split("/")[0];return packageName}function isWorkspacePackage(packageName){return packageName.startsWith("@workspace/")||packageName.startsWith("@company/")}function checkImport(importPath,node){const packageName=isExternalPackage(importPath);if(!packageName){return}const isAllowedByPattern=allowPatterns.some(pattern=>{try{const regex=new RegExp(pattern);return regex.test(packageName)}catch{return false}});if(isAllowedByPattern){return}const shouldCheckDependency=()=>{switch(resolutionStrategy){case"workspace":return!allowedPackages.has(packageName)&&!isWorkspacePackage(packageName);case"monorepo":return!allowedPackages.has(packageName)&&!isWorkspacePackage(packageName);case"strict":default:return!allowedPackages.has(packageName)}};if(shouldCheckDependency()){const isInDevDeps=resolvedPackageJson?.devDependencies&&resolvedPackageJson.devDependencies[packageName];if(isInDevDeps&&!devDependencies){context.report({node,messageId:"devDependencyInProduction",data:{packageName,importPath,suggestion:"Move to dependencies if used in production, or ensure this code is only executed in development"},suggest:[{messageId:"moveToDependencies",fix(fixer){let parentStatement=node;while(parentStatement&&parentStatement.type!=="ImportDeclaration"&&parentStatement.type!=="VariableDeclaration"&&parentStatement.type!=="ExpressionStatement"){parentStatement=parentStatement.parent}if(parentStatement){return fixer.insertTextBefore(parentStatement,`// TODO: Move ${packageName} from devDependencies to dependencies in package.json
|
|
2
|
+
`)}return fixer.insertTextBefore(node,`// TODO: Move ${packageName} from devDependencies to dependencies in package.json
|
|
3
|
+
`)}}]})}else{context.report({node,messageId:"missingDependency",data:{packageName,importPath,allowedPackages:Array.from(allowedPackages).slice(0,5).join(", ")+(allowedPackages.size>5?"...":""),suggestion:`Add "${packageName}" to package.json dependencies`},suggest:[{messageId:"addToDependencies",fix(fixer){let parentStatement=node;while(parentStatement&&parentStatement.type!=="ImportDeclaration"&&parentStatement.type!=="VariableDeclaration"&&parentStatement.type!=="ExpressionStatement"){parentStatement=parentStatement.parent}if(parentStatement){return fixer.insertTextBefore(parentStatement,`// TODO: Run: npm install ${packageName}
|
|
4
|
+
`)}return fixer.insertTextBefore(node,`// TODO: Run: npm install ${packageName}
|
|
5
|
+
`)}},{messageId:"addToDevDependencies",fix(fixer){let parentStatement=node;while(parentStatement&&parentStatement.type!=="ImportDeclaration"&&parentStatement.type!=="VariableDeclaration"&&parentStatement.type!=="ExpressionStatement"){parentStatement=parentStatement.parent}if(parentStatement){return fixer.insertTextBefore(parentStatement,`// TODO: Run: npm install --save-dev ${packageName}
|
|
6
|
+
`)}return fixer.insertTextBefore(node,`// TODO: Run: npm install --save-dev ${packageName}
|
|
7
|
+
`)}}]})}}}return{ImportDeclaration(node){if(node.source.value&&typeof node.source.value==="string"){checkImport(node.source.value,node.source)}},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"){checkImport(arg.value,arg)}}},ImportExpression(node){if(node.source.type==="Literal"&&typeof node.source.value==="string"){checkImport(node.source.value,node.source)}}}}});
|
|
@@ -1,134 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noFullPackageImport = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const DEFAULT_BLOCKED_PACKAGES = [
|
|
6
|
-
{
|
|
7
|
-
name: 'lodash',
|
|
8
|
-
suggestion: 'Use subpath imports like lodash/debounce',
|
|
9
|
-
example: "import debounce from 'lodash/debounce';",
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
name: 'lodash-es',
|
|
13
|
-
suggestion: 'Use named imports for tree-shaking',
|
|
14
|
-
example: "import { debounce } from 'lodash-es';",
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
name: 'rxjs',
|
|
18
|
-
suggestion: 'Use named imports from rxjs',
|
|
19
|
-
example: "import { Observable, map } from 'rxjs';",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: 'ramda',
|
|
23
|
-
suggestion: 'Use subpath imports like ramda/src/compose',
|
|
24
|
-
example: "import compose from 'ramda/src/compose';",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
name: 'moment',
|
|
28
|
-
suggestion: 'Consider migrating to date-fns or dayjs for smaller bundles',
|
|
29
|
-
example: "import { format } from 'date-fns';",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'underscore',
|
|
33
|
-
suggestion: 'Consider migrating to lodash-es or native methods',
|
|
34
|
-
example: 'array.filter(fn) instead of _.filter(array, fn)',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: '@fortawesome/free-solid-svg-icons',
|
|
38
|
-
suggestion: 'Import individual icons',
|
|
39
|
-
example: "import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
name: '@fortawesome/free-regular-svg-icons',
|
|
43
|
-
suggestion: 'Import individual icons',
|
|
44
|
-
example: "import { faCircle } from '@fortawesome/free-regular-svg-icons/faCircle';",
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: 'aws-sdk',
|
|
48
|
-
suggestion: 'Use AWS SDK v3 with modular imports',
|
|
49
|
-
example: "import { S3Client } from '@aws-sdk/client-s3';",
|
|
50
|
-
},
|
|
51
|
-
];
|
|
52
|
-
function isFullPackageImport(importPath, packageName) {
|
|
53
|
-
return importPath === packageName;
|
|
54
|
-
}
|
|
55
|
-
function hasNamespaceImport(node) {
|
|
56
|
-
return node.specifiers.some((spec) => spec.type === eslint_devkit_1.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
57
|
-
}
|
|
58
|
-
function hasDefaultImport(node) {
|
|
59
|
-
return node.specifiers.some((spec) => spec.type === eslint_devkit_1.AST_NODE_TYPES.ImportDefaultSpecifier);
|
|
60
|
-
}
|
|
61
|
-
exports.noFullPackageImport = (0, eslint_devkit_1.createRule)({
|
|
62
|
-
name: 'no-full-package-import',
|
|
63
|
-
meta: {
|
|
64
|
-
type: 'suggestion',
|
|
65
|
-
docs: {
|
|
66
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md',
|
|
67
|
-
description: 'Disallow full package imports from known large packages that prevent tree-shaking',
|
|
68
|
-
},
|
|
69
|
-
hasSuggestions: true,
|
|
70
|
-
messages: {
|
|
71
|
-
fullPackageImport: (0, eslint_devkit_1.formatLLMMessage)({
|
|
72
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
73
|
-
issueName: 'Full Package Import Blocks Tree-Shaking',
|
|
74
|
-
description: "Importing the entire '{{packageName}}' package prevents tree-shaking and bloats your bundle. {{suggestion}}",
|
|
75
|
-
severity: 'MEDIUM',
|
|
76
|
-
fix: '{{example}}',
|
|
77
|
-
documentationLink: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md',
|
|
78
|
-
}),
|
|
79
|
-
},
|
|
80
|
-
schema: [
|
|
81
|
-
{
|
|
82
|
-
type: 'object',
|
|
83
|
-
properties: {
|
|
84
|
-
blockedPackages: {
|
|
85
|
-
type: 'array',
|
|
86
|
-
items: {
|
|
87
|
-
type: 'object',
|
|
88
|
-
properties: {
|
|
89
|
-
name: { type: 'string' },
|
|
90
|
-
suggestion: { type: 'string' },
|
|
91
|
-
example: { type: 'string' },
|
|
92
|
-
},
|
|
93
|
-
required: ['name', 'suggestion'],
|
|
94
|
-
},
|
|
95
|
-
default: [],
|
|
96
|
-
description: 'Packages to block full imports from',
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
additionalProperties: false,
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
},
|
|
103
|
-
defaultOptions: [
|
|
104
|
-
{
|
|
105
|
-
blockedPackages: DEFAULT_BLOCKED_PACKAGES,
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
create(context, [options = {}]) {
|
|
109
|
-
const { blockedPackages = DEFAULT_BLOCKED_PACKAGES, } = options || {};
|
|
110
|
-
return {
|
|
111
|
-
ImportDeclaration(node) {
|
|
112
|
-
const importPath = node.source.value;
|
|
113
|
-
if (typeof importPath !== 'string')
|
|
114
|
-
return;
|
|
115
|
-
for (const blocked of blockedPackages) {
|
|
116
|
-
if (!isFullPackageImport(importPath, blocked.name)) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
if (hasNamespaceImport(node) || hasDefaultImport(node)) {
|
|
120
|
-
context.report({
|
|
121
|
-
node,
|
|
122
|
-
messageId: 'fullPackageImport',
|
|
123
|
-
data: {
|
|
124
|
-
packageName: blocked.name,
|
|
125
|
-
suggestion: blocked.suggestion,
|
|
126
|
-
example: blocked.example || 'Use subpath or named imports',
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
},
|
|
134
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noFullPackageImport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const DEFAULT_BLOCKED_PACKAGES=[{name:"lodash",suggestion:"Use subpath imports like lodash/debounce",example:"import debounce from 'lodash/debounce';"},{name:"lodash-es",suggestion:"Use named imports for tree-shaking",example:"import { debounce } from 'lodash-es';"},{name:"rxjs",suggestion:"Use named imports from rxjs",example:"import { Observable, map } from 'rxjs';"},{name:"ramda",suggestion:"Use subpath imports like ramda/src/compose",example:"import compose from 'ramda/src/compose';"},{name:"moment",suggestion:"Consider migrating to date-fns or dayjs for smaller bundles",example:"import { format } from 'date-fns';"},{name:"underscore",suggestion:"Consider migrating to lodash-es or native methods",example:"array.filter(fn) instead of _.filter(array, fn)"},{name:"@fortawesome/free-solid-svg-icons",suggestion:"Import individual icons",example:"import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';"},{name:"@fortawesome/free-regular-svg-icons",suggestion:"Import individual icons",example:"import { faCircle } from '@fortawesome/free-regular-svg-icons/faCircle';"},{name:"aws-sdk",suggestion:"Use AWS SDK v3 with modular imports",example:"import { S3Client } from '@aws-sdk/client-s3';"}];function isFullPackageImport(importPath,packageName){return importPath===packageName}function hasNamespaceImport(node){return node.specifiers.some(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportNamespaceSpecifier)}function hasDefaultImport(node){return node.specifiers.some(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportDefaultSpecifier)}exports.noFullPackageImport=(0,eslint_devkit_1.createRule)({name:"no-full-package-import",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md",description:"Disallow full package imports from known large packages that prevent tree-shaking"},hasSuggestions:true,messages:{fullPackageImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Full Package Import Blocks Tree-Shaking",description:"Importing the entire '{{packageName}}' package prevents tree-shaking and bloats your bundle. {{suggestion}}",severity:"MEDIUM",fix:"{{example}}",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md"})},schema:[{type:"object",properties:{blockedPackages:{type:"array",items:{type:"object",properties:{name:{type:"string"},suggestion:{type:"string"},example:{type:"string"}},required:["name","suggestion"]},default:[],description:"Packages to block full imports from"}},additionalProperties:false}]},defaultOptions:[{blockedPackages:DEFAULT_BLOCKED_PACKAGES}],create(context,[options={}]){const{blockedPackages=DEFAULT_BLOCKED_PACKAGES}=options||{};return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath!=="string")return;for(const blocked of blockedPackages){if(!isFullPackageImport(importPath,blocked.name)){continue}if(hasNamespaceImport(node)||hasDefaultImport(node)){context.report({node,messageId:"fullPackageImport",data:{packageName:blocked.name,suggestion:blocked.suggestion,example:blocked.example||"Use subpath or named imports"}})}}}}}});
|
|
@@ -1,76 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noImportModuleExports = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
exports.noImportModuleExports = (0, eslint_devkit_1.createRule)({
|
|
6
|
-
name: 'no-import-module-exports',
|
|
7
|
-
meta: {
|
|
8
|
-
type: 'problem',
|
|
9
|
-
docs: {
|
|
10
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-import-module-exports.md',
|
|
11
|
-
description: 'Forbid import statements with CommonJS module.exports',
|
|
12
|
-
cwe: 'CWE-1078',
|
|
13
|
-
cvss: 7.5,
|
|
14
|
-
},
|
|
15
|
-
messages: {
|
|
16
|
-
importModuleExports: (0, eslint_devkit_1.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
|
|
18
|
-
issueName: 'Mixed Module Syntax',
|
|
19
|
-
cwe: 'CWE-1078',
|
|
20
|
-
description: 'Cannot use import statement with module.exports in the same file',
|
|
21
|
-
severity: 'HIGH',
|
|
22
|
-
fix: 'Use ES6 export syntax: export default or export { }',
|
|
23
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-import-module-exports.md',
|
|
24
|
-
}),
|
|
25
|
-
},
|
|
26
|
-
schema: [
|
|
27
|
-
{
|
|
28
|
-
type: 'object',
|
|
29
|
-
properties: {
|
|
30
|
-
exceptions: {
|
|
31
|
-
type: 'array',
|
|
32
|
-
items: { type: 'string' },
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
additionalProperties: false,
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
defaultOptions: [{ exceptions: [] }],
|
|
40
|
-
create(context) {
|
|
41
|
-
let hasImport = false;
|
|
42
|
-
const importNodes = [];
|
|
43
|
-
const moduleExportsNodes = [];
|
|
44
|
-
return {
|
|
45
|
-
ImportDeclaration(node) {
|
|
46
|
-
hasImport = true;
|
|
47
|
-
importNodes.push(node);
|
|
48
|
-
},
|
|
49
|
-
MemberExpression(node) {
|
|
50
|
-
if (node.object.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
51
|
-
node.object.name === 'module' &&
|
|
52
|
-
node.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
53
|
-
node.property.name === 'exports') {
|
|
54
|
-
moduleExportsNodes.push(node);
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
AssignmentExpression(node) {
|
|
58
|
-
if (node.left.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
|
|
59
|
-
node.left.object.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
60
|
-
node.left.object.name === 'exports') {
|
|
61
|
-
moduleExportsNodes.push(node.left);
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
'Program:exit'() {
|
|
65
|
-
if (hasImport && moduleExportsNodes.length > 0) {
|
|
66
|
-
moduleExportsNodes.forEach((node) => {
|
|
67
|
-
context.report({
|
|
68
|
-
node,
|
|
69
|
-
messageId: 'importModuleExports',
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
},
|
|
76
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noImportModuleExports=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.noImportModuleExports=(0,eslint_devkit_1.createRule)({name:"no-import-module-exports",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-import-module-exports.md",description:"Forbid import statements with CommonJS module.exports",cwe:"CWE-1078",cvss:7.5},messages:{importModuleExports:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Mixed Module Syntax",cwe:"CWE-1078",description:"Cannot use import statement with module.exports in the same file",severity:"HIGH",fix:"Use ES6 export syntax: export default or export { }",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-import-module-exports.md"})},schema:[{type:"object",properties:{exceptions:{type:"array",items:{type:"string"}}},additionalProperties:false}]},defaultOptions:[{exceptions:[]}],create(context){let hasImport=false;const importNodes=[];const moduleExportsNodes=[];return{ImportDeclaration(node){hasImport=true;importNodes.push(node)},MemberExpression(node){if(node.object.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&node.object.name==="module"&&node.property.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&node.property.name==="exports"){moduleExportsNodes.push(node)}},AssignmentExpression(node){if(node.left.type===eslint_devkit_1.AST_NODE_TYPES.MemberExpression&&node.left.object.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&node.left.object.name==="exports"){moduleExportsNodes.push(node.left)}},"Program:exit"(){if(hasImport&&moduleExportsNodes.length>0){moduleExportsNodes.forEach(node=>{context.report({node,messageId:"importModuleExports"})})}}}}});
|