Refactor, Added documentation, moved from avj-cli to avj, update script and added tests
This commit is contained in:
76
source/extended-json.ts
Normal file
76
source/extended-json.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { binToHex, hexToBin } from '@bitauth/libauth';
|
||||
|
||||
/**
|
||||
* Matches a bigint encoded in Extended JSON format: `<bigint: 123n>`.
|
||||
*/
|
||||
const EXTENDED_JSON_BIGINT_PATTERN = /^<bigint: (?<bigint>[+-]?[0-9]+)n>$/u;
|
||||
|
||||
/**
|
||||
* Matches a Uint8Array encoded in Extended JSON format: `<uint8array: abcd>`.
|
||||
*/
|
||||
const EXTENDED_JSON_UINT8ARRAY_PATTERN = /^<uint8array: (?<hex>[0-9a-f]*)>$/u;
|
||||
|
||||
/**
|
||||
* The JSON replacer that encodes `bigint` and `Uint8Array` values in Extended JSON format,
|
||||
* compatible with the format expected by `extendedJsonReviver`.
|
||||
*
|
||||
* - BigInts are encoded as `<bigint: 123n>`.
|
||||
* - Uint8Arrays are encoded as `<uint8array: abcd>`.
|
||||
* All other values pass through unchanged and if any incompatible type is encountered, an error is thrown.
|
||||
*
|
||||
* Note: To use this function, pass it as the second argument to `JSON.stringify` when serializing data.
|
||||
*
|
||||
* Note to developers: Libauth's `stringify` is the replacer. It also serializes functions and symbols,
|
||||
* which we do not support. Passing it would let templates include those values, but revival would then fail.
|
||||
* This module provides a dedicated replacer and reviver so serialization and deserialization stay aligned.
|
||||
*
|
||||
* @param _propertyKey The property key being serialized, required by the `JSON.stringify` replacer but not used here.
|
||||
* @param value The value to encode or pass through unchanged.
|
||||
* @returns The encoded string
|
||||
*/
|
||||
export const extendedJsonReplacer = (_propertyKey: string, value: unknown): unknown => {
|
||||
if (value instanceof Uint8Array) {
|
||||
return `<uint8array: ${binToHex(value)}>`;
|
||||
}
|
||||
|
||||
if (typeof value === 'bigint') {
|
||||
return `<bigint: ${value.toString()}n>`;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* The JSON reviver that reconstructs `bigint` and `Uint8Array` values encoded by `extendedJsonReplacer`.
|
||||
*
|
||||
* Note: To use this function, pass it as the second argument to `JSON.parse` when deserializing data.
|
||||
*
|
||||
* @param _propertyKey The property key being deserialized, required by the `JSON.parse` reviver but not used here.
|
||||
* @param value The value to reconstruct or pass through unchanged.
|
||||
* @returns The reconstructed value
|
||||
*/
|
||||
export const extendedJsonReviver = (_propertyKey: string, value: unknown): unknown => {
|
||||
// If the value is not a string, return the original value
|
||||
if (typeof value !== 'string') {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Match the bigint pattern
|
||||
const bigintPatternMatch = value.match(EXTENDED_JSON_BIGINT_PATTERN);
|
||||
|
||||
// If the value matches the bigint pattern, return the reconstructed bigint
|
||||
if (bigintPatternMatch) {
|
||||
return BigInt(bigintPatternMatch.groups!.bigint);
|
||||
}
|
||||
|
||||
// Match the Uint8Array pattern
|
||||
const uint8arrayPatternMatch = value.match(EXTENDED_JSON_UINT8ARRAY_PATTERN);
|
||||
|
||||
// If the value matches the Uint8Array pattern, return the reconstructed Uint8Array
|
||||
if (uint8arrayPatternMatch) {
|
||||
return hexToBin(uint8arrayPatternMatch.groups!.hex);
|
||||
}
|
||||
|
||||
// If the value does not match either pattern, return the original value
|
||||
return value;
|
||||
};
|
||||
Reference in New Issue
Block a user