canonicalize

import { canonicalize } from "jsr:@ende/json";

function

function canonicalize(value: JsonValue): string

Serializes a JSON value to a canonical string per RFC 8785 JSON Canonicalization Scheme (JCS).

This produces a deterministic JSON string suitable for hashing or signing, with object keys sorted lexicographically by UTF-16 code units and no whitespace between tokens.

Note: The input must be JSON-compatible data. Objects with toJSON() methods (like Date) should be converted to their JSON representation first.

value: JsonValue

The JSON value to canonicalize.

Returns

The canonical JSON string.

Example: Basic usage (RFC 8785 Appendix E inspired)

import { canonicalize } from "@ende/json/canonicalize";
import { assertEquals } from "@ende/assert";

// Keys are sorted lexicographically, no whitespace between tokens
const data = {
  time: "2019-01-28T07:45:10Z",
  big: "055",
  val: 3.5,
};
assertEquals(canonicalize(data), '{"big":"055","time":"2019-01-28T07:45:10Z","val":3.5}');

Example: Number serialization (RFC 8785 Section 3.2.2.3)

import { canonicalize } from "@ende/json/canonicalize";
import { assertEquals } from "@ende/assert";

// Numbers follow ECMAScript serialization rules
assertEquals(canonicalize(10.0), "10");           // No unnecessary decimals
assertEquals(canonicalize(1e21), "1e+21");        // Scientific notation for large
assertEquals(canonicalize(0.0000001), "1e-7");    // Scientific notation for small
assertEquals(canonicalize(-0), "0");              // Negative zero becomes "0"

Example: Key sorting by UTF-16 code units (RFC 8785 Section 3.2.3)

import { canonicalize } from "@ende/json/canonicalize";
import { assertEquals } from "@ende/assert";

// Keys sorted by UTF-16 code units: digits < uppercase < lowercase
const data = { a: 1, A: 2, "1": 3 };
assertEquals(canonicalize(data), '{"1":3,"A":2,"a":1}');

See also

Source