import { createHash } from 'node:crypto'; function canonicalValue(value: unknown): unknown { if (value instanceof Date) return value.toISOString(); if (Array.isArray(value)) return value.map(canonicalValue); if (value !== null && typeof value === 'object') { return Object.fromEntries( Object.entries(value as Record) .sort(([left], [right]) => left.localeCompare(right)) .map(([key, item]) => [key, canonicalValue(item)]), ); } return value; } export function canonicalJson(value: unknown): string { return JSON.stringify(canonicalValue(value)); } export function sha256CanonicalJson(value: unknown): string { return createHash('sha256').update(canonicalJson(value)).digest('hex'); }