@nielspeter/eess-ts 0.1.0
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/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/builders/call-rule-builder.d.ts +199 -0
- package/dist/builders/call-rule-builder.d.ts.map +1 -0
- package/dist/builders/call-rule-builder.js +254 -0
- package/dist/builders/call-rule-builder.js.map +1 -0
- package/dist/builders/class-rule-builder.d.ts +136 -0
- package/dist/builders/class-rule-builder.d.ts.map +1 -0
- package/dist/builders/class-rule-builder.js +253 -0
- package/dist/builders/class-rule-builder.js.map +1 -0
- package/dist/builders/cross-layer-builder.d.ts +96 -0
- package/dist/builders/cross-layer-builder.d.ts.map +1 -0
- package/dist/builders/cross-layer-builder.js +172 -0
- package/dist/builders/cross-layer-builder.js.map +1 -0
- package/dist/builders/function-rule-builder.d.ts +198 -0
- package/dist/builders/function-rule-builder.d.ts.map +1 -0
- package/dist/builders/function-rule-builder.js +287 -0
- package/dist/builders/function-rule-builder.js.map +1 -0
- package/dist/builders/jsx-rule-builder.d.ts +113 -0
- package/dist/builders/jsx-rule-builder.d.ts.map +1 -0
- package/dist/builders/jsx-rule-builder.js +150 -0
- package/dist/builders/jsx-rule-builder.js.map +1 -0
- package/dist/builders/module-rule-builder.d.ts +159 -0
- package/dist/builders/module-rule-builder.d.ts.map +1 -0
- package/dist/builders/module-rule-builder.js +237 -0
- package/dist/builders/module-rule-builder.js.map +1 -0
- package/dist/builders/scoped-function-rule-builder.d.ts +21 -0
- package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -0
- package/dist/builders/scoped-function-rule-builder.js +26 -0
- package/dist/builders/scoped-function-rule-builder.js.map +1 -0
- package/dist/builders/slice-rule-builder.d.ts +85 -0
- package/dist/builders/slice-rule-builder.d.ts.map +1 -0
- package/dist/builders/slice-rule-builder.js +134 -0
- package/dist/builders/slice-rule-builder.js.map +1 -0
- package/dist/builders/type-rule-builder.d.ts +103 -0
- package/dist/builders/type-rule-builder.d.ts.map +1 -0
- package/dist/builders/type-rule-builder.js +170 -0
- package/dist/builders/type-rule-builder.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +4 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/baseline.d.ts +11 -0
- package/dist/cli/commands/baseline.d.ts.map +1 -0
- package/dist/cli/commands/baseline.js +16 -0
- package/dist/cli/commands/baseline.js.map +1 -0
- package/dist/cli/commands/check.d.ts +21 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +94 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/explain.d.ts +9 -0
- package/dist/cli/commands/explain.d.ts.map +1 -0
- package/dist/cli/commands/explain.js +49 -0
- package/dist/cli/commands/explain.js.map +1 -0
- package/dist/cli/config.d.ts +31 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +20 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +21 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +168 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/load-rules.d.ts +20 -0
- package/dist/cli/load-rules.d.ts.map +1 -0
- package/dist/cli/load-rules.js +97 -0
- package/dist/cli/load-rules.js.map +1 -0
- package/dist/cli/resolve-config.d.ts +11 -0
- package/dist/cli/resolve-config.d.ts.map +1 -0
- package/dist/cli/resolve-config.js +61 -0
- package/dist/cli/resolve-config.js.map +1 -0
- package/dist/cli/watch.d.ts +49 -0
- package/dist/cli/watch.d.ts.map +1 -0
- package/dist/cli/watch.js +138 -0
- package/dist/cli/watch.js.map +1 -0
- package/dist/conditions/body-analysis-function.d.ts +23 -0
- package/dist/conditions/body-analysis-function.d.ts.map +1 -0
- package/dist/conditions/body-analysis-function.js +103 -0
- package/dist/conditions/body-analysis-function.js.map +1 -0
- package/dist/conditions/body-analysis-module.d.ts +27 -0
- package/dist/conditions/body-analysis-module.d.ts.map +1 -0
- package/dist/conditions/body-analysis-module.js +99 -0
- package/dist/conditions/body-analysis-module.js.map +1 -0
- package/dist/conditions/body-analysis.d.ts +34 -0
- package/dist/conditions/body-analysis.d.ts.map +1 -0
- package/dist/conditions/body-analysis.js +95 -0
- package/dist/conditions/body-analysis.js.map +1 -0
- package/dist/conditions/call.d.ts +62 -0
- package/dist/conditions/call.d.ts.map +1 -0
- package/dist/conditions/call.js +267 -0
- package/dist/conditions/call.js.map +1 -0
- package/dist/conditions/catch-analysis.d.ts +31 -0
- package/dist/conditions/catch-analysis.d.ts.map +1 -0
- package/dist/conditions/catch-analysis.js +78 -0
- package/dist/conditions/catch-analysis.js.map +1 -0
- package/dist/conditions/class.d.ts +33 -0
- package/dist/conditions/class.d.ts.map +1 -0
- package/dist/conditions/class.js +110 -0
- package/dist/conditions/class.js.map +1 -0
- package/dist/conditions/cross-layer.d.ts +28 -0
- package/dist/conditions/cross-layer.d.ts.map +1 -0
- package/dist/conditions/cross-layer.js +105 -0
- package/dist/conditions/cross-layer.js.map +1 -0
- package/dist/conditions/dependency.d.ts +73 -0
- package/dist/conditions/dependency.d.ts.map +1 -0
- package/dist/conditions/dependency.js +177 -0
- package/dist/conditions/dependency.js.map +1 -0
- package/dist/conditions/exports.d.ts +33 -0
- package/dist/conditions/exports.d.ts.map +1 -0
- package/dist/conditions/exports.js +101 -0
- package/dist/conditions/exports.js.map +1 -0
- package/dist/conditions/function.d.ts +79 -0
- package/dist/conditions/function.d.ts.map +1 -0
- package/dist/conditions/function.js +167 -0
- package/dist/conditions/function.js.map +1 -0
- package/dist/conditions/helpers.d.ts +14 -0
- package/dist/conditions/helpers.d.ts.map +1 -0
- package/dist/conditions/helpers.js +26 -0
- package/dist/conditions/helpers.js.map +1 -0
- package/dist/conditions/jsx.d.ts +40 -0
- package/dist/conditions/jsx.d.ts.map +1 -0
- package/dist/conditions/jsx.js +133 -0
- package/dist/conditions/jsx.js.map +1 -0
- package/dist/conditions/members.d.ts +74 -0
- package/dist/conditions/members.d.ts.map +1 -0
- package/dist/conditions/members.js +224 -0
- package/dist/conditions/members.js.map +1 -0
- package/dist/conditions/pattern.d.ts +20 -0
- package/dist/conditions/pattern.d.ts.map +1 -0
- package/dist/conditions/pattern.js +108 -0
- package/dist/conditions/pattern.js.map +1 -0
- package/dist/conditions/reverse-dependency.d.ts +28 -0
- package/dist/conditions/reverse-dependency.d.ts.map +1 -0
- package/dist/conditions/reverse-dependency.js +275 -0
- package/dist/conditions/reverse-dependency.js.map +1 -0
- package/dist/conditions/slice.d.ts +49 -0
- package/dist/conditions/slice.d.ts.map +1 -0
- package/dist/conditions/slice.js +153 -0
- package/dist/conditions/slice.js.map +1 -0
- package/dist/conditions/structural.d.ts +58 -0
- package/dist/conditions/structural.d.ts.map +1 -0
- package/dist/conditions/structural.js +102 -0
- package/dist/conditions/structural.js.map +1 -0
- package/dist/conditions/type-level.d.ts +29 -0
- package/dist/conditions/type-level.d.ts.map +1 -0
- package/dist/conditions/type-level.js +48 -0
- package/dist/conditions/type-level.js.map +1 -0
- package/dist/core/import-options.d.ts +32 -0
- package/dist/core/import-options.d.ts.map +1 -0
- package/dist/core/import-options.js +29 -0
- package/dist/core/import-options.js.map +1 -0
- package/dist/core/module-dependencies.d.ts +28 -0
- package/dist/core/module-dependencies.d.ts.map +1 -0
- package/dist/core/module-dependencies.js +35 -0
- package/dist/core/module-dependencies.js.map +1 -0
- package/dist/core/pair-condition.d.ts +10 -0
- package/dist/core/pair-condition.d.ts.map +1 -0
- package/dist/core/pair-condition.js +2 -0
- package/dist/core/pair-condition.js.map +1 -0
- package/dist/core/project.d.ts +68 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +127 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/type-matcher.d.ts +10 -0
- package/dist/core/type-matcher.d.ts.map +1 -0
- package/dist/core/type-matcher.js +2 -0
- package/dist/core/type-matcher.js.map +1 -0
- package/dist/core/violation.d.ts +38 -0
- package/dist/core/violation.d.ts.map +1 -0
- package/dist/core/violation.js +130 -0
- package/dist/core/violation.js.map +1 -0
- package/dist/graphql/index.d.ts +76 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +108 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/graphql/resolver-rule-builder.d.ts +75 -0
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -0
- package/dist/graphql/resolver-rule-builder.js +146 -0
- package/dist/graphql/resolver-rule-builder.js.map +1 -0
- package/dist/graphql/schema-conditions.d.ts +31 -0
- package/dist/graphql/schema-conditions.d.ts.map +1 -0
- package/dist/graphql/schema-conditions.js +119 -0
- package/dist/graphql/schema-conditions.js.map +1 -0
- package/dist/graphql/schema-loader.d.ts +75 -0
- package/dist/graphql/schema-loader.d.ts.map +1 -0
- package/dist/graphql/schema-loader.js +113 -0
- package/dist/graphql/schema-loader.js.map +1 -0
- package/dist/graphql/schema-predicates.d.ts +42 -0
- package/dist/graphql/schema-predicates.d.ts.map +1 -0
- package/dist/graphql/schema-predicates.js +74 -0
- package/dist/graphql/schema-predicates.js.map +1 -0
- package/dist/graphql/schema-rule-builder.d.ts +74 -0
- package/dist/graphql/schema-rule-builder.d.ts.map +1 -0
- package/dist/graphql/schema-rule-builder.js +188 -0
- package/dist/graphql/schema-rule-builder.js.map +1 -0
- package/dist/helpers/body-traversal.d.ts +58 -0
- package/dist/helpers/body-traversal.d.ts.map +1 -0
- package/dist/helpers/body-traversal.js +180 -0
- package/dist/helpers/body-traversal.js.map +1 -0
- package/dist/helpers/callback-extractor.d.ts +28 -0
- package/dist/helpers/callback-extractor.d.ts.map +1 -0
- package/dist/helpers/callback-extractor.js +159 -0
- package/dist/helpers/callback-extractor.js.map +1 -0
- package/dist/helpers/complexity.d.ts +26 -0
- package/dist/helpers/complexity.d.ts.map +1 -0
- package/dist/helpers/complexity.js +64 -0
- package/dist/helpers/complexity.js.map +1 -0
- package/dist/helpers/matchers.d.ts +206 -0
- package/dist/helpers/matchers.d.ts.map +1 -0
- package/dist/helpers/matchers.js +470 -0
- package/dist/helpers/matchers.js.map +1 -0
- package/dist/helpers/pattern.d.ts +37 -0
- package/dist/helpers/pattern.d.ts.map +1 -0
- package/dist/helpers/pattern.js +22 -0
- package/dist/helpers/pattern.js.map +1 -0
- package/dist/helpers/slice-graph.d.ts +32 -0
- package/dist/helpers/slice-graph.d.ts.map +1 -0
- package/dist/helpers/slice-graph.js +89 -0
- package/dist/helpers/slice-graph.js.map +1 -0
- package/dist/helpers/tarjan.d.ts +21 -0
- package/dist/helpers/tarjan.d.ts.map +1 -0
- package/dist/helpers/tarjan.js +71 -0
- package/dist/helpers/tarjan.js.map +1 -0
- package/dist/helpers/type-matchers.d.ts +67 -0
- package/dist/helpers/type-matchers.d.ts.map +1 -0
- package/dist/helpers/type-matchers.js +108 -0
- package/dist/helpers/type-matchers.js.map +1 -0
- package/dist/helpers/within.d.ts +41 -0
- package/dist/helpers/within.d.ts.map +1 -0
- package/dist/helpers/within.js +32 -0
- package/dist/helpers/within.js.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/models/arch-call.d.ts +83 -0
- package/dist/models/arch-call.d.ts.map +1 -0
- package/dist/models/arch-call.js +90 -0
- package/dist/models/arch-call.js.map +1 -0
- package/dist/models/arch-function.d.ts +76 -0
- package/dist/models/arch-function.d.ts.map +1 -0
- package/dist/models/arch-function.js +122 -0
- package/dist/models/arch-function.js.map +1 -0
- package/dist/models/arch-jsx-element.d.ts +75 -0
- package/dist/models/arch-jsx-element.d.ts.map +1 -0
- package/dist/models/arch-jsx-element.js +231 -0
- package/dist/models/arch-jsx-element.js.map +1 -0
- package/dist/models/cross-layer.d.ts +15 -0
- package/dist/models/cross-layer.d.ts.map +1 -0
- package/dist/models/cross-layer.js +2 -0
- package/dist/models/cross-layer.js.map +1 -0
- package/dist/models/slice.d.ts +60 -0
- package/dist/models/slice.d.ts.map +1 -0
- package/dist/models/slice.js +89 -0
- package/dist/models/slice.js.map +1 -0
- package/dist/predicates/call.d.ts +49 -0
- package/dist/predicates/call.d.ts.map +1 -0
- package/dist/predicates/call.js +115 -0
- package/dist/predicates/call.js.map +1 -0
- package/dist/predicates/class.d.ts +42 -0
- package/dist/predicates/class.d.ts.map +1 -0
- package/dist/predicates/class.js +83 -0
- package/dist/predicates/class.js.map +1 -0
- package/dist/predicates/function.d.ts +81 -0
- package/dist/predicates/function.d.ts.map +1 -0
- package/dist/predicates/function.js +157 -0
- package/dist/predicates/function.js.map +1 -0
- package/dist/predicates/identity.d.ts +55 -0
- package/dist/predicates/identity.d.ts.map +1 -0
- package/dist/predicates/identity.js +96 -0
- package/dist/predicates/identity.js.map +1 -0
- package/dist/predicates/index.d.ts +4 -0
- package/dist/predicates/index.d.ts.map +1 -0
- package/dist/predicates/index.js +3 -0
- package/dist/predicates/index.js.map +1 -0
- package/dist/predicates/jsx.d.ts +41 -0
- package/dist/predicates/jsx.d.ts.map +1 -0
- package/dist/predicates/jsx.js +84 -0
- package/dist/predicates/jsx.js.map +1 -0
- package/dist/predicates/metrics.d.ts +30 -0
- package/dist/predicates/metrics.d.ts.map +1 -0
- package/dist/predicates/metrics.js +65 -0
- package/dist/predicates/metrics.js.map +1 -0
- package/dist/predicates/module.d.ts +44 -0
- package/dist/predicates/module.d.ts.map +1 -0
- package/dist/predicates/module.js +70 -0
- package/dist/predicates/module.js.map +1 -0
- package/dist/predicates/type.d.ts +48 -0
- package/dist/predicates/type.d.ts.map +1 -0
- package/dist/predicates/type.js +107 -0
- package/dist/predicates/type.js.map +1 -0
- package/dist/presets/boundaries.d.ts +19 -0
- package/dist/presets/boundaries.d.ts.map +1 -0
- package/dist/presets/boundaries.js +93 -0
- package/dist/presets/boundaries.js.map +1 -0
- package/dist/presets/data-layer.d.ts +20 -0
- package/dist/presets/data-layer.d.ts.map +1 -0
- package/dist/presets/data-layer.js +30 -0
- package/dist/presets/data-layer.js.map +1 -0
- package/dist/presets/index.d.ts +9 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +5 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/layered.d.ts +21 -0
- package/dist/presets/layered.d.ts.map +1 -0
- package/dist/presets/layered.js +103 -0
- package/dist/presets/layered.js.map +1 -0
- package/dist/presets/shared.d.ts +3 -0
- package/dist/presets/shared.d.ts.map +1 -0
- package/dist/presets/shared.js +5 -0
- package/dist/presets/shared.js.map +1 -0
- package/dist/rules/architecture.d.ts +10 -0
- package/dist/rules/architecture.d.ts.map +1 -0
- package/dist/rules/architecture.js +14 -0
- package/dist/rules/architecture.js.map +1 -0
- package/dist/rules/code-quality.d.ts +55 -0
- package/dist/rules/code-quality.d.ts.map +1 -0
- package/dist/rules/code-quality.js +116 -0
- package/dist/rules/code-quality.js.map +1 -0
- package/dist/rules/dependencies.d.ts +32 -0
- package/dist/rules/dependencies.d.ts.map +1 -0
- package/dist/rules/dependencies.js +37 -0
- package/dist/rules/dependencies.js.map +1 -0
- package/dist/rules/errors.d.ts +31 -0
- package/dist/rules/errors.d.ts.map +1 -0
- package/dist/rules/errors.js +97 -0
- package/dist/rules/errors.js.map +1 -0
- package/dist/rules/hygiene.d.ts +54 -0
- package/dist/rules/hygiene.d.ts.map +1 -0
- package/dist/rules/hygiene.js +62 -0
- package/dist/rules/hygiene.js.map +1 -0
- package/dist/rules/metrics-function.d.ts +45 -0
- package/dist/rules/metrics-function.d.ts.map +1 -0
- package/dist/rules/metrics-function.js +87 -0
- package/dist/rules/metrics-function.js.map +1 -0
- package/dist/rules/metrics.d.ts +64 -0
- package/dist/rules/metrics.d.ts.map +1 -0
- package/dist/rules/metrics.js +157 -0
- package/dist/rules/metrics.js.map +1 -0
- package/dist/rules/naming.d.ts +24 -0
- package/dist/rules/naming.d.ts.map +1 -0
- package/dist/rules/naming.js +51 -0
- package/dist/rules/naming.js.map +1 -0
- package/dist/rules/security.d.ts +59 -0
- package/dist/rules/security.d.ts.map +1 -0
- package/dist/rules/security.js +92 -0
- package/dist/rules/security.js.map +1 -0
- package/dist/rules/typescript.d.ts +73 -0
- package/dist/rules/typescript.d.ts.map +1 -0
- package/dist/rules/typescript.js +105 -0
- package/dist/rules/typescript.js.map +1 -0
- package/dist/smells/duplicate-bodies.d.ts +24 -0
- package/dist/smells/duplicate-bodies.d.ts.map +1 -0
- package/dist/smells/duplicate-bodies.js +131 -0
- package/dist/smells/duplicate-bodies.js.map +1 -0
- package/dist/smells/fingerprint.d.ts +27 -0
- package/dist/smells/fingerprint.d.ts.map +1 -0
- package/dist/smells/fingerprint.js +50 -0
- package/dist/smells/fingerprint.js.map +1 -0
- package/dist/smells/inconsistent-siblings.d.ts +21 -0
- package/dist/smells/inconsistent-siblings.d.ts.map +1 -0
- package/dist/smells/inconsistent-siblings.js +135 -0
- package/dist/smells/inconsistent-siblings.js.map +1 -0
- package/dist/smells/index.d.ts +12 -0
- package/dist/smells/index.d.ts.map +1 -0
- package/dist/smells/index.js +15 -0
- package/dist/smells/index.js.map +1 -0
- package/dist/smells/smell-builder.d.ts +37 -0
- package/dist/smells/smell-builder.d.ts.map +1 -0
- package/dist/smells/smell-builder.js +51 -0
- package/dist/smells/smell-builder.js.map +1 -0
- package/package.json +121 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Node } from 'ts-morph';
|
|
2
|
+
import { generateCodeFrame } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a node is a named declaration and return its name, or undefined.
|
|
5
|
+
* Constructors return "constructor" since they have no getName().
|
|
6
|
+
*/
|
|
7
|
+
function getNodeName(node) {
|
|
8
|
+
if (Node.isConstructorDeclaration(node))
|
|
9
|
+
return 'constructor';
|
|
10
|
+
if (Node.isClassDeclaration(node) ||
|
|
11
|
+
Node.isFunctionDeclaration(node) ||
|
|
12
|
+
Node.isInterfaceDeclaration(node) ||
|
|
13
|
+
Node.isTypeAliasDeclaration(node) ||
|
|
14
|
+
Node.isEnumDeclaration(node) ||
|
|
15
|
+
Node.isMethodDeclaration(node) ||
|
|
16
|
+
Node.isGetAccessorDeclaration(node) ||
|
|
17
|
+
Node.isSetAccessorDeclaration(node) ||
|
|
18
|
+
Node.isPropertyDeclaration(node) ||
|
|
19
|
+
Node.isVariableDeclaration(node)) {
|
|
20
|
+
return node.getName();
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if a node is a structural member that should appear in
|
|
26
|
+
* qualified element names (e.g., "ClassName.methodName").
|
|
27
|
+
* Returns the member name, or undefined to skip.
|
|
28
|
+
*/
|
|
29
|
+
function getStructuralName(node) {
|
|
30
|
+
if (Node.isConstructorDeclaration(node))
|
|
31
|
+
return 'constructor';
|
|
32
|
+
if (Node.isMethodDeclaration(node) ||
|
|
33
|
+
Node.isGetAccessorDeclaration(node) ||
|
|
34
|
+
Node.isSetAccessorDeclaration(node) ||
|
|
35
|
+
Node.isPropertyDeclaration(node)) {
|
|
36
|
+
return node.getName();
|
|
37
|
+
}
|
|
38
|
+
// Arrow/function expressions: check if assigned to a named variable
|
|
39
|
+
if (Node.isArrowFunction(node) || Node.isFunctionExpression(node)) {
|
|
40
|
+
const parent = node.getParent();
|
|
41
|
+
if (parent && Node.isVariableDeclaration(parent)) {
|
|
42
|
+
return parent.getName();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if a node is a top-level architectural boundary where
|
|
49
|
+
* the ancestor walk should stop.
|
|
50
|
+
*/
|
|
51
|
+
function isTopLevelDeclaration(node) {
|
|
52
|
+
return (Node.isClassDeclaration(node) ||
|
|
53
|
+
Node.isInterfaceDeclaration(node) ||
|
|
54
|
+
Node.isTypeAliasDeclaration(node) ||
|
|
55
|
+
Node.isEnumDeclaration(node) ||
|
|
56
|
+
Node.isFunctionDeclaration(node));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extract a human-readable name from a ts-morph Node.
|
|
60
|
+
*
|
|
61
|
+
* If the node itself is a named declaration (class, function, method, etc.),
|
|
62
|
+
* returns its name directly. Otherwise, walks up the AST ancestors to find
|
|
63
|
+
* the nearest named declaration and builds a qualified name like
|
|
64
|
+
* "ClassName.methodName". This ensures that inner nodes (e.g., AsExpression,
|
|
65
|
+
* CallExpression) produce meaningful element names for `.excluding()` matching.
|
|
66
|
+
*
|
|
67
|
+
* Falls back to the node's kind name only if no named ancestor is found
|
|
68
|
+
* (e.g., top-level expressions in a module).
|
|
69
|
+
*/
|
|
70
|
+
export function getElementName(node) {
|
|
71
|
+
const directName = getNodeName(node);
|
|
72
|
+
if (directName !== undefined)
|
|
73
|
+
return directName;
|
|
74
|
+
// Walk up ancestors collecting structural names: method/constructor/accessor
|
|
75
|
+
// at the member level, class/function at the top level. Skips variables,
|
|
76
|
+
// properties, and expressions — those are implementation detail.
|
|
77
|
+
const parts = [];
|
|
78
|
+
let current = node.getParent();
|
|
79
|
+
while (current) {
|
|
80
|
+
// Top-level declarations: collect name and stop
|
|
81
|
+
if (isTopLevelDeclaration(current)) {
|
|
82
|
+
const name = getNodeName(current);
|
|
83
|
+
if (name !== undefined)
|
|
84
|
+
parts.unshift(name);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
// Structural members: collect name and keep walking to find the parent class
|
|
88
|
+
const memberName = getStructuralName(current);
|
|
89
|
+
if (memberName !== undefined) {
|
|
90
|
+
parts.unshift(memberName);
|
|
91
|
+
}
|
|
92
|
+
current = current.getParent();
|
|
93
|
+
}
|
|
94
|
+
return parts.length > 0 ? parts.join('.') : node.getKindName();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the absolute file path for a ts-morph Node.
|
|
98
|
+
*/
|
|
99
|
+
export function getElementFile(node) {
|
|
100
|
+
return node.getSourceFile().getFilePath();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get the start line number for a ts-morph Node.
|
|
104
|
+
*/
|
|
105
|
+
export function getElementLine(node) {
|
|
106
|
+
return node.getStartLineNumber();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create an ArchViolation from a ts-morph Node and context.
|
|
110
|
+
*
|
|
111
|
+
* Convenience function used by all condition implementations to produce
|
|
112
|
+
* consistent violation objects.
|
|
113
|
+
*/
|
|
114
|
+
export function createViolation(node, message, context) {
|
|
115
|
+
const line = getElementLine(node);
|
|
116
|
+
const sourceText = node.getSourceFile().getFullText();
|
|
117
|
+
return {
|
|
118
|
+
rule: context.rule,
|
|
119
|
+
ruleId: context.ruleId,
|
|
120
|
+
element: getElementName(node),
|
|
121
|
+
file: getElementFile(node),
|
|
122
|
+
line,
|
|
123
|
+
message,
|
|
124
|
+
because: context.because,
|
|
125
|
+
suggestion: context.suggestion,
|
|
126
|
+
docs: context.docs,
|
|
127
|
+
codeFrame: generateCodeFrame(sourceText, line),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=violation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"violation.js","sourceRoot":"","sources":["../../src/core/violation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL extension for eess-ts.
|
|
3
|
+
*
|
|
4
|
+
* Sub-path export: `import { schema, resolvers } from '@nielspeter/eess-ts/graphql'`
|
|
5
|
+
*
|
|
6
|
+
* Requires the `graphql` npm package as an optional peer dependency.
|
|
7
|
+
* Schema loading will throw a clear error if graphql is not installed.
|
|
8
|
+
*/
|
|
9
|
+
import type { ArchProject } from '../core/project.js';
|
|
10
|
+
import { SchemaRuleBuilder } from './schema-rule-builder.js';
|
|
11
|
+
import { ResolverRuleBuilder } from './resolver-rule-builder.js';
|
|
12
|
+
/**
|
|
13
|
+
* Create a schema rule builder scoped to .graphql files matching the glob.
|
|
14
|
+
*
|
|
15
|
+
* @param projectOrRoot - ArchProject (uses tsconfig root) or a directory path
|
|
16
|
+
* @param glob - Glob pattern for .graphql files (e.g. 'schema/*.graphql')
|
|
17
|
+
* @returns A SchemaRuleBuilder for defining schema architecture rules
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { project } from '@nielspeter/eess-ts'
|
|
22
|
+
* import { schema } from '@nielspeter/eess-ts/graphql'
|
|
23
|
+
*
|
|
24
|
+
* const p = project('tsconfig.json')
|
|
25
|
+
* schema(p, 'src/schema/*.graphql')
|
|
26
|
+
* .typesNamed(/Collection$/)
|
|
27
|
+
* .should()
|
|
28
|
+
* .haveFields('total', 'skip', 'limit', 'items')
|
|
29
|
+
* .check()
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function schema(projectOrRoot: ArchProject | string, glob: string): SchemaRuleBuilder;
|
|
33
|
+
/**
|
|
34
|
+
* Create a schema rule builder from a raw SDL string.
|
|
35
|
+
*
|
|
36
|
+
* @param sdl - GraphQL Schema Definition Language string
|
|
37
|
+
* @param sourcePath - Optional file path for error reporting
|
|
38
|
+
* @returns A SchemaRuleBuilder
|
|
39
|
+
*/
|
|
40
|
+
export declare function schemaFromSDL(sdl: string, sourcePath?: string): SchemaRuleBuilder;
|
|
41
|
+
/**
|
|
42
|
+
* Create a resolver rule builder scoped to TypeScript files matching the glob.
|
|
43
|
+
*
|
|
44
|
+
* Resolver files are regular TypeScript — analyzed via ts-morph, not the graphql package.
|
|
45
|
+
* Conditions like contain(call('loader.load')) reuse the body analysis engine.
|
|
46
|
+
*
|
|
47
|
+
* @param p - The loaded ArchProject
|
|
48
|
+
* @param glob - Glob pattern for resolver files (e.g. 'src/resolvers/**')
|
|
49
|
+
* @returns A ResolverRuleBuilder
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import { project } from '@nielspeter/eess-ts'
|
|
54
|
+
* import { resolvers } from '@nielspeter/eess-ts/graphql'
|
|
55
|
+
* import { call } from '@nielspeter/eess-ts'
|
|
56
|
+
*
|
|
57
|
+
* const p = project('tsconfig.json')
|
|
58
|
+
* resolvers(p, 'src/resolvers/**')
|
|
59
|
+
* .that()
|
|
60
|
+
* .resolveFieldReturning(/^[A-Z]/)
|
|
61
|
+
* .should()
|
|
62
|
+
* .contain(call('loader.load'))
|
|
63
|
+
* .because('prevent N+1 queries')
|
|
64
|
+
* .check()
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolvers(p: ArchProject, glob: string): ResolverRuleBuilder;
|
|
68
|
+
export { SchemaRuleBuilder } from './schema-rule-builder.js';
|
|
69
|
+
export { ResolverRuleBuilder } from './resolver-rule-builder.js';
|
|
70
|
+
export { resolveFieldReturning } from './resolver-rule-builder.js';
|
|
71
|
+
export { queries, mutations, typesNamed, returnListOf } from './schema-predicates.js';
|
|
72
|
+
export type { SchemaElement } from './schema-predicates.js';
|
|
73
|
+
export { haveFields, acceptArgs, haveMatchingResolver } from './schema-conditions.js';
|
|
74
|
+
export { loadSchemaFromGlob, loadSchemaFromSDL, isGraphQLAvailable } from './schema-loader.js';
|
|
75
|
+
export type { LoadedSchema, GraphQLSchemaLike, GraphQLObjectTypeLike, GraphQLFieldLike, GraphQLArgumentLike, GraphQLTypeLike, } from './schema-loader.js';
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAIhE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,aAAa,EAAE,WAAW,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAK3F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAGjF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAM3E;AAID,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAGlE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrF,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAG3D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAGrF,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC9F,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,GAChB,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL extension for eess-ts.
|
|
3
|
+
*
|
|
4
|
+
* Sub-path export: `import { schema, resolvers } from '@nielspeter/eess-ts/graphql'`
|
|
5
|
+
*
|
|
6
|
+
* Requires the `graphql` npm package as an optional peer dependency.
|
|
7
|
+
* Schema loading will throw a clear error if graphql is not installed.
|
|
8
|
+
*/
|
|
9
|
+
import { loadSchemaFromGlob, loadSchemaFromSDL } from './schema-loader.js';
|
|
10
|
+
import { SchemaRuleBuilder } from './schema-rule-builder.js';
|
|
11
|
+
import { ResolverRuleBuilder } from './resolver-rule-builder.js';
|
|
12
|
+
// --- Entry points ---
|
|
13
|
+
/**
|
|
14
|
+
* Create a schema rule builder scoped to .graphql files matching the glob.
|
|
15
|
+
*
|
|
16
|
+
* @param projectOrRoot - ArchProject (uses tsconfig root) or a directory path
|
|
17
|
+
* @param glob - Glob pattern for .graphql files (e.g. 'schema/*.graphql')
|
|
18
|
+
* @returns A SchemaRuleBuilder for defining schema architecture rules
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { project } from '@nielspeter/eess-ts'
|
|
23
|
+
* import { schema } from '@nielspeter/eess-ts/graphql'
|
|
24
|
+
*
|
|
25
|
+
* const p = project('tsconfig.json')
|
|
26
|
+
* schema(p, 'src/schema/*.graphql')
|
|
27
|
+
* .typesNamed(/Collection$/)
|
|
28
|
+
* .should()
|
|
29
|
+
* .haveFields('total', 'skip', 'limit', 'items')
|
|
30
|
+
* .check()
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function schema(projectOrRoot, glob) {
|
|
34
|
+
const rootDir = typeof projectOrRoot === 'string' ? projectOrRoot : extractRootDir(projectOrRoot.tsConfigPath);
|
|
35
|
+
const loaded = loadSchemaFromGlob(rootDir, glob);
|
|
36
|
+
return new SchemaRuleBuilder(loaded);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create a schema rule builder from a raw SDL string.
|
|
40
|
+
*
|
|
41
|
+
* @param sdl - GraphQL Schema Definition Language string
|
|
42
|
+
* @param sourcePath - Optional file path for error reporting
|
|
43
|
+
* @returns A SchemaRuleBuilder
|
|
44
|
+
*/
|
|
45
|
+
export function schemaFromSDL(sdl, sourcePath) {
|
|
46
|
+
const loaded = loadSchemaFromSDL(sdl, sourcePath);
|
|
47
|
+
return new SchemaRuleBuilder(loaded);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create a resolver rule builder scoped to TypeScript files matching the glob.
|
|
51
|
+
*
|
|
52
|
+
* Resolver files are regular TypeScript — analyzed via ts-morph, not the graphql package.
|
|
53
|
+
* Conditions like contain(call('loader.load')) reuse the body analysis engine.
|
|
54
|
+
*
|
|
55
|
+
* @param p - The loaded ArchProject
|
|
56
|
+
* @param glob - Glob pattern for resolver files (e.g. 'src/resolvers/**')
|
|
57
|
+
* @returns A ResolverRuleBuilder
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* import { project } from '@nielspeter/eess-ts'
|
|
62
|
+
* import { resolvers } from '@nielspeter/eess-ts/graphql'
|
|
63
|
+
* import { call } from '@nielspeter/eess-ts'
|
|
64
|
+
*
|
|
65
|
+
* const p = project('tsconfig.json')
|
|
66
|
+
* resolvers(p, 'src/resolvers/**')
|
|
67
|
+
* .that()
|
|
68
|
+
* .resolveFieldReturning(/^[A-Z]/)
|
|
69
|
+
* .should()
|
|
70
|
+
* .contain(call('loader.load'))
|
|
71
|
+
* .because('prevent N+1 queries')
|
|
72
|
+
* .check()
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export function resolvers(p, glob) {
|
|
76
|
+
const sourceFiles = p.getSourceFiles().filter((sf) => {
|
|
77
|
+
const filePath = sf.getFilePath();
|
|
78
|
+
return picomatchFilter(filePath, glob, extractRootDir(p.tsConfigPath));
|
|
79
|
+
});
|
|
80
|
+
return new ResolverRuleBuilder(sourceFiles);
|
|
81
|
+
}
|
|
82
|
+
// --- Re-exports ---
|
|
83
|
+
export { SchemaRuleBuilder } from './schema-rule-builder.js';
|
|
84
|
+
export { ResolverRuleBuilder } from './resolver-rule-builder.js';
|
|
85
|
+
export { resolveFieldReturning } from './resolver-rule-builder.js';
|
|
86
|
+
// Schema predicates (standalone)
|
|
87
|
+
export { queries, mutations, typesNamed, returnListOf } from './schema-predicates.js';
|
|
88
|
+
// Schema conditions (standalone)
|
|
89
|
+
export { haveFields, acceptArgs, haveMatchingResolver } from './schema-conditions.js';
|
|
90
|
+
// Schema loader utilities
|
|
91
|
+
export { loadSchemaFromGlob, loadSchemaFromSDL, isGraphQLAvailable } from './schema-loader.js';
|
|
92
|
+
// --- Internal helpers ---
|
|
93
|
+
import path from 'node:path';
|
|
94
|
+
import picomatch from 'picomatch';
|
|
95
|
+
function extractRootDir(tsConfigPath) {
|
|
96
|
+
return path.dirname(tsConfigPath);
|
|
97
|
+
}
|
|
98
|
+
const matcherCache = new Map();
|
|
99
|
+
function picomatchFilter(filePath, glob, rootDir) {
|
|
100
|
+
const relativePath = path.relative(rootDir, filePath);
|
|
101
|
+
let matcher = matcherCache.get(glob);
|
|
102
|
+
if (!matcher) {
|
|
103
|
+
matcher = picomatch(glob);
|
|
104
|
+
matcherCache.set(glob, matcher);
|
|
105
|
+
}
|
|
106
|
+
return matcher(relativePath);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAEhE,uBAAuB;AAEvB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,MAAM,CAAC,aAAmC,EAAE,IAAY;IACtE,MAAM,OAAO,GACX,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,YAAY,CAAC,CAAA;IAChG,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAChD,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,UAAmB;IAC5D,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;IACjD,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,SAAS,CAAC,CAAc,EAAE,IAAY;IACpD,MAAM,WAAW,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;QACnD,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,CAAA;QACjC,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;IACxE,CAAC,CAAC,CAAA;IACF,OAAO,IAAI,mBAAmB,CAAC,WAAW,CAAC,CAAA;AAC7C,CAAC;AAED,qBAAqB;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAElE,iCAAiC;AACjC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAGrF,iCAAiC;AACjC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAErF,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAU9F,2BAA2B;AAE3B,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,SAAS,cAAc,CAAC,YAAoB;IAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;AACnC,CAAC;AAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAA;AAEzD,SAAS,eAAe,CAAC,QAAgB,EAAE,IAAY,EAAE,OAAe;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACrD,IAAI,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QACzB,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,OAAO,CAAC,YAAY,CAAC,CAAA;AAC9B,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { SourceFile } from 'ts-morph';
|
|
2
|
+
import type { ArchViolation } from '../core/violation.js';
|
|
3
|
+
import type { Predicate } from '@nielspeter/eess';
|
|
4
|
+
import { TerminalBuilder } from '@nielspeter/eess';
|
|
5
|
+
import type { ExpressionMatcher } from '../helpers/matchers.js';
|
|
6
|
+
import type { ArchFunction } from '../models/arch-function.js';
|
|
7
|
+
/**
|
|
8
|
+
* Predicate: filter to resolver functions for fields returning types matching the pattern.
|
|
9
|
+
*
|
|
10
|
+
* Heuristic: a resolver function is one whose name starts with an uppercase letter
|
|
11
|
+
* (type name) or matches common resolver naming conventions. The return type is
|
|
12
|
+
* checked against the pattern.
|
|
13
|
+
*
|
|
14
|
+
* @param pattern - Regex or string to match against the resolved return type text
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveFieldReturning(pattern: RegExp | string): Predicate<ArchFunction>;
|
|
17
|
+
/**
|
|
18
|
+
* Fluent rule builder for GraphQL resolver architecture rules.
|
|
19
|
+
*
|
|
20
|
+
* Operates on TypeScript resolver files analyzed through the ArchFunction model.
|
|
21
|
+
* Reuses the body analysis engine from plan 0011 for conditions like contain/notContain.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* resolvers(p, 'src/resolvers/**')
|
|
26
|
+
* .that()
|
|
27
|
+
* .resolveFieldReturning(/^[A-Z]/)
|
|
28
|
+
* .should()
|
|
29
|
+
* .contain(call('loader.load'))
|
|
30
|
+
* .because('prevent N+1 queries')
|
|
31
|
+
* .check()
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class ResolverRuleBuilder extends TerminalBuilder {
|
|
35
|
+
private readonly sourceFiles;
|
|
36
|
+
private readonly _predicates;
|
|
37
|
+
private readonly _conditions;
|
|
38
|
+
constructor(sourceFiles: SourceFile[]);
|
|
39
|
+
/**
|
|
40
|
+
* Filter to resolver functions for fields returning types matching the pattern.
|
|
41
|
+
*/
|
|
42
|
+
resolveFieldReturning(pattern: RegExp | string): this;
|
|
43
|
+
/**
|
|
44
|
+
* Begin the predicate phase. Purely a readability marker.
|
|
45
|
+
*/
|
|
46
|
+
that(): this;
|
|
47
|
+
/**
|
|
48
|
+
* Add another predicate (AND).
|
|
49
|
+
*/
|
|
50
|
+
and(): this;
|
|
51
|
+
/**
|
|
52
|
+
* Begin the condition phase.
|
|
53
|
+
*/
|
|
54
|
+
should(): this;
|
|
55
|
+
/**
|
|
56
|
+
* Add another condition (AND).
|
|
57
|
+
*/
|
|
58
|
+
andShould(): this;
|
|
59
|
+
/**
|
|
60
|
+
* Assert that the resolver body contains at least one match.
|
|
61
|
+
*/
|
|
62
|
+
contain(matcher: ExpressionMatcher): this;
|
|
63
|
+
/**
|
|
64
|
+
* Assert that the resolver body does NOT contain any match.
|
|
65
|
+
*/
|
|
66
|
+
notContain(matcher: ExpressionMatcher): this;
|
|
67
|
+
/**
|
|
68
|
+
* Assert: must NOT contain 'bad' AND must contain 'good'.
|
|
69
|
+
*/
|
|
70
|
+
useInsteadOf(bad: ExpressionMatcher, good: ExpressionMatcher): this;
|
|
71
|
+
protected collectViolations(): ArchViolation[];
|
|
72
|
+
private getElements;
|
|
73
|
+
private buildRuleDescription;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=resolver-rule-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver-rule-builder.d.ts","sourceRoot":"","sources":["../../src/graphql/resolver-rule-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAQ9D;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAYvF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IAI1C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAHxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;gBAE/B,WAAW,EAAE,UAAU,EAAE;IAMtD;;OAEG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOrD;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,GAAG,IAAI,IAAI;IAIX;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,SAAS,IAAI,IAAI;IAMjB;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAKzC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAK5C;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAOnE,SAAS,CAAC,iBAAiB,IAAI,aAAa,EAAE;IAmC9C,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,oBAAoB;CAQ7B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { TerminalBuilder } from '@nielspeter/eess';
|
|
2
|
+
import { collectFunctions } from '../models/arch-function.js';
|
|
3
|
+
import { functionContain, functionNotContain, functionUseInsteadOf, } from '../conditions/body-analysis-function.js';
|
|
4
|
+
/**
|
|
5
|
+
* Predicate: filter to resolver functions for fields returning types matching the pattern.
|
|
6
|
+
*
|
|
7
|
+
* Heuristic: a resolver function is one whose name starts with an uppercase letter
|
|
8
|
+
* (type name) or matches common resolver naming conventions. The return type is
|
|
9
|
+
* checked against the pattern.
|
|
10
|
+
*
|
|
11
|
+
* @param pattern - Regex or string to match against the resolved return type text
|
|
12
|
+
*/
|
|
13
|
+
export function resolveFieldReturning(pattern) {
|
|
14
|
+
const desc = typeof pattern === 'string' ? `"${pattern}"` : String(pattern);
|
|
15
|
+
return {
|
|
16
|
+
description: `resolve field returning ${desc}`,
|
|
17
|
+
test(fn) {
|
|
18
|
+
const returnType = fn.getReturnType().getText();
|
|
19
|
+
if (typeof pattern === 'string') {
|
|
20
|
+
return returnType.includes(pattern);
|
|
21
|
+
}
|
|
22
|
+
return pattern.test(returnType);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fluent rule builder for GraphQL resolver architecture rules.
|
|
28
|
+
*
|
|
29
|
+
* Operates on TypeScript resolver files analyzed through the ArchFunction model.
|
|
30
|
+
* Reuses the body analysis engine from plan 0011 for conditions like contain/notContain.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* resolvers(p, 'src/resolvers/**')
|
|
35
|
+
* .that()
|
|
36
|
+
* .resolveFieldReturning(/^[A-Z]/)
|
|
37
|
+
* .should()
|
|
38
|
+
* .contain(call('loader.load'))
|
|
39
|
+
* .because('prevent N+1 queries')
|
|
40
|
+
* .check()
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class ResolverRuleBuilder extends TerminalBuilder {
|
|
44
|
+
sourceFiles;
|
|
45
|
+
_predicates = [];
|
|
46
|
+
_conditions = [];
|
|
47
|
+
constructor(sourceFiles) {
|
|
48
|
+
super();
|
|
49
|
+
this.sourceFiles = sourceFiles;
|
|
50
|
+
}
|
|
51
|
+
// --- Predicate methods ---
|
|
52
|
+
/**
|
|
53
|
+
* Filter to resolver functions for fields returning types matching the pattern.
|
|
54
|
+
*/
|
|
55
|
+
resolveFieldReturning(pattern) {
|
|
56
|
+
this._predicates.push(resolveFieldReturning(pattern));
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
// --- Chain methods ---
|
|
60
|
+
/**
|
|
61
|
+
* Begin the predicate phase. Purely a readability marker.
|
|
62
|
+
*/
|
|
63
|
+
that() {
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Add another predicate (AND).
|
|
68
|
+
*/
|
|
69
|
+
and() {
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Begin the condition phase.
|
|
74
|
+
*/
|
|
75
|
+
should() {
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Add another condition (AND).
|
|
80
|
+
*/
|
|
81
|
+
andShould() {
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
// --- Condition methods (reuse body analysis) ---
|
|
85
|
+
/**
|
|
86
|
+
* Assert that the resolver body contains at least one match.
|
|
87
|
+
*/
|
|
88
|
+
contain(matcher) {
|
|
89
|
+
this._conditions.push(functionContain(matcher));
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Assert that the resolver body does NOT contain any match.
|
|
94
|
+
*/
|
|
95
|
+
notContain(matcher) {
|
|
96
|
+
this._conditions.push(functionNotContain(matcher));
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Assert: must NOT contain 'bad' AND must contain 'good'.
|
|
101
|
+
*/
|
|
102
|
+
useInsteadOf(bad, good) {
|
|
103
|
+
this._conditions.push(functionUseInsteadOf(bad, good));
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
// --- Evaluation ---
|
|
107
|
+
collectViolations() {
|
|
108
|
+
const allElements = this.getElements();
|
|
109
|
+
const filtered = allElements.filter((element) => this._predicates.every((predicate) => predicate.test(element)));
|
|
110
|
+
if (filtered.length === 0) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
if (this._conditions.length === 0) {
|
|
114
|
+
const ruleId = this._metadata?.id ?? 'unnamed';
|
|
115
|
+
console.warn(`[eess] Resolver rule '${ruleId}' has predicates but no conditions. ` +
|
|
116
|
+
`Did you forget to add a condition after .should()?`);
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
const context = {
|
|
120
|
+
rule: this.buildRuleDescription(),
|
|
121
|
+
because: this._reason,
|
|
122
|
+
ruleId: this._metadata?.id,
|
|
123
|
+
suggestion: this._metadata?.suggestion,
|
|
124
|
+
docs: this._metadata?.docs,
|
|
125
|
+
};
|
|
126
|
+
const violations = [];
|
|
127
|
+
for (const condition of this._conditions) {
|
|
128
|
+
violations.push(...condition.evaluate(filtered, context));
|
|
129
|
+
}
|
|
130
|
+
return violations;
|
|
131
|
+
}
|
|
132
|
+
getElements() {
|
|
133
|
+
return this.sourceFiles.flatMap((sf) => collectFunctions(sf));
|
|
134
|
+
}
|
|
135
|
+
buildRuleDescription() {
|
|
136
|
+
const predicateDesc = this._predicates.map((p) => p.description).join(' and ');
|
|
137
|
+
const conditionDesc = this._conditions.map((c) => c.description).join(' and ');
|
|
138
|
+
const parts = ['resolvers'];
|
|
139
|
+
if (predicateDesc)
|
|
140
|
+
parts.push(`that ${predicateDesc}`);
|
|
141
|
+
if (conditionDesc)
|
|
142
|
+
parts.push(`should ${conditionDesc}`);
|
|
143
|
+
return parts.join(' ');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=resolver-rule-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver-rule-builder.js","sourceRoot":"","sources":["../../src/graphql/resolver-rule-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Condition } from '@nielspeter/eess';
|
|
2
|
+
import type { SchemaElement } from './schema-predicates.js';
|
|
3
|
+
/**
|
|
4
|
+
* Assert that a type has all listed fields.
|
|
5
|
+
*
|
|
6
|
+
* When applied to a type-level SchemaElement, checks that the object type
|
|
7
|
+
* defines all the named fields. When applied to a field-level element,
|
|
8
|
+
* checks the parent type.
|
|
9
|
+
*
|
|
10
|
+
* @param names - Field names that must exist on the type
|
|
11
|
+
*/
|
|
12
|
+
export declare function haveFields(...names: string[]): Condition<SchemaElement>;
|
|
13
|
+
/**
|
|
14
|
+
* Assert that a field accepts all listed arguments.
|
|
15
|
+
*
|
|
16
|
+
* Only applies to field-level SchemaElements. Type-level elements are skipped.
|
|
17
|
+
*
|
|
18
|
+
* @param names - Argument names that must exist on the field
|
|
19
|
+
*/
|
|
20
|
+
export declare function acceptArgs(...names: string[]): Condition<SchemaElement>;
|
|
21
|
+
/**
|
|
22
|
+
* Assert that each schema field has a matching resolver export.
|
|
23
|
+
*
|
|
24
|
+
* Cross-references schema fields with TypeScript resolver files.
|
|
25
|
+
* A field "users" on type "Query" is matched if any resolver file exports
|
|
26
|
+
* a function/variable named "users" or contains a property assignment "Query.users".
|
|
27
|
+
*
|
|
28
|
+
* @param resolverFileTexts - Map of file paths to their source text (for matching)
|
|
29
|
+
*/
|
|
30
|
+
export declare function haveMatchingResolver(resolverFileTexts: ReadonlyMap<string, string>): Condition<SchemaElement>;
|
|
31
|
+
//# sourceMappingURL=schema-conditions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-conditions.d.ts","sourceRoot":"","sources":["../../src/graphql/schema-conditions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE3D;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,aAAa,CAAC,CA2BvE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,aAAa,CAAC,CA2BvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7C,SAAS,CAAC,aAAa,CAAC,CAqC1B"}
|