Skip to content

Instantly share code, notes, and snippets.

@allain
Last active June 26, 2019 15:28
Show Gist options
  • Save allain/c574333ffc9fe3d51525026253f296d8 to your computer and use it in GitHub Desktop.
Save allain/c574333ffc9fe3d51525026253f296d8 to your computer and use it in GitHub Desktop.
merges GraphQL requests
import { parse, print, visit } from "graphql"
export default function mergeRequests(requests) {
const numberedAsts = requests.map(({ query }, index) => {
let ast = parse(query)
ast = numberVars(ast, index)
ast = numberSelectionSet(ast, index)
return ast
})
const mergedSelections = numberedAsts.reduce(
(selections, ast) =>
selections.concat(ast.definitions[0].selectionSet.selections),
[]
)
const mergedVarNodes = numberedAsts.reduce(
(vars, ast) => vars.concat(ast.definitions[0].variableDefinitions),
[]
)
const mergedAst = numberedAsts[0]
mergedAst.definitions[0].selectionSet.selections = mergedSelections
mergedAst.definitions[0].variableDefinitions = mergedVarNodes
const mergedQuery = print(mergedAst)
const mergedVars = requests.reduce(
(result, { vars }, index) =>
vars
? Object.entries(vars).reduce(
(result, [name, value]) => ({
...result,
[`q${index}_${name}`]: value
}),
result
)
: result,
{}
)
return { query: mergedQuery, vars: mergedVars }
}
/**
* Takes a query and returns the same query with all the variables numbered.
*
* For example
* query ($id:ID) { ... }
* becomes
* query ($id1:ID) { ... }
*/
function numberVars(ast, number) {
return visit(ast, {
Variable(node) {
return {
...node,
name: { ...node.name, value: `q${number}_${node.name.value}` }
}
}
})
}
function numberSelectionSet(ast, number) {
return visit(ast, {
SelectionSet(node, key, parent, path, ancestors) {
// only top level selections need renaming
if (ancestors.length > 2) return node
return {
...node,
selections: node.selections.map(selection => {
// @ts-ignore
const alias = selection.alias
return {
...selection,
alias: alias
? {
...alias,
value: `q${number}_${alias.value}`
}
: {
kind: "Name",
// @ts-ignore
value: `q${number}_${selection.name.value}`
}
}
})
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment