@wundergraph/composition 0.18.0 → 0.18.2

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 (56) hide show
  1. package/dist/ast/ast.d.ts +2 -9
  2. package/dist/ast/ast.js +4 -32
  3. package/dist/ast/ast.js.map +1 -1
  4. package/dist/ast/utils.d.ts +1 -2
  5. package/dist/ast/utils.js.map +1 -1
  6. package/dist/errors/errors.d.ts +6 -11
  7. package/dist/errors/errors.js +18 -29
  8. package/dist/errors/errors.js.map +1 -1
  9. package/dist/federation/federation-factory.d.ts +6 -6
  10. package/dist/federation/federation-factory.js +19 -18
  11. package/dist/federation/federation-factory.js.map +1 -1
  12. package/dist/federation/utils.d.ts +4 -4
  13. package/dist/federation/utils.js +2 -2
  14. package/dist/federation/utils.js.map +1 -1
  15. package/dist/index.d.ts +8 -1
  16. package/dist/index.js +8 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/normalization/normalization-factory.d.ts +19 -26
  19. package/dist/normalization/normalization-factory.js +179 -994
  20. package/dist/normalization/normalization-factory.js.map +1 -1
  21. package/dist/normalization/utils.d.ts +6 -126
  22. package/dist/normalization/utils.js +69 -158
  23. package/dist/normalization/utils.js.map +1 -1
  24. package/dist/normalization/walkers.d.ts +5 -0
  25. package/dist/normalization/walkers.js +593 -0
  26. package/dist/normalization/walkers.js.map +1 -0
  27. package/dist/schema-building/ast.d.ts +104 -0
  28. package/dist/schema-building/ast.js +156 -0
  29. package/dist/schema-building/ast.js.map +1 -0
  30. package/dist/schema-building/type-definition-data.d.ts +108 -0
  31. package/dist/schema-building/type-definition-data.js +3 -0
  32. package/dist/schema-building/type-definition-data.js.map +1 -0
  33. package/dist/schema-building/type-extension-data.d.ts +45 -0
  34. package/dist/schema-building/type-extension-data.js +3 -0
  35. package/dist/schema-building/type-extension-data.js.map +1 -0
  36. package/dist/{type-merging → schema-building}/type-merging.js +5 -4
  37. package/dist/schema-building/type-merging.js.map +1 -0
  38. package/dist/schema-building/utils.d.ts +42 -0
  39. package/dist/schema-building/utils.js +600 -0
  40. package/dist/schema-building/utils.js.map +1 -0
  41. package/dist/subgraph/subgraph.d.ts +4 -5
  42. package/dist/subgraph/subgraph.js +2 -91
  43. package/dist/subgraph/subgraph.js.map +1 -1
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/dist/utils/constants.d.ts +4 -2
  46. package/dist/utils/constants.js +383 -359
  47. package/dist/utils/constants.js.map +1 -1
  48. package/dist/utils/string-constants.d.ts +4 -0
  49. package/dist/utils/string-constants.js +6 -2
  50. package/dist/utils/string-constants.js.map +1 -1
  51. package/dist/utils/utils.d.ts +2 -4
  52. package/dist/utils/utils.js +4 -6
  53. package/dist/utils/utils.js.map +1 -1
  54. package/package.json +2 -2
  55. package/dist/type-merging/type-merging.js.map +0 -1
  56. /package/dist/{type-merging → schema-building}/type-merging.d.ts +0 -0
@@ -5,7 +5,7 @@ const graphql_1 = require("graphql");
5
5
  const utils_1 = require("../ast/utils");
6
6
  const utils_2 = require("./utils");
7
7
  const constants_1 = require("../utils/constants");
8
- const type_merging_1 = require("../type-merging/type-merging");
8
+ const type_merging_1 = require("../schema-building/type-merging");
9
9
  const utils_3 = require("../utils/utils");
10
10
  const errors_1 = require("../errors/errors");
11
11
  const string_constants_1 = require("../utils/string-constants");
@@ -14,6 +14,8 @@ const merge_1 = require("@graphql-tools/merge");
14
14
  const ast_1 = require("../ast/ast");
15
15
  const subgraph_1 = require("../subgraph/subgraph");
16
16
  const warnings_1 = require("../warnings/warnings");
17
+ const walkers_1 = require("./walkers");
18
+ const utils_4 = require("../schema-building/utils");
17
19
  function normalizeSubgraphFromString(subgraphSDL) {
18
20
  const { error, documentNode } = (0, utils_1.safeParse)(subgraphSDL);
19
21
  if (error || !documentNode) {
@@ -30,7 +32,7 @@ function normalizeSubgraph(document, subgraphName) {
30
32
  exports.normalizeSubgraph = normalizeSubgraph;
31
33
  class NormalizationFactory {
32
34
  abstractToConcreteTypeNames = new Map();
33
- allDirectiveDefinitions = new Map();
35
+ directiveDefinitionByDirectiveName = new Map();
34
36
  argumentName = '';
35
37
  authorizationDataByParentTypeName = new Map();
36
38
  childName = '';
@@ -39,10 +41,9 @@ class NormalizationFactory {
39
41
  errors = [];
40
42
  entityContainerByTypeName = new Map();
41
43
  entityInterfaces = new Map();
42
- extensionContainerByTypeName = new Map();
44
+ parentExtensionDataByTypeName = new Map();
43
45
  interfaceTypeNamesWithAuthorizationDirectives = new Set();
44
46
  isCurrentParentExtension = false;
45
- isCurrentParentRootType = false;
46
47
  isSubgraphVersionTwo = false;
47
48
  fieldSetContainerByTypeName = new Map();
48
49
  heirFieldAuthorizationDataByTypeName = new Map();
@@ -52,26 +53,26 @@ class NormalizationFactory {
52
53
  leafTypeNamesWithAuthorizationDirectives = new Set();
53
54
  keyFieldNamesByParentTypeName = new Map();
54
55
  operationTypeNames = new Map();
55
- parentContainerByTypeName = new Map();
56
+ parentDefinitionDataByTypeName = new Map();
56
57
  parentTypeName = '';
57
58
  parentsWithChildArguments = new Set();
58
59
  eventsConfigurations = new Map();
59
60
  overridesByTargetSubgraphName = new Map();
60
61
  invalidOrScopesHostPaths = new Set();
61
62
  schemaDefinition;
62
- referencedDirectives = new Set();
63
+ referencedDirectiveNames = new Set();
63
64
  referencedTypeNames = new Set();
64
65
  warnings = [];
65
66
  subgraphName;
66
67
  constructor(subgraphName) {
67
- for (const baseDirectiveDefinition of constants_1.BASE_DIRECTIVE_DEFINITIONS) {
68
- this.allDirectiveDefinitions.set(baseDirectiveDefinition.name.value, baseDirectiveDefinition);
68
+ for (const [baseDirectiveName, baseDirectiveDefinition] of constants_1.BASE_DIRECTIVE_DEFINITION_BY_DIRECTIVE_NAME) {
69
+ this.directiveDefinitionByDirectiveName.set(baseDirectiveName, baseDirectiveDefinition);
69
70
  }
70
71
  this.subgraphName = subgraphName;
71
72
  this.schemaDefinition = {
72
- directives: new Map(),
73
+ directivesByDirectiveName: new Map(),
73
74
  kind: graphql_1.Kind.SCHEMA_DEFINITION,
74
- name: (0, utils_1.stringToNameNode)(string_constants_1.SCHEMA),
75
+ typeName: string_constants_1.SCHEMA,
75
76
  operationTypes: new Map(),
76
77
  };
77
78
  }
@@ -79,7 +80,7 @@ class NormalizationFactory {
79
80
  if (constants_1.BASE_SCALARS.has(namedType)) {
80
81
  return { hasUnhandledError: false, typeString: '' };
81
82
  }
82
- const parentContainer = this.parentContainerByTypeName.get(namedType);
83
+ const parentContainer = this.parentDefinitionDataByTypeName.get(namedType);
83
84
  if (!parentContainer) {
84
85
  this.errors.push((0, errors_1.undefinedTypeError)(namedType));
85
86
  return { hasUnhandledError: false, typeString: '' };
@@ -93,28 +94,28 @@ class NormalizationFactory {
93
94
  return { hasUnhandledError: true, typeString: (0, utils_3.kindToTypeString)(parentContainer.kind) };
94
95
  }
95
96
  }
96
- extractArguments(node, argumentByName, fieldPath) {
97
+ extractArguments(node, argumentDataByArgumentName, fieldPath) {
97
98
  if (!node.arguments) {
98
- return argumentByName;
99
+ return argumentDataByArgumentName;
99
100
  }
100
101
  this.parentsWithChildArguments.add(this.parentTypeName);
101
102
  const duplicatedArguments = new Set();
102
103
  for (const argumentNode of node.arguments) {
103
104
  const argumentName = argumentNode.name.value;
104
- if (argumentByName.has(argumentName)) {
105
+ if (argumentDataByArgumentName.has(argumentName)) {
105
106
  duplicatedArguments.add(argumentName);
106
107
  continue;
107
108
  }
108
- argumentByName.set(argumentName, (0, ast_1.inputValueDefinitionNodeToMutable)(argumentNode, this.parentTypeName));
109
+ argumentDataByArgumentName.set(argumentName, (0, ast_1.inputValueDefinitionNodeToMutable)(argumentNode, this.parentTypeName));
109
110
  }
110
111
  if (duplicatedArguments.size > 0) {
111
112
  this.errors.push((0, errors_1.duplicateArgumentsError)(fieldPath, [...duplicatedArguments]));
112
113
  }
113
- return argumentByName;
114
+ return argumentDataByArgumentName;
114
115
  }
115
- validateArguments(fieldContainer, fieldPath) {
116
+ validateArguments(fieldData, fieldPath) {
116
117
  const invalidArguments = [];
117
- for (const [argumentName, argumentNode] of fieldContainer.arguments) {
118
+ for (const [argumentName, argumentNode] of fieldData.argumentDataByArgumentName) {
118
119
  const namedType = (0, type_merging_1.getNamedTypeForChild)(fieldPath + `(${argumentName}...)`, argumentNode.type);
119
120
  const { hasUnhandledError, typeString } = this.validateInputNamedType(namedType);
120
121
  if (hasUnhandledError) {
@@ -125,24 +126,6 @@ class NormalizationFactory {
125
126
  this.errors.push((0, errors_1.invalidArgumentsError)(fieldPath, invalidArguments));
126
127
  }
127
128
  }
128
- extractDirectives(node, map) {
129
- if (!node.directives) {
130
- return map;
131
- }
132
- for (const directive of node.directives) {
133
- const directiveName = directive.name.value;
134
- if (directiveName === string_constants_1.EXTENDS) {
135
- continue;
136
- }
137
- const existingDirectives = map.get(directiveName);
138
- if (existingDirectives) {
139
- existingDirectives.push(directive);
140
- continue;
141
- }
142
- map.set(directiveName, [directive]);
143
- }
144
- return map;
145
- }
146
129
  // Note that directive validation errors are handled elsewhere
147
130
  getAuthorizationData(node) {
148
131
  let authorizationData = this.authorizationDataByParentTypeName.get(this.parentTypeName);
@@ -218,28 +201,41 @@ class NormalizationFactory {
218
201
  }
219
202
  return authorizationData;
220
203
  }
221
- extractDirectivesAndAuthorization(node, map) {
204
+ extractDirectivesAndAuthorization(node, directivesByDirectiveName) {
222
205
  if (!node.directives) {
223
- return map;
206
+ return directivesByDirectiveName;
224
207
  }
208
+ const hostPath = this.childName ? `${this.parentTypeName}.${this.childName}` : this.parentTypeName;
225
209
  const authorizationDirectives = [];
226
- for (const directive of node.directives) {
227
- const directiveName = directive.name.value;
210
+ for (const directiveNode of node.directives) {
211
+ const errorMessages = (0, utils_4.getDirectiveValidationErrors)(directiveNode, node.kind, directivesByDirectiveName, this.directiveDefinitionByDirectiveName, this.handledRepeatedDirectivesByHostPath, hostPath);
212
+ const directiveName = directiveNode.name.value;
213
+ if (errorMessages.length > 0) {
214
+ this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, hostPath, errorMessages));
215
+ continue;
216
+ }
228
217
  if (directiveName === string_constants_1.EXTENDS) {
229
218
  continue;
230
219
  }
220
+ if (directiveName === string_constants_1.OVERRIDE) {
221
+ this.handleOverrideDeclaration(directiveNode, hostPath, errorMessages);
222
+ if (errorMessages.length > 0) {
223
+ this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, hostPath, errorMessages));
224
+ }
225
+ continue;
226
+ }
231
227
  if (directiveName === string_constants_1.AUTHENTICATED || directiveName === string_constants_1.REQUIRES_SCOPES) {
232
- authorizationDirectives.push(directive);
228
+ authorizationDirectives.push(directiveNode);
229
+ continue;
233
230
  }
234
- const existingDirectives = map.get(directiveName);
231
+ const existingDirectives = directivesByDirectiveName.get(directiveName);
235
232
  if (existingDirectives) {
236
- existingDirectives.push(directive);
237
- continue;
233
+ existingDirectives.push(directiveNode);
238
234
  }
239
- map.set(directiveName, [directive]);
235
+ directivesByDirectiveName.set(directiveName, [directiveNode]);
240
236
  }
241
237
  if (authorizationDirectives.length < 1) {
242
- return map;
238
+ return directivesByDirectiveName;
243
239
  }
244
240
  if (node.kind !== graphql_1.Kind.FIELD_DEFINITION) {
245
241
  this.leafTypeNamesWithAuthorizationDirectives.add(this.parentTypeName);
@@ -252,30 +248,14 @@ class NormalizationFactory {
252
248
  authorizationData.requiresAuthentication = true;
253
249
  continue;
254
250
  }
255
- if (!directiveNode.arguments || directiveNode.arguments.length !== 1) {
256
- break;
257
- }
258
- const scopesArgument = directiveNode.arguments[0];
259
- if (scopesArgument.name.value !== string_constants_1.SCOPES || scopesArgument.value.kind !== graphql_1.Kind.LIST) {
260
- break;
261
- }
262
- const orScopes = scopesArgument.value.values;
263
- if (orScopes.length < 1) {
264
- continue;
265
- }
251
+ const orScopes = directiveNode.arguments[0].value.values;
266
252
  if (orScopes.length > utils_3.maxOrScopes) {
267
- this.invalidOrScopesHostPaths.add(this.parentTypeName);
253
+ this.invalidOrScopesHostPaths.add(hostPath);
268
254
  continue;
269
255
  }
270
256
  for (const scopes of orScopes) {
271
- if (scopes.kind !== graphql_1.Kind.LIST) {
272
- return map;
273
- }
274
257
  const andScopes = new Set();
275
258
  for (const scope of scopes.values) {
276
- if (scope.kind !== graphql_1.Kind.STRING) {
277
- return map;
278
- }
279
259
  andScopes.add(scope.value);
280
260
  }
281
261
  if (andScopes.size) {
@@ -283,21 +263,7 @@ class NormalizationFactory {
283
263
  }
284
264
  }
285
265
  }
286
- return map;
287
- }
288
- extractUniqueUnionMembers(members, map) {
289
- for (const member of members) {
290
- const name = member.name.value;
291
- if (map.has(name)) {
292
- this.errors.push(new Error(`Member "${name} can only be defined on union "${this.parentTypeName}" once.`));
293
- continue;
294
- }
295
- if (!constants_1.BASE_SCALARS.has(name)) {
296
- this.referencedTypeNames.add(name);
297
- }
298
- map.set(name, member);
299
- }
300
- return map;
266
+ return directivesByDirectiveName;
301
267
  }
302
268
  mergeUniqueInterfaces(extensionInterfaces, interfaces, typeName) {
303
269
  for (const interfaceName of extensionInterfaces) {
@@ -308,109 +274,6 @@ class NormalizationFactory {
308
274
  this.errors.push((0, errors_1.duplicateInterfaceExtensionError)(interfaceName, typeName));
309
275
  }
310
276
  }
311
- mergeUniqueUnionMembers(baseUnion, extensionUnion) {
312
- if (!extensionUnion) {
313
- return;
314
- }
315
- const extensionMembers = extensionUnion.types;
316
- const members = baseUnion.types;
317
- const typeName = baseUnion.name.value;
318
- for (const [memberName, namedTypeNode] of extensionMembers) {
319
- if (!members.has(memberName)) {
320
- members.set(memberName, namedTypeNode);
321
- continue;
322
- }
323
- this.errors.push((0, errors_1.duplicateUnionMemberError)(memberName, typeName));
324
- }
325
- }
326
- mergeDirectives(baseTypeDirectives, extension) {
327
- if (!extension) {
328
- return;
329
- }
330
- for (const [directiveName, directives] of extension.directives) {
331
- const existingDirectives = baseTypeDirectives.get(directiveName);
332
- if (existingDirectives) {
333
- existingDirectives.push(...directives);
334
- continue;
335
- }
336
- baseTypeDirectives.set(directiveName, [...directives]);
337
- }
338
- }
339
- getValidatedAndNormalizedParentDirectives(parent) {
340
- const parentTypeName = parent.name.value;
341
- const normalizedDirectives = [];
342
- for (const [directiveName, directives] of parent.directives) {
343
- const definition = this.allDirectiveDefinitions.get(directiveName);
344
- if (!definition) {
345
- this.errors.push((0, errors_1.undefinedDirectiveError)(directiveName, parentTypeName));
346
- continue;
347
- }
348
- const allArguments = new Set();
349
- const requiredArguments = new Set();
350
- (0, utils_2.getDirectiveDefinitionArgumentSets)(definition.arguments || [], allArguments, requiredArguments);
351
- const entityKeys = new Set();
352
- const errorMessages = [];
353
- for (const directive of directives) {
354
- if (!(0, utils_2.areNodeKindAndDirectiveLocationCompatible)(parent.kind, definition)) {
355
- errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(parentTypeName, parent.kind, directiveName));
356
- }
357
- if (!definition.repeatable && directives.length > 1) {
358
- errorMessages.push((0, errors_1.invalidRepeatedDirectiveErrorMessage)(directiveName, parentTypeName));
359
- }
360
- if (!definition.arguments || definition.arguments.length < 1) {
361
- if (directive.arguments && directive.arguments.length > 0) {
362
- errorMessages.push((0, errors_1.unexpectedDirectiveArgumentsErrorMessage)(directive, parentTypeName));
363
- }
364
- else {
365
- normalizedDirectives.push(directive);
366
- }
367
- continue;
368
- }
369
- if (!directive.arguments || directive.arguments.length < 1) {
370
- if (requiredArguments.size > 0) {
371
- errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, parentTypeName, [...requiredArguments]));
372
- }
373
- else {
374
- normalizedDirectives.push(directive);
375
- }
376
- continue;
377
- }
378
- const definedArguments = (0, utils_2.getDefinedArgumentsForDirective)(directive.arguments, allArguments, directiveName, parentTypeName, errorMessages);
379
- const missingRequiredArguments = (0, utils_3.getEntriesNotInHashSet)(requiredArguments, definedArguments);
380
- if (missingRequiredArguments.length > 0) {
381
- errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, parentTypeName, [...requiredArguments], missingRequiredArguments));
382
- }
383
- // Only add unique entity keys
384
- if (directiveName === string_constants_1.KEY) {
385
- const directiveKind = directive.arguments[0].value.kind;
386
- if (directiveKind !== graphql_1.Kind.STRING) {
387
- errorMessages.push((0, errors_1.invalidKeyDirectiveArgumentErrorMessage)(directiveKind));
388
- continue;
389
- }
390
- const entityKey = directive.arguments[0].value.value;
391
- if (entityKeys.has(entityKey)) {
392
- continue;
393
- }
394
- entityKeys.add(entityKey);
395
- }
396
- normalizedDirectives.push(directive);
397
- }
398
- if (errorMessages.length > 0) {
399
- this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, parentTypeName, errorMessages));
400
- }
401
- }
402
- return normalizedDirectives;
403
- }
404
- convertKindForExtension(node) {
405
- switch (node.kind) {
406
- case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
407
- return graphql_1.Kind.INTERFACE_TYPE_EXTENSION;
408
- case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
409
- return graphql_1.Kind.OBJECT_TYPE_EXTENSION;
410
- default:
411
- return node.kind;
412
- }
413
- }
414
277
  handleInterfaceObject(node) {
415
278
  if (!(0, utils_1.isNodeInterfaceObject)(node)) {
416
279
  return;
@@ -427,28 +290,22 @@ class NormalizationFactory {
427
290
  typeName: name,
428
291
  });
429
292
  }
430
- handleObjectLikeExtension(node) {
293
+ handleExtensionWithFields(node) {
431
294
  this.isCurrentParentExtension = true;
432
- const extension = this.extensionContainerByTypeName.get(this.parentTypeName);
433
- const convertedKind = this.convertKindForExtension(node);
295
+ const extension = this.parentExtensionDataByTypeName.get(this.parentTypeName);
296
+ const convertedKind = (0, utils_4.convertKindForExtension)(node);
434
297
  if (extension) {
435
298
  if (extension.kind !== convertedKind) {
436
299
  this.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
437
300
  return false;
438
301
  }
439
- this.extractDirectives(node, extension.directives);
440
- (0, utils_1.extractInterfaces)(node, extension.interfaces, this.errors);
302
+ (0, utils_4.extractDirectives)(node, extension.directivesByDirectiveName, this.errors, this.directiveDefinitionByDirectiveName, this.handledRepeatedDirectivesByHostPath, this.parentTypeName);
303
+ (0, utils_1.extractInterfaces)(node, extension.implementedInterfaceTypeNames, this.errors);
441
304
  return;
442
305
  }
443
306
  const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
444
- this.extensionContainerByTypeName.set(this.parentTypeName, {
445
- directives: this.extractDirectives(node, new Map()),
446
- fields: new Map(),
447
- interfaces: (0, utils_1.extractInterfaces)(node, new Set(), this.errors),
448
- isEntity,
449
- kind: convertedKind,
450
- name: node.name,
451
- });
307
+ (0, utils_4.upsertExtensionWithFieldsDataByNode)(this.parentExtensionDataByTypeName, node, this.errors, this.directiveDefinitionByDirectiveName, this.handledRepeatedDirectivesByHostPath, isEntity);
308
+ // TODO re-assess this line
452
309
  if (node.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION || node.kind === graphql_1.Kind.INTERFACE_TYPE_EXTENSION || !isEntity) {
453
310
  return;
454
311
  }
@@ -460,48 +317,6 @@ class NormalizationFactory {
460
317
  ...(this.subgraphName ? { subgraphNames: [this.subgraphName] } : {}),
461
318
  });
462
319
  }
463
- validateChildDirectives(child, hostPath) {
464
- const childKind = child.node.kind;
465
- for (const [directiveName, directives] of child.directives) {
466
- const definition = this.allDirectiveDefinitions.get(directiveName);
467
- if (!definition) {
468
- this.errors.push((0, errors_1.undefinedDirectiveError)(directiveName, hostPath));
469
- continue;
470
- }
471
- const allArguments = new Set();
472
- const requiredArguments = new Set();
473
- (0, utils_2.getDirectiveDefinitionArgumentSets)(definition.arguments || [], allArguments, requiredArguments);
474
- const errorMessages = [];
475
- for (const directive of directives) {
476
- if (!(0, utils_2.areNodeKindAndDirectiveLocationCompatible)(childKind, definition)) {
477
- errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(hostPath, childKind, directiveName));
478
- }
479
- if (!definition.repeatable && directives.length > 1) {
480
- errorMessages.push((0, errors_1.invalidRepeatedDirectiveErrorMessage)(directiveName, hostPath));
481
- }
482
- if (!definition.arguments || definition.arguments.length < 1) {
483
- if (directive.arguments && directive.arguments.length > 0) {
484
- errorMessages.push((0, errors_1.unexpectedDirectiveArgumentsErrorMessage)(directive, hostPath));
485
- }
486
- continue;
487
- }
488
- if (!directive.arguments || directive.arguments.length < 1) {
489
- if (requiredArguments.size > 0) {
490
- errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, hostPath, [...requiredArguments]));
491
- }
492
- continue;
493
- }
494
- const definedArguments = (0, utils_2.getDefinedArgumentsForDirective)(directive.arguments, allArguments, directiveName, hostPath, errorMessages);
495
- const missingRequiredArguments = (0, utils_3.getEntriesNotInHashSet)(requiredArguments, definedArguments);
496
- if (missingRequiredArguments.length > 0) {
497
- errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, hostPath, [...requiredArguments], missingRequiredArguments));
498
- }
499
- }
500
- if (errorMessages.length > 0) {
501
- this.errors.push((0, errors_1.invalidDirectiveError)(directiveName, hostPath, errorMessages));
502
- }
503
- }
504
- }
505
320
  isTypeValidImplementation(originalType, implementationType) {
506
321
  if (originalType.kind === graphql_1.Kind.NON_NULL_TYPE) {
507
322
  if (implementationType.kind !== graphql_1.Kind.NON_NULL_TYPE) {
@@ -534,18 +349,6 @@ class NormalizationFactory {
534
349
  return false;
535
350
  }
536
351
  }
537
- canContainEventDirectives() {
538
- if (!this.isCurrentParentRootType) {
539
- return false;
540
- }
541
- const operationTypeNode = this.operationTypeNames.get(this.parentTypeName);
542
- if (!operationTypeNode) {
543
- return string_constants_1.ROOT_TYPES.has(this.parentTypeName);
544
- }
545
- return (operationTypeNode === graphql_1.OperationTypeNode.QUERY ||
546
- operationTypeNode === graphql_1.OperationTypeNode.MUTATION ||
547
- operationTypeNode === graphql_1.OperationTypeNode.SUBSCRIPTION);
548
- }
549
352
  extractKeyFieldSets(node, fieldSetContainer) {
550
353
  const rawFieldSets = fieldSetContainer.keys;
551
354
  const parentTypeName = node.name.value;
@@ -587,12 +390,12 @@ class NormalizationFactory {
587
390
  }
588
391
  }
589
392
  validateInterfaceImplementations(container) {
590
- if (container.interfaces.size < 1) {
393
+ if (container.implementedInterfaceTypeNames.size < 1) {
591
394
  return;
592
395
  }
593
396
  const implementationErrorsMap = new Map();
594
- for (const interfaceName of container.interfaces) {
595
- const interfaceContainer = (0, utils_3.getOrThrowError)(this.parentContainerByTypeName, interfaceName, string_constants_1.PARENTS);
397
+ for (const interfaceName of container.implementedInterfaceTypeNames) {
398
+ const interfaceContainer = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, interfaceName, string_constants_1.PARENTS);
596
399
  if (interfaceContainer.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
597
400
  throw (0, errors_1.incompatibleParentKindFatalError)(interfaceName, graphql_1.Kind.INTERFACE_TYPE_DEFINITION, interfaceContainer.kind);
598
401
  }
@@ -601,9 +404,9 @@ class NormalizationFactory {
601
404
  unimplementedFields: [],
602
405
  };
603
406
  let hasErrors = false;
604
- for (const [fieldName, interfaceField] of interfaceContainer.fields) {
407
+ for (const [fieldName, interfaceField] of interfaceContainer.fieldDataByFieldName) {
605
408
  let hasNestedErrors = false;
606
- const containerField = container.fields.get(fieldName);
409
+ const containerField = container.fieldDataByFieldName.get(fieldName);
607
410
  if (!containerField) {
608
411
  hasErrors = true;
609
412
  implementationErrors.unimplementedFields.push(fieldName);
@@ -622,9 +425,9 @@ class NormalizationFactory {
622
425
  invalidFieldImplementation.implementedResponseType = (0, merge_1.printTypeNode)(containerField.node.type);
623
426
  }
624
427
  const handledArguments = new Set();
625
- for (const [argumentName, interfaceArgument] of interfaceField.arguments) {
428
+ for (const [argumentName, interfaceArgument] of interfaceField.argumentDataByArgumentName) {
626
429
  handledArguments.add(argumentName);
627
- const containerArgument = containerField.arguments.get(argumentName);
430
+ const containerArgument = containerField.argumentDataByArgumentName.get(argumentName);
628
431
  // The type implementing the interface must include all arguments with no variation for that argument
629
432
  if (!containerArgument) {
630
433
  hasErrors = true;
@@ -642,11 +445,11 @@ class NormalizationFactory {
642
445
  }
643
446
  }
644
447
  // Additional arguments must be optional (nullable)
645
- for (const [argumentName, argumentNode] of containerField.arguments) {
448
+ for (const [argumentName, argumentData] of containerField.argumentDataByArgumentName) {
646
449
  if (handledArguments.has(argumentName)) {
647
450
  continue;
648
451
  }
649
- if (argumentNode.type.kind !== graphql_1.Kind.NON_NULL_TYPE) {
452
+ if (argumentData.type.kind !== graphql_1.Kind.NON_NULL_TYPE) {
650
453
  continue;
651
454
  }
652
455
  hasErrors = true;
@@ -662,81 +465,25 @@ class NormalizationFactory {
662
465
  }
663
466
  }
664
467
  if (implementationErrorsMap.size) {
665
- this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.name.value, (0, utils_3.kindToTypeString)(container.kind), implementationErrorsMap));
468
+ this.errors.push((0, errors_1.unimplementedInterfaceFieldsError)(container.typeName, (0, utils_3.kindToTypeString)(container.kind), implementationErrorsMap));
666
469
  }
667
470
  }
668
- handleOverride(node) {
669
- if (node.name.value !== string_constants_1.OVERRIDE) {
471
+ handleOverrideDeclaration(node, hostPath, errorMessages) {
472
+ const argumentNode = node.arguments[0];
473
+ if (argumentNode.value.kind !== graphql_1.Kind.STRING) {
474
+ errorMessages.push((0, errors_1.invalidDirectiveArgumentTypeErrorMessage)(true, string_constants_1.FROM, graphql_1.Kind.STRING, argumentNode.value.kind));
670
475
  return;
671
476
  }
672
- const errorMessages = [];
673
- let hostPath = `${this.parentTypeName}.${this.childName}`;
674
- let kind = this.lastChildNodeKind === graphql_1.Kind.NULL ? this.lastParentNodeKind : this.lastChildNodeKind;
675
- if (this.argumentName) {
676
- hostPath += `(${this.argumentName}: ...)`;
677
- kind = graphql_1.Kind.ARGUMENT;
678
- }
679
- if (kind !== graphql_1.Kind.FIELD_DEFINITION) {
680
- errorMessages.push((0, errors_1.invalidDirectiveLocationErrorMessage)(hostPath, kind, string_constants_1.OVERRIDE));
681
- }
682
- let targetSubgraphName = '';
683
- if (node.arguments && node.arguments.length > 0) {
684
- const observedArguments = new Set();
685
- const handledDuplicateArguments = new Set();
686
- for (const argumentNode of node.arguments) {
687
- const argumentName = argumentNode.name.value;
688
- if (argumentName !== string_constants_1.FROM && !observedArguments.has(argumentName)) {
689
- observedArguments.add(argumentName);
690
- errorMessages.push((0, errors_1.unexpectedDirectiveArgumentErrorMessage)(string_constants_1.OVERRIDE, argumentName));
691
- continue;
692
- }
693
- // If an argument is observed more than once, it is a duplication error.
694
- // However, the error should only propagate once.
695
- if (observedArguments.has(argumentName)) {
696
- if (!handledDuplicateArguments.has(argumentName)) {
697
- errorMessages.push((0, errors_1.duplicateDirectiveArgumentDefinitionErrorMessage)(string_constants_1.OVERRIDE, hostPath, argumentName));
698
- }
699
- continue;
700
- }
701
- if (argumentNode.value.kind !== graphql_1.Kind.STRING) {
702
- errorMessages.push((0, errors_1.invalidDirectiveArgumentTypeErrorMessage)(true, string_constants_1.FROM, graphql_1.Kind.STRING, argumentNode.value.kind));
703
- }
704
- else {
705
- observedArguments.add(string_constants_1.FROM);
706
- targetSubgraphName = argumentNode.value.value;
707
- if (targetSubgraphName === this.subgraphName) {
708
- this.errors.push((0, errors_1.equivalentSourceAndTargetOverrideError)(targetSubgraphName, hostPath));
709
- }
710
- }
711
- }
712
- if (!observedArguments.has(string_constants_1.FROM)) {
713
- errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(string_constants_1.OVERRIDE, hostPath, [string_constants_1.FROM], [string_constants_1.FROM]));
714
- }
715
- }
716
- else {
717
- errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(string_constants_1.OVERRIDE, hostPath, [string_constants_1.FROM], []));
718
- }
719
- if (errorMessages.length > 0) {
720
- this.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.OVERRIDE, hostPath, errorMessages));
477
+ const targetSubgraphName = argumentNode.value.value;
478
+ if (targetSubgraphName === this.subgraphName) {
479
+ errorMessages.push((0, errors_1.equivalentSourceAndTargetOverrideErrorMessage)(targetSubgraphName, hostPath));
721
480
  return;
722
481
  }
723
482
  const overrideDataForSubgraph = (0, utils_3.getValueOrDefault)(this.overridesByTargetSubgraphName, targetSubgraphName, () => new Map());
724
483
  const overriddenFieldNamesForParent = (0, utils_3.getValueOrDefault)(overrideDataForSubgraph, this.parentTypeName, () => new Set());
725
- if (overriddenFieldNamesForParent.has(this.childName)) {
726
- const handledRepeatedDirectives = this.handledRepeatedDirectivesByHostPath.get(hostPath);
727
- // If the directive name exists as a value on the host path key, the repeatable error has been handled
728
- if (handledRepeatedDirectives && handledRepeatedDirectives.has(string_constants_1.OVERRIDE)) {
729
- return;
730
- }
731
- // Add the directive name to the existing set (if other invalid repeated directives exist) or a new set
732
- (0, utils_3.getValueOrDefault)(this.handledRepeatedDirectivesByHostPath, hostPath, () => new Set()).add(string_constants_1.OVERRIDE);
733
- // The invalid repeated directive error should propagate only once per directive per host path
734
- this.errors.push((0, errors_1.invalidDirectiveError)(string_constants_1.OVERRIDE, hostPath, [(0, errors_1.invalidRepeatedDirectiveErrorMessage)(string_constants_1.OVERRIDE, hostPath)]));
735
- return;
736
- }
737
484
  overriddenFieldNamesForParent.add(this.childName);
738
485
  }
739
- extractEventDirectives(node) {
486
+ extractEventDirectivesToConfiguration(node) {
740
487
  if (!node.directives) {
741
488
  return;
742
489
  }
@@ -802,584 +549,52 @@ class NormalizationFactory {
802
549
  }
803
550
  }
804
551
  normalize(document) {
805
- const factory = this;
806
552
  /* factory.allDirectiveDefinitions is initialized with v1 directive definitions, and v2 definitions are only added
807
553
  after the visitor has visited the entire schema and the subgraph is known to be a V2 graph. Consequently,
808
554
  allDirectiveDefinitions cannot be used to check for duplicate definitions, and another set (below) is required */
809
- const definedDirectives = new Set();
810
- const handledRootTypes = new Set();
811
555
  // Collect any renamed root types
812
- (0, graphql_1.visit)(document, {
813
- OperationTypeDefinition: {
814
- enter(node) {
815
- const operationType = node.operation;
816
- const operationPath = `${factory.parentTypeName}.${operationType}`;
817
- const definitionNode = factory.schemaDefinition.operationTypes.get(operationType);
818
- const newTypeName = (0, type_merging_1.getNamedTypeForChild)(operationPath, node.type);
819
- if (definitionNode) {
820
- (0, errors_1.duplicateOperationTypeDefinitionError)(operationType, newTypeName, (0, type_merging_1.getNamedTypeForChild)(operationPath, definitionNode.type));
821
- return false;
822
- }
823
- const existingOperationType = factory.operationTypeNames.get(newTypeName);
824
- if (existingOperationType) {
825
- factory.errors.push((0, errors_1.invalidOperationTypeDefinitionError)(existingOperationType, newTypeName, operationType));
826
- }
827
- else {
828
- handledRootTypes.add(operationType);
829
- factory.operationTypeNames.set(newTypeName, operationType);
830
- factory.schemaDefinition.operationTypes.set(operationType, node);
831
- }
832
- return false;
833
- },
834
- },
835
- SchemaDefinition: {
836
- enter(node) {
837
- factory.extractDirectives(node, factory.schemaDefinition.directives);
838
- factory.schemaDefinition.description = node.description;
839
- },
840
- },
841
- SchemaExtension: {
842
- enter(node) {
843
- factory.extractDirectives(node, factory.schemaDefinition.directives);
844
- },
845
- },
846
- });
847
- (0, graphql_1.visit)(document, {
848
- DirectiveDefinition: {
849
- enter(node) {
850
- const name = node.name.value;
851
- if (definedDirectives.has(name)) {
852
- factory.errors.push((0, errors_1.duplicateDirectiveDefinitionError)(name));
853
- return false;
854
- }
855
- else {
856
- definedDirectives.add(name);
857
- }
858
- // Normalize federation directives by replacing them with predefined definitions
859
- if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
860
- factory.isSubgraphVersionTwo = true;
861
- return false;
862
- }
863
- // The V1 directives are always injected
864
- if (constants_1.VERSION_ONE_DIRECTIVES.has(name)) {
865
- return false;
866
- }
867
- factory.allDirectiveDefinitions.set(name, node);
868
- factory.customDirectiveDefinitions.set(name, node);
869
- return false;
870
- },
871
- },
872
- Directive: {
873
- enter(node) {
874
- const name = node.name.value;
875
- factory.handleOverride(node);
876
- if (constants_1.VERSION_TWO_DIRECTIVES.has(name)) {
877
- factory.isSubgraphVersionTwo = true;
878
- return false;
879
- }
880
- if (constants_1.VERSION_ONE_DIRECTIVES.has(name)) {
881
- return false;
882
- }
883
- factory.referencedDirectives.add(name);
884
- },
885
- },
886
- EnumTypeDefinition: {
887
- enter(node) {
888
- const typeName = node.name.value;
889
- if (factory.parentContainerByTypeName.has(typeName)) {
890
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), typeName));
891
- return false;
892
- }
893
- factory.parentTypeName = typeName;
894
- factory.lastParentNodeKind = node.kind;
895
- const directives = factory.extractDirectivesAndAuthorization(node, new Map());
896
- factory.parentContainerByTypeName.set(typeName, {
897
- description: (0, utils_1.formatDescription)(node.description),
898
- directives,
899
- kind: node.kind,
900
- name: node.name,
901
- values: new Map(),
902
- });
903
- },
904
- leave() {
905
- factory.parentTypeName = '';
906
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
907
- },
908
- },
909
- EnumTypeExtension: {
910
- enter(node) {
911
- const name = node.name.value;
912
- factory.parentTypeName = name;
913
- factory.lastParentNodeKind = node.kind;
914
- factory.isCurrentParentExtension = true;
915
- const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
916
- if (extension) {
917
- if (extension.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
918
- factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
919
- return false;
920
- }
921
- factory.extractDirectivesAndAuthorization(node, extension.directives);
922
- return;
923
- }
924
- factory.extensionContainerByTypeName.set(name, {
925
- directives: factory.extractDirectivesAndAuthorization(node, new Map()),
926
- kind: node.kind,
927
- name: node.name,
928
- values: new Map(),
929
- });
930
- },
931
- leave() {
932
- factory.parentTypeName = '';
933
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
934
- factory.isCurrentParentExtension = false;
935
- },
936
- },
937
- EnumValueDefinition: {
938
- enter(node) {
939
- const name = node.name.value;
940
- factory.childName = name;
941
- factory.lastChildNodeKind = node.kind;
942
- const parent = factory.isCurrentParentExtension
943
- ? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
944
- : (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
945
- if (parent.kind !== graphql_1.Kind.ENUM_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.ENUM_TYPE_EXTENSION) {
946
- throw (0, errors_1.unexpectedKindFatalError)(name);
947
- }
948
- if (parent.values.has(name)) {
949
- const error = factory.isCurrentParentExtension
950
- ? (0, errors_1.duplicateValueExtensionError)('enum', factory.parentTypeName, name)
951
- : (0, errors_1.duplicateEnumValueDefinitionError)(name, factory.parentTypeName);
952
- factory.errors.push(error);
953
- return;
954
- }
955
- parent.values.set(name, {
956
- directives: factory.extractDirectives(node, new Map()),
957
- name,
958
- node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
959
- });
960
- },
961
- leave() {
962
- factory.childName = '';
963
- factory.lastChildNodeKind = graphql_1.Kind.NULL;
964
- },
965
- },
966
- FieldDefinition: {
967
- enter(node) {
968
- const fieldName = node.name.value;
969
- if (factory.isCurrentParentRootType && (fieldName === string_constants_1.SERVICE_FIELD || fieldName === string_constants_1.ENTITIES_FIELD)) {
970
- return false;
971
- }
972
- factory.childName = fieldName;
973
- factory.lastChildNodeKind = node.kind;
974
- if (factory.canContainEventDirectives()) {
975
- factory.extractEventDirectives(node);
976
- }
977
- const fieldPath = `${factory.parentTypeName}.${fieldName}`;
978
- factory.lastChildNodeKind = node.kind;
979
- const fieldNamedTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, node.type);
980
- if (!constants_1.BASE_SCALARS.has(fieldNamedTypeName)) {
981
- factory.referencedTypeNames.add(fieldNamedTypeName);
982
- }
983
- const parent = factory.isCurrentParentExtension
984
- ? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
985
- : (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
986
- if (parent.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
987
- parent.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
988
- parent.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION &&
989
- parent.kind !== graphql_1.Kind.INTERFACE_TYPE_EXTENSION) {
990
- throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
991
- }
992
- if (parent.fields.has(fieldName)) {
993
- factory.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, factory.parentTypeName));
994
- return;
995
- }
996
- // recreate the node so the argument descriptions are updated
997
- const fieldContainer = {
998
- arguments: factory.extractArguments(node, new Map(), fieldPath),
999
- directives: factory.extractDirectivesAndAuthorization(node, new Map()),
1000
- name: fieldName,
1001
- node: {
1002
- ...node,
1003
- arguments: node.arguments?.map((arg) => ({
1004
- ...arg,
1005
- description: (0, utils_1.formatDescription)(arg.description),
1006
- })),
1007
- },
1008
- };
1009
- parent.fields.set(fieldName, fieldContainer);
1010
- const entityContainer = factory.entityContainerByTypeName.get(factory.parentTypeName);
1011
- if (entityContainer) {
1012
- entityContainer.fieldNames.add(fieldName);
1013
- // Only entities will have an existing FieldSet
1014
- const existingFieldSet = factory.fieldSetContainerByTypeName.get(factory.parentTypeName);
1015
- if (existingFieldSet) {
1016
- // @requires should only be defined on a field whose parent is an entity
1017
- // If there is existingFieldSet, it's an entity
1018
- (0, utils_2.extractFieldSetValue)(fieldName, existingFieldSet.requires, fieldContainer.directives.get(string_constants_1.REQUIRES));
1019
- // @provides only makes sense on entities, but the field can be encountered before the type definition
1020
- // When the FieldSet is evaluated, it will be checked whether the field is an entity.
1021
- (0, utils_2.extractFieldSetValue)(fieldName, existingFieldSet.provides, fieldContainer.directives.get(string_constants_1.PROVIDES));
1022
- return;
1023
- }
1024
- }
1025
- const providesDirectives = fieldContainer.directives.get(string_constants_1.PROVIDES);
1026
- // Check whether the directive exists to avoid creating unnecessary fieldSet configurations
1027
- if (!providesDirectives) {
1028
- return;
1029
- }
1030
- const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, factory.parentTypeName, utils_2.newFieldSetContainer);
1031
- // @provides only makes sense on entities, but the field can be encountered before the type definition
1032
- // When the FieldSet is evaluated, it will be checked whether the field is an entity.
1033
- (0, utils_2.extractFieldSetValue)(fieldName, fieldSetContainer.provides, providesDirectives);
1034
- },
1035
- leave() {
1036
- factory.childName = '';
1037
- factory.lastChildNodeKind = graphql_1.Kind.NULL;
1038
- },
1039
- },
1040
- InputObjectTypeDefinition: {
1041
- enter(node) {
1042
- const name = node.name.value;
1043
- if (factory.parentContainerByTypeName.has(name)) {
1044
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1045
- return false;
1046
- }
1047
- factory.lastParentNodeKind = node.kind;
1048
- factory.parentTypeName = name;
1049
- factory.parentContainerByTypeName.set(name, {
1050
- description: (0, utils_1.formatDescription)(node.description),
1051
- directives: factory.extractDirectives(node, new Map()),
1052
- fields: new Map(),
1053
- kind: node.kind,
1054
- name: node.name,
1055
- });
1056
- },
1057
- leave() {
1058
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1059
- factory.parentTypeName = '';
1060
- },
1061
- },
1062
- InputObjectTypeExtension: {
1063
- enter(node) {
1064
- const name = node.name.value;
1065
- factory.parentTypeName = name;
1066
- factory.lastParentNodeKind = node.kind;
1067
- factory.isCurrentParentExtension = true;
1068
- const extension = factory.extensionContainerByTypeName.get(factory.parentTypeName);
1069
- if (extension) {
1070
- if (extension.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
1071
- factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
1072
- return false;
1073
- }
1074
- factory.extractDirectives(node, extension.directives);
1075
- return;
1076
- }
1077
- factory.extensionContainerByTypeName.set(name, {
1078
- directives: factory.extractDirectives(node, new Map()),
1079
- fields: new Map(),
1080
- kind: node.kind,
1081
- name: node.name,
1082
- });
1083
- },
1084
- leave() {
1085
- factory.parentTypeName = '';
1086
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1087
- factory.isCurrentParentExtension = false;
1088
- },
1089
- },
1090
- InputValueDefinition: {
1091
- enter(node) {
1092
- const name = node.name.value;
1093
- // If the parent is not an object type definition/extension, this node is an argument
1094
- if (factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION &&
1095
- factory.lastParentNodeKind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
1096
- factory.argumentName = name;
1097
- return;
1098
- }
1099
- factory.childName = name;
1100
- factory.lastChildNodeKind = node.kind;
1101
- const valueRootTypeName = (0, type_merging_1.getNamedTypeForChild)(`${factory.parentTypeName}.${name}`, node.type);
1102
- if (!constants_1.BASE_SCALARS.has(valueRootTypeName)) {
1103
- factory.referencedTypeNames.add(valueRootTypeName);
1104
- }
1105
- const parent = factory.isCurrentParentExtension
1106
- ? (0, utils_3.getOrThrowError)(factory.extensionContainerByTypeName, factory.parentTypeName, string_constants_1.EXTENSIONS)
1107
- : (0, utils_3.getOrThrowError)(factory.parentContainerByTypeName, factory.parentTypeName, string_constants_1.PARENTS);
1108
- if (parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION && parent.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_EXTENSION) {
1109
- throw (0, errors_1.unexpectedKindFatalError)(factory.parentTypeName);
1110
- }
1111
- if (parent.fields.has(name)) {
1112
- factory.errors.push((0, errors_1.duplicateValueExtensionError)('input', factory.parentTypeName, name));
1113
- return;
1114
- }
1115
- parent.fields.set(name, {
1116
- directives: factory.extractDirectives(node, new Map()),
1117
- name,
1118
- node: { ...node, description: (0, utils_1.formatDescription)(node.description) },
1119
- });
1120
- },
1121
- leave() {
1122
- factory.argumentName = '';
1123
- // Only reset childName and lastNodeKind if this input value was NOT an argument
1124
- if (factory.lastChildNodeKind === graphql_1.Kind.INPUT_VALUE_DEFINITION) {
1125
- factory.childName = '';
1126
- factory.lastChildNodeKind = graphql_1.Kind.NULL;
1127
- }
1128
- },
1129
- },
1130
- InterfaceTypeDefinition: {
1131
- enter(node) {
1132
- const name = node.name.value;
1133
- factory.parentTypeName = name;
1134
- factory.lastParentNodeKind = node.kind;
1135
- if ((0, utils_1.isNodeExtension)(node)) {
1136
- return factory.handleObjectLikeExtension(node);
1137
- }
1138
- if (factory.parentContainerByTypeName.has(name)) {
1139
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1140
- return false;
1141
- }
1142
- const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
1143
- factory.parentContainerByTypeName.set(name, {
1144
- description: (0, utils_1.formatDescription)(node.description),
1145
- directives: factory.extractDirectives(node, new Map()),
1146
- fields: new Map(),
1147
- interfaces: (0, utils_1.extractInterfaces)(node, new Set(), factory.errors),
1148
- isEntity,
1149
- kind: node.kind,
1150
- name: node.name,
1151
- });
1152
- if (!isEntity) {
1153
- return;
1154
- }
1155
- factory.entityInterfaces.set(name, {
1156
- concreteTypeNames: new Set(),
1157
- interfaceFieldNames: new Set(node.fields?.map((field) => field.name.value)),
1158
- interfaceObjectFieldNames: new Set(),
1159
- isInterfaceObject: false,
1160
- typeName: name,
1161
- });
1162
- (0, utils_3.upsertEntityContainerProperties)(factory.entityContainerByTypeName, {
1163
- typeName: factory.parentTypeName,
1164
- ...(factory.subgraphName ? { subgraphNames: [factory.subgraphName] } : {}),
1165
- });
1166
- const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, name, utils_2.newFieldSetContainer);
1167
- factory.extractKeyFieldSets(node, fieldSetContainer);
1168
- },
1169
- leave() {
1170
- factory.parentTypeName = '';
1171
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1172
- factory.isCurrentParentExtension = false;
1173
- },
1174
- },
1175
- InterfaceTypeExtension: {
1176
- enter(node) {
1177
- factory.parentTypeName = node.name.value;
1178
- factory.lastParentNodeKind = node.kind;
1179
- return factory.handleObjectLikeExtension(node);
1180
- },
1181
- leave() {
1182
- factory.isCurrentParentExtension = false;
1183
- factory.parentTypeName = '';
1184
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1185
- },
1186
- },
1187
- ObjectTypeDefinition: {
1188
- enter(node) {
1189
- const typeName = node.name.value;
1190
- if (typeName === string_constants_1.SERVICE_OBJECT) {
1191
- return false;
1192
- }
1193
- factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(typeName) || factory.operationTypeNames.has(typeName);
1194
- factory.parentTypeName = typeName;
1195
- factory.lastParentNodeKind = node.kind;
1196
- (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
1197
- factory.handleInterfaceObject(node);
1198
- // handling for @extends directive
1199
- if ((0, utils_1.isNodeExtension)(node)) {
1200
- return factory.handleObjectLikeExtension(node);
1201
- }
1202
- if (factory.parentContainerByTypeName.has(typeName)) {
1203
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), typeName));
1204
- return false;
1205
- }
1206
- const isEntity = (0, utils_1.isObjectLikeNodeEntity)(node);
1207
- factory.parentContainerByTypeName.set(typeName, {
1208
- description: (0, utils_1.formatDescription)(node.description),
1209
- directives: factory.extractDirectives(node, new Map()),
1210
- fields: new Map(),
1211
- interfaces: (0, utils_1.extractInterfaces)(node, new Set(), factory.errors),
1212
- isEntity,
1213
- kind: node.kind,
1214
- name: node.name,
1215
- });
1216
- if (!isEntity) {
1217
- return;
1218
- }
1219
- const fieldSetContainer = (0, utils_3.getValueOrDefault)(factory.fieldSetContainerByTypeName, typeName, utils_2.newFieldSetContainer);
1220
- factory.extractKeyFieldSets(node, fieldSetContainer);
1221
- (0, utils_3.upsertEntityContainerProperties)(factory.entityContainerByTypeName, {
1222
- typeName: factory.parentTypeName,
1223
- keyFieldSets: fieldSetContainer.keys,
1224
- ...(factory.subgraphName ? { subgraphNames: [factory.subgraphName] } : {}),
1225
- });
1226
- },
1227
- leave() {
1228
- factory.isCurrentParentRootType = false;
1229
- factory.isCurrentParentExtension = false;
1230
- factory.parentTypeName = '';
1231
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1232
- },
1233
- },
1234
- ObjectTypeExtension: {
1235
- enter(node) {
1236
- const name = node.name.value;
1237
- if (name === string_constants_1.SERVICE_OBJECT) {
1238
- return false;
1239
- }
1240
- factory.isCurrentParentRootType = string_constants_1.ROOT_TYPES.has(name) || factory.operationTypeNames.has(name);
1241
- factory.parentTypeName = name;
1242
- factory.lastParentNodeKind = node.kind;
1243
- (0, utils_1.addConcreteTypesForImplementedInterfaces)(node, factory.abstractToConcreteTypeNames);
1244
- return factory.handleObjectLikeExtension(node);
1245
- },
1246
- leave() {
1247
- factory.isCurrentParentRootType = false;
1248
- factory.isCurrentParentExtension = false;
1249
- factory.parentTypeName = '';
1250
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1251
- },
1252
- },
1253
- ScalarTypeDefinition: {
1254
- enter(node) {
1255
- const name = node.name.value;
1256
- if (name === string_constants_1.ANY_SCALAR) {
1257
- return false;
1258
- }
1259
- const parent = factory.parentContainerByTypeName.get(name);
1260
- if (parent) {
1261
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1262
- return false;
1263
- }
1264
- factory.parentTypeName = name;
1265
- factory.lastParentNodeKind = node.kind;
1266
- factory.parentContainerByTypeName.set(name, {
1267
- description: (0, utils_1.formatDescription)(node.description),
1268
- directives: factory.extractDirectivesAndAuthorization(node, new Map()),
1269
- kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
1270
- name: node.name,
1271
- });
1272
- },
1273
- leave() {
1274
- factory.parentTypeName = '';
1275
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1276
- },
1277
- },
1278
- ScalarTypeExtension: {
1279
- enter(node) {
1280
- const name = node.name.value;
1281
- if (name === string_constants_1.ANY_SCALAR) {
1282
- return false;
1283
- }
1284
- const extension = factory.extensionContainerByTypeName.get(name);
1285
- if (extension) {
1286
- if (extension.kind !== graphql_1.Kind.SCALAR_TYPE_EXTENSION) {
1287
- factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
1288
- return false;
1289
- }
1290
- factory.extractDirectivesAndAuthorization(node, extension.directives);
1291
- }
1292
- else {
1293
- factory.parentTypeName = name;
1294
- factory.lastParentNodeKind = node.kind;
1295
- factory.extensionContainerByTypeName.set(name, {
1296
- directives: factory.extractDirectivesAndAuthorization(node, new Map()),
1297
- kind: node.kind,
1298
- name: node.name,
1299
- });
1300
- }
1301
- return false;
1302
- },
1303
- leave() {
1304
- factory.parentTypeName = '';
1305
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1306
- },
1307
- },
1308
- UnionTypeDefinition: {
1309
- enter(node) {
1310
- const name = node.name.value;
1311
- if (name === string_constants_1.ENTITY_UNION) {
1312
- return false;
1313
- }
1314
- factory.parentTypeName = name;
1315
- const parent = factory.parentContainerByTypeName.get(name);
1316
- if (parent) {
1317
- factory.errors.push((0, errors_1.duplicateTypeDefinitionError)((0, utils_3.kindToTypeString)(node.kind), name));
1318
- return false;
1319
- }
1320
- if (!node.types) {
1321
- factory.errors.push((0, errors_1.noDefinedUnionMembersError)(name));
1322
- return false;
1323
- }
1324
- factory.lastParentNodeKind = node.kind;
1325
- (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
1326
- factory.parentContainerByTypeName.set(name, {
1327
- description: (0, utils_1.formatDescription)(node.description),
1328
- directives: factory.extractDirectives(node, new Map()),
1329
- kind: node.kind,
1330
- name: node.name,
1331
- types: factory.extractUniqueUnionMembers([...node.types], new Map()),
1332
- });
1333
- },
1334
- leave() {
1335
- factory.parentTypeName = '';
1336
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1337
- },
1338
- },
1339
- UnionTypeExtension: {
1340
- enter(node) {
1341
- const name = node.name.value;
1342
- if (name === string_constants_1.ENTITY_UNION) {
1343
- return false;
1344
- }
1345
- const extension = factory.extensionContainerByTypeName.get(name);
1346
- if (!node.types) {
1347
- factory.errors.push();
1348
- return false;
1349
- }
1350
- factory.lastParentNodeKind = node.kind;
1351
- (0, utils_1.addConcreteTypesForUnion)(node, factory.abstractToConcreteTypeNames);
1352
- if (extension) {
1353
- if (extension.kind !== graphql_1.Kind.UNION_TYPE_EXTENSION) {
1354
- factory.errors.push((0, errors_1.incompatibleExtensionKindsError)(node, extension.kind));
1355
- return false;
1356
- }
1357
- factory.extractDirectives(node, extension.directives);
1358
- }
1359
- else {
1360
- factory.extensionContainerByTypeName.set(name, {
1361
- directives: factory.extractDirectives(node, new Map()),
1362
- kind: node.kind,
1363
- name: node.name,
1364
- types: factory.extractUniqueUnionMembers([...node.types], new Map()),
1365
- });
556
+ (0, walkers_1.upsertDirectiveAndSchemaDefinitions)(this, document);
557
+ (0, walkers_1.upsertParentsAndChildren)(this, document);
558
+ (0, walkers_1.consolidateAuthorizationDirectives)(this, document);
559
+ for (const interfaceTypeName of this.interfaceTypeNamesWithAuthorizationDirectives) {
560
+ const interfaceAuthorizationData = this.authorizationDataByParentTypeName.get(interfaceTypeName);
561
+ if (!interfaceAuthorizationData) {
562
+ continue;
563
+ }
564
+ const concreteTypeNames = this.abstractToConcreteTypeNames.get(interfaceTypeName);
565
+ for (const concreteTypeName of concreteTypeNames || []) {
566
+ const concreteAuthorizationData = (0, utils_3.getValueOrDefault)(this.authorizationDataByParentTypeName, concreteTypeName, () => (0, utils_3.newAuthorizationData)(concreteTypeName));
567
+ for (const [fieldName, interfaceFieldAuthorizationData,] of interfaceAuthorizationData.fieldAuthorizationDataByFieldName) {
568
+ if (!(0, utils_3.upsertFieldAuthorizationData)(concreteAuthorizationData.fieldAuthorizationDataByFieldName, interfaceFieldAuthorizationData)) {
569
+ this.invalidOrScopesHostPaths.add(`${concreteTypeName}.${fieldName}`);
1366
570
  }
1367
- return false;
1368
- },
1369
- leave() {
1370
- factory.lastParentNodeKind = graphql_1.Kind.NULL;
1371
- },
1372
- },
1373
- });
571
+ }
572
+ }
573
+ }
574
+ // Apply inherited leaf authorization that was not applied to interface fields of that type earlier
575
+ for (const [typeName, fieldAuthorizationDatas] of this.heirFieldAuthorizationDataByTypeName) {
576
+ const authorizationData = this.authorizationDataByParentTypeName.get(typeName);
577
+ if (!authorizationData) {
578
+ continue;
579
+ }
580
+ for (const fieldAuthorizationData of fieldAuthorizationDatas) {
581
+ if (!(0, utils_3.mergeAuthorizationDataByAND)(authorizationData, fieldAuthorizationData)) {
582
+ this.invalidOrScopesHostPaths.add(`${typeName}.${fieldAuthorizationData.fieldName}`);
583
+ }
584
+ }
585
+ }
586
+ if (this.invalidOrScopesHostPaths.size > 0) {
587
+ this.errors.push((0, errors_1.orScopesLimitError)(utils_3.maxOrScopes, [...this.invalidOrScopesHostPaths]));
588
+ }
1374
589
  const definitions = [];
1375
590
  for (const directiveDefinition of constants_1.BASE_DIRECTIVE_DEFINITIONS) {
1376
591
  definitions.push(directiveDefinition);
1377
592
  }
1378
593
  definitions.push(constants_1.FIELD_SET_SCALAR_DEFINITION);
1379
- if (factory.isSubgraphVersionTwo) {
594
+ if (this.isSubgraphVersionTwo) {
1380
595
  for (const directiveDefinition of constants_1.VERSION_TWO_DIRECTIVE_DEFINITIONS) {
1381
596
  definitions.push(directiveDefinition);
1382
- this.allDirectiveDefinitions.set(directiveDefinition.name.value, directiveDefinition);
597
+ this.directiveDefinitionByDirectiveName.set(directiveDefinition.name.value, directiveDefinition);
1383
598
  }
1384
599
  definitions.push(constants_1.SCOPE_SCALAR_DEFINITION);
1385
600
  }
@@ -1387,11 +602,11 @@ class NormalizationFactory {
1387
602
  definitions.push(directiveDefinition);
1388
603
  }
1389
604
  if (this.schemaDefinition.operationTypes.size > 0) {
1390
- definitions.push((0, utils_2.schemaContainerToNode)(this, this.schemaDefinition));
605
+ definitions.push((0, utils_4.getSchemaNodeByData)(this.schemaDefinition, this.errors, this.directiveDefinitionByDirectiveName));
1391
606
  }
1392
607
  const validExtensionOrphans = new Set();
1393
608
  const parentsToIgnore = new Set();
1394
- for (const [extensionTypeName, extensionContainer] of this.extensionContainerByTypeName) {
609
+ for (const [extensionTypeName, parentExtensionData] of this.parentExtensionDataByTypeName) {
1395
610
  const isEntity = this.entityContainerByTypeName.has(extensionTypeName);
1396
611
  const configurationData = {
1397
612
  fieldNames: new Set(),
@@ -1399,91 +614,91 @@ class NormalizationFactory {
1399
614
  typeName: extensionTypeName,
1400
615
  };
1401
616
  this.configurationDataMap.set(extensionTypeName, configurationData);
1402
- if (extensionContainer.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
617
+ if (parentExtensionData.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
1403
618
  if (this.operationTypeNames.has(extensionTypeName)) {
1404
- extensionContainer.fields.delete(string_constants_1.SERVICE_FIELD);
1405
- extensionContainer.fields.delete(string_constants_1.ENTITIES_FIELD);
619
+ parentExtensionData.fieldDataByFieldName.delete(string_constants_1.SERVICE_FIELD);
620
+ parentExtensionData.fieldDataByFieldName.delete(string_constants_1.ENTITIES_FIELD);
1406
621
  }
1407
- (0, utils_2.addNonExternalFieldsToSet)(extensionContainer.fields, configurationData.fieldNames);
622
+ (0, utils_2.addNonExternalFieldsToSet)(parentExtensionData.fieldDataByFieldName, configurationData.fieldNames);
1408
623
  }
1409
- const baseType = this.parentContainerByTypeName.get(extensionTypeName);
1410
- if (!baseType) {
1411
- if (extensionContainer.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
624
+ const parentDefinitionData = this.parentDefinitionDataByTypeName.get(extensionTypeName);
625
+ if (!parentDefinitionData) {
626
+ if (parentExtensionData.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
1412
627
  this.errors.push((0, errors_1.noBaseTypeExtensionError)(extensionTypeName));
1413
628
  }
1414
629
  else {
1415
- this.validateInterfaceImplementations(extensionContainer);
630
+ this.validateInterfaceImplementations(parentExtensionData);
1416
631
  validExtensionOrphans.add(extensionTypeName);
1417
- definitions.push((0, utils_2.objectLikeContainerToNode)(this, extensionContainer));
632
+ definitions.push((0, utils_4.getParentWithFieldsNodeByData)(parentExtensionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
1418
633
  }
1419
634
  continue;
1420
635
  }
1421
- if (!(0, utils_1.areBaseAndExtensionKindsCompatible)(baseType.kind, extensionContainer.kind, extensionTypeName)) {
1422
- this.errors.push((0, errors_1.incompatibleExtensionError)(extensionTypeName, baseType.kind, extensionContainer.kind));
636
+ if (!(0, utils_1.areBaseAndExtensionKindsCompatible)(parentDefinitionData.kind, parentExtensionData.kind, extensionTypeName)) {
637
+ this.errors.push((0, errors_1.incompatibleExtensionError)(extensionTypeName, parentDefinitionData.kind, parentExtensionData.kind));
1423
638
  continue;
1424
639
  }
1425
- switch (baseType.kind) {
640
+ switch (parentDefinitionData.kind) {
1426
641
  case graphql_1.Kind.ENUM_TYPE_DEFINITION:
1427
- const enumExtension = extensionContainer;
1428
- for (const [valueName, enumValueDefinitionNode] of enumExtension.values) {
1429
- if (!baseType.values.has(valueName)) {
1430
- baseType.values.set(valueName, enumValueDefinitionNode);
642
+ const enumExtensionData = parentExtensionData;
643
+ for (const [valueName, enumValueDefinitionNode] of enumExtensionData.enumValueDataByValueName) {
644
+ if (!parentDefinitionData.enumValueDataByValueName.has(valueName)) {
645
+ parentDefinitionData.enumValueDataByValueName.set(valueName, enumValueDefinitionNode);
1431
646
  continue;
1432
647
  }
1433
648
  this.errors.push((0, errors_1.duplicateEnumValueDefinitionError)(valueName, extensionTypeName));
1434
649
  }
1435
- definitions.push((0, utils_2.enumContainerToNode)(this, baseType, enumExtension));
650
+ definitions.push((0, utils_4.getEnumNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName, enumExtensionData));
1436
651
  break;
1437
652
  case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
1438
- const inputExtension = extensionContainer;
1439
- for (const [fieldName, inputValueDefinitionNode] of inputExtension.fields) {
1440
- if (!baseType.fields.has(fieldName)) {
1441
- baseType.fields.set(fieldName, inputValueDefinitionNode);
653
+ const inputObjectExtensionData = parentExtensionData;
654
+ for (const [fieldName, inputValueDefinitionNode] of inputObjectExtensionData.inputValueDataByValueName) {
655
+ if (!parentDefinitionData.inputValueDataByValueName.has(fieldName)) {
656
+ parentDefinitionData.inputValueDataByValueName.set(fieldName, inputValueDefinitionNode);
1442
657
  continue;
1443
658
  }
1444
659
  this.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, extensionTypeName));
1445
660
  }
1446
- definitions.push((0, utils_2.inputObjectContainerToNode)(this, baseType, inputExtension));
661
+ definitions.push((0, utils_4.getInputObjectNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName, inputObjectExtensionData));
1447
662
  break;
1448
663
  case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
1449
664
  // intentional fallthrough
1450
665
  case graphql_1.Kind.OBJECT_TYPE_DEFINITION:
1451
- const objectLikeExtension = extensionContainer;
666
+ const extensionWithFieldsData = parentExtensionData;
1452
667
  const operationTypeNode = this.operationTypeNames.get(extensionTypeName);
1453
668
  if (operationTypeNode) {
1454
- objectLikeExtension.fields.delete(string_constants_1.SERVICE_FIELD);
1455
- objectLikeExtension.fields.delete(string_constants_1.ENTITIES_FIELD);
669
+ extensionWithFieldsData.fieldDataByFieldName.delete(string_constants_1.SERVICE_FIELD);
670
+ extensionWithFieldsData.fieldDataByFieldName.delete(string_constants_1.ENTITIES_FIELD);
1456
671
  }
1457
- for (const [fieldName, fieldContainer] of objectLikeExtension.fields) {
1458
- if (fieldContainer.arguments.size > 0) {
672
+ for (const [fieldName, fieldData] of extensionWithFieldsData.fieldDataByFieldName) {
673
+ if (fieldData.argumentDataByArgumentName.size > 0) {
1459
674
  // Arguments can only be fully validated once all parents types are known
1460
- this.validateArguments(fieldContainer, `${extensionTypeName}.${fieldName}`);
675
+ this.validateArguments(fieldData, `${extensionTypeName}.${fieldName}`);
1461
676
  }
1462
- if (baseType.fields.has(fieldName)) {
677
+ if (parentDefinitionData.fieldDataByFieldName.has(fieldName)) {
1463
678
  this.errors.push((0, errors_1.duplicateFieldDefinitionError)(fieldName, extensionTypeName));
1464
679
  continue;
1465
680
  }
1466
- baseType.fields.set(fieldName, fieldContainer);
1467
- if (!fieldContainer.arguments.has(string_constants_1.EXTERNAL)) {
681
+ parentDefinitionData.fieldDataByFieldName.set(fieldName, fieldData);
682
+ if (!fieldData.argumentDataByArgumentName.has(string_constants_1.EXTERNAL)) {
1468
683
  configurationData.fieldNames.add(fieldName);
1469
684
  }
1470
685
  }
1471
- this.mergeUniqueInterfaces(objectLikeExtension.interfaces, baseType.interfaces, extensionTypeName);
1472
- this.validateInterfaceImplementations(baseType);
1473
- definitions.push((0, utils_2.objectLikeContainerToNode)(this, baseType, objectLikeExtension));
686
+ this.mergeUniqueInterfaces(extensionWithFieldsData.implementedInterfaceTypeNames, parentDefinitionData.implementedInterfaceTypeNames, extensionTypeName);
687
+ this.validateInterfaceImplementations(parentDefinitionData);
688
+ definitions.push((0, utils_4.getParentWithFieldsNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName, extensionWithFieldsData));
1474
689
  // Interfaces and objects must define at least one field
1475
- if (baseType.fields.size < 1 && !(0, utils_2.isNodeQuery)(extensionTypeName, operationTypeNode)) {
1476
- this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(baseType.kind), extensionTypeName));
690
+ if (parentDefinitionData.fieldDataByFieldName.size < 1 &&
691
+ !(0, utils_2.isNodeQuery)(extensionTypeName, operationTypeNode)) {
692
+ this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(parentDefinitionData.kind), extensionTypeName));
1477
693
  }
1478
694
  // Add the non-external base type field names to the configuration data
1479
- (0, utils_2.addNonExternalFieldsToSet)(baseType.fields, configurationData.fieldNames);
695
+ (0, utils_2.addNonExternalFieldsToSet)(parentDefinitionData.fieldDataByFieldName, configurationData.fieldNames);
1480
696
  break;
1481
697
  case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
1482
- definitions.push((0, utils_2.scalarContainerToNode)(this, baseType, extensionContainer));
698
+ definitions.push((0, utils_4.getScalarNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, parentExtensionData));
1483
699
  break;
1484
700
  case graphql_1.Kind.UNION_TYPE_DEFINITION:
1485
- const unionExtension = extensionContainer;
1486
- definitions.push((0, utils_2.unionContainerToNode)(this, baseType, unionExtension));
701
+ definitions.push((0, utils_4.getUnionNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, parentExtensionData));
1487
702
  break;
1488
703
  default:
1489
704
  throw (0, errors_1.unexpectedKindFatalError)(extensionTypeName);
@@ -1491,16 +706,16 @@ class NormalizationFactory {
1491
706
  // At this point, the base type has been dealt with, so it doesn't need to be dealt with again
1492
707
  parentsToIgnore.add(extensionTypeName);
1493
708
  }
1494
- for (const [parentTypeName, parentContainer] of this.parentContainerByTypeName) {
709
+ for (const [parentTypeName, parentDefinitionData] of this.parentDefinitionDataByTypeName) {
1495
710
  if (parentsToIgnore.has(parentTypeName)) {
1496
711
  continue;
1497
712
  }
1498
- switch (parentContainer.kind) {
713
+ switch (parentDefinitionData.kind) {
1499
714
  case graphql_1.Kind.ENUM_TYPE_DEFINITION:
1500
- definitions.push((0, utils_2.enumContainerToNode)(this, parentContainer));
715
+ definitions.push((0, utils_4.getEnumNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
1501
716
  break;
1502
717
  case graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION:
1503
- definitions.push((0, utils_2.inputObjectContainerToNode)(this, parentContainer));
718
+ definitions.push((0, utils_4.getInputObjectNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
1504
719
  break;
1505
720
  case graphql_1.Kind.INTERFACE_TYPE_DEFINITION:
1506
721
  // intentional fallthrough
@@ -1508,15 +723,15 @@ class NormalizationFactory {
1508
723
  const isEntity = this.entityContainerByTypeName.has(parentTypeName);
1509
724
  const operationTypeNode = this.operationTypeNames.get(parentTypeName);
1510
725
  if (operationTypeNode) {
1511
- parentContainer.fields.delete(string_constants_1.SERVICE_FIELD);
1512
- parentContainer.fields.delete(string_constants_1.ENTITIES_FIELD);
726
+ parentDefinitionData.fieldDataByFieldName.delete(string_constants_1.SERVICE_FIELD);
727
+ parentDefinitionData.fieldDataByFieldName.delete(string_constants_1.ENTITIES_FIELD);
1513
728
  }
1514
729
  if (this.parentsWithChildArguments.has(parentTypeName)) {
1515
- if (parentContainer.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
1516
- parentContainer.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
730
+ if (parentDefinitionData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
731
+ parentDefinitionData.kind !== graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
1517
732
  continue;
1518
733
  }
1519
- for (const [fieldName, fieldContainer] of parentContainer.fields) {
734
+ for (const [fieldName, fieldContainer] of parentDefinitionData.fieldDataByFieldName) {
1520
735
  // Arguments can only be fully validated once all parents types are known
1521
736
  this.validateArguments(fieldContainer, `${parentTypeName}.${fieldName}`);
1522
737
  }
@@ -1538,19 +753,19 @@ class NormalizationFactory {
1538
753
  configurationData.events = events;
1539
754
  }
1540
755
  this.configurationDataMap.set(parentTypeName, configurationData);
1541
- (0, utils_2.addNonExternalFieldsToSet)(parentContainer.fields, configurationData.fieldNames);
1542
- this.validateInterfaceImplementations(parentContainer);
1543
- definitions.push((0, utils_2.objectLikeContainerToNode)(this, parentContainer));
756
+ (0, utils_2.addNonExternalFieldsToSet)(parentDefinitionData.fieldDataByFieldName, configurationData.fieldNames);
757
+ this.validateInterfaceImplementations(parentDefinitionData);
758
+ definitions.push((0, utils_4.getParentWithFieldsNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName, this.authorizationDataByParentTypeName));
1544
759
  // interfaces and objects must define at least one field
1545
- if (parentContainer.fields.size < 1 && !(0, utils_2.isNodeQuery)(parentTypeName, operationTypeNode)) {
1546
- this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(parentContainer.kind), parentTypeName));
760
+ if (parentDefinitionData.fieldDataByFieldName.size < 1 && !(0, utils_2.isNodeQuery)(parentTypeName, operationTypeNode)) {
761
+ this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_3.kindToTypeString)(parentDefinitionData.kind), parentTypeName));
1547
762
  }
1548
763
  break;
1549
764
  case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
1550
- definitions.push((0, utils_2.scalarContainerToNode)(this, parentContainer));
765
+ definitions.push((0, utils_4.getScalarNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName));
1551
766
  break;
1552
767
  case graphql_1.Kind.UNION_TYPE_DEFINITION:
1553
- definitions.push((0, utils_2.unionContainerToNode)(this, parentContainer));
768
+ definitions.push((0, utils_4.getUnionNodeByData)(parentDefinitionData, this.errors, this.directiveDefinitionByDirectiveName));
1554
769
  break;
1555
770
  default:
1556
771
  throw (0, errors_1.unexpectedKindFatalError)(parentTypeName);
@@ -1564,12 +779,13 @@ class NormalizationFactory {
1564
779
  const operationTypeName = node ? (0, type_merging_1.getNamedTypeForChild)(`schema.${operationType}`, node.type) : defaultTypeName;
1565
780
  // If a custom type is used, the default type should not be defined
1566
781
  if (operationTypeName !== defaultTypeName &&
1567
- (this.parentContainerByTypeName.has(defaultTypeName) || this.extensionContainerByTypeName.has(defaultTypeName))) {
782
+ (this.parentDefinitionDataByTypeName.has(defaultTypeName) ||
783
+ this.parentExtensionDataByTypeName.has(defaultTypeName))) {
1568
784
  this.errors.push((0, errors_1.invalidRootTypeDefinitionError)(operationType, operationTypeName, defaultTypeName));
1569
785
  continue;
1570
786
  }
1571
- const object = this.parentContainerByTypeName.get(operationTypeName);
1572
- const extension = this.extensionContainerByTypeName.get(operationTypeName);
787
+ const object = this.parentDefinitionDataByTypeName.get(operationTypeName);
788
+ const extension = this.parentExtensionDataByTypeName.get(operationTypeName);
1573
789
  // Node is truthy if an operation type was explicitly declared
1574
790
  if (node) {
1575
791
  // If the type is not defined in the schema, it's always an error
@@ -1599,12 +815,11 @@ class NormalizationFactory {
1599
815
  }
1600
816
  // Root types fields whose response type is an extension orphan could be valid through a federated graph
1601
817
  // However, the field would have to be shareable to ever be valid TODO
1602
- for (const fieldContainer of container.fields.values()) {
1603
- const fieldName = fieldContainer.name;
818
+ for (const [fieldName, fieldData] of container.fieldDataByFieldName) {
1604
819
  const fieldPath = `${operationTypeName}.${fieldName}`;
1605
- const fieldTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, fieldContainer.node.type);
820
+ const fieldTypeName = (0, type_merging_1.getNamedTypeForChild)(fieldPath, fieldData.node.type);
1606
821
  if (!constants_1.BASE_SCALARS.has(fieldTypeName) &&
1607
- !this.parentContainerByTypeName.has(fieldTypeName) &&
822
+ !this.parentDefinitionDataByTypeName.has(fieldTypeName) &&
1608
823
  !validExtensionOrphans.has(fieldTypeName)) {
1609
824
  this.errors.push((0, errors_1.undefinedTypeError)(fieldTypeName));
1610
825
  }
@@ -1612,17 +827,18 @@ class NormalizationFactory {
1612
827
  }
1613
828
  }
1614
829
  for (const referencedTypeName of this.referencedTypeNames) {
1615
- if (this.parentContainerByTypeName.has(referencedTypeName) ||
830
+ if (this.parentDefinitionDataByTypeName.has(referencedTypeName) ||
1616
831
  this.entityContainerByTypeName.has(referencedTypeName)) {
1617
832
  continue;
1618
833
  }
1619
- const extension = this.extensionContainerByTypeName.get(referencedTypeName);
834
+ const extension = this.parentExtensionDataByTypeName.get(referencedTypeName);
1620
835
  if (!extension || extension.kind !== graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
1621
836
  this.errors.push((0, errors_1.undefinedTypeError)(referencedTypeName));
1622
837
  }
1623
838
  }
1624
839
  for (const [parentTypeName, fieldSetContainers] of this.fieldSetContainerByTypeName) {
1625
- const parentContainer = this.parentContainerByTypeName.get(parentTypeName) || this.extensionContainerByTypeName.get(parentTypeName);
840
+ const parentContainer = this.parentDefinitionDataByTypeName.get(parentTypeName) ||
841
+ this.parentExtensionDataByTypeName.get(parentTypeName);
1626
842
  if (!parentContainer ||
1627
843
  (parentContainer.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
1628
844
  parentContainer.kind != graphql_1.Kind.OBJECT_TYPE_EXTENSION &&
@@ -1634,37 +850,6 @@ class NormalizationFactory {
1634
850
  // this is where keys, provides, and requires are added to the ConfigurationData
1635
851
  (0, utils_2.validateAndAddDirectivesWithFieldSetToConfigurationData)(this, parentContainer, fieldSetContainers);
1636
852
  }
1637
- (0, subgraph_1.walkSubgraphToApplyFieldAuthorization)(factory, document);
1638
- for (const interfaceTypeName of this.interfaceTypeNamesWithAuthorizationDirectives) {
1639
- const interfaceAuthorizationData = factory.authorizationDataByParentTypeName.get(interfaceTypeName);
1640
- if (!interfaceAuthorizationData) {
1641
- continue;
1642
- }
1643
- const concreteTypeNames = factory.abstractToConcreteTypeNames.get(interfaceTypeName);
1644
- for (const concreteTypeName of concreteTypeNames || []) {
1645
- const concreteAuthorizationData = (0, utils_3.getValueOrDefault)(factory.authorizationDataByParentTypeName, concreteTypeName, () => (0, utils_3.newAuthorizationData)(concreteTypeName));
1646
- for (const [fieldName, interfaceFieldAuthorizationData,] of interfaceAuthorizationData.fieldAuthorizationDataByFieldName) {
1647
- if (!(0, utils_3.upsertFieldAuthorizationData)(concreteAuthorizationData.fieldAuthorizationDataByFieldName, interfaceFieldAuthorizationData)) {
1648
- this.invalidOrScopesHostPaths.add(`${concreteTypeName}.${fieldName}`);
1649
- }
1650
- }
1651
- }
1652
- }
1653
- // Apply inherited leaf authorization that was not applied to interface fields of that type earlier
1654
- for (const [typeName, fieldAuthorizationDatas] of this.heirFieldAuthorizationDataByTypeName) {
1655
- const authorizationData = this.authorizationDataByParentTypeName.get(typeName);
1656
- if (!authorizationData) {
1657
- continue;
1658
- }
1659
- for (const fieldAuthorizationData of fieldAuthorizationDatas) {
1660
- if (!(0, utils_3.mergeAuthorizationDataByAND)(authorizationData, fieldAuthorizationData)) {
1661
- this.invalidOrScopesHostPaths.add(`${typeName}.${fieldAuthorizationData.fieldName}`);
1662
- }
1663
- }
1664
- }
1665
- if (this.invalidOrScopesHostPaths.size > 0) {
1666
- this.errors.push((0, errors_1.orScopesLimitError)(utils_3.maxOrScopes, [...this.invalidOrScopesHostPaths]));
1667
- }
1668
853
  if (this.errors.length > 0) {
1669
854
  return { errors: this.errors };
1670
855
  }
@@ -1680,12 +865,12 @@ class NormalizationFactory {
1680
865
  configurationDataMap: this.configurationDataMap,
1681
866
  entityContainerByTypeName: this.entityContainerByTypeName,
1682
867
  entityInterfaces: this.entityInterfaces,
1683
- extensionContainerByTypeName: this.extensionContainerByTypeName,
868
+ parentExtensionDataByTypeName: this.parentExtensionDataByTypeName,
1684
869
  isVersionTwo: this.isSubgraphVersionTwo,
1685
870
  keyFieldNamesByParentTypeName: this.keyFieldNamesByParentTypeName,
1686
871
  operationTypes: this.operationTypeNames,
1687
872
  overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
1688
- parentContainerByTypeName: this.parentContainerByTypeName,
873
+ parentDataByTypeName: this.parentDefinitionDataByTypeName,
1689
874
  subgraphAST: newAST,
1690
875
  subgraphString: (0, graphql_1.print)(newAST),
1691
876
  schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { assumeValid: true }),
@@ -1701,7 +886,7 @@ function batchNormalize(subgraphs) {
1701
886
  const allOverridesByTargetSubgraphName = new Map();
1702
887
  const overrideSourceSubgraphNamesByFieldPath = new Map();
1703
888
  const duplicateOverriddenFieldPaths = new Set();
1704
- const parentContainerMapsBySubgraphName = new Map();
889
+ const parentDefinitionDataMapsBySubgraphName = new Map();
1705
890
  const subgraphNames = new Set();
1706
891
  const nonUniqueSubgraphNames = new Set();
1707
892
  const invalidNameErrorMessages = [];
@@ -1729,7 +914,7 @@ function batchNormalize(subgraphs) {
1729
914
  validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
1730
915
  continue;
1731
916
  }
1732
- parentContainerMapsBySubgraphName.set(subgraphName, normalizationResult.parentContainerByTypeName);
917
+ parentDefinitionDataMapsBySubgraphName.set(subgraphName, normalizationResult.parentDataByTypeName);
1733
918
  for (const authorizationData of normalizationResult.authorizationDataByParentTypeName.values()) {
1734
919
  (0, utils_3.upsertAuthorizationData)(authorizationDataByParentTypeName, authorizationData, invalidOrScopesHostPaths);
1735
920
  }
@@ -1741,13 +926,13 @@ function batchNormalize(subgraphs) {
1741
926
  configurationDataMap: normalizationResult.configurationDataMap,
1742
927
  definitions: normalizationResult.subgraphAST,
1743
928
  entityInterfaces: normalizationResult.entityInterfaces,
1744
- extensionContainerByTypeName: normalizationResult.extensionContainerByTypeName,
929
+ parentExtensionDataByTypeName: normalizationResult.parentExtensionDataByTypeName,
1745
930
  keyFieldNamesByParentTypeName: normalizationResult.keyFieldNamesByParentTypeName,
1746
931
  isVersionTwo: normalizationResult.isVersionTwo,
1747
932
  name: subgraphName,
1748
933
  operationTypes: normalizationResult.operationTypes,
1749
934
  overriddenFieldNamesByParentTypeName: new Map(),
1750
- parentContainerByTypeName: normalizationResult.parentContainerByTypeName,
935
+ parentDataByTypeName: normalizationResult.parentDataByTypeName,
1751
936
  schema: normalizationResult.schema,
1752
937
  url: subgraph.url,
1753
938
  });