json-bigint-extend 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Andrey Sidorov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,240 @@
1
+ # json-bigint
2
+
3
+ [![Build Status](https://secure.travis-ci.org/sidorares/json-bigint.png)](http://travis-ci.org/sidorares/json-bigint)
4
+ [![NPM](https://nodei.co/npm/json-bigint.png?downloads=true&stars=true)](https://nodei.co/npm/json-bigint/)
5
+
6
+ JSON.parse/stringify with bigints support. Based on Douglas Crockford [JSON.js](https://github.com/douglascrockford/JSON-js) package and [bignumber.js](https://github.com/MikeMcl/bignumber.js) library.
7
+
8
+ 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.
9
+
10
+ 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 }`
11
+
12
+ ==========
13
+
14
+ example:
15
+
16
+ ```js
17
+ var JSONbig = require('json-bigint');
18
+
19
+ var json = '{ "value" : 9223372036854775807, "v2": 123 }';
20
+ console.log('Input:', json);
21
+ console.log('');
22
+
23
+ console.log('node.js built-in JSON:');
24
+ var r = JSON.parse(json);
25
+ console.log('JSON.parse(input).value : ', r.value.toString());
26
+ console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));
27
+
28
+ console.log('\n\nbig number JSON:');
29
+ var r1 = JSONbig.parse(json);
30
+ console.log('JSONbig.parse(input).value : ', r1.value.toString());
31
+ console.log('JSONbig.stringify(JSONbig.parse(input)):', JSONbig.stringify(r1));
32
+ ```
33
+
34
+ Output:
35
+
36
+ ```
37
+ Input: { "value" : 9223372036854775807, "v2": 123 }
38
+
39
+ node.js built-in JSON:
40
+ JSON.parse(input).value : 9223372036854776000
41
+ JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}
42
+
43
+
44
+ big number JSON:
45
+ JSONbig.parse(input).value : 9223372036854775807
46
+ JSONbig.stringify(JSONbig.parse(input)): {"value":9223372036854775807,"v2":123}
47
+ ```
48
+
49
+ ### Options
50
+
51
+ The behaviour of the parser is somewhat configurable through 'options'
52
+
53
+ #### options.strict, boolean, default false
54
+
55
+ Specifies the parsing should be "strict" towards reporting duplicate-keys in the parsed string.
56
+ 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.
57
+
58
+ Setting options.strict = true will fail-fast on such duplicate-key occurances and thus warn you upfront of possible lost information.
59
+
60
+ example:
61
+
62
+ ```js
63
+ var JSONbig = require('json-bigint');
64
+ var JSONstrict = require('json-bigint')({ strict: true });
65
+
66
+ var dupkeys = '{ "dupkey": "value 1", "dupkey": "value 2"}';
67
+ console.log('\n\nDuplicate Key test with both lenient and strict JSON parsing');
68
+ console.log('Input:', dupkeys);
69
+ var works = JSONbig.parse(dupkeys);
70
+ console.log('JSON.parse(dupkeys).dupkey: %s', works.dupkey);
71
+ var fails = 'will stay like this';
72
+ try {
73
+ fails = JSONstrict.parse(dupkeys);
74
+ console.log('ERROR!! Should never get here');
75
+ } catch (e) {
76
+ console.log(
77
+ 'Succesfully catched expected exception on duplicate keys: %j',
78
+ e
79
+ );
80
+ }
81
+ ```
82
+
83
+ Output
84
+
85
+ ```
86
+ Duplicate Key test with big number JSON
87
+ Input: { "dupkey": "value 1", "dupkey": "value 2"}
88
+ JSON.parse(dupkeys).dupkey: value 2
89
+ Succesfully catched expected exception on duplicate keys: {"name":"SyntaxError","message":"Duplicate key \"dupkey\"","at":33,"text":"{ \"dupkey\": \"value 1\", \"dupkey\": \"value 2\"}"}
90
+
91
+ ```
92
+
93
+ #### options.storeAsString, boolean, default false
94
+
95
+ Specifies if BigInts should be stored in the object as a string, rather than the default BigNumber.
96
+
97
+ 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).
98
+
99
+ example:
100
+
101
+ ```js
102
+ var JSONbig = require('json-bigint');
103
+ var JSONbigString = require('json-bigint')({ storeAsString: true });
104
+ var key = '{ "key": 1234567890123456789 }';
105
+ console.log('\n\nStoring the BigInt as a string, instead of a BigNumber');
106
+ console.log('Input:', key);
107
+ var withInt = JSONbig.parse(key);
108
+ var withString = JSONbigString.parse(key);
109
+ console.log(
110
+ 'Default type: %s, With option type: %s',
111
+ typeof withInt.key,
112
+ typeof withString.key
113
+ );
114
+ ```
115
+
116
+ Output
117
+
118
+ ```
119
+ Storing the BigInt as a string, instead of a BigNumber
120
+ Input: { "key": 1234567890123456789 }
121
+ Default type: object, With option type: string
122
+
123
+ ```
124
+
125
+ #### options.useNativeBigInt, boolean, default false
126
+
127
+ Specifies if parser uses native BigInt instead of bignumber.js
128
+
129
+ example:
130
+
131
+ ```js
132
+ var JSONbig = require('json-bigint');
133
+ var JSONbigNative = require('json-bigint')({ useNativeBigInt: true });
134
+ var key = '{ "key": 993143214321423154315154321 }';
135
+ console.log(`\n\nStoring the Number as native BigInt, instead of a BigNumber`);
136
+ console.log('Input:', key);
137
+ var normal = JSONbig.parse(key);
138
+ var nativeBigInt = JSONbigNative.parse(key);
139
+ console.log(
140
+ 'Default type: %s, With option type: %s',
141
+ typeof normal.key,
142
+ typeof nativeBigInt.key
143
+ );
144
+ ```
145
+
146
+ Output
147
+
148
+ ```
149
+ Storing the Number as native BigInt, instead of a BigNumber
150
+ Input: { "key": 993143214321423154315154321 }
151
+ Default type: object, With option type: bigint
152
+
153
+ ```
154
+
155
+ #### options.alwaysParseAsBig, boolean, default false
156
+
157
+ Specifies if all numbers should be stored as BigNumber.
158
+
159
+ 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)
160
+
161
+ example:
162
+
163
+ ```js
164
+ var JSONbig = require('json-bigint');
165
+ var JSONbigAlways = require('json-bigint')({ alwaysParseAsBig: true });
166
+ var key = '{ "key": 123 }'; // there is no need for BigNumber by default, but we're forcing it
167
+ console.log(`\n\nStoring the Number as a BigNumber, instead of a Number`);
168
+ console.log('Input:', key);
169
+ var normal = JSONbig.parse(key);
170
+ var always = JSONbigAlways.parse(key);
171
+ console.log(
172
+ 'Default type: %s, With option type: %s',
173
+ typeof normal.key,
174
+ typeof always.key
175
+ );
176
+ ```
177
+
178
+ Output
179
+
180
+ ```
181
+ Storing the Number as a BigNumber, instead of a Number
182
+ Input: { "key": 123 }
183
+ Default type: number, With option type: object
184
+
185
+ ```
186
+
187
+ If you want to force all numbers to be parsed as native `BigInt`
188
+ (you probably do! Otherwise any calulations become a real headache):
189
+
190
+ ```js
191
+ var JSONbig = require('json-bigint')({
192
+ alwaysParseAsBig: true,
193
+ useNativeBigInt: true,
194
+ });
195
+ ```
196
+
197
+ #### options.protoAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"
198
+
199
+ #### options.constructorAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"
200
+
201
+ Controls how `__proto__` and `constructor` properties are treated. If set to "error" they are not allowed and
202
+ parse() call will throw an error. If set to "ignore" the prroperty and it;s value is skipped from parsing and object building.
203
+ If set to "preserve" the `__proto__` property is set. One should be extra careful and make sure any other library consuming generated data
204
+ is not vulnerable to prototype poisoning attacks.
205
+
206
+ example:
207
+
208
+ ```js
209
+ var JSONbigAlways = require('json-bigint')({ protoAction: 'ignore' });
210
+ const user = JSONbig.parse('{ "__proto__": { "admin": true }, "id": 12345 }');
211
+ // => result is { id: 12345 }
212
+ ```
213
+
214
+ ### Links:
215
+
216
+ - [RFC4627: The application/json Media Type for JavaScript Object Notation (JSON)](http://www.ietf.org/rfc/rfc4627.txt)
217
+ - [Re: \[Json\] Limitations on number size?](http://www.ietf.org/mail-archive/web/json/current/msg00297.html)
218
+ - [Is there any proper way to parse JSON with large numbers? (long, bigint, int64)](http://stackoverflow.com/questions/18755125/node-js-is-there-any-proper-way-to-parse-json-with-large-numbers-long-bigint)
219
+ - [What is JavaScript's Max Int? What's the highest Integer value a Number can go to without losing precision?](http://stackoverflow.com/questions/307179/what-is-javascripts-max-int-whats-the-highest-integer-value-a-number-can-go-t)
220
+ - [Large numbers erroneously rounded in Javascript](http://stackoverflow.com/questions/1379934/large-numbers-erroneously-rounded-in-javascript)
221
+
222
+ ### Note on native BigInt support
223
+
224
+ #### Stringifying
225
+
226
+ Full support out-of-the-box, stringifies BigInts as pure numbers (no quotes, no `n`)
227
+
228
+ #### Limitations
229
+
230
+ - Roundtrip operations
231
+
232
+ `s === JSONbig.stringify(JSONbig.parse(s))` but
233
+
234
+ `o !== JSONbig.parse(JSONbig.stringify(o))`
235
+
236
+ when `o` has a value with something like `123n`.
237
+
238
+ `JSONbig` stringify `123n` as `123`, which becomes `number` (aka `123` not `123n`) by default when being reparsed.
239
+
240
+ 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.