@wundergraph/composition 0.43.3 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/errors/errors.d.ts +7 -2
  2. package/dist/errors/errors.js +28 -1
  3. package/dist/errors/errors.js.map +1 -1
  4. package/dist/errors/types.d.ts +9 -0
  5. package/dist/router-configuration/types.d.ts +7 -5
  6. package/dist/router-configuration/utils.js.map +1 -1
  7. package/dist/schema-building/types.d.ts +2 -0
  8. package/dist/schema-building/utils.d.ts +3 -3
  9. package/dist/schema-building/utils.js +11 -7
  10. package/dist/schema-building/utils.js.map +1 -1
  11. package/dist/subgraph/types.d.ts +3 -2
  12. package/dist/tsconfig.tsbuildinfo +1 -1
  13. package/dist/types/types.d.ts +1 -0
  14. package/dist/utils/composition-version.js +1 -1
  15. package/dist/utils/string-constants.d.ts +7 -3
  16. package/dist/utils/string-constants.js +13 -9
  17. package/dist/utils/string-constants.js.map +1 -1
  18. package/dist/utils/utils.d.ts +2 -1
  19. package/dist/utils/utils.js +28 -3
  20. package/dist/utils/utils.js.map +1 -1
  21. package/dist/v1/federation/federation-factory.d.ts +3 -1
  22. package/dist/v1/federation/federation-factory.js +61 -5
  23. package/dist/v1/federation/federation-factory.js.map +1 -1
  24. package/dist/v1/normalization/directive-definition-data.d.ts +2 -0
  25. package/dist/v1/normalization/directive-definition-data.js +45 -1
  26. package/dist/v1/normalization/directive-definition-data.js.map +1 -1
  27. package/dist/v1/normalization/normalization-factory.d.ts +3 -1
  28. package/dist/v1/normalization/normalization-factory.js +107 -12
  29. package/dist/v1/normalization/normalization-factory.js.map +1 -1
  30. package/dist/v1/normalization/types.d.ts +7 -1
  31. package/dist/v1/normalization/utils.js +2 -0
  32. package/dist/v1/normalization/utils.js.map +1 -1
  33. package/dist/v1/normalization/walkers.js +6 -1
  34. package/dist/v1/normalization/walkers.js.map +1 -1
  35. package/dist/v1/utils/constants.d.ts +2 -0
  36. package/dist/v1/utils/constants.js +43 -1
  37. package/dist/v1/utils/constants.js.map +1 -1
  38. package/dist/v1/utils/utils.d.ts +2 -2
  39. package/dist/v1/utils/utils.js +17 -4
  40. package/dist/v1/utils/utils.js.map +1 -1
  41. package/package.json +2 -2
@@ -47,6 +47,7 @@ class NormalizationFactory {
47
47
  definedDirectiveNames = new Set();
48
48
  directiveDefinitionByDirectiveName = new Map();
49
49
  directiveDefinitionDataByDirectiveName = (0, utils_2.initializeDirectiveDefinitionDatas)();
50
+ doesParentObjectRequireFetchReasons = false;
50
51
  edfsDirectiveReferences = new Set();
51
52
  errors = [];
52
53
  entityDataByTypeName = new Map();
@@ -207,14 +208,18 @@ class NormalizationFactory {
207
208
  }
208
209
  }
209
210
  addInheritedDirectivesToFieldData(fieldDirectivesByDirectiveName, inheritedDirectiveNames) {
210
- if (this.isParentObjectShareable && !fieldDirectivesByDirectiveName.has(string_constants_2.SHAREABLE)) {
211
- fieldDirectivesByDirectiveName.set(string_constants_2.SHAREABLE, [(0, utils_5.generateSimpleDirective)(string_constants_2.SHAREABLE)]);
212
- inheritedDirectiveNames.add(string_constants_2.SHAREABLE);
213
- }
214
211
  if (this.isParentObjectExternal && !fieldDirectivesByDirectiveName.has(string_constants_2.EXTERNAL)) {
215
212
  fieldDirectivesByDirectiveName.set(string_constants_2.EXTERNAL, [(0, utils_5.generateSimpleDirective)(string_constants_2.EXTERNAL)]);
216
213
  inheritedDirectiveNames.add(string_constants_2.EXTERNAL);
217
214
  }
215
+ if (this.doesParentObjectRequireFetchReasons && !fieldDirectivesByDirectiveName.has(string_constants_2.REQUIRE_FETCH_REASONS)) {
216
+ fieldDirectivesByDirectiveName.set(string_constants_2.REQUIRE_FETCH_REASONS, [(0, utils_5.generateSimpleDirective)(string_constants_2.REQUIRE_FETCH_REASONS)]);
217
+ inheritedDirectiveNames.add(string_constants_2.REQUIRE_FETCH_REASONS);
218
+ }
219
+ if (this.isParentObjectShareable && !fieldDirectivesByDirectiveName.has(string_constants_2.SHAREABLE)) {
220
+ fieldDirectivesByDirectiveName.set(string_constants_2.SHAREABLE, [(0, utils_5.generateSimpleDirective)(string_constants_2.SHAREABLE)]);
221
+ inheritedDirectiveNames.add(string_constants_2.SHAREABLE);
222
+ }
218
223
  return fieldDirectivesByDirectiveName;
219
224
  }
220
225
  extractDirectives(node, directivesByDirectiveName) {
@@ -234,6 +239,7 @@ class NormalizationFactory {
234
239
  continue;
235
240
  }
236
241
  this.isParentObjectExternal ||= directiveName === string_constants_2.EXTERNAL;
242
+ this.doesParentObjectRequireFetchReasons ||= directiveName === string_constants_2.REQUIRE_FETCH_REASONS;
237
243
  this.isParentObjectShareable ||= directiveName === string_constants_2.SHAREABLE;
238
244
  }
239
245
  return directivesByDirectiveName;
@@ -242,8 +248,10 @@ class NormalizationFactory {
242
248
  const directiveName = directiveNode.name.value;
243
249
  const parentTypeName = data.kind === graphql_1.Kind.FIELD_DEFINITION ? data.renamedParentTypeName || data.originalParentTypeName : data.name;
244
250
  const isAuthenticated = directiveName === string_constants_2.AUTHENTICATED;
251
+ const isField = (0, utils_4.isFieldData)(data);
245
252
  const isOverride = directiveName === string_constants_2.OVERRIDE;
246
253
  const isRequiresScopes = directiveName === string_constants_2.REQUIRES_SCOPES;
254
+ const isSemanticNonNull = directiveName === string_constants_2.SEMANTIC_NON_NULL;
247
255
  if (!directiveNode.arguments || directiveNode.arguments.length < 1) {
248
256
  if (definitionData.requiredArgumentNames.size > 0) {
249
257
  errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, requiredArgumentNames, []));
@@ -251,6 +259,18 @@ class NormalizationFactory {
251
259
  if (isAuthenticated) {
252
260
  this.handleAuthenticatedDirective(data, parentTypeName);
253
261
  }
262
+ if (isSemanticNonNull && isField) {
263
+ // The default argument for levels is [0], so a non-null wrapper is invalid.
264
+ if ((0, utils_4.isTypeRequired)(data.type)) {
265
+ errorMessages.push((0, errors_1.semanticNonNullLevelsNonNullErrorMessage)({
266
+ typeString: (0, merge_1.printTypeNode)(data.type),
267
+ value: '0',
268
+ }));
269
+ }
270
+ else {
271
+ data.nullLevelsBySubgraphName.set(this.subgraphName, new Set([0]));
272
+ }
273
+ }
254
274
  return errorMessages;
255
275
  }
256
276
  const definedArgumentNames = new Set();
@@ -273,8 +293,11 @@ class NormalizationFactory {
273
293
  errorMessages.push((0, errors_1.invalidArgumentValueErrorMessage)((0, graphql_1.print)(argumentNode.value), `@${directiveName}`, argumentName, (0, merge_1.printTypeNode)(argumentData.typeNode)));
274
294
  continue;
275
295
  }
276
- // The directive location validation means the kind check should be unnecessary
277
- if (isOverride && data.kind === graphql_1.Kind.FIELD_DEFINITION) {
296
+ /* Individual directives are handled in the loop because they validate a single argument, and duplicate
297
+ * arguments would short-circuit.
298
+ * The directive location validation means the node kind check should be unnecessary
299
+ * */
300
+ if (isOverride && isField) {
278
301
  this.handleOverrideDirective({
279
302
  data,
280
303
  directiveCoords,
@@ -283,6 +306,14 @@ class NormalizationFactory {
283
306
  });
284
307
  continue;
285
308
  }
309
+ if (isSemanticNonNull && isField) {
310
+ this.handleSemanticNonNullDirective({
311
+ data,
312
+ directiveNode,
313
+ errorMessages,
314
+ });
315
+ continue;
316
+ }
286
317
  if (!isRequiresScopes || argumentName !== string_constants_2.SCOPES) {
287
318
  continue;
288
319
  }
@@ -666,6 +697,7 @@ class NormalizationFactory {
666
697
  namedTypeKind: constants_1.BASE_SCALARS.has(namedTypeName) ? graphql_1.Kind.SCALAR_TYPE_DEFINITION : graphql_1.Kind.NULL,
667
698
  namedTypeName,
668
699
  node: (0, ast_1.getMutableFieldNode)(node, fieldCoords, this.errors),
700
+ nullLevelsBySubgraphName: new Map(),
669
701
  originalParentTypeName: this.originalParentTypeName,
670
702
  persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
671
703
  renamedParentTypeName: parentTypeName,
@@ -784,7 +816,7 @@ class NormalizationFactory {
784
816
  upsertObjectDataByNode(node, isRealExtension = false) {
785
817
  const typeName = node.name.value;
786
818
  const parentData = this.parentDefinitionDataByTypeName.get(typeName);
787
- const directivesByDirectiveName = this.extractDirectives(node, parentData?.directivesByDirectiveName || new Map());
819
+ const directivesByDirectiveName = this.extractDirectives(node, parentData?.directivesByDirectiveName ?? new Map());
788
820
  const isRootType = this.isTypeNameRootType(typeName);
789
821
  const extensionType = this.getNodeExtensionType(isRealExtension, directivesByDirectiveName, isRootType);
790
822
  this.addInterfaceObjectFieldsByNode(node);
@@ -816,6 +848,7 @@ class NormalizationFactory {
816
848
  name: typeName,
817
849
  node: (0, ast_1.getMutableObjectNode)(node.name),
818
850
  persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
851
+ requireFetchReasonsFieldNames: new Set(),
819
852
  renamedTypeName: this.getRenamedRootTypeName(typeName),
820
853
  subgraphNames: new Set([this.subgraphName]),
821
854
  description: (0, utils_1.formatDescription)('description' in node ? node.description : undefined),
@@ -1470,6 +1503,62 @@ class NormalizationFactory {
1470
1503
  const overrideDataForSubgraph = (0, utils_5.getValueOrDefault)(this.overridesByTargetSubgraphName, targetSubgraphName, () => new Map());
1471
1504
  (0, utils_5.getValueOrDefault)(overrideDataForSubgraph, data.renamedParentTypeName, () => new Set()).add(data.name);
1472
1505
  }
1506
+ handleSemanticNonNullDirective({ data, directiveNode, errorMessages }) {
1507
+ const nonNullIndices = new Set();
1508
+ let currentType = data.node.type;
1509
+ let index = 0;
1510
+ while (currentType) {
1511
+ switch (currentType.kind) {
1512
+ case graphql_1.Kind.LIST_TYPE: {
1513
+ index += 1;
1514
+ currentType = currentType.type;
1515
+ break;
1516
+ }
1517
+ case graphql_1.Kind.NON_NULL_TYPE: {
1518
+ nonNullIndices.add(index);
1519
+ currentType = currentType.type;
1520
+ break;
1521
+ }
1522
+ default: {
1523
+ currentType = null;
1524
+ break;
1525
+ }
1526
+ }
1527
+ }
1528
+ const levelsArg = directiveNode.arguments?.find((arg) => arg.name.value === string_constants_2.LEVELS);
1529
+ if (!levelsArg || levelsArg.value.kind !== graphql_1.Kind.LIST) {
1530
+ // Should never happen because the argument will have just been validated.
1531
+ errorMessages.push(errors_1.semanticNonNullArgumentErrorMessage);
1532
+ return;
1533
+ }
1534
+ const values = levelsArg.value.values;
1535
+ const typeString = (0, merge_1.printTypeNode)(data.type);
1536
+ const levels = new Set();
1537
+ for (const { value } of values) {
1538
+ const int = parseInt(value, 10);
1539
+ if (Number.isNaN(int)) {
1540
+ errorMessages.push((0, errors_1.semanticNonNullLevelsNaNIndexErrorMessage)(value));
1541
+ continue;
1542
+ }
1543
+ if (int < 0 || int > index) {
1544
+ errorMessages.push((0, errors_1.semanticNonNullLevelsIndexOutOfBoundsErrorMessage)({
1545
+ maxIndex: index,
1546
+ typeString,
1547
+ value,
1548
+ }));
1549
+ continue;
1550
+ }
1551
+ if (!nonNullIndices.has(int)) {
1552
+ levels.add(int);
1553
+ continue;
1554
+ }
1555
+ errorMessages.push((0, errors_1.semanticNonNullLevelsNonNullErrorMessage)({
1556
+ typeString,
1557
+ value,
1558
+ }));
1559
+ }
1560
+ data.nullLevelsBySubgraphName.set(this.subgraphName, levels);
1561
+ }
1473
1562
  extractRequiredScopes({ directiveCoords, orScopes, requiredScopes }) {
1474
1563
  if (orScopes.length > constants_1.MAX_OR_SCOPES) {
1475
1564
  this.invalidORScopesCoords.add(directiveCoords);
@@ -2059,11 +2148,6 @@ class NormalizationFactory {
2059
2148
  this.parentDefinitionDataByTypeName.delete(string_constants_2.EDFS_NATS_STREAM_CONFIGURATION);
2060
2149
  definitions.push(constants_1.EDFS_NATS_STREAM_CONFIGURATION_DEFINITION);
2061
2150
  }
2062
- if (this.referencedDirectiveNames.has(string_constants_2.LINK)) {
2063
- definitions.push(constants_1.LINK_DEFINITION);
2064
- definitions.push(constants_1.LINK_IMPORT_DEFINITION);
2065
- definitions.push(constants_1.LINK_PURPOSE_DEFINITION);
2066
- }
2067
2151
  if (invalidEventsDirectiveDataByRootFieldPath.size > 0) {
2068
2152
  errorMessages.push((0, errors_1.invalidRootTypeFieldEventsDirectivesErrorMessage)(invalidEventsDirectiveDataByRootFieldPath));
2069
2153
  }
@@ -2436,12 +2520,20 @@ class NormalizationFactory {
2436
2520
  definitions.push(constants_1.SUBSCRIPTION_FIELD_CONDITION_DEFINITION);
2437
2521
  definitions.push(constants_1.SUBSCRIPTION_FILTER_VALUE_DEFINITION);
2438
2522
  }
2523
+ if (this.referencedDirectiveNames.has(string_constants_2.LINK)) {
2524
+ definitions.push(constants_1.LINK_DEFINITION);
2525
+ definitions.push(constants_1.LINK_IMPORT_DEFINITION);
2526
+ definitions.push(constants_1.LINK_PURPOSE_DEFINITION);
2527
+ }
2439
2528
  if (this.referencedDirectiveNames.has(string_constants_2.CONFIGURE_DESCRIPTION)) {
2440
2529
  definitions.push(constants_1.CONFIGURE_DESCRIPTION_DEFINITION);
2441
2530
  }
2442
2531
  if (this.referencedDirectiveNames.has(string_constants_2.CONFIGURE_CHILD_DESCRIPTIONS)) {
2443
2532
  definitions.push(constants_1.CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION);
2444
2533
  }
2534
+ if (this.referencedDirectiveNames.has(string_constants_2.REQUIRE_FETCH_REASONS)) {
2535
+ definitions.push(constants_1.REQUIRE_FETCH_REASONS_DEFINITION);
2536
+ }
2445
2537
  for (const directiveDefinition of this.customDirectiveDefinitions.values()) {
2446
2538
  definitions.push(directiveDefinition);
2447
2539
  }
@@ -2566,6 +2658,9 @@ class NormalizationFactory {
2566
2658
  if (parentData.fieldDataByName.size < 1 && !(0, utils_2.isNodeQuery)(parentTypeName, operationTypeNode)) {
2567
2659
  this.errors.push((0, errors_1.noFieldDefinitionsError)((0, utils_5.kindToNodeType)(parentData.kind), parentTypeName));
2568
2660
  }
2661
+ if (isObject && parentData.requireFetchReasonsFieldNames.size > 0) {
2662
+ configurationData.requireFetchReasonsFieldNames = [...parentData.requireFetchReasonsFieldNames];
2663
+ }
2569
2664
  break;
2570
2665
  case graphql_1.Kind.SCALAR_TYPE_DEFINITION:
2571
2666
  if (parentData.extensionType === types_1.ExtensionType.REAL) {