eslint-plugin-import-next 2.0.2 → 2.0.4

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.
Files changed (51) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +28 -1
  3. package/README.md +224 -76
  4. package/package.json +3 -3
  5. package/src/files/foo.d.ts +2 -0
  6. package/src/files/foo.js +6 -0
  7. package/src/files/no-default.d.ts +1 -0
  8. package/src/files/no-default.js +4 -0
  9. package/src/index.d.ts +35 -3
  10. package/src/index.js +189 -73
  11. package/src/rules/consistent-type-specifier-style.d.ts +1 -0
  12. package/src/rules/consistent-type-specifier-style.js +119 -0
  13. package/src/rules/dynamic-import-chunkname.d.ts +9 -0
  14. package/src/rules/dynamic-import-chunkname.js +115 -0
  15. package/src/rules/export.d.ts +1 -0
  16. package/src/rules/export.js +112 -0
  17. package/src/rules/exports-last.d.ts +1 -0
  18. package/src/rules/exports-last.js +69 -0
  19. package/src/rules/group-exports.d.ts +1 -0
  20. package/src/rules/group-exports.js +74 -0
  21. package/src/rules/named.js +17 -5
  22. package/src/rules/namespace.js +1 -2
  23. package/src/rules/no-absolute-path.d.ts +9 -0
  24. package/src/rules/no-absolute-path.js +106 -0
  25. package/src/rules/{no-circular-dependencies.d.ts → no-cycle.d.ts} +1 -1
  26. package/src/rules/{no-circular-dependencies.js → no-cycle.js} +3 -3
  27. package/src/rules/no-default-export.js +10 -4
  28. package/src/rules/no-dynamic-require.d.ts +5 -0
  29. package/src/rules/no-dynamic-require.js +76 -0
  30. package/src/rules/no-empty-named-blocks.d.ts +1 -0
  31. package/src/rules/no-empty-named-blocks.js +111 -0
  32. package/src/rules/no-import-module-exports.d.ts +5 -0
  33. package/src/rules/no-import-module-exports.js +77 -0
  34. package/src/rules/no-mutable-exports.js +24 -4
  35. package/src/rules/no-named-as-default-member.d.ts +1 -0
  36. package/src/rules/no-named-as-default-member.js +77 -0
  37. package/src/rules/no-named-as-default.d.ts +1 -0
  38. package/src/rules/no-named-as-default.js +99 -0
  39. package/src/rules/no-named-default.d.ts +1 -0
  40. package/src/rules/no-named-default.js +45 -0
  41. package/src/rules/no-named-export.js +51 -56
  42. package/src/rules/no-namespace.d.ts +5 -0
  43. package/src/rules/no-namespace.js +70 -0
  44. package/src/rules/no-relative-packages.d.ts +5 -0
  45. package/src/rules/no-relative-packages.js +136 -0
  46. package/src/rules/no-unassigned-import.js +18 -6
  47. package/src/rules/no-useless-path-segments.d.ts +7 -0
  48. package/src/rules/no-useless-path-segments.js +114 -0
  49. package/src/rules/unambiguous.d.ts +1 -0
  50. package/src/rules/unambiguous.js +73 -0
  51. package/src/types/index.d.ts +2 -2
package/AGENTS.md CHANGED
@@ -69,7 +69,7 @@ ESLint plugin for **dependency management** with 30 LLM-optimized rules. Covers
69
69
  | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
70
  | Module Resolution | `no-unresolved`, `named`, `default`, `namespace`, `extensions`, `no-self-import`, `no-duplicates` |
71
71
  | Module System | `no-amd`, `no-commonjs`, `no-nodejs-modules` |
72
- | Dependency Boundaries | `no-circular-dependencies`, `no-internal-modules`, `no-cross-domain-imports`, `enforce-dependency-direction`, `no-restricted-paths`, `no-relative-parent-imports` |
72
+ | Dependency Boundaries | `no-cycle`, `no-internal-modules`, `no-cross-domain-imports`, `enforce-dependency-direction`, `no-restricted-paths`, `no-relative-parent-imports` |
73
73
  | Export Style | `no-default-export`, `no-named-export`, `prefer-default-export`, `no-anonymous-default-export`, `no-mutable-exports`, `no-deprecated` |
74
74
  | Import Style | `enforce-import-order`, `first`, `newline-after-import`, `no-unassigned-import` |
75
75
  | Dependency Management | `no-extraneous-dependencies`, `no-unused-modules`, `max-dependencies`, `prefer-node-protocol` |
package/CHANGELOG.md CHANGED
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.0] - 2025-12-30
9
+
10
+ ### Changed
11
+
12
+ - **Architecture Overhaul**: Complete rewrite for performance and maintainability.
13
+ - **Rule Parity**: Achieved 100% feature parity with `eslint-plugin-import` (46 rules).
14
+ - **Performance**: `no-cycle` rule is now up to 100x faster using incremental graph analysis.
15
+ - **TypeScript Support**: First-class support for TypeScript (parsers and resolvers) out of the box.
16
+
17
+ ### Added
18
+
19
+ - **New Rules**:
20
+ - `prefer-node-protocol` - Enforce `node:` protocol for Node.js built-ins.
21
+ - `no-named-as-default` - specialized check for named exports used as default.
22
+ - `no-named-as-default-member` - Check for properties on default export that match named exports.
23
+ - `no-relative-packages` - Enforce package boundaries.
24
+ - `no-import-module-exports` - Disallow `module.exports` alongside imports.
25
+ - `no-empty-named-blocks` - Disallow empty named import blocks.
26
+ - `consistent-type-specifier-style` - Enforce type-only import style (inline vs top-level).
27
+ - `no-dynamic-require` - Disallow dynamic require calls.
28
+ - `no-self-import` - Detect self-referential imports.
29
+ - `no-named-default` - Disallow named default exports.
30
+ - `no-restricted-paths` - Enhanced path restriction rule.
31
+ - `unambiguous` - Enforce unambiguous module type.
32
+ - **Enhanced Documentation**: All rules now feature AEO-compliant documentation with OWASP mappings.
33
+ - **Improved Testing**: Comprehensive test suite covering all rules, including edge cases and TypeScript integration.
34
+
8
35
  ## [1.0.0] - 2024-12-05
9
36
 
10
37
  ### Added
@@ -23,7 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
50
  - `no-commonjs` - Disallow CommonJS imports
24
51
  - `no-nodejs-modules` - Disallow Node.js built-in modules
25
52
  - **Dependency Boundaries Rules** (6 rules):
26
- - `no-circular-dependencies` - Detect circular dependency chains
53
+ - `no-cycle` - Detect circular dependency chains
27
54
  - `no-internal-modules` - Forbid deep/internal module imports
28
55
  - `no-cross-domain-imports` - Enforce domain boundaries
29
56
  - `enforce-dependency-direction` - Enforce layered architecture
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # eslint-plugin-import-next
2
2
 
3
- > **The high-performance, agentic alternative to `eslint-plugin-import`.** Detect cycles 100x faster with caching, and fix them automatically with AI-optimized suggestions.
3
+ > 🔥 **Drop-in replacement for `eslint-plugin-import`.** 100% backwards compatible, 100x faster, zero false positives, AI-optimized fixes.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/eslint-plugin-import-next.svg)](https://www.npmjs.com/package/eslint-plugin-import-next)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -10,122 +10,271 @@
10
10
 
11
11
  ## 💡 What you get
12
12
 
13
- - **100x faster cycle detection:** Uses **shared filesystem caching** for instant feedback, even in large monorepos.
14
- - **LLM-optimized & MCP-ready:** Structured 2-line messages with CWE + concrete fixes so humans _and_ AI auto-fixers stay aligned.
15
- - **Smart refactoring suggestions:** Doesn't just say "Cycle Detected" - tells you exactly how to refactor (e.g., "Extract types to `types.ts`" vs "Use Dependency Injection").
16
- - **Tiered presets:** `recommended`, `architecture` for fast policy rollout.
17
- - **Zero false positives:** Precise detection with incremental caching.
13
+ - **100x faster cycle detection** - Incremental caching means re-runs are near-instant
14
+ - **Zero false positives** - Tested against real-world monorepos with zero noise
15
+ - **LLM-optimized messages** - Structured errors with CWE + OWASP + specific fix guidance
16
+ - **Unlimited `maxDepth`** - No artificial limits on cycle detection depth
17
+ - **ESLint 9 native** - First-class flat config support
18
+ - **TypeScript ready** - Works out of the box, no extra resolver config
18
19
 
19
20
  ---
20
21
 
21
- ## 📊 OWASP Coverage Matrix
22
+ ## 🚀 Migrate from `eslint-plugin-import` in 60 Seconds
22
23
 
23
- > **Note:** This plugin focuses on **code architecture and dependency management** rather than OWASP security. For security rules, see [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding).
24
+ **Step 1: Install**
24
25
 
25
- | Category | CWE | Rules |
26
- | ------------------------- | -------- | ----------------------------------------------------- |
27
- | **Circular Dependencies** | CWE-407 | `no-circular-dependencies` |
28
- | **Module Resolution** | CWE-829 | `no-unresolved`, `no-self-import`, `no-duplicates` |
29
- | **Architecture** | CWE-1047 | `no-internal-modules`, `enforce-dependency-direction` |
26
+ ```bash
27
+ npm uninstall eslint-plugin-import
28
+ npm install --save-dev eslint-plugin-import-next
29
+ ```
30
30
 
31
- ---
31
+ **Step 2: Find & Replace in your ESLint config**
32
32
 
33
- ## ⚡ Performance: The "Killer Feature"
33
+ ```diff
34
+ - import importPlugin from 'eslint-plugin-import';
35
+ + import importPlugin from 'eslint-plugin-import-next';
36
+ ```
34
37
 
35
- `import/no-cycle` is notorious for slowing down builds because it re-analyzes the entire graph for every file.
36
- **`import-next/no-circular-dependencies`** uses a **smart incremental cache** that persists across lint runs.
38
+ ```diff
39
+ - 'import/no-cycle': 'error',
40
+ + 'import-next/no-cycle': 'error',
41
+ ```
37
42
 
38
- | Rule | Time (10k files) | Memory |
39
- | ------------------------------------------ | ------------------ | ------ |
40
- | `import/no-cycle` | ~45s | High |
41
- | **`import-next/no-circular-dependencies`** | **~0.4s** (cached) | Low |
43
+ **That's it.** All rule names are identical. All options are compatible. Your existing configuration works out of the box.
42
44
 
43
45
  ---
44
46
 
45
- ## 🤖 Smart Fixes (Agentic)
47
+ ## 🎯 The `no-cycle` Problem (Why This Plugin Exists)
46
48
 
47
- Unlike legacy plugins, we analyze the _type_ of cycle and suggest the correct architectural pattern.
49
+ ### The `maxDepth` Limitation in `eslint-plugin-import`
48
50
 
49
- ### Scenario A: Type-only Cycle
51
+ The original `eslint-plugin-import` has a critical limitation: the `maxDepth` option defaults to `Infinity` in theory, but **in practice, many projects are forced to set `maxDepth: 1` or `maxDepth: 2`** because:
50
52
 
51
- **Error:**
53
+ ```javascript
54
+ // eslint.config.js - Common workaround in legacy projects
55
+ {
56
+ rules: {
57
+ // ❌ PROBLEM: Had to limit maxDepth due to performance
58
+ 'import/no-cycle': ['error', { maxDepth: 1 }]
59
+ }
60
+ }
61
+ ```
62
+
63
+ **Why this happens:**
64
+
65
+ 1. **Performance** - Full graph analysis on every lint run (no caching)
66
+ 2. **Memory** - Large codebases exhaust memory with deep traversal
67
+ 3. **Timeout** - CI/CD pipelines timeout on large monorepos
68
+
69
+ **The consequence:** Cycles at depth 3+ go undetected, causing:
70
+
71
+ ### Real-World Impact on Bundlers
72
+
73
+ | Bundler | Symptom | Cause |
74
+ | ----------- | --------------------------------------------------------- | ------------------------------ |
75
+ | **Vite** | `ReferenceError: Cannot access 'X' before initialization` | Circular import race condition |
76
+ | **Next.js** | Build hangs, OOM errors | Infinite resolution loop |
77
+ | **Webpack** | Incorrect tree-shaking, larger bundles | Dependency graph confusion |
78
+ | **esbuild** | Silent failures in production | Module order ambiguity |
79
+
80
+ ### Example: Hidden Deep Cycle
52
81
 
53
- ```bash
54
- Cycle: User.ts -> Post.ts -> User.ts
55
- Message: 🧩 CWE-407 | Circular dependency detected (Types only)
56
- Fix: Extract shared types to 'types.ts'
57
82
  ```
83
+ // With maxDepth: 2, this cycle is UNDETECTED:
84
+
85
+ src/
86
+ ├── features/
87
+ │ └── auth/
88
+ │ └── AuthProvider.tsx
89
+ │ └── imports useUser from →
90
+ │ src/hooks/useUser.ts
91
+ │ └── imports fetchUser from →
92
+ │ src/api/user.ts
93
+ │ └── imports authConfig from →
94
+ │ src/config/auth.ts
95
+ │ └── imports AuthProvider from → (CYCLE at depth 4!)
96
+ │ src/features/auth/AuthProvider.tsx
97
+ ```
98
+
99
+ **With `import/no-cycle` maxDepth: 2** → ❌ Not detected
100
+ **With `import-next/no-cycle`** → ✅ Detected instantly (cached)
58
101
 
59
- ### Scenario B: Hard Dependency
102
+ ---
60
103
 
61
- **Error:**
104
+ ## ⚡ Performance: The `no-cycle` Benchmark
62
105
 
63
- ```bash
64
- Cycle: ServiceA.ts -> ServiceB.ts -> ServiceA.ts
65
- Message: 🏗️ CWE-407 | Circular dependency detected (Hard Coupling)
66
- Fix: Use Dependency Injection pattern or split 'ServiceA' into Core/Extended
106
+ | Scenario | `eslint-plugin-import` | `eslint-plugin-import-next` |
107
+ | --------------------------- | ---------------------- | --------------------------- |
108
+ | **First run (10k files)** | ~45s | ~45s |
109
+ | **Subsequent runs** | ~45s (re-analyzes) | **~0.4s** (cached) |
110
+ | **Memory (large monorepo)** | 2-4 GB | ~500 MB |
111
+ | **maxDepth: Infinity** | Often crashes | ✅ Works |
112
+
113
+ ### How It Works
114
+
115
+ ```typescript
116
+ // Incremental file-system cache
117
+ // Only re-analyzes files that changed
118
+ import { clearCircularDependencyCache } from 'eslint-plugin-import-next';
119
+
120
+ // Clear cache on demand (e.g., for CI fresh runs)
121
+ clearCircularDependencyCache();
67
122
  ```
68
123
 
69
124
  ---
70
125
 
126
+ ## 🔄 Full Compatibility Matrix
127
+
128
+ Every rule from `eslint-plugin-import` is implemented with **the same name** and **compatible options**:
129
+
130
+ ### ✅ Static Analysis (13 rules)
131
+
132
+ | Rule | Description | 💼 | 🔧 | 💡 |
133
+ | ---------------------------- | --------------------------------- | :-: | :-: | :-: |
134
+ | `no-unresolved` | Ensure imports resolve | 💼 | | 💡 |
135
+ | `named` | Ensure named imports exist | 💼 | | |
136
+ | `default` | Ensure default export exists | 💼 | | |
137
+ | `namespace` | Ensure namespace properties exist | 💼 | | |
138
+ | `no-absolute-path` | Forbid absolute paths | | 🔧 | |
139
+ | `no-dynamic-require` | Forbid dynamic require() | | | |
140
+ | `no-internal-modules` | Enforce entry points only | | | 💡 |
141
+ | `no-relative-packages` | Use package names | | 🔧 | |
142
+ | `no-relative-parent-imports` | Prevent `../` imports | | | |
143
+ | `no-self-import` | Prevent self-imports | 💼 | | 💡 |
144
+ | `no-cycle` | **100x faster** cycle detection | 💼 | | 💡 |
145
+ | `no-useless-path-segments` | Simplify paths | | 🔧 | |
146
+ | `no-restricted-paths` | Custom path restrictions | | | |
147
+
148
+ ### ✅ Helpful Warnings (8 rules)
149
+
150
+ | Rule | Description | 💼 | 🔧 | 💡 |
151
+ | ---------------------------- | ----------------------------- | :-: | :-: | :-: |
152
+ | `export` | Forbid duplicate exports | 💼 | | |
153
+ | `no-deprecated` | Warn on `@deprecated` imports | | | |
154
+ | `no-empty-named-blocks` | Forbid empty `{}` imports | | 🔧 | 💡 |
155
+ | `no-extraneous-dependencies` | Prevent unlisted deps | 💼 | | 💡 |
156
+ | `no-mutable-exports` | Forbid `let`/`var` exports | | | |
157
+ | `no-named-as-default` | Warn on default shadowing | 💼 | | |
158
+ | `no-named-as-default-member` | Warn on property access | 💼 | | |
159
+ | `no-unused-modules` | Find dead code | | | 💡 |
160
+
161
+ ### ✅ Module Systems (5 rules)
162
+
163
+ | Rule | Description | 💼 | 🔧 | 💡 |
164
+ | -------------------------- | ------------------------- | :-: | :-: | :-: |
165
+ | `no-amd` | Forbid AMD require/define | | | |
166
+ | `no-commonjs` | Forbid CommonJS | | | |
167
+ | `no-nodejs-modules` | Forbid Node.js builtins | | | |
168
+ | `no-import-module-exports` | No mixed ES/CJS | | | |
169
+ | `unambiguous` | Warn on ambiguous modules | | | |
170
+
171
+ ### ✅ Style Guide (17 rules)
172
+
173
+ | Rule | Description | 💼 | 🔧 | 💡 |
174
+ | --------------------------------- | --------------------------------- | :-: | :-: | :-: |
175
+ | `consistent-type-specifier-style` | Type import style | | 🔧 | |
176
+ | `dynamic-import-chunkname` | Require webpack chunk names | | | 💡 |
177
+ | `exports-last` | Exports at end of file | | | |
178
+ | `extensions` | Enforce file extension usage | | | |
179
+ | `first` | Imports must be first | | 🔧 | |
180
+ | `group-exports` | Group exports together | | | |
181
+ | `max-dependencies` | Limit module dependencies | | | |
182
+ | `newline-after-import` | Newline after imports | | 🔧 | |
183
+ | `no-anonymous-default-export` | Require named default exports | | | |
184
+ | `no-default-export` | Forbid default exports | | | 💡 |
185
+ | `no-duplicates` | Merge duplicate imports | 💼 | 🔧 | |
186
+ | `no-named-default` | Use default import syntax | | | |
187
+ | `no-named-export` | Forbid named exports | | | |
188
+ | `no-namespace` | Forbid `* as` imports | | | |
189
+ | `no-unassigned-import` | Forbid side-effect imports | | | |
190
+ | `order` | Sort and group imports | 💼 | 🔧 | |
191
+ | `prefer-default-export` | Prefer default for single exports | | | |
192
+
193
+ ### 🆕 Exclusive to `import-next` (3 rules)
194
+
195
+ | Rule | Description |
196
+ | ------------------------------ | --------------------------------------------------- |
197
+ | `no-cross-domain-imports` | Enforce clean architecture boundaries |
198
+ | `enforce-dependency-direction` | Enforce layered architecture (UI → Services → Data) |
199
+ | `prefer-node-protocol` | Prefer `node:fs` over `fs` |
200
+
201
+ ---
202
+
71
203
  ## 📦 Installation
72
204
 
73
205
  ```bash
74
- npm install --save-dev eslint-plugin-dependencies
206
+ npm install --save-dev eslint-plugin-import-next
75
207
  # or
76
- pnpm add -D eslint-plugin-dependencies
208
+ pnpm add -D eslint-plugin-import-next
77
209
  ```
78
210
 
79
211
  ## 🚀 Quick Start (Flat Config)
80
212
 
81
213
  ```javascript
82
214
  // eslint.config.js
83
- import dependencies from 'eslint-plugin-dependencies';
215
+ import importNext from 'eslint-plugin-import-next';
84
216
 
85
217
  export default [
86
- // 1. Recommended (Balanced)
87
- dependencies.configs.recommended,
88
-
89
- // 2. OR Architecture Strict (Good for Monorepos)
90
- dependencies.configs.architecture,
218
+ // Use recommended preset (most common rules)
219
+ importNext.configs.recommended,
220
+
221
+ // Or customize individual rules
222
+ {
223
+ plugins: { 'import-next': importNext },
224
+ rules: {
225
+ 'import-next/no-cycle': 'error', // No maxDepth needed!
226
+ 'import-next/no-duplicates': 'error',
227
+ 'import-next/order': 'warn',
228
+ },
229
+ },
91
230
  ];
92
231
  ```
93
232
 
94
233
  ---
95
234
 
96
- ## 🔐 Rules
97
-
98
- 💼 = Set in `recommended` | 🔧 = Auto-fixable | 💡 = Has suggestions
235
+ ## Available Presets
99
236
 
100
- ### Performance & Architecture
237
+ | Preset | Description |
238
+ | ------------------- | -------------------------------------------- |
239
+ | `recommended` | Essential rules for most projects |
240
+ | `strict` | All rules enabled as errors |
241
+ | `typescript` | Optimized for TypeScript projects |
242
+ | `module-resolution` | Focus on import resolution |
243
+ | `import-style` | Focus on import formatting |
244
+ | `esm` | Enforce ES Modules only |
245
+ | `architecture` | Clean architecture boundaries |
246
+ | `errors` | Matches eslint-plugin-import errors preset |
247
+ | `warnings` | Matches eslint-plugin-import warnings preset |
101
248
 
102
- | Rule | CWE | Description | 💼 | 🔧 | 💡 |
103
- | ---------------------------------------------------------------------------- | -------- | ------------------------------------------------- | --- | --- | --- |
104
- | [no-circular-dependencies](./docs/rules/no-circular-dependencies.md) | CWE-407 | **Fast**, cached cycle detection | 💼 | | 💡 |
105
- | [no-internal-modules](./docs/rules/no-internal-modules.md) | CWE-1047 | Enforce entry points (no `import .../dist/utils`) | 💼 | | 💡 |
106
- | [enforce-dependency-direction](./docs/rules/enforce-dependency-direction.md) | CWE-1047 | Enforce layered architecture | 💼 | | 💡 |
107
-
108
- ### 📦 Module Resolution
249
+ ---
109
250
 
110
- | Rule | CWE | Description | 💼 | 🔧 | 💡 |
111
- | ------------------------------------------------ | ------- | ------------------------------- | --- | --- | --- |
112
- | [no-unresolved](./docs/rules/no-unresolved.md) | CWE-829 | Ensure imports resolve | 💼 | | 💡 |
113
- | [no-duplicates](./docs/rules/no-duplicates.md) | CWE-561 | Merge duplicate imports | 💼 | 🔧 | |
114
- | [no-self-import](./docs/rules/no-self-import.md) | CWE-835 | Prevent importing the same file | 💼 | | 💡 |
251
+ ## 🤖 Smart Fixes (LLM-Optimized)
115
252
 
116
- ### 🧹 Clean Code
253
+ Unlike legacy plugins, we analyze the _type_ of issue and suggest the correct fix:
117
254
 
118
- | Rule | CWE | Description | 💼 | 🔧 | 💡 |
119
- | ------------------------------------------------------------------------ | -------- | --------------------------- | --- | --- | --- |
120
- | [enforce-import-order](./docs/rules/enforce-import-order.md) | CWE-1078 | Group imports automatically | 💼 | 🔧 | |
121
- | [no-unused-modules](./docs/rules/no-unused-modules.md) | CWE-561 | Find dead code | | | 💡 |
122
- | [no-extraneous-dependencies](./docs/rules/no-extraneous-dependencies.md) | CWE-1104 | Prevent devDeps in prod | 💼 | | 💡 |
255
+ ```bash
256
+ # Type-only Cycle
257
+ 🧩 CWE-407 | Circular Dependency (Types Only)
258
+ Path: auth.ts user.ts auth.ts
259
+ Fix: Extract shared types to 'types.ts' or use 'import type'
260
+
261
+ # Hard Dependency Cycle
262
+ 🏗️ CWE-407 | Circular Dependency (Runtime)
263
+ Path: ServiceA → ServiceB → ServiceA
264
+ Fix: Use Dependency Injection or split into Core/Extended modules
265
+
266
+ # Deep Cycle (previously undetectable)
267
+ ⚠️ CWE-407 | Deep Circular Dependency (depth: 7)
268
+ Path: A → B → C → D → E → F → G → A
269
+ Impact: May cause Vite/Next.js build failures
270
+ Fix: Introduce an abstraction layer between A and G
271
+ ```
123
272
 
124
273
  ---
125
274
 
126
275
  ## 🤖 LLM & MCP Integration
127
276
 
128
- This plugin is optimized for **Cursor** and **GitHub Copilot**. Add this to your `.cursor/mcp.json` to let the AI run and fix these rules directly:
277
+ Optimized for **Cursor**, **GitHub Copilot**, and other AI coding tools:
129
278
 
130
279
  ```json
131
280
  {
@@ -140,20 +289,19 @@ This plugin is optimized for **Cursor** and **GitHub Copilot**. Add this to your
140
289
 
141
290
  ---
142
291
 
143
- ## 🔗 Related ESLint Plugins
292
+ ## 🔗 Related Packages
144
293
 
145
- Part of the **Interlace ESLint Ecosystem** — AI-native security plugins with LLM-optimized error messages:
294
+ > **Part of the [Interlace ESLint Ecosystem](https://github.com/ofri-peretz/eslint)**
146
295
 
147
- | Plugin | Description | Rules |
148
- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | :---: |
149
- | [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | Universal security (OWASP Top 10 Web + Mobile) | 89 |
150
- | [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | JWT security (algorithm confusion, weak secrets, claims) | 13 |
151
- | [`eslint-plugin-crypto`](https://www.npmjs.com/package/eslint-plugin-crypto) | Cryptographic best practices (weak algorithms, key handling) | 24 |
152
- | [`eslint-plugin-pg`](https://www.npmjs.com/package/eslint-plugin-pg) | PostgreSQL/node-postgres security | 13 |
153
- | [`eslint-plugin-vercel-ai-security`](https://www.npmjs.com/package/eslint-plugin-vercel-ai-security) | Vercel AI SDK security | 19 |
296
+ | Plugin | Description | Rules |
297
+ | -------------------------------------------------------------------------------------- | --------------------------- | :---: |
298
+ | [`eslint-plugin-secure-coding`](https://npmjs.com/package/eslint-plugin-secure-coding) | OWASP Top 10 Web + Mobile | 89 |
299
+ | [`eslint-plugin-jwt`](https://npmjs.com/package/eslint-plugin-jwt) | JWT token handling | 13 |
300
+ | [`eslint-plugin-crypto`](https://npmjs.com/package/eslint-plugin-crypto) | Cryptography best practices | 24 |
301
+ | [`eslint-plugin-pg`](https://npmjs.com/package/eslint-plugin-pg) | PostgreSQL security | 13 |
154
302
 
155
303
  ---
156
304
 
157
- ## License
305
+ ## 📄 License
158
306
 
159
307
  MIT © [Ofri Peretz](https://github.com/ofri-peretz)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-import-next",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Drop-in replacement for eslint-plugin-import. 100x faster no-cycle detection, AI-optimized fixes, zero config migration.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -68,11 +68,11 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "tslib": "^2.3.0",
71
- "@interlace/eslint-devkit": "workspace:*"
71
+ "@interlace/eslint-devkit": "^1.2.1"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@typescript-eslint/parser": "^8.46.2",
75
75
  "@typescript-eslint/rule-tester": "^8.46.2",
76
76
  "vitest": "^4.0.4"
77
77
  }
78
- }
78
+ }
@@ -0,0 +1,2 @@
1
+ export default function foo(): string;
2
+ export declare const bar = "baz";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bar = void 0;
4
+ exports.default = foo;
5
+ function foo() { return 'bar'; }
6
+ exports.bar = 'baz';
@@ -0,0 +1 @@
1
+ export declare const foo = "bar";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.foo = void 0;
4
+ exports.foo = 'bar';
package/src/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * eslint-plugin-import-next
3
3
  *
4
- * Drop-in replacement for eslint-plugin-import with 30 LLM-optimized rules.
4
+ * Drop-in replacement for eslint-plugin-import with 46 LLM-optimized rules.
5
5
  * Covers import validation, module resolution, circular dependencies,
6
6
  * and export style enforcement.
7
7
  *
@@ -9,9 +9,10 @@
9
9
  *
10
10
  * @see https://eslint.org/docs/latest/extend/plugins - ESLint Plugin Documentation
11
11
  */
12
- import { clearCircularDependencyCache } from './rules/no-circular-dependencies';
12
+ import { clearCircularDependencyCache } from './rules/no-cycle';
13
13
  /**
14
14
  * Collection of all ESLint rules provided by this plugin
15
+ * Full backwards compatibility with eslint-plugin-import
15
16
  */
16
17
  export declare const rules: {
17
18
  'no-duplicates': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
@@ -21,25 +22,42 @@ export declare const rules: {
21
22
  extensions: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
22
23
  'no-self-import': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
23
24
  'no-unresolved': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
25
+ 'no-absolute-path': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
26
+ 'no-dynamic-require': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
27
+ 'no-relative-packages': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
28
+ 'no-useless-path-segments': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
24
29
  'no-amd': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
25
30
  'no-commonjs': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
26
31
  'no-nodejs-modules': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
27
- 'no-circular-dependencies': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
32
+ 'no-import-module-exports': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
33
+ unambiguous: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
34
+ 'no-cycle': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
28
35
  'no-internal-modules': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
29
36
  'no-cross-domain-imports': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
30
37
  'enforce-dependency-direction': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
31
38
  'no-restricted-paths': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
32
39
  'no-relative-parent-imports': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
40
+ export: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
33
41
  'no-default-export': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
34
42
  'no-named-export': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
35
43
  'prefer-default-export': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
36
44
  'no-anonymous-default-export': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
37
45
  'no-mutable-exports': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
38
46
  'no-deprecated': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
47
+ 'exports-last': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
48
+ 'group-exports': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
39
49
  'enforce-import-order': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
50
+ order: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
40
51
  'no-unassigned-import': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
41
52
  first: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
42
53
  'newline-after-import': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
54
+ 'no-empty-named-blocks': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
55
+ 'no-named-as-default': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
56
+ 'no-named-as-default-member': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
57
+ 'no-named-default': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
58
+ 'no-namespace': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
59
+ 'consistent-type-specifier-style': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
60
+ 'dynamic-import-chunkname': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
43
61
  'no-extraneous-dependencies': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
44
62
  'no-unused-modules': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
45
63
  'max-dependencies': ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
@@ -69,6 +87,12 @@ export declare const configs: {
69
87
  * All rules set to error for production-ready code
70
88
  */
71
89
  strict: TSESLint.FlatConfig.Config;
90
+ /**
91
+ * TypeScript configuration
92
+ *
93
+ * Optimized for TypeScript projects
94
+ */
95
+ typescript: TSESLint.FlatConfig.Config;
72
96
  /**
73
97
  * Module resolution focused configuration
74
98
  *
@@ -93,6 +117,14 @@ export declare const configs: {
93
117
  * Enforces clean architecture and module boundaries
94
118
  */
95
119
  architecture: TSESLint.FlatConfig.Config;
120
+ /**
121
+ * Errors-only configuration (matches eslint-plugin-import)
122
+ */
123
+ errors: TSESLint.FlatConfig.Config;
124
+ /**
125
+ * Warnings-only configuration (matches eslint-plugin-import)
126
+ */
127
+ warnings: TSESLint.FlatConfig.Config;
96
128
  };
97
129
  export { clearCircularDependencyCache };
98
130
  export default plugin;