UNPKG

@graphql-mesh/compose-cli

Version:
108 lines (107 loc) 5.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FatalCompositionError = void 0; exports.validateSupergraphSdl = validateSupergraphSdl; const graphql_1 = require("graphql"); const fusion_composition_1 = require("@graphql-mesh/fusion-composition"); const utils_1 = require("@graphql-tools/utils"); class FatalCompositionError extends Error { constructor(message) { super(`Fatal composition error: ${message}`); this.name = 'FatalCompositionError'; Error.captureStackTrace(this, this.constructor); } } exports.FatalCompositionError = FatalCompositionError; function validateSupergraphSdl(supergraphSdl, subgraphs) { const schema = (0, graphql_1.buildSchema)(supergraphSdl, { assumeValid: true, assumeValidSDL: true, noLocation: true, }); const typeMap = schema.getTypeMap(); const errors = []; for (const typeName in typeMap) { const type = typeMap[typeName]; if (type) { const directives = (0, utils_1.getDirectiveExtensions)(type, schema); if (directives?.merge) { for (const mergeDirective of directives.merge) { const subgraphName = mergeDirective.subgraph; const subgraph = subgraphs.find(s => s.name === subgraphName); if (!subgraphName) { errors.push((0, utils_1.createGraphQLError)(`Expected @merge directive on type ${typeName} to have a subgraph argument`, { nodes: type.astNode, })); continue; } else if (!subgraph) { errors.push((0, utils_1.createGraphQLError)(`@merge directive on type ${typeName} references unknown subgraph ${subgraphName}`, { nodes: type.astNode, })); } continue; } } if (directives?.resolveTo) { for (const resolveToDirective of directives.resolveTo) { const subgraphName = resolveToDirective.sourceName; const subgraph = subgraphs.find(s => s.name === subgraphName); if (!subgraphName) { errors.push((0, utils_1.createGraphQLError)(`Expected @resolveTo directive on type ${typeName} to have a sourceName argument`, { nodes: type.astNode, })); continue; } else if (!subgraph) { errors.push((0, utils_1.createGraphQLError)(`@resolveTo directive on type ${typeName} references unknown subgraph ${subgraphName}`, { nodes: type.astNode, })); continue; } if (resolveToDirective.sourceFieldName && resolveToDirective.sourceTypeName) { const typeDef = subgraph.typeDefs.definitions.find(def => 'name' in def && def.name.value === resolveToDirective.sourceTypeName); if (!typeDef) { errors.push((0, utils_1.createGraphQLError)(`@resolveTo directive on type ${typeName} references unknown type ${resolveToDirective.sourceTypeName} in subgraph ${subgraphName}`, { nodes: type.astNode, })); continue; } const fields = ('fields' in typeDef && typeDef.fields) || []; const fieldName = resolveToDirective.sourceFieldName; const fieldDef = fields.find(f => f.name.value === fieldName); if (!fieldDef) { const suggestions = (0, fusion_composition_1.suggestionList)(fieldName, fields.map(f => f.name.value)); const suggestionStr = suggestions.length ? ` Did you mean "${suggestions.join(' or ')}"?` : ''; errors.push((0, utils_1.createGraphQLError)(`@resolveTo directive on type ${typeName} references unknown field ${fieldName} in subgraph ${subgraphName} ${suggestionStr}`, { nodes: type.astNode, })); continue; } // Args validation if (resolveToDirective.sourceArgs) { const argOfFields = 'arguments' in fieldDef && fieldDef.arguments ? fieldDef.arguments.map(arg => arg.name.value) : []; for (const argName in resolveToDirective.sourceArgs) { const argNameInField = argOfFields.find(arg => arg === argName); if (!argNameInField) { const suggestions = (0, fusion_composition_1.suggestionList)(argName, argOfFields); const suggestionStr = suggestions.length ? ` Did you mean "${suggestions.join(' or ')}"?` : ''; errors.push((0, utils_1.createGraphQLError)(`@resolveTo directive on type ${typeName} references unknown argument ${argName} in field ${fieldName} of subgraph ${subgraphName} ${suggestionStr}`, { nodes: type.astNode, })); } } } } } } } } return errors; }