Skip to content

Commit 789771a

Browse files
authoredOct 27, 2023
Fix code frame for Node.js v21 (#40)
1 parent be6fbf9 commit 789771a

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed
 

‎.github/workflows/main.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
node-version:
13+
- 21
1314
- 20
1415
- 18
1516
- 16
1617
steps:
17-
- uses: actions/checkout@v3
18-
- uses: actions/setup-node@v3
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-node@v4
1920
with:
2021
node-version: ${{ matrix.node-version }}
2122
- run: npm install

‎index.js

+26-14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,27 @@ export const JSONError = errorEx('JSONError', {
88
codeFrame: errorEx.append('\n\n%s\n'),
99
});
1010

11+
const generateCodeFrame = (string, location, highlightCode = true) =>
12+
codeFrameColumns(string, {start: location}, {highlightCode});
13+
14+
const getErrorLocation = (string, error) => {
15+
const match = error.message.match(/in JSON at position (?<index>\d+)(?: \(line (?<line>\d+) column (?<column>\d+)\))? while parsing/);
16+
17+
if (!match) {
18+
return;
19+
}
20+
21+
let {index, line, column} = match.groups;
22+
23+
if (line && column) {
24+
return {line: Number(line), column: Number(column)};
25+
}
26+
27+
({line, column} = new LinesAndColumns(string).locationForIndex(Number(index)));
28+
29+
return {line: line + 1, column: column + 1};
30+
};
31+
1132
export default function parseJson(string, reviver, filename) {
1233
if (typeof reviver === 'string') {
1334
filename = reviver;
@@ -23,26 +44,17 @@ export default function parseJson(string, reviver, filename) {
2344
}
2445
} catch (error) {
2546
error.message = error.message.replace(/\n/g, '');
26-
const indexMatch = error.message.match(/in JSON at position (\d+) while parsing/);
2747

2848
const jsonError = new JSONError(error);
49+
2950
if (filename) {
3051
jsonError.fileName = filename;
3152
}
3253

33-
if (indexMatch && indexMatch.length > 0) {
34-
const lines = new LinesAndColumns(string);
35-
const index = Number(indexMatch[1]);
36-
const location = lines.locationForIndex(index);
37-
38-
const generateCodeFrame = ({highlightCode}) => codeFrameColumns(
39-
string,
40-
{start: {line: location.line + 1, column: location.column + 1}},
41-
{highlightCode},
42-
);
43-
44-
jsonError.codeFrame = generateCodeFrame({highlightCode: true});
45-
jsonError.rawCodeFrame = generateCodeFrame({highlightCode: false});
54+
const location = getErrorLocation(string, error);
55+
if (location) {
56+
jsonError.codeFrame = generateCodeFrame(string, location);
57+
jsonError.rawCodeFrame = generateCodeFrame(string, location, /* highlightCode */ false);
4658
}
4759

4860
throw jsonError;

‎test.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@ import process from 'node:process';
22
import test from 'ava';
33
import parseJson, {JSONError} from './index.js';
44

5-
const errorMessageRegex = /^v(?:16|18)\./.test(process.version)
6-
? /Unexpected token "}"/
7-
: /Expected double-quoted property name in JSON at position 16 while parsing/;
5+
const errorMessageRegex = (() => {
6+
const version = Number(process.versions.node.split('.')[0]);
7+
8+
if (version < 20) {
9+
return /Unexpected token "}"/;
10+
}
11+
12+
if (version < 21) {
13+
return /Expected double-quoted property name in JSON at position 16 while parsing/;
14+
}
15+
16+
return /Expected double-quoted property name in JSON at position 16 \(line 3 column 1\) while parsing/;
17+
})();
818
const errorMessageRegexWithFileName = new RegExp(errorMessageRegex.source + '.*in foo\\.json');
919

1020
test('main', t => {

0 commit comments

Comments
 (0)
Please sign in to comment.