feat: add core registry schemas

This commit is contained in:
chungyeong
2026-05-09 23:56:10 +09:00
parent 44103839af
commit 4a7fc94f5c
18 changed files with 1267 additions and 12 deletions

View File

@@ -17,10 +17,47 @@ describe("content hashing", () => {
expect(left).toMatch(/^[a-f0-9]{64}$/);
});
it("preserves own __proto__ keys while canonicalizing objects", () => {
const withProtoKey = JSON.parse('{"__proto__":{"x":1},"a":2}') as unknown;
expect(canonicalize(withProtoKey)).toBe('{"__proto__":{"x":1},"a":2}');
expect(hash(withProtoKey)).not.toBe(hash({ a: 2 }));
});
it("rejects hidden object keys that would be ignored by JSON rendering", () => {
const withSymbol = { a: 1, [Symbol("x")]: 2 };
const withHidden = { a: 1 };
Object.defineProperty(withHidden, "hidden", { value: 2, enumerable: false });
expect(() => canonicalize(withSymbol)).toThrow(/non-enumerable or symbol/);
expect(() => canonicalize(withHidden)).toThrow(/non-enumerable or symbol/);
});
it("rejects non-index array object keys that would be ignored by JSON rendering", () => {
const withStringKey = [1] as number[] & { extra?: number };
withStringKey.extra = 2;
const withSymbol = [1] as unknown[];
Object.defineProperty(withSymbol, Symbol("x"), { value: 2, enumerable: true });
expect(() => canonicalize(withStringKey)).toThrow(/non-index array/);
expect(() => canonicalize(withSymbol)).toThrow(/non-index array/);
});
it("renders the shortest round-trippable number literals without plus signs", () => {
expect(canonicalize([100, 1000, 11000, 123000, 1e20, 1e21, 0.000001, 0.0000001])).toBe(
"[100,1e3,11e3,123e3,1e20,1e21,1e-6,1e-7]",
);
});
it("rejects values that are not JSON-safe", () => {
const sparse = Array<number>(3);
sparse[0] = 1;
sparse[2] = 3;
expect(() => canonicalize({ date: new Date("2026-05-09T00:00:00Z") })).toThrow(
/non-plain object/,
);
expect(() => canonicalize({ missing: undefined })).toThrow(/undefined/);
expect(() => canonicalize(sparse)).toThrow(/sparse array/);
});
});