node_modules.graphql.utilities.buildASTSchema.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-client-maven-plugin Show documentation
Show all versions of apollo-client-maven-plugin Show documentation
Maven plugin for generating graphql clients
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.buildASTSchema = buildASTSchema;
exports.getDeprecationReason = getDeprecationReason;
exports.getDescription = getDescription;
exports.buildSchema = buildSchema;
var _invariant = require('../jsutils/invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _keyValMap = require('../jsutils/keyValMap');
var _keyValMap2 = _interopRequireDefault(_keyValMap);
var _valueFromAST = require('./valueFromAST');
var _lexer = require('../language/lexer');
var _parser = require('../language/parser');
var _values = require('../execution/values');
var _kinds = require('../language/kinds');
var Kind = _interopRequireWildcard(_kinds);
var _schema = require('../type/schema');
var _scalars = require('../type/scalars');
var _definition = require('../type/definition');
var _directives = require('../type/directives');
var _introspection = require('../type/introspection');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
function buildWrappedType(innerType, inputTypeNode) {
if (inputTypeNode.kind === Kind.LIST_TYPE) {
return new _definition.GraphQLList(buildWrappedType(innerType, inputTypeNode.type));
}
if (inputTypeNode.kind === Kind.NON_NULL_TYPE) {
var wrappedType = buildWrappedType(innerType, inputTypeNode.type);
!!(wrappedType instanceof _definition.GraphQLNonNull) ? (0, _invariant2.default)(0, 'No nesting nonnull.') : void 0;
return new _definition.GraphQLNonNull(wrappedType);
}
return innerType;
}
function getNamedTypeNode(typeNode) {
var namedType = typeNode;
while (namedType.kind === Kind.LIST_TYPE || namedType.kind === Kind.NON_NULL_TYPE) {
namedType = namedType.type;
}
return namedType;
}
/**
* This takes the ast of a schema document produced by the parse function in
* src/language/parser.js.
*
* If no schema definition is provided, then it will look for types named Query
* and Mutation.
*
* Given that AST it constructs a GraphQLSchema. The resulting schema
* has no resolve methods, so execution will use default resolvers.
*/
function buildASTSchema(ast) {
if (!ast || ast.kind !== Kind.DOCUMENT) {
throw new Error('Must provide a document ast.');
}
var schemaDef = void 0;
var typeDefs = [];
var nodeMap = Object.create(null);
var directiveDefs = [];
for (var i = 0; i < ast.definitions.length; i++) {
var d = ast.definitions[i];
switch (d.kind) {
case Kind.SCHEMA_DEFINITION:
if (schemaDef) {
throw new Error('Must provide only one schema definition.');
}
schemaDef = d;
break;
case Kind.SCALAR_TYPE_DEFINITION:
case Kind.OBJECT_TYPE_DEFINITION:
case Kind.INTERFACE_TYPE_DEFINITION:
case Kind.ENUM_TYPE_DEFINITION:
case Kind.UNION_TYPE_DEFINITION:
case Kind.INPUT_OBJECT_TYPE_DEFINITION:
var typeName = d.name.value;
if (nodeMap[typeName]) {
throw new Error('Type "' + typeName + '" was defined more than once.');
}
typeDefs.push(d);
nodeMap[typeName] = d;
break;
case Kind.DIRECTIVE_DEFINITION:
directiveDefs.push(d);
break;
}
}
var queryTypeName = void 0;
var mutationTypeName = void 0;
var subscriptionTypeName = void 0;
if (schemaDef) {
schemaDef.operationTypes.forEach(function (operationType) {
var typeName = operationType.type.name.value;
if (operationType.operation === 'query') {
if (queryTypeName) {
throw new Error('Must provide only one query type in schema.');
}
if (!nodeMap[typeName]) {
throw new Error('Specified query type "' + typeName + '" not found in document.');
}
queryTypeName = typeName;
} else if (operationType.operation === 'mutation') {
if (mutationTypeName) {
throw new Error('Must provide only one mutation type in schema.');
}
if (!nodeMap[typeName]) {
throw new Error('Specified mutation type "' + typeName + '" not found in document.');
}
mutationTypeName = typeName;
} else if (operationType.operation === 'subscription') {
if (subscriptionTypeName) {
throw new Error('Must provide only one subscription type in schema.');
}
if (!nodeMap[typeName]) {
throw new Error('Specified subscription type "' + typeName + '" not found in document.');
}
subscriptionTypeName = typeName;
}
});
} else {
if (nodeMap.Query) {
queryTypeName = 'Query';
}
if (nodeMap.Mutation) {
mutationTypeName = 'Mutation';
}
if (nodeMap.Subscription) {
subscriptionTypeName = 'Subscription';
}
}
if (!queryTypeName) {
throw new Error('Must provide schema definition with query type or a type named Query.');
}
var innerTypeMap = {
String: _scalars.GraphQLString,
Int: _scalars.GraphQLInt,
Float: _scalars.GraphQLFloat,
Boolean: _scalars.GraphQLBoolean,
ID: _scalars.GraphQLID,
__Schema: _introspection.__Schema,
__Directive: _introspection.__Directive,
__DirectiveLocation: _introspection.__DirectiveLocation,
__Type: _introspection.__Type,
__Field: _introspection.__Field,
__InputValue: _introspection.__InputValue,
__EnumValue: _introspection.__EnumValue,
__TypeKind: _introspection.__TypeKind
};
var types = typeDefs.map(function (def) {
return typeDefNamed(def.name.value);
});
var directives = directiveDefs.map(getDirective);
// If specified directives were not explicitly declared, add them.
if (!directives.some(function (directive) {
return directive.name === 'skip';
})) {
directives.push(_directives.GraphQLSkipDirective);
}
if (!directives.some(function (directive) {
return directive.name === 'include';
})) {
directives.push(_directives.GraphQLIncludeDirective);
}
if (!directives.some(function (directive) {
return directive.name === 'deprecated';
})) {
directives.push(_directives.GraphQLDeprecatedDirective);
}
return new _schema.GraphQLSchema({
query: getObjectType(nodeMap[queryTypeName]),
mutation: mutationTypeName ? getObjectType(nodeMap[mutationTypeName]) : null,
subscription: subscriptionTypeName ? getObjectType(nodeMap[subscriptionTypeName]) : null,
types: types,
directives: directives,
astNode: schemaDef
});
function getDirective(directiveNode) {
return new _directives.GraphQLDirective({
name: directiveNode.name.value,
description: getDescription(directiveNode),
locations: directiveNode.locations.map(function (node) {
return node.value;
}),
args: directiveNode.arguments && makeInputValues(directiveNode.arguments),
astNode: directiveNode
});
}
function getObjectType(typeNode) {
var type = typeDefNamed(typeNode.name.value);
!(type instanceof _definition.GraphQLObjectType) ? (0, _invariant2.default)(0, 'AST must provide object type.') : void 0;
return type;
}
function produceType(typeNode) {
var typeName = getNamedTypeNode(typeNode).name.value;
var typeDef = typeDefNamed(typeName);
return buildWrappedType(typeDef, typeNode);
}
function produceInputType(typeNode) {
return (0, _definition.assertInputType)(produceType(typeNode));
}
function produceOutputType(typeNode) {
return (0, _definition.assertOutputType)(produceType(typeNode));
}
function produceObjectType(typeNode) {
var type = produceType(typeNode);
!(type instanceof _definition.GraphQLObjectType) ? (0, _invariant2.default)(0, 'Expected Object type.') : void 0;
return type;
}
function produceInterfaceType(typeNode) {
var type = produceType(typeNode);
!(type instanceof _definition.GraphQLInterfaceType) ? (0, _invariant2.default)(0, 'Expected Interface type.') : void 0;
return type;
}
function typeDefNamed(typeName) {
if (innerTypeMap[typeName]) {
return innerTypeMap[typeName];
}
if (!nodeMap[typeName]) {
throw new Error('Type "' + typeName + '" not found in document.');
}
var innerTypeDef = makeSchemaDef(nodeMap[typeName]);
if (!innerTypeDef) {
throw new Error('Nothing constructed for "' + typeName + '".');
}
innerTypeMap[typeName] = innerTypeDef;
return innerTypeDef;
}
function makeSchemaDef(def) {
if (!def) {
throw new Error('def must be defined');
}
switch (def.kind) {
case Kind.OBJECT_TYPE_DEFINITION:
return makeTypeDef(def);
case Kind.INTERFACE_TYPE_DEFINITION:
return makeInterfaceDef(def);
case Kind.ENUM_TYPE_DEFINITION:
return makeEnumDef(def);
case Kind.UNION_TYPE_DEFINITION:
return makeUnionDef(def);
case Kind.SCALAR_TYPE_DEFINITION:
return makeScalarDef(def);
case Kind.INPUT_OBJECT_TYPE_DEFINITION:
return makeInputObjectDef(def);
default:
throw new Error('Type kind "' + def.kind + '" not supported.');
}
}
function makeTypeDef(def) {
var typeName = def.name.value;
return new _definition.GraphQLObjectType({
name: typeName,
description: getDescription(def),
fields: function fields() {
return makeFieldDefMap(def);
},
interfaces: function interfaces() {
return makeImplementedInterfaces(def);
},
astNode: def
});
}
function makeFieldDefMap(def) {
return (0, _keyValMap2.default)(def.fields, function (field) {
return field.name.value;
}, function (field) {
return {
type: produceOutputType(field.type),
description: getDescription(field),
args: makeInputValues(field.arguments),
deprecationReason: getDeprecationReason(field),
astNode: field
};
});
}
function makeImplementedInterfaces(def) {
return def.interfaces && def.interfaces.map(function (iface) {
return produceInterfaceType(iface);
});
}
function makeInputValues(values) {
return (0, _keyValMap2.default)(values, function (value) {
return value.name.value;
}, function (value) {
var type = produceInputType(value.type);
return {
type: type,
description: getDescription(value),
defaultValue: (0, _valueFromAST.valueFromAST)(value.defaultValue, type),
astNode: value
};
});
}
function makeInterfaceDef(def) {
var typeName = def.name.value;
return new _definition.GraphQLInterfaceType({
name: typeName,
description: getDescription(def),
fields: function fields() {
return makeFieldDefMap(def);
},
astNode: def,
resolveType: cannotExecuteSchema
});
}
function makeEnumDef(def) {
var enumType = new _definition.GraphQLEnumType({
name: def.name.value,
description: getDescription(def),
values: (0, _keyValMap2.default)(def.values, function (enumValue) {
return enumValue.name.value;
}, function (enumValue) {
return {
description: getDescription(enumValue),
deprecationReason: getDeprecationReason(enumValue),
astNode: enumValue
};
}),
astNode: def
});
return enumType;
}
function makeUnionDef(def) {
return new _definition.GraphQLUnionType({
name: def.name.value,
description: getDescription(def),
types: def.types.map(function (t) {
return produceObjectType(t);
}),
resolveType: cannotExecuteSchema,
astNode: def
});
}
function makeScalarDef(def) {
return new _definition.GraphQLScalarType({
name: def.name.value,
description: getDescription(def),
astNode: def,
serialize: function serialize() {
return null;
},
// Note: validation calls the parse functions to determine if a
// literal value is correct. Returning null would cause use of custom
// scalars to always fail validation. Returning false causes them to
// always pass validation.
parseValue: function parseValue() {
return false;
},
parseLiteral: function parseLiteral() {
return false;
}
});
}
function makeInputObjectDef(def) {
return new _definition.GraphQLInputObjectType({
name: def.name.value,
description: getDescription(def),
fields: function fields() {
return makeInputValues(def.fields);
},
astNode: def
});
}
}
/**
* Given a field or enum value node, returns the string value for the
* deprecation reason.
*/
function getDeprecationReason(node) {
var deprecated = (0, _values.getDirectiveValues)(_directives.GraphQLDeprecatedDirective, node);
return deprecated && deprecated.reason;
}
/**
* Given an ast node, returns its string description based on a contiguous
* block full-line of comments preceding it.
*/
function getDescription(node) {
var loc = node.loc;
if (!loc) {
return;
}
var comments = [];
var minSpaces = void 0;
var token = loc.startToken.prev;
while (token && token.kind === _lexer.TokenKind.COMMENT && token.next && token.prev && token.line + 1 === token.next.line && token.line !== token.prev.line) {
var value = String(token.value);
var spaces = leadingSpaces(value);
if (minSpaces === undefined || spaces < minSpaces) {
minSpaces = spaces;
}
comments.push(value);
token = token.prev;
}
return comments.reverse().map(function (comment) {
return comment.slice(minSpaces);
}).join('\n');
}
/**
* A helper function to build a GraphQLSchema directly from a source
* document.
*/
function buildSchema(source) {
return buildASTSchema((0, _parser.parse)(source));
}
// Count the number of spaces on the starting side of a string.
function leadingSpaces(str) {
var i = 0;
for (; i < str.length; i++) {
if (str[i] !== ' ') {
break;
}
}
return i;
}
function cannotExecuteSchema() {
throw new Error('Generated Schema cannot use Interface or Union types for execution.');
}