diff --git a/gateway-js/src/schema-helper/addResolversToSchema.ts b/gateway-js/src/schema-helper/addResolversToSchema.ts index c97785088..5ba92758e 100644 --- a/gateway-js/src/schema-helper/addResolversToSchema.ts +++ b/gateway-js/src/schema-helper/addResolversToSchema.ts @@ -19,7 +19,20 @@ export function addResolversToSchema( if (isAbstractType(type)) { for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { - if (fieldName.startsWith("__")) { + if (fieldName === "__resolveReference") { + type.extensions = { + ...type.extensions, + apollo: { + // extensions is nullable in graphql@15 so the conditional chain is + // necessary for back compat + ...type.extensions?.apollo, + subgraph: { + ...type.extensions?.apollo?.subgraph, + resolveReference: fieldConfig, + } + }, + }; + } else if (fieldName.startsWith("__")) { (type as any)[fieldName.substring(2)] = fieldConfig; } } @@ -65,7 +78,20 @@ export function addResolversToSchema( const fieldMap = type.getFields(); for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { - if (fieldName.startsWith("__")) { + if (fieldName === "__resolveReference") { + type.extensions = { + ...type.extensions, + apollo: { + // extensions is nullable in graphql@15 so the conditional chain is + // necessary for back compat + ...type.extensions?.apollo, + subgraph: { + ...type.extensions?.apollo?.subgraph, + resolveReference: fieldConfig, + } + }, + }; + } else if (fieldName.startsWith("__")) { (type as any)[fieldName.substring(2)] = fieldConfig; continue; } diff --git a/gateway-js/src/typings/graphql.ts b/gateway-js/src/typings/graphql.ts new file mode 100644 index 000000000..af398cfdd --- /dev/null +++ b/gateway-js/src/typings/graphql.ts @@ -0,0 +1,31 @@ +import { GraphQLResolveInfo } from 'graphql'; + +type GraphQLReferenceResolver = ( + reference: object, + context: TContext, + info: GraphQLResolveInfo, +) => any; + +interface ApolloSubgraphExtensions { + resolveReference?: GraphQLReferenceResolver; +} + +declare module 'graphql/type/definition' { + interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; + } + } + + interface GraphQLInterfaceTypeExtensions<_TSource = any, _TContext = any> { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; + } + } + + interface GraphQLUnionTypeExtensions<_TSource = any, _TContext = any> { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; + } + } +} diff --git a/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts b/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts index b484dad7e..898c3d6ce 100644 --- a/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts +++ b/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts @@ -107,7 +107,20 @@ export function addResolversToSchema( if (isAbstractType(type)) { for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { - if (fieldName.startsWith("__")) { + if (fieldName === "__resolveReference") { + type.extensions = { + ...type.extensions, + apollo: { + // extensions is nullable in graphql@15 so the conditional chain is + // necessary for back compat + ...type.extensions?.apollo, + subgraph: { + ...type.extensions?.apollo?.subgraph, + resolveReference: fieldConfig, + } + }, + }; + } else if (fieldName.startsWith("__")) { (type as any)[fieldName.substring(2)] = fieldConfig; } } @@ -153,7 +166,20 @@ export function addResolversToSchema( const fieldMap = type.getFields(); for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { - if (fieldName.startsWith("__")) { + if (fieldName === "__resolveReference") { + type.extensions = { + ...type.extensions, + apollo: { + // extensions is nullable in graphql@15 so the conditional chain is + // necessary for back compat + ...type.extensions?.apollo, + subgraph: { + ...type.extensions?.apollo?.subgraph, + resolveReference: fieldConfig, + } + }, + }; + } else if (fieldName.startsWith("__")) { (type as any)[fieldName.substring(2)] = fieldConfig; continue; } diff --git a/subgraph-js/src/schemaExtensions.ts b/subgraph-js/src/schemaExtensions.ts index 2f6b10b5a..10d10b96a 100644 --- a/subgraph-js/src/schemaExtensions.ts +++ b/subgraph-js/src/schemaExtensions.ts @@ -6,12 +6,26 @@ type GraphQLReferenceResolver = ( info: GraphQLResolveInfo, ) => any; +interface ApolloSubgraphExtensions { + resolveReference?: GraphQLReferenceResolver; +} + declare module 'graphql/type/definition' { - interface GraphQLObjectType { - resolveReference?: GraphQLReferenceResolver; + interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; + }; + } + + interface GraphQLInterfaceTypeExtensions<_TSource = any, _TContext = any> { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; + }; } - interface GraphQLObjectTypeConfig { - resolveReference?: GraphQLReferenceResolver; + interface GraphQLUnionTypeExtensions<_TSource = any, _TContext = any> { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; + }; } } diff --git a/subgraph-js/src/types.ts b/subgraph-js/src/types.ts index 3841e3170..4c4ce45b8 100644 --- a/subgraph-js/src/types.ts +++ b/subgraph-js/src/types.ts @@ -86,11 +86,11 @@ export const entitiesField: GraphQLFieldConfig = { } } - const resolveReference = type.resolveReference - ? type.resolveReference - : function defaultResolveReference() { - return reference; - }; + const resolveReference = + type.extensions?.apollo?.subgraph?.resolveReference ?? + function defaultResolveReference() { + return reference; + }; // FIXME somehow get this to show up special in Studio traces? const result = resolveReference(reference, context, info);