Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
next-json
Advanced tools
Readme
Next JavaScript Object Notation
Because JSON is awesome, but...
JSON is awesome mainly for two reasons:
... but it has some limitations:
undefined
values,BigInt
numbers,This package is intended to offer something as great as JSON... trying to add something more.
undefined
-0
, NaN
and Infinity
BigInt
Date
Error
(with exception)Map
RegExp
Set
TypedArray
sURL
This doesn't mean it's 100% compliant: due its higher number of supported features the result string of the
serialization through NJSON.stringify
may differs from the result of the serialization through JSON.stringify
.
On the other hand, the result of the deserialization of a valid JSON encoded string through NJSON.parse
will
produce a value deep equal to the value produced by JSON.parse
and the reviver
function will be called the same
amount of times, with the same parameters and in the same order.
Taken the result of a JSON.parse
call (i.e. a value which contains only valid JSON values), if serialized through
JSON.stringify
or NJSON.stringify
produces two equal strings and the replacer
function will be called the same
amount of times, with the same parameters and in the same order.
NJSON offers its own parser which means it doesn't use eval
with its related security hole.
Even if the NJSON serialized string is JavaScript compliant, NJSON.parse
is not able to parse any JavaScript
code, but only the subset produced by NJSON.stringify
(otherwise it would have been another eval
implementation).
NJSON do not supports some Object
s by design; when one of them is encountered during the serialization process
NJSON
tries to act as JSON
does. Nonetheless they take part in the repeated references algorithm anyway. Follow
the details.
ArrayBuffer
s can't be manipulated by JavaScript design: they are serialized as empty objects as JSON
does.
NJSON is designed to serialize / deserialize complex data to be shared between different systems, possibly written with other languages than JavaScript (once implementations in other languages will be written). Even if JavaScript can see a function as a piece of data, it is actually code, not data. More than this, for other languages, may be a complex problem execute JavaScript functions.
Last but not least, allowing the deserialization of a function would open once again the security hole implied by the
use of eval
, and one of the reasons why NJSON was born, is exactly to avoid that security hole.
A Symbol
is something strictly bound to the JavaScript execution environment which instantiate it: sharing it between
distinct systems is something almost meaningless.
Note: except for Int8Array
, Uint8Array
and Uint8ClampedArray
, TypedArray
s are platform dependant: they are
supported, but trying to transfer one of them between different architectures may be source of unexpected problems.
Error
exceptionError
's are special objects. By specifications the properties cause
, message
, name
and stack
are not
enumerable, NJSON serializes them as any other property. This, plus the nature of the stack
property, originates
the Error
exception to the rule that an NJSON encoded string produces exactly the same value if parsed or
evaluated.
cause
:
NJSON.parse
the result is a not enumerable property;eval
the result may be an enumerable or a not enumerable property depending on the running
JavaScript engine;stack
:
if absent:
NJSON.parse
the result is a not enumerable property with value a pseudo-stack;eval
the result is the standard stack
property for the running JavaScript engine;if present:
NJSON.parse
the result is a not enumerable property;eval
the result may be an enumerable or a not enumerable property depending on the running
JavaScript engine;The only option in my mind to avoid this exception is the use of Object.defineProperties
, but it would increase both
the complexity of the parser and the size of the produced serialized string. Maybe in the future... configurable
through an option... if this can't be really tolerated.
With npm:
npm install --save next-json
import { NJSON } from "next-json";
const serialized = NJSON.stringify({ some: "value" });
const deserialized = NJSON.parse(serialized);
import { NJSON, NjsonParseOptions, NjsonStringifyOptions } from "next-json";
const serialized = NJSON.stringify({ some: "value" });
const deserialized = NJSON.parse<{ some: string }>(serialized);
const obj = { test: Infinity };
const set = new Set();
const arr = [NaN, obj, set];
set.add(obj);
set.add(arr);
arr.push(arr);
console.log(NJSON.stringify(arr));
// ((A,B)=>{B.push(A,new Set([A,B]),B);return B})({"test":Infinity},[NaN])
import express from "express";
import { expressNJSON } from "next-json";
const app = express();
app.use(expressNJSON()); // install the polyfill
app.all("/mirror", (req, res) => res.njson(req.body)); // there is an 'n' more than usual
app.listen(3000);
import { NJSON, fetchNJSON } from "next-json";
fetchNJSON(); // install the polyfill
const payload = { infinity: Infinity };
payload.circular = payload;
const response = await fetch("http://localhost:3000/mirror", {
body: NJSON.stringify(payload), // there is an 'N' more than usual
headers: { "Content-Type": "application/njson" }, // there is an 'n' more than usual
method: "POST"
});
const body = await response.njson({}); // there is an 'n' more than usual
Here payload
deep equals payload.circular
, which deep equals body
, which deep equals body.circular
, which deep
equals req.body
in server side, which deep equals req.body.circular
in server side! 🎉
The MIME type for NJSON format is: application/njson
.
Just for compatibility with JSON.parse
. Alias for:
NJSON.parse(text, { reviver });
Converts a Next JavaScript Object Notation (NJSON) string into an object.
text
: <string> The text
to deserialize.options
: <NjsonParseOptions> Deserialization options.text
.Just for compatibility with JSON.stringify
. Alias for:
NJSON.stringify(value, { replacer, space });
Converts a JavaScript value to a Next JavaScript Object Notation (NJSON) string.
value
: <unknown> The value to
serialize.options
: <NjsonStringifyOptions> Serialization options.value
.numberKey
:
<boolean>
Alters the type of the key
argument for reviver
. Default: false
.reviver
:
<Function> Alters the
behavior of the deserialization process. Default: null
.If true
, the reviver
function, for Array
elements, will be called with the key
argument in a Number
form.
As the
reviver
parameter of JSON.parse
. See also replacer / reviver for NJSON specific details.
date
:
<string>
Specifies Date
s conversion method. Default: "time"
.numberKey
:
<boolean>
Alters the type of the key
argument for replacer
. Default: false
.omitStack
:
<boolean>
Specifies if to stringify stack
for Error
s. Default: false
.replacer
:
<Function> |
<Array> | null
Alters
the behavior of the serialization process. Default: null
.sortKeys
:
<boolean>
Specifies whether to sort Object
keys. Default: false
.space
:
<number> |
<string> | null
Specifies
the indentation. Default: null
.stringLength
:
<number> | null
Makes
String
s to be treated as references. Default: null
.undef
:
<boolean>
Specifies the undefined
behavior. Default: true
.Specifies the method of Date
objects used to serialize them. Follows the list of the allowed values and the relative
method used.
"iso"
: Date.toISOString()
"string"
: Date.toString()
"time"
: Date.getTime()
- the default"utc"
: Date.toUTCString()
If true
, the replacer
function, for Array
elements, will be called with the key
argument in a Number
form.
For default NJSON.stringify
serializes the stack
property for Error
s. If set to true
, the property is omitted
from the serialized representation.
As the
replacer
parameter of JSON.serialize
. See also replacer / reviver for NJSON specific details.
For default NJSON stringifies (and replaces as well) Object
keys in the order they appear in the Object
itself.
If set to true
, Object
keys are sorted alphabetically before both the processes. This can be useful to compare two
references: using this option, the stringified representation of two deep equal references are two equal strings.
As the
space
parameter of JSON.serialize
.
If specified, String
s which length
is greater or equal to the specified value take part in the repeated references
algorithm.
For default NJSON.stringify
serializes undefined
values as well. If set to false
, undefined
values are
treated as JSON.stringify
does.
An Express middleware which works as NJSON body parser and installs the
Express.Response.njson
method.
options
: <NjsonStringifyOptions> NJSON Express middleware options.parse
: <NjsonParseOptions> The options
passed to
NJSON.parse
by the middleware to parse the request body.stringify
: <NjsonStringifyOptions> The
default options
passed to NJSON.stringify
by
Express.Response.njson
to serialize the response body.The options
passed to NJSON.parse
by the middleware to parse the request body.
The default options
passed to NJSON.stringify
by
Express.Response.njson
to serialize the response.
Encodes the body in NJSON format and sends it; sets the proper Content-Type
header as well. Installed by
expressNJSON
.
body
: <unknown> The body to be sent
serialized.options
: <NjsonStringifyOptions> The options
passed to
NJSON.stringify
to serialize the response body; overrides the default
options.stringify
passed to expressNJSON
.Installs the Response.njson
method.
options
: <NjsonParseOptions> The default options
passed to NJSON.parse
by Response.njson
to parse the response
body.Parses the response body with NJSON.parse
. Installed by
fetchNJSON
.
options
: <NjsonParseOptions> The options
passed to
NJSON.parse
to parse the response body; overrides the default options
passed to
fetchNJSON
.NJSON.parse
.Even if Date
, RegExp
, TypedArray
s and URL
are Object
s, they are treated as native values i.e. replacer
and
reviver
will be never called with one of them as this
context.
For Array
s the key
argument is a positive integer, but in a String
form for JSON
compatibility. This can be
altered (i.e. in a Number
form) through the numberKey
option.
Map
's keys can be Function
s and Symbol
s; for Map
s the key
argument is a positive integer in a Number
form
and the value
argument is the entry in the form [mapKey, mapValue]
. This gives a way to replace/revive keys
which can't be serialized. If replacer
or reviver
do not return a two elements array, the value is omitted.
For Set
s the key
argument is a positive integer and it is passed in a Number
form.
Unlike JSON
, NJSON
does not call replacer
and reviver
for each element.
Except for Int8Array
, Uint8Array
and Uint8ClampedArray
, TypedArray
s are platform dependant: trying to transfer
one of them between different architectures may be source of unexpected problems.
Regardless of whether they are omitted, serialized as native values or not, every Object
s (but null
), Function
s
and Symbol
s take part in the repeated references algorithm; long String
s can take part as well (refer to
NjsonStringifyOptions.stringLength
for details).
When a repeated reference is encountered, replacer
and reviver
are called against the reference, but it is not
called recursively against its properties. If a property of a repeated reference is changed, the same change has effect
in all other occurrences of the same reference.
Circular references are simply special cases of repeated references.
Requires Node.js v14.
Exception: fetchNJSON
requires Node.js v18.
The package is tested under all Node.js versions currently supported accordingly to Node.js Release.
TypeScript types are distributed with the package itself.
Do not hesitate to report any bug or inconsistency @github.
If you find useful this package, please consider the opportunity to donate on one of following cryptos:
ADA: DdzFFzCqrhsxfKAujiyG5cv3Bz7wt5uahr9k3hEa8M6LSYQMu9bqc25mG72CBZS3vJEWtWj9PKDUVtfBFcq5hAtDYsZxfG55sCcBeHM9
BTC: 3BqXRqgCU2CWEoZUgrjU3b6VTR26Hee5gq
ETH: 0x8039fD67b895fAA1F3e0cF539b8F0290EDe1C042
Other projects which aim to solve similar problems:
FAQs
Next JavaScript Object Notation
The npm package next-json receives a total of 2,325 weekly downloads. As such, next-json popularity was classified as popular.
We found that next-json demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.