diff --git a/src/library/cbor/recordid.ts b/src/library/cbor/recordid.ts index 1b1773d4..4b655864 100644 --- a/src/library/cbor/recordid.ts +++ b/src/library/cbor/recordid.ts @@ -49,6 +49,11 @@ export class StringRecordId { } function escape_ident(str: string) { + // String which looks like a number should always be escaped, to prevent it from being parsed as a number + if (isOnlyNumbers(str)) { + return `⟨${str}⟩`; + } + let code, i, len; for (i = 0, len = str.length; i < len; i++) { @@ -65,3 +70,8 @@ function escape_ident(str: string) { return str; } + +function isOnlyNumbers(str: string) { + const parsed = parseInt(str); + return !isNaN(parsed) && parsed.toString() === str; +} diff --git a/tests/unit/__snapshots__/jsonify.ts.snap b/tests/unit/__snapshots__/jsonify.ts.snap index 221af7dd..4f14fae1 100644 --- a/tests/unit/__snapshots__/jsonify.ts.snap +++ b/tests/unit/__snapshots__/jsonify.ts.snap @@ -71,6 +71,9 @@ snapshot[`jsonify matches snapshot 1`] = ` ], type: "GeometryCollection", }, + id_almost_a_number: "⟨some:thing⟩:1e23", + id_is_a_number: "⟨some:thing⟩:123", + id_looks_like_number: "⟨some:thing⟩:⟨123⟩", null: null, num: 123, rid: "⟨some:thing⟩:under_score", diff --git a/tests/unit/jsonify.ts b/tests/unit/jsonify.ts index 30ae6482..85379eed 100644 --- a/tests/unit/jsonify.ts +++ b/tests/unit/jsonify.ts @@ -18,6 +18,9 @@ Deno.test("jsonify matches snapshot", async function (t) { const json = jsonify( { rid: new RecordId("some:thing", "under_score"), + id_looks_like_number: new RecordId("some:thing", "123"), + id_almost_a_number: new RecordId("some:thing", "1e23"), + id_is_a_number: new RecordId("some:thing", 123), str_rid: new StringRecordId("⟨some:thing⟩:under_score"), dec: new Decimal("3.333333"), dur: new Duration("1d2h"),