UNPKG

@graphql-tools/delegate

Version:

A set of utils for faster development of GraphQL tools

101 lines (100 loc) 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OverlappingAliasesTransform = void 0; const graphql_1 = require("graphql"); const OverlappingAliases = Symbol('OverlappingAliases'); class OverlappingAliasesTransform { transformRequest(request, delegationContext, transformationContext) { const newDocument = (0, graphql_1.visit)(request.document, { [graphql_1.Kind.SELECTION_SET]: node => { const seenNonNullable = new Set(); const seenNullable = new Set(); return { ...node, selections: node.selections.map(selection => { if (selection.kind === graphql_1.Kind.INLINE_FRAGMENT) { const selectionTypeName = selection.typeCondition?.name.value; if (selectionTypeName) { const selectionType = delegationContext.transformedSchema.getType(selectionTypeName); if (selectionType && 'getFields' in selectionType) { const selectionTypeFields = selectionType.getFields(); return { ...selection, selectionSet: { ...selection.selectionSet, selections: selection.selectionSet.selections.map(subSelection => { if (subSelection.kind === graphql_1.Kind.FIELD) { const fieldName = subSelection.name.value; if (!subSelection.alias) { const field = selectionTypeFields[fieldName]; if (field) { let currentNullable; if ((0, graphql_1.isNullableType)(field.type)) { seenNullable.add(fieldName); currentNullable = true; } else { seenNonNullable.add(fieldName); currentNullable = false; } if (seenNullable.has(fieldName) && seenNonNullable.has(fieldName)) { transformationContext[OverlappingAliases] = true; return { ...subSelection, alias: { kind: graphql_1.Kind.NAME, value: currentNullable ? `_nullable_${fieldName}` : `_nonNullable_${fieldName}`, }, }; } } } } return subSelection; }), }, }; } } } return selection; }), }; }, }); return { ...request, document: newDocument, }; } transformResult(result, _delegationContext, transformationContext) { if (transformationContext[OverlappingAliases]) { return removeOverlappingAliases(result); } return result; } } exports.OverlappingAliasesTransform = OverlappingAliasesTransform; function removeOverlappingAliases(result) { if (result != null) { if (Array.isArray(result)) { return result.map(removeOverlappingAliases); } else if (typeof result === 'object') { const newResult = {}; for (const key in result) { if (key.startsWith('_nullable_') || key.startsWith('_nonNullable_')) { const newKey = key.replace(/^_nullable_/, '').replace(/^_nonNullable_/, ''); newResult[newKey] = removeOverlappingAliases(result[key]); } else { newResult[key] = removeOverlappingAliases(result[key]); } } return newResult; } } return result; }