blob: c66dad4e403ed69785a4afe58ea860763548b5d8 [file] [log] [blame]
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parse = parse;
exports.parseValue = parseValue;
exports.parseType = parseType;
var _inspect = _interopRequireDefault(require("../jsutils/inspect"));
var _devAssert = _interopRequireDefault(require("../jsutils/devAssert"));
var _syntaxError = require("../error/syntaxError");
var _kinds = require("./kinds");
var _source = require("./source");
var _directiveLocation = require("./directiveLocation");
var _tokenKind = require("./tokenKind");
var _lexer = require("./lexer");
var _ast = require("./ast");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Given a GraphQL source, parses it into a Document.
* Throws GraphQLError if a syntax error is encountered.
*/
function parse(source, options) {
var parser = new Parser(source, options);
return parser.parseDocument();
}
/**
* Given a string containing a GraphQL value (ex. `[42]`), parse the AST for
* that value.
* Throws GraphQLError if a syntax error is encountered.
*
* This is useful within tools that operate upon GraphQL Values directly and
* in isolation of complete GraphQL documents.
*
* Consider providing the results to the utility function: valueFromAST().
*/
function parseValue(source, options) {
var parser = new Parser(source, options);
parser.expectToken(_tokenKind.TokenKind.SOF);
var value = parser.parseValueLiteral(false);
parser.expectToken(_tokenKind.TokenKind.EOF);
return value;
}
/**
* Given a string containing a GraphQL Type (ex. `[Int!]`), parse the AST for
* that type.
* Throws GraphQLError if a syntax error is encountered.
*
* This is useful within tools that operate upon GraphQL Types directly and
* in isolation of complete GraphQL documents.
*
* Consider providing the results to the utility function: typeFromAST().
*/
function parseType(source, options) {
var parser = new Parser(source, options);
parser.expectToken(_tokenKind.TokenKind.SOF);
var type = parser.parseTypeReference();
parser.expectToken(_tokenKind.TokenKind.EOF);
return type;
}
var Parser =
/*#__PURE__*/
function () {
function Parser(source, options) {
var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
sourceObj instanceof _source.Source || (0, _devAssert.default)(0, "Must provide Source. Received: ".concat((0, _inspect.default)(sourceObj), "."));
this._lexer = new _lexer.Lexer(sourceObj);
this._options = options;
}
/**
* Converts a name lex token into a name parse node.
*/
var _proto = Parser.prototype;
_proto.parseName = function parseName() {
var token = this.expectToken(_tokenKind.TokenKind.NAME);
return {
kind: _kinds.Kind.NAME,
value: token.value,
loc: this.loc(token)
};
} // Implements the parsing rules in the Document section.
/**
* Document : Definition+
*/
;
_proto.parseDocument = function parseDocument() {
var start = this._lexer.token;
return {
kind: _kinds.Kind.DOCUMENT,
definitions: this.many(_tokenKind.TokenKind.SOF, this.parseDefinition, _tokenKind.TokenKind.EOF),
loc: this.loc(start)
};
}
/**
* Definition :
* - ExecutableDefinition
* - TypeSystemDefinition
* - TypeSystemExtension
*
* ExecutableDefinition :
* - OperationDefinition
* - FragmentDefinition
*/
;
_proto.parseDefinition = function parseDefinition() {
if (this.peek(_tokenKind.TokenKind.NAME)) {
switch (this._lexer.token.value) {
case 'query':
case 'mutation':
case 'subscription':
return this.parseOperationDefinition();
case 'fragment':
return this.parseFragmentDefinition();
case 'schema':
case 'scalar':
case 'type':
case 'interface':
case 'union':
case 'enum':
case 'input':
case 'directive':
return this.parseTypeSystemDefinition();
case 'extend':
return this.parseTypeSystemExtension();
}
} else if (this.peek(_tokenKind.TokenKind.BRACE_L)) {
return this.parseOperationDefinition();
} else if (this.peekDescription()) {
return this.parseTypeSystemDefinition();
}
throw this.unexpected();
} // Implements the parsing rules in the Operations section.
/**
* OperationDefinition :
* - SelectionSet
* - OperationType Name? VariableDefinitions? Directives? SelectionSet
*/
;
_proto.parseOperationDefinition = function parseOperationDefinition() {
var start = this._lexer.token;
if (this.peek(_tokenKind.TokenKind.BRACE_L)) {
return {
kind: _kinds.Kind.OPERATION_DEFINITION,
operation: 'query',
name: undefined,
variableDefinitions: [],
directives: [],
selectionSet: this.parseSelectionSet(),
loc: this.loc(start)
};
}
var operation = this.parseOperationType();
var name;
if (this.peek(_tokenKind.TokenKind.NAME)) {
name = this.parseName();
}
return {
kind: _kinds.Kind.OPERATION_DEFINITION,
operation: operation,
name: name,
variableDefinitions: this.parseVariableDefinitions(),
directives: this.parseDirectives(false),
selectionSet: this.parseSelectionSet(),
loc: this.loc(start)
};
}
/**
* OperationType : one of query mutation subscription
*/
;
_proto.parseOperationType = function parseOperationType() {
var operationToken = this.expectToken(_tokenKind.TokenKind.NAME);
switch (operationToken.value) {
case 'query':
return 'query';
case 'mutation':
return 'mutation';
case 'subscription':
return 'subscription';
}
throw this.unexpected(operationToken);
}
/**
* VariableDefinitions : ( VariableDefinition+ )
*/
;
_proto.parseVariableDefinitions = function parseVariableDefinitions() {
return this.optionalMany(_tokenKind.TokenKind.PAREN_L, this.parseVariableDefinition, _tokenKind.TokenKind.PAREN_R);
}
/**
* VariableDefinition : Variable : Type DefaultValue? Directives[Const]?
*/
;
_proto.parseVariableDefinition = function parseVariableDefinition() {
var start = this._lexer.token;
return {
kind: _kinds.Kind.VARIABLE_DEFINITION,
variable: this.parseVariable(),
type: (this.expectToken(_tokenKind.TokenKind.COLON), this.parseTypeReference()),
defaultValue: this.expectOptionalToken(_tokenKind.TokenKind.EQUALS) ? this.parseValueLiteral(true) : undefined,
directives: this.parseDirectives(true),
loc: this.loc(start)
};
}
/**
* Variable : $ Name
*/
;
_proto.parseVariable = function parseVariable() {
var start = this._lexer.token;
this.expectToken(_tokenKind.TokenKind.DOLLAR);
return {
kind: _kinds.Kind.VARIABLE,
name: this.parseName(),
loc: this.loc(start)
};
}
/**
* SelectionSet : { Selection+ }
*/
;
_proto.parseSelectionSet = function parseSelectionSet() {
var start = this._lexer.token;
return {
kind: _kinds.Kind.SELECTION_SET,
selections: this.many(_tokenKind.TokenKind.BRACE_L, this.parseSelection, _tokenKind.TokenKind.BRACE_R),
loc: this.loc(start)
};
}
/**
* Selection :
* - Field
* - FragmentSpread
* - InlineFragment
*/
;
_proto.parseSelection = function parseSelection() {
return this.peek(_tokenKind.TokenKind.SPREAD) ? this.parseFragment() : this.parseField();
}
/**
* Field : Alias? Name Arguments? Directives? SelectionSet?
*
* Alias : Name :
*/
;
_proto.parseField = function parseField() {
var start = this._lexer.token;
var nameOrAlias = this.parseName();
var alias;
var name;
if (this.expectOptionalToken(_tokenKind.TokenKind.COLON)) {
alias = nameOrAlias;
name = this.parseName();
} else {
name = nameOrAlias;
}
return {
kind: _kinds.Kind.FIELD,
alias: alias,
name: name,
arguments: this.parseArguments(false),
directives: this.parseDirectives(false),
selectionSet: this.peek(_tokenKind.TokenKind.BRACE_L) ? this.parseSelectionSet() : undefined,
loc: this.loc(start)
};
}
/**
* Arguments[Const] : ( Argument[?Const]+ )
*/
;
_proto.parseArguments = function parseArguments(isConst) {
var item = isConst ? this.parseConstArgument : this.parseArgument;
return this.optionalMany(_tokenKind.TokenKind.PAREN_L, item, _tokenKind.TokenKind.PAREN_R);
}
/**
* Argument[Const] : Name : Value[?Const]
*/
;
_proto.parseArgument = function parseArgument() {
var start = this._lexer.token;
var name = this.parseName();
this.expectToken(_tokenKind.TokenKind.COLON);
return {
kind: _kinds.Kind.ARGUMENT,
name: name,
value: this.parseValueLiteral(false),
loc: this.loc(start)
};
};
_proto.parseConstArgument = function parseConstArgument() {
var start = this._lexer.token;
return {
kind: _kinds.Kind.ARGUMENT,
name: this.parseName(),
value: (this.expectToken(_tokenKind.TokenKind.COLON), this.parseValueLiteral(true)),
loc: this.loc(start)
};
} // Implements the parsing rules in the Fragments section.
/**
* Corresponds to both FragmentSpread and InlineFragment in the spec.
*
* FragmentSpread : ... FragmentName Directives?
*
* InlineFragment : ... TypeCondition? Directives? SelectionSet
*/
;
_proto.parseFragment = function parseFragment() {
var start = this._lexer.token;
this.expectToken(_tokenKind.TokenKind.SPREAD);
var hasTypeCondition = this.expectOptionalKeyword('on');
if (!hasTypeCondition && this.peek(_tokenKind.TokenKind.NAME)) {
return {
kind: _kinds.Kind.FRAGMENT_SPREAD,
name: this.parseFragmentName(),
directives: this.parseDirectives(false),
loc: this.loc(start)
};
}
return {
kind: _kinds.Kind.INLINE_FRAGMENT,
typeCondition: hasTypeCondition ? this.parseNamedType() : undefined,
directives: this.parseDirectives(false),
selectionSet: this.parseSelectionSet(),
loc: this.loc(start)
};
}
/**
* FragmentDefinition :
* - fragment FragmentName on TypeCondition Directives? SelectionSet
*
* TypeCondition : NamedType
*/
;
_proto.parseFragmentDefinition = function parseFragmentDefinition() {
var _this$_options;
var start = this._lexer.token;
this.expectKeyword('fragment'); // Experimental support for defining variables within fragments changes
// the grammar of FragmentDefinition:
// - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
if (((_this$_options = this._options) === null || _this$_options === void 0 ? void 0 : _this$_options.experimentalFragmentVariables) === true) {
return {
kind: _kinds.Kind.FRAGMENT_DEFINITION,
name: this.parseFragmentName(),
variableDefinitions: this.parseVariableDefinitions(),
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
directives: this.parseDirectives(false),
selectionSet: this.parseSelectionSet(),
loc: this.loc(start)
};
}
return {
kind: _kinds.Kind.FRAGMENT_DEFINITION,
name: this.parseFragmentName(),
typeCondition: (this.expectKeyword('on'), this.parseNamedType()),
directives: this.parseDirectives(false),
selectionSet: this.parseSelectionSet(),
loc: this.loc(start)
};
}
/**
* FragmentName : Name but not `on`
*/
;
_proto.parseFragmentName = function parseFragmentName() {
if (this._lexer.token.value === 'on') {
throw this.unexpected();
}
return this.parseName();
} // Implements the parsing rules in the Values section.
/**
* Value[Const] :
* - [~Const] Variable
* - IntValue
* - FloatValue
* - StringValue
* - BooleanValue
* - NullValue
* - EnumValue
* - ListValue[?Const]
* - ObjectValue[?Const]
*
* BooleanValue : one of `true` `false`
*
* NullValue : `null`
*
* EnumValue : Name but not `true`, `false` or `null`
*/
;
_proto.parseValueLiteral = function parseValueLiteral(isConst) {
var token = this._lexer.token;
switch (token.kind) {
case _tokenKind.TokenKind.BRACKET_L:
return this.parseList(isConst);
case _tokenKind.TokenKind.BRACE_L:
return this.parseObject(isConst);
case _tokenKind.TokenKind.INT:
this._lexer.advance();
return {
kind: _kinds.Kind.INT,
value: token.value,
loc: this.loc(token)
};
case _tokenKind.TokenKind.FLOAT:
this._lexer.advance();
return {
kind: _kinds.Kind.FLOAT,
value: token.value,
loc: this.loc(token)
};
case _tokenKind.TokenKind.STRING:
case _tokenKind.TokenKind.BLOCK_STRING:
return this.parseStringLiteral();
case _tokenKind.TokenKind.NAME:
this._lexer.advance();
switch (token.value) {
case 'true':
return {
kind: _kinds.Kind.BOOLEAN,
value: true,
loc: this.loc(token)
};
case 'false':
return {
kind: _kinds.Kind.BOOLEAN,
value: false,
loc: this.loc(token)
};
case 'null':
return {
kind: _kinds.Kind.NULL,
loc: this.loc(token)
};
default:
return {
kind: _kinds.Kind.ENUM,
value: token.value,
loc: this.loc(token)
};
}
case _tokenKind.TokenKind.DOLLAR:
if (!isConst) {
return this.parseVariable();
}
break;
}
throw this.unexpected();
};
_proto.parseStringLiteral = function parseStringLiteral() {
var token = this._lexer.token;
this._lexer.advance();
return {
kind: _kinds.Kind.STRING,
value: token.value,
block: token.kind === _tokenKind.TokenKind.BLOCK_STRING,
loc: this.loc(token)
};
}
/**
* ListValue[Const] :
* - [ ]
* - [ Value[?Const]+ ]
*/
;
_proto.parseList = function parseList(isConst) {
var _this = this;
var start = this._lexer.token;
var item = function item() {
return _this.parseValueLiteral(isConst);
};
return {
kind: _kinds.Kind.LIST,
values: this.any(_tokenKind.TokenKind.BRACKET_L, item, _tokenKind.TokenKind.BRACKET_R),
loc: this.loc(start)
};
}
/**
* ObjectValue[Const] :
* - { }
* - { ObjectField[?Const]+ }
*/
;
_proto.parseObject = function parseObject(isConst) {
var _this2 = this;
var start = this._lexer.token;
var item = function item() {
return _this2.parseObjectField(isConst);
};
return {
kind: _kinds.Kind.OBJECT,
fields: this.any(_tokenKind.TokenKind.BRACE_L, item, _tokenKind.TokenKind.BRACE_R),
loc: this.loc(start)
};
}
/**
* ObjectField[Const] : Name : Value[?Const]
*/
;
_proto.parseObjectField = function parseObjectField(isConst) {
var start = this._lexer.token;
var name = this.parseName();
this.expectToken(_tokenKind.TokenKind.COLON);
return {
kind: _kinds.Kind.OBJECT_FIELD,
name: name,
value: this.parseValueLiteral(isConst),
loc: this.loc(start)
};
} // Implements the parsing rules in the Directives section.
/**
* Directives[Const] : Directive[?Const]+
*/
;
_proto.parseDirectives = function parseDirectives(isConst) {
var directives = [];
while (this.peek(_tokenKind.TokenKind.AT)) {
directives.push(this.parseDirective(isConst));
}
return directives;
}
/**
* Directive[Const] : @ Name Arguments[?Const]?
*/
;
_proto.parseDirective = function parseDirective(isConst) {
var start = this._lexer.token;
this.expectToken(_tokenKind.TokenKind.AT);
return {
kind: _kinds.Kind.DIRECTIVE,
name: this.parseName(),
arguments: this.parseArguments(isConst),
loc: this.loc(start)
};
} // Implements the parsing rules in the Types section.
/**
* Type :
* - NamedType
* - ListType
* - NonNullType
*/
;
_proto.parseTypeReference = function parseTypeReference() {
var start = this._lexer.token;
var type;
if (this.expectOptionalToken(_tokenKind.TokenKind.BRACKET_L)) {
type = this.parseTypeReference();
this.expectToken(_tokenKind.TokenKind.BRACKET_R);
type = {
kind: _kinds.Kind.LIST_TYPE,
type: type,
loc: this.loc(start)
};
} else {
type = this.parseNamedType();
}
if (this.expectOptionalToken(_tokenKind.TokenKind.BANG)) {
return {
kind: _kinds.Kind.NON_NULL_TYPE,
type: type,
loc: this.loc(start)
};
}
return type;
}
/**
* NamedType : Name
*/
;
_proto.parseNamedType = function parseNamedType() {
var start = this._lexer.token;
return {
kind: _kinds.Kind.NAMED_TYPE,
name: this.parseName(),
loc: this.loc(start)
};
} // Implements the parsing rules in the Type Definition section.
/**
* TypeSystemDefinition :
* - SchemaDefinition
* - TypeDefinition
* - DirectiveDefinition
*
* TypeDefinition :
* - ScalarTypeDefinition
* - ObjectTypeDefinition
* - InterfaceTypeDefinition
* - UnionTypeDefinition
* - EnumTypeDefinition
* - InputObjectTypeDefinition
*/
;
_proto.parseTypeSystemDefinition = function parseTypeSystemDefinition() {
// Many definitions begin with a description and require a lookahead.
var keywordToken = this.peekDescription() ? this._lexer.lookahead() : this._lexer.token;
if (keywordToken.kind === _tokenKind.TokenKind.NAME) {
switch (keywordToken.value) {
case 'schema':
return this.parseSchemaDefinition();
case 'scalar':
return this.parseScalarTypeDefinition();
case 'type':
return this.parseObjectTypeDefinition();
case 'interface':
return this.parseInterfaceTypeDefinition();
case 'union':
return this.parseUnionTypeDefinition();
case 'enum':
return this.parseEnumTypeDefinition();
case 'input':
return this.parseInputObjectTypeDefinition();
case 'directive':
return this.parseDirectiveDefinition();
}
}
throw this.unexpected(keywordToken);
};
_proto.peekDescription = function peekDescription() {
return this.peek(_tokenKind.TokenKind.STRING) || this.peek(_tokenKind.TokenKind.BLOCK_STRING);
}
/**
* Description : StringValue
*/
;
_proto.parseDescription = function parseDescription() {
if (this.peekDescription()) {
return this.parseStringLiteral();
}
}
/**
* SchemaDefinition : Description? schema Directives[Const]? { OperationTypeDefinition+ }
*/
;
_proto.parseSchemaDefinition = function parseSchemaDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('schema');
var directives = this.parseDirectives(true);
var operationTypes = this.many(_tokenKind.TokenKind.BRACE_L, this.parseOperationTypeDefinition, _tokenKind.TokenKind.BRACE_R);
return {
kind: _kinds.Kind.SCHEMA_DEFINITION,
description: description,
directives: directives,
operationTypes: operationTypes,
loc: this.loc(start)
};
}
/**
* OperationTypeDefinition : OperationType : NamedType
*/
;
_proto.parseOperationTypeDefinition = function parseOperationTypeDefinition() {
var start = this._lexer.token;
var operation = this.parseOperationType();
this.expectToken(_tokenKind.TokenKind.COLON);
var type = this.parseNamedType();
return {
kind: _kinds.Kind.OPERATION_TYPE_DEFINITION,
operation: operation,
type: type,
loc: this.loc(start)
};
}
/**
* ScalarTypeDefinition : Description? scalar Name Directives[Const]?
*/
;
_proto.parseScalarTypeDefinition = function parseScalarTypeDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('scalar');
var name = this.parseName();
var directives = this.parseDirectives(true);
return {
kind: _kinds.Kind.SCALAR_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
loc: this.loc(start)
};
}
/**
* ObjectTypeDefinition :
* Description?
* type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition?
*/
;
_proto.parseObjectTypeDefinition = function parseObjectTypeDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('type');
var name = this.parseName();
var interfaces = this.parseImplementsInterfaces();
var directives = this.parseDirectives(true);
var fields = this.parseFieldsDefinition();
return {
kind: _kinds.Kind.OBJECT_TYPE_DEFINITION,
description: description,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: this.loc(start)
};
}
/**
* ImplementsInterfaces :
* - implements `&`? NamedType
* - ImplementsInterfaces & NamedType
*/
;
_proto.parseImplementsInterfaces = function parseImplementsInterfaces() {
var types = [];
if (this.expectOptionalKeyword('implements')) {
// Optional leading ampersand
this.expectOptionalToken(_tokenKind.TokenKind.AMP);
do {
var _this$_options2;
types.push(this.parseNamedType());
} while (this.expectOptionalToken(_tokenKind.TokenKind.AMP) || // Legacy support for the SDL?
((_this$_options2 = this._options) === null || _this$_options2 === void 0 ? void 0 : _this$_options2.allowLegacySDLImplementsInterfaces) === true && this.peek(_tokenKind.TokenKind.NAME));
}
return types;
}
/**
* FieldsDefinition : { FieldDefinition+ }
*/
;
_proto.parseFieldsDefinition = function parseFieldsDefinition() {
var _this$_options3;
// Legacy support for the SDL?
if (((_this$_options3 = this._options) === null || _this$_options3 === void 0 ? void 0 : _this$_options3.allowLegacySDLEmptyFields) === true && this.peek(_tokenKind.TokenKind.BRACE_L) && this._lexer.lookahead().kind === _tokenKind.TokenKind.BRACE_R) {
this._lexer.advance();
this._lexer.advance();
return [];
}
return this.optionalMany(_tokenKind.TokenKind.BRACE_L, this.parseFieldDefinition, _tokenKind.TokenKind.BRACE_R);
}
/**
* FieldDefinition :
* - Description? Name ArgumentsDefinition? : Type Directives[Const]?
*/
;
_proto.parseFieldDefinition = function parseFieldDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
var name = this.parseName();
var args = this.parseArgumentDefs();
this.expectToken(_tokenKind.TokenKind.COLON);
var type = this.parseTypeReference();
var directives = this.parseDirectives(true);
return {
kind: _kinds.Kind.FIELD_DEFINITION,
description: description,
name: name,
arguments: args,
type: type,
directives: directives,
loc: this.loc(start)
};
}
/**
* ArgumentsDefinition : ( InputValueDefinition+ )
*/
;
_proto.parseArgumentDefs = function parseArgumentDefs() {
return this.optionalMany(_tokenKind.TokenKind.PAREN_L, this.parseInputValueDef, _tokenKind.TokenKind.PAREN_R);
}
/**
* InputValueDefinition :
* - Description? Name : Type DefaultValue? Directives[Const]?
*/
;
_proto.parseInputValueDef = function parseInputValueDef() {
var start = this._lexer.token;
var description = this.parseDescription();
var name = this.parseName();
this.expectToken(_tokenKind.TokenKind.COLON);
var type = this.parseTypeReference();
var defaultValue;
if (this.expectOptionalToken(_tokenKind.TokenKind.EQUALS)) {
defaultValue = this.parseValueLiteral(true);
}
var directives = this.parseDirectives(true);
return {
kind: _kinds.Kind.INPUT_VALUE_DEFINITION,
description: description,
name: name,
type: type,
defaultValue: defaultValue,
directives: directives,
loc: this.loc(start)
};
}
/**
* InterfaceTypeDefinition :
* - Description? interface Name Directives[Const]? FieldsDefinition?
*/
;
_proto.parseInterfaceTypeDefinition = function parseInterfaceTypeDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('interface');
var name = this.parseName();
var interfaces = this.parseImplementsInterfaces();
var directives = this.parseDirectives(true);
var fields = this.parseFieldsDefinition();
return {
kind: _kinds.Kind.INTERFACE_TYPE_DEFINITION,
description: description,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: this.loc(start)
};
}
/**
* UnionTypeDefinition :
* - Description? union Name Directives[Const]? UnionMemberTypes?
*/
;
_proto.parseUnionTypeDefinition = function parseUnionTypeDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('union');
var name = this.parseName();
var directives = this.parseDirectives(true);
var types = this.parseUnionMemberTypes();
return {
kind: _kinds.Kind.UNION_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
types: types,
loc: this.loc(start)
};
}
/**
* UnionMemberTypes :
* - = `|`? NamedType
* - UnionMemberTypes | NamedType
*/
;
_proto.parseUnionMemberTypes = function parseUnionMemberTypes() {
var types = [];
if (this.expectOptionalToken(_tokenKind.TokenKind.EQUALS)) {
// Optional leading pipe
this.expectOptionalToken(_tokenKind.TokenKind.PIPE);
do {
types.push(this.parseNamedType());
} while (this.expectOptionalToken(_tokenKind.TokenKind.PIPE));
}
return types;
}
/**
* EnumTypeDefinition :
* - Description? enum Name Directives[Const]? EnumValuesDefinition?
*/
;
_proto.parseEnumTypeDefinition = function parseEnumTypeDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('enum');
var name = this.parseName();
var directives = this.parseDirectives(true);
var values = this.parseEnumValuesDefinition();
return {
kind: _kinds.Kind.ENUM_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
values: values,
loc: this.loc(start)
};
}
/**
* EnumValuesDefinition : { EnumValueDefinition+ }
*/
;
_proto.parseEnumValuesDefinition = function parseEnumValuesDefinition() {
return this.optionalMany(_tokenKind.TokenKind.BRACE_L, this.parseEnumValueDefinition, _tokenKind.TokenKind.BRACE_R);
}
/**
* EnumValueDefinition : Description? EnumValue Directives[Const]?
*
* EnumValue : Name
*/
;
_proto.parseEnumValueDefinition = function parseEnumValueDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
var name = this.parseName();
var directives = this.parseDirectives(true);
return {
kind: _kinds.Kind.ENUM_VALUE_DEFINITION,
description: description,
name: name,
directives: directives,
loc: this.loc(start)
};
}
/**
* InputObjectTypeDefinition :
* - Description? input Name Directives[Const]? InputFieldsDefinition?
*/
;
_proto.parseInputObjectTypeDefinition = function parseInputObjectTypeDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('input');
var name = this.parseName();
var directives = this.parseDirectives(true);
var fields = this.parseInputFieldsDefinition();
return {
kind: _kinds.Kind.INPUT_OBJECT_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
fields: fields,
loc: this.loc(start)
};
}
/**
* InputFieldsDefinition : { InputValueDefinition+ }
*/
;
_proto.parseInputFieldsDefinition = function parseInputFieldsDefinition() {
return this.optionalMany(_tokenKind.TokenKind.BRACE_L, this.parseInputValueDef, _tokenKind.TokenKind.BRACE_R);
}
/**
* TypeSystemExtension :
* - SchemaExtension
* - TypeExtension
*
* TypeExtension :
* - ScalarTypeExtension
* - ObjectTypeExtension
* - InterfaceTypeExtension
* - UnionTypeExtension
* - EnumTypeExtension
* - InputObjectTypeDefinition
*/
;
_proto.parseTypeSystemExtension = function parseTypeSystemExtension() {
var keywordToken = this._lexer.lookahead();
if (keywordToken.kind === _tokenKind.TokenKind.NAME) {
switch (keywordToken.value) {
case 'schema':
return this.parseSchemaExtension();
case 'scalar':
return this.parseScalarTypeExtension();
case 'type':
return this.parseObjectTypeExtension();
case 'interface':
return this.parseInterfaceTypeExtension();
case 'union':
return this.parseUnionTypeExtension();
case 'enum':
return this.parseEnumTypeExtension();
case 'input':
return this.parseInputObjectTypeExtension();
}
}
throw this.unexpected(keywordToken);
}
/**
* SchemaExtension :
* - extend schema Directives[Const]? { OperationTypeDefinition+ }
* - extend schema Directives[Const]
*/
;
_proto.parseSchemaExtension = function parseSchemaExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('schema');
var directives = this.parseDirectives(true);
var operationTypes = this.optionalMany(_tokenKind.TokenKind.BRACE_L, this.parseOperationTypeDefinition, _tokenKind.TokenKind.BRACE_R);
if (directives.length === 0 && operationTypes.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.SCHEMA_EXTENSION,
directives: directives,
operationTypes: operationTypes,
loc: this.loc(start)
};
}
/**
* ScalarTypeExtension :
* - extend scalar Name Directives[Const]
*/
;
_proto.parseScalarTypeExtension = function parseScalarTypeExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('scalar');
var name = this.parseName();
var directives = this.parseDirectives(true);
if (directives.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.SCALAR_TYPE_EXTENSION,
name: name,
directives: directives,
loc: this.loc(start)
};
}
/**
* ObjectTypeExtension :
* - extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
* - extend type Name ImplementsInterfaces? Directives[Const]
* - extend type Name ImplementsInterfaces
*/
;
_proto.parseObjectTypeExtension = function parseObjectTypeExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('type');
var name = this.parseName();
var interfaces = this.parseImplementsInterfaces();
var directives = this.parseDirectives(true);
var fields = this.parseFieldsDefinition();
if (interfaces.length === 0 && directives.length === 0 && fields.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.OBJECT_TYPE_EXTENSION,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: this.loc(start)
};
}
/**
* InterfaceTypeExtension :
* - extend interface Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
* - extend interface Name ImplementsInterfaces? Directives[Const]
* - extend interface Name ImplementsInterfaces
*/
;
_proto.parseInterfaceTypeExtension = function parseInterfaceTypeExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('interface');
var name = this.parseName();
var interfaces = this.parseImplementsInterfaces();
var directives = this.parseDirectives(true);
var fields = this.parseFieldsDefinition();
if (interfaces.length === 0 && directives.length === 0 && fields.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.INTERFACE_TYPE_EXTENSION,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: this.loc(start)
};
}
/**
* UnionTypeExtension :
* - extend union Name Directives[Const]? UnionMemberTypes
* - extend union Name Directives[Const]
*/
;
_proto.parseUnionTypeExtension = function parseUnionTypeExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('union');
var name = this.parseName();
var directives = this.parseDirectives(true);
var types = this.parseUnionMemberTypes();
if (directives.length === 0 && types.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.UNION_TYPE_EXTENSION,
name: name,
directives: directives,
types: types,
loc: this.loc(start)
};
}
/**
* EnumTypeExtension :
* - extend enum Name Directives[Const]? EnumValuesDefinition
* - extend enum Name Directives[Const]
*/
;
_proto.parseEnumTypeExtension = function parseEnumTypeExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('enum');
var name = this.parseName();
var directives = this.parseDirectives(true);
var values = this.parseEnumValuesDefinition();
if (directives.length === 0 && values.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.ENUM_TYPE_EXTENSION,
name: name,
directives: directives,
values: values,
loc: this.loc(start)
};
}
/**
* InputObjectTypeExtension :
* - extend input Name Directives[Const]? InputFieldsDefinition
* - extend input Name Directives[Const]
*/
;
_proto.parseInputObjectTypeExtension = function parseInputObjectTypeExtension() {
var start = this._lexer.token;
this.expectKeyword('extend');
this.expectKeyword('input');
var name = this.parseName();
var directives = this.parseDirectives(true);
var fields = this.parseInputFieldsDefinition();
if (directives.length === 0 && fields.length === 0) {
throw this.unexpected();
}
return {
kind: _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION,
name: name,
directives: directives,
fields: fields,
loc: this.loc(start)
};
}
/**
* DirectiveDefinition :
* - Description? directive @ Name ArgumentsDefinition? `repeatable`? on DirectiveLocations
*/
;
_proto.parseDirectiveDefinition = function parseDirectiveDefinition() {
var start = this._lexer.token;
var description = this.parseDescription();
this.expectKeyword('directive');
this.expectToken(_tokenKind.TokenKind.AT);
var name = this.parseName();
var args = this.parseArgumentDefs();
var repeatable = this.expectOptionalKeyword('repeatable');
this.expectKeyword('on');
var locations = this.parseDirectiveLocations();
return {
kind: _kinds.Kind.DIRECTIVE_DEFINITION,
description: description,
name: name,
arguments: args,
repeatable: repeatable,
locations: locations,
loc: this.loc(start)
};
}
/**
* DirectiveLocations :
* - `|`? DirectiveLocation
* - DirectiveLocations | DirectiveLocation
*/
;
_proto.parseDirectiveLocations = function parseDirectiveLocations() {
// Optional leading pipe
this.expectOptionalToken(_tokenKind.TokenKind.PIPE);
var locations = [];
do {
locations.push(this.parseDirectiveLocation());
} while (this.expectOptionalToken(_tokenKind.TokenKind.PIPE));
return locations;
}
/*
* DirectiveLocation :
* - ExecutableDirectiveLocation
* - TypeSystemDirectiveLocation
*
* ExecutableDirectiveLocation : one of
* `QUERY`
* `MUTATION`
* `SUBSCRIPTION`
* `FIELD`
* `FRAGMENT_DEFINITION`
* `FRAGMENT_SPREAD`
* `INLINE_FRAGMENT`
*
* TypeSystemDirectiveLocation : one of
* `SCHEMA`
* `SCALAR`
* `OBJECT`
* `FIELD_DEFINITION`
* `ARGUMENT_DEFINITION`
* `INTERFACE`
* `UNION`
* `ENUM`
* `ENUM_VALUE`
* `INPUT_OBJECT`
* `INPUT_FIELD_DEFINITION`
*/
;
_proto.parseDirectiveLocation = function parseDirectiveLocation() {
var start = this._lexer.token;
var name = this.parseName();
if (_directiveLocation.DirectiveLocation[name.value] !== undefined) {
return name;
}
throw this.unexpected(start);
} // Core parsing utility functions
/**
* Returns a location object, used to identify the place in
* the source that created a given parsed object.
*/
;
_proto.loc = function loc(startToken) {
var _this$_options4;
if (((_this$_options4 = this._options) === null || _this$_options4 === void 0 ? void 0 : _this$_options4.noLocation) !== true) {
return new _ast.Location(startToken, this._lexer.lastToken, this._lexer.source);
}
}
/**
* Determines if the next token is of a given kind
*/
;
_proto.peek = function peek(kind) {
return this._lexer.token.kind === kind;
}
/**
* If the next token is of the given kind, return that token after advancing
* the lexer. Otherwise, do not change the parser state and throw an error.
*/
;
_proto.expectToken = function expectToken(kind) {
var token = this._lexer.token;
if (token.kind === kind) {
this._lexer.advance();
return token;
}
throw (0, _syntaxError.syntaxError)(this._lexer.source, token.start, "Expected ".concat(getTokenKindDesc(kind), ", found ").concat(getTokenDesc(token), "."));
}
/**
* If the next token is of the given kind, return that token after advancing
* the lexer. Otherwise, do not change the parser state and return undefined.
*/
;
_proto.expectOptionalToken = function expectOptionalToken(kind) {
var token = this._lexer.token;
if (token.kind === kind) {
this._lexer.advance();
return token;
}
return undefined;
}
/**
* If the next token is a given keyword, advance the lexer.
* Otherwise, do not change the parser state and throw an error.
*/
;
_proto.expectKeyword = function expectKeyword(value) {
var token = this._lexer.token;
if (token.kind === _tokenKind.TokenKind.NAME && token.value === value) {
this._lexer.advance();
} else {
throw (0, _syntaxError.syntaxError)(this._lexer.source, token.start, "Expected \"".concat(value, "\", found ").concat(getTokenDesc(token), "."));
}
}
/**
* If the next token is a given keyword, return "true" after advancing
* the lexer. Otherwise, do not change the parser state and return "false".
*/
;
_proto.expectOptionalKeyword = function expectOptionalKeyword(value) {
var token = this._lexer.token;
if (token.kind === _tokenKind.TokenKind.NAME && token.value === value) {
this._lexer.advance();
return true;
}
return false;
}
/**
* Helper function for creating an error when an unexpected lexed token
* is encountered.
*/
;
_proto.unexpected = function unexpected(atToken) {
var token = atToken !== null && atToken !== void 0 ? atToken : this._lexer.token;
return (0, _syntaxError.syntaxError)(this._lexer.source, token.start, "Unexpected ".concat(getTokenDesc(token), "."));
}
/**
* Returns a possibly empty list of parse nodes, determined by
* the parseFn. This list begins with a lex token of openKind
* and ends with a lex token of closeKind. Advances the parser
* to the next lex token after the closing token.
*/
;
_proto.any = function any(openKind, parseFn, closeKind) {
this.expectToken(openKind);
var nodes = [];
while (!this.expectOptionalToken(closeKind)) {
nodes.push(parseFn.call(this));
}
return nodes;
}
/**
* Returns a list of parse nodes, determined by the parseFn.
* It can be empty only if open token is missing otherwise it will always
* return non-empty list that begins with a lex token of openKind and ends
* with a lex token of closeKind. Advances the parser to the next lex token
* after the closing token.
*/
;
_proto.optionalMany = function optionalMany(openKind, parseFn, closeKind) {
if (this.expectOptionalToken(openKind)) {
var nodes = [];
do {
nodes.push(parseFn.call(this));
} while (!this.expectOptionalToken(closeKind));
return nodes;
}
return [];
}
/**
* Returns a non-empty list of parse nodes, determined by
* the parseFn. This list begins with a lex token of openKind
* and ends with a lex token of closeKind. Advances the parser
* to the next lex token after the closing token.
*/
;
_proto.many = function many(openKind, parseFn, closeKind) {
this.expectToken(openKind);
var nodes = [];
do {
nodes.push(parseFn.call(this));
} while (!this.expectOptionalToken(closeKind));
return nodes;
};
return Parser;
}();
/**
* A helper function to describe a token as a string for debugging
*/
function getTokenDesc(token) {
var value = token.value;
return getTokenKindDesc(token.kind) + (value != null ? " \"".concat(value, "\"") : '');
}
/**
* A helper function to describe a token kind as a string for debugging
*/
function getTokenKindDesc(kind) {
return (0, _lexer.isPunctuatorTokenKind)(kind) ? "\"".concat(kind, "\"") : kind;
}