function merge(queries) {
  const mergedVariables = {}
  const mergedVariableDefinitions = []
  const mergedSelections = []
  const mergedFragmentMap = new Map()

  queries.forEach((query, index) => {
    const prefixedQuery = prefixQueryParts(Prefix.create(index), query)

    prefixedQuery.query.definitions.forEach(def => {
      if (isQueryDefinition(def)) {
        mergedSelections.push(...def.selectionSet.selections)
        mergedVariableDefinitions.push(...(def.variableDefinitions ?? []))
      }
      if (isFragmentDefinition(def)) {
        // Theoretically it is possible to have fragments with the same name but different content
        // in different queries. But Gatsby validation doesn't allow this and we rely on this here
        // One example where this can occur is in gatsby-node or GraphiQL queries
        // (but those are usually not batched)
        mergedFragmentMap.set(def.name.value, def)
      }
    })
    Object.assign(mergedVariables, prefixedQuery.variables)
  })

  const mergedQueryDefinition = {
    kind: Kind.OPERATION_DEFINITION,
    operation: `query`,
    variableDefinitions: mergedVariableDefinitions,
    selectionSet: {
      kind: Kind.SELECTION_SET,
      selections: mergedSelections,
    },
  }

  return {
    query: {
      kind: Kind.DOCUMENT,
      definitions: [mergedQueryDefinition, ...mergedFragmentMap.values()],
    },
    variables: mergedVariables,
  }
}
Merge multiple queries into a single query in such a way that query results
can be split and transformed as if they were obtained by running original queries.

Merging algorithm involves several transformations:
 1. Replace top-level fragment spreads with inline fragments (... on Query {})
 2. Add unique aliases to all top-level query fields (including those on inline fragments)
 3. Prefix all variable definitions and variable usages
 4. Prefix names (and spreads) of fragments with variables
 5. Dedupe repeating fragments

i.e transform:
  [
    `query Foo($id: ID!) { foo, bar(id: $id), ...FooQuery }
    fragment FooQuery on Query { baz }`,

   `query Bar($id: ID!) { foo: baz, bar(id: $id), ... on Query { baz } }`
  ]
to:
  query (
    $gatsby1_id: ID!
    $gatsby2_id: ID!
  ) {
    gatsby1_foo: foo,
    gatsby1_bar: bar(id: $gatsby1_id)
    ... on Query @originalFragment(name: "FooQuery") {
      gatsby1_baz: baz
    }
    gatsby2_foo: baz
    gatsby2_bar: bar(id: $gatsby2_id)
    ... on Query {
      gatsby2_baz: baz
    }
  }
  fragment FooQuery on Query { baz }