@webpieces/nx-webpieces-rules 0.2.127 → 0.3.129

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
@@ -119,6 +119,11 @@
119
119
  "implementation": "./src/executors/validate-eslint-sync/executor",
120
120
  "schema": "./src/executors/validate-eslint-sync/schema.json",
121
121
  "description": "Validate that workspace and template eslint.webpieces.config.mjs files have identical rules"
122
+ },
123
+ "validate-nx-wiring": {
124
+ "implementation": "./src/executors/validate-nx-wiring/executor",
125
+ "schema": "./src/executors/validate-nx-wiring/schema.json",
126
+ "description": "Validate the webpieces validators are wired into the build via nx.json targetDefaults dependsOn"
122
127
  }
123
128
  }
124
129
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/nx-webpieces-rules",
3
- "version": "0.2.127",
3
+ "version": "0.3.129",
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,10 +18,10 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@webpieces/ai-hook-rules": "0.2.127",
22
- "@webpieces/code-rules": "0.2.127",
23
- "@webpieces/eslint-rules": "0.2.127",
24
- "@webpieces/rules-config": "0.2.127"
21
+ "@webpieces/ai-hook-rules": "0.3.129",
22
+ "@webpieces/code-rules": "0.3.129",
23
+ "@webpieces/eslint-rules": "0.3.129",
24
+ "@webpieces/rules-config": "0.3.129"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@nx/devkit": ">=18.0.0"
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Validate Nx Wiring Executor
3
+ *
4
+ * Enforces that the webpieces validators are actually wired into the build in
5
+ * nx.json. The plugin auto-infers the validator targets (architecture:validate-complete,
6
+ * per-project validate-no-file-import-cycles), but the load-bearing connection that
7
+ * makes a build DEPEND on them lives in each repo's hand-edited nx.json:
8
+ *
9
+ * "@nx/js:tsc": {
10
+ * "dependsOn": ["architecture:validate-complete", "validate-no-file-import-cycles", "^build"]
11
+ * }
12
+ *
13
+ * If that dependsOn is stripped, the validators exist but never run and a build stays
14
+ * green while validating nothing. This executor fails when the wiring is missing.
15
+ *
16
+ * Conservative by design: it only REQUIRES wiring on compile executors that are
17
+ * actually used somewhere in the project graph (@nx/js:tsc, @angular/build:application).
18
+ * A repo that uses neither has nothing to gate and passes.
19
+ *
20
+ * Disable per validator in webpieces.config.json (rules[name].mode="OFF"), but the
21
+ * wiring itself is governed by the "nx-wiring" rule (default on) so the build gate stays.
22
+ *
23
+ * Usage: nx run architecture:validate-nx-wiring
24
+ */
25
+ import type { ExecutorContext } from '@nx/devkit';
26
+ export interface ValidateNxWiringOptions {
27
+ requiredDeps?: string[];
28
+ compileExecutors?: string[];
29
+ }
30
+ export interface ExecutorResult {
31
+ success: boolean;
32
+ }
33
+ export default function runExecutor(options: ValidateNxWiringOptions, context: ExecutorContext): Promise<ExecutorResult>;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * Validate Nx Wiring Executor
4
+ *
5
+ * Enforces that the webpieces validators are actually wired into the build in
6
+ * nx.json. The plugin auto-infers the validator targets (architecture:validate-complete,
7
+ * per-project validate-no-file-import-cycles), but the load-bearing connection that
8
+ * makes a build DEPEND on them lives in each repo's hand-edited nx.json:
9
+ *
10
+ * "@nx/js:tsc": {
11
+ * "dependsOn": ["architecture:validate-complete", "validate-no-file-import-cycles", "^build"]
12
+ * }
13
+ *
14
+ * If that dependsOn is stripped, the validators exist but never run and a build stays
15
+ * green while validating nothing. This executor fails when the wiring is missing.
16
+ *
17
+ * Conservative by design: it only REQUIRES wiring on compile executors that are
18
+ * actually used somewhere in the project graph (@nx/js:tsc, @angular/build:application).
19
+ * A repo that uses neither has nothing to gate and passes.
20
+ *
21
+ * Disable per validator in webpieces.config.json (rules[name].mode="OFF"), but the
22
+ * wiring itself is governed by the "nx-wiring" rule (default on) so the build gate stays.
23
+ *
24
+ * Usage: nx run architecture:validate-nx-wiring
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.default = runExecutor;
28
+ const tslib_1 = require("tslib");
29
+ const devkit_1 = require("@nx/devkit");
30
+ const rules_config_1 = require("@webpieces/rules-config");
31
+ const fs = tslib_1.__importStar(require("fs"));
32
+ const path = tslib_1.__importStar(require("path"));
33
+ const DEFAULT_REQUIRED_DEPS = [
34
+ 'architecture:validate-complete',
35
+ 'validate-no-file-import-cycles',
36
+ ];
37
+ const DEFAULT_COMPILE_EXECUTORS = [
38
+ '@nx/js:tsc',
39
+ '@angular/build:application',
40
+ ];
41
+ class WiringProblem {
42
+ constructor(executorName, missing, found) {
43
+ this.executorName = executorName;
44
+ this.missing = missing;
45
+ this.found = found;
46
+ }
47
+ }
48
+ function readTargetDefaults(workspaceRoot) {
49
+ const nxJsonPath = path.join(workspaceRoot, 'nx.json');
50
+ if (!fs.existsSync(nxJsonPath))
51
+ return {};
52
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
53
+ try {
54
+ const raw = fs.readFileSync(nxJsonPath, 'utf8');
55
+ const parsed = JSON.parse(raw);
56
+ return parsed.targetDefaults ?? {};
57
+ // webpieces-disable catch-error-pattern -- malformed nx.json fails open so the check does not crash the build
58
+ }
59
+ catch (err) {
60
+ //const error = toError(err); -- malformed nx.json fails open
61
+ void err;
62
+ return {};
63
+ }
64
+ }
65
+ async function findCompileExecutorsInUse(compileExecutors) {
66
+ const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
67
+ const projectsConfig = (0, devkit_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
68
+ const known = new Set(compileExecutors);
69
+ const inUse = new Set();
70
+ for (const cfg of Object.values(projectsConfig.projects)) {
71
+ const targets = cfg.targets ?? {};
72
+ for (const target of Object.values(targets)) {
73
+ const executorName = target.executor;
74
+ if (executorName && known.has(executorName)) {
75
+ inUse.add(executorName);
76
+ }
77
+ }
78
+ }
79
+ return inUse;
80
+ }
81
+ function findProblems(relevantExecutors, targetDefaults, requiredDeps) {
82
+ const problems = [];
83
+ for (const executorName of relevantExecutors) {
84
+ const entry = targetDefaults[executorName];
85
+ const dependsOn = entry?.dependsOn ?? [];
86
+ const missing = requiredDeps.filter((dep) => !dependsOn.includes(dep));
87
+ if (missing.length > 0) {
88
+ problems.push(new WiringProblem(executorName, missing, dependsOn));
89
+ }
90
+ }
91
+ return problems;
92
+ }
93
+ function reportFailure(problems, requiredDeps) {
94
+ console.error('\n❌ webpieces validators are not wired into your build.\n');
95
+ console.error('The validators exist but no build depends on them, so they never run.');
96
+ console.error('Add the missing dependsOn entries to nx.json targetDefaults:\n');
97
+ const depsList = requiredDeps.map((dep) => `"${dep}"`).join(', ');
98
+ for (const problem of problems) {
99
+ const missingList = problem.missing.map((dep) => `"${dep}"`).join(', ');
100
+ console.error(` "${problem.executorName}": {`);
101
+ console.error(` "dependsOn": [${depsList}, "^build"]`);
102
+ console.error(' }');
103
+ console.error(` missing: ${missingList}\n`);
104
+ }
105
+ console.error('To disable an INDIVIDUAL validator, set rules[name].mode="OFF" in');
106
+ console.error('webpieces.config.json — but the wiring above must stay installed so the');
107
+ console.error('build gate keeps working. To turn this wiring check itself off, set');
108
+ console.error('rules["nx-wiring"].mode="OFF" in webpieces.config.json.\n');
109
+ }
110
+ async function runExecutor(options, context) {
111
+ const shared = (0, rules_config_1.loadConfig)(context.root);
112
+ const rule = shared.rules.get('nx-wiring');
113
+ if (rule && rule.isOff) {
114
+ console.log('\n⏭️ Skipping validate-nx-wiring (mode: OFF)\n');
115
+ return { success: true };
116
+ }
117
+ const requiredDeps = options.requiredDeps ?? DEFAULT_REQUIRED_DEPS;
118
+ const compileExecutors = options.compileExecutors ?? DEFAULT_COMPILE_EXECUTORS;
119
+ console.log('\n🔌 Validating webpieces validators are wired into the build\n');
120
+ const inUse = await findCompileExecutorsInUse(compileExecutors);
121
+ const relevantExecutors = compileExecutors.filter((executorName) => inUse.has(executorName));
122
+ if (relevantExecutors.length === 0) {
123
+ console.log('✅ No known compile executors in use — nothing to gate\n');
124
+ return { success: true };
125
+ }
126
+ const targetDefaults = readTargetDefaults(context.root);
127
+ const problems = findProblems(relevantExecutors, targetDefaults, requiredDeps);
128
+ if (problems.length === 0) {
129
+ console.log('✅ Validators are wired into the build\n');
130
+ return { success: true };
131
+ }
132
+ reportFailure(problems, requiredDeps);
133
+ return { success: false };
134
+ }
135
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-nx-wiring/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Nx Wiring Executor\n *\n * Enforces that the webpieces validators are actually wired into the build in\n * nx.json. The plugin auto-infers the validator targets (architecture:validate-complete,\n * per-project validate-no-file-import-cycles), but the load-bearing connection that\n * makes a build DEPEND on them lives in each repo's hand-edited nx.json:\n *\n * \"@nx/js:tsc\": {\n * \"dependsOn\": [\"architecture:validate-complete\", \"validate-no-file-import-cycles\", \"^build\"]\n * }\n *\n * If that dependsOn is stripped, the validators exist but never run and a build stays\n * green while validating nothing. This executor fails when the wiring is missing.\n *\n * Conservative by design: it only REQUIRES wiring on compile executors that are\n * actually used somewhere in the project graph (@nx/js:tsc, @angular/build:application).\n * A repo that uses neither has nothing to gate and passes.\n *\n * Disable per validator in webpieces.config.json (rules[name].mode=\"OFF\"), but the\n * wiring itself is governed by the \"nx-wiring\" rule (default on) so the build gate stays.\n *\n * Usage: nx run architecture:validate-nx-wiring\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { createProjectGraphAsync, readProjectsConfigurationFromProjectGraph } from '@nx/devkit';\nimport { loadConfig } from '@webpieces/rules-config';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface ValidateNxWiringOptions {\n requiredDeps?: string[];\n compileExecutors?: string[];\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nconst DEFAULT_REQUIRED_DEPS: string[] = [\n 'architecture:validate-complete',\n 'validate-no-file-import-cycles',\n];\n\nconst DEFAULT_COMPILE_EXECUTORS: string[] = [\n '@nx/js:tsc',\n '@angular/build:application',\n];\n\nclass WiringProblem {\n executorName: string;\n missing: string[];\n found: string[];\n\n constructor(executorName: string, missing: string[], found: string[]) {\n this.executorName = executorName;\n this.missing = missing;\n this.found = found;\n }\n}\n\ninterface TargetDefaultEntry {\n dependsOn?: string[];\n}\n\ninterface RawNxJson {\n targetDefaults?: Record<string, TargetDefaultEntry>;\n}\n\nfunction readTargetDefaults(workspaceRoot: string): Record<string, TargetDefaultEntry> {\n const nxJsonPath = path.join(workspaceRoot, 'nx.json');\n if (!fs.existsSync(nxJsonPath)) return {};\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const raw = fs.readFileSync(nxJsonPath, 'utf8');\n const parsed = JSON.parse(raw) as RawNxJson;\n return parsed.targetDefaults ?? {};\n // webpieces-disable catch-error-pattern -- malformed nx.json fails open so the check does not crash the build\n } catch (err: unknown) {\n //const error = toError(err); -- malformed nx.json fails open\n void err;\n return {};\n }\n}\n\nasync function findCompileExecutorsInUse(compileExecutors: string[]): Promise<Set<string>> {\n const projectGraph = await createProjectGraphAsync();\n const projectsConfig = readProjectsConfigurationFromProjectGraph(projectGraph);\n const known = new Set(compileExecutors);\n const inUse = new Set<string>();\n for (const cfg of Object.values(projectsConfig.projects)) {\n const targets = cfg.targets ?? {};\n for (const target of Object.values(targets)) {\n const executorName = target.executor;\n if (executorName && known.has(executorName)) {\n inUse.add(executorName);\n }\n }\n }\n return inUse;\n}\n\nfunction findProblems(\n relevantExecutors: string[],\n targetDefaults: Record<string, TargetDefaultEntry>,\n requiredDeps: string[],\n): WiringProblem[] {\n const problems: WiringProblem[] = [];\n for (const executorName of relevantExecutors) {\n const entry = targetDefaults[executorName];\n const dependsOn = entry?.dependsOn ?? [];\n const missing = requiredDeps.filter((dep: string) => !dependsOn.includes(dep));\n if (missing.length > 0) {\n problems.push(new WiringProblem(executorName, missing, dependsOn));\n }\n }\n return problems;\n}\n\nfunction reportFailure(problems: WiringProblem[], requiredDeps: string[]): void {\n console.error('\\n❌ webpieces validators are not wired into your build.\\n');\n console.error('The validators exist but no build depends on them, so they never run.');\n console.error('Add the missing dependsOn entries to nx.json targetDefaults:\\n');\n const depsList = requiredDeps.map((dep: string) => `\"${dep}\"`).join(', ');\n for (const problem of problems) {\n const missingList = problem.missing.map((dep: string) => `\"${dep}\"`).join(', ');\n console.error(` \"${problem.executorName}\": {`);\n console.error(` \"dependsOn\": [${depsList}, \"^build\"]`);\n console.error(' }');\n console.error(` missing: ${missingList}\\n`);\n }\n console.error('To disable an INDIVIDUAL validator, set rules[name].mode=\"OFF\" in');\n console.error('webpieces.config.json — but the wiring above must stay installed so the');\n console.error('build gate keeps working. To turn this wiring check itself off, set');\n console.error('rules[\"nx-wiring\"].mode=\"OFF\" in webpieces.config.json.\\n');\n}\n\nexport default async function runExecutor(\n options: ValidateNxWiringOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n const shared = loadConfig(context.root);\n const rule = shared.rules.get('nx-wiring');\n if (rule && rule.isOff) {\n console.log('\\n⏭️ Skipping validate-nx-wiring (mode: OFF)\\n');\n return { success: true };\n }\n\n const requiredDeps = options.requiredDeps ?? DEFAULT_REQUIRED_DEPS;\n const compileExecutors = options.compileExecutors ?? DEFAULT_COMPILE_EXECUTORS;\n\n console.log('\\n🔌 Validating webpieces validators are wired into the build\\n');\n\n const inUse = await findCompileExecutorsInUse(compileExecutors);\n const relevantExecutors = compileExecutors.filter((executorName: string) =>\n inUse.has(executorName),\n );\n\n if (relevantExecutors.length === 0) {\n console.log('✅ No known compile executors in use — nothing to gate\\n');\n return { success: true };\n }\n\n const targetDefaults = readTargetDefaults(context.root);\n const problems = findProblems(relevantExecutors, targetDefaults, requiredDeps);\n\n if (problems.length === 0) {\n console.log('✅ Validators are wired into the build\\n');\n return { success: true };\n }\n\n reportFailure(problems, requiredDeps);\n return { success: false };\n}\n"]}
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "Validate Nx Wiring Executor",
4
+ "description": "Validates that the webpieces validators are wired into the build via nx.json targetDefaults dependsOn, so a build cannot pass while running zero validators.",
5
+ "type": "object",
6
+ "properties": {
7
+ "requiredDeps": {
8
+ "type": "array",
9
+ "items": { "type": "string" },
10
+ "description": "Target names that each compile executor's dependsOn must include. Defaults: architecture:validate-complete, validate-no-file-import-cycles."
11
+ },
12
+ "compileExecutors": {
13
+ "type": "array",
14
+ "items": { "type": "string" },
15
+ "description": "Compile executors to require wiring on, but only when actually used in the project graph. Defaults: @nx/js:tsc, @angular/build:application."
16
+ }
17
+ },
18
+ "required": []
19
+ }
@@ -3,18 +3,18 @@
3
3
  *
4
4
  * Two-layer rule:
5
5
  * Layer 1: every .ts file inside an Nx project must live under src/
6
- * (jest.config.ts at project root is the only exception)
7
6
  * Layer 2: every .ts file anywhere in the workspace must belong to some
8
7
  * Nx project. Orphan files (at workspace root or in a non-project
9
8
  * directory) fail the rule unless explicitly allowlisted.
10
9
  *
11
- * Configurable via nx.json targetDefaults:
10
+ * `excludePaths` is holistic — its bare dir names and globs exempt files
11
+ * from BOTH layers. Defaults exempt **\/*.d.ts and **\/jest.config.ts.
12
+ *
13
+ * Configurable via webpieces.config.json:
12
14
  * "validate-ts-in-src": {
13
- * "options": {
14
- * "mode": "ON",
15
- * "excludePaths": [...],
16
- * "allowedRootFiles": [...]
17
- * }
15
+ * "mode": "ON", // "OFF" disables the rule
16
+ * "excludePaths": [...], // dir names + globs, e.g. "**\/codegen.ts"
17
+ * "allowedRootFiles": [...]
18
18
  * }
19
19
  *
20
20
  * Usage: nx run architecture:validate-ts-in-src
@@ -4,18 +4,18 @@
4
4
  *
5
5
  * Two-layer rule:
6
6
  * Layer 1: every .ts file inside an Nx project must live under src/
7
- * (jest.config.ts at project root is the only exception)
8
7
  * Layer 2: every .ts file anywhere in the workspace must belong to some
9
8
  * Nx project. Orphan files (at workspace root or in a non-project
10
9
  * directory) fail the rule unless explicitly allowlisted.
11
10
  *
12
- * Configurable via nx.json targetDefaults:
11
+ * `excludePaths` is holistic — its bare dir names and globs exempt files
12
+ * from BOTH layers. Defaults exempt **\/*.d.ts and **\/jest.config.ts.
13
+ *
14
+ * Configurable via webpieces.config.json:
13
15
  * "validate-ts-in-src": {
14
- * "options": {
15
- * "mode": "ON",
16
- * "excludePaths": [...],
17
- * "allowedRootFiles": [...]
18
- * }
16
+ * "mode": "ON", // "OFF" disables the rule
17
+ * "excludePaths": [...], // dir names + globs, e.g. "**\/codegen.ts"
18
+ * "allowedRootFiles": [...]
19
19
  * }
20
20
  *
21
21
  * Usage: nx run architecture:validate-ts-in-src
@@ -30,6 +30,7 @@ const path = tslib_1.__importStar(require("path"));
30
30
  const DEFAULT_EXCLUDE_PATHS = [
31
31
  'node_modules', 'dist', '.nx', '.git',
32
32
  'architecture', 'tmp', 'scripts',
33
+ '**/*.d.ts', '**/jest.config.ts',
33
34
  ];
34
35
  const DEFAULT_ALLOWED_ROOT_FILES = ['jest.setup.ts'];
35
36
  class LayerOneViolation {
@@ -77,8 +78,6 @@ function findTsFilesOutsideSrc(projectDir) {
77
78
  if (entry.name === 'dist')
78
79
  continue;
79
80
  if (entry.isFile() && entry.name.endsWith('.ts')) {
80
- if (entry.name === 'jest.config.ts')
81
- continue;
82
81
  violations.push(path.join(projectDir, entry.name));
83
82
  }
84
83
  if (entry.isDirectory()) {
@@ -129,13 +128,15 @@ function findOrphanTsFiles(dir, projectRootSet, workspaceRoot, results) {
129
128
  }
130
129
  }
131
130
  }
132
- function checkLayerOne(projectRoots, workspaceRoot) {
131
+ function checkLayerOne(projectRoots, workspaceRoot, excludePaths) {
133
132
  const violations = [];
134
133
  for (const projectDir of projectRoots) {
135
134
  const projectName = path.relative(workspaceRoot, projectDir);
136
135
  const tsFiles = findTsFilesOutsideSrc(projectDir);
137
136
  for (const tsFile of tsFiles) {
138
137
  const relativePath = path.relative(workspaceRoot, tsFile);
138
+ if ((0, rules_config_1.isPathExcluded)(relativePath, excludePaths))
139
+ continue;
139
140
  violations.push(new LayerOneViolation(relativePath, projectName));
140
141
  }
141
142
  }
@@ -151,6 +152,8 @@ function checkLayerTwo(workspaceRoot, projectRoots, excludePaths, allowedRootFil
151
152
  continue;
152
153
  if (allowedRootFiles.includes(entry.name))
153
154
  continue;
155
+ if ((0, rules_config_1.isPathExcluded)(entry.name, excludePaths))
156
+ continue;
154
157
  violations.push(new LayerTwoViolation(entry.name));
155
158
  continue;
156
159
  }
@@ -161,7 +164,10 @@ function checkLayerTwo(workspaceRoot, projectRoots, excludePaths, allowedRootFil
161
164
  const orphans = [];
162
165
  findOrphanTsFiles(path.join(workspaceRoot, entry.name), projectRootSet, workspaceRoot, orphans);
163
166
  for (const orphan of orphans) {
164
- violations.push(new LayerTwoViolation(path.relative(workspaceRoot, orphan)));
167
+ const relativePath = path.relative(workspaceRoot, orphan);
168
+ if ((0, rules_config_1.isPathExcluded)(relativePath, excludePaths))
169
+ continue;
170
+ violations.push(new LayerTwoViolation(relativePath));
165
171
  }
166
172
  }
167
173
  return violations;
@@ -178,8 +184,11 @@ function reportLayerOneFailure(violations) {
178
184
  for (const v of violations) {
179
185
  console.error(` ❌ ${v.filePath}`);
180
186
  }
181
- console.error('\nTo fix: Move the .ts file(s) into the src/ directory');
182
- console.error('Only exception: jest.config.ts at project root\n');
187
+ console.error('\nTo fix, pick one:');
188
+ console.error(' (a) Move the .ts file(s) into the src/ directory');
189
+ console.error(' (b) Add a glob/dir to validate-ts-in-src.excludePaths in');
190
+ console.error(' webpieces.config.json (e.g. "**/codegen.ts"). Defaults already');
191
+ console.error(' exempt **/*.d.ts and **/jest.config.ts.\n');
183
192
  }
184
193
  function reportLayerTwoFailure(violations) {
185
194
  console.error('❌ TypeScript files found outside any Nx project!\n');
@@ -201,8 +210,8 @@ async function runExecutor(_nxOptions, context) {
201
210
  // and validate-code — via @webpieces/rules-config.
202
211
  const shared = (0, rules_config_1.loadConfig)(context.root);
203
212
  const rule = shared.rules.get('validate-ts-in-src');
204
- if (rule && rule.enabled === false) {
205
- console.log('\n⏭️ Skipping validate-ts-in-src (enabled: false)\n');
213
+ if (rule && rule.isOff) {
214
+ console.log('\n⏭️ Skipping validate-ts-in-src (mode: OFF)\n');
206
215
  return { success: true };
207
216
  }
208
217
  const workspaceRoot = context.root;
@@ -210,7 +219,7 @@ async function runExecutor(_nxOptions, context) {
210
219
  const allowedRootFiles = rule?.options['allowedRootFiles'] ?? DEFAULT_ALLOWED_ROOT_FILES;
211
220
  console.log('\n📁 Validating TypeScript files are in src/ and owned by a project\n');
212
221
  const projectRoots = await getProjectRoots(workspaceRoot);
213
- const layerOneViolations = checkLayerOne(projectRoots, workspaceRoot);
222
+ const layerOneViolations = checkLayerOne(projectRoots, workspaceRoot, excludePaths);
214
223
  const layerTwoViolations = checkLayerTwo(workspaceRoot, projectRoots, excludePaths, allowedRootFiles);
215
224
  if (layerOneViolations.length === 0 && layerTwoViolations.length === 0) {
216
225
  console.log('✅ All .ts files are inside a project\'s src/ directory\n');
@@ -222,7 +231,7 @@ async function runExecutor(_nxOptions, context) {
222
231
  if (layerTwoViolations.length > 0) {
223
232
  reportLayerTwoFailure(layerTwoViolations);
224
233
  }
225
- console.error('To disable: set rules["validate-ts-in-src"].enabled to false in webpieces.config.json\n');
234
+ console.error('To disable: set rules["validate-ts-in-src"].mode to "OFF" in webpieces.config.json\n');
226
235
  return { success: false };
227
236
  }
228
237
  //# sourceMappingURL=executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-ts-in-src/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate TypeScript Files in src/ Executor\n *\n * Two-layer rule:\n * Layer 1: every .ts file inside an Nx project must live under src/\n * (jest.config.ts at project root is the only exception)\n * Layer 2: every .ts file anywhere in the workspace must belong to some\n * Nx project. Orphan files (at workspace root or in a non-project\n * directory) fail the rule unless explicitly allowlisted.\n *\n * Configurable via nx.json targetDefaults:\n * \"validate-ts-in-src\": {\n * \"options\": {\n * \"mode\": \"ON\",\n * \"excludePaths\": [...],\n * \"allowedRootFiles\": [...]\n * }\n * }\n *\n * Usage: nx run architecture:validate-ts-in-src\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { createProjectGraphAsync, readProjectsConfigurationFromProjectGraph } from '@nx/devkit';\nimport { loadConfig } from '@webpieces/rules-config';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport type ValidateTsInSrcMode = 'ON' | 'OFF';\n\nexport interface ValidateTsInSrcOptions {\n mode?: ValidateTsInSrcMode;\n excludePaths?: string[];\n allowedRootFiles?: string[];\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nconst DEFAULT_EXCLUDE_PATHS: string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n 'architecture', 'tmp', 'scripts',\n];\n\nconst DEFAULT_ALLOWED_ROOT_FILES: string[] = ['jest.setup.ts'];\n\nclass LayerOneViolation {\n filePath: string;\n projectName: string;\n\n constructor(filePath: string, projectName: string) {\n this.filePath = filePath;\n this.projectName = projectName;\n }\n}\n\nclass LayerTwoViolation {\n filePath: string;\n\n constructor(filePath: string) {\n this.filePath = filePath;\n }\n}\n\nfunction isNodeModulesDir(name: string): boolean {\n return name === 'node_modules' || name.startsWith('node_modules_');\n}\n\nfunction shouldSkipTopLevelDir(name: string, excludePaths: string[]): boolean {\n if (isNodeModulesDir(name)) return true;\n return excludePaths.includes(name);\n}\n\nasync function getProjectRoots(workspaceRoot: string): Promise<string[]> {\n const projectGraph = await createProjectGraphAsync();\n const projectsConfig = readProjectsConfigurationFromProjectGraph(projectGraph);\n const roots: string[] = [];\n for (const cfg of Object.values(projectsConfig.projects)) {\n if (cfg.root === '' || cfg.root === '.') continue;\n if (cfg.root === 'architecture') continue;\n roots.push(path.join(workspaceRoot, cfg.root));\n }\n return roots;\n}\n\nfunction findTsFilesOutsideSrc(projectDir: string): string[] {\n const violations: string[] = [];\n if (!fs.existsSync(projectDir)) return violations;\n const entries = fs.readdirSync(projectDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.name === 'src') continue;\n if (isNodeModulesDir(entry.name)) continue;\n if (entry.name === 'dist') continue;\n\n if (entry.isFile() && entry.name.endsWith('.ts')) {\n if (entry.name === 'jest.config.ts') continue;\n violations.push(path.join(projectDir, entry.name));\n }\n\n if (entry.isDirectory()) {\n const tsFiles = findTsFilesRecursively(path.join(projectDir, entry.name));\n violations.push(...tsFiles);\n }\n }\n\n return violations;\n}\n\nfunction findTsFilesRecursively(dir: string): string[] {\n const results: string[] = [];\n if (!fs.existsSync(dir)) return results;\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (isNodeModulesDir(entry.name)) continue;\n if (entry.name === 'dist') continue;\n const fullPath = path.join(dir, entry.name);\n if (entry.isFile() && entry.name.endsWith('.ts')) {\n results.push(fullPath);\n } else if (entry.isDirectory()) {\n results.push(...findTsFilesRecursively(fullPath));\n }\n }\n return results;\n}\n\nfunction findOrphanTsFiles(\n dir: string,\n projectRootSet: Set<string>,\n workspaceRoot: string,\n results: string[],\n): void {\n if (!fs.existsSync(dir)) return;\n\n const relDir = path.relative(workspaceRoot, dir);\n if (projectRootSet.has(relDir)) return;\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (isNodeModulesDir(entry.name)) continue;\n if (entry.name === 'dist') continue;\n const fullPath = path.join(dir, entry.name);\n if (entry.isFile() && entry.name.endsWith('.ts')) {\n results.push(fullPath);\n } else if (entry.isDirectory()) {\n findOrphanTsFiles(fullPath, projectRootSet, workspaceRoot, results);\n }\n }\n}\n\nfunction checkLayerOne(projectRoots: string[], workspaceRoot: string): LayerOneViolation[] {\n const violations: LayerOneViolation[] = [];\n for (const projectDir of projectRoots) {\n const projectName = path.relative(workspaceRoot, projectDir);\n const tsFiles = findTsFilesOutsideSrc(projectDir);\n for (const tsFile of tsFiles) {\n const relativePath = path.relative(workspaceRoot, tsFile);\n violations.push(new LayerOneViolation(relativePath, projectName));\n }\n }\n return violations;\n}\n\nfunction checkLayerTwo(\n workspaceRoot: string,\n projectRoots: string[],\n excludePaths: string[],\n allowedRootFiles: string[],\n): LayerTwoViolation[] {\n const violations: LayerTwoViolation[] = [];\n const projectRootSet = new Set(\n projectRoots.map((p) => path.relative(workspaceRoot, p)),\n );\n\n const entries = fs.readdirSync(workspaceRoot, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isFile()) {\n if (!entry.name.endsWith('.ts')) continue;\n if (allowedRootFiles.includes(entry.name)) continue;\n violations.push(new LayerTwoViolation(entry.name));\n continue;\n }\n if (!entry.isDirectory()) continue;\n if (shouldSkipTopLevelDir(entry.name, excludePaths)) continue;\n\n const orphans: string[] = [];\n findOrphanTsFiles(\n path.join(workspaceRoot, entry.name),\n projectRootSet,\n workspaceRoot,\n orphans,\n );\n for (const orphan of orphans) {\n violations.push(new LayerTwoViolation(path.relative(workspaceRoot, orphan)));\n }\n }\n\n return violations;\n}\n\nfunction reportLayerOneFailure(violations: LayerOneViolation[]): void {\n console.error('❌ TypeScript files found outside src/ directory!\\n');\n console.error('All .ts source files must be inside the project\\'s src/ directory.');\n console.error('This enforces the standard project structure:\\n');\n console.error(' packages/{category}/{name}/');\n console.error(' ├── src/ ← ALL .ts files here');\n console.error(' ├── package.json');\n console.error(' ├── project.json');\n console.error(' └── tsconfig.json\\n');\n\n for (const v of violations) {\n console.error(` ❌ ${v.filePath}`);\n }\n\n console.error('\\nTo fix: Move the .ts file(s) into the src/ directory');\n console.error('Only exception: jest.config.ts at project root\\n');\n}\n\nfunction reportLayerTwoFailure(violations: LayerTwoViolation[]): void {\n console.error('❌ TypeScript files found outside any Nx project!\\n');\n console.error('Every .ts file must belong to an Nx project so it is compiled,');\n console.error('linted, and tested under a known project config. Orphan files are');\n console.error('invisible to the build graph and will rot.\\n');\n\n for (const v of violations) {\n console.error(` ❌ ${v.filePath}`);\n }\n\n console.error('\\nTo fix, pick one:');\n console.error(' (a) Move the file into an existing project\\'s src/ directory');\n console.error(' (b) Create a new project (add project.json) that owns the directory');\n console.error(' (c) Add the containing top-level directory to validate-ts-in-src.excludePaths');\n console.error(' in nx.json targetDefaults, or add the filename to allowedRootFiles');\n console.error(' if it is a legitimate workspace-root file (e.g., jest.setup.ts)\\n');\n}\n\nexport default async function runExecutor(\n _nxOptions: ValidateTsInSrcOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n // Config comes from webpieces.config.json — same source as ai-hooks\n // and validate-code — via @webpieces/rules-config.\n const shared = loadConfig(context.root);\n const rule = shared.rules.get('validate-ts-in-src');\n\n if (rule && rule.enabled === false) {\n console.log('\\n⏭️ Skipping validate-ts-in-src (enabled: false)\\n');\n return { success: true };\n }\n\n const workspaceRoot = context.root;\n const excludePaths =\n (rule?.options['excludePaths'] as string[] | undefined) ?? DEFAULT_EXCLUDE_PATHS;\n const allowedRootFiles =\n (rule?.options['allowedRootFiles'] as string[] | undefined) ?? DEFAULT_ALLOWED_ROOT_FILES;\n\n console.log('\\n📁 Validating TypeScript files are in src/ and owned by a project\\n');\n\n const projectRoots = await getProjectRoots(workspaceRoot);\n\n const layerOneViolations = checkLayerOne(projectRoots, workspaceRoot);\n const layerTwoViolations = checkLayerTwo(\n workspaceRoot, projectRoots, excludePaths, allowedRootFiles,\n );\n\n if (layerOneViolations.length === 0 && layerTwoViolations.length === 0) {\n console.log('✅ All .ts files are inside a project\\'s src/ directory\\n');\n return { success: true };\n }\n\n if (layerOneViolations.length > 0) {\n reportLayerOneFailure(layerOneViolations);\n }\n if (layerTwoViolations.length > 0) {\n reportLayerTwoFailure(layerTwoViolations);\n }\n\n console.error('To disable: set rules[\"validate-ts-in-src\"].enabled to false in webpieces.config.json\\n');\n return { success: false };\n}\n"]}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-ts-in-src/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;AAsOH,8BA2CC;;AA9QD,uCAAgG;AAChG,0DAAqE;AACrE,+CAAyB;AACzB,mDAA6B;AAc7B,MAAM,qBAAqB,GAAa;IACpC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACrC,cAAc,EAAE,KAAK,EAAE,SAAS;IAChC,WAAW,EAAE,mBAAmB;CACnC,CAAC;AAEF,MAAM,0BAA0B,GAAa,CAAC,eAAe,CAAC,CAAC;AAE/D,MAAM,iBAAiB;IAInB,YAAY,QAAgB,EAAE,WAAmB;QAC7C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;CACJ;AAED,MAAM,iBAAiB;IAGnB,YAAY,QAAgB;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AAED,SAAS,gBAAgB,CAAC,IAAY;IAClC,OAAO,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,YAAsB;IAC/D,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,aAAqB;IAChD,MAAM,YAAY,GAAG,MAAM,IAAA,gCAAuB,GAAE,CAAC;IACrD,MAAM,cAAc,GAAG,IAAA,kDAAyC,EAAC,YAAY,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;YAAE,SAAS;QAClD,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;YAAE,SAAS;QAC1C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAkB;IAC7C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAClD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS;QACnC,IAAI,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAEpC,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1E,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAChC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAW;IACvC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAExC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtD,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CACtB,GAAW,EACX,cAA2B,EAC3B,aAAqB,EACrB,OAAiB;IAEjB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO;IAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO;IAEvC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;QACxE,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAClB,YAAsB,EACtB,aAAqB,EACrB,YAAsB;IAEtB,MAAM,UAAU,GAAwB,EAAE,CAAC;IAC3C,KAAK,MAAM,UAAU,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAClD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC1D,IAAI,IAAA,6BAAc,EAAC,YAAY,EAAE,YAAY,CAAC;gBAAE,SAAS;YACzD,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CAClB,aAAqB,EACrB,YAAsB,EACtB,YAAsB,EACtB,gBAA0B;IAE1B,MAAM,UAAU,GAAwB,EAAE,CAAC;IAC3C,MAAM,cAAc,GAAG,IAAI,GAAG,CAC1B,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAC3D,CAAC;IAEF,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC1C,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACpD,IAAI,IAAA,6BAAc,EAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC;gBAAE,SAAS;YACvD,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACnD,SAAS;QACb,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,IAAI,qBAAqB,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC;YAAE,SAAS;QAE9D,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,iBAAiB,CACb,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,EACpC,cAAc,EACd,aAAa,EACb,OAAO,CACV,CAAC;QACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC1D,IAAI,IAAA,6BAAc,EAAC,YAAY,EAAE,YAAY,CAAC;gBAAE,SAAS;YACzD,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC;QACzD,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,SAAS,qBAAqB,CAAC,UAA+B;IAC1D,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACpF,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC1D,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAEvC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACrC,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAC5E,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;IACtF,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,qBAAqB,CAAC,UAA+B;IAC1D,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;IAChF,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACnF,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAE9D,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACrC,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;IAChF,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;IACvF,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACjG,OAAO,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC1F,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;AAC7F,CAAC;AAEc,KAAK,UAAU,WAAW,CACrC,UAAkC,EAClC,OAAwB;IAExB,oEAAoE;IACpE,mDAAmD;IACnD,MAAM,MAAM,GAAG,IAAA,yBAAU,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAEpD,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IACnC,MAAM,YAAY,GACb,IAAI,EAAE,OAAO,CAAC,cAAc,CAA0B,IAAI,qBAAqB,CAAC;IACrF,MAAM,gBAAgB,GACjB,IAAI,EAAE,OAAO,CAAC,kBAAkB,CAA0B,IAAI,0BAA0B,CAAC;IAE9F,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;IAErF,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;IAE1D,MAAM,kBAAkB,GAAG,aAAa,CAAC,YAAY,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IACpF,MAAM,kBAAkB,GAAG,aAAa,CACpC,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,CAC9D,CAAC;IAEF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;QACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,sFAAsF,CAAC,CAAC;IACtG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC","sourcesContent":["/**\n * Validate TypeScript Files in src/ Executor\n *\n * Two-layer rule:\n * Layer 1: every .ts file inside an Nx project must live under src/\n * Layer 2: every .ts file anywhere in the workspace must belong to some\n * Nx project. Orphan files (at workspace root or in a non-project\n * directory) fail the rule unless explicitly allowlisted.\n *\n * `excludePaths` is holistic — its bare dir names and globs exempt files\n * from BOTH layers. Defaults exempt **\\/*.d.ts and **\\/jest.config.ts.\n *\n * Configurable via webpieces.config.json:\n * \"validate-ts-in-src\": {\n * \"mode\": \"ON\", // \"OFF\" disables the rule\n * \"excludePaths\": [...], // dir names + globs, e.g. \"**\\/codegen.ts\"\n * \"allowedRootFiles\": [...]\n * }\n *\n * Usage: nx run architecture:validate-ts-in-src\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { createProjectGraphAsync, readProjectsConfigurationFromProjectGraph } from '@nx/devkit';\nimport { loadConfig, isPathExcluded } from '@webpieces/rules-config';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport type ValidateTsInSrcMode = 'ON' | 'OFF';\n\nexport interface ValidateTsInSrcOptions {\n mode?: ValidateTsInSrcMode;\n excludePaths?: string[];\n allowedRootFiles?: string[];\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nconst DEFAULT_EXCLUDE_PATHS: string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n 'architecture', 'tmp', 'scripts',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\nconst DEFAULT_ALLOWED_ROOT_FILES: string[] = ['jest.setup.ts'];\n\nclass LayerOneViolation {\n filePath: string;\n projectName: string;\n\n constructor(filePath: string, projectName: string) {\n this.filePath = filePath;\n this.projectName = projectName;\n }\n}\n\nclass LayerTwoViolation {\n filePath: string;\n\n constructor(filePath: string) {\n this.filePath = filePath;\n }\n}\n\nfunction isNodeModulesDir(name: string): boolean {\n return name === 'node_modules' || name.startsWith('node_modules_');\n}\n\nfunction shouldSkipTopLevelDir(name: string, excludePaths: string[]): boolean {\n if (isNodeModulesDir(name)) return true;\n return excludePaths.includes(name);\n}\n\nasync function getProjectRoots(workspaceRoot: string): Promise<string[]> {\n const projectGraph = await createProjectGraphAsync();\n const projectsConfig = readProjectsConfigurationFromProjectGraph(projectGraph);\n const roots: string[] = [];\n for (const cfg of Object.values(projectsConfig.projects)) {\n if (cfg.root === '' || cfg.root === '.') continue;\n if (cfg.root === 'architecture') continue;\n roots.push(path.join(workspaceRoot, cfg.root));\n }\n return roots;\n}\n\nfunction findTsFilesOutsideSrc(projectDir: string): string[] {\n const violations: string[] = [];\n if (!fs.existsSync(projectDir)) return violations;\n const entries = fs.readdirSync(projectDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.name === 'src') continue;\n if (isNodeModulesDir(entry.name)) continue;\n if (entry.name === 'dist') continue;\n\n if (entry.isFile() && entry.name.endsWith('.ts')) {\n violations.push(path.join(projectDir, entry.name));\n }\n\n if (entry.isDirectory()) {\n const tsFiles = findTsFilesRecursively(path.join(projectDir, entry.name));\n violations.push(...tsFiles);\n }\n }\n\n return violations;\n}\n\nfunction findTsFilesRecursively(dir: string): string[] {\n const results: string[] = [];\n if (!fs.existsSync(dir)) return results;\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (isNodeModulesDir(entry.name)) continue;\n if (entry.name === 'dist') continue;\n const fullPath = path.join(dir, entry.name);\n if (entry.isFile() && entry.name.endsWith('.ts')) {\n results.push(fullPath);\n } else if (entry.isDirectory()) {\n results.push(...findTsFilesRecursively(fullPath));\n }\n }\n return results;\n}\n\nfunction findOrphanTsFiles(\n dir: string,\n projectRootSet: Set<string>,\n workspaceRoot: string,\n results: string[],\n): void {\n if (!fs.existsSync(dir)) return;\n\n const relDir = path.relative(workspaceRoot, dir);\n if (projectRootSet.has(relDir)) return;\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (isNodeModulesDir(entry.name)) continue;\n if (entry.name === 'dist') continue;\n const fullPath = path.join(dir, entry.name);\n if (entry.isFile() && entry.name.endsWith('.ts')) {\n results.push(fullPath);\n } else if (entry.isDirectory()) {\n findOrphanTsFiles(fullPath, projectRootSet, workspaceRoot, results);\n }\n }\n}\n\nfunction checkLayerOne(\n projectRoots: string[],\n workspaceRoot: string,\n excludePaths: string[],\n): LayerOneViolation[] {\n const violations: LayerOneViolation[] = [];\n for (const projectDir of projectRoots) {\n const projectName = path.relative(workspaceRoot, projectDir);\n const tsFiles = findTsFilesOutsideSrc(projectDir);\n for (const tsFile of tsFiles) {\n const relativePath = path.relative(workspaceRoot, tsFile);\n if (isPathExcluded(relativePath, excludePaths)) continue;\n violations.push(new LayerOneViolation(relativePath, projectName));\n }\n }\n return violations;\n}\n\nfunction checkLayerTwo(\n workspaceRoot: string,\n projectRoots: string[],\n excludePaths: string[],\n allowedRootFiles: string[],\n): LayerTwoViolation[] {\n const violations: LayerTwoViolation[] = [];\n const projectRootSet = new Set(\n projectRoots.map((p) => path.relative(workspaceRoot, p)),\n );\n\n const entries = fs.readdirSync(workspaceRoot, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isFile()) {\n if (!entry.name.endsWith('.ts')) continue;\n if (allowedRootFiles.includes(entry.name)) continue;\n if (isPathExcluded(entry.name, excludePaths)) continue;\n violations.push(new LayerTwoViolation(entry.name));\n continue;\n }\n if (!entry.isDirectory()) continue;\n if (shouldSkipTopLevelDir(entry.name, excludePaths)) continue;\n\n const orphans: string[] = [];\n findOrphanTsFiles(\n path.join(workspaceRoot, entry.name),\n projectRootSet,\n workspaceRoot,\n orphans,\n );\n for (const orphan of orphans) {\n const relativePath = path.relative(workspaceRoot, orphan);\n if (isPathExcluded(relativePath, excludePaths)) continue;\n violations.push(new LayerTwoViolation(relativePath));\n }\n }\n\n return violations;\n}\n\nfunction reportLayerOneFailure(violations: LayerOneViolation[]): void {\n console.error('❌ TypeScript files found outside src/ directory!\\n');\n console.error('All .ts source files must be inside the project\\'s src/ directory.');\n console.error('This enforces the standard project structure:\\n');\n console.error(' packages/{category}/{name}/');\n console.error(' ├── src/ ← ALL .ts files here');\n console.error(' ├── package.json');\n console.error(' ├── project.json');\n console.error(' └── tsconfig.json\\n');\n\n for (const v of violations) {\n console.error(` ❌ ${v.filePath}`);\n }\n\n console.error('\\nTo fix, pick one:');\n console.error(' (a) Move the .ts file(s) into the src/ directory');\n console.error(' (b) Add a glob/dir to validate-ts-in-src.excludePaths in');\n console.error(' webpieces.config.json (e.g. \"**/codegen.ts\"). Defaults already');\n console.error(' exempt **/*.d.ts and **/jest.config.ts.\\n');\n}\n\nfunction reportLayerTwoFailure(violations: LayerTwoViolation[]): void {\n console.error('❌ TypeScript files found outside any Nx project!\\n');\n console.error('Every .ts file must belong to an Nx project so it is compiled,');\n console.error('linted, and tested under a known project config. Orphan files are');\n console.error('invisible to the build graph and will rot.\\n');\n\n for (const v of violations) {\n console.error(` ❌ ${v.filePath}`);\n }\n\n console.error('\\nTo fix, pick one:');\n console.error(' (a) Move the file into an existing project\\'s src/ directory');\n console.error(' (b) Create a new project (add project.json) that owns the directory');\n console.error(' (c) Add the containing top-level directory to validate-ts-in-src.excludePaths');\n console.error(' in nx.json targetDefaults, or add the filename to allowedRootFiles');\n console.error(' if it is a legitimate workspace-root file (e.g., jest.setup.ts)\\n');\n}\n\nexport default async function runExecutor(\n _nxOptions: ValidateTsInSrcOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n // Config comes from webpieces.config.json — same source as ai-hooks\n // and validate-code — via @webpieces/rules-config.\n const shared = loadConfig(context.root);\n const rule = shared.rules.get('validate-ts-in-src');\n\n if (rule && rule.isOff) {\n console.log('\\n⏭️ Skipping validate-ts-in-src (mode: OFF)\\n');\n return { success: true };\n }\n\n const workspaceRoot = context.root;\n const excludePaths =\n (rule?.options['excludePaths'] as string[] | undefined) ?? DEFAULT_EXCLUDE_PATHS;\n const allowedRootFiles =\n (rule?.options['allowedRootFiles'] as string[] | undefined) ?? DEFAULT_ALLOWED_ROOT_FILES;\n\n console.log('\\n📁 Validating TypeScript files are in src/ and owned by a project\\n');\n\n const projectRoots = await getProjectRoots(workspaceRoot);\n\n const layerOneViolations = checkLayerOne(projectRoots, workspaceRoot, excludePaths);\n const layerTwoViolations = checkLayerTwo(\n workspaceRoot, projectRoots, excludePaths, allowedRootFiles,\n );\n\n if (layerOneViolations.length === 0 && layerTwoViolations.length === 0) {\n console.log('✅ All .ts files are inside a project\\'s src/ directory\\n');\n return { success: true };\n }\n\n if (layerOneViolations.length > 0) {\n reportLayerOneFailure(layerOneViolations);\n }\n if (layerTwoViolations.length > 0) {\n reportLayerTwoFailure(layerTwoViolations);\n }\n\n console.error('To disable: set rules[\"validate-ts-in-src\"].mode to \"OFF\" in webpieces.config.json\\n');\n return { success: false };\n}\n"]}
@@ -8,12 +8,12 @@
8
8
  "type": "string",
9
9
  "enum": ["ON", "OFF"],
10
10
  "default": "ON",
11
- "description": "ON = enforce both layers, OFF = skip validation"
11
+ "description": "ON = enforce both layers, OFF = skip validation. This is the single on/off switch (the legacy 'enabled' boolean has been removed)."
12
12
  },
13
13
  "excludePaths": {
14
14
  "type": "array",
15
15
  "items": { "type": "string" },
16
- "description": "Top-level workspace directory names to skip entirely when looking for orphan .ts files. Defaults: node_modules, dist, .nx, .git, architecture, tmp, scripts. node_modules_* backup directories are always skipped regardless of this list. Override replaces the defaults — re-list any defaults you want to keep."
16
+ "description": "Holistic exclusion list applied to BOTH layers. Each entry is either a bare directory/segment name matched at any depth (e.g. node_modules, dist, scripts) or a glob matched against the workspace-relative path (e.g. '**/*.d.ts', '**/codegen.ts'). Defaults: node_modules, dist, .nx, .git, architecture, tmp, scripts, **/*.d.ts, **/jest.config.ts. node_modules_* backup directories are always skipped. Override replaces the defaults — re-list any defaults you want to keep."
17
17
  },
18
18
  "allowedRootFiles": {
19
19
  "type": "array",
package/src/plugin.d.ts CHANGED
@@ -37,6 +37,7 @@ export interface ValidationOptions {
37
37
  validateModifiedFiles?: boolean;
38
38
  validateVersionsLocked?: boolean;
39
39
  validateTsInSrc?: boolean;
40
+ validateNxWiring?: boolean;
40
41
  newMethodsMaxLines?: number;
41
42
  modifiedAndNewMethodsMaxLines?: number;
42
43
  modifiedFilesMaxLines?: number;
package/src/plugin.js CHANGED
@@ -40,6 +40,7 @@ const DEFAULT_OPTIONS = {
40
40
  validateModifiedFiles: true,
41
41
  validateVersionsLocked: true,
42
42
  validateTsInSrc: true,
43
+ validateNxWiring: true,
43
44
  newMethodsMaxLines: 30,
44
45
  modifiedAndNewMethodsMaxLines: 80,
45
46
  modifiedFilesMaxLines: 900,
@@ -184,6 +185,8 @@ function buildValidationTargetsList(validations) {
184
185
  targets.push('validate-versions-locked');
185
186
  if (validations.validateTsInSrc)
186
187
  targets.push('validate-ts-in-src');
188
+ if (validations.validateNxWiring)
189
+ targets.push('validate-nx-wiring');
187
190
  return targets;
188
191
  }
189
192
  /**
@@ -228,6 +231,9 @@ function createWorkspaceTargetsWithoutPrefix(opts) {
228
231
  if (validations.validateTsInSrc) {
229
232
  targets['validate-ts-in-src'] = createValidateTsInSrcTarget();
230
233
  }
234
+ if (validations.validateNxWiring) {
235
+ targets['validate-nx-wiring'] = createValidateNxWiringTarget();
236
+ }
231
237
  // Add validate-complete target that runs all enabled validations
232
238
  const validationTargets = buildValidationTargetsList(validations);
233
239
  if (validationTargets.length > 0) {
@@ -428,6 +434,17 @@ function createValidateTsInSrcTarget() {
428
434
  },
429
435
  };
430
436
  }
437
+ function createValidateNxWiringTarget() {
438
+ return {
439
+ executor: '@webpieces/nx-webpieces-rules:validate-nx-wiring',
440
+ cache: false, // Cheap; depends on nx.json + project graph, not worth caching
441
+ inputs: ['{workspaceRoot}/nx.json', '{workspaceRoot}/webpieces.config.json'],
442
+ metadata: {
443
+ technologies: ['nx'],
444
+ description: 'Validate the webpieces validators are wired into the build via nx.json dependsOn',
445
+ },
446
+ };
447
+ }
431
448
  function createValidateCompleteTarget(validationTargets) {
432
449
  return {
433
450
  executor: 'nx:noop',
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 *\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';\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 noSkipLevelDeps?: boolean;\n architectureUnchanged?: boolean;\n validatePackageJson?: boolean;\n validateNewMethods?: boolean;\n validateModifiedMethods?: boolean;\n validateModifiedFiles?: boolean;\n validateVersionsLocked?: boolean;\n validateTsInSrc?: 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}\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 noSkipLevelDeps: true,\n architectureUnchanged: true,\n validatePackageJson: true,\n validateNewMethods: true,\n validateModifiedMethods: true,\n validateModifiedFiles: true,\n validateVersionsLocked: true,\n validateTsInSrc: true,\n newMethodsMaxLines: 30,\n modifiedAndNewMethodsMaxLines: 80,\n modifiedFilesMaxLines: 900,\n validationMode: 'NORMAL',\n },\n features: {\n generate: true,\n visualize: 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)\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\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 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 targets: Record<string, TargetConfiguration> = {};\n\n // Add circular-deps target ONLY for project.json projects\n // (package.json-only projects may not have TypeScript source)\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 }\n }\n\n // Add ci target to ALL projects (both project.json and package.json)\n targets['ci'] = createCiTarget();\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 * 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!.noSkipLevelDeps) targets.push('validate-no-skiplevel-deps');\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 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\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 (validations.noCycles) {\n targets['validate-no-architecture-cycles'] = createValidateNoCyclesTarget();\n }\n if (validations.architectureUnchanged) {\n targets['validate-architecture-unchanged'] = createValidateUnchangedTarget(graphPath);\n }\n if (validations.noSkipLevelDeps) {\n targets['validate-no-skiplevel-deps'] = createValidateNoSkipLevelTarget();\n }\n if (validations.validatePackageJson) {\n targets['validate-packagejson'] = createValidatePackageJsonTarget();\n }\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'] = createValidateCodeTarget();\n }\n if (validations.validateVersionsLocked) {\n targets['validate-versions-locked'] = createValidateVersionsLockedTarget();\n }\n if (validations.validateTsInSrc) {\n targets['validate-ts-in-src'] = createValidateTsInSrcTarget();\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\n/**\n * Create workspace-level architecture validation targets (DEPRECATED - keeping for backward compat)\n * Used when root project.json exists (old style with '.' project)\n */\nfunction createWorkspaceTargets(\n opts: Required<ArchitecturePluginOptions>,\n): Record<string, TargetConfiguration> {\n const targets: Record<string, TargetConfiguration> = {};\n const prefix = opts.workspace.targetPrefix!;\n const graphPath = opts.workspace.graphPath!;\n\n // Add help target (always available)\n targets[`${prefix}help`] = createHelpTarget();\n\n if (opts.workspace.features!.generate) {\n targets[`${prefix}generate`] = createGenerateTarget(graphPath);\n }\n\n if (opts.workspace.features!.visualize) {\n targets[`${prefix}visualize`] = createVisualizeTarget(prefix, graphPath);\n }\n\n if (opts.workspace.validations!.noCycles) {\n targets[`${prefix}validate-no-architecture-cycles`] = createValidateNoCyclesTarget();\n }\n\n if (opts.workspace.validations!.architectureUnchanged) {\n targets[`${prefix}validate-architecture-unchanged`] =\n createValidateUnchangedTarget(graphPath);\n }\n\n if (opts.workspace.validations!.noSkipLevelDeps) {\n targets[`${prefix}validate-no-skiplevel-deps`] = createValidateNoSkipLevelTarget();\n }\n\n if (opts.workspace.validations!.validatePackageJson) {\n targets[`${prefix}validate-packagejson`] = createValidatePackageJsonTarget();\n }\n\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 opts.workspace.validations!.validateNewMethods ||\n opts.workspace.validations!.validateModifiedMethods ||\n opts.workspace.validations!.validateModifiedFiles\n ) {\n targets[`${prefix}validate-code`] = createValidateCodeTarget();\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: ['{workspaceRoot}/architecture/dependencies.json'],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Generate the architecture dependency graph from project.json files',\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 createVisualizeTarget(prefix: string, graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:visualize',\n dependsOn: [`${prefix}generate`],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Generate visual representations of the architecture graph',\n },\n };\n}\n\nfunction createValidateNoCyclesTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-no-architecture-cycles',\n cache: true,\n inputs: ['{workspaceRoot}/**/project.json', '{workspaceRoot}/architecture/dependencies.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate the architecture has no circular project dependencies',\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 createValidateNoSkipLevelTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-no-skiplevel-deps',\n cache: true,\n inputs: ['{workspaceRoot}/**/project.json', '{workspaceRoot}/architecture/dependencies.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate no project has redundant transitive dependencies',\n },\n };\n}\n\nfunction createValidatePackageJsonTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-packagejson',\n cache: true,\n inputs: ['{workspaceRoot}/**/project.json', '{workspaceRoot}/**/package.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate package.json dependencies match project.json build dependencies',\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\n/**\n * Create combined validate-code target\n * Options come from webpieces.config.json at the workspace root\n * (loaded by the executor via @webpieces/rules-config — same source of truth as @webpieces/ai-hook-rules)\n */\nfunction createValidateCodeTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-code',\n cache: false, // Don't cache - depends on git state\n inputs: ['default', '{workspaceRoot}/webpieces.config.json'],\n // No options here - they come from webpieces.config.json at runtime\n metadata: {\n technologies: ['nx'],\n description: 'Combined validation for new methods, modified methods, and file sizes',\n },\n };\n}\n\nfunction createValidateVersionsLockedTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-versions-locked',\n cache: true,\n inputs: ['{workspaceRoot}/**/package.json'],\n metadata: {\n technologies: ['nx'],\n description:\n 'Validate package.json versions are locked (no semver ranges) and consistent across projects',\n },\n };\n}\n\nfunction createValidateTsInSrcTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-ts-in-src',\n cache: false,\n inputs: ['default', '{workspaceRoot}/webpieces.config.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate all .ts files in projects are inside the src/ directory',\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, skip-level deps)',\n },\n };\n}\n\n/**\n * Create per-project ci target - Gradle-style composite target\n * Runs lint, build, and test in parallel\n * (with test depending on build via targetDefaults)\n *\n * NOTE: Type checking is done by the build target (@nx/js:tsc) during compilation.\n */\nfunction createCiTarget(): TargetConfiguration {\n return {\n executor: 'nx:noop',\n cache: true,\n dependsOn: ['lint', 'build', 'test'],\n metadata: {\n technologies: ['nx'],\n description: 'Run all CI checks: lint, build, and test (Gradle-style composite target)',\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 * Runs on project root (.) to check ALL TypeScript files in the project\n */\nfunction createCircularDepsTarget(projectRoot: string, targetName: string): TargetConfiguration {\n return {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n outputs: [] as string[],\n options: {\n command: 'npx madge --circular --extensions ts,tsx .',\n cwd: projectRoot,\n },\n metadata: {\n technologies: ['madge'],\n description: 'Check for circular 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) => {\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 *\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';\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 noSkipLevelDeps?: 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 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}\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 noSkipLevelDeps: 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 newMethodsMaxLines: 30,\n modifiedAndNewMethodsMaxLines: 80,\n modifiedFilesMaxLines: 900,\n validationMode: 'NORMAL',\n },\n features: {\n generate: true,\n visualize: 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)\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\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 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 targets: Record<string, TargetConfiguration> = {};\n\n // Add circular-deps target ONLY for project.json projects\n // (package.json-only projects may not have TypeScript source)\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 }\n }\n\n // Add ci target to ALL projects (both project.json and package.json)\n targets['ci'] = createCiTarget();\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 * 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!.noSkipLevelDeps) targets.push('validate-no-skiplevel-deps');\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 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\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 (validations.noCycles) {\n targets['validate-no-architecture-cycles'] = createValidateNoCyclesTarget();\n }\n if (validations.architectureUnchanged) {\n targets['validate-architecture-unchanged'] = createValidateUnchangedTarget(graphPath);\n }\n if (validations.noSkipLevelDeps) {\n targets['validate-no-skiplevel-deps'] = createValidateNoSkipLevelTarget();\n }\n if (validations.validatePackageJson) {\n targets['validate-packagejson'] = createValidatePackageJsonTarget();\n }\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'] = createValidateCodeTarget();\n }\n if (validations.validateVersionsLocked) {\n targets['validate-versions-locked'] = createValidateVersionsLockedTarget();\n }\n if (validations.validateTsInSrc) {\n targets['validate-ts-in-src'] = createValidateTsInSrcTarget();\n }\n if (validations.validateNxWiring) {\n targets['validate-nx-wiring'] = createValidateNxWiringTarget();\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\n/**\n * Create workspace-level architecture validation targets (DEPRECATED - keeping for backward compat)\n * Used when root project.json exists (old style with '.' project)\n */\nfunction createWorkspaceTargets(\n opts: Required<ArchitecturePluginOptions>,\n): Record<string, TargetConfiguration> {\n const targets: Record<string, TargetConfiguration> = {};\n const prefix = opts.workspace.targetPrefix!;\n const graphPath = opts.workspace.graphPath!;\n\n // Add help target (always available)\n targets[`${prefix}help`] = createHelpTarget();\n\n if (opts.workspace.features!.generate) {\n targets[`${prefix}generate`] = createGenerateTarget(graphPath);\n }\n\n if (opts.workspace.features!.visualize) {\n targets[`${prefix}visualize`] = createVisualizeTarget(prefix, graphPath);\n }\n\n if (opts.workspace.validations!.noCycles) {\n targets[`${prefix}validate-no-architecture-cycles`] = createValidateNoCyclesTarget();\n }\n\n if (opts.workspace.validations!.architectureUnchanged) {\n targets[`${prefix}validate-architecture-unchanged`] =\n createValidateUnchangedTarget(graphPath);\n }\n\n if (opts.workspace.validations!.noSkipLevelDeps) {\n targets[`${prefix}validate-no-skiplevel-deps`] = createValidateNoSkipLevelTarget();\n }\n\n if (opts.workspace.validations!.validatePackageJson) {\n targets[`${prefix}validate-packagejson`] = createValidatePackageJsonTarget();\n }\n\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 opts.workspace.validations!.validateNewMethods ||\n opts.workspace.validations!.validateModifiedMethods ||\n opts.workspace.validations!.validateModifiedFiles\n ) {\n targets[`${prefix}validate-code`] = createValidateCodeTarget();\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: ['{workspaceRoot}/architecture/dependencies.json'],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Generate the architecture dependency graph from project.json files',\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 createVisualizeTarget(prefix: string, graphPath: string): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:visualize',\n dependsOn: [`${prefix}generate`],\n options: { graphPath },\n metadata: {\n technologies: ['nx'],\n description: 'Generate visual representations of the architecture graph',\n },\n };\n}\n\nfunction createValidateNoCyclesTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-no-architecture-cycles',\n cache: true,\n inputs: ['{workspaceRoot}/**/project.json', '{workspaceRoot}/architecture/dependencies.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate the architecture has no circular project dependencies',\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 createValidateNoSkipLevelTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-no-skiplevel-deps',\n cache: true,\n inputs: ['{workspaceRoot}/**/project.json', '{workspaceRoot}/architecture/dependencies.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate no project has redundant transitive dependencies',\n },\n };\n}\n\nfunction createValidatePackageJsonTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-packagejson',\n cache: true,\n inputs: ['{workspaceRoot}/**/project.json', '{workspaceRoot}/**/package.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate package.json dependencies match project.json build dependencies',\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\n/**\n * Create combined validate-code target\n * Options come from webpieces.config.json at the workspace root\n * (loaded by the executor via @webpieces/rules-config — same source of truth as @webpieces/ai-hook-rules)\n */\nfunction createValidateCodeTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-code',\n cache: false, // Don't cache - depends on git state\n inputs: ['default', '{workspaceRoot}/webpieces.config.json'],\n // No options here - they come from webpieces.config.json at runtime\n metadata: {\n technologies: ['nx'],\n description: 'Combined validation for new methods, modified methods, and file sizes',\n },\n };\n}\n\nfunction createValidateVersionsLockedTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-versions-locked',\n cache: true,\n inputs: ['{workspaceRoot}/**/package.json'],\n metadata: {\n technologies: ['nx'],\n description:\n 'Validate package.json versions are locked (no semver ranges) and consistent across projects',\n },\n };\n}\n\nfunction createValidateTsInSrcTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-ts-in-src',\n cache: false,\n inputs: ['default', '{workspaceRoot}/webpieces.config.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate all .ts files in projects are inside the src/ directory',\n },\n };\n}\n\nfunction createValidateNxWiringTarget(): TargetConfiguration {\n return {\n executor: '@webpieces/nx-webpieces-rules:validate-nx-wiring',\n cache: false, // Cheap; depends on nx.json + project graph, not worth caching\n inputs: ['{workspaceRoot}/nx.json', '{workspaceRoot}/webpieces.config.json'],\n metadata: {\n technologies: ['nx'],\n description: 'Validate the webpieces validators are wired into the build via nx.json dependsOn',\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, skip-level deps)',\n },\n };\n}\n\n/**\n * Create per-project ci target - Gradle-style composite target\n * Runs lint, build, and test in parallel\n * (with test depending on build via targetDefaults)\n *\n * NOTE: Type checking is done by the build target (@nx/js:tsc) during compilation.\n */\nfunction createCiTarget(): TargetConfiguration {\n return {\n executor: 'nx:noop',\n cache: true,\n dependsOn: ['lint', 'build', 'test'],\n metadata: {\n technologies: ['nx'],\n description: 'Run all CI checks: lint, build, and test (Gradle-style composite target)',\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 * Runs on project root (.) to check ALL TypeScript files in the project\n */\nfunction createCircularDepsTarget(projectRoot: string, targetName: string): TargetConfiguration {\n return {\n executor: 'nx:run-commands',\n cache: true,\n inputs: ['default'],\n outputs: [] as string[],\n options: {\n command: 'npx madge --circular --extensions ts,tsx .',\n cwd: projectRoot,\n },\n metadata: {\n technologies: ['madge'],\n description: 'Check for circular 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) => {\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"]}