@wundergraph/protographic 0.18.2 → 0.19.1
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/abstract-selection-rewriter.js +1 -1
- package/dist/src/abstract-selection-rewriter.js.map +1 -1
- package/dist/src/required-fields-visitor.js +1 -1
- package/dist/src/required-fields-visitor.js.map +1 -1
- package/dist/src/sdl-validation-visitor.d.ts +2 -70
- package/dist/src/sdl-validation-visitor.js +49 -101
- package/dist/src/sdl-validation-visitor.js.map +1 -1
- package/dist/src/selection-set-validation-visitor.d.ts +24 -66
- package/dist/src/selection-set-validation-visitor.js +59 -110
- package/dist/src/selection-set-validation-visitor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -1,36 +1,33 @@
|
|
|
1
|
-
import { DocumentNode, GraphQLObjectType } from 'graphql';
|
|
1
|
+
import { DocumentNode, GraphQLObjectType, GraphQLSchema } from 'graphql';
|
|
2
2
|
import { ValidationResult } from './sdl-validation-visitor.js';
|
|
3
3
|
/**
|
|
4
4
|
* Validates selection sets within @requires directive field sets.
|
|
5
5
|
*
|
|
6
|
-
* This visitor traverses a parsed field set document and
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* This visitor traverses a parsed field set document and ensures that inline
|
|
7
|
+
* fragments on composite types (interfaces, unions) include `__typename` for
|
|
8
|
+
* type discrimination in protobuf. The `__typename` field can appear either
|
|
9
|
+
* in the parent field's selection set or within each inline fragment's
|
|
10
|
+
* selection set — at least one of these locations must contain it.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
-
* ```
|
|
12
|
+
* Before validation, the selection set is normalized by the
|
|
13
|
+
* {@link AbstractSelectionRewriter}, which distributes parent-level fields
|
|
14
|
+
* (including `__typename`) into each inline fragment.
|
|
21
15
|
*/
|
|
22
16
|
export declare class SelectionSetValidationVisitor {
|
|
23
|
-
private
|
|
24
|
-
private
|
|
17
|
+
private currentFieldSelectionSet;
|
|
18
|
+
private fieldSelectionSetStack;
|
|
25
19
|
private readonly operationDocument;
|
|
20
|
+
private readonly schema;
|
|
21
|
+
private readonly objectType;
|
|
26
22
|
private validationResult;
|
|
27
23
|
/**
|
|
28
24
|
* Creates a new SelectionSetValidationVisitor.
|
|
29
25
|
*
|
|
30
26
|
* @param operationDocument - The parsed GraphQL document representing the field set
|
|
31
27
|
* @param objectType - The root GraphQL object type to validate against
|
|
28
|
+
* @param schema - The full GraphQL schema, used for normalization of abstract type selections
|
|
32
29
|
*/
|
|
33
|
-
constructor(operationDocument: DocumentNode, objectType: GraphQLObjectType);
|
|
30
|
+
constructor(operationDocument: DocumentNode, objectType: GraphQLObjectType, schema: GraphQLSchema);
|
|
34
31
|
/**
|
|
35
32
|
* Executes the validation by traversing the operation document.
|
|
36
33
|
* After calling this method, use `getValidationResult()` to retrieve any errors or warnings.
|
|
@@ -43,70 +40,31 @@ export declare class SelectionSetValidationVisitor {
|
|
|
43
40
|
*/
|
|
44
41
|
getValidationResult(): ValidationResult;
|
|
45
42
|
/**
|
|
46
|
-
*
|
|
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
|
|
43
|
+
* Normalizes the parsed field set operation by rewriting abstract selections.
|
|
44
|
+
* This ensures consistent handling of interface and union type selections.
|
|
57
45
|
*/
|
|
58
|
-
private
|
|
46
|
+
private normalizeSelectionSet;
|
|
59
47
|
/**
|
|
60
|
-
*
|
|
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.
|
|
48
|
+
* Creates the AST visitor configuration for traversing the document.
|
|
70
49
|
*
|
|
71
|
-
* @
|
|
72
|
-
* @returns The GraphQL field definition, or null if not found
|
|
50
|
+
* @returns An ASTVisitor object with enter/leave handlers for SelectionSet nodes
|
|
73
51
|
*/
|
|
74
|
-
private
|
|
52
|
+
private createASTVisitor;
|
|
75
53
|
/**
|
|
76
54
|
* 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
55
|
*
|
|
80
56
|
* @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
57
|
*/
|
|
83
58
|
private onEnterSelectionSet;
|
|
59
|
+
private selectionSetContainsTypename;
|
|
84
60
|
/**
|
|
85
61
|
* Handles leaving a selection set node during traversal.
|
|
86
|
-
* Restores the previous
|
|
62
|
+
* Restores the previous field selection set from the stack when leaving a field's selection set.
|
|
87
63
|
*
|
|
88
64
|
* @param ctx - The visit context containing the selection set node and its parent
|
|
89
65
|
*/
|
|
90
66
|
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
|
-
*/
|
|
67
|
+
private getFieldPath;
|
|
97
68
|
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
69
|
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
70
|
}
|
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kind, visit, } from 'graphql';
|
|
2
|
+
import { AbstractSelectionRewriter } from './abstract-selection-rewriter.js';
|
|
2
3
|
/**
|
|
3
4
|
* Validates selection sets within @requires directive field sets.
|
|
4
5
|
*
|
|
5
|
-
* This visitor traverses a parsed field set document and
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* This visitor traverses a parsed field set document and ensures that inline
|
|
7
|
+
* fragments on composite types (interfaces, unions) include `__typename` for
|
|
8
|
+
* type discrimination in protobuf. The `__typename` field can appear either
|
|
9
|
+
* in the parent field's selection set or within each inline fragment's
|
|
10
|
+
* selection set — at least one of these locations must contain it.
|
|
9
11
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
-
* ```
|
|
12
|
+
* Before validation, the selection set is normalized by the
|
|
13
|
+
* {@link AbstractSelectionRewriter}, which distributes parent-level fields
|
|
14
|
+
* (including `__typename`) into each inline fragment.
|
|
20
15
|
*/
|
|
21
16
|
export class SelectionSetValidationVisitor {
|
|
22
17
|
/**
|
|
@@ -24,15 +19,18 @@ export class SelectionSetValidationVisitor {
|
|
|
24
19
|
*
|
|
25
20
|
* @param operationDocument - The parsed GraphQL document representing the field set
|
|
26
21
|
* @param objectType - The root GraphQL object type to validate against
|
|
22
|
+
* @param schema - The full GraphQL schema, used for normalization of abstract type selections
|
|
27
23
|
*/
|
|
28
|
-
constructor(operationDocument, objectType) {
|
|
29
|
-
this.
|
|
24
|
+
constructor(operationDocument, objectType, schema) {
|
|
25
|
+
this.fieldSelectionSetStack = [];
|
|
30
26
|
this.validationResult = {
|
|
31
27
|
errors: [],
|
|
32
28
|
warnings: [],
|
|
33
29
|
};
|
|
34
30
|
this.operationDocument = operationDocument;
|
|
35
|
-
this.
|
|
31
|
+
this.objectType = objectType;
|
|
32
|
+
this.schema = schema;
|
|
33
|
+
this.normalizeSelectionSet();
|
|
36
34
|
}
|
|
37
35
|
/**
|
|
38
36
|
* Executes the validation by traversing the operation document.
|
|
@@ -49,18 +47,21 @@ export class SelectionSetValidationVisitor {
|
|
|
49
47
|
getValidationResult() {
|
|
50
48
|
return this.validationResult;
|
|
51
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Normalizes the parsed field set operation by rewriting abstract selections.
|
|
52
|
+
* This ensures consistent handling of interface and union type selections.
|
|
53
|
+
*/
|
|
54
|
+
normalizeSelectionSet() {
|
|
55
|
+
const visitor = new AbstractSelectionRewriter(this.operationDocument, this.schema, this.objectType);
|
|
56
|
+
visitor.normalize();
|
|
57
|
+
}
|
|
52
58
|
/**
|
|
53
59
|
* Creates the AST visitor configuration for traversing the document.
|
|
54
60
|
*
|
|
55
|
-
* @returns An ASTVisitor object with handlers for
|
|
61
|
+
* @returns An ASTVisitor object with enter/leave handlers for SelectionSet nodes
|
|
56
62
|
*/
|
|
57
63
|
createASTVisitor() {
|
|
58
64
|
return {
|
|
59
|
-
Field: {
|
|
60
|
-
enter: (node, key, parent, path, ancestors) => {
|
|
61
|
-
return this.onEnterField({ node, key, parent, path, ancestors });
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
65
|
SelectionSet: {
|
|
65
66
|
enter: (node, key, parent, path, ancestors) => {
|
|
66
67
|
return this.onEnterSelectionSet({ node, key, parent, path, ancestors });
|
|
@@ -71,129 +72,77 @@ export class SelectionSetValidationVisitor {
|
|
|
71
72
|
},
|
|
72
73
|
};
|
|
73
74
|
}
|
|
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
75
|
/**
|
|
121
76
|
* 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
77
|
*
|
|
125
78
|
* @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
79
|
*/
|
|
128
80
|
onEnterSelectionSet(ctx) {
|
|
81
|
+
var _a;
|
|
82
|
+
// When we have no parent, we are at the root of the selection set.
|
|
129
83
|
if (!ctx.parent) {
|
|
130
84
|
return;
|
|
131
85
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
86
|
+
// We store the ancestor field selection sets on the stack so we can restore them when leaving a nested field.
|
|
87
|
+
if (this.isFieldNode(ctx.parent)) {
|
|
88
|
+
if (this.currentFieldSelectionSet) {
|
|
89
|
+
this.fieldSelectionSetStack.push(this.currentFieldSelectionSet);
|
|
90
|
+
}
|
|
91
|
+
this.currentFieldSelectionSet = ctx.node;
|
|
137
92
|
return;
|
|
138
93
|
}
|
|
139
|
-
|
|
140
|
-
if (!
|
|
94
|
+
// We currently only check for inline fragments.
|
|
95
|
+
if (!this.isInlineFragment(ctx.parent)) {
|
|
141
96
|
return;
|
|
142
97
|
}
|
|
143
|
-
|
|
144
|
-
if (
|
|
145
|
-
this.
|
|
146
|
-
|
|
98
|
+
// either the selection set of the inline fragment or the parent selection set must contain __typename.
|
|
99
|
+
if (!this.selectionSetContainsTypename(ctx.node) &&
|
|
100
|
+
!this.selectionSetContainsTypename(this.currentFieldSelectionSet)) {
|
|
101
|
+
const fieldPath = this.getFieldPath(ctx.ancestors);
|
|
102
|
+
const pathSuffix = fieldPath ? ` in "${fieldPath}"` : '';
|
|
103
|
+
this.validationResult.errors.push(`Selection set must contain __typename for inline fragment ${(_a = ctx.parent.typeCondition) === null || _a === void 0 ? void 0 : _a.name.value}${pathSuffix}`);
|
|
147
104
|
}
|
|
148
105
|
}
|
|
106
|
+
selectionSetContainsTypename(selectionSet) {
|
|
107
|
+
if (!selectionSet) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return selectionSet.selections.some((selection) => selection.kind === Kind.FIELD && selection.name.value === '__typename');
|
|
111
|
+
}
|
|
149
112
|
/**
|
|
150
113
|
* Handles leaving a selection set node during traversal.
|
|
151
|
-
* Restores the previous
|
|
114
|
+
* Restores the previous field selection set from the stack when leaving a field's selection set.
|
|
152
115
|
*
|
|
153
116
|
* @param ctx - The visit context containing the selection set node and its parent
|
|
154
117
|
*/
|
|
155
118
|
onLeaveSelectionSet(ctx) {
|
|
156
|
-
var _a;
|
|
157
119
|
if (!ctx.parent) {
|
|
158
120
|
return;
|
|
159
121
|
}
|
|
160
|
-
if (
|
|
161
|
-
|
|
122
|
+
if (this.isFieldNode(ctx.parent)) {
|
|
123
|
+
this.currentFieldSelectionSet = this.fieldSelectionSetStack.pop();
|
|
162
124
|
}
|
|
163
|
-
this.currentType = (_a = this.ancestors.pop()) !== null && _a !== void 0 ? _a : this.currentType;
|
|
164
125
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
126
|
+
getFieldPath(ancestors) {
|
|
127
|
+
if (!ancestors) {
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
return ancestors
|
|
131
|
+
.filter((a) => this.isFieldNode(a))
|
|
132
|
+
.map((f) => f.name.value)
|
|
133
|
+
.join('.');
|
|
134
|
+
}
|
|
171
135
|
isInlineFragment(node) {
|
|
172
136
|
if (Array.isArray(node)) {
|
|
173
137
|
return false;
|
|
174
138
|
}
|
|
175
139
|
return node.kind === Kind.INLINE_FRAGMENT;
|
|
176
140
|
}
|
|
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
141
|
isFieldNode(node) {
|
|
184
142
|
if (Array.isArray(node)) {
|
|
185
143
|
return false;
|
|
186
144
|
}
|
|
187
145
|
return node.kind === Kind.FIELD;
|
|
188
146
|
}
|
|
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
147
|
}
|
|
199
148
|
//# sourceMappingURL=selection-set-validation-visitor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-set-validation-visitor.js","sourceRoot":"","sources":["../../src/selection-set-validation-visitor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"selection-set-validation-visitor.js","sourceRoot":"","sources":["../../src/selection-set-validation-visitor.ts"],"names":[],"mappings":"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"}
|