@webpieces/nx-webpieces-rules 0.0.1 → 0.2.114
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 +4 -4
- package/src/executor-result.d.ts +4 -0
- package/src/executor-result.js +10 -0
- package/src/executor-result.js.map +1 -0
- package/src/executors/generate/executor.d.ts +16 -0
- package/src/executors/generate/{executor.ts → executor.js} +15 -30
- package/src/executors/generate/executor.js.map +1 -0
- package/src/executors/help/executor.d.ts +8 -0
- package/src/executors/help/{executor.ts → executor.js} +5 -12
- package/src/executors/help/executor.js.map +1 -0
- package/src/executors/validate-architecture-unchanged/executor.d.ts +17 -0
- package/src/executors/validate-architecture-unchanged/{executor.ts → executor.js} +24 -46
- package/src/executors/validate-architecture-unchanged/executor.js.map +1 -0
- package/src/executors/validate-catch-error-pattern/executor.d.ts +3 -0
- package/src/executors/validate-catch-error-pattern/executor.js +10 -0
- package/src/executors/validate-catch-error-pattern/executor.js.map +1 -0
- package/src/executors/validate-code/executor.d.ts +3 -0
- package/src/executors/validate-code/executor.js +10 -0
- package/src/executors/validate-code/executor.js.map +1 -0
- package/src/executors/validate-dtos/executor.d.ts +3 -0
- package/src/executors/validate-dtos/executor.js +10 -0
- package/src/executors/validate-dtos/executor.js.map +1 -0
- package/src/executors/validate-eslint-sync/executor.d.ts +7 -0
- package/src/executors/validate-eslint-sync/{executor.ts → executor.js} +19 -37
- package/src/executors/validate-eslint-sync/executor.js.map +1 -0
- package/src/executors/validate-modified-files/executor.d.ts +3 -0
- package/src/executors/validate-modified-files/executor.js +10 -0
- package/src/executors/validate-modified-files/executor.js.map +1 -0
- package/src/executors/validate-modified-methods/executor.d.ts +3 -0
- package/src/executors/validate-modified-methods/executor.js +10 -0
- package/src/executors/validate-modified-methods/executor.js.map +1 -0
- package/src/executors/validate-new-methods/executor.d.ts +3 -0
- package/src/executors/validate-new-methods/executor.js +10 -0
- package/src/executors/validate-new-methods/executor.js.map +1 -0
- package/src/executors/validate-no-any-unknown/executor.d.ts +3 -0
- package/src/executors/validate-no-any-unknown/executor.js +10 -0
- package/src/executors/validate-no-any-unknown/executor.js.map +1 -0
- package/src/executors/validate-no-architecture-cycles/executor.d.ts +16 -0
- package/src/executors/validate-no-architecture-cycles/{executor.ts → executor.js} +16 -28
- package/src/executors/validate-no-architecture-cycles/executor.js.map +1 -0
- package/src/executors/validate-no-destructure/executor.d.ts +3 -0
- package/src/executors/validate-no-destructure/executor.js +10 -0
- package/src/executors/validate-no-destructure/executor.js.map +1 -0
- package/src/executors/validate-no-direct-api-resolver/executor.d.ts +3 -0
- package/src/executors/validate-no-direct-api-resolver/executor.js +10 -0
- package/src/executors/validate-no-direct-api-resolver/executor.js.map +1 -0
- package/src/executors/validate-no-implicit-any/executor.d.ts +3 -0
- package/src/executors/validate-no-implicit-any/executor.js +10 -0
- package/src/executors/validate-no-implicit-any/executor.js.map +1 -0
- package/src/executors/validate-no-inline-types/executor.d.ts +3 -0
- package/src/executors/validate-no-inline-types/executor.js +10 -0
- package/src/executors/validate-no-inline-types/executor.js.map +1 -0
- package/src/executors/validate-no-skiplevel-deps/executor.d.ts +19 -0
- package/src/executors/validate-no-skiplevel-deps/{executor.ts → executor.js} +23 -63
- package/src/executors/validate-no-skiplevel-deps/executor.js.map +1 -0
- package/src/executors/validate-no-unmanaged-exceptions/executor.d.ts +3 -0
- package/src/executors/validate-no-unmanaged-exceptions/executor.js +10 -0
- package/src/executors/validate-no-unmanaged-exceptions/executor.js.map +1 -0
- package/src/executors/validate-packagejson/executor.d.ts +16 -0
- package/src/executors/validate-packagejson/{executor.ts → executor.js} +15 -32
- package/src/executors/validate-packagejson/executor.js.map +1 -0
- package/src/executors/validate-prisma-converters/executor.d.ts +3 -0
- package/src/executors/validate-prisma-converters/executor.js +10 -0
- package/src/executors/validate-prisma-converters/executor.js.map +1 -0
- package/src/executors/validate-return-types/executor.d.ts +3 -0
- package/src/executors/validate-return-types/executor.js +10 -0
- package/src/executors/validate-return-types/executor.js.map +1 -0
- package/src/executors/validate-ts-in-src/executor.d.ts +32 -0
- package/src/executors/validate-ts-in-src/{executor.ts → executor.js} +80 -135
- package/src/executors/validate-ts-in-src/executor.js.map +1 -0
- package/src/executors/validate-versions-locked/executor.d.ts +22 -0
- package/src/executors/validate-versions-locked/{executor.ts → executor.js} +49 -116
- package/src/executors/validate-versions-locked/executor.js.map +1 -0
- package/src/executors/visualize/executor.d.ts +17 -0
- package/src/executors/visualize/{executor.ts → executor.js} +16 -30
- package/src/executors/visualize/executor.js.map +1 -0
- package/src/{index.ts → index.d.ts} +5 -1
- package/src/index.js +14 -0
- package/src/index.js.map +1 -0
- package/src/lib/graph-comparator.d.ts +39 -0
- package/src/lib/{graph-comparator.ts → graph-comparator.js} +18 -67
- package/src/lib/graph-comparator.js.map +1 -0
- package/src/lib/graph-generator.d.ts +19 -0
- package/src/lib/{graph-generator.ts → graph-generator.js} +17 -30
- package/src/lib/graph-generator.js.map +1 -0
- package/src/lib/graph-loader.d.ts +31 -0
- package/src/lib/{graph-loader.ts → graph-loader.js} +24 -42
- package/src/lib/graph-loader.js.map +1 -0
- package/src/lib/graph-sorter.d.ts +37 -0
- package/src/lib/{graph-sorter.ts → graph-sorter.js} +26 -53
- package/src/lib/graph-sorter.js.map +1 -0
- package/src/lib/graph-visualizer.d.ts +31 -0
- package/src/lib/{graph-visualizer.ts → graph-visualizer.js} +32 -56
- package/src/lib/graph-visualizer.js.map +1 -0
- package/src/lib/package-validator.d.ts +40 -0
- package/src/lib/package-validator.js +175 -0
- package/src/lib/package-validator.js.map +1 -0
- package/src/plugin.d.ts +86 -0
- package/src/{plugin.ts → plugin.js} +100 -255
- package/src/plugin.js.map +1 -0
- package/src/toError.d.ts +5 -0
- package/src/{toError.ts → toError.js} +7 -6
- package/src/toError.js.map +1 -0
- package/LICENSE +0 -373
- package/src/executor-result.ts +0 -7
- package/src/executors/validate-catch-error-pattern/executor.ts +0 -11
- package/src/executors/validate-code/executor.ts +0 -11
- package/src/executors/validate-dtos/executor.ts +0 -11
- package/src/executors/validate-modified-files/executor.ts +0 -11
- package/src/executors/validate-modified-methods/executor.ts +0 -11
- package/src/executors/validate-new-methods/executor.ts +0 -11
- package/src/executors/validate-no-any-unknown/executor.ts +0 -11
- package/src/executors/validate-no-destructure/executor.ts +0 -11
- package/src/executors/validate-no-direct-api-resolver/executor.ts +0 -11
- package/src/executors/validate-no-implicit-any/executor.ts +0 -11
- package/src/executors/validate-no-inline-types/executor.ts +0 -11
- package/src/executors/validate-no-unmanaged-exceptions/executor.ts +0 -11
- package/src/executors/validate-prisma-converters/executor.ts +0 -11
- package/src/executors/validate-return-types/executor.ts +0 -11
- package/src/lib/package-validator.ts +0 -184
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-modified-methods/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAAgE;AAEjD,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,oCAAuB,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateModifiedMethods } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateModifiedMethods(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNewMethods)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-new-methods/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAA2D;AAE5C,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,+BAAkB,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNewMethods } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNewMethods(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNoAnyUnknown)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-any-unknown/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAA6D;AAE9C,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,iCAAoB,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNoAnyUnknown } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNoAnyUnknown(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate No Architecture Cycles Executor
|
|
3
|
+
*
|
|
4
|
+
* Validates that the architecture dependency graph has no circular dependencies.
|
|
5
|
+
* This is a fast check that only validates acyclicity at the project level.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* nx run architecture:validate-no-architecture-cycles
|
|
9
|
+
*/
|
|
10
|
+
import type { ExecutorContext } from '@nx/devkit';
|
|
11
|
+
export interface ValidateNoCyclesOptions {
|
|
12
|
+
}
|
|
13
|
+
export interface ExecutorResult {
|
|
14
|
+
success: boolean;
|
|
15
|
+
}
|
|
16
|
+
export default function runExecutor(_options: ValidateNoCyclesOptions, _context: ExecutorContext): Promise<ExecutorResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Validate No Architecture Cycles Executor
|
|
3
4
|
*
|
|
@@ -7,46 +8,31 @@
|
|
|
7
8
|
* Usage:
|
|
8
9
|
* nx run architecture:validate-no-architecture-cycles
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export interface ValidateNoCyclesOptions {
|
|
17
|
-
// No options needed
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ExecutorResult {
|
|
21
|
-
success: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default async function runExecutor(
|
|
25
|
-
_options: ValidateNoCyclesOptions,
|
|
26
|
-
_context: ExecutorContext
|
|
27
|
-
): Promise<ExecutorResult> {
|
|
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 toError_1 = require("../../toError");
|
|
16
|
+
async function runExecutor(_options, _context) {
|
|
28
17
|
console.log('\n🔄 Validating No Circular Dependencies\n');
|
|
29
|
-
|
|
30
18
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
31
19
|
try {
|
|
32
20
|
// Step 1: Generate current graph from project.json files
|
|
33
21
|
console.log('📊 Generating dependency graph from project.json files...');
|
|
34
|
-
const rawGraph = await generateGraph();
|
|
35
|
-
|
|
22
|
+
const rawGraph = await (0, graph_generator_1.generateGraph)();
|
|
36
23
|
// Step 2: Topological sort (validates acyclic)
|
|
37
24
|
console.log('🔄 Checking for cycles (topological sort)...');
|
|
38
25
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
39
26
|
try {
|
|
40
|
-
sortGraphTopologically(rawGraph);
|
|
27
|
+
(0, graph_sorter_1.sortGraphTopologically)(rawGraph);
|
|
41
28
|
console.log('✅ No circular dependencies detected!');
|
|
42
|
-
|
|
43
29
|
// Print summary
|
|
44
30
|
const projectCount = Object.keys(rawGraph).length;
|
|
45
31
|
console.log(`\n📈 Summary: ${projectCount} projects, all acyclic`);
|
|
46
|
-
|
|
47
32
|
return { success: true };
|
|
48
|
-
}
|
|
49
|
-
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
const error = (0, toError_1.toError)(err);
|
|
50
36
|
console.error('❌ Circular dependency detected!');
|
|
51
37
|
console.error(error.message);
|
|
52
38
|
console.error('\nTo fix:');
|
|
@@ -55,9 +41,11 @@ export default async function runExecutor(
|
|
|
55
41
|
console.error(' 3. Run this check again');
|
|
56
42
|
return { success: false };
|
|
57
43
|
}
|
|
58
|
-
}
|
|
59
|
-
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const error = (0, toError_1.toError)(err);
|
|
60
47
|
console.error('❌ Cycle validation failed:', error.message);
|
|
61
48
|
return { success: false };
|
|
62
49
|
}
|
|
63
50
|
}
|
|
51
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-architecture-cycles/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAeH,8BAuCC;AAnDD,+DAA0D;AAC1D,yDAAgE;AAChE,2CAAwC;AAUzB,KAAK,UAAU,WAAW,CACrC,QAAiC,EACjC,QAAyB;IAEzB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAE1D,8DAA8D;IAC9D,IAAI,CAAC;QACD,yDAAyD;QACzD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAa,GAAE,CAAC;QAEvC,+CAA+C;QAC/C,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,8DAA8D;QAC9D,IAAI,CAAC;YACD,IAAA,qCAAsB,EAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;YAEpD,gBAAgB;YAChB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,iBAAiB,YAAY,wBAAwB,CAAC,CAAC;YAEnE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAA,iBAAO,EAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACjD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAClE,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,iBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,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 * Validate No Architecture Cycles Executor\n *\n * Validates that the architecture dependency graph has no circular dependencies.\n * This is a fast check that only validates acyclicity at the project level.\n *\n * Usage:\n * nx run architecture:validate-no-architecture-cycles\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport { sortGraphTopologically } from '../../lib/graph-sorter';\nimport { toError } from '../../toError';\n\nexport interface ValidateNoCyclesOptions {\n // No options needed\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\nexport default async function runExecutor(\n _options: ValidateNoCyclesOptions,\n _context: ExecutorContext\n): Promise<ExecutorResult> {\n console.log('\\n🔄 Validating No Circular Dependencies\\n');\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\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)\n console.log('🔄 Checking for cycles (topological sort)...');\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n sortGraphTopologically(rawGraph);\n console.log('✅ No circular dependencies detected!');\n\n // Print summary\n const projectCount = Object.keys(rawGraph).length;\n console.log(`\\n📈 Summary: ${projectCount} projects, all acyclic`);\n\n return { success: true };\n } catch (err: unknown) {\n const error = toError(err);\n console.error('❌ Circular dependency detected!');\n console.error(error.message);\n console.error('\\nTo fix:');\n console.error(' 1. Review the cycle above');\n console.error(' 2. Break the cycle by refactoring dependencies');\n console.error(' 3. Run this check again');\n return { success: false };\n }\n } catch (err: unknown) {\n const error = toError(err);\n console.error('❌ Cycle validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNoDestructure)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-destructure/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAA8D;AAE/C,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,kCAAqB,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNoDestructure } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNoDestructure(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNoDirectApiResolver)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-direct-api-resolver/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAAoE;AAErD,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,wCAA2B,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNoDirectApiResolver } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNoDirectApiResolver(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNoImplicitAny)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-implicit-any/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAA8D;AAE/C,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,kCAAqB,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNoImplicitAny } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNoImplicitAny(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNoInlineTypes)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-inline-types/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAA8D;AAE/C,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,kCAAqB,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNoInlineTypes } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNoInlineTypes(options, context.root);\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate No Skip-Level Dependencies Executor
|
|
3
|
+
*
|
|
4
|
+
* Validates that no project has redundant transitive dependencies.
|
|
5
|
+
* If project A depends on B, and B transitively brings in C, then A should NOT
|
|
6
|
+
* also directly depend on C (it's redundant and clutters the dependency graph).
|
|
7
|
+
*
|
|
8
|
+
* This keeps the architecture graph clean for visualization and human understanding.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* nx run architecture:validate-no-skiplevel-deps
|
|
12
|
+
*/
|
|
13
|
+
import type { ExecutorContext } from '@nx/devkit';
|
|
14
|
+
export interface ValidateNoSkipLevelDepsOptions {
|
|
15
|
+
}
|
|
16
|
+
export interface ExecutorResult {
|
|
17
|
+
success: boolean;
|
|
18
|
+
}
|
|
19
|
+
export default function runExecutor(_options: ValidateNoSkipLevelDepsOptions, context: ExecutorContext): Promise<ExecutorResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Validate No Skip-Level Dependencies Executor
|
|
3
4
|
*
|
|
@@ -10,27 +11,13 @@
|
|
|
10
11
|
* Usage:
|
|
11
12
|
* nx run architecture:validate-no-skiplevel-deps
|
|
12
13
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export interface ValidateNoSkipLevelDepsOptions {
|
|
21
|
-
// No options needed
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ExecutorResult {
|
|
25
|
-
success: boolean;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface RedundantDep {
|
|
29
|
-
project: string;
|
|
30
|
-
redundantDep: string;
|
|
31
|
-
alreadyBroughtInBy: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.default = runExecutor;
|
|
16
|
+
const tslib_1 = require("tslib");
|
|
17
|
+
const graph_generator_1 = require("../../lib/graph-generator");
|
|
18
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
19
|
+
const path = tslib_1.__importStar(require("path"));
|
|
20
|
+
const toError_1 = require("../../toError");
|
|
34
21
|
const TRANSITIVE_DEPS_DOC = `# AI Agent Instructions: Redundant Transitive Dependency Violation
|
|
35
22
|
|
|
36
23
|
**READ THIS FILE FIRST before making any changes!**
|
|
@@ -134,22 +121,15 @@ npm run build-all
|
|
|
134
121
|
- Only declare what you DIRECTLY need that isn't already transitively available
|
|
135
122
|
- When in doubt, check with \`npx nx run architecture:visualize\`
|
|
136
123
|
`;
|
|
137
|
-
|
|
138
124
|
/**
|
|
139
125
|
* Compute all transitive dependencies for a project
|
|
140
126
|
*/
|
|
141
|
-
function computeTransitiveDeps(
|
|
142
|
-
|
|
143
|
-
graph: Record<string, string[]>,
|
|
144
|
-
visited: Set<string> = new Set()
|
|
145
|
-
): Set<string> {
|
|
146
|
-
const result = new Set<string>();
|
|
147
|
-
|
|
127
|
+
function computeTransitiveDeps(project, graph, visited = new Set()) {
|
|
128
|
+
const result = new Set();
|
|
148
129
|
if (visited.has(project)) {
|
|
149
130
|
return result;
|
|
150
131
|
}
|
|
151
132
|
visited.add(project);
|
|
152
|
-
|
|
153
133
|
const directDeps = graph[project] || [];
|
|
154
134
|
for (const dep of directDeps) {
|
|
155
135
|
result.add(dep);
|
|
@@ -159,26 +139,19 @@ function computeTransitiveDeps(
|
|
|
159
139
|
result.add(t);
|
|
160
140
|
}
|
|
161
141
|
}
|
|
162
|
-
|
|
163
142
|
return result;
|
|
164
143
|
}
|
|
165
|
-
|
|
166
144
|
/**
|
|
167
145
|
* Find redundant dependencies for a project
|
|
168
146
|
*/
|
|
169
|
-
function findRedundantDeps(
|
|
170
|
-
|
|
171
|
-
graph: Record<string, string[]>
|
|
172
|
-
): RedundantDep[] {
|
|
173
|
-
const redundant: RedundantDep[] = [];
|
|
147
|
+
function findRedundantDeps(project, graph) {
|
|
148
|
+
const redundant = [];
|
|
174
149
|
const directDeps = graph[project] || [];
|
|
175
|
-
|
|
176
150
|
// For each direct dependency, compute what it transitively brings in
|
|
177
|
-
const transitiveByDep = new Map
|
|
151
|
+
const transitiveByDep = new Map();
|
|
178
152
|
for (const dep of directDeps) {
|
|
179
153
|
transitiveByDep.set(dep, computeTransitiveDeps(dep, graph));
|
|
180
154
|
}
|
|
181
|
-
|
|
182
155
|
// Check if any direct dependency is already brought in by another
|
|
183
156
|
const transitiveEntries = Array.from(transitiveByDep.entries());
|
|
184
157
|
for (const dep of directDeps) {
|
|
@@ -195,80 +168,67 @@ function findRedundantDeps(
|
|
|
195
168
|
}
|
|
196
169
|
}
|
|
197
170
|
}
|
|
198
|
-
|
|
199
171
|
return redundant;
|
|
200
172
|
}
|
|
201
|
-
|
|
202
173
|
/**
|
|
203
174
|
* Write documentation file when violations are found
|
|
204
175
|
*/
|
|
205
|
-
function writeDocFile(workspaceRoot
|
|
176
|
+
function writeDocFile(workspaceRoot) {
|
|
206
177
|
const docPath = path.join(workspaceRoot, '.webpieces', 'instruct-ai', 'webpieces.transitivedeps.md');
|
|
207
178
|
const docDir = path.dirname(docPath);
|
|
208
|
-
|
|
209
179
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
210
180
|
try {
|
|
211
181
|
fs.mkdirSync(docDir, { recursive: true });
|
|
212
182
|
fs.writeFileSync(docPath, TRANSITIVE_DEPS_DOC, 'utf-8');
|
|
213
|
-
}
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
214
185
|
//const error = toError(err);
|
|
215
186
|
void err;
|
|
216
187
|
console.warn(`Could not write documentation file: ${docPath}`);
|
|
217
188
|
}
|
|
218
189
|
}
|
|
219
|
-
|
|
220
|
-
export default async function runExecutor(
|
|
221
|
-
_options: ValidateNoSkipLevelDepsOptions,
|
|
222
|
-
context: ExecutorContext
|
|
223
|
-
): Promise<ExecutorResult> {
|
|
190
|
+
async function runExecutor(_options, context) {
|
|
224
191
|
console.log('\n🔄 Validating No Skip-Level Dependencies\n');
|
|
225
|
-
|
|
226
192
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
227
193
|
try {
|
|
228
194
|
// Step 1: Generate current graph from project.json files
|
|
229
195
|
console.log('📊 Generating dependency graph from project.json files...');
|
|
230
|
-
const graph = await generateGraph();
|
|
231
|
-
|
|
196
|
+
const graph = await (0, graph_generator_1.generateGraph)();
|
|
232
197
|
// Step 2: Find all redundant dependencies
|
|
233
198
|
console.log('🔍 Checking for redundant transitive dependencies...');
|
|
234
|
-
const allRedundant
|
|
235
|
-
|
|
199
|
+
const allRedundant = [];
|
|
236
200
|
for (const project of Object.keys(graph)) {
|
|
237
201
|
const redundant = findRedundantDeps(project, graph);
|
|
238
202
|
allRedundant.push(...redundant);
|
|
239
203
|
}
|
|
240
|
-
|
|
241
204
|
if (allRedundant.length === 0) {
|
|
242
205
|
console.log('✅ No redundant transitive dependencies detected!');
|
|
243
206
|
console.log('\n📈 Graph is clean and minimal.');
|
|
244
207
|
return { success: true };
|
|
245
208
|
}
|
|
246
|
-
|
|
247
209
|
// Write documentation file
|
|
248
210
|
const workspaceRoot = context.root || process.cwd();
|
|
249
211
|
writeDocFile(workspaceRoot);
|
|
250
|
-
|
|
251
212
|
// Report violations
|
|
252
213
|
console.error('\n❌ Redundant transitive dependencies detected!\n');
|
|
253
214
|
console.error('⚠️ AI Agent: READ .webpieces/instruct-ai/webpieces.transitivedeps.md for fix instructions!\n');
|
|
254
|
-
|
|
255
215
|
for (const r of allRedundant) {
|
|
256
216
|
console.error(` ${r.project}:`);
|
|
257
217
|
console.error(` └─ "${r.redundantDep}" is REDUNDANT`);
|
|
258
218
|
console.error(` (already brought in by "${r.alreadyBroughtInBy}")\n`);
|
|
259
219
|
}
|
|
260
|
-
|
|
261
220
|
console.error('\nTo fix:');
|
|
262
221
|
console.error(' 1. READ .webpieces/instruct-ai/webpieces.transitivedeps.md');
|
|
263
222
|
console.error(' 2. Remove redundant deps from project.json build.dependsOn');
|
|
264
223
|
console.error(' 3. Remove redundant deps from package.json dependencies');
|
|
265
224
|
console.error(' 4. Run: npx nx run architecture:generate');
|
|
266
225
|
console.error(' 5. Run: npm run build-all');
|
|
267
|
-
|
|
268
226
|
return { success: false };
|
|
269
|
-
}
|
|
270
|
-
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
const error = (0, toError_1.toError)(err);
|
|
271
230
|
console.error('❌ Skip-level validation failed:', error.message);
|
|
272
231
|
return { success: false };
|
|
273
232
|
}
|
|
274
233
|
}
|
|
234
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-skiplevel-deps/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate No Skip-Level Dependencies Executor\n *\n * Validates that no project has redundant transitive dependencies.\n * If project A depends on B, and B transitively brings in C, then A should NOT\n * also directly depend on C (it's redundant and clutters the dependency graph).\n *\n * This keeps the architecture graph clean for visualization and human understanding.\n *\n * Usage:\n * nx run architecture:validate-no-skiplevel-deps\n */\n\nimport type { ExecutorContext } from '@nx/devkit';\nimport { generateGraph } from '../../lib/graph-generator';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { toError } from '../../toError';\n\nexport interface ValidateNoSkipLevelDepsOptions {\n // No options needed\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface RedundantDep {\n project: string;\n redundantDep: string;\n alreadyBroughtInBy: string;\n}\n\nconst TRANSITIVE_DEPS_DOC = `# AI Agent Instructions: Redundant Transitive Dependency Violation\n\n**READ THIS FILE FIRST before making any changes!**\n\n## Why This Rule Exists\n\nThis rule keeps the architecture dependency graph **CLEAN and SIMPLE**.\n\nWhen you run \\`npx nx run architecture:visualize\\`, it generates a visual diagram of all\npackage dependencies. Without this rule, you end up with a tangled mess of 100+ lines\nwhere everything depends on everything - making it impossible to understand.\n\n**Clean graphs = easier understanding for humans AND AI agents.**\n\n## Understanding the Error\n\nYou have a **redundant transitive dependency**. This means:\n\n1. Project A directly depends on Project C\n2. BUT Project A also depends on Project B\n3. AND Project B already brings in Project C (transitively)\n\nTherefore, Project A's direct dependency on C is **redundant** - it's already available\nthrough B. This extra line clutters the dependency graph.\n\n**Example:**\n\\`\\`\\`\nhttp-server depends on: [http-routing, http-filters, core-util]\n ^^^^^^^^^ ^^^^^^^^\n REDUNDANT! REDUNDANT!\n\nWhy? Because http-routing already brings in:\n - http-filters (direct)\n - core-util (via http-api)\n\\`\\`\\`\n\n## How to Fix\n\n### Step 1: Identify the Redundant Dependency\n\nLook at the error message. It tells you:\n- Which project has the problem\n- Which dependency is redundant\n- Which other dependency already brings it in\n\n### Step 2: Remove from project.json\n\nRemove the redundant dependency from \\`build.dependsOn\\`:\n\n\\`\\`\\`json\n{\n \"targets\": {\n \"build\": {\n \"dependsOn\": [\n \"^build\",\n \"http-routing:build\"\n // REMOVE: \"http-filters:build\" <-- redundant, http-routing brings it in\n // REMOVE: \"core-util:build\" <-- redundant, http-routing brings it in\n ]\n }\n }\n}\n\\`\\`\\`\n\n### Step 3: Remove from package.json\n\nRemove the redundant dependency from \\`dependencies\\`:\n\n\\`\\`\\`json\n{\n \"dependencies\": {\n \"@webpieces/http-routing\": \"*\"\n // REMOVE: \"@webpieces/http-filters\": \"*\" <-- redundant\n // REMOVE: \"@webpieces/core-util\": \"*\" <-- redundant\n }\n}\n\\`\\`\\`\n\n### Step 4: Regenerate Architecture\n\n\\`\\`\\`bash\nnpx nx run architecture:generate\n\\`\\`\\`\n\n### Step 5: Verify\n\n\\`\\`\\`bash\nnpm run build-all\n\\`\\`\\`\n\n## Important Notes\n\n- You DON'T lose access to the transitive dependency - it's still available through the parent\n- This is about keeping the DECLARED dependencies minimal and clean\n- The actual runtime/compile behavior is unchanged\n- TypeScript will still find the types through the transitive path\n\n## Remember\n\n- Fewer lines in the graph = easier to understand\n- Only declare what you DIRECTLY need that isn't already transitively available\n- When in doubt, check with \\`npx nx run architecture:visualize\\`\n`;\n\n/**\n * Compute all transitive dependencies for a project\n */\nfunction computeTransitiveDeps(\n project: string,\n graph: Record<string, string[]>,\n visited: Set<string> = new Set()\n): Set<string> {\n const result = new Set<string>();\n\n if (visited.has(project)) {\n return result;\n }\n visited.add(project);\n\n const directDeps = graph[project] || [];\n for (const dep of directDeps) {\n result.add(dep);\n // Recursively get transitive deps\n const transitive = computeTransitiveDeps(dep, graph, visited);\n for (const t of transitive) {\n result.add(t);\n }\n }\n\n return result;\n}\n\n/**\n * Find redundant dependencies for a project\n */\nfunction findRedundantDeps(\n project: string,\n graph: Record<string, string[]>\n): RedundantDep[] {\n const redundant: RedundantDep[] = [];\n const directDeps = graph[project] || [];\n\n // For each direct dependency, compute what it transitively brings in\n const transitiveByDep = new Map<string, Set<string>>();\n for (const dep of directDeps) {\n transitiveByDep.set(dep, computeTransitiveDeps(dep, graph));\n }\n\n // Check if any direct dependency is already brought in by another\n const transitiveEntries = Array.from(transitiveByDep.entries());\n for (const dep of directDeps) {\n for (const entry of transitiveEntries) {\n const otherDep = entry[0];\n const otherTransitive = entry[1];\n if (otherDep !== dep && otherTransitive.has(dep)) {\n redundant.push({\n project,\n redundantDep: dep,\n alreadyBroughtInBy: otherDep,\n });\n break; // Only report once per redundant dep\n }\n }\n }\n\n return redundant;\n}\n\n/**\n * Write documentation file when violations are found\n */\nfunction writeDocFile(workspaceRoot: string): void {\n const docPath = path.join(workspaceRoot, '.webpieces', 'instruct-ai', 'webpieces.transitivedeps.md');\n const docDir = path.dirname(docPath);\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n fs.mkdirSync(docDir, { recursive: true });\n fs.writeFileSync(docPath, TRANSITIVE_DEPS_DOC, 'utf-8');\n } catch (err: unknown) {\n //const error = toError(err);\n void err;\n console.warn(`Could not write documentation file: ${docPath}`);\n }\n}\n\nexport default async function runExecutor(\n _options: ValidateNoSkipLevelDepsOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n console.log('\\n🔄 Validating No Skip-Level Dependencies\\n');\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n // Step 1: Generate current graph from project.json files\n console.log('📊 Generating dependency graph from project.json files...');\n const graph = await generateGraph();\n\n // Step 2: Find all redundant dependencies\n console.log('🔍 Checking for redundant transitive dependencies...');\n const allRedundant: RedundantDep[] = [];\n\n for (const project of Object.keys(graph)) {\n const redundant = findRedundantDeps(project, graph);\n allRedundant.push(...redundant);\n }\n\n if (allRedundant.length === 0) {\n console.log('✅ No redundant transitive dependencies detected!');\n console.log('\\n📈 Graph is clean and minimal.');\n return { success: true };\n }\n\n // Write documentation file\n const workspaceRoot = context.root || process.cwd();\n writeDocFile(workspaceRoot);\n\n // Report violations\n console.error('\\n❌ Redundant transitive dependencies detected!\\n');\n console.error('⚠️ AI Agent: READ .webpieces/instruct-ai/webpieces.transitivedeps.md for fix instructions!\\n');\n\n for (const r of allRedundant) {\n console.error(` ${r.project}:`);\n console.error(` └─ \"${r.redundantDep}\" is REDUNDANT`);\n console.error(` (already brought in by \"${r.alreadyBroughtInBy}\")\\n`);\n }\n\n console.error('\\nTo fix:');\n console.error(' 1. READ .webpieces/instruct-ai/webpieces.transitivedeps.md');\n console.error(' 2. Remove redundant deps from project.json build.dependsOn');\n console.error(' 3. Remove redundant deps from package.json dependencies');\n console.error(' 4. Run: npx nx run architecture:generate');\n console.error(' 5. Run: npm run build-all');\n\n return { success: false };\n } catch (err: unknown) {\n const error = toError(err);\n console.error('❌ Skip-level validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = runExecutor;
|
|
4
|
+
const code_rules_1 = require("@webpieces/code-rules");
|
|
5
|
+
async function runExecutor(
|
|
6
|
+
// webpieces-disable no-any-unknown -- options are passed through to code-rules validators
|
|
7
|
+
options, context) {
|
|
8
|
+
return (0, code_rules_1.validateNoUnmanagedExceptions)(options, context.root);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-no-unmanaged-exceptions/executor.ts"],"names":[],"mappings":";;AAIA,8BAMC;AARD,sDAAsE;AAEvD,KAAK,UAAU,WAAW;AACrC,0FAA0F;AAC1F,OAAgC,EAChC,OAAwB;IAExB,OAAO,IAAA,0CAA6B,EAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import type { ExecutorContext } from '@nx/devkit';\nimport { ExecutorResult } from '../../executor-result';\nimport { validateNoUnmanagedExceptions } from '@webpieces/code-rules';\n\nexport default async function runExecutor(\n // webpieces-disable no-any-unknown -- options are passed through to code-rules validators\n options: Record<string, unknown>,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n return validateNoUnmanagedExceptions(options, context.root);\n}\n"]}
|
|
@@ -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>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Validate Package.json Executor
|
|
3
4
|
*
|
|
@@ -7,43 +8,26 @@
|
|
|
7
8
|
* Usage:
|
|
8
9
|
* nx run architecture:validate-packagejson
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export interface ValidatePackageJsonOptions {
|
|
18
|
-
// No options needed for now
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface ExecutorResult {
|
|
22
|
-
success: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export default async function runExecutor(
|
|
26
|
-
options: ValidatePackageJsonOptions,
|
|
27
|
-
context: ExecutorContext
|
|
28
|
-
): Promise<ExecutorResult> {
|
|
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
|
+
const toError_1 = require("../../toError");
|
|
17
|
+
async function runExecutor(options, context) {
|
|
29
18
|
const workspaceRoot = context.root;
|
|
30
|
-
|
|
31
19
|
console.log('\n📦 Validating Package.json Dependencies\n');
|
|
32
|
-
|
|
33
20
|
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
34
21
|
try {
|
|
35
22
|
// Step 1: Generate current graph from project.json files
|
|
36
23
|
console.log('📊 Generating dependency graph from project.json files...');
|
|
37
|
-
const rawGraph = await generateGraph();
|
|
38
|
-
|
|
24
|
+
const rawGraph = await (0, graph_generator_1.generateGraph)();
|
|
39
25
|
// Step 2: Topological sort (to get enhanced graph with levels)
|
|
40
26
|
console.log('🔄 Computing topological layers...');
|
|
41
|
-
const enhancedGraph = sortGraphTopologically(rawGraph);
|
|
42
|
-
|
|
27
|
+
const enhancedGraph = (0, graph_sorter_1.sortGraphTopologically)(rawGraph);
|
|
43
28
|
// Step 3: Validate package.json dependencies match
|
|
44
29
|
console.log('📦 Validating package.json dependencies match project.json...');
|
|
45
|
-
const packageValidation = await validatePackageJsonDependencies(enhancedGraph, workspaceRoot);
|
|
46
|
-
|
|
30
|
+
const packageValidation = await (0, package_validator_1.validatePackageJsonDependencies)(enhancedGraph, workspaceRoot);
|
|
47
31
|
if (!packageValidation.valid) {
|
|
48
32
|
console.error('❌ Package.json validation failed!');
|
|
49
33
|
console.error('\nErrors:');
|
|
@@ -56,9 +40,7 @@ export default async function runExecutor(
|
|
|
56
40
|
console.error(' 3. Ensure dependencies in package.json match build.dependsOn in project.json');
|
|
57
41
|
return { success: false };
|
|
58
42
|
}
|
|
59
|
-
|
|
60
43
|
console.log('✅ Package.json dependencies match project.json');
|
|
61
|
-
|
|
62
44
|
// Print summary
|
|
63
45
|
const validProjects = packageValidation.projectResults.filter(r => r.valid).length;
|
|
64
46
|
const totalProjects = packageValidation.projectResults.length;
|
|
@@ -66,11 +48,12 @@ export default async function runExecutor(
|
|
|
66
48
|
console.log(` Projects validated: ${totalProjects}`);
|
|
67
49
|
console.log(` Valid: ${validProjects}`);
|
|
68
50
|
console.log(` Invalid: ${totalProjects - validProjects}`);
|
|
69
|
-
|
|
70
51
|
return { success: true };
|
|
71
|
-
}
|
|
72
|
-
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const error = (0, toError_1.toError)(err);
|
|
73
55
|
console.error('❌ Package.json validation failed:', error.message);
|
|
74
56
|
return { success: false };
|
|
75
57
|
}
|
|
76
58
|
}
|
|
59
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/validate-packagejson/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAgBH,8BAmDC;AAhED,+DAA0D;AAC1D,yDAAgE;AAChE,mEAA8E;AAC9E,2CAAwC;AAUzB,KAAK,UAAU,WAAW,CACrC,OAAmC,EACnC,OAAwB;IAExB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAE3D,8DAA8D;IAC9D,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,IAAA,iBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,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';\nimport { toError } from '../../toError';\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 // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\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 = toError(err);\n console.error('❌ Package.json validation failed:', error.message);\n return { success: false };\n }\n}\n"]}
|