JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 8874
  • Score
    100M100P100Q121855F
  • License MIT

JSON toolkit for JavaScript

Package Exports

  • json8
  • json8/lib/clone
  • json8/lib/equal
  • json8/lib/isJSON
  • json8/lib/type

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (json8) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

JSON8

build status

Introduction

JSON8 is a JavaScript library that makes working with JSON/data/structures safer and easier.

Features

See also

  • mole to work with Array/Map/Object/Set data structures.
  • JSON8 Patch for JSON diffing and patching
  • JSON8 Pointer for JSON Pointer (URL for JSON) implementation
  • JSON8 Merge Patch for simpler JSON object diffing/patching alternative to JSON Patch and Pointer

Getting started

npm install json8


var oo = require('json8');

or

<script src="node_modules/json8/JSON8.js"></script>
var oo = window.JSON8

Methods

oo.clone

Deep clone any value.

var doc = {"foo": "bar"}
var clone = oo.clone(doc) // {"foo":"bar"}
doc === copy        // false
oo.equal(doc, copy) // true

oo.clone(true) // true
oo.clone(42)   // 42
oo.clone(-0)   // -0

oo.equal

Test for equality between two documents.

oo.equal(true, true)     // true
oo.equal([], [])         // true
oo.equal({}, {})         // true
oo.equal(
  {foo: 'bar', bar: 'foo'}
  {bar: 'foo', foo: 'bar'}
)                        // true
oo.equal(new Set([1, 2]), new Set([1, 2])) // true
oo.equal(new Set([2, 1]), new Set([1, 2])) // false

oo.equal(new Set(), []) // true
oo.equal(new Map(), {}) // true

oo.equal([1, 2], [2, 1]) // false

oo.equal(-0, +0) // false

oo.type

Returns the JSON type for a value, undefined if the value is not of any JSON type.

oo.type({})        // 'object'
oo.type(new Map()) // 'object'
oo.type([])        // 'array'
oo.type(new Set()) // 'array'
oo.type(42)        // 'number'
oo.type('foo')     // 'string'
oo.type(null)      // 'null'
oo.type(true)      // 'boolean'

oo.type(undefined)      // undefined
oo.type(Infinity)       // undefined
oo.type(-Infinity)      // undefined
oo.type(NaN)            // undefined
oo.type(Symbol())       // undefined
oo.type(function() {})  // undefined

oo.is

For each type you can use the syntax

oo.is('foo', type)

or

oo.isType('foo')

Where type is any of:

structure

Returns true for arrays and objects, false otherwise.

oo.is({}, 'structure')    // true
oo.isStructure([])        // true
oo.isStructure(new Set()) // true
oo.isStructure(new Map()) // true

oo.isStructure(null)   // false

primitive

Returns true for primitives, false otherwise. Primitives are: number, boolean, null, string.

oo.is(null, 'primitive') // true
oo.isPrimitive(true)     // true
oo.isPrimitive('foo')    // true
oo.isPrimitive(42)       // true

oo.isPrimitive([]])      // false
oo.isPrimitive({})       // false
oo.isPrimitive(Infinity) // false
oo.isPrimitive(NaN)      // false

object

Returns true for object, false otherwise.

oo.is({}, 'object')        // true
oo.isObject({})            // true
oo.isObject(new Map())     // true

oo.isObject(null)          // false
oo.isObject([])            // false
oo.isObject(null)          // false
oo.isObject(function() {}) // false
oo.isObject(new Set())     // false

array

Returns true for array, false otherwise.

oo.is([], 'array')    // true
oo.isArray([])        // true
oo.isArray(new Set()) // true

oo.isArray({})        // false
oo.isArray(new Map()) // false

number

Returns true for number, false otherwise.

oo.is(42, 'number')    // true
oo.isNumber(4.2)       // true
oo.isNumber(-42)       // true

oo.isNumber(Infinity)  // false; Infinity is not valid JSON
oo.isNumber(-Infinity) // false; -Infinity is not valid JSON
oo.isNumber(NaN)       // false; NaN is not valid JSON

string

Returns true for string, false otherwise.

oo.is('foo', 'string') // true
oo.isString('☕')       // true
oo.isString('')        // true

oo.isString(42)        // false
oo.isString(undefined) // false
oo.isString(null)      // false

boolean

Returns true for boolean, false otherwise.

oo.is(true, 'boolean') // true
oo.isBoolean(false)    // true

oo.isBoolean(0)        // false
oo.isBoolean('foo')    // false

null

Returns true for null, false otherwise.

oo.is(null, 'null')  // true
oo.isNull(null)      // true

oo.isNull(undefined) // false

JSON

Returns true for any JSON valid value. JSON valid values are: number, boolean, null, string, array, object.

This method is not recursive, if you need to deep check for validity use the valid method.

oo.is(true, 'JSON')      //true
oo.isJSON('foo')         //true
oo.isJSON(null)          //true
oo.isJSON({})            //true
oo.isJSON([])            //true
oo.isJSON(42)            //true
oo.isJSON(new Map())     //true
oo.isJSON(new Set())     //true

oo.isJSON(undefined)     //false
oo.isJSON(NaN)           //false
oo.isJSON(Infinity)      //false
oo.isJSON(-Infinity)     //false
oo.isJSON(function() {}) //false

oo.valid

Recursive version of is JSON, works on primitive values as well.

oo.valid(true)                   //true
oo.valid({"foo": "bar"})         //true

oo.valid({"foo": undefined})     //false
oo.valid({"foo": NaN})           //false
oo.valid(["bar", function() {}]) //false

oo.serialize

Takes a JSON document and returns a parseable JSON string. Uses JSON.stringify underneath so it's still fast.

Differences with JSON.stringify

  • Throws a TypeError for any invalid JSON value encountered such as
    • undefined
    • Infinity
    • -Infinity
    • NaN
    • symbols
    • functions
  • Works with Map (serialized as JSON object)
  • Works with Set (serialized as JSON array)
  • Serializes signed zeros -0 as "-0" while JSON.stringify returns "0"
  • Options are provided as an object instead of arguments

Options

oo.serialize(doc[, options]);

oo.serialize({"foo": "bar"})
// {"foo":"bar"}

/*
 * Set serialization
 */
var set = new Set()
set.add('hello')
oo.serialize(set)
// ["hello"]

/*
 * Map serialization
 */
var map = new Map()
map.set('foo', 'bar')
oo.serialize(map)
// {"foo":"bar"}

/*
 * toJSON option
 */
oo.serialize(new Date())
// "2015-10-21T16:29:00.000Z"
oo.serialize(new Date(), {toJSON: false})
// {}

/*
 * space option
 */
var obj = {foo: 'bar'}
oo.serialize(obj)
// {"foo":"bar"}
oo.serialize(obj, {space: 2})
// {
//   "foo": "bar"
// }

oo.parse

Takes a JSON string and returns a JavaScript value.

var doc = oo.parse(string[, options]);

options.set to parse JSON arrays as Set (default false). options.map to parse JSON objects as Map (default false).

Motivations

Types

Getting/asserting the JSON type of a value in JavaScript is troublesome.

  • oo.type returns the JSON type of any value

  • oo.is checks if a value is of the provided type

  • oo.isStructure checks if a value is a JSON structure (an array or an object)

  • oo.isPrimitive checks if a value is a JSON primitive (null, boolean, string, number)

  • oo.isJSON checks if the value is a JSON valid value

Safety

oo.serialize will throw an exception for any non JSON valid value (undefined, NaN, Infinity, -Infinity, ...) instead of ignoring it or replacing it with null like JSON.striginfy does. It also accept an optional argument to disable toJSON behavior which is a common pitfall.

JSON8 types helps avoiding many common errors as well.

oo.equal performs a deep JSON equality comparaison

oo.valid performs a recursive JSON validation on any value

Map and Set

Map and Set are new structures available in ES6. Both are serializable and parseable as JSON, Map as object and Set as array. JSON8 was designed with that in mind and every single method supports Map and Set, a few examples:

  • isArray returns true for Set
  • isObject returns true for Map
  • valid, isStructure, isJSON return true for Map and Set
  • type returns 'array' for Set and 'object' for Map
  • serialize stringifies Set as array and Map as object
  • parse optionally parses arrays as Set and objects as Map

Comparaisons

// undefined is not JSON valid
JSON.stringify(undefined) // undefined
oo.serialize(undefined)   // TypeError

JSON.stringify({foo: undefined}) // '{}'
oo.serialize({foo: undefined})   // TypeError

JSON.stringify([undefined]) // '[null]'
oo.serialize([undefined])   // TypeError

// same applies for NaN, Infinity and -Infinity
typeof NaN   // 'number'
oo.type(NaN) // undefined

JSON.stringify(NaN)        // 'null'
JSON.stringify({foo: NaN}) // '{"foo":null}'
JSON.stringify([NaN])      // '[null]'
oo.serialize(NaN)          // TypeError

// typeof null returns 'object'
typeof null   // 'object'
oo.type(null) // 'null'

// arrays
var array = []
typeof []      // 'object'
oo.type(array) // 'array'
array[2] = 'foo'
array[1]              // undefined
array[0]              // undefined
JSON.stringify(array) // '[null,null,"foo"]'
oo.serialize(array)   // TypeError

// functions
JSON.stringify(function(){})        // undefined
JSON.stringify({foo: function(){}}) // '{}'
JSON.stringify([function(){}])      // '[null]'
oo.serialize(function() {})         // TypeError

// Set
var set = new Set()
typeof set   // 'object'
oo.type(set) // 'array'

set.add('foo')
JSON.stringify(set) // '{}'
oo.serialize(set)   // '["foo"]'

// Map
var map = new Map()
typeof map   // 'object'
oo.type(map) // 'object'

map.set('foo', 'bar')
JSON.stringify(map) // '{}'
oo.serialize(map)   // '{"foo": "bar"}'

// typeof Date returns 'object' but JSON.stringify returns a string
typeof new Date()                         // 'object'
JSON.stringify(new Date())                // '2015-10-21T16:29:00.000Z'
oo.type(new Date())                       // 'object'
oo.serialize(new Date(), {toJSON: false}) // '{}'
oo.serialize(new Date())                  // '2015-10-21T16:29:00.000Z'

// -0
-0 === 0           //  true
oo.equal(-0, 0)    //  false

JSON.parse("-0")   //  -0
JSON.stringify(-0) //  "0"

oo.parse("-0")     //  -0
oo.serialize(-0)   // "-0"

Tests

npm install -g mocha babel browserify
npm test

Contributing

See CONTRIBUTING.md