@morriconeluca/eslint-plugin-faf 0.3.0 → 0.5.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.md +71 -22
- package/dist/main.cjs +835 -511
- package/dist/main.cjs.map +1 -1
- package/dist/main.d.cts +4 -0
- package/dist/main.d.ts +4 -0
- package/dist/main.js +835 -511
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ This plugin is designed for complex TypeScript/JavaScript codebases to ensure **
|
|
|
11
11
|
- **Strict Enforcing of FAF Taxonomy**: Ensures your folder structure strictly maps to Layers, Categories, Fragments, and Fractal Branches.
|
|
12
12
|
- **Law of Separation between Peers**: Prevents lateral dependency coupling between sibling modules without explicit hierarchy.
|
|
13
13
|
- **Access Node Encapsulation**: Guarantees that internal Fragment files are never imported directly, enforcing consumption solely through the Fragment's barrel file (`index.ts`).
|
|
14
|
-
- **High-Performance Architecture**: Features optimized caching (`dirCache`, `classifyCache`, `rolesCache`) to minimize disk I/O during linting runs.
|
|
14
|
+
- **High-Performance Architecture**: Features optimized caching (`dirCache`, `classifyCache`, `ancestorChainCache`, `rolesCache`) to minimize disk I/O during linting runs.
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -273,54 +273,84 @@ Determines horizontal import flow (Peer Separation). Each hierarchy is an array
|
|
|
273
273
|
|
|
274
274
|
### 1. `faf/naming-conventions`
|
|
275
275
|
|
|
276
|
-
Verifies
|
|
276
|
+
Verifies pure lexical FAF naming conventions:
|
|
277
277
|
|
|
278
278
|
- Enforces `kebab-case` naming for all folders and files in the logical domain.
|
|
279
|
-
-
|
|
280
|
-
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
- Fractal Branches cannot be nested inside other Fractal Branches.
|
|
279
|
+
- Requires an underscore prefix for Layers/Categories/Sub-Categories, and forbids it for Fragments/Sub-Fragments/Root Fragments.
|
|
280
|
+
- Validates that a Fractal Branch's name matches its parent scope (`_<Scope>@shared`).
|
|
281
|
+
- Restricts a Logical Node's name to a single Role segment, whether it is a Fragment Node or a loose file inside a Category.
|
|
282
|
+
- For loose files inside a Category: validates the file extension against the category's whitelist, requires a role suffix on code files, and validates that the role matches the Category's configured role.
|
|
283
|
+
|
|
284
|
+
### 2. `faf/logical-domain-placement`
|
|
285
|
+
|
|
286
|
+
Enforces FAF topological placement constraints between Logical Domains:
|
|
288
287
|
|
|
289
|
-
|
|
288
|
+
- Root Fragments can only reside directly in the Root Container or another Root Fragment.
|
|
289
|
+
- Layers cannot reside inside Fragments, and cannot contain files or Fragments directly, except the terminal Layer of a configured Route Hierarchy.
|
|
290
|
+
- Fragments cannot be placed directly inside other Fragments (they must be nested within a Private Category), Layers (unless terminating a Route Hierarchy), Fractal Branches, or nested Root Fragments.
|
|
291
|
+
- Fractal Branches cannot be nested inside other Fractal Branches, and cannot contain files directly.
|
|
292
|
+
|
|
293
|
+
### 3. `faf/enforce-access-node`
|
|
290
294
|
|
|
291
295
|
Enforces Access Node (`index.ts` / `index.js`) integrity:
|
|
292
296
|
|
|
297
|
+
- Requires a directory that isn't a Category, Layer, Fractal Branch, or Root Fragment to have an Access Node.
|
|
298
|
+
- Restricts Access Nodes to Fragments: an index file directly inside any other Logical Domain is forbidden.
|
|
299
|
+
- Requires every Fragment to contain at least one Fragment Node (its Master Node).
|
|
293
300
|
- Restricts the Access Node to import/export only its own sibling Fragment Nodes.
|
|
294
301
|
- Prevents import of nested Private Categories, Fractal Branches, or unrelated external paths.
|
|
295
302
|
|
|
296
|
-
###
|
|
303
|
+
### 4. `faf/fragment-master-node`
|
|
304
|
+
|
|
305
|
+
Enforces Fragment Node identity and Master Node integrity:
|
|
306
|
+
|
|
307
|
+
- Validates that internal Fragment files share their parent Fragment's name prefix (e.g. files in folder `button/` must be named `button.<role>.<ext>`).
|
|
308
|
+
- Requires a role suffix on every Fragment Node, and forbids two Fragment Nodes from sharing the same Role.
|
|
309
|
+
- Assures a Fragment placed under a Category (or terminating a Route Hierarchy) contains a Master Node carrying the Role imposed by that Category/Route (e.g. a `.api.ts` file under `_apis`).
|
|
310
|
+
- Assures route terminal Fragments follow the `<method>-<object>` naming pattern (e.g. `get-todo`), with the HTTP method restricted to `routeHierarchies[].httpMethods` or, by default, all standard HTTP methods.
|
|
311
|
+
|
|
312
|
+
### 5. `faf/no-direct-fragment-import`
|
|
297
313
|
|
|
298
314
|
Applies **Fragment Encapsulation**:
|
|
299
315
|
|
|
300
316
|
- Prevents external files from directly importing a Fragment's internal files. All imports must pass through the Fragment's Access Node (`index.ts`).
|
|
301
317
|
|
|
302
|
-
###
|
|
318
|
+
### 6. `faf/no-private-category-leak`
|
|
303
319
|
|
|
304
320
|
Applies **Private Category Encapsulation**:
|
|
305
321
|
|
|
306
322
|
- Restricts consumption of elements inside a Private Category (e.g. `_components/` nested inside a Fragment) to the direct child Fragment Nodes of the owning Fragment/Root Fragment, and to sibling nodes within the same immediate sub-domain of the Private Category. Access does not extend to other sub-domains, nor to a Fractal Branch nested inside the Private Category (governed instead by its own encapsulation rule).
|
|
307
323
|
|
|
308
|
-
###
|
|
324
|
+
### 7. `faf/no-fractal-branch-leak`
|
|
309
325
|
|
|
310
326
|
Applies **Fractal Branch Encapsulation**:
|
|
311
327
|
|
|
312
328
|
- Fractal Branches named `_<Scope>@shared` are only importable by modules residing inside the parent Scope's subtree.
|
|
329
|
+
- A Fractal Branch itself must never depend, not even indirectly, on the subtree it serves: importing anything from its owner's subtree that isn't part of the branch itself is forbidden.
|
|
330
|
+
|
|
331
|
+
### 8. `faf/no-peer-dependency`
|
|
332
|
+
|
|
333
|
+
Applies **Peer Isolation** via horizontal hierarchy resolution:
|
|
334
|
+
|
|
335
|
+
- **Inside a Fragment**: Flow is governed by the `roles` array order.
|
|
336
|
+
- **Between folders**: Flow is governed exclusively by `localHorizontalHierarchies` or `globalHorizontalHierarchies`; a sibling pair without a matching entry is denied in both directions.
|
|
313
337
|
|
|
314
|
-
|
|
338
|
+
Foreign Domain imports and Root Node dependency direction are handled by dedicated rules (see below).
|
|
315
339
|
|
|
316
|
-
|
|
340
|
+
### 9. `faf/foreign-domain-isolation`
|
|
317
341
|
|
|
318
|
-
|
|
319
|
-
- **Inside a Fragment**: Flow is governed by the `roles` array order.
|
|
320
|
-
- **Between folders**: Flow is governed by `localHorizontalHierarchies` or `globalHorizontalHierarchies`. If undefined, the linter falls back to mapped roles. Otherwise, peer isolation is strictly enforced.
|
|
321
|
-
- **Root Nodes**: Flow is governed exclusively by the defined index order in `rootFragments.rootNodes`. Root Nodes are exempt from the Role naming convention, so relationships between them never fall back to the `roles` scale: any relationship without a matching `rootNodes` entry is denied.
|
|
342
|
+
Applies **Foreign Domain isolation**:
|
|
322
343
|
|
|
323
|
-
|
|
344
|
+
- Prevents Logical Nodes from importing a file from a Foreign Domain (e.g. `src/configs`).
|
|
345
|
+
- Prevents a Foreign Domain file from importing a Logical Node from the FAF tree.
|
|
346
|
+
|
|
347
|
+
### 10. `faf/root-node-dependency-direction`
|
|
348
|
+
|
|
349
|
+
Enforces explicit, non-Role-based dependency direction between **Root Nodes**:
|
|
350
|
+
|
|
351
|
+
- Flow is governed exclusively by the defined index order in `rootFragments.rootNodes`. Root Nodes are exempt from the Role naming convention, so relationships between them (sibling or nested Root Fragments) never fall back to the `roles` scale: any relationship without a matching `rootNodes` entry is denied.
|
|
352
|
+
|
|
353
|
+
### 11. `faf/category-mutually-exclusive`
|
|
324
354
|
|
|
325
355
|
Ensures category purity:
|
|
326
356
|
|
|
@@ -329,12 +359,31 @@ Ensures category purity:
|
|
|
329
359
|
|
|
330
360
|
---
|
|
331
361
|
|
|
362
|
+
## Migrating from 7 rules to 11
|
|
363
|
+
|
|
364
|
+
Starting with this release, five checks that used to live inside two large rules (`naming-conventions` and `no-peer-dependency`) have moved to dedicated rules with their own `id`. The underlying checks and their error messages are unchanged — only the `ruleId` reporting them is different. This is a breaking change for anyone who doesn't use `configs.recommended` (which picks up the new rules automatically) or who references a specific rule `id` directly, e.g. in `// eslint-disable-next-line faf/<id>` comments or a hand-written `rules` block.
|
|
365
|
+
|
|
366
|
+
| Old rule id | Check moved to |
|
|
367
|
+
| ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
|
|
368
|
+
| `naming-conventions` — folder/file placement (Root Fragment, Layer, Fragment, Fractal Branch containment) | `logical-domain-placement` (new) |
|
|
369
|
+
| `naming-conventions` — Access Node existence, Master Node existence | `enforce-access-node` |
|
|
370
|
+
| `naming-conventions` — Fragment Node name prefix, role requirement/uniqueness, Category/Route Master Node role, route naming pattern | `fragment-master-node` (new) |
|
|
371
|
+
| `naming-conventions` — kebab-case, underscore prefix, Fractal Branch naming, single-Role-segment, Category loose-file naming | unchanged, stays in `naming-conventions` |
|
|
372
|
+
| `no-peer-dependency` — Foreign Domain imports (both directions) | `foreign-domain-isolation` (new) |
|
|
373
|
+
| `no-peer-dependency` — Root Node dependency direction (`rootFragments.rootNodes`) | `root-node-dependency-direction` (new) |
|
|
374
|
+
| `no-peer-dependency` — horizontal hierarchy resolution (Fragment Node roles, sibling folders) | unchanged, stays in `no-peer-dependency` |
|
|
375
|
+
|
|
376
|
+
`no-direct-fragment-import`, `no-private-category-leak`, `category-mutually-exclusive` are unaffected. `no-fractal-branch-leak` keeps its `id` and gains one new check: a Fractal Branch depending on the subtree it serves is now reported.
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
332
380
|
## Performance Optimizations
|
|
333
381
|
|
|
334
382
|
To prevent sluggish linting in large codebases, the core engine implements aggressive, state-cached optimizations:
|
|
335
383
|
|
|
336
384
|
- **Directory Cache (`dirCache`)**: Inspects the physical disk exactly once per folder, storing the contents in-memory. It is optimized to perform exactly one system call on cache misses by removing redundant `fs.existsSync` checks.
|
|
337
385
|
- **Classification Cache (`classifyCache`)**: Memoizes the structural type (`FolderType`) of each directory for the lifetime of the ESLint run.
|
|
386
|
+
- **Ancestor Chain Cache (`ancestorChainCache`)**: Memoizes the full chain of classified ancestors above a directory, so rules that walk upward from a file (folder taxonomy, topological placement) do so once per directory rather than once per file.
|
|
338
387
|
- **Role Cache (`rolesCache`)**: Uses a `WeakMap` to cache the allowed roles per tree configuration as a native `Set`, avoiding memory leaks, redundant array flattening allocations, and speeding up role lookup checks to $O(1)$.
|
|
339
388
|
- **Category Configuration Cache (`categoryConfigCache`)**: Memoizes resolved category configurations per folder path to eliminate repetitive directory walks and path parent traversals.
|
|
340
389
|
- **Tree Configuration Cache (`treeConfigCache` / `treeConfigIncludingExcludedCache`)**: Memoizes resolved tree configurations per file path, reducing tree lookup checks to a simple map-lookup.
|