From 8548afcd218e3b6f49ae73ba5a8d9918b393196a Mon Sep 17 00:00:00 2001 From: protom Date: Sat, 22 Aug 2026 16:54:29 +0200 Subject: [PATCH] refactor: add strict JSON parsing helpers --- src/lnurlcash/jsonParsing.ts | 20 ++++++++++++++++++++ src/lnurlcash/test-utils.ts | 16 ++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/lnurlcash/jsonParsing.ts diff --git a/src/lnurlcash/jsonParsing.ts b/src/lnurlcash/jsonParsing.ts new file mode 100644 index 0000000..3e888f9 --- /dev/null +++ b/src/lnurlcash/jsonParsing.ts @@ -0,0 +1,20 @@ +export const isJsonObject = (value: unknown): value is Record => + typeof value === 'object' && value !== null && !Array.isArray(value) + +export const parseJsonObject = (source: string): Record => { + const parsed: unknown = JSON.parse(source) + if (!isJsonObject(parsed)) throw new TypeError('Expected a JSON object.') + return parsed +} + +export const parseJsonArray = (source: string): unknown[] => { + const parsed: unknown = JSON.parse(source) + if (!Array.isArray(parsed)) throw new TypeError('Expected a JSON array.') + return Array.from(parsed, (value: unknown) => value) +} + +export const parseJsonObjectArray = (source: string): Array> => + parseJsonArray(source).map((value) => { + if (!isJsonObject(value)) throw new TypeError('Expected a JSON object array.') + return value + }) diff --git a/src/lnurlcash/test-utils.ts b/src/lnurlcash/test-utils.ts index 4e9697f..42a6fb5 100644 --- a/src/lnurlcash/test-utils.ts +++ b/src/lnurlcash/test-utils.ts @@ -2,6 +2,9 @@ // a browser) plus the mock-mint helpers every suite uses. import {vi} from 'vitest' +import {parseJsonArray, parseJsonObject, parseJsonObjectArray} from './jsonParsing' + +export {parseJsonArray, parseJsonObject, parseJsonObjectArray} export class LocalStorageStub { private map = new Map() @@ -26,3 +29,16 @@ export const stubLocalStorage = (): LocalStorageStub => { vi.stubGlobal('localStorage', stub) return stub } + +export const requiredValue = ( + value: T | null | undefined, + message = 'Expected test value to be present', +): T => { + if (value === null || value === undefined) throw new TypeError(message) + return value +} + +export const requiredString = (value: unknown, message = 'Expected a string value'): string => { + if (typeof value !== 'string') throw new TypeError(message) + return value +}