@ -28,6 +28,7 @@ import {
|
|||||||
} from '@typebot.io/schemas/features/blocks/integrations/webhook/constants'
|
} from '@typebot.io/schemas/features/blocks/integrations/webhook/constants'
|
||||||
import { env } from '@typebot.io/env'
|
import { env } from '@typebot.io/env'
|
||||||
import { parseAnswers } from '@typebot.io/results/parseAnswers'
|
import { parseAnswers } from '@typebot.io/results/parseAnswers'
|
||||||
|
import { JSONParse } from '@typebot.io/lib/JSONParse'
|
||||||
|
|
||||||
type ParsedWebhook = ExecutableHttpRequest & {
|
type ParsedWebhook = ExecutableHttpRequest & {
|
||||||
basicAuth: { username?: string; password?: string }
|
basicAuth: { username?: string; password?: string }
|
||||||
@ -326,7 +327,7 @@ export const convertKeyValueTableToObject = (
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const safeJsonParse = (json: unknown): { data: any; isJson: boolean } => {
|
const safeJsonParse = (json: unknown): { data: any; isJson: boolean } => {
|
||||||
try {
|
try {
|
||||||
return { data: JSON.parse(json as string), isJson: true }
|
return { data: JSONParse(json as string), isJson: true }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { data: json, isJson: false }
|
return { data: json, isJson: false }
|
||||||
}
|
}
|
||||||
|
28
packages/lib/JSONParse.ts
Normal file
28
packages/lib/JSONParse.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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 =
|
||||||
|
/(?<=[^\\]":[\[]?|[^\\]":\[.*)(-?\d{17,}|-?(?:[9](?:[1-9]07199254740991|0[1-9]7199254740991|00[8-9]199254740991|007[2-9]99254740991|007199[3-9]54740991|0071992[6-9]4740991|00719925[5-9]740991|007199254[8-9]40991|0071992547[5-9]0991|00719925474[1-9]991|00719925474099[2-9])))(?=,|\}[^"]|\][^"])/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
|
||||||
|
})
|
||||||
|
}
|
Reference in New Issue
Block a user