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,189 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noUnresolved = void 0;
|
|
4
|
-
const node_module_1 = require("node:module");
|
|
5
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
6
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
7
|
-
const eslint_devkit_3 = require("@interlace/eslint-devkit");
|
|
8
|
-
exports.noUnresolved = (0, eslint_devkit_1.createRule)({
|
|
9
|
-
name: 'no-unresolved',
|
|
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-unresolved.md',
|
|
14
|
-
description: 'Ensures imports point to resolvable modules',
|
|
15
|
-
},
|
|
16
|
-
hasSuggestions: true,
|
|
17
|
-
messages: {
|
|
18
|
-
unresolvedImport: (0, eslint_devkit_2.formatLLMMessage)({
|
|
19
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
20
|
-
issueName: 'Unresolved Import',
|
|
21
|
-
description: 'Import cannot be resolved to a module',
|
|
22
|
-
severity: 'HIGH',
|
|
23
|
-
fix: 'Ensure the module exists or check the import path spelling',
|
|
24
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md',
|
|
25
|
-
}),
|
|
26
|
-
moduleNotFound: (0, eslint_devkit_2.formatLLMMessage)({
|
|
27
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
28
|
-
issueName: 'Module Not Found',
|
|
29
|
-
description: 'Cannot find module or file',
|
|
30
|
-
severity: 'HIGH',
|
|
31
|
-
fix: 'Verify the file exists and the path is correct',
|
|
32
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md',
|
|
33
|
-
}),
|
|
34
|
-
invalidExtension: (0, eslint_devkit_2.formatLLMMessage)({
|
|
35
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
36
|
-
issueName: 'Invalid File Extension',
|
|
37
|
-
description: 'File extension missing or invalid',
|
|
38
|
-
severity: 'MEDIUM',
|
|
39
|
-
fix: 'Add correct file extension or check if file exists',
|
|
40
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md',
|
|
41
|
-
}),
|
|
42
|
-
addIgnoreComment: (0, eslint_devkit_2.formatLLMMessage)({
|
|
43
|
-
icon: eslint_devkit_2.MessageIcons.INFO,
|
|
44
|
-
issueName: 'Add to Ignore',
|
|
45
|
-
description: 'Add to ignore list if intentional',
|
|
46
|
-
severity: 'LOW',
|
|
47
|
-
fix: '// eslint-disable-next-line import/no-unresolved',
|
|
48
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md',
|
|
49
|
-
}),
|
|
50
|
-
},
|
|
51
|
-
schema: [
|
|
52
|
-
{
|
|
53
|
-
type: 'object',
|
|
54
|
-
properties: {
|
|
55
|
-
extensions: {
|
|
56
|
-
type: 'array',
|
|
57
|
-
items: {
|
|
58
|
-
type: 'string',
|
|
59
|
-
},
|
|
60
|
-
description: 'File extensions to consider when resolving imports.',
|
|
61
|
-
},
|
|
62
|
-
ignore: {
|
|
63
|
-
type: 'array',
|
|
64
|
-
items: {
|
|
65
|
-
type: 'string',
|
|
66
|
-
},
|
|
67
|
-
description: 'Modules/patterns to ignore during resolution.',
|
|
68
|
-
},
|
|
69
|
-
allowUnresolved: {
|
|
70
|
-
type: 'boolean',
|
|
71
|
-
default: false,
|
|
72
|
-
description: 'Allow unresolved imports in certain contexts.',
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
additionalProperties: false,
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
},
|
|
79
|
-
defaultOptions: [
|
|
80
|
-
{
|
|
81
|
-
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
|
|
82
|
-
ignore: [],
|
|
83
|
-
allowUnresolved: false,
|
|
84
|
-
},
|
|
85
|
-
],
|
|
86
|
-
create(context) {
|
|
87
|
-
const [options] = context.options;
|
|
88
|
-
const { ignore = [], allowUnresolved = false } = options || {};
|
|
89
|
-
if (allowUnresolved) {
|
|
90
|
-
return {};
|
|
91
|
-
}
|
|
92
|
-
function shouldIgnore(importPath) {
|
|
93
|
-
return ignore.some((pattern) => {
|
|
94
|
-
if (pattern.includes('*')) {
|
|
95
|
-
const regex = new RegExp(pattern.replace(/\*/g, '.*'));
|
|
96
|
-
return regex.test(importPath);
|
|
97
|
-
}
|
|
98
|
-
return importPath === pattern || importPath.startsWith(pattern + '/');
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
function checkImport(importPath, node) {
|
|
102
|
-
if (shouldIgnore(importPath)) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (importPath.startsWith('node:') ||
|
|
106
|
-
node_module_1.builtinModules.includes(importPath)) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const filePath = context.filename;
|
|
110
|
-
const resolved = (0, eslint_devkit_3.resolveModule)(importPath, filePath, {
|
|
111
|
-
extensions: options?.extensions,
|
|
112
|
-
});
|
|
113
|
-
if (!resolved) {
|
|
114
|
-
context.report({
|
|
115
|
-
node,
|
|
116
|
-
messageId: 'moduleNotFound',
|
|
117
|
-
data: {
|
|
118
|
-
importPath,
|
|
119
|
-
suggestion: 'Check if the file exists, verify the path, or add to ignore list',
|
|
120
|
-
},
|
|
121
|
-
suggest: [
|
|
122
|
-
{
|
|
123
|
-
messageId: 'addIgnoreComment',
|
|
124
|
-
fix(fixer) {
|
|
125
|
-
let statement = node;
|
|
126
|
-
while (statement.parent &&
|
|
127
|
-
statement.parent.type !== 'Program') {
|
|
128
|
-
if ([
|
|
129
|
-
'ImportDeclaration',
|
|
130
|
-
'VariableDeclaration',
|
|
131
|
-
'ExpressionStatement',
|
|
132
|
-
'ExportNamedDeclaration',
|
|
133
|
-
'ExportAllDeclaration',
|
|
134
|
-
].includes(statement.parent.type)) {
|
|
135
|
-
statement = statement.parent;
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
statement = statement.parent;
|
|
139
|
-
}
|
|
140
|
-
return fixer.insertTextBefore(statement, '// eslint-disable-next-line import-next/no-unresolved\n');
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
ImportDeclaration(node) {
|
|
149
|
-
const importPath = node.source.value;
|
|
150
|
-
if (typeof importPath === 'string') {
|
|
151
|
-
checkImport(importPath, node.source);
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
ExportNamedDeclaration(node) {
|
|
155
|
-
if (node.source && typeof node.source.value === 'string') {
|
|
156
|
-
checkImport(node.source.value, node.source);
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
ExportAllDeclaration(node) {
|
|
160
|
-
if (node.source && typeof node.source.value === 'string') {
|
|
161
|
-
checkImport(node.source.value, node.source);
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
CallExpression(node) {
|
|
165
|
-
if (node.callee.type === 'Identifier' &&
|
|
166
|
-
node.callee.name === 'require' &&
|
|
167
|
-
node.arguments.length === 1) {
|
|
168
|
-
const arg = node.arguments[0];
|
|
169
|
-
if (arg.type === 'Literal' && typeof arg.value === 'string') {
|
|
170
|
-
checkImport(arg.value, arg);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
ImportExpression(node) {
|
|
175
|
-
if (node.source.type === 'Literal' &&
|
|
176
|
-
typeof node.source.value === 'string') {
|
|
177
|
-
checkImport(node.source.value, node.source);
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
TSImportEqualsDeclaration(node) {
|
|
181
|
-
if (node.moduleReference.type === 'TSExternalModuleReference' &&
|
|
182
|
-
node.moduleReference.expression.type === 'Literal' &&
|
|
183
|
-
typeof node.moduleReference.expression.value === 'string') {
|
|
184
|
-
checkImport(node.moduleReference.expression.value, node.moduleReference);
|
|
185
|
-
}
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
},
|
|
189
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noUnresolved=void 0;const node_module_1=require("node:module");const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");exports.noUnresolved=(0,eslint_devkit_1.createRule)({name:"no-unresolved",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-unresolved.md",description:"Ensures imports point to resolvable modules"},hasSuggestions:true,messages:{unresolvedImport:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Unresolved Import",description:"Import cannot be resolved to a module",severity:"HIGH",fix:"Ensure the module exists or check the import path spelling",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md"}),moduleNotFound:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Module Not Found",description:"Cannot find module or file",severity:"HIGH",fix:"Verify the file exists and the path is correct",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md"}),invalidExtension:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Invalid File Extension",description:"File extension missing or invalid",severity:"MEDIUM",fix:"Add correct file extension or check if file exists",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md"}),addIgnoreComment:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Add to Ignore",description:"Add to ignore list if intentional",severity:"LOW",fix:"// eslint-disable-next-line import/no-unresolved",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unresolved.md"})},schema:[{type:"object",properties:{extensions:{type:"array",items:{type:"string"},description:"File extensions to consider when resolving imports."},ignore:{type:"array",items:{type:"string"},description:"Modules/patterns to ignore during resolution."},allowUnresolved:{type:"boolean",default:false,description:"Allow unresolved imports in certain contexts."}},additionalProperties:false}]},defaultOptions:[{extensions:[".js",".jsx",".ts",".tsx",".json"],ignore:[],allowUnresolved:false}],create(context){const[options]=context.options;const{ignore=[],allowUnresolved=false}=options||{};if(allowUnresolved){return{}}function shouldIgnore(importPath){return ignore.some(pattern=>{if(pattern.includes("*")){const regex=new RegExp(pattern.replace(/\*/g,".*"));return regex.test(importPath)}return importPath===pattern||importPath.startsWith(pattern+"/")})}function checkImport(importPath,node){if(shouldIgnore(importPath)){return}if(importPath.startsWith("node:")||node_module_1.builtinModules.includes(importPath)){return}const filePath=context.filename;const resolved=(0,eslint_devkit_3.resolveModule)(importPath,filePath,{extensions:options?.extensions});if(!resolved){context.report({node,messageId:"moduleNotFound",data:{importPath,suggestion:"Check if the file exists, verify the path, or add to ignore list"},suggest:[{messageId:"addIgnoreComment",fix(fixer){let statement=node;while(statement.parent&&statement.parent.type!=="Program"){if(["ImportDeclaration","VariableDeclaration","ExpressionStatement","ExportNamedDeclaration","ExportAllDeclaration"].includes(statement.parent.type)){statement=statement.parent;break}statement=statement.parent}return fixer.insertTextBefore(statement,"// eslint-disable-next-line import-next/no-unresolved\n")}}]})}}return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath==="string"){checkImport(importPath,node.source)}},ExportNamedDeclaration(node){if(node.source&&typeof node.source.value==="string"){checkImport(node.source.value,node.source)}},ExportAllDeclaration(node){if(node.source&&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)}},TSImportEqualsDeclaration(node){if(node.moduleReference.type==="TSExternalModuleReference"&&node.moduleReference.expression.type==="Literal"&&typeof node.moduleReference.expression.value==="string"){checkImport(node.moduleReference.expression.value,node.moduleReference)}}}}});
|
|
@@ -1,82 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noUnusedModules = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
exports.noUnusedModules = (0, eslint_devkit_1.createRule)({
|
|
7
|
-
name: 'no-unused-modules',
|
|
8
|
-
meta: {
|
|
9
|
-
type: 'problem',
|
|
10
|
-
docs: {
|
|
11
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-unused-modules.md',
|
|
12
|
-
description: 'Forbid modules without exports',
|
|
13
|
-
},
|
|
14
|
-
hasSuggestions: false,
|
|
15
|
-
messages: {
|
|
16
|
-
missingExports: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
|
|
18
|
-
issueName: 'Missing Exports',
|
|
19
|
-
description: 'Module has no exports',
|
|
20
|
-
severity: 'LOW',
|
|
21
|
-
fix: 'Add exports or remove if module is unused',
|
|
22
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unused-modules.md',
|
|
23
|
-
}),
|
|
24
|
-
},
|
|
25
|
-
schema: [
|
|
26
|
-
{
|
|
27
|
-
type: 'object',
|
|
28
|
-
properties: {
|
|
29
|
-
allowImportOnly: {
|
|
30
|
-
type: 'boolean',
|
|
31
|
-
default: false,
|
|
32
|
-
description: 'Allow modules that only contain imports.',
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
additionalProperties: false,
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
defaultOptions: [
|
|
40
|
-
{
|
|
41
|
-
allowImportOnly: false,
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
create(context) {
|
|
45
|
-
const [options] = context.options;
|
|
46
|
-
const { allowImportOnly = false } = options || {};
|
|
47
|
-
let hasExports = false;
|
|
48
|
-
return {
|
|
49
|
-
ExportNamedDeclaration() {
|
|
50
|
-
hasExports = true;
|
|
51
|
-
},
|
|
52
|
-
ExportDefaultDeclaration() {
|
|
53
|
-
hasExports = true;
|
|
54
|
-
},
|
|
55
|
-
ExportAllDeclaration() {
|
|
56
|
-
hasExports = true;
|
|
57
|
-
},
|
|
58
|
-
AssignmentExpression(node) {
|
|
59
|
-
if (node.left.type === 'MemberExpression' &&
|
|
60
|
-
node.left.object.type === 'Identifier' &&
|
|
61
|
-
node.left.object.name === 'module' &&
|
|
62
|
-
node.left.property.type === 'Identifier' &&
|
|
63
|
-
node.left.property.name === 'exports') {
|
|
64
|
-
hasExports = true;
|
|
65
|
-
}
|
|
66
|
-
if (node.left.type === 'MemberExpression' &&
|
|
67
|
-
node.left.object.type === 'Identifier' &&
|
|
68
|
-
node.left.object.name === 'exports') {
|
|
69
|
-
hasExports = true;
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
'Program:exit'() {
|
|
73
|
-
if (!hasExports && !allowImportOnly) {
|
|
74
|
-
context.report({
|
|
75
|
-
node: context.sourceCode.ast,
|
|
76
|
-
messageId: 'missingExports',
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
},
|
|
82
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noUnusedModules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.noUnusedModules=(0,eslint_devkit_1.createRule)({name:"no-unused-modules",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-unused-modules.md",description:"Forbid modules without exports"},hasSuggestions:false,messages:{missingExports:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Missing Exports",description:"Module has no exports",severity:"LOW",fix:"Add exports or remove if module is unused",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-unused-modules.md"})},schema:[{type:"object",properties:{allowImportOnly:{type:"boolean",default:false,description:"Allow modules that only contain imports."}},additionalProperties:false}]},defaultOptions:[{allowImportOnly:false}],create(context){const[options]=context.options;const{allowImportOnly=false}=options||{};let hasExports=false;return{ExportNamedDeclaration(){hasExports=true},ExportDefaultDeclaration(){hasExports=true},ExportAllDeclaration(){hasExports=true},AssignmentExpression(node){if(node.left.type==="MemberExpression"&&node.left.object.type==="Identifier"&&node.left.object.name==="module"&&node.left.property.type==="Identifier"&&node.left.property.name==="exports"){hasExports=true}if(node.left.type==="MemberExpression"&&node.left.object.type==="Identifier"&&node.left.object.name==="exports"){hasExports=true}},"Program:exit"(){if(!hasExports&&!allowImportOnly){context.report({node:context.sourceCode.ast,messageId:"missingExports"})}}}}});
|
|
@@ -1,107 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noUselessPathSegments = 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.noUselessPathSegments = (0, eslint_devkit_1.createRule)({
|
|
8
|
-
name: 'no-useless-path-segments',
|
|
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-useless-path-segments.md',
|
|
13
|
-
description: 'Forbid unnecessary path segments in import and require statements',
|
|
14
|
-
cwe: 'CWE-1078',
|
|
15
|
-
cvss: 2.5,
|
|
16
|
-
},
|
|
17
|
-
fixable: 'code',
|
|
18
|
-
messages: {
|
|
19
|
-
uselessPathSegments: (0, eslint_devkit_1.formatLLMMessage)({
|
|
20
|
-
icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
|
|
21
|
-
issueName: 'Useless Path Segments',
|
|
22
|
-
cwe: 'CWE-1078',
|
|
23
|
-
description: 'Useless path segments in import: {{importPath}}',
|
|
24
|
-
severity: 'LOW',
|
|
25
|
-
fix: 'Simplify to: {{simplifiedPath}}',
|
|
26
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-useless-path-segments.md',
|
|
27
|
-
}),
|
|
28
|
-
},
|
|
29
|
-
schema: [
|
|
30
|
-
{
|
|
31
|
-
type: 'object',
|
|
32
|
-
properties: {
|
|
33
|
-
noUselessIndex: { type: 'boolean', default: false },
|
|
34
|
-
commonjs: { type: 'boolean', default: true },
|
|
35
|
-
},
|
|
36
|
-
additionalProperties: false,
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
defaultOptions: [{ noUselessIndex: false, commonjs: true }],
|
|
41
|
-
create(context) {
|
|
42
|
-
const options = context.options[0] || {};
|
|
43
|
-
const { noUselessIndex = false, commonjs = true } = options;
|
|
44
|
-
function simplifyPath(importPath) {
|
|
45
|
-
if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
const normalized = path.posix.normalize(importPath);
|
|
49
|
-
let simplified = normalized;
|
|
50
|
-
if (noUselessIndex) {
|
|
51
|
-
simplified = simplified.replace(/\/index$/, '');
|
|
52
|
-
if (simplified === './index' || simplified === 'index') {
|
|
53
|
-
simplified = '.';
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (!simplified.startsWith('./') &&
|
|
57
|
-
!simplified.startsWith('../') &&
|
|
58
|
-
!simplified.startsWith('.')) {
|
|
59
|
-
simplified = './' + simplified;
|
|
60
|
-
}
|
|
61
|
-
if (simplified === importPath) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
return simplified;
|
|
65
|
-
}
|
|
66
|
-
function checkImport(source) {
|
|
67
|
-
const importPath = source.value;
|
|
68
|
-
if (typeof importPath !== 'string')
|
|
69
|
-
return;
|
|
70
|
-
const simplified = simplifyPath(importPath);
|
|
71
|
-
if (simplified) {
|
|
72
|
-
context.report({
|
|
73
|
-
node: source,
|
|
74
|
-
messageId: 'uselessPathSegments',
|
|
75
|
-
data: {
|
|
76
|
-
importPath,
|
|
77
|
-
simplifiedPath: simplified,
|
|
78
|
-
},
|
|
79
|
-
fix(fixer) {
|
|
80
|
-
const quote = source.raw?.charAt(0) || "'";
|
|
81
|
-
return fixer.replaceText(source, `${quote}${simplified}${quote}`);
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
ImportDeclaration(node) {
|
|
88
|
-
checkImport(node.source);
|
|
89
|
-
},
|
|
90
|
-
ImportExpression(node) {
|
|
91
|
-
if (node.source.type === eslint_devkit_1.AST_NODE_TYPES.Literal) {
|
|
92
|
-
checkImport(node.source);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
CallExpression(node) {
|
|
96
|
-
if (!commonjs)
|
|
97
|
-
return;
|
|
98
|
-
if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
99
|
-
node.callee.name === 'require' &&
|
|
100
|
-
node.arguments.length === 1 &&
|
|
101
|
-
node.arguments[0].type === eslint_devkit_1.AST_NODE_TYPES.Literal) {
|
|
102
|
-
checkImport(node.arguments[0]);
|
|
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.noUselessPathSegments=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const path=__importStar(require("node:path"));exports.noUselessPathSegments=(0,eslint_devkit_1.createRule)({name:"no-useless-path-segments",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-useless-path-segments.md",description:"Forbid unnecessary path segments in import and require statements",cwe:"CWE-1078",cvss:2.5},fixable:"code",messages:{uselessPathSegments:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Useless Path Segments",cwe:"CWE-1078",description:"Useless path segments in import: {{importPath}}",severity:"LOW",fix:"Simplify to: {{simplifiedPath}}",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-useless-path-segments.md"})},schema:[{type:"object",properties:{noUselessIndex:{type:"boolean",default:false},commonjs:{type:"boolean",default:true}},additionalProperties:false}]},defaultOptions:[{noUselessIndex:false,commonjs:true}],create(context){const options=context.options[0]||{};const{noUselessIndex=false,commonjs=true}=options;function simplifyPath(importPath){if(!importPath.startsWith("./")&&!importPath.startsWith("../")){return null}const normalized=path.posix.normalize(importPath);let simplified=normalized;if(noUselessIndex){simplified=simplified.replace(/\/index$/,"");if(simplified==="./index"||simplified==="index"){simplified="."}}if(!simplified.startsWith("./")&&!simplified.startsWith("../")&&!simplified.startsWith(".")){simplified="./"+simplified}if(simplified===importPath){return null}return simplified}function checkImport(source){const importPath=source.value;if(typeof importPath!=="string")return;const simplified=simplifyPath(importPath);if(simplified){context.report({node:source,messageId:"uselessPathSegments",data:{importPath,simplifiedPath:simplified},fix(fixer){const quote=source.raw?.charAt(0)||"'";return fixer.replaceText(source,`${quote}${simplified}${quote}`)}})}}return{ImportDeclaration(node){checkImport(node.source)},ImportExpression(node){if(node.source.type===eslint_devkit_1.AST_NODE_TYPES.Literal){checkImport(node.source)}},CallExpression(node){if(!commonjs)return;if(node.callee.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&node.callee.name==="require"&&node.arguments.length===1&&node.arguments[0].type===eslint_devkit_1.AST_NODE_TYPES.Literal){checkImport(node.arguments[0])}}}}});
|
|
@@ -1,188 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.preferDefaultExport = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
exports.preferDefaultExport = (0, eslint_devkit_1.createRule)({
|
|
7
|
-
name: 'prefer-default-export',
|
|
8
|
-
meta: {
|
|
9
|
-
type: 'suggestion',
|
|
10
|
-
docs: {
|
|
11
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-default-export.md',
|
|
12
|
-
description: 'Prefer a default export if module exports a single name',
|
|
13
|
-
},
|
|
14
|
-
hasSuggestions: true,
|
|
15
|
-
messages: {
|
|
16
|
-
preferDefaultExport: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
18
|
-
issueName: 'Prefer Default Export',
|
|
19
|
-
description: 'Single named export should be a default export',
|
|
20
|
-
severity: 'LOW',
|
|
21
|
-
fix: 'Convert named export to default export',
|
|
22
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/prefer-default-export.md',
|
|
23
|
-
}),
|
|
24
|
-
singleNamedExport: (0, eslint_devkit_2.formatLLMMessage)({
|
|
25
|
-
icon: eslint_devkit_2.MessageIcons.INFO,
|
|
26
|
-
issueName: 'Single Export Pattern',
|
|
27
|
-
description: 'Module exports single item that could be default export',
|
|
28
|
-
severity: 'LOW',
|
|
29
|
-
fix: 'Consider using default export for cleaner imports',
|
|
30
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/prefer-default-export.md',
|
|
31
|
-
}),
|
|
32
|
-
multipleNamedToDefault: (0, eslint_devkit_2.formatLLMMessage)({
|
|
33
|
-
icon: eslint_devkit_2.MessageIcons.INFO,
|
|
34
|
-
issueName: 'Multiple Named Exports',
|
|
35
|
-
description: 'Consider consolidating related exports into default export',
|
|
36
|
-
severity: 'LOW',
|
|
37
|
-
fix: 'Group related exports as named properties of default export',
|
|
38
|
-
documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/prefer-default-export.md',
|
|
39
|
-
}),
|
|
40
|
-
},
|
|
41
|
-
schema: [
|
|
42
|
-
{
|
|
43
|
-
type: 'object',
|
|
44
|
-
properties: {
|
|
45
|
-
target: {
|
|
46
|
-
type: 'string',
|
|
47
|
-
enum: ['always', 'single', 'as-needed'],
|
|
48
|
-
default: 'single',
|
|
49
|
-
description: 'When to enforce default exports: always (all), single (single export), as-needed (when beneficial)',
|
|
50
|
-
},
|
|
51
|
-
ignoreFiles: {
|
|
52
|
-
type: 'array',
|
|
53
|
-
items: { type: 'string' },
|
|
54
|
-
description: 'File patterns to ignore',
|
|
55
|
-
},
|
|
56
|
-
allowNamedExports: {
|
|
57
|
-
type: 'boolean',
|
|
58
|
-
default: false,
|
|
59
|
-
description: 'Allow named exports without warnings',
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
additionalProperties: false,
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
defaultOptions: [
|
|
67
|
-
{
|
|
68
|
-
target: 'single',
|
|
69
|
-
ignoreFiles: [],
|
|
70
|
-
allowNamedExports: false,
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
create(context) {
|
|
74
|
-
const [options] = context.options;
|
|
75
|
-
const { target = 'single', ignoreFiles = [], allowNamedExports = false, } = options || {};
|
|
76
|
-
const filename = context.filename;
|
|
77
|
-
if (!filename) {
|
|
78
|
-
return {};
|
|
79
|
-
}
|
|
80
|
-
function shouldIgnoreFile() {
|
|
81
|
-
return ignoreFiles.some((pattern) => filename.includes(pattern));
|
|
82
|
-
}
|
|
83
|
-
if (shouldIgnoreFile() || allowNamedExports) {
|
|
84
|
-
return {};
|
|
85
|
-
}
|
|
86
|
-
const namedExports = new Map();
|
|
87
|
-
let defaultExportNode = null;
|
|
88
|
-
function addNamedExport(name, exportNode) {
|
|
89
|
-
namedExports.set(name, exportNode);
|
|
90
|
-
}
|
|
91
|
-
function checkSingleExport() {
|
|
92
|
-
if (target === 'single' &&
|
|
93
|
-
namedExports.size === 1 &&
|
|
94
|
-
!defaultExportNode) {
|
|
95
|
-
const [exportName, exportNode] = Array.from(namedExports.entries())[0];
|
|
96
|
-
context.report({
|
|
97
|
-
node: exportNode,
|
|
98
|
-
messageId: 'preferDefaultExport',
|
|
99
|
-
data: {
|
|
100
|
-
exportName,
|
|
101
|
-
exportCount: namedExports.size,
|
|
102
|
-
suggestion: 'Convert to default export for cleaner imports',
|
|
103
|
-
benefit: 'Default exports provide cleaner import syntax and better tree-shaking',
|
|
104
|
-
},
|
|
105
|
-
suggest: [
|
|
106
|
-
{
|
|
107
|
-
messageId: 'preferDefaultExport',
|
|
108
|
-
fix(fixer) {
|
|
109
|
-
return fixer.insertTextBefore(exportNode, '// TODO: Convert named export to default export\n');
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
ExportNamedDeclaration(node) {
|
|
118
|
-
if (node.source && node.specifiers) {
|
|
119
|
-
const hasDefaultReExport = node.specifiers.some((specifier) => specifier.exported.type === 'Identifier' &&
|
|
120
|
-
specifier.exported.name === 'default');
|
|
121
|
-
if (hasDefaultReExport) {
|
|
122
|
-
defaultExportNode =
|
|
123
|
-
node;
|
|
124
|
-
}
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (node.source) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
if (node.exportKind === 'type') {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
if (node.declaration) {
|
|
134
|
-
if (node.declaration.type === 'TSInterfaceDeclaration' ||
|
|
135
|
-
node.declaration.type === 'TSTypeAliasDeclaration') {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (node.declaration.type === 'VariableDeclaration') {
|
|
139
|
-
node.declaration.declarations.forEach((decl) => {
|
|
140
|
-
if (decl.id.type === 'Identifier') {
|
|
141
|
-
addNamedExport(decl.id.name, node);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
else if (node.declaration.type === 'FunctionDeclaration' &&
|
|
146
|
-
node.declaration.id) {
|
|
147
|
-
addNamedExport(node.declaration.id.name, node);
|
|
148
|
-
}
|
|
149
|
-
else if (node.declaration.type === 'ClassDeclaration' &&
|
|
150
|
-
node.declaration.id) {
|
|
151
|
-
addNamedExport(node.declaration.id.name, node);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (node.specifiers) {
|
|
155
|
-
node.specifiers.forEach((specifier) => {
|
|
156
|
-
if (specifier.exportKind === 'type') {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (specifier.exported.type === 'Identifier') {
|
|
160
|
-
addNamedExport(specifier.exported.name, node);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
ExportDefaultDeclaration(node) {
|
|
166
|
-
defaultExportNode = node;
|
|
167
|
-
},
|
|
168
|
-
'Program:exit'(node) {
|
|
169
|
-
if (target === 'always' &&
|
|
170
|
-
namedExports.size > 0 &&
|
|
171
|
-
!defaultExportNode) {
|
|
172
|
-
context.report({
|
|
173
|
-
node,
|
|
174
|
-
messageId: 'multipleNamedToDefault',
|
|
175
|
-
data: {
|
|
176
|
-
exportCount: namedExports.size,
|
|
177
|
-
exports: Array.from(namedExports).join(', '),
|
|
178
|
-
suggestion: 'Consider grouping related exports as a default export object',
|
|
179
|
-
},
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
checkSingleExport();
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
};
|
|
187
|
-
},
|
|
188
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.preferDefaultExport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.preferDefaultExport=(0,eslint_devkit_1.createRule)({name:"prefer-default-export",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-default-export.md",description:"Prefer a default export if module exports a single name"},hasSuggestions:true,messages:{preferDefaultExport:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Prefer Default Export",description:"Single named export should be a default export",severity:"LOW",fix:"Convert named export to default export",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/prefer-default-export.md"}),singleNamedExport:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Single Export Pattern",description:"Module exports single item that could be default export",severity:"LOW",fix:"Consider using default export for cleaner imports",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/prefer-default-export.md"}),multipleNamedToDefault:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Multiple Named Exports",description:"Consider consolidating related exports into default export",severity:"LOW",fix:"Group related exports as named properties of default export",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/prefer-default-export.md"})},schema:[{type:"object",properties:{target:{type:"string",enum:["always","single","as-needed"],default:"single",description:"When to enforce default exports: always (all), single (single export), as-needed (when beneficial)"},ignoreFiles:{type:"array",items:{type:"string"},description:"File patterns to ignore"},allowNamedExports:{type:"boolean",default:false,description:"Allow named exports without warnings"}},additionalProperties:false}]},defaultOptions:[{target:"single",ignoreFiles:[],allowNamedExports:false}],create(context){const[options]=context.options;const{target="single",ignoreFiles=[],allowNamedExports=false}=options||{};const filename=context.filename;if(!filename){return{}}function shouldIgnoreFile(){return ignoreFiles.some(pattern=>filename.includes(pattern))}if(shouldIgnoreFile()||allowNamedExports){return{}}const namedExports=new Map;let defaultExportNode=null;function addNamedExport(name,exportNode){namedExports.set(name,exportNode)}function checkSingleExport(){if(target==="single"&&namedExports.size===1&&!defaultExportNode){const[exportName,exportNode]=Array.from(namedExports.entries())[0];context.report({node:exportNode,messageId:"preferDefaultExport",data:{exportName,exportCount:namedExports.size,suggestion:"Convert to default export for cleaner imports",benefit:"Default exports provide cleaner import syntax and better tree-shaking"},suggest:[{messageId:"preferDefaultExport",fix(fixer){return fixer.insertTextBefore(exportNode,"// TODO: Convert named export to default export\n")}}]})}}return{ExportNamedDeclaration(node){if(node.source&&node.specifiers){const hasDefaultReExport=node.specifiers.some(specifier=>specifier.exported.type==="Identifier"&&specifier.exported.name==="default");if(hasDefaultReExport){defaultExportNode=node}return}if(node.source){return}if(node.exportKind==="type"){return}if(node.declaration){if(node.declaration.type==="TSInterfaceDeclaration"||node.declaration.type==="TSTypeAliasDeclaration"){return}if(node.declaration.type==="VariableDeclaration"){node.declaration.declarations.forEach(decl=>{if(decl.id.type==="Identifier"){addNamedExport(decl.id.name,node)}})}else if(node.declaration.type==="FunctionDeclaration"&&node.declaration.id){addNamedExport(node.declaration.id.name,node)}else if(node.declaration.type==="ClassDeclaration"&&node.declaration.id){addNamedExport(node.declaration.id.name,node)}}if(node.specifiers){node.specifiers.forEach(specifier=>{if(specifier.exportKind==="type"){return}if(specifier.exported.type==="Identifier"){addNamedExport(specifier.exported.name,node)}})}},ExportDefaultDeclaration(node){defaultExportNode=node},"Program:exit"(node){if(target==="always"&&namedExports.size>0&&!defaultExportNode){context.report({node,messageId:"multipleNamedToDefault",data:{exportCount:namedExports.size,exports:Array.from(namedExports).join(", "),suggestion:"Consider grouping related exports as a default export object"}})}else{checkSingleExport()}}}}});
|