@apollo/federation-internals 2.11.4 → 2.11.5-preview.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.
- package/dist/argumentCompositionStrategies.d.ts +2 -1
- package/dist/argumentCompositionStrategies.d.ts.map +1 -1
- package/dist/argumentCompositionStrategies.js +24 -2
- package/dist/argumentCompositionStrategies.js.map +1 -1
- package/dist/definitions.d.ts +1 -0
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +5 -1
- package/dist/definitions.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.js +2 -2
- package/dist/error.js.map +1 -1
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +10 -13
- package/dist/federation.js.map +1 -1
- package/dist/specs/authenticatedSpec.d.ts.map +1 -1
- package/dist/specs/authenticatedSpec.js.map +1 -1
- package/dist/specs/policySpec.d.ts.map +1 -1
- package/dist/specs/policySpec.js.map +1 -1
- package/dist/specs/requiresScopesSpec.d.ts.map +1 -1
- package/dist/specs/requiresScopesSpec.js.map +1 -1
- package/package.json +1 -1
- package/src/argumentCompositionStrategies.ts +38 -4
- package/src/definitions.ts +4 -0
- package/src/error.ts +4 -4
- package/src/federation.ts +19 -18
- package/src/specs/authenticatedSpec.ts +4 -0
- package/src/specs/policySpec.ts +4 -0
- package/src/specs/requiresScopesSpec.ts +4 -0
package/src/federation.ts
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
isWrapperType,
|
|
38
38
|
possibleRuntimeTypes,
|
|
39
39
|
isIntType,
|
|
40
|
-
Type, isFieldDefinition,
|
|
40
|
+
Type, isFieldDefinition, isElementNamedType,
|
|
41
41
|
} from "./definitions";
|
|
42
42
|
import { assert, MultiMap, printHumanReadableList, OrderedMap, mapValues, assertUnreachable } from "./utils";
|
|
43
43
|
import { SDLValidationRule } from "graphql/validation/ValidationContext";
|
|
@@ -1071,7 +1071,7 @@ function validateListSizeAppliedToList(
|
|
|
1071
1071
|
) {
|
|
1072
1072
|
const { sizedFields = [] } = application.arguments();
|
|
1073
1073
|
// @listSize must be applied to a list https://ibm.github.io/graphql-specs/cost-spec.html#sec-Valid-List-Size-Target
|
|
1074
|
-
if (!sizedFields.length && parent.type && !isListType(parent.type)) {
|
|
1074
|
+
if (!sizedFields.length && parent.type && !isListType(parent.type) && !isNonNullListType(parent.type)) {
|
|
1075
1075
|
errorCollector.push(ERRORS.LIST_SIZE_APPLIED_TO_NON_LIST.err(
|
|
1076
1076
|
`"${parent.coordinate}" is not a list`,
|
|
1077
1077
|
{ nodes: sourceASTs(application, parent) },
|
|
@@ -1141,8 +1141,9 @@ function validateSizedFieldsAreValidLists(
|
|
|
1141
1141
|
) {
|
|
1142
1142
|
const { sizedFields = [] } = application.arguments();
|
|
1143
1143
|
// Validate sizedFields https://ibm.github.io/graphql-specs/cost-spec.html#sec-Valid-Sized-Fields-Target
|
|
1144
|
-
if (sizedFields.length) {
|
|
1145
|
-
|
|
1144
|
+
if (sizedFields.length && parent.type) {
|
|
1145
|
+
const baseParentType = baseType(parent.type);
|
|
1146
|
+
if (!isCompositeType(baseParentType)) {
|
|
1146
1147
|
// The output type must have fields
|
|
1147
1148
|
errorCollector.push(ERRORS.LIST_SIZE_INVALID_SIZED_FIELD.err(
|
|
1148
1149
|
`Sized fields cannot be used because "${parent.type}" is not a composite type`,
|
|
@@ -1150,11 +1151,11 @@ function validateSizedFieldsAreValidLists(
|
|
|
1150
1151
|
));
|
|
1151
1152
|
} else {
|
|
1152
1153
|
for (const sizedFieldName of sizedFields) {
|
|
1153
|
-
const sizedField =
|
|
1154
|
+
const sizedField = baseParentType.field(sizedFieldName);
|
|
1154
1155
|
if (!sizedField) {
|
|
1155
1156
|
// Sized fields must be present on the output type
|
|
1156
1157
|
errorCollector.push(ERRORS.LIST_SIZE_INVALID_SIZED_FIELD.err(
|
|
1157
|
-
`Sized field "${sizedFieldName}" is not a field on type "${
|
|
1158
|
+
`Sized field "${sizedFieldName}" is not a field on type "${baseParentType.coordinate}"`,
|
|
1158
1159
|
{ nodes: sourceASTs(application, parent) }
|
|
1159
1160
|
));
|
|
1160
1161
|
} else if (!sizedField.type || !(isListType(sizedField.type) || isNonNullListType(sizedField.type))) {
|
|
@@ -1838,7 +1839,7 @@ export class FederationBlueprint extends SchemaBlueprint {
|
|
|
1838
1839
|
validateSizedFieldsAreValidLists(application, parent, errorCollector);
|
|
1839
1840
|
}
|
|
1840
1841
|
|
|
1841
|
-
// Validate @authenticated, @requireScopes and @policy
|
|
1842
|
+
// Validate @authenticated, @requireScopes and @policy usage on interfaces and interface objects
|
|
1842
1843
|
validateNoAuthenticationOnInterfaces(metadata, errorCollector);
|
|
1843
1844
|
|
|
1844
1845
|
return errorCollector;
|
|
@@ -2899,15 +2900,15 @@ function validateNoAuthenticationOnInterfaces(metadata: FederationMetadata, erro
|
|
|
2899
2900
|
const policyDirective = metadata.policyDirective();
|
|
2900
2901
|
[authenticatedDirective, requiresScopesDirective, policyDirective].forEach((directive) => {
|
|
2901
2902
|
for (const application of directive.applications()) {
|
|
2902
|
-
const element = application.parent;
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2903
|
+
const element: SchemaElement<any, any> = application.parent;
|
|
2904
|
+
if (
|
|
2905
|
+
// Is it applied on interface or interface object types?
|
|
2906
|
+
(isElementNamedType(element) &&
|
|
2907
|
+
(isInterfaceType(element) || isInterfaceObjectType(element))
|
|
2908
|
+
) ||
|
|
2909
|
+
// Is it applied on interface fields?
|
|
2910
|
+
(isFieldDefinition(element) && isInterfaceType(element.parent))
|
|
2911
|
+
) {
|
|
2911
2912
|
let kind = '';
|
|
2912
2913
|
switch (element.kind) {
|
|
2913
2914
|
case 'FieldDefinition':
|
|
@@ -2920,8 +2921,8 @@ function validateNoAuthenticationOnInterfaces(metadata: FederationMetadata, erro
|
|
|
2920
2921
|
kind = 'interface object';
|
|
2921
2922
|
break;
|
|
2922
2923
|
}
|
|
2923
|
-
errorCollector.push(ERRORS.
|
|
2924
|
-
`Invalid use of @${directive.name} on ${kind} "${element.coordinate}": @${directive.name} cannot be applied on interfaces, interface
|
|
2924
|
+
errorCollector.push(ERRORS.AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE.err(
|
|
2925
|
+
`Invalid use of @${directive.name} on ${kind} "${element.coordinate}": @${directive.name} cannot be applied on interfaces, interface fields and interface objects`,
|
|
2925
2926
|
{nodes: sourceASTs(application, element.parent)},
|
|
2926
2927
|
));
|
|
2927
2928
|
}
|
|
@@ -24,6 +24,10 @@ export class AuthenticatedSpecDefinition extends FeatureDefinition {
|
|
|
24
24
|
minimumFederationVersion,
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
+
// WARNING: we cannot declare staticArgumentTransform() as access control merge logic needs to propagate
|
|
28
|
+
// requirements upwards/downwards between types and interfaces. We hijack the merge process by providing
|
|
29
|
+
// implementations/interfaces as "additional sources". This means that we cannot apply staticArgumentTransform()
|
|
30
|
+
// as subgraph index index will be wrong/undefined.
|
|
27
31
|
this.registerDirective(createDirectiveSpecification({
|
|
28
32
|
name: AuthenticatedSpecDefinition.directiveName,
|
|
29
33
|
locations: [
|
package/src/specs/policySpec.ts
CHANGED
|
@@ -31,6 +31,10 @@ export class PolicySpecDefinition extends FeatureDefinition {
|
|
|
31
31
|
|
|
32
32
|
this.registerType(createScalarTypeSpecification({ name: PolicyTypeName.POLICY }));
|
|
33
33
|
|
|
34
|
+
// WARNING: we cannot declare staticArgumentTransform() as access control merge logic needs to propagate
|
|
35
|
+
// requirements upwards/downwards between types and interfaces. We hijack the merge process by providing
|
|
36
|
+
// implementations/interfaces as "additional sources". This means that we cannot apply staticArgumentTransform()
|
|
37
|
+
// as subgraph index index will be wrong/undefined.
|
|
34
38
|
this.registerDirective(createDirectiveSpecification({
|
|
35
39
|
name: PolicySpecDefinition.directiveName,
|
|
36
40
|
args: [{
|
|
@@ -32,6 +32,10 @@ export class RequiresScopesSpecDefinition extends FeatureDefinition {
|
|
|
32
32
|
|
|
33
33
|
this.registerType(createScalarTypeSpecification({ name: RequiresScopesTypeName.SCOPE }));
|
|
34
34
|
|
|
35
|
+
// WARNING: we cannot declare staticArgumentTransform() as access control merge logic needs to propagate
|
|
36
|
+
// requirements upwards/downwards between types and interfaces. We hijack the merge process by providing
|
|
37
|
+
// implementations/interfaces as "additional sources". This means that we cannot apply staticArgumentTransform()
|
|
38
|
+
// as subgraph index index will be wrong/undefined.
|
|
35
39
|
this.registerDirective(createDirectiveSpecification({
|
|
36
40
|
name: RequiresScopesSpecDefinition.directiveName,
|
|
37
41
|
args: [{
|