Skip to content

Commit

Permalink
Update typescript exports for schema extensions (apollographql#2118)
Browse files Browse the repository at this point in the history
* Update typescript exports for schema extensions

Co-authored-by: Chris Lenfest <clenfest@apollographql.com>
  • Loading branch information
smyrick and clenfest authored Sep 14, 2022
1 parent ccf9459 commit b817494
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 67 deletions.
13 changes: 9 additions & 4 deletions gateway-js/src/schema-helper/__tests__/addExtensions.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { buildSchema } from 'graphql';
import { addExtensions } from '../addExtensions';
import { ApolloGraphQLSchemaExtensions } from '../../typings/graphql';
const { version } = require('../../../package.json');

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 () => {
Expand All @@ -21,7 +23,8 @@ describe('addExtensions', () => {
}
}
};
expect(addExtensions(schema).extensions).toEqual({
const actualExtensions: ApolloGraphQLSchemaExtensions = addExtensions(schema).extensions;
expect(actualExtensions).toEqual({
foo: 'bar',
apollo: {
gateway: {
Expand All @@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions gateway-js/src/schema-helper/addExtensions.ts
Original file line number Diff line number Diff line change
@@ -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 ?? {};

Expand Down
40 changes: 4 additions & 36 deletions gateway-js/src/typings/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,11 @@
import { GraphQLResolveInfo } from 'graphql';

type GraphQLReferenceResolver<TContext> = (
reference: object,
context: TContext,
info: GraphQLResolveInfo,
) => any;

interface ApolloSubgraphExtensions<TContext> {
resolveReference?: GraphQLReferenceResolver<TContext>;
}
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;
}
}
19 changes: 13 additions & 6 deletions subgraph-js/src/schema-helper/buildSchemaFromSDL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(
value: T | null | undefined,
Expand Down Expand Up @@ -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,
},
},
Expand Down Expand Up @@ -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,
},
},
Expand Down
31 changes: 17 additions & 14 deletions subgraph-js/src/schemaExtensions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { GraphQLResolveInfo } from 'graphql';
import {
GraphQLInterfaceTypeExtensions,
GraphQLObjectTypeExtensions,
GraphQLResolveInfo,
GraphQLUnionTypeExtensions
} from 'graphql';

type GraphQLReferenceResolver<TContext> = (
reference: object,
Expand All @@ -10,22 +15,20 @@ interface ApolloSubgraphExtensions<TContext> {
resolveReference?: GraphQLReferenceResolver<TContext>;
}

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>;
}
}
8 changes: 3 additions & 5 deletions subgraph-js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> = null | undefined | T;

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit b817494

Please sign in to comment.