From 4b563a71a7d1f50b5acb753a9cd50df44f05371b Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Wed, 18 Sep 2024 12:10:40 +0100 Subject: [PATCH 1/4] Render large numbers in JSON payloads as strings Signed-off-by: Matthew Whitehead --- src/utils/fetches.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/utils/fetches.ts b/src/utils/fetches.ts index 5dcc038..81c61c7 100644 --- a/src/utils/fetches.ts +++ b/src/utils/fetches.ts @@ -10,6 +10,8 @@ import { ITokenTransferWithPool, } from '../interfaces'; +import { parse, isSafeNumber, LosslessNumber } from 'lossless-json'; + export const fetchWithCredentials = ( resource: string, options?: RequestInit @@ -20,12 +22,23 @@ export const fetchWithCredentials = ( ); }; +export function parseLargeNumbersAsStrings(value: any) { + return isSafeNumber(value, { approx: false }) + ? parseFloat(value) // Smaller numbers are kept as Javascript numbers + : new LosslessNumber(value).toString(); // Large numbers are safely stringified +} + export const fetchCatcher = async (resource: string): Promise => { const response = await fetchWithCredentials(resource); if (!response.ok) { - console.log(`error fetching ${resource}`); } else { - return await response.json(); + const responseText = await response.text(); + const responseJSONLargeNumbersStringified = parse( + responseText, + null, + parseLargeNumbersAsStrings + ); + return responseJSONLargeNumbersStringified; } }; From 9c3f26c77a9e5990a122b7d7956b3056aa041260 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Wed, 18 Sep 2024 12:12:53 +0100 Subject: [PATCH 2/4] Pull in MIT licenses package 'lossless-json' Signed-off-by: Matthew Whitehead --- package-lock.json | 24 ++++++++++++++++++++++++ package.json | 2 ++ 2 files changed, 26 insertions(+) diff --git a/package-lock.json b/package-lock.json index 2eba763..7252d86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "dagre": "^0.8.5", "dayjs": "^1.11.1", "i18next": "^21.6.16", + "lossless-json": "^4.0.2", "pretty-bytes": "^6.0.0", "react": "^17.0.2", "react-copy-to-clipboard": "^5.1.0", @@ -38,6 +39,7 @@ }, "devDependencies": { "@types/jest": "^27.4.1", + "@types/lossless-json": "^1.0.4", "@types/node": "^17.0.25", "@types/react": "^17.0.43", "@types/react-copy-to-clipboard": "^5.0.2", @@ -4136,6 +4138,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "node_modules/@types/lossless-json": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/lossless-json/-/lossless-json-1.0.4.tgz", + "integrity": "sha512-eHhzo0p2p9On3cTr5X0Q0XsOjJxkqYzQi5Le5ObSiJjnLlGpDQvTcQEXknCkvKOFLBLa8ny4dgJKr0ADRV8yig==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -11958,6 +11966,11 @@ "loose-envify": "cli.js" } }, + "node_modules/lossless-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.0.2.tgz", + "integrity": "sha512-+z0EaLi2UcWi8MZRxA5iTb6m4Ys4E80uftGY+yG5KNFJb5EceQXOhdW/pWJZ8m97s26u7yZZAYMcKWNztSZssA==" + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -20277,6 +20290,12 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" }, + "@types/lossless-json": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/lossless-json/-/lossless-json-1.0.4.tgz", + "integrity": "sha512-eHhzo0p2p9On3cTr5X0Q0XsOjJxkqYzQi5Le5ObSiJjnLlGpDQvTcQEXknCkvKOFLBLa8ny4dgJKr0ADRV8yig==", + "dev": true + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -26054,6 +26073,11 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lossless-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.0.2.tgz", + "integrity": "sha512-+z0EaLi2UcWi8MZRxA5iTb6m4Ys4E80uftGY+yG5KNFJb5EceQXOhdW/pWJZ8m97s26u7yZZAYMcKWNztSZssA==" + }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", diff --git a/package.json b/package.json index ec6fa8b..0e394cf 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dagre": "^0.8.5", "dayjs": "^1.11.1", "i18next": "^21.6.16", + "lossless-json": "^4.0.2", "pretty-bytes": "^6.0.0", "react": "^17.0.2", "react-copy-to-clipboard": "^5.1.0", @@ -60,6 +61,7 @@ }, "devDependencies": { "@types/jest": "^27.4.1", + "@types/lossless-json": "^1.0.4", "@types/node": "^17.0.25", "@types/react": "^17.0.43", "@types/react-copy-to-clipboard": "^5.0.2", From c0d316500e9297219694d64c647c54ab8d2d8ee8 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Wed, 18 Sep 2024 12:21:21 +0100 Subject: [PATCH 3/4] Refactor Signed-off-by: Matthew Whitehead --- src/utils/fetches.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/utils/fetches.ts b/src/utils/fetches.ts index 81c61c7..eecd5cf 100644 --- a/src/utils/fetches.ts +++ b/src/utils/fetches.ts @@ -32,13 +32,7 @@ export const fetchCatcher = async (resource: string): Promise => { const response = await fetchWithCredentials(resource); if (!response.ok) { } else { - const responseText = await response.text(); - const responseJSONLargeNumbersStringified = parse( - responseText, - null, - parseLargeNumbersAsStrings - ); - return responseJSONLargeNumbersStringified; + return await parse(await response.text(), null, parseLargeNumbersAsStrings); } }; From 3d90bf804b635383530b95743a47f00fb3beb6e0 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Wed, 18 Sep 2024 12:26:54 +0100 Subject: [PATCH 4/4] Remove extraneous 'await' Signed-off-by: Matthew Whitehead --- src/utils/fetches.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/fetches.ts b/src/utils/fetches.ts index eecd5cf..e1acfd2 100644 --- a/src/utils/fetches.ts +++ b/src/utils/fetches.ts @@ -32,7 +32,7 @@ export const fetchCatcher = async (resource: string): Promise => { const response = await fetchWithCredentials(resource); if (!response.ok) { } else { - return await parse(await response.text(), null, parseLargeNumbersAsStrings); + return parse(await response.text(), null, parseLargeNumbersAsStrings); } };