@wundergraph/composition 0.24.0 → 0.25.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.
- package/dist/errors/errors.d.ts +20 -1
- package/dist/errors/errors.js +150 -6
- package/dist/errors/errors.js.map +1 -1
- package/dist/federation/federation-factory.d.ts +11 -2
- package/dist/federation/federation-factory.js +293 -4
- package/dist/federation/federation-factory.js.map +1 -1
- package/dist/federation/utils.d.ts +7 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/normalization/normalization-factory.d.ts +2 -1
- package/dist/normalization/normalization-factory.js +26 -1
- package/dist/normalization/normalization-factory.js.map +1 -1
- package/dist/normalization/walkers.js +11 -1
- package/dist/normalization/walkers.js.map +1 -1
- package/dist/router-configuration/router-configuration.d.ts +12 -0
- package/dist/schema-building/ast.js +3 -3
- package/dist/schema-building/ast.js.map +1 -1
- package/dist/schema-building/type-merging.js +5 -5
- package/dist/schema-building/type-merging.js.map +1 -1
- package/dist/schema-building/utils.d.ts +4 -2
- package/dist/schema-building/utils.js +35 -3
- package/dist/schema-building/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/constants.d.ts +5 -2
- package/dist/utils/constants.js +100 -4
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/integer-constants.d.ts +2 -0
- package/dist/utils/integer-constants.js +6 -0
- package/dist/utils/integer-constants.js.map +1 -0
- package/dist/utils/string-constants.d.ts +20 -0
- package/dist/utils/string-constants.js +23 -3
- package/dist/utils/string-constants.js.map +1 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +57 -15
- package/dist/utils/utils.js.map +1 -1
- package/package.json +2 -2
|
@@ -16,6 +16,7 @@ const utils_5 = require("../schema-building/utils");
|
|
|
16
16
|
const walkers_1 = require("./walkers");
|
|
17
17
|
const lodash_1 = require("lodash");
|
|
18
18
|
const type_merging_1 = require("../schema-building/type-merging");
|
|
19
|
+
const integer_constants_1 = require("../utils/integer-constants");
|
|
19
20
|
class FederationFactory {
|
|
20
21
|
authorizationDataByParentTypeName;
|
|
21
22
|
concreteTypeNamesByAbstractTypeName;
|
|
@@ -50,6 +51,8 @@ class FederationFactory {
|
|
|
50
51
|
potentialPersistedDirectiveDefinitionDataByDirectiveName = new Map();
|
|
51
52
|
routerDefinitions = [constants_1.DEPRECATED_DEFINITION, constants_1.TAG_DEFINITION];
|
|
52
53
|
shareableErrorTypeNames = new Map();
|
|
54
|
+
subscriptionFilterDataByFieldPath = new Map();
|
|
55
|
+
isMaxDepth = false;
|
|
53
56
|
tagNamesByPath = new Map();
|
|
54
57
|
warnings;
|
|
55
58
|
constructor(authorizationDataByParentTypeName, concreteTypeNamesByAbstractTypeName, entityContainersByTypeName, entityInterfaceFederationDataByTypeName, graph, internalSubgraphBySubgraphName, warnings) {
|
|
@@ -634,12 +637,30 @@ class FederationFactory {
|
|
|
634
637
|
this.inaccessiblePaths.add(argumentPath);
|
|
635
638
|
}
|
|
636
639
|
}
|
|
640
|
+
handleSubscriptionFilterDirective(incomingData, fieldPath, baseData) {
|
|
641
|
+
const subscriptionFilters = incomingData.directivesByDirectiveName.get(string_constants_1.SUBSCRIPTION_FILTER);
|
|
642
|
+
if (subscriptionFilters) {
|
|
643
|
+
// There should only be a single entry in the set
|
|
644
|
+
const subgraphName = (0, utils_3.getSingleSetEntry)(incomingData.subgraphNames);
|
|
645
|
+
if (subgraphName === undefined) {
|
|
646
|
+
this.errors.push((0, errors_1.unknownFieldSubgraphNameError)(fieldPath));
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
// @openfed__subscriptionFilter is non-repeatable
|
|
650
|
+
this.subscriptionFilterDataByFieldPath.set(fieldPath, {
|
|
651
|
+
directive: subscriptionFilters[0],
|
|
652
|
+
fieldData: baseData || incomingData,
|
|
653
|
+
directiveSubgraphName: subgraphName,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
}
|
|
637
657
|
upsertFieldData(fieldDataByFieldName, incomingData, isParentInaccessible) {
|
|
638
658
|
const fieldPath = `${incomingData.renamedParentTypeName}.${incomingData.name}`;
|
|
639
659
|
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, incomingData.namedTypeName, () => new Set()).add(fieldPath);
|
|
640
660
|
this.namedOutputTypeNames.add(incomingData.namedTypeName);
|
|
641
661
|
const existingData = fieldDataByFieldName.get(incomingData.name);
|
|
642
662
|
const baseData = existingData || incomingData;
|
|
663
|
+
this.handleSubscriptionFilterDirective(incomingData, fieldPath, baseData);
|
|
643
664
|
(0, utils_5.extractPersistedDirectives)(baseData.persistedDirectivesData, incomingData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
644
665
|
const isFieldInaccessible = (0, utils_5.isNodeDataInaccessible)(incomingData);
|
|
645
666
|
if (isParentInaccessible || isFieldInaccessible) {
|
|
@@ -783,6 +804,7 @@ class FederationFactory {
|
|
|
783
804
|
type: fieldData.type,
|
|
784
805
|
};
|
|
785
806
|
const fieldPath = `${fieldData.renamedParentTypeName}.${fieldData.name}`;
|
|
807
|
+
this.handleSubscriptionFilterDirective(fieldData, fieldPath);
|
|
786
808
|
(0, utils_3.getValueOrDefault)(this.pathsByNamedTypeName, fieldData.namedTypeName, () => new Set()).add(fieldPath);
|
|
787
809
|
this.namedOutputTypeNames.add(fieldData.namedTypeName);
|
|
788
810
|
(0, utils_5.extractPersistedDirectives)(fieldData.persistedDirectivesData, fieldData.directivesByDirectiveName, this.persistedDirectiveDefinitionByDirectiveName);
|
|
@@ -941,7 +963,7 @@ class FederationFactory {
|
|
|
941
963
|
for (const [fieldName, fieldData] of data.fieldDataByFieldName) {
|
|
942
964
|
const fieldPath = `${fieldData.renamedParentTypeName}.${fieldName}`;
|
|
943
965
|
this.inaccessiblePaths.add(fieldPath);
|
|
944
|
-
for (const
|
|
966
|
+
for (const inputValueData of fieldData.argumentDataByArgumentName.values()) {
|
|
945
967
|
this.inaccessiblePaths.add(inputValueData.renamedPath);
|
|
946
968
|
}
|
|
947
969
|
}
|
|
@@ -1327,7 +1349,7 @@ class FederationFactory {
|
|
|
1327
1349
|
federateSubgraphData() {
|
|
1328
1350
|
this.federateInternalSubgraphData();
|
|
1329
1351
|
this.handleEntityInterfaces();
|
|
1330
|
-
for (const
|
|
1352
|
+
for (const objectExtensionData of this.objectExtensionDataByTypeName.values()) {
|
|
1331
1353
|
this.upsertValidObjectExtensionData(objectExtensionData);
|
|
1332
1354
|
}
|
|
1333
1355
|
// generate the map of tag data that is used by contracts
|
|
@@ -1336,8 +1358,7 @@ class FederationFactory {
|
|
|
1336
1358
|
}
|
|
1337
1359
|
validateInterfaceImplementationsAndPushToDocumentDefinitions(interfaceImplementations) {
|
|
1338
1360
|
for (const { data, clientSchemaFieldNodes } of interfaceImplementations) {
|
|
1339
|
-
|
|
1340
|
-
data.node.interfaces = validInterfaces;
|
|
1361
|
+
data.node.interfaces = this.getValidImplementedInterfaces(data);
|
|
1341
1362
|
this.routerDefinitions.push((0, utils_5.getNodeForRouterSchemaByData)(data, this.persistedDirectiveDefinitionByDirectiveName, this.errors));
|
|
1342
1363
|
if ((0, utils_5.isNodeDataInaccessible)(data)) {
|
|
1343
1364
|
this.validateReferencesOfInaccessibleType(data);
|
|
@@ -1404,7 +1425,272 @@ class FederationFactory {
|
|
|
1404
1425
|
}
|
|
1405
1426
|
this.errors.push(errors_1.noQueryRootTypeError);
|
|
1406
1427
|
}
|
|
1428
|
+
validateSubscriptionFieldConditionFieldPath(conditionFieldPath, objectData, inputFieldPath, directiveSubgraphName, fieldErrorMessages) {
|
|
1429
|
+
const paths = conditionFieldPath.split(string_constants_1.PERIOD);
|
|
1430
|
+
if (paths.length < 1) {
|
|
1431
|
+
fieldErrorMessages.push((0, errors_1.invalidSubscriptionFieldConditionFieldPathErrorMessage)(inputFieldPath, conditionFieldPath));
|
|
1432
|
+
return [];
|
|
1433
|
+
}
|
|
1434
|
+
let lastData = objectData;
|
|
1435
|
+
if (this.inaccessiblePaths.has(lastData.renamedTypeName)) {
|
|
1436
|
+
fieldErrorMessages.push((0, errors_1.inaccessibleSubscriptionFieldConditionFieldPathFieldErrorMessage)(inputFieldPath, conditionFieldPath, paths[0], lastData.renamedTypeName));
|
|
1437
|
+
return [];
|
|
1438
|
+
}
|
|
1439
|
+
let partialConditionFieldPath = '';
|
|
1440
|
+
for (let i = 0; i < paths.length; i++) {
|
|
1441
|
+
const fieldName = paths[i];
|
|
1442
|
+
partialConditionFieldPath += partialConditionFieldPath.length > 0 ? `.${fieldName}` : fieldName;
|
|
1443
|
+
if (lastData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1444
|
+
fieldErrorMessages.push((0, errors_1.invalidSubscriptionFieldConditionFieldPathParentErrorMessage)(inputFieldPath, conditionFieldPath, partialConditionFieldPath));
|
|
1445
|
+
return [];
|
|
1446
|
+
}
|
|
1447
|
+
const fieldData = lastData.fieldDataByFieldName.get(fieldName);
|
|
1448
|
+
if (!fieldData) {
|
|
1449
|
+
fieldErrorMessages.push((0, errors_1.undefinedSubscriptionFieldConditionFieldPathFieldErrorMessage)(inputFieldPath, conditionFieldPath, partialConditionFieldPath, fieldName, lastData.renamedTypeName));
|
|
1450
|
+
return [];
|
|
1451
|
+
}
|
|
1452
|
+
const fieldPath = `${lastData.renamedTypeName}.${fieldName}`;
|
|
1453
|
+
if (!fieldData.subgraphNames.has(directiveSubgraphName)) {
|
|
1454
|
+
fieldErrorMessages.push((0, errors_1.invalidSubscriptionFieldConditionFieldPathFieldErrorMessage)(inputFieldPath, conditionFieldPath, partialConditionFieldPath, fieldPath, directiveSubgraphName));
|
|
1455
|
+
return [];
|
|
1456
|
+
}
|
|
1457
|
+
if (constants_1.BASE_SCALARS.has(fieldData.namedTypeName)) {
|
|
1458
|
+
lastData = { kind: graphql_1.Kind.SCALAR_TYPE_DEFINITION, name: fieldData.namedTypeName };
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
lastData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, fieldData.namedTypeName, string_constants_1.PARENT_DEFINITION_DATA);
|
|
1462
|
+
if (this.inaccessiblePaths.has(fieldPath)) {
|
|
1463
|
+
fieldErrorMessages.push((0, errors_1.inaccessibleSubscriptionFieldConditionFieldPathFieldErrorMessage)(inputFieldPath, conditionFieldPath, partialConditionFieldPath, fieldPath));
|
|
1464
|
+
return [];
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
if (!(0, utils_5.isLeafKind)(lastData.kind)) {
|
|
1468
|
+
fieldErrorMessages.push((0, errors_1.nonLeafSubscriptionFieldConditionFieldPathFinalFieldErrorMessage)(inputFieldPath, conditionFieldPath, paths[paths.length - 1], (0, utils_3.kindToTypeString)(lastData.kind), lastData.name));
|
|
1469
|
+
return [];
|
|
1470
|
+
}
|
|
1471
|
+
return paths;
|
|
1472
|
+
}
|
|
1473
|
+
validateSubscriptionFieldCondition(objectValueNode, condition, objectData, depth, inputPath, directiveSubgraphName, errorMessages) {
|
|
1474
|
+
if (depth > integer_constants_1.MAX_SUBSCRIPTION_FILTER_DEPTH || this.isMaxDepth) {
|
|
1475
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionDepthExceededErrorMessage)(inputPath));
|
|
1476
|
+
this.isMaxDepth = true;
|
|
1477
|
+
return false;
|
|
1478
|
+
}
|
|
1479
|
+
let hasErrors = false;
|
|
1480
|
+
const validFieldNames = new Set([string_constants_1.FIELD_PATH, string_constants_1.VALUES]);
|
|
1481
|
+
const duplicatedFieldNames = new Set();
|
|
1482
|
+
const invalidFieldNames = new Set();
|
|
1483
|
+
const fieldErrorMessages = [];
|
|
1484
|
+
for (const objectFieldNode of objectValueNode.fields) {
|
|
1485
|
+
const inputFieldName = objectFieldNode.name.value;
|
|
1486
|
+
const inputFieldPath = inputPath + `.${inputFieldName}`;
|
|
1487
|
+
switch (inputFieldName) {
|
|
1488
|
+
case string_constants_1.FIELD_PATH: {
|
|
1489
|
+
if (validFieldNames.has(string_constants_1.FIELD_PATH)) {
|
|
1490
|
+
validFieldNames.delete(string_constants_1.FIELD_PATH);
|
|
1491
|
+
}
|
|
1492
|
+
else {
|
|
1493
|
+
hasErrors = true;
|
|
1494
|
+
duplicatedFieldNames.add(string_constants_1.FIELD_PATH);
|
|
1495
|
+
break;
|
|
1496
|
+
}
|
|
1497
|
+
if (objectFieldNode.value.kind !== graphql_1.Kind.STRING) {
|
|
1498
|
+
fieldErrorMessages.push((0, errors_1.invalidInputFieldTypeErrorMessage)(inputFieldPath, string_constants_1.STRING, (0, utils_3.kindToTypeString)(objectFieldNode.value.kind)));
|
|
1499
|
+
hasErrors = true;
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
const fieldPath = this.validateSubscriptionFieldConditionFieldPath(objectFieldNode.value.value, objectData, inputFieldPath, directiveSubgraphName, fieldErrorMessages);
|
|
1503
|
+
if (fieldPath.length < 1) {
|
|
1504
|
+
hasErrors = true;
|
|
1505
|
+
break;
|
|
1506
|
+
}
|
|
1507
|
+
condition.fieldPath = fieldPath;
|
|
1508
|
+
break;
|
|
1509
|
+
}
|
|
1510
|
+
case string_constants_1.VALUES: {
|
|
1511
|
+
if (validFieldNames.has(string_constants_1.VALUES)) {
|
|
1512
|
+
validFieldNames.delete(string_constants_1.VALUES);
|
|
1513
|
+
}
|
|
1514
|
+
else {
|
|
1515
|
+
hasErrors = true;
|
|
1516
|
+
duplicatedFieldNames.add(string_constants_1.VALUES);
|
|
1517
|
+
break;
|
|
1518
|
+
}
|
|
1519
|
+
const objectFieldValueKind = objectFieldNode.value.kind;
|
|
1520
|
+
if (objectFieldValueKind == graphql_1.Kind.NULL || objectFieldValueKind == graphql_1.Kind.OBJECT) {
|
|
1521
|
+
fieldErrorMessages.push((0, errors_1.invalidInputFieldTypeErrorMessage)(inputFieldPath, string_constants_1.LIST, (0, utils_3.kindToTypeString)(objectFieldNode.value.kind)));
|
|
1522
|
+
hasErrors = true;
|
|
1523
|
+
break;
|
|
1524
|
+
}
|
|
1525
|
+
// Coerce scalars into a list
|
|
1526
|
+
if (objectFieldValueKind !== graphql_1.Kind.LIST) {
|
|
1527
|
+
condition.values = [(0, utils_5.getSubscriptionFilterValue)(objectFieldNode.value)];
|
|
1528
|
+
break;
|
|
1529
|
+
}
|
|
1530
|
+
// Prevent duplicate values
|
|
1531
|
+
const values = new Set();
|
|
1532
|
+
const invalidIndices = [];
|
|
1533
|
+
for (let i = 0; i < objectFieldNode.value.values.length; i++) {
|
|
1534
|
+
const valueNode = objectFieldNode.value.values[i];
|
|
1535
|
+
if (valueNode.kind === graphql_1.Kind.OBJECT || valueNode.kind === graphql_1.Kind.LIST) {
|
|
1536
|
+
hasErrors = true;
|
|
1537
|
+
invalidIndices.push(i);
|
|
1538
|
+
continue;
|
|
1539
|
+
}
|
|
1540
|
+
values.add((0, utils_5.getSubscriptionFilterValue)(valueNode));
|
|
1541
|
+
}
|
|
1542
|
+
if (invalidIndices.length > 0) {
|
|
1543
|
+
errorMessages.push((0, errors_1.subscriptionFieldConditionInvalidValuesArrayErrorMessage)(inputFieldPath, invalidIndices));
|
|
1544
|
+
continue;
|
|
1545
|
+
}
|
|
1546
|
+
if (values.size < 1) {
|
|
1547
|
+
errorMessages.push((0, errors_1.subscriptionFieldConditionEmptyValuesArrayErrorMessage)(inputFieldPath));
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
condition.values = [...values];
|
|
1551
|
+
break;
|
|
1552
|
+
}
|
|
1553
|
+
default: {
|
|
1554
|
+
invalidFieldNames.add(inputFieldName);
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
if (!hasErrors) {
|
|
1559
|
+
return true;
|
|
1560
|
+
}
|
|
1561
|
+
errorMessages.push((0, errors_1.subscriptionFieldConditionInvalidInputFieldErrorMessage)(inputPath, [...validFieldNames], [...duplicatedFieldNames], [...invalidFieldNames], fieldErrorMessages));
|
|
1562
|
+
return false;
|
|
1563
|
+
}
|
|
1564
|
+
validateSubscriptionFilterCondition(objectValueNode, configuration, objectData, depth, inputPath, directiveSubgraphName, errorMessages) {
|
|
1565
|
+
if (depth > integer_constants_1.MAX_SUBSCRIPTION_FILTER_DEPTH || this.isMaxDepth) {
|
|
1566
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionDepthExceededErrorMessage)(inputPath));
|
|
1567
|
+
this.isMaxDepth = true;
|
|
1568
|
+
return false;
|
|
1569
|
+
}
|
|
1570
|
+
depth += 1;
|
|
1571
|
+
if (objectValueNode.fields.length !== 1) {
|
|
1572
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionInvalidInputFieldNumberErrorMessage)(inputPath, objectValueNode.fields.length));
|
|
1573
|
+
return false;
|
|
1574
|
+
}
|
|
1575
|
+
const objectFieldNode = objectValueNode.fields[0];
|
|
1576
|
+
const fieldName = objectFieldNode.name.value;
|
|
1577
|
+
if (!string_constants_1.SUBSCRIPTION_FILTER_INPUT_NAMES.has(fieldName)) {
|
|
1578
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionInvalidInputFieldErrorMessage)(inputPath, fieldName));
|
|
1579
|
+
return false;
|
|
1580
|
+
}
|
|
1581
|
+
const inputFieldPath = inputPath + `.${fieldName}`;
|
|
1582
|
+
switch (objectFieldNode.value.kind) {
|
|
1583
|
+
case graphql_1.Kind.OBJECT: {
|
|
1584
|
+
switch (fieldName) {
|
|
1585
|
+
case string_constants_1.IN_UPPER: {
|
|
1586
|
+
configuration.in = { fieldPath: [], values: [] };
|
|
1587
|
+
return this.validateSubscriptionFieldCondition(objectFieldNode.value, configuration.in, objectData, depth, inputPath + `.IN`, directiveSubgraphName, errorMessages);
|
|
1588
|
+
}
|
|
1589
|
+
case string_constants_1.NOT_UPPER: {
|
|
1590
|
+
configuration.not = {};
|
|
1591
|
+
return this.validateSubscriptionFilterCondition(objectFieldNode.value, configuration.not, objectData, depth, inputPath + `.NOT`, directiveSubgraphName, errorMessages);
|
|
1592
|
+
}
|
|
1593
|
+
default:
|
|
1594
|
+
// The field is guaranteed to be an AND or an OR
|
|
1595
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionInvalidInputFieldTypeErrorMessage)(inputFieldPath, string_constants_1.LIST, string_constants_1.OBJECT));
|
|
1596
|
+
return false;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
case graphql_1.Kind.LIST: {
|
|
1600
|
+
const listConfigurations = [];
|
|
1601
|
+
switch (fieldName) {
|
|
1602
|
+
case string_constants_1.AND_UPPER: {
|
|
1603
|
+
configuration.and = listConfigurations;
|
|
1604
|
+
break;
|
|
1605
|
+
}
|
|
1606
|
+
case string_constants_1.OR_UPPER: {
|
|
1607
|
+
configuration.or = listConfigurations;
|
|
1608
|
+
break;
|
|
1609
|
+
}
|
|
1610
|
+
default:
|
|
1611
|
+
// The field is guaranteed to be an IN or a NOT
|
|
1612
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionInvalidInputFieldTypeErrorMessage)(inputFieldPath, string_constants_1.OBJECT, string_constants_1.LIST));
|
|
1613
|
+
return false;
|
|
1614
|
+
}
|
|
1615
|
+
const listLength = objectFieldNode.value.values.length;
|
|
1616
|
+
if (listLength < 1 || listLength > 5) {
|
|
1617
|
+
errorMessages.push((0, errors_1.subscriptionFilterArrayConditionInvalidLengthErrorMessage)(inputFieldPath, listLength));
|
|
1618
|
+
return false;
|
|
1619
|
+
}
|
|
1620
|
+
let isValid = true;
|
|
1621
|
+
const invalidIndices = [];
|
|
1622
|
+
for (let i = 0; i < objectFieldNode.value.values.length; i++) {
|
|
1623
|
+
const arrayIndexPath = inputFieldPath + `[${i}]`;
|
|
1624
|
+
const listValueNode = objectFieldNode.value.values[i];
|
|
1625
|
+
if (listValueNode.kind !== graphql_1.Kind.OBJECT) {
|
|
1626
|
+
invalidIndices.push(i);
|
|
1627
|
+
continue;
|
|
1628
|
+
}
|
|
1629
|
+
const listConfiguration = {};
|
|
1630
|
+
isValid &&= this.validateSubscriptionFilterCondition(listValueNode, listConfiguration, objectData, depth, arrayIndexPath, directiveSubgraphName, errorMessages);
|
|
1631
|
+
if (isValid) {
|
|
1632
|
+
listConfigurations.push(listConfiguration);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
if (invalidIndices.length > 0) {
|
|
1636
|
+
errorMessages.push((0, errors_1.subscriptionFilterArrayConditionInvalidItemTypeErrorMessage)(inputFieldPath, invalidIndices));
|
|
1637
|
+
return false;
|
|
1638
|
+
}
|
|
1639
|
+
return isValid;
|
|
1640
|
+
}
|
|
1641
|
+
default: {
|
|
1642
|
+
const expectedTypeString = string_constants_1.SUBSCRIPTION_FILTER_LIST_INPUT_NAMES.has(fieldName) ? string_constants_1.LIST : string_constants_1.OBJECT;
|
|
1643
|
+
errorMessages.push((0, errors_1.subscriptionFilterConditionInvalidInputFieldTypeErrorMessage)(inputFieldPath, expectedTypeString, (0, utils_3.kindToTypeString)(objectFieldNode.value.kind)));
|
|
1644
|
+
return false;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
validateSubscriptionFilterAndGenerateConfiguration(directiveNode, objectData, fieldPath, fieldName, parentTypeName, directiveSubgraphName) {
|
|
1649
|
+
// directive validation occurs elsewhere
|
|
1650
|
+
if (!directiveNode.arguments || directiveNode.arguments.length !== 1) {
|
|
1651
|
+
return;
|
|
1652
|
+
}
|
|
1653
|
+
const argumentNode = directiveNode.arguments[0];
|
|
1654
|
+
if (argumentNode.value.kind !== graphql_1.Kind.OBJECT) {
|
|
1655
|
+
this.errors.push((0, errors_1.invalidSubscriptionFilterDirectiveError)(fieldPath, [
|
|
1656
|
+
(0, errors_1.subscriptionFilterConditionInvalidInputFieldTypeErrorMessage)(string_constants_1.CONDITION, 'object', (0, utils_3.kindToTypeString)(argumentNode.value.kind)),
|
|
1657
|
+
]));
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
const condition = {};
|
|
1661
|
+
const errorMessages = [];
|
|
1662
|
+
if (!this.validateSubscriptionFilterCondition(argumentNode.value, condition, objectData, 0, string_constants_1.CONDITION, directiveSubgraphName, errorMessages)) {
|
|
1663
|
+
this.errors.push((0, errors_1.invalidSubscriptionFilterDirectiveError)(fieldPath, errorMessages));
|
|
1664
|
+
this.isMaxDepth = false;
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
(0, utils_3.getValueOrDefault)(this.fieldConfigurationByFieldPath, fieldPath, () => ({
|
|
1668
|
+
argumentNames: [],
|
|
1669
|
+
fieldName,
|
|
1670
|
+
typeName: parentTypeName,
|
|
1671
|
+
})).subscriptionFilterCondition = condition;
|
|
1672
|
+
}
|
|
1673
|
+
validateSubscriptionFiltersAndGenerateConfiguration() {
|
|
1674
|
+
for (const [fieldPath, data] of this.subscriptionFilterDataByFieldPath) {
|
|
1675
|
+
if (this.inaccessiblePaths.has(fieldPath)) {
|
|
1676
|
+
continue;
|
|
1677
|
+
}
|
|
1678
|
+
const namedTypeData = (0, utils_3.getOrThrowError)(this.parentDefinitionDataByTypeName, data.fieldData.namedTypeName, string_constants_1.PARENT_DEFINITION_DATA);
|
|
1679
|
+
if ((0, utils_5.isNodeDataInaccessible)(namedTypeData)) {
|
|
1680
|
+
// @inaccessible error are caught elsewhere
|
|
1681
|
+
continue;
|
|
1682
|
+
}
|
|
1683
|
+
// TODO handle Unions and Interfaces
|
|
1684
|
+
if (namedTypeData.kind !== graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1685
|
+
continue;
|
|
1686
|
+
}
|
|
1687
|
+
this.validateSubscriptionFilterAndGenerateConfiguration(data.directive, namedTypeData, fieldPath, data.fieldData.name, data.fieldData.renamedParentTypeName, data.directiveSubgraphName);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1407
1690
|
buildFederationResult() {
|
|
1691
|
+
if (this.subscriptionFilterDataByFieldPath.size > 0) {
|
|
1692
|
+
this.validateSubscriptionFiltersAndGenerateConfiguration();
|
|
1693
|
+
}
|
|
1408
1694
|
if (this.invalidOrScopesHostPaths.size > 0) {
|
|
1409
1695
|
this.errors.push((0, errors_1.orScopesLimitError)(utils_3.maxOrScopes, [...this.invalidOrScopesHostPaths]));
|
|
1410
1696
|
}
|
|
@@ -1557,6 +1843,9 @@ class FederationFactory {
|
|
|
1557
1843
|
}
|
|
1558
1844
|
}
|
|
1559
1845
|
}
|
|
1846
|
+
if (this.subscriptionFilterDataByFieldPath.size > 0) {
|
|
1847
|
+
this.validateSubscriptionFiltersAndGenerateConfiguration();
|
|
1848
|
+
}
|
|
1560
1849
|
for (const data of this.potentialPersistedDirectiveDefinitionDataByDirectiveName.values()) {
|
|
1561
1850
|
(0, utils_5.addValidPersistedDirectiveDefinitionNodeByData)(this.routerDefinitions, data, this.persistedDirectiveDefinitionByDirectiveName, this.errors);
|
|
1562
1851
|
}
|