eslint-plugin-import-next 2.3.14 → 2.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/package.json +9 -4
  2. package/src/files/foo.js +1 -6
  3. package/src/files/no-default.js +1 -4
  4. package/src/index.js +1 -326
  5. package/src/oxlint.js +1 -3
  6. package/src/rules/consistent-type-specifier-style.js +1 -109
  7. package/src/rules/default.js +1 -56
  8. package/src/rules/dynamic-import-chunkname.js +1 -115
  9. package/src/rules/enforce-dependency-direction.js +1 -213
  10. package/src/rules/enforce-import-order.js +1 -299
  11. package/src/rules/enforce-team-boundaries.js +1 -191
  12. package/src/rules/export.js +1 -111
  13. package/src/rules/exports-last.js +1 -67
  14. package/src/rules/extensions.js +1 -105
  15. package/src/rules/first.js +1 -53
  16. package/src/rules/group-exports.js +1 -69
  17. package/src/rules/max-dependencies.js +1 -241
  18. package/src/rules/named.js +1 -67
  19. package/src/rules/namespace.js +1 -64
  20. package/src/rules/newline-after-import.js +1 -57
  21. package/src/rules/no-absolute-path.js +1 -107
  22. package/src/rules/no-amd.js +1 -108
  23. package/src/rules/no-anonymous-default-export.js +1 -135
  24. package/src/rules/no-barrel-file.js +1 -194
  25. package/src/rules/no-barrel-import.js +1 -135
  26. package/src/rules/no-commonjs.js +1 -312
  27. package/src/rules/no-cross-domain-imports.js +1 -233
  28. package/src/rules/no-cycle.js +2 -396
  29. package/src/rules/no-default-export.js +2 -213
  30. package/src/rules/no-deprecated.js +1 -316
  31. package/src/rules/no-duplicates.js +1 -81
  32. package/src/rules/no-dynamic-require.js +1 -78
  33. package/src/rules/no-empty-named-blocks.js +1 -103
  34. package/src/rules/no-extraneous-dependencies.js +7 -385
  35. package/src/rules/no-full-package-import.js +1 -134
  36. package/src/rules/no-import-module-exports.js +1 -76
  37. package/src/rules/no-internal-modules.js +1 -256
  38. package/src/rules/no-legacy-imports.js +1 -125
  39. package/src/rules/no-mutable-exports.js +1 -146
  40. package/src/rules/no-named-as-default-member.js +1 -73
  41. package/src/rules/no-named-as-default.js +1 -90
  42. package/src/rules/no-named-default.js +1 -48
  43. package/src/rules/no-named-export.js +1 -174
  44. package/src/rules/no-namespace.js +1 -71
  45. package/src/rules/no-nodejs-modules.js +1 -229
  46. package/src/rules/no-relative-packages.js +1 -129
  47. package/src/rules/no-relative-parent-imports.js +1 -118
  48. package/src/rules/no-restricted-paths.js +1 -89
  49. package/src/rules/no-self-import.js +1 -113
  50. package/src/rules/no-unassigned-import.js +1 -115
  51. package/src/rules/no-unresolved.js +1 -189
  52. package/src/rules/no-unused-modules.js +1 -82
  53. package/src/rules/no-useless-path-segments.js +1 -107
  54. package/src/rules/prefer-default-export.js +1 -188
  55. package/src/rules/prefer-direct-import.js +1 -170
  56. package/src/rules/prefer-modern-api.js +1 -212
  57. package/src/rules/prefer-node-protocol.js +1 -174
  58. package/src/rules/prefer-tree-shakeable-imports.js +1 -134
  59. package/src/rules/require-import-approval.js +1 -174
  60. package/src/rules/unambiguous.js +1 -70
  61. package/src/types/index.js +1 -2
  62. package/src/utils/typescript-peer.js +1 -23
@@ -1,191 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enforceTeamBoundaries = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- function globToRegex(pattern) {
6
- const escaped = pattern.replace(/[.+?^${}()|[\]\\*]/g, '\\$&');
7
- return new RegExp(escaped
8
- .replace(/\\\*\\\*/g, '.*')
9
- .replace(/\\\*/g, '[^/]*'));
10
- }
11
- function getFileTeam(filePath, teams) {
12
- for (const team of teams) {
13
- for (const pattern of team.paths) {
14
- if (globToRegex(pattern).test(filePath)) {
15
- return team;
16
- }
17
- }
18
- }
19
- return null;
20
- }
21
- function getImportTeam(importPath, teams) {
22
- for (const team of teams) {
23
- for (const pattern of team.paths) {
24
- if (globToRegex(pattern).test(importPath)) {
25
- return team;
26
- }
27
- }
28
- if (team.publicPackages) {
29
- for (const pkg of team.publicPackages) {
30
- if (importPath.startsWith(pkg)) {
31
- return team;
32
- }
33
- }
34
- }
35
- }
36
- return null;
37
- }
38
- function isExternalImport(importPath) {
39
- if (importPath.startsWith('.') || importPath.startsWith('/')) {
40
- return false;
41
- }
42
- if (importPath.startsWith('@/') || importPath.startsWith('~/')) {
43
- return false;
44
- }
45
- if (importPath.startsWith('src/') ||
46
- importPath.startsWith('lib/') ||
47
- importPath.startsWith('packages/') ||
48
- importPath.startsWith('apps/')) {
49
- return false;
50
- }
51
- return true;
52
- }
53
- function isSharedPath(importPath, sharedPaths) {
54
- for (const shared of sharedPaths) {
55
- if (globToRegex(shared).test(importPath)) {
56
- return true;
57
- }
58
- }
59
- return false;
60
- }
61
- exports.enforceTeamBoundaries = (0, eslint_devkit_1.createRule)({
62
- name: 'enforce-team-boundaries',
63
- meta: {
64
- type: 'problem',
65
- docs: {
66
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/enforce-team-boundaries.md',
67
- description: 'Prevent unauthorized cross-team imports in large codebases',
68
- },
69
- messages: {
70
- unauthorizedTeamImport: (0, eslint_devkit_1.formatLLMMessage)({
71
- icon: eslint_devkit_1.MessageIcons.SECURITY,
72
- issueName: 'Unauthorized Cross-Team Import',
73
- description: "Team '{{sourceTeam}}' is importing from team '{{targetTeam}}' " +
74
- "without explicit permission. This creates tight coupling between teams. " +
75
- "Module: '{{importPath}}'",
76
- severity: 'HIGH',
77
- fix: 'Either:\n' +
78
- " 1. Add '{{targetTeam}}' to allowedDependencies in ESLint config\n" +
79
- " 2. Move shared code to a public package\n" +
80
- ' 3. Request API from target team via approved interface',
81
- documentationLink: 'https://nx.dev/concepts/enforce-project-boundaries',
82
- }),
83
- },
84
- schema: [
85
- {
86
- type: 'object',
87
- properties: {
88
- teams: {
89
- type: 'array',
90
- items: {
91
- type: 'object',
92
- properties: {
93
- team: { type: 'string' },
94
- paths: { type: 'array', items: { type: 'string' } },
95
- allowedDependencies: {
96
- type: 'array',
97
- items: { type: 'string' },
98
- },
99
- publicPackages: { type: 'array', items: { type: 'string' } },
100
- },
101
- required: ['team', 'paths'],
102
- },
103
- },
104
- sharedPaths: {
105
- type: 'array',
106
- items: { type: 'string' },
107
- default: [],
108
- },
109
- allowExternalPackages: {
110
- type: 'boolean',
111
- default: true,
112
- },
113
- },
114
- required: ['teams'],
115
- additionalProperties: false,
116
- },
117
- ],
118
- },
119
- defaultOptions: [
120
- {
121
- teams: [],
122
- sharedPaths: [],
123
- allowExternalPackages: true,
124
- },
125
- ],
126
- create(context, [options]) {
127
- const { teams, sharedPaths = [], allowExternalPackages = true } = options;
128
- const filename = context.filename;
129
- const sourceTeam = getFileTeam(filename, teams);
130
- if (!sourceTeam) {
131
- return {};
132
- }
133
- const owningTeam = sourceTeam;
134
- function checkImport(node) {
135
- let importPath = null;
136
- if (node.type === eslint_devkit_1.AST_NODE_TYPES.ImportDeclaration) {
137
- importPath = typeof node.source.value === 'string' ? node.source.value : null;
138
- }
139
- else if (node.type === eslint_devkit_1.AST_NODE_TYPES.ImportExpression) {
140
- if (node.source.type === eslint_devkit_1.AST_NODE_TYPES.Literal) {
141
- importPath = typeof node.source.value === 'string' ? node.source.value : null;
142
- }
143
- }
144
- else if (node.type === eslint_devkit_1.AST_NODE_TYPES.CallExpression &&
145
- node.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
146
- node.callee.name === 'require' &&
147
- node.arguments.length > 0 &&
148
- node.arguments[0].type === eslint_devkit_1.AST_NODE_TYPES.Literal) {
149
- importPath = typeof node.arguments[0].value === 'string' ? node.arguments[0].value : null;
150
- }
151
- if (!importPath)
152
- return;
153
- if (allowExternalPackages && isExternalImport(importPath)) {
154
- return;
155
- }
156
- if (isSharedPath(importPath, sharedPaths)) {
157
- return;
158
- }
159
- const targetTeam = getImportTeam(importPath, teams);
160
- if (!targetTeam) {
161
- return;
162
- }
163
- if (targetTeam.team === owningTeam.team) {
164
- return;
165
- }
166
- const allowedDeps = owningTeam.allowedDependencies || [];
167
- if (allowedDeps.includes(targetTeam.team)) {
168
- return;
169
- }
170
- context.report({
171
- node,
172
- messageId: 'unauthorizedTeamImport',
173
- data: {
174
- sourceTeam: owningTeam.team,
175
- targetTeam: targetTeam.team,
176
- importPath,
177
- },
178
- });
179
- }
180
- return {
181
- ImportDeclaration: checkImport,
182
- ImportExpression: checkImport,
183
- CallExpression(node) {
184
- if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
185
- node.callee.name === 'require') {
186
- checkImport(node);
187
- }
188
- },
189
- };
190
- },
191
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.enforceTeamBoundaries=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");function globToRegex(pattern){const escaped=pattern.replace(/[.+?^${}()|[\]\\*]/g,"\\$&");return new RegExp(escaped.replace(/\\\*\\\*/g,".*").replace(/\\\*/g,"[^/]*"))}function getFileTeam(filePath,teams){for(const team of teams){for(const pattern of team.paths){if(globToRegex(pattern).test(filePath)){return team}}}return null}function getImportTeam(importPath,teams){for(const team of teams){for(const pattern of team.paths){if(globToRegex(pattern).test(importPath)){return team}}if(team.publicPackages){for(const pkg of team.publicPackages){if(importPath.startsWith(pkg)){return team}}}}return null}function isExternalImport(importPath){if(importPath.startsWith(".")||importPath.startsWith("/")){return false}if(importPath.startsWith("@/")||importPath.startsWith("~/")){return false}if(importPath.startsWith("src/")||importPath.startsWith("lib/")||importPath.startsWith("packages/")||importPath.startsWith("apps/")){return false}return true}function isSharedPath(importPath,sharedPaths){for(const shared of sharedPaths){if(globToRegex(shared).test(importPath)){return true}}return false}exports.enforceTeamBoundaries=(0,eslint_devkit_1.createRule)({name:"enforce-team-boundaries",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/enforce-team-boundaries.md",description:"Prevent unauthorized cross-team imports in large codebases"},messages:{unauthorizedTeamImport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Unauthorized Cross-Team Import",description:"Team '{{sourceTeam}}' is importing from team '{{targetTeam}}' without explicit permission. This creates tight coupling between teams. Module: '{{importPath}}'",severity:"HIGH",fix:"Either:\n 1. Add '{{targetTeam}}' to allowedDependencies in ESLint config\n 2. Move shared code to a public package\n 3. Request API from target team via approved interface",documentationLink:"https://nx.dev/concepts/enforce-project-boundaries"})},schema:[{type:"object",properties:{teams:{type:"array",items:{type:"object",properties:{team:{type:"string"},paths:{type:"array",items:{type:"string"}},allowedDependencies:{type:"array",items:{type:"string"}},publicPackages:{type:"array",items:{type:"string"}}},required:["team","paths"]}},sharedPaths:{type:"array",items:{type:"string"},default:[]},allowExternalPackages:{type:"boolean",default:true}},required:["teams"],additionalProperties:false}]},defaultOptions:[{teams:[],sharedPaths:[],allowExternalPackages:true}],create(context,[options]){const{teams,sharedPaths=[],allowExternalPackages=true}=options;const filename=context.filename;const sourceTeam=getFileTeam(filename,teams);if(!sourceTeam){return{}}const owningTeam=sourceTeam;function checkImport(node){let importPath=null;if(node.type===eslint_devkit_1.AST_NODE_TYPES.ImportDeclaration){importPath=typeof node.source.value==="string"?node.source.value:null}else if(node.type===eslint_devkit_1.AST_NODE_TYPES.ImportExpression){if(node.source.type===eslint_devkit_1.AST_NODE_TYPES.Literal){importPath=typeof node.source.value==="string"?node.source.value:null}}else if(node.type===eslint_devkit_1.AST_NODE_TYPES.CallExpression&&node.callee.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&node.callee.name==="require"&&node.arguments.length>0&&node.arguments[0].type===eslint_devkit_1.AST_NODE_TYPES.Literal){importPath=typeof node.arguments[0].value==="string"?node.arguments[0].value:null}if(!importPath)return;if(allowExternalPackages&&isExternalImport(importPath)){return}if(isSharedPath(importPath,sharedPaths)){return}const targetTeam=getImportTeam(importPath,teams);if(!targetTeam){return}if(targetTeam.team===owningTeam.team){return}const allowedDeps=owningTeam.allowedDependencies||[];if(allowedDeps.includes(targetTeam.team)){return}context.report({node,messageId:"unauthorizedTeamImport",data:{sourceTeam:owningTeam.team,targetTeam:targetTeam.team,importPath}})}return{ImportDeclaration:checkImport,ImportExpression:checkImport,CallExpression(node){if(node.callee.type===eslint_devkit_1.AST_NODE_TYPES.Identifier&&node.callee.name==="require"){checkImport(node)}}}}});
@@ -1,111 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exportRule = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- exports.exportRule = (0, eslint_devkit_1.createRule)({
6
- name: 'export',
7
- meta: {
8
- type: 'problem',
9
- docs: {
10
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/export.md',
11
- description: 'Forbid any invalid exports, i.e. re-export of the same name',
12
- cwe: 'CWE-694',
13
- cvss: 7.5,
14
- },
15
- messages: {
16
- duplicateExport: (0, eslint_devkit_1.formatLLMMessage)({
17
- icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
18
- issueName: 'Duplicate Export',
19
- cwe: 'CWE-694',
20
- description: 'Multiple exports of name "{{name}}"',
21
- severity: 'HIGH',
22
- fix: 'Remove duplicate export or rename one of them',
23
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/export.md',
24
- }),
25
- duplicateDefault: (0, eslint_devkit_1.formatLLMMessage)({
26
- icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
27
- issueName: 'Duplicate Default Export',
28
- cwe: 'CWE-694',
29
- description: 'Multiple default exports',
30
- severity: 'HIGH',
31
- fix: 'A module can only have one default export',
32
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/export.md',
33
- }),
34
- },
35
- schema: [],
36
- },
37
- defaultOptions: [],
38
- create(context) {
39
- const exportedNames = new Map();
40
- let hasDefaultExport = null;
41
- function checkAndAddExport(name, node) {
42
- if (exportedNames.has(name)) {
43
- context.report({
44
- node,
45
- messageId: 'duplicateExport',
46
- data: { name },
47
- });
48
- }
49
- else {
50
- exportedNames.set(name, node);
51
- }
52
- }
53
- function checkDefaultExport(node) {
54
- if (hasDefaultExport) {
55
- context.report({
56
- node,
57
- messageId: 'duplicateDefault',
58
- });
59
- }
60
- else {
61
- hasDefaultExport = node;
62
- }
63
- }
64
- return {
65
- ExportDefaultDeclaration(node) {
66
- checkDefaultExport(node);
67
- },
68
- ExportNamedDeclaration(node) {
69
- if (node.declaration) {
70
- if (node.declaration.type === eslint_devkit_1.AST_NODE_TYPES.VariableDeclaration) {
71
- node.declaration.declarations.forEach((decl) => {
72
- if (decl.id.type === eslint_devkit_1.AST_NODE_TYPES.Identifier) {
73
- checkAndAddExport(decl.id.name, node);
74
- }
75
- });
76
- }
77
- else if (node.declaration.type === eslint_devkit_1.AST_NODE_TYPES.FunctionDeclaration ||
78
- node.declaration.type === eslint_devkit_1.AST_NODE_TYPES.ClassDeclaration) {
79
- if (node.declaration.id) {
80
- checkAndAddExport(node.declaration.id.name, node);
81
- }
82
- }
83
- else if (node.declaration.type === eslint_devkit_1.AST_NODE_TYPES.TSEnumDeclaration ||
84
- node.declaration.type === eslint_devkit_1.AST_NODE_TYPES.TSInterfaceDeclaration ||
85
- node.declaration.type === eslint_devkit_1.AST_NODE_TYPES.TSTypeAliasDeclaration) {
86
- if (node.declaration.id) {
87
- checkAndAddExport(node.declaration.id.name, node);
88
- }
89
- }
90
- }
91
- node.specifiers.forEach((spec) => {
92
- const exportedName = spec.exported.type === eslint_devkit_1.AST_NODE_TYPES.Identifier
93
- ? spec.exported.name
94
- : spec.exported.value;
95
- if (exportedName === 'default') {
96
- checkDefaultExport(spec);
97
- }
98
- else {
99
- checkAndAddExport(exportedName, spec);
100
- }
101
- });
102
- },
103
- ExportAllDeclaration(node) {
104
- if (node.exported) {
105
- const exportedName = node.exported.name;
106
- checkAndAddExport(exportedName, node);
107
- }
108
- },
109
- };
110
- },
111
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.exportRule=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.exportRule=(0,eslint_devkit_1.createRule)({name:"export",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/export.md",description:"Forbid any invalid exports, i.e. re-export of the same name",cwe:"CWE-694",cvss:7.5},messages:{duplicateExport:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Duplicate Export",cwe:"CWE-694",description:'Multiple exports of name "{{name}}"',severity:"HIGH",fix:"Remove duplicate export or rename one of them",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/export.md"}),duplicateDefault:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Duplicate Default Export",cwe:"CWE-694",description:"Multiple default exports",severity:"HIGH",fix:"A module can only have one default export",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/export.md"})},schema:[]},defaultOptions:[],create(context){const exportedNames=new Map;let hasDefaultExport=null;function checkAndAddExport(name,node){if(exportedNames.has(name)){context.report({node,messageId:"duplicateExport",data:{name}})}else{exportedNames.set(name,node)}}function checkDefaultExport(node){if(hasDefaultExport){context.report({node,messageId:"duplicateDefault"})}else{hasDefaultExport=node}}return{ExportDefaultDeclaration(node){checkDefaultExport(node)},ExportNamedDeclaration(node){if(node.declaration){if(node.declaration.type===eslint_devkit_1.AST_NODE_TYPES.VariableDeclaration){node.declaration.declarations.forEach(decl=>{if(decl.id.type===eslint_devkit_1.AST_NODE_TYPES.Identifier){checkAndAddExport(decl.id.name,node)}})}else if(node.declaration.type===eslint_devkit_1.AST_NODE_TYPES.FunctionDeclaration||node.declaration.type===eslint_devkit_1.AST_NODE_TYPES.ClassDeclaration){if(node.declaration.id){checkAndAddExport(node.declaration.id.name,node)}}else if(node.declaration.type===eslint_devkit_1.AST_NODE_TYPES.TSEnumDeclaration||node.declaration.type===eslint_devkit_1.AST_NODE_TYPES.TSInterfaceDeclaration||node.declaration.type===eslint_devkit_1.AST_NODE_TYPES.TSTypeAliasDeclaration){if(node.declaration.id){checkAndAddExport(node.declaration.id.name,node)}}}node.specifiers.forEach(spec=>{const exportedName=spec.exported.type===eslint_devkit_1.AST_NODE_TYPES.Identifier?spec.exported.name:spec.exported.value;if(exportedName==="default"){checkDefaultExport(spec)}else{checkAndAddExport(exportedName,spec)}})},ExportAllDeclaration(node){if(node.exported){const exportedName=node.exported.name;checkAndAddExport(exportedName,node)}}}}});
@@ -1,67 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exportsLast = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- exports.exportsLast = (0, eslint_devkit_1.createRule)({
6
- name: 'exports-last',
7
- meta: {
8
- type: 'suggestion',
9
- docs: {
10
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/exports-last.md',
11
- description: 'Ensure all exports appear after other statements',
12
- cwe: 'CWE-1078',
13
- cvss: 2.5,
14
- },
15
- messages: {
16
- exportNotLast: (0, eslint_devkit_1.formatLLMMessage)({
17
- icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
18
- issueName: 'Export Not Last',
19
- cwe: 'CWE-1078',
20
- description: 'Export statements should appear at the end of the file',
21
- severity: 'LOW',
22
- fix: 'Move this export to the end of the file',
23
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/exports-last.md',
24
- }),
25
- },
26
- schema: [],
27
- },
28
- defaultOptions: [],
29
- create(context) {
30
- return {
31
- 'Program:exit'(node) {
32
- const body = node.body;
33
- let lastNonExportIndex = -1;
34
- const exportIndices = [];
35
- const nonExportIndices = [];
36
- body.forEach((statement, index) => {
37
- const isExport = statement.type === eslint_devkit_1.AST_NODE_TYPES.ExportDefaultDeclaration ||
38
- statement.type === eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration ||
39
- statement.type === eslint_devkit_1.AST_NODE_TYPES.ExportAllDeclaration;
40
- if (isExport) {
41
- if (statement.type === eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration &&
42
- statement.declaration) {
43
- nonExportIndices.push(index);
44
- }
45
- else {
46
- exportIndices.push(index);
47
- }
48
- }
49
- else {
50
- nonExportIndices.push(index);
51
- }
52
- });
53
- if (nonExportIndices.length > 0) {
54
- lastNonExportIndex = Math.max(...nonExportIndices);
55
- }
56
- for (const exportIndex of exportIndices) {
57
- if (exportIndex < lastNonExportIndex) {
58
- context.report({
59
- node: body[exportIndex],
60
- messageId: 'exportNotLast',
61
- });
62
- }
63
- }
64
- },
65
- };
66
- },
67
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.exportsLast=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.exportsLast=(0,eslint_devkit_1.createRule)({name:"exports-last",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/exports-last.md",description:"Ensure all exports appear after other statements",cwe:"CWE-1078",cvss:2.5},messages:{exportNotLast:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Export Not Last",cwe:"CWE-1078",description:"Export statements should appear at the end of the file",severity:"LOW",fix:"Move this export to the end of the file",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/exports-last.md"})},schema:[]},defaultOptions:[],create(context){return{"Program:exit"(node){const body=node.body;let lastNonExportIndex=-1;const exportIndices=[];const nonExportIndices=[];body.forEach((statement,index)=>{const isExport=statement.type===eslint_devkit_1.AST_NODE_TYPES.ExportDefaultDeclaration||statement.type===eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration||statement.type===eslint_devkit_1.AST_NODE_TYPES.ExportAllDeclaration;if(isExport){if(statement.type===eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration&&statement.declaration){nonExportIndices.push(index)}else{exportIndices.push(index)}}else{nonExportIndices.push(index)}});if(nonExportIndices.length>0){lastNonExportIndex=Math.max(...nonExportIndices)}for(const exportIndex of exportIndices){if(exportIndex<lastNonExportIndex){context.report({node:body[exportIndex],messageId:"exportNotLast"})}}}}}});
@@ -1,105 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extensions = void 0;
4
- const tslib_1 = require("tslib");
5
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
6
- const eslint_devkit_2 = require("@interlace/eslint-devkit");
7
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
8
- exports.extensions = (0, eslint_devkit_1.createRule)({
9
- name: 'extensions',
10
- meta: {
11
- type: 'suggestion',
12
- docs: {
13
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/extensions.md',
14
- description: 'Ensure consistent use of file extensions in imports',
15
- },
16
- fixable: 'code',
17
- messages: {
18
- missingExtension: (0, eslint_devkit_2.formatLLMMessage)({
19
- icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
20
- issueName: 'Missing Extension',
21
- description: 'Missing file extension in import',
22
- severity: 'MEDIUM',
23
- fix: 'Add the file extension (e.g., .js, .ts)',
24
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/extensions.md',
25
- }),
26
- unexpectedExtension: (0, eslint_devkit_2.formatLLMMessage)({
27
- icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
28
- issueName: 'Unexpected Extension',
29
- description: 'Unexpected file extension in import',
30
- severity: 'MEDIUM',
31
- fix: 'Remove the file extension',
32
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/extensions.md',
33
- }),
34
- },
35
- schema: [
36
- {
37
- type: 'object',
38
- properties: {
39
- pattern: {
40
- type: 'object',
41
- additionalProperties: { type: 'string', enum: ['always', 'never'] },
42
- },
43
- default: { type: 'string', enum: ['always', 'never'] },
44
- },
45
- additionalProperties: false,
46
- },
47
- ],
48
- },
49
- defaultOptions: [
50
- {
51
- default: 'never',
52
- pattern: {
53
- js: 'never',
54
- ts: 'never',
55
- tsx: 'never',
56
- jsx: 'never',
57
- json: 'always',
58
- css: 'always',
59
- scss: 'always',
60
- svg: 'always',
61
- png: 'always',
62
- jpg: 'always',
63
- },
64
- },
65
- ],
66
- create(context) {
67
- const [options = {}] = context.options;
68
- const defaultBehavior = options.default ?? 'never';
69
- const pattern = options.pattern ?? {
70
- js: 'never',
71
- ts: 'never',
72
- tsx: 'never',
73
- jsx: 'never',
74
- json: 'always',
75
- css: 'always',
76
- scss: 'always',
77
- };
78
- return {
79
- ImportDeclaration(node) {
80
- const source = node.source.value;
81
- if (!source.startsWith('.'))
82
- return;
83
- const ext = node_path_1.default.extname(source).slice(1);
84
- const expected = pattern[ext] || defaultBehavior;
85
- if (ext && expected === 'never') {
86
- context.report({
87
- node: node.source,
88
- messageId: 'unexpectedExtension',
89
- fix(fixer) {
90
- return fixer.replaceText(node.source, `'${source.slice(0, -ext.length - 1)}'`);
91
- },
92
- });
93
- }
94
- else if (!ext) {
95
- if (defaultBehavior === 'always') {
96
- context.report({
97
- node: node.source,
98
- messageId: 'missingExtension',
99
- });
100
- }
101
- }
102
- },
103
- };
104
- },
105
- });
1
+ "use strict";var __importDefault=this&&this.__importDefault||function(mod){return mod&&mod.__esModule?mod:{"default":mod}};Object.defineProperty(exports,"__esModule",{value:true});exports.extensions=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const node_path_1=__importDefault(require("node:path"));exports.extensions=(0,eslint_devkit_1.createRule)({name:"extensions",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/extensions.md",description:"Ensure consistent use of file extensions in imports"},fixable:"code",messages:{missingExtension:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Missing Extension",description:"Missing file extension in import",severity:"MEDIUM",fix:"Add the file extension (e.g., .js, .ts)",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/extensions.md"}),unexpectedExtension:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Unexpected Extension",description:"Unexpected file extension in import",severity:"MEDIUM",fix:"Remove the file extension",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/extensions.md"})},schema:[{type:"object",properties:{pattern:{type:"object",additionalProperties:{type:"string",enum:["always","never"]}},default:{type:"string",enum:["always","never"]}},additionalProperties:false}]},defaultOptions:[{default:"never",pattern:{js:"never",ts:"never",tsx:"never",jsx:"never",json:"always",css:"always",scss:"always",svg:"always",png:"always",jpg:"always"}}],create(context){const[options={}]=context.options;const defaultBehavior=options.default??"never";const pattern=options.pattern??{js:"never",ts:"never",tsx:"never",jsx:"never",json:"always",css:"always",scss:"always"};return{ImportDeclaration(node){const source=node.source.value;if(!source.startsWith("."))return;const ext=node_path_1.default.extname(source).slice(1);const expected=pattern[ext]||defaultBehavior;if(ext&&expected==="never"){context.report({node:node.source,messageId:"unexpectedExtension",fix(fixer){return fixer.replaceText(node.source,`'${source.slice(0,-ext.length-1)}'`)}})}else if(!ext){if(defaultBehavior==="always"){context.report({node:node.source,messageId:"missingExtension"})}}}}}});
@@ -1,53 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.first = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
- exports.first = (0, eslint_devkit_1.createRule)({
7
- name: 'first',
8
- meta: {
9
- type: 'suggestion',
10
- docs: {
11
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/first.md',
12
- description: 'Ensure all imports appear before other statements',
13
- },
14
- messages: {
15
- first: (0, eslint_devkit_2.formatLLMMessage)({
16
- icon: eslint_devkit_2.MessageIcons.ARCHITECTURE,
17
- issueName: 'Import Placement',
18
- description: 'Import statements should be at the top of the file',
19
- severity: 'MEDIUM',
20
- fix: 'Move import to the top of the file',
21
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/first.md',
22
- }),
23
- },
24
- schema: [],
25
- },
26
- defaultOptions: [],
27
- create(context) {
28
- return {
29
- ImportDeclaration(node) {
30
- const sourceCode = context.sourceCode;
31
- const body = sourceCode.ast.body;
32
- const index = body.indexOf(node);
33
- if (index > 0) {
34
- const prevNode = body[index - 1];
35
- if (prevNode.type !== 'ImportDeclaration' &&
36
- prevNode.type !== 'TSImportEqualsDeclaration' &&
37
- !isDirective(prevNode)) {
38
- context.report({
39
- node,
40
- messageId: 'first',
41
- });
42
- }
43
- }
44
- },
45
- };
46
- function isDirective(node) {
47
- return (node.type === 'ExpressionStatement' &&
48
- node.expression.type === 'Literal' &&
49
- typeof node.expression.value === 'string' &&
50
- node.expression.value.startsWith('use '));
51
- }
52
- },
53
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.first=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.first=(0,eslint_devkit_1.createRule)({name:"first",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/first.md",description:"Ensure all imports appear before other statements"},messages:{first:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.ARCHITECTURE,issueName:"Import Placement",description:"Import statements should be at the top of the file",severity:"MEDIUM",fix:"Move import to the top of the file",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/first.md"})},schema:[]},defaultOptions:[],create(context){return{ImportDeclaration(node){const sourceCode=context.sourceCode;const body=sourceCode.ast.body;const index=body.indexOf(node);if(index>0){const prevNode=body[index-1];if(prevNode.type!=="ImportDeclaration"&&prevNode.type!=="TSImportEqualsDeclaration"&&!isDirective(prevNode)){context.report({node,messageId:"first"})}}}};function isDirective(node){return node.type==="ExpressionStatement"&&node.expression.type==="Literal"&&typeof node.expression.value==="string"&&node.expression.value.startsWith("use ")}}});
@@ -1,69 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.groupExports = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- exports.groupExports = (0, eslint_devkit_1.createRule)({
6
- name: 'group-exports',
7
- meta: {
8
- type: 'suggestion',
9
- docs: {
10
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/group-exports.md',
11
- description: 'Prefer named exports to be grouped together in a single export declaration',
12
- cwe: 'CWE-1078',
13
- cvss: 2.5,
14
- },
15
- messages: {
16
- groupExports: (0, eslint_devkit_1.formatLLMMessage)({
17
- icon: eslint_devkit_1.MessageIcons.ARCHITECTURE,
18
- issueName: 'Scattered Exports',
19
- cwe: 'CWE-1078',
20
- description: 'Multiple export statements can be grouped into a single export',
21
- severity: 'LOW',
22
- fix: 'Combine exports into: export { a, b, c }',
23
- documentationLink: 'https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/group-exports.md',
24
- }),
25
- },
26
- schema: [],
27
- },
28
- defaultOptions: [],
29
- create(context) {
30
- const separateExports = [];
31
- const reExportSources = new Map();
32
- return {
33
- ExportNamedDeclaration(node) {
34
- if (!node.declaration && node.specifiers.length > 0) {
35
- if (node.source) {
36
- const source = node.source.value;
37
- if (!reExportSources.has(source)) {
38
- reExportSources.set(source, []);
39
- }
40
- reExportSources.get(source)?.push(node);
41
- }
42
- else {
43
- separateExports.push(node);
44
- }
45
- }
46
- },
47
- 'Program:exit'() {
48
- if (separateExports.length > 1) {
49
- for (let i = 1; i < separateExports.length; i++) {
50
- context.report({
51
- node: separateExports[i],
52
- messageId: 'groupExports',
53
- });
54
- }
55
- }
56
- for (const [, exports] of reExportSources) {
57
- if (exports.length > 1) {
58
- for (let i = 1; i < exports.length; i++) {
59
- context.report({
60
- node: exports[i],
61
- messageId: 'groupExports',
62
- });
63
- }
64
- }
65
- }
66
- },
67
- };
68
- },
69
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.groupExports=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.groupExports=(0,eslint_devkit_1.createRule)({name:"group-exports",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-import-next/docs/rules/group-exports.md",description:"Prefer named exports to be grouped together in a single export declaration",cwe:"CWE-1078",cvss:2.5},messages:{groupExports:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.ARCHITECTURE,issueName:"Scattered Exports",cwe:"CWE-1078",description:"Multiple export statements can be grouped into a single export",severity:"LOW",fix:"Combine exports into: export { a, b, c }",documentationLink:"https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/group-exports.md"})},schema:[]},defaultOptions:[],create(context){const separateExports=[];const reExportSources=new Map;return{ExportNamedDeclaration(node){if(!node.declaration&&node.specifiers.length>0){if(node.source){const source=node.source.value;if(!reExportSources.has(source)){reExportSources.set(source,[])}reExportSources.get(source)?.push(node)}else{separateExports.push(node)}}},"Program:exit"(){if(separateExports.length>1){for(let i=1;i<separateExports.length;i++){context.report({node:separateExports[i],messageId:"groupExports"})}}for(const[,exports2]of reExportSources){if(exports2.length>1){for(let i=1;i<exports2.length;i++){context.report({node:exports2[i],messageId:"groupExports"})}}}}}}});