eslint-plugin-import-next 2.3.16 → 2.3.17

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 CHANGED
@@ -111,7 +111,7 @@ Detection parity is checked per shape before any timing is trusted, and every nu
111
111
  ## 📦 Compatibility
112
112
  | Package | Version |
113
113
  | :--- | :--- |
114
- | ESLint | `^8.0.0 \|\| ^9.0.0 \|\| ^10.0.0` |
114
+ | ESLint | `^8.40.0 \|\| ^9.0.0 \|\| ^10.0.0` |
115
115
  | Node.js | `>=18.0.0` |
116
116
 
117
117
  See the [ESLint Version Support Policy](../../docs/ESLINT_VERSION_SUPPORT.md) for the full matrix.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-import-next",
3
- "version": "2.3.16",
3
+ "version": "2.3.17",
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",
@@ -72,11 +72,11 @@
72
72
  "node": ">=18.0.0"
73
73
  },
74
74
  "peerDependencies": {
75
- "eslint": "^8.0.0 || ^9.0.0 || ^10.0.0",
75
+ "eslint": "^8.40.0 || ^9.0.0 || ^10.0.0",
76
76
  "typescript": ">=4.8.4"
77
77
  },
78
78
  "dependencies": {
79
- "@interlace/eslint-devkit": "^1.10.0",
79
+ "@interlace/eslint-devkit": "^1.11.0",
80
80
  "oxc-resolver": "^11.24.2"
81
81
  },
82
82
  "funding": {
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.3.16"},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/order":"warn","import-next/first":"warn","import-next/newline-after-import":"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.3.17"},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/order":"warn","import-next/first":"warn","import-next/newline-after-import":"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 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.enforceDependencyDirection=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");function arraysEqual(a,b){if(a.length!==b.length)return false;return a.every((val,index)=>val===b[index])}function extractLayer(filePath,layerPatterns){const normalizedPath=(0,eslint_devkit_3.normalizePath)(filePath);for(const pattern of layerPatterns){if(normalizedPath.includes(`/${pattern}/`)||normalizedPath.includes(`\\${pattern}\\`)||normalizedPath.startsWith(`${pattern}/`)||normalizedPath.startsWith(`${pattern}\\`)){return pattern}}return null}function getLayerOrder(layer,layers){if(!layer){return-1}const index=layers.indexOf(layer);return index>=0?index:-1}exports.enforceDependencyDirection=(0,eslint_devkit_2.createRule)({name:"enforce-dependency-direction",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/enforce-dependency-direction.md",description:"Ensures dependencies flow in the correct architectural direction"},messages:{dependencyDirectionViolation:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Dependency direction violation",description:"Import from {{targetLayer}} to {{sourceLayer}} violates dependency direction",severity:"HIGH",fix:"Use dependency inversion or refactor dependency",documentationLink:"https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html"}),useDependencyInversion:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Dependency Inversion",description:"Use dependency inversion principle",severity:"LOW",fix:"Depend on interfaces/abstractions, not implementations",documentationLink:"https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html"}),refactorDependency:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Refactor Dependency",description:"Refactor to respect dependency direction",severity:"LOW",fix:"Move import to correct layer",documentationLink:"https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html"})},schema:[{type:"object",properties:{layers:{type:"array",items:{type:"string"},default:["domain","application","infrastructure","presentation"],description:"Layer definitions with dependency order"},layerPatterns:{type:"array",items:{type:"string"},default:["domain","application","infrastructure","presentation","ui","api"],description:"Layer directory patterns"},allowSameLayer:{type:"boolean",default:true,description:"Allow same-layer imports"}},additionalProperties:false}]},defaultOptions:[{layers:["domain","application","infrastructure","presentation"],layerPatterns:["domain","application","infrastructure","presentation","ui","api"],allowSameLayer:true}],create(context,[options={}]){const filename=context.filename;const{layers:providedLayers,layerPatterns:providedLayerPatterns,allowSameLayer=true}=options||{};const layers=providedLayers||["domain","application","infrastructure","presentation"];const defaultLayerPatterns=["domain","application","infrastructure","presentation","ui","api"];let layerPatterns;if(providedLayerPatterns&&!arraysEqual(providedLayerPatterns,defaultLayerPatterns)){layerPatterns=providedLayerPatterns}else if(providedLayers){layerPatterns=providedLayers}else{layerPatterns=defaultLayerPatterns}const sourceLayer=extractLayer(filename,layerPatterns);const sourceOrder=getLayerOrder(sourceLayer,layers);function checkImport(node){let importPath="";if(node.type==="ImportDeclaration"){importPath=node.source.value}else if(node.type==="ImportExpression"){if(node.source.type==="Literal"){importPath=node.source.value}else{return}}if(!importPath.startsWith(".")){return}let targetLayer=null;const segments=importPath.split(/[/\\]/);for(const segment of segments){if(layerPatterns.includes(segment.toLowerCase())){targetLayer=segment.toLowerCase();break}}if(!targetLayer){for(const pattern of layerPatterns){const regex=new RegExp(`[/\\\\]${pattern}[/\\\\]`,"i");if(regex.test(importPath)){targetLayer=pattern;break}}}const targetOrder=getLayerOrder(targetLayer,layers);if(sourceOrder<0||targetOrder<0){return}if(allowSameLayer&&sourceLayer===targetLayer){return}if(targetOrder>sourceOrder){context.report({node,messageId:"dependencyDirectionViolation",data:{sourceLayer,targetLayer},suggest:[{messageId:"useDependencyInversion",fix:()=>null},{messageId:"refactorDependency",fix:()=>null}]})}}return{ImportDeclaration:checkImport,ImportExpression:checkImport}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.enforceDependencyDirection=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");function arraysEqual(a,b){if(a.length!==b.length)return false;return a.every((val,index)=>val===b[index])}function extractLayer(filePath,layerPatterns){const normalizedPath=(0,eslint_devkit_3.normalizePath)(filePath);for(const pattern of layerPatterns){if(normalizedPath.includes(`/${pattern}/`)||normalizedPath.includes(`\\${pattern}\\`)||normalizedPath.startsWith(`${pattern}/`)||normalizedPath.startsWith(`${pattern}\\`)){return pattern}}return null}function getLayerOrder(layer,layers){if(!layer){return-1}const index=layers.indexOf(layer);return index>=0?index:-1}exports.enforceDependencyDirection=(0,eslint_devkit_2.createRule)({name:"enforce-dependency-direction",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/enforce-dependency-direction.md",description:"Ensures dependencies flow in the correct architectural direction"},hasSuggestions:true,messages:{dependencyDirectionViolation:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Dependency direction violation",description:"Import from {{targetLayer}} to {{sourceLayer}} violates dependency direction",severity:"HIGH",fix:"Use dependency inversion or refactor dependency",documentationLink:"https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html"}),useDependencyInversion:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Dependency Inversion",description:"Use dependency inversion principle",severity:"LOW",fix:"Depend on interfaces/abstractions, not implementations",documentationLink:"https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html"}),refactorDependency:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Refactor Dependency",description:"Refactor to respect dependency direction",severity:"LOW",fix:"Move import to correct layer",documentationLink:"https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html"})},schema:[{type:"object",properties:{layers:{type:"array",items:{type:"string"},default:["domain","application","infrastructure","presentation"],description:"Layer definitions with dependency order"},layerPatterns:{type:"array",items:{type:"string"},default:["domain","application","infrastructure","presentation","ui","api"],description:"Layer directory patterns"},allowSameLayer:{type:"boolean",default:true,description:"Allow same-layer imports"}},additionalProperties:false}]},defaultOptions:[{layers:["domain","application","infrastructure","presentation"],layerPatterns:["domain","application","infrastructure","presentation","ui","api"],allowSameLayer:true}],create(context,[options={}]){const filename=context.filename;const{layers:providedLayers,layerPatterns:providedLayerPatterns,allowSameLayer=true}=options||{};const layers=providedLayers||["domain","application","infrastructure","presentation"];const defaultLayerPatterns=["domain","application","infrastructure","presentation","ui","api"];let layerPatterns;if(providedLayerPatterns&&!arraysEqual(providedLayerPatterns,defaultLayerPatterns)){layerPatterns=providedLayerPatterns}else if(providedLayers){layerPatterns=providedLayers}else{layerPatterns=defaultLayerPatterns}const sourceLayer=extractLayer(filename,layerPatterns);const sourceOrder=getLayerOrder(sourceLayer,layers);function checkImport(node){let importPath="";if(node.type==="ImportDeclaration"){importPath=node.source.value}else if(node.type==="ImportExpression"){if(node.source.type==="Literal"){importPath=node.source.value}else{return}}if(!importPath.startsWith(".")){return}let targetLayer=null;const segments=importPath.split(/[/\\]/);for(const segment of segments){if(layerPatterns.includes(segment.toLowerCase())){targetLayer=segment.toLowerCase();break}}if(!targetLayer){for(const pattern of layerPatterns){const regex=new RegExp(`[/\\\\]${pattern}[/\\\\]`,"i");if(regex.test(importPath)){targetLayer=pattern;break}}}const targetOrder=getLayerOrder(targetLayer,layers);if(sourceOrder<0||targetOrder<0){return}if(allowSameLayer&&sourceLayer===targetLayer){return}if(targetOrder>sourceOrder){context.report({node,messageId:"dependencyDirectionViolation",data:{sourceLayer,targetLayer},suggest:[{messageId:"useDependencyInversion",fix:()=>null},{messageId:"refactorDependency",fix:()=>null}]})}}return{ImportDeclaration:checkImport,ImportExpression:checkImport}}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noBarrelFile=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const DEFAULT_BARREL_PATTERNS=[".*[/\\\\]index\\.(ts|tsx|js|jsx|mts|mjs)$"];function matchesPattern(filePath,patterns){return patterns.some(pattern=>{try{const regex=new RegExp(pattern);return regex.test(filePath)}catch{return filePath.includes(pattern)}})}function isReexport(node){if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportAllDeclaration){return true}if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration&&node.source!==null){return true}return false}function isLocalExport(node){if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration){return node.source===null&&node.declaration!==null}if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportDefaultDeclaration){return true}return false}function countReexportSources(reexports,namedReexports){const sources=new Set;for(const node of reexports){if(node.source?.value){sources.add(String(node.source.value))}}for(const node of namedReexports){if(node.source?.value){sources.add(String(node.source.value))}}return sources.size}exports.noBarrelFile=(0,eslint_devkit_1.createRule)({name:"no-barrel-file",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-file.md",description:"Disallow barrel files that harm build performance and tree-shaking efficiency"},hasSuggestions:true,messages:{barrelFileDetected:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Barrel File Detected",description:"This file re-exports {{reexportCount}} modules without adding local logic. Barrel files severely impact build performance and prevent effective tree-shaking.",severity:"MEDIUM",fix:"Replace barrel pattern with direct imports. Instead of: import { Button } from '@/components'; Use: import { Button } from '@/components/Button';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-file.md"}),considerDirectExports:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Consider Direct Exports",description:"This file has a high ratio of re-exports ({{ratio}}%). Consider using direct imports for better tree-shaking.",severity:"LOW",fix:"Evaluate if consumers can import directly from source modules instead of through this barrel file.",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-file.md"})},schema:[{type:"object",properties:{threshold:{type:"number",minimum:1,default:3,description:"Minimum number of re-exports to consider a file a barrel"},allowedPaths:{type:"array",items:{type:"string"},default:[],description:"Regex patterns for paths where barrel files are allowed"},barrelPatterns:{type:"array",items:{type:"string"},default:DEFAULT_BARREL_PATTERNS,description:"File patterns considered barrel candidates"},allowWithLocalExports:{type:"boolean",default:false,description:"Allow barrel files that also export local declarations"},reexportRatio:{type:"number",minimum:0,maximum:1,default:.8,description:"Maximum allowed ratio of re-exports to total exports"}},additionalProperties:false}]},defaultOptions:[{threshold:3,allowedPaths:[],barrelPatterns:DEFAULT_BARREL_PATTERNS,allowWithLocalExports:false,reexportRatio:.8}],create(context,[options={}]){const{threshold=3,allowedPaths=[],barrelPatterns=DEFAULT_BARREL_PATTERNS,allowWithLocalExports=false,reexportRatio=.8}=options||{};const filename=context.filename;if(!matchesPattern(filename,barrelPatterns)){return{}}if(allowedPaths.length>0&&matchesPattern(filename,allowedPaths)){return{}}const exportAllDeclarations=[];const namedReexports=[];const localExports=[];return{ExportAllDeclaration(node){exportAllDeclarations.push(node)},ExportNamedDeclaration(node){if(isReexport(node)){namedReexports.push(node)}else if(isLocalExport(node)){localExports.push(node)}},ExportDefaultDeclaration(node){if(isLocalExport(node)){localExports.push(node)}},"Program:exit"(node){const totalReexports=exportAllDeclarations.length+namedReexports.length;const totalExports=totalReexports+localExports.length;if(totalExports===0){return}const sourceCount=countReexportSources(exportAllDeclarations,namedReexports);const hasLocalExports=localExports.length>0;if(allowWithLocalExports&&hasLocalExports){return}const ratio=totalReexports/totalExports;if(sourceCount>=threshold&&!hasLocalExports){context.report({node,messageId:"barrelFileDetected",data:{reexportCount:String(sourceCount)}})}else if(hasLocalExports&&sourceCount>=threshold&&ratio>=reexportRatio){context.report({node,messageId:"considerDirectExports",data:{ratio:String(Math.round(ratio*100))}})}}}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noBarrelFile=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const DEFAULT_BARREL_PATTERNS=[".*[/\\\\]index\\.(ts|tsx|js|jsx|mts|mjs)$"];function matchesPattern(filePath,patterns){return patterns.some(pattern=>{try{const regex=new RegExp(pattern);return regex.test(filePath)}catch{return filePath.includes(pattern)}})}function isReexport(node){if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportAllDeclaration){return true}if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration&&node.source!==null){return true}return false}function isLocalExport(node){if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration){return node.source===null&&node.declaration!==null}if(node.type===eslint_devkit_1.AST_NODE_TYPES.ExportDefaultDeclaration){return true}return false}function countReexportSources(reexports,namedReexports){const sources=new Set;for(const node of reexports){if(node.source?.value){sources.add(String(node.source.value))}}for(const node of namedReexports){if(node.source?.value){sources.add(String(node.source.value))}}return sources.size}exports.noBarrelFile=(0,eslint_devkit_1.createRule)({name:"no-barrel-file",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-file.md",description:"Disallow barrel files that harm build performance and tree-shaking efficiency"},messages:{barrelFileDetected:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Barrel File Detected",description:"This file re-exports {{reexportCount}} modules without adding local logic. Barrel files severely impact build performance and prevent effective tree-shaking.",severity:"MEDIUM",fix:"Replace barrel pattern with direct imports. Instead of: import { Button } from '@/components'; Use: import { Button } from '@/components/Button';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-file.md"}),considerDirectExports:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Consider Direct Exports",description:"This file has a high ratio of re-exports ({{ratio}}%). Consider using direct imports for better tree-shaking.",severity:"LOW",fix:"Evaluate if consumers can import directly from source modules instead of through this barrel file.",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-file.md"})},schema:[{type:"object",properties:{threshold:{type:"number",minimum:1,default:3,description:"Minimum number of re-exports to consider a file a barrel"},allowedPaths:{type:"array",items:{type:"string"},default:[],description:"Regex patterns for paths where barrel files are allowed"},barrelPatterns:{type:"array",items:{type:"string"},default:DEFAULT_BARREL_PATTERNS,description:"File patterns considered barrel candidates"},allowWithLocalExports:{type:"boolean",default:false,description:"Allow barrel files that also export local declarations"},reexportRatio:{type:"number",minimum:0,maximum:1,default:.8,description:"Maximum allowed ratio of re-exports to total exports"}},additionalProperties:false}]},defaultOptions:[{threshold:3,allowedPaths:[],barrelPatterns:DEFAULT_BARREL_PATTERNS,allowWithLocalExports:false,reexportRatio:.8}],create(context,[options={}]){const{threshold=3,allowedPaths=[],barrelPatterns=DEFAULT_BARREL_PATTERNS,allowWithLocalExports=false,reexportRatio=.8}=options||{};const filename=context.filename;if(!matchesPattern(filename,barrelPatterns)){return{}}if(allowedPaths.length>0&&matchesPattern(filename,allowedPaths)){return{}}const exportAllDeclarations=[];const namedReexports=[];const localExports=[];return{ExportAllDeclaration(node){exportAllDeclarations.push(node)},ExportNamedDeclaration(node){if(isReexport(node)){namedReexports.push(node)}else if(isLocalExport(node)){localExports.push(node)}},ExportDefaultDeclaration(node){if(isLocalExport(node)){localExports.push(node)}},"Program:exit"(node){const totalReexports=exportAllDeclarations.length+namedReexports.length;const totalExports=totalReexports+localExports.length;if(totalExports===0){return}const sourceCount=countReexportSources(exportAllDeclarations,namedReexports);const hasLocalExports=localExports.length>0;if(allowWithLocalExports&&hasLocalExports){return}const ratio=totalReexports/totalExports;if(sourceCount>=threshold&&!hasLocalExports){context.report({node,messageId:"barrelFileDetected",data:{reexportCount:String(sourceCount)}})}else if(hasLocalExports&&sourceCount>=threshold&&ratio>=reexportRatio){context.report({node,messageId:"considerDirectExports",data:{ratio:String(Math.round(ratio*100))}})}}}}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noBarrelImport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");function matchesPattern(importPath,patterns){return patterns.some(pattern=>{try{const regex=new RegExp(pattern);return regex.test(importPath)}catch{return importPath===pattern}})}function isNodeModulesImport(importPath){if(importPath.startsWith(".")||importPath.startsWith("/")){return false}return true}function endsWithIndex(importPath){return/\/index(\.[mc]?[jt]sx?)?$/.test(importPath)}exports.noBarrelImport=(0,eslint_devkit_1.createRule)({name:"no-barrel-import",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-import.md",description:"Disallow imports from barrel files to improve build performance and tree-shaking"},hasSuggestions:true,messages:{barrelImportDetected:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Barrel Import Detected",description:"Importing from '{{importPath}}' loads an index file that may include unused modules. Barrel imports harm build performance and prevent effective tree-shaking.",severity:"LOW",fix:"Import directly from the source module instead. For example:\n \u274C import { Button } from '@/components';\n \u274C import { Button } from '@/components/index';\n \u2705 import { Button } from '@/components/Button';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-import.md"})},schema:[{type:"object",properties:{knownBarrels:{type:"array",items:{type:"string"},default:[],description:"Regex patterns for paths known to be barrels"},ignoreNodeModules:{type:"boolean",default:true,description:"Ignore imports from node_modules"},ignoredPackages:{type:"array",items:{type:"string"},default:[],description:"Packages to ignore (good tree-shaking support)"}},additionalProperties:false}]},defaultOptions:[{knownBarrels:[],ignoreNodeModules:true,ignoredPackages:[]}],create(context,[options={}]){const{knownBarrels=[],ignoreNodeModules=true,ignoredPackages=[]}=options||{};function checkImportPath(node,importPath){if(ignoreNodeModules&&isNodeModulesImport(importPath)){if(ignoredPackages.length>0&&matchesPattern(importPath,ignoredPackages)){return}if(knownBarrels.length===0){return}}if(knownBarrels.length>0&&matchesPattern(importPath,knownBarrels)){context.report({node,messageId:"barrelImportDetected",data:{importPath}});return}if(endsWithIndex(importPath)){context.report({node,messageId:"barrelImportDetected",data:{importPath}})}}return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath==="string"){checkImportPath(node,importPath)}},ExportAllDeclaration(node){const importPath=node.source.value;if(typeof importPath==="string"){checkImportPath(node,importPath)}},ExportNamedDeclaration(node){if(node.source){const importPath=node.source.value;if(typeof importPath==="string"){checkImportPath(node,importPath)}}}}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noBarrelImport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");function matchesPattern(importPath,patterns){return patterns.some(pattern=>{try{const regex=new RegExp(pattern);return regex.test(importPath)}catch{return importPath===pattern}})}function isNodeModulesImport(importPath){if(importPath.startsWith(".")||importPath.startsWith("/")){return false}return true}function endsWithIndex(importPath){return/\/index(\.[mc]?[jt]sx?)?$/.test(importPath)}exports.noBarrelImport=(0,eslint_devkit_1.createRule)({name:"no-barrel-import",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-import.md",description:"Disallow imports from barrel files to improve build performance and tree-shaking"},messages:{barrelImportDetected:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Barrel Import Detected",description:"Importing from '{{importPath}}' loads an index file that may include unused modules. Barrel imports harm build performance and prevent effective tree-shaking.",severity:"LOW",fix:"Import directly from the source module instead. For example:\n \u274C import { Button } from '@/components';\n \u274C import { Button } from '@/components/index';\n \u2705 import { Button } from '@/components/Button';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-barrel-import.md"})},schema:[{type:"object",properties:{knownBarrels:{type:"array",items:{type:"string"},default:[],description:"Regex patterns for paths known to be barrels"},ignoreNodeModules:{type:"boolean",default:true,description:"Ignore imports from node_modules"},ignoredPackages:{type:"array",items:{type:"string"},default:[],description:"Packages to ignore (good tree-shaking support)"}},additionalProperties:false}]},defaultOptions:[{knownBarrels:[],ignoreNodeModules:true,ignoredPackages:[]}],create(context,[options={}]){const{knownBarrels=[],ignoreNodeModules=true,ignoredPackages=[]}=options||{};function checkImportPath(node,importPath){if(ignoreNodeModules&&isNodeModulesImport(importPath)){if(ignoredPackages.length>0&&matchesPattern(importPath,ignoredPackages)){return}if(knownBarrels.length===0){return}}if(knownBarrels.length>0&&matchesPattern(importPath,knownBarrels)){context.report({node,messageId:"barrelImportDetected",data:{importPath}});return}if(endsWithIndex(importPath)){context.report({node,messageId:"barrelImportDetected",data:{importPath}})}}return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath==="string"){checkImportPath(node,importPath)}},ExportAllDeclaration(node){const importPath=node.source.value;if(typeof importPath==="string"){checkImportPath(node,importPath)}},ExportNamedDeclaration(node){if(node.source){const importPath=node.source.value;if(typeof importPath==="string"){checkImportPath(node,importPath)}}}}}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noCrossDomainImports=void 0;exports.violatesDomainBoundary=violatesDomainBoundary;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");function extractDomain(filePath,domainPatterns){const normalizedPath=(0,eslint_devkit_3.normalizePath)(filePath);for(const pattern of domainPatterns){const regex=new RegExp(`(?:^|[/\\\\])${pattern}[/\\\\]([^/\\\\]+)`,"i");const match=normalizedPath.match(regex);if(match&&match[1]){return match[1]}}return null}function isSharedModule(filePath,allowedSharedModules){const normalizedPath=(0,eslint_devkit_3.normalizePath)(filePath);for(const shared of allowedSharedModules){if(normalizedPath.includes(`/${shared}/`)||normalizedPath.includes(`\\${shared}\\`)){return true}}return false}function violatesDomainBoundary(sourceFile,importPath,options){const{domainPatterns=["domains","features","modules"],allowedSharedModules=["shared","common","utils"],customRules=[]}=options||{};if(!importPath.startsWith(".")){return{violates:false,sourceDomain:null,targetDomain:null}}const sourceDomain=extractDomain(sourceFile,domainPatterns);let targetDomain=null;{for(const pattern of domainPatterns){const regex=new RegExp(`[/\\\\]${pattern}[/\\\\]([^/\\\\]+)`,"i");const match=importPath.match(regex);if(match&&match[1]){targetDomain=match[1];break}}if(!targetDomain){const segments=importPath.split(/[/\\]/);if(segments.length>=3&&segments[0]===".."&&segments[1]!=="."&&segments[1]!==".."&&segments[1]!==""&&segments[2]!==""&&segments.filter(s=>s==="..").length===1){const potentialDomain=segments[1];if(domainPatterns.some(p=>p.toLowerCase().includes(potentialDomain.toLowerCase())||potentialDomain.toLowerCase().includes(p))){targetDomain=potentialDomain}else if(["product","order"].includes(potentialDomain)){targetDomain=potentialDomain}}}}if(!sourceDomain||!targetDomain){return{violates:false,sourceDomain,targetDomain}}if(sourceDomain===targetDomain){return{violates:false,sourceDomain,targetDomain}}if(isSharedModule(importPath,allowedSharedModules)){return{violates:false,sourceDomain,targetDomain}}for(const rule of customRules){if(sourceFile.includes(rule.from)){const isAllowed=rule.allowed?.some(allowed=>importPath.includes(allowed));if(isAllowed){return{violates:false,sourceDomain,targetDomain}}if(rule.to.some(to=>importPath.includes(to))){return{violates:true,sourceDomain,targetDomain}}}}return{violates:true,sourceDomain,targetDomain}}exports.noCrossDomainImports=(0,eslint_devkit_2.createRule)({name:"no-cross-domain-imports",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-cross-domain-imports.md",description:"Prevents imports across domain/feature boundaries"},messages:{crossDomainImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Cross-domain import",description:"Import from {{targetDomain}} to {{sourceDomain}} violates domain boundaries",severity:"HIGH",fix:"Use shared modules, events, or application services",documentationLink:"https://martinfowler.com/bliki/BoundedContext.html"}),useSharedModule:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Shared Module",description:"Move shared code to shared module",severity:"LOW",fix:"Extract to shared/ or common/ directory",documentationLink:"https://martinfowler.com/bliki/BoundedContext.html"}),useEvents:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Events",description:"Use event-driven communication",severity:"LOW",fix:"Publish events instead of direct imports",documentationLink:"https://martinfowler.com/eaaDev/DomainEvent.html"}),useApplicationService:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Application Service",description:"Use application service layer",severity:"LOW",fix:"Route through application service for cross-domain calls",documentationLink:"https://martinfowler.com/bliki/BoundedContext.html"})},schema:[{type:"object",properties:{domainPatterns:{type:"array",items:{type:"string"},default:["domains","features","modules"],description:"Domain/feature directory patterns"},allowedSharedModules:{type:"array",items:{type:"string"},default:["shared","common","utils"],description:"Shared modules that can be imported"},ignoreNodeModules:{type:"boolean",default:true,description:"Ignore imports from node_modules"},customRules:{type:"array",items:{type:"object",properties:{from:{type:"string"},to:{type:"array",items:{type:"string"}},allowed:{type:"array",items:{type:"string"}}},required:["from","to"]},default:[],description:"Custom domain boundary rules"}},additionalProperties:false}]},defaultOptions:[{domainPatterns:["domains","features","modules"],allowedSharedModules:["shared","common","utils"],ignoreNodeModules:true,customRules:[]}],create(context,[options={}]){const filename=context.filename;function checkImport(node){let importPath="";if(node.type==="ImportDeclaration"){importPath=node.source.value}else if(node.type==="ImportExpression"){if(node.source.type==="Literal"){importPath=node.source.value}else{return}}if(importPath.startsWith(".")){const violation=violatesDomainBoundary(filename,importPath,options);if(violation.violates&&violation.sourceDomain&&violation.targetDomain){context.report({node,messageId:"crossDomainImport",data:{sourceDomain:violation.sourceDomain,targetDomain:violation.targetDomain},suggest:[{messageId:"useSharedModule",fix:()=>null},{messageId:"useEvents",fix:()=>null},{messageId:"useApplicationService",fix:()=>null}]})}}}return{ImportDeclaration:checkImport,ImportExpression:checkImport}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noCrossDomainImports=void 0;exports.violatesDomainBoundary=violatesDomainBoundary;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const eslint_devkit_3=require("@interlace/eslint-devkit");function extractDomain(filePath,domainPatterns){const normalizedPath=(0,eslint_devkit_3.normalizePath)(filePath);for(const pattern of domainPatterns){const regex=new RegExp(`(?:^|[/\\\\])${pattern}[/\\\\]([^/\\\\]+)`,"i");const match=normalizedPath.match(regex);if(match&&match[1]){return match[1]}}return null}function isSharedModule(filePath,allowedSharedModules){const normalizedPath=(0,eslint_devkit_3.normalizePath)(filePath);for(const shared of allowedSharedModules){if(normalizedPath.includes(`/${shared}/`)||normalizedPath.includes(`\\${shared}\\`)){return true}}return false}function violatesDomainBoundary(sourceFile,importPath,options){const{domainPatterns=["domains","features","modules"],allowedSharedModules=["shared","common","utils"],customRules=[]}=options||{};if(!importPath.startsWith(".")){return{violates:false,sourceDomain:null,targetDomain:null}}const sourceDomain=extractDomain(sourceFile,domainPatterns);let targetDomain=null;{for(const pattern of domainPatterns){const regex=new RegExp(`[/\\\\]${pattern}[/\\\\]([^/\\\\]+)`,"i");const match=importPath.match(regex);if(match&&match[1]){targetDomain=match[1];break}}if(!targetDomain){const segments=importPath.split(/[/\\]/);if(segments.length>=3&&segments[0]===".."&&segments[1]!=="."&&segments[1]!==".."&&segments[1]!==""&&segments[2]!==""&&segments.filter(s=>s==="..").length===1){const potentialDomain=segments[1];if(domainPatterns.some(p=>p.toLowerCase().includes(potentialDomain.toLowerCase())||potentialDomain.toLowerCase().includes(p))){targetDomain=potentialDomain}else if(["product","order"].includes(potentialDomain)){targetDomain=potentialDomain}}}}if(!sourceDomain||!targetDomain){return{violates:false,sourceDomain,targetDomain}}if(sourceDomain===targetDomain){return{violates:false,sourceDomain,targetDomain}}if(isSharedModule(importPath,allowedSharedModules)){return{violates:false,sourceDomain,targetDomain}}for(const rule of customRules){if(sourceFile.includes(rule.from)){const isAllowed=rule.allowed?.some(allowed=>importPath.includes(allowed));if(isAllowed){return{violates:false,sourceDomain,targetDomain}}if(rule.to.some(to=>importPath.includes(to))){return{violates:true,sourceDomain,targetDomain}}}}return{violates:true,sourceDomain,targetDomain}}exports.noCrossDomainImports=(0,eslint_devkit_2.createRule)({name:"no-cross-domain-imports",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-cross-domain-imports.md",description:"Prevents imports across domain/feature boundaries"},hasSuggestions:true,messages:{crossDomainImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Cross-domain import",description:"Import from {{targetDomain}} to {{sourceDomain}} violates domain boundaries",severity:"HIGH",fix:"Use shared modules, events, or application services",documentationLink:"https://martinfowler.com/bliki/BoundedContext.html"}),useSharedModule:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Shared Module",description:"Move shared code to shared module",severity:"LOW",fix:"Extract to shared/ or common/ directory",documentationLink:"https://martinfowler.com/bliki/BoundedContext.html"}),useEvents:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Events",description:"Use event-driven communication",severity:"LOW",fix:"Publish events instead of direct imports",documentationLink:"https://martinfowler.com/eaaDev/DomainEvent.html"}),useApplicationService:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Application Service",description:"Use application service layer",severity:"LOW",fix:"Route through application service for cross-domain calls",documentationLink:"https://martinfowler.com/bliki/BoundedContext.html"})},schema:[{type:"object",properties:{domainPatterns:{type:"array",items:{type:"string"},default:["domains","features","modules"],description:"Domain/feature directory patterns"},allowedSharedModules:{type:"array",items:{type:"string"},default:["shared","common","utils"],description:"Shared modules that can be imported"},ignoreNodeModules:{type:"boolean",default:true,description:"Ignore imports from node_modules"},customRules:{type:"array",items:{type:"object",properties:{from:{type:"string"},to:{type:"array",items:{type:"string"}},allowed:{type:"array",items:{type:"string"}}},required:["from","to"]},default:[],description:"Custom domain boundary rules"}},additionalProperties:false}]},defaultOptions:[{domainPatterns:["domains","features","modules"],allowedSharedModules:["shared","common","utils"],ignoreNodeModules:true,customRules:[]}],create(context,[options={}]){const filename=context.filename;function checkImport(node){let importPath="";if(node.type==="ImportDeclaration"){importPath=node.source.value}else if(node.type==="ImportExpression"){if(node.source.type==="Literal"){importPath=node.source.value}else{return}}if(importPath.startsWith(".")){const violation=violatesDomainBoundary(filename,importPath,options);if(violation.violates&&violation.sourceDomain&&violation.targetDomain){context.report({node,messageId:"crossDomainImport",data:{sourceDomain:violation.sourceDomain,targetDomain:violation.targetDomain},suggest:[{messageId:"useSharedModule",fix:()=>null},{messageId:"useEvents",fix:()=>null},{messageId:"useApplicationService",fix:()=>null}]})}}}return{ImportDeclaration:checkImport,ImportExpression:checkImport}}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noFullPackageImport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const DEFAULT_BLOCKED_PACKAGES=[{name:"lodash",suggestion:"Use subpath imports like lodash/debounce",example:"import debounce from 'lodash/debounce';"},{name:"lodash-es",suggestion:"Use named imports for tree-shaking",example:"import { debounce } from 'lodash-es';"},{name:"rxjs",suggestion:"Use named imports from rxjs",example:"import { Observable, map } from 'rxjs';"},{name:"ramda",suggestion:"Use subpath imports like ramda/src/compose",example:"import compose from 'ramda/src/compose';"},{name:"moment",suggestion:"Consider migrating to date-fns or dayjs for smaller bundles",example:"import { format } from 'date-fns';"},{name:"underscore",suggestion:"Consider migrating to lodash-es or native methods",example:"array.filter(fn) instead of _.filter(array, fn)"},{name:"@fortawesome/free-solid-svg-icons",suggestion:"Import individual icons",example:"import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';"},{name:"@fortawesome/free-regular-svg-icons",suggestion:"Import individual icons",example:"import { faCircle } from '@fortawesome/free-regular-svg-icons/faCircle';"},{name:"aws-sdk",suggestion:"Use AWS SDK v3 with modular imports",example:"import { S3Client } from '@aws-sdk/client-s3';"}];function isFullPackageImport(importPath,packageName){return importPath===packageName}function hasNamespaceImport(node){return node.specifiers.some(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportNamespaceSpecifier)}function hasDefaultImport(node){return node.specifiers.some(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportDefaultSpecifier)}exports.noFullPackageImport=(0,eslint_devkit_1.createRule)({name:"no-full-package-import",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md",description:"Disallow full package imports from known large packages that prevent tree-shaking"},hasSuggestions:true,messages:{fullPackageImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Full Package Import Blocks Tree-Shaking",description:"Importing the entire '{{packageName}}' package prevents tree-shaking and bloats your bundle. {{suggestion}}",severity:"MEDIUM",fix:"{{example}}",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md"})},schema:[{type:"object",properties:{blockedPackages:{type:"array",items:{type:"object",properties:{name:{type:"string"},suggestion:{type:"string"},example:{type:"string"}},required:["name","suggestion"]},default:[],description:"Packages to block full imports from"}},additionalProperties:false}]},defaultOptions:[{blockedPackages:DEFAULT_BLOCKED_PACKAGES}],create(context,[options={}]){const{blockedPackages=DEFAULT_BLOCKED_PACKAGES}=options||{};return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath!=="string")return;for(const blocked of blockedPackages){if(!isFullPackageImport(importPath,blocked.name)){continue}if(hasNamespaceImport(node)||hasDefaultImport(node)){context.report({node,messageId:"fullPackageImport",data:{packageName:blocked.name,suggestion:blocked.suggestion,example:blocked.example||"Use subpath or named imports"}})}}}}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noFullPackageImport=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const DEFAULT_BLOCKED_PACKAGES=[{name:"lodash",suggestion:"Use subpath imports like lodash/debounce",example:"import debounce from 'lodash/debounce';"},{name:"lodash-es",suggestion:"Use named imports for tree-shaking",example:"import { debounce } from 'lodash-es';"},{name:"rxjs",suggestion:"Use named imports from rxjs",example:"import { Observable, map } from 'rxjs';"},{name:"ramda",suggestion:"Use subpath imports like ramda/src/compose",example:"import compose from 'ramda/src/compose';"},{name:"moment",suggestion:"Consider migrating to date-fns or dayjs for smaller bundles",example:"import { format } from 'date-fns';"},{name:"underscore",suggestion:"Consider migrating to lodash-es or native methods",example:"array.filter(fn) instead of _.filter(array, fn)"},{name:"@fortawesome/free-solid-svg-icons",suggestion:"Import individual icons",example:"import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';"},{name:"@fortawesome/free-regular-svg-icons",suggestion:"Import individual icons",example:"import { faCircle } from '@fortawesome/free-regular-svg-icons/faCircle';"},{name:"aws-sdk",suggestion:"Use AWS SDK v3 with modular imports",example:"import { S3Client } from '@aws-sdk/client-s3';"}];function isFullPackageImport(importPath,packageName){return importPath===packageName}function hasNamespaceImport(node){return node.specifiers.some(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportNamespaceSpecifier)}function hasDefaultImport(node){return node.specifiers.some(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportDefaultSpecifier)}exports.noFullPackageImport=(0,eslint_devkit_1.createRule)({name:"no-full-package-import",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md",description:"Disallow full package imports from known large packages that prevent tree-shaking"},messages:{fullPackageImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Full Package Import Blocks Tree-Shaking",description:"Importing the entire '{{packageName}}' package prevents tree-shaking and bloats your bundle. {{suggestion}}",severity:"MEDIUM",fix:"{{example}}",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/no-full-package-import.md"})},schema:[{type:"object",properties:{blockedPackages:{type:"array",items:{type:"object",properties:{name:{type:"string"},suggestion:{type:"string"},example:{type:"string"}},required:["name","suggestion"]},default:[],description:"Packages to block full imports from"}},additionalProperties:false}]},defaultOptions:[{blockedPackages:DEFAULT_BLOCKED_PACKAGES}],create(context,[options={}]){const{blockedPackages=DEFAULT_BLOCKED_PACKAGES}=options||{};return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath!=="string")return;for(const blocked of blockedPackages){if(!isFullPackageImport(importPath,blocked.name)){continue}if(hasNamespaceImport(node)||hasDefaultImport(node)){context.report({node,messageId:"fullPackageImport",data:{packageName:blocked.name,suggestion:blocked.suggestion,example:blocked.example||"Use subpath or named imports"}})}}}}}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.preferNodeProtocol=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const NODE_BUILT_INS=new Set(["assert","async_hooks","buffer","child_process","cluster","console","constants","crypto","dgram","diagnostics_channel","dns","domain","events","fs","http","http2","https","inspector","module","net","os","path","perf_hooks","process","punycode","querystring","readline","repl","stream","string_decoder","sys","timers","tls","trace_events","tty","url","util","v8","vm","wasi","worker_threads","zlib"]);exports.preferNodeProtocol=(0,eslint_devkit_1.createRule)({name:"prefer-node-protocol",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-node-protocol.md",description:"Prefer using the node: protocol when importing Node.js builtin modules"},fixable:"code",hasSuggestions:true,messages:{preferNodeProtocol:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Node.js Protocol Import",description:"Use node: protocol for built-in modules",severity:"MEDIUM",fix:'Change "{{moduleName}}" to "node:{{moduleName}}" in import',documentationLink:"https://nodejs.org/api/modules.html#modules_node_imports"})},schema:[{type:"object",properties:{additionalModules:{type:"array",items:{type:"string"},default:[]}},additionalProperties:false}]},defaultOptions:[{}],create(context,[options={}]){const{additionalModules=[]}=options||{};const allModulesToCheck=new Set([...NODE_BUILT_INS,...additionalModules]);return{ImportDeclaration(node){const moduleName=node.source.value;if(typeof moduleName==="string"&&isBuiltInModule(moduleName,allModulesToCheck)){const fixedModuleName=`node:${moduleName}`;context.report({node:node.source,messageId:"preferNodeProtocol",data:{moduleName,fix:`Change "${moduleName}" to "${fixedModuleName}"`},fix(fixer){return fixer.replaceText(node.source,`"${fixedModuleName}"`)}})}},CallExpression(node){if(node.callee.type==="Identifier"&&node.callee.name==="require"&&node.arguments.length===1){const arg=node.arguments[0];if(arg.type==="Literal"&&typeof arg.value==="string"){const moduleName=arg.value;if(isBuiltInModule(moduleName,allModulesToCheck)){const fixedModuleName=`node:${moduleName}`;context.report({node:arg,messageId:"preferNodeProtocol",data:{moduleName,fix:`Change "${moduleName}" to "${fixedModuleName}"`},fix(fixer){return fixer.replaceText(arg,`"${fixedModuleName}"`)}})}}}},ImportExpression(node){if(node.source.type==="Literal"&&typeof node.source.value==="string"){const moduleName=node.source.value;if(isBuiltInModule(moduleName,allModulesToCheck)){const fixedModuleName=`node:${moduleName}`;context.report({node:node.source,messageId:"preferNodeProtocol",data:{moduleName,fix:`Change "${moduleName}" to "${fixedModuleName}"`},fix(fixer){return fixer.replaceText(node.source,`"${fixedModuleName}"`)}})}}}};function isBuiltInModule(moduleName,modulesToCheck){if(moduleName.startsWith("node:")){return false}if(modulesToCheck.has(moduleName)){return true}const lowerCaseModule=moduleName.toLowerCase();if(modulesToCheck.has(lowerCaseModule)){return true}const baseModule=moduleName.split("/")[0];if(modulesToCheck.has(baseModule)){return true}const lowerCaseBaseModule=baseModule.toLowerCase();return modulesToCheck.has(lowerCaseBaseModule)}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.preferNodeProtocol=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const NODE_BUILT_INS=new Set(["assert","async_hooks","buffer","child_process","cluster","console","constants","crypto","dgram","diagnostics_channel","dns","domain","events","fs","http","http2","https","inspector","module","net","os","path","perf_hooks","process","punycode","querystring","readline","repl","stream","string_decoder","sys","timers","tls","trace_events","tty","url","util","v8","vm","wasi","worker_threads","zlib"]);exports.preferNodeProtocol=(0,eslint_devkit_1.createRule)({name:"prefer-node-protocol",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-node-protocol.md",description:"Prefer using the node: protocol when importing Node.js builtin modules"},fixable:"code",messages:{preferNodeProtocol:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Node.js Protocol Import",description:"Use node: protocol for built-in modules",severity:"MEDIUM",fix:'Change "{{moduleName}}" to "node:{{moduleName}}" in import',documentationLink:"https://nodejs.org/api/modules.html#modules_node_imports"})},schema:[{type:"object",properties:{additionalModules:{type:"array",items:{type:"string"},default:[]}},additionalProperties:false}]},defaultOptions:[{}],create(context,[options={}]){const{additionalModules=[]}=options||{};const allModulesToCheck=new Set([...NODE_BUILT_INS,...additionalModules]);return{ImportDeclaration(node){const moduleName=node.source.value;if(typeof moduleName==="string"&&isBuiltInModule(moduleName,allModulesToCheck)){const fixedModuleName=`node:${moduleName}`;context.report({node:node.source,messageId:"preferNodeProtocol",data:{moduleName,fix:`Change "${moduleName}" to "${fixedModuleName}"`},fix(fixer){return fixer.replaceText(node.source,`"${fixedModuleName}"`)}})}},CallExpression(node){if(node.callee.type==="Identifier"&&node.callee.name==="require"&&node.arguments.length===1){const arg=node.arguments[0];if(arg.type==="Literal"&&typeof arg.value==="string"){const moduleName=arg.value;if(isBuiltInModule(moduleName,allModulesToCheck)){const fixedModuleName=`node:${moduleName}`;context.report({node:arg,messageId:"preferNodeProtocol",data:{moduleName,fix:`Change "${moduleName}" to "${fixedModuleName}"`},fix(fixer){return fixer.replaceText(arg,`"${fixedModuleName}"`)}})}}}},ImportExpression(node){if(node.source.type==="Literal"&&typeof node.source.value==="string"){const moduleName=node.source.value;if(isBuiltInModule(moduleName,allModulesToCheck)){const fixedModuleName=`node:${moduleName}`;context.report({node:node.source,messageId:"preferNodeProtocol",data:{moduleName,fix:`Change "${moduleName}" to "${fixedModuleName}"`},fix(fixer){return fixer.replaceText(node.source,`"${fixedModuleName}"`)}})}}}};function isBuiltInModule(moduleName,modulesToCheck){if(moduleName.startsWith("node:")){return false}if(modulesToCheck.has(moduleName)){return true}const lowerCaseModule=moduleName.toLowerCase();if(modulesToCheck.has(lowerCaseModule)){return true}const baseModule=moduleName.split("/")[0];if(modulesToCheck.has(baseModule)){return true}const lowerCaseBaseModule=baseModule.toLowerCase();return modulesToCheck.has(lowerCaseBaseModule)}}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.preferTreeShakeableImports=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const KNOWN_LARGE_PACKAGES=[{name:"lodash",subpathPattern:"lodash/{method}",preferNamed:false},{name:"@mui/material",subpathPattern:"@mui/material/{Component}",preferNamed:true},{name:"@mui/icons-material",subpathPattern:"@mui/icons-material/{Icon}",preferNamed:false},{name:"@heroicons/react",preferNamed:false},{name:"date-fns",preferNamed:true},{name:"rxjs",preferNamed:true},{name:"rxjs/operators",preferNamed:true},{name:"ramda",subpathPattern:"ramda/src/{fn}",preferNamed:true},{name:"@fortawesome/free-solid-svg-icons",preferNamed:true},{name:"@fortawesome/free-regular-svg-icons",preferNamed:true},{name:"antd",preferNamed:true},{name:"@ant-design/icons",preferNamed:true}];function matchesPackage(importPath,packages){for(const pkg of packages){if(importPath===pkg.name||importPath.startsWith(`${pkg.name}/`)){return pkg}}return null}exports.preferTreeShakeableImports=(0,eslint_devkit_1.createRule)({name:"prefer-tree-shakeable-imports",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-tree-shakeable-imports.md",description:"Prefer import patterns that enable effective tree-shaking"},hasSuggestions:true,messages:{namespaceImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Namespace Import Blocks Tree-Shaking",description:`Namespace import 'import * as {{alias}} from "{{source}}"' prevents tree-shaking. The bundler cannot determine which exports are actually used.`,severity:"MEDIUM",fix:"Use named imports instead:\n \u274C import * as utils from 'lodash';\n \u2705 import { debounce, throttle } from 'lodash';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-tree-shakeable-imports.md"}),defaultImportFromLargePackage:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Default Import from Large Package",description:"Default import from '{{source}}' may include the entire library. This package ({{packageHint}}) works better with named or subpath imports.",severity:"LOW",fix:"Use named imports or subpath imports:\n \u274C import _ from 'lodash';\n \u2705 import { debounce } from 'lodash';\n \u2705 import debounce from 'lodash/debounce';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-tree-shakeable-imports.md"})},schema:[{type:"object",properties:{targetPackages:{type:"array",items:{type:"object",properties:{name:{type:"string"},subpathPattern:{type:"string"},preferNamed:{type:"boolean"}},required:["name"]},default:[],description:"Packages to enforce tree-shakeable imports"},blockAllNamespaceImports:{type:"boolean",default:false,description:"Block all namespace imports"}},additionalProperties:false}]},defaultOptions:[{targetPackages:KNOWN_LARGE_PACKAGES,blockAllNamespaceImports:false}],create(context,[options={}]){const{targetPackages=KNOWN_LARGE_PACKAGES,blockAllNamespaceImports=false}=options||{};return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath!=="string")return;const namespaceSpecifier=node.specifiers.find(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportNamespaceSpecifier);if(namespaceSpecifier){const matchedPackage=matchesPackage(importPath,targetPackages);if(matchedPackage||blockAllNamespaceImports){context.report({node,messageId:"namespaceImport",data:{alias:namespaceSpecifier.local.name,source:importPath}});return}}const defaultSpecifier=node.specifiers.find(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportDefaultSpecifier);if(defaultSpecifier){const matchedPackage=matchesPackage(importPath,targetPackages);if(matchedPackage&&importPath===matchedPackage.name){context.report({node,messageId:"defaultImportFromLargePackage",data:{source:importPath,packageHint:matchedPackage.subpathPattern||"use named imports"}})}}}}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.preferTreeShakeableImports=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const KNOWN_LARGE_PACKAGES=[{name:"lodash",subpathPattern:"lodash/{method}",preferNamed:false},{name:"@mui/material",subpathPattern:"@mui/material/{Component}",preferNamed:true},{name:"@mui/icons-material",subpathPattern:"@mui/icons-material/{Icon}",preferNamed:false},{name:"@heroicons/react",preferNamed:false},{name:"date-fns",preferNamed:true},{name:"rxjs",preferNamed:true},{name:"rxjs/operators",preferNamed:true},{name:"ramda",subpathPattern:"ramda/src/{fn}",preferNamed:true},{name:"@fortawesome/free-solid-svg-icons",preferNamed:true},{name:"@fortawesome/free-regular-svg-icons",preferNamed:true},{name:"antd",preferNamed:true},{name:"@ant-design/icons",preferNamed:true}];function matchesPackage(importPath,packages){for(const pkg of packages){if(importPath===pkg.name||importPath.startsWith(`${pkg.name}/`)){return pkg}}return null}exports.preferTreeShakeableImports=(0,eslint_devkit_1.createRule)({name:"prefer-tree-shakeable-imports",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-tree-shakeable-imports.md",description:"Prefer import patterns that enable effective tree-shaking"},messages:{namespaceImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Namespace Import Blocks Tree-Shaking",description:`Namespace import 'import * as {{alias}} from "{{source}}"' prevents tree-shaking. The bundler cannot determine which exports are actually used.`,severity:"MEDIUM",fix:"Use named imports instead:\n \u274C import * as utils from 'lodash';\n \u2705 import { debounce, throttle } from 'lodash';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-tree-shakeable-imports.md"}),defaultImportFromLargePackage:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Default Import from Large Package",description:"Default import from '{{source}}' may include the entire library. This package ({{packageHint}}) works better with named or subpath imports.",severity:"LOW",fix:"Use named imports or subpath imports:\n \u274C import _ from 'lodash';\n \u2705 import { debounce } from 'lodash';\n \u2705 import debounce from 'lodash/debounce';",documentationLink:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/prefer-tree-shakeable-imports.md"})},schema:[{type:"object",properties:{targetPackages:{type:"array",items:{type:"object",properties:{name:{type:"string"},subpathPattern:{type:"string"},preferNamed:{type:"boolean"}},required:["name"]},default:[],description:"Packages to enforce tree-shakeable imports"},blockAllNamespaceImports:{type:"boolean",default:false,description:"Block all namespace imports"}},additionalProperties:false}]},defaultOptions:[{targetPackages:KNOWN_LARGE_PACKAGES,blockAllNamespaceImports:false}],create(context,[options={}]){const{targetPackages=KNOWN_LARGE_PACKAGES,blockAllNamespaceImports=false}=options||{};return{ImportDeclaration(node){const importPath=node.source.value;if(typeof importPath!=="string")return;const namespaceSpecifier=node.specifiers.find(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportNamespaceSpecifier);if(namespaceSpecifier){const matchedPackage=matchesPackage(importPath,targetPackages);if(matchedPackage||blockAllNamespaceImports){context.report({node,messageId:"namespaceImport",data:{alias:namespaceSpecifier.local.name,source:importPath}});return}}const defaultSpecifier=node.specifiers.find(spec=>spec.type===eslint_devkit_1.AST_NODE_TYPES.ImportDefaultSpecifier);if(defaultSpecifier){const matchedPackage=matchesPackage(importPath,targetPackages);if(matchedPackage&&importPath===matchedPackage.name){context.report({node,messageId:"defaultImportFromLargePackage",data:{source:importPath,packageHint:matchedPackage.subpathPattern||"use named imports"}})}}}}}});