@webpieces/nx-webpieces-rules 0.4.835 → 0.4.837

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/executors.json CHANGED
@@ -60,6 +60,11 @@
60
60
  "schema": "./src/executors/validate-checklist-docs/schema.json",
61
61
  "description": "Validate the pr-gate checklists[] block: docs exist, patterns compile, ids unique, blockMessage on BLOCK"
62
62
  },
63
+ "validate-rules-config": {
64
+ "implementation": "./src/executors/validate-rules-config/executor",
65
+ "schema": "./src/executors/validate-rules-config/schema.json",
66
+ "description": "Validate webpieces.config.json once at the scoped rules:check boundary"
67
+ },
63
68
  "validate-no-any-unknown": {
64
69
  "implementation": "./src/executors/validate-no-any-unknown/executor",
65
70
  "schema": "./src/executors/validate-no-any-unknown/schema.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/nx-webpieces-rules",
3
- "version": "0.4.835",
3
+ "version": "0.4.837",
4
4
  "description": "Nx-specific webpieces validation rules and graph tooling. Bundles all @webpieces rule packages with Nx graph validators and an inference plugin.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -18,13 +18,14 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@webpieces/ai-hook-rules": "0.4.835",
22
- "@webpieces/api-doc-model": "0.4.835",
23
- "@webpieces/code-rules": "0.4.835",
24
- "@webpieces/core-util": "0.4.835",
25
- "@webpieces/eslint-rules": "0.4.835",
26
- "@webpieces/pr-gate": "0.4.835",
27
- "@webpieces/rules-config": "0.4.835",
21
+ "@webpieces/ai-hook-rules": "0.4.837",
22
+ "@webpieces/hook-runtime": "0.4.837",
23
+ "@webpieces/api-doc-model": "0.4.837",
24
+ "@webpieces/code-rules": "0.4.837",
25
+ "@webpieces/core-util": "0.4.837",
26
+ "@webpieces/eslint-rules": "0.4.837",
27
+ "@webpieces/pr-gate": "0.4.837",
28
+ "@webpieces/rules-config": "0.4.837",
28
29
  "madge": "8.0.0"
29
30
  },
30
31
  "peerDependencies": {
@@ -0,0 +1,9 @@
1
+ import type { ExecutorContext } from '@nx/devkit';
2
+ export declare class ValidateRulesConfigOptions {
3
+ readonly placeholder?: never;
4
+ }
5
+ export declare class ValidateRulesConfigResult {
6
+ readonly success: boolean;
7
+ constructor(success: boolean);
8
+ }
9
+ export default function runExecutor(_options: ValidateRulesConfigOptions, context: ExecutorContext): Promise<ValidateRulesConfigResult>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValidateRulesConfigResult = exports.ValidateRulesConfigOptions = void 0;
4
+ exports.default = runExecutor;
5
+ const rules_config_1 = require("@webpieces/rules-config");
6
+ class ValidateRulesConfigOptions {
7
+ // No options: the workspace-root declaration is the one policy source.
8
+ placeholder;
9
+ }
10
+ exports.ValidateRulesConfigOptions = ValidateRulesConfigOptions;
11
+ class ValidateRulesConfigResult {
12
+ success;
13
+ constructor(success) {
14
+ this.success = success;
15
+ }
16
+ }
17
+ exports.ValidateRulesConfigResult = ValidateRulesConfigResult;
18
+ // webpieces-disable no-function-outside-class -- Nx invokes executor entrypoints as default-exported functions.
19
+ function runExecutor(_options, context) {
20
+ (0, rules_config_1.loadAndValidate)(context.root);
21
+ console.log('✅ webpieces.config.json is valid');
22
+ return Promise.resolve(new ValidateRulesConfigResult(true));
23
+ }
24
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-rules-config/executor.ts"],"names":[],"mappings":";;;AAaA,8BAOC;AAnBD,0DAA0D;AAE1D,MAAa,0BAA0B;IACnC,uEAAuE;IAC9D,WAAW,CAAS;CAChC;AAHD,gEAGC;AAED,MAAa,yBAAyB;IACb;IAArB,YAAqB,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;CAC5C;AAFD,8DAEC;AAED,gHAAgH;AAChH,SAAwB,WAAW,CAC/B,QAAoC,EACpC,OAAwB;IAExB,IAAA,8BAAe,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { loadAndValidate } from '@webpieces/rules-config';\n\nexport class ValidateRulesConfigOptions {\n // No options: the workspace-root declaration is the one policy source.\n readonly placeholder?: never;\n}\n\nexport class ValidateRulesConfigResult {\n constructor(readonly success: boolean) {}\n}\n\n// webpieces-disable no-function-outside-class -- Nx invokes executor entrypoints as default-exported functions.\nexport default function runExecutor(\n _options: ValidateRulesConfigOptions,\n context: ExecutorContext,\n): Promise<ValidateRulesConfigResult> {\n loadAndValidate(context.root);\n console.log('✅ webpieces.config.json is valid');\n return Promise.resolve(new ValidateRulesConfigResult(true));\n}\n"]}
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "Validate Rules Config Executor",
4
+ "description": "Validates webpieces.config.json once through the scoped rules:check target.",
5
+ "type": "object",
6
+ "properties": {},
7
+ "required": []
8
+ }
package/src/plugin.js CHANGED
@@ -32,6 +32,7 @@ const branch_identity_inputs_1 = require("./branch-identity-inputs");
32
32
  const validation_targets_1 = require("./validation-targets");
33
33
  const di_graph_targets_1 = require("./di-graph-targets");
34
34
  const generate_targets_1 = require("./generate-targets");
35
+ const rules_target_1 = require("./rules-target");
35
36
  const DEFAULT_OPTIONS = {
36
37
  circularDeps: {
37
38
  enabled: true,
@@ -95,8 +96,13 @@ async function createNodesFunction(projectFiles, options, context) {
95
96
  const results = [];
96
97
  // Add workspace-level architecture targets
97
98
  addArchitectureProject(results, projectFiles, opts, context);
99
+ // One root policy target. webpieces.config.json is not a shared input of every product project;
100
+ // this virtual project is its sole Nx owner and the gate runs it before affected CI.
98
101
  // Add per-project targets (circular-deps, ci, di-graph)
99
102
  addPerProjectTargets(results, projectFiles, opts, context);
103
+ // Append the virtual root project after concrete projects so callers that select the first result
104
+ // for a project.json still receive that project's inferred targets.
105
+ new rules_target_1.RulesTarget().add(results, projectFiles);
100
106
  return results;
101
107
  }
102
108
  function addArchitectureProject(results, projectFiles, opts, context) {
@@ -150,6 +156,10 @@ function addPerProjectTargets(results, projectFiles, opts, context) {
150
156
  // Skip root (workspace manifest, not a project)
151
157
  if (projectRoot === '.')
152
158
  continue;
159
+ // The scoped root policy project declares check/ci itself. It has no product source to lint,
160
+ // compile or test, so the ordinary per-project aggregate would recreate irrelevant fan-out.
161
+ if (projectRoot === 'rules')
162
+ continue;
153
163
  // Skip projects inside a nested git repo (vendored clones under repositories/): they are
154
164
  // separate repos and must not be swept into this workspace's `nx affected` graph.
155
165
  if (isInsideNestedGitRepo(context.workspaceRoot, projectRoot))
package/src/plugin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unified Nx Inference Plugin for @webpieces/nx-webpieces-rules\n *\n * This plugin automatically creates targets for:\n * 1. Workspace-level architecture validation (generate, visualize, validate-*)\n * 2. Per-project circular dependency checking\n * 3. Per-project API documents, opted into with a TAG: `generate:openapi` infers `openapi-generate`,\n * `generate:openapi-components` infers `openapi-components-generate` (a DTO library's\n * components.openapi.json), `generate:docs-site` infers `openapi-generate` + `docs-generate`\n * (see generate-targets.ts)\n *\n * Install with: nx add @webpieces/nx-webpieces-rules\n *\n * Usage:\n * Add to nx.json plugins array:\n * {\n * \"plugins\": [\"@webpieces/nx-webpieces-rules\"]\n * }\n *\n * Then all targets appear automatically without manual project.json configuration.\n */\n\nimport { dirname, join } from 'path';\nimport { existsSync } from 'fs';\nimport type {\n CreateNodesV2,\n CreateNodesContextV2,\n CreateNodesResultV2,\n CreateNodesResult,\n TargetConfiguration,\n} from '@nx/devkit';\nimport {\n createVisualizeRuntimeTarget,\n createValidateRuntimeArchitectureTarget,\n} from './runtime-targets';\nimport { BRANCH_IDENTITY_INPUTS } from './branch-identity-inputs';\nimport { ValidationTargets } from './validation-targets';\nimport { createDiGraphGenerateTarget } from './di-graph-targets';\nimport { GenerateTargets, RawProjectJson, RawProjectJsonReader } from './generate-targets';\n\n/**\n * Circular dependency checking options\n */\nexport interface CircularDepsOptions {\n enabled?: boolean;\n targetName?: string;\n excludePatterns?: string[];\n}\n\n/**\n * Validation options for architecture checks\n */\nexport interface ValidationOptions {\n noCycles?: boolean;\n architectureUnchanged?: boolean;\n validatePackageJson?: boolean;\n validateNewMethods?: boolean;\n validateModifiedMethods?: boolean;\n validateModifiedFiles?: boolean;\n validateVersionsLocked?: boolean;\n validateTsInSrc?: boolean;\n validateNxWiring?: boolean;\n runtimeArchitecture?: boolean;\n validateApiRelations?: boolean;\n validateApiLibTag?: boolean;\n diGraph?: boolean;\n newMethodsMaxLines?: number;\n modifiedAndNewMethodsMaxLines?: number;\n modifiedFilesMaxLines?: number;\n /**\n * Validation mode for method/file size limits:\n * - STRICT: All limits enforced, disable comments ignored\n * - NORMAL: Limits enforced, disable comments with dates work\n * - OFF: Skip size validations entirely (for fast iteration)\n */\n validationMode?: 'STRICT' | 'NORMAL' | 'OFF';\n}\n\n/**\n * Feature flags for workspace targets\n */\nexport interface FeatureOptions {\n generate?: boolean;\n visualize?: boolean;\n visualizeRuntime?: boolean;\n}\n\n/**\n * Workspace-level configuration options\n */\nexport interface WorkspaceOptions {\n enabled?: boolean;\n targetPrefix?: string;\n graphPath?: string;\n validations?: ValidationOptions;\n features?: FeatureOptions;\n}\n\n/**\n * Configuration for @webpieces/nx-webpieces-rules Nx plugin\n */\nexport interface ArchitecturePluginOptions {\n circularDeps?: CircularDepsOptions;\n workspace?: WorkspaceOptions;\n}\n\nconst DEFAULT_OPTIONS: Required<ArchitecturePluginOptions> = {\n circularDeps: {\n enabled: true,\n targetName: 'validate-no-file-import-cycles',\n excludePatterns: [],\n },\n workspace: {\n enabled: true,\n targetPrefix: 'arch:',\n graphPath: 'architecture/dependencies.json',\n validations: {\n noCycles: true,\n architectureUnchanged: true,\n validatePackageJson: true,\n validateNewMethods: true,\n validateModifiedMethods: true,\n validateModifiedFiles: true,\n validateVersionsLocked: true,\n validateTsInSrc: true,\n validateNxWiring: true,\n runtimeArchitecture: true,\n validateApiRelations: true,\n validateApiLibTag: true,\n diGraph: true,\n newMethodsMaxLines: 30,\n modifiedAndNewMethodsMaxLines: 80,\n modifiedFilesMaxLines: 900,\n validationMode: 'NORMAL',\n },\n features: {\n generate: true,\n visualize: true,\n visualizeRuntime: true,\n },\n },\n};\n\nfunction normalizeOptions(\n options: ArchitecturePluginOptions | undefined,\n): Required<ArchitecturePluginOptions> {\n const circularDeps = {\n ...DEFAULT_OPTIONS.circularDeps,\n ...options?.circularDeps,\n };\n\n const workspace = {\n ...DEFAULT_OPTIONS.workspace,\n ...options?.workspace,\n validations: {\n ...DEFAULT_OPTIONS.workspace.validations,\n ...options?.workspace?.validations,\n },\n features: {\n ...DEFAULT_OPTIONS.workspace.features,\n ...options?.workspace?.features,\n },\n };\n\n return {\n circularDeps,\n workspace,\n } as Required<ArchitecturePluginOptions>;\n}\n\nasync function createNodesFunction(\n projectFiles: readonly string[],\n options: ArchitecturePluginOptions | undefined,\n context: CreateNodesContextV2,\n): Promise<CreateNodesResultV2> {\n const opts = normalizeOptions(options);\n const results: CreateNodesResultV2 = [];\n\n // Add workspace-level architecture targets\n addArchitectureProject(results, projectFiles, opts, context);\n\n // Add per-project targets (circular-deps, ci, di-graph)\n addPerProjectTargets(results, projectFiles, opts, context);\n\n return results;\n}\n\nfunction addArchitectureProject(\n results: CreateNodesResultV2,\n projectFiles: readonly string[],\n opts: Required<ArchitecturePluginOptions>,\n context: CreateNodesContextV2,\n): void {\n if (!opts.workspace.enabled) return;\n\n const archDirPath = join(context.workspaceRoot, 'architecture');\n if (!existsSync(archDirPath)) return;\n\n const workspaceTargets = createWorkspaceTargetsWithoutPrefix(opts);\n if (Object.keys(workspaceTargets).length === 0) return;\n\n const result: CreateNodesResult = {\n projects: {\n architecture: {\n name: 'architecture',\n root: 'architecture',\n targets: workspaceTargets,\n },\n },\n };\n\n const firstProjectFile = projectFiles[0];\n if (firstProjectFile) {\n results.push([firstProjectFile, result] as const);\n }\n}\n\n\n// A project sits inside a NESTED git repo (e.g. a clone under repositories/) when any of its\n// ancestor dirs — up to but NOT including the workspace root — contains a `.git`. Such projects are\n// separate repos, not part of THIS workspace's graph, so they must not get inferred targets (that is\n// what drags foreign clones into `nx affected`). Same repo-boundary signal the AI guards use.\nexport function isInsideNestedGitRepo(workspaceRoot: string, projectRoot: string): boolean {\n let dir = projectRoot;\n while (dir && dir !== '.' && dir !== '/') {\n if (existsSync(join(workspaceRoot, dir, '.git'))) return true;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return false;\n}\n\nfunction addPerProjectTargets(\n results: CreateNodesResultV2,\n projectFiles: readonly string[],\n opts: Required<ArchitecturePluginOptions>,\n context: CreateNodesContextV2,\n): void {\n // Track processed project roots to avoid duplicates when both files exist\n const processedRoots = new Set<string>();\n\n for (const projectFile of projectFiles) {\n const isProjectJson = projectFile.endsWith('project.json');\n const isPackageJson = projectFile.endsWith('package.json');\n\n if (!isProjectJson && !isPackageJson) continue;\n\n const projectRoot = dirname(projectFile);\n\n // Skip root (workspace manifest, not a project)\n if (projectRoot === '.') continue;\n\n // Skip projects inside a nested git repo (vendored clones under repositories/): they are\n // separate repos and must not be swept into this workspace's `nx affected` graph.\n if (isInsideNestedGitRepo(context.workspaceRoot, projectRoot)) continue;\n\n // Skip if we've already processed this project root\n if (processedRoots.has(projectRoot)) continue;\n\n // For package.json, skip if project.json also exists in same directory\n // (prefer project.json - it will be processed separately)\n if (isPackageJson) {\n const projectJsonPath = join(context.workspaceRoot, projectRoot, 'project.json');\n if (existsSync(projectJsonPath)) continue;\n }\n\n processedRoots.add(projectRoot);\n\n const architectureEnabled =\n opts.workspace.enabled === true &&\n existsSync(join(context.workspaceRoot, 'architecture'));\n const targets = buildPerProjectTargets(\n isProjectJson,\n projectRoot,\n opts,\n architectureEnabled,\n isProjectJson ? new RawProjectJsonReader().read(context.workspaceRoot, projectFile, projectRoot) : undefined,\n );\n\n if (Object.keys(targets).length === 0) continue;\n\n const result: CreateNodesResult = {\n projects: {\n [projectRoot]: {\n targets,\n },\n },\n };\n\n results.push([projectFile, result] as const);\n }\n}\n\n/**\n * Build the target map for one project. Most targets are project.json-only\n * (package.json-only projects may not have TypeScript source); `ci` goes on all.\n */\n// webpieces-disable no-function-outside-class -- Nx requires its inference callback and target-map assembly at module scope; this existing functional plugin is invoked by Nx, not DI.\nfunction buildPerProjectTargets(\n isProjectJson: boolean,\n projectRoot: string,\n opts: Required<ArchitecturePluginOptions>,\n architectureEnabled: boolean,\n rawProject: RawProjectJson | undefined,\n): Record<string, TargetConfiguration> {\n const targets: Record<string, TargetConfiguration> = {};\n\n // Per-project validation gates that `ci` must depend on. Collected as they are added\n // so `ci` references only gates that actually exist on THIS project (a package.json-only\n // project has none).\n const validationTargets: string[] = [];\n\n // Add circular-deps target ONLY for project.json projects\n if (isProjectJson && opts.circularDeps.enabled) {\n if (!isExcluded(projectRoot, opts.circularDeps.excludePatterns!)) {\n const targetName = opts.circularDeps.targetName!;\n targets[targetName] = createCircularDepsTarget(projectRoot, targetName);\n validationTargets.push(targetName);\n }\n }\n\n // Per-project DI design DAG: regenerate design.json/design.md/design.html on every build.\n //\n // `di-graph-generate` is itself pushed onto validationTargets so `ci` still RUNS it — it used to ride\n // in only as the `dependsOn` of the deleted `validate-di-graph-unchanged` gate. There is no staleness\n // gate here any more: \"the regenerated design files are committed\" is now one repo-wide check in\n // `wp-review-upsert-pr` (see di-graph-targets.ts for why the per-project gate could not work).\n if (isProjectJson && opts.workspace.validations!.diGraph) {\n targets['di-graph-generate'] = createDiGraphGenerateTarget();\n validationTargets.push('di-graph-generate');\n }\n\n // API documents, opted into with a TAG (generate:openapi / generate:docs-site). An untagged project\n // costs this one in-memory tag check. They ride ci like every other build step — generation is\n // ordinary BUILD work, not a side channel (#1021).\n if (rawProject !== undefined) {\n const generated = new GenerateTargets(projectRoot, rawProject).infer();\n for (const [name, target] of Object.entries(generated)) {\n targets[name] = target;\n validationTargets.push(name);\n }\n }\n\n // Add ci target to ALL projects (both project.json and package.json). ci aggregates\n // lint + build + test + the validation gates that formerly rode on the compile\n // executor's targetDefaults, so a bare `build` stays a fast compile-only step.\n targets['ci'] = createCiTarget(validationTargets, architectureEnabled);\n targets['hotfix-ci'] = createHotfixCiTarget();\n\n return targets;\n}\n\n/**\n * Nx V2 Inference Plugin\n * Matches project.json and package.json files to create targets\n */\nexport const createNodesV2: CreateNodesV2<ArchitecturePluginOptions> = [\n // Pattern to match project.json and package.json files\n '**/{project,package}.json',\n\n // Inference function\n createNodesFunction,\n];\n\n/**\n * Build list of enabled validation target names for validate-complete dependency chain\n */\nfunction buildValidationTargetsList(\n validations: Required<ArchitecturePluginOptions>['workspace']['validations'],\n): string[] {\n const targets: string[] = [];\n if (validations!.noCycles) targets.push('validate-no-architecture-cycles');\n if (validations!.architectureUnchanged) targets.push('validate-architecture-unchanged');\n if (validations!.validatePackageJson) targets.push('validate-packagejson');\n // Use combined validate-code instead of 3 separate targets\n if (\n validations!.validateNewMethods ||\n validations!.validateModifiedMethods ||\n validations!.validateModifiedFiles\n ) {\n targets.push('validate-code');\n }\n if (validations!.validateVersionsLocked) targets.push('validate-versions-locked');\n if (validations!.validateTsInSrc) targets.push('validate-ts-in-src');\n if (validations!.validateNxWiring) targets.push('validate-nx-wiring');\n if (validations!.runtimeArchitecture) targets.push('validate-runtime-architecture');\n if (validations!.validateApiRelations) targets.push('validate-api-relations');\n if (validations!.validateApiLibTag) targets.push('validate-api-lib-tag');\n return targets;\n}\n\n/**\n * Create workspace-level architecture validation targets WITHOUT prefix\n * Used for virtual 'architecture' project\n */\nfunction createWorkspaceTargetsWithoutPrefix(\n opts: Required<ArchitecturePluginOptions>,\n): Record<string, TargetConfiguration> {\n const targets: Record<string, TargetConfiguration> = {};\n const graphPath = opts.workspace.graphPath!;\n const validations = opts.workspace.validations!;\n // One ValidationTargets instance, injected below to build each target config.\n const targetFactory = new ValidationTargets();\n\n // Add help target (always available)\n targets['help'] = createHelpTarget();\n\n if (opts.workspace.features!.generate) {\n targets['generate'] = createGenerateTarget(graphPath);\n }\n if (opts.workspace.features!.visualize) {\n targets['visualize'] = createVisualizeTargetWithoutPrefix(graphPath);\n }\n if (opts.workspace.features!.visualizeRuntime) {\n targets['visualize-runtime'] = createVisualizeRuntimeTarget();\n }\n if (validations.noCycles) {\n targets['validate-no-architecture-cycles'] = targetFactory.noCycles();\n }\n if (validations.architectureUnchanged) {\n targets['validate-architecture-unchanged'] = createValidateUnchangedTarget(graphPath);\n }\n if (validations.validatePackageJson) {\n targets['validate-packagejson'] = targetFactory.packageJson();\n }\n // Always available (cheap; success when a repo has no checklists). Kept out of the validate-complete /\n // ci aggregate so it does not change existing gate behavior — consumers point a required check at it.\n targets['validate-checklist-docs'] = targetFactory.checklistDocs();\n // Use combined validate-code instead of 3 separate targets\n // Options come from webpieces.config.json at the workspace root\n // (loaded via @webpieces/rules-config; same source of truth as @webpieces/ai-hook-rules)\n if (\n validations.validateNewMethods ||\n validations.validateModifiedMethods ||\n validations.validateModifiedFiles\n ) {\n targets['validate-code'] = targetFactory.code();\n }\n if (validations.validateVersionsLocked) {\n targets['validate-versions-locked'] = targetFactory.versionsLocked();\n }\n if (validations.validateTsInSrc) {\n targets['validate-ts-in-src'] = targetFactory.tsInSrc();\n }\n if (validations.validateNxWiring) {\n targets['validate-nx-wiring'] = targetFactory.nxWiring();\n }\n if (validations.runtimeArchitecture) {\n targets['validate-runtime-architecture'] = createValidateRuntimeArchitectureTarget();\n }\n if (validations.validateApiRelations) {\n targets['validate-api-relations'] = targetFactory.apiRelations();\n }\n if (validations.validateApiLibTag) {\n targets['validate-api-lib-tag'] = targetFactory.apiLibTag();\n }\n\n // Add validate-complete target that runs all enabled validations\n const validationTargets = buildValidationTargetsList(validations);\n if (validationTargets.length > 0) {\n targets['validate-complete'] = createValidateCompleteTarget(validationTargets);\n }\n\n return targets;\n}\n\nfunction createGenerateTarget(graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:generate',\n cache: false,\n outputs: [\n '{workspaceRoot}/architecture/dependencies.json',\n '{workspaceRoot}/architecture/dependencies.html',\n '{workspaceRoot}/architecture/apis',\n '{workspaceRoot}/architecture/runtime-dependencies.json',\n ],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description:\n 'Generate the architecture dependency graph (+ clickable dependencies.html) and the runtime microservice graph',\n },\n };\n}\n\nfunction createVisualizeTargetWithoutPrefix(graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:visualize',\n dependsOn: ['generate'],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Generate visual representations of the architecture graph',\n },\n };\n}\n\nfunction createValidateUnchangedTarget(graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-architecture-unchanged',\n cache: false,\n inputs: ['default', '{workspaceRoot}/architecture/dependencies.json'],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Validate the architecture matches the saved blessed graph',\n },\n };\n}\n\nfunction createValidateNewMethodsTarget(\n maxLines: number,\n mode: 'STRICT' | 'NORMAL' | 'OFF',\n): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-new-methods',\n cache: false, // Don't cache - depends on git state\n inputs: ['default'],\n options: { max: maxLines, mode },\n metadata: {\n technologies: ['nx'],\n description: `Validate new methods do not exceed ${maxLines} lines (only runs in affected mode)`,\n },\n };\n}\n\nfunction createValidateModifiedMethodsTarget(\n maxLines: number,\n mode: 'STRICT' | 'NORMAL' | 'OFF',\n): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-modified-methods',\n cache: false, // Don't cache - depends on git state\n inputs: ['default'],\n options: { max: maxLines, mode },\n metadata: {\n technologies: ['nx'],\n description: `Validate new and modified methods do not exceed ${maxLines} lines (encourages gradual cleanup)`,\n },\n };\n}\n\nfunction createValidateModifiedFilesTarget(\n maxLines: number,\n mode: 'STRICT' | 'NORMAL' | 'OFF',\n): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-modified-files',\n cache: false, // Don't cache - depends on git state\n inputs: ['default'],\n options: { max: maxLines, mode },\n metadata: {\n technologies: ['nx'],\n description: `Validate modified files do not exceed ${maxLines} lines (encourages keeping files small)`,\n },\n };\n}\n\nfunction createValidateCompleteTarget(validationTargets: string[]): TargetConfiguration {\n return {\n executor: 'nx:noop',\n cache: true,\n dependsOn: validationTargets,\n metadata: {\n technologies: ['nx'],\n description: 'Run all architecture validations (cycles, unchanged, package.json, code rules)',\n },\n };\n}\n\n/**\n * Create per-project ci target - Gradle-style composite target\n * Composite CI target: runs lint, build, test, and every validation gate.\n *\n * Validation (architecture graph completeness, per-project file-import cycles, DI-graph\n * unchanged) lives HERE, not on the build/compile target. That keeps `nx build` a fast\n * compile-only step for local iteration while `nx ci` is the full gate the PR check runs.\n *\n * The per-project gates are passed in because they exist only on project.json projects;\n * `architecture:validate-complete` is a cross-project dep added only when the workspace\n * `architecture` project exists.\n *\n * NOTE: Type checking is done by the build target (@nx/js:tsc) during compilation.\n */\n// webpieces-disable no-function-outside-class -- Nx inference plugin: createNodes invokes these as module-scope target factories; the entire plugin is intentionally functional (matching the surrounding 18 factories), a DI class is not how the Nx plugin API is called.\nexport function createCiTarget(\n perProjectValidation: string[],\n architectureEnabled: boolean,\n): TargetConfiguration {\n const dependsOn: string[] = ['lint', 'build', 'test', ...perProjectValidation];\n if (architectureEnabled) {\n dependsOn.push('architecture:validate-complete');\n }\n return {\n executor: 'nx:noop',\n cache: true,\n // The branch is part of what `ci` asserts, because the rules it aggregates can be switched off by\n // turnOffRuleWhileOnBranch. Its own cache entry is a noop, but a `ci` hash that ignores the branch\n // is a green claim about a branch that was never checked. See branch-identity-inputs.ts.\n inputs: ['default', ...BRANCH_IDENTITY_INPUTS],\n dependsOn,\n metadata: {\n technologies: ['nx'],\n description:\n 'Run all CI checks: lint, build, test, and validation (Gradle-style composite target)',\n },\n };\n}\n\n/** Emergency profile: retain compilation/typechecking and tests, schedule no lint or policy target. */\n// webpieces-disable no-function-outside-class -- Nx inference target factory, matching createCiTarget and invoked by the module-scope plugin callback.\nexport function createHotfixCiTarget(): TargetConfiguration {\n return {\n executor: 'nx:noop',\n cache: true,\n inputs: ['default', ...BRANCH_IDENTITY_INPUTS],\n dependsOn: ['build', 'test'],\n metadata: {\n technologies: ['nx'],\n description: 'Hotfix CI: compilation/typechecking and tests only; lint and Webpieces validators bypassed',\n },\n };\n}\n\nfunction createHelpTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:help',\n cache: false, // Never cache - always show help output\n metadata: {\n technologies: ['nx'],\n description: 'Display help for @webpieces/nx-webpieces-rules commands and targets',\n },\n };\n}\n\n/**\n * Create per-project circular dependency checking target.\n *\n * Uses the `validate-no-file-import-cycles` executor (which bundles madge as a\n * dependency) rather than a runtime `npx madge` fetch. The executor reads\n * webpieces.config.json so the gate can be turned on/off (`mode`) and\n * time-boxed (`turnOffRuleUntilEpoch`) like every other webpieces rule.\n *\n * Note `projectRoot` is intentionally unused now — the executor derives the\n * project root from the Nx context — but the param is kept for call-site\n * symmetry with the rest of the per-project target factories.\n */\nfunction createCircularDepsTarget(_projectRoot: string, _targetName: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-no-file-import-cycles',\n cache: true,\n // BRANCH_IDENTITY_INPUTS: this gate honors turnOffRuleWhileOnBranch, and it is CACHED, so without\n // the branch in its hash a hatched green replays onto branches the hatch never covered.\n inputs: ['default', ...BRANCH_IDENTITY_INPUTS],\n outputs: [] as string[],\n metadata: {\n technologies: ['madge'],\n description: 'Check for circular file-import dependencies using madge',\n },\n };\n}\n\n/**\n * Check if a project should be excluded based on patterns\n */\nfunction isExcluded(projectRoot: string, excludePatterns: string[]): boolean {\n if (excludePatterns.length === 0) {\n return false;\n }\n\n // Simple glob matching (could be enhanced with minimatch if needed)\n return excludePatterns.some((pattern: string) => {\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/\\*\\*/g, '.*') // ** matches any path\n .replace(/\\*/g, '[^/]*'); // * matches any string except /\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(projectRoot);\n });\n}\n\n/**\n * Export plugin as default for Nx\n */\nexport default { createNodesV2 };\n"]}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unified Nx Inference Plugin for @webpieces/nx-webpieces-rules\n *\n * This plugin automatically creates targets for:\n * 1. Workspace-level architecture validation (generate, visualize, validate-*)\n * 2. Per-project circular dependency checking\n * 3. Per-project API documents, opted into with a TAG: `generate:openapi` infers `openapi-generate`,\n * `generate:openapi-components` infers `openapi-components-generate` (a DTO library's\n * components.openapi.json), `generate:docs-site` infers `openapi-generate` + `docs-generate`\n * (see generate-targets.ts)\n *\n * Install with: nx add @webpieces/nx-webpieces-rules\n *\n * Usage:\n * Add to nx.json plugins array:\n * {\n * \"plugins\": [\"@webpieces/nx-webpieces-rules\"]\n * }\n *\n * Then all targets appear automatically without manual project.json configuration.\n */\n\nimport { dirname, join } from 'path';\nimport { existsSync } from 'fs';\nimport type {\n CreateNodesV2,\n CreateNodesContextV2,\n CreateNodesResultV2,\n CreateNodesResult,\n TargetConfiguration,\n} from '@nx/devkit';\nimport {\n createVisualizeRuntimeTarget,\n createValidateRuntimeArchitectureTarget,\n} from './runtime-targets';\nimport { BRANCH_IDENTITY_INPUTS } from './branch-identity-inputs';\nimport { ValidationTargets } from './validation-targets';\nimport { createDiGraphGenerateTarget } from './di-graph-targets';\nimport { GenerateTargets, RawProjectJson, RawProjectJsonReader } from './generate-targets';\nimport { RulesTarget } from './rules-target';\n\n/**\n * Circular dependency checking options\n */\nexport interface CircularDepsOptions {\n enabled?: boolean;\n targetName?: string;\n excludePatterns?: string[];\n}\n\n/**\n * Validation options for architecture checks\n */\nexport interface ValidationOptions {\n noCycles?: boolean;\n architectureUnchanged?: boolean;\n validatePackageJson?: boolean;\n validateNewMethods?: boolean;\n validateModifiedMethods?: boolean;\n validateModifiedFiles?: boolean;\n validateVersionsLocked?: boolean;\n validateTsInSrc?: boolean;\n validateNxWiring?: boolean;\n runtimeArchitecture?: boolean;\n validateApiRelations?: boolean;\n validateApiLibTag?: boolean;\n diGraph?: boolean;\n newMethodsMaxLines?: number;\n modifiedAndNewMethodsMaxLines?: number;\n modifiedFilesMaxLines?: number;\n /**\n * Validation mode for method/file size limits:\n * - STRICT: All limits enforced, disable comments ignored\n * - NORMAL: Limits enforced, disable comments with dates work\n * - OFF: Skip size validations entirely (for fast iteration)\n */\n validationMode?: 'STRICT' | 'NORMAL' | 'OFF';\n}\n\n/**\n * Feature flags for workspace targets\n */\nexport interface FeatureOptions {\n generate?: boolean;\n visualize?: boolean;\n visualizeRuntime?: boolean;\n}\n\n/**\n * Workspace-level configuration options\n */\nexport interface WorkspaceOptions {\n enabled?: boolean;\n targetPrefix?: string;\n graphPath?: string;\n validations?: ValidationOptions;\n features?: FeatureOptions;\n}\n\n/**\n * Configuration for @webpieces/nx-webpieces-rules Nx plugin\n */\nexport interface ArchitecturePluginOptions {\n circularDeps?: CircularDepsOptions;\n workspace?: WorkspaceOptions;\n}\n\nconst DEFAULT_OPTIONS: Required<ArchitecturePluginOptions> = {\n circularDeps: {\n enabled: true,\n targetName: 'validate-no-file-import-cycles',\n excludePatterns: [],\n },\n workspace: {\n enabled: true,\n targetPrefix: 'arch:',\n graphPath: 'architecture/dependencies.json',\n validations: {\n noCycles: true,\n architectureUnchanged: true,\n validatePackageJson: true,\n validateNewMethods: true,\n validateModifiedMethods: true,\n validateModifiedFiles: true,\n validateVersionsLocked: true,\n validateTsInSrc: true,\n validateNxWiring: true,\n runtimeArchitecture: true,\n validateApiRelations: true,\n validateApiLibTag: true,\n diGraph: true,\n newMethodsMaxLines: 30,\n modifiedAndNewMethodsMaxLines: 80,\n modifiedFilesMaxLines: 900,\n validationMode: 'NORMAL',\n },\n features: {\n generate: true,\n visualize: true,\n visualizeRuntime: true,\n },\n },\n};\n\nfunction normalizeOptions(\n options: ArchitecturePluginOptions | undefined,\n): Required<ArchitecturePluginOptions> {\n const circularDeps = {\n ...DEFAULT_OPTIONS.circularDeps,\n ...options?.circularDeps,\n };\n\n const workspace = {\n ...DEFAULT_OPTIONS.workspace,\n ...options?.workspace,\n validations: {\n ...DEFAULT_OPTIONS.workspace.validations,\n ...options?.workspace?.validations,\n },\n features: {\n ...DEFAULT_OPTIONS.workspace.features,\n ...options?.workspace?.features,\n },\n };\n\n return {\n circularDeps,\n workspace,\n } as Required<ArchitecturePluginOptions>;\n}\n\nasync function createNodesFunction(\n projectFiles: readonly string[],\n options: ArchitecturePluginOptions | undefined,\n context: CreateNodesContextV2,\n): Promise<CreateNodesResultV2> {\n const opts = normalizeOptions(options);\n const results: CreateNodesResultV2 = [];\n\n // Add workspace-level architecture targets\n addArchitectureProject(results, projectFiles, opts, context);\n\n // One root policy target. webpieces.config.json is not a shared input of every product project;\n // this virtual project is its sole Nx owner and the gate runs it before affected CI.\n // Add per-project targets (circular-deps, ci, di-graph)\n addPerProjectTargets(results, projectFiles, opts, context);\n\n // Append the virtual root project after concrete projects so callers that select the first result\n // for a project.json still receive that project's inferred targets.\n new RulesTarget().add(results, projectFiles);\n\n return results;\n}\n\nfunction addArchitectureProject(\n results: CreateNodesResultV2,\n projectFiles: readonly string[],\n opts: Required<ArchitecturePluginOptions>,\n context: CreateNodesContextV2,\n): void {\n if (!opts.workspace.enabled) return;\n\n const archDirPath = join(context.workspaceRoot, 'architecture');\n if (!existsSync(archDirPath)) return;\n\n const workspaceTargets = createWorkspaceTargetsWithoutPrefix(opts);\n if (Object.keys(workspaceTargets).length === 0) return;\n\n const result: CreateNodesResult = {\n projects: {\n architecture: {\n name: 'architecture',\n root: 'architecture',\n targets: workspaceTargets,\n },\n },\n };\n\n const firstProjectFile = projectFiles[0];\n if (firstProjectFile) {\n results.push([firstProjectFile, result] as const);\n }\n}\n\n\n// A project sits inside a NESTED git repo (e.g. a clone under repositories/) when any of its\n// ancestor dirs — up to but NOT including the workspace root — contains a `.git`. Such projects are\n// separate repos, not part of THIS workspace's graph, so they must not get inferred targets (that is\n// what drags foreign clones into `nx affected`). Same repo-boundary signal the AI guards use.\nexport function isInsideNestedGitRepo(workspaceRoot: string, projectRoot: string): boolean {\n let dir = projectRoot;\n while (dir && dir !== '.' && dir !== '/') {\n if (existsSync(join(workspaceRoot, dir, '.git'))) return true;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return false;\n}\n\nfunction addPerProjectTargets(\n results: CreateNodesResultV2,\n projectFiles: readonly string[],\n opts: Required<ArchitecturePluginOptions>,\n context: CreateNodesContextV2,\n): void {\n // Track processed project roots to avoid duplicates when both files exist\n const processedRoots = new Set<string>();\n\n for (const projectFile of projectFiles) {\n const isProjectJson = projectFile.endsWith('project.json');\n const isPackageJson = projectFile.endsWith('package.json');\n\n if (!isProjectJson && !isPackageJson) continue;\n\n const projectRoot = dirname(projectFile);\n\n // Skip root (workspace manifest, not a project)\n if (projectRoot === '.') continue;\n // The scoped root policy project declares check/ci itself. It has no product source to lint,\n // compile or test, so the ordinary per-project aggregate would recreate irrelevant fan-out.\n if (projectRoot === 'rules') continue;\n\n // Skip projects inside a nested git repo (vendored clones under repositories/): they are\n // separate repos and must not be swept into this workspace's `nx affected` graph.\n if (isInsideNestedGitRepo(context.workspaceRoot, projectRoot)) continue;\n\n // Skip if we've already processed this project root\n if (processedRoots.has(projectRoot)) continue;\n\n // For package.json, skip if project.json also exists in same directory\n // (prefer project.json - it will be processed separately)\n if (isPackageJson) {\n const projectJsonPath = join(context.workspaceRoot, projectRoot, 'project.json');\n if (existsSync(projectJsonPath)) continue;\n }\n\n processedRoots.add(projectRoot);\n\n const architectureEnabled =\n opts.workspace.enabled === true &&\n existsSync(join(context.workspaceRoot, 'architecture'));\n const targets = buildPerProjectTargets(\n isProjectJson,\n projectRoot,\n opts,\n architectureEnabled,\n isProjectJson ? new RawProjectJsonReader().read(context.workspaceRoot, projectFile, projectRoot) : undefined,\n );\n\n if (Object.keys(targets).length === 0) continue;\n\n const result: CreateNodesResult = {\n projects: {\n [projectRoot]: {\n targets,\n },\n },\n };\n\n results.push([projectFile, result] as const);\n }\n}\n\n/**\n * Build the target map for one project. Most targets are project.json-only\n * (package.json-only projects may not have TypeScript source); `ci` goes on all.\n */\n// webpieces-disable no-function-outside-class -- Nx requires its inference callback and target-map assembly at module scope; this existing functional plugin is invoked by Nx, not DI.\nfunction buildPerProjectTargets(\n isProjectJson: boolean,\n projectRoot: string,\n opts: Required<ArchitecturePluginOptions>,\n architectureEnabled: boolean,\n rawProject: RawProjectJson | undefined,\n): Record<string, TargetConfiguration> {\n const targets: Record<string, TargetConfiguration> = {};\n\n // Per-project validation gates that `ci` must depend on. Collected as they are added\n // so `ci` references only gates that actually exist on THIS project (a package.json-only\n // project has none).\n const validationTargets: string[] = [];\n\n // Add circular-deps target ONLY for project.json projects\n if (isProjectJson && opts.circularDeps.enabled) {\n if (!isExcluded(projectRoot, opts.circularDeps.excludePatterns!)) {\n const targetName = opts.circularDeps.targetName!;\n targets[targetName] = createCircularDepsTarget(projectRoot, targetName);\n validationTargets.push(targetName);\n }\n }\n\n // Per-project DI design DAG: regenerate design.json/design.md/design.html on every build.\n //\n // `di-graph-generate` is itself pushed onto validationTargets so `ci` still RUNS it — it used to ride\n // in only as the `dependsOn` of the deleted `validate-di-graph-unchanged` gate. There is no staleness\n // gate here any more: \"the regenerated design files are committed\" is now one repo-wide check in\n // `wp-review-upsert-pr` (see di-graph-targets.ts for why the per-project gate could not work).\n if (isProjectJson && opts.workspace.validations!.diGraph) {\n targets['di-graph-generate'] = createDiGraphGenerateTarget();\n validationTargets.push('di-graph-generate');\n }\n\n // API documents, opted into with a TAG (generate:openapi / generate:docs-site). An untagged project\n // costs this one in-memory tag check. They ride ci like every other build step — generation is\n // ordinary BUILD work, not a side channel (#1021).\n if (rawProject !== undefined) {\n const generated = new GenerateTargets(projectRoot, rawProject).infer();\n for (const [name, target] of Object.entries(generated)) {\n targets[name] = target;\n validationTargets.push(name);\n }\n }\n\n // Add ci target to ALL projects (both project.json and package.json). ci aggregates\n // lint + build + test + the validation gates that formerly rode on the compile\n // executor's targetDefaults, so a bare `build` stays a fast compile-only step.\n targets['ci'] = createCiTarget(validationTargets, architectureEnabled);\n targets['hotfix-ci'] = createHotfixCiTarget();\n\n return targets;\n}\n\n/**\n * Nx V2 Inference Plugin\n * Matches project.json and package.json files to create targets\n */\nexport const createNodesV2: CreateNodesV2<ArchitecturePluginOptions> = [\n // Pattern to match project.json and package.json files\n '**/{project,package}.json',\n\n // Inference function\n createNodesFunction,\n];\n\n/**\n * Build list of enabled validation target names for validate-complete dependency chain\n */\nfunction buildValidationTargetsList(\n validations: Required<ArchitecturePluginOptions>['workspace']['validations'],\n): string[] {\n const targets: string[] = [];\n if (validations!.noCycles) targets.push('validate-no-architecture-cycles');\n if (validations!.architectureUnchanged) targets.push('validate-architecture-unchanged');\n if (validations!.validatePackageJson) targets.push('validate-packagejson');\n // Use combined validate-code instead of 3 separate targets\n if (\n validations!.validateNewMethods ||\n validations!.validateModifiedMethods ||\n validations!.validateModifiedFiles\n ) {\n targets.push('validate-code');\n }\n if (validations!.validateVersionsLocked) targets.push('validate-versions-locked');\n if (validations!.validateTsInSrc) targets.push('validate-ts-in-src');\n if (validations!.validateNxWiring) targets.push('validate-nx-wiring');\n if (validations!.runtimeArchitecture) targets.push('validate-runtime-architecture');\n if (validations!.validateApiRelations) targets.push('validate-api-relations');\n if (validations!.validateApiLibTag) targets.push('validate-api-lib-tag');\n return targets;\n}\n\n/**\n * Create workspace-level architecture validation targets WITHOUT prefix\n * Used for virtual 'architecture' project\n */\nfunction createWorkspaceTargetsWithoutPrefix(\n opts: Required<ArchitecturePluginOptions>,\n): Record<string, TargetConfiguration> {\n const targets: Record<string, TargetConfiguration> = {};\n const graphPath = opts.workspace.graphPath!;\n const validations = opts.workspace.validations!;\n // One ValidationTargets instance, injected below to build each target config.\n const targetFactory = new ValidationTargets();\n\n // Add help target (always available)\n targets['help'] = createHelpTarget();\n\n if (opts.workspace.features!.generate) {\n targets['generate'] = createGenerateTarget(graphPath);\n }\n if (opts.workspace.features!.visualize) {\n targets['visualize'] = createVisualizeTargetWithoutPrefix(graphPath);\n }\n if (opts.workspace.features!.visualizeRuntime) {\n targets['visualize-runtime'] = createVisualizeRuntimeTarget();\n }\n if (validations.noCycles) {\n targets['validate-no-architecture-cycles'] = targetFactory.noCycles();\n }\n if (validations.architectureUnchanged) {\n targets['validate-architecture-unchanged'] = createValidateUnchangedTarget(graphPath);\n }\n if (validations.validatePackageJson) {\n targets['validate-packagejson'] = targetFactory.packageJson();\n }\n // Always available (cheap; success when a repo has no checklists). Kept out of the validate-complete /\n // ci aggregate so it does not change existing gate behavior — consumers point a required check at it.\n targets['validate-checklist-docs'] = targetFactory.checklistDocs();\n // Use combined validate-code instead of 3 separate targets\n // Options come from webpieces.config.json at the workspace root\n // (loaded via @webpieces/rules-config; same source of truth as @webpieces/ai-hook-rules)\n if (\n validations.validateNewMethods ||\n validations.validateModifiedMethods ||\n validations.validateModifiedFiles\n ) {\n targets['validate-code'] = targetFactory.code();\n }\n if (validations.validateVersionsLocked) {\n targets['validate-versions-locked'] = targetFactory.versionsLocked();\n }\n if (validations.validateTsInSrc) {\n targets['validate-ts-in-src'] = targetFactory.tsInSrc();\n }\n if (validations.validateNxWiring) {\n targets['validate-nx-wiring'] = targetFactory.nxWiring();\n }\n if (validations.runtimeArchitecture) {\n targets['validate-runtime-architecture'] = createValidateRuntimeArchitectureTarget();\n }\n if (validations.validateApiRelations) {\n targets['validate-api-relations'] = targetFactory.apiRelations();\n }\n if (validations.validateApiLibTag) {\n targets['validate-api-lib-tag'] = targetFactory.apiLibTag();\n }\n\n // Add validate-complete target that runs all enabled validations\n const validationTargets = buildValidationTargetsList(validations);\n if (validationTargets.length > 0) {\n targets['validate-complete'] = createValidateCompleteTarget(validationTargets);\n }\n\n return targets;\n}\n\nfunction createGenerateTarget(graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:generate',\n cache: false,\n outputs: [\n '{workspaceRoot}/architecture/dependencies.json',\n '{workspaceRoot}/architecture/dependencies.html',\n '{workspaceRoot}/architecture/apis',\n '{workspaceRoot}/architecture/runtime-dependencies.json',\n ],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description:\n 'Generate the architecture dependency graph (+ clickable dependencies.html) and the runtime microservice graph',\n },\n };\n}\n\nfunction createVisualizeTargetWithoutPrefix(graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:visualize',\n dependsOn: ['generate'],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Generate visual representations of the architecture graph',\n },\n };\n}\n\nfunction createValidateUnchangedTarget(graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-architecture-unchanged',\n cache: false,\n inputs: ['default', '{workspaceRoot}/architecture/dependencies.json'],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Validate the architecture matches the saved blessed graph',\n },\n };\n}\n\nfunction createValidateNewMethodsTarget(\n maxLines: number,\n mode: 'STRICT' | 'NORMAL' | 'OFF',\n): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-new-methods',\n cache: false, // Don't cache - depends on git state\n inputs: ['default'],\n options: { max: maxLines, mode },\n metadata: {\n technologies: ['nx'],\n description: `Validate new methods do not exceed ${maxLines} lines (only runs in affected mode)`,\n },\n };\n}\n\nfunction createValidateModifiedMethodsTarget(\n maxLines: number,\n mode: 'STRICT' | 'NORMAL' | 'OFF',\n): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-modified-methods',\n cache: false, // Don't cache - depends on git state\n inputs: ['default'],\n options: { max: maxLines, mode },\n metadata: {\n technologies: ['nx'],\n description: `Validate new and modified methods do not exceed ${maxLines} lines (encourages gradual cleanup)`,\n },\n };\n}\n\nfunction createValidateModifiedFilesTarget(\n maxLines: number,\n mode: 'STRICT' | 'NORMAL' | 'OFF',\n): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-modified-files',\n cache: false, // Don't cache - depends on git state\n inputs: ['default'],\n options: { max: maxLines, mode },\n metadata: {\n technologies: ['nx'],\n description: `Validate modified files do not exceed ${maxLines} lines (encourages keeping files small)`,\n },\n };\n}\n\nfunction createValidateCompleteTarget(validationTargets: string[]): TargetConfiguration {\n return {\n executor: 'nx:noop',\n cache: true,\n dependsOn: validationTargets,\n metadata: {\n technologies: ['nx'],\n description: 'Run all architecture validations (cycles, unchanged, package.json, code rules)',\n },\n };\n}\n\n/**\n * Create per-project ci target - Gradle-style composite target\n * Composite CI target: runs lint, build, test, and every validation gate.\n *\n * Validation (architecture graph completeness, per-project file-import cycles, DI-graph\n * unchanged) lives HERE, not on the build/compile target. That keeps `nx build` a fast\n * compile-only step for local iteration while `nx ci` is the full gate the PR check runs.\n *\n * The per-project gates are passed in because they exist only on project.json projects;\n * `architecture:validate-complete` is a cross-project dep added only when the workspace\n * `architecture` project exists.\n *\n * NOTE: Type checking is done by the build target (@nx/js:tsc) during compilation.\n */\n// webpieces-disable no-function-outside-class -- Nx inference plugin: createNodes invokes these as module-scope target factories; the entire plugin is intentionally functional (matching the surrounding 18 factories), a DI class is not how the Nx plugin API is called.\nexport function createCiTarget(\n perProjectValidation: string[],\n architectureEnabled: boolean,\n): TargetConfiguration {\n const dependsOn: string[] = ['lint', 'build', 'test', ...perProjectValidation];\n if (architectureEnabled) {\n dependsOn.push('architecture:validate-complete');\n }\n return {\n executor: 'nx:noop',\n cache: true,\n // The branch is part of what `ci` asserts, because the rules it aggregates can be switched off by\n // turnOffRuleWhileOnBranch. Its own cache entry is a noop, but a `ci` hash that ignores the branch\n // is a green claim about a branch that was never checked. See branch-identity-inputs.ts.\n inputs: ['default', ...BRANCH_IDENTITY_INPUTS],\n dependsOn,\n metadata: {\n technologies: ['nx'],\n description:\n 'Run all CI checks: lint, build, test, and validation (Gradle-style composite target)',\n },\n };\n}\n\n/** Emergency profile: retain compilation/typechecking and tests, schedule no lint or policy target. */\n// webpieces-disable no-function-outside-class -- Nx inference target factory, matching createCiTarget and invoked by the module-scope plugin callback.\nexport function createHotfixCiTarget(): TargetConfiguration {\n return {\n executor: 'nx:noop',\n cache: true,\n inputs: ['default', ...BRANCH_IDENTITY_INPUTS],\n dependsOn: ['build', 'test'],\n metadata: {\n technologies: ['nx'],\n description: 'Hotfix CI: compilation/typechecking and tests only; lint and Webpieces validators bypassed',\n },\n };\n}\n\nfunction createHelpTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:help',\n cache: false, // Never cache - always show help output\n metadata: {\n technologies: ['nx'],\n description: 'Display help for @webpieces/nx-webpieces-rules commands and targets',\n },\n };\n}\n\n/**\n * Create per-project circular dependency checking target.\n *\n * Uses the `validate-no-file-import-cycles` executor (which bundles madge as a\n * dependency) rather than a runtime `npx madge` fetch. The executor reads\n * webpieces.config.json so the gate can be turned on/off (`mode`) and\n * time-boxed (`turnOffRuleUntilEpoch`) like every other webpieces rule.\n *\n * Note `projectRoot` is intentionally unused now — the executor derives the\n * project root from the Nx context — but the param is kept for call-site\n * symmetry with the rest of the per-project target factories.\n */\nfunction createCircularDepsTarget(_projectRoot: string, _targetName: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-no-file-import-cycles',\n cache: true,\n // BRANCH_IDENTITY_INPUTS: this gate honors turnOffRuleWhileOnBranch, and it is CACHED, so without\n // the branch in its hash a hatched green replays onto branches the hatch never covered.\n inputs: ['default', ...BRANCH_IDENTITY_INPUTS],\n outputs: [] as string[],\n metadata: {\n technologies: ['madge'],\n description: 'Check for circular file-import dependencies using madge',\n },\n };\n}\n\n/**\n * Check if a project should be excluded based on patterns\n */\nfunction isExcluded(projectRoot: string, excludePatterns: string[]): boolean {\n if (excludePatterns.length === 0) {\n return false;\n }\n\n // Simple glob matching (could be enhanced with minimatch if needed)\n return excludePatterns.some((pattern: string) => {\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/\\*\\*/g, '.*') // ** matches any path\n .replace(/\\*/g, '[^/]*'); // * matches any string except /\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(projectRoot);\n });\n}\n\n/**\n * Export plugin as default for Nx\n */\nexport default { createNodesV2 };\n"]}
@@ -0,0 +1,5 @@
1
+ import type { CreateNodesResultV2 } from '@nx/devkit';
2
+ /** Adds the single virtual owner for root webpieces policy when a source checkout has no declaration. */
3
+ export declare class RulesTarget {
4
+ add(results: CreateNodesResultV2, projectFiles: readonly string[]): void;
5
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RulesTarget = void 0;
4
+ /** Adds the single virtual owner for root webpieces policy when a source checkout has no declaration. */
5
+ class RulesTarget {
6
+ add(results, projectFiles) {
7
+ // A source checkout carries the declaration explicitly so it can exercise the target before
8
+ // this plugin release exists in node_modules. Once installed, that declaration wins.
9
+ if (projectFiles.includes('rules/project.json'))
10
+ return;
11
+ const firstProjectFile = projectFiles[0];
12
+ if (!firstProjectFile)
13
+ return;
14
+ results.push([firstProjectFile, {
15
+ projects: {
16
+ rules: {
17
+ name: 'rules',
18
+ root: '.',
19
+ tags: ['type:tooling', 'role:app', 'framework:node'],
20
+ targets: {
21
+ check: {
22
+ executor: '@webpieces/nx-webpieces-rules:validate-rules-config',
23
+ cache: true,
24
+ inputs: ['rulesConfig'],
25
+ metadata: {
26
+ technologies: ['nx'],
27
+ description: 'Validate the root webpieces.config.json policy declaration',
28
+ },
29
+ },
30
+ },
31
+ },
32
+ },
33
+ }]);
34
+ }
35
+ }
36
+ exports.RulesTarget = RulesTarget;
37
+ //# sourceMappingURL=rules-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules-target.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/rules-target.ts"],"names":[],"mappings":";;;AAEA,yGAAyG;AACzG,MAAa,WAAW;IACpB,GAAG,CAAC,OAA4B,EAAE,YAA+B;QAC7D,4FAA4F;QAC5F,qFAAqF;QACrF,IAAI,YAAY,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAAE,OAAO;QACxD,MAAM,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE;gBAC5B,QAAQ,EAAE;oBACN,KAAK,EAAE;wBACH,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,GAAG;wBACT,IAAI,EAAE,CAAC,cAAc,EAAE,UAAU,EAAE,gBAAgB,CAAC;wBACpD,OAAO,EAAE;4BACL,KAAK,EAAE;gCACH,QAAQ,EAAE,qDAAqD;gCAC/D,KAAK,EAAE,IAAI;gCACX,MAAM,EAAE,CAAC,aAAa,CAAC;gCACvB,QAAQ,EAAE;oCACN,YAAY,EAAE,CAAC,IAAI,CAAC;oCACpB,WAAW,EAAE,4DAA4D;iCAC5E;6BACJ;yBACJ;qBACJ;iBACJ;aACJ,CAAU,CAAC,CAAC;IACjB,CAAC;CACJ;AA5BD,kCA4BC","sourcesContent":["import type { CreateNodesResultV2 } from '@nx/devkit';\n\n/** Adds the single virtual owner for root webpieces policy when a source checkout has no declaration. */\nexport class RulesTarget {\n add(results: CreateNodesResultV2, projectFiles: readonly string[]): void {\n // A source checkout carries the declaration explicitly so it can exercise the target before\n // this plugin release exists in node_modules. Once installed, that declaration wins.\n if (projectFiles.includes('rules/project.json')) return;\n const firstProjectFile = projectFiles[0];\n if (!firstProjectFile) return;\n results.push([firstProjectFile, {\n projects: {\n rules: {\n name: 'rules',\n root: '.',\n tags: ['type:tooling', 'role:app', 'framework:node'],\n targets: {\n check: {\n executor: '@webpieces/nx-webpieces-rules:validate-rules-config',\n cache: true,\n inputs: ['rulesConfig'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate the root webpieces.config.json policy declaration',\n },\n },\n },\n },\n },\n }] as const);\n }\n}\n"]}