node_modules.graphql.language.parser.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.parse = parse;
exports.parseValue = parseValue;
exports.parseType = parseType;
exports.parseConstValue = parseConstValue;
exports.parseTypeReference = parseTypeReference;
exports.parseNamedType = parseNamedType;
var _source = require('./source');
var _error = require('../error');
var _lexer = require('./lexer');
var _kinds = require('./kinds');
var _directiveLocation = require('./directiveLocation');
/**
* Given a GraphQL source, parses it into a Document.
* Throws GraphQLError if a syntax error is encountered.
*/
/**
* Configuration options to control parser behavior
*/
function parse(source, options) {
var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
if (!(sourceObj instanceof _source.Source)) {
throw new TypeError('Must provide Source. Received: ' + String(sourceObj));
}
var lexer = (0, _lexer.createLexer)(sourceObj, options || {});
return parseDocument(lexer);
}
/**
* 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().
*/
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* strict
*/
function parseValue(source, options) {
var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
var lexer = (0, _lexer.createLexer)(sourceObj, options || {});
expect(lexer, _lexer.TokenKind.SOF);
var value = parseValueLiteral(lexer, false);
expect(lexer, _lexer.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 sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
var lexer = (0, _lexer.createLexer)(sourceObj, options || {});
expect(lexer, _lexer.TokenKind.SOF);
var type = parseTypeReference(lexer);
expect(lexer, _lexer.TokenKind.EOF);
return type;
}
/**
* Converts a name lex token into a name parse node.
*/
function parseName(lexer) {
var token = expect(lexer, _lexer.TokenKind.NAME);
return {
kind: _kinds.Kind.NAME,
value: token.value,
loc: loc(lexer, token)
};
}
// Implements the parsing rules in the Document section.
/**
* Document : Definition+
*/
function parseDocument(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.SOF);
var definitions = [];
do {
definitions.push(parseDefinition(lexer));
} while (!skip(lexer, _lexer.TokenKind.EOF));
return {
kind: _kinds.Kind.DOCUMENT,
definitions: definitions,
loc: loc(lexer, start)
};
}
/**
* Definition :
* - ExecutableDefinition
* - TypeSystemDefinition
*/
function parseDefinition(lexer) {
if (peek(lexer, _lexer.TokenKind.NAME)) {
switch (lexer.token.value) {
case 'query':
case 'mutation':
case 'subscription':
case 'fragment':
return parseExecutableDefinition(lexer);
case 'schema':
case 'scalar':
case 'type':
case 'interface':
case 'union':
case 'enum':
case 'input':
case 'extend':
case 'directive':
// Note: The schema definition language is an experimental addition.
return parseTypeSystemDefinition(lexer);
}
} else if (peek(lexer, _lexer.TokenKind.BRACE_L)) {
return parseExecutableDefinition(lexer);
} else if (peekDescription(lexer)) {
// Note: The schema definition language is an experimental addition.
return parseTypeSystemDefinition(lexer);
}
throw unexpected(lexer);
}
/**
* ExecutableDefinition :
* - OperationDefinition
* - FragmentDefinition
*/
function parseExecutableDefinition(lexer) {
if (peek(lexer, _lexer.TokenKind.NAME)) {
switch (lexer.token.value) {
case 'query':
case 'mutation':
case 'subscription':
return parseOperationDefinition(lexer);
case 'fragment':
return parseFragmentDefinition(lexer);
}
} else if (peek(lexer, _lexer.TokenKind.BRACE_L)) {
return parseOperationDefinition(lexer);
}
throw unexpected(lexer);
}
// Implements the parsing rules in the Operations section.
/**
* OperationDefinition :
* - SelectionSet
* - OperationType Name? VariableDefinitions? Directives? SelectionSet
*/
function parseOperationDefinition(lexer) {
var start = lexer.token;
if (peek(lexer, _lexer.TokenKind.BRACE_L)) {
return {
kind: _kinds.Kind.OPERATION_DEFINITION,
operation: 'query',
name: undefined,
variableDefinitions: [],
directives: [],
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
var operation = parseOperationType(lexer);
var name = void 0;
if (peek(lexer, _lexer.TokenKind.NAME)) {
name = parseName(lexer);
}
return {
kind: _kinds.Kind.OPERATION_DEFINITION,
operation: operation,
name: name,
variableDefinitions: parseVariableDefinitions(lexer),
directives: parseDirectives(lexer, false),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
/**
* OperationType : one of query mutation subscription
*/
function parseOperationType(lexer) {
var operationToken = expect(lexer, _lexer.TokenKind.NAME);
switch (operationToken.value) {
case 'query':
return 'query';
case 'mutation':
return 'mutation';
case 'subscription':
return 'subscription';
}
throw unexpected(lexer, operationToken);
}
/**
* VariableDefinitions : ( VariableDefinition+ )
*/
function parseVariableDefinitions(lexer) {
return peek(lexer, _lexer.TokenKind.PAREN_L) ? many(lexer, _lexer.TokenKind.PAREN_L, parseVariableDefinition, _lexer.TokenKind.PAREN_R) : [];
}
/**
* VariableDefinition : Variable : Type DefaultValue?
*/
function parseVariableDefinition(lexer) {
var start = lexer.token;
return {
kind: _kinds.Kind.VARIABLE_DEFINITION,
variable: parseVariable(lexer),
type: (expect(lexer, _lexer.TokenKind.COLON), parseTypeReference(lexer)),
defaultValue: skip(lexer, _lexer.TokenKind.EQUALS) ? parseValueLiteral(lexer, true) : undefined,
loc: loc(lexer, start)
};
}
/**
* Variable : $ Name
*/
function parseVariable(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.DOLLAR);
return {
kind: _kinds.Kind.VARIABLE,
name: parseName(lexer),
loc: loc(lexer, start)
};
}
/**
* SelectionSet : { Selection+ }
*/
function parseSelectionSet(lexer) {
var start = lexer.token;
return {
kind: _kinds.Kind.SELECTION_SET,
selections: many(lexer, _lexer.TokenKind.BRACE_L, parseSelection, _lexer.TokenKind.BRACE_R),
loc: loc(lexer, start)
};
}
/**
* Selection :
* - Field
* - FragmentSpread
* - InlineFragment
*/
function parseSelection(lexer) {
return peek(lexer, _lexer.TokenKind.SPREAD) ? parseFragment(lexer) : parseField(lexer);
}
/**
* Field : Alias? Name Arguments? Directives? SelectionSet?
*
* Alias : Name :
*/
function parseField(lexer) {
var start = lexer.token;
var nameOrAlias = parseName(lexer);
var alias = void 0;
var name = void 0;
if (skip(lexer, _lexer.TokenKind.COLON)) {
alias = nameOrAlias;
name = parseName(lexer);
} else {
name = nameOrAlias;
}
return {
kind: _kinds.Kind.FIELD,
alias: alias,
name: name,
arguments: parseArguments(lexer, false),
directives: parseDirectives(lexer, false),
selectionSet: peek(lexer, _lexer.TokenKind.BRACE_L) ? parseSelectionSet(lexer) : undefined,
loc: loc(lexer, start)
};
}
/**
* Arguments[Const] : ( Argument[?Const]+ )
*/
function parseArguments(lexer, isConst) {
var item = isConst ? parseConstArgument : parseArgument;
return peek(lexer, _lexer.TokenKind.PAREN_L) ? many(lexer, _lexer.TokenKind.PAREN_L, item, _lexer.TokenKind.PAREN_R) : [];
}
/**
* Argument[Const] : Name : Value[?Const]
*/
function parseArgument(lexer) {
var start = lexer.token;
return {
kind: _kinds.Kind.ARGUMENT,
name: parseName(lexer),
value: (expect(lexer, _lexer.TokenKind.COLON), parseValueLiteral(lexer, false)),
loc: loc(lexer, start)
};
}
function parseConstArgument(lexer) {
var start = lexer.token;
return {
kind: _kinds.Kind.ARGUMENT,
name: parseName(lexer),
value: (expect(lexer, _lexer.TokenKind.COLON), parseConstValue(lexer)),
loc: loc(lexer, 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
*/
function parseFragment(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.SPREAD);
if (peek(lexer, _lexer.TokenKind.NAME) && lexer.token.value !== 'on') {
return {
kind: _kinds.Kind.FRAGMENT_SPREAD,
name: parseFragmentName(lexer),
directives: parseDirectives(lexer, false),
loc: loc(lexer, start)
};
}
var typeCondition = void 0;
if (lexer.token.value === 'on') {
lexer.advance();
typeCondition = parseNamedType(lexer);
}
return {
kind: _kinds.Kind.INLINE_FRAGMENT,
typeCondition: typeCondition,
directives: parseDirectives(lexer, false),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
/**
* FragmentDefinition :
* - fragment FragmentName on TypeCondition Directives? SelectionSet
*
* TypeCondition : NamedType
*/
function parseFragmentDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'fragment');
// Experimental support for defining variables within fragments changes
// the grammar of FragmentDefinition:
// - fragment FragmentName VariableDefinitions? on TypeCondition Directives? SelectionSet
if (lexer.options.experimentalFragmentVariables) {
return {
kind: _kinds.Kind.FRAGMENT_DEFINITION,
name: parseFragmentName(lexer),
variableDefinitions: parseVariableDefinitions(lexer),
typeCondition: (expectKeyword(lexer, 'on'), parseNamedType(lexer)),
directives: parseDirectives(lexer, false),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
return {
kind: _kinds.Kind.FRAGMENT_DEFINITION,
name: parseFragmentName(lexer),
typeCondition: (expectKeyword(lexer, 'on'), parseNamedType(lexer)),
directives: parseDirectives(lexer, false),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
/**
* FragmentName : Name but not `on`
*/
function parseFragmentName(lexer) {
if (lexer.token.value === 'on') {
throw unexpected(lexer);
}
return parseName(lexer);
}
// 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`
*/
function parseValueLiteral(lexer, isConst) {
var token = lexer.token;
switch (token.kind) {
case _lexer.TokenKind.BRACKET_L:
return parseList(lexer, isConst);
case _lexer.TokenKind.BRACE_L:
return parseObject(lexer, isConst);
case _lexer.TokenKind.INT:
lexer.advance();
return {
kind: _kinds.Kind.INT,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.FLOAT:
lexer.advance();
return {
kind: _kinds.Kind.FLOAT,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.STRING:
case _lexer.TokenKind.BLOCK_STRING:
return parseStringLiteral(lexer);
case _lexer.TokenKind.NAME:
if (token.value === 'true' || token.value === 'false') {
lexer.advance();
return {
kind: _kinds.Kind.BOOLEAN,
value: token.value === 'true',
loc: loc(lexer, token)
};
} else if (token.value === 'null') {
lexer.advance();
return {
kind: _kinds.Kind.NULL,
loc: loc(lexer, token)
};
}
lexer.advance();
return {
kind: _kinds.Kind.ENUM,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.DOLLAR:
if (!isConst) {
return parseVariable(lexer);
}
break;
}
throw unexpected(lexer);
}
function parseStringLiteral(lexer) {
var token = lexer.token;
lexer.advance();
return {
kind: _kinds.Kind.STRING,
value: token.value,
block: token.kind === _lexer.TokenKind.BLOCK_STRING,
loc: loc(lexer, token)
};
}
function parseConstValue(lexer) {
return parseValueLiteral(lexer, true);
}
function parseValueValue(lexer) {
return parseValueLiteral(lexer, false);
}
/**
* ListValue[Const] :
* - [ ]
* - [ Value[?Const]+ ]
*/
function parseList(lexer, isConst) {
var start = lexer.token;
var item = isConst ? parseConstValue : parseValueValue;
return {
kind: _kinds.Kind.LIST,
values: any(lexer, _lexer.TokenKind.BRACKET_L, item, _lexer.TokenKind.BRACKET_R),
loc: loc(lexer, start)
};
}
/**
* ObjectValue[Const] :
* - { }
* - { ObjectField[?Const]+ }
*/
function parseObject(lexer, isConst) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.BRACE_L);
var fields = [];
while (!skip(lexer, _lexer.TokenKind.BRACE_R)) {
fields.push(parseObjectField(lexer, isConst));
}
return {
kind: _kinds.Kind.OBJECT,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* ObjectField[Const] : Name : Value[?Const]
*/
function parseObjectField(lexer, isConst) {
var start = lexer.token;
return {
kind: _kinds.Kind.OBJECT_FIELD,
name: parseName(lexer),
value: (expect(lexer, _lexer.TokenKind.COLON), parseValueLiteral(lexer, isConst)),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Directives section.
/**
* Directives[Const] : Directive[?Const]+
*/
function parseDirectives(lexer, isConst) {
var directives = [];
while (peek(lexer, _lexer.TokenKind.AT)) {
directives.push(parseDirective(lexer, isConst));
}
return directives;
}
/**
* Directive[Const] : @ Name Arguments[?Const]?
*/
function parseDirective(lexer, isConst) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.AT);
return {
kind: _kinds.Kind.DIRECTIVE,
name: parseName(lexer),
arguments: parseArguments(lexer, isConst),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Types section.
/**
* Type :
* - NamedType
* - ListType
* - NonNullType
*/
function parseTypeReference(lexer) {
var start = lexer.token;
var type = void 0;
if (skip(lexer, _lexer.TokenKind.BRACKET_L)) {
type = parseTypeReference(lexer);
expect(lexer, _lexer.TokenKind.BRACKET_R);
type = {
kind: _kinds.Kind.LIST_TYPE,
type: type,
loc: loc(lexer, start)
};
} else {
type = parseNamedType(lexer);
}
if (skip(lexer, _lexer.TokenKind.BANG)) {
return {
kind: _kinds.Kind.NON_NULL_TYPE,
type: type,
loc: loc(lexer, start)
};
}
return type;
}
/**
* NamedType : Name
*/
function parseNamedType(lexer) {
var start = lexer.token;
return {
kind: _kinds.Kind.NAMED_TYPE,
name: parseName(lexer),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Type Definition section.
/**
* TypeSystemDefinition :
* - SchemaDefinition
* - TypeDefinition
* - TypeExtension
* - DirectiveDefinition
*
* TypeDefinition :
* - ScalarTypeDefinition
* - ObjectTypeDefinition
* - InterfaceTypeDefinition
* - UnionTypeDefinition
* - EnumTypeDefinition
* - InputObjectTypeDefinition
*/
function parseTypeSystemDefinition(lexer) {
// Many definitions begin with a description and require a lookahead.
var keywordToken = peekDescription(lexer) ? lexer.lookahead() : lexer.token;
if (keywordToken.kind === _lexer.TokenKind.NAME) {
switch (keywordToken.value) {
case 'schema':
return parseSchemaDefinition(lexer);
case 'scalar':
return parseScalarTypeDefinition(lexer);
case 'type':
return parseObjectTypeDefinition(lexer);
case 'interface':
return parseInterfaceTypeDefinition(lexer);
case 'union':
return parseUnionTypeDefinition(lexer);
case 'enum':
return parseEnumTypeDefinition(lexer);
case 'input':
return parseInputObjectTypeDefinition(lexer);
case 'extend':
return parseTypeExtension(lexer);
case 'directive':
return parseDirectiveDefinition(lexer);
}
}
throw unexpected(lexer, keywordToken);
}
function peekDescription(lexer) {
return peek(lexer, _lexer.TokenKind.STRING) || peek(lexer, _lexer.TokenKind.BLOCK_STRING);
}
/**
* Description : StringValue
*/
function parseDescription(lexer) {
if (peekDescription(lexer)) {
return parseStringLiteral(lexer);
}
}
/**
* SchemaDefinition : schema Directives[Const]? { OperationTypeDefinition+ }
*/
function parseSchemaDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'schema');
var directives = parseDirectives(lexer, true);
var operationTypes = many(lexer, _lexer.TokenKind.BRACE_L, parseOperationTypeDefinition, _lexer.TokenKind.BRACE_R);
return {
kind: _kinds.Kind.SCHEMA_DEFINITION,
directives: directives,
operationTypes: operationTypes,
loc: loc(lexer, start)
};
}
/**
* OperationTypeDefinition : OperationType : NamedType
*/
function parseOperationTypeDefinition(lexer) {
var start = lexer.token;
var operation = parseOperationType(lexer);
expect(lexer, _lexer.TokenKind.COLON);
var type = parseNamedType(lexer);
return {
kind: _kinds.Kind.OPERATION_TYPE_DEFINITION,
operation: operation,
type: type,
loc: loc(lexer, start)
};
}
/**
* ScalarTypeDefinition : Description? scalar Name Directives[Const]?
*/
function parseScalarTypeDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'scalar');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
return {
kind: _kinds.Kind.SCALAR_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* ObjectTypeDefinition :
* Description?
* type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition?
*/
function parseObjectTypeDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'type');
var name = parseName(lexer);
var interfaces = parseImplementsInterfaces(lexer);
var directives = parseDirectives(lexer, true);
var fields = parseFieldsDefinition(lexer);
return {
kind: _kinds.Kind.OBJECT_TYPE_DEFINITION,
description: description,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* ImplementsInterfaces :
* - implements `&`? NamedType
* - ImplementsInterfaces & NamedType
*/
function parseImplementsInterfaces(lexer) {
var types = [];
if (lexer.token.value === 'implements') {
lexer.advance();
// Optional leading ampersand
skip(lexer, _lexer.TokenKind.AMP);
do {
types.push(parseNamedType(lexer));
} while (skip(lexer, _lexer.TokenKind.AMP) ||
// Legacy support for the SDL?
lexer.options.allowLegacySDLImplementsInterfaces && peek(lexer, _lexer.TokenKind.NAME));
}
return types;
}
/**
* FieldsDefinition : { FieldDefinition+ }
*/
function parseFieldsDefinition(lexer) {
// Legacy support for the SDL?
if (lexer.options.allowLegacySDLEmptyFields && peek(lexer, _lexer.TokenKind.BRACE_L) && lexer.lookahead().kind === _lexer.TokenKind.BRACE_R) {
lexer.advance();
lexer.advance();
return [];
}
return peek(lexer, _lexer.TokenKind.BRACE_L) ? many(lexer, _lexer.TokenKind.BRACE_L, parseFieldDefinition, _lexer.TokenKind.BRACE_R) : [];
}
/**
* FieldDefinition :
* - Description? Name ArgumentsDefinition? : Type Directives[Const]?
*/
function parseFieldDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
var name = parseName(lexer);
var args = parseArgumentDefs(lexer);
expect(lexer, _lexer.TokenKind.COLON);
var type = parseTypeReference(lexer);
var directives = parseDirectives(lexer, true);
return {
kind: _kinds.Kind.FIELD_DEFINITION,
description: description,
name: name,
arguments: args,
type: type,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* ArgumentsDefinition : ( InputValueDefinition+ )
*/
function parseArgumentDefs(lexer) {
if (!peek(lexer, _lexer.TokenKind.PAREN_L)) {
return [];
}
return many(lexer, _lexer.TokenKind.PAREN_L, parseInputValueDef, _lexer.TokenKind.PAREN_R);
}
/**
* InputValueDefinition :
* - Description? Name : Type DefaultValue? Directives[Const]?
*/
function parseInputValueDef(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
var name = parseName(lexer);
expect(lexer, _lexer.TokenKind.COLON);
var type = parseTypeReference(lexer);
var defaultValue = void 0;
if (skip(lexer, _lexer.TokenKind.EQUALS)) {
defaultValue = parseConstValue(lexer);
}
var directives = parseDirectives(lexer, true);
return {
kind: _kinds.Kind.INPUT_VALUE_DEFINITION,
description: description,
name: name,
type: type,
defaultValue: defaultValue,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* InterfaceTypeDefinition :
* - Description? interface Name Directives[Const]? FieldsDefinition?
*/
function parseInterfaceTypeDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'interface');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var fields = parseFieldsDefinition(lexer);
return {
kind: _kinds.Kind.INTERFACE_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* UnionTypeDefinition :
* - Description? union Name Directives[Const]? UnionMemberTypes?
*/
function parseUnionTypeDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'union');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var types = parseUnionMemberTypes(lexer);
return {
kind: _kinds.Kind.UNION_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
types: types,
loc: loc(lexer, start)
};
}
/**
* UnionMemberTypes :
* - = `|`? NamedType
* - UnionMemberTypes | NamedType
*/
function parseUnionMemberTypes(lexer) {
var types = [];
if (skip(lexer, _lexer.TokenKind.EQUALS)) {
// Optional leading pipe
skip(lexer, _lexer.TokenKind.PIPE);
do {
types.push(parseNamedType(lexer));
} while (skip(lexer, _lexer.TokenKind.PIPE));
}
return types;
}
/**
* EnumTypeDefinition :
* - Description? enum Name Directives[Const]? EnumValuesDefinition?
*/
function parseEnumTypeDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'enum');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var values = parseEnumValuesDefinition(lexer);
return {
kind: _kinds.Kind.ENUM_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
values: values,
loc: loc(lexer, start)
};
}
/**
* EnumValuesDefinition : { EnumValueDefinition+ }
*/
function parseEnumValuesDefinition(lexer) {
return peek(lexer, _lexer.TokenKind.BRACE_L) ? many(lexer, _lexer.TokenKind.BRACE_L, parseEnumValueDefinition, _lexer.TokenKind.BRACE_R) : [];
}
/**
* EnumValueDefinition : Description? EnumValue Directives[Const]?
*
* EnumValue : Name
*/
function parseEnumValueDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
return {
kind: _kinds.Kind.ENUM_VALUE_DEFINITION,
description: description,
name: name,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* InputObjectTypeDefinition :
* - Description? input Name Directives[Const]? InputFieldsDefinition?
*/
function parseInputObjectTypeDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'input');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var fields = parseInputFieldsDefinition(lexer);
return {
kind: _kinds.Kind.INPUT_OBJECT_TYPE_DEFINITION,
description: description,
name: name,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* InputFieldsDefinition : { InputValueDefinition+ }
*/
function parseInputFieldsDefinition(lexer) {
return peek(lexer, _lexer.TokenKind.BRACE_L) ? many(lexer, _lexer.TokenKind.BRACE_L, parseInputValueDef, _lexer.TokenKind.BRACE_R) : [];
}
/**
* TypeExtension :
* - ScalarTypeExtension
* - ObjectTypeExtension
* - InterfaceTypeExtension
* - UnionTypeExtension
* - EnumTypeExtension
* - InputObjectTypeDefinition
*/
function parseTypeExtension(lexer) {
var keywordToken = lexer.lookahead();
if (keywordToken.kind === _lexer.TokenKind.NAME) {
switch (keywordToken.value) {
case 'scalar':
return parseScalarTypeExtension(lexer);
case 'type':
return parseObjectTypeExtension(lexer);
case 'interface':
return parseInterfaceTypeExtension(lexer);
case 'union':
return parseUnionTypeExtension(lexer);
case 'enum':
return parseEnumTypeExtension(lexer);
case 'input':
return parseInputObjectTypeExtension(lexer);
}
}
throw unexpected(lexer, keywordToken);
}
/**
* ScalarTypeExtension :
* - extend scalar Name Directives[Const]
*/
function parseScalarTypeExtension(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
expectKeyword(lexer, 'scalar');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
if (directives.length === 0) {
throw unexpected(lexer);
}
return {
kind: _kinds.Kind.SCALAR_TYPE_EXTENSION,
name: name,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* ObjectTypeExtension :
* - extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
* - extend type Name ImplementsInterfaces? Directives[Const]
* - extend type Name ImplementsInterfaces
*/
function parseObjectTypeExtension(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
expectKeyword(lexer, 'type');
var name = parseName(lexer);
var interfaces = parseImplementsInterfaces(lexer);
var directives = parseDirectives(lexer, true);
var fields = parseFieldsDefinition(lexer);
if (interfaces.length === 0 && directives.length === 0 && fields.length === 0) {
throw unexpected(lexer);
}
return {
kind: _kinds.Kind.OBJECT_TYPE_EXTENSION,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* InterfaceTypeExtension :
* - extend interface Name Directives[Const]? FieldsDefinition
* - extend interface Name Directives[Const]
*/
function parseInterfaceTypeExtension(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
expectKeyword(lexer, 'interface');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var fields = parseFieldsDefinition(lexer);
if (directives.length === 0 && fields.length === 0) {
throw unexpected(lexer);
}
return {
kind: _kinds.Kind.INTERFACE_TYPE_EXTENSION,
name: name,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* UnionTypeExtension :
* - extend union Name Directives[Const]? UnionMemberTypes
* - extend union Name Directives[Const]
*/
function parseUnionTypeExtension(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
expectKeyword(lexer, 'union');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var types = parseUnionMemberTypes(lexer);
if (directives.length === 0 && types.length === 0) {
throw unexpected(lexer);
}
return {
kind: _kinds.Kind.UNION_TYPE_EXTENSION,
name: name,
directives: directives,
types: types,
loc: loc(lexer, start)
};
}
/**
* EnumTypeExtension :
* - extend enum Name Directives[Const]? EnumValuesDefinition
* - extend enum Name Directives[Const]
*/
function parseEnumTypeExtension(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
expectKeyword(lexer, 'enum');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var values = parseEnumValuesDefinition(lexer);
if (directives.length === 0 && values.length === 0) {
throw unexpected(lexer);
}
return {
kind: _kinds.Kind.ENUM_TYPE_EXTENSION,
name: name,
directives: directives,
values: values,
loc: loc(lexer, start)
};
}
/**
* InputObjectTypeExtension :
* - extend input Name Directives[Const]? InputFieldsDefinition
* - extend input Name Directives[Const]
*/
function parseInputObjectTypeExtension(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
expectKeyword(lexer, 'input');
var name = parseName(lexer);
var directives = parseDirectives(lexer, true);
var fields = parseInputFieldsDefinition(lexer);
if (directives.length === 0 && fields.length === 0) {
throw unexpected(lexer);
}
return {
kind: _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION,
name: name,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* DirectiveDefinition :
* - Description? directive @ Name ArgumentsDefinition? on DirectiveLocations
*/
function parseDirectiveDefinition(lexer) {
var start = lexer.token;
var description = parseDescription(lexer);
expectKeyword(lexer, 'directive');
expect(lexer, _lexer.TokenKind.AT);
var name = parseName(lexer);
var args = parseArgumentDefs(lexer);
expectKeyword(lexer, 'on');
var locations = parseDirectiveLocations(lexer);
return {
kind: _kinds.Kind.DIRECTIVE_DEFINITION,
description: description,
name: name,
arguments: args,
locations: locations,
loc: loc(lexer, start)
};
}
/**
* DirectiveLocations :
* - `|`? DirectiveLocation
* - DirectiveLocations | DirectiveLocation
*/
function parseDirectiveLocations(lexer) {
// Optional leading pipe
skip(lexer, _lexer.TokenKind.PIPE);
var locations = [];
do {
locations.push(parseDirectiveLocation(lexer));
} while (skip(lexer, _lexer.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`
*/
function parseDirectiveLocation(lexer) {
var start = lexer.token;
var name = parseName(lexer);
if (_directiveLocation.DirectiveLocation.hasOwnProperty(name.value)) {
return name;
}
throw unexpected(lexer, start);
}
// Core parsing utility functions
/**
* Returns a location object, used to identify the place in
* the source that created a given parsed object.
*/
function loc(lexer, startToken) {
if (!lexer.options.noLocation) {
return new Loc(startToken, lexer.lastToken, lexer.source);
}
}
function Loc(startToken, endToken, source) {
this.start = startToken.start;
this.end = endToken.end;
this.startToken = startToken;
this.endToken = endToken;
this.source = source;
}
// Print a simplified form when appearing in JSON/util.inspect.
Loc.prototype.toJSON = Loc.prototype.inspect = function toJSON() {
return { start: this.start, end: this.end };
};
/**
* Determines if the next token is of a given kind
*/
function peek(lexer, kind) {
return lexer.token.kind === kind;
}
/**
* If the next token is of the given kind, return true after advancing
* the lexer. Otherwise, do not change the parser state and return false.
*/
function skip(lexer, kind) {
var match = lexer.token.kind === kind;
if (match) {
lexer.advance();
}
return match;
}
/**
* 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.
*/
function expect(lexer, kind) {
var token = lexer.token;
if (token.kind === kind) {
lexer.advance();
return token;
}
throw (0, _error.syntaxError)(lexer.source, token.start, 'Expected ' + kind + ', found ' + (0, _lexer.getTokenDesc)(token));
}
/**
* If the next token is a keyword with the given value, return that token after
* advancing the lexer. Otherwise, do not change the parser state and return
* false.
*/
function expectKeyword(lexer, value) {
var token = lexer.token;
if (token.kind === _lexer.TokenKind.NAME && token.value === value) {
lexer.advance();
return token;
}
throw (0, _error.syntaxError)(lexer.source, token.start, 'Expected "' + value + '", found ' + (0, _lexer.getTokenDesc)(token));
}
/**
* Helper function for creating an error when an unexpected lexed token
* is encountered.
*/
function unexpected(lexer, atToken) {
var token = atToken || lexer.token;
return (0, _error.syntaxError)(lexer.source, token.start, 'Unexpected ' + (0, _lexer.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.
*/
function any(lexer, openKind, parseFn, closeKind) {
expect(lexer, openKind);
var nodes = [];
while (!skip(lexer, closeKind)) {
nodes.push(parseFn(lexer));
}
return nodes;
}
/**
* 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.
*/
function many(lexer, openKind, parseFn, closeKind) {
expect(lexer, openKind);
var nodes = [parseFn(lexer)];
while (!skip(lexer, closeKind)) {
nodes.push(parseFn(lexer));
}
return nodes;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy