@graphiql/toolkit
Version:
Utility to build a fetcher for GraphiQL
115 lines (114 loc) • 3.86 kB
JavaScript
import {
__spreadProps,
__spreadValues
} from "../chunk-LMOQIXV4.js";
import {
TypeInfo,
getNamedType,
visit,
visitWithTypeInfo,
Kind
} from "graphql";
function uniqueBy(array, iteratee) {
var _a;
const FilteredMap = /* @__PURE__ */ new Map(), result = [];
for (const item of array)
if (item.kind === "Field") {
const uniqueValue = iteratee(item), existing = FilteredMap.get(uniqueValue);
if ((_a = item.directives) != null && _a.length) {
const itemClone = __spreadValues({}, item);
result.push(itemClone);
} else if (existing != null && existing.selectionSet && item.selectionSet)
existing.selectionSet.selections = [
...existing.selectionSet.selections,
...item.selectionSet.selections
];
else if (!existing) {
const itemClone = __spreadValues({}, 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, outputSelections = [], 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;
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 && // Cannot inline if there are directives
(!selection.directives || ((_a = selection.directives) == null ? 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;
}
function mergeAst(documentAST, schema) {
const typeInfo = schema ? new TypeInfo(schema) : null, fragmentDefinitions = /* @__PURE__ */ Object.create(null);
for (const definition of documentAST.definitions)
definition.kind === Kind.FRAGMENT_DEFINITION && (fragmentDefinitions[definition.name.value] = definition);
const flattenVisitors = {
SelectionSet(node) {
const selectionSetType = typeInfo ? typeInfo.getParentType() : null;
let { selections } = node;
return selections = inlineRelevantFragmentSpreads(
fragmentDefinitions,
selections,
selectionSetType
), __spreadProps(__spreadValues({}, node), {
selections
});
},
FragmentDefinition() {
return null;
}
}, flattenedAST = visit(
documentAST,
typeInfo ? visitWithTypeInfo(typeInfo, flattenVisitors) : flattenVisitors
);
return visit(flattenedAST, {
SelectionSet(node) {
let { selections } = node;
return selections = uniqueBy(
selections,
(selection) => selection.alias ? selection.alias.value : selection.name.value
), __spreadProps(__spreadValues({}, node), {
selections
});
},
FragmentDefinition() {
return null;
}
});
}
export {
mergeAst
};