'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); exports.resolveASTSchemaCoordinate = resolveASTSchemaCoordinate; exports.resolveSchemaCoordinate = resolveSchemaCoordinate; var _inspect = require('../jsutils/inspect.js'); var _kinds = require('../language/kinds.js'); var _parser = require('../language/parser.js'); var _definition = require('../type/definition.js'); /** * A schema coordinate is resolved in the context of a GraphQL schema to * uniquely identify a schema element. It returns undefined if the schema * coordinate does not resolve to a schema element, meta-field, or introspection * schema element. It will throw if the containing schema element (if * applicable) does not exist. * * https://spec.graphql.org/draft/#sec-Schema-Coordinates.Semantics */ function resolveSchemaCoordinate(schema, schemaCoordinate) { return resolveASTSchemaCoordinate( schema, (0, _parser.parseSchemaCoordinate)(schemaCoordinate), ); } /** * TypeCoordinate : Name */ function resolveTypeCoordinate(schema, schemaCoordinate) { // 1. Let {typeName} be the value of {Name}. const typeName = schemaCoordinate.name.value; const type = schema.getType(typeName); // 2. Return the type in the {schema} named {typeName} if it exists. if (type == null) { return; } return { kind: 'NamedType', type, }; } /** * MemberCoordinate : Name . Name */ function resolveMemberCoordinate(schema, schemaCoordinate) { // 1. Let {typeName} be the value of the first {Name}. // 2. Let {type} be the type in the {schema} named {typeName}. const typeName = schemaCoordinate.name.value; const type = schema.getType(typeName); // 3. Assert: {type} must exist, and must be an Enum, Input Object, Object or Interface type. if (!type) { throw new Error( `Expected ${(0, _inspect.inspect)( typeName, )} to be defined as a type in the schema.`, ); } if ( !(0, _definition.isEnumType)(type) && !(0, _definition.isInputObjectType)(type) && !(0, _definition.isObjectType)(type) && !(0, _definition.isInterfaceType)(type) ) { throw new Error( `Expected ${(0, _inspect.inspect)( typeName, )} to be an Enum, Input Object, Object or Interface type.`, ); } // 4. If {type} is an Enum type: if ((0, _definition.isEnumType)(type)) { // 1. Let {enumValueName} be the value of the second {Name}. const enumValueName = schemaCoordinate.memberName.value; const enumValue = type.getValue(enumValueName); // 2. Return the enum value of {type} named {enumValueName} if it exists. if (enumValue == null) { return; } return { kind: 'EnumValue', type, enumValue, }; } // 5. Otherwise, if {type} is an Input Object type: if ((0, _definition.isInputObjectType)(type)) { // 1. Let {inputFieldName} be the value of the second {Name}. const inputFieldName = schemaCoordinate.memberName.value; const inputField = type.getFields()[inputFieldName]; // 2. Return the input field of {type} named {inputFieldName} if it exists. if (inputField == null) { return; } return { kind: 'InputField', type, inputField, }; } // 6. Otherwise: // 1. Let {fieldName} be the value of the second {Name}. const fieldName = schemaCoordinate.memberName.value; const field = type.getFields()[fieldName]; // 2. Return the field of {type} named {fieldName} if it exists. if (field == null) { return; } return { kind: 'Field', type, field, }; } /** * ArgumentCoordinate : Name . Name ( Name : ) */ function resolveArgumentCoordinate(schema, schemaCoordinate) { // 1. Let {typeName} be the value of the first {Name}. // 2. Let {type} be the type in the {schema} named {typeName}. const typeName = schemaCoordinate.name.value; const type = schema.getType(typeName); // 3. Assert: {type} must exist, and be an Object or Interface type. if (type == null) { throw new Error( `Expected ${(0, _inspect.inspect)( typeName, )} to be defined as a type in the schema.`, ); } if ( !(0, _definition.isObjectType)(type) && !(0, _definition.isInterfaceType)(type) ) { throw new Error( `Expected ${(0, _inspect.inspect)( typeName, )} to be an object type or interface type.`, ); } // 4. Let {fieldName} be the value of the second {Name}. // 5. Let {field} be the field of {type} named {fieldName}. const fieldName = schemaCoordinate.fieldName.value; const field = type.getFields()[fieldName]; // 7. Assert: {field} must exist. if (field == null) { throw new Error( `Expected ${(0, _inspect.inspect)( fieldName, )} to exist as a field of type ${(0, _inspect.inspect)( typeName, )} in the schema.`, ); } // 7. Let {fieldArgumentName} be the value of the third {Name}. const fieldArgumentName = schemaCoordinate.argumentName.value; const fieldArgument = field.args.find( (arg) => arg.name === fieldArgumentName, ); // 8. Return the argument of {field} named {fieldArgumentName} if it exists. if (fieldArgument == null) { return; } return { kind: 'FieldArgument', type, field, fieldArgument, }; } /** * DirectiveCoordinate : \@ Name */ function resolveDirectiveCoordinate(schema, schemaCoordinate) { // 1. Let {directiveName} be the value of {Name}. const directiveName = schemaCoordinate.name.value; const directive = schema.getDirective(directiveName); // 2. Return the directive in the {schema} named {directiveName} if it exists. if (!directive) { return; } return { kind: 'Directive', directive, }; } /** * DirectiveArgumentCoordinate : \@ Name ( Name : ) */ function resolveDirectiveArgumentCoordinate(schema, schemaCoordinate) { // 1. Let {directiveName} be the value of the first {Name}. // 2. Let {directive} be the directive in the {schema} named {directiveName}. const directiveName = schemaCoordinate.name.value; const directive = schema.getDirective(directiveName); // 3. Assert {directive} must exist. if (!directive) { throw new Error( `Expected ${(0, _inspect.inspect)( directiveName, )} to be defined as a directive in the schema.`, ); } // 4. Let {directiveArgumentName} be the value of the second {Name}. const { argumentName: { value: directiveArgumentName }, } = schemaCoordinate; const directiveArgument = directive.args.find( (arg) => arg.name === directiveArgumentName, ); // 5. Return the argument of {directive} named {directiveArgumentName} if it exists. if (!directiveArgument) { return; } return { kind: 'DirectiveArgument', directive, directiveArgument, }; } /** * Resolves schema coordinate from a parsed SchemaCoordinate node. */ function resolveASTSchemaCoordinate(schema, schemaCoordinate) { switch (schemaCoordinate.kind) { case _kinds.Kind.TYPE_COORDINATE: return resolveTypeCoordinate(schema, schemaCoordinate); case _kinds.Kind.MEMBER_COORDINATE: return resolveMemberCoordinate(schema, schemaCoordinate); case _kinds.Kind.ARGUMENT_COORDINATE: return resolveArgumentCoordinate(schema, schemaCoordinate); case _kinds.Kind.DIRECTIVE_COORDINATE: return resolveDirectiveCoordinate(schema, schemaCoordinate); case _kinds.Kind.DIRECTIVE_ARGUMENT_COORDINATE: return resolveDirectiveArgumentCoordinate(schema, schemaCoordinate); } }