eslint-plugin-barrel-rules 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # **Advanced Barrel Pattern Enforcement for JavaScript/TypeScript Projects**
4
4
 
5
5
  <div align="center">
6
- <img src="https://img.shields.io/badge/version-1.3.1-blue.svg" alt="Version"/>
6
+ <img src="https://img.shields.io/badge/version-1.4.0-blue.svg" alt="Version"/>
7
7
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License"/>
8
8
  <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"/>
9
9
  </div>
@@ -282,6 +282,7 @@ import { SharedUtil } from "@shared/utils"; // allowedImportPaths에 "src/shared
282
282
  - **잘못된 경로 설정 검증 기능** (OK)
283
283
  - **와일드카드 import/export 제한 규칙** (OK)
284
284
  - **지정한 Barrel 경로 격리** (OK)
285
+ - **빈 디렉토리 지원** (예: 'src/shares/\*'가 설정되어 있어도 shares 디렉토리가 비어있어도 됨) (OK)
285
286
 
286
287
  ---
287
288
 
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # **Advanced Barrel Pattern Enforcement for JavaScript/TypeScript Projects**
4
4
 
5
5
  <div align="center">
6
- <img src="https://img.shields.io/badge/version-1.3.1-blue.svg" alt="Version"/>
6
+ <img src="https://img.shields.io/badge/version-1.4.0-blue.svg" alt="Version"/>
7
7
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License"/>
8
8
  <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"/>
9
9
  </div>
@@ -291,6 +291,7 @@ import { SharedUtil } from "@shared/utils"; // if "src/shared/*" is in allowedPa
291
291
  - **Wrong Path Setup Validator** (OK)
292
292
  - **Wildcard Import/Export Protection Rule** (OK)
293
293
  - **Isolation Barrel Module** (OK)
294
+ - **Empty Directory Support** (e.g., 'src/shares/\*' can be configured even if the shares directory is empty) (OK)
294
295
 
295
296
  ---
296
297
 
package/dist/index.cjs CHANGED
@@ -48,11 +48,6 @@ var Glob = class {
48
48
  onlyDirectories: true,
49
49
  absolute: true
50
50
  });
51
- if (globResult.length === 0) {
52
- throw new Error(
53
- `[Glob] In baseDir: ${baseDir}, path: ${path4}, any directory was not found`
54
- );
55
- }
56
51
  return globResult;
57
52
  }
58
53
  };
@@ -190,66 +185,78 @@ var enforceBarrelPattern = {
190
185
  const absoluteTargetPaths = option.paths.flatMap((_path) => {
191
186
  return Glob.resolvePath(_path, baseDir);
192
187
  });
193
- return {
194
- //check only import declaration(ESM)
195
- ImportDeclaration(node) {
196
- const rawImportPath = node.source.value;
197
- const absoluteCurrentFilePath = context.getFilename();
198
- let absoluteImportPath = null;
199
- try {
200
- const aliasResult = Alias.resolvePath(
201
- rawImportPath,
202
- import_path2.default.dirname(absoluteCurrentFilePath)
203
- );
204
- if (aliasResult.type === "success") {
205
- absoluteImportPath = aliasResult.absolutePath;
206
- } else {
207
- if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
208
- return;
209
- }
210
- absoluteImportPath = import_resolve.default.sync(rawImportPath, {
211
- basedir: import_path2.default.dirname(absoluteCurrentFilePath),
212
- extensions: RESOLVE_EXTENSIONS
213
- });
188
+ function checker(node) {
189
+ if (!node.source) {
190
+ return;
191
+ }
192
+ const rawImportPath = node.source.value;
193
+ const absoluteCurrentFilePath = context.getFilename();
194
+ let absoluteImportPath = null;
195
+ try {
196
+ const aliasResult = Alias.resolvePath(
197
+ rawImportPath,
198
+ import_path2.default.dirname(absoluteCurrentFilePath)
199
+ );
200
+ if (aliasResult.type === "success") {
201
+ absoluteImportPath = aliasResult.absolutePath;
202
+ } else {
203
+ if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
204
+ return;
214
205
  }
215
- } catch (e) {
216
- context.report({
217
- node,
218
- messageId: "TransformedAliasResolveFailed"
206
+ absoluteImportPath = import_resolve.default.sync(rawImportPath, {
207
+ basedir: import_path2.default.dirname(absoluteCurrentFilePath),
208
+ extensions: RESOLVE_EXTENSIONS
219
209
  });
220
- return;
221
210
  }
222
- {
223
- let matchedLatestTargetPath = null;
224
- const invalidDirectedImport = absoluteTargetPaths.some(
225
- (absoluteTargetPath) => {
226
- const targetPathEntryPoints = BARREL_ENTRY_POINT_FILE_NAMES.map(
227
- (entry) => import_path2.default.resolve(absoluteTargetPath, entry)
228
- );
229
- const closedTargetPath = absoluteTargetPath + "/";
230
- const targetPathEntryPointed = targetPathEntryPoints.includes(absoluteImportPath);
231
- const importedEnforceBarrelFile = absoluteImportPath.startsWith(closedTargetPath);
232
- const currentFileInEnforceBarrel = absoluteCurrentFilePath.startsWith(closedTargetPath);
233
- const importedOutsideOfTargetPath = !currentFileInEnforceBarrel && importedEnforceBarrelFile;
234
- const invalidImported = !targetPathEntryPointed && importedOutsideOfTargetPath;
235
- if (invalidImported) {
236
- matchedLatestTargetPath = absoluteTargetPath;
237
- }
238
- return invalidImported;
211
+ } catch (e) {
212
+ context.report({
213
+ node,
214
+ messageId: "TransformedAliasResolveFailed"
215
+ });
216
+ return;
217
+ }
218
+ {
219
+ let matchedLatestTargetPath = null;
220
+ const invalidDirectedImport = absoluteTargetPaths.some(
221
+ (absoluteTargetPath) => {
222
+ const targetPathEntryPoints = BARREL_ENTRY_POINT_FILE_NAMES.map(
223
+ (entry) => import_path2.default.resolve(absoluteTargetPath, entry)
224
+ );
225
+ const closedTargetPath = absoluteTargetPath + "/";
226
+ const targetPathEntryPointed = targetPathEntryPoints.includes(absoluteImportPath);
227
+ const importedEnforceBarrelFile = absoluteImportPath.startsWith(closedTargetPath);
228
+ const currentFileInEnforceBarrel = absoluteCurrentFilePath.startsWith(closedTargetPath);
229
+ const importedOutsideOfTargetPath = !currentFileInEnforceBarrel && importedEnforceBarrelFile;
230
+ const invalidImported = !targetPathEntryPointed && importedOutsideOfTargetPath;
231
+ if (invalidImported) {
232
+ matchedLatestTargetPath = absoluteTargetPath;
239
233
  }
240
- );
241
- if (invalidDirectedImport) {
242
- context.report({
243
- node,
244
- messageId: "DirectImportDisallowed",
245
- data: {
246
- rawImportPath,
247
- matchedTargetPath: matchedLatestTargetPath
248
- }
249
- });
234
+ return invalidImported;
250
235
  }
236
+ );
237
+ if (invalidDirectedImport) {
238
+ context.report({
239
+ node,
240
+ messageId: "DirectImportDisallowed",
241
+ data: {
242
+ rawImportPath,
243
+ matchedTargetPath: matchedLatestTargetPath
244
+ }
245
+ });
251
246
  }
252
247
  }
248
+ }
249
+ return {
250
+ ExportNamedDeclaration(node) {
251
+ return checker(node);
252
+ },
253
+ ExportAllDeclaration(node) {
254
+ return checker(node);
255
+ },
256
+ //check only import declaration(ESM)
257
+ ImportDeclaration(node) {
258
+ return checker(node);
259
+ }
253
260
  };
254
261
  }
255
262
  };
package/dist/index.js CHANGED
@@ -12,11 +12,6 @@ var Glob = class {
12
12
  onlyDirectories: true,
13
13
  absolute: true
14
14
  });
15
- if (globResult.length === 0) {
16
- throw new Error(
17
- `[Glob] In baseDir: ${baseDir}, path: ${path4}, any directory was not found`
18
- );
19
- }
20
15
  return globResult;
21
16
  }
22
17
  };
@@ -154,66 +149,78 @@ var enforceBarrelPattern = {
154
149
  const absoluteTargetPaths = option.paths.flatMap((_path) => {
155
150
  return Glob.resolvePath(_path, baseDir);
156
151
  });
157
- return {
158
- //check only import declaration(ESM)
159
- ImportDeclaration(node) {
160
- const rawImportPath = node.source.value;
161
- const absoluteCurrentFilePath = context.getFilename();
162
- let absoluteImportPath = null;
163
- try {
164
- const aliasResult = Alias.resolvePath(
165
- rawImportPath,
166
- path2.dirname(absoluteCurrentFilePath)
167
- );
168
- if (aliasResult.type === "success") {
169
- absoluteImportPath = aliasResult.absolutePath;
170
- } else {
171
- if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
172
- return;
173
- }
174
- absoluteImportPath = resolve.sync(rawImportPath, {
175
- basedir: path2.dirname(absoluteCurrentFilePath),
176
- extensions: RESOLVE_EXTENSIONS
177
- });
152
+ function checker(node) {
153
+ if (!node.source) {
154
+ return;
155
+ }
156
+ const rawImportPath = node.source.value;
157
+ const absoluteCurrentFilePath = context.getFilename();
158
+ let absoluteImportPath = null;
159
+ try {
160
+ const aliasResult = Alias.resolvePath(
161
+ rawImportPath,
162
+ path2.dirname(absoluteCurrentFilePath)
163
+ );
164
+ if (aliasResult.type === "success") {
165
+ absoluteImportPath = aliasResult.absolutePath;
166
+ } else {
167
+ if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
168
+ return;
178
169
  }
179
- } catch (e) {
180
- context.report({
181
- node,
182
- messageId: "TransformedAliasResolveFailed"
170
+ absoluteImportPath = resolve.sync(rawImportPath, {
171
+ basedir: path2.dirname(absoluteCurrentFilePath),
172
+ extensions: RESOLVE_EXTENSIONS
183
173
  });
184
- return;
185
174
  }
186
- {
187
- let matchedLatestTargetPath = null;
188
- const invalidDirectedImport = absoluteTargetPaths.some(
189
- (absoluteTargetPath) => {
190
- const targetPathEntryPoints = BARREL_ENTRY_POINT_FILE_NAMES.map(
191
- (entry) => path2.resolve(absoluteTargetPath, entry)
192
- );
193
- const closedTargetPath = absoluteTargetPath + "/";
194
- const targetPathEntryPointed = targetPathEntryPoints.includes(absoluteImportPath);
195
- const importedEnforceBarrelFile = absoluteImportPath.startsWith(closedTargetPath);
196
- const currentFileInEnforceBarrel = absoluteCurrentFilePath.startsWith(closedTargetPath);
197
- const importedOutsideOfTargetPath = !currentFileInEnforceBarrel && importedEnforceBarrelFile;
198
- const invalidImported = !targetPathEntryPointed && importedOutsideOfTargetPath;
199
- if (invalidImported) {
200
- matchedLatestTargetPath = absoluteTargetPath;
201
- }
202
- return invalidImported;
175
+ } catch (e) {
176
+ context.report({
177
+ node,
178
+ messageId: "TransformedAliasResolveFailed"
179
+ });
180
+ return;
181
+ }
182
+ {
183
+ let matchedLatestTargetPath = null;
184
+ const invalidDirectedImport = absoluteTargetPaths.some(
185
+ (absoluteTargetPath) => {
186
+ const targetPathEntryPoints = BARREL_ENTRY_POINT_FILE_NAMES.map(
187
+ (entry) => path2.resolve(absoluteTargetPath, entry)
188
+ );
189
+ const closedTargetPath = absoluteTargetPath + "/";
190
+ const targetPathEntryPointed = targetPathEntryPoints.includes(absoluteImportPath);
191
+ const importedEnforceBarrelFile = absoluteImportPath.startsWith(closedTargetPath);
192
+ const currentFileInEnforceBarrel = absoluteCurrentFilePath.startsWith(closedTargetPath);
193
+ const importedOutsideOfTargetPath = !currentFileInEnforceBarrel && importedEnforceBarrelFile;
194
+ const invalidImported = !targetPathEntryPointed && importedOutsideOfTargetPath;
195
+ if (invalidImported) {
196
+ matchedLatestTargetPath = absoluteTargetPath;
203
197
  }
204
- );
205
- if (invalidDirectedImport) {
206
- context.report({
207
- node,
208
- messageId: "DirectImportDisallowed",
209
- data: {
210
- rawImportPath,
211
- matchedTargetPath: matchedLatestTargetPath
212
- }
213
- });
198
+ return invalidImported;
214
199
  }
200
+ );
201
+ if (invalidDirectedImport) {
202
+ context.report({
203
+ node,
204
+ messageId: "DirectImportDisallowed",
205
+ data: {
206
+ rawImportPath,
207
+ matchedTargetPath: matchedLatestTargetPath
208
+ }
209
+ });
215
210
  }
216
211
  }
212
+ }
213
+ return {
214
+ ExportNamedDeclaration(node) {
215
+ return checker(node);
216
+ },
217
+ ExportAllDeclaration(node) {
218
+ return checker(node);
219
+ },
220
+ //check only import declaration(ESM)
221
+ ImportDeclaration(node) {
222
+ return checker(node);
223
+ }
217
224
  };
218
225
  }
219
226
  };
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "isolated barrel module",
26
26
  "no-wildcard"
27
27
  ],
28
- "version": "1.3.1",
28
+ "version": "1.4.0",
29
29
  "type": "module",
30
30
  "main": "dist/index.cjs",
31
31
  "module": "dist/index.js",
@@ -49,6 +49,7 @@
49
49
  "typescript": "~5.8.3"
50
50
  },
51
51
  "scripts": {
52
+ "lint": "eslint src/**/*.ts",
52
53
  "build": "pnpm run test && tsup src/index.ts --dts --format cjs,esm",
53
54
  "type-check": "tsc --noEmit",
54
55
  "test": "jest",