diff --git a/.eslintrc.yml b/.eslintrc.yml index 50d2991..15db3d0 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,3 +1,5 @@ +parserOptions: + ecmaVersion: 6 extends: eslint:recommended env: node: true @@ -7,7 +9,7 @@ rules: no-shadow: 1 block-scoped-var: 2 callback-return: 2 - complexity: [2, 13] + complexity: [2, 15] curly: [2, multi-or-nest, consistent] dot-location: [2, property] dot-notation: 2 @@ -27,3 +29,5 @@ rules: valid-jsdoc: [2, requireReturn: false] globals: BigInt: false + Map: true + Set: true diff --git a/README.md b/README.md index f5bfdef..1edd150 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # json-source-map Parse/stringify JSON and provide source-map for JSON-pointers to all nodes. -NEW: BigInt support. +NEW: supports BigInt, Maps, Sets and Typed arrays. [![Build Status](https://travis-ci.org/epoberezkin/json-source-map.svg?branch=master)](https://travis-ci.org/epoberezkin/json-source-map) [![npm version](https://badge.fury.io/js/json-source-map.svg)](https://www.npmjs.com/package/json-source-map) @@ -131,6 +131,7 @@ Comparison with the standard `JSON.stringify`: Options: - _space_: same as `space` parameter. +- _es6_: stringify ES6 Maps, Sets and Typed arrays (as JSON arrays). ## License diff --git a/index.js b/index.js index 5069ccc..983691c 100644 --- a/index.js +++ b/index.js @@ -279,6 +279,7 @@ exports.stringify = function (data, _, options) { var line = 0; var column = 0; var pos = 0; + var es6 = options && options.es6 && typeof Map == 'function'; _stringify(data, 0, ''); return { json: json, @@ -295,14 +296,24 @@ exports.stringify = function (data, _, options) { case 'string': out(quoted(_data)); break; case 'object': - if (_data === null) + if (_data === null) { out('null'); - else if (typeof _data.toJSON == 'function') + } else if (typeof _data.toJSON == 'function') { out(quoted(_data.toJSON())); - else if (Array.isArray(_data)) + } else if (Array.isArray(_data)) { stringifyArray(); - else + } else if (es6) { + if (_data.constructor.BYTES_PER_ELEMENT) + stringifyArray(); + else if (_data instanceof Map) + stringifyMapSet(); + else if (_data instanceof Set) + stringifyMapSet(true); + else + stringifyObject(); + } else { stringifyObject(); + } } map(ptr, 'valueEnd'); @@ -350,6 +361,34 @@ exports.stringify = function (data, _, options) { out('{}'); } } + + function stringifyMapSet(isSet) { + if (_data.size) { + out('{'); + var propLvl = lvl + 1; + var first = true; + for (var item of _data.entries()) { + var key = item[0]; + var value = isSet ? true : item[1]; + if (validType(value)) { + if (!first) out(','); + first = false; + var propPtr = ptr + '/' + escapeJsonPointer(key); + indent(propLvl); + map(propPtr, 'key'); + out(quoted(key)); + map(propPtr, 'keyEnd'); + out(':'); + if (whitespace) out(' '); + _stringify(value, propLvl, propPtr); + } + } + indent(lvl); + out('}'); + } else { + out('{}'); + } + } } function out(str) { diff --git a/spec/.eslintrc.yml b/spec/.eslintrc.yml index ecd2fff..a9bab7e 100644 --- a/spec/.eslintrc.yml +++ b/spec/.eslintrc.yml @@ -1,5 +1,3 @@ -parserOptions: - ecmaVersion: 6 rules: no-console: 0 quotes: 0 @@ -7,3 +5,4 @@ globals: describe: false it: false Symbol: false + Int8Array: false diff --git a/spec/index.js b/spec/index.js index 1b693cf..f254f4e 100644 --- a/spec/index.js +++ b/spec/index.js @@ -618,14 +618,51 @@ describe('stringify', function() { assert.equal(result.json, '{\n "foo": "bar"\n}'); }); + describe('option es6', function() { + it('should strigify Maps', function() { + var data = new Map; + testStringify(data, {}, false, {es6: true}); + + data.set('foo', 1); + data.set('bar', 2); + testStringify(data, {foo: 1, bar: 2}, false, {es6: true}); + testStringify(data, {foo: 1, bar: 2}, false, {es6: true, space: 2}); + }); + + it('should strigify Sets', function() { + var data = new Set; + testStringify(data, {}, false, {es6: true}); + + data.add('foo'); + data.add('bar'); + testStringify(data, {foo: true, bar: true}, false, {es6: true}); + testStringify(data, {foo: true, bar: true}, false, {es6: true, space: 2}); + }); + + it('should strigify Typed arrays', function() { + var data = new Int8Array(2); + testStringify(data, [0, 0], false, {es6: true}); + + data[0] = 1; + data[1] = 2; + testStringify(data, [1, 2], false, {es6: true}); + testStringify(data, [1, 2], false, {es6: true, space: 2}); + }); + + it('should still strigify Objects', function() { + testStringify({}, {}, false, {es6: true}); + testStringify({foo: 1, bar: 2}, {foo: 1, bar: 2}, false, {es6: true}); + }); + }); + function equal(objects) { for (var i=1; i