import { TypeInfo, getNamedType, visit, visitWithTypeInfo, Kind, } from 'graphql'; function uniqueBy(array, iteratee) { var _a; const FilteredMap = new Map(); const result = []; for (const item of array) { if (item.kind === 'Field') { const uniqueValue = iteratee(item); const existing = FilteredMap.get(uniqueValue); if ((_a = item.directives) === null || _a === void 0 ? void 0 : _a.length) { const itemClone = Object.assign({}, item); result.push(itemClone); } else if ((existing === null || existing === void 0 ? void 0 : existing.selectionSet) && item.selectionSet) { existing.selectionSet.selections = [ ...existing.selectionSet.selections, ...item.selectionSet.selections, ]; } else if (!existing) { const itemClone = Object.assign({}, item); FilteredMap.set(uniqueValue, itemClone); result.push(itemClone); } } else { result.push(item); } } return result; } function inlineRelevantFragmentSpreads(fragmentDefinitions, selections, selectionSetType) { var _a; const selectionSetTypeName = selectionSetType ? getNamedType(selectionSetType).name : null; const outputSelections = []; const seenSpreads = []; for (let selection of selections) { if (selection.kind === 'FragmentSpread') { const fragmentName = selection.name.value; if (!selection.directives || selection.directives.length === 0) { if (seenSpreads.includes(fragmentName)) { continue; } else { seenSpreads.push(fragmentName); } } const fragmentDefinition = fragmentDefinitions[selection.name.value]; if (fragmentDefinition) { const { typeCondition, directives, selectionSet } = fragmentDefinition; selection = { kind: Kind.INLINE_FRAGMENT, typeCondition, directives, selectionSet, }; } } if (selection.kind === Kind.INLINE_FRAGMENT && (!selection.directives || ((_a = selection.directives) === null || _a === void 0 ? void 0 : _a.length) === 0)) { const fragmentTypeName = selection.typeCondition ? selection.typeCondition.name.value : null; if (!fragmentTypeName || fragmentTypeName === selectionSetTypeName) { outputSelections.push(...inlineRelevantFragmentSpreads(fragmentDefinitions, selection.selectionSet.selections, selectionSetType)); continue; } } outputSelections.push(selection); } return outputSelections; } export function mergeAst(documentAST, schema) { const typeInfo = schema ? new TypeInfo(schema) : null; const fragmentDefinitions = Object.create(null); for (const definition of documentAST.definitions) { if (definition.kind === Kind.FRAGMENT_DEFINITION) { fragmentDefinitions[definition.name.value] = definition; } } const flattenVisitors = { SelectionSet(node) { const selectionSetType = typeInfo ? typeInfo.getParentType() : null; let { selections } = node; selections = inlineRelevantFragmentSpreads(fragmentDefinitions, selections, selectionSetType); return Object.assign(Object.assign({}, node), { selections }); }, FragmentDefinition() { return null; }, }; const flattenedAST = visit(documentAST, typeInfo ? visitWithTypeInfo(typeInfo, flattenVisitors) : flattenVisitors); const deduplicateVisitors = { SelectionSet(node) { let { selections } = node; selections = uniqueBy(selections, selection => selection.alias ? selection.alias.value : selection.name.value); return Object.assign(Object.assign({}, node), { selections }); }, FragmentDefinition() { return null; }, }; return visit(flattenedAST, deduplicateVisitors); } //# sourceMappingURL=merge-ast.js.map