From a9a9b04a5a99658b2d74b4d54538d727ca27e4ae Mon Sep 17 00:00:00 2001 From: ztimson Date: Mon, 20 Oct 2025 15:51:10 -0400 Subject: [PATCH] JSONAttemptPrase fallback --- package.json | 2 +- src/index.ts | 1 + src/json.ts | 40 ++++++++++++++++++++++++++++++++++++++++ src/objects.ts | 42 ++---------------------------------------- 4 files changed, 44 insertions(+), 41 deletions(-) create mode 100644 src/json.ts diff --git a/package.json b/package.json index cf4c8eb..ec52912 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ztimson/utils", - "version": "0.27.8", + "version": "0.27.9", "description": "Utility library", "author": "Zak Timson", "license": "MIT", diff --git a/src/index.ts b/src/index.ts index 4655739..cf20437 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ export * from './files'; export * from './emitter'; export * from './errors'; export * from './http'; +export * from './json'; export * from './jwt'; export * from './logger'; export * from './math'; diff --git a/src/json.ts b/src/json.ts new file mode 100644 index 0000000..20e0ab8 --- /dev/null +++ b/src/json.ts @@ -0,0 +1,40 @@ +/** + * Parse JSON but return the original string if it fails + * + * @param {any} json JSON string to parse + * @param fallback Fallback value if unable to parse, defaults to original string + * @return {string | T} Object if successful, original string otherwise + */ +export function JSONAttemptParse(json: T2, fallback?: T1): T1 | T2 { + try { return JSON.parse(json); } + catch { return fallback ?? json; } +} + +/** + * Stringifies objects & skips primitives + * + * @param {any} obj Object to convert to serializable value + * @return {string | T} Serialized value + */ +export function JSONSerialize(obj: T1): T1 | string { + if(typeof obj == 'object' && obj != null) return JSONSanitize(obj); + return obj; +} + +/** + * Convert an object to a JSON string avoiding any circular references. + * + * @param obj Object to convert to JSON + * @param {number} space Format the JSON with spaces + * @return {string} JSON string + */ +export function JSONSanitize(obj: any, space?: number): string { + const cache: any[] = []; + return JSON.stringify(obj, (key, value) => { + if(typeof value === 'object' && value !== null) { + if(cache.includes(value)) return '[Circular]'; + cache.push(value); + } + return value; + }, space); +} diff --git a/src/objects.ts b/src/objects.ts index 6d5d772..1275b4f 100644 --- a/src/objects.ts +++ b/src/objects.ts @@ -1,3 +1,5 @@ +import {JSONSanitize} from './json.ts'; + export type Delta = { [key: string]: any | Delta | null }; @@ -303,43 +305,3 @@ export function objectMap(obj: any, fn: (key: string, value: any) => any): T return Object.entries(obj).map(([key, value]: [string, any]) => [key, fn(key, value)]) .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}); } - -/** - * Parse JSON but return the original string if it fails - * - * @param {any} json JSON string to parse - * @return {string | T} Object if successful, original string otherwise - */ -export function JSONAttemptParse(json: T2): T1 | T2 { - try { return JSON.parse(json); } - catch { return json; } -} - -/** - * Stringifies objects & skips primitives - * - * @param {any} obj Object to convert to serializable value - * @return {string | T} Serialized value - */ -export function JSONSerialize(obj: T1): T1 | string { - if(typeof obj == 'object' && obj != null) return JSONSanitize(obj); - return obj; -} - -/** - * Convert an object to a JSON string avoiding any circular references. - * - * @param obj Object to convert to JSON - * @param {number} space Format the JSON with spaces - * @return {string} JSON string - */ -export function JSONSanitize(obj: any, space?: number): string { - const cache: any[] = []; - return JSON.stringify(obj, (key, value) => { - if(typeof value === 'object' && value !== null) { - if(cache.includes(value)) return '[Circular]'; - cache.push(value); - } - return value; - }, space); -}