| '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; |