UNPKG

@graphql-mesh/transform-transfer-schema

Version:
125 lines (124 loc) 6.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const graphql_1 = require("graphql"); const micromatch_1 = tslib_1.__importDefault(require("micromatch")); const utils_1 = require("@graphql-tools/utils"); class TransferSchemaTransform { constructor(options) { this.noWrap = true; const { config } = options; this.additionalFieldsMap = new Map(); this.additionalArgsMap = new Map(); this.additionalFieldsConfig = new Map(); this.additionalArgsConfig = new Map(); this.removalFieldsMap = new Map(); this.removalArgsMap = new Map(); for (const transfer of config.transfers) { const [fromType, fromFieldNameOrGlob, fromArgsGlob] = transfer.from.split('.'); const rawGlob = fromArgsGlob || fromFieldNameOrGlob; const fixedGlob = rawGlob.includes('{') && !rawGlob.includes(',') ? rawGlob.replace('{', '').replace('}', '') : rawGlob; const polishedGlob = fixedGlob.split(', ').join(',').trim(); const mapName = fromArgsGlob ? 'ArgsMap' : 'FieldsMap'; const mapKey = fromArgsGlob ? `${fromType}.${fromFieldNameOrGlob}` : fromType; if (transfer.action === 'move') { const currentRemovalRules = this[`removal${mapName}`].get(mapKey) || new Set(); currentRemovalRules.add(polishedGlob); this[`removal${mapName}`].set(mapKey, currentRemovalRules); } const currentAdditionalRules = this[`additional${mapName}`].get(mapKey) || new Set(); currentAdditionalRules.add(`${transfer.to}.${polishedGlob}`); this[`additional${mapName}`].set(mapKey, currentAdditionalRules); } } handleAdditions(rulesArray, value, config) { for (const rule of rulesArray) { const [toType, toField, pattern] = rule.split('.'); const usePattern = pattern || toField; const mapIdentifier = pattern ? 'ArgsConfig' : 'FieldsConfig'; const mapKey = pattern ? `${toType}.${toField}` : toType; const isMatch = micromatch_1.default.matcher(usePattern); if (isMatch(value)) { const currentAdditionalConfigs = this[`additional${mapIdentifier}`].get(mapKey) || {}; this[`additional${mapIdentifier}`].set(mapKey, { ...currentAdditionalConfigs, [value]: config, }); break; } } } matchInSet(rulesSet, value) { for (const rule of rulesSet) { const isMatch = micromatch_1.default.matcher(rule); if (isMatch(value)) return true; } return undefined; } transformSchema(schema) { // initial mapSchema is necessary to store fields/args configs that will be attached to Types/fields in second map const schemaWithRemovals = (0, utils_1.mapSchema)(schema, { [utils_1.MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => { const additionalFieldRules = this.additionalFieldsMap.get(typeName); const additionalArgRules = this.additionalArgsMap.get(`${typeName}.${fieldName}`); const removalFieldRules = this.removalFieldsMap.get(typeName); const removalArgRules = this.removalArgsMap.get(`${typeName}.${fieldName}`); const hasAdditionalFieldRules = Boolean(additionalFieldRules); const hasAdditionalArgRules = Boolean(additionalArgRules); const hasRemovalFieldRules = Boolean(removalFieldRules && removalFieldRules.size); const hasRemovalArgRules = Boolean(removalArgRules && removalArgRules.size); // handle field addition if (hasAdditionalFieldRules) { this.handleAdditions(additionalFieldRules, fieldName, fieldConfig); } // handle args addition if (hasAdditionalArgRules) { for (const [argName, argConfig] of Object.entries(fieldConfig.args)) { this.handleAdditions(additionalArgRules, argName, argConfig); } } // handle field removal if (hasRemovalFieldRules && this.matchInSet(removalFieldRules, fieldName)) return null; // handle args removal if (hasRemovalArgRules) { const newArgs = Object.entries(fieldConfig.args).reduce((args, [argName, argConfig]) => { return this.matchInSet(removalArgRules, argName) ? args : { ...args, [argName]: argConfig }; }, {}); return { ...fieldConfig, args: newArgs }; } return undefined; }, }); const schemaWithAdditions = (0, utils_1.mapSchema)(schemaWithRemovals, { ...(this.additionalFieldsConfig.size && { [utils_1.MapperKind.OBJECT_TYPE]: type => { const additionalFieldsConfigMap = this.additionalFieldsConfig.get(type.toString()); if (!additionalFieldsConfigMap) return undefined; const newConfig = { ...type.toConfig() }; newConfig.fields = { ...newConfig.fields, ...additionalFieldsConfigMap }; return new graphql_1.GraphQLObjectType(newConfig); }, }), ...(this.additionalArgsConfig.size && { [utils_1.MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => { const additionalArgsConfigMap = this.additionalArgsConfig.get(`${typeName}.${fieldName}`); if (!additionalArgsConfigMap) return undefined; return { ...fieldConfig, args: { ...(fieldConfig.args || {}), ...additionalArgsConfigMap }, }; }, }), }); return (0, utils_1.pruneSchema)(schemaWithAdditions); } } exports.default = TransferSchemaTransform;