1import * as Schema from "effect/Schema"
2import { createHash } from "node:crypto"
3
4export const decodeJson = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Unknown))
5
6export const stableJson = (value: unknown): string => {
7 const visit = (input: unknown): unknown => {
8 if (Array.isArray(input)) {
9 return input.map(visit)
10 }
11 if (input !== null && typeof input === "object") {
12 return Object.fromEntries(
13 Object.entries(input)
14 .filter(([, entry]) => entry !== undefined)
15 .sort(([left], [right]) => left.localeCompare(right))
16 .map(([key, entry]) => [key, visit(entry)])
17 )
18 }
19 return input
20 }
21 return JSON.stringify(visit(value))
22}
23
24export const fingerprint = (value: unknown): string => createHash("sha256").update(stableJson(value)).digest("hex")
25
26export const prettyJson = (value: unknown): string => `${JSON.stringify(value, null, 2)}\n`