eslint-plugin-import-next 2.3.9 → 2.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +47 -0
  2. package/package.json +16 -12
  3. package/src/files/foo.js +0 -5
  4. package/src/files/no-default.js +0 -5
  5. package/src/index.d.ts +15 -2812
  6. package/src/index.js +5 -147
  7. package/src/oxlint.d.ts +17 -20
  8. package/src/oxlint.js +0 -18
  9. package/src/rules/consistent-type-specifier-style.js +0 -19
  10. package/src/rules/default.js +0 -7
  11. package/src/rules/dynamic-import-chunkname.js +0 -8
  12. package/src/rules/enforce-dependency-direction.js +2 -39
  13. package/src/rules/enforce-import-order.js +3 -33
  14. package/src/rules/enforce-team-boundaries.js +0 -49
  15. package/src/rules/export.js +0 -9
  16. package/src/rules/exports-last.js +0 -10
  17. package/src/rules/extensions.js +2 -11
  18. package/src/rules/first.js +0 -6
  19. package/src/rules/group-exports.js +0 -13
  20. package/src/rules/max-dependencies.js +0 -16
  21. package/src/rules/named.js +1 -10
  22. package/src/rules/namespace.js +1 -11
  23. package/src/rules/newline-after-import.js +2 -13
  24. package/src/rules/no-absolute-path.js +0 -7
  25. package/src/rules/no-amd.js +1 -18
  26. package/src/rules/no-anonymous-default-export.js +0 -13
  27. package/src/rules/no-barrel-file.js +0 -32
  28. package/src/rules/no-barrel-import.js +0 -25
  29. package/src/rules/no-commonjs.js +0 -18
  30. package/src/rules/no-cross-domain-imports.js +2 -47
  31. package/src/rules/no-cycle.js +2 -135
  32. package/src/rules/no-default-export.js +0 -28
  33. package/src/rules/no-deprecated.js +0 -32
  34. package/src/rules/no-duplicates.js +2 -10
  35. package/src/rules/no-dynamic-require.js +0 -6
  36. package/src/rules/no-empty-named-blocks.js +1 -17
  37. package/src/rules/no-extraneous-dependencies.js +0 -38
  38. package/src/rules/no-full-package-import.js +0 -19
  39. package/src/rules/no-import-module-exports.js +0 -8
  40. package/src/rules/no-internal-modules.js +0 -40
  41. package/src/rules/no-legacy-imports.js +1 -11
  42. package/src/rules/no-mutable-exports.js +0 -14
  43. package/src/rules/no-named-as-default-member.js +0 -11
  44. package/src/rules/no-named-as-default.js +0 -17
  45. package/src/rules/no-named-default.js +0 -5
  46. package/src/rules/no-named-export.js +1 -22
  47. package/src/rules/no-namespace.js +0 -10
  48. package/src/rules/no-nodejs-modules.js +0 -15
  49. package/src/rules/no-relative-packages.js +0 -15
  50. package/src/rules/no-relative-parent-imports.js +0 -11
  51. package/src/rules/no-restricted-paths.js +0 -6
  52. package/src/rules/no-self-import.js +0 -22
  53. package/src/rules/no-unassigned-import.js +0 -14
  54. package/src/rules/no-unresolved.js +0 -16
  55. package/src/rules/no-unused-modules.js +0 -7
  56. package/src/rules/no-useless-path-segments.js +0 -15
  57. package/src/rules/prefer-default-export.js +0 -18
  58. package/src/rules/prefer-direct-import.js +1 -21
  59. package/src/rules/prefer-modern-api.js +0 -21
  60. package/src/rules/prefer-node-protocol.js +0 -15
  61. package/src/rules/prefer-tree-shakeable-imports.js +0 -14
  62. package/src/rules/require-import-approval.js +0 -21
  63. package/src/rules/unambiguous.js +0 -11
  64. package/src/types/index.js +0 -5
  65. package/AGENTS.md +0 -95
  66. package/CHANGELOG.md +0 -170
  67. package/src/files/foo.d.ts +0 -7
  68. package/src/files/no-default.d.ts +0 -6
  69. package/src/rules/consistent-type-specifier-style.d.ts +0 -13
  70. package/src/rules/default.d.ts +0 -9
  71. package/src/rules/dynamic-import-chunkname.d.ts +0 -26
  72. package/src/rules/enforce-dependency-direction.d.ts +0 -27
  73. package/src/rules/enforce-import-order.d.ts +0 -29
  74. package/src/rules/enforce-team-boundaries.d.ts +0 -47
  75. package/src/rules/export.d.ts +0 -17
  76. package/src/rules/exports-last.d.ts +0 -15
  77. package/src/rules/extensions.d.ts +0 -17
  78. package/src/rules/first.d.ts +0 -13
  79. package/src/rules/group-exports.d.ts +0 -15
  80. package/src/rules/max-dependencies.d.ts +0 -26
  81. package/src/rules/named.d.ts +0 -13
  82. package/src/rules/namespace.d.ts +0 -13
  83. package/src/rules/newline-after-import.d.ts +0 -13
  84. package/src/rules/no-absolute-path.d.ts +0 -25
  85. package/src/rules/no-amd.d.ts +0 -21
  86. package/src/rules/no-anonymous-default-export.d.ts +0 -24
  87. package/src/rules/no-barrel-file.d.ts +0 -55
  88. package/src/rules/no-barrel-import.d.ts +0 -48
  89. package/src/rules/no-commonjs.d.ts +0 -28
  90. package/src/rules/no-cross-domain-imports.d.ts +0 -41
  91. package/src/rules/no-cycle.d.ts +0 -102
  92. package/src/rules/no-default-export.d.ts +0 -24
  93. package/src/rules/no-deprecated.d.ts +0 -26
  94. package/src/rules/no-duplicates.d.ts +0 -13
  95. package/src/rules/no-dynamic-require.d.ts +0 -22
  96. package/src/rules/no-empty-named-blocks.d.ts +0 -17
  97. package/src/rules/no-extraneous-dependencies.d.ts +0 -45
  98. package/src/rules/no-full-package-import.d.ts +0 -42
  99. package/src/rules/no-import-module-exports.d.ts +0 -21
  100. package/src/rules/no-internal-modules.d.ts +0 -28
  101. package/src/rules/no-legacy-imports.d.ts +0 -47
  102. package/src/rules/no-mutable-exports.d.ts +0 -22
  103. package/src/rules/no-named-as-default-member.d.ts +0 -15
  104. package/src/rules/no-named-as-default.d.ts +0 -15
  105. package/src/rules/no-named-default.d.ts +0 -15
  106. package/src/rules/no-named-export.d.ts +0 -26
  107. package/src/rules/no-namespace.d.ts +0 -21
  108. package/src/rules/no-nodejs-modules.d.ts +0 -24
  109. package/src/rules/no-relative-packages.d.ts +0 -21
  110. package/src/rules/no-relative-parent-imports.d.ts +0 -22
  111. package/src/rules/no-restricted-paths.d.ts +0 -20
  112. package/src/rules/no-self-import.d.ts +0 -15
  113. package/src/rules/no-unassigned-import.d.ts +0 -20
  114. package/src/rules/no-unresolved.d.ts +0 -20
  115. package/src/rules/no-unused-modules.d.ts +0 -19
  116. package/src/rules/no-useless-path-segments.d.ts +0 -23
  117. package/src/rules/prefer-default-export.d.ts +0 -24
  118. package/src/rules/prefer-direct-import.d.ts +0 -51
  119. package/src/rules/prefer-modern-api.d.ts +0 -47
  120. package/src/rules/prefer-node-protocol.d.ts +0 -19
  121. package/src/rules/prefer-tree-shakeable-imports.d.ts +0 -49
  122. package/src/rules/require-import-approval.d.ts +0 -52
  123. package/src/rules/unambiguous.d.ts +0 -15
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.named = void 0;
9
4
  const tslib_1 = require("tslib");
@@ -20,7 +15,7 @@ exports.named = (0, eslint_devkit_1.createRule)({
20
15
  },
21
16
  messages: {
22
17
  named: (0, eslint_devkit_2.formatLLMMessage)({
23
- icon: eslint_devkit_2.MessageIcons.SECURITY, // Using SECURITY as incorrect imports can be dangerous or break build
18
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
24
19
  issueName: 'Missing Named Export',
25
20
  description: 'Named export not found in module',
26
21
  severity: 'HIGH',
@@ -43,22 +38,18 @@ exports.named = (0, eslint_devkit_1.createRule)({
43
38
  return;
44
39
  const tsNode = services.esTreeNodeToTSNodeMap.get(node.imported);
45
40
  let symbol = checker?.getSymbolAtLocation?.(tsNode);
46
- // Resolve alias if needed
47
41
  if (symbol && (symbol.flags & typescript_1.default.SymbolFlags.Alias)) {
48
42
  try {
49
43
  symbol = checker?.getAliasedSymbol?.(symbol);
50
44
  }
51
45
  catch {
52
- // If resolving alias fails, symbol implies broken import
53
46
  symbol = undefined;
54
47
  }
55
48
  }
56
- // Check if symbol is "unknown" or broken
57
49
  if (symbol && symbol.escapedName === 'unknown') {
58
50
  symbol = undefined;
59
51
  }
60
52
  if (!symbol) {
61
- // Check if module itself resolves
62
53
  const source = node.parent.source;
63
54
  if (!source)
64
55
  return;
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.namespace = void 0;
9
4
  const tslib_1 = require("tslib");
@@ -38,7 +33,6 @@ exports.namespace = (0, eslint_devkit_1.createRule)({
38
33
  const checker = services.program?.getTypeChecker?.();
39
34
  return {
40
35
  MemberExpression(node) {
41
- // Check if object is a namespace import
42
36
  const object = node.object;
43
37
  if (object.type !== 'Identifier')
44
38
  return;
@@ -47,17 +41,13 @@ exports.namespace = (0, eslint_devkit_1.createRule)({
47
41
  if (symbol && symbol.declarations && symbol.declarations.length > 0) {
48
42
  const declaration = symbol.declarations[0];
49
43
  if (declaration.kind === typescript_1.default.SyntaxKind.NamespaceImport) {
50
- // If we have a namespace import, the symbol should refer to the module.
51
- // We need to check if the property being accessed exists on the module exports.
52
44
  if (node.property.type !== 'Identifier')
53
- return; // Computed access might be hard to check
45
+ return;
54
46
  const propertyName = node.property.name;
55
- // This is a bit simplified; we really need to check the type of the symbol
56
47
  const type = checker?.getTypeAtLocation?.(tsNode);
57
48
  if (!type)
58
49
  return;
59
50
  const propertySymbol = checker?.getPropertyOfType?.(type, propertyName);
60
- // Removed erroneous early return here
61
51
  if (!propertySymbol) {
62
52
  context.report({
63
53
  node: node.property,
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.newlineAfterImport = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
@@ -36,13 +31,8 @@ exports.newlineAfterImport = (0, eslint_devkit_1.createRule)({
36
31
  const sourceCode = context.sourceCode;
37
32
  const nextToken = sourceCode.getTokenAfter(node);
38
33
  if (!nextToken)
39
- return; // End of file
40
- // If the next token is on the same line, it's an error (unless it's a comment, but usually imports are on own line)
34
+ return;
41
35
  if (nextToken.loc.start.line === node.loc.end.line) {
42
- // Maybe it's fine if it's another import?
43
- // Wait, logic is: after the *last* import in a block or any import?
44
- // "Enforce a newline after import statements" usually means after the *group* of imports.
45
- // But checking every import: if next node is NOT an import, there should be a blank line.
46
36
  }
47
37
  const nextNode = sourceCode.getNodeByRangeIndex(nextToken.range[0]);
48
38
  if (nextNode &&
@@ -50,14 +40,13 @@ exports.newlineAfterImport = (0, eslint_devkit_1.createRule)({
50
40
  nextNode.type === 'TSImportEqualsDeclaration')) {
51
41
  return;
52
42
  }
53
- // Check lines between
54
43
  if (nextToken.loc.start.line - node.loc.end.line < 2) {
55
44
  context.report({
56
45
  node,
57
46
  messageId: 'newlineAfterImport',
58
47
  fix(fixer) {
59
48
  const linesBetween = nextToken.loc.start.line - node.loc.end.line;
60
- const newlinesToAdd = 2 - linesBetween; // Add enough to make it 2 lines total
49
+ const newlinesToAdd = 2 - linesBetween;
61
50
  return fixer.insertTextAfter(node, '\n'.repeat(newlinesToAdd));
62
51
  },
63
52
  });
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noAbsolutePath = void 0;
9
4
  const tslib_1 = require("tslib");
@@ -93,14 +88,12 @@ exports.noAbsolutePath = (0, eslint_devkit_1.createRule)({
93
88
  if (node.callee.type !== 'Identifier')
94
89
  return;
95
90
  const calleeName = node.callee.name;
96
- // CommonJS require
97
91
  if (commonjs &&
98
92
  calleeName === 'require' &&
99
93
  node.arguments.length === 1 &&
100
94
  node.arguments[0].type === 'Literal') {
101
95
  checkImport(node, node.arguments[0]);
102
96
  }
103
- // AMD define/require
104
97
  if (amd && (calleeName === 'define' || calleeName === 'require')) {
105
98
  node.arguments.forEach((arg) => {
106
99
  if (arg.type === 'Literal') {
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noAmd = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
@@ -56,35 +51,27 @@ exports.noAmd = (0, eslint_devkit_1.createRule)({
56
51
  ],
57
52
  create(context) {
58
53
  const [options] = context.options;
59
- const { allow = [],
60
- // suggestES6 = true // Reserved for future use when hasSuggestions is enabled
61
- } = options || {};
54
+ const { allow = [], } = options || {};
62
55
  const filename = context.filename;
63
56
  function shouldAllow() {
64
- // Check if the call is in an allowed pattern
65
57
  return allow.some((pattern) => {
66
58
  if (!filename)
67
59
  return false;
68
- // Support glob patterns like **/legacy/**
69
60
  if (pattern.includes('**')) {
70
- // Simple glob matching: ** matches any path segment, * matches any name segment
71
61
  const regexPattern = pattern
72
62
  .replace(/\*\*/g, '.*')
73
63
  .replace(/\*/g, '[^/]*');
74
64
  const regex = new RegExp(`^${regexPattern}$`);
75
65
  return regex.test(filename);
76
66
  }
77
- // Simple string matching for non-glob patterns
78
67
  return filename.includes(pattern);
79
68
  });
80
69
  }
81
- // Note: ES6 suggestion generation could be added here when hasSuggestions is enabled
82
70
  return {
83
71
  CallExpression(node) {
84
72
  if (shouldAllow()) {
85
73
  return;
86
74
  }
87
- // Check for define() calls
88
75
  if (node.callee.type === 'Identifier' &&
89
76
  node.callee.name === 'define') {
90
77
  context.report({
@@ -97,16 +84,12 @@ exports.noAmd = (0, eslint_devkit_1.createRule)({
97
84
  },
98
85
  });
99
86
  }
100
- // Check for AMD-style require() calls (not CommonJS)
101
87
  else if (node.callee.type === 'Identifier' &&
102
88
  node.callee.name === 'require' &&
103
89
  node.arguments.length > 0) {
104
90
  const firstArg = node.arguments[0];
105
- // AMD require typically has a callback function as second argument
106
- // or is part of a define() call
107
91
  const hasCallback = node.arguments.length > 1 &&
108
92
  node.arguments[1]?.type === 'FunctionExpression';
109
- // Check if this looks like AMD require (array of deps + callback)
110
93
  if (firstArg.type === 'ArrayExpression' && hasCallback) {
111
94
  context.report({
112
95
  node: node.callee,
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noAnonymousDefaultExport = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
@@ -94,28 +89,20 @@ exports.noAnonymousDefaultExport = (0, eslint_devkit_1.createRule)({
94
89
  case 'FunctionExpression':
95
90
  return !allowFunctionExpression;
96
91
  case 'FunctionDeclaration':
97
- // Function declarations in default exports are anonymous if they have no name
98
- // (e.g., export default function() {}), and should be treated like function expressions
99
92
  return declaration.id ? false : !allowFunctionExpression;
100
93
  case 'ClassDeclaration':
101
- // Class declarations in default exports are anonymous if they have no name
102
- // (e.g., export default class {}), and should be treated like class expressions
103
94
  return declaration.id ? false : !allowClassExpression;
104
95
  case 'CallExpression':
105
- // Allow calls like React.forwardRef(() => ...)
106
- // Allow calls like withRouter(Component)
107
96
  return false;
108
97
  case 'Identifier':
109
98
  case 'Literal':
110
99
  case 'ObjectExpression':
111
100
  case 'ArrayExpression':
112
- // These are not anonymous - they're named references or literals
113
101
  return false;
114
102
  default:
115
103
  return true;
116
104
  }
117
105
  }
118
- // oxlint-disable-next-line consistent-function-scoping
119
106
  function getSuggestionText(node) {
120
107
  const declaration = node.declaration;
121
108
  switch (declaration.type) {
@@ -1,19 +1,10 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noBarrelFile = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
- // Default barrel patterns - index files in various extensions
11
5
  const DEFAULT_BARREL_PATTERNS = [
12
6
  '.*[/\\\\]index\\.(ts|tsx|js|jsx|mts|mjs)$',
13
7
  ];
14
- /**
15
- * Check if a path matches any of the regex patterns
16
- */
17
8
  function matchesPattern(filePath, patterns) {
18
9
  return patterns.some((pattern) => {
19
10
  try {
@@ -21,14 +12,10 @@ function matchesPattern(filePath, patterns) {
21
12
  return regex.test(filePath);
22
13
  }
23
14
  catch {
24
- // Invalid regex, try simple includes
25
15
  return filePath.includes(pattern);
26
16
  }
27
17
  });
28
18
  }
29
- /**
30
- * Check if a node is a re-export statement
31
- */
32
19
  function isReexport(node) {
33
20
  if (node.type === eslint_devkit_1.AST_NODE_TYPES.ExportAllDeclaration) {
34
21
  return true;
@@ -39,12 +26,8 @@ function isReexport(node) {
39
26
  }
40
27
  return false;
41
28
  }
42
- /**
43
- * Check if a node is a local export (not re-exporting from another module)
44
- */
45
29
  function isLocalExport(node) {
46
30
  if (node.type === eslint_devkit_1.AST_NODE_TYPES.ExportNamedDeclaration) {
47
- // Has a declaration (export const x = ...) or no source (export { x })
48
31
  return node.source === null && node.declaration !== null;
49
32
  }
50
33
  if (node.type === eslint_devkit_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
@@ -52,9 +35,6 @@ function isLocalExport(node) {
52
35
  }
53
36
  return false;
54
37
  }
55
- /**
56
- * Count the number of modules being re-exported
57
- */
58
38
  function countReexportSources(reexports, namedReexports) {
59
39
  const sources = new Set();
60
40
  for (const node of reexports) {
@@ -150,15 +130,12 @@ exports.noBarrelFile = (0, eslint_devkit_1.createRule)({
150
130
  create(context, [options = {}]) {
151
131
  const { threshold = 3, allowedPaths = [], barrelPatterns = DEFAULT_BARREL_PATTERNS, allowWithLocalExports = false, reexportRatio = 0.8, } = options || {};
152
132
  const filename = context.filename;
153
- // Check if file matches barrel patterns
154
133
  if (!matchesPattern(filename, barrelPatterns)) {
155
134
  return {};
156
135
  }
157
- // Check if file is in allowed paths
158
136
  if (allowedPaths.length > 0 && matchesPattern(filename, allowedPaths)) {
159
137
  return {};
160
138
  }
161
- // Collect all exports
162
139
  const exportAllDeclarations = [];
163
140
  const namedReexports = [];
164
141
  const localExports = [];
@@ -182,23 +159,16 @@ exports.noBarrelFile = (0, eslint_devkit_1.createRule)({
182
159
  'Program:exit'(node) {
183
160
  const totalReexports = exportAllDeclarations.length + namedReexports.length;
184
161
  const totalExports = totalReexports + localExports.length;
185
- // No exports = not a barrel file
186
162
  if (totalExports === 0) {
187
163
  return;
188
164
  }
189
- // Count unique source modules
190
165
  const sourceCount = countReexportSources(exportAllDeclarations, namedReexports);
191
- // Check if file has local exports
192
166
  const hasLocalExports = localExports.length > 0;
193
- // Skip if allows local exports and has them
194
167
  if (allowWithLocalExports && hasLocalExports) {
195
168
  return;
196
169
  }
197
- // Calculate re-export ratio
198
170
  const ratio = totalReexports / totalExports;
199
- // Check if this is a barrel file
200
171
  if (sourceCount >= threshold && !hasLocalExports) {
201
- // Pure barrel file - definitely flag
202
172
  context.report({
203
173
  node,
204
174
  messageId: 'barrelFileDetected',
@@ -210,8 +180,6 @@ exports.noBarrelFile = (0, eslint_devkit_1.createRule)({
210
180
  else if (hasLocalExports &&
211
181
  sourceCount >= threshold &&
212
182
  ratio >= reexportRatio) {
213
- // Mixed file with high re-export ratio - suggest improvement
214
- // Only applies when there ARE local exports (mixed barrels)
215
183
  context.report({
216
184
  node,
217
185
  messageId: 'considerDirectExports',
@@ -1,15 +1,7 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noBarrelImport = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
- /**
11
- * Check if an import path matches any of the patterns
12
- */
13
5
  function matchesPattern(importPath, patterns) {
14
6
  return patterns.some((pattern) => {
15
7
  try {
@@ -21,23 +13,13 @@ function matchesPattern(importPath, patterns) {
21
13
  }
22
14
  });
23
15
  }
24
- /**
25
- * Check if import path looks like it's from node_modules
26
- */
27
16
  function isNodeModulesImport(importPath) {
28
- // Starts with package name (not relative or absolute)
29
17
  if (importPath.startsWith('.') || importPath.startsWith('/')) {
30
18
  return false;
31
19
  }
32
- // Could be a scoped or regular package
33
20
  return true;
34
21
  }
35
- /**
36
- * Check if import path explicitly references /index
37
- * This is a safe heuristic - explicit index imports are clearly barrel imports
38
- */
39
22
  function endsWithIndex(importPath) {
40
- // Matches: /index, /index.ts, /index.tsx, /index.js, /index.jsx, /index.mjs
41
23
  return /\/index(\.[mc]?[jt]sx?)?$/.test(importPath);
42
24
  }
43
25
  exports.noBarrelImport = (0, eslint_devkit_1.createRule)({
@@ -99,18 +81,14 @@ exports.noBarrelImport = (0, eslint_devkit_1.createRule)({
99
81
  create(context, [options = {}]) {
100
82
  const { knownBarrels = [], ignoreNodeModules = true, ignoredPackages = [], } = options || {};
101
83
  function checkImportPath(node, importPath) {
102
- // Skip node_modules if configured
103
84
  if (ignoreNodeModules && isNodeModulesImport(importPath)) {
104
- // Check if it's an ignored package
105
85
  if (ignoredPackages.length > 0 && matchesPattern(importPath, ignoredPackages)) {
106
86
  return;
107
87
  }
108
- // For node_modules, only flag if explicitly in knownBarrels
109
88
  if (knownBarrels.length === 0) {
110
89
  return;
111
90
  }
112
91
  }
113
- // Check against known barrels first (explicit configuration)
114
92
  if (knownBarrels.length > 0 && matchesPattern(importPath, knownBarrels)) {
115
93
  context.report({
116
94
  node,
@@ -121,8 +99,6 @@ exports.noBarrelImport = (0, eslint_devkit_1.createRule)({
121
99
  });
122
100
  return;
123
101
  }
124
- // Safe heuristic: only flag explicit /index imports (not directory imports)
125
- // We can't distinguish './utils' (directory) from './utils' (file) without FS access
126
102
  if (endsWithIndex(importPath)) {
127
103
  context.report({
128
104
  node,
@@ -140,7 +116,6 @@ exports.noBarrelImport = (0, eslint_devkit_1.createRule)({
140
116
  checkImportPath(node, importPath);
141
117
  }
142
118
  },
143
- // Also check re-exports that import from barrels
144
119
  ExportAllDeclaration(node) {
145
120
  const importPath = node.source.value;
146
121
  if (typeof importPath === 'string') {
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * Copyright (c) 2025 Ofri Peretz
4
- * Licensed under the MIT License. Use of this source code is governed by the
5
- * MIT license that can be found in the LICENSE file.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noCommonjs = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
@@ -104,7 +99,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
104
99
  if (!filename) {
105
100
  return false;
106
101
  }
107
- // Check if file is in allowed list
108
102
  return allowInFiles.some((pattern) => {
109
103
  if (pattern.includes('*')) {
110
104
  const regex = new RegExp(pattern.replace(/\*/g, '.*'));
@@ -114,11 +108,9 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
114
108
  });
115
109
  }
116
110
  function generateES6Suggestion(node) {
117
- // Try to generate ES6 equivalent based on the CommonJS pattern
118
111
  if (node.type === 'CallExpression' &&
119
112
  node.callee.type === 'Identifier' &&
120
113
  node.callee.name === 'require') {
121
- // require('module')
122
114
  const arg = node.arguments[0];
123
115
  if (arg?.type === 'Literal' && typeof arg.value === 'string') {
124
116
  return `// Convert to: import * as moduleName from '${arg.value}';`;
@@ -127,7 +119,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
127
119
  if (node.type === 'AssignmentExpression') {
128
120
  const left = node.left;
129
121
  const right = node.right;
130
- // module.exports = ...
131
122
  if (left.type === 'MemberExpression' &&
132
123
  left.object.type === 'Identifier' &&
133
124
  left.object.name === 'module' &&
@@ -140,7 +131,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
140
131
  return `// Convert to: export default ${context.sourceCode.getText(right)};`;
141
132
  }
142
133
  }
143
- // exports.something = ...
144
134
  if (left.type === 'MemberExpression' &&
145
135
  left.object.type === 'Identifier' &&
146
136
  left.object.name === 'exports' &&
@@ -161,7 +151,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
161
151
  if (shouldAllow() || allowRequire) {
162
152
  return;
163
153
  }
164
- // Check for require() calls
165
154
  if (node.callee.type === 'Identifier' &&
166
155
  node.callee.name === 'require') {
167
156
  context.report({
@@ -191,7 +180,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
191
180
  return;
192
181
  }
193
182
  const left = node.left;
194
- // Check for module.exports = ...
195
183
  if (left.type === 'MemberExpression' &&
196
184
  left.object.type === 'Identifier' &&
197
185
  left.object.name === 'module' &&
@@ -219,7 +207,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
219
207
  : undefined,
220
208
  });
221
209
  }
222
- // Check for module.exports.property = ... (nested)
223
210
  else if (left.type === 'MemberExpression' &&
224
211
  left.object.type === 'MemberExpression' &&
225
212
  left.object.object.type === 'Identifier' &&
@@ -247,7 +234,6 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
247
234
  : undefined,
248
235
  });
249
236
  }
250
- // Check for exports.* = ...
251
237
  else if (left.type === 'MemberExpression' &&
252
238
  left.object.type === 'Identifier' &&
253
239
  left.object.name === 'exports' &&
@@ -274,12 +260,10 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
274
260
  });
275
261
  }
276
262
  },
277
- // Check for TypeScript import = require() syntax
278
263
  TSImportEqualsDeclaration(node) {
279
264
  if (shouldAllow() || allowRequire) {
280
265
  return;
281
266
  }
282
- // Check if it's import x = require('module')
283
267
  if (node.moduleReference.type === 'TSExternalModuleReference') {
284
268
  context.report({
285
269
  node,
@@ -307,13 +291,11 @@ exports.noCommonjs = (0, eslint_devkit_1.createRule)({
307
291
  });
308
292
  }
309
293
  },
310
- // Also check for __dirname, __filename which are CommonJS-specific
311
294
  Identifier(node) {
312
295
  if (shouldAllow()) {
313
296
  return;
314
297
  }
315
298
  if (node.name === '__dirname' || node.name === '__filename') {
316
- // These are CommonJS globals that don't work in ES modules
317
299
  context.report({
318
300
  node,
319
301
  messageId: 'preferES6',