@wundergraph/composition 0.57.0 → 0.58.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 (126) hide show
  1. package/dist/{v1/normalization → directive-definition-data}/directive-definition-data.d.ts +2 -2
  2. package/dist/{v1/normalization → directive-definition-data}/directive-definition-data.js +308 -280
  3. package/dist/directive-definition-data/directive-definition-data.js.map +1 -0
  4. package/dist/directive-definition-data/types/params.d.ts +48 -0
  5. package/dist/directive-definition-data/types/params.js.map +1 -0
  6. package/dist/directive-definition-data/types/types.d.ts +39 -0
  7. package/dist/directive-definition-data/types/types.js.map +1 -0
  8. package/dist/directive-definition-data/utils.d.ts +5 -0
  9. package/dist/directive-definition-data/utils.js +75 -0
  10. package/dist/directive-definition-data/utils.js.map +1 -0
  11. package/dist/errors/errors.d.ts +35 -9
  12. package/dist/errors/errors.js +141 -21
  13. package/dist/errors/errors.js.map +1 -1
  14. package/dist/errors/{types.d.ts → types/params.d.ts} +34 -6
  15. package/dist/{federation → errors/types}/params.js.map +1 -1
  16. package/dist/errors/types/types.d.ts +5 -0
  17. package/dist/{federation → errors/types}/types.js.map +1 -1
  18. package/dist/federation/federation.d.ts +2 -2
  19. package/dist/federation/{params.d.ts → types/params.d.ts} +4 -4
  20. package/dist/{v1/federation → federation/types}/params.js.map +1 -1
  21. package/dist/federation/{types.d.ts → types/types.d.ts} +17 -20
  22. package/dist/{errors → federation/types}/types.js.map +1 -1
  23. package/dist/index.d.ts +16 -7
  24. package/dist/index.js +16 -7
  25. package/dist/index.js.map +1 -1
  26. package/dist/normalization/normalization.d.ts +2 -3
  27. package/dist/normalization/normalization.js +0 -8
  28. package/dist/normalization/normalization.js.map +1 -1
  29. package/dist/normalization/types.d.ts +21 -18
  30. package/dist/router-configuration/types.d.ts +1 -0
  31. package/dist/schema-building/ast.d.ts +2 -10
  32. package/dist/schema-building/ast.js +35 -32
  33. package/dist/schema-building/ast.js.map +1 -1
  34. package/dist/schema-building/types/params.d.ts +54 -0
  35. package/dist/schema-building/types/params.js.map +1 -0
  36. package/dist/schema-building/types/results.d.ts +39 -0
  37. package/dist/schema-building/types/results.js +3 -0
  38. package/dist/schema-building/types/results.js.map +1 -0
  39. package/dist/schema-building/{types.d.ts → types/types.d.ts} +21 -41
  40. package/dist/schema-building/types/types.js.map +1 -0
  41. package/dist/schema-building/utils.d.ts +21 -13
  42. package/dist/schema-building/utils.js +257 -82
  43. package/dist/schema-building/utils.js.map +1 -1
  44. package/dist/subgraph/types/params.d.ts +6 -0
  45. package/dist/subgraph/types/params.js +3 -0
  46. package/dist/{schema-building → subgraph/types}/params.js.map +1 -1
  47. package/dist/subgraph/types.d.ts +6 -6
  48. package/dist/subgraph/utils.d.ts +3 -0
  49. package/dist/subgraph/utils.js +23 -0
  50. package/dist/subgraph/utils.js.map +1 -0
  51. package/dist/tsconfig.tsbuildinfo +1 -1
  52. package/dist/types/results.d.ts +14 -0
  53. package/dist/types/results.js +3 -0
  54. package/dist/types/results.js.map +1 -0
  55. package/dist/types/types.d.ts +2 -0
  56. package/dist/utils/composition-version.js +1 -1
  57. package/dist/utils/params.d.ts +4 -0
  58. package/dist/utils/string-constants.d.ts +2 -1
  59. package/dist/utils/string-constants.js +5 -4
  60. package/dist/utils/string-constants.js.map +1 -1
  61. package/dist/utils/utils.d.ts +2 -1
  62. package/dist/utils/utils.js +14 -0
  63. package/dist/utils/utils.js.map +1 -1
  64. package/dist/v1/constants/directive-definitions.js +3 -3
  65. package/dist/v1/constants/directive-definitions.js.map +1 -1
  66. package/dist/v1/constants/strings.d.ts +3 -1
  67. package/dist/v1/constants/strings.js +12 -2
  68. package/dist/v1/constants/strings.js.map +1 -1
  69. package/dist/v1/federation/federation-factory.d.ts +15 -16
  70. package/dist/v1/federation/federation-factory.js +344 -213
  71. package/dist/v1/federation/federation-factory.js.map +1 -1
  72. package/dist/v1/federation/{params.d.ts → types/params.d.ts} +16 -9
  73. package/dist/v1/federation/types/params.js +3 -0
  74. package/dist/v1/federation/types/params.js.map +1 -0
  75. package/dist/v1/federation/utils.d.ts +2 -2
  76. package/dist/v1/normalization/batch-normalization/batch-normalizer.d.ts +37 -0
  77. package/dist/v1/normalization/batch-normalization/batch-normalizer.js +245 -0
  78. package/dist/v1/normalization/batch-normalization/batch-normalizer.js.map +1 -0
  79. package/dist/v1/normalization/batch-normalization/types/params.d.ts +6 -0
  80. package/dist/v1/normalization/batch-normalization/types/params.js +3 -0
  81. package/dist/v1/normalization/batch-normalization/types/params.js.map +1 -0
  82. package/dist/v1/normalization/normalization-factory.d.ts +24 -19
  83. package/dist/v1/normalization/normalization-factory.js +263 -445
  84. package/dist/v1/normalization/normalization-factory.js.map +1 -1
  85. package/dist/v1/normalization/{params.d.ts → types/params.d.ts} +6 -12
  86. package/dist/v1/normalization/types/params.js +3 -0
  87. package/dist/v1/normalization/types/params.js.map +1 -0
  88. package/dist/v1/normalization/types/results.d.ts +26 -0
  89. package/dist/v1/normalization/types/results.js +3 -0
  90. package/dist/v1/normalization/types/results.js.map +1 -0
  91. package/dist/v1/normalization/types/types.d.ts +103 -0
  92. package/dist/v1/normalization/types/types.js +3 -0
  93. package/dist/v1/normalization/types/types.js.map +1 -0
  94. package/dist/v1/normalization/utils.d.ts +9 -2
  95. package/dist/v1/normalization/utils.js +308 -2
  96. package/dist/v1/normalization/utils.js.map +1 -1
  97. package/dist/v1/normalization/walkers.js +2 -1
  98. package/dist/v1/normalization/walkers.js.map +1 -1
  99. package/dist/v1/schema-building/type-merging.d.ts +1 -1
  100. package/dist/v1/utils/utils.d.ts +2 -3
  101. package/dist/v1/utils/utils.js +0 -17
  102. package/dist/v1/utils/utils.js.map +1 -1
  103. package/dist/v1/warnings/params.d.ts +6 -1
  104. package/dist/v1/warnings/warnings.d.ts +4 -1
  105. package/dist/v1/warnings/warnings.js +23 -0
  106. package/dist/v1/warnings/warnings.js.map +1 -1
  107. package/dist/validation/types/params.d.ts +22 -0
  108. package/dist/validation/types/params.js +3 -0
  109. package/dist/{v1/normalization → validation/types}/params.js.map +1 -1
  110. package/dist/validation/validation.d.ts +5 -0
  111. package/dist/validation/validation.js +213 -0
  112. package/dist/validation/validation.js.map +1 -0
  113. package/package.json +5 -4
  114. package/dist/schema-building/params.d.ts +0 -8
  115. package/dist/schema-building/types.js.map +0 -1
  116. package/dist/v1/normalization/directive-definition-data.js.map +0 -1
  117. package/dist/v1/normalization/types.d.ts +0 -79
  118. package/dist/v1/normalization/types.js.map +0 -1
  119. /package/dist/{federation → directive-definition-data/types}/params.js +0 -0
  120. /package/dist/{errors → directive-definition-data/types}/types.js +0 -0
  121. /package/dist/{schema-building → errors/types}/params.js +0 -0
  122. /package/dist/{federation → errors/types}/types.js +0 -0
  123. /package/dist/{v1/federation → federation/types}/params.js +0 -0
  124. /package/dist/{v1/normalization → federation/types}/types.js +0 -0
  125. /package/dist/{v1/normalization → schema-building/types}/params.js +0 -0
  126. /package/dist/schema-building/{types.js → types/types.js} +0 -0
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NormalizationFactory = void 0;
4
4
  exports.normalizeSubgraphFromString = normalizeSubgraphFromString;
5
5
  exports.normalizeSubgraph = normalizeSubgraph;
6
- exports.batchNormalize = batchNormalize;
7
6
  const graphql_1 = require("graphql");
8
7
  const utils_1 = require("../../ast/utils");
9
8
  const utils_2 = require("./utils");
@@ -13,10 +12,9 @@ const errors_1 = require("../../errors/errors");
13
12
  const strings_1 = require("../constants/strings");
14
13
  const buildASTSchema_1 = require("../../buildASTSchema/buildASTSchema");
15
14
  const merge_1 = require("@graphql-tools/merge");
16
- const subgraph_1 = require("../subgraph/subgraph");
17
15
  const warnings_1 = require("../warnings/warnings");
18
16
  const walkers_1 = require("./walkers");
19
- const types_1 = require("../../schema-building/types");
17
+ const types_1 = require("../../schema-building/types/types");
20
18
  const utils_4 = require("../../schema-building/utils");
21
19
  const ast_1 = require("../../schema-building/ast");
22
20
  const graph_1 = require("../../resolvability-graph/graph");
@@ -26,6 +24,8 @@ const integer_constants_1 = require("../../utils/integer-constants");
26
24
  const utils_5 = require("../../utils/utils");
27
25
  const utils_6 = require("../../router-configuration/utils");
28
26
  const non_directive_definitions_1 = require("../constants/non-directive-definitions");
27
+ const validation_1 = require("../../validation/validation");
28
+ const utils_7 = require("../../directive-definition-data/utils");
29
29
  function normalizeSubgraphFromString({ noLocation, options, sdlString, }) {
30
30
  const { error, documentNode } = (0, utils_1.safeParse)(sdlString, noLocation);
31
31
  if (error || !documentNode) {
@@ -64,7 +64,9 @@ class NormalizationFactory {
64
64
  entityDataByTypeName = new Map();
65
65
  entityInterfaceDataByTypeName = new Map();
66
66
  eventsConfigurations = new Map();
67
+ federatedDirectiveDataByName = new Map();
67
68
  fieldSetDataByTypeName = new Map();
69
+ importDataByDirectiveName = new Map();
68
70
  interfaceImplementationTypeNamesByInterfaceTypeName = new Map();
69
71
  internalGraph;
70
72
  invalidConfigureDescriptionNodeDatas = [];
@@ -85,12 +87,12 @@ class NormalizationFactory {
85
87
  operationTypeNodeByTypeName = new Map();
86
88
  originalParentTypeName = '';
87
89
  originalTypeNameByRenamedTypeName = new Map();
88
- overridesByTargetSubgraphName = new Map();
90
+ overriddenFieldNamesByTypeNameByTargetSubgraphName = new Map();
89
91
  parentDefinitionDataByTypeName = new Map();
90
- schemaData;
91
92
  referencedDirectiveNames = new Set();
92
93
  referencedTypeNames = new Set();
93
94
  renamedParentTypeName = '';
95
+ schemaData;
94
96
  subgraphName;
95
97
  unvalidatedExternalFieldCoords = new Set();
96
98
  usesEdfsNatsStreamConfiguration = false;
@@ -107,27 +109,6 @@ class NormalizationFactory {
107
109
  operationTypes: new Map(),
108
110
  };
109
111
  }
110
- sanitizeDefaultValue({ data, namedTypeData, node }) {
111
- if (!data.defaultValue) {
112
- return;
113
- }
114
- if (!(0, utils_4.isEnumData)(namedTypeData)) {
115
- return;
116
- }
117
- data.defaultValue = (0, graphql_1.visit)(data.defaultValue, {
118
- StringValue: {
119
- enter(node) {
120
- return {
121
- kind: graphql_1.Kind.ENUM,
122
- value: node.value,
123
- };
124
- },
125
- },
126
- });
127
- if (node) {
128
- node.defaultValue = data.defaultValue;
129
- }
130
- }
131
112
  validateArguments(fieldData, parentKind) {
132
113
  for (const argumentData of fieldData.argumentDataByName.values()) {
133
114
  const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(argumentData.type);
@@ -142,7 +123,7 @@ class NormalizationFactory {
142
123
  }
143
124
  if ((0, utils_4.isInputNodeKind)(namedTypeData.kind)) {
144
125
  argumentData.namedTypeKind = namedTypeData.kind;
145
- this.sanitizeDefaultValue({ data: argumentData, namedTypeData, node: argumentData.node });
126
+ (0, utils_4.sanitizeDefaultValue)({ data: argumentData, namedTypeData, node: argumentData.node });
146
127
  continue;
147
128
  }
148
129
  this.errors.push((0, errors_1.invalidNamedTypeError)({
@@ -155,89 +136,6 @@ class NormalizationFactory {
155
136
  isTypeNameRootType(typeName) {
156
137
  return string_constants_1.ROOT_TYPE_NAMES.has(typeName) || this.operationTypeNodeByTypeName.has(typeName);
157
138
  }
158
- isArgumentValueValid(typeNode, argumentValue) {
159
- if (argumentValue.kind === graphql_1.Kind.NULL) {
160
- return typeNode.kind !== graphql_1.Kind.NON_NULL_TYPE;
161
- }
162
- switch (typeNode.kind) {
163
- case graphql_1.Kind.LIST_TYPE: {
164
- if (argumentValue.kind !== graphql_1.Kind.LIST) {
165
- // This handles List coercion
166
- return this.isArgumentValueValid((0, ast_1.getNamedTypeNode)(typeNode.type), argumentValue);
167
- }
168
- for (const value of argumentValue.values) {
169
- if (!this.isArgumentValueValid(typeNode.type, value)) {
170
- return false;
171
- }
172
- }
173
- return true;
174
- }
175
- case graphql_1.Kind.NAMED_TYPE: {
176
- switch (typeNode.name.value) {
177
- case string_constants_1.BOOLEAN_SCALAR: {
178
- return argumentValue.kind === graphql_1.Kind.BOOLEAN;
179
- }
180
- case string_constants_1.FLOAT_SCALAR: {
181
- return argumentValue.kind === graphql_1.Kind.FLOAT || argumentValue.kind === graphql_1.Kind.INT;
182
- }
183
- case string_constants_1.ID_SCALAR: {
184
- return argumentValue.kind === graphql_1.Kind.STRING || argumentValue.kind === graphql_1.Kind.INT;
185
- }
186
- case string_constants_1.INT_SCALAR: {
187
- return argumentValue.kind === graphql_1.Kind.INT;
188
- }
189
- case string_constants_1.FIELD_SET_SCALAR:
190
- // intentional fallthrough
191
- case string_constants_1.SCOPE_SCALAR:
192
- // intentional fallthrough
193
- case string_constants_1.STRING_SCALAR: {
194
- return argumentValue.kind === graphql_1.Kind.STRING;
195
- }
196
- case string_constants_1.LINK_IMPORT: {
197
- return true;
198
- }
199
- case string_constants_1.LINK_PURPOSE: {
200
- if (argumentValue.kind !== graphql_1.Kind.ENUM) {
201
- return false;
202
- }
203
- return argumentValue.value === string_constants_1.SECURITY || argumentValue.value === string_constants_1.EXECUTION;
204
- }
205
- case string_constants_1.SUBSCRIPTION_FIELD_CONDITION:
206
- // intentional fallthrough
207
- case string_constants_1.SUBSCRIPTION_FILTER_CONDITION:
208
- return argumentValue.kind === graphql_1.Kind.OBJECT;
209
- default: {
210
- const parentData = this.parentDefinitionDataByTypeName.get(typeNode.name.value);
211
- if (!parentData) {
212
- return false;
213
- }
214
- if (parentData.kind === graphql_1.Kind.SCALAR_TYPE_DEFINITION) {
215
- // For now, allow custom scalars to be any value kind.
216
- return true;
217
- }
218
- if (parentData.kind === graphql_1.Kind.ENUM_TYPE_DEFINITION) {
219
- if (argumentValue.kind !== graphql_1.Kind.ENUM && argumentValue.kind !== graphql_1.Kind.STRING) {
220
- return false;
221
- }
222
- const enumValue = parentData.enumValueDataByName.get(argumentValue.value);
223
- if (!enumValue) {
224
- return false;
225
- }
226
- return !enumValue.directivesByName.has(string_constants_1.INACCESSIBLE);
227
- }
228
- if (parentData.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION) {
229
- return false;
230
- }
231
- // TODO deep comparison
232
- return argumentValue.kind === graphql_1.Kind.OBJECT;
233
- }
234
- }
235
- }
236
- default: {
237
- return this.isArgumentValueValid(typeNode.type, argumentValue);
238
- }
239
- }
240
- }
241
139
  handleFieldInheritableDirectives({ directivesByName, fieldName, inheritedDirectiveNames, parentData, }) {
242
140
  if (this.doesParentRequireFetchReasons && !directivesByName.has(string_constants_1.REQUIRE_FETCH_REASONS)) {
243
141
  directivesByName.set(string_constants_1.REQUIRE_FETCH_REASONS, [(0, utils_5.generateSimpleDirective)(string_constants_1.REQUIRE_FETCH_REASONS)]);
@@ -269,8 +167,8 @@ class NormalizationFactory {
269
167
  const isObjectKind = (0, utils_3.isObjectNodeKind)(node.kind);
270
168
  for (const directiveNode of node.directives) {
271
169
  const directiveName = directiveNode.name.value;
272
- // Don't create pointless repetitions of @shareable
273
170
  if (directiveName === string_constants_1.SHAREABLE) {
171
+ // @shareable need only be propagated once
274
172
  (0, utils_5.getValueOrDefault)(directivesByName, directiveName, () => [directiveNode]);
275
173
  }
276
174
  else {
@@ -305,7 +203,10 @@ class NormalizationFactory {
305
203
  if (isAuthenticated) {
306
204
  this.handleAuthenticatedDirective(data, parentTypeName);
307
205
  }
308
- if (isSemanticNonNull && isField) {
206
+ if (!isField) {
207
+ return errorMessages;
208
+ }
209
+ if (isSemanticNonNull) {
309
210
  // The default argument for levels is [0], so a non-null wrapper is invalid.
310
211
  if ((0, utils_4.isTypeRequired)(data.type)) {
311
212
  errorMessages.push((0, errors_1.semanticNonNullLevelsNonNullErrorMessage)({
@@ -317,9 +218,12 @@ class NormalizationFactory {
317
218
  data.nullLevelsBySubgraphName.set(this.subgraphName, new Set([0]));
318
219
  }
319
220
  }
320
- if (isListSize && isField && !(0, utils_4.isTypeNodeListType)(data.type)) {
221
+ if (isListSize && !(0, utils_4.isTypeNodeListType)(data.type)) {
321
222
  errorMessages.push((0, errors_1.listSizeFieldMustReturnListOrUseSizedFieldsErrorMessage)(directiveCoords, (0, merge_1.printTypeNode)(data.type)));
322
223
  }
224
+ if (!isCost && !isListSize) {
225
+ this.recordDirectiveWeightOnField({ data: data, definitionData, directiveName, directiveNode });
226
+ }
323
227
  return errorMessages;
324
228
  }
325
229
  const definedArgumentNames = new Set();
@@ -333,13 +237,17 @@ class NormalizationFactory {
333
237
  continue;
334
238
  }
335
239
  definedArgumentNames.add(argumentName);
336
- const argumentData = definitionData.argumentTypeNodeByName.get(argumentName);
240
+ const argumentData = definitionData.argumentDataByName.get(argumentName);
337
241
  if (!argumentData) {
338
242
  unexpectedArgumentNames.add(argumentName);
339
243
  continue;
340
244
  }
341
- if (!this.isArgumentValueValid(argumentData.typeNode, argumentNode.value)) {
342
- errorMessages.push((0, errors_1.invalidArgumentValueErrorMessage)((0, graphql_1.print)(argumentNode.value), `@${directiveName}`, argumentName, (0, merge_1.printTypeNode)(argumentData.typeNode)));
245
+ if (!(0, validation_1.isArgumentValueValid)({
246
+ argumentValue: argumentNode.value,
247
+ parentDefinitionDataByTypeName: this.parentDefinitionDataByTypeName,
248
+ typeNode: argumentData.type,
249
+ })) {
250
+ errorMessages.push((0, errors_1.invalidArgumentValueErrorMessage)((0, graphql_1.print)(argumentNode.value), `@${directiveName}`, argumentName, (0, merge_1.printTypeNode)(argumentData.type)));
343
251
  continue;
344
252
  }
345
253
  /* Individual directives are handled in the loop because they validate a single argument, and duplicate
@@ -376,8 +284,13 @@ class NormalizationFactory {
376
284
  if (isCost) {
377
285
  this.handleCostDirective({ data, directiveCoords, directiveNode, errorMessages });
378
286
  }
379
- else if (isListSize && isField) {
380
- this.handleListSizeDirective({ data, directiveCoords, directiveNode, errorMessages });
287
+ else if (isField) {
288
+ if (isListSize) {
289
+ this.handleListSizeDirective({ data, directiveCoords, directiveNode, errorMessages });
290
+ }
291
+ else {
292
+ this.recordDirectiveWeightOnField({ data: data, definitionData, directiveName, directiveNode });
293
+ }
381
294
  }
382
295
  if (duplicateArgumentNames.size > 0) {
383
296
  errorMessages.push((0, errors_1.duplicateDirectiveArgumentDefinitionsErrorMessage)([...duplicateArgumentNames]));
@@ -404,6 +317,49 @@ class NormalizationFactory {
404
317
  }
405
318
  return errorMessages;
406
319
  }
320
+ handleComposeDirective(node) {
321
+ const argNode = node.arguments[0];
322
+ if (!argNode) {
323
+ return;
324
+ }
325
+ const rawValue = argNode.value.value;
326
+ if (!rawValue.startsWith(string_constants_1.LITERAL_AT)) {
327
+ this.errors.push((0, errors_1.noLeadingAtComposeDirectiveNameError)(rawValue));
328
+ return;
329
+ }
330
+ const directiveName = rawValue.substring(1);
331
+ if (constants_1.DIRECTIVE_DEFINITION_BY_NAME.has(directiveName)) {
332
+ if (directiveName === string_constants_1.ONE_OF) {
333
+ this.warnings.push((0, warnings_1.composedOneOfDirectiveWarning)(this.subgraphName));
334
+ }
335
+ else {
336
+ this.errors.push((0, errors_1.invalidComposeDirectiveNameError)(rawValue));
337
+ return;
338
+ }
339
+ }
340
+ const definitionData = this.directiveDefinitionDataByName.get(directiveName);
341
+ if (!definitionData) {
342
+ this.errors.push((0, errors_1.unknownComposeDirectiveNameError)(rawValue));
343
+ return;
344
+ }
345
+ const importData = this.importDataByDirectiveName.get(rawValue);
346
+ if (!importData) {
347
+ this.errors.push((0, errors_1.unimportedComposeDirectiveNameError)(rawValue));
348
+ return;
349
+ }
350
+ definitionData.majorVersion = importData.majorVersion;
351
+ definitionData.minorVersion = importData.minorVersion;
352
+ definitionData.isComposed = true;
353
+ this.federatedDirectiveDataByName.set(directiveName, definitionData);
354
+ }
355
+ handleExecutableDirectives() {
356
+ for (const [directiveName, definitionData] of this.directiveDefinitionDataByName) {
357
+ if (definitionData.isComposed || definitionData.executableLocations.size < 1) {
358
+ continue;
359
+ }
360
+ this.federatedDirectiveDataByName.set(directiveName, definitionData);
361
+ }
362
+ }
407
363
  validateDirectives(data, directiveCoords) {
408
364
  const undefinedDirectiveNames = new Set();
409
365
  for (const [directiveName, directiveNodes] of data.directivesByName) {
@@ -415,6 +371,9 @@ class NormalizationFactory {
415
371
  }
416
372
  continue;
417
373
  }
374
+ if (definitionData.isComposed) {
375
+ definitionData.isReferenced = true;
376
+ }
418
377
  const definitionErrorMessages = [];
419
378
  const directiveLocation = (0, utils_1.nodeKindToDirectiveLocation)(data.kind);
420
379
  if (!definitionData.locations.has(directiveLocation)) {
@@ -432,21 +391,22 @@ class NormalizationFactory {
432
391
  if (!argumentNode.defaultValue) {
433
392
  continue;
434
393
  }
435
- const argumentData = definitionData.argumentTypeNodeByName.get(argumentNode.name.value);
394
+ const argumentData = definitionData.argumentDataByName.get(argumentNode.name.value);
436
395
  if (!argumentData) {
437
396
  continue;
438
397
  }
439
- const namedTypeData = this.parentDefinitionDataByTypeName.get((0, ast_1.getTypeNodeNamedTypeName)(argumentData.typeNode));
398
+ const namedTypeData = this.parentDefinitionDataByTypeName.get((0, ast_1.getTypeNodeNamedTypeName)(argumentData.type));
440
399
  // Undefined types are handled elsewhere
441
400
  if (!namedTypeData) {
442
401
  continue;
443
402
  }
444
- this.sanitizeDefaultValue({ data: argumentData, namedTypeData, node: argumentNode });
403
+ (0, utils_4.sanitizeDefaultValue)({ data: argumentData, namedTypeData, node: argumentNode });
445
404
  }
446
405
  for (let i = 0; i < directiveNodes.length; i++) {
406
+ const directiveNode = directiveNodes[i];
447
407
  const errorMessages = this.validateDirective({
448
408
  data,
449
- directiveNode: directiveNodes[i],
409
+ directiveNode,
450
410
  definitionData,
451
411
  directiveCoords,
452
412
  errorMessages: i < 1 ? definitionErrorMessages : [],
@@ -544,14 +504,14 @@ class NormalizationFactory {
544
504
  for (const argument of directiveNode.arguments) {
545
505
  switch (argument.name.value) {
546
506
  case string_constants_1.PROPAGATE: {
547
- if (argument.value.kind != graphql_1.Kind.BOOLEAN) {
507
+ if (argument.value.kind !== graphql_1.Kind.BOOLEAN) {
548
508
  return;
549
509
  }
550
510
  configureDescriptionData.propagate = argument.value.value;
551
511
  break;
552
512
  }
553
513
  case string_constants_1.DESCRIPTION_OVERRIDE: {
554
- if (argument.value.kind != graphql_1.Kind.STRING) {
514
+ if (argument.value.kind !== graphql_1.Kind.STRING) {
555
515
  return;
556
516
  }
557
517
  configureDescriptionData.description = argument.value.value;
@@ -638,55 +598,12 @@ class NormalizationFactory {
638
598
  }
639
599
  return argumentDataByName;
640
600
  }
641
- addPersistedDirectiveDefinitionDataByNode(persistedDirectiveDefinitionDataByDirectiveName, node, executableLocations) {
642
- const name = node.name.value;
643
- const directiveName = `@${name}`;
601
+ extractDirectiveArgumentData({ argumentNodes, directiveName, errorMessages, }) {
644
602
  const argumentDataByName = new Map();
645
- for (const argumentNode of node.arguments || []) {
646
- this.addInputValueDataByNode({
647
- inputValueDataByName: argumentDataByName,
648
- isArgument: true,
649
- node: argumentNode,
650
- originalParentTypeName: directiveName,
651
- });
652
- }
653
- persistedDirectiveDefinitionDataByDirectiveName.set(name, {
654
- argumentDataByName: argumentDataByName,
655
- executableLocations,
656
- name,
657
- repeatable: node.repeatable,
658
- subgraphNames: new Set([this.subgraphName]),
659
- description: (0, utils_1.formatDescription)(node.description),
660
- });
661
- }
662
- extractDirectiveLocations(node, errorMessages) {
663
- const locations = new Set();
664
- const handledLocations = new Set();
665
- for (const locationNode of node.locations) {
666
- const locationName = locationNode.value;
667
- if (handledLocations.has(locationName)) {
668
- continue;
669
- }
670
- if (!string_constants_1.EXECUTABLE_DIRECTIVE_LOCATIONS.has(locationName) && !strings_1.TYPE_SYSTEM_DIRECTIVE_LOCATIONS.has(locationName)) {
671
- errorMessages.push((0, errors_1.invalidDirectiveDefinitionLocationErrorMessage)(locationName));
672
- handledLocations.add(locationName);
673
- continue;
674
- }
675
- if (locations.has(locationName)) {
676
- errorMessages.push((0, errors_1.duplicateDirectiveDefinitionLocationErrorMessage)(locationName));
677
- handledLocations.add(locationName);
678
- continue;
679
- }
680
- locations.add(locationName);
681
- }
682
- return locations;
683
- }
684
- extractArgumentData(argumentNodes, errorMessages) {
685
- const argumentTypeNodeByName = new Map();
686
603
  const optionalArgumentNames = new Set();
687
604
  const requiredArgumentNames = new Set();
688
605
  const output = {
689
- argumentTypeNodeByName,
606
+ argumentDataByName,
690
607
  optionalArgumentNames,
691
608
  requiredArgumentNames,
692
609
  };
@@ -694,23 +611,13 @@ class NormalizationFactory {
694
611
  return output;
695
612
  }
696
613
  const duplicateArgumentNames = new Set();
697
- for (const argumentNode of argumentNodes) {
698
- const name = argumentNode.name.value;
699
- if (argumentTypeNodeByName.has(name)) {
614
+ for (const node of argumentNodes) {
615
+ const name = node.name.value;
616
+ if (argumentDataByName.has(name)) {
700
617
  duplicateArgumentNames.add(name);
701
618
  continue;
702
619
  }
703
- if (argumentNode.defaultValue) {
704
- optionalArgumentNames.add(name);
705
- }
706
- if ((0, utils_4.isTypeRequired)(argumentNode.type) && !argumentNode.defaultValue) {
707
- requiredArgumentNames.add(name);
708
- }
709
- argumentTypeNodeByName.set(name, {
710
- name,
711
- typeNode: argumentNode.type,
712
- defaultValue: argumentNode.defaultValue,
713
- });
620
+ argumentDataByName.set(name, this.addDirectiveArgumentDataByNode({ directiveName, node, optionalArgumentNames, requiredArgumentNames }));
714
621
  }
715
622
  if (duplicateArgumentNames.size > 0) {
716
623
  errorMessages.push((0, errors_1.duplicateDirectiveDefinitionArgumentErrorMessage)([...duplicateArgumentNames]));
@@ -748,6 +655,35 @@ class NormalizationFactory {
748
655
  }
749
656
  }
750
657
  }
658
+ addDirectiveArgumentDataByNode({ directiveName, node, optionalArgumentNames, requiredArgumentNames, }) {
659
+ const name = node.name.value;
660
+ const parentName = `@${directiveName}`;
661
+ if (node.defaultValue && !(0, utils_4.areDefaultValuesCompatible)(node.type, node.defaultValue)) {
662
+ this.errors.push((0, errors_1.incompatibleInputValueDefaultValueTypeError)(`argument "${name}"`, parentName, (0, merge_1.printTypeNode)(node.type), (0, graphql_1.print)(node.defaultValue)));
663
+ }
664
+ const isRequired = (0, utils_4.isTypeRequired)(node.type);
665
+ if (node.defaultValue) {
666
+ optionalArgumentNames.add(name);
667
+ }
668
+ else if (isRequired) {
669
+ requiredArgumentNames.add(name);
670
+ }
671
+ const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(node.type);
672
+ const argumentData = (0, utils_7.newDirectiveArgumentData)({
673
+ name,
674
+ directive: `@${directiveName}`,
675
+ directivesByName: this.extractDirectives(node, new Map()),
676
+ defaultValue: node.defaultValue,
677
+ description: (0, utils_1.formatDescription)(node.description),
678
+ namedTypeKind: constants_1.BASE_SCALARS.has(namedTypeName) ? graphql_1.Kind.SCALAR_TYPE_DEFINITION : graphql_1.Kind.NULL,
679
+ node: (0, ast_1.getMutableInputValueNode)(node, parentName, this.errors),
680
+ requiredSubgraphNames: new Set(isRequired ? [this.subgraphName] : []),
681
+ subgraphNames: new Set([this.subgraphName]),
682
+ typeNode: (0, ast_1.getMutableTypeNode)(node.type, parentName, this.errors),
683
+ });
684
+ this.extractConfigureDescriptionsData(argumentData);
685
+ return argumentData;
686
+ }
751
687
  // returns true if the directive is custom; otherwise, false
752
688
  addDirectiveDefinitionDataByNode(node) {
753
689
  const name = node.name.value;
@@ -771,30 +707,42 @@ class NormalizationFactory {
771
707
  return false;
772
708
  }
773
709
  this.directiveDefinitionByName.set(name, node);
710
+ // @TODO
774
711
  const errorMessages = [];
775
- const { argumentTypeNodeByName, optionalArgumentNames, requiredArgumentNames } = this.extractArgumentData(node.arguments, errorMessages);
776
- this.directiveDefinitionDataByName.set(name, {
777
- argumentTypeNodeByName: argumentTypeNodeByName,
712
+ const { argumentDataByName, optionalArgumentNames, requiredArgumentNames } = this.extractDirectiveArgumentData({
713
+ argumentNodes: node.arguments,
714
+ directiveName: name,
715
+ errorMessages,
716
+ });
717
+ const { errors, locations } = (0, ast_1.extractDirectiveLocations)(node);
718
+ // @TODO
719
+ if (errors.length > 0) {
720
+ this.errors.push(...errors);
721
+ }
722
+ this.directiveDefinitionDataByName.set(name, (0, utils_7.newDirectiveDefinitionData)({
723
+ argumentDataByName: argumentDataByName,
724
+ description: node.description,
778
725
  isRepeatable: node.repeatable,
779
- locations: this.extractDirectiveLocations(node, errorMessages),
726
+ locations,
780
727
  name,
781
728
  node,
782
729
  optionalArgumentNames,
783
730
  requiredArgumentNames,
784
- });
731
+ subgraphNames: new Set([this.subgraphName]),
732
+ }));
785
733
  if (errorMessages.length > 0) {
786
734
  this.errors.push((0, errors_1.invalidDirectiveDefinitionError)(name, errorMessages));
787
735
  }
788
736
  return true;
789
737
  }
790
- addFieldDataByNode(fieldDataByFieldName, node, argumentDataByArgumentName, directivesByName, inheritedDirectiveNames = new Set()) {
738
+ addFieldDataByNode(fieldDataByName, node, argumentDataByName, directivesByName, inheritedDirectiveNames = new Set()) {
791
739
  const name = node.name.value;
792
740
  const parentTypeName = this.renamedParentTypeName || this.originalParentTypeName;
793
741
  const fieldCoords = `${this.originalParentTypeName}.${name}`;
794
742
  const { isExternal, isShareable } = (0, utils_4.isNodeExternalOrShareable)(node, !this.isSubgraphVersionTwo, directivesByName);
795
743
  const namedTypeName = (0, ast_1.getTypeNodeNamedTypeName)(node.type);
796
744
  const fieldData = {
797
- argumentDataByName: argumentDataByArgumentName,
745
+ argumentDataByName: argumentDataByName,
798
746
  configureDescriptionDataBySubgraphName: new Map(),
799
747
  externalFieldDataBySubgraphName: new Map([
800
748
  [this.subgraphName, (0, utils_4.newExternalFieldData)(isExternal)],
@@ -810,7 +758,7 @@ class NormalizationFactory {
810
758
  node: (0, ast_1.getMutableFieldNode)(node, fieldCoords, this.errors),
811
759
  nullLevelsBySubgraphName: new Map(),
812
760
  originalParentTypeName: this.originalParentTypeName,
813
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
761
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
814
762
  renamedParentTypeName: parentTypeName,
815
763
  subgraphNames: new Set([this.subgraphName]),
816
764
  type: (0, ast_1.getMutableTypeNode)(node.type, fieldCoords, this.errors),
@@ -821,7 +769,7 @@ class NormalizationFactory {
821
769
  this.referencedTypeNames.add(fieldData.namedTypeName);
822
770
  }
823
771
  this.extractConfigureDescriptionsData(fieldData);
824
- fieldDataByFieldName.set(name, fieldData);
772
+ fieldDataByName.set(name, fieldData);
825
773
  return fieldData;
826
774
  }
827
775
  addInputValueDataByNode({ fieldName, inputValueDataByName, isArgument, node, originalParentTypeName, renamedParentTypeName, }) {
@@ -852,7 +800,7 @@ class NormalizationFactory {
852
800
  node: (0, ast_1.getMutableInputValueNode)(node, originalParentTypeName, this.errors),
853
801
  originalCoords,
854
802
  originalParentTypeName: originalParentTypeName,
855
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
803
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
856
804
  renamedParentTypeName: federatedParentTypeName,
857
805
  requiredSubgraphNames: new Set((0, utils_4.isTypeRequired)(node.type) ? [this.subgraphName] : []),
858
806
  subgraphNames: new Set([this.subgraphName]),
@@ -893,7 +841,7 @@ class NormalizationFactory {
893
841
  kind: graphql_1.Kind.INTERFACE_TYPE_DEFINITION,
894
842
  name: typeName,
895
843
  node: (0, ast_1.getMutableInterfaceNode)(node.name),
896
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
844
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
897
845
  requireFetchReasonsFieldNames: new Set(),
898
846
  subgraphNames: new Set([this.subgraphName]),
899
847
  description: (0, utils_1.formatDescription)('description' in node ? node.description : undefined),
@@ -959,7 +907,7 @@ class NormalizationFactory {
959
907
  kind: graphql_1.Kind.OBJECT_TYPE_DEFINITION,
960
908
  name: typeName,
961
909
  node: (0, ast_1.getMutableObjectNode)(node.name),
962
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
910
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
963
911
  requireFetchReasonsFieldNames: new Set(),
964
912
  renamedTypeName: this.getRenamedRootTypeName(typeName),
965
913
  subgraphNames: new Set([this.subgraphName]),
@@ -996,7 +944,7 @@ class NormalizationFactory {
996
944
  kind: graphql_1.Kind.ENUM_TYPE_DEFINITION,
997
945
  name: typeName,
998
946
  node: (0, ast_1.getMutableEnumNode)(node.name),
999
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
947
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
1000
948
  subgraphNames: new Set([this.subgraphName]),
1001
949
  description: (0, utils_1.formatDescription)('description' in node ? node.description : undefined),
1002
950
  };
@@ -1010,6 +958,7 @@ class NormalizationFactory {
1010
958
  const extensionType = this.getNodeExtensionType(isRealExtension, directivesByName);
1011
959
  if (parentData) {
1012
960
  if (parentData.kind !== graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION) {
961
+ // TODO
1013
962
  this.errors.push((0, errors_1.multipleNamedTypeDefinitionError)(typeName, (0, utils_5.kindToNodeType)(parentData.kind), (0, utils_3.kindToConvertedTypeString)(node.kind)));
1014
963
  return {
1015
964
  success: false,
@@ -1034,7 +983,7 @@ class NormalizationFactory {
1034
983
  kind: graphql_1.Kind.INPUT_OBJECT_TYPE_DEFINITION,
1035
984
  name: typeName,
1036
985
  node: (0, ast_1.getMutableInputObjectNode)(node.name),
1037
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
986
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
1038
987
  subgraphNames: new Set([this.subgraphName]),
1039
988
  description: (0, utils_1.formatDescription)('description' in node ? node.description : undefined),
1040
989
  };
@@ -1069,7 +1018,7 @@ class NormalizationFactory {
1069
1018
  kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION,
1070
1019
  name: typeName,
1071
1020
  node: (0, ast_1.getMutableScalarNode)(node.name),
1072
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
1021
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
1073
1022
  subgraphNames: new Set([this.subgraphName]),
1074
1023
  description: (0, utils_1.formatDescription)('description' in node ? node.description : undefined),
1075
1024
  };
@@ -1128,7 +1077,7 @@ class NormalizationFactory {
1128
1077
  memberByMemberTypeName: this.extractUnionMembers(node, new Map()),
1129
1078
  name: typeName,
1130
1079
  node: (0, ast_1.getMutableUnionNode)(node.name),
1131
- persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
1080
+ federatedDirectivesData: (0, utils_4.newFederatedDirectivesData)(),
1132
1081
  subgraphNames: new Set([this.subgraphName]),
1133
1082
  description: (0, utils_1.formatDescription)('description' in node ? node.description : undefined),
1134
1083
  };
@@ -1674,7 +1623,7 @@ class NormalizationFactory {
1674
1623
  errorMessages.push((0, errors_1.equivalentSourceAndTargetOverrideErrorMessage)(targetSubgraphName, directiveCoords));
1675
1624
  return;
1676
1625
  }
1677
- const overrideDataForSubgraph = (0, utils_5.getValueOrDefault)(this.overridesByTargetSubgraphName, targetSubgraphName, () => new Map());
1626
+ const overrideDataForSubgraph = (0, utils_5.getValueOrDefault)(this.overriddenFieldNamesByTypeNameByTargetSubgraphName, targetSubgraphName, () => new Map());
1678
1627
  (0, utils_5.getValueOrDefault)(overrideDataForSubgraph, data.renamedParentTypeName, () => new Set()).add(data.name);
1679
1628
  }
1680
1629
  handleSemanticNonNullDirective({ data, directiveNode, errorMessages }) {
@@ -1733,6 +1682,15 @@ class NormalizationFactory {
1733
1682
  }
1734
1683
  data.nullLevelsBySubgraphName.set(this.subgraphName, levels);
1735
1684
  }
1685
+ getOrCreateFieldWeight(typeName, fieldName) {
1686
+ const fieldCoords = `${typeName}.${fieldName}`;
1687
+ return (0, utils_5.getValueOrDefault)(this.costs.fieldWeights, fieldCoords, () => ({
1688
+ typeName,
1689
+ fieldName,
1690
+ argumentWeights: new Map(),
1691
+ directiveArgumentWeights: new Map(),
1692
+ }));
1693
+ }
1736
1694
  handleCostDirective({ data, directiveCoords, directiveNode, errorMessages }) {
1737
1695
  const weightArg = directiveNode.arguments?.find((arg) => arg.name.value === string_constants_1.WEIGHT);
1738
1696
  if (!weightArg || weightArg.value.kind !== graphql_1.Kind.INT) {
@@ -1756,12 +1714,7 @@ class NormalizationFactory {
1756
1714
  errorMessages.push((0, errors_1.costOnInterfaceFieldErrorMessage)(directiveCoords));
1757
1715
  break;
1758
1716
  }
1759
- const fieldCoords = `${typeName}.${data.name}`;
1760
- const fieldWeight = (0, utils_5.getValueOrDefault)(this.costs.fieldWeights, fieldCoords, () => ({
1761
- typeName,
1762
- fieldName: data.name,
1763
- argumentWeights: new Map(),
1764
- }));
1717
+ const fieldWeight = this.getOrCreateFieldWeight(typeName, data.name);
1765
1718
  fieldWeight.weight = weightValue;
1766
1719
  break;
1767
1720
  }
@@ -1779,28 +1732,61 @@ class NormalizationFactory {
1779
1732
  errorMessages.push((0, errors_1.costOnInterfaceFieldErrorMessage)(directiveCoords));
1780
1733
  break;
1781
1734
  }
1782
- const parentFieldCoords = `${typeName}.${ivData.fieldName}`;
1783
- const fieldWeight = (0, utils_5.getValueOrDefault)(this.costs.fieldWeights, parentFieldCoords, () => ({
1784
- typeName,
1785
- fieldName: ivData.fieldName,
1786
- argumentWeights: new Map(),
1787
- }));
1735
+ const fieldWeight = this.getOrCreateFieldWeight(typeName, ivData.fieldName);
1788
1736
  fieldWeight.argumentWeights.set(ivData.name, weightValue);
1789
1737
  }
1790
1738
  else {
1791
1739
  const typeName = ivData.renamedParentTypeName || ivData.originalParentTypeName;
1792
- const fieldCoords = `${typeName}.${ivData.name}`;
1793
- const fieldWeight = (0, utils_5.getValueOrDefault)(this.costs.fieldWeights, fieldCoords, () => ({
1794
- typeName,
1795
- fieldName: ivData.name,
1796
- argumentWeights: new Map(),
1797
- }));
1740
+ const fieldWeight = this.getOrCreateFieldWeight(typeName, ivData.name);
1798
1741
  fieldWeight.weight = weightValue;
1799
1742
  }
1800
1743
  break;
1801
1744
  }
1802
1745
  }
1803
1746
  }
1747
+ recordDirectiveWeightOnField({ data, definitionData, directiveName, directiveNode, }) {
1748
+ // This method walks every argument defined on the directive and records a directive weight
1749
+ // on the field only when all these conditions hold:
1750
+ // 1. The argument of the directive has a cost weight assigned
1751
+ // 2. The argument is non-null
1752
+ // 3. The parent type is not an interface type.
1753
+ const typeName = data.renamedParentTypeName || data.originalParentTypeName;
1754
+ const parentTypeData = this.parentDefinitionDataByTypeName.get(typeName);
1755
+ // Directive argument weights should only be recorded for concrete type fields.
1756
+ if (!parentTypeData || parentTypeData.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
1757
+ return;
1758
+ }
1759
+ // Determine which arguments are non-null on this directive usage.
1760
+ // Record the DirectiveArgument coords if its argument has an explicit non-null value or
1761
+ // if it has a default value and was not explicitly set to null.
1762
+ const suppliedArgNodeByName = new Map();
1763
+ for (const arg of directiveNode.arguments ?? []) {
1764
+ suppliedArgNodeByName.set(arg.name.value, arg.value);
1765
+ }
1766
+ for (const [argName, argData] of definitionData.argumentDataByName) {
1767
+ const coords = `${directiveName}.${argName}`;
1768
+ const argWeight = this.costs.directiveArgumentWeights.get(coords);
1769
+ // Bail if the argName argument does not have cost attached to it.
1770
+ if (argWeight === undefined) {
1771
+ continue;
1772
+ }
1773
+ // Check if this argument is non-null at the usage site:
1774
+ const argNode = suppliedArgNodeByName.get(argName);
1775
+ if (argNode) {
1776
+ if (argNode.kind === graphql_1.Kind.NULL) {
1777
+ continue;
1778
+ }
1779
+ }
1780
+ else if (!argData.defaultValue || argData.defaultValue.kind === graphql_1.Kind.NULL) {
1781
+ continue;
1782
+ }
1783
+ const fieldWeight = this.getOrCreateFieldWeight(typeName, data.name);
1784
+ // Accumulate across directive usages so that repeatable directives on the same
1785
+ // field are charged once per usage.
1786
+ const existingWeight = fieldWeight.directiveArgumentWeights.get(coords) ?? 0;
1787
+ fieldWeight.directiveArgumentWeights.set(coords, existingWeight + argWeight);
1788
+ }
1789
+ }
1804
1790
  handleListSizeDirective({ data, directiveCoords, directiveNode, errorMessages }) {
1805
1791
  const args = directiveNode.arguments;
1806
1792
  if (!args) {
@@ -2102,7 +2088,7 @@ class NormalizationFactory {
2102
2088
  }
2103
2089
  switch (fieldName) {
2104
2090
  case string_constants_1.CONSUMER_NAME:
2105
- if (field.value.kind != graphql_1.Kind.STRING || field.value.value.length < 1) {
2091
+ if (field.value.kind !== graphql_1.Kind.STRING || field.value.value.length < 1) {
2106
2092
  invalidRequiredFieldNames.add(fieldName);
2107
2093
  isValid = false;
2108
2094
  continue;
@@ -2110,7 +2096,7 @@ class NormalizationFactory {
2110
2096
  consumerName = field.value.value;
2111
2097
  break;
2112
2098
  case string_constants_1.STREAM_NAME:
2113
- if (field.value.kind != graphql_1.Kind.STRING || field.value.value.length < 1) {
2099
+ if (field.value.kind !== graphql_1.Kind.STRING || field.value.value.length < 1) {
2114
2100
  invalidRequiredFieldNames.add(fieldName);
2115
2101
  isValid = false;
2116
2102
  continue;
@@ -2118,7 +2104,7 @@ class NormalizationFactory {
2118
2104
  streamName = field.value.value;
2119
2105
  break;
2120
2106
  case string_constants_1.CONSUMER_INACTIVE_THRESHOLD:
2121
- if (field.value.kind != graphql_1.Kind.INT) {
2107
+ if (field.value.kind !== graphql_1.Kind.INT) {
2122
2108
  errorMessages.push((0, errors_1.invalidArgumentValueErrorMessage)((0, graphql_1.print)(field.value), 'edfs__NatsStreamConfiguration', `consumerInactiveThreshold`, string_constants_1.INT_SCALAR));
2123
2109
  isValid = false;
2124
2110
  continue;
@@ -2416,7 +2402,7 @@ class NormalizationFactory {
2416
2402
  if (data.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
2417
2403
  return false;
2418
2404
  }
2419
- if (data.fieldDataByName.size != 1) {
2405
+ if (data.fieldDataByName.size !== 1) {
2420
2406
  return false;
2421
2407
  }
2422
2408
  for (const [fieldName, fieldData] of data.fieldDataByName) {
@@ -2436,7 +2422,7 @@ class NormalizationFactory {
2436
2422
  if (!(0, utils_4.isInputObjectDefinitionData)(streamConfigurationInputData)) {
2437
2423
  return false;
2438
2424
  }
2439
- if (streamConfigurationInputData.inputValueDataByName.size != 3) {
2425
+ if (streamConfigurationInputData.inputValueDataByName.size !== 3) {
2440
2426
  return false;
2441
2427
  }
2442
2428
  for (const [inputValueName, inputValueData] of streamConfigurationInputData.inputValueDataByName) {
@@ -2672,7 +2658,7 @@ class NormalizationFactory {
2672
2658
  scalarDefinitionData.node.directives = this.getValidFlattenedDirectiveArray(scalarDefinitionData.directivesByName, scalarDefinitionData.name);
2673
2659
  return scalarDefinitionData.node;
2674
2660
  }
2675
- getSchemaNodeByData(schemaData) {
2661
+ schemaNodeFromData(schemaData) {
2676
2662
  const operationTypes = [];
2677
2663
  for (const [operation, { type: { name: { value }, }, },] of schemaData.operationTypes) {
2678
2664
  const data = this.parentDefinitionDataByTypeName.get(value);
@@ -2685,21 +2671,44 @@ class NormalizationFactory {
2685
2671
  type: (0, utils_1.stringToNamedTypeNode)(value),
2686
2672
  });
2687
2673
  }
2674
+ const linkResult = (0, utils_2.extractLinkArgs)(schemaData.directivesByName);
2675
+ if (!linkResult.success) {
2676
+ return linkResult;
2677
+ }
2678
+ this.importDataByDirectiveName = linkResult.importDataByDirectiveName;
2679
+ const composeDirectives = schemaData.directivesByName.get(string_constants_1.COMPOSE_DIRECTIVE);
2680
+ for (const composeDirective of composeDirectives ?? []) {
2681
+ this.handleComposeDirective(composeDirective);
2682
+ }
2683
+ // If the directive is not part of @composeDirective, it is effectively ignored by federation.
2684
+ for (const directiveName of this.importDataByDirectiveName.keys()) {
2685
+ if (!this.federatedDirectiveDataByName.has(directiveName.substring(1))) {
2686
+ this.importDataByDirectiveName.delete(directiveName);
2687
+ }
2688
+ }
2688
2689
  if (operationTypes.length > 0) {
2689
- const node = {
2690
- ...(schemaData.description ? { description: schemaData.description } : {}),
2691
- directives: this.getValidFlattenedDirectiveArray(schemaData.directivesByName, schemaData.name),
2692
- kind: graphql_1.Kind.SCHEMA_DEFINITION,
2693
- operationTypes: operationTypes,
2690
+ return {
2691
+ node: {
2692
+ ...(schemaData.description ? { description: schemaData.description } : {}),
2693
+ directives: this.getValidFlattenedDirectiveArray(schemaData.directivesByName, schemaData.name),
2694
+ kind: graphql_1.Kind.SCHEMA_DEFINITION,
2695
+ operationTypes: operationTypes,
2696
+ },
2697
+ success: true,
2694
2698
  };
2695
- return node;
2696
2699
  }
2697
2700
  if (schemaData.directivesByName.size < 1) {
2698
- return;
2701
+ return {
2702
+ node: undefined,
2703
+ success: true,
2704
+ };
2699
2705
  }
2700
2706
  return {
2701
- directives: this.getValidFlattenedDirectiveArray(schemaData.directivesByName, schemaData.name),
2702
- kind: graphql_1.Kind.SCHEMA_EXTENSION,
2707
+ node: {
2708
+ directives: this.getValidFlattenedDirectiveArray(schemaData.directivesByName, schemaData.name),
2709
+ kind: graphql_1.Kind.SCHEMA_EXTENSION,
2710
+ },
2711
+ success: true,
2703
2712
  };
2704
2713
  }
2705
2714
  getUnionNodeByData(unionDefinitionData) {
@@ -2928,14 +2937,22 @@ class NormalizationFactory {
2928
2937
  const definitions = [];
2929
2938
  this.#addDirectiveDefinitionsToDocument(definitions);
2930
2939
  this.validateDirectives(this.schemaData, string_constants_1.SCHEMA);
2931
- const schemaNode = this.getSchemaNodeByData(this.schemaData);
2940
+ const schemaNodeResult = this.schemaNodeFromData(this.schemaData);
2941
+ if (!schemaNodeResult.success) {
2942
+ this.errors.push(...schemaNodeResult.errors);
2943
+ return {
2944
+ errors: this.errors,
2945
+ success: false,
2946
+ warnings: this.warnings,
2947
+ };
2948
+ }
2932
2949
  /* Schema extension orphans are not supported on old routers.
2933
2950
  * Consequently, it is a breaking change that requires a new composition version, and that composition version
2934
2951
  * would only be compatible with newer routers that support schema extension orphans.
2935
2952
  * For now, only a valid schema definition node is pushed.
2936
2953
  */
2937
- if (schemaNode?.kind === graphql_1.Kind.SCHEMA_DEFINITION) {
2938
- definitions.push(schemaNode);
2954
+ if (schemaNodeResult.node?.kind === graphql_1.Kind.SCHEMA_DEFINITION) {
2955
+ definitions.push(schemaNodeResult.node);
2939
2956
  }
2940
2957
  for (const [parentTypeName, parentData] of this.parentDefinitionDataByTypeName) {
2941
2958
  this.validateDirectives(parentData, parentTypeName);
@@ -2983,7 +3000,7 @@ class NormalizationFactory {
2983
3000
  // Undefined types are handled elsewhere
2984
3001
  continue;
2985
3002
  }
2986
- this.sanitizeDefaultValue({ data: valueData, namedTypeData, node: valueData.node });
3003
+ (0, utils_4.sanitizeDefaultValue)({ data: valueData, namedTypeData, node: valueData.node });
2987
3004
  if (!(0, utils_4.isInputNodeKind)(namedTypeData.kind)) {
2988
3005
  this.errors.push((0, errors_1.invalidNamedTypeError)({
2989
3006
  data: valueData,
@@ -3161,15 +3178,7 @@ class NormalizationFactory {
3161
3178
  this.warnings.push((0, warnings_1.unimplementedInterfaceOutputTypeWarning)(this.subgraphName, referencedTypeName));
3162
3179
  }
3163
3180
  }
3164
- const persistedDirectiveDefinitionDataByDirectiveName = new Map();
3165
- for (const directiveDefinitionNode of this.directiveDefinitionByName.values()) {
3166
- // TODO @composeDirective directives would also be handled here
3167
- const executableLocations = (0, utils_1.extractExecutableDirectiveLocations)(directiveDefinitionNode.locations, new Set());
3168
- if (executableLocations.size < 1) {
3169
- continue;
3170
- }
3171
- this.addPersistedDirectiveDefinitionDataByNode(persistedDirectiveDefinitionDataByDirectiveName, directiveDefinitionNode, executableLocations);
3172
- }
3181
+ this.handleExecutableDirectives();
3173
3182
  if (this.isSubgraphEventDrivenGraph) {
3174
3183
  this.validateEventDrivenSubgraph();
3175
3184
  }
@@ -3190,16 +3199,19 @@ class NormalizationFactory {
3190
3199
  };
3191
3200
  return {
3192
3201
  authorizationDataByParentTypeName: this.authorizationDataByParentTypeName,
3193
- // configurationDataMap is map of ConfigurationData per type name.
3194
- // It is an Intermediate configuration object that will be converted to an engine configuration in the router
3195
3202
  concreteTypeNamesByAbstractTypeName: this.concreteTypeNamesByAbstractTypeName,
3196
3203
  conditionalFieldDataByCoordinates: this.conditionalFieldDataByCoords,
3204
+ /* `configurationDataByTypeName` is an intermediate object that is converted
3205
+ * to an engine configuration in the router
3206
+ */
3197
3207
  configurationDataByTypeName: this.configurationDataByTypeName,
3198
3208
  costs: this.costs,
3199
3209
  directiveDefinitionByName: this.directiveDefinitionByName,
3200
3210
  entityDataByTypeName: this.entityDataByTypeName,
3201
3211
  entityInterfaces: this.entityInterfaceDataByTypeName,
3212
+ federatedDirectiveDataByName: this.federatedDirectiveDataByName,
3202
3213
  fieldCoordsByNamedTypeName: this.fieldCoordsByNamedTypeName,
3214
+ importDataByDirectiveName: this.importDataByDirectiveName,
3203
3215
  interfaceImplementationTypeNamesByInterfaceTypeName: this.interfaceImplementationTypeNamesByInterfaceTypeName,
3204
3216
  isEventDrivenGraph: this.isSubgraphEventDrivenGraph,
3205
3217
  isVersionTwo: this.isSubgraphVersionTwo,
@@ -3207,210 +3219,16 @@ class NormalizationFactory {
3207
3219
  keyFieldSetsByEntityTypeNameByKeyFieldCoords: this.keyFieldSetsByEntityTypeNameByFieldCoords,
3208
3220
  operationTypes: this.operationTypeNodeByTypeName,
3209
3221
  originalTypeNameByRenamedTypeName: this.originalTypeNameByRenamedTypeName,
3210
- overridesByTargetSubgraphName: this.overridesByTargetSubgraphName,
3222
+ overriddenFieldNamesByParentTypeNameByTargetSubgraphName: this.overriddenFieldNamesByTypeNameByTargetSubgraphName,
3211
3223
  parentDefinitionDataByTypeName: this.parentDefinitionDataByTypeName,
3212
- persistedDirectiveDefinitionDataByDirectiveName,
3213
- schemaNode,
3224
+ schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { addInvalidExtensionOrphans: true, assumeValid: true, assumeValidSDL: true }),
3225
+ schemaNode: schemaNodeResult.node,
3214
3226
  subgraphAST: newAST,
3215
3227
  subgraphString: (0, graphql_1.print)(newAST),
3216
- schema: (0, buildASTSchema_1.buildASTSchema)(newAST, { addInvalidExtensionOrphans: true, assumeValid: true, assumeValidSDL: true }),
3217
3228
  success: true,
3218
3229
  warnings: this.warnings,
3219
3230
  };
3220
3231
  }
3221
3232
  }
3222
3233
  exports.NormalizationFactory = NormalizationFactory;
3223
- function batchNormalize({ options, subgraphs }) {
3224
- const authorizationDataByParentTypeName = new Map();
3225
- const concreteTypeNamesByAbstractTypeName = new Map();
3226
- const entityDataByTypeName = new Map();
3227
- const interfaceImplementationTypeNamesByInterfaceTypeName = new Map();
3228
- const internalSubgraphBySubgraphName = new Map();
3229
- const allOverridesByTargetSubgraphName = new Map();
3230
- const overrideSourceSubgraphNamesByFieldPath = new Map();
3231
- const duplicateOverriddenFieldPaths = new Set();
3232
- const parentDefinitionDataMapsBySubgraphName = new Map();
3233
- const subgraphNames = new Set();
3234
- const nonUniqueSubgraphNames = new Set();
3235
- const invalidNameErrorMessages = [];
3236
- const invalidORScopesCoords = new Set();
3237
- const fieldCoordsByNamedTypeName = new Map();
3238
- const warnings = [];
3239
- const validationErrors = [];
3240
- // Record the subgraph names first, so that subgraph references can be validated
3241
- for (const subgraph of subgraphs) {
3242
- if (subgraph.name) {
3243
- (0, subgraph_1.recordSubgraphName)(subgraph.name, subgraphNames, nonUniqueSubgraphNames);
3244
- }
3245
- }
3246
- const internalGraph = new graph_1.Graph();
3247
- for (let i = 0; i < subgraphs.length; i++) {
3248
- const subgraph = subgraphs[i];
3249
- const subgraphName = subgraph.name || `subgraph-${i}-${Date.now()}`;
3250
- if (!subgraph.name) {
3251
- invalidNameErrorMessages.push((0, errors_1.invalidSubgraphNameErrorMessage)(i, subgraphName));
3252
- }
3253
- const normalizationResult = normalizeSubgraph({
3254
- document: subgraph.definitions,
3255
- internalGraph,
3256
- options,
3257
- subgraphName,
3258
- });
3259
- if (normalizationResult.warnings.length > 0) {
3260
- warnings.push(...normalizationResult.warnings);
3261
- }
3262
- if (!normalizationResult.success) {
3263
- validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, normalizationResult.errors));
3264
- continue;
3265
- }
3266
- if (!normalizationResult) {
3267
- validationErrors.push((0, errors_1.subgraphValidationError)(subgraphName, [errors_1.subgraphValidationFailureError]));
3268
- continue;
3269
- }
3270
- parentDefinitionDataMapsBySubgraphName.set(subgraphName, normalizationResult.parentDefinitionDataByTypeName);
3271
- for (const authorizationData of normalizationResult.authorizationDataByParentTypeName.values()) {
3272
- (0, utils_3.upsertAuthorizationData)(authorizationDataByParentTypeName, authorizationData, invalidORScopesCoords);
3273
- }
3274
- for (const [namedTypeName, fieldCoords] of normalizationResult.fieldCoordsByNamedTypeName) {
3275
- (0, utils_5.addIterableToSet)({
3276
- source: fieldCoords,
3277
- target: (0, utils_5.getValueOrDefault)(fieldCoordsByNamedTypeName, namedTypeName, () => new Set()),
3278
- });
3279
- }
3280
- for (const [abstractTypeName, incomingConcreteTypeNames,] of normalizationResult.concreteTypeNamesByAbstractTypeName) {
3281
- const existingConcreteTypeNames = concreteTypeNamesByAbstractTypeName.get(abstractTypeName);
3282
- if (!existingConcreteTypeNames) {
3283
- concreteTypeNamesByAbstractTypeName.set(abstractTypeName, new Set(incomingConcreteTypeNames));
3284
- continue;
3285
- }
3286
- (0, utils_5.addIterableToSet)({
3287
- source: incomingConcreteTypeNames,
3288
- target: existingConcreteTypeNames,
3289
- });
3290
- }
3291
- for (const [interfaceTypeName, incomingInterfaceTypeNames,] of normalizationResult.interfaceImplementationTypeNamesByInterfaceTypeName) {
3292
- const existingInterfaceTypeNames = interfaceImplementationTypeNamesByInterfaceTypeName.get(interfaceTypeName);
3293
- if (!existingInterfaceTypeNames) {
3294
- interfaceImplementationTypeNamesByInterfaceTypeName.set(interfaceTypeName, new Set(incomingInterfaceTypeNames));
3295
- continue;
3296
- }
3297
- (0, utils_5.addIterableToSet)({
3298
- source: incomingInterfaceTypeNames,
3299
- target: existingInterfaceTypeNames,
3300
- });
3301
- }
3302
- for (const [typeName, entityData] of normalizationResult.entityDataByTypeName) {
3303
- const keyFieldSetDataByFieldSet = entityData.keyFieldSetDatasBySubgraphName.get(subgraphName);
3304
- if (!keyFieldSetDataByFieldSet) {
3305
- continue;
3306
- }
3307
- (0, utils_3.upsertEntityData)({
3308
- entityDataByTypeName,
3309
- keyFieldSetDataByFieldSet,
3310
- typeName,
3311
- subgraphName,
3312
- });
3313
- }
3314
- if (subgraph.name) {
3315
- internalSubgraphBySubgraphName.set(subgraphName, {
3316
- conditionalFieldDataByCoordinates: normalizationResult.conditionalFieldDataByCoordinates,
3317
- configurationDataByTypeName: normalizationResult.configurationDataByTypeName,
3318
- costs: normalizationResult.costs,
3319
- definitions: normalizationResult.subgraphAST,
3320
- directiveDefinitionByName: normalizationResult.directiveDefinitionByName,
3321
- entityInterfaces: normalizationResult.entityInterfaces,
3322
- isVersionTwo: normalizationResult.isVersionTwo,
3323
- keyFieldNamesByParentTypeName: normalizationResult.keyFieldNamesByParentTypeName,
3324
- name: subgraphName,
3325
- operationTypes: normalizationResult.operationTypes,
3326
- overriddenFieldNamesByParentTypeName: new Map(),
3327
- parentDefinitionDataByTypeName: normalizationResult.parentDefinitionDataByTypeName,
3328
- persistedDirectiveDefinitionDataByDirectiveName: normalizationResult.persistedDirectiveDefinitionDataByDirectiveName,
3329
- schema: normalizationResult.schema,
3330
- schemaNode: normalizationResult.schemaNode,
3331
- url: subgraph.url,
3332
- });
3333
- }
3334
- if (normalizationResult.overridesByTargetSubgraphName.size < 1) {
3335
- continue;
3336
- }
3337
- for (const [targetSubgraphName, overridesData] of normalizationResult.overridesByTargetSubgraphName) {
3338
- const isTargetValid = subgraphNames.has(targetSubgraphName);
3339
- for (const [parentTypeName, fieldNames] of overridesData) {
3340
- /* It's possible for a renamed root type to have a field overridden, so make sure any errors at this stage are
3341
- propagated with the original typename. */
3342
- const originalParentTypeName = normalizationResult.originalTypeNameByRenamedTypeName.get(parentTypeName) || parentTypeName;
3343
- if (!isTargetValid) {
3344
- warnings.push((0, warnings_1.invalidOverrideTargetSubgraphNameWarning)(targetSubgraphName, originalParentTypeName, [...fieldNames], subgraph.name));
3345
- }
3346
- else {
3347
- const overridesData = (0, utils_5.getValueOrDefault)(allOverridesByTargetSubgraphName, targetSubgraphName, () => new Map());
3348
- const existingFieldNames = (0, utils_5.getValueOrDefault)(overridesData, parentTypeName, () => new Set(fieldNames));
3349
- (0, utils_5.addIterableToSet)({
3350
- source: fieldNames,
3351
- target: existingFieldNames,
3352
- });
3353
- }
3354
- for (const fieldName of fieldNames) {
3355
- const fieldCoords = `${originalParentTypeName}.${fieldName}`;
3356
- const sourceSubgraphs = overrideSourceSubgraphNamesByFieldPath.get(fieldCoords);
3357
- if (!sourceSubgraphs) {
3358
- overrideSourceSubgraphNamesByFieldPath.set(fieldCoords, [subgraphName]);
3359
- continue;
3360
- }
3361
- sourceSubgraphs.push(subgraphName);
3362
- duplicateOverriddenFieldPaths.add(fieldCoords);
3363
- }
3364
- }
3365
- }
3366
- }
3367
- const allErrors = [];
3368
- if (invalidORScopesCoords.size > 0) {
3369
- allErrors.push((0, errors_1.orScopesLimitError)(constants_1.MAX_OR_SCOPES, [...invalidORScopesCoords]));
3370
- }
3371
- if (invalidNameErrorMessages.length > 0 || nonUniqueSubgraphNames.size > 0) {
3372
- allErrors.push((0, errors_1.invalidSubgraphNamesError)([...nonUniqueSubgraphNames], invalidNameErrorMessages));
3373
- }
3374
- if (duplicateOverriddenFieldPaths.size > 0) {
3375
- const duplicateOverriddenFieldErrorMessages = [];
3376
- for (const fieldPath of duplicateOverriddenFieldPaths) {
3377
- const sourceSubgraphNames = (0, utils_5.getOrThrowError)(overrideSourceSubgraphNamesByFieldPath, fieldPath, 'overrideSourceSubgraphNamesByFieldPath');
3378
- duplicateOverriddenFieldErrorMessages.push((0, errors_1.duplicateOverriddenFieldErrorMessage)(fieldPath, sourceSubgraphNames));
3379
- }
3380
- allErrors.push((0, errors_1.duplicateOverriddenFieldsError)(duplicateOverriddenFieldErrorMessages));
3381
- }
3382
- allErrors.push(...validationErrors);
3383
- if (allErrors.length > 0) {
3384
- return {
3385
- errors: allErrors,
3386
- success: false,
3387
- warnings,
3388
- };
3389
- }
3390
- for (const [targetSubgraphName, overridesData] of allOverridesByTargetSubgraphName) {
3391
- const internalSubgraph = (0, utils_5.getOrThrowError)(internalSubgraphBySubgraphName, targetSubgraphName, 'internalSubgraphBySubgraphName');
3392
- internalSubgraph.overriddenFieldNamesByParentTypeName = overridesData;
3393
- for (const [parentTypeName, fieldNames] of overridesData) {
3394
- const configurationData = internalSubgraph.configurationDataByTypeName.get(parentTypeName);
3395
- if (!configurationData) {
3396
- continue;
3397
- }
3398
- (0, utils_3.subtractSet)(fieldNames, configurationData.fieldNames);
3399
- if (configurationData.fieldNames.size < 1) {
3400
- internalSubgraph.configurationDataByTypeName.delete(parentTypeName);
3401
- }
3402
- }
3403
- }
3404
- return {
3405
- authorizationDataByParentTypeName,
3406
- concreteTypeNamesByAbstractTypeName,
3407
- entityDataByTypeName,
3408
- fieldCoordsByNamedTypeName,
3409
- interfaceImplementationTypeNamesByInterfaceTypeName,
3410
- internalSubgraphBySubgraphName: internalSubgraphBySubgraphName,
3411
- internalGraph,
3412
- success: true,
3413
- warnings,
3414
- };
3415
- }
3416
3234
  //# sourceMappingURL=normalization-factory.js.map