@wundergraph/composition 0.44.0 → 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 (36) 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/schema-building/types.d.ts +1 -0
  6. package/dist/schema-building/utils.d.ts +2 -2
  7. package/dist/schema-building/utils.js +8 -4
  8. package/dist/schema-building/utils.js.map +1 -1
  9. package/dist/tsconfig.tsbuildinfo +1 -1
  10. package/dist/types/types.d.ts +1 -0
  11. package/dist/utils/composition-version.js +1 -1
  12. package/dist/utils/string-constants.d.ts +7 -4
  13. package/dist/utils/string-constants.js +12 -9
  14. package/dist/utils/string-constants.js.map +1 -1
  15. package/dist/utils/utils.d.ts +2 -1
  16. package/dist/utils/utils.js +28 -3
  17. package/dist/utils/utils.js.map +1 -1
  18. package/dist/v1/federation/federation-factory.d.ts +3 -1
  19. package/dist/v1/federation/federation-factory.js +60 -5
  20. package/dist/v1/federation/federation-factory.js.map +1 -1
  21. package/dist/v1/normalization/directive-definition-data.d.ts +1 -0
  22. package/dist/v1/normalization/directive-definition-data.js +36 -1
  23. package/dist/v1/normalization/directive-definition-data.js.map +1 -1
  24. package/dist/v1/normalization/normalization-factory.d.ts +2 -1
  25. package/dist/v1/normalization/normalization-factory.js +84 -2
  26. package/dist/v1/normalization/normalization-factory.js.map +1 -1
  27. package/dist/v1/normalization/types.d.ts +7 -1
  28. package/dist/v1/normalization/utils.js +1 -0
  29. package/dist/v1/normalization/utils.js.map +1 -1
  30. package/dist/v1/utils/constants.d.ts +1 -0
  31. package/dist/v1/utils/constants.js +35 -1
  32. package/dist/v1/utils/constants.js.map +1 -1
  33. package/dist/v1/utils/utils.d.ts +2 -1
  34. package/dist/v1/utils/utils.js +17 -0
  35. package/dist/v1/utils/utils.js.map +1 -1
  36. package/package.json +2 -2
@@ -248,8 +248,10 @@ class NormalizationFactory {
248
248
  const directiveName = directiveNode.name.value;
249
249
  const parentTypeName = data.kind === graphql_1.Kind.FIELD_DEFINITION ? data.renamedParentTypeName || data.originalParentTypeName : data.name;
250
250
  const isAuthenticated = directiveName === string_constants_2.AUTHENTICATED;
251
+ const isField = (0, utils_4.isFieldData)(data);
251
252
  const isOverride = directiveName === string_constants_2.OVERRIDE;
252
253
  const isRequiresScopes = directiveName === string_constants_2.REQUIRES_SCOPES;
254
+ const isSemanticNonNull = directiveName === string_constants_2.SEMANTIC_NON_NULL;
253
255
  if (!directiveNode.arguments || directiveNode.arguments.length < 1) {
254
256
  if (definitionData.requiredArgumentNames.size > 0) {
255
257
  errorMessages.push((0, errors_1.undefinedRequiredArgumentsErrorMessage)(directiveName, requiredArgumentNames, []));
@@ -257,6 +259,18 @@ class NormalizationFactory {
257
259
  if (isAuthenticated) {
258
260
  this.handleAuthenticatedDirective(data, parentTypeName);
259
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
+ }
260
274
  return errorMessages;
261
275
  }
262
276
  const definedArgumentNames = new Set();
@@ -279,8 +293,11 @@ class NormalizationFactory {
279
293
  errorMessages.push((0, errors_1.invalidArgumentValueErrorMessage)((0, graphql_1.print)(argumentNode.value), `@${directiveName}`, argumentName, (0, merge_1.printTypeNode)(argumentData.typeNode)));
280
294
  continue;
281
295
  }
282
- // The directive location validation means the kind check should be unnecessary
283
- 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) {
284
301
  this.handleOverrideDirective({
285
302
  data,
286
303
  directiveCoords,
@@ -289,6 +306,14 @@ class NormalizationFactory {
289
306
  });
290
307
  continue;
291
308
  }
309
+ if (isSemanticNonNull && isField) {
310
+ this.handleSemanticNonNullDirective({
311
+ data,
312
+ directiveNode,
313
+ errorMessages,
314
+ });
315
+ continue;
316
+ }
292
317
  if (!isRequiresScopes || argumentName !== string_constants_2.SCOPES) {
293
318
  continue;
294
319
  }
@@ -672,6 +697,7 @@ class NormalizationFactory {
672
697
  namedTypeKind: constants_1.BASE_SCALARS.has(namedTypeName) ? graphql_1.Kind.SCALAR_TYPE_DEFINITION : graphql_1.Kind.NULL,
673
698
  namedTypeName,
674
699
  node: (0, ast_1.getMutableFieldNode)(node, fieldCoords, this.errors),
700
+ nullLevelsBySubgraphName: new Map(),
675
701
  originalParentTypeName: this.originalParentTypeName,
676
702
  persistedDirectivesData: (0, utils_4.newPersistedDirectivesData)(),
677
703
  renamedParentTypeName: parentTypeName,
@@ -1477,6 +1503,62 @@ class NormalizationFactory {
1477
1503
  const overrideDataForSubgraph = (0, utils_5.getValueOrDefault)(this.overridesByTargetSubgraphName, targetSubgraphName, () => new Map());
1478
1504
  (0, utils_5.getValueOrDefault)(overrideDataForSubgraph, data.renamedParentTypeName, () => new Set()).add(data.name);
1479
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
+ }
1480
1562
  extractRequiredScopes({ directiveCoords, orScopes, requiredScopes }) {
1481
1563
  if (orScopes.length > constants_1.MAX_OR_SCOPES) {
1482
1564
  this.invalidORScopesCoords.add(directiveCoords);