@apollo/federation-internals 2.10.3 → 2.10.5

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.
@@ -3825,3 +3825,7 @@ function copyDirectiveDefinitionInner(
3825
3825
  export function isFieldDefinition(elem: SchemaElement<any, any>): elem is FieldDefinition<any> {
3826
3826
  return elem instanceof FieldDefinition;
3827
3827
  }
3828
+
3829
+ export function isElementNamedType(elem: SchemaElement<any, any>): elem is NamedType {
3830
+ return elem instanceof BaseNamedType;
3831
+ }
package/src/error.ts CHANGED
@@ -633,9 +633,9 @@ const MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED = makeCodeDefinition(
633
633
  { addedIn: '2.8.0' },
634
634
  );
635
635
 
636
- const AUTHENTICATION_APPLIED_ON_INTERFACE = makeCodeDefinition(
637
- 'AUTHENTICATION_APPLIED_ON_INTERFACE',
638
- 'The @authenticated, @requiresScopes and @policy directive cannot be applied on interface, interface object or their fields.',
636
+ const AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE = makeCodeDefinition(
637
+ 'AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE',
638
+ 'The @authenticated, @requiresScopes and @policy directive cannot be applied on interface, interface fields and interface object',
639
639
  { addedIn: '2.9.4' },
640
640
  );
641
641
 
@@ -746,7 +746,7 @@ export const ERRORS = {
746
746
  LIST_SIZE_INVALID_SIZED_FIELD,
747
747
  LIST_SIZE_INVALID_SLICING_ARGUMENT,
748
748
  MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED,
749
- AUTHENTICATION_APPLIED_ON_INTERFACE,
749
+ AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE,
750
750
  MISSING_TRANSITIVE_AUTH_REQUIREMENTS,
751
751
  };
752
752
 
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";
@@ -1840,7 +1840,7 @@ export class FederationBlueprint extends SchemaBlueprint {
1840
1840
  validateSizedFieldsAreValidLists(application, parent, errorCollector);
1841
1841
  }
1842
1842
 
1843
- // Validate @authenticated, @requireScopes and @policy
1843
+ // Validate @authenticated, @requireScopes and @policy usage on interfaces and interface objects
1844
1844
  validateNoAuthenticationOnInterfaces(metadata, errorCollector);
1845
1845
 
1846
1846
  return errorCollector;
@@ -2901,15 +2901,15 @@ function validateNoAuthenticationOnInterfaces(metadata: FederationMetadata, erro
2901
2901
  const policyDirective = metadata.policyDirective();
2902
2902
  [authenticatedDirective, requiresScopesDirective, policyDirective].forEach((directive) => {
2903
2903
  for (const application of directive.applications()) {
2904
- const element = application.parent;
2905
- function isAppliedOnInterface(type: Type) {
2906
- return isInterfaceType(type) || isInterfaceObjectType(baseType(type));
2907
- }
2908
- function isAppliedOnInterfaceField(elem: SchemaElement<any, any>) {
2909
- return isFieldDefinition(elem) && isAppliedOnInterface(elem.parent);
2910
- }
2911
-
2912
- if (isAppliedOnInterface(element) || isAppliedOnInterfaceField(element)) {
2904
+ const element: SchemaElement<any, any> = application.parent;
2905
+ if (
2906
+ // Is it applied on interface or interface object types?
2907
+ (isElementNamedType(element) &&
2908
+ (isInterfaceType(element) || isInterfaceObjectType(element))
2909
+ ) ||
2910
+ // Is it applied on interface fields?
2911
+ (isFieldDefinition(element) && isInterfaceType(element.parent))
2912
+ ) {
2913
2913
  let kind = '';
2914
2914
  switch (element.kind) {
2915
2915
  case 'FieldDefinition':
@@ -2922,8 +2922,8 @@ function validateNoAuthenticationOnInterfaces(metadata: FederationMetadata, erro
2922
2922
  kind = 'interface object';
2923
2923
  break;
2924
2924
  }
2925
- errorCollector.push(ERRORS.AUTHENTICATION_APPLIED_ON_INTERFACE.err(
2926
- `Invalid use of @${directive.name} on ${kind} "${element.coordinate}": @${directive.name} cannot be applied on interfaces, interface objects or their fields`,
2925
+ errorCollector.push(ERRORS.AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE.err(
2926
+ `Invalid use of @${directive.name} on ${kind} "${element.coordinate}": @${directive.name} cannot be applied on interfaces, interface fields and interface objects`,
2927
2927
  {nodes: sourceASTs(application, element.parent)},
2928
2928
  ));
2929
2929
  }
package/src/operations.ts CHANGED
@@ -1123,7 +1123,7 @@ export class Operation extends DirectiveTargetElement<Operation> {
1123
1123
  }
1124
1124
 
1125
1125
  collectDefaultedVariableValues(): Record<string, any> {
1126
- const defaultedVariableValues: Record<string, any> = {};
1126
+ const defaultedVariableValues: Record<string, any> = Object.create(null);
1127
1127
  for (const { variable, defaultValue } of this.variableDefinitions.definitions()) {
1128
1128
  if (defaultValue !== undefined) {
1129
1129
  defaultedVariableValues[variable.name] = defaultValue;
@@ -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: [
@@ -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: [{