Skip to content

Commit c648020

Browse files
committed
deps: json-parse-even-better-errors@3.0.1
1 parent 53aa8f2 commit c648020

File tree

4 files changed

+100
-93
lines changed

4 files changed

+100
-93
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,78 @@
11
'use strict'
22

3-
const hexify = char => {
3+
const INDENT = Symbol.for('indent')
4+
const NEWLINE = Symbol.for('newline')
5+
6+
const DEFAULT_NEWLINE = '\n'
7+
const DEFAULT_INDENT = ' '
8+
const BOM = /^\uFEFF/
9+
10+
// only respect indentation if we got a line break, otherwise squash it
11+
// things other than objects and arrays aren't indented, so ignore those
12+
// Important: in both of these regexps, the $1 capture group is the newline
13+
// or undefined, and the $2 capture group is the indent, or undefined.
14+
const FORMAT = /^\s*[{[]((?:\r?\n)+)([\s\t]*)/
15+
const EMPTY = /^(?:\{\}|\[\])((?:\r?\n)+)?$/
16+
17+
// Node 20 puts single quotes around the token and a comma after it
18+
const UNEXPECTED_TOKEN = /^Unexpected token '?(.)'?(,)? /i
19+
20+
const hexify = (char) => {
421
const h = char.charCodeAt(0).toString(16).toUpperCase()
5-
return '0x' + (h.length % 2 ? '0' : '') + h
22+
return `0x${h.length % 2 ? '0' : ''}${h}`
623
}
724

8-
const parseError = (e, txt, context) => {
25+
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
26+
// because the buffer-to-string conversion in `fs.readFileSync()`
27+
// translates it to FEFF, the UTF-16 BOM.
28+
const stripBOM = (txt) => String(txt).replace(BOM, '')
29+
30+
const makeParsedError = (msg, parsing, position = 0) => ({
31+
message: `${msg} while parsing ${parsing}`,
32+
position,
33+
})
34+
35+
const parseError = (e, txt, context = 20) => {
36+
let msg = e.message
37+
938
if (!txt) {
10-
return {
11-
message: e.message + ' while parsing empty string',
12-
position: 0,
13-
}
39+
return makeParsedError(msg, 'empty string')
1440
}
15-
const badToken = e.message.match(/^Unexpected token (.) .*position\s+(\d+)/i)
16-
const errIdx = badToken ? +badToken[2]
17-
: e.message.match(/^Unexpected end of JSON.*/i) ? txt.length - 1
18-
: null
1941

20-
const msg = badToken ? e.message.replace(/^Unexpected token ./, `Unexpected token ${
21-
JSON.stringify(badToken[1])
22-
} (${hexify(badToken[1])})`)
23-
: e.message
42+
const badTokenMatch = msg.match(UNEXPECTED_TOKEN)
43+
const badIndexMatch = msg.match(/ position\s+(\d+)/i)
2444

25-
if (errIdx !== null && errIdx !== undefined) {
26-
const start = errIdx <= context ? 0
27-
: errIdx - context
45+
if (badTokenMatch) {
46+
msg = msg.replace(
47+
UNEXPECTED_TOKEN,
48+
`Unexpected token ${JSON.stringify(badTokenMatch[1])} (${hexify(badTokenMatch[1])})$2 `
49+
)
50+
}
2851

29-
const end = errIdx + context >= txt.length ? txt.length
30-
: errIdx + context
52+
let errIdx
53+
if (badIndexMatch) {
54+
errIdx = +badIndexMatch[1]
55+
} else if (msg.match(/^Unexpected end of JSON.*/i)) {
56+
errIdx = txt.length - 1
57+
}
3158

32-
const slice = (start === 0 ? '' : '...') +
33-
txt.slice(start, end) +
34-
(end === txt.length ? '' : '...')
59+
if (errIdx == null) {
60+
return makeParsedError(msg, `'${txt.slice(0, context * 2)}'`)
61+
}
3562

36-
const near = txt === slice ? '' : 'near '
63+
const start = errIdx <= context ? 0 : errIdx - context
64+
const end = errIdx + context >= txt.length ? txt.length : errIdx + context
65+
const slice = `${start ? '...' : ''}${txt.slice(start, end)}${end === txt.length ? '' : '...'}`
3766

38-
return {
39-
message: msg + ` while parsing ${near}${JSON.stringify(slice)}`,
40-
position: errIdx,
41-
}
42-
} else {
43-
return {
44-
message: msg + ` while parsing '${txt.slice(0, context * 2)}'`,
45-
position: 0,
46-
}
47-
}
67+
return makeParsedError(
68+
msg,
69+
`${txt === slice ? '' : 'near '}${JSON.stringify(slice)}`,
70+
errIdx
71+
)
4872
}
4973

5074
class JSONParseError extends SyntaxError {
5175
constructor (er, txt, context, caller) {
52-
context = context || 20
5376
const metadata = parseError(er, txt, context)
5477
super(metadata.message)
5578
Object.assign(this, metadata)
@@ -63,67 +86,50 @@ class JSONParseError extends SyntaxError {
6386
}
6487

6588
set name (n) {}
89+
6690
get [Symbol.toStringTag] () {
6791
return this.constructor.name
6892
}
6993
}
7094

71-
const kIndent = Symbol.for('indent')
72-
const kNewline = Symbol.for('newline')
73-
// only respect indentation if we got a line break, otherwise squash it
74-
// things other than objects and arrays aren't indented, so ignore those
75-
// Important: in both of these regexps, the $1 capture group is the newline
76-
// or undefined, and the $2 capture group is the indent, or undefined.
77-
const formatRE = /^\s*[{[]((?:\r?\n)+)([\s\t]*)/
78-
const emptyRE = /^(?:\{\}|\[\])((?:\r?\n)+)?$/
79-
80-
const parseJson = (txt, reviver, context) => {
81-
const parseText = stripBOM(txt)
82-
context = context || 20
83-
try {
95+
const parseJson = (txt, reviver) => {
96+
const result = JSON.parse(txt, reviver)
97+
if (result && typeof result === 'object') {
8498
// get the indentation so that we can save it back nicely
8599
// if the file starts with {" then we have an indent of '', ie, none
86-
// otherwise, pick the indentation of the next line after the first \n
87-
// If the pattern doesn't match, then it means no indentation.
88-
// JSON.stringify ignores symbols, so this is reasonably safe.
89-
// if the string is '{}' or '[]', then use the default 2-space indent.
90-
const [, newline = '\n', indent = ' '] = parseText.match(emptyRE) ||
91-
parseText.match(formatRE) ||
92-
[null, '', '']
93-
94-
const result = JSON.parse(parseText, reviver)
95-
if (result && typeof result === 'object') {
96-
result[kNewline] = newline
97-
result[kIndent] = indent
98-
}
99-
return result
100+
// otherwise, pick the indentation of the next line after the first \n If the
101+
// pattern doesn't match, then it means no indentation. JSON.stringify ignores
102+
// symbols, so this is reasonably safe. if the string is '{}' or '[]', then
103+
// use the default 2-space indent.
104+
const match = txt.match(EMPTY) || txt.match(FORMAT) || [null, '', '']
105+
result[NEWLINE] = match[1] ?? DEFAULT_NEWLINE
106+
result[INDENT] = match[2] ?? DEFAULT_INDENT
107+
}
108+
return result
109+
}
110+
111+
const parseJsonError = (raw, reviver, context) => {
112+
const txt = stripBOM(raw)
113+
try {
114+
return parseJson(txt, reviver)
100115
} catch (e) {
101-
if (typeof txt !== 'string' && !Buffer.isBuffer(txt)) {
102-
const isEmptyArray = Array.isArray(txt) && txt.length === 0
103-
throw Object.assign(new TypeError(
104-
`Cannot parse ${isEmptyArray ? 'an empty array' : String(txt)}`
105-
), {
106-
code: 'EJSONPARSE',
107-
systemError: e,
108-
})
116+
if (typeof raw !== 'string' && !Buffer.isBuffer(raw)) {
117+
const msg = Array.isArray(raw) && raw.length === 0 ? 'an empty array' : String(raw)
118+
throw Object.assign(
119+
new TypeError(`Cannot parse ${msg}`),
120+
{ code: 'EJSONPARSE', systemError: e }
121+
)
109122
}
110-
111-
throw new JSONParseError(e, parseText, context, parseJson)
123+
throw new JSONParseError(e, txt, context, parseJsonError)
112124
}
113125
}
114126

115-
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
116-
// because the buffer-to-string conversion in `fs.readFileSync()`
117-
// translates it to FEFF, the UTF-16 BOM.
118-
const stripBOM = txt => String(txt).replace(/^\uFEFF/, '')
119-
120-
module.exports = parseJson
121-
parseJson.JSONParseError = JSONParseError
122-
123-
parseJson.noExceptions = (txt, reviver) => {
127+
module.exports = parseJsonError
128+
parseJsonError.JSONParseError = JSONParseError
129+
parseJsonError.noExceptions = (raw, reviver) => {
124130
try {
125-
return JSON.parse(stripBOM(txt), reviver)
126-
} catch (e) {
131+
return parseJson(stripBOM(raw), reviver)
132+
} catch {
127133
// no exceptions
128134
}
129135
}

node_modules/json-parse-even-better-errors/package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-parse-even-better-errors",
3-
"version": "3.0.0",
3+
"version": "3.0.1",
44
"description": "JSON.parse with context information on error",
55
"main": "lib/index.js",
66
"files": [
@@ -10,7 +10,7 @@
1010
"scripts": {
1111
"test": "tap",
1212
"snap": "tap",
13-
"lint": "eslint \"**/*.js\"",
13+
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
1414
"postlint": "template-oss-check",
1515
"template-oss-apply": "template-oss-apply --force",
1616
"lintfix": "npm run lint -- --fix",
@@ -27,8 +27,8 @@
2727
"author": "GitHub Inc.",
2828
"license": "MIT",
2929
"devDependencies": {
30-
"@npmcli/eslint-config": "^3.1.0",
31-
"@npmcli/template-oss": "4.5.1",
30+
"@npmcli/eslint-config": "^4.0.0",
31+
"@npmcli/template-oss": "4.20.0",
3232
"tap": "^16.3.0"
3333
},
3434
"tap": {
@@ -43,6 +43,7 @@
4343
},
4444
"templateOSS": {
4545
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
46-
"version": "4.5.1"
46+
"version": "4.20.0",
47+
"publish": true
4748
}
4849
}

package-lock.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
"ini": "^4.1.1",
115115
"init-package-json": "^6.0.0",
116116
"is-cidr": "^5.0.3",
117-
"json-parse-even-better-errors": "^3.0.0",
117+
"json-parse-even-better-errors": "^3.0.1",
118118
"libnpmaccess": "^8.0.1",
119119
"libnpmdiff": "^6.0.3",
120120
"libnpmexec": "^7.0.4",
@@ -8916,9 +8916,9 @@
89168916
}
89178917
},
89188918
"node_modules/json-parse-even-better-errors": {
8919-
"version": "3.0.0",
8920-
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz",
8921-
"integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==",
8919+
"version": "3.0.1",
8920+
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz",
8921+
"integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==",
89228922
"inBundle": true,
89238923
"engines": {
89248924
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"ini": "^4.1.1",
7777
"init-package-json": "^6.0.0",
7878
"is-cidr": "^5.0.3",
79-
"json-parse-even-better-errors": "^3.0.0",
79+
"json-parse-even-better-errors": "^3.0.1",
8080
"libnpmaccess": "^8.0.1",
8181
"libnpmdiff": "^6.0.3",
8282
"libnpmexec": "^7.0.4",

0 commit comments

Comments
 (0)