@webpieces/dev-config 0.2.36 → 0.2.38

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.
@@ -2,7 +2,6 @@
2
2
  * Generate Executor
3
3
  *
4
4
  * Generates the architecture dependency graph and saves it to architecture/dependencies.json.
5
- * Also validates that package.json dependencies match project.json.
6
5
  *
7
6
  * Usage:
8
7
  * nx run architecture:generate
@@ -3,7 +3,6 @@
3
3
  * Generate Executor
4
4
  *
5
5
  * Generates the architecture dependency graph and saves it to architecture/dependencies.json.
6
- * Also validates that package.json dependencies match project.json.
7
6
  *
8
7
  * Usage:
9
8
  * nx run architecture:generate
@@ -12,7 +11,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
11
  exports.default = runExecutor;
13
12
  const graph_generator_1 = require("../../lib/graph-generator");
14
13
  const graph_sorter_1 = require("../../lib/graph-sorter");
15
- const package_validator_1 = require("../../lib/package-validator");
16
14
  const graph_loader_1 = require("../../lib/graph-loader");
17
15
  async function runExecutor(options, context) {
18
16
  const { graphPath } = options;
@@ -22,31 +20,10 @@ async function runExecutor(options, context) {
22
20
  // Step 1: Generate current graph from project.json files
23
21
  console.log('šŸ“Š Generating dependency graph from project.json files...');
24
22
  const rawGraph = await (0, graph_generator_1.generateGraph)();
25
- // Step 2: Topological sort (validates acyclic and assigns levels)
23
+ // Step 2: Topological sort (to assign levels for visualization)
26
24
  console.log('šŸ”„ Computing topological layers...');
27
- let enhancedGraph;
28
- try {
29
- enhancedGraph = (0, graph_sorter_1.sortGraphTopologically)(rawGraph);
30
- console.log('āœ… Graph is acyclic');
31
- }
32
- catch (err) {
33
- const error = err instanceof Error ? err : new Error(String(err));
34
- console.error('āŒ Circular dependency detected!');
35
- console.error(error.message);
36
- return { success: false };
37
- }
38
- // Step 3: Validate package.json dependencies match
39
- console.log('šŸ“¦ Validating package.json dependencies match project.json...');
40
- const packageValidation = await (0, package_validator_1.validatePackageJsonDependencies)(enhancedGraph, workspaceRoot);
41
- if (!packageValidation.valid) {
42
- console.error('āŒ Package.json validation failed!');
43
- for (const error of packageValidation.errors) {
44
- console.error(` ${error}`);
45
- }
46
- return { success: false };
47
- }
48
- console.log('āœ… Package.json dependencies match');
49
- // Step 4: Save the graph
25
+ const enhancedGraph = (0, graph_sorter_1.sortGraphTopologically)(rawGraph);
26
+ // Step 3: Save the graph
50
27
  console.log('šŸ’¾ Saving graph to architecture/dependencies.json...');
51
28
  (0, graph_loader_1.saveGraph)(enhancedGraph, workspaceRoot, graphPath);
52
29
  console.log('āœ… Graph saved successfully');
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/generate/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generate Executor\n *\n * Generates the architecture dependency graph and saves it to architecture/dependencies.json.\n * Also validates that package.json dependencies match project.json.\n *\n * Usage:\n * nx run architecture:generate\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport { sortGraphTopologically } from '../../lib/graph-sorter';\nimport { validatePackageJsonDependencies } from '../../lib/package-validator';\nimport { saveGraph } from '../../lib/graph-loader';\n\nexport interface GenerateExecutorOptions {\n graphPath?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n options: GenerateExecutorOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const { graphPath } = options;\n const workspaceRoot = context.root;\n\n console.log('\\nšŸ“Š Architecture Graph Generator\\n');\n\n try {\n // Step 1: Generate current graph from project.json files\n console.log('šŸ“Š Generating dependency graph from project.json files...');\n const rawGraph = await generateGraph();\n\n // Step 2: Topological sort (validates acyclic and assigns levels)\n console.log('šŸ”„ Computing topological layers...');\n let enhancedGraph;\n try {\n enhancedGraph = sortGraphTopologically(rawGraph);\n console.log('āœ… Graph is acyclic');\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('āŒ Circular dependency detected!');\n console.error(error.message);\n return { success: false };\n }\n\n // Step 3: Validate package.json dependencies match\n console.log('šŸ“¦ Validating package.json dependencies match project.json...');\n const packageValidation = await validatePackageJsonDependencies(enhancedGraph, workspaceRoot);\n\n if (!packageValidation.valid) {\n console.error('āŒ Package.json validation failed!');\n for (const error of packageValidation.errors) {\n console.error(` ${error}`);\n }\n return { success: false };\n }\n console.log('āœ… Package.json dependencies match');\n\n // Step 4: Save the graph\n console.log('šŸ’¾ Saving graph to architecture/dependencies.json...');\n saveGraph(enhancedGraph, workspaceRoot, graphPath);\n console.log('āœ… Graph saved successfully');\n\n // Print summary\n const projectCount = Object.keys(enhancedGraph).length;\n const levels = new Set(Object.values(enhancedGraph).map((e) => e.level));\n console.log(`\\nšŸ“ˆ Graph Summary:`);\n console.log(` Projects: ${projectCount}`);\n console.log(` Levels: ${levels.size} (0-${Math.max(...levels)})`);\n\n return { success: true };\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('āŒ Graph generation failed:', error.message);\n return { success: false };\n }\n}\n"]}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/generate/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAeH,8BAoCC;AAhDD,+DAA0D;AAC1D,yDAAgE;AAChE,yDAAmD;AAUpC,KAAK,UAAU,WAAW,CACrC,OAAgC,EAChC,OAAwB;IAExB,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IAEnD,IAAI,CAAC;QACD,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAa,GAAE,CAAC;QAEvC,gEAAgE;QAChE,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,IAAA,qCAAsB,EAAC,QAAQ,CAAC,CAAC;QAEvD,yBAAyB;QACzB,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,IAAA,wBAAS,EAAC,aAAa,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAE1C,gBAAgB;QAChB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAEpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACL,CAAC","sourcesContent":["/**\n * Generate Executor\n *\n * Generates the architecture dependency graph and saves it to architecture/dependencies.json.\n *\n * Usage:\n * nx run architecture:generate\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport { sortGraphTopologically } from '../../lib/graph-sorter';\nimport { saveGraph } from '../../lib/graph-loader';\n\nexport interface GenerateExecutorOptions {\n graphPath?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n options: GenerateExecutorOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const { graphPath } = options;\n const workspaceRoot = context.root;\n\n console.log('\\nšŸ“Š Architecture Graph Generator\\n');\n\n try {\n // Step 1: Generate current graph from project.json files\n console.log('šŸ“Š Generating dependency graph from project.json files...');\n const rawGraph = await generateGraph();\n\n // Step 2: Topological sort (to assign levels for visualization)\n console.log('šŸ”„ Computing topological layers...');\n const enhancedGraph = sortGraphTopologically(rawGraph);\n\n // Step 3: Save the graph\n console.log('šŸ’¾ Saving graph to architecture/dependencies.json...');\n saveGraph(enhancedGraph, workspaceRoot, graphPath);\n console.log('āœ… Graph saved successfully');\n\n // Print summary\n const projectCount = Object.keys(enhancedGraph).length;\n const levels = new Set(Object.values(enhancedGraph).map((e) => e.level));\n console.log(`\\nšŸ“ˆ Graph Summary:`);\n console.log(` Projects: ${projectCount}`);\n console.log(` Levels: ${levels.size} (0-${Math.max(...levels)})`);\n\n return { success: true };\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('āŒ Graph generation failed:', error.message);\n return { success: false };\n }\n}\n"]}
@@ -2,7 +2,6 @@
2
2
  * Generate Executor
3
3
  *
4
4
  * Generates the architecture dependency graph and saves it to architecture/dependencies.json.
5
- * Also validates that package.json dependencies match project.json.
6
5
  *
7
6
  * Usage:
8
7
  * nx run architecture:generate
@@ -11,7 +10,6 @@
11
10
  import type { ExecutorContext } from '@nx/devkit';
12
11
  import { generateGraph } from '../../lib/graph-generator';
13
12
  import { sortGraphTopologically } from '../../lib/graph-sorter';
14
- import { validatePackageJsonDependencies } from '../../lib/package-validator';
15
13
  import { saveGraph } from '../../lib/graph-loader';
16
14
 
17
15
  export interface GenerateExecutorOptions {
@@ -36,33 +34,11 @@ export default async function runExecutor(
36
34
  console.log('šŸ“Š Generating dependency graph from project.json files...');
37
35
  const rawGraph = await generateGraph();
38
36
 
39
- // Step 2: Topological sort (validates acyclic and assigns levels)
37
+ // Step 2: Topological sort (to assign levels for visualization)
40
38
  console.log('šŸ”„ Computing topological layers...');
41
- let enhancedGraph;
42
- try {
43
- enhancedGraph = sortGraphTopologically(rawGraph);
44
- console.log('āœ… Graph is acyclic');
45
- } catch (err: unknown) {
46
- const error = err instanceof Error ? err : new Error(String(err));
47
- console.error('āŒ Circular dependency detected!');
48
- console.error(error.message);
49
- return { success: false };
50
- }
39
+ const enhancedGraph = sortGraphTopologically(rawGraph);
51
40
 
52
- // Step 3: Validate package.json dependencies match
53
- console.log('šŸ“¦ Validating package.json dependencies match project.json...');
54
- const packageValidation = await validatePackageJsonDependencies(enhancedGraph, workspaceRoot);
55
-
56
- if (!packageValidation.valid) {
57
- console.error('āŒ Package.json validation failed!');
58
- for (const error of packageValidation.errors) {
59
- console.error(` ${error}`);
60
- }
61
- return { success: false };
62
- }
63
- console.log('āœ… Package.json dependencies match');
64
-
65
- // Step 4: Save the graph
41
+ // Step 3: Save the graph
66
42
  console.log('šŸ’¾ Saving graph to architecture/dependencies.json...');
67
43
  saveGraph(enhancedGraph, workspaceRoot, graphPath);
68
44
  console.log('āœ… Graph saved successfully');
@@ -51,7 +51,7 @@ async function runExecutor(options, context) {
51
51
  console.error(comparison.summary);
52
52
  console.error('\nTo fix:');
53
53
  console.error(' 1. Review the changes above');
54
- console.error(' 2. If intentional, run: nx run architecture:generate');
54
+ console.error(' 2. If intentional, ASK USER to run: nx run architecture:generate since this is a critical change');
55
55
  console.error(' 3. Commit the updated architecture/dependencies.json');
56
56
  return { success: false };
57
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-architecture-unchanged/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAgBH,8BAwDC;AArED,+DAA0D;AAC1D,yDAAgE;AAChE,iEAA2D;AAC3D,yDAA2E;AAU5D,KAAK,UAAU,WAAW,CACrC,OAA6C,EAC7C,OAAwB;IAExB,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAExD,IAAI,CAAC;QACD,8BAA8B;QAC9B,IAAI,CAAC,IAAA,8BAAe,EAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAC1E,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAa,GAAE,CAAC;QAEvC,+DAA+D;QAC/D,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,IAAA,qCAAsB,EAAC,QAAQ,CAAC,CAAC;QAEtD,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,IAAA,+BAAgB,EAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAE9D,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,yBAAyB;QACzB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAA,gCAAa,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAE3D,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;YAC5E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC/D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAC/C,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACL,CAAC","sourcesContent":["/**\n * Validate Architecture Unchanged Executor\n *\n * Validates that the current architecture graph matches the saved blessed graph.\n * This ensures no unapproved architecture changes have been made.\n *\n * Usage:\n * nx run architecture:validate-architecture-unchanged\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport { sortGraphTopologically } from '../../lib/graph-sorter';\nimport { compareGraphs } from '../../lib/graph-comparator';\nimport { loadBlessedGraph, graphFileExists } from '../../lib/graph-loader';\n\nexport interface ValidateArchitectureUnchangedOptions {\n graphPath?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n options: ValidateArchitectureUnchangedOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const { graphPath } = options;\n const workspaceRoot = context.root;\n\n console.log('\\nšŸ” Validating Architecture Unchanged\\n');\n\n try {\n // Check if saved graph exists\n if (!graphFileExists(workspaceRoot, graphPath)) {\n console.error('āŒ No saved graph found at architecture/dependencies.json');\n console.error(' Run: nx run architecture:generate first');\n return { success: false };\n }\n\n // Step 1: Generate current graph from project.json files\n console.log('šŸ“Š Generating current dependency graph...');\n const rawGraph = await generateGraph();\n\n // Step 2: Topological sort (to get enhanced graph with levels)\n console.log('šŸ”„ Computing topological layers...');\n const currentGraph = sortGraphTopologically(rawGraph);\n\n // Step 3: Load saved graph\n console.log('šŸ“‚ Loading saved graph...');\n const savedGraph = loadBlessedGraph(workspaceRoot, graphPath);\n\n if (!savedGraph) {\n console.error('āŒ Could not load saved graph');\n return { success: false };\n }\n\n // Step 4: Compare graphs\n console.log('šŸ” Comparing current graph to saved graph...');\n const comparison = compareGraphs(currentGraph, savedGraph);\n\n if (comparison.identical) {\n console.log('āœ… Architecture unchanged - current graph matches saved graph');\n return { success: true };\n } else {\n console.error('āŒ Architecture has changed since last update!');\n console.error('\\nDifferences:');\n console.error(comparison.summary);\n console.error('\\nTo fix:');\n console.error(' 1. Review the changes above');\n console.error(' 2. If intentional, run: nx run architecture:generate');\n console.error(' 3. Commit the updated architecture/dependencies.json');\n return { success: false };\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('āŒ Architecture validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-architecture-unchanged/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAgBH,8BAwDC;AArED,+DAA0D;AAC1D,yDAAgE;AAChE,iEAA2D;AAC3D,yDAA2E;AAU5D,KAAK,UAAU,WAAW,CACrC,OAA6C,EAC7C,OAAwB;IAExB,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAExD,IAAI,CAAC;QACD,8BAA8B;QAC9B,IAAI,CAAC,IAAA,8BAAe,EAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAC1E,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAa,GAAE,CAAC;QAEvC,+DAA+D;QAC/D,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,IAAA,qCAAsB,EAAC,QAAQ,CAAC,CAAC;QAEtD,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,IAAA,+BAAgB,EAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAE9D,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,yBAAyB;QACzB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAA,gCAAa,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAE3D,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;YAC5E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC/D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAC/C,OAAO,CAAC,KAAK,CAAC,oGAAoG,CAAC,CAAC;YACpH,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACL,CAAC","sourcesContent":["/**\n * Validate Architecture Unchanged Executor\n *\n * Validates that the current architecture graph matches the saved blessed graph.\n * This ensures no unapproved architecture changes have been made.\n *\n * Usage:\n * nx run architecture:validate-architecture-unchanged\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport { sortGraphTopologically } from '../../lib/graph-sorter';\nimport { compareGraphs } from '../../lib/graph-comparator';\nimport { loadBlessedGraph, graphFileExists } from '../../lib/graph-loader';\n\nexport interface ValidateArchitectureUnchangedOptions {\n graphPath?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n options: ValidateArchitectureUnchangedOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const { graphPath } = options;\n const workspaceRoot = context.root;\n\n console.log('\\nšŸ” Validating Architecture Unchanged\\n');\n\n try {\n // Check if saved graph exists\n if (!graphFileExists(workspaceRoot, graphPath)) {\n console.error('āŒ No saved graph found at architecture/dependencies.json');\n console.error(' Run: nx run architecture:generate first');\n return { success: false };\n }\n\n // Step 1: Generate current graph from project.json files\n console.log('šŸ“Š Generating current dependency graph...');\n const rawGraph = await generateGraph();\n\n // Step 2: Topological sort (to get enhanced graph with levels)\n console.log('šŸ”„ Computing topological layers...');\n const currentGraph = sortGraphTopologically(rawGraph);\n\n // Step 3: Load saved graph\n console.log('šŸ“‚ Loading saved graph...');\n const savedGraph = loadBlessedGraph(workspaceRoot, graphPath);\n\n if (!savedGraph) {\n console.error('āŒ Could not load saved graph');\n return { success: false };\n }\n\n // Step 4: Compare graphs\n console.log('šŸ” Comparing current graph to saved graph...');\n const comparison = compareGraphs(currentGraph, savedGraph);\n\n if (comparison.identical) {\n console.log('āœ… Architecture unchanged - current graph matches saved graph');\n return { success: true };\n } else {\n console.error('āŒ Architecture has changed since last update!');\n console.error('\\nDifferences:');\n console.error(comparison.summary);\n console.error('\\nTo fix:');\n console.error(' 1. Review the changes above');\n console.error(' 2. If intentional, ASK USER to run: nx run architecture:generate since this is a critical change');\n console.error(' 3. Commit the updated architecture/dependencies.json');\n return { success: false };\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('āŒ Architecture validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
@@ -69,7 +69,7 @@ export default async function runExecutor(
69
69
  console.error(comparison.summary);
70
70
  console.error('\nTo fix:');
71
71
  console.error(' 1. Review the changes above');
72
- console.error(' 2. If intentional, run: nx run architecture:generate');
72
+ console.error(' 2. If intentional, ASK USER to run: nx run architecture:generate since this is a critical change');
73
73
  console.error(' 3. Commit the updated architecture/dependencies.json');
74
74
  return { success: false };
75
75
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Validate Package.json Executor
3
+ *
4
+ * Validates that package.json dependencies match project.json build dependencies.
5
+ * This ensures the two sources of truth don't drift apart.
6
+ *
7
+ * Usage:
8
+ * nx run architecture:validate-packagejson
9
+ */
10
+ import type { ExecutorContext } from '@nx/devkit';
11
+ export interface ValidatePackageJsonOptions {
12
+ }
13
+ export interface ExecutorResult {
14
+ success: boolean;
15
+ }
16
+ export default function runExecutor(options: ValidatePackageJsonOptions, context: ExecutorContext): Promise<ExecutorResult>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * Validate Package.json Executor
4
+ *
5
+ * Validates that package.json dependencies match project.json build dependencies.
6
+ * This ensures the two sources of truth don't drift apart.
7
+ *
8
+ * Usage:
9
+ * nx run architecture:validate-packagejson
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.default = runExecutor;
13
+ const graph_generator_1 = require("../../lib/graph-generator");
14
+ const graph_sorter_1 = require("../../lib/graph-sorter");
15
+ const package_validator_1 = require("../../lib/package-validator");
16
+ async function runExecutor(options, context) {
17
+ const workspaceRoot = context.root;
18
+ console.log('\nšŸ“¦ Validating Package.json Dependencies\n');
19
+ try {
20
+ // Step 1: Generate current graph from project.json files
21
+ console.log('šŸ“Š Generating dependency graph from project.json files...');
22
+ const rawGraph = await (0, graph_generator_1.generateGraph)();
23
+ // Step 2: Topological sort (to get enhanced graph with levels)
24
+ console.log('šŸ”„ Computing topological layers...');
25
+ const enhancedGraph = (0, graph_sorter_1.sortGraphTopologically)(rawGraph);
26
+ // Step 3: Validate package.json dependencies match
27
+ console.log('šŸ“¦ Validating package.json dependencies match project.json...');
28
+ const packageValidation = await (0, package_validator_1.validatePackageJsonDependencies)(enhancedGraph, workspaceRoot);
29
+ if (!packageValidation.valid) {
30
+ console.error('āŒ Package.json validation failed!');
31
+ console.error('\nErrors:');
32
+ for (const error of packageValidation.errors) {
33
+ console.error(` ${error}`);
34
+ }
35
+ console.error('\nTo fix:');
36
+ console.error(' 1. Review the missing dependencies above');
37
+ console.error(' 2. Add the missing dependencies to the respective package.json files');
38
+ console.error(' 3. Ensure dependencies in package.json match build.dependsOn in project.json');
39
+ return { success: false };
40
+ }
41
+ console.log('āœ… Package.json dependencies match project.json');
42
+ // Print summary
43
+ const validProjects = packageValidation.projectResults.filter(r => r.valid).length;
44
+ const totalProjects = packageValidation.projectResults.length;
45
+ console.log(`\nšŸ“ˆ Validation Summary:`);
46
+ console.log(` Projects validated: ${totalProjects}`);
47
+ console.log(` Valid: ${validProjects}`);
48
+ console.log(` Invalid: ${totalProjects - validProjects}`);
49
+ return { success: true };
50
+ }
51
+ catch (err) {
52
+ const error = err instanceof Error ? err : new Error(String(err));
53
+ console.error('āŒ Package.json validation failed:', error.message);
54
+ return { success: false };
55
+ }
56
+ }
57
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-packagejson/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAeH,8BAkDC;AA9DD,+DAA0D;AAC1D,yDAAgE;AAChE,mEAA8E;AAU/D,KAAK,UAAU,WAAW,CACrC,OAAmC,EACnC,OAAwB;IAExB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAE3D,IAAI,CAAC;QACD,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAa,GAAE,CAAC;QAEvC,+DAA+D;QAC/D,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,IAAA,qCAAsB,EAAC,QAAQ,CAAC,CAAC;QAEvD,mDAAmD;QACnD,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;QAC7E,MAAM,iBAAiB,GAAG,MAAM,IAAA,mDAA+B,EAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QAE9F,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACnD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3B,KAAK,MAAM,KAAK,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;YAChC,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;YACxF,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;YAChG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAE9D,gBAAgB;QAChB,MAAM,aAAa,GAAG,iBAAiB,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QACnF,MAAM,aAAa,GAAG,iBAAiB,CAAC,cAAc,CAAC,MAAM,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,0BAA0B,aAAa,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,aAAa,aAAa,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,aAAa,GAAG,aAAa,EAAE,CAAC,CAAC;QAE5D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;AACL,CAAC","sourcesContent":["/**\n * Validate Package.json Executor\n *\n * Validates that package.json dependencies match project.json build dependencies.\n * This ensures the two sources of truth don't drift apart.\n *\n * Usage:\n * nx run architecture:validate-packagejson\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport { sortGraphTopologically } from '../../lib/graph-sorter';\nimport { validatePackageJsonDependencies } from '../../lib/package-validator';\n\nexport interface ValidatePackageJsonOptions {\n // No options needed for now\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n options: ValidatePackageJsonOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n\n console.log('\\nšŸ“¦ Validating Package.json Dependencies\\n');\n\n try {\n // Step 1: Generate current graph from project.json files\n console.log('šŸ“Š Generating dependency graph from project.json files...');\n const rawGraph = await generateGraph();\n\n // Step 2: Topological sort (to get enhanced graph with levels)\n console.log('šŸ”„ Computing topological layers...');\n const enhancedGraph = sortGraphTopologically(rawGraph);\n\n // Step 3: Validate package.json dependencies match\n console.log('šŸ“¦ Validating package.json dependencies match project.json...');\n const packageValidation = await validatePackageJsonDependencies(enhancedGraph, workspaceRoot);\n\n if (!packageValidation.valid) {\n console.error('āŒ Package.json validation failed!');\n console.error('\\nErrors:');\n for (const error of packageValidation.errors) {\n console.error(` ${error}`);\n }\n console.error('\\nTo fix:');\n console.error(' 1. Review the missing dependencies above');\n console.error(' 2. Add the missing dependencies to the respective package.json files');\n console.error(' 3. Ensure dependencies in package.json match build.dependsOn in project.json');\n return { success: false };\n }\n\n console.log('āœ… Package.json dependencies match project.json');\n\n // Print summary\n const validProjects = packageValidation.projectResults.filter(r => r.valid).length;\n const totalProjects = packageValidation.projectResults.length;\n console.log(`\\nšŸ“ˆ Validation Summary:`);\n console.log(` Projects validated: ${totalProjects}`);\n console.log(` Valid: ${validProjects}`);\n console.log(` Invalid: ${totalProjects - validProjects}`);\n\n return { success: true };\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error('āŒ Package.json validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Validate Package.json Executor
3
+ *
4
+ * Validates that package.json dependencies match project.json build dependencies.
5
+ * This ensures the two sources of truth don't drift apart.
6
+ *
7
+ * Usage:
8
+ * nx run architecture:validate-packagejson
9
+ */
10
+
11
+ import type { ExecutorContext } from '@nx/devkit';
12
+ import { generateGraph } from '../../lib/graph-generator';
13
+ import { sortGraphTopologically } from '../../lib/graph-sorter';
14
+ import { validatePackageJsonDependencies } from '../../lib/package-validator';
15
+
16
+ export interface ValidatePackageJsonOptions {
17
+ // No options needed for now
18
+ }
19
+
20
+ export interface ExecutorResult {
21
+ success: boolean;
22
+ }
23
+
24
+ export default async function runExecutor(
25
+ options: ValidatePackageJsonOptions,
26
+ context: ExecutorContext
27
+ ): Promise<ExecutorResult> {
28
+ const workspaceRoot = context.root;
29
+
30
+ console.log('\nšŸ“¦ Validating Package.json Dependencies\n');
31
+
32
+ try {
33
+ // Step 1: Generate current graph from project.json files
34
+ console.log('šŸ“Š Generating dependency graph from project.json files...');
35
+ const rawGraph = await generateGraph();
36
+
37
+ // Step 2: Topological sort (to get enhanced graph with levels)
38
+ console.log('šŸ”„ Computing topological layers...');
39
+ const enhancedGraph = sortGraphTopologically(rawGraph);
40
+
41
+ // Step 3: Validate package.json dependencies match
42
+ console.log('šŸ“¦ Validating package.json dependencies match project.json...');
43
+ const packageValidation = await validatePackageJsonDependencies(enhancedGraph, workspaceRoot);
44
+
45
+ if (!packageValidation.valid) {
46
+ console.error('āŒ Package.json validation failed!');
47
+ console.error('\nErrors:');
48
+ for (const error of packageValidation.errors) {
49
+ console.error(` ${error}`);
50
+ }
51
+ console.error('\nTo fix:');
52
+ console.error(' 1. Review the missing dependencies above');
53
+ console.error(' 2. Add the missing dependencies to the respective package.json files');
54
+ console.error(' 3. Ensure dependencies in package.json match build.dependsOn in project.json');
55
+ return { success: false };
56
+ }
57
+
58
+ console.log('āœ… Package.json dependencies match project.json');
59
+
60
+ // Print summary
61
+ const validProjects = packageValidation.projectResults.filter(r => r.valid).length;
62
+ const totalProjects = packageValidation.projectResults.length;
63
+ console.log(`\nšŸ“ˆ Validation Summary:`);
64
+ console.log(` Projects validated: ${totalProjects}`);
65
+ console.log(` Valid: ${validProjects}`);
66
+ console.log(` Invalid: ${totalProjects - validProjects}`);
67
+
68
+ return { success: true };
69
+ } catch (err: unknown) {
70
+ const error = err instanceof Error ? err : new Error(String(err));
71
+ console.error('āŒ Package.json validation failed:', error.message);
72
+ return { success: false };
73
+ }
74
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "title": "Validate Package.json Executor",
4
+ "description": "Validates that package.json dependencies match project.json build dependencies",
5
+ "type": "object",
6
+ "properties": {},
7
+ "required": []
8
+ }
package/executors.json CHANGED
@@ -25,6 +25,11 @@
25
25
  "schema": "./architecture/executors/validate-no-skiplevel-deps/schema.json",
26
26
  "description": "Validate no project has redundant transitive dependencies"
27
27
  },
28
+ "validate-packagejson": {
29
+ "implementation": "./architecture/executors/validate-packagejson/executor",
30
+ "schema": "./architecture/executors/validate-packagejson/schema.json",
31
+ "description": "Validate package.json dependencies match project.json build dependencies"
32
+ },
28
33
  "help": {
29
34
  "implementation": "./executors/help/executor",
30
35
  "schema": "./executors/help/schema.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/dev-config",
3
- "version": "0.2.36",
3
+ "version": "0.2.38",
4
4
  "description": "Development configuration, scripts, and patterns for WebPieces projects",
5
5
  "type": "commonjs",
6
6
  "bin": {
package/plugin.js CHANGED
@@ -157,6 +157,20 @@ function createWorkspaceTargetsWithoutPrefix(opts) {
157
157
  if (opts.workspace.validations.noSkipLevelDeps) {
158
158
  targets['validate-no-skiplevel-deps'] = createValidateNoSkipLevelTarget();
159
159
  }
160
+ // Add validate-complete target that runs all validations
161
+ const validationTargets = [];
162
+ if (opts.workspace.validations.noCycles) {
163
+ validationTargets.push('validate-no-cycles');
164
+ }
165
+ if (opts.workspace.validations.architectureUnchanged) {
166
+ validationTargets.push('validate-architecture-unchanged');
167
+ }
168
+ if (opts.workspace.validations.noSkipLevelDeps) {
169
+ validationTargets.push('validate-no-skiplevel-deps');
170
+ }
171
+ if (validationTargets.length > 0) {
172
+ targets['validate-complete'] = createValidateCompleteTarget(validationTargets);
173
+ }
160
174
  return targets;
161
175
  }
162
176
  /**
@@ -255,6 +269,17 @@ function createValidateNoSkipLevelTarget() {
255
269
  },
256
270
  };
257
271
  }
272
+ function createValidateCompleteTarget(validationTargets) {
273
+ return {
274
+ executor: 'nx:noop',
275
+ cache: true,
276
+ dependsOn: validationTargets,
277
+ metadata: {
278
+ technologies: ['nx'],
279
+ description: 'Run all architecture validations (cycles, unchanged, skip-level deps)',
280
+ },
281
+ };
282
+ }
258
283
  function createHelpTarget() {
259
284
  return {
260
285
  executor: '@webpieces/dev-config:help',
@@ -36,11 +36,11 @@ async function initGenerator(tree, options) {
36
36
  const installTask = addMadgeDependency(tree);
37
37
  createArchitectureDirectory(tree);
38
38
  addNpmScripts(tree);
39
- createEslintConfig(tree);
39
+ const hasExistingEslintConfig = createEslintConfig(tree);
40
40
  if (!options.skipFormat) {
41
41
  await (0, devkit_1.formatFiles)(tree);
42
42
  }
43
- return createSuccessCallback(installTask);
43
+ return createSuccessCallback(installTask, hasExistingEslintConfig);
44
44
  }
45
45
  function registerPlugin(tree) {
46
46
  const nxJson = (0, devkit_1.readNxJson)(tree);
@@ -146,24 +146,8 @@ function createEslintConfig(tree) {
146
146
  // Always create eslint.webpieces.config.mjs with our rules
147
147
  createWebpiecesEslintConfig(tree, webpiecesConfigPath);
148
148
  // Check if main eslint.config.mjs exists
149
- if (tree.exists(mainConfigPath)) {
150
- // Existing config - show them how to import
151
- console.log('');
152
- console.log('šŸ“‹ Existing eslint.config.mjs detected');
153
- console.log('');
154
- console.log('To use @webpieces/dev-config ESLint rules, add this import to your eslint.config.mjs:');
155
- console.log('');
156
- console.log(' import webpiecesConfig from \'./eslint.webpieces.config.mjs\';');
157
- console.log('');
158
- console.log('Then spread it into your config array:');
159
- console.log('');
160
- console.log(' export default [');
161
- console.log(' ...webpiecesConfig, // Add this line');
162
- console.log(' // ... your existing config');
163
- console.log(' ];');
164
- console.log('');
165
- }
166
- else {
149
+ const hasExistingConfig = tree.exists(mainConfigPath);
150
+ if (!hasExistingConfig) {
167
151
  // No existing config - create one that imports webpieces config
168
152
  const mainConfig = `// ESLint configuration
169
153
  // Imports @webpieces/dev-config rules
@@ -180,6 +164,7 @@ export default [
180
164
  tree.write(mainConfigPath, mainConfig);
181
165
  console.log('āœ… Created eslint.config.mjs with @webpieces/dev-config rules');
182
166
  }
167
+ return hasExistingConfig;
183
168
  }
184
169
  function getWebpiecesEslintConfigTemplate(tree) {
185
170
  // Read from canonical template file (single source of truth)
@@ -227,7 +212,7 @@ function createWebpiecesEslintConfig(tree, configPath) {
227
212
  }
228
213
  warnConfigChanges(tree, configPath, webpiecesConfig);
229
214
  }
230
- function createSuccessCallback(installTask) {
215
+ function createSuccessCallback(installTask, hasExistingEslintConfig) {
231
216
  return async () => {
232
217
  await installTask();
233
218
  // ANSI color codes for formatted output
@@ -244,6 +229,22 @@ function createSuccessCallback(installTask) {
244
229
  console.log(` ${BOLD}npm run arch:validate-complete${RESET} # Run complete validation`);
245
230
  console.log('');
246
231
  console.log(`šŸ’” For full documentation, run: ${BOLD}nx run architecture:help${RESET}`);
232
+ // Show ESLint integration instructions if they have an existing config
233
+ if (hasExistingEslintConfig) {
234
+ console.log('');
235
+ console.log('šŸ“‹ Existing eslint.config.mjs detected');
236
+ console.log('');
237
+ console.log('To use @webpieces/dev-config ESLint rules, add this import to your eslint.config.mjs:');
238
+ console.log('');
239
+ console.log(' import webpiecesConfig from \'./eslint.webpieces.config.mjs\';');
240
+ console.log('');
241
+ console.log('Then spread it into your config array:');
242
+ console.log('');
243
+ console.log(' export default [');
244
+ console.log(' ...webpiecesConfig, // Add this line');
245
+ console.log(' // ... your existing config');
246
+ console.log(' ];');
247
+ }
247
248
  console.log('');
248
249
  };
249
250
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/src/generators/init/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatFiles, readNxJson, Tree, updateNxJson, updateJson, addDependenciesToPackageJson } from '@nx/devkit';\nimport { createHash } from 'crypto';\n\nexport interface InitGeneratorSchema {\n skipFormat?: boolean;\n}\n\nfunction calculateHash(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nfunction getPackageVersion(tree: Tree): string {\n const content = tree.read('node_modules/@webpieces/dev-config/package.json', 'utf-8');\n if (!content) {\n throw new Error('Could not read package.json from node_modules/@webpieces/dev-config');\n }\n const pkgJson = JSON.parse(content);\n return pkgJson.version;\n}\n\n/**\n * Init generator for @webpieces/dev-config\n *\n * Automatically runs when users execute: nx add @webpieces/dev-config\n *\n * Responsibilities:\n * - Registers the plugin in nx.json\n * - Adds architecture validation to targetDefaults (runs once before all builds)\n * - Creates architecture/ directory if needed\n * - Adds madge as a devDependency (required for circular dep checking)\n * - Adds convenient npm scripts to package.json\n * - Always creates eslint.webpieces.config.mjs with @webpieces rules\n * - Creates eslint.config.mjs (if not exists) that imports eslint.webpieces.config.mjs\n * - If eslint.config.mjs exists, shows user how to import eslint.webpieces.config.mjs\n * - Provides helpful output about available targets\n */\nexport default async function initGenerator(tree: Tree, options: InitGeneratorSchema) {\n registerPlugin(tree);\n addTargetDefaults(tree);\n const installTask = addMadgeDependency(tree);\n createArchitectureDirectory(tree);\n addNpmScripts(tree);\n createEslintConfig(tree);\n\n if (!options.skipFormat) {\n await formatFiles(tree);\n }\n\n return createSuccessCallback(installTask);\n}\n\nfunction registerPlugin(tree: Tree): void {\n const nxJson = readNxJson(tree);\n if (!nxJson) {\n throw new Error('Could not read nx.json. Are you in an Nx workspace?');\n }\n\n if (!nxJson.plugins) {\n nxJson.plugins = [];\n }\n\n const pluginName = '@webpieces/dev-config';\n const alreadyRegistered = nxJson.plugins.some(\n (p) => typeof p === 'string' ? p === pluginName : p.plugin === pluginName\n );\n\n if (!alreadyRegistered) {\n nxJson.plugins.push(pluginName);\n updateNxJson(tree, nxJson);\n console.log(`āœ… Registered ${pluginName} plugin in nx.json`);\n } else {\n console.log(`ā„¹ļø ${pluginName} plugin is already registered`);\n }\n}\n\nfunction addTargetDefaults(tree: Tree): void {\n const nxJson = readNxJson(tree);\n if (!nxJson) {\n throw new Error('Could not read nx.json. Are you in an Nx workspace?');\n }\n\n if (!nxJson.targetDefaults) {\n nxJson.targetDefaults = {};\n }\n\n // List of common build executors that should validate architecture first\n const buildExecutors = [\n '@nx/js:tsc',\n '@nx/esbuild:esbuild',\n '@nx/webpack:webpack',\n '@nx/rollup:rollup',\n '@nx/vite:build',\n '@angular/build:application',\n '@angular-devkit/build-angular:browser',\n '@angular-devkit/build-angular:application'\n ];\n\n let updated = false;\n\n buildExecutors.forEach((executor) => {\n if (!nxJson.targetDefaults![executor]) {\n nxJson.targetDefaults![executor] = {};\n }\n\n const targetDef = nxJson.targetDefaults![executor];\n let dependsOn = targetDef.dependsOn || [];\n\n // Ensure dependsOn is an array\n if (!Array.isArray(dependsOn)) {\n dependsOn = [dependsOn];\n }\n\n // Check if architecture validation is already in dependsOn\n const hasArchValidation = dependsOn.some((dep) => {\n if (typeof dep === 'string') {\n return dep === 'architecture:validate-complete';\n }\n // Handle object format: { target: 'validate', projects: 'self' }\n return dep.target === 'architecture:validate-complete';\n });\n\n if (!hasArchValidation) {\n // Add architecture validation before other dependencies\n dependsOn.unshift('architecture:validate-complete');\n targetDef.dependsOn = dependsOn;\n updated = true;\n }\n });\n\n if (updated) {\n updateNxJson(tree, nxJson);\n console.log('āœ… Added architecture validation to targetDefaults (runs once before all builds)');\n } else {\n console.log('ā„¹ļø Architecture validation already configured in targetDefaults');\n }\n}\n\nfunction addMadgeDependency(tree: Tree) {\n return addDependenciesToPackageJson(tree, {}, { 'madge': '^8.0.0' });\n}\n\nfunction createArchitectureDirectory(tree: Tree): void {\n if (!tree.exists('architecture')) {\n tree.write('architecture/.gitkeep', '');\n console.log('āœ… Created architecture/ directory');\n }\n}\n\nfunction addNpmScripts(tree: Tree): void {\n updateJson(tree, 'package.json', (pkgJson) => {\n pkgJson.scripts = pkgJson.scripts ?? {};\n\n // Add architecture validation scripts\n pkgJson.scripts['arch:generate'] = 'nx run architecture:generate';\n pkgJson.scripts['arch:visualize'] = 'nx run architecture:visualize';\n pkgJson.scripts['arch:validate'] = 'nx run architecture:validate-no-cycles && nx run architecture:validate-no-skiplevel-deps';\n pkgJson.scripts['arch:validate-all'] = 'nx run architecture:validate-no-cycles && nx run architecture:validate-no-skiplevel-deps && nx run architecture:validate-architecture-unchanged';\n\n // Add circular dependency checking scripts\n pkgJson.scripts['arch:check-circular'] = 'nx run-many --target=check-circular-deps --all';\n pkgJson.scripts['arch:check-circular-affected'] = 'nx affected --target=check-circular-deps';\n\n // Complete validation including circular deps\n pkgJson.scripts['arch:validate-complete'] = 'npm run arch:validate-all && npm run arch:check-circular';\n\n return pkgJson;\n });\n\n console.log('āœ… Added npm scripts for architecture validation and circular dependency checking');\n}\n\nfunction createEslintConfig(tree: Tree): void {\n const webpiecesConfigPath = 'eslint.webpieces.config.mjs';\n const mainConfigPath = 'eslint.config.mjs';\n\n // Always create eslint.webpieces.config.mjs with our rules\n createWebpiecesEslintConfig(tree, webpiecesConfigPath);\n\n // Check if main eslint.config.mjs exists\n if (tree.exists(mainConfigPath)) {\n // Existing config - show them how to import\n console.log('');\n console.log('šŸ“‹ Existing eslint.config.mjs detected');\n console.log('');\n console.log('To use @webpieces/dev-config ESLint rules, add this import to your eslint.config.mjs:');\n console.log('');\n console.log(' import webpiecesConfig from \\'./eslint.webpieces.config.mjs\\';');\n console.log('');\n console.log('Then spread it into your config array:');\n console.log('');\n console.log(' export default [');\n console.log(' ...webpiecesConfig, // Add this line');\n console.log(' // ... your existing config');\n console.log(' ];');\n console.log('');\n } else {\n // No existing config - create one that imports webpieces config\n const mainConfig = `// ESLint configuration\n// Imports @webpieces/dev-config rules\n\nimport webpiecesConfig from './eslint.webpieces.config.mjs';\n\n// Export the webpieces configuration\n// You can add your own rules after spreading webpiecesConfig\nexport default [\n ...webpiecesConfig,\n // Add your custom ESLint configuration here\n];\n`;\n\n tree.write(mainConfigPath, mainConfig);\n console.log('āœ… Created eslint.config.mjs with @webpieces/dev-config rules');\n }\n}\n\nfunction getWebpiecesEslintConfigTemplate(tree: Tree): string {\n // Read from canonical template file (single source of truth)\n const templatePath = 'node_modules/@webpieces/dev-config/templates/eslint.webpieces.config.mjs';\n const template = tree.read(templatePath, 'utf-8');\n\n if (!template) {\n throw new Error(`Could not read ESLint template from ${templatePath}`);\n }\n\n return template;\n}\n\nfunction warnConfigChanges(tree: Tree, configPath: string, newConfig: string): void {\n const version = getPackageVersion(tree);\n const versionedFilename = `${configPath}.v${version}`;\n\n tree.write(versionedFilename, newConfig);\n\n console.log('');\n console.log(`āš ļø ${configPath} has changes`);\n console.log('');\n console.log(' Either you modified the file OR @webpieces/dev-config has updates.');\n console.log('');\n console.log(` Created: ${versionedFilename} with latest version`);\n console.log('');\n console.log(' Please review and merge if needed:');\n console.log(` - Your current: ${configPath}`);\n console.log(` - New version: ${versionedFilename}`);\n console.log('');\n}\n\nfunction createWebpiecesEslintConfig(tree: Tree, configPath: string): void {\n const webpiecesConfig = getWebpiecesEslintConfigTemplate(tree);\n\n if (!tree.exists(configPath)) {\n tree.write(configPath, webpiecesConfig);\n console.log(`āœ… Created ${configPath}`);\n return;\n }\n\n const currentContent = tree.read(configPath, 'utf-8');\n if (!currentContent) {\n tree.write(configPath, webpiecesConfig);\n console.log(`āœ… Created ${configPath}`);\n return;\n }\n\n const currentHash = calculateHash(currentContent);\n const newHash = calculateHash(webpiecesConfig);\n\n if (currentHash === newHash) {\n console.log(`āœ… ${configPath} is up to date`);\n return;\n }\n\n warnConfigChanges(tree, configPath, webpiecesConfig);\n}\n\nfunction createSuccessCallback(installTask: ReturnType<typeof addDependenciesToPackageJson>) {\n return async () => {\n await installTask();\n\n // ANSI color codes for formatted output\n const GREEN = '\\x1b[32m\\x1b[1m';\n const BOLD = '\\x1b[1m';\n const RESET = '\\x1b[0m';\n\n console.log('');\n console.log('āœ… Added madge to devDependencies');\n console.log('');\n console.log(`${GREEN}āœ… @webpieces/dev-config plugin initialized!${RESET}`);\n console.log('');\n console.log(`${GREEN}šŸ’” Quick start:${RESET}`);\n console.log(` ${BOLD}npm run arch:generate${RESET} # Generate the dependency graph`);\n console.log(` ${BOLD}npm run arch:validate-complete${RESET} # Run complete validation`);\n console.log('');\n console.log(`šŸ’” For full documentation, run: ${BOLD}nx run architecture:help${RESET}`);\n console.log('');\n };\n}\n"]}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/src/generators/init/generator.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatFiles, readNxJson, Tree, updateNxJson, updateJson, addDependenciesToPackageJson } from '@nx/devkit';\nimport { createHash } from 'crypto';\n\nexport interface InitGeneratorSchema {\n skipFormat?: boolean;\n}\n\nfunction calculateHash(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nfunction getPackageVersion(tree: Tree): string {\n const content = tree.read('node_modules/@webpieces/dev-config/package.json', 'utf-8');\n if (!content) {\n throw new Error('Could not read package.json from node_modules/@webpieces/dev-config');\n }\n const pkgJson = JSON.parse(content);\n return pkgJson.version;\n}\n\n/**\n * Init generator for @webpieces/dev-config\n *\n * Automatically runs when users execute: nx add @webpieces/dev-config\n *\n * Responsibilities:\n * - Registers the plugin in nx.json\n * - Adds architecture validation to targetDefaults (runs once before all builds)\n * - Creates architecture/ directory if needed\n * - Adds madge as a devDependency (required for circular dep checking)\n * - Adds convenient npm scripts to package.json\n * - Always creates eslint.webpieces.config.mjs with @webpieces rules\n * - Creates eslint.config.mjs (if not exists) that imports eslint.webpieces.config.mjs\n * - If eslint.config.mjs exists, shows user how to import eslint.webpieces.config.mjs\n * - Provides helpful output about available targets\n */\nexport default async function initGenerator(tree: Tree, options: InitGeneratorSchema) {\n registerPlugin(tree);\n addTargetDefaults(tree);\n const installTask = addMadgeDependency(tree);\n createArchitectureDirectory(tree);\n addNpmScripts(tree);\n const hasExistingEslintConfig = createEslintConfig(tree);\n\n if (!options.skipFormat) {\n await formatFiles(tree);\n }\n\n return createSuccessCallback(installTask, hasExistingEslintConfig);\n}\n\nfunction registerPlugin(tree: Tree): void {\n const nxJson = readNxJson(tree);\n if (!nxJson) {\n throw new Error('Could not read nx.json. Are you in an Nx workspace?');\n }\n\n if (!nxJson.plugins) {\n nxJson.plugins = [];\n }\n\n const pluginName = '@webpieces/dev-config';\n const alreadyRegistered = nxJson.plugins.some(\n (p) => typeof p === 'string' ? p === pluginName : p.plugin === pluginName\n );\n\n if (!alreadyRegistered) {\n nxJson.plugins.push(pluginName);\n updateNxJson(tree, nxJson);\n console.log(`āœ… Registered ${pluginName} plugin in nx.json`);\n } else {\n console.log(`ā„¹ļø ${pluginName} plugin is already registered`);\n }\n}\n\nfunction addTargetDefaults(tree: Tree): void {\n const nxJson = readNxJson(tree);\n if (!nxJson) {\n throw new Error('Could not read nx.json. Are you in an Nx workspace?');\n }\n\n if (!nxJson.targetDefaults) {\n nxJson.targetDefaults = {};\n }\n\n // List of common build executors that should validate architecture first\n const buildExecutors = [\n '@nx/js:tsc',\n '@nx/esbuild:esbuild',\n '@nx/webpack:webpack',\n '@nx/rollup:rollup',\n '@nx/vite:build',\n '@angular/build:application',\n '@angular-devkit/build-angular:browser',\n '@angular-devkit/build-angular:application'\n ];\n\n let updated = false;\n\n buildExecutors.forEach((executor) => {\n if (!nxJson.targetDefaults![executor]) {\n nxJson.targetDefaults![executor] = {};\n }\n\n const targetDef = nxJson.targetDefaults![executor];\n let dependsOn = targetDef.dependsOn || [];\n\n // Ensure dependsOn is an array\n if (!Array.isArray(dependsOn)) {\n dependsOn = [dependsOn];\n }\n\n // Check if architecture validation is already in dependsOn\n const hasArchValidation = dependsOn.some((dep) => {\n if (typeof dep === 'string') {\n return dep === 'architecture:validate-complete';\n }\n // Handle object format: { target: 'validate', projects: 'self' }\n return dep.target === 'architecture:validate-complete';\n });\n\n if (!hasArchValidation) {\n // Add architecture validation before other dependencies\n dependsOn.unshift('architecture:validate-complete');\n targetDef.dependsOn = dependsOn;\n updated = true;\n }\n });\n\n if (updated) {\n updateNxJson(tree, nxJson);\n console.log('āœ… Added architecture validation to targetDefaults (runs once before all builds)');\n } else {\n console.log('ā„¹ļø Architecture validation already configured in targetDefaults');\n }\n}\n\nfunction addMadgeDependency(tree: Tree) {\n return addDependenciesToPackageJson(tree, {}, { 'madge': '^8.0.0' });\n}\n\nfunction createArchitectureDirectory(tree: Tree): void {\n if (!tree.exists('architecture')) {\n tree.write('architecture/.gitkeep', '');\n console.log('āœ… Created architecture/ directory');\n }\n}\n\nfunction addNpmScripts(tree: Tree): void {\n updateJson(tree, 'package.json', (pkgJson) => {\n pkgJson.scripts = pkgJson.scripts ?? {};\n\n // Add architecture validation scripts\n pkgJson.scripts['arch:generate'] = 'nx run architecture:generate';\n pkgJson.scripts['arch:visualize'] = 'nx run architecture:visualize';\n pkgJson.scripts['arch:validate'] = 'nx run architecture:validate-no-cycles && nx run architecture:validate-no-skiplevel-deps';\n pkgJson.scripts['arch:validate-all'] = 'nx run architecture:validate-no-cycles && nx run architecture:validate-no-skiplevel-deps && nx run architecture:validate-architecture-unchanged';\n\n // Add circular dependency checking scripts\n pkgJson.scripts['arch:check-circular'] = 'nx run-many --target=check-circular-deps --all';\n pkgJson.scripts['arch:check-circular-affected'] = 'nx affected --target=check-circular-deps';\n\n // Complete validation including circular deps\n pkgJson.scripts['arch:validate-complete'] = 'npm run arch:validate-all && npm run arch:check-circular';\n\n return pkgJson;\n });\n\n console.log('āœ… Added npm scripts for architecture validation and circular dependency checking');\n}\n\nfunction createEslintConfig(tree: Tree): boolean {\n const webpiecesConfigPath = 'eslint.webpieces.config.mjs';\n const mainConfigPath = 'eslint.config.mjs';\n\n // Always create eslint.webpieces.config.mjs with our rules\n createWebpiecesEslintConfig(tree, webpiecesConfigPath);\n\n // Check if main eslint.config.mjs exists\n const hasExistingConfig = tree.exists(mainConfigPath);\n\n if (!hasExistingConfig) {\n // No existing config - create one that imports webpieces config\n const mainConfig = `// ESLint configuration\n// Imports @webpieces/dev-config rules\n\nimport webpiecesConfig from './eslint.webpieces.config.mjs';\n\n// Export the webpieces configuration\n// You can add your own rules after spreading webpiecesConfig\nexport default [\n ...webpiecesConfig,\n // Add your custom ESLint configuration here\n];\n`;\n\n tree.write(mainConfigPath, mainConfig);\n console.log('āœ… Created eslint.config.mjs with @webpieces/dev-config rules');\n }\n\n return hasExistingConfig;\n}\n\nfunction getWebpiecesEslintConfigTemplate(tree: Tree): string {\n // Read from canonical template file (single source of truth)\n const templatePath = 'node_modules/@webpieces/dev-config/templates/eslint.webpieces.config.mjs';\n const template = tree.read(templatePath, 'utf-8');\n\n if (!template) {\n throw new Error(`Could not read ESLint template from ${templatePath}`);\n }\n\n return template;\n}\n\nfunction warnConfigChanges(tree: Tree, configPath: string, newConfig: string): void {\n const version = getPackageVersion(tree);\n const versionedFilename = `${configPath}.v${version}`;\n\n tree.write(versionedFilename, newConfig);\n\n console.log('');\n console.log(`āš ļø ${configPath} has changes`);\n console.log('');\n console.log(' Either you modified the file OR @webpieces/dev-config has updates.');\n console.log('');\n console.log(` Created: ${versionedFilename} with latest version`);\n console.log('');\n console.log(' Please review and merge if needed:');\n console.log(` - Your current: ${configPath}`);\n console.log(` - New version: ${versionedFilename}`);\n console.log('');\n}\n\nfunction createWebpiecesEslintConfig(tree: Tree, configPath: string): void {\n const webpiecesConfig = getWebpiecesEslintConfigTemplate(tree);\n\n if (!tree.exists(configPath)) {\n tree.write(configPath, webpiecesConfig);\n console.log(`āœ… Created ${configPath}`);\n return;\n }\n\n const currentContent = tree.read(configPath, 'utf-8');\n if (!currentContent) {\n tree.write(configPath, webpiecesConfig);\n console.log(`āœ… Created ${configPath}`);\n return;\n }\n\n const currentHash = calculateHash(currentContent);\n const newHash = calculateHash(webpiecesConfig);\n\n if (currentHash === newHash) {\n console.log(`āœ… ${configPath} is up to date`);\n return;\n }\n\n warnConfigChanges(tree, configPath, webpiecesConfig);\n}\n\nfunction createSuccessCallback(\n installTask: ReturnType<typeof addDependenciesToPackageJson>,\n hasExistingEslintConfig: boolean\n) {\n return async () => {\n await installTask();\n\n // ANSI color codes for formatted output\n const GREEN = '\\x1b[32m\\x1b[1m';\n const BOLD = '\\x1b[1m';\n const RESET = '\\x1b[0m';\n\n console.log('');\n console.log('āœ… Added madge to devDependencies');\n console.log('');\n console.log(`${GREEN}āœ… @webpieces/dev-config plugin initialized!${RESET}`);\n console.log('');\n console.log(`${GREEN}šŸ’” Quick start:${RESET}`);\n console.log(` ${BOLD}npm run arch:generate${RESET} # Generate the dependency graph`);\n console.log(` ${BOLD}npm run arch:validate-complete${RESET} # Run complete validation`);\n console.log('');\n console.log(`šŸ’” For full documentation, run: ${BOLD}nx run architecture:help${RESET}`);\n\n // Show ESLint integration instructions if they have an existing config\n if (hasExistingEslintConfig) {\n console.log('');\n console.log('šŸ“‹ Existing eslint.config.mjs detected');\n console.log('');\n console.log('To use @webpieces/dev-config ESLint rules, add this import to your eslint.config.mjs:');\n console.log('');\n console.log(' import webpiecesConfig from \\'./eslint.webpieces.config.mjs\\';');\n console.log('');\n console.log('Then spread it into your config array:');\n console.log('');\n console.log(' export default [');\n console.log(' ...webpiecesConfig, // Add this line');\n console.log(' // ... your existing config');\n console.log(' ];');\n }\n\n console.log('');\n };\n}\n"]}