@morriconeluca/eslint-plugin-faf 0.3.0 → 0.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.md +1 -1
- package/dist/main.cjs +5 -36
- package/dist/main.cjs.map +1 -1
- package/dist/main.js +5 -36
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/_rules/category-mutually-exclusive/category-mutually-exclusive.rule.ts","../src/_rules/_rules@shared/_utils/_aggregates/classify-folder/classify-folder.util.ts","../src/_rules/_rules@shared/_utils/_utils@shared/_stores/cache/cache.store.ts","../src/_rules/_rules@shared/_utils/_primitives/get-root-fragment-config/get-root-fragment-config.util.ts","../src/_rules/_rules@shared/_utils/_compounds/is-root-fragment/is-root-fragment.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-category-config/get-category-config.util.ts","../src/_rules/_rules@shared/_utils/_primitives/read-dir-cached/read-dir-cached.util.ts","../src/_rules/_rules@shared/_utils/_primitives/find-tree-config/find-tree-config.util.ts","../src/_rules/_rules@shared/_utils/_primitives/to-relative-path/to-relative-path.util.ts","../src/_rules/enforce-access-node/enforce-access-node.rule.ts","../src/_rules/naming-conventions/naming-conventions.rule.ts","../src/_rules/_rules@shared/_utils/_primitives/get-file-role/get-file-role.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-project-root/get-project-root.util.ts","../src/_rules/no-direct-fragment-import/no-direct-fragment-import.rule.ts","../src/_rules/_rules@shared/_utils/_aggregates/resolve-import-path/resolve-import-path.util.ts","../src/_rules/no-fractal-branch-leak/no-fractal-branch-leak.rule.ts","../src/_rules/_rules@shared/_utils/_primitives/get-fractal-branch-owner/get-fractal-branch-owner.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-immediate-sub-domain/get-immediate-sub-domain.util.ts","../src/_rules/_rules@shared/_utils/_systems/get-private-category-info/get-private-category-info.util.ts","../src/_rules/no-peer-dependency/no-peer-dependency.rule.ts","../src/_rules/_rules@shared/_utils/_primitives/find-tree-config-including-excluded/find-tree-config-including-excluded.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-lca-and-sub-branches/get-lca-and-sub-branches.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-role-hierarchy-index/get-role-hierarchy-index.util.ts","../src/_rules/_rules@shared/_utils/_primitives/resolve-horizontal-hierarchy/resolve-horizontal-hierarchy.util.ts","../src/_rules/no-private-category-leak/no-private-category-leak.rule.ts","../src/rules.ts","../src/configs.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@morriconeluca/eslint-plugin-faf\",\n \"version\": \"0.3.0\",\n \"description\": \"An ESLint plugin for FAF projects.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/morriconeluca/eslint-plugin-faf.git\"\n },\n \"main\": \"./dist/main.cjs\",\n \"module\": \"./dist/main.js\",\n \"types\": \"./dist/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/main.d.ts\",\n \"import\": \"./dist/main.js\",\n \"require\": \"./dist/main.cjs\"\n }\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"imports\": {\n \"#_rules@shared/*\": \"./src/_rules/_rules@shared/*\",\n \"#_utils@shared/*\": \"./src/_rules/_rules@shared/_utils/_utils@shared/*\"\n },\n \"type\": \"module\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"npm run lint && tsup\",\n \"test\": \"vitest run\",\n \"dev\": \"vitest\",\n \"lint\": \"npm run lint:types && npm run lint:eslint\",\n \"lint:eslint\": \"eslint .\",\n \"lint:types\": \"tsc --noEmit\",\n \"lint:fix\": \"eslint --fix .\",\n \"format\": \"prettier --write .\",\n \"check-format\": \"prettier --check .\",\n \"ci\": \"npm run build && npm run check-format && npm run test\",\n \"prepublishOnly\": \"npm run ci\",\n \"local-release\": \"changeset version && changeset publish\",\n \"prepare\": \"husky\"\n },\n \"keywords\": [\n \"eslint\",\n \"eslintplugin\",\n \"faf\"\n ],\n \"author\": \"Luca Morricone\",\n \"license\": \"MIT\",\n \"peerDependencies\": {\n \"eslint\": \"^8.57.0 || ^9.0.0 || ^10.0.0\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.31.0\",\n \"@commitlint/cli\": \"^21.0.2\",\n \"@commitlint/config-conventional\": \"^21.0.2\",\n \"@eslint/js\": \"^10.0.1\",\n \"@types/eslint\": \"^9.6.1\",\n \"@types/node\": \"^25.9.3\",\n \"@typescript-eslint/utils\": \"^8.24.1\",\n \"dependency-cruiser\": \"^17.4.3\",\n \"eslint\": \"^10.5.0\",\n \"eslint-import-resolver-typescript\": \"^4.4.5\",\n \"eslint-plugin-import-x\": \"^4.16.2\",\n \"eslint-plugin-perfectionist\": \"^5.9.0\",\n \"husky\": \"^9.1.7\",\n \"lint-staged\": \"^17.0.7\",\n \"prettier\": \"^3.8.4\",\n \"tsup\": \"^8.3.6\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.61.0\",\n \"vitest\": \"^4.1.9\"\n },\n \"lint-staged\": {\n \"*\": \"prettier --write --ignore-unknown\",\n \"src/**/*.ts\": \"eslint --fix\"\n }\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getCategoryConfig } from '#_rules@shared/_utils/_primitives/get-category-config/index.js';\nimport { readDirCached } from '#_rules@shared/_utils/_primitives/read-dir-cached/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\n/**\n * @fileoverview Rule: faf/category-mutually-exclusive\n * Enforces the FAF rule of Category Purity (Mutua Esclusività).\n *\n * FAF Law: Categories must contain either ONLY single files (Logical Nodes) or ONLY subfolders (Fragments).\n *\n * Valid:\n * - A category configured with `allowSingleFiles: true` containing only files (e.g. `_types/user.type.ts`).\n * - A category configured with `allowSingleFiles: false` containing only Fragment folders (e.g. `_utils/get-path/`).\n *\n * Invalid:\n * - Mixing single files and subfolders directly inside the same category directory.\n * - Placing files directly in a Category that is not configured to allow single files (`allowSingleFiles: false`).\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n const relDir = path.dirname(relPath);\n const parentType = classifyFolder(relDir, config);\n\n if (parentType !== 'category') {\n return {};\n }\n\n const fileName = path.basename(relPath);\n\n return {\n Program(node) {\n const contents = readDirCached(relDir);\n\n const activeFiles = contents.files.filter(\n (f) => f !== 'README.md' && f !== 'package.json' && !f.startsWith('.')\n );\n const activeDirs = contents.dirs.filter((d) => !d.startsWith('_')); // Ignore sub-categories/layers/fractal branches\n\n const hasFiles = activeFiles.length > 0;\n const hasDirs = activeDirs.length > 0;\n\n if (hasFiles && hasDirs) {\n context.report({\n loc: { column: 0, line: 1 },\n message: `Mutua Esclusività violation in Category \"${path.basename(relDir)}\": cannot mix single files (${activeFiles.join(', ')}) and Fragment directories (${activeDirs.join(', ')}).`,\n node,\n });\n }\n\n // Also check if category config allows single files\n if (hasFiles) {\n const folderName = path.basename(relDir);\n const catConfig = getCategoryConfig(relDir, config);\n if (catConfig) {\n const ext = path.extname(fileName);\n const isAllowedAsset =\n catConfig.allowedExtensions?.includes(ext) ?? false;\n\n // If the category defines allowedExtensions and this file's\n // extension is not in the list, skip — naming-conventions\n // already reports a precise extension-mismatch error.\n if (\n !isAllowedAsset &&\n catConfig.allowedExtensions &&\n catConfig.allowedExtensions.length > 0\n ) {\n return;\n }\n\n if (!catConfig.allowSingleFiles && !isAllowedAsset) {\n context.report({\n message: `Category \"${folderName}\" cannot contain file nodes directly. File \"${fileName}\" must be encapsulated inside a Fragment.`,\n node,\n });\n }\n }\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Enforce that Categories contain either only file nodes or only Fragment folders, and check whitelist roles',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFolderType, TTreeConfig } from '../../../_types/faf.type.js';\n\nimport { isRootFragment } from '../../_compounds/is-root-fragment/index.js';\nimport { getCategoryConfig } from '../../_primitives/get-category-config/index.js';\nimport { readDirCached } from '../../_primitives/read-dir-cached/index.js';\n\n/**\n * Classifies a relative directory path into a FAF structural category (Layer, Category, Fragment, etc.).\n * Memoizes results in `state.classifyCache` to optimize recursive parent checks.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns The classified folder type.\n */\nexport function classifyFolder(\n relDirPath: string,\n config: TTreeConfig\n): TFolderType {\n const cached = state.classifyCache.get(relDirPath);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = _classifyFolder(relDirPath, config);\n state.classifyCache.set(relDirPath, result);\n return result;\n}\n\nfunction _classifyFolder(relDirPath: string, config: TTreeConfig): TFolderType {\n const isExcluded = config.excludes?.some(\n (exc) => relDirPath === exc || relDirPath.startsWith(exc + '/')\n );\n if (isExcluded) {\n return 'foreign';\n }\n\n if (isRootFragment(relDirPath, config)) {\n return 'root-fragment';\n }\n\n const folderName = path.basename(relDirPath);\n\n if (folderName.startsWith('_') && folderName.includes('@shared')) {\n return 'fractal-branch';\n }\n\n const contents = readDirCached(relDirPath);\n const hasAccessNode = contents.files.some(\n (f) => f === 'index.ts' || f === 'index.js'\n );\n\n const isRoute =\n config.routeHierarchies &&\n config.routeHierarchies.some((rh) =>\n rh.paths.some((rp) => {\n if (relDirPath.startsWith(rp + '/')) {\n const remainder = relDirPath.substring(rp.length + 1);\n const segments = remainder.split('/');\n return !segments.some(\n (seg) => seg.endsWith('@shared') || seg.includes('@shared')\n );\n }\n return false;\n })\n );\n\n if (isRoute && !hasAccessNode) {\n return 'layer';\n }\n\n if (folderName.startsWith('_')) {\n const catConfig = getCategoryConfig(relDirPath, config);\n if (catConfig) {\n return 'category';\n }\n\n return 'layer';\n }\n\n const isCategory =\n config.categories &&\n config.categories.some((c) => c.name === '_' + folderName);\n if (isCategory && !hasAccessNode) {\n return 'category';\n }\n\n if (hasAccessNode) {\n return 'fragment';\n }\n\n return 'invalid-fragment';\n}\n","import type { TCacheState } from './cache.type.js';\n\n/**\n * Persistent global caching state mapping to optimized native collections.\n * Persists for the lifetime of a single ESLint run.\n * Cleaned up between testing suites dynamically using clearDirCache.\n */\nexport const state: TCacheState = {\n categoryConfigCache: new Map(),\n classifyCache: new Map(),\n dirCache: {},\n packageImports: null,\n projectRoot: process.cwd(),\n resolvedImportPathCache: new Map(),\n rolesCache: new WeakMap(),\n treeConfigCache: new Map(),\n treeConfigIncludingExcludedCache: new Map(),\n};\n","import type {\n TRootFragmentConfig,\n TTreeConfig,\n} from '../../../_types/faf.type.js';\n\n/**\n * Searches the tree configuration for the Root Fragment configuration matching the given path.\n * Traverses recursively down through sub-root configurations.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns The matching Root Fragment configuration or null if not found.\n */\nexport function getRootFragmentConfig(\n relDirPath: string,\n config: TTreeConfig\n): null | TRootFragmentConfig {\n const checkConfig = (\n rfConfig: TRootFragmentConfig\n ): null | TRootFragmentConfig => {\n if (rfConfig.paths.includes(relDirPath)) {\n return rfConfig;\n }\n if (rfConfig.subRootFragments) {\n for (const sub of rfConfig.subRootFragments) {\n const res = checkConfig(sub);\n if (res) return res;\n }\n }\n return null;\n };\n\n if (config.rootFragments) {\n for (const rf of config.rootFragments) {\n const res = checkConfig(rf);\n if (res) return res;\n }\n }\n return null;\n}\n","import type { TTreeConfig } from '../../../_types/faf.type.js';\n\nimport { getRootFragmentConfig } from '../../_primitives/get-root-fragment-config/index.js';\n\n/**\n * Checks if a relative directory path corresponds to a configured Root Fragment.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns True if the path is a Root Fragment.\n */\nexport function isRootFragment(\n relDirPath: string,\n config: TTreeConfig\n): boolean {\n return getRootFragmentConfig(relDirPath, config) !== null;\n}\n","import path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TCategoryConfig, TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Returns the TCategoryConfig for a given path by traversing upwards to the closest Category folder.\n * Result is cached in `state.categoryConfigCache`.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns The Category configuration or null if not in a Category.\n */\nexport function getCategoryConfig(\n relDirPath: string,\n config: TTreeConfig\n): null | TCategoryConfig {\n const cached = state.categoryConfigCache.get(relDirPath);\n if (cached !== undefined) {\n return cached;\n }\n\n let result: null | TCategoryConfig = null;\n let current = relDirPath;\n while (current && current !== '.' && current !== '/') {\n const folderName = path.basename(current);\n if (folderName.startsWith('_') && !folderName.includes('@shared')) {\n const catConfig = config.categories?.find((c) => c.name === folderName);\n if (catConfig) {\n result = catConfig;\n break;\n }\n } else {\n break;\n }\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) break;\n current = parent;\n }\n\n state.categoryConfigCache.set(relDirPath, result);\n return result;\n}\n","import fs from 'fs';\nimport path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\n/**\n * Returns a cached record of files and directories within a target directory path.\n * Limits disk access by caching results in `state.dirCache` on the first miss.\n * Performs a single fs.readdirSync operation to optimize synchronous I/O.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @returns Object with arrays of directory names and file names.\n */\nexport function readDirCached(relDirPath: string): {\n dirs: string[];\n files: string[];\n} {\n const absPath = path\n .resolve(state.projectRoot, relDirPath)\n .replace(/\\\\/g, '/');\n if (state.dirCache[absPath]) {\n return state.dirCache[absPath];\n }\n\n try {\n const entries = fs.readdirSync(absPath, { withFileTypes: true });\n const files: string[] = [];\n const dirs: string[] = [];\n\n for (const entry of entries) {\n if (entry.isFile()) {\n files.push(entry.name);\n } else if (entry.isDirectory()) {\n dirs.push(entry.name);\n }\n }\n\n state.dirCache[absPath] = { dirs, files };\n return state.dirCache[absPath];\n } catch {\n return { dirs: [], files: [] };\n }\n}\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFafSettings, TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Finds the tree configuration that includes the given relative file path,\n * excluding paths designated as Foreign Domains. Uses `state.treeConfigCache`\n * to speed up subsequent queries.\n *\n * @param relPath - Path relative to the project root.\n * @param settings - The global FAF settings containing trees configuration.\n * @returns The matching tree configuration or null if not found or excluded.\n */\nexport function findTreeConfig(\n relPath: string,\n settings: TFafSettings\n): null | TTreeConfig {\n if (!settings || !settings.trees) {\n return null;\n }\n\n const cached = state.treeConfigCache.get(relPath);\n if (cached !== undefined) {\n return cached;\n }\n\n let result: null | TTreeConfig = null;\n for (const tree of settings.trees) {\n const isIncluded = tree.includes.some(\n (inc) => relPath === inc || relPath.startsWith(inc + '/')\n );\n const isExcluded = tree.excludes?.some(\n (exc) => relPath === exc || relPath.startsWith(exc + '/')\n );\n\n if (isIncluded && !isExcluded) {\n result = tree;\n break;\n }\n }\n\n state.treeConfigCache.set(relPath, result);\n return result;\n}\n","import path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\n/**\n * Normalizes any path to be relative to the project root and formats it with forward slashes.\n *\n * @param absoluteOrRelative - Input path string.\n * @returns Normalized relative path.\n */\nexport function toRelativePath(absoluteOrRelative: string): string {\n let abs = absoluteOrRelative;\n if (!path.isAbsolute(abs)) {\n abs = path.resolve(state.projectRoot, abs);\n }\n const rel = path.relative(state.projectRoot, abs);\n return rel.replace(/\\\\/g, '/');\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\n/**\n * @fileoverview Rule: faf/enforce-access-node\n * Enforces the FAF Law of Access Node Integrity.\n *\n * FAF Law: An Access Node (barrel file like `index.ts`) must only define and export the Fragment's public interface.\n * It is restricted to import/export only its own sibling Fragment Nodes using simple relative paths.\n *\n * Valid:\n * - `export * from './button.component';` inside `button/index.ts`.\n * - `export type * from './button.type';` inside `button/index.ts`.\n *\n * Invalid:\n * - Importing/exporting files from subfolders (e.g. `export * from './_components/child';`).\n * - Importing/exporting files from parent folders or external paths (e.g. `export * from '../utils';`).\n * - Exporting files that do not share the parent Fragment's name prefix.\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const fileName = path.basename(relPath);\n\n if (fileName !== 'index.ts' && fileName !== 'index.js') {\n return {};\n }\n\n const settings = context.settings as { faf?: TFafSettings };\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n const relDir = path.dirname(relPath);\n const parentType = classifyFolder(relDir, config);\n\n // If it's not a Fragment, naming-conventions handles it, but let's ignore it here\n if (parentType !== 'fragment') {\n return {};\n }\n\n function checkSource(node: Rule.Node, sourceVal: string) {\n // Matches only \"./filename\" with no further \"/\" (no subfolders, no parent folders)\n const isValidSibling = /^\\.\\/[^/]+$/.test(sourceVal);\n if (!isValidSibling) {\n context.report({\n message: `Access Node (index file) can only import or export its own sibling Fragment Nodes using simple relative paths (e.g. \"./example.component\"). Got \"${sourceVal}\".`,\n node,\n });\n return;\n }\n\n const importedFilename = path.basename(sourceVal);\n if (\n importedFilename === 'index' ||\n importedFilename === 'index.ts' ||\n importedFilename === 'index.js' ||\n importedFilename === 'README.md' ||\n importedFilename === 'package.json'\n ) {\n return;\n }\n\n const fragmentName = path.basename(relDir);\n if (!importedFilename.startsWith(fragmentName + '.')) {\n context.report({\n message: `Access Node (index file) can only re-export its own Fragment Nodes (names starting with \"${fragmentName}.\"). Got \"${importedFilename}\".`,\n node,\n });\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkSource(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkSource(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkSource(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description: 'Enforce Access Node rules for Fragments',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type {\n TFafSettings,\n THttpMethod,\n} from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getCategoryConfig } from '#_rules@shared/_utils/_primitives/get-category-config/index.js';\nimport { getFileRole } from '#_rules@shared/_utils/_primitives/get-file-role/index.js';\nimport { getProjectRoot } from '#_rules@shared/_utils/_primitives/get-project-root/index.js';\nimport { getRootFragmentConfig } from '#_rules@shared/_utils/_primitives/get-root-fragment-config/index.js';\nimport { readDirCached } from '#_rules@shared/_utils/_primitives/read-dir-cached/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\nconst KEBAB_CASE_REGEX = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst DEFAULT_HTTP_METHODS: THttpMethod[] = [\n 'connect',\n 'delete',\n 'get',\n 'head',\n 'options',\n 'patch',\n 'post',\n 'put',\n 'trace',\n];\n\n/**\n * @fileoverview Rule: faf/naming-conventions\n * Enforces FAF folder taxonomy, naming conventions, and file role suffixes.\n *\n * FAF Law:\n * - Folders and files in the logical domain must use kebab-case.\n * - Categories/Layers must start with an underscore (e.g. `_components`).\n * - Fragments must NOT start with an underscore.\n * - Sibling Fragment Nodes must share the parent Fragment folder's name.\n * - All logical nodes must end with a valid role suffix (e.g. `[name].[role].ts`).\n * - Fragments placed under a Category (or Route) must contain a Master Node with the corresponding role.\n * - Every Fragment must have a Master Node, and Fragment Nodes must have unique Roles.\n * - A route terminal Fragment's name must follow the \"<method>-<object>\" pattern.\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n return {\n Program(node) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return;\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return;\n }\n\n const relDir = path.dirname(relPath);\n const folderName = path.basename(relDir);\n const parentType = classifyFolder(relDir, config);\n\n if (parentType === 'foreign') {\n return;\n }\n\n const fileName = path.basename(relPath);\n\n // Validate folder conventions across all ancestors, not just the immediate parent\n let currentDir = relDir;\n while (currentDir && currentDir !== '.' && currentDir !== '/') {\n const isInTree = config.includes.some(\n (inc) => currentDir === inc || currentDir.startsWith(inc + '/')\n );\n const isExcluded =\n config.excludes?.some(\n (exc) => currentDir === exc || currentDir.startsWith(exc + '/')\n ) ?? false;\n\n if (!isInTree || isExcluded) {\n break;\n }\n\n const currentFolderName = path.basename(currentDir);\n const currentType = classifyFolder(currentDir, config);\n\n // Layers and Categories must be prefixed with an underscore\n if (\n (currentType === 'layer' || currentType === 'category') &&\n !currentFolderName.startsWith('_')\n ) {\n context.report({\n message: `Layer/Category directory \"${currentFolderName}\" must be prefixed with an underscore (e.g. \"_${currentFolderName}\").`,\n node,\n });\n }\n\n // Fragments must NOT be prefixed with an underscore\n if (\n currentFolderName.startsWith('_') &&\n !currentFolderName.includes('@shared')\n ) {\n const contents = readDirCached(currentDir);\n const hasIndex =\n contents.files.includes('index.ts') ||\n contents.files.includes('index.js');\n if (hasIndex) {\n context.report({\n message: `Directory \"${currentFolderName}\" has an Access Node (index.ts) but its name starts with \"_\". Fragments must not be prefixed with underscore.`,\n node,\n });\n }\n }\n\n if (currentFolderName !== 'src') {\n let baseFolderName = currentFolderName.replace(/@shared$/, '');\n if (baseFolderName.startsWith('_')) {\n baseFolderName = baseFolderName.substring(1);\n }\n if (\n baseFolderName.startsWith('[') &&\n baseFolderName.endsWith(']')\n ) {\n baseFolderName = baseFolderName.substring(\n 1,\n baseFolderName.length - 1\n );\n }\n const isKebab = KEBAB_CASE_REGEX.test(baseFolderName);\n if (!isKebab) {\n context.report({\n message: `Folder name \"${currentFolderName}\" must be in kebab-case (e.g. \"_my-folder\" or \"_[my-param]\").`,\n node,\n });\n }\n }\n\n if (currentType === 'fractal-branch') {\n const expectedScope = path.basename(path.dirname(currentDir));\n const normalizedExpectedScope = expectedScope.startsWith('_')\n ? expectedScope.substring(1)\n : expectedScope;\n const expectedName = `_${normalizedExpectedScope}@shared`;\n if (currentFolderName !== expectedName) {\n context.report({\n message: `Fractal Branch name \"${currentFolderName}\" must match its parent scope name: \"${expectedName}\".`,\n node,\n });\n }\n }\n\n if (currentType === 'invalid-fragment') {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" is missing an Access Node (index.ts/index.js).`,\n node,\n });\n }\n\n const relParentDir = path.dirname(currentDir).replace(/\\\\/g, '/');\n const parentFolderName = path.basename(relParentDir);\n // 'unknown' means relParentDir falls outside any configured tree path,\n // i.e. it is the literal Root Container\n const relParentType =\n relParentDir === '.' || relParentDir === '/'\n ? 'unknown'\n : classifyFolder(relParentDir, config);\n\n if (currentType === 'root-fragment') {\n if (\n relParentType !== 'root-fragment' &&\n relParentType !== 'unknown'\n ) {\n context.report({\n message: `Root Fragment directory \"${currentFolderName}\" must be placed directly inside a Root Container or another Root Fragment, not inside \"${parentFolderName}\" (classified as ${relParentType}).`,\n node,\n });\n }\n }\n\n if (currentType === 'layer') {\n if (\n relParentType === 'fragment' ||\n relParentType === 'invalid-fragment'\n ) {\n context.report({\n message: `Layer directory \"${currentFolderName}\" cannot be placed inside \"${parentFolderName}\" (classified as ${relParentType}). Layers cannot reside within Fragments.`,\n node,\n });\n }\n }\n\n // A Fragment cannot be placed directly:\n // - under a Layer (unless it terminates a configured Route Hierarchy)\n // - inside another Fragment (must be nested within a Private Category)\n // - inside a Fractal Branch\n // - inside a nested Root Fragment (must be contained within a Category)\n if (\n currentType === 'fragment' ||\n currentType === 'invalid-fragment'\n ) {\n const isParentRootContainer =\n config.includes.includes(relParentDir);\n if (relParentType === 'layer') {\n const isParentRoute =\n config.routeHierarchies &&\n config.routeHierarchies.some((rh) =>\n rh.paths.some(\n (rp) =>\n relParentDir === rp || relParentDir.startsWith(rp + '/')\n )\n );\n if (!isParentRoute) {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Layer \"${parentFolderName}\". Fragments must be contained within a Category.`,\n node,\n });\n }\n } else if (\n relParentType === 'fragment' ||\n relParentType === 'invalid-fragment'\n ) {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Fragment \"${parentFolderName}\". Sub-Fragments must be contained within a Private Category.`,\n node,\n });\n } else if (relParentType === 'fractal-branch') {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Fractal Branch \"${parentFolderName}\". Fragments must be contained within a Category.`,\n node,\n });\n } else if (\n relParentType === 'root-fragment' &&\n !isParentRootContainer\n ) {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Root Fragment \"${parentFolderName}\". Fragments must be contained within a Category.`,\n node,\n });\n }\n }\n\n if (currentType === 'fractal-branch') {\n if (relParentType === 'fractal-branch') {\n context.report({\n message: `Fractal Branch \"${currentFolderName}\" cannot be placed inside another Fractal Branch \"${parentFolderName}\".`,\n node,\n });\n }\n }\n\n currentDir = path.dirname(currentDir).replace(/\\\\/g, '/');\n }\n\n if (parentType === 'layer') {\n context.report({\n message: `Layers cannot contain files directly. File \"${fileName}\" is placed directly inside Layer \"${folderName}\".`,\n node,\n });\n return;\n }\n\n if (parentType === 'fractal-branch') {\n context.report({\n message: `Fractal Branches cannot contain files directly. File \"${fileName}\" is placed directly inside Fractal Branch \"${folderName}\".`,\n node,\n });\n return;\n }\n\n if (parentType === 'invalid-fragment') {\n return; // Already reported by ancestor loop\n }\n\n // Must run before the Access Node check below: a Root Fragment's internal\n // naming (including a file named \"index.ts\") is governed by \"rootNodes\", not\n // by the ordinary Fragment taxonomy\n const rfConfig = getRootFragmentConfig(relDir, config);\n if (rfConfig) {\n const flatRootNodes = rfConfig.rootNodes.flat();\n const isMatchedRootNode = flatRootNodes.some((rn) => {\n if (rn.includes('/')) {\n const rfPath = rfConfig.paths[0] ?? '';\n const absRn = path.resolve(getProjectRoot(), rfPath, rn);\n return toRelativePath(absRn) === relPath;\n }\n return rn === fileName;\n });\n\n if (isMatchedRootNode) {\n return; // Valid Root Node\n }\n }\n\n if (fileName === 'index.ts' || fileName === 'index.js') {\n if (parentType !== 'fragment') {\n context.report({\n message: `Access Nodes (\"index.ts/index.js\") are exclusive to Fragments. Found index file directly inside \"${folderName}\" (classified as ${parentType}).`,\n node,\n });\n } else {\n const contents = readDirCached(relDir);\n const hasFragmentNode = contents.files.some(\n (f) =>\n f !== 'index.ts' &&\n f !== 'index.js' &&\n f !== 'README.md' &&\n f !== 'package.json' &&\n f !== 'tsconfig.json'\n );\n if (!hasFragmentNode) {\n context.report({\n message: `Fragment \"${folderName}\" has no Master Node. Every Fragment must contain at least one Fragment Node establishing its Role.`,\n node,\n });\n }\n }\n return;\n }\n\n if (\n fileName === 'README.md' ||\n fileName === 'package.json' ||\n fileName === 'tsconfig.json'\n ) {\n return;\n }\n\n const role = getFileRole(fileName, config);\n const ext = path.extname(fileName);\n\n // A Logical Node's name admits exactly one Role segment\n const allRoleNames = new Set(config.roles.flat());\n const roleSegments = fileName\n .slice(0, fileName.length - ext.length)\n .split('.')\n .slice(1)\n .filter((part) => allRoleNames.has(part));\n const multiRoleMessage = `File \"${fileName}\" composes multiple Roles (\"${roleSegments.join('\", \"')}\") in its name. A Logical Node may declare only one Role; promote the detail that needs its own Role to an autonomous Sub-Fragment.`;\n\n if (parentType === 'fragment') {\n // Check route hierarchy role constraint\n const matchedRoute = config.routeHierarchies?.find((rh) =>\n rh.paths.some((rp) => relDir === rp || relDir.startsWith(rp + '/'))\n );\n if (matchedRoute) {\n const contents = readDirCached(relDir);\n const fileRoles = contents.files.map((f) => getFileRole(f, config));\n if (!fileRoles.includes(matchedRoute.role)) {\n context.report({\n message: `Route terminal Fragment \"${folderName}\" must contain a Master Node with role \"${matchedRoute.role}\" (e.g. \"${folderName}.${matchedRoute.role}.ts\").`,\n node,\n });\n }\n\n const httpMethods =\n matchedRoute.httpMethods ?? DEFAULT_HTTP_METHODS;\n const routeNameRegex = new RegExp(\n `^(${httpMethods.join('|')})-[a-z0-9]+(-[a-z0-9]+)*$`\n );\n if (!routeNameRegex.test(folderName)) {\n context.report({\n message: `Route terminal Fragment \"${folderName}\" must follow the \"<method>-<object>\" pattern with a lowercase HTTP method (${httpMethods.join(', ')}).`,\n node,\n });\n }\n }\n\n // Check category role constraint\n let currentParent = path.dirname(relDir).replace(/\\\\/g, '/');\n let categoryConfig = null;\n let categoryFolderName = '';\n while (\n currentParent &&\n currentParent !== '.' &&\n currentParent !== '/'\n ) {\n const parentType = classifyFolder(currentParent, config);\n if (parentType === 'category') {\n categoryConfig = getCategoryConfig(currentParent, config);\n categoryFolderName = path.basename(currentParent);\n break;\n } else if (\n parentType === 'fragment' ||\n parentType === 'root-fragment' ||\n parentType === 'layer'\n ) {\n break;\n }\n const nextParent = path.dirname(currentParent).replace(/\\\\/g, '/');\n if (nextParent === currentParent) break;\n currentParent = nextParent;\n }\n\n if (categoryConfig && categoryConfig.role) {\n const contents = readDirCached(relDir);\n const fileRoles = contents.files.map((f) => getFileRole(f, config));\n if (!fileRoles.includes(categoryConfig.role)) {\n context.report({\n message: `Fragment \"${folderName}\" inside Category \"${categoryFolderName}\" must contain a Master Node with role \"${categoryConfig.role}\" (e.g. \"${folderName}.${categoryConfig.role}.ts\").`,\n node,\n });\n }\n }\n\n if (!fileName.startsWith(folderName + '.')) {\n context.report({\n message: `Fragment Node \"${fileName}\" must share the parent Fragment name: \"${folderName}.<role>${ext}\".`,\n node,\n });\n }\n\n // In a Fragment, ALL files must have a role, even if they have whitelisted extensions\n if (!role) {\n context.report({\n message: `File \"${fileName}\" inside Fragment \"${folderName}\" must have an explicit role suffix (e.g. \"${folderName}.style${ext}\").`,\n node,\n });\n } else if (roleSegments.length > 1) {\n context.report({ message: multiRoleMessage, node });\n } else {\n const contents = readDirCached(relDir);\n // Exclude the Access Node: it always resolves to role 'index', which a\n // Fragment Node could otherwise also carry via an explicit \".index\" suffix\n const duplicate = contents.files.find(\n (f) =>\n f !== fileName &&\n f !== 'index.ts' &&\n f !== 'index.js' &&\n getFileRole(f, config) === role\n );\n if (duplicate) {\n context.report({\n message: `Fragment Node \"${fileName}\" shares Role \"${role}\" with sibling \"${duplicate}\". Each Fragment Node must have a unique Role within its Fragment.`,\n node,\n });\n }\n }\n }\n\n if (parentType === 'category') {\n const catConfig = getCategoryConfig(relDir, config);\n if (catConfig) {\n const allowedExts = catConfig.allowedExtensions ?? [\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n ];\n if (!allowedExts.includes(ext)) {\n context.report({\n message: `File extension \"${ext}\" is not allowed in Category \"${folderName}\". Allowed extensions: ${allowedExts.join(', ')}.`,\n node,\n });\n return;\n }\n\n const isCodeExt = ['.js', '.jsx', '.ts', '.tsx'].includes(ext);\n if (isCodeExt) {\n if (!role) {\n context.report({\n message: `Logical Node \"${fileName}\" inside Category \"${folderName}\" must have a role suffix.`,\n node,\n });\n } else if (role !== catConfig.role) {\n context.report({\n message: `Role \"${role}\" for file \"${fileName}\" does not match the expected Category role \"${catConfig.role}\".`,\n node,\n });\n } else if (roleSegments.length > 1) {\n context.report({ message: multiRoleMessage, node });\n }\n } else {\n // Asset files\n if (role && role !== catConfig.role) {\n context.report({\n message: `Role \"${role}\" for asset \"${fileName}\" does not match the expected Category role \"${catConfig.role}\".`,\n node,\n });\n } else if (role && roleSegments.length > 1) {\n context.report({ message: multiRoleMessage, node });\n }\n }\n }\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Enforce naming conventions and folder taxonomy in FAF architecture',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Extracts the architectural role of a file based on its name extensions.\n * Returns special role 'index' for Access Nodes.\n * Uses `state.rolesCache` to store configurations flattened as Set for O(1) lookups.\n *\n * @param fileName - Base name of the file.\n * @param config - Tree configuration.\n * @returns The matching role suffix or null if none.\n */\nexport function getFileRole(\n fileName: string,\n config: TTreeConfig\n): null | string {\n // Exclusions: Access nodes\n if (fileName === 'index.ts' || fileName === 'index.js') {\n return 'index';\n }\n\n const parts = fileName.split('.');\n\n // Cache flat roles as a Set inside WeakMap\n let allRoles = state.rolesCache.get(config);\n if (!allRoles) {\n allRoles = new Set(config.roles.flat());\n state.rolesCache.set(config, allRoles);\n }\n\n // Search from right to left\n for (let i = parts.length - 2; i >= 1; i--) {\n const part = parts[i];\n if (part && allRoles.has(part)) {\n return part;\n }\n }\n\n return null;\n}\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\n/**\n * Returns the currently configured project root directory path.\n */\nexport function getProjectRoot(): string {\n return state.projectRoot;\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\n/**\n * @fileoverview Rule: faf/no-direct-fragment-import\n * Enforces the FAF Law of Fragment Encapsulation.\n *\n * FAF Law: External files must never import directly a Fragment's internal files.\n * All imports from outside the Fragment's boundaries must pass exclusively through its Access Node (`index.ts`).\n *\n * Valid:\n * - `import { Button } from '#_ui/_components/button/index.js';`\n *\n * Invalid:\n * - `import { Button } from '#_ui/_components/button/button.component.js';`\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import or unresolved alias\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n const importedFile = path.basename(resolvedRelPath);\n\n // If the imported file is inside a Fragment\n const importedFolderType = classifyFolder(importedDir, config!);\n if (importedFolderType === 'fragment') {\n const isAccessNode =\n importedFile === 'index.ts' || importedFile === 'index.js';\n if (!isAccessNode) {\n // Only a sibling Fragment Node (same directory) is exempt from the Access Node\n const isInside = path.dirname(relPath) === importedDir;\n if (!isInside) {\n context.report({\n message: `Direct import of Fragment internal file \"${importedFile}\" is forbidden. You must import through its Access Node (index file) in \"${importedDir}\".`,\n node,\n });\n }\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Prevent direct import of Fragment internal files from outside the Fragment',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import fs from 'fs';\nimport path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFafSettings } from '../../../_types/faf.type.js';\n\nimport { readDirCached } from '../../_primitives/read-dir-cached/index.js';\nimport { toRelativePath } from '../../_primitives/to-relative-path/index.js';\n\n/**\n * Resolves an import path into a project-root-relative path.\n * Checks against aliases (both package.json subpath imports and faf.config.ts settings).\n * Caches mapping in `state.resolvedImportPathCache` to optimize duplicate node checks.\n *\n * @param importPath - Import value (e.g. \"./helper.js\" or \"#_rules@shared/foo\").\n * @param currentFileRelative - Path of the file performing the import, relative to root.\n * @param settings - Global FAF settings.\n * @returns The resolved project-relative path, or empty string if it's an external library.\n */\nexport function resolveImportPath(\n importPath: string,\n currentFileRelative: string,\n settings: TFafSettings\n): string {\n const cacheKey = `${currentFileRelative}::${importPath}`;\n const cached = state.resolvedImportPathCache.get(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = _resolveImportPath(importPath, currentFileRelative, settings);\n state.resolvedImportPathCache.set(cacheKey, result);\n return result;\n}\n\nfunction _resolveImportPath(\n importPath: string,\n currentFileRelative: string,\n settings: TFafSettings\n): string {\n const pkgImports = loadPackageImports(state.projectRoot);\n const aliases =\n Object.keys(pkgImports).length > 0 ? pkgImports : settings?.aliases || {};\n\n // Check if it matches any registered alias prefix\n let matchedAlias: null | string = null;\n let longestMatch = 0;\n\n for (const alias of Object.keys(aliases)) {\n if (importPath === alias || importPath.startsWith(alias + '/')) {\n if (alias.length > longestMatch) {\n longestMatch = alias.length;\n matchedAlias = alias;\n }\n }\n }\n\n let relResolved: string;\n\n if (matchedAlias) {\n // 1. Alias resolution\n const target = aliases[matchedAlias];\n if (target) {\n const remainder = importPath.substring(matchedAlias.length);\n const absTarget = path.resolve(state.projectRoot, target + remainder);\n relResolved = toRelativePath(absTarget);\n } else {\n return ''; // Unresolved alias target\n }\n } else {\n // 2. Relative/absolute path resolution\n if (importPath.startsWith('.') || importPath.startsWith('/')) {\n const absCurrentDir = path.dirname(\n path.resolve(state.projectRoot, currentFileRelative)\n );\n const absResolved = path.resolve(absCurrentDir, importPath);\n relResolved = toRelativePath(absResolved);\n } else {\n return ''; // External import (e.g. library from node_modules)\n }\n }\n\n return finalizeResolvedPath(relResolved);\n}\n\n/**\n * Bare script extensions (i.e. without any additional Role/suffix segment) considered\n * when disambiguating an extension-less import against multiple same-prefix candidates.\n */\nconst SCRIPT_EXTENSIONS = new Set([\n 'cjs',\n 'cts',\n 'js',\n 'jsx',\n 'mjs',\n 'mts',\n 'ts',\n 'tsx',\n]);\n\n/**\n * Helper to check if a resolved relative path points to a directory with an index file,\n * or a file missing its extension, and resolves it accordingly.\n */\nfunction finalizeResolvedPath(relResolved: string): string {\n const resolvedDir = path.dirname(relResolved).replace(/\\\\/g, '/');\n const resolvedBase = path.basename(relResolved);\n\n // 1. Check if the path itself is a directory containing index.ts/js\n const dirContents = readDirCached(relResolved);\n if (dirContents.files.includes('index.ts')) {\n return (relResolved === '.' ? '' : relResolved + '/') + 'index.ts';\n }\n if (dirContents.files.includes('index.js')) {\n return (relResolved === '.' ? '' : relResolved + '/') + 'index.js';\n }\n\n // 2. Check if the path is a file missing its extension\n const parentContents = readDirCached(resolvedDir);\n const exactMatch = parentContents.files.find((f) => f === resolvedBase);\n if (!exactMatch) {\n // Multiple files can share the same prefix (e.g. \"foo.ts\" and \"foo.spec.ts\" both\n // start with \"foo.\"). Prefer the candidate whose remainder is a bare script\n // extension over one carrying an additional Role/suffix segment, so resolution\n // doesn't depend on filesystem readdir order.\n const candidates = parentContents.files.filter((f) =>\n f.startsWith(resolvedBase + '.')\n );\n const matchWithExt =\n candidates.find((f) =>\n SCRIPT_EXTENSIONS.has(f.slice(resolvedBase.length + 1))\n ) ?? candidates[0];\n if (matchWithExt) {\n return (resolvedDir === '.' ? '' : resolvedDir + '/') + matchWithExt;\n }\n }\n\n return relResolved;\n}\n\nfunction loadPackageImports(projectRootPath: string): Record<string, string> {\n if (state.packageImports !== null) {\n return state.packageImports;\n }\n\n state.packageImports = {};\n\n // Isolate the test environment from physical package.json of the host plugin codebase\n const isTest =\n typeof process !== 'undefined' &&\n (process.env.NODE_ENV === 'test' || process.env.VITEST === 'true');\n if (isTest) {\n return state.packageImports;\n }\n\n const pkgPath = path.resolve(projectRootPath, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkgContent = fs.readFileSync(pkgPath, 'utf8');\n const pkg = JSON.parse(pkgContent) as {\n imports?: Record<string, unknown>;\n };\n if (pkg.imports) {\n for (const [key, val] of Object.entries(pkg.imports)) {\n if (typeof val === 'string') {\n // Strip wildcards\n const cleanKey = key.endsWith('/*')\n ? key.slice(0, -2)\n : key.endsWith('*')\n ? key.slice(0, -1)\n : key;\n let cleanVal = val.endsWith('/*')\n ? val.slice(0, -2)\n : val.endsWith('*')\n ? val.slice(0, -1)\n : val;\n\n // Normalize target path (remove leading './' or '/')\n if (cleanVal.startsWith('./')) {\n cleanVal = cleanVal.substring(2);\n } else if (cleanVal.startsWith('/')) {\n cleanVal = cleanVal.substring(1);\n }\n\n state.packageImports[cleanKey] = cleanVal;\n }\n }\n }\n } catch {\n // Ignore parsing errors and keep packageImports empty\n }\n }\n\n return state.packageImports;\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getFractalBranchOwner } from '#_rules@shared/_utils/_primitives/get-fractal-branch-owner/index.js';\nimport { getImmediateSubDomain } from '#_rules@shared/_utils/_primitives/get-immediate-sub-domain/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\nimport { getPrivateCategoryInfo } from '#_rules@shared/_utils/_systems/get-private-category-info/index.js';\n\n/**\n * @fileoverview Rule: faf/no-fractal-branch-leak\n * Enforces the FAF Law of Fractal Branch Encapsulation.\n *\n * FAF Law: Fractal Branches (directories following the `_<Scope>@shared` naming convention)\n * hold internal shared implementations. They are private to their parent Scope's subtree\n * and cannot leak or be imported by files outside of that scope.\n *\n * Valid:\n * - A utility inside `src/_rules/_rules@shared/_utils/` importing from `src/_rules/_rules@shared/`.\n *\n * Invalid:\n * - A rule inside `src/_rules/naming-conventions/` importing from `src/_rules/_rules@shared/_utils/_utils@shared/` (out-of-scope).\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import or unresolved alias\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n const fractalBranchOwner = getFractalBranchOwner(importedDir);\n\n if (fractalBranchOwner) {\n // The importing file must be inside the owner's sub-tree\n const isDescendant =\n relPath === fractalBranchOwner ||\n relPath.startsWith(fractalBranchOwner + '/');\n if (!isDescendant) {\n context.report({\n message: `Importing from Fractal Branch is forbidden. The imported resource is private to \"${fractalBranchOwner}\" and its descendants.`,\n node,\n });\n } else {\n // Even within an authorized Fractal Branch scope, a Private Category nested\n // inside it still applies its own, narrower access restriction\n const info = getPrivateCategoryInfo(importedDir, config!);\n if (info) {\n const { owner, privateCategoryPath } = info;\n const isPrivateDirectChild = path.dirname(relPath) === owner;\n\n const importerSubDomain = getImmediateSubDomain(\n relPath,\n privateCategoryPath\n );\n const importedSubDomain = getImmediateSubDomain(\n resolvedRelPath,\n privateCategoryPath\n );\n const isInsideSameSubDomain =\n importerSubDomain !== '' &&\n importerSubDomain === importedSubDomain;\n\n // `fractalBranchOwner` is already the closest Fractal Branch to importedDir (same\n // input as above), so if it lies inside the Private Category, `isDescendant` above\n // has already proven the importer's access to it.\n const isFractalBranchAllowed =\n fractalBranchOwner === privateCategoryPath ||\n fractalBranchOwner.startsWith(privateCategoryPath + '/');\n\n if (\n !isPrivateDirectChild &&\n !isInsideSameSubDomain &&\n !isFractalBranchAllowed\n ) {\n context.report({\n message: `Importing from Private Category is forbidden. The imported resource is private to \"${owner}\".`,\n node,\n });\n }\n }\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Prevent leakage of Fractal Branch internals outside their owner scope',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import path from 'path';\n\n/**\n * Returns the owner of the closest Fractal Branch ancestor, or null.\n */\nexport function getFractalBranchOwner(relPath: string): null | string {\n let current = relPath;\n while (current && current !== '.' && current !== '/') {\n const folderName = path.basename(current);\n if (folderName.startsWith('_') && folderName.includes('@shared')) {\n return path.dirname(current).replace(/\\\\/g, '/');\n }\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return null;\n}\n","/**\n * Returns the immediate sub-domain path relative to the private category path,\n * or the private category path itself if no sub-segment exists.\n * Returns an empty string if the relPath is not inside the private category path.\n */\nexport function getImmediateSubDomain(\n relPath: string,\n privateCategoryPath: string\n): string {\n if (\n relPath !== privateCategoryPath &&\n !relPath.startsWith(privateCategoryPath + '/')\n ) {\n return '';\n }\n const relative = relPath.substring(privateCategoryPath.length + 1);\n const firstSegment = relative.split('/')[0];\n return firstSegment\n ? privateCategoryPath + '/' + firstSegment\n : privateCategoryPath;\n}\n","import path from 'path';\n\nimport type { TTreeConfig } from '../../../_types/faf.type.js';\n\nimport { classifyFolder } from '../../_aggregates/classify-folder/index.js';\n\n/**\n * Returns the owner and private category path of the private category if the given path is inside one, or null.\n */\nexport function getPrivateCategoryInfo(\n relPath: string,\n config: TTreeConfig\n): null | { owner: string; privateCategoryPath: string } {\n let current = relPath;\n while (current && current !== '.' && current !== '/') {\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) {\n break;\n }\n\n const currentType = classifyFolder(current, config);\n const parentType = classifyFolder(parent, config);\n\n if (\n currentType === 'category' &&\n (parentType === 'fragment' || parentType === 'root-fragment')\n ) {\n return { owner: parent, privateCategoryPath: current };\n }\n\n current = parent;\n }\n return null;\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type {\n TFafSettings,\n TRootFragmentConfig,\n TTreeConfig,\n} from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfigIncludingExcluded } from '#_rules@shared/_utils/_primitives/find-tree-config-including-excluded/index.js';\nimport { getFileRole } from '#_rules@shared/_utils/_primitives/get-file-role/index.js';\nimport { getLcaAndSubBranches } from '#_rules@shared/_utils/_primitives/get-lca-and-sub-branches/index.js';\nimport { getRoleHierarchyIndex } from '#_rules@shared/_utils/_primitives/get-role-hierarchy-index/index.js';\nimport { getRootFragmentConfig } from '#_rules@shared/_utils/_primitives/get-root-fragment-config/index.js';\nimport { readDirCached } from '#_rules@shared/_utils/_primitives/read-dir-cached/index.js';\nimport { resolveHorizontalHierarchy } from '#_rules@shared/_utils/_primitives/resolve-horizontal-hierarchy/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\nfunction getDirectoryRole(dirPath: string, config: TTreeConfig): null | string {\n const folderName = path.basename(dirPath);\n if (folderName.startsWith('_')) {\n return getRoleFromFolderName(folderName, config);\n }\n const contents = readDirCached(dirPath);\n for (const file of contents.files) {\n if (file.startsWith(folderName + '.')) {\n const role = getFileRole(file, config);\n if (role) return role;\n }\n }\n return null;\n}\n\nfunction getRoleFromFolderName(\n name: string,\n config: TTreeConfig\n): null | string {\n const catConfig = config.categories?.find((c) => c.name === name);\n return catConfig ? (catConfig.role ?? null) : null;\n}\n\nfunction getRootNodeIndex(\n relPath: string,\n rfConfig: TRootFragmentConfig,\n lcaPath: string\n): number {\n const relToLca = path.relative(lcaPath, relPath).replace(/\\\\/g, '/');\n for (let i = 0; i < rfConfig.rootNodes.length; i++) {\n const group = rfConfig.rootNodes[i];\n if (group && group.includes(relToLca)) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Checks if B is inside a Private Category of the LCA directory.\n */\nfunction isInsidePrivateCategoryOfLca(\n relPathB: string,\n lcaPath: string,\n config: TTreeConfig\n): boolean {\n let current = relPathB;\n while (current && current !== '.' && current !== '/' && current !== lcaPath) {\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) {\n break;\n }\n\n const currentType = classifyFolder(current, config);\n const parentType = classifyFolder(parent, config);\n\n if (\n currentType === 'category' &&\n (parentType === 'fragment' || parentType === 'root-fragment') &&\n parent === lcaPath\n ) {\n return true;\n }\n\n current = parent;\n }\n return false;\n}\n\n/**\n * @fileoverview Rule: faf/no-peer-dependency\n * Enforces the FAF Law of Separation between Peers.\n *\n * FAF Law: Sibling directories and files (at the same filesystem level) must not import each other\n * unless a horizontal hierarchy flow is explicitly configured (via local/global horizontal hierarchies).\n * For files inside a Fragment, peer imports flow according to the index order defined in the `roles` configuration.\n *\n * Valid:\n * - A compound utility importing from a primitive utility (if compounds ➔ primitives is configured).\n * - Sibling Fragment Nodes importing from each other according to the roles scale order (e.g. `util` imports `type`).\n *\n * Invalid:\n * - A primitive utility importing from a compound utility (violating horizontal hierarchy).\n * - Circular imports between sibling folders with no configured hierarchy.\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfigIncludingExcluded(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n const currentDir = path.dirname(relPath);\n const isCurrentFileExcluded =\n config.excludes?.some(\n (exc) => relPath === exc || relPath.startsWith(exc + '/')\n ) ?? false;\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import\n }\n\n const isImportedFileExcluded =\n config?.excludes?.some(\n (exc) =>\n resolvedRelPath === exc || resolvedRelPath.startsWith(exc + '/')\n ) ?? false;\n\n // Case A (Logical Node ➔ Foreign Domain)\n if (!isCurrentFileExcluded && isImportedFileExcluded) {\n context.report({\n message: `Importing from Foreign Domain \"${resolvedRelPath}\" is forbidden for Logical Nodes.`,\n node,\n });\n return;\n }\n\n // Case B (Foreign Domain ➔ Logical Node)\n if (isCurrentFileExcluded && !isImportedFileExcluded) {\n context.report({\n message: `Foreign Domain files cannot import Logical Nodes from FAF tree (\"${resolvedRelPath}\").`,\n node,\n });\n return;\n }\n\n // If either is excluded, do not run further peer dependency checks\n if (isCurrentFileExcluded || isImportedFileExcluded) {\n return;\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n\n // Scenario 1: Same directory (Fragment Nodes or direct siblings)\n if (currentDir === importedDir) {\n const fileA = path.basename(relPath);\n const fileB = path.basename(resolvedRelPath);\n\n const roleA = getFileRole(fileA, config!);\n const roleB = getFileRole(fileB, config!);\n\n if (roleA && roleB) {\n const idxA = getRoleHierarchyIndex(roleA, config!);\n const idxB = getRoleHierarchyIndex(roleB, config!);\n\n if (idxA !== -1 && idxB !== -1) {\n if (idxB >= idxA) {\n context.report({\n message: `Sibling import violation: \"${fileA}\" (role \"${roleA}\", level ${idxA}) cannot import from \"${fileB}\" (role \"${roleB}\", level ${idxB}). Imports must flow from lower to higher levels.`,\n node,\n });\n }\n }\n }\n return;\n }\n\n // Scenario 2: Different directories\n const lcaInfo = getLcaAndSubBranches(currentDir, importedDir);\n if (!lcaInfo) {\n return;\n }\n\n const { lca, subA, subB } = lcaInfo;\n\n // Exception: Fractal Branch\n if (subB.startsWith('_') && subB.includes('@shared')) {\n // Allowed to import from own Fractal Branch\n return;\n }\n\n // Exception: Private Category of the LCA\n if (isInsidePrivateCategoryOfLca(importedDir, lca, config!)) {\n return;\n }\n\n // A descendant reaching for the Fragment root has no privileged access to it\n if (subB === '' && classifyFolder(lca, config!) === 'fragment') {\n context.report({\n message: `Peer separation violation: \"${subA}\" cannot import directly from the root of Fragment \"${lca}\". A node nested inside a Private Category or Fractal Branch has no privileged access to its owning Fragment's other direct children; promote the shared resource to a Fractal Branch if the sharing need is genuine.`,\n node,\n });\n return;\n }\n\n // Check if LCA is a Root Fragment and we are importing between Root Nodes\n const rfConfig = getRootFragmentConfig(lca, config!);\n if (rfConfig) {\n const idxRootA = getRootNodeIndex(relPath, rfConfig, lca);\n const idxRootB = getRootNodeIndex(resolvedRelPath, rfConfig, lca);\n\n if (idxRootA !== -1 && idxRootB !== -1) {\n if (idxRootB >= idxRootA) {\n context.report({\n message: `Root Node import violation: \"${path.basename(relPath)}\" cannot import from \"${path.basename(resolvedRelPath)}\" under Root Fragment \"${lca}\".`,\n node,\n });\n }\n return;\n }\n }\n\n // Root Nodes are exempt from the Role naming convention, so relationships involving them\n // (including nested or sibling Root Fragments) can never fall back to the Role scale: they\n // must always be explicitly authorized by the architect via \"rootNodes\" at the common ancestor.\n const isSubARootFragment =\n classifyFolder(path.posix.join(lca, subA), config!) === 'root-fragment';\n const isSubBRootFragment =\n classifyFolder(path.posix.join(lca, subB), config!) === 'root-fragment';\n\n if (isSubARootFragment || isSubBRootFragment) {\n context.report({\n message: `Root Node import violation: \"${relPath}\" cannot import from \"${resolvedRelPath}\" because no \"rootNodes\" relationship is configured under Root Fragment \"${lca}\". Relationships between Root Nodes must always be explicitly authorized by the architect.`,\n node,\n });\n return;\n }\n\n // Determine if there is a defined horizontal hierarchy at LCA and whether the import is allowed\n const { allowed, defined: hasDefinedHierarchy } =\n resolveHorizontalHierarchy(lca, subA, subB, config!);\n\n if (hasDefinedHierarchy) {\n if (!allowed) {\n context.report({\n message: `Horizontal hierarchy violation: \"${subA}\" cannot import from \"${subB}\" under parent \"${lca}\".`,\n node,\n });\n }\n } else {\n // Fallback to role-based hierarchy comparison\n const roleA = getDirectoryRole(path.posix.join(lca, subA), config!);\n const roleB = getDirectoryRole(path.posix.join(lca, subB), config!);\n\n const idxA = roleA ? getRoleHierarchyIndex(roleA, config!) : -1;\n const idxB = roleB ? getRoleHierarchyIndex(roleB, config!) : -1;\n\n if (idxA !== -1 && idxB !== -1) {\n if (idxB >= idxA) {\n context.report({\n message: `Horizontal hierarchy violation (fallback to roles): sibling directory \"${subA}\" (mapped to role \"${roleA}\", level ${idxA}) cannot import from \"${subB}\" (mapped to role \"${roleB}\", level ${idxB}) under parent \"${lca}\".`,\n node,\n });\n }\n } else {\n // If no hierarchy is defined and cannot resolve roles, it is forbidden by default\n context.report({\n message: `Peer separation violation: sibling directories \"${subA}\" and \"${subB}\" cannot import each other because no horizontal hierarchy is defined under parent \"${lca}\".`,\n node,\n });\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Enforce the Law of Separation between Peers (no-peer-dependency)',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFafSettings, TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Finds the tree configuration that includes the given relative file path,\n * even if it is otherwise excluded (Foreign Domain). Uses `state.treeConfigIncludingExcludedCache`\n * for performance.\n *\n * @param relPath - Path relative to the project root.\n * @param settings - The global FAF settings containing trees configuration.\n * @returns The matching tree configuration or null if not found.\n */\nexport function findTreeConfigIncludingExcluded(\n relPath: string,\n settings: TFafSettings\n): null | TTreeConfig {\n if (!settings || !settings.trees) {\n return null;\n }\n\n const cached = state.treeConfigIncludingExcludedCache.get(relPath);\n if (cached !== undefined) {\n return cached;\n }\n\n let result: null | TTreeConfig = null;\n for (const tree of settings.trees) {\n const isIncluded = tree.includes.some(\n (inc) => relPath === inc || relPath.startsWith(inc + '/')\n );\n\n if (isIncluded) {\n result = tree;\n break;\n }\n }\n\n state.treeConfigIncludingExcludedCache.set(relPath, result);\n return result;\n}\n","/**\n * Finds the Lowest Common Ancestor (LCA) path of two given path strings,\n * as well as the immediate child segment of the LCA for each path.\n * Used to identify parent-child relationships and siblings.\n *\n * @param pathA - First path string.\n * @param pathB - Second path string.\n * @returns Object containing the LCA and immediate sub-branches, or null if no common ancestor.\n */\nexport function getLcaAndSubBranches(\n pathA: string,\n pathB: string\n): null | { lca: string; subA: string; subB: string } {\n const partsA = pathA.split('/');\n const partsB = pathB.split('/');\n\n let commonLength = 0;\n while (\n commonLength < partsA.length &&\n commonLength < partsB.length &&\n partsA[commonLength] === partsB[commonLength]\n ) {\n commonLength++;\n }\n\n if (commonLength === 0) {\n return null;\n }\n\n const lca = partsA.slice(0, commonLength).join('/');\n const subA = partsA[commonLength] || '';\n const subB = partsB[commonLength] || '';\n\n return { lca, subA, subB };\n}\n","import type { TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Returns the hierarchy level index of a given role.\n * Roles at lower indexes (earlier in the roles array) represent lower-level/primitive constructs,\n * while higher indexes represent higher-level/composed ones.\n *\n * @param role - Role string to look up.\n * @param config - Tree configuration containing the roles scale.\n * @returns The index of the role group or -1 if the role is not defined.\n */\nexport function getRoleHierarchyIndex(\n role: string,\n config: TTreeConfig\n): number {\n for (let i = 0; i < config.roles.length; i++) {\n const roleGroup = config.roles[i];\n if (roleGroup && roleGroup.includes(role)) {\n return i;\n }\n }\n return -1;\n}\n","import type { TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Resolves the horizontal hierarchy relationship between sub-directories subA and subB at a common ancestor lcaPath.\n * Checks local path-specific hierarchies before falling back to global hierarchies.\n * Returns both whether a hierarchy constraint is defined, and if defined, whether the import is allowed.\n *\n * @param lcaPath - Path of the common parent directory.\n * @param subA - Sibling directory segment of the importer.\n * @param subB - Sibling directory segment of the imported module.\n * @param config - Tree configuration.\n * @returns Object indicating if the hierarchy is defined and if the import is allowed.\n */\nexport function resolveHorizontalHierarchy(\n lcaPath: string,\n subA: string,\n subB: string,\n config: TTreeConfig\n): { allowed: boolean; defined: boolean } {\n // 1. Check local hierarchies first\n const local = config.localHorizontalHierarchies?.find((lh) =>\n lh.paths.includes(lcaPath)\n );\n if (local) {\n const idxA = local.hierarchies.findIndex((group) => group.includes(subA));\n const idxB = local.hierarchies.findIndex((group) => group.includes(subB));\n if (idxA !== -1 && idxB !== -1) {\n return { allowed: idxB < idxA, defined: true };\n }\n }\n\n // 2. Check global hierarchies\n const globalHierarchies = config.globalHorizontalHierarchies || [];\n for (const gh of globalHierarchies) {\n const idxA = gh.findIndex((group) => group.includes(subA));\n const idxB = gh.findIndex((group) => group.includes(subB));\n if (idxA !== -1 && idxB !== -1) {\n return { allowed: idxB < idxA, defined: true };\n }\n }\n\n // No hierarchy defined for this pair — sibling imports forbidden by default\n return { allowed: false, defined: false };\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getFractalBranchOwner } from '#_rules@shared/_utils/_primitives/get-fractal-branch-owner/index.js';\nimport { getImmediateSubDomain } from '#_rules@shared/_utils/_primitives/get-immediate-sub-domain/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\nimport { getPrivateCategoryInfo } from '#_rules@shared/_utils/_systems/get-private-category-info/index.js';\n\n/**\n * @fileoverview Rule: faf/no-private-category-leak\n * Enforces the FAF Law of Private Category Encapsulation.\n *\n * FAF Law: Category folders prefixed with `_` nested directly inside a Fragment/Root Fragment\n * are Private Categories containing internal implementation details.\n * Their contents are private to the owning Fragment/Root Fragment subtree and cannot leak or be imported externally.\n *\n * Valid:\n * - Sibling nodes within the owner Fragment importing from the Private Category (e.g. `example/example.component.tsx`\n * importing from `example/_components/child/index.js`).\n *\n * Invalid:\n * - A rule inside `src/_rules/naming-conventions/` importing from `src/_rules/_rules@shared/_utils/_utils@shared/_stores/cache/` (leak).\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import or unresolved alias\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n const info = getPrivateCategoryInfo(importedDir, config!);\n\n if (info) {\n const { owner, privateCategoryPath } = info;\n\n // A Fractal Branch nested inside the Private Category is a closer, more specific\n // encapsulation boundary: its own Law is the sole authority on access to it, and\n // the Private Category's direct-child/sub-domain grants do not apply (non-transitivity).\n let isFractalBranchInPrivateCategory = false;\n let isFractalBranchAllowed = false;\n const fbOwner = getFractalBranchOwner(importedDir);\n if (fbOwner) {\n const isFbInsidePrivateCategory =\n fbOwner === privateCategoryPath ||\n fbOwner.startsWith(privateCategoryPath + '/');\n if (isFbInsidePrivateCategory) {\n isFractalBranchInPrivateCategory = true;\n isFractalBranchAllowed =\n relPath === fbOwner || relPath.startsWith(fbOwner + '/');\n }\n }\n\n const isDirectChild = path.dirname(relPath) === owner;\n\n const importerSubDomain = getImmediateSubDomain(\n relPath,\n privateCategoryPath\n );\n const importedSubDomain = getImmediateSubDomain(\n resolvedRelPath,\n privateCategoryPath\n );\n const isInsideSameSubDomain =\n importerSubDomain !== '' && importerSubDomain === importedSubDomain;\n\n const isAllowed = isFractalBranchInPrivateCategory\n ? isFractalBranchAllowed\n : isDirectChild || isInsideSameSubDomain;\n\n if (!isAllowed) {\n context.report({\n message: `Importing from Private Category is forbidden. The imported resource is private to \"${owner}\".`,\n node,\n });\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Prevent leakage and unauthorized imports of Private Category internals',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import categoryMutuallyExclusive from './_rules/category-mutually-exclusive/index.js';\nimport enforceAccessNode from './_rules/enforce-access-node/index.js';\nimport namingConventions from './_rules/naming-conventions/index.js';\nimport noDirectFragmentImport from './_rules/no-direct-fragment-import/index.js';\nimport noFractalBranchLeak from './_rules/no-fractal-branch-leak/index.js';\nimport noPeerDependency from './_rules/no-peer-dependency/index.js';\nimport noPrivateCategoryLeak from './_rules/no-private-category-leak/index.js';\n\n/**\n * Mapping of FAF rule identifiers to their respective ESLint rule modules.\n * All rules are namespaced under 'faf/*' when consumed in configurations.\n */\nexport const rules = {\n 'category-mutually-exclusive': categoryMutuallyExclusive,\n 'enforce-access-node': enforceAccessNode,\n 'naming-conventions': namingConventions,\n 'no-direct-fragment-import': noDirectFragmentImport,\n 'no-fractal-branch-leak': noFractalBranchLeak,\n 'no-peer-dependency': noPeerDependency,\n 'no-private-category-leak': noPrivateCategoryLeak,\n} as const;\n","import type { TFafPlugin } from './types.js';\n\nimport { rules } from './rules.js';\n\n/**\n * Predefined configuration presets exposed by the FAF ESLint plugin.\n * Includes the recommended flat configuration preset that registers the plugin\n * and activates all taxonomy and dependency rules as blocking \"error\" diagnostics.\n */\nexport const configs: TFafPlugin['configs'] = {\n recommended: {\n plugins: {\n faf: {\n rules,\n },\n },\n rules: {\n 'faf/category-mutually-exclusive': 'error',\n 'faf/enforce-access-node': 'error',\n 'faf/naming-conventions': 'error',\n 'faf/no-direct-fragment-import': 'error',\n 'faf/no-fractal-branch-leak': 'error',\n 'faf/no-peer-dependency': 'error',\n 'faf/no-private-category-leak': 'error',\n },\n },\n};\n","import type { TFafPlugin } from './types.js';\n\nimport pkg from '../package.json' with { type: 'json' };\nimport { configs } from './configs.js';\nimport { rules } from './rules.js';\n\nexport { configs } from './configs.js';\nexport { rules } from './rules.js';\n\n/**\n * Default export representing the ESLint plugin for the Fractal Architecture Framework (FAF).\n * Assembles configs, rules, and package metadata.\n *\n * Exposes rules and configs both as named exports (for backward compatibility/direct consumption)\n * and within the default plugin export container.\n */\nconst plugin: TFafPlugin = {\n configs,\n meta: {\n name: '@morriconeluca/eslint-plugin-faf',\n version: pkg.version,\n },\n rules,\n};\n\nexport default plugin;\n"],"mappings":"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","names":["path","path","path","path","path","path","path","path","path","rule","path","path","rule","path","parentType","path","fs","path","path","fs","rule","path","path","path","path","path","rule","path","path","path","rule","path","rule","path"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/_rules/category-mutually-exclusive/category-mutually-exclusive.rule.ts","../src/_rules/_rules@shared/_utils/_aggregates/classify-folder/classify-folder.util.ts","../src/_rules/_rules@shared/_utils/_utils@shared/_stores/cache/cache.store.ts","../src/_rules/_rules@shared/_utils/_primitives/get-root-fragment-config/get-root-fragment-config.util.ts","../src/_rules/_rules@shared/_utils/_compounds/is-root-fragment/is-root-fragment.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-category-config/get-category-config.util.ts","../src/_rules/_rules@shared/_utils/_primitives/read-dir-cached/read-dir-cached.util.ts","../src/_rules/_rules@shared/_utils/_primitives/find-tree-config/find-tree-config.util.ts","../src/_rules/_rules@shared/_utils/_primitives/to-relative-path/to-relative-path.util.ts","../src/_rules/enforce-access-node/enforce-access-node.rule.ts","../src/_rules/naming-conventions/naming-conventions.rule.ts","../src/_rules/_rules@shared/_utils/_primitives/get-file-role/get-file-role.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-project-root/get-project-root.util.ts","../src/_rules/no-direct-fragment-import/no-direct-fragment-import.rule.ts","../src/_rules/_rules@shared/_utils/_aggregates/resolve-import-path/resolve-import-path.util.ts","../src/_rules/no-fractal-branch-leak/no-fractal-branch-leak.rule.ts","../src/_rules/_rules@shared/_utils/_primitives/get-fractal-branch-owner/get-fractal-branch-owner.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-immediate-sub-domain/get-immediate-sub-domain.util.ts","../src/_rules/_rules@shared/_utils/_systems/get-private-category-info/get-private-category-info.util.ts","../src/_rules/no-peer-dependency/no-peer-dependency.rule.ts","../src/_rules/_rules@shared/_utils/_primitives/find-tree-config-including-excluded/find-tree-config-including-excluded.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-lca-and-sub-branches/get-lca-and-sub-branches.util.ts","../src/_rules/_rules@shared/_utils/_primitives/get-role-hierarchy-index/get-role-hierarchy-index.util.ts","../src/_rules/_rules@shared/_utils/_primitives/resolve-horizontal-hierarchy/resolve-horizontal-hierarchy.util.ts","../src/_rules/no-private-category-leak/no-private-category-leak.rule.ts","../src/rules.ts","../src/configs.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@morriconeluca/eslint-plugin-faf\",\n \"version\": \"0.4.0\",\n \"description\": \"An ESLint plugin for FAF projects.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/morriconeluca/eslint-plugin-faf.git\"\n },\n \"main\": \"./dist/main.cjs\",\n \"module\": \"./dist/main.js\",\n \"types\": \"./dist/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/main.d.ts\",\n \"import\": \"./dist/main.js\",\n \"require\": \"./dist/main.cjs\"\n }\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"imports\": {\n \"#_rules@shared/*\": \"./src/_rules/_rules@shared/*\",\n \"#_utils@shared/*\": \"./src/_rules/_rules@shared/_utils/_utils@shared/*\"\n },\n \"type\": \"module\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"npm run lint && tsup\",\n \"test\": \"vitest run\",\n \"dev\": \"vitest\",\n \"lint\": \"npm run lint:types && npm run lint:eslint\",\n \"lint:eslint\": \"eslint .\",\n \"lint:types\": \"tsc --noEmit\",\n \"lint:fix\": \"eslint --fix .\",\n \"format\": \"prettier --write .\",\n \"check-format\": \"prettier --check .\",\n \"ci\": \"npm run build && npm run check-format && npm run test\",\n \"prepublishOnly\": \"npm run ci\",\n \"local-release\": \"changeset version && changeset publish\",\n \"prepare\": \"husky\"\n },\n \"keywords\": [\n \"eslint\",\n \"eslintplugin\",\n \"faf\"\n ],\n \"author\": \"Luca Morricone\",\n \"license\": \"MIT\",\n \"peerDependencies\": {\n \"eslint\": \"^8.57.0 || ^9.0.0 || ^10.0.0\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.31.0\",\n \"@commitlint/cli\": \"^21.0.2\",\n \"@commitlint/config-conventional\": \"^21.0.2\",\n \"@eslint/js\": \"^10.0.1\",\n \"@types/eslint\": \"^9.6.1\",\n \"@types/node\": \"^25.9.3\",\n \"@typescript-eslint/utils\": \"^8.24.1\",\n \"dependency-cruiser\": \"^17.4.3\",\n \"eslint\": \"^10.5.0\",\n \"eslint-import-resolver-typescript\": \"^4.4.5\",\n \"eslint-plugin-import-x\": \"^4.16.2\",\n \"eslint-plugin-perfectionist\": \"^5.9.0\",\n \"husky\": \"^9.1.7\",\n \"lint-staged\": \"^17.0.7\",\n \"prettier\": \"^3.8.4\",\n \"tsup\": \"^8.3.6\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.61.0\",\n \"vitest\": \"^4.1.9\"\n },\n \"lint-staged\": {\n \"*\": \"prettier --write --ignore-unknown\",\n \"src/**/*.ts\": \"eslint --fix\"\n }\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getCategoryConfig } from '#_rules@shared/_utils/_primitives/get-category-config/index.js';\nimport { readDirCached } from '#_rules@shared/_utils/_primitives/read-dir-cached/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\n/**\n * @fileoverview Rule: faf/category-mutually-exclusive\n * Enforces the FAF rule of Category Purity (Mutua Esclusività).\n *\n * FAF Law: Categories must contain either ONLY single files (Logical Nodes) or ONLY subfolders (Fragments).\n *\n * Valid:\n * - A category configured with `allowSingleFiles: true` containing only files (e.g. `_types/user.type.ts`).\n * - A category configured with `allowSingleFiles: false` containing only Fragment folders (e.g. `_utils/get-path/`).\n *\n * Invalid:\n * - Mixing single files and subfolders directly inside the same category directory.\n * - Placing files directly in a Category that is not configured to allow single files (`allowSingleFiles: false`).\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n const relDir = path.dirname(relPath);\n const parentType = classifyFolder(relDir, config);\n\n if (parentType !== 'category') {\n return {};\n }\n\n const fileName = path.basename(relPath);\n\n return {\n Program(node) {\n const contents = readDirCached(relDir);\n\n const activeFiles = contents.files.filter(\n (f) => f !== 'README.md' && f !== 'package.json' && !f.startsWith('.')\n );\n const activeDirs = contents.dirs.filter((d) => !d.startsWith('_')); // Ignore sub-categories/layers/fractal branches\n\n const hasFiles = activeFiles.length > 0;\n const hasDirs = activeDirs.length > 0;\n\n if (hasFiles && hasDirs) {\n context.report({\n loc: { column: 0, line: 1 },\n message: `Mutua Esclusività violation in Category \"${path.basename(relDir)}\": cannot mix single files (${activeFiles.join(', ')}) and Fragment directories (${activeDirs.join(', ')}).`,\n node,\n });\n }\n\n // Also check if category config allows single files\n if (hasFiles) {\n const folderName = path.basename(relDir);\n const catConfig = getCategoryConfig(relDir, config);\n if (catConfig) {\n const ext = path.extname(fileName);\n const isAllowedAsset =\n catConfig.allowedExtensions?.includes(ext) ?? false;\n\n // If the category defines allowedExtensions and this file's\n // extension is not in the list, skip — naming-conventions\n // already reports a precise extension-mismatch error.\n if (\n !isAllowedAsset &&\n catConfig.allowedExtensions &&\n catConfig.allowedExtensions.length > 0\n ) {\n return;\n }\n\n if (!catConfig.allowSingleFiles && !isAllowedAsset) {\n context.report({\n message: `Category \"${folderName}\" cannot contain file nodes directly. File \"${fileName}\" must be encapsulated inside a Fragment.`,\n node,\n });\n }\n }\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Enforce that Categories contain either only file nodes or only Fragment folders, and check whitelist roles',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFolderType, TTreeConfig } from '../../../_types/faf.type.js';\n\nimport { isRootFragment } from '../../_compounds/is-root-fragment/index.js';\nimport { getCategoryConfig } from '../../_primitives/get-category-config/index.js';\nimport { readDirCached } from '../../_primitives/read-dir-cached/index.js';\n\n/**\n * Classifies a relative directory path into a FAF structural category (Layer, Category, Fragment, etc.).\n * Memoizes results in `state.classifyCache` to optimize recursive parent checks.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns The classified folder type.\n */\nexport function classifyFolder(\n relDirPath: string,\n config: TTreeConfig\n): TFolderType {\n const cached = state.classifyCache.get(relDirPath);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = _classifyFolder(relDirPath, config);\n state.classifyCache.set(relDirPath, result);\n return result;\n}\n\nfunction _classifyFolder(relDirPath: string, config: TTreeConfig): TFolderType {\n const isExcluded = config.excludes?.some(\n (exc) => relDirPath === exc || relDirPath.startsWith(exc + '/')\n );\n if (isExcluded) {\n return 'foreign';\n }\n\n if (isRootFragment(relDirPath, config)) {\n return 'root-fragment';\n }\n\n const folderName = path.basename(relDirPath);\n\n if (folderName.startsWith('_') && folderName.includes('@shared')) {\n return 'fractal-branch';\n }\n\n const contents = readDirCached(relDirPath);\n const hasAccessNode = contents.files.some(\n (f) => f === 'index.ts' || f === 'index.js'\n );\n\n const isRoute =\n config.routeHierarchies &&\n config.routeHierarchies.some((rh) =>\n rh.paths.some((rp) => {\n if (relDirPath.startsWith(rp + '/')) {\n const remainder = relDirPath.substring(rp.length + 1);\n const segments = remainder.split('/');\n return !segments.some(\n (seg) => seg.endsWith('@shared') || seg.includes('@shared')\n );\n }\n return false;\n })\n );\n\n if (isRoute && !hasAccessNode) {\n return 'layer';\n }\n\n if (folderName.startsWith('_')) {\n const catConfig = getCategoryConfig(relDirPath, config);\n if (catConfig) {\n return 'category';\n }\n\n return 'layer';\n }\n\n const isCategory =\n config.categories &&\n config.categories.some((c) => c.name === '_' + folderName);\n if (isCategory && !hasAccessNode) {\n return 'category';\n }\n\n if (hasAccessNode) {\n return 'fragment';\n }\n\n return 'invalid-fragment';\n}\n","import type { TCacheState } from './cache.type.js';\n\n/**\n * Persistent global caching state mapping to optimized native collections.\n * Persists for the lifetime of a single ESLint run.\n * Cleaned up between testing suites dynamically using clearDirCache.\n */\nexport const state: TCacheState = {\n categoryConfigCache: new Map(),\n classifyCache: new Map(),\n dirCache: {},\n packageImports: null,\n projectRoot: process.cwd(),\n resolvedImportPathCache: new Map(),\n rolesCache: new WeakMap(),\n treeConfigCache: new Map(),\n treeConfigIncludingExcludedCache: new Map(),\n};\n","import type {\n TRootFragmentConfig,\n TTreeConfig,\n} from '../../../_types/faf.type.js';\n\n/**\n * Searches the tree configuration for the Root Fragment configuration matching the given path.\n * Traverses recursively down through sub-root configurations.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns The matching Root Fragment configuration or null if not found.\n */\nexport function getRootFragmentConfig(\n relDirPath: string,\n config: TTreeConfig\n): null | TRootFragmentConfig {\n const checkConfig = (\n rfConfig: TRootFragmentConfig\n ): null | TRootFragmentConfig => {\n if (rfConfig.paths.includes(relDirPath)) {\n return rfConfig;\n }\n if (rfConfig.subRootFragments) {\n for (const sub of rfConfig.subRootFragments) {\n const res = checkConfig(sub);\n if (res) return res;\n }\n }\n return null;\n };\n\n if (config.rootFragments) {\n for (const rf of config.rootFragments) {\n const res = checkConfig(rf);\n if (res) return res;\n }\n }\n return null;\n}\n","import type { TTreeConfig } from '../../../_types/faf.type.js';\n\nimport { getRootFragmentConfig } from '../../_primitives/get-root-fragment-config/index.js';\n\n/**\n * Checks if a relative directory path corresponds to a configured Root Fragment.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns True if the path is a Root Fragment.\n */\nexport function isRootFragment(\n relDirPath: string,\n config: TTreeConfig\n): boolean {\n return getRootFragmentConfig(relDirPath, config) !== null;\n}\n","import path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TCategoryConfig, TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Returns the TCategoryConfig for a given path by traversing upwards to the closest Category folder.\n * Result is cached in `state.categoryConfigCache`.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @param config - Tree configuration.\n * @returns The Category configuration or null if not in a Category.\n */\nexport function getCategoryConfig(\n relDirPath: string,\n config: TTreeConfig\n): null | TCategoryConfig {\n const cached = state.categoryConfigCache.get(relDirPath);\n if (cached !== undefined) {\n return cached;\n }\n\n let result: null | TCategoryConfig = null;\n let current = relDirPath;\n while (current && current !== '.' && current !== '/') {\n const folderName = path.basename(current);\n if (folderName.startsWith('_') && !folderName.includes('@shared')) {\n const catConfig = config.categories?.find((c) => c.name === folderName);\n if (catConfig) {\n result = catConfig;\n break;\n }\n } else {\n break;\n }\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) break;\n current = parent;\n }\n\n state.categoryConfigCache.set(relDirPath, result);\n return result;\n}\n","import fs from 'fs';\nimport path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\n/**\n * Returns a cached record of files and directories within a target directory path.\n * Limits disk access by caching results in `state.dirCache` on the first miss.\n * Performs a single fs.readdirSync operation to optimize synchronous I/O.\n *\n * @param relDirPath - Directory path relative to the project root.\n * @returns Object with arrays of directory names and file names.\n */\nexport function readDirCached(relDirPath: string): {\n dirs: string[];\n files: string[];\n} {\n const absPath = path\n .resolve(state.projectRoot, relDirPath)\n .replace(/\\\\/g, '/');\n if (state.dirCache[absPath]) {\n return state.dirCache[absPath];\n }\n\n try {\n const entries = fs.readdirSync(absPath, { withFileTypes: true });\n const files: string[] = [];\n const dirs: string[] = [];\n\n for (const entry of entries) {\n if (entry.isFile()) {\n files.push(entry.name);\n } else if (entry.isDirectory()) {\n dirs.push(entry.name);\n }\n }\n\n state.dirCache[absPath] = { dirs, files };\n return state.dirCache[absPath];\n } catch {\n return { dirs: [], files: [] };\n }\n}\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFafSettings, TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Finds the tree configuration that includes the given relative file path,\n * excluding paths designated as Foreign Domains. Uses `state.treeConfigCache`\n * to speed up subsequent queries.\n *\n * @param relPath - Path relative to the project root.\n * @param settings - The global FAF settings containing trees configuration.\n * @returns The matching tree configuration or null if not found or excluded.\n */\nexport function findTreeConfig(\n relPath: string,\n settings: TFafSettings\n): null | TTreeConfig {\n if (!settings || !settings.trees) {\n return null;\n }\n\n const cached = state.treeConfigCache.get(relPath);\n if (cached !== undefined) {\n return cached;\n }\n\n let result: null | TTreeConfig = null;\n for (const tree of settings.trees) {\n const isIncluded = tree.includes.some(\n (inc) => relPath === inc || relPath.startsWith(inc + '/')\n );\n const isExcluded = tree.excludes?.some(\n (exc) => relPath === exc || relPath.startsWith(exc + '/')\n );\n\n if (isIncluded && !isExcluded) {\n result = tree;\n break;\n }\n }\n\n state.treeConfigCache.set(relPath, result);\n return result;\n}\n","import path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\n/**\n * Normalizes any path to be relative to the project root and formats it with forward slashes.\n *\n * @param absoluteOrRelative - Input path string.\n * @returns Normalized relative path.\n */\nexport function toRelativePath(absoluteOrRelative: string): string {\n let abs = absoluteOrRelative;\n if (!path.isAbsolute(abs)) {\n abs = path.resolve(state.projectRoot, abs);\n }\n const rel = path.relative(state.projectRoot, abs);\n return rel.replace(/\\\\/g, '/');\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\n/**\n * @fileoverview Rule: faf/enforce-access-node\n * Enforces the FAF Law of Access Node Integrity.\n *\n * FAF Law: An Access Node (barrel file like `index.ts`) must only define and export the Fragment's public interface.\n * It is restricted to import/export only its own sibling Fragment Nodes using simple relative paths.\n *\n * Valid:\n * - `export * from './button.component';` inside `button/index.ts`.\n * - `export type * from './button.type';` inside `button/index.ts`.\n *\n * Invalid:\n * - Importing/exporting files from subfolders (e.g. `export * from './_components/child';`).\n * - Importing/exporting files from parent folders or external paths (e.g. `export * from '../utils';`).\n * - Exporting files that do not share the parent Fragment's name prefix.\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const fileName = path.basename(relPath);\n\n if (fileName !== 'index.ts' && fileName !== 'index.js') {\n return {};\n }\n\n const settings = context.settings as { faf?: TFafSettings };\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n const relDir = path.dirname(relPath);\n const parentType = classifyFolder(relDir, config);\n\n // If it's not a Fragment, naming-conventions handles it, but let's ignore it here\n if (parentType !== 'fragment') {\n return {};\n }\n\n function checkSource(node: Rule.Node, sourceVal: string) {\n // Matches only \"./filename\" with no further \"/\" (no subfolders, no parent folders)\n const isValidSibling = /^\\.\\/[^/]+$/.test(sourceVal);\n if (!isValidSibling) {\n context.report({\n message: `Access Node (index file) can only import or export its own sibling Fragment Nodes using simple relative paths (e.g. \"./example.component\"). Got \"${sourceVal}\".`,\n node,\n });\n return;\n }\n\n const importedFilename = path.basename(sourceVal);\n if (\n importedFilename === 'index' ||\n importedFilename === 'index.ts' ||\n importedFilename === 'index.js' ||\n importedFilename === 'README.md' ||\n importedFilename === 'package.json'\n ) {\n return;\n }\n\n const fragmentName = path.basename(relDir);\n if (!importedFilename.startsWith(fragmentName + '.')) {\n context.report({\n message: `Access Node (index file) can only re-export its own Fragment Nodes (names starting with \"${fragmentName}.\"). Got \"${importedFilename}\".`,\n node,\n });\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkSource(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkSource(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkSource(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description: 'Enforce Access Node rules for Fragments',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type {\n TFafSettings,\n THttpMethod,\n} from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getCategoryConfig } from '#_rules@shared/_utils/_primitives/get-category-config/index.js';\nimport { getFileRole } from '#_rules@shared/_utils/_primitives/get-file-role/index.js';\nimport { getProjectRoot } from '#_rules@shared/_utils/_primitives/get-project-root/index.js';\nimport { getRootFragmentConfig } from '#_rules@shared/_utils/_primitives/get-root-fragment-config/index.js';\nimport { readDirCached } from '#_rules@shared/_utils/_primitives/read-dir-cached/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\nconst KEBAB_CASE_REGEX = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst DEFAULT_HTTP_METHODS: THttpMethod[] = [\n 'connect',\n 'delete',\n 'get',\n 'head',\n 'options',\n 'patch',\n 'post',\n 'put',\n 'trace',\n];\n\n/**\n * @fileoverview Rule: faf/naming-conventions\n * Enforces FAF folder taxonomy, naming conventions, and file role suffixes.\n *\n * FAF Law:\n * - Folders and files in the logical domain must use kebab-case.\n * - Categories/Layers must start with an underscore (e.g. `_components`).\n * - Fragments must NOT start with an underscore.\n * - Sibling Fragment Nodes must share the parent Fragment folder's name.\n * - All logical nodes must end with a valid role suffix (e.g. `[name].[role].ts`).\n * - Fragments placed under a Category (or Route) must contain a Master Node with the corresponding role.\n * - Every Fragment must have a Master Node, and Fragment Nodes must have unique Roles.\n * - A route terminal Fragment's name must follow the \"<method>-<object>\" pattern.\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n return {\n Program(node) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return;\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return;\n }\n\n const relDir = path.dirname(relPath);\n const folderName = path.basename(relDir);\n const parentType = classifyFolder(relDir, config);\n\n if (parentType === 'foreign') {\n return;\n }\n\n const fileName = path.basename(relPath);\n\n // Validate folder conventions across all ancestors, not just the immediate parent\n let currentDir = relDir;\n while (currentDir && currentDir !== '.' && currentDir !== '/') {\n const isInTree = config.includes.some(\n (inc) => currentDir === inc || currentDir.startsWith(inc + '/')\n );\n const isExcluded =\n config.excludes?.some(\n (exc) => currentDir === exc || currentDir.startsWith(exc + '/')\n ) ?? false;\n\n if (!isInTree || isExcluded) {\n break;\n }\n\n const currentFolderName = path.basename(currentDir);\n const currentType = classifyFolder(currentDir, config);\n\n // Layers and Categories must be prefixed with an underscore\n if (\n (currentType === 'layer' || currentType === 'category') &&\n !currentFolderName.startsWith('_')\n ) {\n context.report({\n message: `Layer/Category directory \"${currentFolderName}\" must be prefixed with an underscore (e.g. \"_${currentFolderName}\").`,\n node,\n });\n }\n\n // Fragments must NOT be prefixed with an underscore\n if (\n currentFolderName.startsWith('_') &&\n !currentFolderName.includes('@shared')\n ) {\n const contents = readDirCached(currentDir);\n const hasIndex =\n contents.files.includes('index.ts') ||\n contents.files.includes('index.js');\n if (hasIndex) {\n context.report({\n message: `Directory \"${currentFolderName}\" has an Access Node (index.ts) but its name starts with \"_\". Fragments must not be prefixed with underscore.`,\n node,\n });\n }\n }\n\n if (currentFolderName !== 'src') {\n let baseFolderName = currentFolderName.replace(/@shared$/, '');\n if (baseFolderName.startsWith('_')) {\n baseFolderName = baseFolderName.substring(1);\n }\n if (\n baseFolderName.startsWith('[') &&\n baseFolderName.endsWith(']')\n ) {\n baseFolderName = baseFolderName.substring(\n 1,\n baseFolderName.length - 1\n );\n }\n const isKebab = KEBAB_CASE_REGEX.test(baseFolderName);\n if (!isKebab) {\n context.report({\n message: `Folder name \"${currentFolderName}\" must be in kebab-case (e.g. \"_my-folder\" or \"_[my-param]\").`,\n node,\n });\n }\n }\n\n if (currentType === 'fractal-branch') {\n const expectedScope = path.basename(path.dirname(currentDir));\n const normalizedExpectedScope = expectedScope.startsWith('_')\n ? expectedScope.substring(1)\n : expectedScope;\n const expectedName = `_${normalizedExpectedScope}@shared`;\n if (currentFolderName !== expectedName) {\n context.report({\n message: `Fractal Branch name \"${currentFolderName}\" must match its parent scope name: \"${expectedName}\".`,\n node,\n });\n }\n }\n\n if (currentType === 'invalid-fragment') {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" is missing an Access Node (index.ts/index.js).`,\n node,\n });\n }\n\n const relParentDir = path.dirname(currentDir).replace(/\\\\/g, '/');\n const parentFolderName = path.basename(relParentDir);\n // 'unknown' means relParentDir falls outside any configured tree path,\n // i.e. it is the literal Root Container\n const relParentType =\n relParentDir === '.' || relParentDir === '/'\n ? 'unknown'\n : classifyFolder(relParentDir, config);\n\n if (currentType === 'root-fragment') {\n if (\n relParentType !== 'root-fragment' &&\n relParentType !== 'unknown'\n ) {\n context.report({\n message: `Root Fragment directory \"${currentFolderName}\" must be placed directly inside a Root Container or another Root Fragment, not inside \"${parentFolderName}\" (classified as ${relParentType}).`,\n node,\n });\n }\n }\n\n if (currentType === 'layer') {\n if (\n relParentType === 'fragment' ||\n relParentType === 'invalid-fragment'\n ) {\n context.report({\n message: `Layer directory \"${currentFolderName}\" cannot be placed inside \"${parentFolderName}\" (classified as ${relParentType}). Layers cannot reside within Fragments.`,\n node,\n });\n }\n }\n\n // A Fragment cannot be placed directly:\n // - under a Layer (unless it terminates a configured Route Hierarchy)\n // - inside another Fragment (must be nested within a Private Category)\n // - inside a Fractal Branch\n // - inside a nested Root Fragment (must be contained within a Category)\n if (\n currentType === 'fragment' ||\n currentType === 'invalid-fragment'\n ) {\n const isParentRootContainer =\n config.includes.includes(relParentDir);\n if (relParentType === 'layer') {\n const isParentRoute =\n config.routeHierarchies &&\n config.routeHierarchies.some((rh) =>\n rh.paths.some(\n (rp) =>\n relParentDir === rp || relParentDir.startsWith(rp + '/')\n )\n );\n if (!isParentRoute) {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Layer \"${parentFolderName}\". Fragments must be contained within a Category.`,\n node,\n });\n }\n } else if (\n relParentType === 'fragment' ||\n relParentType === 'invalid-fragment'\n ) {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Fragment \"${parentFolderName}\". Sub-Fragments must be contained within a Private Category.`,\n node,\n });\n } else if (relParentType === 'fractal-branch') {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Fractal Branch \"${parentFolderName}\". Fragments must be contained within a Category.`,\n node,\n });\n } else if (\n relParentType === 'root-fragment' &&\n !isParentRootContainer\n ) {\n context.report({\n message: `Fragment directory \"${currentFolderName}\" cannot be placed directly inside Root Fragment \"${parentFolderName}\". Fragments must be contained within a Category.`,\n node,\n });\n }\n }\n\n if (currentType === 'fractal-branch') {\n if (relParentType === 'fractal-branch') {\n context.report({\n message: `Fractal Branch \"${currentFolderName}\" cannot be placed inside another Fractal Branch \"${parentFolderName}\".`,\n node,\n });\n }\n }\n\n currentDir = path.dirname(currentDir).replace(/\\\\/g, '/');\n }\n\n if (parentType === 'layer') {\n context.report({\n message: `Layers cannot contain files directly. File \"${fileName}\" is placed directly inside Layer \"${folderName}\".`,\n node,\n });\n return;\n }\n\n if (parentType === 'fractal-branch') {\n context.report({\n message: `Fractal Branches cannot contain files directly. File \"${fileName}\" is placed directly inside Fractal Branch \"${folderName}\".`,\n node,\n });\n return;\n }\n\n if (parentType === 'invalid-fragment') {\n return; // Already reported by ancestor loop\n }\n\n // Must run before the Access Node check below: a Root Fragment's internal\n // naming (including a file named \"index.ts\") is governed by \"rootNodes\", not\n // by the ordinary Fragment taxonomy\n const rfConfig = getRootFragmentConfig(relDir, config);\n if (rfConfig) {\n const flatRootNodes = rfConfig.rootNodes.flat();\n const isMatchedRootNode = flatRootNodes.some((rn) => {\n if (rn.includes('/')) {\n const rfPath = rfConfig.paths[0] ?? '';\n const absRn = path.resolve(getProjectRoot(), rfPath, rn);\n return toRelativePath(absRn) === relPath;\n }\n return rn === fileName;\n });\n\n if (isMatchedRootNode) {\n return; // Valid Root Node\n }\n }\n\n if (fileName === 'index.ts' || fileName === 'index.js') {\n if (parentType !== 'fragment') {\n context.report({\n message: `Access Nodes (\"index.ts/index.js\") are exclusive to Fragments. Found index file directly inside \"${folderName}\" (classified as ${parentType}).`,\n node,\n });\n } else {\n const contents = readDirCached(relDir);\n const hasFragmentNode = contents.files.some(\n (f) =>\n f !== 'index.ts' &&\n f !== 'index.js' &&\n f !== 'README.md' &&\n f !== 'package.json' &&\n f !== 'tsconfig.json'\n );\n if (!hasFragmentNode) {\n context.report({\n message: `Fragment \"${folderName}\" has no Master Node. Every Fragment must contain at least one Fragment Node establishing its Role.`,\n node,\n });\n }\n }\n return;\n }\n\n if (\n fileName === 'README.md' ||\n fileName === 'package.json' ||\n fileName === 'tsconfig.json'\n ) {\n return;\n }\n\n const role = getFileRole(fileName, config);\n const ext = path.extname(fileName);\n\n // A Logical Node's name admits exactly one Role segment\n const allRoleNames = new Set(config.roles.flat());\n const roleSegments = fileName\n .slice(0, fileName.length - ext.length)\n .split('.')\n .slice(1)\n .filter((part) => allRoleNames.has(part));\n const multiRoleMessage = `File \"${fileName}\" composes multiple Roles (\"${roleSegments.join('\", \"')}\") in its name. A Logical Node may declare only one Role; promote the detail that needs its own Role to an autonomous Sub-Fragment.`;\n\n if (parentType === 'fragment') {\n // Check route hierarchy role constraint\n const matchedRoute = config.routeHierarchies?.find((rh) =>\n rh.paths.some((rp) => relDir === rp || relDir.startsWith(rp + '/'))\n );\n if (matchedRoute) {\n const contents = readDirCached(relDir);\n const fileRoles = contents.files.map((f) => getFileRole(f, config));\n if (!fileRoles.includes(matchedRoute.role)) {\n context.report({\n message: `Route terminal Fragment \"${folderName}\" must contain a Master Node with role \"${matchedRoute.role}\" (e.g. \"${folderName}.${matchedRoute.role}.ts\").`,\n node,\n });\n }\n\n const httpMethods =\n matchedRoute.httpMethods ?? DEFAULT_HTTP_METHODS;\n const routeNameRegex = new RegExp(\n `^(${httpMethods.join('|')})-[a-z0-9]+(-[a-z0-9]+)*$`\n );\n if (!routeNameRegex.test(folderName)) {\n context.report({\n message: `Route terminal Fragment \"${folderName}\" must follow the \"<method>-<object>\" pattern with a lowercase HTTP method (${httpMethods.join(', ')}).`,\n node,\n });\n }\n }\n\n // Check category role constraint\n let currentParent = path.dirname(relDir).replace(/\\\\/g, '/');\n let categoryConfig = null;\n let categoryFolderName = '';\n while (\n currentParent &&\n currentParent !== '.' &&\n currentParent !== '/'\n ) {\n const parentType = classifyFolder(currentParent, config);\n if (parentType === 'category') {\n categoryConfig = getCategoryConfig(currentParent, config);\n categoryFolderName = path.basename(currentParent);\n break;\n } else if (\n parentType === 'fragment' ||\n parentType === 'root-fragment' ||\n parentType === 'layer'\n ) {\n break;\n }\n const nextParent = path.dirname(currentParent).replace(/\\\\/g, '/');\n if (nextParent === currentParent) break;\n currentParent = nextParent;\n }\n\n if (categoryConfig && categoryConfig.role) {\n const contents = readDirCached(relDir);\n const fileRoles = contents.files.map((f) => getFileRole(f, config));\n if (!fileRoles.includes(categoryConfig.role)) {\n context.report({\n message: `Fragment \"${folderName}\" inside Category \"${categoryFolderName}\" must contain a Master Node with role \"${categoryConfig.role}\" (e.g. \"${folderName}.${categoryConfig.role}.ts\").`,\n node,\n });\n }\n }\n\n if (!fileName.startsWith(folderName + '.')) {\n context.report({\n message: `Fragment Node \"${fileName}\" must share the parent Fragment name: \"${folderName}.<role>${ext}\".`,\n node,\n });\n }\n\n // In a Fragment, ALL files must have a role, even if they have whitelisted extensions\n if (!role) {\n context.report({\n message: `File \"${fileName}\" inside Fragment \"${folderName}\" must have an explicit role suffix (e.g. \"${folderName}.style${ext}\").`,\n node,\n });\n } else if (roleSegments.length > 1) {\n context.report({ message: multiRoleMessage, node });\n } else {\n const contents = readDirCached(relDir);\n // Exclude the Access Node: it always resolves to role 'index', which a\n // Fragment Node could otherwise also carry via an explicit \".index\" suffix\n const duplicate = contents.files.find(\n (f) =>\n f !== fileName &&\n f !== 'index.ts' &&\n f !== 'index.js' &&\n getFileRole(f, config) === role\n );\n if (duplicate) {\n context.report({\n message: `Fragment Node \"${fileName}\" shares Role \"${role}\" with sibling \"${duplicate}\". Each Fragment Node must have a unique Role within its Fragment.`,\n node,\n });\n }\n }\n }\n\n if (parentType === 'category') {\n const catConfig = getCategoryConfig(relDir, config);\n if (catConfig) {\n const allowedExts = catConfig.allowedExtensions ?? [\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n ];\n if (!allowedExts.includes(ext)) {\n context.report({\n message: `File extension \"${ext}\" is not allowed in Category \"${folderName}\". Allowed extensions: ${allowedExts.join(', ')}.`,\n node,\n });\n return;\n }\n\n const isCodeExt = ['.js', '.jsx', '.ts', '.tsx'].includes(ext);\n if (isCodeExt) {\n if (!role) {\n context.report({\n message: `Logical Node \"${fileName}\" inside Category \"${folderName}\" must have a role suffix.`,\n node,\n });\n } else if (role !== catConfig.role) {\n context.report({\n message: `Role \"${role}\" for file \"${fileName}\" does not match the expected Category role \"${catConfig.role}\".`,\n node,\n });\n } else if (roleSegments.length > 1) {\n context.report({ message: multiRoleMessage, node });\n }\n } else {\n // Asset files\n if (role && role !== catConfig.role) {\n context.report({\n message: `Role \"${role}\" for asset \"${fileName}\" does not match the expected Category role \"${catConfig.role}\".`,\n node,\n });\n } else if (role && roleSegments.length > 1) {\n context.report({ message: multiRoleMessage, node });\n }\n }\n }\n }\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Enforce naming conventions and folder taxonomy in FAF architecture',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Extracts the architectural role of a file based on its name extensions.\n * Returns special role 'index' for Access Nodes.\n * Uses `state.rolesCache` to store configurations flattened as Set for O(1) lookups.\n *\n * @param fileName - Base name of the file.\n * @param config - Tree configuration.\n * @returns The matching role suffix or null if none.\n */\nexport function getFileRole(\n fileName: string,\n config: TTreeConfig\n): null | string {\n // Exclusions: Access nodes\n if (fileName === 'index.ts' || fileName === 'index.js') {\n return 'index';\n }\n\n const parts = fileName.split('.');\n\n // Cache flat roles as a Set inside WeakMap\n let allRoles = state.rolesCache.get(config);\n if (!allRoles) {\n allRoles = new Set(config.roles.flat());\n state.rolesCache.set(config, allRoles);\n }\n\n // Search from right to left\n for (let i = parts.length - 2; i >= 1; i--) {\n const part = parts[i];\n if (part && allRoles.has(part)) {\n return part;\n }\n }\n\n return null;\n}\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\n/**\n * Returns the currently configured project root directory path.\n */\nexport function getProjectRoot(): string {\n return state.projectRoot;\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\n/**\n * @fileoverview Rule: faf/no-direct-fragment-import\n * Enforces the FAF Law of Fragment Encapsulation.\n *\n * FAF Law: External files must never import directly a Fragment's internal files.\n * All imports from outside the Fragment's boundaries must pass exclusively through its Access Node (`index.ts`).\n *\n * Valid:\n * - `import { Button } from '#_ui/_components/button/index.js';`\n *\n * Invalid:\n * - `import { Button } from '#_ui/_components/button/button.component.js';`\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import or unresolved alias\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n const importedFile = path.basename(resolvedRelPath);\n\n // If the imported file is inside a Fragment\n const importedFolderType = classifyFolder(importedDir, config!);\n if (importedFolderType === 'fragment') {\n const isAccessNode =\n importedFile === 'index.ts' || importedFile === 'index.js';\n if (!isAccessNode) {\n // Only a sibling Fragment Node (same directory) is exempt from the Access Node\n const isInside = path.dirname(relPath) === importedDir;\n if (!isInside) {\n context.report({\n message: `Direct import of Fragment internal file \"${importedFile}\" is forbidden. You must import through its Access Node (index file) in \"${importedDir}\".`,\n node,\n });\n }\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Prevent direct import of Fragment internal files from outside the Fragment',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import fs from 'fs';\nimport path from 'path';\n\nimport { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFafSettings } from '../../../_types/faf.type.js';\n\nimport { readDirCached } from '../../_primitives/read-dir-cached/index.js';\nimport { toRelativePath } from '../../_primitives/to-relative-path/index.js';\n\n/**\n * Resolves an import path into a project-root-relative path.\n * Checks against aliases (both package.json subpath imports and faf.config.ts settings).\n * Caches mapping in `state.resolvedImportPathCache` to optimize duplicate node checks.\n *\n * @param importPath - Import value (e.g. \"./helper.js\" or \"#_rules@shared/foo\").\n * @param currentFileRelative - Path of the file performing the import, relative to root.\n * @param settings - Global FAF settings.\n * @returns The resolved project-relative path, or empty string if it's an external library.\n */\nexport function resolveImportPath(\n importPath: string,\n currentFileRelative: string,\n settings: TFafSettings\n): string {\n const cacheKey = `${currentFileRelative}::${importPath}`;\n const cached = state.resolvedImportPathCache.get(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = _resolveImportPath(importPath, currentFileRelative, settings);\n state.resolvedImportPathCache.set(cacheKey, result);\n return result;\n}\n\nfunction _resolveImportPath(\n importPath: string,\n currentFileRelative: string,\n settings: TFafSettings\n): string {\n const pkgImports = loadPackageImports(state.projectRoot);\n const aliases =\n Object.keys(pkgImports).length > 0 ? pkgImports : settings?.aliases || {};\n\n // Check if it matches any registered alias prefix\n let matchedAlias: null | string = null;\n let longestMatch = 0;\n\n for (const alias of Object.keys(aliases)) {\n if (importPath === alias || importPath.startsWith(alias + '/')) {\n if (alias.length > longestMatch) {\n longestMatch = alias.length;\n matchedAlias = alias;\n }\n }\n }\n\n let relResolved: string;\n\n if (matchedAlias) {\n // 1. Alias resolution\n const target = aliases[matchedAlias];\n if (target) {\n const remainder = importPath.substring(matchedAlias.length);\n const absTarget = path.resolve(state.projectRoot, target + remainder);\n relResolved = toRelativePath(absTarget);\n } else {\n return ''; // Unresolved alias target\n }\n } else {\n // 2. Relative/absolute path resolution\n if (importPath.startsWith('.') || importPath.startsWith('/')) {\n const absCurrentDir = path.dirname(\n path.resolve(state.projectRoot, currentFileRelative)\n );\n const absResolved = path.resolve(absCurrentDir, importPath);\n relResolved = toRelativePath(absResolved);\n } else {\n return ''; // External import (e.g. library from node_modules)\n }\n }\n\n return finalizeResolvedPath(relResolved);\n}\n\n/**\n * Bare script extensions (i.e. without any additional Role/suffix segment) considered\n * when disambiguating an extension-less import against multiple same-prefix candidates.\n */\nconst SCRIPT_EXTENSIONS = new Set([\n 'cjs',\n 'cts',\n 'js',\n 'jsx',\n 'mjs',\n 'mts',\n 'ts',\n 'tsx',\n]);\n\n/**\n * Helper to check if a resolved relative path points to a directory with an index file,\n * or a file missing its extension, and resolves it accordingly.\n */\nfunction finalizeResolvedPath(relResolved: string): string {\n const resolvedDir = path.dirname(relResolved).replace(/\\\\/g, '/');\n const resolvedBase = path.basename(relResolved);\n\n // 1. Check if the path itself is a directory containing index.ts/js\n const dirContents = readDirCached(relResolved);\n if (dirContents.files.includes('index.ts')) {\n return (relResolved === '.' ? '' : relResolved + '/') + 'index.ts';\n }\n if (dirContents.files.includes('index.js')) {\n return (relResolved === '.' ? '' : relResolved + '/') + 'index.js';\n }\n\n // 2. Check if the path is a file missing its extension\n const parentContents = readDirCached(resolvedDir);\n const exactMatch = parentContents.files.find((f) => f === resolvedBase);\n if (!exactMatch) {\n // Multiple files can share the same prefix (e.g. \"foo.ts\" and \"foo.spec.ts\" both\n // start with \"foo.\"). Prefer the candidate whose remainder is a bare script\n // extension over one carrying an additional Role/suffix segment, so resolution\n // doesn't depend on filesystem readdir order.\n const candidates = parentContents.files.filter((f) =>\n f.startsWith(resolvedBase + '.')\n );\n const matchWithExt =\n candidates.find((f) =>\n SCRIPT_EXTENSIONS.has(f.slice(resolvedBase.length + 1))\n ) ?? candidates[0];\n if (matchWithExt) {\n return (resolvedDir === '.' ? '' : resolvedDir + '/') + matchWithExt;\n }\n }\n\n return relResolved;\n}\n\nfunction loadPackageImports(projectRootPath: string): Record<string, string> {\n if (state.packageImports !== null) {\n return state.packageImports;\n }\n\n state.packageImports = {};\n\n // Isolate the test environment from physical package.json of the host plugin codebase\n const isTest =\n typeof process !== 'undefined' &&\n (process.env.NODE_ENV === 'test' || process.env.VITEST === 'true');\n if (isTest) {\n return state.packageImports;\n }\n\n const pkgPath = path.resolve(projectRootPath, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkgContent = fs.readFileSync(pkgPath, 'utf8');\n const pkg = JSON.parse(pkgContent) as {\n imports?: Record<string, unknown>;\n };\n if (pkg.imports) {\n for (const [key, val] of Object.entries(pkg.imports)) {\n if (typeof val === 'string') {\n // Strip wildcards\n const cleanKey = key.endsWith('/*')\n ? key.slice(0, -2)\n : key.endsWith('*')\n ? key.slice(0, -1)\n : key;\n let cleanVal = val.endsWith('/*')\n ? val.slice(0, -2)\n : val.endsWith('*')\n ? val.slice(0, -1)\n : val;\n\n // Normalize target path (remove leading './' or '/')\n if (cleanVal.startsWith('./')) {\n cleanVal = cleanVal.substring(2);\n } else if (cleanVal.startsWith('/')) {\n cleanVal = cleanVal.substring(1);\n }\n\n state.packageImports[cleanKey] = cleanVal;\n }\n }\n }\n } catch {\n // Ignore parsing errors and keep packageImports empty\n }\n }\n\n return state.packageImports;\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getFractalBranchOwner } from '#_rules@shared/_utils/_primitives/get-fractal-branch-owner/index.js';\nimport { getImmediateSubDomain } from '#_rules@shared/_utils/_primitives/get-immediate-sub-domain/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\nimport { getPrivateCategoryInfo } from '#_rules@shared/_utils/_systems/get-private-category-info/index.js';\n\n/**\n * @fileoverview Rule: faf/no-fractal-branch-leak\n * Enforces the FAF Law of Fractal Branch Encapsulation.\n *\n * FAF Law: Fractal Branches (directories following the `_<Scope>@shared` naming convention)\n * hold internal shared implementations. They are private to their parent Scope's subtree\n * and cannot leak or be imported by files outside of that scope.\n *\n * Valid:\n * - A utility inside `src/_rules/_rules@shared/_utils/` importing from `src/_rules/_rules@shared/`.\n *\n * Invalid:\n * - A rule inside `src/_rules/naming-conventions/` importing from `src/_rules/_rules@shared/_utils/_utils@shared/` (out-of-scope).\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import or unresolved alias\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n const fractalBranchOwner = getFractalBranchOwner(importedDir);\n\n if (fractalBranchOwner) {\n // The importing file must be inside the owner's sub-tree\n const isDescendant =\n relPath === fractalBranchOwner ||\n relPath.startsWith(fractalBranchOwner + '/');\n if (!isDescendant) {\n context.report({\n message: `Importing from Fractal Branch is forbidden. The imported resource is private to \"${fractalBranchOwner}\" and its descendants.`,\n node,\n });\n } else {\n // Even within an authorized Fractal Branch scope, a Private Category nested\n // inside it still applies its own, narrower access restriction\n const info = getPrivateCategoryInfo(importedDir, config!);\n if (info) {\n const { owner, privateCategoryPath } = info;\n const isPrivateDirectChild = path.dirname(relPath) === owner;\n\n const importerSubDomain = getImmediateSubDomain(\n relPath,\n privateCategoryPath\n );\n const importedSubDomain = getImmediateSubDomain(\n resolvedRelPath,\n privateCategoryPath\n );\n const isInsideSameSubDomain =\n importerSubDomain !== '' &&\n importerSubDomain === importedSubDomain;\n\n // `fractalBranchOwner` is already the closest Fractal Branch to importedDir (same\n // input as above), so if it lies inside the Private Category, `isDescendant` above\n // has already proven the importer's access to it.\n const isFractalBranchAllowed =\n fractalBranchOwner === privateCategoryPath ||\n fractalBranchOwner.startsWith(privateCategoryPath + '/');\n\n if (\n !isPrivateDirectChild &&\n !isInsideSameSubDomain &&\n !isFractalBranchAllowed\n ) {\n context.report({\n message: `Importing from Private Category is forbidden. The imported resource is private to \"${owner}\".`,\n node,\n });\n }\n }\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Prevent leakage of Fractal Branch internals outside their owner scope',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import path from 'path';\n\n/**\n * Returns the owner of the closest Fractal Branch ancestor, or null.\n */\nexport function getFractalBranchOwner(relPath: string): null | string {\n let current = relPath;\n while (current && current !== '.' && current !== '/') {\n const folderName = path.basename(current);\n if (folderName.startsWith('_') && folderName.includes('@shared')) {\n return path.dirname(current).replace(/\\\\/g, '/');\n }\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return null;\n}\n","/**\n * Returns the immediate sub-domain path relative to the private category path,\n * or the private category path itself if no sub-segment exists.\n * Returns an empty string if the relPath is not inside the private category path.\n */\nexport function getImmediateSubDomain(\n relPath: string,\n privateCategoryPath: string\n): string {\n if (\n relPath !== privateCategoryPath &&\n !relPath.startsWith(privateCategoryPath + '/')\n ) {\n return '';\n }\n const relative = relPath.substring(privateCategoryPath.length + 1);\n const firstSegment = relative.split('/')[0];\n return firstSegment\n ? privateCategoryPath + '/' + firstSegment\n : privateCategoryPath;\n}\n","import path from 'path';\n\nimport type { TTreeConfig } from '../../../_types/faf.type.js';\n\nimport { classifyFolder } from '../../_aggregates/classify-folder/index.js';\n\n/**\n * Returns the owner and private category path of the private category if the given path is inside one, or null.\n */\nexport function getPrivateCategoryInfo(\n relPath: string,\n config: TTreeConfig\n): null | { owner: string; privateCategoryPath: string } {\n let current = relPath;\n while (current && current !== '.' && current !== '/') {\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) {\n break;\n }\n\n const currentType = classifyFolder(current, config);\n const parentType = classifyFolder(parent, config);\n\n if (\n currentType === 'category' &&\n (parentType === 'fragment' || parentType === 'root-fragment')\n ) {\n return { owner: parent, privateCategoryPath: current };\n }\n\n current = parent;\n }\n return null;\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type {\n TFafSettings,\n TRootFragmentConfig,\n TTreeConfig,\n} from '#_rules@shared/_types/faf.type.js';\n\nimport { classifyFolder } from '#_rules@shared/_utils/_aggregates/classify-folder/index.js';\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfigIncludingExcluded } from '#_rules@shared/_utils/_primitives/find-tree-config-including-excluded/index.js';\nimport { getFileRole } from '#_rules@shared/_utils/_primitives/get-file-role/index.js';\nimport { getLcaAndSubBranches } from '#_rules@shared/_utils/_primitives/get-lca-and-sub-branches/index.js';\nimport { getRoleHierarchyIndex } from '#_rules@shared/_utils/_primitives/get-role-hierarchy-index/index.js';\nimport { getRootFragmentConfig } from '#_rules@shared/_utils/_primitives/get-root-fragment-config/index.js';\nimport { resolveHorizontalHierarchy } from '#_rules@shared/_utils/_primitives/resolve-horizontal-hierarchy/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\n\nfunction getRootNodeIndex(\n relPath: string,\n rfConfig: TRootFragmentConfig,\n lcaPath: string\n): number {\n const relToLca = path.relative(lcaPath, relPath).replace(/\\\\/g, '/');\n for (let i = 0; i < rfConfig.rootNodes.length; i++) {\n const group = rfConfig.rootNodes[i];\n if (group && group.includes(relToLca)) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Checks if B is inside a Private Category of the LCA directory.\n */\nfunction isInsidePrivateCategoryOfLca(\n relPathB: string,\n lcaPath: string,\n config: TTreeConfig\n): boolean {\n let current = relPathB;\n while (current && current !== '.' && current !== '/' && current !== lcaPath) {\n const parent = path.dirname(current).replace(/\\\\/g, '/');\n if (parent === current) {\n break;\n }\n\n const currentType = classifyFolder(current, config);\n const parentType = classifyFolder(parent, config);\n\n if (\n currentType === 'category' &&\n (parentType === 'fragment' || parentType === 'root-fragment') &&\n parent === lcaPath\n ) {\n return true;\n }\n\n current = parent;\n }\n return false;\n}\n\n/**\n * @fileoverview Rule: faf/no-peer-dependency\n * Enforces the FAF Law of Separation between Peers.\n *\n * FAF Law: Sibling directories and files (at the same filesystem level) must not import each other\n * unless a horizontal hierarchy flow is explicitly configured (via local/global horizontal hierarchies).\n * For files inside a Fragment, peer imports flow according to the index order defined in the `roles` configuration.\n *\n * Valid:\n * - A compound utility importing from a primitive utility (if compounds ➔ primitives is configured).\n * - Sibling Fragment Nodes importing from each other according to the roles scale order (e.g. `util` imports `type`).\n *\n * Invalid:\n * - A primitive utility importing from a compound utility (violating horizontal hierarchy).\n * - Circular imports between sibling folders with no configured hierarchy.\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfigIncludingExcluded(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n const currentDir = path.dirname(relPath);\n const isCurrentFileExcluded =\n config.excludes?.some(\n (exc) => relPath === exc || relPath.startsWith(exc + '/')\n ) ?? false;\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import\n }\n\n const isImportedFileExcluded =\n config?.excludes?.some(\n (exc) =>\n resolvedRelPath === exc || resolvedRelPath.startsWith(exc + '/')\n ) ?? false;\n\n // Case A (Logical Node ➔ Foreign Domain)\n if (!isCurrentFileExcluded && isImportedFileExcluded) {\n context.report({\n message: `Importing from Foreign Domain \"${resolvedRelPath}\" is forbidden for Logical Nodes.`,\n node,\n });\n return;\n }\n\n // Case B (Foreign Domain ➔ Logical Node)\n if (isCurrentFileExcluded && !isImportedFileExcluded) {\n context.report({\n message: `Foreign Domain files cannot import Logical Nodes from FAF tree (\"${resolvedRelPath}\").`,\n node,\n });\n return;\n }\n\n // If either is excluded, do not run further peer dependency checks\n if (isCurrentFileExcluded || isImportedFileExcluded) {\n return;\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n\n // Scenario 1: Same directory (Fragment Nodes or direct siblings)\n if (currentDir === importedDir) {\n const fileA = path.basename(relPath);\n const fileB = path.basename(resolvedRelPath);\n\n const roleA = getFileRole(fileA, config!);\n const roleB = getFileRole(fileB, config!);\n\n if (roleA && roleB) {\n const idxA = getRoleHierarchyIndex(roleA, config!);\n const idxB = getRoleHierarchyIndex(roleB, config!);\n\n if (idxA !== -1 && idxB !== -1) {\n if (idxB >= idxA) {\n context.report({\n message: `Sibling import violation: \"${fileA}\" (role \"${roleA}\", level ${idxA}) cannot import from \"${fileB}\" (role \"${roleB}\", level ${idxB}). Imports must flow from lower to higher levels.`,\n node,\n });\n }\n }\n }\n return;\n }\n\n // Scenario 2: Different directories\n const lcaInfo = getLcaAndSubBranches(currentDir, importedDir);\n if (!lcaInfo) {\n return;\n }\n\n const { lca, subA, subB } = lcaInfo;\n\n // Exception: Fractal Branch\n if (subB.startsWith('_') && subB.includes('@shared')) {\n // Allowed to import from own Fractal Branch\n return;\n }\n\n // Exception: Private Category of the LCA\n if (isInsidePrivateCategoryOfLca(importedDir, lca, config!)) {\n return;\n }\n\n // A descendant reaching for the Fragment root has no privileged access to it\n if (subB === '' && classifyFolder(lca, config!) === 'fragment') {\n context.report({\n message: `Peer separation violation: \"${subA}\" cannot import directly from the root of Fragment \"${lca}\". A node nested inside a Private Category or Fractal Branch has no privileged access to its owning Fragment's other direct children; promote the shared resource to a Fractal Branch if the sharing need is genuine.`,\n node,\n });\n return;\n }\n\n // Check if LCA is a Root Fragment and we are importing between Root Nodes\n const rfConfig = getRootFragmentConfig(lca, config!);\n if (rfConfig) {\n const idxRootA = getRootNodeIndex(relPath, rfConfig, lca);\n const idxRootB = getRootNodeIndex(resolvedRelPath, rfConfig, lca);\n\n if (idxRootA !== -1 && idxRootB !== -1) {\n if (idxRootB >= idxRootA) {\n context.report({\n message: `Root Node import violation: \"${path.basename(relPath)}\" cannot import from \"${path.basename(resolvedRelPath)}\" under Root Fragment \"${lca}\".`,\n node,\n });\n }\n return;\n }\n }\n\n // Root Nodes are exempt from the Role naming convention, so relationships involving them\n // (including nested or sibling Root Fragments) can never fall back to the Role scale: they\n // must always be explicitly authorized by the architect via \"rootNodes\" at the common ancestor.\n const isSubARootFragment =\n classifyFolder(path.posix.join(lca, subA), config!) === 'root-fragment';\n const isSubBRootFragment =\n classifyFolder(path.posix.join(lca, subB), config!) === 'root-fragment';\n\n if (isSubARootFragment || isSubBRootFragment) {\n context.report({\n message: `Root Node import violation: \"${relPath}\" cannot import from \"${resolvedRelPath}\" because no \"rootNodes\" relationship is configured under Root Fragment \"${lca}\". Relationships between Root Nodes must always be explicitly authorized by the architect.`,\n node,\n });\n return;\n }\n\n // Determine if there is a defined horizontal hierarchy at LCA and whether the import is allowed\n const { allowed, defined: hasDefinedHierarchy } =\n resolveHorizontalHierarchy(lca, subA, subB, config!);\n\n if (hasDefinedHierarchy) {\n if (!allowed) {\n context.report({\n message: `Horizontal hierarchy violation: \"${subA}\" cannot import from \"${subB}\" under parent \"${lca}\".`,\n node,\n });\n }\n } else {\n context.report({\n message: `Peer separation violation: sibling directories \"${subA}\" and \"${subB}\" cannot import each other because no horizontal hierarchy is defined under parent \"${lca}\".`,\n node,\n });\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Enforce the Law of Separation between Peers (no-peer-dependency)',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import { state } from '#_utils@shared/_stores/cache/index.js';\n\nimport type { TFafSettings, TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Finds the tree configuration that includes the given relative file path,\n * even if it is otherwise excluded (Foreign Domain). Uses `state.treeConfigIncludingExcludedCache`\n * for performance.\n *\n * @param relPath - Path relative to the project root.\n * @param settings - The global FAF settings containing trees configuration.\n * @returns The matching tree configuration or null if not found.\n */\nexport function findTreeConfigIncludingExcluded(\n relPath: string,\n settings: TFafSettings\n): null | TTreeConfig {\n if (!settings || !settings.trees) {\n return null;\n }\n\n const cached = state.treeConfigIncludingExcludedCache.get(relPath);\n if (cached !== undefined) {\n return cached;\n }\n\n let result: null | TTreeConfig = null;\n for (const tree of settings.trees) {\n const isIncluded = tree.includes.some(\n (inc) => relPath === inc || relPath.startsWith(inc + '/')\n );\n\n if (isIncluded) {\n result = tree;\n break;\n }\n }\n\n state.treeConfigIncludingExcludedCache.set(relPath, result);\n return result;\n}\n","/**\n * Finds the Lowest Common Ancestor (LCA) path of two given path strings,\n * as well as the immediate child segment of the LCA for each path.\n * Used to identify parent-child relationships and siblings.\n *\n * @param pathA - First path string.\n * @param pathB - Second path string.\n * @returns Object containing the LCA and immediate sub-branches, or null if no common ancestor.\n */\nexport function getLcaAndSubBranches(\n pathA: string,\n pathB: string\n): null | { lca: string; subA: string; subB: string } {\n const partsA = pathA.split('/');\n const partsB = pathB.split('/');\n\n let commonLength = 0;\n while (\n commonLength < partsA.length &&\n commonLength < partsB.length &&\n partsA[commonLength] === partsB[commonLength]\n ) {\n commonLength++;\n }\n\n if (commonLength === 0) {\n return null;\n }\n\n const lca = partsA.slice(0, commonLength).join('/');\n const subA = partsA[commonLength] || '';\n const subB = partsB[commonLength] || '';\n\n return { lca, subA, subB };\n}\n","import type { TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Returns the hierarchy level index of a given role.\n * Roles at lower indexes (earlier in the roles array) represent lower-level/primitive constructs,\n * while higher indexes represent higher-level/composed ones.\n *\n * @param role - Role string to look up.\n * @param config - Tree configuration containing the roles scale.\n * @returns The index of the role group or -1 if the role is not defined.\n */\nexport function getRoleHierarchyIndex(\n role: string,\n config: TTreeConfig\n): number {\n for (let i = 0; i < config.roles.length; i++) {\n const roleGroup = config.roles[i];\n if (roleGroup && roleGroup.includes(role)) {\n return i;\n }\n }\n return -1;\n}\n","import type { TTreeConfig } from '../../../_types/faf.type.js';\n\n/**\n * Resolves the horizontal hierarchy relationship between sub-directories subA and subB at a common ancestor lcaPath.\n * Checks local path-specific hierarchies before falling back to global hierarchies.\n * Returns both whether a hierarchy constraint is defined, and if defined, whether the import is allowed.\n *\n * @param lcaPath - Path of the common parent directory.\n * @param subA - Sibling directory segment of the importer.\n * @param subB - Sibling directory segment of the imported module.\n * @param config - Tree configuration.\n * @returns Object indicating if the hierarchy is defined and if the import is allowed.\n */\nexport function resolveHorizontalHierarchy(\n lcaPath: string,\n subA: string,\n subB: string,\n config: TTreeConfig\n): { allowed: boolean; defined: boolean } {\n // 1. Check local hierarchies first\n const local = config.localHorizontalHierarchies?.find((lh) =>\n lh.paths.includes(lcaPath)\n );\n if (local) {\n const idxA = local.hierarchies.findIndex((group) => group.includes(subA));\n const idxB = local.hierarchies.findIndex((group) => group.includes(subB));\n if (idxA !== -1 && idxB !== -1) {\n return { allowed: idxB < idxA, defined: true };\n }\n }\n\n // 2. Check global hierarchies\n const globalHierarchies = config.globalHorizontalHierarchies || [];\n for (const gh of globalHierarchies) {\n const idxA = gh.findIndex((group) => group.includes(subA));\n const idxB = gh.findIndex((group) => group.includes(subB));\n if (idxA !== -1 && idxB !== -1) {\n return { allowed: idxB < idxA, defined: true };\n }\n }\n\n // No hierarchy defined for this pair — sibling imports forbidden by default\n return { allowed: false, defined: false };\n}\n","import type { Rule } from 'eslint';\n\nimport path from 'path';\n\nimport type { TFafSettings } from '#_rules@shared/_types/faf.type.js';\n\nimport { resolveImportPath } from '#_rules@shared/_utils/_aggregates/resolve-import-path/index.js';\nimport { findTreeConfig } from '#_rules@shared/_utils/_primitives/find-tree-config/index.js';\nimport { getFractalBranchOwner } from '#_rules@shared/_utils/_primitives/get-fractal-branch-owner/index.js';\nimport { getImmediateSubDomain } from '#_rules@shared/_utils/_primitives/get-immediate-sub-domain/index.js';\nimport { toRelativePath } from '#_rules@shared/_utils/_primitives/to-relative-path/index.js';\nimport { getPrivateCategoryInfo } from '#_rules@shared/_utils/_systems/get-private-category-info/index.js';\n\n/**\n * @fileoverview Rule: faf/no-private-category-leak\n * Enforces the FAF Law of Private Category Encapsulation.\n *\n * FAF Law: Category folders prefixed with `_` nested directly inside a Fragment/Root Fragment\n * are Private Categories containing internal implementation details.\n * Their contents are private to the owning Fragment/Root Fragment subtree and cannot leak or be imported externally.\n *\n * Valid:\n * - Sibling nodes within the owner Fragment importing from the Private Category (e.g. `example/example.component.tsx`\n * importing from `example/_components/child/index.js`).\n *\n * Invalid:\n * - A rule inside `src/_rules/naming-conventions/` importing from `src/_rules/_rules@shared/_utils/_utils@shared/_stores/cache/` (leak).\n */\nconst rule: Rule.RuleModule = {\n create(context) {\n const absPath = context.filename;\n const relPath = toRelativePath(absPath);\n const settings = context.settings as { faf?: TFafSettings };\n\n if (!settings.faf) {\n return {};\n }\n\n const config = findTreeConfig(relPath, settings.faf);\n if (!config) {\n return {};\n }\n\n function checkImport(node: Rule.Node, importValue: string) {\n const resolvedRelPath = resolveImportPath(\n importValue,\n relPath,\n settings.faf!\n );\n if (!resolvedRelPath) {\n return; // External import or unresolved alias\n }\n\n const importedDir = path.dirname(resolvedRelPath);\n const info = getPrivateCategoryInfo(importedDir, config!);\n\n if (info) {\n const { owner, privateCategoryPath } = info;\n\n // A Fractal Branch nested inside the Private Category is a closer, more specific\n // encapsulation boundary: its own Law is the sole authority on access to it, and\n // the Private Category's direct-child/sub-domain grants do not apply (non-transitivity).\n let isFractalBranchInPrivateCategory = false;\n let isFractalBranchAllowed = false;\n const fbOwner = getFractalBranchOwner(importedDir);\n if (fbOwner) {\n const isFbInsidePrivateCategory =\n fbOwner === privateCategoryPath ||\n fbOwner.startsWith(privateCategoryPath + '/');\n if (isFbInsidePrivateCategory) {\n isFractalBranchInPrivateCategory = true;\n isFractalBranchAllowed =\n relPath === fbOwner || relPath.startsWith(fbOwner + '/');\n }\n }\n\n const isDirectChild = path.dirname(relPath) === owner;\n\n const importerSubDomain = getImmediateSubDomain(\n relPath,\n privateCategoryPath\n );\n const importedSubDomain = getImmediateSubDomain(\n resolvedRelPath,\n privateCategoryPath\n );\n const isInsideSameSubDomain =\n importerSubDomain !== '' && importerSubDomain === importedSubDomain;\n\n const isAllowed = isFractalBranchInPrivateCategory\n ? isFractalBranchAllowed\n : isDirectChild || isInsideSameSubDomain;\n\n if (!isAllowed) {\n context.report({\n message: `Importing from Private Category is forbidden. The imported resource is private to \"${owner}\".`,\n node,\n });\n }\n }\n }\n\n return {\n ExportAllDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n ExportNamedDeclaration(node) {\n if (node.source) {\n checkImport(node, node.source.value as string);\n }\n },\n ImportDeclaration(node) {\n checkImport(node, node.source.value as string);\n },\n };\n },\n meta: {\n docs: {\n description:\n 'Prevent leakage and unauthorized imports of Private Category internals',\n },\n schema: [],\n type: 'problem',\n },\n};\n\nexport default rule;\n","import categoryMutuallyExclusive from './_rules/category-mutually-exclusive/index.js';\nimport enforceAccessNode from './_rules/enforce-access-node/index.js';\nimport namingConventions from './_rules/naming-conventions/index.js';\nimport noDirectFragmentImport from './_rules/no-direct-fragment-import/index.js';\nimport noFractalBranchLeak from './_rules/no-fractal-branch-leak/index.js';\nimport noPeerDependency from './_rules/no-peer-dependency/index.js';\nimport noPrivateCategoryLeak from './_rules/no-private-category-leak/index.js';\n\n/**\n * Mapping of FAF rule identifiers to their respective ESLint rule modules.\n * All rules are namespaced under 'faf/*' when consumed in configurations.\n */\nexport const rules = {\n 'category-mutually-exclusive': categoryMutuallyExclusive,\n 'enforce-access-node': enforceAccessNode,\n 'naming-conventions': namingConventions,\n 'no-direct-fragment-import': noDirectFragmentImport,\n 'no-fractal-branch-leak': noFractalBranchLeak,\n 'no-peer-dependency': noPeerDependency,\n 'no-private-category-leak': noPrivateCategoryLeak,\n} as const;\n","import type { TFafPlugin } from './types.js';\n\nimport { rules } from './rules.js';\n\n/**\n * Predefined configuration presets exposed by the FAF ESLint plugin.\n * Includes the recommended flat configuration preset that registers the plugin\n * and activates all taxonomy and dependency rules as blocking \"error\" diagnostics.\n */\nexport const configs: TFafPlugin['configs'] = {\n recommended: {\n plugins: {\n faf: {\n rules,\n },\n },\n rules: {\n 'faf/category-mutually-exclusive': 'error',\n 'faf/enforce-access-node': 'error',\n 'faf/naming-conventions': 'error',\n 'faf/no-direct-fragment-import': 'error',\n 'faf/no-fractal-branch-leak': 'error',\n 'faf/no-peer-dependency': 'error',\n 'faf/no-private-category-leak': 'error',\n },\n },\n};\n","import type { TFafPlugin } from './types.js';\n\nimport pkg from '../package.json' with { type: 'json' };\nimport { configs } from './configs.js';\nimport { rules } from './rules.js';\n\nexport { configs } from './configs.js';\nexport { rules } from './rules.js';\n\n/**\n * Default export representing the ESLint plugin for the Fractal Architecture Framework (FAF).\n * Assembles configs, rules, and package metadata.\n *\n * Exposes rules and configs both as named exports (for backward compatibility/direct consumption)\n * and within the default plugin export container.\n */\nconst plugin: TFafPlugin = {\n configs,\n meta: {\n name: '@morriconeluca/eslint-plugin-faf',\n version: pkg.version,\n },\n rules,\n};\n\nexport default plugin;\n"],"mappings":"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","names":["path","path","path","path","path","path","path","path","path","rule","path","path","rule","path","parentType","path","fs","path","path","fs","rule","path","path","path","path","path","rule","path","path","path","rule","path","rule","path"]}
|