• Stars
    star
    722
  • Rank 62,738 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 11 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JSON.parse/stringify with bigints support

json-bigint

Build Status NPM

JSON.parse/stringify with bigints support. Based on Douglas Crockford JSON.js package and bignumber.js library.

Native Bigint was added to JS recently, so we added an option to leverage it instead of bignumber.js. However, the parsing with native BigInt is kept an option for backward compability.

While most JSON parsers assume numeric values have same precision restrictions as IEEE 754 double, JSON specification does not say anything about number precision. Any floating point number in decimal (optionally scientific) notation is valid JSON value. It's a good idea to serialize values which might fall out of IEEE 754 integer precision as strings in your JSON api, but { "value" : 9223372036854775807}, for example, is still a valid RFC4627 JSON string, and in most JS runtimes the result of JSON.parse is this object: { value: 9223372036854776000 }

==========

example:

var JSONbig = require('json-bigint');

var json = '{ "value" : 9223372036854775807, "v2": 123 }';
console.log('Input:', json);
console.log('');

console.log('node.js built-in JSON:');
var r = JSON.parse(json);
console.log('JSON.parse(input).value : ', r.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));

console.log('\n\nbig number JSON:');
var r1 = JSONbig.parse(json);
console.log('JSONbig.parse(input).value : ', r1.value.toString());
console.log('JSONbig.stringify(JSONbig.parse(input)):', JSONbig.stringify(r1));

Output:

Input: { "value" : 9223372036854775807, "v2": 123 }

node.js built-in JSON:
JSON.parse(input).value :  9223372036854776000
JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}


big number JSON:
JSONbig.parse(input).value :  9223372036854775807
JSONbig.stringify(JSONbig.parse(input)): {"value":9223372036854775807,"v2":123}

Options

The behaviour of the parser is somewhat configurable through 'options'

options.strict, boolean, default false

Specifies the parsing should be "strict" towards reporting duplicate-keys in the parsed string. The default follows what is allowed in standard json and resembles the behavior of JSON.parse, but overwrites any previous values with the last one assigned to the duplicate-key.

Setting options.strict = true will fail-fast on such duplicate-key occurances and thus warn you upfront of possible lost information.

example:

var JSONbig = require('json-bigint');
var JSONstrict = require('json-bigint')({ strict: true });

var dupkeys = '{ "dupkey": "value 1", "dupkey": "value 2"}';
console.log('\n\nDuplicate Key test with both lenient and strict JSON parsing');
console.log('Input:', dupkeys);
var works = JSONbig.parse(dupkeys);
console.log('JSON.parse(dupkeys).dupkey: %s', works.dupkey);
var fails = 'will stay like this';
try {
  fails = JSONstrict.parse(dupkeys);
  console.log('ERROR!! Should never get here');
} catch (e) {
  console.log(
    'Succesfully catched expected exception on duplicate keys: %j',
    e
  );
}

Output

Duplicate Key test with big number JSON
Input: { "dupkey": "value 1", "dupkey": "value 2"}
JSON.parse(dupkeys).dupkey: value 2
Succesfully catched expected exception on duplicate keys: {"name":"SyntaxError","message":"Duplicate key \"dupkey\"","at":33,"text":"{ \"dupkey\": \"value 1\", \"dupkey\": \"value 2\"}"}

options.storeAsString, boolean, default false

Specifies if BigInts should be stored in the object as a string, rather than the default BigNumber.

Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all BigInts to be-and-stay strings).

example:

var JSONbig = require('json-bigint');
var JSONbigString = require('json-bigint')({ storeAsString: true });
var key = '{ "key": 1234567890123456789 }';
console.log('\n\nStoring the BigInt as a string, instead of a BigNumber');
console.log('Input:', key);
var withInt = JSONbig.parse(key);
var withString = JSONbigString.parse(key);
console.log(
  'Default type: %s, With option type: %s',
  typeof withInt.key,
  typeof withString.key
);

Output

Storing the BigInt as a string, instead of a BigNumber
Input: { "key": 1234567890123456789 }
Default type: object, With option type: string

options.useNativeBigInt, boolean, default false

Specifies if parser uses native BigInt instead of bignumber.js

example:

var JSONbig = require('json-bigint');
var JSONbigNative = require('json-bigint')({ useNativeBigInt: true });
var key = '{ "key": 993143214321423154315154321 }';
console.log(`\n\nStoring the Number as native BigInt, instead of a BigNumber`);
console.log('Input:', key);
var normal = JSONbig.parse(key);
var nativeBigInt = JSONbigNative.parse(key);
console.log(
  'Default type: %s, With option type: %s',
  typeof normal.key,
  typeof nativeBigInt.key
);

Output

Storing the Number as native BigInt, instead of a BigNumber
Input: { "key": 993143214321423154315154321 }
Default type: object, With option type: bigint

options.alwaysParseAsBig, boolean, default false

Specifies if all numbers should be stored as BigNumber.

Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all Number to be-and-stay BigNumber)

example:

var JSONbig = require('json-bigint');
var JSONbigAlways = require('json-bigint')({ alwaysParseAsBig: true });
var key = '{ "key": 123 }'; // there is no need for BigNumber by default, but we're forcing it
console.log(`\n\nStoring the Number as a BigNumber, instead of a Number`);
console.log('Input:', key);
var normal = JSONbig.parse(key);
var always = JSONbigAlways.parse(key);
console.log(
  'Default type: %s, With option type: %s',
  typeof normal.key,
  typeof always.key
);

Output

Storing the Number as a BigNumber, instead of a Number
Input: { "key": 123 }
Default type: number, With option type: object

If you want to force all numbers to be parsed as native BigInt (you probably do! Otherwise any calulations become a real headache):

var JSONbig = require('json-bigint')({
  alwaysParseAsBig: true,
  useNativeBigInt: true,
});

options.protoAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"

options.constructorAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"

Controls how __proto__ and constructor properties are treated. If set to "error" they are not allowed and parse() call will throw an error. If set to "ignore" the prroperty and it;s value is skipped from parsing and object building. If set to "preserve" the __proto__ property is set. One should be extra careful and make sure any other library consuming generated data is not vulnerable to prototype poisoning attacks.

example:

var JSONbigAlways = require('json-bigint')({ protoAction: 'ignore' });
const user = JSONbig.parse('{ "__proto__": { "admin": true }, "id": 12345 }');
// => result is { id: 12345 }

Links:

Note on native BigInt support

Stringifying

Full support out-of-the-box, stringifies BigInts as pure numbers (no quotes, no n)

Limitations

  • Roundtrip operations

s === JSONbig.stringify(JSONbig.parse(s)) but

o !== JSONbig.parse(JSONbig.stringify(o))

when o has a value with something like 123n.

JSONbig stringify 123n as 123, which becomes number (aka 123 not 123n) by default when being reparsed.

There is currently no consistent way to deal with this issue, so we decided to leave it, handling this specific case is then up to users.

More Repositories

1

node-mysql2

⚑ fast mysqljs/mysql compatible mysql driver for node.js
JavaScript
4,062
star
2

node-vim-debugger

node.js step by step debugging from vim
JavaScript
562
star
3

node-x11

X11 node.js network protocol client
JavaScript
518
star
4

vnc-over-gif

JavaScript
512
star
5

node-tick

node.js-runnable v8.log processor (d8 + %platform%-tick-processor friend)
JavaScript
322
star
6

dbus-native

D-bus protocol client and server for node.js written in native javascript
JavaScript
259
star
7

crconsole

Remote JavaScript console for Chrome/Webkit
JavaScript
254
star
8

nodejs-mysql-native

Native mysql async client for node.js
JavaScript
239
star
9

react-x11

React renderer with X11 as a target
JavaScript
233
star
10

node-rfb2

rfb wire protocol client and server
JavaScript
135
star
11

crmux

Chrome developer tools remote protocol multiplexer.
JavaScript
123
star
12

ntk

node.js desktop UI toolkit
JavaScript
91
star
13

node-wrk

wrk load testing tool node wrapper
JavaScript
80
star
14

hot-module-replacement

Hot module replacement for node.js
JavaScript
56
star
15

pugify

jade transform for browserify v2. Sourcemaps generation included.
JavaScript
41
star
16

node-adbhost

node.js adb (android debug bridge) client
JavaScript
41
star
17

mysql-pg-proxy

mysql to postgres proxy server
JavaScript
34
star
18

yandex-translate

Yandex.Translate translation service client
JavaScript
31
star
19

osquery-node

node.js client for osquery
JavaScript
31
star
20

node-i3

i3-ipc node.js client
JavaScript
31
star
21

mysqlite.js

sqlite db server talking mysql protocol, all native js
JavaScript
30
star
22

node-vnc

Node.js vnc client with gui
JavaScript
15
star
23

mysql-co

mysql2 wrappers for "co"
JavaScript
15
star
24

ni

script to simplify node-inspector debugger workflow
JavaScript
14
star
25

mysql-osquery-proxy

mysql server proxying queries to facebook osquery daemon
JavaScript
14
star
26

node-shaper

Create through stream which limits speed to bytes per second/chunks per second
JavaScript
13
star
27

npdf

desktop pdf viewer using pdfium.js + node-x11
JavaScript
12
star
28

nierika

pixel based testing library with VNC as a driver
JavaScript
12
star
29

node-ptv

Public Transport Victoria API client for node.js
JavaScript
12
star
30

dbusfs

FUSE filesystem exposing dbus objects
JavaScript
11
star
31

rfbrecord

stream VNC connection to a video file
JavaScript
11
star
32

ansi-vnc

terminal vnc client
JavaScript
10
star
33

atom-vnc

VNC client for atom editor
CoffeeScript
9
star
34

node-pidgin

Pidgin node.js client using pidgin dbus api
JavaScript
7
star
35

react-show-in-atom

Navigate to line of code where react element is defined by clicking on it
JavaScript
6
star
36

node-skype-dbus

node.js SkypeAPI dbus client
JavaScript
6
star
37

node-cli-debugger

node.js command-line debugger
JavaScript
5
star
38

nodejs-memcached-native

Native async memcached client for node.js
5
star
39

exec-stream

create read-write stream from child process stdin/stdout
JavaScript
5
star
40

node-gday

dns-sd client (Avahi/dbus wrapper)
JavaScript
5
star
41

repl-co

node repl with yield support
JavaScript
5
star
42

v8-debugger-protocol

v8 debugger protocol client
JavaScript
5
star
43

node-skype

node.js SkypeAPI client
JavaScript
4
star
44

node-dbusmenu

node.js dbusmenu client
JavaScript
3
star
45

x11-xsettings

XSETTINGS binary format encoder/decoder
JavaScript
3
star
46

embed-source-map

Convert sourcemaps with external references to inlineable sourcemap
JavaScript
3
star
47

gaussian-convolution-kernel

calculate square matrix - gaussian blur convolution kernel
JavaScript
3
star
48

tfn

JavaScript
3
star
49

node-harfbuzz

node.js harfbuzz bindings
C++
3
star
50

node-resolve-cache

Cache and reuse results of node module file name resolution algorithm
JavaScript
3
star
51

_sidorares.github.com

personal tech blog
CSS
2
star
52

melbnodejs

Melbourne node.js meetup - proposals, links, website
2
star
53

xclimsg

send ewmh ClientMessage to x11 window from command line
JavaScript
2
star
54

australian-business-number

validate ABN
JavaScript
2
star
55

pr-linecommits

Chrome extension to help reviw "files" pane of github PR page
JavaScript
2
star
56

xml2jade

xml -> jade convertor
JavaScript
2
star
57

diamond

stdin + arguments composite stream (aka <> or diamond)
JavaScript
2
star
58

canvas-fontstyle

canvas fontStyle parser
JavaScript
1
star
59

netlify-test

HTML
1
star
60

Browserless

Dockerfile
1
star
61

node-streamagent

Connect http/websockets node.js client using arbitrary duplex stream
JavaScript
1
star
62

australian-tax-rate

return tax rate based on annual income
JavaScript
1
star
63

webpubsub-local

A drop in replacement for Azure webpubsub you can run locally
JavaScript
1
star
64

node-mssql

Node.js support for talking to microsoft sql server. [currently only connect is OK]
JavaScript
1
star
65

hackduino

arduino workshop examples
1
star
66

node-unpack

Pack and unpack binary data using pyhon-alike pack syntax
JavaScript
1
star
67

node-skype-applescript

skype applescript wrapper + repl
1
star
68

mfe-version-resolver

JavaScript
1
star
69

d3bench

benchmark app
JavaScript
1
star
70

logcomments

wrap every comments in JavaScript source to function call
JavaScript
1
star
71

android-xserver

This is a fork of Matt Kwan's android X server project
Java
1
star
72

http-nodejs

JavaScript
1
star
73

compare-energy-rates

graph cost of your electricyty based on your past usage and new rates
1
star
74

mysql-client-benchmarks

JavaScript
1
star
75

andreysidorov.com

HTML
1
star
76

argnames

print javascript function argument values together with names from function definition
JavaScript
1
star
77

generators-and-co

My presentation at MelbJS about generators & generator control flow libraries
JavaScript
1
star