4a0523f309
Made-with: Cursor
19 lines
848 B
JavaScript
19 lines
848 B
JavaScript
/** Детерминированная JSON-сериализация для подписи (должна совпадать с `app/shared/license/canonicalJson.ts` в клиенте DNDGamePlayer). */
|
||
export function canonicalJson(value) {
|
||
if (value === null) return 'null';
|
||
const t = typeof value;
|
||
if (t === 'number') {
|
||
if (!Number.isFinite(value)) throw new TypeError('non-finite number in license payload');
|
||
return JSON.stringify(value);
|
||
}
|
||
if (t === 'string' || t === 'boolean') return JSON.stringify(value);
|
||
if (Array.isArray(value)) {
|
||
return `[${value.map((x) => canonicalJson(x)).join(',')}]`;
|
||
}
|
||
if (t === 'object') {
|
||
const keys = Object.keys(value).sort();
|
||
return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalJson(value[k])}`).join(',')}}`;
|
||
}
|
||
throw new TypeError(`unsupported type: ${t}`);
|
||
}
|