diff --git a/README.md b/README.md index aaff8134..bea5eb78 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ And nested ones, too. | -----------|------------------------------| | `Date` | `string` via `toISOString()` | | `RegExp` | `string` | +| `BigInt` | `integer` via `toString` | #### Required @@ -439,9 +440,28 @@ const stringify = fastJson(schema, { schema: externalSchema }) #### Long integers -Long integers (64-bit) are supported using the [long](https://github.com/dcodeIO/long.js) module. +By default the library will handle automatically [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) from Node.js v10.3 and above. +If you can't use BigInts in your environment, long integers (64-bit) are also supported using the [long](https://github.com/dcodeIO/long.js) module. Example: ```javascript +// => using native BigInt +const stringify = fastJson({ + title: 'Example Schema', + type: 'object', + properties: { + id: { + type: 'integer' + } + } +}) + +const obj = { + id: 18446744073709551615n +} + +console.log(stringify(obj)) // '{"id":18446744073709551615}' + +// => using the long library const Long = require('long') const stringify = fastJson({ diff --git a/index.js b/index.js index da89b0e0..f669c538 100644 --- a/index.js +++ b/index.js @@ -214,6 +214,8 @@ function $asNull () { function $asInteger (i) { if (isLong && isLong(i)) { return i.toString() + } else if (typeof i === 'bigint') { + return i.toString() } else { return $asNumber(i) } diff --git a/package.json b/package.json index 1a4dde6f..c59c56b4 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "long": "^4.0.0", "pre-commit": "^1.2.2", "proxyquire": "^2.1.3", + "semver": "^6.3.0", "standard": "^14.0.0", "tap": "^12.6.5", "tap-mocha-reporter": "^3.0.9", diff --git a/test/bigint.js b/test/bigint.js new file mode 100644 index 00000000..ec166b46 --- /dev/null +++ b/test/bigint.js @@ -0,0 +1,74 @@ +'use strict' + +module.exports = function (test, build) { + test('render a bigint as JSON', (t) => { + t.plan(1) + + const schema = { + title: 'bigint', + type: 'integer' + } + + const stringify = build(schema) + const output = stringify(1615n) + + t.equal(output, '1615') + }) + + test('render an object with a bigint as JSON', (t) => { + t.plan(1) + + const schema = { + title: 'object with bigint', + type: 'object', + properties: { + id: { + type: 'integer' + } + } + } + + const stringify = build(schema) + const output = stringify({ + id: 1615n + }) + + t.equal(output, '{"id":1615}') + }) + + test('render an array with a bigint as JSON', (t) => { + t.plan(1) + + const schema = { + title: 'array with bigint', + type: 'array', + items: { + type: 'integer' + } + } + + const stringify = build(schema) + const output = stringify([1615n]) + + t.equal(output, '[1615]') + }) + + test('render an object with an additionalProperty of type bigint as JSON', (t) => { + t.plan(1) + + const schema = { + title: 'object with bigint', + type: 'object', + additionalProperties: { + type: 'integer' + } + } + + const stringify = build(schema) + const output = stringify({ + num: 1615n + }) + + t.equal(output, '{"num":1615}') + }) +} diff --git a/test/integer.test.js b/test/integer.test.js index 69e1c340..3c7146f7 100644 --- a/test/integer.test.js +++ b/test/integer.test.js @@ -1,6 +1,8 @@ 'use strict' -const test = require('tap').test +const t = require('tap') +const test = t.test +const semver = require('semver') const validator = require('is-my-json-valid') const proxyquire = require('proxyquire') const build = proxyquire('..', { long: null }) @@ -83,3 +85,10 @@ test('render an object with an additionalProperty of type integer as JSON', (t) t.equal(output, '{"num":1615}') t.ok(validate(JSON.parse(output)), 'valid schema') }) + +if (semver.gt(process.versions.node, '10.3.0')) { + require('./bigint')(t.test, build) +} else { + t.pass('Skip because Node version < 10.4') + t.end() +}