Skip to content

Commit

Permalink
Merge 56bf79e into 240f5b9
Browse files Browse the repository at this point in the history
  • Loading branch information
trevor-scheer committed Jun 20, 2019
2 parents 240f5b9 + 56bf79e commit f4280b8
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 42 deletions.
58 changes: 24 additions & 34 deletions src/stitching/makeRemoteExecutableSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {
printSchema,
Kind,
GraphQLResolveInfo,
DocumentNode
DocumentNode,
BuildSchemaOptions
} from 'graphql';
import linkToFetcher, { execute } from './linkToFetcher';
import isEmptyObject from '../isEmptyObject';
Expand All @@ -30,12 +31,13 @@ import resolveParentFromTypename from './resolveFromParentTypename';
import defaultMergedResolver from './defaultMergedResolver';
import { checkResultAndHandleErrors } from './errors';
import { observableToAsyncIterable } from './observableToAsyncIterable';
import { Options as PrintSchemaOptions } from 'graphql/utilities/schemaPrinter';

export type ResolverFn = (
rootValue?: any,
args?: any,
context?: any,
info?: GraphQLResolveInfo,
info?: GraphQLResolveInfo
) => AsyncIterator<any>;

export type Fetcher = (operation: FetcherOperation) => Promise<ExecutionResult>;
Expand All @@ -51,26 +53,28 @@ export default function makeRemoteExecutableSchema({
schema,
link,
fetcher,
createResolver: customCreateResolver = createResolver
createResolver: customCreateResolver = createResolver,
buildSchemaOptions,
printSchemaOptions = { commentDescriptions: true }
}: {
schema: GraphQLSchema | string;
link?: ApolloLink;
fetcher?: Fetcher;
createResolver?: (fetcher: Fetcher) => GraphQLFieldResolver<any, any>
createResolver?: (fetcher: Fetcher) => GraphQLFieldResolver<any, any>;
buildSchemaOptions?: BuildSchemaOptions;
printSchemaOptions?: PrintSchemaOptions;
}): GraphQLSchema {
if (!fetcher && link) {
fetcher = linkToFetcher(link);
}

let typeDefs: string;
const printOptions = { commentDescriptions: true };

if (typeof schema === 'string') {
typeDefs = schema;
schema = buildSchema(typeDefs);
schema = buildSchema(typeDefs, buildSchemaOptions);
} else {
// TODO fix types https://github.com/apollographql/graphql-tools/issues/542
typeDefs = (printSchema as any)(schema, printOptions);
typeDefs = printSchema(schema, printSchemaOptions);
}

// prepare query resolvers
Expand Down Expand Up @@ -98,7 +102,7 @@ export default function makeRemoteExecutableSchema({
const subscriptions = subscriptionType.getFields();
Object.keys(subscriptions).forEach(key => {
subscriptionResolvers[key] = {
subscribe: createSubscriptionResolver(key, link),
subscribe: createSubscriptionResolver(key, link)
};
});
}
Expand All @@ -118,14 +122,11 @@ export default function makeRemoteExecutableSchema({
const typeMap = schema.getTypeMap();
const types = Object.keys(typeMap).map(name => typeMap[name]);
for (const type of types) {
if (
type instanceof GraphQLInterfaceType ||
type instanceof GraphQLUnionType
) {
if (type instanceof GraphQLInterfaceType || type instanceof GraphQLUnionType) {
resolvers[type.name] = {
__resolveType(parent, context, info) {
return resolveParentFromTypename(parent, info.schema);
},
}
};
} else if (type instanceof GraphQLScalarType) {
if (
Expand All @@ -137,11 +138,7 @@ export default function makeRemoteExecutableSchema({
type === GraphQLInt
)
) {
resolvers[type.name] = recreateType(
type,
(name: string) => null,
false,
) as GraphQLScalarType;
resolvers[type.name] = recreateType(type, (name: string) => null, false) as GraphQLScalarType;
}
} else if (
type instanceof GraphQLObjectType &&
Expand All @@ -160,45 +157,38 @@ export default function makeRemoteExecutableSchema({

return makeExecutableSchema({
typeDefs,
resolvers,
resolvers
});
}

export function createResolver(fetcher: Fetcher): GraphQLFieldResolver<any, any> {
return async (root, args, context, info) => {
const fragments = Object.keys(info.fragments).map(
fragment => info.fragments[fragment],
);
const fragments = Object.keys(info.fragments).map(fragment => info.fragments[fragment]);
const document = {
kind: Kind.DOCUMENT,
definitions: [info.operation, ...fragments],
definitions: [info.operation, ...fragments]
};
const result = await fetcher({
query: document,
variables: info.variableValues,
context: { graphqlContext: context },
context: { graphqlContext: context }
});
return checkResultAndHandleErrors(result, info);
};
}

function createSubscriptionResolver(
name: string,
link: ApolloLink,
): ResolverFn {
function createSubscriptionResolver(name: string, link: ApolloLink): ResolverFn {
return (root, args, context, info) => {
const fragments = Object.keys(info.fragments).map(
fragment => info.fragments[fragment],
);
const fragments = Object.keys(info.fragments).map(fragment => info.fragments[fragment]);
const document = {
kind: Kind.DOCUMENT,
definitions: [info.operation, ...fragments],
definitions: [info.operation, ...fragments]
};

const operation = {
query: document,
variables: info.variableValues,
context: { graphqlContext: context },
context: { graphqlContext: context }
};

const observable = execute(link, operation);
Expand Down
48 changes: 40 additions & 8 deletions src/test/testMakeRemoteExecutableSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
subscriptionSchema,
subscriptionPubSubTrigger,
subscriptionPubSub,
makeSchemaRemoteFromLink,
makeSchemaRemoteFromLink
} from '../test/testingSchemas';
import { makeRemoteExecutableSchema } from '../stitching';

describe('remote subscriptions', () => {
let schema: GraphQLSchema;
Expand All @@ -19,8 +20,8 @@ describe('remote subscriptions', () => {
it('should work', done => {
const mockNotification = {
notifications: {
text: 'Hello world',
},
text: 'Hello world'
}
};

const subscription = parse(`
Expand All @@ -37,7 +38,7 @@ describe('remote subscriptions', () => {
expect(result).to.have.property('data');
expect(result.data).to.deep.equal(mockNotification);
!notificationCnt++ ? done() : null;
}),
})
);

subscriptionPubSub.publish(subscriptionPubSubTrigger, mockNotification);
Expand All @@ -46,8 +47,8 @@ describe('remote subscriptions', () => {
it('should work without triggering multiple times per notification', done => {
const mockNotification = {
notifications: {
text: 'Hello world',
},
text: 'Hello world'
}
};

const subscription = parse(`
Expand All @@ -64,14 +65,14 @@ describe('remote subscriptions', () => {
expect(result).to.have.property('data');
expect(result.data).to.deep.equal(mockNotification);
notificationCnt++;
}),
})
);

subscribe(schema, subscription).then(results =>
forAwaitEach(results as AsyncIterable<ExecutionResult>, (result: ExecutionResult) => {
expect(result).to.have.property('data');
expect(result.data).to.deep.equal(mockNotification);
}),
})
);

subscriptionPubSub.publish(subscriptionPubSubTrigger, mockNotification);
Expand All @@ -83,3 +84,34 @@ describe('remote subscriptions', () => {
}, 0);
});
});

describe('respects buildSchema options', () => {
const schema = `
type Query {
# Field description
custom: CustomScalar!
}
# Scalar description
scalar CustomScalar
`;

it('without comment descriptions', () => {
const remoteSchema = makeRemoteExecutableSchema({ schema });

const customScalar = remoteSchema.getType('CustomScalar');
expect(customScalar.description).to.eq(undefined);
});

it('with comment descriptions', () => {
const remoteSchema = makeRemoteExecutableSchema({
schema,
buildSchemaOptions: { commentDescriptions: true }
});

const field = remoteSchema.getQueryType().getFields()['custom'];
expect(field.description).to.eq('Field description');
const customScalar = remoteSchema.getType('CustomScalar');
expect(customScalar.description).to.eq('Scalar description');
});
});

0 comments on commit f4280b8

Please sign in to comment.