blob: 19129c0a064d4066932f74b09e8ba0a58a46e788 [file] [log] [blame]
"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