@wundergraph/protographic 0.15.6 → 0.16.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/abstract-selection-rewriter.d.ts +265 -0
- package/dist/src/abstract-selection-rewriter.js +585 -0
- package/dist/src/abstract-selection-rewriter.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +4 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/naming-conventions.d.ts +59 -0
- package/dist/src/naming-conventions.js +82 -7
- package/dist/src/naming-conventions.js.map +1 -1
- package/dist/src/operation-to-proto.js +9 -6
- package/dist/src/operation-to-proto.js.map +1 -1
- package/dist/src/operations/field-numbering.js +6 -3
- package/dist/src/operations/field-numbering.js.map +1 -1
- package/dist/src/operations/message-builder.js +38 -23
- package/dist/src/operations/message-builder.js.map +1 -1
- package/dist/src/operations/proto-field-options.js.map +1 -1
- package/dist/src/operations/proto-text-generator.js +16 -27
- package/dist/src/operations/proto-text-generator.js.map +1 -1
- package/dist/src/operations/request-builder.js +5 -3
- package/dist/src/operations/request-builder.js.map +1 -1
- package/dist/src/operations/type-mapper.js +3 -22
- package/dist/src/operations/type-mapper.js.map +1 -1
- package/dist/src/proto-lock.js +19 -19
- package/dist/src/proto-lock.js.map +1 -1
- package/dist/src/proto-utils.d.ts +74 -0
- package/dist/src/proto-utils.js +286 -0
- package/dist/src/proto-utils.js.map +1 -0
- package/dist/src/required-fields-visitor.d.ts +230 -0
- package/dist/src/required-fields-visitor.js +513 -0
- package/dist/src/required-fields-visitor.js.map +1 -0
- package/dist/src/sdl-to-mapping-visitor.d.ts +9 -1
- package/dist/src/sdl-to-mapping-visitor.js +72 -12
- package/dist/src/sdl-to-mapping-visitor.js.map +1 -1
- package/dist/src/sdl-to-proto-visitor.d.ts +20 -66
- package/dist/src/sdl-to-proto-visitor.js +270 -390
- package/dist/src/sdl-to-proto-visitor.js.map +1 -1
- package/dist/src/sdl-validation-visitor.d.ts +2 -0
- package/dist/src/sdl-validation-visitor.js +85 -29
- package/dist/src/sdl-validation-visitor.js.map +1 -1
- package/dist/src/selection-set-validation-visitor.d.ts +112 -0
- package/dist/src/selection-set-validation-visitor.js +199 -0
- package/dist/src/selection-set-validation-visitor.js.map +1 -0
- package/dist/src/string-constants.d.ts +4 -0
- package/dist/src/string-constants.js +4 -0
- package/dist/src/string-constants.js.map +1 -1
- package/dist/src/types.d.ts +102 -0
- package/dist/src/types.js +37 -1
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -5
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { isListType, isNonNullType, isScalarType, isEnumType, getNamedType, } from 'graphql';
|
|
2
|
+
import { isUnionMessageDefinition, SCALAR_TYPE_MAP, SCALAR_WRAPPER_TYPE_MAP, } from './types.js';
|
|
3
|
+
import { unwrapNonNullType, isNestedListType, calculateNestingLevel } from './operations/list-type-utils.js';
|
|
4
|
+
import { graphqlFieldToProtoField } from './naming-conventions.js';
|
|
5
|
+
const SPACE_INDENT = ' '; // 2 spaces
|
|
6
|
+
const LINE_COMMENT_PREFIX = '// ';
|
|
7
|
+
const BLOCK_COMMENT_START = '/*';
|
|
8
|
+
const BLOCK_COMMENT_END = '*/';
|
|
9
|
+
/**
|
|
10
|
+
* Builds a message definition from a ProtoMessage object
|
|
11
|
+
* @param message - The ProtoMessage object
|
|
12
|
+
* @returns The message definition
|
|
13
|
+
*/
|
|
14
|
+
export function buildProtoMessage(includeComments, message) {
|
|
15
|
+
return buildProtoMessageWithIndent(includeComments, message, 0, new Set());
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds a message definition from a ProtoMessage object with an indent level
|
|
19
|
+
* @param includeComments - Whether to include comments
|
|
20
|
+
* @param message - The ProtoMessage object
|
|
21
|
+
* @param indent - The indent level
|
|
22
|
+
* @returns The message lines
|
|
23
|
+
*/
|
|
24
|
+
function buildProtoMessageWithIndent(includeComments, message, indent, seenTypes) {
|
|
25
|
+
const messageLines = formatComment(includeComments, message.description, indent);
|
|
26
|
+
if (seenTypes.has(message.messageName)) {
|
|
27
|
+
throw new Error(`Duplicate nested message name: ${message.messageName}`);
|
|
28
|
+
}
|
|
29
|
+
seenTypes.add(message.messageName);
|
|
30
|
+
messageLines.push(indentContent(indent, `message ${message.messageName} {`));
|
|
31
|
+
// Build nested messages first - use a new Set for this level since
|
|
32
|
+
// protobuf allows the same message name at different nesting levels
|
|
33
|
+
if (message.nestedMessages && message.nestedMessages.length > 0) {
|
|
34
|
+
const nestedSeenTypes = new Set();
|
|
35
|
+
for (const nestedMessage of message.nestedMessages) {
|
|
36
|
+
messageLines.push(...buildProtoMessageWithIndent(includeComments, nestedMessage, indent + 1, nestedSeenTypes));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (message.reservedNumbers && message.reservedNumbers.length > 0) {
|
|
40
|
+
messageLines.push(indentContent(indent + 1, `reserved ${message.reservedNumbers};`));
|
|
41
|
+
}
|
|
42
|
+
const compositeTypeFields = message.fields.filter((f) => f.compositeType);
|
|
43
|
+
for (const compositeTypeField of compositeTypeFields) {
|
|
44
|
+
messageLines.push(...buildCompositeTypeMessage(includeComments, compositeTypeField.compositeType, indent + 1, seenTypes));
|
|
45
|
+
}
|
|
46
|
+
for (const field of message.fields) {
|
|
47
|
+
if (field.description) {
|
|
48
|
+
messageLines.push(...formatComment(includeComments, field.description, indent + 1));
|
|
49
|
+
}
|
|
50
|
+
const repeated = field.isRepeated ? 'repeated ' : '';
|
|
51
|
+
messageLines.push(indentContent(indent + 1, `${repeated}${field.typeName} ${field.fieldName} = ${field.fieldNumber};`));
|
|
52
|
+
}
|
|
53
|
+
messageLines.push(indentContent(indent, '}'), '');
|
|
54
|
+
return messageLines;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Builds a composite type message
|
|
58
|
+
* @param includeComments - Whether to include comments
|
|
59
|
+
* @param compositeType - The composite type definition
|
|
60
|
+
* @param indent - The indent level
|
|
61
|
+
* @returns The message lines
|
|
62
|
+
* @example
|
|
63
|
+
* ```proto
|
|
64
|
+
* // A union type uses `value`
|
|
65
|
+
* message Animal {
|
|
66
|
+
* oneof value {
|
|
67
|
+
* Cat cat = 1;
|
|
68
|
+
* Dog dog = 2;
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* // An interface type uses `instance`
|
|
73
|
+
* message Animal {
|
|
74
|
+
* oneof instance {
|
|
75
|
+
* Cat cat = 1;
|
|
76
|
+
* Dog dog = 2;
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
function buildCompositeTypeMessage(includeComments, compositeType, indent, seenTypes) {
|
|
82
|
+
if (seenTypes.has(compositeType.typeName)) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
seenTypes.add(compositeType.typeName);
|
|
86
|
+
const lines = [];
|
|
87
|
+
if (includeComments && compositeType.description) {
|
|
88
|
+
lines.push(...formatComment(includeComments, compositeType.description, indent));
|
|
89
|
+
}
|
|
90
|
+
let oneOfName = '';
|
|
91
|
+
let compositeTypes = [];
|
|
92
|
+
if (isUnionMessageDefinition(compositeType)) {
|
|
93
|
+
oneOfName = 'value';
|
|
94
|
+
compositeTypes = compositeType.memberTypes;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
oneOfName = 'instance';
|
|
98
|
+
compositeTypes = compositeType.implementingTypes;
|
|
99
|
+
}
|
|
100
|
+
// Create a sorted copy to ensure deterministic field numbers without mutating the input.
|
|
101
|
+
compositeTypes = [...compositeTypes].sort((a, b) => a.localeCompare(b));
|
|
102
|
+
lines.push(indentContent(indent, `message ${compositeType.typeName} {`), indentContent(indent + 1, `oneof ${oneOfName} {`));
|
|
103
|
+
for (const [index, compositeType] of compositeTypes.entries()) {
|
|
104
|
+
lines.push(indentContent(indent + 2, `${compositeType} ${graphqlFieldToProtoField(compositeType)} = ${index + 1};`));
|
|
105
|
+
}
|
|
106
|
+
lines.push(indentContent(indent + 1, '}'));
|
|
107
|
+
lines.push(indentContent(indent, '}'));
|
|
108
|
+
return lines;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Convert a GraphQL description to Protocol Buffer comment
|
|
112
|
+
* @param description - The GraphQL description text
|
|
113
|
+
* @param indentLevel - The level of indentation for the comment (in number of 2-space blocks)
|
|
114
|
+
* @returns Array of comment lines with proper indentation
|
|
115
|
+
*/
|
|
116
|
+
export function formatComment(includeComments, description, indentLevel = 0) {
|
|
117
|
+
if (!includeComments || !description) {
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
// Sanitize description to prevent breaking block comments.
|
|
121
|
+
// Replace "/*" and "*/" with safe alternatives so they don't interfere
|
|
122
|
+
// with the BLOCK_COMMENT_START/BLOCK_COMMENT_END markers.
|
|
123
|
+
const sanitized = description.replace(/\/\*/g, '/ *').replace(/\*\//g, '* /');
|
|
124
|
+
// Use 2-space indentation consistently
|
|
125
|
+
const indent = SPACE_INDENT.repeat(indentLevel);
|
|
126
|
+
const lines = sanitized.trim().split('\n');
|
|
127
|
+
return lines.length === 1
|
|
128
|
+
? [`${indent}${LINE_COMMENT_PREFIX}${lines[0]}`]
|
|
129
|
+
: [
|
|
130
|
+
`${indent}${BLOCK_COMMENT_START}`,
|
|
131
|
+
...lines.map((line) => `${indent} * ${line}`),
|
|
132
|
+
`${indent} ${BLOCK_COMMENT_END}`,
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
export function renderRPCMethod(includeComments, rpcMethod) {
|
|
136
|
+
const lines = [];
|
|
137
|
+
if (includeComments && rpcMethod.description) {
|
|
138
|
+
lines.push(...formatComment(includeComments, rpcMethod.description, 1));
|
|
139
|
+
}
|
|
140
|
+
lines.push(indentContent(1, `rpc ${rpcMethod.name}(${rpcMethod.request}) returns (${rpcMethod.response}) {}`));
|
|
141
|
+
return lines;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Map GraphQL type to Protocol Buffer type
|
|
145
|
+
*
|
|
146
|
+
* Determines the appropriate Protocol Buffer type for a given GraphQL type,
|
|
147
|
+
* including the use of wrapper types for nullable scalar fields to distinguish
|
|
148
|
+
* between unset fields and zero values.
|
|
149
|
+
*
|
|
150
|
+
* @param graphqlType - The GraphQL type to convert
|
|
151
|
+
* @param ignoreWrapperTypes - If true, do not use wrapper types for nullable scalar fields
|
|
152
|
+
* @returns The corresponding Protocol Buffer type name
|
|
153
|
+
*/
|
|
154
|
+
export function getProtoTypeFromGraphQL(includeComments, graphqlType, ignoreWrapperTypes = false) {
|
|
155
|
+
// Nullable lists need to be handled first, otherwise they will be treated as scalar types
|
|
156
|
+
if (isListType(graphqlType) || (isNonNullType(graphqlType) && isListType(graphqlType.ofType))) {
|
|
157
|
+
return handleListType(includeComments, graphqlType);
|
|
158
|
+
}
|
|
159
|
+
// For nullable scalar types, use wrapper types
|
|
160
|
+
if (isScalarType(graphqlType)) {
|
|
161
|
+
if (ignoreWrapperTypes) {
|
|
162
|
+
return { typeName: SCALAR_TYPE_MAP[graphqlType.name] || 'string', isRepeated: false, isWrapper: false };
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
typeName: SCALAR_WRAPPER_TYPE_MAP[graphqlType.name] || 'google.protobuf.StringValue',
|
|
166
|
+
isRepeated: false,
|
|
167
|
+
isWrapper: true,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (isEnumType(graphqlType)) {
|
|
171
|
+
return { typeName: graphqlType.name, isRepeated: false, isWrapper: false };
|
|
172
|
+
}
|
|
173
|
+
if (isNonNullType(graphqlType)) {
|
|
174
|
+
// For non-null scalar types, use the base type
|
|
175
|
+
if (isScalarType(graphqlType.ofType)) {
|
|
176
|
+
return { typeName: SCALAR_TYPE_MAP[graphqlType.ofType.name] || 'string', isRepeated: false, isWrapper: false };
|
|
177
|
+
}
|
|
178
|
+
return getProtoTypeFromGraphQL(includeComments, graphqlType.ofType);
|
|
179
|
+
}
|
|
180
|
+
// Named types (object, interface, union, input)
|
|
181
|
+
const namedType = graphqlType;
|
|
182
|
+
if (namedType && typeof namedType.name === 'string') {
|
|
183
|
+
return { typeName: namedType.name, isRepeated: false, isWrapper: false };
|
|
184
|
+
}
|
|
185
|
+
return { typeName: 'string', isRepeated: false, isWrapper: false }; // Default fallback
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Converts GraphQL list types to appropriate Protocol Buffer representations.
|
|
189
|
+
*
|
|
190
|
+
* For non-nullable, single-level lists (e.g., [String!]!), generates simple repeated fields.
|
|
191
|
+
* For nullable lists (e.g., [String]) or nested lists (e.g., [[String]]), creates wrapper
|
|
192
|
+
* messages to properly handle nullability in proto3.
|
|
193
|
+
*
|
|
194
|
+
* Examples:
|
|
195
|
+
* - [String!]! → repeated string field_name = 1;
|
|
196
|
+
* - [String] → ListOfString field_name = 1; (with wrapper message)
|
|
197
|
+
* - [[String!]!]! → ListOfListOfString field_name = 1; (with nested wrapper messages)
|
|
198
|
+
* - [[String]] → ListOfListOfString field_name = 1; (with nested wrapper messages)
|
|
199
|
+
*
|
|
200
|
+
* @param graphqlType - The GraphQL list type to convert
|
|
201
|
+
* @returns ProtoType object containing the type name and whether it should be repeated
|
|
202
|
+
*/
|
|
203
|
+
export function handleListType(includeComments, graphqlType) {
|
|
204
|
+
const listType = unwrapNonNullType(graphqlType);
|
|
205
|
+
const isNullableList = !isNonNullType(graphqlType);
|
|
206
|
+
const isNested = isNestedListType(listType);
|
|
207
|
+
// Simple non-nullable lists can use repeated fields directly
|
|
208
|
+
if (!isNullableList && !isNested) {
|
|
209
|
+
return { ...getProtoTypeFromGraphQL(includeComments, getNamedType(listType), true), isRepeated: true };
|
|
210
|
+
}
|
|
211
|
+
// Nullable or nested lists need wrapper messages
|
|
212
|
+
const baseType = getNamedType(listType);
|
|
213
|
+
const nestingLevel = calculateNestingLevel(listType);
|
|
214
|
+
// For nested lists, always use full nesting level to preserve inner list nullability
|
|
215
|
+
// For single-level nullable lists, use nesting level 1
|
|
216
|
+
const wrapperNestingLevel = isNested ? nestingLevel : 1;
|
|
217
|
+
// Generate all required wrapper messages
|
|
218
|
+
const wrapperName = listNameByNestingLevel(wrapperNestingLevel, baseType);
|
|
219
|
+
// For nested lists, never use repeated at field level to preserve nullability
|
|
220
|
+
return {
|
|
221
|
+
typeName: wrapperName,
|
|
222
|
+
isWrapper: false,
|
|
223
|
+
isRepeated: false,
|
|
224
|
+
listWrapper: { baseType, nestingLevel: wrapperNestingLevel },
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
export function listNameByNestingLevel(nestingLevel, baseType) {
|
|
228
|
+
return `${'ListOf'.repeat(nestingLevel)}${baseType.name}`;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Creates wrapper messages for nullable or nested GraphQL lists.
|
|
232
|
+
*
|
|
233
|
+
* Generates Protocol Buffer message definitions to handle list nullability and nesting.
|
|
234
|
+
* The wrapper messages are stored and later included in the final proto output.
|
|
235
|
+
*
|
|
236
|
+
* For level 1: Creates simple wrapper like:
|
|
237
|
+
* message ListOfString {
|
|
238
|
+
* repeated string items = 1;
|
|
239
|
+
* }
|
|
240
|
+
*
|
|
241
|
+
* For level > 1: Creates nested wrapper structures like:
|
|
242
|
+
* message ListOfListOfString {
|
|
243
|
+
* message List {
|
|
244
|
+
* repeated ListOfString items = 1;
|
|
245
|
+
* }
|
|
246
|
+
* List list = 1;
|
|
247
|
+
* }
|
|
248
|
+
*
|
|
249
|
+
* @param includeComments - Whether to include descriptive comments in the output
|
|
250
|
+
* @param level - The nesting level (1 for simple wrapper, >1 for nested structures)
|
|
251
|
+
* @param baseType - The GraphQL base type being wrapped (e.g., String, User, etc.)
|
|
252
|
+
* @returns The generated wrapper message definition as a proto message string.
|
|
253
|
+
* Constructs a `wrapperName` (e.g., "ListOfString", "ListOfListOfUser") and
|
|
254
|
+
* uses `buildWrapperMessage(includeComments, wrapperName, level, baseType)`
|
|
255
|
+
* to render the full message text.
|
|
256
|
+
*/
|
|
257
|
+
export function createNestedListWrapper(includeComments, level, baseType) {
|
|
258
|
+
const wrapperName = `${'ListOf'.repeat(level)}${baseType.name}`;
|
|
259
|
+
return buildWrapperMessage(includeComments, wrapperName, level, baseType).join('\n');
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Builds the message lines for a wrapper message
|
|
263
|
+
*/
|
|
264
|
+
function buildWrapperMessage(includeComments, wrapperName, level, baseType) {
|
|
265
|
+
const lines = [];
|
|
266
|
+
// Add comment if enabled
|
|
267
|
+
if (includeComments) {
|
|
268
|
+
lines.push(...formatComment(includeComments, `Wrapper message for a list of ${baseType.name}.`, 0));
|
|
269
|
+
}
|
|
270
|
+
lines.push(`message ${wrapperName} {`);
|
|
271
|
+
let innerWrapperName = '';
|
|
272
|
+
innerWrapperName =
|
|
273
|
+
level > 1
|
|
274
|
+
? `${'ListOf'.repeat(level - 1)}${baseType.name}`
|
|
275
|
+
: getProtoTypeFromGraphQL(includeComments, baseType, true).typeName;
|
|
276
|
+
lines.push(indentContent(1, `message List {`), indentContent(2, `repeated ${innerWrapperName} items = 1;`), indentContent(1, `}`), indentContent(1, `List list = 1;`), `}`);
|
|
277
|
+
return lines;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Indents the content by the given indent level
|
|
281
|
+
* @param indentLevel - The indent level
|
|
282
|
+
* @param content - The content to indent
|
|
283
|
+
* @returns The indented content
|
|
284
|
+
*/
|
|
285
|
+
const indentContent = (indentLevel, content) => SPACE_INDENT.repeat(indentLevel) + content;
|
|
286
|
+
//# sourceMappingURL=proto-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proto-utils.js","sourceRoot":"","sources":["../../src/proto-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { GraphQLField, GraphQLObjectType, GraphQLSchema } from 'graphql';
|
|
2
|
+
import { FieldMapping } from '@wundergraph/cosmo-connect/dist/node/v1/node_pb';
|
|
3
|
+
import { ProtoMessage, RPCMethod } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A record mapping key directive strings to their corresponding RequiredFieldMapping.
|
|
6
|
+
* Each entity can have multiple @key directives, and each key needs its own RPC mapping.
|
|
7
|
+
*/
|
|
8
|
+
type RequiredFieldMappings = Record<string, RequiredFieldMapping>;
|
|
9
|
+
/**
|
|
10
|
+
* Represents the mapping configuration for a single @requires field.
|
|
11
|
+
* This mapping is keyed by the @key directive fields string.
|
|
12
|
+
*/
|
|
13
|
+
export type RequiredFieldMapping = {
|
|
14
|
+
/** The RPC method configuration for resolving this required field */
|
|
15
|
+
rpc?: RPCMethod;
|
|
16
|
+
/** The field mapping between GraphQL and proto field names */
|
|
17
|
+
requiredFieldMapping?: FieldMapping;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Generates protobuf messages and RPC methods for @requires directive field sets.
|
|
21
|
+
*
|
|
22
|
+
* This visitor processes the field set defined in a @requires directive and generates:
|
|
23
|
+
* - RPC method definitions for fetching required fields
|
|
24
|
+
* - Request/response message definitions
|
|
25
|
+
* - Field mappings between GraphQL and protobuf
|
|
26
|
+
*
|
|
27
|
+
* The visitor handles each @key directive on the entity separately, creating
|
|
28
|
+
* distinct RPC methods for each key since required fields may need to be
|
|
29
|
+
* fetched using different entity keys.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const visitor = new RequiredFieldsVisitor(
|
|
34
|
+
* schema,
|
|
35
|
+
* ProductType,
|
|
36
|
+
* weightField,
|
|
37
|
+
* 'dimensions { width height }'
|
|
38
|
+
* );
|
|
39
|
+
* visitor.visit();
|
|
40
|
+
*
|
|
41
|
+
* const messages = visitor.getMessageDefinitions();
|
|
42
|
+
* const rpcs = visitor.getRPCMethods();
|
|
43
|
+
* const mappings = visitor.getMapping();
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare class RequiredFieldsVisitor {
|
|
47
|
+
private readonly schema;
|
|
48
|
+
private readonly objectType;
|
|
49
|
+
private readonly requiredField;
|
|
50
|
+
private readonly visitor;
|
|
51
|
+
private readonly fieldSetDoc;
|
|
52
|
+
private ancestors;
|
|
53
|
+
private currentType;
|
|
54
|
+
private keyDirectives;
|
|
55
|
+
private currentKeyFieldsString;
|
|
56
|
+
/** Collected RPC methods for the required fields */
|
|
57
|
+
private rpcMethods;
|
|
58
|
+
/** All generated protobuf message definitions */
|
|
59
|
+
private messageDefinitions;
|
|
60
|
+
/** The current required field message being built */
|
|
61
|
+
private requiredFieldMessage;
|
|
62
|
+
/** The current message context during traversal */
|
|
63
|
+
private current;
|
|
64
|
+
/** Stack for tracking nested message contexts */
|
|
65
|
+
private stack;
|
|
66
|
+
private currentInlineFragment?;
|
|
67
|
+
private inlineFragmentStack;
|
|
68
|
+
/** Mappings keyed by @key directive fields string */
|
|
69
|
+
private mapping;
|
|
70
|
+
/**
|
|
71
|
+
* Creates a new RequiredFieldsVisitor.
|
|
72
|
+
*
|
|
73
|
+
* @param schema - The GraphQL schema containing type definitions
|
|
74
|
+
* @param objectType - The entity type that has the @requires directive
|
|
75
|
+
* @param requiredField - The field with the @requires directive
|
|
76
|
+
* @param fieldSet - The field set string from the @requires directive (e.g., "dimensions { width height }")
|
|
77
|
+
* @param options - Optional configuration options
|
|
78
|
+
* @throws Error if the object type is not an entity (has no @key directive)
|
|
79
|
+
*/
|
|
80
|
+
constructor(schema: GraphQLSchema, objectType: GraphQLObjectType, requiredField: GraphQLField<any, any, any>, fieldSet: string);
|
|
81
|
+
/**
|
|
82
|
+
* Executes the visitor, processing the field set for each @key directive.
|
|
83
|
+
* Creates separate RPC methods and mappings for each entity key.
|
|
84
|
+
*/
|
|
85
|
+
visit(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Normalizes the parsed field set operation by rewriting abstract selections.
|
|
88
|
+
* This ensures consistent handling of interface and union type selections.
|
|
89
|
+
*/
|
|
90
|
+
private normalizeSelectionSet;
|
|
91
|
+
/**
|
|
92
|
+
* Returns all generated protobuf message definitions.
|
|
93
|
+
*
|
|
94
|
+
* @returns Array of ProtoMessage definitions for request, response, and nested messages
|
|
95
|
+
*/
|
|
96
|
+
getMessageDefinitions(): ProtoMessage[];
|
|
97
|
+
/**
|
|
98
|
+
* Returns the generated RPC method definitions.
|
|
99
|
+
*
|
|
100
|
+
* @returns Array of RPCMethod definitions for fetching required fields
|
|
101
|
+
*/
|
|
102
|
+
getRPCMethods(): RPCMethod[];
|
|
103
|
+
/**
|
|
104
|
+
* Returns the field mappings keyed by @key directive fields string.
|
|
105
|
+
*
|
|
106
|
+
* @returns Record mapping key strings to their RequiredFieldMapping configurations
|
|
107
|
+
*/
|
|
108
|
+
getMapping(): RequiredFieldMappings;
|
|
109
|
+
/**
|
|
110
|
+
* Resolves all @key directives from the object type.
|
|
111
|
+
* Each key directive will result in a separate RPC method.
|
|
112
|
+
*
|
|
113
|
+
* @throws Error if the object type has no @key directives
|
|
114
|
+
*/
|
|
115
|
+
private resolveKeyDirectives;
|
|
116
|
+
/**
|
|
117
|
+
* Creates the AST visitor configuration for traversing the field set document.
|
|
118
|
+
*
|
|
119
|
+
* @returns An ASTVisitor with handlers for Document, Field, InlineFragment, and SelectionSet nodes
|
|
120
|
+
*/
|
|
121
|
+
private createASTVisitor;
|
|
122
|
+
/**
|
|
123
|
+
* Handles leaving the document node.
|
|
124
|
+
* Finalizes the required field message and generates type field mappings.
|
|
125
|
+
*/
|
|
126
|
+
private onLeaveDocument;
|
|
127
|
+
/**
|
|
128
|
+
* Handles entering the document node.
|
|
129
|
+
* Creates the RPC method definition and all request/response message structures
|
|
130
|
+
* for fetching the required fields.
|
|
131
|
+
*
|
|
132
|
+
* @param node - The document node being entered
|
|
133
|
+
*/
|
|
134
|
+
private onEnterDocument;
|
|
135
|
+
/**
|
|
136
|
+
* Handles entering a field node during traversal.
|
|
137
|
+
* Adds the field to the current proto message with appropriate type mapping.
|
|
138
|
+
*
|
|
139
|
+
* @param ctx - The visit context containing the field node and its ancestors
|
|
140
|
+
* @throws Error if the field definition is not found on the current type
|
|
141
|
+
*/
|
|
142
|
+
private onEnterField;
|
|
143
|
+
/**
|
|
144
|
+
* Handles entering an inline fragment node.
|
|
145
|
+
* Pushes the current inline fragment onto the stack for nested fragment handling.
|
|
146
|
+
*
|
|
147
|
+
* @param ctx - The visit context containing the inline fragment node
|
|
148
|
+
*/
|
|
149
|
+
private onEnterInlineFragment;
|
|
150
|
+
/**
|
|
151
|
+
* Handles leaving an inline fragment node.
|
|
152
|
+
* Records union member types when processing union type fragments.
|
|
153
|
+
*
|
|
154
|
+
* @param ctx - The visit context containing the inline fragment node
|
|
155
|
+
*/
|
|
156
|
+
private onLeaveInlineFragment;
|
|
157
|
+
/**
|
|
158
|
+
* Handles entering a selection set node.
|
|
159
|
+
* Creates a new nested proto message for object type selections and updates
|
|
160
|
+
* the current type context for proper field resolution.
|
|
161
|
+
*
|
|
162
|
+
* @param ctx - The visit context containing the selection set node and its parent
|
|
163
|
+
*/
|
|
164
|
+
private onEnterSelectionSet;
|
|
165
|
+
/**
|
|
166
|
+
* Handles leaving a selection set node.
|
|
167
|
+
* Restores the previous type and message context when ascending the tree,
|
|
168
|
+
* but only if onEnterSelectionSet actually pushed state.
|
|
169
|
+
*
|
|
170
|
+
* @param ctx - The visit context containing the selection set node
|
|
171
|
+
*/
|
|
172
|
+
private onLeaveSelectionSet;
|
|
173
|
+
/**
|
|
174
|
+
* Handles composite types (interfaces and unions) by setting up the
|
|
175
|
+
* appropriate composite type metadata on the current message.
|
|
176
|
+
*
|
|
177
|
+
* @param fieldDefinition - The field definition with a composite type
|
|
178
|
+
*/
|
|
179
|
+
private handleCompositeType;
|
|
180
|
+
/**
|
|
181
|
+
* Type guard to check if a node is a FieldNode.
|
|
182
|
+
*
|
|
183
|
+
* @param node - The AST node or array of nodes to check
|
|
184
|
+
* @returns True if the node is a FieldNode
|
|
185
|
+
*/
|
|
186
|
+
private isFieldNode;
|
|
187
|
+
/**
|
|
188
|
+
* Type guard to check if a node is an InlineFragmentNode.
|
|
189
|
+
*
|
|
190
|
+
* @param node - The AST node or array of nodes to check
|
|
191
|
+
* @returns True if the node is an InlineFragmentNode
|
|
192
|
+
*/
|
|
193
|
+
private isInlineFragmentNode;
|
|
194
|
+
/**
|
|
195
|
+
* Finds the GraphQL object type for a field by looking up the field's return type.
|
|
196
|
+
*
|
|
197
|
+
* @param fieldName - The name of the field to look up
|
|
198
|
+
* @returns The GraphQL object type if the field returns an object type, undefined otherwise
|
|
199
|
+
*/
|
|
200
|
+
private findObjectTypeForField;
|
|
201
|
+
/**
|
|
202
|
+
* Retrieves the field definition for a field name from the current type.
|
|
203
|
+
*
|
|
204
|
+
* @param fieldName - The name of the field to look up
|
|
205
|
+
* @returns The GraphQL field definition, or undefined if not found
|
|
206
|
+
*/
|
|
207
|
+
private fieldDefinition;
|
|
208
|
+
/**
|
|
209
|
+
* Finds a GraphQL object type by name from the schema's type map.
|
|
210
|
+
*
|
|
211
|
+
* @param typeName - The name of the type to find
|
|
212
|
+
* @returns The GraphQL object type if found and is an object type, undefined otherwise
|
|
213
|
+
*/
|
|
214
|
+
private findObjectType;
|
|
215
|
+
/**
|
|
216
|
+
* Extracts the fields string from a @key directive's fields argument.
|
|
217
|
+
*
|
|
218
|
+
* @param directive - The @key directive node
|
|
219
|
+
* @returns The fields string value, or empty string if not found
|
|
220
|
+
*/
|
|
221
|
+
private getKeyFieldsString;
|
|
222
|
+
/**
|
|
223
|
+
* Checks if a GraphQL type is a composite type (interface or union).
|
|
224
|
+
*
|
|
225
|
+
* @param type - The GraphQL type to check
|
|
226
|
+
* @returns True if the type is an interface or union type
|
|
227
|
+
*/
|
|
228
|
+
private isCompositeType;
|
|
229
|
+
}
|
|
230
|
+
export {};
|