@wundergraph/protographic 0.18.1 → 0.19.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/dist/src/sdl-validation-visitor.d.ts +0 -8
- package/dist/src/sdl-validation-visitor.js +3 -65
- package/dist/src/sdl-validation-visitor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/src/selection-set-validation-visitor.d.ts +0 -112
- package/dist/src/selection-set-validation-visitor.js +0 -199
- package/dist/src/selection-set-validation-visitor.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wundergraph/protographic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"module": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@bufbuild/protobuf": "^1.8.0",
|
|
44
|
-
"@wundergraph/composition": "0.
|
|
45
|
-
"@wundergraph/cosmo-connect": "0.
|
|
44
|
+
"@wundergraph/composition": "0.54.1",
|
|
45
|
+
"@wundergraph/cosmo-connect": "0.137.0",
|
|
46
46
|
"graphql": "^16.9.0",
|
|
47
47
|
"lodash-es": "4.17.21",
|
|
48
48
|
"protobufjs": "^7.5.0"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "0e5fa811a1910aff80ff66b5746a69655b459708"
|
|
51
51
|
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { DocumentNode, GraphQLObjectType } from 'graphql';
|
|
2
|
-
import { ValidationResult } from './sdl-validation-visitor.js';
|
|
3
|
-
/**
|
|
4
|
-
* Validates selection sets within @requires directive field sets.
|
|
5
|
-
*
|
|
6
|
-
* This visitor traverses a parsed field set document and enforces constraints
|
|
7
|
-
* specific to @requires directives:
|
|
8
|
-
* - Abstract types (interfaces, unions) are not allowed
|
|
9
|
-
* - Inline fragments are not allowed
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* const doc = parse('{ address { street city } }');
|
|
14
|
-
* const visitor = new SelectionSetValidationVisitor(doc, ProductType);
|
|
15
|
-
* visitor.visit();
|
|
16
|
-
* const result = visitor.getValidationResult();
|
|
17
|
-
* if (result.errors.length > 0) {
|
|
18
|
-
* console.error('Validation failed:', result.errors);
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare class SelectionSetValidationVisitor {
|
|
23
|
-
private currentType;
|
|
24
|
-
private ancestors;
|
|
25
|
-
private readonly operationDocument;
|
|
26
|
-
private validationResult;
|
|
27
|
-
/**
|
|
28
|
-
* Creates a new SelectionSetValidationVisitor.
|
|
29
|
-
*
|
|
30
|
-
* @param operationDocument - The parsed GraphQL document representing the field set
|
|
31
|
-
* @param objectType - The root GraphQL object type to validate against
|
|
32
|
-
*/
|
|
33
|
-
constructor(operationDocument: DocumentNode, objectType: GraphQLObjectType);
|
|
34
|
-
/**
|
|
35
|
-
* Executes the validation by traversing the operation document.
|
|
36
|
-
* After calling this method, use `getValidationResult()` to retrieve any errors or warnings.
|
|
37
|
-
*/
|
|
38
|
-
visit(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Returns the validation result containing any errors and warnings found during traversal.
|
|
41
|
-
*
|
|
42
|
-
* @returns The validation result with errors and warnings arrays
|
|
43
|
-
*/
|
|
44
|
-
getValidationResult(): ValidationResult;
|
|
45
|
-
/**
|
|
46
|
-
* Creates the AST visitor configuration for traversing the document.
|
|
47
|
-
*
|
|
48
|
-
* @returns An ASTVisitor object with handlers for Field and SelectionSet nodes
|
|
49
|
-
*/
|
|
50
|
-
private createASTVisitor;
|
|
51
|
-
/**
|
|
52
|
-
* Handles entering a field node during traversal.
|
|
53
|
-
* Validates that the field's type is not an abstract type (interface or union).
|
|
54
|
-
*
|
|
55
|
-
* @param ctx - The visit context containing the field node and its ancestors
|
|
56
|
-
* @returns BREAK if validation fails to stop traversal, undefined otherwise
|
|
57
|
-
*/
|
|
58
|
-
private onEnterField;
|
|
59
|
-
/**
|
|
60
|
-
* Unwraps a GraphQL type to get its underlying named type.
|
|
61
|
-
* Strips NonNull and List wrappers to get the base type.
|
|
62
|
-
*
|
|
63
|
-
* @param type - The GraphQL type to unwrap
|
|
64
|
-
* @returns The underlying named type
|
|
65
|
-
*/
|
|
66
|
-
private getUnderlyingType;
|
|
67
|
-
/**
|
|
68
|
-
* Retrieves the field definition for a field node from the current type.
|
|
69
|
-
* If the field is not found, a validation error is recorded and null is returned.
|
|
70
|
-
*
|
|
71
|
-
* @param node - The field node to look up
|
|
72
|
-
* @returns The GraphQL field definition, or null if not found
|
|
73
|
-
*/
|
|
74
|
-
private getFieldDefinition;
|
|
75
|
-
/**
|
|
76
|
-
* Handles entering a selection set node during traversal.
|
|
77
|
-
* Validates that inline fragments are not used and updates the current type
|
|
78
|
-
* context when descending into nested object types.
|
|
79
|
-
*
|
|
80
|
-
* @param ctx - The visit context containing the selection set node and its parent
|
|
81
|
-
* @returns BREAK if validation fails to stop traversal, undefined otherwise
|
|
82
|
-
*/
|
|
83
|
-
private onEnterSelectionSet;
|
|
84
|
-
/**
|
|
85
|
-
* Handles leaving a selection set node during traversal.
|
|
86
|
-
* Restores the previous type context when ascending back up the tree.
|
|
87
|
-
*
|
|
88
|
-
* @param ctx - The visit context containing the selection set node and its parent
|
|
89
|
-
*/
|
|
90
|
-
private onLeaveSelectionSet;
|
|
91
|
-
/**
|
|
92
|
-
* Type guard to check if a node is an InlineFragmentNode.
|
|
93
|
-
*
|
|
94
|
-
* @param node - The AST node or array of nodes to check
|
|
95
|
-
* @returns True if the node is an InlineFragmentNode
|
|
96
|
-
*/
|
|
97
|
-
private isInlineFragment;
|
|
98
|
-
/**
|
|
99
|
-
* Type guard to check if a node is a FieldNode.
|
|
100
|
-
*
|
|
101
|
-
* @param node - The AST node or array of nodes to check
|
|
102
|
-
* @returns True if the node is a FieldNode
|
|
103
|
-
*/
|
|
104
|
-
private isFieldNode;
|
|
105
|
-
/**
|
|
106
|
-
* Checks if a named type is an abstract type (interface or union).
|
|
107
|
-
*
|
|
108
|
-
* @param node - The GraphQL named type to check
|
|
109
|
-
* @returns True if the type is an interface or union type
|
|
110
|
-
*/
|
|
111
|
-
private isAbstractType;
|
|
112
|
-
}
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { BREAK, isInterfaceType, isNamedType, isObjectType, isUnionType, Kind, visit, } from 'graphql';
|
|
2
|
-
/**
|
|
3
|
-
* Validates selection sets within @requires directive field sets.
|
|
4
|
-
*
|
|
5
|
-
* This visitor traverses a parsed field set document and enforces constraints
|
|
6
|
-
* specific to @requires directives:
|
|
7
|
-
* - Abstract types (interfaces, unions) are not allowed
|
|
8
|
-
* - Inline fragments are not allowed
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* const doc = parse('{ address { street city } }');
|
|
13
|
-
* const visitor = new SelectionSetValidationVisitor(doc, ProductType);
|
|
14
|
-
* visitor.visit();
|
|
15
|
-
* const result = visitor.getValidationResult();
|
|
16
|
-
* if (result.errors.length > 0) {
|
|
17
|
-
* console.error('Validation failed:', result.errors);
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export class SelectionSetValidationVisitor {
|
|
22
|
-
/**
|
|
23
|
-
* Creates a new SelectionSetValidationVisitor.
|
|
24
|
-
*
|
|
25
|
-
* @param operationDocument - The parsed GraphQL document representing the field set
|
|
26
|
-
* @param objectType - The root GraphQL object type to validate against
|
|
27
|
-
*/
|
|
28
|
-
constructor(operationDocument, objectType) {
|
|
29
|
-
this.ancestors = [];
|
|
30
|
-
this.validationResult = {
|
|
31
|
-
errors: [],
|
|
32
|
-
warnings: [],
|
|
33
|
-
};
|
|
34
|
-
this.operationDocument = operationDocument;
|
|
35
|
-
this.currentType = objectType;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Executes the validation by traversing the operation document.
|
|
39
|
-
* After calling this method, use `getValidationResult()` to retrieve any errors or warnings.
|
|
40
|
-
*/
|
|
41
|
-
visit() {
|
|
42
|
-
visit(this.operationDocument, this.createASTVisitor());
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Returns the validation result containing any errors and warnings found during traversal.
|
|
46
|
-
*
|
|
47
|
-
* @returns The validation result with errors and warnings arrays
|
|
48
|
-
*/
|
|
49
|
-
getValidationResult() {
|
|
50
|
-
return this.validationResult;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Creates the AST visitor configuration for traversing the document.
|
|
54
|
-
*
|
|
55
|
-
* @returns An ASTVisitor object with handlers for Field and SelectionSet nodes
|
|
56
|
-
*/
|
|
57
|
-
createASTVisitor() {
|
|
58
|
-
return {
|
|
59
|
-
Field: {
|
|
60
|
-
enter: (node, key, parent, path, ancestors) => {
|
|
61
|
-
return this.onEnterField({ node, key, parent, path, ancestors });
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
SelectionSet: {
|
|
65
|
-
enter: (node, key, parent, path, ancestors) => {
|
|
66
|
-
return this.onEnterSelectionSet({ node, key, parent, path, ancestors });
|
|
67
|
-
},
|
|
68
|
-
leave: (node, key, parent, path, ancestors) => {
|
|
69
|
-
this.onLeaveSelectionSet({ node, key, parent, path, ancestors });
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Handles entering a field node during traversal.
|
|
76
|
-
* Validates that the field's type is not an abstract type (interface or union).
|
|
77
|
-
*
|
|
78
|
-
* @param ctx - The visit context containing the field node and its ancestors
|
|
79
|
-
* @returns BREAK if validation fails to stop traversal, undefined otherwise
|
|
80
|
-
*/
|
|
81
|
-
onEnterField(ctx) {
|
|
82
|
-
const fieldDefinition = this.getFieldDefinition(ctx.node);
|
|
83
|
-
if (!fieldDefinition) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
const namedType = this.getUnderlyingType(fieldDefinition.type);
|
|
87
|
-
if (this.isAbstractType(namedType)) {
|
|
88
|
-
this.validationResult.errors.push(`Abstract types are not allowed in requires directives. Found ${namedType.name} in ${this.currentType.name}.${ctx.node.name.value}`);
|
|
89
|
-
return BREAK;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Unwraps a GraphQL type to get its underlying named type.
|
|
94
|
-
* Strips NonNull and List wrappers to get the base type.
|
|
95
|
-
*
|
|
96
|
-
* @param type - The GraphQL type to unwrap
|
|
97
|
-
* @returns The underlying named type
|
|
98
|
-
*/
|
|
99
|
-
getUnderlyingType(type) {
|
|
100
|
-
while (!isNamedType(type)) {
|
|
101
|
-
type = type.ofType;
|
|
102
|
-
}
|
|
103
|
-
return type;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Retrieves the field definition for a field node from the current type.
|
|
107
|
-
* If the field is not found, a validation error is recorded and null is returned.
|
|
108
|
-
*
|
|
109
|
-
* @param node - The field node to look up
|
|
110
|
-
* @returns The GraphQL field definition, or null if not found
|
|
111
|
-
*/
|
|
112
|
-
getFieldDefinition(node) {
|
|
113
|
-
const fieldDef = this.currentType.getFields()[node.name.value];
|
|
114
|
-
if (!fieldDef) {
|
|
115
|
-
this.validationResult.errors.push(`Field '${node.name.value}' not found on type '${this.currentType.name}'`);
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
return fieldDef;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Handles entering a selection set node during traversal.
|
|
122
|
-
* Validates that inline fragments are not used and updates the current type
|
|
123
|
-
* context when descending into nested object types.
|
|
124
|
-
*
|
|
125
|
-
* @param ctx - The visit context containing the selection set node and its parent
|
|
126
|
-
* @returns BREAK if validation fails to stop traversal, undefined otherwise
|
|
127
|
-
*/
|
|
128
|
-
onEnterSelectionSet(ctx) {
|
|
129
|
-
if (!ctx.parent) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (this.isInlineFragment(ctx.parent)) {
|
|
133
|
-
this.validationResult.errors.push('Inline fragments are not allowed in requires directives');
|
|
134
|
-
return BREAK;
|
|
135
|
-
}
|
|
136
|
-
if (!this.isFieldNode(ctx.parent)) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
const fieldDefinition = this.getFieldDefinition(ctx.parent);
|
|
140
|
-
if (!fieldDefinition) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const namedType = this.getUnderlyingType(fieldDefinition.type);
|
|
144
|
-
if (isObjectType(namedType)) {
|
|
145
|
-
this.ancestors.push(this.currentType);
|
|
146
|
-
this.currentType = namedType;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Handles leaving a selection set node during traversal.
|
|
151
|
-
* Restores the previous type context when ascending back up the tree.
|
|
152
|
-
*
|
|
153
|
-
* @param ctx - The visit context containing the selection set node and its parent
|
|
154
|
-
*/
|
|
155
|
-
onLeaveSelectionSet(ctx) {
|
|
156
|
-
var _a;
|
|
157
|
-
if (!ctx.parent) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
if (!this.isFieldNode(ctx.parent)) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
this.currentType = (_a = this.ancestors.pop()) !== null && _a !== void 0 ? _a : this.currentType;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Type guard to check if a node is an InlineFragmentNode.
|
|
167
|
-
*
|
|
168
|
-
* @param node - The AST node or array of nodes to check
|
|
169
|
-
* @returns True if the node is an InlineFragmentNode
|
|
170
|
-
*/
|
|
171
|
-
isInlineFragment(node) {
|
|
172
|
-
if (Array.isArray(node)) {
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
return node.kind === Kind.INLINE_FRAGMENT;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Type guard to check if a node is a FieldNode.
|
|
179
|
-
*
|
|
180
|
-
* @param node - The AST node or array of nodes to check
|
|
181
|
-
* @returns True if the node is a FieldNode
|
|
182
|
-
*/
|
|
183
|
-
isFieldNode(node) {
|
|
184
|
-
if (Array.isArray(node)) {
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
return node.kind === Kind.FIELD;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Checks if a named type is an abstract type (interface or union).
|
|
191
|
-
*
|
|
192
|
-
* @param node - The GraphQL named type to check
|
|
193
|
-
* @returns True if the type is an interface or union type
|
|
194
|
-
*/
|
|
195
|
-
isAbstractType(node) {
|
|
196
|
-
return isInterfaceType(node) || isUnionType(node);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
//# sourceMappingURL=selection-set-validation-visitor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"selection-set-validation-visitor.js","sourceRoot":"","sources":["../../src/selection-set-validation-visitor.ts"],"names":[],"mappings":"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"}
|