28 lines
1.4 KiB
TypeScript
28 lines
1.4 KiB
TypeScript
// Taken from https://github.com/Ivan-Korolenko/json-with-bigint/blob/main/json-with-bigint.js
|
|
|
|
/*
|
|
Function to parse JSON
|
|
If JSON has values presented in a lib's custom format (strings with digits and "n" character at the end), we just parse them to BigInt values (for backward compatibility with previous versions of the lib)
|
|
If JSON has values greater than Number.MAX_SAFE_INTEGER, we convert those values to our custom format, then parse them to BigInt values.
|
|
Other types of values are not affected and parsed as native JSON.parse() would parse them.
|
|
|
|
Big numbers are found and marked using RegEx with these conditions:
|
|
- Before the match there is ": OR ":[ OR ":[anyNumberOf(anyCharacters) with no \ before them
|
|
- The match itself has more than 16 digits OR (16 digits and any digit of the number is greater than that of the Number.MAX_SAFE_INTEGER). And it may have a - sign at the start
|
|
- After the match there is , OR } without " after it OR ] without " after it
|
|
*/
|
|
export const JSONParse = (json: string) => {
|
|
const numbersBiggerThanMaxInt = /(?<!\\)":\s*(-?\d{17,})(?=[,\]}])/g
|
|
const serializedData = json.replace(numbersBiggerThanMaxInt, `"$1n"`)
|
|
|
|
return JSON.parse(serializedData, (_, value) => {
|
|
const isCustomFormatBigInt =
|
|
typeof value === 'string' && Boolean(value.match(/^-?\d+n$/))
|
|
|
|
if (isCustomFormatBigInt)
|
|
return BigInt(value.substring(0, value.length - 1))
|
|
|
|
return value
|
|
})
|
|
}
|