@apollo/federation-internals 2.9.4 → 2.9.6

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
@@ -746,9 +746,9 @@ const MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED = makeCodeDefinition(
746
746
  { addedIn: '2.8.0' },
747
747
  );
748
748
 
749
- const AUTHENTICATION_APPLIED_ON_INTERFACE = makeCodeDefinition(
750
- 'AUTHENTICATION_APPLIED_ON_INTERFACE',
751
- 'The @authenticated, @requiresScopes and @policy directive cannot be applied on interface, interface object or their fields.',
749
+ const AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE = makeCodeDefinition(
750
+ 'AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE',
751
+ 'The @authenticated, @requiresScopes and @policy directive cannot be applied on interface, interface fields and interface object',
752
752
  { addedIn: '2.9.4' },
753
753
  );
754
754
 
@@ -879,7 +879,7 @@ export const ERRORS = {
879
879
  LIST_SIZE_INVALID_SIZED_FIELD,
880
880
  LIST_SIZE_INVALID_SLICING_ARGUMENT,
881
881
  MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED,
882
- AUTHENTICATION_APPLIED_ON_INTERFACE,
882
+ AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE,
883
883
  MISSING_TRANSITIVE_AUTH_REQUIREMENTS,
884
884
  };
885
885
 
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";
@@ -1875,7 +1875,7 @@ export class FederationBlueprint extends SchemaBlueprint {
1875
1875
  validateSizedFieldsAreValidLists(application, parent, errorCollector);
1876
1876
  }
1877
1877
 
1878
- // Validate @authenticated, @requireScopes and @policy
1878
+ // Validate @authenticated, @requireScopes and @policy usage on interfaces and interface objects
1879
1879
  validateNoAuthenticationOnInterfaces(metadata, errorCollector);
1880
1880
 
1881
1881
  return errorCollector;
@@ -2936,15 +2936,15 @@ function validateNoAuthenticationOnInterfaces(metadata: FederationMetadata, erro
2936
2936
  const policyDirective = metadata.policyDirective();
2937
2937
  [authenticatedDirective, requiresScopesDirective, policyDirective].forEach((directive) => {
2938
2938
  for (const application of directive.applications()) {
2939
- const element = application.parent;
2940
- function isAppliedOnInterface(type: Type) {
2941
- return isInterfaceType(type) || isInterfaceObjectType(baseType(type));
2942
- }
2943
- function isAppliedOnInterfaceField(elem: SchemaElement<any, any>) {
2944
- return isFieldDefinition(elem) && isAppliedOnInterface(elem.parent);
2945
- }
2946
-
2947
- if (isAppliedOnInterface(element) || isAppliedOnInterfaceField(element)) {
2939
+ const element: SchemaElement<any, any> = application.parent;
2940
+ if (
2941
+ // Is it applied on interface or interface object types?
2942
+ (isElementNamedType(element) &&
2943
+ (isInterfaceType(element) || isInterfaceObjectType(element))
2944
+ ) ||
2945
+ // Is it applied on interface fields?
2946
+ (isFieldDefinition(element) && isInterfaceType(element.parent))
2947
+ ) {
2948
2948
  let kind = '';
2949
2949
  switch (element.kind) {
2950
2950
  case 'FieldDefinition':
@@ -2957,8 +2957,8 @@ function validateNoAuthenticationOnInterfaces(metadata: FederationMetadata, erro
2957
2957
  kind = 'interface object';
2958
2958
  break;
2959
2959
  }
2960
- errorCollector.push(ERRORS.AUTHENTICATION_APPLIED_ON_INTERFACE.err(
2961
- `Invalid use of @${directive.name} on ${kind} "${element.coordinate}": @${directive.name} cannot be applied on interfaces, interface objects or their fields`,
2960
+ errorCollector.push(ERRORS.AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE.err(
2961
+ `Invalid use of @${directive.name} on ${kind} "${element.coordinate}": @${directive.name} cannot be applied on interfaces, interface fields and interface objects`,
2962
2962
  {nodes: sourceASTs(application, element.parent)},
2963
2963
  ));
2964
2964
  }
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: [{