eslint-plugin-import-next 2.3.9 → 2.3.11
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/README.md +47 -0
- package/package.json +16 -12
- package/src/files/foo.js +0 -5
- package/src/files/no-default.js +0 -5
- package/src/index.d.ts +15 -2812
- package/src/index.js +5 -147
- package/src/oxlint.d.ts +17 -20
- package/src/oxlint.js +0 -18
- package/src/rules/consistent-type-specifier-style.js +0 -19
- package/src/rules/default.js +0 -7
- package/src/rules/dynamic-import-chunkname.js +0 -8
- package/src/rules/enforce-dependency-direction.js +2 -39
- package/src/rules/enforce-import-order.js +3 -33
- package/src/rules/enforce-team-boundaries.js +0 -49
- package/src/rules/export.js +0 -9
- package/src/rules/exports-last.js +0 -10
- package/src/rules/extensions.js +2 -11
- package/src/rules/first.js +0 -6
- package/src/rules/group-exports.js +0 -13
- package/src/rules/max-dependencies.js +0 -16
- package/src/rules/named.js +1 -10
- package/src/rules/namespace.js +1 -11
- package/src/rules/newline-after-import.js +2 -13
- package/src/rules/no-absolute-path.js +0 -7
- package/src/rules/no-amd.js +1 -18
- package/src/rules/no-anonymous-default-export.js +0 -13
- package/src/rules/no-barrel-file.js +0 -32
- package/src/rules/no-barrel-import.js +0 -25
- package/src/rules/no-commonjs.js +0 -18
- package/src/rules/no-cross-domain-imports.js +2 -47
- package/src/rules/no-cycle.js +2 -135
- package/src/rules/no-default-export.js +0 -28
- package/src/rules/no-deprecated.js +0 -32
- package/src/rules/no-duplicates.js +2 -10
- package/src/rules/no-dynamic-require.js +0 -6
- package/src/rules/no-empty-named-blocks.js +1 -17
- package/src/rules/no-extraneous-dependencies.js +0 -38
- package/src/rules/no-full-package-import.js +0 -19
- package/src/rules/no-import-module-exports.js +0 -8
- package/src/rules/no-internal-modules.js +0 -40
- package/src/rules/no-legacy-imports.js +1 -11
- package/src/rules/no-mutable-exports.js +0 -14
- package/src/rules/no-named-as-default-member.js +0 -11
- package/src/rules/no-named-as-default.js +0 -17
- package/src/rules/no-named-default.js +0 -5
- package/src/rules/no-named-export.js +1 -22
- package/src/rules/no-namespace.js +0 -10
- package/src/rules/no-nodejs-modules.js +0 -15
- package/src/rules/no-relative-packages.js +0 -15
- package/src/rules/no-relative-parent-imports.js +0 -11
- package/src/rules/no-restricted-paths.js +0 -6
- package/src/rules/no-self-import.js +0 -22
- package/src/rules/no-unassigned-import.js +0 -14
- package/src/rules/no-unresolved.js +0 -16
- package/src/rules/no-unused-modules.js +0 -7
- package/src/rules/no-useless-path-segments.js +0 -15
- package/src/rules/prefer-default-export.js +0 -18
- package/src/rules/prefer-direct-import.js +1 -21
- package/src/rules/prefer-modern-api.js +0 -21
- package/src/rules/prefer-node-protocol.js +0 -15
- package/src/rules/prefer-tree-shakeable-imports.js +0 -14
- package/src/rules/require-import-approval.js +0 -21
- package/src/rules/unambiguous.js +0 -11
- package/src/types/index.js +0 -5
- package/AGENTS.md +0 -95
- package/CHANGELOG.md +0 -170
- package/src/files/foo.d.ts +0 -7
- package/src/files/no-default.d.ts +0 -6
- package/src/rules/consistent-type-specifier-style.d.ts +0 -13
- package/src/rules/default.d.ts +0 -9
- package/src/rules/dynamic-import-chunkname.d.ts +0 -26
- package/src/rules/enforce-dependency-direction.d.ts +0 -27
- package/src/rules/enforce-import-order.d.ts +0 -29
- package/src/rules/enforce-team-boundaries.d.ts +0 -47
- package/src/rules/export.d.ts +0 -17
- package/src/rules/exports-last.d.ts +0 -15
- package/src/rules/extensions.d.ts +0 -17
- package/src/rules/first.d.ts +0 -13
- package/src/rules/group-exports.d.ts +0 -15
- package/src/rules/max-dependencies.d.ts +0 -26
- package/src/rules/named.d.ts +0 -13
- package/src/rules/namespace.d.ts +0 -13
- package/src/rules/newline-after-import.d.ts +0 -13
- package/src/rules/no-absolute-path.d.ts +0 -25
- package/src/rules/no-amd.d.ts +0 -21
- package/src/rules/no-anonymous-default-export.d.ts +0 -24
- package/src/rules/no-barrel-file.d.ts +0 -55
- package/src/rules/no-barrel-import.d.ts +0 -48
- package/src/rules/no-commonjs.d.ts +0 -28
- package/src/rules/no-cross-domain-imports.d.ts +0 -41
- package/src/rules/no-cycle.d.ts +0 -102
- package/src/rules/no-default-export.d.ts +0 -24
- package/src/rules/no-deprecated.d.ts +0 -26
- package/src/rules/no-duplicates.d.ts +0 -13
- package/src/rules/no-dynamic-require.d.ts +0 -22
- package/src/rules/no-empty-named-blocks.d.ts +0 -17
- package/src/rules/no-extraneous-dependencies.d.ts +0 -45
- package/src/rules/no-full-package-import.d.ts +0 -42
- package/src/rules/no-import-module-exports.d.ts +0 -21
- package/src/rules/no-internal-modules.d.ts +0 -28
- package/src/rules/no-legacy-imports.d.ts +0 -47
- package/src/rules/no-mutable-exports.d.ts +0 -22
- package/src/rules/no-named-as-default-member.d.ts +0 -15
- package/src/rules/no-named-as-default.d.ts +0 -15
- package/src/rules/no-named-default.d.ts +0 -15
- package/src/rules/no-named-export.d.ts +0 -26
- package/src/rules/no-namespace.d.ts +0 -21
- package/src/rules/no-nodejs-modules.d.ts +0 -24
- package/src/rules/no-relative-packages.d.ts +0 -21
- package/src/rules/no-relative-parent-imports.d.ts +0 -22
- package/src/rules/no-restricted-paths.d.ts +0 -20
- package/src/rules/no-self-import.d.ts +0 -15
- package/src/rules/no-unassigned-import.d.ts +0 -20
- package/src/rules/no-unresolved.d.ts +0 -20
- package/src/rules/no-unused-modules.d.ts +0 -19
- package/src/rules/no-useless-path-segments.d.ts +0 -23
- package/src/rules/prefer-default-export.d.ts +0 -24
- package/src/rules/prefer-direct-import.d.ts +0 -51
- package/src/rules/prefer-modern-api.d.ts +0 -47
- package/src/rules/prefer-node-protocol.d.ts +0 -19
- package/src/rules/prefer-tree-shakeable-imports.d.ts +0 -49
- package/src/rules/require-import-approval.d.ts +0 -52
- package/src/rules/unambiguous.d.ts +0 -15
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noLegacyImports = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
|
-
/**
|
|
11
|
-
* Check if import matches a legacy pattern
|
|
12
|
-
*/
|
|
13
5
|
function matchLegacyPattern(importPath, pattern) {
|
|
14
6
|
try {
|
|
15
7
|
const regex = new RegExp(pattern);
|
|
16
8
|
return regex.test(importPath);
|
|
17
9
|
}
|
|
18
10
|
catch {
|
|
19
|
-
// Fallback to exact match
|
|
20
11
|
return importPath === pattern || importPath.startsWith(pattern);
|
|
21
12
|
}
|
|
22
13
|
}
|
|
@@ -96,11 +87,10 @@ exports.noLegacyImports = (0, eslint_devkit_1.createRule)({
|
|
|
96
87
|
deadline: deadlineText,
|
|
97
88
|
},
|
|
98
89
|
fix: (fixer) => {
|
|
99
|
-
// Simple replacement - replace the import path
|
|
100
90
|
return fixer.replaceText(sourceNode, `'${mapping.replacement}'`);
|
|
101
91
|
},
|
|
102
92
|
});
|
|
103
|
-
break;
|
|
93
|
+
break;
|
|
104
94
|
}
|
|
105
95
|
}
|
|
106
96
|
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noMutableExports = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -120,7 +115,6 @@ exports.noMutableExports = (0, eslint_devkit_1.createRule)({
|
|
|
120
115
|
return;
|
|
121
116
|
}
|
|
122
117
|
const { kind, declarations } = node.declaration;
|
|
123
|
-
// Only check var and let declarations
|
|
124
118
|
if (kind !== 'var' && kind !== 'let') {
|
|
125
119
|
return;
|
|
126
120
|
}
|
|
@@ -128,25 +122,17 @@ exports.noMutableExports = (0, eslint_devkit_1.createRule)({
|
|
|
128
122
|
checkPattern(decl.id, kind);
|
|
129
123
|
});
|
|
130
124
|
},
|
|
131
|
-
// Also check for re-exports that might be mutable
|
|
132
|
-
// This is more complex as it requires following the import chain
|
|
133
125
|
VariableDeclaration(node) {
|
|
134
|
-
// Check if this variable declaration is exported
|
|
135
126
|
const parent = node.parent;
|
|
136
127
|
if (parent && parent.type === 'ExportNamedDeclaration') {
|
|
137
|
-
// This is already handled above
|
|
138
128
|
return;
|
|
139
129
|
}
|
|
140
|
-
// Check if this variable is exported elsewhere in the file
|
|
141
|
-
// This is a simplified check - a full implementation would need to track all exports
|
|
142
130
|
const sourceCode = context.sourceCode;
|
|
143
131
|
const fileText = sourceCode.getText();
|
|
144
132
|
if (node.kind === 'var' || node.kind === 'let') {
|
|
145
133
|
node.declarations.forEach((decl) => {
|
|
146
134
|
if (decl.id.type === 'Identifier') {
|
|
147
135
|
const varName = decl.id.name;
|
|
148
|
-
// Check if this variable is exported later in the file
|
|
149
|
-
// This is a heuristic - real implementation would need AST analysis
|
|
150
136
|
const exportPattern = new RegExp(`export\\s*{\\s*${varName}\\s*}`, 'g');
|
|
151
137
|
if (exportPattern.test(fileText)) {
|
|
152
138
|
reportMutableExport(decl.id, varName, node.kind);
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noNamedAsDefaultMember = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -32,9 +27,7 @@ exports.noNamedAsDefaultMember = (0, eslint_devkit_1.createRule)({
|
|
|
32
27
|
},
|
|
33
28
|
defaultOptions: [],
|
|
34
29
|
create(context) {
|
|
35
|
-
// Track default imports and their sources
|
|
36
30
|
const defaultImports = new Map();
|
|
37
|
-
// Track named imports per source
|
|
38
31
|
const namedImportsBySource = new Map();
|
|
39
32
|
return {
|
|
40
33
|
ImportDeclaration(node) {
|
|
@@ -55,21 +48,17 @@ exports.noNamedAsDefaultMember = (0, eslint_devkit_1.createRule)({
|
|
|
55
48
|
});
|
|
56
49
|
},
|
|
57
50
|
MemberExpression(node) {
|
|
58
|
-
// Check if accessing property of default import
|
|
59
51
|
if (node.object.type !== eslint_devkit_1.AST_NODE_TYPES.Identifier) {
|
|
60
52
|
return;
|
|
61
53
|
}
|
|
62
|
-
// Skip computed properties like obj[prop]
|
|
63
54
|
if (node.computed)
|
|
64
55
|
return;
|
|
65
56
|
const defaultImportInfo = defaultImports.get(node.object.name);
|
|
66
57
|
if (!defaultImportInfo)
|
|
67
58
|
return;
|
|
68
|
-
// Get the property name being accessed
|
|
69
59
|
if (node.property.type !== eslint_devkit_1.AST_NODE_TYPES.Identifier)
|
|
70
60
|
return;
|
|
71
61
|
const propertyName = node.property.name;
|
|
72
|
-
// Check if this property is a known named export from the same source
|
|
73
62
|
const namedExports = namedImportsBySource.get(defaultImportInfo.source);
|
|
74
63
|
if (namedExports && namedExports.has(propertyName)) {
|
|
75
64
|
context.report({
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noNamedAsDefault = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -32,14 +27,9 @@ exports.noNamedAsDefault = (0, eslint_devkit_1.createRule)({
|
|
|
32
27
|
},
|
|
33
28
|
defaultOptions: [],
|
|
34
29
|
create(context) {
|
|
35
|
-
// This rule requires resolving the imported module to see its exports
|
|
36
|
-
// For a basic implementation without full resolution, we track what we can
|
|
37
|
-
// In practice, this would need TypeScript language service or resolver
|
|
38
|
-
// Track exports from the current file for same-file detection
|
|
39
30
|
const exportedNames = new Set();
|
|
40
31
|
let defaultExportName = null;
|
|
41
32
|
return {
|
|
42
|
-
// Collect exports to detect potential issues
|
|
43
33
|
ExportNamedDeclaration(node) {
|
|
44
34
|
if (node.declaration) {
|
|
45
35
|
if ((node.declaration.type === 'FunctionDeclaration' ||
|
|
@@ -62,7 +52,6 @@ exports.noNamedAsDefault = (0, eslint_devkit_1.createRule)({
|
|
|
62
52
|
});
|
|
63
53
|
},
|
|
64
54
|
ExportDefaultDeclaration(node) {
|
|
65
|
-
// Track if default export is a named identifier
|
|
66
55
|
if (node.declaration.type === 'Identifier') {
|
|
67
56
|
defaultExportName = node.declaration.name;
|
|
68
57
|
}
|
|
@@ -73,20 +62,14 @@ exports.noNamedAsDefault = (0, eslint_devkit_1.createRule)({
|
|
|
73
62
|
}
|
|
74
63
|
},
|
|
75
64
|
'Program:exit'() {
|
|
76
|
-
// If the default export shares a name with a named export, report
|
|
77
65
|
if (defaultExportName && exportedNames.has(defaultExportName)) {
|
|
78
|
-
// This is a heuristic - ideally we'd track the import site
|
|
79
|
-
// For now, we report on the pattern where importing default as the name
|
|
80
|
-
// would shadow the named export
|
|
81
66
|
}
|
|
82
67
|
},
|
|
83
68
|
ImportDeclaration(node) {
|
|
84
|
-
// Check if default import name matches a named import from same module
|
|
85
69
|
const defaultSpec = node.specifiers.find((s) => s.type === 'ImportDefaultSpecifier');
|
|
86
70
|
if (!defaultSpec)
|
|
87
71
|
return;
|
|
88
72
|
const defaultName = defaultSpec.local.name;
|
|
89
|
-
// Check if there's also a named import with the same name being imported
|
|
90
73
|
const namedSpecs = node.specifiers.filter((s) => s.type === 'ImportSpecifier');
|
|
91
74
|
for (const namedSpec of namedSpecs) {
|
|
92
75
|
const importedName = namedSpec.imported.type === 'Identifier'
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noNamedDefault = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noNamedExport = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -80,26 +75,20 @@ exports.noNamedExport = (0, eslint_devkit_1.createRule)({
|
|
|
80
75
|
],
|
|
81
76
|
create(context) {
|
|
82
77
|
const [options] = context.options;
|
|
83
|
-
const { allowInFiles = [], allowNames = [], allowPatterns = [],
|
|
84
|
-
// suggestDefault // unused option
|
|
85
|
-
} = options || {};
|
|
78
|
+
const { allowInFiles = [], allowNames = [], allowPatterns = [], } = options || {};
|
|
86
79
|
const filename = context.filename;
|
|
87
80
|
function shouldAllow(specifier) {
|
|
88
81
|
if (!filename) {
|
|
89
82
|
return false;
|
|
90
83
|
}
|
|
91
|
-
// Check if file is in allowed list
|
|
92
84
|
const allowedByFile = allowInFiles.some((pattern) => {
|
|
93
85
|
if (pattern.includes('*')) {
|
|
94
86
|
const regexStr = '^' + pattern
|
|
95
87
|
.replace(/[.+?^${}()|[\]\\]/g, (match) => {
|
|
96
|
-
// The char class above never matches '*', so no special-casing needed.
|
|
97
88
|
return '\\' + match;
|
|
98
89
|
})
|
|
99
90
|
.replace(/\*\*/g, '.*')
|
|
100
91
|
.replace(/\*/g, '[^/]*') + '$';
|
|
101
|
-
// regexStr escapes every regex metacharacter before translating
|
|
102
|
-
// glob tokens, so new RegExp() can never throw here.
|
|
103
92
|
const regex = new RegExp(regexStr);
|
|
104
93
|
return regex.test(filename);
|
|
105
94
|
}
|
|
@@ -108,18 +97,14 @@ exports.noNamedExport = (0, eslint_devkit_1.createRule)({
|
|
|
108
97
|
if (allowedByFile) {
|
|
109
98
|
return true;
|
|
110
99
|
}
|
|
111
|
-
// Check if filename matches allowed patterns
|
|
112
100
|
const allowedByPattern = allowPatterns.some((pattern) => {
|
|
113
101
|
if (pattern.includes('*')) {
|
|
114
102
|
const regexStr = '^' + pattern
|
|
115
103
|
.replace(/[.+?^${}()|[\]\\]/g, (match) => {
|
|
116
|
-
// The char class above never matches '*', so no special-casing needed.
|
|
117
104
|
return '\\' + match;
|
|
118
105
|
})
|
|
119
106
|
.replace(/\*\*/g, '.*')
|
|
120
107
|
.replace(/\*/g, '[^/]*') + '$';
|
|
121
|
-
// regexStr escapes every regex metacharacter before translating
|
|
122
|
-
// glob tokens, so new RegExp() can never throw here.
|
|
123
108
|
const regex = new RegExp(regexStr);
|
|
124
109
|
return regex.test(filename);
|
|
125
110
|
}
|
|
@@ -128,7 +113,6 @@ exports.noNamedExport = (0, eslint_devkit_1.createRule)({
|
|
|
128
113
|
if (allowedByPattern) {
|
|
129
114
|
return true;
|
|
130
115
|
}
|
|
131
|
-
// Check if specific export name is allowed
|
|
132
116
|
if (specifier &&
|
|
133
117
|
specifier.exported.type === 'Identifier' &&
|
|
134
118
|
allowNames.includes(specifier.exported.name)) {
|
|
@@ -138,17 +122,14 @@ exports.noNamedExport = (0, eslint_devkit_1.createRule)({
|
|
|
138
122
|
}
|
|
139
123
|
return {
|
|
140
124
|
ExportNamedDeclaration(node) {
|
|
141
|
-
// Skip type exports
|
|
142
125
|
if (node.exportKind === 'type' ||
|
|
143
126
|
(node.declaration &&
|
|
144
127
|
(node.declaration.type === 'TSInterfaceDeclaration' ||
|
|
145
128
|
node.declaration.type === 'TSTypeAliasDeclaration'))) {
|
|
146
129
|
return;
|
|
147
130
|
}
|
|
148
|
-
// Check each specifier individually
|
|
149
131
|
if (node.specifiers && node.specifiers.length > 0) {
|
|
150
132
|
for (const specifier of node.specifiers) {
|
|
151
|
-
// Allow re-exporting default as named export
|
|
152
133
|
if (specifier.exported.type === 'Identifier' &&
|
|
153
134
|
specifier.exported.name !== 'default' &&
|
|
154
135
|
!shouldAllow(specifier)) {
|
|
@@ -161,10 +142,8 @@ exports.noNamedExport = (0, eslint_devkit_1.createRule)({
|
|
|
161
142
|
}
|
|
162
143
|
}
|
|
163
144
|
}
|
|
164
|
-
// Check for export declarations (export const foo = 1;)
|
|
165
145
|
else if (node.declaration) {
|
|
166
146
|
if (node.declaration.type === 'VariableDeclaration') {
|
|
167
|
-
// Report on each variable declarator individually
|
|
168
147
|
for (const declarator of node.declaration.declarations) {
|
|
169
148
|
const varName = declarator.id.type === 'Identifier'
|
|
170
149
|
? declarator.id.name
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noNamespace = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -47,11 +42,6 @@ exports.noNamespace = (0, eslint_devkit_1.createRule)({
|
|
|
47
42
|
const ignorePatterns = options.ignore || [];
|
|
48
43
|
function isIgnored(source) {
|
|
49
44
|
return ignorePatterns.some((pattern) => {
|
|
50
|
-
// Escape ALL regex metacharacters — including `*`, `?`, and `\` — so
|
|
51
|
-
// the subsequent replaces can find the now-escaped `\*` and `\?` and
|
|
52
|
-
// translate them back to glob meanings. Without escaping `*` and `?`,
|
|
53
|
-
// the inner replaces don't match anything and raw `*` / `?` reach
|
|
54
|
-
// `new RegExp()` (CodeQL: `js/incomplete-sanitization`).
|
|
55
45
|
const escaped = pattern.replace(/[.+^${}()|[\]\\*?]/g, '\\$&');
|
|
56
46
|
const regex = new RegExp('^' +
|
|
57
47
|
escaped
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noNodejsModules = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
5
|
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
11
|
-
// Node.js builtin modules that should be flagged
|
|
12
6
|
const NODEJS_BUILTINS = new Set([
|
|
13
7
|
'assert',
|
|
14
8
|
'buffer',
|
|
@@ -42,7 +36,6 @@ const NODEJS_BUILTINS = new Set([
|
|
|
42
36
|
'module',
|
|
43
37
|
'process',
|
|
44
38
|
]);
|
|
45
|
-
// Alternative suggestions for common builtins
|
|
46
39
|
const BUILTIN_ALTERNATIVES = {
|
|
47
40
|
fs: 'Use platform-specific file APIs or isomorphic libraries',
|
|
48
41
|
path: 'Use URL constructor or path utilities from your bundler',
|
|
@@ -131,23 +124,18 @@ exports.noNodejsModules = (0, eslint_devkit_1.createRule)({
|
|
|
131
124
|
create(context) {
|
|
132
125
|
const [options] = context.options;
|
|
133
126
|
const { allow = [], additionalBuiltins = [], suggestAlternatives = true, } = options || {};
|
|
134
|
-
// Create set of all builtins to check
|
|
135
127
|
const allBuiltins = new Set([...NODEJS_BUILTINS, ...additionalBuiltins]);
|
|
136
|
-
// Create set of allowed builtins
|
|
137
128
|
const allowedBuiltins = new Set(allow);
|
|
138
129
|
function isNodejsBuiltin(moduleName) {
|
|
139
|
-
// Check exact match
|
|
140
130
|
if (allBuiltins.has(moduleName)) {
|
|
141
131
|
return !allowedBuiltins.has(moduleName);
|
|
142
132
|
}
|
|
143
|
-
// Check node: protocol prefix (Node.js 14.18.0+)
|
|
144
133
|
if (moduleName.startsWith('node:')) {
|
|
145
134
|
const builtinName = moduleName.slice(5);
|
|
146
135
|
return (allBuiltins.has(builtinName) && !allowedBuiltins.has(builtinName));
|
|
147
136
|
}
|
|
148
137
|
return false;
|
|
149
138
|
}
|
|
150
|
-
// oxlint-disable-next-line consistent-function-scoping
|
|
151
139
|
function getBuiltinName(moduleName) {
|
|
152
140
|
if (moduleName.startsWith('node:')) {
|
|
153
141
|
return moduleName.slice(5);
|
|
@@ -205,7 +193,6 @@ exports.noNodejsModules = (0, eslint_devkit_1.createRule)({
|
|
|
205
193
|
}
|
|
206
194
|
},
|
|
207
195
|
CallExpression(node) {
|
|
208
|
-
// Check require() calls
|
|
209
196
|
if (node.callee.type === 'Identifier' &&
|
|
210
197
|
node.callee.name === 'require' &&
|
|
211
198
|
node.arguments.length === 1) {
|
|
@@ -218,7 +205,6 @@ exports.noNodejsModules = (0, eslint_devkit_1.createRule)({
|
|
|
218
205
|
}
|
|
219
206
|
}
|
|
220
207
|
},
|
|
221
|
-
// Check dynamic imports via ImportExpression
|
|
222
208
|
ImportExpression(node) {
|
|
223
209
|
const source = node.source;
|
|
224
210
|
if (source.type === 'Literal' && typeof source.value === 'string') {
|
|
@@ -229,7 +215,6 @@ exports.noNodejsModules = (0, eslint_devkit_1.createRule)({
|
|
|
229
215
|
}
|
|
230
216
|
},
|
|
231
217
|
TSImportEqualsDeclaration(node) {
|
|
232
|
-
// Handle TypeScript import = require() syntax
|
|
233
218
|
if (node.moduleReference.type === 'TSExternalModuleReference' &&
|
|
234
219
|
node.moduleReference.expression.type === 'Literal' &&
|
|
235
220
|
typeof node.moduleReference.expression.value === 'string') {
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noRelativePackages = void 0;
|
|
9
4
|
const tslib_1 = require("tslib");
|
|
10
5
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
11
6
|
const path = tslib_1.__importStar(require("node:path"));
|
|
12
7
|
const fs = tslib_1.__importStar(require("node:fs"));
|
|
13
|
-
// Cache for package.json lookups
|
|
14
8
|
const packageJsonCache = new Map();
|
|
15
9
|
function findPackageJson(startDir) {
|
|
16
10
|
if (packageJsonCache.has(startDir)) {
|
|
@@ -71,22 +65,17 @@ exports.noRelativePackages = (0, eslint_devkit_1.createRule)({
|
|
|
71
65
|
const importPath = source.value;
|
|
72
66
|
if (typeof importPath !== 'string')
|
|
73
67
|
return;
|
|
74
|
-
// Only check relative imports
|
|
75
68
|
if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
|
|
76
69
|
return;
|
|
77
70
|
}
|
|
78
|
-
// Resolve the import path
|
|
79
71
|
const resolvedPath = path.resolve(currentDir, importPath);
|
|
80
72
|
const importPackageRoot = findPackageJson(path.dirname(resolvedPath));
|
|
81
|
-
// Skip if we're in the same package
|
|
82
73
|
if (allowSamePackage && currentPackageRoot === importPackageRoot) {
|
|
83
74
|
return;
|
|
84
75
|
}
|
|
85
|
-
// Skip if either path doesn't have a package.json
|
|
86
76
|
if (!currentPackageRoot || !importPackageRoot) {
|
|
87
77
|
return;
|
|
88
78
|
}
|
|
89
|
-
// Different packages - report error
|
|
90
79
|
if (currentPackageRoot !== importPackageRoot) {
|
|
91
80
|
try {
|
|
92
81
|
const pkgJsonPath = path.join(importPackageRoot, 'package.json');
|
|
@@ -100,9 +89,6 @@ exports.noRelativePackages = (0, eslint_devkit_1.createRule)({
|
|
|
100
89
|
packageName,
|
|
101
90
|
},
|
|
102
91
|
fix(fixer) {
|
|
103
|
-
// Calculate the subpath within the package
|
|
104
|
-
// subPath is never '' or '.': the package root is found by walking
|
|
105
|
-
// UP from the resolved path's parent, so it is a strict ancestor.
|
|
106
92
|
const subPath = path.relative(importPackageRoot, resolvedPath);
|
|
107
93
|
const newImport = `${packageName}/${subPath.replace(/\.[^/.]+$/, '')}`;
|
|
108
94
|
return fixer.replaceText(source, `'${newImport}'`);
|
|
@@ -110,7 +96,6 @@ exports.noRelativePackages = (0, eslint_devkit_1.createRule)({
|
|
|
110
96
|
});
|
|
111
97
|
}
|
|
112
98
|
catch {
|
|
113
|
-
// If we can't read package.json, just report without fix
|
|
114
99
|
context.report({
|
|
115
100
|
node: source,
|
|
116
101
|
messageId: 'relativePackage',
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noRelativeParentImports = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -72,7 +67,6 @@ exports.noRelativeParentImports = (0, eslint_devkit_1.createRule)({
|
|
|
72
67
|
const [options] = context.options;
|
|
73
68
|
const { commonjs = true, amd = false } = options || {};
|
|
74
69
|
function checkImport(importPath, node) {
|
|
75
|
-
// Check if the import path starts with .. (parent directory)
|
|
76
70
|
if (importPath.startsWith('..')) {
|
|
77
71
|
context.report({
|
|
78
72
|
node,
|
|
@@ -88,7 +82,6 @@ exports.noRelativeParentImports = (0, eslint_devkit_1.createRule)({
|
|
|
88
82
|
}
|
|
89
83
|
},
|
|
90
84
|
CallExpression(node) {
|
|
91
|
-
// Check require() calls if commonjs is enabled
|
|
92
85
|
if (commonjs &&
|
|
93
86
|
node.callee.type === 'Identifier' &&
|
|
94
87
|
node.callee.name === 'require' &&
|
|
@@ -98,12 +91,10 @@ exports.noRelativeParentImports = (0, eslint_devkit_1.createRule)({
|
|
|
98
91
|
checkImport(arg.value, arg);
|
|
99
92
|
}
|
|
100
93
|
}
|
|
101
|
-
// Check AMD define/require calls if amd is enabled
|
|
102
94
|
if (amd &&
|
|
103
95
|
node.callee.type === 'Identifier' &&
|
|
104
96
|
(node.callee.name === 'define' || node.callee.name === 'require') &&
|
|
105
97
|
node.arguments.length >= 1) {
|
|
106
|
-
// AMD dependencies are usually in the first argument (array of strings)
|
|
107
98
|
const depsArg = node.arguments[0];
|
|
108
99
|
if (depsArg.type === 'ArrayExpression') {
|
|
109
100
|
depsArg.elements.forEach((element) => {
|
|
@@ -114,10 +105,8 @@ exports.noRelativeParentImports = (0, eslint_devkit_1.createRule)({
|
|
|
114
105
|
});
|
|
115
106
|
}
|
|
116
107
|
}
|
|
117
|
-
// Note: Dynamic imports (import()) are handled by ImportExpression visitor
|
|
118
108
|
},
|
|
119
109
|
TSImportEqualsDeclaration(node) {
|
|
120
|
-
// Handle TypeScript import = require() syntax
|
|
121
110
|
if (node.moduleReference.type === 'TSExternalModuleReference' &&
|
|
122
111
|
node.moduleReference.expression.type === 'Literal' &&
|
|
123
112
|
typeof node.moduleReference.expression.value === 'string') {
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noRestrictedPaths = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -80,7 +75,6 @@ exports.noRestrictedPaths = (0, eslint_devkit_1.createRule)({
|
|
|
80
75
|
}
|
|
81
76
|
},
|
|
82
77
|
CallExpression(node) {
|
|
83
|
-
// Check require() calls
|
|
84
78
|
if (node.callee.type === 'Identifier' &&
|
|
85
79
|
node.callee.name === 'require' &&
|
|
86
80
|
node.arguments.length === 1) {
|
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noSelfImport = void 0;
|
|
9
4
|
const tslib_1 = require("tslib");
|
|
10
|
-
/**
|
|
11
|
-
* ESLint Rule: no-self-import
|
|
12
|
-
* Forbid a module from importing itself (eslint-plugin-import inspired)
|
|
13
|
-
*/
|
|
14
5
|
const path = tslib_1.__importStar(require("node:path"));
|
|
15
6
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
16
7
|
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
17
8
|
function isImportingSelf(context, node, importPath) {
|
|
18
9
|
const filename = context.filename;
|
|
19
|
-
// If the input is from stdin, this test can't fail
|
|
20
10
|
if (filename === '<text>') {
|
|
21
11
|
return false;
|
|
22
12
|
}
|
|
23
|
-
// Skip test files if allowed
|
|
24
13
|
const [options] = context.options;
|
|
25
14
|
const { allowInTests = false } = options || {};
|
|
26
15
|
if (allowInTests &&
|
|
@@ -30,22 +19,17 @@ function isImportingSelf(context, node, importPath) {
|
|
|
30
19
|
filename.includes('__tests__'))) {
|
|
31
20
|
return false;
|
|
32
21
|
}
|
|
33
|
-
// Resolve the import path
|
|
34
22
|
let resolvedPath;
|
|
35
23
|
if (importPath.startsWith('./') || importPath.startsWith('../')) {
|
|
36
|
-
// Relative import - resolve relative to current file
|
|
37
24
|
const currentDir = path.dirname(filename);
|
|
38
25
|
resolvedPath = path.resolve(currentDir, importPath);
|
|
39
26
|
}
|
|
40
27
|
else if (importPath.startsWith('/')) {
|
|
41
|
-
// Absolute import
|
|
42
28
|
resolvedPath = importPath;
|
|
43
29
|
}
|
|
44
30
|
else {
|
|
45
|
-
// Module import (like 'lodash') - not a self-import
|
|
46
31
|
return false;
|
|
47
32
|
}
|
|
48
|
-
// Compare resolved paths (normalize by removing extensions)
|
|
49
33
|
const normalizedCurrent = filename.replace(/\.[^/.]+$/, '');
|
|
50
34
|
const normalizedImport = resolvedPath.replace(/\.[^/.]+$/, '');
|
|
51
35
|
return normalizedCurrent === normalizedImport;
|
|
@@ -84,7 +68,6 @@ exports.noSelfImport = (0, eslint_devkit_1.createRule)({
|
|
|
84
68
|
},
|
|
85
69
|
defaultOptions: [{ allowInTests: false }],
|
|
86
70
|
create(context) {
|
|
87
|
-
// Visit all module imports and requires
|
|
88
71
|
function visitModule(source, node) {
|
|
89
72
|
const importPath = source.value;
|
|
90
73
|
if (typeof importPath === 'string' &&
|
|
@@ -97,14 +80,12 @@ exports.noSelfImport = (0, eslint_devkit_1.createRule)({
|
|
|
97
80
|
}
|
|
98
81
|
return {
|
|
99
82
|
ImportDeclaration(node) {
|
|
100
|
-
// Allow type imports in TypeScript
|
|
101
83
|
if (node.importKind === 'type') {
|
|
102
84
|
return;
|
|
103
85
|
}
|
|
104
86
|
visitModule(node.source, node);
|
|
105
87
|
},
|
|
106
88
|
CallExpression(node) {
|
|
107
|
-
// Handle require() calls
|
|
108
89
|
if (node.callee.type === 'Identifier' &&
|
|
109
90
|
node.callee.name === 'require' &&
|
|
110
91
|
node.arguments.length === 1) {
|
|
@@ -115,19 +96,16 @@ exports.noSelfImport = (0, eslint_devkit_1.createRule)({
|
|
|
115
96
|
}
|
|
116
97
|
},
|
|
117
98
|
ImportExpression(node) {
|
|
118
|
-
// Handle dynamic imports - only check if source is a literal
|
|
119
99
|
if (node.source.type === 'Literal') {
|
|
120
100
|
visitModule(node.source, node);
|
|
121
101
|
}
|
|
122
102
|
},
|
|
123
103
|
ExportNamedDeclaration(node) {
|
|
124
|
-
// Handle re-exports
|
|
125
104
|
if (node.source) {
|
|
126
105
|
visitModule(node.source, node);
|
|
127
106
|
}
|
|
128
107
|
},
|
|
129
108
|
ExportAllDeclaration(node) {
|
|
130
|
-
// Handle re-exports
|
|
131
109
|
visitModule(node.source, node);
|
|
132
110
|
},
|
|
133
111
|
};
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
-
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
-
* MIT license that can be found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
3
|
exports.noUnassignedImport = void 0;
|
|
9
4
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -79,17 +74,14 @@ exports.noUnassignedImport = (0, eslint_devkit_1.createRule)({
|
|
|
79
74
|
if (shouldAllow(importPath)) {
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
82
|
-
// Check if import has any specifiers
|
|
83
77
|
const hasSpecifiers = node.specifiers && node.specifiers.length > 0;
|
|
84
78
|
if (!hasSpecifiers) {
|
|
85
|
-
// This is a bare import like: import 'module'
|
|
86
79
|
context.report({
|
|
87
80
|
node: node.source,
|
|
88
81
|
messageId: 'unassignedImport',
|
|
89
82
|
});
|
|
90
83
|
}
|
|
91
84
|
},
|
|
92
|
-
// Also check require() calls
|
|
93
85
|
CallExpression(node) {
|
|
94
86
|
if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
95
87
|
node.callee.name === 'require' &&
|
|
@@ -98,18 +90,12 @@ exports.noUnassignedImport = (0, eslint_devkit_1.createRule)({
|
|
|
98
90
|
if (arg.type === 'Literal' && typeof arg.value === 'string') {
|
|
99
91
|
if (!shouldAllow(arg.value)) {
|
|
100
92
|
const parent = node.parent;
|
|
101
|
-
// Only report if the parent is an ExpressionStatement
|
|
102
|
-
// This strictly catches `require('foo');` which is a side-effect import.
|
|
103
|
-
// Any other parent (VariableDecl, Assignment, Call, Conditional, etc.) means it's used.
|
|
104
93
|
if (parent && parent.type === eslint_devkit_1.AST_NODE_TYPES.ExpressionStatement) {
|
|
105
94
|
context.report({
|
|
106
95
|
node: arg,
|
|
107
96
|
messageId: 'unassignedImport',
|
|
108
97
|
});
|
|
109
98
|
}
|
|
110
|
-
// Also check SequenceExpression: (a, require('b')) -> b is returned, a is unassigned.
|
|
111
|
-
// But strictly `no-unassigned-import` might only care about top level.
|
|
112
|
-
// For safety and compatibility, we report if it's in a sequence and NOT the last item.
|
|
113
99
|
else if (parent &&
|
|
114
100
|
parent.type === eslint_devkit_1.AST_NODE_TYPES.SequenceExpression) {
|
|
115
101
|
const expressions = parent.expressions;
|