@wundergraph/composition 0.37.0 → 0.37.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.
Files changed (70) hide show
  1. package/README.md +41 -48
  2. package/dist/ast/utils.js +2 -2
  3. package/dist/ast/utils.js.map +1 -1
  4. package/dist/errors/errors.d.ts +9 -12
  5. package/dist/errors/errors.js +71 -68
  6. package/dist/errors/errors.js.map +1 -1
  7. package/dist/federation/types.d.ts +2 -2
  8. package/dist/index.d.ts +4 -2
  9. package/dist/index.js +4 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/normalization/normalization.d.ts +3 -1
  12. package/dist/normalization/normalization.js +8 -0
  13. package/dist/normalization/normalization.js.map +1 -1
  14. package/dist/normalization/types.d.ts +2 -2
  15. package/dist/resolvability-graph/graph-nodes.d.ts +1 -1
  16. package/dist/resolvability-graph/graph-nodes.js.map +1 -1
  17. package/dist/resolvability-graph/graph.d.ts +1 -2
  18. package/dist/resolvability-graph/graph.js.map +1 -1
  19. package/dist/resolvability-graph/utils.d.ts +1 -1
  20. package/dist/resolvability-graph/utils.js.map +1 -1
  21. package/dist/router-configuration/{router-configuration.d.ts → types.d.ts} +3 -4
  22. package/dist/router-configuration/types.js +3 -0
  23. package/dist/router-configuration/types.js.map +1 -0
  24. package/dist/router-configuration/utils.d.ts +3 -0
  25. package/dist/router-configuration/{router-configuration.js → utils.js} +9 -1
  26. package/dist/router-configuration/utils.js.map +1 -0
  27. package/dist/schema-building/types.d.ts +23 -7
  28. package/dist/schema-building/types.js.map +1 -1
  29. package/dist/schema-building/utils.d.ts +3 -6
  30. package/dist/schema-building/utils.js +11 -8
  31. package/dist/schema-building/utils.js.map +1 -1
  32. package/dist/subgraph/types.d.ts +1 -1
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/dist/utils/composition-version.js +1 -1
  35. package/dist/utils/string-constants.d.ts +3 -2
  36. package/dist/utils/string-constants.js +5 -4
  37. package/dist/utils/string-constants.js.map +1 -1
  38. package/dist/utils/types.d.ts +38 -0
  39. package/dist/utils/utils.d.ts +0 -48
  40. package/dist/utils/utils.js +0 -10
  41. package/dist/utils/utils.js.map +1 -1
  42. package/dist/v1/federation/federation-factory.d.ts +4 -4
  43. package/dist/v1/federation/federation-factory.js +46 -35
  44. package/dist/v1/federation/federation-factory.js.map +1 -1
  45. package/dist/v1/federation/utils.d.ts +7 -8
  46. package/dist/v1/federation/utils.js +22 -20
  47. package/dist/v1/federation/utils.js.map +1 -1
  48. package/dist/v1/normalization/normalization-factory.d.ts +19 -22
  49. package/dist/v1/normalization/normalization-factory.js +568 -70
  50. package/dist/v1/normalization/normalization-factory.js.map +1 -1
  51. package/dist/v1/normalization/types.d.ts +49 -0
  52. package/dist/v1/normalization/types.js +3 -0
  53. package/dist/v1/normalization/types.js.map +1 -0
  54. package/dist/v1/normalization/utils.d.ts +7 -42
  55. package/dist/v1/normalization/utils.js +59 -382
  56. package/dist/v1/normalization/utils.js.map +1 -1
  57. package/dist/v1/normalization/walkers.js +36 -23
  58. package/dist/v1/normalization/walkers.js.map +1 -1
  59. package/dist/v1/utils/utils.d.ts +15 -12
  60. package/dist/v1/utils/utils.js +53 -47
  61. package/dist/v1/utils/utils.js.map +1 -1
  62. package/dist/v1/warnings/warnings.d.ts +4 -3
  63. package/dist/v1/warnings/warnings.js +47 -17
  64. package/dist/v1/warnings/warnings.js.map +1 -1
  65. package/dist/warnings/{warnings.js → types.js} +1 -1
  66. package/dist/warnings/types.js.map +1 -0
  67. package/package.json +2 -2
  68. package/dist/router-configuration/router-configuration.js.map +0 -1
  69. package/dist/warnings/warnings.js.map +0 -1
  70. /package/dist/warnings/{warnings.d.ts → types.d.ts} +0 -0
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.newKeyFieldSetData = newKeyFieldSetData;
4
3
  exports.newFieldSetData = newFieldSetData;
5
- exports.addFieldNamesToConfigurationData = addFieldNamesToConfigurationData;
6
4
  exports.extractFieldSetValue = extractFieldSetValue;
7
5
  exports.getNormalizedFieldSet = getNormalizedFieldSet;
6
+ exports.getInitialFieldCoordsPath = getInitialFieldCoordsPath;
8
7
  exports.validateKeyFieldSets = validateKeyFieldSets;
9
- exports.validateAndAddConditionalFieldSetsToConfiguration = validateAndAddConditionalFieldSetsToConfiguration;
8
+ exports.getConditionalFieldSetDirectiveName = getConditionalFieldSetDirectiveName;
10
9
  exports.isNodeQuery = isNodeQuery;
11
10
  exports.validateArgumentTemplateReferences = validateArgumentTemplateReferences;
12
11
  exports.initializeDirectiveDefinitionDatas = initializeDirectiveDefinitionDatas;
@@ -14,43 +13,16 @@ const graphql_1 = require("graphql");
14
13
  const utils_1 = require("../../ast/utils");
15
14
  const errors_1 = require("../../errors/errors");
16
15
  const constants_1 = require("../utils/constants");
17
- const router_configuration_1 = require("../../router-configuration/router-configuration");
18
16
  const ast_1 = require("../../schema-building/ast");
19
- const utils_2 = require("../../schema-building/utils");
20
- const warnings_1 = require("../warnings/warnings");
21
17
  const directive_definition_data_1 = require("./directive-definition-data");
22
18
  const string_constants_1 = require("../../utils/string-constants");
23
- const utils_3 = require("../../utils/utils");
24
- function newKeyFieldSetData() {
25
- return {
26
- isUnresolvableByKeyFieldSet: new Map(),
27
- };
28
- }
19
+ const utils_2 = require("../../utils/utils");
29
20
  function newFieldSetData() {
30
21
  return {
31
22
  provides: new Map(),
32
23
  requires: new Map(),
33
24
  };
34
25
  }
35
- function addFieldNamesToConfigurationData(fieldDataByFieldName, configurationData) {
36
- const externalFieldNames = new Set();
37
- for (const [fieldName, fieldContainer] of fieldDataByFieldName) {
38
- if (fieldContainer.directivesByDirectiveName.has(string_constants_1.EXTERNAL)) {
39
- if (configurationData.externalFieldNames) {
40
- configurationData.externalFieldNames.add(fieldName);
41
- }
42
- else {
43
- externalFieldNames.add(fieldName);
44
- }
45
- }
46
- else {
47
- configurationData.fieldNames.add(fieldName);
48
- }
49
- }
50
- if (externalFieldNames.size > 0) {
51
- configurationData.externalFieldNames = externalFieldNames;
52
- }
53
- }
54
26
  function extractFieldSetValue(name, map, directives) {
55
27
  // ALl directive validation errors are accounted for later
56
28
  // Requires and provides should not be repeatable, so the length should be no more than 1
@@ -78,249 +50,28 @@ function getNormalizedFieldSet(documentNode) {
78
50
  */
79
51
  return (0, graphql_1.print)((0, utils_1.lexicographicallySortDocumentNode)(documentNode)).replaceAll(/\s+/g, ' ').slice(2, -2);
80
52
  }
81
- function getInitialFieldCoordinatesPath(fieldSetDirective, directiveParentTypeName, directiveFieldName) {
82
- switch (fieldSetDirective) {
83
- case utils_2.FieldSetDirective.PROVIDES:
84
- return [`${directiveParentTypeName}.${directiveFieldName}`];
85
- default:
86
- return [];
53
+ function getInitialFieldCoordsPath(isProvides, directiveCoords) {
54
+ if (isProvides) {
55
+ return [directiveCoords];
87
56
  }
57
+ return [];
88
58
  }
89
- function validateNonRepeatableFieldSet(nf, selectionSetParentData, fieldSet, directiveFieldName, fieldSetDirective, directiveParentTypeName) {
90
- // Create a new selection set so that the value can be parsed as a new DocumentNode
91
- const { error, documentNode } = (0, utils_1.safeParse)('{' + fieldSet + '}');
92
- if (error || !documentNode) {
93
- return { errorMessage: (0, errors_1.unparsableFieldSetErrorMessage)(fieldSet, error) };
94
- }
95
- const parentDatas = [selectionSetParentData];
96
- const definedFields = [];
97
- const fieldCoordinatesPath = getInitialFieldCoordinatesPath(fieldSetDirective, directiveParentTypeName, directiveFieldName);
98
- const fieldPath = [directiveFieldName];
99
- const externalAncestors = new Set();
100
- let errorMessage;
101
- let currentDepth = -1;
102
- let shouldDefineSelectionSet = true;
103
- let lastFieldName = directiveFieldName;
104
- (0, graphql_1.visit)(documentNode, {
105
- Argument: {
106
- enter() {
107
- return false;
108
- },
109
- },
110
- Field: {
111
- enter(node) {
112
- const parentData = parentDatas[currentDepth];
113
- const parentTypeName = parentData.name;
114
- if (parentData.kind === graphql_1.Kind.UNION_TYPE_DEFINITION) {
115
- errorMessage = (0, errors_1.invalidSelectionOnUnionErrorMessage)(fieldSet, fieldCoordinatesPath, parentTypeName);
116
- return graphql_1.BREAK;
117
- }
118
- const fieldName = node.name.value;
119
- const currentFieldCoords = `${parentTypeName}.${fieldName}`;
120
- nf.unvalidatedExternalFieldCoords.delete(currentFieldCoords);
121
- // If an object-like was just visited, a selection set should have been entered
122
- if (shouldDefineSelectionSet) {
123
- errorMessage = (0, errors_1.invalidSelectionSetErrorMessage)(fieldSet, fieldCoordinatesPath, parentTypeName, (0, utils_3.kindToTypeString)(parentData.kind));
124
- return graphql_1.BREAK;
125
- }
126
- fieldCoordinatesPath.push(currentFieldCoords);
127
- fieldPath.push(fieldName);
128
- lastFieldName = fieldName;
129
- const fieldData = parentData.fieldDataByFieldName.get(fieldName);
130
- // undefined if the field does not exist on the parent
131
- if (!fieldData) {
132
- errorMessage = (0, errors_1.undefinedFieldInFieldSetErrorMessage)(fieldSet, parentTypeName, fieldName);
133
- return graphql_1.BREAK;
134
- }
135
- if (definedFields[currentDepth].has(fieldName)) {
136
- errorMessage = (0, errors_1.duplicateFieldInFieldSetErrorMessage)(fieldSet, currentFieldCoords);
137
- return graphql_1.BREAK;
138
- }
139
- definedFields[currentDepth].add(fieldName);
140
- const isExternal = fieldData.isExternalBySubgraphName.get(nf.subgraphName);
141
- const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
142
- // The child could itself be a parent
143
- const namedTypeData = nf.parentDefinitionDataByTypeName.get(namedTypeName);
144
- // The base scalars are not in the parents map
145
- if (constants_1.BASE_SCALARS.has(namedTypeName) ||
146
- namedTypeData?.kind === graphql_1.Kind.SCALAR_TYPE_DEFINITION ||
147
- namedTypeData?.kind === graphql_1.Kind.ENUM_TYPE_DEFINITION) {
148
- if (externalAncestors.size < 1 && !isExternal) {
149
- if (nf.isSubgraphVersionTwo) {
150
- nf.errors.push((0, errors_1.nonExternalConditionalFieldError)(`${directiveParentTypeName}.${directiveFieldName}`, nf.subgraphName, currentFieldCoords, fieldSet, fieldSetDirective));
151
- }
152
- else {
153
- /* In V1, @requires and @provides do not need to declare any part of the field set @external.
154
- * It would appear that any such non-external fields are treated as if they are non-conditionally provided.
155
- * */
156
- nf.warnings.push((0, warnings_1.nonExternalConditionalFieldWarning)(`${directiveParentTypeName}.${directiveFieldName}`, nf.subgraphName, currentFieldCoords, fieldSet, fieldSetDirective));
157
- }
158
- return;
159
- }
160
- const conditionalFieldData = (0, utils_3.getValueOrDefault)(nf.conditionalFieldDataByCoordinates, currentFieldCoords, utils_2.newConditionalFieldData);
161
- const fieldSetCondition = (0, router_configuration_1.newFieldSetConditionData)({
162
- fieldCoordinatesPath: [...fieldCoordinatesPath],
163
- fieldPath: [...fieldPath],
164
- });
165
- fieldSetDirective === utils_2.FieldSetDirective.PROVIDES
166
- ? conditionalFieldData.providedBy.push(fieldSetCondition)
167
- : conditionalFieldData.requiredBy.push(fieldSetCondition);
168
- return;
169
- }
170
- if (!namedTypeData) {
171
- // Should not be possible to receive this error
172
- errorMessage = (0, errors_1.unknownTypeInFieldSetErrorMessage)(fieldSet, currentFieldCoords, namedTypeName);
173
- return graphql_1.BREAK;
174
- }
175
- if (isExternal) {
176
- const data = (0, utils_3.getValueOrDefault)(nf.conditionalFieldDataByCoordinates, currentFieldCoords, utils_2.newConditionalFieldData);
177
- switch (fieldSetDirective) {
178
- case utils_2.FieldSetDirective.PROVIDES:
179
- data.providedBy.push((0, router_configuration_1.newFieldSetConditionData)({
180
- fieldCoordinatesPath: [...fieldCoordinatesPath],
181
- fieldPath: [...fieldPath],
182
- }));
183
- break;
184
- default:
185
- break;
186
- }
187
- externalAncestors.add(currentFieldCoords);
188
- }
189
- if (namedTypeData.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION ||
190
- namedTypeData.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION ||
191
- namedTypeData.kind === graphql_1.Kind.UNION_TYPE_DEFINITION) {
192
- shouldDefineSelectionSet = true;
193
- parentDatas.push(namedTypeData);
194
- return;
195
- }
196
- },
197
- leave() {
198
- externalAncestors.delete(fieldCoordinatesPath.pop() || '');
199
- fieldPath.pop();
200
- },
201
- },
202
- InlineFragment: {
203
- enter(node) {
204
- const parentData = parentDatas[currentDepth];
205
- const parentTypeName = parentData.name;
206
- const fieldCoordinates = fieldCoordinatesPath.length < 1
207
- ? selectionSetParentData.name
208
- : fieldCoordinatesPath[fieldCoordinatesPath.length - 1];
209
- if (!node.typeCondition) {
210
- errorMessage = (0, errors_1.inlineFragmentWithoutTypeConditionErrorMessage)(fieldSet, fieldCoordinates);
211
- return graphql_1.BREAK;
212
- }
213
- const typeConditionName = node.typeCondition.name.value;
214
- // It's possible to infinitely define fragments
215
- if (typeConditionName === parentTypeName) {
216
- parentDatas.push(parentData);
217
- shouldDefineSelectionSet = true;
218
- return;
219
- }
220
- if (!(0, utils_1.isKindAbstract)(parentData.kind)) {
221
- errorMessage = (0, errors_1.invalidInlineFragmentTypeErrorMessage)(fieldSet, fieldCoordinatesPath, typeConditionName, parentTypeName);
222
- return graphql_1.BREAK;
223
- }
224
- const fragmentNamedTypeData = nf.parentDefinitionDataByTypeName.get(typeConditionName);
225
- if (!fragmentNamedTypeData) {
226
- errorMessage = (0, errors_1.unknownInlineFragmentTypeConditionErrorMessage)(fieldSet, fieldCoordinatesPath, parentTypeName, typeConditionName);
227
- return graphql_1.BREAK;
228
- }
229
- shouldDefineSelectionSet = true;
230
- switch (fragmentNamedTypeData.kind) {
231
- case graphql_1.Kind.INTERFACE_TYPE_DEFINITION: {
232
- if (!fragmentNamedTypeData.implementedInterfaceTypeNames.has(parentTypeName)) {
233
- break;
234
- }
235
- parentDatas.push(fragmentNamedTypeData);
236
- return;
237
- }
238
- case graphql_1.Kind.OBJECT_TYPE_DEFINITION: {
239
- const concreteTypeNames = nf.concreteTypeNamesByAbstractTypeName.get(parentTypeName);
240
- if (!concreteTypeNames || !concreteTypeNames.has(typeConditionName)) {
241
- break;
242
- }
243
- parentDatas.push(fragmentNamedTypeData);
244
- return;
245
- }
246
- case graphql_1.Kind.UNION_TYPE_DEFINITION: {
247
- parentDatas.push(fragmentNamedTypeData);
248
- return;
249
- }
250
- default: {
251
- errorMessage = (0, errors_1.invalidInlineFragmentTypeConditionTypeErrorMessage)(fieldSet, fieldCoordinatesPath, parentTypeName, typeConditionName, (0, utils_3.kindToTypeString)(fragmentNamedTypeData.kind));
252
- return graphql_1.BREAK;
253
- }
254
- }
255
- errorMessage = (0, errors_1.invalidInlineFragmentTypeConditionErrorMessage)(fieldSet, fieldCoordinatesPath, typeConditionName, (0, utils_3.kindToTypeString)(parentData.kind), parentTypeName);
256
- return graphql_1.BREAK;
257
- },
258
- },
259
- SelectionSet: {
260
- enter() {
261
- if (!shouldDefineSelectionSet) {
262
- const parentData = parentDatas[currentDepth];
263
- if (parentData.kind === graphql_1.Kind.UNION_TYPE_DEFINITION) {
264
- // Should never happen
265
- errorMessage = (0, errors_1.unparsableFieldSetSelectionErrorMessage)(fieldSet, lastFieldName);
266
- return graphql_1.BREAK;
267
- }
268
- const fieldData = parentData.fieldDataByFieldName.get(lastFieldName);
269
- if (!fieldData) {
270
- errorMessage = (0, errors_1.undefinedFieldInFieldSetErrorMessage)(fieldSet, parentData.name, lastFieldName);
271
- return graphql_1.BREAK;
272
- }
273
- const fieldNamedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
274
- // If the child is not found, it's a base scalar. Undefined types would have already been handled.
275
- const namedTypeData = nf.parentDefinitionDataByTypeName.get(fieldNamedTypeName);
276
- const childKind = namedTypeData ? namedTypeData.kind : graphql_1.Kind.SCALAR_TYPE_DEFINITION;
277
- errorMessage = (0, errors_1.invalidSelectionSetDefinitionErrorMessage)(fieldSet, fieldCoordinatesPath, fieldNamedTypeName, (0, utils_3.kindToTypeString)(childKind));
278
- return graphql_1.BREAK;
279
- }
280
- currentDepth += 1;
281
- shouldDefineSelectionSet = false;
282
- if (currentDepth < 0 || currentDepth >= parentDatas.length) {
283
- errorMessage = (0, errors_1.unparsableFieldSetSelectionErrorMessage)(fieldSet, lastFieldName);
284
- return graphql_1.BREAK;
285
- }
286
- definedFields.push(new Set());
287
- },
288
- leave() {
289
- if (shouldDefineSelectionSet) {
290
- const parentData = parentDatas[currentDepth + 1];
291
- errorMessage = (0, errors_1.invalidSelectionSetErrorMessage)(fieldSet, fieldCoordinatesPath, parentData.name, (0, utils_3.kindToTypeString)(parentData.kind));
292
- shouldDefineSelectionSet = false;
293
- }
294
- // Empty selection sets would be a parse error, so it is unnecessary to handle them
295
- currentDepth -= 1;
296
- parentDatas.pop();
297
- definedFields.pop();
298
- },
299
- },
300
- });
301
- if (errorMessage) {
302
- return { errorMessage };
303
- }
304
- return { configuration: { fieldName: directiveFieldName, selectionSet: getNormalizedFieldSet(documentNode) } };
305
- }
306
- function validateKeyFieldSets(nf, entityParentData, nonResolvableByKeyFieldSet, fieldNames) {
307
- const isEntityInterface = nf.entityInterfaceDataByTypeName.has(entityParentData.name);
59
+ function validateKeyFieldSets(nf, entityParentData, keyFieldSetDataByFieldSet, fieldNames) {
60
+ const entityInterfaceData = nf.entityInterfaceDataByTypeName.get(entityParentData.name);
308
61
  const entityTypeName = entityParentData.name;
309
- const errorMessages = [];
310
62
  const configurations = [];
311
- const keyFieldNames = new Set();
312
63
  const allKeyFieldSetPaths = [];
313
64
  // If the key is on an entity interface/interface object, an entity data node should not be propagated
314
- const entityDataNode = isEntityInterface ? undefined : nf.internalGraph.addEntityDataNode(entityParentData.name);
65
+ const entityDataNode = entityInterfaceData ? undefined : nf.internalGraph.addEntityDataNode(entityParentData.name);
315
66
  const graphNode = nf.internalGraph.addOrUpdateNode(entityParentData.name);
316
- for (const [fieldSet, disableEntityResolver] of nonResolvableByKeyFieldSet) {
317
- // Create a new selection set so that the value can be parsed as a new DocumentNode
318
- const { error, documentNode } = (0, utils_1.safeParse)('{' + fieldSet + '}');
319
- if (error || !documentNode) {
320
- errorMessages.push((0, errors_1.unparsableFieldSetErrorMessage)(fieldSet, error));
321
- continue;
67
+ let keyNumber = 0;
68
+ for (const [fieldSet, { documentNode, isUnresolvable, rawFieldSet }] of keyFieldSetDataByFieldSet) {
69
+ if (entityInterfaceData) {
70
+ entityInterfaceData.resolvable ||= !isUnresolvable;
322
71
  }
323
- const parentWithFieldsDatas = [entityParentData];
72
+ keyNumber += 1;
73
+ const errorMessages = [];
74
+ const parentDatas = [entityParentData];
324
75
  const definedFields = [];
325
76
  const currentPath = [];
326
77
  const keyFieldSetPaths = new Set();
@@ -332,59 +83,52 @@ function validateKeyFieldSets(nf, entityParentData, nonResolvableByKeyFieldSet,
332
83
  enter(node) {
333
84
  // Fields that define arguments are never allowed in a key FieldSet
334
85
  // However, at this stage, it actually means the argument is undefined on the field
335
- errorMessages.push((0, errors_1.unexpectedArgumentErrorMessage)(fieldSet, `${parentWithFieldsDatas[currentDepth].name}.${lastFieldName}`, node.name.value));
86
+ errorMessages.push((0, errors_1.unexpectedArgumentErrorMessage)(rawFieldSet, `${parentDatas[currentDepth].name}.${lastFieldName}`, node.name.value));
336
87
  return graphql_1.BREAK;
337
88
  },
338
89
  },
339
90
  Field: {
340
91
  enter(node) {
341
- const grandparentData = parentWithFieldsDatas[currentDepth - 1];
342
- const parentData = parentWithFieldsDatas[currentDepth];
92
+ const parentData = parentDatas[currentDepth];
343
93
  const parentTypeName = parentData.name;
344
- const fieldName = node.name.value;
345
- const fieldCoords = `${parentTypeName}.${fieldName}`;
346
- nf.unvalidatedExternalFieldCoords.delete(fieldCoords);
347
- // If an object-like was just visited, a selection set should have been entered
94
+ // If a composite type was just visited, a selection set should have been entered
348
95
  if (shouldDefineSelectionSet) {
349
- errorMessages.push((0, errors_1.invalidSelectionSetErrorMessage)(fieldSet, [`${grandparentData.name}.${lastFieldName}`], parentTypeName, (0, utils_3.kindToTypeString)(parentData.kind)));
96
+ const lastFieldCoords = `${parentTypeName}.${lastFieldName}`;
97
+ const lastFieldData = parentData.fieldDataByFieldName.get(lastFieldName);
98
+ if (!lastFieldData) {
99
+ errorMessages.push((0, errors_1.undefinedFieldInFieldSetErrorMessage)(rawFieldSet, lastFieldCoords, lastFieldName));
100
+ return graphql_1.BREAK;
101
+ }
102
+ const lastFieldNamedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(lastFieldData.node.type);
103
+ // If the child is not found, it's a base scalar. Undefined types would have already been handled.
104
+ const namedTypeData = nf.parentDefinitionDataByTypeName.get(lastFieldNamedTypeName);
105
+ const namedTypeKind = namedTypeData ? namedTypeData.kind : graphql_1.Kind.SCALAR_TYPE_DEFINITION;
106
+ errorMessages.push((0, errors_1.invalidSelectionSetErrorMessage)(rawFieldSet, [lastFieldCoords], lastFieldNamedTypeName, (0, utils_2.kindToTypeString)(namedTypeKind)));
350
107
  return graphql_1.BREAK;
351
108
  }
109
+ const fieldName = node.name.value;
110
+ const fieldCoords = `${parentTypeName}.${fieldName}`;
352
111
  lastFieldName = fieldName;
353
112
  const fieldData = parentData.fieldDataByFieldName.get(fieldName);
354
113
  // undefined if the field does not exist on the parent
355
114
  if (!fieldData) {
356
- errorMessages.push((0, errors_1.undefinedFieldInFieldSetErrorMessage)(fieldSet, parentTypeName, fieldName));
115
+ errorMessages.push((0, errors_1.undefinedFieldInFieldSetErrorMessage)(rawFieldSet, parentTypeName, fieldName));
357
116
  return graphql_1.BREAK;
358
117
  }
359
118
  // TODO navigate already provided keys
360
119
  if (fieldData.argumentDataByArgumentName.size) {
361
- errorMessages.push((0, errors_1.argumentsInKeyFieldSetErrorMessage)(fieldSet, fieldCoords));
120
+ errorMessages.push((0, errors_1.argumentsInKeyFieldSetErrorMessage)(rawFieldSet, fieldCoords));
362
121
  return graphql_1.BREAK;
363
122
  }
364
123
  if (definedFields[currentDepth].has(fieldName)) {
365
- errorMessages.push((0, errors_1.duplicateFieldInFieldSetErrorMessage)(fieldSet, fieldCoords));
124
+ errorMessages.push((0, errors_1.duplicateFieldInFieldSetErrorMessage)(rawFieldSet, fieldCoords));
366
125
  return graphql_1.BREAK;
367
126
  }
368
127
  currentPath.push(fieldName);
369
128
  // Fields that form part of an entity key are intrinsically shareable
370
129
  fieldData.isShareableBySubgraphName.set(nf.subgraphName, true);
371
130
  definedFields[currentDepth].add(fieldName);
372
- /* Depth 0 is the original parent type
373
- * If a field is external, but it's part of a key FieldSet, it should be included in its respective
374
- * root or child node */
375
- if (currentDepth === 0) {
376
- keyFieldNames.add(fieldName);
377
- fieldNames.add(fieldName);
378
- }
379
- else {
380
- const nestedConfigurationData = nf.configurationDataByParentTypeName.get(parentTypeName);
381
- if (!nestedConfigurationData) {
382
- errorMessages.push((0, errors_1.invalidConfigurationDataErrorMessage)(parentTypeName, fieldName, fieldSet));
383
- return graphql_1.BREAK;
384
- }
385
- nestedConfigurationData.fieldNames.add(fieldName);
386
- }
387
- (0, utils_3.getValueOrDefault)(nf.keyFieldNamesByParentTypeName, parentTypeName, () => new Set()).add(fieldName);
131
+ (0, utils_2.getValueOrDefault)(nf.keyFieldNamesByParentTypeName, parentTypeName, () => new Set()).add(fieldName);
388
132
  const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
389
133
  // The base scalars are not in the parents map
390
134
  if (constants_1.BASE_SCALARS.has(namedTypeName)) {
@@ -396,17 +140,17 @@ function validateKeyFieldSets(nf, entityParentData, nonResolvableByKeyFieldSet,
396
140
  const namedTypeData = nf.parentDefinitionDataByTypeName.get(namedTypeName);
397
141
  if (!namedTypeData) {
398
142
  // Should not be possible to receive this error
399
- errorMessages.push((0, errors_1.unknownTypeInFieldSetErrorMessage)(fieldSet, fieldCoords, namedTypeName));
143
+ errorMessages.push((0, errors_1.unknownTypeInFieldSetErrorMessage)(rawFieldSet, fieldCoords, namedTypeName));
400
144
  return graphql_1.BREAK;
401
145
  }
402
146
  if (namedTypeData.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
403
147
  shouldDefineSelectionSet = true;
404
- parentWithFieldsDatas.push(namedTypeData);
148
+ parentDatas.push(namedTypeData);
405
149
  return;
406
150
  }
407
151
  // interfaces and unions are invalid in a key directive
408
152
  if ((0, utils_1.isKindAbstract)(namedTypeData.kind)) {
409
- errorMessages.push((0, errors_1.abstractTypeInKeyFieldSetErrorMessage)(fieldSet, fieldCoords, namedTypeName, (0, utils_3.kindToTypeString)(namedTypeData.kind)));
153
+ errorMessages.push((0, errors_1.abstractTypeInKeyFieldSetErrorMessage)(rawFieldSet, fieldCoords, namedTypeName, (0, utils_2.kindToTypeString)(namedTypeData.kind)));
410
154
  return graphql_1.BREAK;
411
155
  }
412
156
  keyFieldSetPaths.add(currentPath.join(string_constants_1.PERIOD));
@@ -422,140 +166,73 @@ function validateKeyFieldSets(nf, entityParentData, nonResolvableByKeyFieldSet,
422
166
  SelectionSet: {
423
167
  enter() {
424
168
  if (!shouldDefineSelectionSet) {
425
- const parentData = parentWithFieldsDatas[currentDepth];
169
+ const parentData = parentDatas[currentDepth];
426
170
  const parentTypeName = parentData.name;
427
171
  const fieldCoordinates = `${parentTypeName}.${lastFieldName}`;
428
172
  // If the last field is not an object-like
429
173
  const fieldData = parentData.fieldDataByFieldName.get(lastFieldName);
430
174
  if (!fieldData) {
431
- errorMessages.push((0, errors_1.undefinedFieldInFieldSetErrorMessage)(fieldSet, fieldCoordinates, lastFieldName));
175
+ errorMessages.push((0, errors_1.undefinedFieldInFieldSetErrorMessage)(rawFieldSet, fieldCoordinates, lastFieldName));
432
176
  return graphql_1.BREAK;
433
177
  }
434
178
  const fieldNamedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
435
179
  // If the child is not found, it's a base scalar. Undefined types would have already been handled.
436
180
  const namedTypeData = nf.parentDefinitionDataByTypeName.get(fieldNamedTypeName);
437
181
  const namedTypeKind = namedTypeData ? namedTypeData.kind : graphql_1.Kind.SCALAR_TYPE_DEFINITION;
438
- errorMessages.push((0, errors_1.invalidSelectionSetDefinitionErrorMessage)(fieldSet, [fieldCoordinates], fieldNamedTypeName, (0, utils_3.kindToTypeString)(namedTypeKind)));
182
+ errorMessages.push((0, errors_1.invalidSelectionSetDefinitionErrorMessage)(rawFieldSet, [fieldCoordinates], fieldNamedTypeName, (0, utils_2.kindToTypeString)(namedTypeKind)));
439
183
  return graphql_1.BREAK;
440
184
  }
441
185
  currentDepth += 1;
442
186
  shouldDefineSelectionSet = false;
443
- if (currentDepth < 0 || currentDepth >= parentWithFieldsDatas.length) {
444
- errorMessages.push((0, errors_1.unparsableFieldSetSelectionErrorMessage)(fieldSet, lastFieldName));
187
+ if (currentDepth < 0 || currentDepth >= parentDatas.length) {
188
+ errorMessages.push((0, errors_1.unparsableFieldSetSelectionErrorMessage)(rawFieldSet, lastFieldName));
445
189
  return graphql_1.BREAK;
446
190
  }
447
191
  definedFields.push(new Set());
448
192
  },
449
193
  leave() {
450
194
  if (shouldDefineSelectionSet) {
451
- const grandparentData = parentWithFieldsDatas[currentDepth];
195
+ const grandparentData = parentDatas[currentDepth];
452
196
  const grandparentTypeName = grandparentData.name;
453
- const parentData = parentWithFieldsDatas[currentDepth + 1];
197
+ const parentData = parentDatas[currentDepth + 1];
454
198
  const fieldCoordinates = `${grandparentTypeName}.${lastFieldName}`;
455
- errorMessages.push((0, errors_1.invalidSelectionSetErrorMessage)(fieldSet, [fieldCoordinates], parentData.name, (0, utils_3.kindToTypeString)(parentData.kind)));
199
+ errorMessages.push((0, errors_1.invalidSelectionSetErrorMessage)(rawFieldSet, [fieldCoordinates], parentData.name, (0, utils_2.kindToTypeString)(parentData.kind)));
456
200
  shouldDefineSelectionSet = false;
457
201
  }
458
202
  // Empty selection sets would be a parse error, so it is unnecessary to handle them
459
203
  currentDepth -= 1;
460
- parentWithFieldsDatas.pop();
204
+ parentDatas.pop();
461
205
  definedFields.pop();
462
206
  },
463
207
  },
464
208
  });
465
209
  if (errorMessages.length > 0) {
210
+ nf.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.KEY, entityTypeName, (0, utils_2.numberToOrdinal)(keyNumber), errorMessages));
466
211
  continue;
467
212
  }
468
- const normalizedFieldSet = getNormalizedFieldSet(documentNode);
469
213
  configurations.push({
470
214
  fieldName: '',
471
- selectionSet: normalizedFieldSet,
472
- ...(disableEntityResolver ? { disableEntityResolver: true } : {}),
215
+ selectionSet: fieldSet,
216
+ ...(isUnresolvable ? { disableEntityResolver: true } : {}),
473
217
  });
474
- graphNode.satisfiedFieldSets.add(normalizedFieldSet);
475
- if (disableEntityResolver) {
218
+ graphNode.satisfiedFieldSets.add(fieldSet);
219
+ if (isUnresolvable) {
476
220
  continue;
477
221
  }
478
- entityDataNode?.addTargetSubgraphByFieldSet(normalizedFieldSet, nf.subgraphName);
222
+ entityDataNode?.addTargetSubgraphByFieldSet(fieldSet, nf.subgraphName);
479
223
  allKeyFieldSetPaths.push(keyFieldSetPaths);
480
224
  }
481
- if (errorMessages.length) {
482
- nf.errors.push((0, errors_1.invalidKeyDirectivesError)(entityTypeName, errorMessages));
483
- return;
484
- }
485
225
  // todo
486
226
  // nf.internalGraph.addEntityNode(entityTypeName, allKeyFieldSetPaths);
487
- if (configurations.length) {
488
- return configurations;
489
- }
490
- }
491
- function getFieldSetParent(factory, fieldSetDirective, parentData, fieldName, parentTypeName) {
492
- if (fieldSetDirective !== utils_2.FieldSetDirective.PROVIDES) {
493
- return { fieldSetParentData: parentData };
494
- }
495
- const fieldData = (0, utils_3.getOrThrowError)(parentData.fieldDataByFieldName, fieldName, `${parentTypeName}.fieldDataByFieldName`);
496
- const fieldNamedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(fieldData.node.type);
497
- const namedTypeData = factory.parentDefinitionDataByTypeName.get(fieldNamedTypeName);
498
- // This error should never happen
499
- if (!namedTypeData) {
500
- return {
501
- errorString: (0, errors_1.unknownNamedTypeErrorMessage)(`${parentTypeName}.${fieldName}`, fieldNamedTypeName),
502
- };
503
- }
504
- if (namedTypeData.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION && namedTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
505
- return {
506
- errorString: (0, errors_1.incompatibleTypeWithProvidesErrorMessage)(`${parentTypeName}.${fieldName}`, fieldNamedTypeName),
507
- };
508
- }
509
- return { fieldSetParentData: namedTypeData };
510
- }
511
- function validateProvidesOrRequires(nf, parentData, fieldSetByFieldName, fieldSetDirective) {
512
- const errorMessages = [];
513
- const configurations = [];
514
- const parentTypeName = (0, utils_2.getParentTypeName)(parentData);
515
- for (const [fieldName, fieldSet] of fieldSetByFieldName) {
516
- /* It is possible to encounter a field before encountering the type definition.
517
- Consequently, at that time, it is unknown whether the named type is an entity.
518
- If it isn't, the @provides directive does not make sense and can be ignored.
519
- */
520
- const { fieldSetParentData, errorString } = getFieldSetParent(nf, fieldSetDirective, parentData, fieldName, parentTypeName);
521
- const fieldCoords = `${parentTypeName}.${fieldName}`;
522
- if (errorString) {
523
- errorMessages.push(errorString);
524
- continue;
525
- }
526
- if (!fieldSetParentData) {
527
- continue;
528
- }
529
- const { errorMessage, configuration } = validateNonRepeatableFieldSet(nf, fieldSetParentData, fieldSet, fieldName, fieldSetDirective, parentTypeName);
530
- if (errorMessage) {
531
- errorMessages.push(` On "${fieldCoords}" —` + errorMessage);
532
- continue;
533
- }
534
- if (configuration) {
535
- configurations.push(configuration);
536
- continue;
537
- }
538
- // Should never happen
539
- throw (0, errors_1.invalidConfigurationResultFatalError)(fieldCoords);
540
- }
541
- if (errorMessages.length > 0) {
542
- nf.errors.push((0, errors_1.invalidProvidesOrRequiresDirectivesError)(fieldSetDirective, errorMessages));
543
- return;
544
- }
545
227
  if (configurations.length > 0) {
546
228
  return configurations;
547
229
  }
548
230
  }
549
- function validateAndAddConditionalFieldSetsToConfiguration(nf, parentData, fieldSetData) {
550
- const configurationData = (0, utils_3.getOrThrowError)(nf.configurationDataByParentTypeName, (0, utils_2.getParentTypeName)(parentData), 'configurationDataByParentTypeName');
551
- const provides = validateProvidesOrRequires(nf, parentData, fieldSetData.provides, utils_2.FieldSetDirective.PROVIDES);
552
- if (provides) {
553
- configurationData.provides = provides;
554
- }
555
- const requires = validateProvidesOrRequires(nf, parentData, fieldSetData.requires, utils_2.FieldSetDirective.REQUIRES);
556
- if (requires) {
557
- configurationData.requires = requires;
231
+ function getConditionalFieldSetDirectiveName(isProvides) {
232
+ if (isProvides) {
233
+ return string_constants_1.PROVIDES;
558
234
  }
235
+ return string_constants_1.REQUIRES;
559
236
  }
560
237
  function isNodeQuery(typeName, operationTypeNode) {
561
238
  return typeName === string_constants_1.QUERY || operationTypeNode === graphql_1.OperationTypeNode.QUERY;