Last active
February 6, 2022 15:11
-
-
Save voodooattack/b0484625a90191a4dde4aabae8884243 to your computer and use it in GitHub Desktop.
Combine two GraphQL schemas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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