| 'use strict'; |
| const errorEx = require('error-ex'); |
| const fallback = require('json-parse-even-better-errors'); |
| const {default: LinesAndColumns} = require('lines-and-columns'); |
| const {codeFrameColumns} = require('@babel/code-frame'); |
| |
| const JSONError = errorEx('JSONError', { |
| fileName: errorEx.append('in %s'), |
| codeFrame: errorEx.append('\n\n%s\n') |
| }); |
| |
| const parseJson = (string, reviver, filename) => { |
| if (typeof reviver === 'string') { |
| filename = reviver; |
| reviver = null; |
| } |
| |
| try { |
| try { |
| return JSON.parse(string, reviver); |
| } catch (error) { |
| fallback(string, reviver); |
| throw error; |
| } |
| } catch (error) { |
| error.message = error.message.replace(/\n/g, ''); |
| const indexMatch = error.message.match(/in JSON at position (\d+) while parsing/); |
| |
| const jsonError = new JSONError(error); |
| if (filename) { |
| jsonError.fileName = filename; |
| } |
| |
| if (indexMatch && indexMatch.length > 0) { |
| const lines = new LinesAndColumns(string); |
| const index = Number(indexMatch[1]); |
| const location = lines.locationForIndex(index); |
| |
| const codeFrame = codeFrameColumns( |
| string, |
| {start: {line: location.line + 1, column: location.column + 1}}, |
| {highlightCode: true} |
| ); |
| |
| jsonError.codeFrame = codeFrame; |
| } |
| |
| throw jsonError; |
| } |
| }; |
| |
| parseJson.JSONError = JSONError; |
| |
| module.exports = parseJson; |