mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-20 05:40:17 +08:00
90 lines
3.5 KiB
TypeScript
90 lines
3.5 KiB
TypeScript
// JSON.stringify's space parameter (replacer null), differentially vs Node —
|
|
// pretty output must be byte-exact: indentation depth per nesting level,
|
|
// newline placement, the space after ':', inline empty {} / [], dropped
|
|
// undefined-valued optional fields, and primitives (no structure to indent).
|
|
// Record fields serialize in DECLARED order (JS insertion order, exactly
|
|
// Node — 1880-json-declared-field-order pins the non-alphabetical cases);
|
|
// this file's alphabetical fields are historical layout, not load-bearing.
|
|
|
|
// Primitives: no structure, space is inert.
|
|
console.log(JSON.stringify(1, null, 2));
|
|
console.log(JSON.stringify("a:b,{c}", null, 2));
|
|
console.log(JSON.stringify(true, null, 4));
|
|
|
|
// Flat and nested records, number spaces.
|
|
const point = { label: "origin", x: 0, y: -1.5 };
|
|
console.log(JSON.stringify(point, null, 2));
|
|
console.log(JSON.stringify(point, null, 1));
|
|
console.log(JSON.stringify(point, null, 10));
|
|
const cfg = {
|
|
debug: true,
|
|
name: "svc",
|
|
ports: [80, 443],
|
|
server: { host: "example.com", port: 8080 },
|
|
};
|
|
console.log(JSON.stringify(cfg, null, 2));
|
|
|
|
// Arrays: nested, empty, and empty-inside-nonempty.
|
|
const grid: number[][] = [[1, 2], [], [3]];
|
|
console.log(JSON.stringify(grid, null, 2));
|
|
const none: string[] = [];
|
|
console.log(JSON.stringify(none, null, 2));
|
|
|
|
// Empty object inline; empty containers nested in records.
|
|
type Holder = { items: number[]; meta: { a?: number } };
|
|
const h: Holder = { items: [], meta: {} };
|
|
console.log(JSON.stringify(h, null, 2));
|
|
|
|
// Unions serialize as their arm; null arms print as null.
|
|
type MaybeNum = { v: number | null };
|
|
const mn: MaybeNum = { v: null };
|
|
console.log(JSON.stringify(mn, null, 2));
|
|
const mv: MaybeNum = { v: 3.5 };
|
|
console.log(JSON.stringify(mv, null, 2));
|
|
|
|
// Optional fields DROP while undefined — comma/newline placement must
|
|
// follow the survivors.
|
|
interface Opt {
|
|
host: string;
|
|
note?: string | null;
|
|
port?: number;
|
|
}
|
|
const o1: Opt = { host: "h1" };
|
|
const o2: Opt = { host: "h2", note: null, port: 8080 };
|
|
const o3: Opt = { host: "h3", note: "n", port: undefined };
|
|
console.log(JSON.stringify(o1, null, 2));
|
|
console.log(JSON.stringify(o2, null, 2));
|
|
console.log(JSON.stringify(o3, null, 2));
|
|
|
|
// Strings containing JSON structure characters must NOT be re-indented.
|
|
const tricky = { s: '{"a":[1,2],"b":"x"}', t: "line\nbreak, \"quoted\": ok" };
|
|
console.log(JSON.stringify(tricky, null, 2));
|
|
|
|
// Number space clamping: fractional truncates, negative and 0 mean compact,
|
|
// >10 clamps to 10.
|
|
console.log(JSON.stringify(point, null, 2.9));
|
|
console.log(JSON.stringify(point, null, 0));
|
|
console.log(JSON.stringify(point, null, -3));
|
|
console.log(JSON.stringify(point, null, 99));
|
|
|
|
// String spaces: used verbatim, first 10 code units only; empty is compact.
|
|
console.log(JSON.stringify(cfg, null, "\t"));
|
|
console.log(JSON.stringify(point, null, "-->"));
|
|
console.log(JSON.stringify(mn, null, "0123456789abcdef"));
|
|
console.log(JSON.stringify(point, null, ""));
|
|
|
|
// Undefined space and the 2-argument form: all compact.
|
|
console.log(JSON.stringify(point, null, undefined));
|
|
console.log(JSON.stringify(point, null));
|
|
console.log(JSON.stringify(point, undefined, 2));
|
|
|
|
// The pretty result is an ordinary string.
|
|
const s = JSON.stringify(cfg, null, 2);
|
|
console.log(s.length, s.includes(' "debug": true'));
|
|
|
|
// Round-trip: pretty text parses back to the same value.
|
|
type Point = { label: string; x: number; y: number };
|
|
const back = JSON.parse(JSON.stringify(point, null, 2)) as Point;
|
|
console.log(back.label, back.x, back.y);
|
|
console.log(JSON.stringify(back, null, 2) === JSON.stringify(point, null, 2));
|