UNPKG

@dillonkearns/elm-graphql

Version:

<img src="https://cdn.jsdelivr.net/gh/martimatix/logo-graphqelm/logo.svg" alt="dillonearns/elm-graphql logo" width="40%" align="right">

78 lines (70 loc) 2.4 kB
/** * 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. * * @flow */ import { getLocation } from '../language/location'; import type { Source } from '../language/source'; import { GraphQLError } from './GraphQLError'; import type {SourceLocation} from '../language/location'; /** * Produces a GraphQLError representing a syntax error, containing useful * descriptive information about the syntax error's position in the source. */ export function syntaxError( source: Source, position: number, description: string ): GraphQLError { const location = getLocation(source, position); const line = location.line + source.locationOffset.line - 1; const columnOffset = getColumnOffset(source, location); const column = location.column + columnOffset; const error = new GraphQLError( `Syntax Error ${source.name} (${line}:${column}) ${description}` + '\n\n' + highlightSourceAtLocation(source, location), undefined, source, [ position ] ); return error; } /** * Render a helpful description of the location of the error in the GraphQL * Source document. */ function highlightSourceAtLocation(source, location) { const line = location.line; const lineOffset = source.locationOffset.line - 1; const columnOffset = getColumnOffset(source, location); const contextLine = line + lineOffset; const prevLineNum = (contextLine - 1).toString(); const lineNum = contextLine.toString(); const nextLineNum = (contextLine + 1).toString(); const padLen = nextLineNum.length; const lines = source.body.split(/\r\n|[\n\r]/g); lines[0] = whitespace(source.locationOffset.column - 1) + lines[0]; return ( (line >= 2 ? lpad(padLen, prevLineNum) + ': ' + lines[line - 2] + '\n' : '') + lpad(padLen, lineNum) + ': ' + lines[line - 1] + '\n' + whitespace(2 + padLen + location.column - 1 + columnOffset) + '^\n' + (line < lines.length ? lpad(padLen, nextLineNum) + ': ' + lines[line] + '\n' : '') ); } function getColumnOffset( source: Source, location: SourceLocation ): number { return location.line === 1 ? source.locationOffset.column - 1 : 0; } function whitespace(len) { return Array(len + 1).join(' '); } function lpad(len, str) { return whitespace(len - str.length) + str; }