json.sortify
Advanced tools
Comparing version
53
index.js
@@ -1,52 +0,1 @@ | ||
/*! | ||
* Copyright 2015 Thomas Rosenau | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
JSON.sortify = JSON.sortify || (function (jsonStringify) { | ||
var sortKeys = function (o) { | ||
// {b:1,a:2} -> {a:2,b:1} | ||
if (Object.prototype.toString.call(o) === '[object Object]') { | ||
// make use of the fact that all JS engines sort an object's keys chronologically when stringifying | ||
// with the exception of v8, which always puts numeric keys first | ||
var numeric = []; | ||
var nonNumeric = []; | ||
Object.keys(o).forEach(function (key) { | ||
if (/^(0|[1-9][0-9]*)$/.test(key)) { | ||
numeric.push(+key); | ||
} else { | ||
nonNumeric.push(key); | ||
} | ||
}); | ||
return numeric.sort().concat(nonNumeric.sort()).reduce(function (result, key) { | ||
result[key] = sortKeys(o[key]); | ||
return result; | ||
}, {}); | ||
} else if (Array.isArray(o)) { | ||
return o.map(sortKeys); | ||
} | ||
return o; | ||
}; | ||
return function (value, replacer, space) { | ||
// replacer, toJSON(), cyclic references and other stuff is better handled by native stringifier | ||
var native = jsonStringify(value, replacer, 0); | ||
if (!native || native[0] !== '{' && native[0] !== '[') { // if value is not an Object or Array | ||
return native; | ||
} | ||
var cleanObj = JSON.parse(native); | ||
return jsonStringify(sortKeys(cleanObj), null, space); | ||
}; | ||
})(JSON.stringify.bind(JSON)); | ||
module.exports = require('./lib'); |
{ | ||
"name": "json.sortify", | ||
"description": "A deterministic version of JSON.stringify that sorts object keys alphabetically.", | ||
"version": "1.0.2", | ||
"author": { | ||
"name" : "Thomas Rosenau", | ||
"email" : "thomasr@fantasymail.de", | ||
"url" : "http://thomas-rosenau.de/" | ||
}, | ||
"keywords": [ | ||
"JSON", | ||
"stringify", | ||
"sort" | ||
], | ||
"homepage": "https://github.com/ThomasR/JSON.sortify", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/ThomasR/JSON.sortify" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/ThomasR/JSON.sortify/issues" | ||
}, | ||
"license": "Apache-2.0", | ||
"main": "index.js", | ||
"devDependencies": { | ||
"istanbul": "^0.3.17", | ||
"mocha": "^2.2.5", | ||
"should": "^7.0.2" | ||
}, | ||
"scripts": { | ||
"test": "mocha --check-leaks --bail --reporter spec test/", | ||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/", | ||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec test/" | ||
} | ||
"name": "json.sortify", | ||
"description": "A deterministic version of JSON.stringify that sorts object keys alphabetically.", | ||
"version": "2.0.0", | ||
"engines": { | ||
"node": ">=0.10.0" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
"es2015" | ||
] | ||
}, | ||
"author": { | ||
"name": "Thomas Rosenau", | ||
"email": "thomasr@fantasymail.de", | ||
"url": "http://thomas-rosenau.de/" | ||
}, | ||
"keywords": [ | ||
"JSON", | ||
"deterministic", | ||
"stringify", | ||
"sort", | ||
"hash" | ||
], | ||
"homepage": "https://github.com/ThomasR/JSON.sortify", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/ThomasR/JSON.sortify" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/ThomasR/JSON.sortify/issues" | ||
}, | ||
"license": "Apache-2.0", | ||
"main": "index.js", | ||
"devDependencies": { | ||
"babel-core": "^6.7.2", | ||
"babel-preset-es2015": "^6.6.0", | ||
"istanbul": "^0.3.17", | ||
"mocha": "^2.2.5", | ||
"should": "^7.0.2" | ||
}, | ||
"scripts": { | ||
"prepublish": "node build/build.js", | ||
"test": "mocha --check-leaks --bail --reporter spec test/", | ||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/", | ||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec test/" | ||
} | ||
} |
108
README.md
JSON.sortify | ||
===== | ||
<!-- [](https://codeclimate.com/github/ThomasR/JSON.sortify) --> | ||
[](https://www.npmjs.com/package/json.sortify) | ||
[](https://travis-ci.org/ThomasR/JSON.sortify) | ||
[](https://codeclimate.com/github/ThomasR/JSON.sortify/coverage) | ||
[](https://codeclimate.com/github/ThomasR/JSON.sortify/code) | ||
A deterministic version of `JSON.stringify` that sorts object keys alphabetically. | ||
@@ -10,4 +12,5 @@ | ||
## Install | ||
## Install as an NPM module | ||
```bash | ||
@@ -17,21 +20,74 @@ $ npm install json.sortify | ||
## Usage | ||
### Usage | ||
```JavaScript | ||
let jsonSortify = require('json.sortify'); | ||
``` | ||
require('json.sortify'); // will inject the JSON.sortify() function | ||
or | ||
```JavaScript | ||
JSON.sortify = require('json.sortify'); | ||
``` | ||
or even | ||
```JavaScript | ||
JSON.stringify = require('json.sortify'); | ||
``` | ||
`JSON.sortify` can be used exactly like `JSON.stringify` | ||
JSON.sortify is fully compatible with JSON.stringify, so you can overwrite the native implementation without any problems. | ||
```js | ||
// basic: | ||
JSON.sortify({a:1,b:2}); /* | ||
## In HTML | ||
Download [dist/JSON.sortify.js](JSON.sortify.js) and save it to your server. | ||
```html | ||
<script src="JSON.sortify.js"></script> <!-- will inject the JSON.sortify() function --> | ||
``` | ||
`JSON.sortify` can be used exactly like `JSON.stringify`. As mentioned above, you can overwrite JSON.stringify if you want to: | ||
```html | ||
<script src="JSON.sortify"></script> | ||
<script>JSON.stringify = JSON.sortify</script> | ||
``` | ||
### AMD module | ||
You can also use JSON.sortify as an AMD module: | ||
```JavaScript | ||
JSON.stringify = require('json.sortify'); | ||
``` | ||
## How to use | ||
Use `JSON.sortify` exactly like `JSON.stringify`. Refer to [MDN:JSON/stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) for details. | ||
### Basic | ||
```JavaScript | ||
JSON.sortify({a:1,b:2}); | ||
``` | ||
```Text | ||
{"a":1,"b":2} | ||
``` | ||
sorting: */ | ||
JSON.sortify({b:1,a:2}); /* | ||
{"a":2,"b":1} | ||
indentation: */ | ||
JSON.sortify({b:1,a:2}, null, 2); /* | ||
### Sorting | ||
```JavaScript | ||
JSON.sortify({b:1,a:2,c:3,5:4}); | ||
``` | ||
```Text | ||
{"5":4,"a":2,"b":1,"c":3} | ||
``` | ||
### Indentation: | ||
```JavaScript | ||
JSON.sortify({b:1,a:2}, null, 2); | ||
``` | ||
```Text | ||
{ | ||
@@ -41,5 +97,11 @@ "a": 2, | ||
} | ||
``` | ||
key whitelist: */ | ||
JSON.sortify({b:1,foo:2,a:3}, ['a', 'foo'], 4); /* | ||
### Whitelisting of object keys: | ||
```JavaScript | ||
JSON.sortify({b:1,foo:2,a:3}, ['a', 'foo'], 4); | ||
``` | ||
```Text | ||
{ | ||
@@ -49,7 +111,13 @@ "a": 3, | ||
} | ||
``` | ||
replacer function: */ | ||
### Replacer Function: | ||
```JavaScript | ||
JSON.sortify({b:1,foo:'woot',a:3}, function (key, value) { | ||
return typeof value == 'string' ? value + '!!!' : value; | ||
}, '\t'); /* | ||
}, '\t'); | ||
``` | ||
```Text | ||
{ | ||
@@ -60,7 +128,5 @@ "a": 3, | ||
} | ||
*/ | ||
``` | ||
## License | ||
[Apache-2.0](LICENSE) | ||
[](LICENSE) |
@@ -1,2 +0,2 @@ | ||
require('../'); | ||
JSON.sortify = require('../'); | ||
var assert = require('assert'); | ||
@@ -7,8 +7,12 @@ var should = require('should'); | ||
describe('interface', function () { | ||
it('should define JSON.sortify', function () { | ||
it('should define a function', function () { | ||
JSON.sortify.should.be.a.function; | ||
}); | ||
it('should take precisely three arguments', function () { | ||
assert.equal(JSON.sortify.length, 3); | ||
}); | ||
}); | ||
describe('functionality', function () { | ||
describe('compatibility', function () { | ||
it('should stringify simple values', function () { | ||
@@ -19,2 +23,3 @@ var fixtures = [ | ||
Infinity, | ||
NaN, | ||
null, | ||
@@ -29,2 +34,5 @@ true, | ||
]; | ||
if (typeof global.Symbol !== 'undefined') { | ||
fixtures.push(Symbol()); | ||
} | ||
fixtures.forEach(function (fixture) { | ||
@@ -40,3 +48,4 @@ assert.equal(JSON.sortify(fixture), JSON.stringify(fixture)); | ||
{a:.1, b:undefined, c:function () {}}, '{"a":0.1}', | ||
{' ': '"', 'null': 'null', 'undefined': '\t'} | ||
{' ': '"', 'null': 'null', 'undefined': '\t'}, | ||
{'"\n\t\\:': ''} | ||
]; | ||
@@ -70,5 +79,6 @@ fixtures.forEach(function (fixture) { | ||
var fixtures = [ | ||
{toJSON: function () { return 'Banana!';}}, | ||
{a: 1, b:2, toJSON: function () { return null;}}, | ||
{a: {b:1, toJSON: function () { return 'x';}}, c:3} | ||
{toJSON:function () { return 'Banana!'; }}, | ||
{a: 1, b:2, toJSON:function () { return null; }}, | ||
{a: {b:1, toJSON:function () { return 'x'; }}, c:3}, | ||
{a: {b:1, toJSON:function (key) { return 'x' + key + 'y'; }}} | ||
]; | ||
@@ -102,3 +112,3 @@ fixtures.forEach(function (fixture) { | ||
[{a:{b:2, c:[{d:3}, 4, 'hello']}}, '\t'], | ||
[{a:{b:2, c:[{d:3}, 4, 'hello']}}, 'gooble'], | ||
[{a:{b:2, c:[{d:3}, 4, 'hello']}}, 'garbage'], | ||
[{a:{b:2, c:[{d:3}, 4, 'hello']}}, 'too long, must be shortened'] | ||
@@ -115,3 +125,3 @@ ]; | ||
[{a:{a:2, c:[{d:3}, 4, 'hello']}}, ['a'], '\t'], | ||
[{a:{b:2, c:[{d:3}, 4, 'hello']}}, function (key, value) { return value; },'gooble'] | ||
[{a:{b:2, c:[{d:3}, 4, 'hello']}}, function (key, value) { return value; }, 'garbage '] | ||
]; | ||
@@ -140,3 +150,5 @@ fixtures.forEach(function (fixture) { | ||
}); | ||
}); | ||
describe('sortification', function () { | ||
it('should sort keys', function () { | ||
@@ -146,4 +158,4 @@ var fixtures = [ | ||
[{c:1, 42:2, a:3, 0:4, '':5, '00':6, 5:7}, '{"0":4,"5":7,"42":2,"":5,"00":6,"a":3,"c":1}'], | ||
[{c:1, b:2, a:{y:1,z:2,x:3}}, '{"a":{"x":3,"y":1,"z":2},"b":2,"c":1}'], | ||
[{c:1, b:['foo', 2, {a:{y:1,z:2,x:3}}]}, '{"b":["foo",2,{"a":{"x":3,"y":1,"z":2}}],"c":1}'] | ||
[{c:1, b:2, a:{y:1, z:2, x:3}}, '{"a":{"x":3,"y":1,"z":2},"b":2,"c":1}'], | ||
[{c:1, b:['foo', 2, {a:{y:1, z:2, x:3}}]}, '{"b":["foo",2,{"a":{"x":3,"y":1,"z":2}}],"c":1}'] | ||
]; | ||
@@ -158,3 +170,3 @@ fixtures.forEach(function (fixture) { | ||
[ | ||
{x:1,b:2, a:3}, | ||
{x:1, b:2, a:3}, | ||
['a', 'b', 'c'], | ||
@@ -165,3 +177,3 @@ 2, | ||
[ | ||
{x:1,b:{toJSON:function () {return 'b';}}, a:3}, | ||
{x:1, b:{toJSON:function () { return 'b'; }}, a:3}, | ||
['a', 'b', 'c'], | ||
@@ -172,4 +184,4 @@ '••', | ||
[ | ||
{a:undefined,b:function(){},x:1,c:2,0:3,5:5,11:11,' d ':5,z:'foo',aa:'a',d:[{f:{h:2,e:1}},null,'2']}, | ||
function (key,val) {return typeof val == 'string' ? val+'!!!' : val;}, | ||
{a:undefined, b:function(){}, x:1, c:2, 0:3, 5:5, 11:11, ' d ':5, z:'foo', aa:'a', d:[{f:{h:2, e:1}}, null, '2']}, | ||
function (key,val) { return typeof val == 'string' ? val+'!!!' : val; }, | ||
4, | ||
@@ -176,0 +188,0 @@ '{\n "0": 3,\n "5": 5,\n "11": 11,\n " d ": 5,\n "aa": "a!!!",\n "c": 2,\n "d": [\n {\n "f": {\n "e": 1,\n "h": 2\n }\n },\n null,\n "2!!!"\n ],\n "x": 1,\n "z": "foo!!!"\n}' |
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
27199
24.74%8
33.33%272
30.77%128
106.45%5
66.67%1
Infinity%1
Infinity%