eslint-plugin-import-next 2.4.0 → 2.5.0
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 +1 -1
- package/src/index.js +1 -1
- package/src/rules/no-cycle.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-import-next",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "ESLint plugin for imports and module boundaries — drop-in replacement for eslint-plugin-import, 3.1x faster end-to-end, zero-config migration.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.clearCircularDependencyCache=exports.configs=exports.plugin=exports.rules=void 0;const no_cycle_1=require("./rules/no-cycle");Object.defineProperty(exports,"clearCircularDependencyCache",{enumerable:true,get:function(){return no_cycle_1.clearCircularDependencyCache}});exports.rules={get"no-duplicates"(){return require("./rules/no-duplicates").noDuplicates},get named(){return require("./rules/named").named},get default(){return require("./rules/default").defaultRule},get namespace(){return require("./rules/namespace").namespace},get extensions(){return require("./rules/extensions").extensions},get"no-self-import"(){return require("./rules/no-self-import").noSelfImport},get"no-unresolved"(){return require("./rules/no-unresolved").noUnresolved},get"no-absolute-path"(){return require("./rules/no-absolute-path").noAbsolutePath},get"no-dynamic-require"(){return require("./rules/no-dynamic-require").noDynamicRequire},get"no-relative-packages"(){return require("./rules/no-relative-packages").noRelativePackages},get"no-useless-path-segments"(){return require("./rules/no-useless-path-segments").noUselessPathSegments},get"no-amd"(){return require("./rules/no-amd").noAmd},get"no-commonjs"(){return require("./rules/no-commonjs").noCommonjs},get"no-nodejs-modules"(){return require("./rules/no-nodejs-modules").noNodejsModules},get"no-import-module-exports"(){return require("./rules/no-import-module-exports").noImportModuleExports},get unambiguous(){return require("./rules/unambiguous").unambiguous},get"no-cycle"(){return require("./rules/no-cycle").noCycle},get"no-internal-modules"(){return require("./rules/no-internal-modules").noInternalModules},get"no-cross-domain-imports"(){return require("./rules/no-cross-domain-imports").noCrossDomainImports},get"enforce-dependency-direction"(){return require("./rules/enforce-dependency-direction").enforceDependencyDirection},get"no-restricted-paths"(){return require("./rules/no-restricted-paths").noRestrictedPaths},get"no-relative-parent-imports"(){return require("./rules/no-relative-parent-imports").noRelativeParentImports},get export(){return require("./rules/export").exportRule},get"no-default-export"(){return require("./rules/no-default-export").noDefaultExport},get"no-named-export"(){return require("./rules/no-named-export").noNamedExport},get"prefer-default-export"(){return require("./rules/prefer-default-export").preferDefaultExport},get"no-anonymous-default-export"(){return require("./rules/no-anonymous-default-export").noAnonymousDefaultExport},get"no-mutable-exports"(){return require("./rules/no-mutable-exports").noMutableExports},get"no-deprecated"(){return require("./rules/no-deprecated").noDeprecated},get"exports-last"(){return require("./rules/exports-last").exportsLast},get"group-exports"(){return require("./rules/group-exports").groupExports},get"enforce-import-order"(){return require("./rules/enforce-import-order").enforceImportOrder},get order(){return require("./rules/enforce-import-order").enforceImportOrder},get"no-unassigned-import"(){return require("./rules/no-unassigned-import").noUnassignedImport},get first(){return require("./rules/first").first},get"newline-after-import"(){return require("./rules/newline-after-import").newlineAfterImport},get"no-empty-named-blocks"(){return require("./rules/no-empty-named-blocks").noEmptyNamedBlocks},get"no-named-as-default"(){return require("./rules/no-named-as-default").noNamedAsDefault},get"no-named-as-default-member"(){return require("./rules/no-named-as-default-member").noNamedAsDefaultMember},get"no-named-default"(){return require("./rules/no-named-default").noNamedDefault},get"no-namespace"(){return require("./rules/no-namespace").noNamespace},get"consistent-type-specifier-style"(){return require("./rules/consistent-type-specifier-style").consistentTypeSpecifierStyle},get"dynamic-import-chunkname"(){return require("./rules/dynamic-import-chunkname").dynamicImportChunkname},get"no-extraneous-dependencies"(){return require("./rules/no-extraneous-dependencies").noExtraneousDependencies},get"no-unused-modules"(){return require("./rules/no-unused-modules").noUnusedModules},get"max-dependencies"(){return require("./rules/max-dependencies").maxDependencies},get"prefer-node-protocol"(){return require("./rules/prefer-node-protocol").preferNodeProtocol},get"no-barrel-file"(){return require("./rules/no-barrel-file").noBarrelFile},get"no-barrel-import"(){return require("./rules/no-barrel-import").noBarrelImport},get"prefer-tree-shakeable-imports"(){return require("./rules/prefer-tree-shakeable-imports").preferTreeShakeableImports},get"prefer-direct-import"(){return require("./rules/prefer-direct-import").preferDirectImport},get"no-full-package-import"(){return require("./rules/no-full-package-import").noFullPackageImport},get"enforce-team-boundaries"(){return require("./rules/enforce-team-boundaries").enforceTeamBoundaries},get"no-legacy-imports"(){return require("./rules/no-legacy-imports").noLegacyImports},get"require-import-approval"(){return require("./rules/require-import-approval").requireImportApproval},get"prefer-modern-api"(){return require("./rules/prefer-modern-api").preferModernApi}};exports.plugin={meta:{name:"eslint-plugin-import-next",version:"2.4.0"},rules:exports.rules};exports.configs={flagship:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-cycle":"error"}},recommended:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"warn","import-next/no-duplicates":"error","import-next/export":"error","import-next/no-cycle":"error","import-next/no-self-import":"error","import-next/no-named-as-default":"warn","import-next/no-named-as-default-member":"warn","import-next/no-amd":"warn","import-next/no-empty-named-blocks":"warn","import-next/no-extraneous-dependencies":"warn"}},strict:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"error","import-next/extensions":"error","import-next/no-self-import":"error","import-next/no-duplicates":"error","import-next/no-absolute-path":"error","import-next/no-dynamic-require":"error","import-next/no-useless-path-segments":"error","import-next/export":"error","import-next/no-amd":"error","import-next/no-commonjs":"error","import-next/no-nodejs-modules":"error","import-next/no-import-module-exports":"error","import-next/unambiguous":"error","import-next/no-cycle":"error","import-next/no-internal-modules":"error","import-next/no-cross-domain-imports":"error","import-next/enforce-dependency-direction":"error","import-next/no-restricted-paths":"error","import-next/no-relative-parent-imports":"error","import-next/no-relative-packages":"error","import-next/no-anonymous-default-export":"error","import-next/no-mutable-exports":"error","import-next/no-deprecated":"error","import-next/exports-last":"error","import-next/group-exports":"error","import-next/order":"error","import-next/no-unassigned-import":"error","import-next/first":"error","import-next/newline-after-import":"error","import-next/no-empty-named-blocks":"error","import-next/no-named-as-default":"error","import-next/no-named-as-default-member":"error","import-next/no-named-default":"error","import-next/no-namespace":"error","import-next/consistent-type-specifier-style":"error","import-next/no-extraneous-dependencies":"error","import-next/no-unused-modules":"error","import-next/max-dependencies":"error","import-next/prefer-node-protocol":"error"}},typescript:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"off","import-next/default":"error","import-next/namespace":"error","import-next/export":"error","import-next/no-cycle":"error","import-next/no-duplicates":"error","import-next/order":"warn","import-next/first":"warn","import-next/newline-after-import":"warn","import-next/consistent-type-specifier-style":["warn","prefer-inline"]}},"module-resolution":{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"error","import-next/extensions":"warn","import-next/no-self-import":"error","import-next/no-duplicates":"error","import-next/no-absolute-path":"error","import-next/no-useless-path-segments":"warn"}},"import-style":{plugins:{"import-next":exports.plugin},rules:{"import-next/order":"error","import-next/first":"error","import-next/newline-after-import":"error","import-next/no-duplicates":"error","import-next/no-unassigned-import":"warn","import-next/no-empty-named-blocks":"error","import-next/no-namespace":"warn"}},esm:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-amd":"error","import-next/no-commonjs":"error","import-next/no-import-module-exports":"error","import-next/unambiguous":"error","import-next/prefer-node-protocol":"error"}},architecture:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-cycle":"error","import-next/no-internal-modules":"error","import-next/no-cross-domain-imports":"error","import-next/enforce-dependency-direction":"error","import-next/no-restricted-paths":"error","import-next/no-relative-parent-imports":"warn","import-next/no-relative-packages":"error"}},errors:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"error","import-next/export":"error"}},warnings:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-named-as-default":"warn","import-next/no-named-as-default-member":"warn","import-next/no-duplicates":"warn"}},performance:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-barrel-file":"error","import-next/no-barrel-import":"warn","import-next/prefer-tree-shakeable-imports":"warn","import-next/prefer-direct-import":"warn","import-next/no-full-package-import":"warn","import-next/no-cycle":"error"}},enterprise:{plugins:{"import-next":exports.plugin},rules:{"import-next/enforce-team-boundaries":"off","import-next/no-legacy-imports":"off","import-next/no-cross-domain-imports":"warn","import-next/enforce-dependency-direction":"warn","import-next/no-internal-modules":"warn"}}};exports.default=exports.plugin;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.clearCircularDependencyCache=exports.configs=exports.plugin=exports.rules=void 0;const no_cycle_1=require("./rules/no-cycle");Object.defineProperty(exports,"clearCircularDependencyCache",{enumerable:true,get:function(){return no_cycle_1.clearCircularDependencyCache}});exports.rules={get"no-duplicates"(){return require("./rules/no-duplicates").noDuplicates},get named(){return require("./rules/named").named},get default(){return require("./rules/default").defaultRule},get namespace(){return require("./rules/namespace").namespace},get extensions(){return require("./rules/extensions").extensions},get"no-self-import"(){return require("./rules/no-self-import").noSelfImport},get"no-unresolved"(){return require("./rules/no-unresolved").noUnresolved},get"no-absolute-path"(){return require("./rules/no-absolute-path").noAbsolutePath},get"no-dynamic-require"(){return require("./rules/no-dynamic-require").noDynamicRequire},get"no-relative-packages"(){return require("./rules/no-relative-packages").noRelativePackages},get"no-useless-path-segments"(){return require("./rules/no-useless-path-segments").noUselessPathSegments},get"no-amd"(){return require("./rules/no-amd").noAmd},get"no-commonjs"(){return require("./rules/no-commonjs").noCommonjs},get"no-nodejs-modules"(){return require("./rules/no-nodejs-modules").noNodejsModules},get"no-import-module-exports"(){return require("./rules/no-import-module-exports").noImportModuleExports},get unambiguous(){return require("./rules/unambiguous").unambiguous},get"no-cycle"(){return require("./rules/no-cycle").noCycle},get"no-internal-modules"(){return require("./rules/no-internal-modules").noInternalModules},get"no-cross-domain-imports"(){return require("./rules/no-cross-domain-imports").noCrossDomainImports},get"enforce-dependency-direction"(){return require("./rules/enforce-dependency-direction").enforceDependencyDirection},get"no-restricted-paths"(){return require("./rules/no-restricted-paths").noRestrictedPaths},get"no-relative-parent-imports"(){return require("./rules/no-relative-parent-imports").noRelativeParentImports},get export(){return require("./rules/export").exportRule},get"no-default-export"(){return require("./rules/no-default-export").noDefaultExport},get"no-named-export"(){return require("./rules/no-named-export").noNamedExport},get"prefer-default-export"(){return require("./rules/prefer-default-export").preferDefaultExport},get"no-anonymous-default-export"(){return require("./rules/no-anonymous-default-export").noAnonymousDefaultExport},get"no-mutable-exports"(){return require("./rules/no-mutable-exports").noMutableExports},get"no-deprecated"(){return require("./rules/no-deprecated").noDeprecated},get"exports-last"(){return require("./rules/exports-last").exportsLast},get"group-exports"(){return require("./rules/group-exports").groupExports},get"enforce-import-order"(){return require("./rules/enforce-import-order").enforceImportOrder},get order(){return require("./rules/enforce-import-order").enforceImportOrder},get"no-unassigned-import"(){return require("./rules/no-unassigned-import").noUnassignedImport},get first(){return require("./rules/first").first},get"newline-after-import"(){return require("./rules/newline-after-import").newlineAfterImport},get"no-empty-named-blocks"(){return require("./rules/no-empty-named-blocks").noEmptyNamedBlocks},get"no-named-as-default"(){return require("./rules/no-named-as-default").noNamedAsDefault},get"no-named-as-default-member"(){return require("./rules/no-named-as-default-member").noNamedAsDefaultMember},get"no-named-default"(){return require("./rules/no-named-default").noNamedDefault},get"no-namespace"(){return require("./rules/no-namespace").noNamespace},get"consistent-type-specifier-style"(){return require("./rules/consistent-type-specifier-style").consistentTypeSpecifierStyle},get"dynamic-import-chunkname"(){return require("./rules/dynamic-import-chunkname").dynamicImportChunkname},get"no-extraneous-dependencies"(){return require("./rules/no-extraneous-dependencies").noExtraneousDependencies},get"no-unused-modules"(){return require("./rules/no-unused-modules").noUnusedModules},get"max-dependencies"(){return require("./rules/max-dependencies").maxDependencies},get"prefer-node-protocol"(){return require("./rules/prefer-node-protocol").preferNodeProtocol},get"no-barrel-file"(){return require("./rules/no-barrel-file").noBarrelFile},get"no-barrel-import"(){return require("./rules/no-barrel-import").noBarrelImport},get"prefer-tree-shakeable-imports"(){return require("./rules/prefer-tree-shakeable-imports").preferTreeShakeableImports},get"prefer-direct-import"(){return require("./rules/prefer-direct-import").preferDirectImport},get"no-full-package-import"(){return require("./rules/no-full-package-import").noFullPackageImport},get"enforce-team-boundaries"(){return require("./rules/enforce-team-boundaries").enforceTeamBoundaries},get"no-legacy-imports"(){return require("./rules/no-legacy-imports").noLegacyImports},get"require-import-approval"(){return require("./rules/require-import-approval").requireImportApproval},get"prefer-modern-api"(){return require("./rules/prefer-modern-api").preferModernApi}};exports.plugin={meta:{name:"eslint-plugin-import-next",version:"2.5.0"},rules:exports.rules};exports.configs={flagship:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-cycle":"error"}},recommended:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"warn","import-next/no-duplicates":"error","import-next/export":"error","import-next/no-cycle":"error","import-next/no-self-import":"error","import-next/no-named-as-default":"warn","import-next/no-named-as-default-member":"warn","import-next/no-amd":"warn","import-next/no-empty-named-blocks":"warn","import-next/no-extraneous-dependencies":"warn"}},strict:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"error","import-next/extensions":"error","import-next/no-self-import":"error","import-next/no-duplicates":"error","import-next/no-absolute-path":"error","import-next/no-dynamic-require":"error","import-next/no-useless-path-segments":"error","import-next/export":"error","import-next/no-amd":"error","import-next/no-commonjs":"error","import-next/no-nodejs-modules":"error","import-next/no-import-module-exports":"error","import-next/unambiguous":"error","import-next/no-cycle":"error","import-next/no-internal-modules":"error","import-next/no-cross-domain-imports":"error","import-next/enforce-dependency-direction":"error","import-next/no-restricted-paths":"error","import-next/no-relative-parent-imports":"error","import-next/no-relative-packages":"error","import-next/no-anonymous-default-export":"error","import-next/no-mutable-exports":"error","import-next/no-deprecated":"error","import-next/exports-last":"error","import-next/group-exports":"error","import-next/order":"error","import-next/no-unassigned-import":"error","import-next/first":"error","import-next/newline-after-import":"error","import-next/no-empty-named-blocks":"error","import-next/no-named-as-default":"error","import-next/no-named-as-default-member":"error","import-next/no-named-default":"error","import-next/no-namespace":"error","import-next/consistent-type-specifier-style":"error","import-next/no-extraneous-dependencies":"error","import-next/no-unused-modules":"error","import-next/max-dependencies":"error","import-next/prefer-node-protocol":"error"}},typescript:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"off","import-next/default":"error","import-next/namespace":"error","import-next/export":"error","import-next/no-cycle":"error","import-next/no-duplicates":"error","import-next/order":"warn","import-next/first":"warn","import-next/newline-after-import":"warn","import-next/consistent-type-specifier-style":["warn","prefer-inline"]}},"module-resolution":{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"error","import-next/extensions":"warn","import-next/no-self-import":"error","import-next/no-duplicates":"error","import-next/no-absolute-path":"error","import-next/no-useless-path-segments":"warn"}},"import-style":{plugins:{"import-next":exports.plugin},rules:{"import-next/order":"error","import-next/first":"error","import-next/newline-after-import":"error","import-next/no-duplicates":"error","import-next/no-unassigned-import":"warn","import-next/no-empty-named-blocks":"error","import-next/no-namespace":"warn"}},esm:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-amd":"error","import-next/no-commonjs":"error","import-next/no-import-module-exports":"error","import-next/unambiguous":"error","import-next/prefer-node-protocol":"error"}},architecture:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-cycle":"error","import-next/no-internal-modules":"error","import-next/no-cross-domain-imports":"error","import-next/enforce-dependency-direction":"error","import-next/no-restricted-paths":"error","import-next/no-relative-parent-imports":"warn","import-next/no-relative-packages":"error"}},errors:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-unresolved":"error","import-next/named":"error","import-next/default":"error","import-next/namespace":"error","import-next/export":"error"}},warnings:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-named-as-default":"warn","import-next/no-named-as-default-member":"warn","import-next/no-duplicates":"warn"}},performance:{plugins:{"import-next":exports.plugin},rules:{"import-next/no-barrel-file":"error","import-next/no-barrel-import":"warn","import-next/prefer-tree-shakeable-imports":"warn","import-next/prefer-direct-import":"warn","import-next/no-full-package-import":"warn","import-next/no-cycle":"error"}},enterprise:{plugins:{"import-next":exports.plugin},rules:{"import-next/enforce-team-boundaries":"off","import-next/no-legacy-imports":"off","import-next/no-cross-domain-imports":"warn","import-next/enforce-dependency-direction":"warn","import-next/no-internal-modules":"warn"}}};exports.default=exports.plugin;
|
package/src/rules/no-cycle.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noCycle=void 0;exports.clearCircularDependencyCache=clearCircularDependencyCache;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");const node_fs_1=require("node:fs");const eslint_devkit_4=require("@interlace/eslint-devkit");const sharedCache=(0,eslint_devkit_4.createFileSystemCache)();function clearCircularDependencyCache(){(0,eslint_devkit_4.clearCache)(sharedCache)}exports.noCycle=(0,eslint_devkit_1.createRule)({name:"no-cycle",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-cycle.md",description:"Detect circular dependencies that cause bundle memory bloat and initialization issues",cwe:"CWE-1047",confidence:"high"},messages:{moduleSplit:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"Split {{moduleToSplit}} into .{{coreFile}} and .{{extendedFile}}",documentationLink:"https://en.wikipedia.org/wiki/Circular_dependency"}),directImport:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"{{newImport}} (direct imports preferred over barrel exports)",documentationLink:"https://en.wikipedia.org/wiki/Circular_dependency"}),extractShared:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"Extract shared types to {{exports}} file",documentationLink:"https://en.wikipedia.org/wiki/Dependency_inversion_principle"}),dependencyInjection:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"Use dependency injection pattern to break cycle",documentationLink:"https://en.wikipedia.org/wiki/Dependency_injection"})},schema:[{type:"object",properties:{maxDepth:{type:"number",default:Number.MAX_SAFE_INTEGER,description:"Maximum depth to traverse when detecting cycles. Default: unlimited (matches eslint-plugin-import and oxlint). Lower values are a performance escape hatch \u2014 but with our nonCyclicFiles cache, traversal cost is amortized, and a low cap silently misses cycles deeper than the limit. Set to a finite number only on huge graphs where the bench latency hurts you."},ignorePatterns:{type:"array",items:{type:"string"},default:["**/*.test.ts","**/*.test.tsx","**/*.spec.ts","**/*.spec.tsx","**/*.stories.tsx","**/__tests__/**","**/__mocks__/**"],description:"File patterns to ignore (glob patterns)"},barrelExports:{type:"array",items:{type:"string"},default:["index.ts","index.tsx","index.js","index.jsx"],description:"Files considered barrel exports"},reportAllCycles:{type:"boolean",default:true,description:"Report all circular dependencies found (not just the first one)"},fixStrategy:{type:"string",enum:["module-split","direct-import","extract-shared","dependency-injection","auto"],default:"auto",description:"Strategy for fixing circular dependencies (auto = smart detection)"},moduleNamingConvention:{type:"string",enum:["semantic","numbered"],default:"semantic",description:"Naming convention for split modules (semantic: .core, .api | numbered: .1, .2)"},coreModuleSuffix:{type:"string",default:"core",description:'Suffix for core module when splitting (e.g., "core", "base", "main")'},extendedModuleSuffix:{type:"string",default:"extended",description:'Suffix for extended module when splitting (e.g., "extended", "api", "helpers")'}},additionalProperties:false}],fixable:void 0},defaultOptions:[{maxDepth:Infinity,ignorePatterns:[],barrelExports:["index.ts","index.tsx","index.js","index.jsx"],reportAllCycles:true,fixStrategy:"auto",moduleNamingConvention:"semantic",coreModuleSuffix:"core",extendedModuleSuffix:"extended"}],create(context){const options=context.options[0]||{};const maxDepth=options.maxDepth??Infinity;const ignorePatterns=options.ignorePatterns??["**/*.test.ts","**/*.test.tsx","**/*.spec.ts","**/*.spec.tsx","**/*.stories.tsx","**/__tests__/**","**/__mocks__/**"];const barrelExports=options.barrelExports??["index.ts","index.tsx","index.js","index.jsx"];const _reportAllCycles=options.reportAllCycles??true;const fixStrategy=options.fixStrategy??"auto";const moduleNamingConvention=options.moduleNamingConvention??"semantic";const coreModuleSuffix=options.coreModuleSuffix??"core";const extendedModuleSuffix=options.extendedModuleSuffix??"extended";const filename=context.filename;const normalizedFilename=(()=>{try{return(0,node_fs_1.realpathSync)(filename)}catch{return filename}})();const workspaceRoot=context.cwd;const settings=context.settings;const resolverSettings=settings?.["import/resolver"]||settings?.["import-next/resolver"];if((0,eslint_devkit_3.shouldIgnoreFile)(filename,ignorePatterns,sharedCache.compiledPatterns)){return{}}sharedCache.pendingCycleReports.clear();const reportedImportNodes=new Set;function selectFixStrategy(cycle,userStrategy){if(userStrategy!=="auto"){return userStrategy}const hasBarrel=cycle.some(file=>(0,eslint_devkit_3.isBarrelExport)(file,barrelExports));const typesOnly=(0,eslint_devkit_4.hasOnlyTypeImports)(cycle,sharedCache);const cycleSize=cycle.length;if(hasBarrel&&cycleSize===2){return"direct-import"}if(typesOnly){return"extract-shared"}return"module-split"}function generateModuleSplitMessage(cycle){const moduleNames=(0,eslint_devkit_3.getModuleNames)(cycle,workspaceRoot);const[module1,module2]=moduleNames;const moduleToSplit=module1;const suffix1=moduleNamingConvention==="semantic"?`.${coreModuleSuffix}`:".1";const suffix2=moduleNamingConvention==="semantic"?`.${extendedModuleSuffix}`:".2";return{cycle:(0,eslint_devkit_3.formatCycleDisplay)(cycle,workspaceRoot),moduleToSplit,coreFile:coreModuleSuffix,extendedFile:extendedModuleSuffix,splitCount:"2",fileStructure:`\u251C\u2500 ${moduleToSplit}/${moduleToSplit}${suffix1}.ts (\u2192 ${module2} \u2713)
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noCycle=void 0;exports.clearCircularDependencyCache=clearCircularDependencyCache;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");const node_fs_1=require("node:fs");const eslint_devkit_4=require("@interlace/eslint-devkit");const sharedCache=(0,eslint_devkit_4.createFileSystemCache)();function clearCircularDependencyCache(){(0,eslint_devkit_4.clearCache)(sharedCache)}exports.noCycle=(0,eslint_devkit_1.createRule)({name:"no-cycle",skipGeneratedFiles:true,meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-cycle.md",description:"Detect circular dependencies that cause bundle memory bloat and initialization issues",cwe:"CWE-1047",confidence:"high"},messages:{moduleSplit:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"Split {{moduleToSplit}} into .{{coreFile}} and .{{extendedFile}}",documentationLink:"https://en.wikipedia.org/wiki/Circular_dependency"}),directImport:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"{{newImport}} (direct imports preferred over barrel exports)",documentationLink:"https://en.wikipedia.org/wiki/Circular_dependency"}),extractShared:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"Extract shared types to {{exports}} file",documentationLink:"https://en.wikipedia.org/wiki/Dependency_inversion_principle"}),dependencyInjection:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Circular dependency",cwe:"CWE-1047",description:"Circular dependency detected",severity:"MEDIUM",fix:"Use dependency injection pattern to break cycle",documentationLink:"https://en.wikipedia.org/wiki/Dependency_injection"})},schema:[{type:"object",properties:{maxDepth:{type:"number",default:Number.MAX_SAFE_INTEGER,description:"Maximum depth to traverse when detecting cycles. Default: unlimited (matches eslint-plugin-import and oxlint). Lower values are a performance escape hatch \u2014 but with our nonCyclicFiles cache, traversal cost is amortized, and a low cap silently misses cycles deeper than the limit. Set to a finite number only on huge graphs where the bench latency hurts you."},ignorePatterns:{type:"array",items:{type:"string"},default:["**/*.test.ts","**/*.test.tsx","**/*.spec.ts","**/*.spec.tsx","**/*.stories.tsx","**/__tests__/**","**/__mocks__/**"],description:"File patterns to ignore (glob patterns)"},barrelExports:{type:"array",items:{type:"string"},default:["index.ts","index.tsx","index.js","index.jsx"],description:"Files considered barrel exports"},reportAllCycles:{type:"boolean",default:true,description:"Report all circular dependencies found (not just the first one)"},fixStrategy:{type:"string",enum:["module-split","direct-import","extract-shared","dependency-injection","auto"],default:"auto",description:"Strategy for fixing circular dependencies (auto = smart detection)"},moduleNamingConvention:{type:"string",enum:["semantic","numbered"],default:"semantic",description:"Naming convention for split modules (semantic: .core, .api | numbered: .1, .2)"},coreModuleSuffix:{type:"string",default:"core",description:'Suffix for core module when splitting (e.g., "core", "base", "main")'},extendedModuleSuffix:{type:"string",default:"extended",description:'Suffix for extended module when splitting (e.g., "extended", "api", "helpers")'}},additionalProperties:false}],fixable:void 0},defaultOptions:[{maxDepth:Infinity,ignorePatterns:[],barrelExports:["index.ts","index.tsx","index.js","index.jsx"],reportAllCycles:true,fixStrategy:"auto",moduleNamingConvention:"semantic",coreModuleSuffix:"core",extendedModuleSuffix:"extended"}],create(context){const options=context.options[0]||{};const maxDepth=options.maxDepth??Infinity;const ignorePatterns=options.ignorePatterns??["**/*.test.ts","**/*.test.tsx","**/*.spec.ts","**/*.spec.tsx","**/*.stories.tsx","**/__tests__/**","**/__mocks__/**"];const barrelExports=options.barrelExports??["index.ts","index.tsx","index.js","index.jsx"];const _reportAllCycles=options.reportAllCycles??true;const fixStrategy=options.fixStrategy??"auto";const moduleNamingConvention=options.moduleNamingConvention??"semantic";const coreModuleSuffix=options.coreModuleSuffix??"core";const extendedModuleSuffix=options.extendedModuleSuffix??"extended";const filename=context.filename;const normalizedFilename=(()=>{try{return(0,node_fs_1.realpathSync)(filename)}catch{return filename}})();const workspaceRoot=context.cwd;const settings=context.settings;const resolverSettings=settings?.["import/resolver"]||settings?.["import-next/resolver"];if((0,eslint_devkit_3.shouldIgnoreFile)(filename,ignorePatterns,sharedCache.compiledPatterns)){return{}}sharedCache.pendingCycleReports.clear();const reportedImportNodes=new Set;function selectFixStrategy(cycle,userStrategy){if(userStrategy!=="auto"){return userStrategy}const hasBarrel=cycle.some(file=>(0,eslint_devkit_3.isBarrelExport)(file,barrelExports));const typesOnly=(0,eslint_devkit_4.hasOnlyTypeImports)(cycle,sharedCache);const cycleSize=cycle.length;if(hasBarrel&&cycleSize===2){return"direct-import"}if(typesOnly){return"extract-shared"}return"module-split"}function generateModuleSplitMessage(cycle){const moduleNames=(0,eslint_devkit_3.getModuleNames)(cycle,workspaceRoot);const[module1,module2]=moduleNames;const moduleToSplit=module1;const suffix1=moduleNamingConvention==="semantic"?`.${coreModuleSuffix}`:".1";const suffix2=moduleNamingConvention==="semantic"?`.${extendedModuleSuffix}`:".2";return{cycle:(0,eslint_devkit_3.formatCycleDisplay)(cycle,workspaceRoot),moduleToSplit,coreFile:coreModuleSuffix,extendedFile:extendedModuleSuffix,splitCount:"2",fileStructure:`\u251C\u2500 ${moduleToSplit}/${moduleToSplit}${suffix1}.ts (\u2192 ${module2} \u2713)
|
|
2
2
|
\u2514\u2500 ${moduleToSplit}/${moduleToSplit}${suffix2}.ts (\u2192 ${suffix1} + ${module2} \u2713)`,result:`${suffix1} \u2192 ${module2} \u2192 ${suffix2} (no cycle)`}}function generateDirectImportMessage(cycle,sourceImport){const currentFile=(0,eslint_devkit_3.getBasename)(context.filename);const targetFile=cycle[1];const relativeImport=(0,eslint_devkit_3.getRelativeImportPath)(context.filename,targetFile);return{cycle:(0,eslint_devkit_3.formatCycleDisplay)(cycle,workspaceRoot),currentFile,oldImport:`import { ... } from '${sourceImport.source}'`,newImport:`import { ... } from '${relativeImport}'`}}function generateExtractSharedMessage(cycle){const moduleNames=(0,eslint_devkit_3.getModuleNames)(cycle,workspaceRoot);const[module1,module2]=moduleNames;const exports2=[`- export type ${module1}Id, ${module2}Id`,`- export interface ${module1}Summary, ${module2}Summary`].join("\n");return{cycle:(0,eslint_devkit_3.formatCycleDisplay)(cycle,workspaceRoot),exports:exports2,result:`shared/types \u2190 ${module1}, ${module2} (no cycle)`}}function generateDependencyInjectionMessage(cycle){const moduleNames=(0,eslint_devkit_3.getModuleNames)(cycle,workspaceRoot);const[service1,service2]=moduleNames;const steps=[`1. Create interfaces/I${service1}.ts, interfaces/I${service2}.ts`,`2. Both services implement their interface`,`3. Inject via constructor: constructor(private dep?: IDep)`,`4. Wire in container.ts`].join("\n");return{cycle:(0,eslint_devkit_3.formatCycleDisplay)(cycle,workspaceRoot),steps}}function generateMessageData(cycle,strategy,sourceImport){switch(strategy){case"direct-import":return{messageId:"directImport",data:generateDirectImportMessage(cycle,sourceImport)};case"extract-shared":return{messageId:"extractShared",data:generateExtractSharedMessage(cycle)};case"dependency-injection":return{messageId:"dependencyInjection",data:generateDependencyInjectionMessage(cycle)};default:return{messageId:"moduleSplit",data:generateModuleSplitMessage(cycle)}}}return{"Program"(){},ImportDeclaration(node){if(node.importKind==="type")return;if(reportedImportNodes.has(node))return;const importSource=node.source.value;const resolved=(0,eslint_devkit_4.resolveImportPath)(importSource,{fromFile:normalizedFilename,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});if(!resolved)return;if(sharedCache.nonCyclicFiles.has(resolved))return;let tgtSCC=sharedCache.sccIndex.get(resolved);if(tgtSCC===void 0){(0,eslint_devkit_4.computeSCCsFromFile)(resolved,{maxDepth:Infinity,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});tgtSCC=sharedCache.sccIndex.get(resolved)}let srcSCC=sharedCache.sccIndex.get(normalizedFilename);if(srcSCC===void 0){(0,eslint_devkit_4.computeSCCsFromFile)(normalizedFilename,{maxDepth:Infinity,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});srcSCC=sharedCache.sccIndex.get(normalizedFilename)}if(srcSCC===void 0||tgtSCC===void 0||srcSCC!==tgtSCC){return}const cyclePath=(0,eslint_devkit_4.findShortestCyclePath)(normalizedFilename,resolved,{maxDepth,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});if(!cyclePath)return;reportedImportNodes.add(node);const cycleStart=cyclePath.indexOf(normalizedFilename);const relevantCycle=cycleStart>=0?[...cyclePath.slice(cycleStart),...cyclePath.slice(0,cycleStart)]:cyclePath;const strategy=selectFixStrategy(relevantCycle,fixStrategy);const sourceImport={path:resolved,source:importSource};const{messageId,data}=generateMessageData(relevantCycle,strategy,sourceImport);context.report({node,messageId,data})},ExportNamedDeclaration(node){if(!node.source)return;if(reportedImportNodes.has(node))return;const importSource=node.source.value;const resolved=(0,eslint_devkit_4.resolveImportPath)(importSource,{fromFile:normalizedFilename,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});if(!resolved)return;if(sharedCache.nonCyclicFiles.has(resolved))return;let tgtSCC=sharedCache.sccIndex.get(resolved);if(tgtSCC===void 0){(0,eslint_devkit_4.computeSCCsFromFile)(resolved,{maxDepth:Infinity,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});tgtSCC=sharedCache.sccIndex.get(resolved)}const srcSCC=sharedCache.sccIndex.get(normalizedFilename);if(srcSCC===void 0||tgtSCC===void 0||srcSCC!==tgtSCC)return;const cyclePath=(0,eslint_devkit_4.findShortestCyclePath)(normalizedFilename,resolved,{maxDepth,workspaceRoot,barrelExports,cache:sharedCache,resolverSettings});if(!cyclePath)return;reportedImportNodes.add(node);const cycleStart=cyclePath.indexOf(normalizedFilename);const relevantCycle=cycleStart>=0?[...cyclePath.slice(cycleStart),...cyclePath.slice(0,cycleStart)]:cyclePath;const strategy=selectFixStrategy(relevantCycle,fixStrategy);const sourceImport={path:resolved,source:importSource};const{messageId,data}=generateMessageData(relevantCycle,strategy,sourceImport);context.report({node,messageId,data})}}}});
|