Skip to content

Instantly share code, notes, and snippets.

@voodooattack
Last active February 6, 2022 15:11
Show Gist options
  • Save voodooattack/b0484625a90191a4dde4aabae8884243 to your computer and use it in GitHub Desktop.
Save voodooattack/b0484625a90191a4dde4aabae8884243 to your computer and use it in GitHub Desktop.
Combine two GraphQL schemas
import { parse, visit, print } = from 'graphql/language';
/**
* Combine the fields of two or more AST nodes, does no error checking!
* @param types An array with types to combine.
* @returns {*}
*/
export function combineASTTypes(types) {
return types.reduce((p, n) => Object.assign(p, n, { fields: n.fields.concat(p.fields || []) }), {});
}
/**
* Combine multiple AST schemas into one. This will consolidate the Query, Mutation, and Subscription types if found.
* @param schemas An array with the schemas to combine.
* @returns {*}
*/
export function combineASTSchemas(schemas) {
const result = { kind: 'Document', definitions: [] };
const queries = [], mutations = [], subscriptions = [];
const withoutRootTypes = schemas.map(schema => visit(schema, {
enter(node /*, key, parent, path, ancestors*/) {
if (node.kind === 'ObjectTypeDefinition') {
if (node.name.value == 'Query') {
queries.push(node);
return null;
} else if (node.name.value == 'Mutation') {
mutations.push(node);
return null;
} else if (node.name.value == 'Subscription') {
subscriptions.push(node);
return null;
}
}
}
}));
const query = combineASTTypes(queries);
const mutation = combineASTTypes(mutations);
const subscription = combineASTTypes(subscriptions);
if (queries.length)
result.definitions.push(query);
if (mutations.length)
result.definitions.push(mutation);
if (subscriptions.length)
result.definitions.push(subscription);
withoutRootTypes.forEach(schema =>
result.definitions = [...result.definitions, ...schema.definitions]);
return result;
}
const combined = combineASTSchemas([
parse(`
type User {
name: String!
hash: String
salt: String
}
type Query {
users: [User!]
}`
),
parse(`
type Query {
viewer: User
}
type Mutation {
test: Boolean
}`
),
parse(`
type Query {
findSomething(str: String): String
}`
)
]);
console.log(print(combined));
/* Output:
type Query {
findSomething(str: String): String
viewer: User
users: [User!]
}
type Mutation {
test: Boolean
}
type User {
name: String!
hash: String
salt: String
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment