| "use strict"; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var lodash_1 = require("lodash"); |
| var builtinTypes = ['String', 'Float', 'Int', 'Boolean', 'ID']; |
| var builtinDirectives = ['deprecated', 'skip', 'include']; |
| /** |
| * Post processing of all imported type definitions. Loops over each of the |
| * imported type definitions, and processes it using collectNewTypeDefinitions. |
| * |
| * @param allDefinitions All definitions from all schemas |
| * @param definitionPool Current definitions (from first schema) |
| * @param newTypeDefinitions All imported definitions |
| * @returns Final collection of type definitions for the resulting schema |
| */ |
| function completeDefinitionPool(allDefinitions, definitionPool, newTypeDefinitions) { |
| var visitedDefinitions = {}; |
| while (newTypeDefinitions.length > 0) { |
| var schemaMap = lodash_1.keyBy(allDefinitions, function (d) { return d.name.value; }); |
| var newDefinition = newTypeDefinitions.shift(); |
| if (visitedDefinitions[newDefinition.name.value]) { |
| continue; |
| } |
| var collectedTypedDefinitions = collectNewTypeDefinitions(allDefinitions, definitionPool, newDefinition, schemaMap); |
| newTypeDefinitions.push.apply(newTypeDefinitions, collectedTypedDefinitions); |
| definitionPool.push.apply(definitionPool, collectedTypedDefinitions); |
| visitedDefinitions[newDefinition.name.value] = true; |
| } |
| return lodash_1.uniqBy(definitionPool, 'name.value'); |
| } |
| exports.completeDefinitionPool = completeDefinitionPool; |
| /** |
| * Processes a single type definition, and performs a number of checks: |
| * - Add missing interface implementations |
| * - Add missing referenced types |
| * - Remove unused type definitions |
| * |
| * @param allDefinitions All definitions from all schemas |
| * (only used to find missing interface implementations) |
| * @param definitionPool Resulting definitions |
| * @param newDefinition All imported definitions |
| * @param schemaMap Map of all definitions for easy lookup |
| * @returns All relevant type definitions to add to the final schema |
| */ |
| function collectNewTypeDefinitions(allDefinitions, definitionPool, newDefinition, schemaMap) { |
| var newTypeDefinitions = []; |
| if (newDefinition.kind !== 'DirectiveDefinition') { |
| newDefinition.directives.forEach(collectDirective); |
| } |
| if (newDefinition.kind === 'InputObjectTypeDefinition') { |
| newDefinition.fields.forEach(collectNode); |
| } |
| if (newDefinition.kind === 'InterfaceTypeDefinition') { |
| var interfaceName_1 = newDefinition.name.value; |
| newDefinition.fields.forEach(collectNode); |
| var interfaceImplementations = allDefinitions.filter(function (d) { |
| return d.kind === 'ObjectTypeDefinition' && |
| d.interfaces.some(function (i) { return i.name.value === interfaceName_1; }); |
| }); |
| newTypeDefinitions.push.apply(newTypeDefinitions, interfaceImplementations); |
| } |
| if (newDefinition.kind === 'UnionTypeDefinition') { |
| newDefinition.types.forEach(function (type) { |
| if (!definitionPool.some(function (d) { return d.name.value === type.name.value; })) { |
| var typeName = type.name.value; |
| var typeMatch = schemaMap[typeName]; |
| if (!typeMatch) { |
| throw new Error("Couldn't find type " + typeName + " in any of the schemas."); |
| } |
| newTypeDefinitions.push(schemaMap[type.name.value]); |
| } |
| }); |
| } |
| if (newDefinition.kind === 'ObjectTypeDefinition') { |
| // collect missing interfaces |
| newDefinition.interfaces.forEach(function (int) { |
| if (!definitionPool.some(function (d) { return d.name.value === int.name.value; })) { |
| var interfaceName = int.name.value; |
| var interfaceMatch = schemaMap[interfaceName]; |
| if (!interfaceMatch) { |
| throw new Error("Couldn't find interface " + interfaceName + " in any of the schemas."); |
| } |
| newTypeDefinitions.push(schemaMap[int.name.value]); |
| } |
| }); |
| // iterate over all fields |
| newDefinition.fields.forEach(function (field) { |
| collectNode(field); |
| // collect missing argument input types |
| field.arguments.forEach(collectNode); |
| }); |
| } |
| return newTypeDefinitions; |
| function collectNode(node) { |
| var nodeType = getNamedType(node.type); |
| var nodeTypeName = nodeType.name.value; |
| // collect missing argument input types |
| if (!definitionPool.some(function (d) { return d.name.value === nodeTypeName; }) && |
| !lodash_1.includes(builtinTypes, nodeTypeName)) { |
| var argTypeMatch = schemaMap[nodeTypeName]; |
| if (!argTypeMatch) { |
| throw new Error("Field " + node.name.value + ": Couldn't find type " + nodeTypeName + " in any of the schemas."); |
| } |
| newTypeDefinitions.push(argTypeMatch); |
| } |
| node.directives.forEach(collectDirective); |
| } |
| function collectDirective(directive) { |
| var directiveName = directive.name.value; |
| if (!definitionPool.some(function (d) { return d.name.value === directiveName; }) && |
| !lodash_1.includes(builtinDirectives, directiveName)) { |
| var directive_1 = schemaMap[directiveName]; |
| if (!directive_1) { |
| throw new Error("Directive " + directiveName + ": Couldn't find type " + directiveName + " in any of the schemas."); |
| } |
| directive_1.arguments.forEach(collectNode); |
| newTypeDefinitions.push(directive_1); |
| } |
| } |
| } |
| /** |
| * Nested visitor for a type node to get to the final NamedType |
| * |
| * @param {TypeNode} type Type node to get NamedTypeNode for |
| * @returns {NamedTypeNode} The found NamedTypeNode |
| */ |
| function getNamedType(type) { |
| if (type.kind === 'NamedType') { |
| return type; |
| } |
| else { |
| return getNamedType(type.type); |
| } |
| } |
| //# sourceMappingURL=definition.js.map |