| import { getLocation } from './location.mjs'; |
|
|
| /** |
| * Render a helpful description of the location in the GraphQL Source document. |
| */ |
| export function printLocation(location) { |
| return printSourceLocation( |
| location.source, |
| getLocation(location.source, location.start), |
| ); |
| } |
| /** |
| * Render a helpful description of the location in the GraphQL Source document. |
| */ |
|
|
| export function printSourceLocation(source, sourceLocation) { |
| const firstLineColumnOffset = source.locationOffset.column - 1; |
| const body = ''.padStart(firstLineColumnOffset) + source.body; |
| const lineIndex = sourceLocation.line - 1; |
| const lineOffset = source.locationOffset.line - 1; |
| const lineNum = sourceLocation.line + lineOffset; |
| const columnOffset = sourceLocation.line === 1 ? firstLineColumnOffset : 0; |
| const columnNum = sourceLocation.column + columnOffset; |
| const locationStr = `${source.name}:${lineNum}:${columnNum}\n`; |
| const lines = body.split(/\r\n|[\n\r]/g); |
| const locationLine = lines[lineIndex]; // Special case for minified documents |
|
|
| if (locationLine.length > 120) { |
| const subLineIndex = Math.floor(columnNum / 80); |
| const subLineColumnNum = columnNum % 80; |
| const subLines = []; |
|
|
| for (let i = 0; i < locationLine.length; i += 80) { |
| subLines.push(locationLine.slice(i, i + 80)); |
| } |
|
|
| return ( |
| locationStr + |
| printPrefixedLines([ |
| [`${lineNum} |`, subLines[0]], |
| ...subLines.slice(1, subLineIndex + 1).map((subLine) => ['|', subLine]), |
| ['|', '^'.padStart(subLineColumnNum)], |
| ['|', subLines[subLineIndex + 1]], |
| ]) |
| ); |
| } |
|
|
| return ( |
| locationStr + |
| printPrefixedLines([ |
| // Lines specified like this: ["prefix", "string"], |
| [`${lineNum - 1} |`, lines[lineIndex - 1]], |
| [`${lineNum} |`, locationLine], |
| ['|', '^'.padStart(columnNum)], |
| [`${lineNum + 1} |`, lines[lineIndex + 1]], |
| ]) |
| ); |
| } |
|
|
| function printPrefixedLines(lines) { |
| const existingLines = lines.filter(([_, line]) => line !== undefined); |
| const padLen = Math.max(...existingLines.map(([prefix]) => prefix.length)); |
| return existingLines |
| .map(([prefix, line]) => prefix.padStart(padLen) + (line ? ' ' + line : '')) |
| .join('\n'); |
| } |