@webpieces/nx-webpieces-rules 0.3.281 → 0.3.284

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/nx-webpieces-rules",
3
- "version": "0.3.281",
3
+ "version": "0.3.284",
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",
@@ -21,11 +21,11 @@
21
21
  "README.md"
22
22
  ],
23
23
  "dependencies": {
24
- "@webpieces/ai-hook-rules": "0.3.281",
25
- "@webpieces/code-rules": "0.3.281",
26
- "@webpieces/eslint-rules": "0.3.281",
27
- "@webpieces/pr-gate": "0.3.281",
28
- "@webpieces/rules-config": "0.3.281",
24
+ "@webpieces/ai-hook-rules": "0.3.284",
25
+ "@webpieces/code-rules": "0.3.284",
26
+ "@webpieces/eslint-rules": "0.3.284",
27
+ "@webpieces/pr-gate": "0.3.284",
28
+ "@webpieces/rules-config": "0.3.284",
29
29
  "madge": "8.0.0"
30
30
  },
31
31
  "peerDependencies": {
@@ -19,10 +19,10 @@ const tslib_1 = require("tslib");
19
19
  const fs = tslib_1.__importStar(require("fs"));
20
20
  const path = tslib_1.__importStar(require("path"));
21
21
  const readline = tslib_1.__importStar(require("readline"));
22
+ const rules_config_1 = require("@webpieces/rules-config");
22
23
  const design_finder_1 = require("../lib/di-graph/design-finder");
23
24
  const design_visualizer_1 = require("../lib/di-graph/design-visualizer");
24
25
  const graph_visualizer_1 = require("../lib/graph-visualizer");
25
- const toError_1 = require("../toError");
26
26
  /** Walk up from cwd to the workspace root (dir containing nx.json). */
27
27
  function findWorkspaceRoot() {
28
28
  let dir = process.cwd();
@@ -74,8 +74,7 @@ async function main() {
74
74
  const workspaceRoot = findWorkspaceRoot();
75
75
  const files = (0, design_finder_1.findDesignFiles)(workspaceRoot);
76
76
  if (files.length === 0) {
77
- console.error('❌ No design.json files found. Run a build or: pnpm nx run-many --target=di-graph-generate');
78
- process.exit(1);
77
+ throw new rules_config_1.CliExitError(1, '❌ No design.json files found. Run a build or: pnpm nx run-many --target=di-graph-generate');
79
78
  }
80
79
  let selections = process.argv.slice(2);
81
80
  if (selections.length === 0) {
@@ -91,9 +90,6 @@ async function main() {
91
90
  renderOne(file, workspaceRoot);
92
91
  }
93
92
  }
94
- main().catch((err) => {
95
- const error = (0, toError_1.toError)(err);
96
- console.error('❌', error.message);
97
- process.exit(1);
98
- });
93
+ if (require.main === module)
94
+ (0, rules_config_1.runMain)(main);
99
95
  //# sourceMappingURL=wp-design-visualize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wp-design-visualize.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/scripts/wp-design-visualize.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * wp-design-visualize — open per-project DI design graphs as Graphviz HTML.\n *\n * Usage:\n * wp-design-visualize interactive picker (numbered list)\n * wp-design-visualize <name|substring>… render matching project(s)\n * wp-design-visualize all render every project\n *\n * Reads each project's committed design.json (schemaVersion 2 — one design\n * per controller/root) and writes tmp/webpieces/design-<project>.html with\n * one graph PER CONTROLLER, the controller (level 0) at the top. Replaces the\n * old mermaid-based scripts/design-visualize.sh (which only showed the first\n * controller).\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport { DesignFileRef, findDesignFiles, resolveSelections } from '../lib/di-graph/design-finder';\nimport { writeDesignVisualization } from '../lib/di-graph/design-visualizer';\nimport { openVisualization } from '../lib/graph-visualizer';\nimport { DiGraph } from '../lib/di-graph/model';\nimport { toError } from '../toError';\n\n/** Walk up from cwd to the workspace root (dir containing nx.json). */\nfunction findWorkspaceRoot(): string {\n let dir = process.cwd();\n for (let i = 0; i < 20; i++) {\n if (fs.existsSync(path.join(dir, 'nx.json'))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return process.cwd();\n}\n\nfunction printList(files: DesignFileRef[]): void {\n console.log('\\nDI design graphs found:\\n');\n files.forEach((file: DesignFileRef, index: number) => {\n console.log(` ${String(index + 1).padStart(3)}. ${file.project.padEnd(24)} ${file.relPath}`);\n });\n console.log('');\n}\n\n/** Prompt for selections: numbers, names/substrings, or \"all\" (blank = cancel). */\nfunction promptSelections(): Promise<string[]> {\n return new Promise((resolve: (selections: string[]) => void) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question('Which designs? (numbers / names / all, blank to cancel): ', (answer: string) => {\n rl.close();\n resolve(answer.split(/[\\s,]+/).filter((part: string) => part.length > 0));\n });\n });\n}\n\nfunction loadDiGraph(file: DesignFileRef): DiGraph {\n const parsed = JSON.parse(fs.readFileSync(file.absPath, 'utf-8'));\n if (!Array.isArray(parsed.designs)) {\n throw new Error(\n `${file.relPath} is an old-format design.json (schemaVersion ${parsed.schemaVersion ?? 1}). ` +\n `Regenerate it with: pnpm nx run ${file.project}:di-graph-generate`\n );\n }\n return parsed as DiGraph;\n}\n\nfunction renderOne(file: DesignFileRef, workspaceRoot: string): void {\n const graph = loadDiGraph(file);\n const paths = writeDesignVisualization(graph, workspaceRoot);\n const designCount = graph.designs.length;\n console.log(`✅ ${file.project}: ${designCount} design(s) → ${paths.htmlPath}`);\n if (!openVisualization(paths.htmlPath)) {\n console.log(`⚠️ Could not auto-open. Open manually: ${paths.htmlPath}`);\n }\n}\n\nasync function main(): Promise<void> {\n const workspaceRoot = findWorkspaceRoot();\n const files = findDesignFiles(workspaceRoot);\n\n if (files.length === 0) {\n console.error('❌ No design.json files found. Run a build or: pnpm nx run-many --target=di-graph-generate');\n process.exit(1);\n }\n\n let selections = process.argv.slice(2);\n if (selections.length === 0) {\n printList(files);\n selections = await promptSelections();\n if (selections.length === 0) {\n console.log('Cancelled.');\n return;\n }\n }\n\n const picked = resolveSelections(selections, files);\n for (const file of picked) {\n renderOne(file, workspaceRoot);\n }\n}\n\nmain().catch((err: Error) => {\n const error = toError(err);\n console.error('❌', error.message);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"file":"wp-design-visualize.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/scripts/wp-design-visualize.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * wp-design-visualize — open per-project DI design graphs as Graphviz HTML.\n *\n * Usage:\n * wp-design-visualize interactive picker (numbered list)\n * wp-design-visualize <name|substring>… render matching project(s)\n * wp-design-visualize all render every project\n *\n * Reads each project's committed design.json (schemaVersion 2 — one design\n * per controller/root) and writes tmp/webpieces/design-<project>.html with\n * one graph PER CONTROLLER, the controller (level 0) at the top. Replaces the\n * old mermaid-based scripts/design-visualize.sh (which only showed the first\n * controller).\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport { CliExitError, runMain } from '@webpieces/rules-config';\nimport { DesignFileRef, findDesignFiles, resolveSelections } from '../lib/di-graph/design-finder';\nimport { writeDesignVisualization } from '../lib/di-graph/design-visualizer';\nimport { openVisualization } from '../lib/graph-visualizer';\nimport { DiGraph } from '../lib/di-graph/model';\n\n/** Walk up from cwd to the workspace root (dir containing nx.json). */\nfunction findWorkspaceRoot(): string {\n let dir = process.cwd();\n for (let i = 0; i < 20; i++) {\n if (fs.existsSync(path.join(dir, 'nx.json'))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return process.cwd();\n}\n\nfunction printList(files: DesignFileRef[]): void {\n console.log('\\nDI design graphs found:\\n');\n files.forEach((file: DesignFileRef, index: number) => {\n console.log(` ${String(index + 1).padStart(3)}. ${file.project.padEnd(24)} ${file.relPath}`);\n });\n console.log('');\n}\n\n/** Prompt for selections: numbers, names/substrings, or \"all\" (blank = cancel). */\nfunction promptSelections(): Promise<string[]> {\n return new Promise((resolve: (selections: string[]) => void) => {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n rl.question('Which designs? (numbers / names / all, blank to cancel): ', (answer: string) => {\n rl.close();\n resolve(answer.split(/[\\s,]+/).filter((part: string) => part.length > 0));\n });\n });\n}\n\nfunction loadDiGraph(file: DesignFileRef): DiGraph {\n const parsed = JSON.parse(fs.readFileSync(file.absPath, 'utf-8'));\n if (!Array.isArray(parsed.designs)) {\n throw new Error(\n `${file.relPath} is an old-format design.json (schemaVersion ${parsed.schemaVersion ?? 1}). ` +\n `Regenerate it with: pnpm nx run ${file.project}:di-graph-generate`\n );\n }\n return parsed as DiGraph;\n}\n\nfunction renderOne(file: DesignFileRef, workspaceRoot: string): void {\n const graph = loadDiGraph(file);\n const paths = writeDesignVisualization(graph, workspaceRoot);\n const designCount = graph.designs.length;\n console.log(`✅ ${file.project}: ${designCount} design(s) → ${paths.htmlPath}`);\n if (!openVisualization(paths.htmlPath)) {\n console.log(`⚠️ Could not auto-open. Open manually: ${paths.htmlPath}`);\n }\n}\n\nasync function main(): Promise<void> {\n const workspaceRoot = findWorkspaceRoot();\n const files = findDesignFiles(workspaceRoot);\n\n if (files.length === 0) {\n throw new CliExitError(1, '❌ No design.json files found. Run a build or: pnpm nx run-many --target=di-graph-generate');\n }\n\n let selections = process.argv.slice(2);\n if (selections.length === 0) {\n printList(files);\n selections = await promptSelections();\n if (selections.length === 0) {\n console.log('Cancelled.');\n return;\n }\n }\n\n const picked = resolveSelections(selections, files);\n for (const file of picked) {\n renderOne(file, workspaceRoot);\n }\n}\n\nif (require.main === module) runMain(main);\n"]}