UNPKG

@ton.js/json-parse-polyfill

Version:

A polyfill for JSON.parse

8 lines (7 loc) 17.6 kB
{ "version": 3, "sources": ["../src/index.ts", "../../json-parser/src/json-parser.ts"], "sourcesContent": ["\nimport type { ReviverFunc } from '@ton.js/json-parser';\nimport { parseJson } from '@ton.js/json-parser';\n\nexport * from '@ton.js/json-parser';\n\n\n/**\n * @public\n */\nexport const nativeJsonParse = JSON.parse;\n\n// Installing the polyfill only once\nif (JSON.parse !== jsonParsePolyfill) {\n JSON.parse = jsonParsePolyfill;\n}\n\n\nfunction jsonParsePolyfill(\n source: string,\n reviver?: ReviverFunc\n) {\n\n // Polyfill is only used when the third argument is\n // defined on the reviver function, otherwise using\n // native (faster) implementation.\n\n return ((reviver?.length || 0) >= 3\n ? parseJson(source, reviver)\n : nativeJsonParse(source, reviver as any)\n );\n\n}\n", "\n/**\n * {@link https://www.json.org/json-en.html | JSON specification}\n */\n\n/**\n * @public\n */\nexport type Maybe<Type> = (Type | undefined);\n\n/**\n * @public\n */\nexport type ReviverFunc = (\n key: string,\n value: any,\n context: ReviverContext\n\n) => any;\n\n/**\n * @public\n */\nexport interface ReviverContext {\n source: string;\n keys: string[];\n}\n\n/**\n * @public\n */\nexport interface Options {\n throwOnProto?: Maybe<boolean>;\n}\n\ninterface ParseContext {\n source: string;\n index: number;\n keys: string[];\n reviver?: Maybe<ReviverFunc>;\n options?: Maybe<Options>;\n}\n\ninterface ParseResult <Type = any> {\n value: Type;\n endIndex: number;\n}\n\ntype Keyword = (\n | 'true'\n | 'false'\n | 'null'\n);\n\n\nconst codePoints: Record<string, string> = {\n '\\\\\"': '\"',\n '\\\\\\\\': '\\\\',\n '\\\\/': '/',\n '\\\\b': '\\b',\n '\\\\f': '\\f',\n '\\\\n': '\\n',\n '\\\\r': '\\r',\n '\\\\t': '\\t',\n};\n\n/**\n * @public\n *\n * Parses JSON document and returns the parsed data.\n */\nexport function parseJson<Type = any>(\n source: string,\n reviver?: Maybe<ReviverFunc>,\n options?: Options\n\n): Type {\n\n const result = parseValue({\n source,\n index: 0,\n keys: [],\n reviver,\n options,\n });\n\n const endIndex = skipSpaces(source, result.endIndex);\n\n if (endIndex <= (source.length - 1)) {\n throw new SyntaxError(\n `Unexpected extra characters after the parsed data: ` +\n `\"${source.substring(endIndex, endIndex + 16)}\u2026\" ` +\n `at position: ${endIndex}`\n );\n }\n\n return result.value;\n\n}\n\nfunction parseValue(context: ParseContext): ParseResult {\n\n const { source, index } = context;\n\n let result: ParseResult;\n\n let i = skipSpaces(source, index);\n\n const newContext = nextContext(context, i);\n\n if (isNumberStart(source[i]!)) {\n\n result = parseNumber(newContext);\n\n } else {\n\n switch (source[i]) {\n case '\"': {\n result = parseString(newContext);\n break;\n }\n case '[': {\n result = parseArray(newContext);\n break;\n }\n case '{': {\n result = parseObject(newContext);\n break;\n }\n case 't': {\n result = parseKeyword(newContext, 'true');\n break;\n }\n case 'f': {\n result = parseKeyword(newContext, 'false');\n break;\n }\n case 'n': {\n result = parseKeyword(newContext, 'null');\n break;\n }\n default: {\n throw new SyntaxError(\n `Unexpected character: \"${source[i]}\" ` +\n `at position: ${i}`\n );\n }\n }\n\n }\n\n result.value = callReviver({\n context,\n rawValue: source.substring(i, result.endIndex),\n value: result.value,\n });\n\n return result;\n\n}\n\nfunction parseArray(context: ParseContext): ParseResult {\n\n const { source, index } = context;\n\n const array: any[] = [];\n\n let i = (index + 1);\n let expectElement = false;\n let elementIndex = 0;\n\n while (i < source.length) {\n\n i = skipSpaces(source, i);\n\n if (source[i] === ']' && !expectElement) {\n // End of the array\n i++;\n break;\n }\n\n const result = parseValue(\n nextContext(context, i, elementIndex.toString())\n );\n\n array.push(result.value);\n i = result.endIndex;\n i = skipUntil(source, i, [',', ']']);\n if (source[i] === ',') {\n // Going to parse the next value\n expectElement = true;\n elementIndex++;\n i++;\n } else if (source[i] === ']') {\n // End of the array\n i++;\n break;\n }\n\n }\n\n return {\n value: array,\n endIndex: i,\n };\n\n}\n\nfunction parseObject(context: ParseContext): ParseResult {\n\n const { source, index } = context;\n\n let object: Record<string, any> = {};\n\n let i = (index + 1);\n let expectKeypair = false;\n\n while (i < source.length) {\n\n i = skipUntil(source, i, ['\"', '}']);\n\n if (source[i] === '}' && !expectKeypair) {\n // End of the object\n i++;\n break;\n }\n\n // Parsing the key\n let result = parseString(\n nextContext(context, i)\n );\n const key = result.value;\n i = result.endIndex;\n i = skipUntil(source, i, ':') + 1;\n\n // Checking forbidden prototype property names and\n // throwing error if related option is set.\n if (context.options?.throwOnProto) {\n if (key === '__proto__') {\n throw new SyntaxError(\n `Forbidden object property name: \"__proto__\"`\n );\n } else if (isConstructorPrototype(key)) {\n throw new SyntaxError(\n `Forbidden object property path: \"constructor.prototype\"`\n );\n }\n }\n\n // Parsing value\n i = skipSpaces(source, i);\n result = parseValue(\n nextContext(context, i, key)\n );\n if (result.value !== undefined && isAllowedKey(key)) {\n object[key] = result.value;\n }\n i = result.endIndex;\n i = skipUntil(source, i, [',', '}']);\n if (source[i] === ',') {\n // Going to parse the next keypair\n expectKeypair = true;\n i++;\n } else if (source[i] === '}') {\n // End of the object\n i++;\n break;\n }\n\n }\n\n return {\n value: object,\n endIndex: i,\n };\n\n\n /**\n * Checks whether the key is part of \"constructor.prototype\"\n * path.\n */\n function isConstructorPrototype(key: string) {\n\n if (key !== 'prototype') {\n return false;\n }\n\n const parentKey = (context.keys.length > 0\n ? context.keys[context.keys.length - 1]\n : undefined\n );\n\n return (parentKey === 'constructor');\n\n }\n\n function isAllowedKey(key: string) {\n\n return (\n key !== '__proto__' &&\n !isConstructorPrototype(key)\n );\n\n }\n\n}\n\nfunction parseString(\n context: ParseContext\n\n): ParseResult<string> {\n\n const { source, index } = context;\n\n let value = '';\n\n let i = (index + 1);\n\n while (i < source.length) {\n\n const char = source[i] as string;\n\n if (char === '\\\\') {\n\n const twoChars = source.substring(i, i + 2);\n const codepoint = codePoints[twoChars];\n\n if (codepoint) {\n value += codepoint;\n i += 2;\n\n } else if (twoChars === '\\\\u') {\n const charHex = source.substring(i + 2, i + 6);\n value += String.fromCharCode(parseInt(charHex, 16));\n i += 6;\n\n } else {\n throw new SyntaxError(\n `Unknown escape sequence: \"${twoChars}\"`\n );\n\n }\n\n } else if (char === '\"') {\n // End of string\n i++;\n break;\n\n } else {\n value += char;\n i++;\n\n }\n\n }\n\n return { value, endIndex: i };\n\n}\n\nfunction isNumberStart(char: string): boolean {\n\n return Boolean(char.match(/^(-|\\d)$/));\n\n}\n\nfunction parseNumber(\n context: ParseContext\n\n): ParseResult<number> {\n\n const { source, index } = context;\n\n let isNegative = false;\n let integer = '0';\n let fraction = '';\n let isExponentNegative = false;\n let exponent = '';\n\n let i = index;\n\n // Parsing sign\n if (source[i] === '-') {\n isNegative = true;\n i++;\n }\n\n // Parsing integer part\n // -----\n\n if (source[i] === '0') {\n i++;\n\n } else if (source[i]!.match(/^[1-9]$/)) {\n\n integer = source[i]!;\n i++;\n\n while (i < source.length) {\n if (source[i]!.match(/^\\d$/)) {\n integer += source[i]!;\n i++;\n } else {\n break;\n }\n }\n\n } else {\n throw new SyntaxError(\n `Failed to parse number at position: ${i}`\n );\n\n }\n\n // Parsing fractional part\n // -----\n\n if (source[i] === '.') {\n\n i++;\n\n while (i < source.length) {\n if (source[i]!.match(/^\\d$/)) {\n fraction += source[i]!;\n i++;\n } else {\n break;\n }\n }\n\n }\n\n // Parsing exponent\n // -----\n\n if (['e', 'E'].includes(source[i]!)) {\n\n i++;\n\n if (source[i] === '+') {\n i++;\n } else if (source[i] === '-') {\n isExponentNegative = true;\n i++;\n }\n\n const exponentStartIndex = i;\n\n while (i < source.length) {\n if (source[i]!.match(/^\\d$/)) {\n exponent += source[i]!;\n i++;\n } else {\n break;\n }\n }\n\n if (exponent.length === 0) {\n throw new SyntaxError(\n `Failed to parse number's exponent value ` +\n `at position: ${exponentStartIndex}`\n );\n }\n\n }\n\n let value = Number(\n (isNegative ? '-' : '') + integer +\n (fraction ? `.${fraction}` : '') +\n (exponent ? `e${isExponentNegative ? '-' : ''}${exponent}` : '')\n );\n\n return {\n value,\n endIndex: i,\n };\n\n}\n\nfunction skipUntil(\n source: string,\n startIndex: number,\n endChar: (string | string[])\n\n): number {\n\n endChar = (Array.isArray(endChar) ? endChar : [endChar]);\n\n const i = skipSpaces(source, startIndex);\n\n const char = source[i] as string;\n\n if (endChar.includes(char)) {\n return i;\n\n } else {\n throw new SyntaxError(\n `Unexpected character: \"${char}\" ` +\n `at position: ${i}`\n );\n\n }\n\n}\n\nfunction skipSpaces(\n source: string,\n startIndex: number\n\n): number {\n\n let i: number;\n\n for (i = startIndex; i < source.length; i++) {\n\n const char = source[i] as string;\n\n if (!isWhitespace(char)) {\n break;\n }\n\n }\n\n return i;\n\n}\n\nfunction isWhitespace(char: string) {\n return [' ', '\\n', '\\r', '\\t'].includes(char);\n}\n\nfunction parseKeyword(\n context: ParseContext,\n keyword: Keyword,\n\n): ParseResult {\n\n const { source, index } = context;\n\n const endIndex = (index + keyword.length);\n\n const slice = source.substring(index, endIndex);\n\n if (slice !== keyword) {\n throw new SyntaxError(\n `Failed to parse value at position: ${index}`\n );\n }\n\n let value = (\n keyword === 'true' ? true :\n keyword === 'false' ? false :\n null\n );\n\n return {\n value,\n endIndex,\n };\n\n}\n\nfunction callReviver(args: {\n context: ParseContext,\n rawValue: string;\n value: any;\n\n}): any {\n\n const { context, rawValue, value } = args;\n const { reviver, keys } = context;\n\n if (!reviver) {\n return value;\n }\n\n const key = ((keys.length > 0)\n ? keys[keys.length - 1]!\n : ''\n );\n\n return reviver(key, value, {\n source: rawValue,\n keys,\n });\n\n}\n\n/**\n * A helper function that creates new parsing context\n * based on the previous one by advancing the reading index\n * and optionally adding a key to the list of keys.\n */\nfunction nextContext(\n context: ParseContext,\n nextIndex: number,\n nextKey?: string,\n\n): ParseContext {\n\n const newContext = {\n ...context,\n index: nextIndex,\n };\n\n if (nextKey) {\n newContext.keys = [\n ...context.keys,\n nextKey,\n ];\n }\n\n return newContext;\n\n}\n"], "mappings": "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", "names": [] }