eslint-plugin-barrel-rules 1.2.0 → 1.3.1

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.2.0-blue.svg" alt="Version"/>
6
+ <img src="https://img.shields.io/badge/version-1.3.1-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>
@@ -28,7 +28,11 @@ JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제
28
28
  내부 파일을 직접 import하는 것을 차단하여
29
29
  **모듈화, 추상화, 유지보수성, 확장성**을 극대화합니다.
30
30
 
31
- > 💡 Tip:
31
+ > 💡 Tip:
32
+ >
33
+ > > 이 플러그인은 `node_modules`(외부 패키지)의 import는 제한하거나 검사하지 않습니다.
34
+ > > 모든 규칙은 오직 프로젝트 내부(로컬 소스 파일) 경로의 import에만 적용됩니다.
35
+ >
32
36
  > 코드 품질을 더욱 강화하고 싶다면, 이 플러그인과 함께 [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import)의 `no-cycle` 룰을 사용하는 것을 추천합니다.
33
37
  > 이를 통해 프로젝트 내의 순환 참조(Import Cycle)도 효과적으로 감지하고 방지할 수 있습니다.
34
38
 
@@ -58,11 +62,7 @@ JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제
58
62
  `import ... from "../domains/foo/components/Bar"`는 차단)
59
63
 
60
64
  - **Isolation Barrel Module**
61
- 지정한 barrel path 외부의 모듈이 내부 파일을 직접 import하지 못하도록 막을 수 있습니다.
62
- `isolated: true` 옵션을 사용하면 같은 barrel path 내부에서는 자유롭게 import가 가능하고,
63
- 외부에서는 해당 barrel path로의 import가 모두 차단됩니다. (barrel(index) 파일을 통한 접근도 불가)
64
- 만약 특정 공유 import 경로만 허용하고 싶다면 `allowedImportPaths` 옵션을 사용할 수 있습니다.
65
- 이를 통해 각 모듈의 경계를 엄격하게 보호하고, 모듈의 독립성을 유지할 수 있습니다.
65
+ 지정한 barrel path 외부의 모듈이 내부 파일을 직접 import하지 못하도록 막을 수 있습니다.
66
66
 
67
67
  - **와일드카드 import/export 방지**
68
68
  `import * as foo from "module"` 또는 `export * from "./module"`과 같은 와일드카드(네임스페이스) import/export를 금지합니다.
@@ -75,17 +75,13 @@ JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제
75
75
 
76
76
  ## 규칙(Rules)
77
77
 
78
- 1. **enforce-barrel-pattern**
78
+ 1. **enforce-barrel-pattern** (isolate 옵션이 제거되었습니다.)
79
79
  모듈 import 시 barrel 패턴을 강제합니다.
80
80
  지정한 barrel 파일(예: index.ts)로만 import를 허용하고, 내부 모듈에 대한 직접 접근을 차단합니다.
81
- `isolated: true` 옵션을 사용하면 같은 barrel path 내부 파일끼리만 import가 가능하며, 외부에서의 import는 barrel 파일을 통한 접근도 모두 차단됩니다.
82
- `allowedImportPaths` 옵션을 사용하면 특정 공유 import 경로만 예외적으로 허용할 수 있습니다.
83
81
 
84
82
  - **옵션:**
85
83
  - `paths`: barrel 패턴을 적용할 디렉토리 목록(`baseDir` 기준 상대경로)
86
- - `baseDir` (선택): `paths` 기준이 되는 베이스 디렉토리 (기본값: ESLint 실행 디렉토리)
87
- - `isolated` (선택): `true`일 경우, barrel path 외부에서의 모든 import를 차단합니다(barrel 파일 통한 접근 포함). 같은 barrel path 내부 또는 `allowedImportPaths`만 허용.
88
- - `allowedImportPaths` (선택): isolation 모드에서도 직접 import를 허용할 경로 배열
84
+ - `baseDir`: `paths` 기준이 되는 베이스 디렉토리 (기본값: ESLint 실행 디렉토리)
89
85
 
90
86
  2. **no-wildcard**
91
87
  `import * as foo from "module"` 또는 `export * from "./module"`과 같은 와일드카드(네임스페이스) import/export를 금지합니다.
@@ -93,6 +89,14 @@ JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제
93
89
  두 룰을 함께 적용하면 모듈 경계를 엄격하게 지킬 수 있을 뿐만 아니라,
94
90
  트리쉐이킹을 통한 성능 향상과 코드 추적 및 유지보수의 용이성까지 모두 얻을 수 있습니다.
95
91
 
92
+ 3. **isolate-barrel-file** (isolated 기능을 새로운 룰로 제작했습니다.)
93
+ 모듈 import 시 barrel 패턴을 강제합니다.
94
+ 지정한 barrel 파일(예: index.ts)로만 import를 허용하고, 내부 모듈에 대한 직접 접근을 차단합니다.
95
+ - **옵션:**
96
+ - `isolations(Array<{ path: string, allowedPaths: string[] }>)`: `path`와 `allowedPaths`로 구성된 isolation을 추가할 수 있습니다.
97
+ - `baseDir`: `paths` 기준이 되는 베이스 디렉토리 (기본값: ESLint 실행 디렉토리)
98
+ - `globalAllowedPaths` : 모든 isolations에 공통적으로 허용할 경로를 지정합니다(node_modules ... etc)
99
+
96
100
  ---
97
101
 
98
102
  ## 설치
@@ -118,23 +122,43 @@ module.exports = {
118
122
  parser: "@typescript-eslint/parser",
119
123
  plugins: ["@typescript-eslint", "barrel-rules"],
120
124
  rules: {
121
- "barrel-rules/enforce-barrel-pattern": [
122
- "error",
123
- {
124
- // 배럴 파일로 보호할 디렉토리의 경로입니다. baseDir을 기준으로 상대 경로로 설정합니다.
125
- paths: ["src/typescript/barrel/*", "src/javascript/barrel/*"],
126
- // (옵션) 설정하지 않으면 기본값은 ESLint를 실행한 위치(작업 디렉토리)입니다.
127
- // 예: `npx eslint .`처럼 실행하면, 실행 시점의 현재 디렉토리가 기본값이 됩니다.
128
- baseDir: __dirname,
129
- // isolation 모드 활성화: barrel path 외부에서의 모든 import를 차단합니다.
130
- isolated: true,
131
- // "shared" 디렉토리만 직접 import를 허용합니다.
132
- // 필요에 따라 배열에 "node_modules/*" 등 원하는 경로를 자유롭게 추가할 수 있습니다.
133
- allowedImportPaths: ["src/typescript/shared", "node_modules/*"],
134
- },
135
- ],
136
- // import * 또는 export * 금지
137
- "barrel-rules/no-wildcard": ["error"],
125
+
126
+ //barrel-file 캡슐화
127
+ "barrel-rules/enforce-barrel-pattern": [
128
+ "error",
129
+ {
130
+ // encapsulation barrel file
131
+ paths: ["src/pages/*", "src/features/*", "src/entities/*"],
132
+ baseDir: __dirname,
133
+ },
134
+ ],
135
+
136
+ //barrel file내부에서 외부 모듈 사용 제한
137
+ "barrel-rules/isolate-barrel-file": [
138
+ "error",
139
+ {
140
+ //isolation options
141
+ isolations: [
142
+ {
143
+ path: "src/pages/*",
144
+ allowedPaths: ["src/features/*", "src/entities/*"],
145
+ },
146
+ {
147
+ path: "src/features/*",
148
+ allowedPaths: ["src/entities/*"],
149
+ },
150
+ {
151
+ path: "src/entities/*",
152
+ allowedPaths: [],
153
+ },
154
+ ],
155
+ baseDir: __dirname,
156
+ globalAllowPaths: ["src/shares/*", "node_modules/*"],
157
+ },
158
+ ],
159
+
160
+ // "*"를 사용한 불 분명한 import/export 방지
161
+ "barrel-rules/no-wildcard": ["error"],
138
162
  },
139
163
  };
140
164
  ```
@@ -172,22 +196,41 @@ export default tseslint.config([
172
196
  },
173
197
  // barrel-rules에 대한 설정만 추가하면 됩니다.
174
198
  rules: {
199
+ //barrel-file 캡슐화
175
200
  "barrel-rules/enforce-barrel-pattern": [
176
201
  "error",
177
202
  {
178
- // 배럴 파일로 보호할 디렉토리의 경로입니다. baseDir을 기준으로 상대 경로로 설정합니다.
179
- paths: ["src/typescript/barrel/*"],
180
- // (옵션) 설정하지 않으면 기본값은 ESLint를 실행한 위치(작업 디렉토리)입니다.
181
- // 예: `npx eslint .`처럼 실행하면, 실행 시점의 현재 디렉토리가 기본값이 됩니다.
203
+ // encapsulation barrel file
204
+ paths: ["src/pages/*", "src/features/*", "src/entities/*"],
182
205
  baseDir: __dirname,
183
- // isolation 모드 활성화: barrel path 외부에서의 모든 import를 차단합니다.
184
- isolated: true,
185
- // "shared" 디렉토리만 직접 import를 허용합니다.
186
- // 필요에 따라 이 배열에 "node_modules/*" 등 원하는 경로를 자유롭게 추가할 수 있습니다.
187
- allowedImportPaths: ["src/typescript/shared", "node_modules/*"],
188
206
  },
189
207
  ],
190
- // import * 또는 export * 금지
208
+
209
+ //barrel file내부에서 외부 모듈 사용 제한
210
+ "barrel-rules/isolate-barrel-file": [
211
+ "error",
212
+ {
213
+ //isolation options
214
+ isolations: [
215
+ {
216
+ path: "src/pages/*",
217
+ allowedPaths: ["src/features/*", "src/entities/*"],
218
+ },
219
+ {
220
+ path: "src/features/*",
221
+ allowedPaths: ["src/entities/*"],
222
+ },
223
+ {
224
+ path: "src/entities/*",
225
+ allowedPaths: [],
226
+ },
227
+ ],
228
+ baseDir: __dirname,
229
+ globalAllowPaths: ["src/shares/*"],
230
+ },
231
+ ],
232
+
233
+ // "*"를 사용한 불 분명한 import/export 방지
191
234
  "barrel-rules/no-wildcard": ["error"],
192
235
  },
193
236
  },
@@ -218,8 +261,6 @@ file(src / domains / foo / index.ts);
218
261
  // ❌ 격리된 barrel로의 외부 import 차단 (alias 사용해도 차단)
219
262
  // barrel 외부에서 접근 (bar의 경로는 src/domains/bar/)
220
263
  import { Test } from "@domains/bar/components/Test";
221
- // 또는
222
- import { Test } from "../domains/bar";
223
264
 
224
265
  // ✅ 같은 barrel 내부에서의 import는 허용 (alias 지원)
225
266
  import { Hook } from "@domains/foo/hooks/useTest"; // 같은 barrel 내부에서
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.2.0-blue.svg" alt="Version"/>
6
+ <img src="https://img.shields.io/badge/version-1.3.1-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>
@@ -32,6 +32,9 @@ Direct imports from internal files are blocked, maximizing
32
32
  **modularity, abstraction, maintainability, and scalability**.
33
33
 
34
34
  > 💡 Tip:
35
+ > This plugin does not restrict or track imports from `node_modules` (external packages).
36
+ > The rules only apply to imports of internal (local source file) paths within your project.
37
+ >
35
38
  > For even stronger code quality, we recommend using the `no-cycle` rule from [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) together with this plugin.
36
39
  > This allows you to detect and prevent circular dependencies (import cycles) in your project.
37
40
 
@@ -60,10 +63,9 @@ Direct imports from internal files are blocked, maximizing
60
63
 
61
64
  - **Isolation Barrel Module**
62
65
  You can prevent modules outside the specified barrel path from directly importing internal files.
63
- By enabling `isolated: true`, only files within the same barrel path can freely import each other.
66
+ By enabling `isolate-barrel-file`, only files within the same barrel path can freely import each other.
64
67
  Any import from outside the enforced barrel path is completely blocked, even if it tries to import via the barrel (index) file.
65
- If you want to allow specific shared imports, you can use the `allowedImportPaths` option.
66
- This helps you strictly protect your module boundaries and keep each module truly independent.
68
+ If you want to allow specific shared imports, you can use the `allowedPaths` or `globalAllowedPaths` option.
67
69
 
68
70
  - **Prevent Wildcard Import/Export**
69
71
  Disallows wildcard (namespace) imports and exports such as `import * as foo from "module"` or `export * from "./module"`.
@@ -76,17 +78,13 @@ Direct imports from internal files are blocked, maximizing
76
78
 
77
79
  ## Rules
78
80
 
79
- 1. **enforce-barrel-pattern**
81
+ 1. **enforce-barrel-pattern** (Isolation is exracted as new rule :))
80
82
  Enforces the barrel pattern for module imports.
81
83
  Only allows imports from designated barrel files and prevents direct access to internal modules.
82
- When `isolated: true` is set, only files within the same barrel path can import each other, and any import from outside the barrel path is completely blocked (even via the barrel file).
83
- You can allow specific shared import paths by using the `allowedImportPaths` option.
84
84
 
85
85
  - **Options:**
86
86
  - `paths`: The directories to be protected by the barrel pattern (relative to `baseDir`).
87
- - `baseDir` (optional): The base directory for resolving `paths`. Defaults to the ESLint execution directory.
88
- - `isolated` (optional): If `true`, blocks all imports from outside the barrel path, even via the barrel file. Only allows imports within the same barrel path or from `allowedImportPaths`.
89
- - `allowedImportPaths` (optional): Array of paths that are allowed to be imported directly, even in isolation mode.
87
+ - `baseDir`: The base directory for resolving `paths`. Defaults to the ESLint execution directory.
90
88
 
91
89
  2. **no-wildcard**
92
90
  Disallows wildcard (namespace) imports such as `import * as foo from "module"` or `export * from "./module"`.
@@ -94,6 +92,14 @@ Direct imports from internal files are blocked, maximizing
94
92
  Using both rules together not only enforces strict module boundaries,
95
93
  but also improves performance through better tree-shaking and makes code tracing and maintenance much easier.
96
94
 
95
+ 3. **isolate-barrel-file** (New Rules!!!)
96
+ Only files within the same barrel path can import each other, and any import from outside the barrel path is completely blocked (even via the barrel file).
97
+ You can allow specific shared import paths by using the `allowedPaths` option.
98
+ - **Options:**
99
+ - `isolations(Array<{ path: string, allowedPaths: string[] }>)`: If you set isolation path, blocks all imports from outside the barrel path, even via the barrel file. Only allows imports within the same barrel path or from `allowedPaths` or `globalAllowedPaths`.
100
+ - `baseDir`: The base directory for resolving `paths`. Defaults to the ESLint execution directory.
101
+ - `globalAllowedPaths` : Array of paths that are allowed to be imported directly, even in isolation mode.
102
+
97
103
  ---
98
104
 
99
105
  ## Install
@@ -119,23 +125,44 @@ module.exports = {
119
125
  parser: "@typescript-eslint/parser",
120
126
  plugins: ["@typescript-eslint", "barrel-rules"],
121
127
  rules: {
122
- "barrel-rules/enforce-barrel-pattern": [
123
- "error",
124
- {
125
- // The path to the directory that should be protected by using a barrel file. This path is relative to baseDir.
126
- paths: ["src/typescript/barrel/*", "src/javascript/barrel/*"],
127
- // Optional config. The default value is the directory where ESLint is executed.
128
- // For example, if you run `npx eslint .`, the default will be the current working directory at the time of execution.
129
- baseDir: __dirname,
130
- // Enable isolation mode: block all imports from outside the barrel path
131
- isolated: true,
132
- // Allow direct imports only from the "shared" directory.
133
- // You can customize this array as needed, e.g., add "node_modules/..." or any other path you want to allow.
134
- allowedImportPaths: ["src/typescript/shared", "node_modules/*"],
135
- },
136
- ],
137
- // Disallow wildcard (namespace) import/export.
138
- "barrel-rules/no-wildcard": ["error"],
128
+
129
+ //enforce barrel capsuling
130
+ "barrel-rules/enforce-barrel-pattern": [
131
+ "error",
132
+ {
133
+ // encapsulation barrel file
134
+ paths: ["src/pages/*", "src/features/*", "src/entities/*"],
135
+ baseDir: __dirname,
136
+ },
137
+ ],
138
+
139
+ //protect barrel file from outside module
140
+ "barrel-rules/isolate-barrel-file": [
141
+ "error",
142
+ {
143
+ //isolation options
144
+ isolations: [
145
+ {
146
+ path: "src/pages/*",
147
+ allowedPaths: ["src/features/*", "src/entities/*"],
148
+ },
149
+ {
150
+ path: "src/features/*",
151
+ allowedPaths: ["src/entities/*"],
152
+ },
153
+ {
154
+ path: "src/entities/*",
155
+ allowedPaths: [],
156
+ },
157
+ ],
158
+ baseDir: __dirname,
159
+ globalAllowPaths: ["src/shares/*", "node_modules/*"],
160
+ },
161
+ ],
162
+
163
+ // protect wildcard import/export
164
+ "barrel-rules/no-wildcard": ["error"],
165
+
139
166
  },
140
167
  };
141
168
  ```
@@ -173,23 +200,44 @@ export default tseslint.config([
173
200
  },
174
201
  //just set your setting for barrel-rules
175
202
  rules: {
203
+
204
+ //enforce barrel capsuling
176
205
  "barrel-rules/enforce-barrel-pattern": [
177
206
  "error",
178
207
  {
179
- // The path to the directory that should be protected by using a barrel file. This path is relative to baseDir.
180
- paths: ["src/typescript/barrel/*"],
181
- // Optional config. The default value is the directory where ESLint is executed.
182
- // For example, if you run `npx eslint .`, the default will be the current working directory at the time of execution.
208
+ // encapsulation barrel file
209
+ paths: ["src/pages/*", "src/features/*", "src/entities/*"],
183
210
  baseDir: __dirname,
184
- // Enable isolation mode: block all imports from outside the barrel path
185
- isolated: true,
186
- // Allow direct imports only from the "shared" directory.
187
- // You can customize this array as needed, e.g., add "node_modules/*" or any other path you want to allow.
188
- allowedImportPaths: ["src/typescript/shared", "node_modules/*"],
189
211
  },
190
212
  ],
191
- // Disallow wildcard (namespace) import/export.
213
+
214
+ //protect barrel file from outside module
215
+ "barrel-rules/isolate-barrel-file": [
216
+ "error",
217
+ {
218
+ //isolation options
219
+ isolations: [
220
+ {
221
+ path: "src/pages/*",
222
+ allowedPaths: ["src/features/*", "src/entities/*"],
223
+ },
224
+ {
225
+ path: "src/features/*",
226
+ allowedPaths: ["src/entities/*"],
227
+ },
228
+ {
229
+ path: "src/entities/*",
230
+ allowedPaths: [],
231
+ },
232
+ ],
233
+ baseDir: __dirname,
234
+ globalAllowPaths: ["src/shares/*"],
235
+ },
236
+ ],
237
+
238
+ // protect wildcard import/export
192
239
  "barrel-rules/no-wildcard": ["error"],
240
+
193
241
  },
194
242
  },
195
243
  ]);
@@ -219,15 +267,13 @@ file(src / domains / foo / index.ts);
219
267
  // ❌ External import to isolated barrel is blocked (even with alias)
220
268
  // from outside barrel (bar's path is src/domains/bar/)
221
269
  import { Test } from "@domains/bar/components/Test";
222
- // or
223
- import { Test } from "../domains/bar";
224
270
 
225
271
  // ✅ Internal imports within same barrel are allowed (alias supported)
226
272
  import { Hook } from "@domains/foo/hooks/useTest"; // from inside same barrel
227
273
  import { Utils } from "./utils/helper"; // from inside same barrel
228
274
 
229
275
  // ✅ Allowed import paths are permitted (alias supported)
230
- import { SharedUtil } from "@shㅇㅇared/utils"; // if "src/shared/*" is in allowedImportPaths
276
+ import { SharedUtil } from "@shared/utils"; // if "src/shared/*" is in allowedPaths or globalAllowedPaths
231
277
  ```
232
278
 
233
279
  ---
package/dist/index.cjs CHANGED
@@ -35,22 +35,22 @@ __export(index_exports, {
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // src/rules/enforce-barrel-pattern.ts
38
- var import_utils = require("@typescript-eslint/utils");
38
+ var import_types = require("@typescript-eslint/types");
39
39
  var import_path2 = __toESM(require("path"), 1);
40
40
  var import_resolve = __toESM(require("resolve"), 1);
41
41
 
42
42
  // src/utils/glob.ts
43
43
  var import_fast_glob = __toESM(require("fast-glob"), 1);
44
44
  var Glob = class {
45
- static resolvePath(path3, baseDir) {
46
- const globResult = import_fast_glob.default.sync(path3, {
45
+ static resolvePath(path4, baseDir) {
46
+ const globResult = import_fast_glob.default.sync(path4, {
47
47
  cwd: baseDir,
48
48
  onlyDirectories: true,
49
49
  absolute: true
50
50
  });
51
51
  if (globResult.length === 0) {
52
52
  throw new Error(
53
- `[Glob] In baseDir: ${baseDir}, path: ${path3}, any directory was not found`
53
+ `[Glob] In baseDir: ${baseDir}, path: ${path4}, any directory was not found`
54
54
  );
55
55
  }
56
56
  return globResult;
@@ -123,13 +123,20 @@ var BARREL_ENTRY_POINT_FILE_NAMES = [
123
123
  ];
124
124
  var RESOLVE_EXTENSIONS = [
125
125
  ".ts",
126
- ".tsx",
127
126
  ".js",
127
+ ".tsx",
128
128
  ".jsx",
129
129
  ".json",
130
+ ".d.js",
130
131
  ".d.ts",
131
132
  ".mjs",
132
- ".cjs"
133
+ ".cjs",
134
+ ".mts",
135
+ ".cts",
136
+ ".d.mjs",
137
+ ".d.cjs",
138
+ ".d.mts",
139
+ ".d.cts"
133
140
  ];
134
141
  var enforceBarrelPattern = {
135
142
  meta: {
@@ -142,37 +149,47 @@ var enforceBarrelPattern = {
142
149
  type: "object",
143
150
  properties: {
144
151
  paths: { type: "array", items: { type: "string" } },
145
- baseDir: { type: "string" },
146
- isolated: { type: "boolean" },
147
- allowedImportPaths: { type: "array", items: { type: "string" } }
152
+ baseDir: { type: "string" }
148
153
  },
149
- required: ["paths"],
154
+ required: ["paths", "baseDir"],
150
155
  additionalProperties: false
151
156
  }
152
157
  ],
153
158
  messages: {
159
+ TransformedAliasResolveFailed: "Transformed alias resolve failed. please check the alias config.",
154
160
  DirectImportDisallowed: "Please import from '{{matchedTargetPath}}'. Direct access to '{{rawImportPath}}' is not allowed. You must use the barrel pattern and only consume APIs exposed externally. This is to ensure encapsulation of internal logic and maintain module boundaries.",
155
- IsolatedBarrelImportDisallowed: "This barrel file is isolated. external import is not allowed. if you want to import outside of the barrel file, please add 'allowedImportPaths' to the plugin options."
161
+ EmptyEslintConfig: "Please set the eslint config '{{property}}' to the eslint config. if you want to use this rule, please set the eslint config."
156
162
  }
157
163
  },
158
164
  //default options(baseDir is current working directory. almost user execute eslint in project root)
159
165
  defaultOptions: [
160
166
  {
161
167
  paths: [],
162
- baseDir: process.cwd(),
163
- isolated: false,
164
- allowedImportPaths: []
168
+ baseDir: process.cwd()
165
169
  }
166
170
  ],
167
171
  create(context) {
168
172
  const option = context.options[0];
173
+ if (!option) {
174
+ return {
175
+ Program(node) {
176
+ const option2 = context.options[0];
177
+ if (!option2) {
178
+ return context.report({
179
+ node,
180
+ messageId: "EmptyEslintConfig",
181
+ data: {
182
+ property: "{ path: Array<string>, baseDir: string }"
183
+ }
184
+ });
185
+ }
186
+ }
187
+ };
188
+ }
169
189
  const baseDir = option.baseDir;
170
190
  const absoluteTargetPaths = option.paths.flatMap((_path) => {
171
191
  return Glob.resolvePath(_path, baseDir);
172
192
  });
173
- const allowedImportPaths = option.allowedImportPaths.flatMap((_path) => {
174
- return Glob.resolvePath(_path, baseDir);
175
- });
176
193
  return {
177
194
  //check only import declaration(ESM)
178
195
  ImportDeclaration(node) {
@@ -187,12 +204,19 @@ var enforceBarrelPattern = {
187
204
  if (aliasResult.type === "success") {
188
205
  absoluteImportPath = aliasResult.absolutePath;
189
206
  } else {
207
+ if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
208
+ return;
209
+ }
190
210
  absoluteImportPath = import_resolve.default.sync(rawImportPath, {
191
211
  basedir: import_path2.default.dirname(absoluteCurrentFilePath),
192
212
  extensions: RESOLVE_EXTENSIONS
193
213
  });
194
214
  }
195
215
  } catch (e) {
216
+ context.report({
217
+ node,
218
+ messageId: "TransformedAliasResolveFailed"
219
+ });
196
220
  return;
197
221
  }
198
222
  {
@@ -225,34 +249,138 @@ var enforceBarrelPattern = {
225
249
  });
226
250
  }
227
251
  }
228
- {
229
- if (option.isolated) {
230
- const currentFileInEnforceBarrel = absoluteTargetPaths.some(
231
- (absoluteTargetPath) => {
232
- const closedTargetPath = absoluteTargetPath + "/";
233
- return absoluteCurrentFilePath.startsWith(closedTargetPath);
234
- }
235
- );
236
- const sameBarrel = absoluteTargetPaths.some(
237
- (absoluteTargetPath) => {
238
- const closedTargetPath = absoluteTargetPath + "/";
239
- const importedEnforceBarrelFile = absoluteImportPath.startsWith(closedTargetPath);
240
- const currentFileInEnforceBarrel2 = absoluteCurrentFilePath.startsWith(closedTargetPath);
241
- return importedEnforceBarrelFile && currentFileInEnforceBarrel2;
242
- }
243
- );
244
- const allowedImportPath = allowedImportPaths.some(
245
- (allowedImportPath2) => {
246
- return absoluteImportPath.startsWith(allowedImportPath2);
247
- }
248
- );
249
- if (!allowedImportPath && !sameBarrel && currentFileInEnforceBarrel) {
250
- context.report({
251
- node,
252
- messageId: "IsolatedBarrelImportDisallowed"
253
- });
252
+ }
253
+ };
254
+ }
255
+ };
256
+
257
+ // src/rules/isolate-barrel-file.ts
258
+ var import_types2 = require("@typescript-eslint/types");
259
+ var import_path3 = __toESM(require("path"), 1);
260
+ var import_resolve2 = __toESM(require("resolve"), 1);
261
+ var RESOLVE_EXTENSIONS2 = [
262
+ ".ts",
263
+ ".js",
264
+ ".tsx",
265
+ ".jsx",
266
+ ".json",
267
+ ".d.js",
268
+ ".d.ts",
269
+ ".mjs",
270
+ ".cjs",
271
+ ".mts",
272
+ ".cts",
273
+ ".d.mjs",
274
+ ".d.cjs",
275
+ ".d.mts",
276
+ ".d.cts"
277
+ ];
278
+ var isolateBarrelFile = {
279
+ meta: {
280
+ type: "problem",
281
+ docs: {
282
+ description: "Isolate barrel file is not allowed to import outside of the barrel file"
283
+ },
284
+ schema: [
285
+ {
286
+ type: "object",
287
+ properties: {
288
+ isolations: { type: "array", items: { type: "object" } },
289
+ baseDir: { type: "string" },
290
+ globalAllowPaths: { type: "array", items: { type: "string" } }
291
+ },
292
+ required: ["isolations", "baseDir", "globalAllowPaths"],
293
+ additionalProperties: false
294
+ }
295
+ ],
296
+ messages: {
297
+ TransformedAliasResolveFailed: "Transformed alias resolve failed. please check the alias config.",
298
+ IsolatedBarrelImportDisallowed: "This barrel file is isolated. external import is not allowed. if you want to import outside of the barrel file, please add 'allowedPath' to the plugin options."
299
+ }
300
+ },
301
+ //default options(baseDir is current working directory. almost user execute eslint in project root)
302
+ defaultOptions: [
303
+ {
304
+ isolations: [],
305
+ baseDir: process.cwd(),
306
+ globalAllowPaths: []
307
+ }
308
+ ],
309
+ create(context) {
310
+ const option = context.options[0];
311
+ const baseDir = option.baseDir;
312
+ const absoluteGlobalAllowPaths = option.globalAllowPaths.flatMap((path4) => {
313
+ return Glob.resolvePath(path4, baseDir);
314
+ });
315
+ const absoluteIsolations = option.isolations.flatMap((isolation) => {
316
+ const isolationPaths = Glob.resolvePath(isolation.path, baseDir);
317
+ const allowedPaths = isolation.allowedPaths.flatMap((path4) => {
318
+ return Glob.resolvePath(path4, baseDir);
319
+ });
320
+ return isolationPaths.map((isolationPath) => ({
321
+ isolationPath,
322
+ //self isolatedPath also allowed to be imported
323
+ allowedPaths: [...allowedPaths, isolationPath]
324
+ }));
325
+ });
326
+ return {
327
+ //check only import declaration(ESM)
328
+ ImportDeclaration(node) {
329
+ const rawImportPath = node.source.value;
330
+ const absoluteCurrentFilePath = context.getFilename();
331
+ let absoluteImportPath = null;
332
+ try {
333
+ const aliasResult = Alias.resolvePath(
334
+ rawImportPath,
335
+ import_path3.default.dirname(absoluteCurrentFilePath)
336
+ );
337
+ if (aliasResult.type === "success") {
338
+ absoluteImportPath = aliasResult.absolutePath;
339
+ } else {
340
+ if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
341
+ return;
254
342
  }
343
+ absoluteImportPath = import_resolve2.default.sync(rawImportPath, {
344
+ basedir: import_path3.default.dirname(absoluteCurrentFilePath),
345
+ extensions: RESOLVE_EXTENSIONS2
346
+ });
255
347
  }
348
+ } catch (e) {
349
+ context.report({
350
+ node,
351
+ messageId: "TransformedAliasResolveFailed"
352
+ });
353
+ return;
354
+ }
355
+ const isolationIndex = absoluteIsolations.findIndex((isolation) => {
356
+ const absoluteIsolationPath = isolation.isolationPath;
357
+ const closedIsolationPath = absoluteIsolationPath + "/";
358
+ return absoluteCurrentFilePath.startsWith(closedIsolationPath);
359
+ });
360
+ const matchedIsolation = absoluteIsolations[isolationIndex];
361
+ if (!matchedIsolation) return;
362
+ const isAllowedImport = matchedIsolation.allowedPaths.some(
363
+ (allowedPath) => {
364
+ const same = absoluteImportPath === allowedPath;
365
+ const closedAllowedPath = allowedPath + "/";
366
+ const sub = absoluteImportPath.startsWith(closedAllowedPath);
367
+ return same || sub;
368
+ }
369
+ );
370
+ const isGlobalAllowedImport = absoluteGlobalAllowPaths.some(
371
+ (allowedPath) => {
372
+ const same = absoluteImportPath === allowedPath;
373
+ const closedAllowedPath = allowedPath + "/";
374
+ const sub = absoluteImportPath.startsWith(closedAllowedPath);
375
+ return same || sub;
376
+ }
377
+ );
378
+ const allowedImport = isAllowedImport || isGlobalAllowedImport;
379
+ if (!allowedImport) {
380
+ context.report({
381
+ node,
382
+ messageId: "IsolatedBarrelImportDisallowed"
383
+ });
256
384
  }
257
385
  }
258
386
  };
@@ -260,7 +388,7 @@ var enforceBarrelPattern = {
260
388
  };
261
389
 
262
390
  // src/rules/no-wildcard.ts
263
- var import_utils2 = require("@typescript-eslint/utils");
391
+ var import_types3 = require("@typescript-eslint/types");
264
392
  var noWildcard = {
265
393
  meta: {
266
394
  type: "problem",
@@ -300,6 +428,7 @@ var noWildcard = {
300
428
  // src/index.ts
301
429
  var rules = {
302
430
  "enforce-barrel-pattern": enforceBarrelPattern,
431
+ "isolate-barrel-file": isolateBarrelFile,
303
432
  "no-wildcard": noWildcard
304
433
  };
305
434
  var index_default = { rules };
package/dist/index.d.cts CHANGED
@@ -2,11 +2,17 @@ import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts
2
2
 
3
3
  declare const _default: {
4
4
  rules: {
5
- "enforce-barrel-pattern": _typescript_eslint_utils_ts_eslint.RuleModule<"DirectImportDisallowed" | "IsolatedBarrelImportDisallowed", {
5
+ "enforce-barrel-pattern": _typescript_eslint_utils_ts_eslint.RuleModule<"DirectImportDisallowed" | "TransformedAliasResolveFailed" | "EmptyEslintConfig", {
6
6
  paths: string[];
7
7
  baseDir: string;
8
- isolated: boolean;
9
- allowedImportPaths: string[];
8
+ }[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
9
+ "isolate-barrel-file": _typescript_eslint_utils_ts_eslint.RuleModule<"TransformedAliasResolveFailed" | "IsolatedBarrelImportDisallowed", {
10
+ isolations: {
11
+ path: string;
12
+ allowedPaths: string[];
13
+ }[];
14
+ baseDir: string;
15
+ globalAllowPaths: string[];
10
16
  }[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
11
17
  "no-wildcard": _typescript_eslint_utils_ts_eslint.RuleModule<"NoWildcardImport" | "NoExportAll", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
12
18
  };
package/dist/index.d.ts CHANGED
@@ -2,11 +2,17 @@ import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts
2
2
 
3
3
  declare const _default: {
4
4
  rules: {
5
- "enforce-barrel-pattern": _typescript_eslint_utils_ts_eslint.RuleModule<"DirectImportDisallowed" | "IsolatedBarrelImportDisallowed", {
5
+ "enforce-barrel-pattern": _typescript_eslint_utils_ts_eslint.RuleModule<"DirectImportDisallowed" | "TransformedAliasResolveFailed" | "EmptyEslintConfig", {
6
6
  paths: string[];
7
7
  baseDir: string;
8
- isolated: boolean;
9
- allowedImportPaths: string[];
8
+ }[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
9
+ "isolate-barrel-file": _typescript_eslint_utils_ts_eslint.RuleModule<"TransformedAliasResolveFailed" | "IsolatedBarrelImportDisallowed", {
10
+ isolations: {
11
+ path: string;
12
+ allowedPaths: string[];
13
+ }[];
14
+ baseDir: string;
15
+ globalAllowPaths: string[];
10
16
  }[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
11
17
  "no-wildcard": _typescript_eslint_utils_ts_eslint.RuleModule<"NoWildcardImport" | "NoExportAll", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
12
18
  };
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
1
  // src/rules/enforce-barrel-pattern.ts
2
- import "@typescript-eslint/utils";
2
+ import "@typescript-eslint/types";
3
3
  import path2 from "path";
4
4
  import resolve from "resolve";
5
5
 
6
6
  // src/utils/glob.ts
7
7
  import FastGlob from "fast-glob";
8
8
  var Glob = class {
9
- static resolvePath(path3, baseDir) {
10
- const globResult = FastGlob.sync(path3, {
9
+ static resolvePath(path4, baseDir) {
10
+ const globResult = FastGlob.sync(path4, {
11
11
  cwd: baseDir,
12
12
  onlyDirectories: true,
13
13
  absolute: true
14
14
  });
15
15
  if (globResult.length === 0) {
16
16
  throw new Error(
17
- `[Glob] In baseDir: ${baseDir}, path: ${path3}, any directory was not found`
17
+ `[Glob] In baseDir: ${baseDir}, path: ${path4}, any directory was not found`
18
18
  );
19
19
  }
20
20
  return globResult;
@@ -87,13 +87,20 @@ var BARREL_ENTRY_POINT_FILE_NAMES = [
87
87
  ];
88
88
  var RESOLVE_EXTENSIONS = [
89
89
  ".ts",
90
- ".tsx",
91
90
  ".js",
91
+ ".tsx",
92
92
  ".jsx",
93
93
  ".json",
94
+ ".d.js",
94
95
  ".d.ts",
95
96
  ".mjs",
96
- ".cjs"
97
+ ".cjs",
98
+ ".mts",
99
+ ".cts",
100
+ ".d.mjs",
101
+ ".d.cjs",
102
+ ".d.mts",
103
+ ".d.cts"
97
104
  ];
98
105
  var enforceBarrelPattern = {
99
106
  meta: {
@@ -106,37 +113,47 @@ var enforceBarrelPattern = {
106
113
  type: "object",
107
114
  properties: {
108
115
  paths: { type: "array", items: { type: "string" } },
109
- baseDir: { type: "string" },
110
- isolated: { type: "boolean" },
111
- allowedImportPaths: { type: "array", items: { type: "string" } }
116
+ baseDir: { type: "string" }
112
117
  },
113
- required: ["paths"],
118
+ required: ["paths", "baseDir"],
114
119
  additionalProperties: false
115
120
  }
116
121
  ],
117
122
  messages: {
123
+ TransformedAliasResolveFailed: "Transformed alias resolve failed. please check the alias config.",
118
124
  DirectImportDisallowed: "Please import from '{{matchedTargetPath}}'. Direct access to '{{rawImportPath}}' is not allowed. You must use the barrel pattern and only consume APIs exposed externally. This is to ensure encapsulation of internal logic and maintain module boundaries.",
119
- IsolatedBarrelImportDisallowed: "This barrel file is isolated. external import is not allowed. if you want to import outside of the barrel file, please add 'allowedImportPaths' to the plugin options."
125
+ EmptyEslintConfig: "Please set the eslint config '{{property}}' to the eslint config. if you want to use this rule, please set the eslint config."
120
126
  }
121
127
  },
122
128
  //default options(baseDir is current working directory. almost user execute eslint in project root)
123
129
  defaultOptions: [
124
130
  {
125
131
  paths: [],
126
- baseDir: process.cwd(),
127
- isolated: false,
128
- allowedImportPaths: []
132
+ baseDir: process.cwd()
129
133
  }
130
134
  ],
131
135
  create(context) {
132
136
  const option = context.options[0];
137
+ if (!option) {
138
+ return {
139
+ Program(node) {
140
+ const option2 = context.options[0];
141
+ if (!option2) {
142
+ return context.report({
143
+ node,
144
+ messageId: "EmptyEslintConfig",
145
+ data: {
146
+ property: "{ path: Array<string>, baseDir: string }"
147
+ }
148
+ });
149
+ }
150
+ }
151
+ };
152
+ }
133
153
  const baseDir = option.baseDir;
134
154
  const absoluteTargetPaths = option.paths.flatMap((_path) => {
135
155
  return Glob.resolvePath(_path, baseDir);
136
156
  });
137
- const allowedImportPaths = option.allowedImportPaths.flatMap((_path) => {
138
- return Glob.resolvePath(_path, baseDir);
139
- });
140
157
  return {
141
158
  //check only import declaration(ESM)
142
159
  ImportDeclaration(node) {
@@ -151,12 +168,19 @@ var enforceBarrelPattern = {
151
168
  if (aliasResult.type === "success") {
152
169
  absoluteImportPath = aliasResult.absolutePath;
153
170
  } else {
171
+ if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
172
+ return;
173
+ }
154
174
  absoluteImportPath = resolve.sync(rawImportPath, {
155
175
  basedir: path2.dirname(absoluteCurrentFilePath),
156
176
  extensions: RESOLVE_EXTENSIONS
157
177
  });
158
178
  }
159
179
  } catch (e) {
180
+ context.report({
181
+ node,
182
+ messageId: "TransformedAliasResolveFailed"
183
+ });
160
184
  return;
161
185
  }
162
186
  {
@@ -189,34 +213,138 @@ var enforceBarrelPattern = {
189
213
  });
190
214
  }
191
215
  }
192
- {
193
- if (option.isolated) {
194
- const currentFileInEnforceBarrel = absoluteTargetPaths.some(
195
- (absoluteTargetPath) => {
196
- const closedTargetPath = absoluteTargetPath + "/";
197
- return absoluteCurrentFilePath.startsWith(closedTargetPath);
198
- }
199
- );
200
- const sameBarrel = absoluteTargetPaths.some(
201
- (absoluteTargetPath) => {
202
- const closedTargetPath = absoluteTargetPath + "/";
203
- const importedEnforceBarrelFile = absoluteImportPath.startsWith(closedTargetPath);
204
- const currentFileInEnforceBarrel2 = absoluteCurrentFilePath.startsWith(closedTargetPath);
205
- return importedEnforceBarrelFile && currentFileInEnforceBarrel2;
206
- }
207
- );
208
- const allowedImportPath = allowedImportPaths.some(
209
- (allowedImportPath2) => {
210
- return absoluteImportPath.startsWith(allowedImportPath2);
211
- }
212
- );
213
- if (!allowedImportPath && !sameBarrel && currentFileInEnforceBarrel) {
214
- context.report({
215
- node,
216
- messageId: "IsolatedBarrelImportDisallowed"
217
- });
216
+ }
217
+ };
218
+ }
219
+ };
220
+
221
+ // src/rules/isolate-barrel-file.ts
222
+ import "@typescript-eslint/types";
223
+ import path3 from "path";
224
+ import resolve2 from "resolve";
225
+ var RESOLVE_EXTENSIONS2 = [
226
+ ".ts",
227
+ ".js",
228
+ ".tsx",
229
+ ".jsx",
230
+ ".json",
231
+ ".d.js",
232
+ ".d.ts",
233
+ ".mjs",
234
+ ".cjs",
235
+ ".mts",
236
+ ".cts",
237
+ ".d.mjs",
238
+ ".d.cjs",
239
+ ".d.mts",
240
+ ".d.cts"
241
+ ];
242
+ var isolateBarrelFile = {
243
+ meta: {
244
+ type: "problem",
245
+ docs: {
246
+ description: "Isolate barrel file is not allowed to import outside of the barrel file"
247
+ },
248
+ schema: [
249
+ {
250
+ type: "object",
251
+ properties: {
252
+ isolations: { type: "array", items: { type: "object" } },
253
+ baseDir: { type: "string" },
254
+ globalAllowPaths: { type: "array", items: { type: "string" } }
255
+ },
256
+ required: ["isolations", "baseDir", "globalAllowPaths"],
257
+ additionalProperties: false
258
+ }
259
+ ],
260
+ messages: {
261
+ TransformedAliasResolveFailed: "Transformed alias resolve failed. please check the alias config.",
262
+ IsolatedBarrelImportDisallowed: "This barrel file is isolated. external import is not allowed. if you want to import outside of the barrel file, please add 'allowedPath' to the plugin options."
263
+ }
264
+ },
265
+ //default options(baseDir is current working directory. almost user execute eslint in project root)
266
+ defaultOptions: [
267
+ {
268
+ isolations: [],
269
+ baseDir: process.cwd(),
270
+ globalAllowPaths: []
271
+ }
272
+ ],
273
+ create(context) {
274
+ const option = context.options[0];
275
+ const baseDir = option.baseDir;
276
+ const absoluteGlobalAllowPaths = option.globalAllowPaths.flatMap((path4) => {
277
+ return Glob.resolvePath(path4, baseDir);
278
+ });
279
+ const absoluteIsolations = option.isolations.flatMap((isolation) => {
280
+ const isolationPaths = Glob.resolvePath(isolation.path, baseDir);
281
+ const allowedPaths = isolation.allowedPaths.flatMap((path4) => {
282
+ return Glob.resolvePath(path4, baseDir);
283
+ });
284
+ return isolationPaths.map((isolationPath) => ({
285
+ isolationPath,
286
+ //self isolatedPath also allowed to be imported
287
+ allowedPaths: [...allowedPaths, isolationPath]
288
+ }));
289
+ });
290
+ return {
291
+ //check only import declaration(ESM)
292
+ ImportDeclaration(node) {
293
+ const rawImportPath = node.source.value;
294
+ const absoluteCurrentFilePath = context.getFilename();
295
+ let absoluteImportPath = null;
296
+ try {
297
+ const aliasResult = Alias.resolvePath(
298
+ rawImportPath,
299
+ path3.dirname(absoluteCurrentFilePath)
300
+ );
301
+ if (aliasResult.type === "success") {
302
+ absoluteImportPath = aliasResult.absolutePath;
303
+ } else {
304
+ if (!rawImportPath.startsWith(".") && !rawImportPath.startsWith("/") || rawImportPath.includes("/node_modules/")) {
305
+ return;
218
306
  }
307
+ absoluteImportPath = resolve2.sync(rawImportPath, {
308
+ basedir: path3.dirname(absoluteCurrentFilePath),
309
+ extensions: RESOLVE_EXTENSIONS2
310
+ });
219
311
  }
312
+ } catch (e) {
313
+ context.report({
314
+ node,
315
+ messageId: "TransformedAliasResolveFailed"
316
+ });
317
+ return;
318
+ }
319
+ const isolationIndex = absoluteIsolations.findIndex((isolation) => {
320
+ const absoluteIsolationPath = isolation.isolationPath;
321
+ const closedIsolationPath = absoluteIsolationPath + "/";
322
+ return absoluteCurrentFilePath.startsWith(closedIsolationPath);
323
+ });
324
+ const matchedIsolation = absoluteIsolations[isolationIndex];
325
+ if (!matchedIsolation) return;
326
+ const isAllowedImport = matchedIsolation.allowedPaths.some(
327
+ (allowedPath) => {
328
+ const same = absoluteImportPath === allowedPath;
329
+ const closedAllowedPath = allowedPath + "/";
330
+ const sub = absoluteImportPath.startsWith(closedAllowedPath);
331
+ return same || sub;
332
+ }
333
+ );
334
+ const isGlobalAllowedImport = absoluteGlobalAllowPaths.some(
335
+ (allowedPath) => {
336
+ const same = absoluteImportPath === allowedPath;
337
+ const closedAllowedPath = allowedPath + "/";
338
+ const sub = absoluteImportPath.startsWith(closedAllowedPath);
339
+ return same || sub;
340
+ }
341
+ );
342
+ const allowedImport = isAllowedImport || isGlobalAllowedImport;
343
+ if (!allowedImport) {
344
+ context.report({
345
+ node,
346
+ messageId: "IsolatedBarrelImportDisallowed"
347
+ });
220
348
  }
221
349
  }
222
350
  };
@@ -224,7 +352,7 @@ var enforceBarrelPattern = {
224
352
  };
225
353
 
226
354
  // src/rules/no-wildcard.ts
227
- import "@typescript-eslint/utils";
355
+ import "@typescript-eslint/types";
228
356
  var noWildcard = {
229
357
  meta: {
230
358
  type: "problem",
@@ -264,6 +392,7 @@ var noWildcard = {
264
392
  // src/index.ts
265
393
  var rules = {
266
394
  "enforce-barrel-pattern": enforceBarrelPattern,
395
+ "isolate-barrel-file": isolateBarrelFile,
267
396
  "no-wildcard": noWildcard
268
397
  };
269
398
  var index_default = { rules };
package/package.json CHANGED
@@ -25,15 +25,21 @@
25
25
  "isolated barrel module",
26
26
  "no-wildcard"
27
27
  ],
28
- "version": "1.2.0",
28
+ "version": "1.3.1",
29
29
  "type": "module",
30
30
  "main": "dist/index.cjs",
31
31
  "module": "dist/index.js",
32
32
  "types": "dist/index.d.ts",
33
33
  "dependencies": {
34
+ "@types/jest": "^30.0.0",
35
+ "@typescript-eslint/parser": "^8.46.2",
36
+ "@typescript-eslint/rule-tester": "^8.46.2",
37
+ "@typescript-eslint/types": "^8.46.2",
34
38
  "@typescript-eslint/utils": "^8.36.0",
35
39
  "fast-glob": "^3.3.3",
40
+ "jest": "^30.2.0",
36
41
  "resolve": "^1.22.10",
42
+ "ts-jest": "^29.4.5",
37
43
  "tsconfig-paths": "^4.2.0"
38
44
  },
39
45
  "devDependencies": {
@@ -43,8 +49,11 @@
43
49
  "typescript": "~5.8.3"
44
50
  },
45
51
  "scripts": {
46
- "build": "tsup src/index.ts --dts --format cjs,esm",
52
+ "build": "pnpm run test && tsup src/index.ts --dts --format cjs,esm",
47
53
  "type-check": "tsc --noEmit",
54
+ "test": "jest",
55
+ "test:watch": "jest --watch",
56
+ "test:coverage": "jest --coverage",
48
57
  "release": "pnpm run build && pnpm publish --access=public"
49
58
  }
50
59
  }