@webpieces/nx-webpieces-rules 0.4.900 → 0.4.902

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.
@@ -216,8 +216,8 @@ class TagTruthValidator {
216
216
  }
217
217
  /**
218
218
  * #1179 — a project whose role the rule lists declares at least one well-formed `product:<name>`.
219
- * The DECLARED tags are read, never the derived `products`: a server inheriting membership from an
220
- * orchestrator that depends on it still states its own product. A malformed tag is not counted here
219
+ * The DECLARED tags are read straight from the project's tags, not from the graph's `products`
220
+ * field, so this check does not depend on enrichment order. A malformed tag is not counted here
221
221
  * because enrichGraph already fails on it, naming the tag.
222
222
  */
223
223
  productTagProblems(info, root, entry, rule) {
@@ -1 +1 @@
1
- {"version":3,"file":"tag-truth.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/tag-truth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tag truth — the four GRAPH rules that make an nx `role:*` / `framework:*` / `product:*` tag true\n * (#1064, #1179):\n *\n * api-lib-dependencies (D2) — a `role:api-lib` depends only on other `role:api-lib` projects plus a\n * stated list of outside packages; a `role:api-client` may also import\n * the packages its own config entry names (its SDK, inversify, …).\n * api-lib-path (D10) — every api-lib / api-client lives under the configured api globs, and\n * everything under them carries one of those two roles.\n * framework-folder (D9) — the folder a library lives in and its framework set + role agree,\n * both directions.\n * product-tags (#1179) — every project whose role is listed (seed: server, client, app)\n * carries a well-formed `product:<name>` tag, the seed the product\n * filter and Product color mode derive membership from; and (#1204)\n * every dependency edge respects the product dependency matrix\n * (product-dependencies.ts), read on the RESOLVED membership.\n *\n * They run beside `library-types-match-client` and `role-dependency` (graph-metadata.ts), in\n * `architecture:generate` and `validate-architecture-unchanged`, AFTER enrichGraph has resolved every\n * project's framework set and role — so a tag is read exactly one way. Every problem across every\n * project is collected and thrown as one MetadataValidationError, before anything is written.\n *\n * There is NO default (`.claude/rules/no-rule-defaults.md`): each rule's fields come from\n * webpieces.config.json, which must state them or fail to load. `TagTruthRules.none()` is what a unit\n * test or a caller that configured nothing asked for — not a default.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { loadAndValidate, matchesAnyGlob, RuleOptions } from \"@webpieces/rules-config\";\nimport { ApiClientPackagesEntry, FrameworkFolderEntry, ProductDependencyEntry } from \"../configs/tag-truth-configs\";\nimport type { EnhancedGraph, GraphEntry } from './graph-sorter';\nimport { APP_ROLES, MetadataValidationError } from './graph-metadata';\nimport { ProjectInfo } from './project-info';\nimport { ProductResolver } from './product-resolver';\nimport { ProductDependencyMatrix } from './product-dependencies';\nimport { RuleGate } from './rule-gate';\nimport { DepUsageScanner } from './dep-usage-scanner';\nimport { toError } from '../toError';\n\n/** The only field of a package.json this check reads. */\ntype RawPackageJson = { name?: string };\n\nexport const API_LIB_ROLE = 'api-lib';\nexport const API_CLIENT_ROLE = 'api-client';\nconst API_ROLES: readonly string[] = [API_LIB_ROLE, API_CLIENT_ROLE];\n\n/** `api-lib-dependencies`, resolved: what an api library may import from outside the api-lib set. */\nexport class ApiLibDependenciesRule {\n constructor(\n /** Package / project names (globs allowed) every api-lib and api-client may depend on. */\n public readonly apiLibPackages: readonly string[],\n /** `role:api-client` project → the extra packages it may depend on. */\n public readonly apiClientPackages: ReadonlyMap<string, readonly string[]>,\n ) {}\n}\n\n/** `api-lib-path`, resolved: the globs every api project — and only api projects — lives under. */\nexport class ApiLibPathRule {\n constructor(public readonly paths: readonly string[]) {}\n}\n\n/** One `framework-folder` entry with its framework sets canonicalised (`a+b`, tokens sorted). */\nexport class FrameworkFolder {\n constructor(\n public readonly paths: readonly string[],\n public readonly frameworkSets: readonly string[],\n public readonly roles: readonly string[],\n ) {}\n\n /** A framework set written in any order, canonicalised: `node+browser` → `browser+node`. */\n // webpieces-disable no-function-outside-class -- static helper of this class\n static canonical(frameworks: readonly string[]): string {\n return [...new Set(frameworks.map((each: string) => each.trim()).filter((each: string) => each !== ''))]\n .sort()\n .join('+');\n }\n\n // webpieces-disable no-function-outside-class -- static factory of this class\n static fromEntry(entry: FrameworkFolderEntry): FrameworkFolder {\n return new FrameworkFolder(\n entry.paths,\n entry.frameworkSets.map((set: string) => FrameworkFolder.canonical(set.split('+'))),\n entry.roles,\n );\n }\n}\n\n/** `framework-folder`, resolved. Entry ORDER matters: the first entry whose glob matches governs. */\nexport class FrameworkFolderRule {\n constructor(public readonly folders: readonly FrameworkFolder[]) {}\n}\n\n/**\n * `product-tags`, resolved: the roles whose every project must declare a `product:<name>` tag, and the\n * product dependency matrix every dependency edge must respect (#1204).\n */\nexport class ProductTagsRule {\n constructor(\n public readonly roles: readonly string[],\n public readonly dependencies: ProductDependencyMatrix,\n ) {}\n}\n\n/**\n * The four rules' switches, read from webpieces.config.json once. A rule that is OFF (or time-boxed /\n * branch-scoped off) is `null`.\n */\nexport class TagTruthRules {\n constructor(\n public readonly apiLibDependencies: ApiLibDependenciesRule | null,\n public readonly apiLibPath: ApiLibPathRule | null,\n public readonly frameworkFolder: FrameworkFolderRule | null,\n public readonly productTags: ProductTagsRule | null,\n ) {}\n\n /** Every rule off — what a caller that configured nothing asked for. */\n // webpieces-disable no-function-outside-class -- static factory of this class\n static none(): TagTruthRules {\n return new TagTruthRules(null, null, null, null);\n }\n\n anyEnabled(): boolean {\n return (\n this.apiLibDependencies !== null ||\n this.apiLibPath !== null ||\n this.frameworkFolder !== null ||\n this.productTags !== null\n );\n }\n\n /** `mode: OFF` and both escape hatches come from RuleGate, so there is ONE reading of them. */\n // webpieces-disable no-function-outside-class -- static factory of this class\n static fromConfig(workspaceRoot: string): TagTruthRules {\n const gate = new RuleGate();\n const rules = loadAndValidate(workspaceRoot).resolved.rules;\n // webpieces-disable no-any-unknown -- a validated rule entry is still opaque JSON in the option bag\n const optionsOf = (name: string): RuleOptions | null =>\n gate.isDisabled(workspaceRoot, name, true) ? null : (rules.get(name)?.options ?? null);\n\n const deps = optionsOf(\"api-lib-dependencies\");\n const where = optionsOf(\"api-lib-path\");\n const folder = optionsOf(\"framework-folder\");\n const products = optionsOf(\"product-tags\");\n return new TagTruthRules(\n deps === null ? null : TagTruthRules.dependenciesRule(deps),\n where === null ? null : new ApiLibPathRule(where['paths'] as string[]),\n folder === null\n ? null\n : new FrameworkFolderRule((folder['entries'] as FrameworkFolderEntry[]).map(FrameworkFolder.fromEntry)),\n products === null\n ? null\n : new ProductTagsRule(\n products['roles'] as string[],\n new ProductDependencyMatrix(products['productDependencies'] as ProductDependencyEntry[]),\n ),\n );\n }\n\n // webpieces-disable no-function-outside-class -- private static reader of this class\n private static dependenciesRule(options: RuleOptions): ApiLibDependenciesRule {\n const clients = new Map<string, readonly string[]>();\n for (const entry of options['apiClients'] as ApiClientPackagesEntry[]) clients.set(entry.project, entry.packages);\n return new ApiLibDependenciesRule(options['apiLibPackages'] as string[], clients);\n }\n}\n\n/** What ONE project imports from production source, and the package name others import it by. */\nexport class ProjectImports {\n constructor(\n /** The project's own `package.json` name, or null when it has none. */\n public readonly packageName: string | null,\n /** Bare package names its production (non-test) source imports. */\n public readonly prodPackages: ReadonlySet<string>,\n ) {}\n}\n\n/** The pure check: every tag-truth problem in a graph whose framework sets and roles are resolved. */\nexport class TagTruthValidator {\n constructor(private readonly rules: TagTruthRules) {}\n\n problems(\n graph: EnhancedGraph,\n infos: Map<string, ProjectInfo>,\n imports: ReadonlyMap<string, ProjectImports>,\n ): string[] {\n const problems: string[] = [];\n for (const name of Object.keys(graph).sort()) {\n const entry = graph[name];\n const info = infos.get(name);\n if (info === undefined || info.root === '' || info.root === '.') continue;\n const root = info.root.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n if (this.rules.apiLibDependencies !== null) {\n problems.push(...this.dependencyProblems(name, entry, graph, imports, this.rules.apiLibDependencies));\n }\n if (this.rules.apiLibPath !== null) {\n problems.push(...this.pathProblems(name, root, entry, this.rules.apiLibPath));\n }\n if (this.rules.frameworkFolder !== null) {\n problems.push(...this.folderProblems(name, root, entry, this.rules.frameworkFolder));\n }\n if (this.rules.productTags !== null) {\n problems.push(...this.productTagProblems(info, root, entry, this.rules.productTags));\n }\n }\n if (this.rules.productTags !== null) {\n problems.push(...this.rules.productTags.dependencies.problems(graph, this.declaredProducts(infos)));\n }\n return problems;\n }\n\n /** Every product some project's `product:` tag names — what a matrix entry may refer to. */\n private declaredProducts(infos: Map<string, ProjectInfo>): Set<string> {\n const resolver = new ProductResolver();\n const declared = new Set<string>();\n for (const info of infos.values()) {\n for (const product of resolver.resolve(info).products) declared.add(product);\n }\n return declared;\n }\n\n /**\n * #1179 — a project whose role the rule lists declares at least one well-formed `product:<name>`.\n * The DECLARED tags are read, never the derived `products`: a server inheriting membership from an\n * orchestrator that depends on it still states its own product. A malformed tag is not counted here\n * because enrichGraph already fails on it, naming the tag.\n */\n private productTagProblems(info: ProjectInfo, root: string, entry: GraphEntry, rule: ProductTagsRule): string[] {\n const role = entry.role;\n if (role === undefined || !rule.roles.includes(role)) return [];\n if (new ProductResolver().resolve(info).products.length > 0) return [];\n return [\n `${\"product-tags\"}: '${info.name}' is role:${role} but carries no product tag — every ` +\n `${rule.roles.map((each: string) => `role:${each}`).join(' / ')} must name the product(s) it belongs ` +\n `to, so the architecture graphs can show one product. Add \"product:<name>\" (lowercase kebab, ` +\n `several allowed) to the \"tags\" in ${root}/project.json, e.g. \"tags\": [..., \"product:<name>\"].`,\n ];\n }\n\n /** D2 — the workspace edges and the outside packages of ONE api-lib / api-client. */\n private dependencyProblems(\n name: string,\n entry: GraphEntry,\n graph: EnhancedGraph,\n imports: ReadonlyMap<string, ProjectImports>,\n rule: ApiLibDependenciesRule,\n ): string[] {\n const role = entry.role;\n if (role === undefined || !API_ROLES.includes(role)) return [];\n const rulePrefix = `${\"api-lib-dependencies\"}: '${name}' (role:${role})`;\n const clientPackages = rule.apiClientPackages.get(name);\n if (role === API_CLIENT_ROLE && clientPackages === undefined) {\n return [\n `${rulePrefix} has no apiClients entry — what an api-client talks to is stated, never inferred. ` +\n `Add { \"project\": \"${name}\", \"packages\": [<its SDK, inversify, …>] } to ` +\n `${\"api-lib-dependencies\"}.apiClients in webpieces.config.json, or retag it role:api-lib ` +\n 'if it bundles no implementation.',\n ];\n }\n const allowed = [...rule.apiLibPackages, ...(clientPackages ?? [])];\n const listName =\n role === API_CLIENT_ROLE ? `apiLibPackages or its apiClients entry` : 'apiLibPackages';\n const problems: string[] = [];\n const workspaceNames = new Set<string>();\n for (const dep of entry.dependsOn) {\n const depImports = imports.get(dep);\n if (depImports?.packageName) workspaceNames.add(depImports.packageName);\n const depRole = graph[dep]?.role;\n if (depRole === API_LIB_ROLE) continue;\n if (matchesAnyGlob(dep, allowed)) continue;\n if (depImports?.packageName && matchesAnyGlob(depImports.packageName, allowed)) continue;\n problems.push(\n `${rulePrefix} must not depend on '${dep}' (role:${depRole ?? 'none'}) — an api library depends ` +\n `only on role:api-lib projects and the packages ${listName} lists. Move what it needs into a ` +\n `role:api-lib project, or add '${depImports?.packageName ?? dep}' to ${listName}.`,\n );\n }\n const own = imports.get(name);\n for (const pkg of [...(own?.prodPackages ?? [])].sort()) {\n if (pkg === own?.packageName || workspaceNames.has(pkg) || this.isWorkspacePackage(pkg, imports)) continue;\n if (matchesAnyGlob(pkg, allowed)) continue;\n problems.push(\n `${rulePrefix} imports '${pkg}', which ${listName} does not list — an api library's wire contract ` +\n `must not drag an outside runtime into every consumer. Remove the import, or add '${pkg}' ` +\n `to ${\"api-lib-dependencies\"}.${role === API_CLIENT_ROLE ? `apiClients[\"${name}\"].packages` : 'apiLibPackages'}.`,\n );\n }\n return problems;\n }\n\n /** A package some workspace project publishes — its edge is judged as a workspace dependency above. */\n private isWorkspacePackage(pkg: string, imports: ReadonlyMap<string, ProjectImports>): boolean {\n for (const each of imports.values()) if (each.packageName === pkg) return true;\n return false;\n }\n\n /** D10 — an api project lives under the api globs, and everything there is an api project. */\n private pathProblems(name: string, root: string, entry: GraphEntry, rule: ApiLibPathRule): string[] {\n const isApi = entry.role !== undefined && API_ROLES.includes(entry.role);\n const inPath = matchesAnyGlob(root, rule.paths);\n const globs = `[${rule.paths.join(', ')}]`;\n if (isApi && !inPath) {\n return [\n `${\"api-lib-path\"}: '${name}' is role:${entry.role} but lives at '${root}', outside ` +\n `${\"api-lib-path\"}.paths ${globs} — move it under one of them ` +\n '(nx g @nx/workspace:move), so every contract in the repo is found in one place.',\n ];\n }\n if (inPath && !isApi) {\n return [\n `${\"api-lib-path\"}: '${name}' lives at '${root}', under ${\"api-lib-path\"}.paths ` +\n `${globs}, but is role:${entry.role ?? 'none'} — everything there is a contract. Retag it ` +\n 'role:api-lib (a contract and/or its DTOs) or role:api-client (a contract plus its SDK ' +\n 'adapter), or move it out of the api tree.',\n ];\n }\n return [];\n }\n\n /** D9 — the folder and the tags agree, both directions. */\n private folderProblems(name: string, root: string, entry: GraphEntry, rule: FrameworkFolderRule): string[] {\n if (entry.framework === undefined || entry.role === undefined) return [];\n const set = FrameworkFolder.canonical(entry.framework);\n const role = entry.role;\n const governing = rule.folders.find((folder: FrameworkFolder) => matchesAnyGlob(root, folder.paths));\n const prefix = `${\"framework-folder\"}: '${name}' at '${root}'`;\n if (governing !== undefined) {\n const problems: string[] = [];\n const glob = governing.paths.join(', ');\n if (!governing.frameworkSets.includes(set)) {\n problems.push(\n `${prefix} carries framework set [${set}], but the folder ${glob} holds ` +\n `[${governing.frameworkSets.join(' | ')}] — retag it to the folder's set, or move it to ` +\n 'the folder that holds its set.',\n );\n }\n if (!governing.roles.includes(role)) {\n problems.push(\n `${prefix} is role:${role}, but the folder ${glob} holds role ` +\n `${governing.roles.map((each: string) => `role:${each}`).join(' | ')} — retag it, or move it.`,\n );\n }\n return problems;\n }\n if (APP_ROLES.includes(role) || role === 'bundle') return [];\n const homes = rule.folders.filter(\n (folder: FrameworkFolder) => folder.frameworkSets.includes(set) && folder.roles.includes(role),\n );\n if (homes.length === 0) return [];\n const globs = homes.map((folder: FrameworkFolder) => folder.paths.join(', ')).join(' | ');\n return [\n `${prefix} is a role:${role} carrying [${set}], which ${\"framework-folder\"} places under ` +\n `${globs} — move it there (nx g @nx/workspace:move), so the folder tells a reader what runs where.`,\n ];\n }\n}\n\n/** The executor-facing entry point: read the config and the imports, check, and throw before any write. */\nexport class TagTruthCheck {\n assertTrue(graph: EnhancedGraph, infos: Map<string, ProjectInfo>, workspaceRoot: string): void {\n const rules = TagTruthRules.fromConfig(workspaceRoot);\n if (!rules.anyEnabled()) return;\n const imports = rules.apiLibDependencies === null ? new Map<string, ProjectImports>() : this.importsOf(infos, workspaceRoot);\n const problems = new TagTruthValidator(rules).problems(graph, infos, imports);\n if (problems.length > 0) throw new MetadataValidationError(problems);\n }\n\n /** Every project's production imports and package name, read from its source and package.json. */\n importsOf(infos: Map<string, ProjectInfo>, workspaceRoot: string): Map<string, ProjectImports> {\n const scanner = new DepUsageScanner();\n const found = new Map<string, ProjectImports>();\n for (const info of infos.values()) {\n if (info.root === '' || info.root === '.') continue;\n const abs = path.resolve(workspaceRoot, info.root);\n found.set(info.name, new ProjectImports(this.packageNameOf(abs), scanner.scan(abs).prodPackages));\n }\n return found;\n }\n\n private packageNameOf(projectDir: string): string | null {\n const file = path.join(projectDir, 'package.json');\n if (!fs.existsSync(file)) return null;\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const parsed = JSON.parse(fs.readFileSync(file, 'utf-8')) as RawPackageJson;\n return typeof parsed.name === 'string' ? parsed.name : null;\n } catch (err: unknown) {\n const error = toError(err);\n throw new Error(`Failed to parse ${file} while reading the package name tag-truth checks against`, {\n cause: error,\n });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"tag-truth.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/tag-truth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tag truth — the four GRAPH rules that make an nx `role:*` / `framework:*` / `product:*` tag true\n * (#1064, #1179):\n *\n * api-lib-dependencies (D2) — a `role:api-lib` depends only on other `role:api-lib` projects plus a\n * stated list of outside packages; a `role:api-client` may also import\n * the packages its own config entry names (its SDK, inversify, …).\n * api-lib-path (D10) — every api-lib / api-client lives under the configured api globs, and\n * everything under them carries one of those two roles.\n * framework-folder (D9) — the folder a library lives in and its framework set + role agree,\n * both directions.\n * product-tags (#1179) — every project whose role is listed (seed: server, client, app)\n * carries a well-formed `product:<name>` tag, the seed the product\n * filter and Product color mode derive membership from; and (#1204)\n * every dependency edge respects the product dependency matrix\n * (product-dependencies.ts), read on the RESOLVED membership.\n *\n * They run beside `library-types-match-client` and `role-dependency` (graph-metadata.ts), in\n * `architecture:generate` and `validate-architecture-unchanged`, AFTER enrichGraph has resolved every\n * project's framework set and role — so a tag is read exactly one way. Every problem across every\n * project is collected and thrown as one MetadataValidationError, before anything is written.\n *\n * There is NO default (`.claude/rules/no-rule-defaults.md`): each rule's fields come from\n * webpieces.config.json, which must state them or fail to load. `TagTruthRules.none()` is what a unit\n * test or a caller that configured nothing asked for — not a default.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { loadAndValidate, matchesAnyGlob, RuleOptions } from \"@webpieces/rules-config\";\nimport { ApiClientPackagesEntry, FrameworkFolderEntry, ProductDependencyEntry } from \"../configs/tag-truth-configs\";\nimport type { EnhancedGraph, GraphEntry } from './graph-sorter';\nimport { APP_ROLES, MetadataValidationError } from './graph-metadata';\nimport { ProjectInfo } from './project-info';\nimport { ProductResolver } from './product-resolver';\nimport { ProductDependencyMatrix } from './product-dependencies';\nimport { RuleGate } from './rule-gate';\nimport { DepUsageScanner } from './dep-usage-scanner';\nimport { toError } from '../toError';\n\n/** The only field of a package.json this check reads. */\ntype RawPackageJson = { name?: string };\n\nexport const API_LIB_ROLE = 'api-lib';\nexport const API_CLIENT_ROLE = 'api-client';\nconst API_ROLES: readonly string[] = [API_LIB_ROLE, API_CLIENT_ROLE];\n\n/** `api-lib-dependencies`, resolved: what an api library may import from outside the api-lib set. */\nexport class ApiLibDependenciesRule {\n constructor(\n /** Package / project names (globs allowed) every api-lib and api-client may depend on. */\n public readonly apiLibPackages: readonly string[],\n /** `role:api-client` project → the extra packages it may depend on. */\n public readonly apiClientPackages: ReadonlyMap<string, readonly string[]>,\n ) {}\n}\n\n/** `api-lib-path`, resolved: the globs every api project — and only api projects — lives under. */\nexport class ApiLibPathRule {\n constructor(public readonly paths: readonly string[]) {}\n}\n\n/** One `framework-folder` entry with its framework sets canonicalised (`a+b`, tokens sorted). */\nexport class FrameworkFolder {\n constructor(\n public readonly paths: readonly string[],\n public readonly frameworkSets: readonly string[],\n public readonly roles: readonly string[],\n ) {}\n\n /** A framework set written in any order, canonicalised: `node+browser` → `browser+node`. */\n // webpieces-disable no-function-outside-class -- static helper of this class\n static canonical(frameworks: readonly string[]): string {\n return [...new Set(frameworks.map((each: string) => each.trim()).filter((each: string) => each !== ''))]\n .sort()\n .join('+');\n }\n\n // webpieces-disable no-function-outside-class -- static factory of this class\n static fromEntry(entry: FrameworkFolderEntry): FrameworkFolder {\n return new FrameworkFolder(\n entry.paths,\n entry.frameworkSets.map((set: string) => FrameworkFolder.canonical(set.split('+'))),\n entry.roles,\n );\n }\n}\n\n/** `framework-folder`, resolved. Entry ORDER matters: the first entry whose glob matches governs. */\nexport class FrameworkFolderRule {\n constructor(public readonly folders: readonly FrameworkFolder[]) {}\n}\n\n/**\n * `product-tags`, resolved: the roles whose every project must declare a `product:<name>` tag, and the\n * product dependency matrix every dependency edge must respect (#1204).\n */\nexport class ProductTagsRule {\n constructor(\n public readonly roles: readonly string[],\n public readonly dependencies: ProductDependencyMatrix,\n ) {}\n}\n\n/**\n * The four rules' switches, read from webpieces.config.json once. A rule that is OFF (or time-boxed /\n * branch-scoped off) is `null`.\n */\nexport class TagTruthRules {\n constructor(\n public readonly apiLibDependencies: ApiLibDependenciesRule | null,\n public readonly apiLibPath: ApiLibPathRule | null,\n public readonly frameworkFolder: FrameworkFolderRule | null,\n public readonly productTags: ProductTagsRule | null,\n ) {}\n\n /** Every rule off — what a caller that configured nothing asked for. */\n // webpieces-disable no-function-outside-class -- static factory of this class\n static none(): TagTruthRules {\n return new TagTruthRules(null, null, null, null);\n }\n\n anyEnabled(): boolean {\n return (\n this.apiLibDependencies !== null ||\n this.apiLibPath !== null ||\n this.frameworkFolder !== null ||\n this.productTags !== null\n );\n }\n\n /** `mode: OFF` and both escape hatches come from RuleGate, so there is ONE reading of them. */\n // webpieces-disable no-function-outside-class -- static factory of this class\n static fromConfig(workspaceRoot: string): TagTruthRules {\n const gate = new RuleGate();\n const rules = loadAndValidate(workspaceRoot).resolved.rules;\n // webpieces-disable no-any-unknown -- a validated rule entry is still opaque JSON in the option bag\n const optionsOf = (name: string): RuleOptions | null =>\n gate.isDisabled(workspaceRoot, name, true) ? null : (rules.get(name)?.options ?? null);\n\n const deps = optionsOf(\"api-lib-dependencies\");\n const where = optionsOf(\"api-lib-path\");\n const folder = optionsOf(\"framework-folder\");\n const products = optionsOf(\"product-tags\");\n return new TagTruthRules(\n deps === null ? null : TagTruthRules.dependenciesRule(deps),\n where === null ? null : new ApiLibPathRule(where['paths'] as string[]),\n folder === null\n ? null\n : new FrameworkFolderRule((folder['entries'] as FrameworkFolderEntry[]).map(FrameworkFolder.fromEntry)),\n products === null\n ? null\n : new ProductTagsRule(\n products['roles'] as string[],\n new ProductDependencyMatrix(products['productDependencies'] as ProductDependencyEntry[]),\n ),\n );\n }\n\n // webpieces-disable no-function-outside-class -- private static reader of this class\n private static dependenciesRule(options: RuleOptions): ApiLibDependenciesRule {\n const clients = new Map<string, readonly string[]>();\n for (const entry of options['apiClients'] as ApiClientPackagesEntry[]) clients.set(entry.project, entry.packages);\n return new ApiLibDependenciesRule(options['apiLibPackages'] as string[], clients);\n }\n}\n\n/** What ONE project imports from production source, and the package name others import it by. */\nexport class ProjectImports {\n constructor(\n /** The project's own `package.json` name, or null when it has none. */\n public readonly packageName: string | null,\n /** Bare package names its production (non-test) source imports. */\n public readonly prodPackages: ReadonlySet<string>,\n ) {}\n}\n\n/** The pure check: every tag-truth problem in a graph whose framework sets and roles are resolved. */\nexport class TagTruthValidator {\n constructor(private readonly rules: TagTruthRules) {}\n\n problems(\n graph: EnhancedGraph,\n infos: Map<string, ProjectInfo>,\n imports: ReadonlyMap<string, ProjectImports>,\n ): string[] {\n const problems: string[] = [];\n for (const name of Object.keys(graph).sort()) {\n const entry = graph[name];\n const info = infos.get(name);\n if (info === undefined || info.root === '' || info.root === '.') continue;\n const root = info.root.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n if (this.rules.apiLibDependencies !== null) {\n problems.push(...this.dependencyProblems(name, entry, graph, imports, this.rules.apiLibDependencies));\n }\n if (this.rules.apiLibPath !== null) {\n problems.push(...this.pathProblems(name, root, entry, this.rules.apiLibPath));\n }\n if (this.rules.frameworkFolder !== null) {\n problems.push(...this.folderProblems(name, root, entry, this.rules.frameworkFolder));\n }\n if (this.rules.productTags !== null) {\n problems.push(...this.productTagProblems(info, root, entry, this.rules.productTags));\n }\n }\n if (this.rules.productTags !== null) {\n problems.push(...this.rules.productTags.dependencies.problems(graph, this.declaredProducts(infos)));\n }\n return problems;\n }\n\n /** Every product some project's `product:` tag names — what a matrix entry may refer to. */\n private declaredProducts(infos: Map<string, ProjectInfo>): Set<string> {\n const resolver = new ProductResolver();\n const declared = new Set<string>();\n for (const info of infos.values()) {\n for (const product of resolver.resolve(info).products) declared.add(product);\n }\n return declared;\n }\n\n /**\n * #1179 — a project whose role the rule lists declares at least one well-formed `product:<name>`.\n * The DECLARED tags are read straight from the project's tags, not from the graph's `products`\n * field, so this check does not depend on enrichment order. A malformed tag is not counted here\n * because enrichGraph already fails on it, naming the tag.\n */\n private productTagProblems(info: ProjectInfo, root: string, entry: GraphEntry, rule: ProductTagsRule): string[] {\n const role = entry.role;\n if (role === undefined || !rule.roles.includes(role)) return [];\n if (new ProductResolver().resolve(info).products.length > 0) return [];\n return [\n `${\"product-tags\"}: '${info.name}' is role:${role} but carries no product tag — every ` +\n `${rule.roles.map((each: string) => `role:${each}`).join(' / ')} must name the product(s) it belongs ` +\n `to, so the architecture graphs can show one product. Add \"product:<name>\" (lowercase kebab, ` +\n `several allowed) to the \"tags\" in ${root}/project.json, e.g. \"tags\": [..., \"product:<name>\"].`,\n ];\n }\n\n /** D2 — the workspace edges and the outside packages of ONE api-lib / api-client. */\n private dependencyProblems(\n name: string,\n entry: GraphEntry,\n graph: EnhancedGraph,\n imports: ReadonlyMap<string, ProjectImports>,\n rule: ApiLibDependenciesRule,\n ): string[] {\n const role = entry.role;\n if (role === undefined || !API_ROLES.includes(role)) return [];\n const rulePrefix = `${\"api-lib-dependencies\"}: '${name}' (role:${role})`;\n const clientPackages = rule.apiClientPackages.get(name);\n if (role === API_CLIENT_ROLE && clientPackages === undefined) {\n return [\n `${rulePrefix} has no apiClients entry — what an api-client talks to is stated, never inferred. ` +\n `Add { \"project\": \"${name}\", \"packages\": [<its SDK, inversify, …>] } to ` +\n `${\"api-lib-dependencies\"}.apiClients in webpieces.config.json, or retag it role:api-lib ` +\n 'if it bundles no implementation.',\n ];\n }\n const allowed = [...rule.apiLibPackages, ...(clientPackages ?? [])];\n const listName =\n role === API_CLIENT_ROLE ? `apiLibPackages or its apiClients entry` : 'apiLibPackages';\n const problems: string[] = [];\n const workspaceNames = new Set<string>();\n for (const dep of entry.dependsOn) {\n const depImports = imports.get(dep);\n if (depImports?.packageName) workspaceNames.add(depImports.packageName);\n const depRole = graph[dep]?.role;\n if (depRole === API_LIB_ROLE) continue;\n if (matchesAnyGlob(dep, allowed)) continue;\n if (depImports?.packageName && matchesAnyGlob(depImports.packageName, allowed)) continue;\n problems.push(\n `${rulePrefix} must not depend on '${dep}' (role:${depRole ?? 'none'}) — an api library depends ` +\n `only on role:api-lib projects and the packages ${listName} lists. Move what it needs into a ` +\n `role:api-lib project, or add '${depImports?.packageName ?? dep}' to ${listName}.`,\n );\n }\n const own = imports.get(name);\n for (const pkg of [...(own?.prodPackages ?? [])].sort()) {\n if (pkg === own?.packageName || workspaceNames.has(pkg) || this.isWorkspacePackage(pkg, imports)) continue;\n if (matchesAnyGlob(pkg, allowed)) continue;\n problems.push(\n `${rulePrefix} imports '${pkg}', which ${listName} does not list — an api library's wire contract ` +\n `must not drag an outside runtime into every consumer. Remove the import, or add '${pkg}' ` +\n `to ${\"api-lib-dependencies\"}.${role === API_CLIENT_ROLE ? `apiClients[\"${name}\"].packages` : 'apiLibPackages'}.`,\n );\n }\n return problems;\n }\n\n /** A package some workspace project publishes — its edge is judged as a workspace dependency above. */\n private isWorkspacePackage(pkg: string, imports: ReadonlyMap<string, ProjectImports>): boolean {\n for (const each of imports.values()) if (each.packageName === pkg) return true;\n return false;\n }\n\n /** D10 — an api project lives under the api globs, and everything there is an api project. */\n private pathProblems(name: string, root: string, entry: GraphEntry, rule: ApiLibPathRule): string[] {\n const isApi = entry.role !== undefined && API_ROLES.includes(entry.role);\n const inPath = matchesAnyGlob(root, rule.paths);\n const globs = `[${rule.paths.join(', ')}]`;\n if (isApi && !inPath) {\n return [\n `${\"api-lib-path\"}: '${name}' is role:${entry.role} but lives at '${root}', outside ` +\n `${\"api-lib-path\"}.paths ${globs} — move it under one of them ` +\n '(nx g @nx/workspace:move), so every contract in the repo is found in one place.',\n ];\n }\n if (inPath && !isApi) {\n return [\n `${\"api-lib-path\"}: '${name}' lives at '${root}', under ${\"api-lib-path\"}.paths ` +\n `${globs}, but is role:${entry.role ?? 'none'} — everything there is a contract. Retag it ` +\n 'role:api-lib (a contract and/or its DTOs) or role:api-client (a contract plus its SDK ' +\n 'adapter), or move it out of the api tree.',\n ];\n }\n return [];\n }\n\n /** D9 — the folder and the tags agree, both directions. */\n private folderProblems(name: string, root: string, entry: GraphEntry, rule: FrameworkFolderRule): string[] {\n if (entry.framework === undefined || entry.role === undefined) return [];\n const set = FrameworkFolder.canonical(entry.framework);\n const role = entry.role;\n const governing = rule.folders.find((folder: FrameworkFolder) => matchesAnyGlob(root, folder.paths));\n const prefix = `${\"framework-folder\"}: '${name}' at '${root}'`;\n if (governing !== undefined) {\n const problems: string[] = [];\n const glob = governing.paths.join(', ');\n if (!governing.frameworkSets.includes(set)) {\n problems.push(\n `${prefix} carries framework set [${set}], but the folder ${glob} holds ` +\n `[${governing.frameworkSets.join(' | ')}] — retag it to the folder's set, or move it to ` +\n 'the folder that holds its set.',\n );\n }\n if (!governing.roles.includes(role)) {\n problems.push(\n `${prefix} is role:${role}, but the folder ${glob} holds role ` +\n `${governing.roles.map((each: string) => `role:${each}`).join(' | ')} — retag it, or move it.`,\n );\n }\n return problems;\n }\n if (APP_ROLES.includes(role) || role === 'bundle') return [];\n const homes = rule.folders.filter(\n (folder: FrameworkFolder) => folder.frameworkSets.includes(set) && folder.roles.includes(role),\n );\n if (homes.length === 0) return [];\n const globs = homes.map((folder: FrameworkFolder) => folder.paths.join(', ')).join(' | ');\n return [\n `${prefix} is a role:${role} carrying [${set}], which ${\"framework-folder\"} places under ` +\n `${globs} — move it there (nx g @nx/workspace:move), so the folder tells a reader what runs where.`,\n ];\n }\n}\n\n/** The executor-facing entry point: read the config and the imports, check, and throw before any write. */\nexport class TagTruthCheck {\n assertTrue(graph: EnhancedGraph, infos: Map<string, ProjectInfo>, workspaceRoot: string): void {\n const rules = TagTruthRules.fromConfig(workspaceRoot);\n if (!rules.anyEnabled()) return;\n const imports = rules.apiLibDependencies === null ? new Map<string, ProjectImports>() : this.importsOf(infos, workspaceRoot);\n const problems = new TagTruthValidator(rules).problems(graph, infos, imports);\n if (problems.length > 0) throw new MetadataValidationError(problems);\n }\n\n /** Every project's production imports and package name, read from its source and package.json. */\n importsOf(infos: Map<string, ProjectInfo>, workspaceRoot: string): Map<string, ProjectImports> {\n const scanner = new DepUsageScanner();\n const found = new Map<string, ProjectImports>();\n for (const info of infos.values()) {\n if (info.root === '' || info.root === '.') continue;\n const abs = path.resolve(workspaceRoot, info.root);\n found.set(info.name, new ProjectImports(this.packageNameOf(abs), scanner.scan(abs).prodPackages));\n }\n return found;\n }\n\n private packageNameOf(projectDir: string): string | null {\n const file = path.join(projectDir, 'package.json');\n if (!fs.existsSync(file)) return null;\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const parsed = JSON.parse(fs.readFileSync(file, 'utf-8')) as RawPackageJson;\n return typeof parsed.name === 'string' ? parsed.name : null;\n } catch (err: unknown) {\n const error = toError(err);\n throw new Error(`Failed to parse ${file} while reading the package name tag-truth checks against`, {\n cause: error,\n });\n }\n }\n}\n"]}