UNPKG

@graphql-tools/resolvers-composition

Version:

Common package containing utils and types for GraphQL tools

93 lines (92 loc) 3.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.composeResolvers = void 0; const tslib_1 = require("tslib"); const lodash_1 = tslib_1.__importDefault(require("lodash")); const micromatch_1 = tslib_1.__importDefault(require("micromatch")); const utils_1 = require("@graphql-tools/utils"); const chain_functions_js_1 = require("./chain-functions.js"); function isScalarTypeConfiguration(config) { return config && 'serialize' in config && 'parseLiteral' in config; } function resolveRelevantMappings(resolvers, path) { if (!resolvers) { return []; } const [typeNameOrGlob, fieldNameOrGlob] = path.split('.'); const isTypeMatch = micromatch_1.default.matcher(typeNameOrGlob); let fixedFieldGlob = fieldNameOrGlob; // convert single value OR `{singleField}` to `singleField` as matching will fail otherwise if (fixedFieldGlob.includes('{') && !fixedFieldGlob.includes(',')) { fixedFieldGlob = fieldNameOrGlob.replace('{', '').replace('}', ''); } fixedFieldGlob = fixedFieldGlob.replace(', ', ',').trim(); const isFieldMatch = micromatch_1.default.matcher(fixedFieldGlob); const mappings = []; for (const typeName in resolvers) { if (!isTypeMatch(typeName)) { continue; } if (isScalarTypeConfiguration(resolvers[typeName])) { continue; } const fieldMap = resolvers[typeName]; if (!fieldMap) { return []; } for (const field in fieldMap) { if (!isFieldMatch(field)) { continue; } const resolvedPath = `${typeName}.${field}`; if (resolvers[typeName] && resolvers[typeName][field]) { if (resolvers[typeName][field].subscribe) { mappings.push(resolvedPath + '.subscribe'); } if (resolvers[typeName][field].resolve) { mappings.push(resolvedPath + '.resolve'); } if (typeof resolvers[typeName][field] === 'function') { mappings.push(resolvedPath); } } } } return mappings; } /** * Wraps the resolvers object with the resolvers composition objects. * Implemented as a simple and basic middleware mechanism. * * @param resolvers - resolvers object * @param mapping - resolvers composition mapping * @hidden */ function composeResolvers(resolvers, mapping = {}) { const mappingResult = {}; for (const resolverPath in mapping) { const resolverPathMapping = mapping[resolverPath]; if (resolverPathMapping instanceof Array || typeof resolverPathMapping === 'function') { const composeFns = resolverPathMapping; const relevantFields = resolveRelevantMappings(resolvers, resolverPath); for (const path of relevantFields) { mappingResult[path] = (0, utils_1.asArray)(composeFns); } } else if (resolverPathMapping) { for (const fieldName in resolverPathMapping) { const composeFns = resolverPathMapping[fieldName]; const relevantFields = resolveRelevantMappings(resolvers, resolverPath + '.' + fieldName); for (const path of relevantFields) { mappingResult[path] = (0, utils_1.asArray)(composeFns); } } } } for (const path in mappingResult) { const fns = (0, chain_functions_js_1.chainFunctions)([...(0, utils_1.asArray)(mappingResult[path]), () => lodash_1.default.get(resolvers, path)]); lodash_1.default.set(resolvers, path, fns()); } return resolvers; } exports.composeResolvers = composeResolvers;