Skip to content

Commit

Permalink
feat: use allowBigInt option so BigInt handling isn't a breaking ch…
Browse files Browse the repository at this point in the history
…ange

Defaults to `false` but if set to `true` it will invoke the BigInt decoding
rules.
  • Loading branch information
rvagg committed Aug 5, 2021
1 parent dc87eb4 commit 66d61b5
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 2 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ Use `import { encode, decode } from 'cborg/json'` or `const { encode, decode } =

Many of the same encode and decode options available for CBOR can be used to manage JSON handling. These include strictness requirements for decode and custom tag encoders for encode. Tag encoders can't create new tags as there are no tags in JSON, but they can replace JavaScript object forms with custom JSON forms (e.g. convert a `Uint8Array` to a valid JSON form rather than having the encoder throw an error). The inverse is also possible, turning specific JSON forms into JavaScript forms, by using a custom tokenizer on decode.

Special notes on options specific to the JSON:

* Decoder `allowBigInt` option: is repurposed for the JSON decoder and defaults to `false`. When `false`, all numbers are decoded as `Number`, possibly losing precision when encountering numbers outside of the JavaScript safe integer range. When `true` numbers that have a decimal point (`.`, even if just `.0`) are returned as a `Number`, but for numbers without a decimal point _and_ that are outside of the JavaScript safe integer range, they are returned as `BigInt`s. This behaviour differs from CBOR decoding which will error when decoding integer and negative integer tokens that are outside of the JavaScript safe integer range if `allowBigInt` is `false`.

See **[@ipld/dag-json](https://github.com/ipld/js-dag-json)** for an advanced use of the **cborg** JSON encoder and decoder including round-tripping of `Uint8Array`s and custom JavaScript classes (IPLD `CID` objects in this case).

### Example
Expand Down
2 changes: 1 addition & 1 deletion lib/json/decode.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class Tokenizer {
if (float) {
return new Token(Type.float, num, this.pos - startPos)
}
if (Number.isSafeInteger(num)) {
if (this.options.allowBigInt !== true || Number.isSafeInteger(num)) {
return new Token(num >= 0 ? Type.uint : Type.negint, num, this.pos - startPos)
}
return new Token(num >= 0 ? Type.uint : Type.negint, BigInt(numStr), this.pos - startPos)
Expand Down
3 changes: 2 additions & 1 deletion test/test-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ describe('json basics', () => {
if (str === undefined) {
str = String(inp)
}
assert.strictEqual(decode(toBytes(str)), inp)
assert.strictEqual(decode(toBytes(str), { allowBigInt: true }), inp)
assert.strictEqual(decode(toBytes(str)), parseFloat(str)) // no BigInt for you
}
verify(Number.MAX_SAFE_INTEGER)
verify(-Number.MAX_SAFE_INTEGER)
Expand Down

0 comments on commit 66d61b5

Please sign in to comment.