From b81749464f4ede5210fc2db8b47a32b6c49b5bb0 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Wed, 14 Sep 2022 11:44:20 -0700 Subject: [PATCH] Update typescript exports for schema extensions (#2118) * Update typescript exports for schema extensions Co-authored-by: Chris Lenfest --- .../__tests__/addExtensions.test.ts | 13 ++++-- gateway-js/src/schema-helper/addExtensions.ts | 4 +- gateway-js/src/typings/graphql.ts | 40 ++----------------- .../src/schema-helper/buildSchemaFromSDL.ts | 19 ++++++--- subgraph-js/src/schemaExtensions.ts | 31 +++++++------- subgraph-js/src/types.ts | 8 ++-- 6 files changed, 48 insertions(+), 67 deletions(-) diff --git a/gateway-js/src/schema-helper/__tests__/addExtensions.test.ts b/gateway-js/src/schema-helper/__tests__/addExtensions.test.ts index c8470bd57..7d3f6fbc9 100644 --- a/gateway-js/src/schema-helper/__tests__/addExtensions.test.ts +++ b/gateway-js/src/schema-helper/__tests__/addExtensions.test.ts @@ -1,5 +1,6 @@ import { buildSchema } from 'graphql'; import { addExtensions } from '../addExtensions'; +import { ApolloGraphQLSchemaExtensions } from '../../typings/graphql'; const { version } = require('../../../package.json'); describe('addExtensions', () => { @@ -7,7 +8,8 @@ describe('addExtensions', () => { it('adds gateway extensions to a schema', async () => { const schema = buildSchema('type Query { hello: String }'); expect(schema.extensions).toEqual({}); - expect(addExtensions(schema).extensions).toEqual({ apollo: { gateway: { version: version } } }); + const actualExtensions: ApolloGraphQLSchemaExtensions = addExtensions(schema).extensions; + expect(actualExtensions).toEqual({ apollo: { gateway: { version: version } } }); }); it('does not delete existing extensions', async () => { @@ -21,7 +23,8 @@ describe('addExtensions', () => { } } }; - expect(addExtensions(schema).extensions).toEqual({ + const actualExtensions: ApolloGraphQLSchemaExtensions = addExtensions(schema).extensions; + expect(actualExtensions).toEqual({ foo: 'bar', apollo: { gateway: { @@ -37,7 +40,8 @@ describe('addExtensions', () => { schema.extensions = { apollo: undefined }; - expect(addExtensions(schema).extensions).toEqual({ + const actualExtensions: ApolloGraphQLSchemaExtensions = addExtensions(schema).extensions; + expect(actualExtensions).toEqual({ apollo: { gateway: { version: version @@ -54,7 +58,8 @@ describe('addExtensions', () => { gateway: undefined } }; - expect(addExtensions(schema).extensions).toEqual({ + const actualExtensions: ApolloGraphQLSchemaExtensions = addExtensions(schema).extensions; + expect(actualExtensions).toEqual({ apollo: { gateway: { version: version diff --git a/gateway-js/src/schema-helper/addExtensions.ts b/gateway-js/src/schema-helper/addExtensions.ts index 7e6d66777..6b2f49a92 100644 --- a/gateway-js/src/schema-helper/addExtensions.ts +++ b/gateway-js/src/schema-helper/addExtensions.ts @@ -1,10 +1,10 @@ import { GraphQLSchema } from 'graphql'; -import { GraphQLSchemaExtensions } from 'graphql/type/schema'; +import { ApolloGraphQLSchemaExtensions } from '../typings/graphql'; const { version } = require('../../package.json'); export function addExtensions(schema: GraphQLSchema): GraphQLSchema { - const schemaExtension = schema.extensions as GraphQLSchemaExtensions ?? {}; + const schemaExtension: ApolloGraphQLSchemaExtensions = schema.extensions ?? {}; const apolloExtension = schemaExtension?.apollo ?? {}; const gatewayExtension = apolloExtension?.gateway ?? {}; diff --git a/gateway-js/src/typings/graphql.ts b/gateway-js/src/typings/graphql.ts index 68f102861..692957c2a 100644 --- a/gateway-js/src/typings/graphql.ts +++ b/gateway-js/src/typings/graphql.ts @@ -1,43 +1,11 @@ -import { GraphQLResolveInfo } from 'graphql'; - -type GraphQLReferenceResolver = ( - reference: object, - context: TContext, - info: GraphQLResolveInfo, -) => any; - -interface ApolloSubgraphExtensions { - resolveReference?: GraphQLReferenceResolver; -} +import { GraphQLSchemaExtensions } from 'graphql'; interface ApolloGatewayExtensions { version?: String; } -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>; - } - } -} - -declare module 'graphql/type/schema' { - interface GraphQLSchemaExtensions { - apollo?: { - gateway?: ApolloGatewayExtensions; - } +export interface ApolloGraphQLSchemaExtensions extends GraphQLSchemaExtensions { + apollo?: { + gateway?: ApolloGatewayExtensions; } } diff --git a/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts b/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts index 9707c08a9..60e02e8bd 100644 --- a/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts +++ b/subgraph-js/src/schema-helper/buildSchemaFromSDL.ts @@ -36,6 +36,11 @@ import { SDLValidationRule } from "graphql/validation/ValidationContext"; import { specifiedSDLRules } from 'graphql/validation/specifiedRules'; import { GraphQLSchemaValidationError } from './error'; +import { + ApolloGraphQLInterfaceTypeExtensions, + ApolloGraphQLObjectTypeExtensions, + ApolloGraphQLUnionTypeExtensions +} from "../schemaExtensions"; function isNotNullOrUndefined( value: T | null | undefined, @@ -107,14 +112,15 @@ export function addResolversToSchema( const type = schema.getType(typeName); if (isAbstractType(type)) { + const existingExtensions: ApolloGraphQLUnionTypeExtensions | ApolloGraphQLInterfaceTypeExtensions = type.extensions; for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { if (fieldName === '__resolveReference') { type.extensions = { - ...type.extensions, + ...existingExtensions, apollo: { - ...type.extensions.apollo, + ...existingExtensions.apollo, subgraph: { - ...type.extensions.apollo?.subgraph, + ...existingExtensions.apollo?.subgraph, resolveReference: fieldConfig, }, }, @@ -163,14 +169,15 @@ export function addResolversToSchema( if (!isObjectType(type)) continue; const fieldMap = type.getFields(); + const existingExtensions: ApolloGraphQLObjectTypeExtensions = type.extensions; for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { if (fieldName === '__resolveReference') { type.extensions = { - ...type.extensions, + ...existingExtensions, apollo: { - ...type.extensions.apollo, + ...existingExtensions.apollo, subgraph: { - ...type.extensions.apollo?.subgraph, + ...existingExtensions.apollo?.subgraph, resolveReference: fieldConfig, }, }, diff --git a/subgraph-js/src/schemaExtensions.ts b/subgraph-js/src/schemaExtensions.ts index 10d10b96a..cdd990883 100644 --- a/subgraph-js/src/schemaExtensions.ts +++ b/subgraph-js/src/schemaExtensions.ts @@ -1,4 +1,9 @@ -import { GraphQLResolveInfo } from 'graphql'; +import { + GraphQLInterfaceTypeExtensions, + GraphQLObjectTypeExtensions, + GraphQLResolveInfo, + GraphQLUnionTypeExtensions +} from 'graphql'; type GraphQLReferenceResolver = ( reference: object, @@ -10,22 +15,20 @@ interface ApolloSubgraphExtensions { resolveReference?: GraphQLReferenceResolver; } -declare module 'graphql/type/definition' { - interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> { - apollo?: { - subgraph?: ApolloSubgraphExtensions<_TContext>; - }; +export interface ApolloGraphQLObjectTypeExtensions<_TSource = any, _TContext = any> extends GraphQLObjectTypeExtensions { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; } +} - interface GraphQLInterfaceTypeExtensions<_TSource = any, _TContext = any> { - apollo?: { - subgraph?: ApolloSubgraphExtensions<_TContext>; - }; +export interface ApolloGraphQLInterfaceTypeExtensions<_TSource = any, _TContext = any> extends GraphQLInterfaceTypeExtensions { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; } +} - interface GraphQLUnionTypeExtensions<_TSource = any, _TContext = any> { - apollo?: { - subgraph?: ApolloSubgraphExtensions<_TContext>; - }; +export interface ApolloGraphQLUnionTypeExtensions<_TSource = any, _TContext = any> extends GraphQLUnionTypeExtensions { + apollo?: { + subgraph?: ApolloSubgraphExtensions<_TContext>; } } diff --git a/subgraph-js/src/types.ts b/subgraph-js/src/types.ts index a0808b37c..e5bed8fe5 100644 --- a/subgraph-js/src/types.ts +++ b/subgraph-js/src/types.ts @@ -14,6 +14,7 @@ import { } from 'graphql'; import { PromiseOrValue } from 'graphql/jsutils/PromiseOrValue'; import { maybeCacheControlFromInfo } from '@apollo/cache-control-types'; +import { ApolloGraphQLObjectTypeExtensions } from './schemaExtensions'; export type Maybe = null | undefined | T; @@ -95,11 +96,8 @@ export function entitiesResolver({ } } - const resolveReference = - type.extensions.apollo?.subgraph?.resolveReference ?? - function defaultResolveReference() { - return reference; - }; + const extensions: ApolloGraphQLObjectTypeExtensions = type.extensions; + const resolveReference = extensions.apollo?.subgraph?.resolveReference ?? (() => reference); // FIXME somehow get this to show up special in Studio traces? const result = resolveReference(reference, context, info);