UNPKG

graphql-compose

Version:

GraphQL schema builder from different data sources with middleware extensions.

254 lines 14 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.defineFieldMap = defineFieldMap; exports.convertObjectFieldMapToConfig = convertObjectFieldMapToConfig; exports.defineEnumValues = defineEnumValues; exports.convertEnumValuesToConfig = convertEnumValuesToConfig; exports.defineInputFieldMap = defineInputFieldMap; exports.convertInputFieldMapToConfig = convertInputFieldMapToConfig; exports.convertObjectTypeArrayAsThunk = convertObjectTypeArrayAsThunk; exports.convertInterfaceArrayAsThunk = convertInterfaceArrayAsThunk; const misc_1 = require("./misc"); const is_1 = require("./is"); const ThunkComposer_1 = require("../ThunkComposer"); const ObjectTypeComposer_1 = require("../ObjectTypeComposer"); const InterfaceTypeComposer_1 = require("../InterfaceTypeComposer"); const typeHelpers_1 = require("./typeHelpers"); const graphqlVersion_1 = require("./graphqlVersion"); function isPlainObj(obj) { return obj && typeof obj === 'object' && !Array.isArray(obj); } function copyMissingProperties(target, source) { if (source == null) return; Object.keys(source).forEach((key) => { if (key === '__proto__' || key === 'constructor' || key === 'prototype') return; if (!(key in target)) { Object.defineProperty(target, key, { value: source[key], enumerable: true, configurable: true, writable: true, }); } }); } function defineFieldMap(config, fieldMap, parentAstNode) { var _a, _b, _c; (0, misc_1.invariant)(isPlainObj(fieldMap), `${config.name} fields must be an object with field names as keys or a ` + 'function which returns such an object.'); const fieldAstNodeMap = Object.create(null); const argAstNodeMap = Object.create(null); for (const fieldNode of (_a = parentAstNode === null || parentAstNode === void 0 ? void 0 : parentAstNode.fields) !== null && _a !== void 0 ? _a : []) { if (!fieldAstNodeMap[fieldNode.name.value]) { fieldAstNodeMap[fieldNode.name.value] = fieldNode; argAstNodeMap[fieldNode.name.value] = Object.create(null); } for (const argAstNode of (_b = fieldNode === null || fieldNode === void 0 ? void 0 : fieldNode.arguments) !== null && _b !== void 0 ? _b : []) { if (!argAstNodeMap[fieldNode.name.value][argAstNode.name.value]) { argAstNodeMap[fieldNode.name.value][argAstNode.name.value] = argAstNode; } } } const resultFieldMap = Object.create(null); for (const fieldName of Object.keys(fieldMap)) { const fieldConfig = fieldMap[fieldName]; const fieldNodeAst = fieldAstNodeMap[fieldName]; (0, misc_1.invariant)(isPlainObj(fieldConfig), `${config.name}.${fieldName} field config must be an object`); const field = Object.assign(Object.assign({}, fieldConfig), { isDeprecated: Boolean(fieldConfig.deprecationReason), name: fieldName, astNode: fieldNodeAst }); (0, misc_1.invariant)(field.resolve == null || typeof field.resolve === 'function', `${config.name}.${fieldName} field resolver must be a function if ` + `provided, but got: ${(0, misc_1.inspect)(field.resolve)}.`); const argsConfig = fieldConfig.args; if (!argsConfig) { field.args = []; } else { (0, misc_1.invariant)(isPlainObj(argsConfig), `${config.name}.${fieldName} args must be an object with argument names as keys.`); const fieldArgNodeMap = (_c = argAstNodeMap[fieldName]) !== null && _c !== void 0 ? _c : Object.create(null); field.args = Object.keys(argsConfig).map((argName) => { const arg = argsConfig[argName]; (0, misc_1.invariant)(isPlainObj(arg), `${config.name}.${fieldName}(${argName}:) argument config must be an object`); return Object.assign(Object.assign({}, arg), { name: argName, description: arg.description === undefined ? null : arg.description, type: arg.type, isDeprecated: Boolean(arg.deprecationReason), deprecationReason: arg.deprecationReason, defaultValue: arg.defaultValue, astNode: fieldArgNodeMap[argName] }); }); } const normalizedArgs = Array.isArray(field.args) ? field.args : []; if (graphqlVersion_1.graphqlVersion >= 17) { const normalizedArgsByName = Object.create(null); normalizedArgs.forEach((arg) => { normalizedArgsByName[arg.name] = arg; }); const graphqlField = new (require('graphql/type/definition').GraphQLField)(config, fieldName, Object.assign(Object.assign({}, fieldConfig), { args: normalizedArgsByName, astNode: fieldNodeAst })); copyMissingProperties(graphqlField, field); graphqlField.args.forEach((arg) => { copyMissingProperties(arg, normalizedArgsByName[arg.name]); }); resultFieldMap[fieldName] = graphqlField; } else { resultFieldMap[fieldName] = field; } } return resultFieldMap; } function convertObjectFieldMapToConfig(fieldMap, sc) { const fields = {}; const isThunk = (0, is_1.isFunction)(fieldMap); const _fields = isThunk ? fieldMap(sc) : fieldMap; if (!(0, is_1.isObject)(_fields)) return {}; Object.keys(_fields).forEach((n) => { var _a; const _b = _fields[n], { name, isDeprecated } = _b, fc = __rest(_b, ["name", "isDeprecated"]); const args = {}; if (Array.isArray(fc.args)) { fc.args.forEach((arg) => { var _a; const { name: argName } = arg, ac = __rest(arg, ["name"]); args[argName] = Object.assign(Object.assign({}, ac), { type: isThunk ? new ThunkComposer_1.ThunkComposer(() => sc.typeMapper.convertInputTypeDefinition(ac.type || arg)) : sc.typeMapper.convertInputTypeDefinition(ac.type || arg), directives: sc.typeMapper.parseDirectives((_a = ac === null || ac === void 0 ? void 0 : ac.astNode) === null || _a === void 0 ? void 0 : _a.directives) }); }); fc.args = args; } else if ((0, is_1.isObject)(fc.args)) { Object.keys(fc.args).forEach((argName) => { const sourceArgs = fc.args; args[argName] = Object.assign(Object.assign({}, ((0, is_1.isObject)(sourceArgs[argName]) ? sourceArgs[argName] : null)), { type: isThunk ? new ThunkComposer_1.ThunkComposer(() => sc.typeMapper.convertInputTypeDefinition(sourceArgs[argName].type || sourceArgs[argName])) : sc.typeMapper.convertInputTypeDefinition(sourceArgs[argName].type || sourceArgs[argName]) }); }); fc.args = args; } fields[n] = Object.assign(Object.assign({}, fc), { type: isThunk ? new ThunkComposer_1.ThunkComposer(() => sc.typeMapper.convertOutputTypeDefinition(fc.type || _fields[n])) : sc.typeMapper.convertOutputTypeDefinition(fc.type || _fields[n]), directives: sc.typeMapper.parseDirectives((_a = fc === null || fc === void 0 ? void 0 : fc.astNode) === null || _a === void 0 ? void 0 : _a.directives) }); }); return fields; } function defineEnumValues(type, valueMap, parentAstNode) { var _a; (0, misc_1.invariant)(isPlainObj(valueMap), `${type.name} values must be an object with value names as keys.`); const astNodeMap = Object.create(null); for (const valueNode of (_a = parentAstNode === null || parentAstNode === void 0 ? void 0 : parentAstNode.values) !== null && _a !== void 0 ? _a : []) { astNodeMap[valueNode.name.value] = valueNode; } return Object.keys(valueMap).map((valueName) => { const value = valueMap[valueName]; (0, misc_1.invariant)(isPlainObj(value), `${type.name}.${valueName} must refer to an object with a "value" key ` + `representing an internal value but got: ${(0, misc_1.inspect)(value)}.`); (0, misc_1.invariant)(!value.hasOwnProperty('isDeprecated'), `${type.name}.${valueName} should provide "deprecationReason" instead of "isDeprecated".`); const enumValue = { name: valueName, description: value.description, isDeprecated: Boolean(value.deprecationReason), deprecationReason: value.deprecationReason, astNode: astNodeMap[valueName], value: value.hasOwnProperty('value') ? value.value : valueName, extensions: {}, }; return graphqlVersion_1.graphqlVersion >= 17 ? new (require('graphql/type/definition').GraphQLEnumValue)(type, valueName, enumValue) : enumValue; }); } function convertEnumValuesToConfig(values, schemaComposer) { const fields = {}; values.forEach((enumValue) => { var _a; const { name, isDeprecated } = enumValue, legacyConfig = __rest(enumValue, ["name", "isDeprecated"]); const fc = typeof enumValue.toConfig === 'function' ? enumValue.toConfig() : legacyConfig; fields[name] = fc; if ((_a = fc === null || fc === void 0 ? void 0 : fc.astNode) === null || _a === void 0 ? void 0 : _a.directives) { const directives = schemaComposer.typeMapper.parseDirectives(fc.astNode.directives); if (directives) { fields[name].directives = directives; } } }); return fields; } function defineInputFieldMap(config, fieldMap, parentAstNode) { var _a; (0, misc_1.invariant)(isPlainObj(fieldMap), `${config.name} fields must be an object with field names as keys or a ` + 'function which returns such an object.'); const astNodeMap = Object.create(null); for (const fieldNode of (_a = parentAstNode === null || parentAstNode === void 0 ? void 0 : parentAstNode.fields) !== null && _a !== void 0 ? _a : []) { astNodeMap[fieldNode.name.value] = fieldNode; } const resultFieldMap = Object.create(null); for (const fieldName of Object.keys(fieldMap)) { const fieldConfig = fieldMap[fieldName]; (0, misc_1.invariant)(isPlainObj(fieldConfig), `${config.name}.${fieldName} field config must be an object`); const field = Object.assign(Object.assign({}, fieldConfig), { name: fieldName, astNode: astNodeMap[fieldName] }); (0, misc_1.invariant)(!field.hasOwnProperty('resolve'), `${config.name}.${fieldName} field has a resolve property, but ` + 'Input Types cannot define resolvers.'); if (graphqlVersion_1.graphqlVersion >= 17) { const graphqlInputField = new (require('graphql/type/definition').GraphQLInputField)(config, fieldName, Object.assign(Object.assign({}, fieldConfig), { astNode: astNodeMap[fieldName] })); copyMissingProperties(graphqlInputField, field); resultFieldMap[fieldName] = graphqlInputField; } else { resultFieldMap[fieldName] = field; } } return resultFieldMap; } function convertInputFieldMapToConfig(fieldMap, sc) { const fields = {}; const isThunk = (0, is_1.isFunction)(fieldMap); const _fields = isThunk ? fieldMap(sc) : fieldMap; Object.keys(_fields).forEach((n) => { var _a; const _b = _fields[n], { name, isDeprecated } = _b, fc = __rest(_b, ["name", "isDeprecated"]); fields[n] = Object.assign(Object.assign({}, fc), { type: isThunk ? new ThunkComposer_1.ThunkComposer(() => sc.typeMapper.convertInputTypeDefinition(fc.type || _fields[n])) : sc.typeMapper.convertInputTypeDefinition(fc.type || _fields[n]), directives: sc.typeMapper.parseDirectives((_a = fc === null || fc === void 0 ? void 0 : fc.astNode) === null || _a === void 0 ? void 0 : _a.directives) }); }); return fields; } function convertObjectTypeArrayAsThunk(types, sc) { const isThunk = (0, is_1.isFunction)(types); const t = isThunk ? types(sc) : types; if (!Array.isArray(t)) return []; return t.map((type) => { if (type instanceof ObjectTypeComposer_1.ObjectTypeComposer || type instanceof ThunkComposer_1.ThunkComposer) { return type; } const tc = sc.typeMapper.convertOutputTypeDefinition(type); if (!tc && isThunk) { return new ThunkComposer_1.ThunkComposer(() => sc.typeMapper.convertOutputTypeDefinition(type), (0, typeHelpers_1.getComposeTypeName)(type, sc)); } if (!(tc instanceof ObjectTypeComposer_1.ObjectTypeComposer) && !(tc instanceof ThunkComposer_1.ThunkComposer)) { throw new Error(`Should be provided ObjectType but received ${(0, misc_1.inspect)(type)}`); } return tc; }); } function convertInterfaceArrayAsThunk(types, sc) { const isThunk = (0, is_1.isFunction)(types); const t = isThunk ? types(sc) : types; if (!Array.isArray(t)) return []; return t.map((type) => { if (type instanceof InterfaceTypeComposer_1.InterfaceTypeComposer || type instanceof ThunkComposer_1.ThunkComposer) { return type; } return isThunk ? new ThunkComposer_1.ThunkComposer(() => sc.typeMapper.convertInterfaceTypeDefinition(type), (0, typeHelpers_1.getComposeTypeName)(type, sc)) : sc.typeMapper.convertInterfaceTypeDefinition(type); }); } //# sourceMappingURL=configToDefine.js.map