This commit is contained in:
darenhsu
2022-07-17 13:16:16 +08:00
parent 84759556ff
commit befd344ab0
28070 changed files with 4008428 additions and 1 deletions
+26
View File
@@ -0,0 +1,26 @@
module.exports = {
extends: ['eslint:recommended', 'google'],
parserOptions: {
ecmaVersion: 5
},
env: {
es6: true,
node: true
},
rules: {
'indent': ['error', 2],
'spaced-comment': ['error', 'always', {markers: ['/']}],
'no-console': 'warn',
'no-var': 'off',
'comma-dangle': ['error', 'never'],
'max-len': [
'error',
{
code: 100,
ignoreComments: true
}
]
// 'valid-jsdoc': 'off',
// 'require-jsdoc': 'off',
}
};
+215
View File
@@ -0,0 +1,215 @@
## Modules
<dl>
<dt><a href="#module_node-object-hash/objectSorter">node-object-hash/objectSorter</a> : <code><a href="#module_node-object-hash/objectSorter..makeObjectSorter..objectToString">objectToString</a></code></dt>
<dd><p>Object sorter module.
It provides object sorter function constructor.</p>
</dd>
<dt><a href="#module_node-object-hash">node-object-hash</a> : <code><a href="#module_node-object-hash..apiConstructor">apiConstructor</a></code></dt>
<dd><p>Node object hash module.
It provides a methods that return object hash or sorted object string.</p>
</dd>
</dl>
<a name="module_node-object-hash/objectSorter"></a>
## node-object-hash/objectSorter : [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
Object sorter module.
It provides object sorter function constructor.
* [node-object-hash/objectSorter](#module_node-object-hash/objectSorter) : [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
* [~_guessObjectType(obj)](#module_node-object-hash/objectSorter.._guessObjectType) ⇒ <code>string</code> ℗
* [~_guessType(obj)](#module_node-object-hash/objectSorter.._guessType) ⇒ <code>string</code> ℗
* [~makeObjectSorter([options])](#module_node-object-hash/objectSorter..makeObjectSorter) ⇒ [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ℗
* [~objectToString(obj)](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ⇒ <code>string</code> ℗
<a name="module_node-object-hash/objectSorter.._guessObjectType"></a>
### node-object-hash/objectSorter~_guessObjectType(obj) ⇒ <code>string</code> ℗
Guesses object's type
**Kind**: inner method of [<code>node-object-hash/objectSorter</code>](#module_node-object-hash/objectSorter)
**Returns**: <code>string</code> - Object type
**Access**: private
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>Object</code> | Object to guess type |
**Example**
```js
var a = [];
_guessObjectType(a) === 'array'; // true
```
<a name="module_node-object-hash/objectSorter.._guessType"></a>
### node-object-hash/objectSorter~_guessType(obj) ⇒ <code>string</code> ℗
Guesses variable type
**Kind**: inner method of [<code>node-object-hash/objectSorter</code>](#module_node-object-hash/objectSorter)
**Returns**: <code>string</code> - Variable type
**Access**: private
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>\*</code> | Variable to guess type |
**Example**
```js
var a = '';
_guessType(a) === 'string'; // true
```
<a name="module_node-object-hash/objectSorter..makeObjectSorter"></a>
### node-object-hash/objectSorter~makeObjectSorter([options]) ⇒ [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ℗
Creates object sorter function
**Kind**: inner method of [<code>node-object-hash/objectSorter</code>](#module_node-object-hash/objectSorter)
**Returns**: [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) - Object sorting function
**Access**: private
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [options] | <code>Object</code> | | Sorter options |
| [options.coerce] | <code>boolean</code> | <code>true</code> | Performs type coercion |
| [options.sort] | <code>boolean</code> | <code>true</code> | Performs array, object, etc. sorting |
**Example**
```js
// with coercion
var sorter = makeObjectSorter({coerce: true, sort: false});
sorter(1) === "1"; // true
// with sort
var sorter = makeObjectSorter({coerce: false, sort: true});
sorter([2, 3, 1]) === [1, 2, 3]; // true
```
<a name="module_node-object-hash/objectSorter..makeObjectSorter..objectToString"></a>
#### makeObjectSorter~objectToString(obj) ⇒ <code>string</code> ℗
Object sorting function
**Kind**: inner method of [<code>makeObjectSorter</code>](#module_node-object-hash/objectSorter..makeObjectSorter)
**Returns**: <code>string</code> - Sorted string
**Access**: private
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>Object</code> | Object to sort |
<a name="module_node-object-hash"></a>
## node-object-hash : [<code>apiConstructor</code>](#module_node-object-hash..apiConstructor)
Node object hash module.
It provides a methods that return object hash or sorted object string.
* [node-object-hash](#module_node-object-hash) : [<code>apiConstructor</code>](#module_node-object-hash..apiConstructor)
* _instance_
* [.sort(obj)](#module_node-object-hash+sort) ⇒ <code>string</code>
* [.hash(obj, [opts])](#module_node-object-hash+hash) ⇒ <code>string</code>
* _inner_
* [~apiConstructor([options])](#module_node-object-hash..apiConstructor) ⇒ [<code>API</code>](#module_node-object-hash..API)
* [~API](#module_node-object-hash..API) : <code>Object</code>
<a name="module_node-object-hash+sort"></a>
### node-object-hash.sort(obj) ⇒ <code>string</code>
Creates sorted string from given object
**Kind**: instance method of [<code>node-object-hash</code>](#module_node-object-hash)
**Returns**: <code>string</code> - Sorted object string
**Access**: public
**See**: [objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>\*</code> | JS object to be sorted |
**Example**
```js
var apiConstructor = require('node-object-hash');
var sorter = apiConstructor({sort:true, coerce:true}).sort;
sort({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
// "{a:[1,3,5],b:{b:1,d:x},c:2}"
```
<a name="module_node-object-hash+hash"></a>
### node-object-hash.hash(obj, [opts]) ⇒ <code>string</code>
Creates hash from given object
**Kind**: instance method of [<code>node-object-hash</code>](#module_node-object-hash)
**Returns**: <code>string</code> - Object hash value
**Access**: public
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| obj | <code>\*</code> | | JS object to hash |
| [opts] | <code>Object</code> | | Options |
| [opts.alg] | <code>string</code> | <code>&quot;sha256&quot;</code> | Crypto algorithm to use |
| [opts.enc] | <code>string</code> | <code>&quot;hex&quot;</code> | Hash string encoding |
**Example**
```js
var apiConstructor = require('node-object-hash');
var hasher = apiConstructor({sort:true, coerce:true}).hash;
hash({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
// "4c18ce0dcb1696b329c8568d94a9830da810437d8c9e6cecf5d969780335a26b"
```
<a name="module_node-object-hash..apiConstructor"></a>
### node-object-hash~apiConstructor([options]) ⇒ [<code>API</code>](#module_node-object-hash..API)
Generates node-object-hash API object
**Kind**: inner method of [<code>node-object-hash</code>](#module_node-object-hash)
**Returns**: [<code>API</code>](#module_node-object-hash..API) - Node object hash API instance
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [options] | <code>Object</code> | | Library options |
| [options.coerce] | <code>boolean</code> | <code>true</code> | Performs type coercion |
| [options.sort] | <code>boolean</code> | <code>true</code> | Performs array, object, etc. sorting |
| [options.alg] | <code>string</code> | <code>&quot;sha256&quot;</code> | Default crypto algorithm to use (can be overridden) |
| [options.enc] | <code>string</code> | <code>&quot;hex&quot;</code> | Hash string encoding (can be overridden) |
**Example**
```js
var apiConstructor = require('node-object-hash');
var hashSortCoerce = apiConstructor({sort:true, coerce:true});
// or
var hashSort = apiConstructor({sort:true, coerce:false});
// or
var hashCoerce = apiConstructor({sort:false, coerce:true});
var objects = {
a: {
a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
b: [1, 'a', {}, null],
},
b: {
b: ['a', 1, {}, undefined],
a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
},
c: ['4', true, 0, 2, 3]
};
hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
// returns true
hashSortCoerce.sort(object.c);
// returns '[0,1,2,3,4]'
```
<a name="module_node-object-hash..API"></a>
### node-object-hash~API : <code>Object</code>
Node object hash API object
**Kind**: inner typedef of [<code>node-object-hash</code>](#module_node-object-hash)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| hash | <code>function</code> | Returns object hash string (see [hash](#module_node-object-hash+hash)) |
| sort | <code>function</code> | Returns sorted object string (see [sort](#module_node-object-hash+sort)) |
+45
View File
@@ -0,0 +1,45 @@
# Changelog
## v1.3.X -> 1.4.X
* Add support for objects without constructor #11 [PR @futpib](https://github.com/SkeLLLa/node-object-hash/pull/12)
* Simplify eslint rules, update codestyle
* Fix npm links issues in readme
* Update dev dependencies
## v1.2.X -> 1.3.X
* Add definition types to support typescript
* Add >=node-8.0.0 support in tests.
## v1.1.X -> 1.2.X
Sorter refactoring and performance improvements
- Added typed arrays support
- Added primitive type constructors support
- Add more docs about type mapping and type coercion
## v1.0.X -> v1.1.X
Mainly all changes affected codestyle and documentation to provide better
experience using this library. There are no changes that should affect
functionality.
- Renamed `sortObject` function to `sort` (old one is still present in code
for backward compatibility).
- Performed some refactoring for better codestyle and documentation.
- Old version (`0.X.X`) moved to subfolder (`./v0`).
- Advanced API reference added: [link](API.md).
## v0.X.X -> v1.0.X
- Sorting mechanism rewritten form ES6 Maps to simple arrays
(add <=node-4.0.0 support)
- Performance optimization (~2 times faster than 0.x.x)
- API changes:
- Now module returns 'constructor' function, where you can set
default parameters: ```var objectHash = require('node-object-hash')(options);```
In case if you still need an old 0.x.x version it's available in `hash.js`
file.
+12
View File
@@ -0,0 +1,12 @@
# Contributor Covenant Code of Conduct
## Basic contribution rules
Basically I don't give a f*** about this CoC. So:
* If you have improvements - you're welcome.
* If you don't you're also welcome.
* If you wanna add some sarcasm into your messages - you're welcome, but be ready to it in answers.
## Purpose of this doc
This doc was created just to get rid of github notification about CoC.
+11
View File
@@ -0,0 +1,11 @@
# Contributing
Feel free to contribute to this repo. Changes that improve overall performance, code quality, tests, etc. are highly appriciated.
## Pull Request Process
1. Ensure that all deps are installed and up to date.
2. Ensure that all tests are OK.
3. Add tests if necessary.
4. Update the README.hbs if necessary and regenerate README.md via provided script (`npm run jsdoc`).
5. Optionally run benchmarks to ensure that your update does no harm to performance.
+15
View File
@@ -0,0 +1,15 @@
ISC License
Copyright (c) 2017, Alexander Kureniov
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+212
View File
@@ -0,0 +1,212 @@
# node-object-hash
Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes.
It also provides a method that returns sorted object strings that can be used for object comparison without hashes.
One of the fastest among other analogues (see [benchmarks](#benchmarks)).
Hashes are built on top of node's crypto module
(so for using in browser use something like [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify) or some kind of crypto functions polyfills). Or you can use only `objectSorter` ([source](https://github.com/SkeLLLa/node-object-hash/blob/master/objectSorter.js)) for getting your objects' string representation and compare or pass them to your own hash function.
[![node](https://img.shields.io/node/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://nodejs.org/download/release/latest)[![NPM](https://img.shields.io/npm/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/package/node-object-hash)[![NPM Downloads](https://img.shields.io/npm/dt/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/package/node-object-hash)[![npms.io Score](https://badges.npms.io/node-object-hash.svg?style=flat-square)](https://npms.io/search?q=node-object-hash)[![Build Status](https://img.shields.io/travis/SkeLLLa/node-object-hash.svg?maxAge=21600&branch=master&style=flat-square)](https://travis-ci.org/SkeLLLa/node-object-hash)[![Known Vulnerabilities](https://snyk.io/test/github/SkeLLLa/node-object-hash/badge.svg?maxAge=21600&style=flat-square)](https://snyk.io/test/github/skellla/node-object-hash)[![Coverage](https://api.codeclimate.com/v1/badges/199467889caf98d59690/test_coverage)](https://codeclimate.com/github/SkeLLLa/node-object-hash/test_coverage)[![Maintainability](https://api.codeclimate.com/v1/badges/199467889caf98d59690/maintainability)](https://codeclimate.com/github/SkeLLLa/node-object-hash/maintainability)[![Inline docs](http://inch-ci.org/github/SkeLLLa/node-object-hash.svg?branch=master&style=flat-square)](http://inch-ci.org/github/SkeLLLa/node-object-hash)[![Analytics](https://ga-beacon.appspot.com/UA-90571586-1/node-object-hash?pixel&useReferer)](https://github.com/igrigorik/ga-beacon)
# Installation
`npm i node-object-hash -S`
# Features
- Supports object property sorting for constant hashes for objects with same properties, but different order.
- Supports ES6 Maps and Sets.
- Supports type coercion (see table below)
- Supports all hashes and encodings of crypto library
- Supports large objects and arrays
- Very fast comparing to other libs (see [Benchmarks](#benchmarks) section)
## Type map
This map displays what types will have identical string representation (e.g. new Set([1, 2, 3]) and [1, 2, 3] will have
equal string representations and hashes.
| Initial type | Mapped type |
|---------------------------|--------------|
| Array ([]) | array |
| ArrayObject (new Array()) | |
| Int8Array | |
| Uint8Array | |
| Uint8ClampedArray | |
| Int16Array | |
| Uint16Array | |
| Int32Array | |
| Uint32Array | |
| Float32Array | |
| Float64Array | |
| Buffer | |
| Set | |
| | |
| Map | array[array] |
| | |
| string ('') | string | string |
| String (new String()) | |
| | |
| boolean (true) | boolean |
| Boolean (new Boolean()) | |
| | |
| number (true) | number |
| Number (new Number()) | |
| | |
| Date | date |
| | |
| Symbol | symbol |
| | |
| undefined | undefined |
| | |
| null | null |
| | |
| function | function |
| | |
| Object ({}) | object |
| Object (new Object()) | |
| | |
| other | unknown |
## Coercion map
| Initial "type" | Coerced type | Example |
|----------------|----------------|--------------|
| boolean | string | true -> 1 |
| number | string | '1' -> 1 |
| string | string | 'a' -> a |
| null | string (empty) | null -> |
| undefined | string (empty) | undefined -> |
# Changes
See [changelog](CHANGELOG.md)
# API overview
## Constructor `require('node-object-hash')([options])`
Returns preconfigured object with API
Parameters:
* `options`:`object` - object with hasher config options
* `options.coerce`:`boolean` - if true performs type coercion (default: `true`);
e.g. `hash(true) == hash('1') == hash(1)`, `hash(false) == hash('0') == hash(0)`
* `options.sort`:`boolean` - if true performs sorting on objects, arrays, etc. (default: `true`);
* `options.alg`:`string` - sets default hash algorithm (default: `'sha256'`); can be overridden in `hash` method;
* `options.enc`:`string` - sets default hash encoding (default: `'hex'`); can be overridden in `hash` method;
## API methods
### `hash(object[, options])`
Returns hash string.
* `object`:`*` object for calculating hash;
* `options`:`object` object with options;
* `options.alg`:`string` - hash algorithm (default: `'sha256'`);
* `options.enc`:`string` - hash encoding (default: `'hex'`);
### `sort(object)`
Returns sorted string generated from object (can be used for object comparison)
* `object`:`*` - object for sorting;
# Full API docs ([separate page](API.md))
{{>main}}
# Requirements
## version \>=1.0.0
- `>=nodejs-0.10.0`
## version \>=0.1.0 && <1.0.0
- `>=nodejs-6.0.0`
- `>=nodejs-4.0.0` (requires to run node with `--harmony` flag)
## browsers
- nodejs `crypto` module for browsers (e.g. [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify)).
# Example
```js
var hasher = require('node-object-hash');
var hashSortCoerce = hasher({sort:true, coerce:true});
// or
// var hashSortCoerce = hasher();
// or
// var hashSort = hasher({sort:true, coerce:false});
// or
// var hashCoerce = hasher({sort:false, coerce:true});
var objects = {
a: {
a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
b: [1, 'a', {}, null],
},
b: {
b: ['a', 1, {}, undefined],
a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
},
c: ['4', true, 0, 2, 3]
};
hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
// returns true
hashSortCoerce.sort(object.c);
// returns '[0,1,2,3,4]'
```
For more examples you can see [tests file](https://github.com/SkeLLLa/node-object-hash/blob/master/test/hash2.js)
or try it out online at [runkit](https://runkit.com/skellla/node-object-hash-example)
# Benchmarks
Bench data - array of 100000 complex objects
## Usage
* `npm run bench` to run custom benchmark
* `npm run bench2` to run benchmark suite
## Results
### Custom benchmark ([code](bench/index.js))
| Library | Time (ms) | Memory (Mb) |
|---------------------------------------|------------|--------------------|
| node-object-hash-0.2.1 | 5813.575 | 34 |
| node-object-hash-1.0.X | 2805.581 | 27 |
| node-object-hash-1.1.X (node v7) | 2555.583 | 27 |
| node-object-hash-1.2.X (node v7) | 2390.752 | 28 |
| object-hash-1.1.5 (node v7) | 28115.553 | 39 |
| object-hash-1.1.4 | 534528.254 | 41 |
| object-hash-1.1.3 | ERROR | Out of heap memory |
| hash-object-0.1.7 | 9219.826 | 42 |
### Benchmark suite module ([code](bench/bench.js))
| Library (node v7) | Perf (ops/s) |
|------------------------|--------------|
| node-object-hash-0.2.1 | 540 ±1.34% |
| node-object-hash-1.1.X | 844 ±2.51% |
| node-object-hash-1.2.X | 1021 ±1.81% |
| object-hash-1.1.5 | 106 ±0.88% |
| hash-object-0.1.7 | 305 ±1.66% |
| Library (node v10) | Perf (ops/s) |
|------------------------|--------------|
| node-object-hash-0.X.X | 758 ±1.40% |
| node-object-hash-1.4.X | 1266 ±1.44% |
| object-hash-1.3.0 | 132 ±4.08% |
| hash-object-0.1.7 | 378 ±1.36% |
## Links
* [object-hash](https://www.npmjs.com/package/object-hash) - Slow, useful for browsers because it not uses node's crypto library
* [hash-object](https://www.npmjs.com/package/hash-object) - no ES6 types support
# License
ISC
+426
View File
@@ -0,0 +1,426 @@
# node-object-hash
Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes.
It also provides a method that returns sorted object strings that can be used for object comparison without hashes.
One of the fastest among other analogues (see [benchmarks](#benchmarks)).
Hashes are built on top of node's crypto module
(so for using in browser use something like [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify) or some kind of crypto functions polyfills). Or you can use only `objectSorter` ([source](https://github.com/SkeLLLa/node-object-hash/blob/master/objectSorter.js)) for getting your objects' string representation and compare or pass them to your own hash function.
[![node](https://img.shields.io/node/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://nodejs.org/download/release/latest)[![NPM](https://img.shields.io/npm/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/package/node-object-hash)[![NPM Downloads](https://img.shields.io/npm/dt/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/package/node-object-hash)[![npms.io Score](https://badges.npms.io/node-object-hash.svg?style=flat-square)](https://npms.io/search?q=node-object-hash)[![Build Status](https://img.shields.io/travis/SkeLLLa/node-object-hash.svg?maxAge=21600&branch=master&style=flat-square)](https://travis-ci.org/SkeLLLa/node-object-hash)[![Known Vulnerabilities](https://snyk.io/test/github/SkeLLLa/node-object-hash/badge.svg?maxAge=21600&style=flat-square)](https://snyk.io/test/github/skellla/node-object-hash)[![Coverage](https://api.codeclimate.com/v1/badges/199467889caf98d59690/test_coverage)](https://codeclimate.com/github/SkeLLLa/node-object-hash/test_coverage)[![Maintainability](https://api.codeclimate.com/v1/badges/199467889caf98d59690/maintainability)](https://codeclimate.com/github/SkeLLLa/node-object-hash/maintainability)[![Inline docs](http://inch-ci.org/github/SkeLLLa/node-object-hash.svg?branch=master&style=flat-square)](http://inch-ci.org/github/SkeLLLa/node-object-hash)[![Analytics](https://ga-beacon.appspot.com/UA-90571586-1/node-object-hash?pixel&useReferer)](https://github.com/igrigorik/ga-beacon)
# Installation
`npm i node-object-hash -S`
# Features
- Supports object property sorting for constant hashes for objects with same properties, but different order.
- Supports ES6 Maps and Sets.
- Supports type coercion (see table below)
- Supports all hashes and encodings of crypto library
- Supports large objects and arrays
- Very fast comparing to other libs (see [Benchmarks](#benchmarks) section)
## Type map
This map displays what types will have identical string representation (e.g. new Set([1, 2, 3]) and [1, 2, 3] will have
equal string representations and hashes.
| Initial type | Mapped type |
|---------------------------|--------------|
| Array ([]) | array |
| ArrayObject (new Array()) | |
| Int8Array | |
| Uint8Array | |
| Uint8ClampedArray | |
| Int16Array | |
| Uint16Array | |
| Int32Array | |
| Uint32Array | |
| Float32Array | |
| Float64Array | |
| Buffer | |
| Set | |
| | |
| Map | array[array] |
| | |
| string ('') | string | string |
| String (new String()) | |
| | |
| boolean (true) | boolean |
| Boolean (new Boolean()) | |
| | |
| number (true) | number |
| Number (new Number()) | |
| | |
| Date | date |
| | |
| Symbol | symbol |
| | |
| undefined | undefined |
| | |
| null | null |
| | |
| function | function |
| | |
| Object ({}) | object |
| Object (new Object()) | |
| | |
| other | unknown |
## Coercion map
| Initial "type" | Coerced type | Example |
|----------------|----------------|--------------|
| boolean | string | true -> 1 |
| number | string | '1' -> 1 |
| string | string | 'a' -> a |
| null | string (empty) | null -> |
| undefined | string (empty) | undefined -> |
# Changes
See [changelog](CHANGELOG.md)
# API overview
## Constructor `require('node-object-hash')([options])`
Returns preconfigured object with API
Parameters:
* `options`:`object` - object with hasher config options
* `options.coerce`:`boolean` - if true performs type coercion (default: `true`);
e.g. `hash(true) == hash('1') == hash(1)`, `hash(false) == hash('0') == hash(0)`
* `options.sort`:`boolean` - if true performs sorting on objects, arrays, etc. (default: `true`);
* `options.alg`:`string` - sets default hash algorithm (default: `'sha256'`); can be overridden in `hash` method;
* `options.enc`:`string` - sets default hash encoding (default: `'hex'`); can be overridden in `hash` method;
## API methods
### `hash(object[, options])`
Returns hash string.
* `object`:`*` object for calculating hash;
* `options`:`object` object with options;
* `options.alg`:`string` - hash algorithm (default: `'sha256'`);
* `options.enc`:`string` - hash encoding (default: `'hex'`);
### `sort(object)`
Returns sorted string generated from object (can be used for object comparison)
* `object`:`*` - object for sorting;
# Full API docs ([separate page](API.md))
## Modules
<dl>
<dt><a href="#module_node-object-hash/objectSorter">node-object-hash/objectSorter</a> : <code><a href="#module_node-object-hash/objectSorter..makeObjectSorter..objectToString">objectToString</a></code></dt>
<dd><p>Object sorter module.
It provides object sorter function constructor.</p>
</dd>
<dt><a href="#module_node-object-hash">node-object-hash</a> : <code><a href="#module_node-object-hash..apiConstructor">apiConstructor</a></code></dt>
<dd><p>Node object hash module.
It provides a methods that return object hash or sorted object string.</p>
</dd>
</dl>
<a name="module_node-object-hash/objectSorter"></a>
## node-object-hash/objectSorter : [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
Object sorter module.
It provides object sorter function constructor.
* [node-object-hash/objectSorter](#module_node-object-hash/objectSorter) : [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
* [~_guessObjectType(obj)](#module_node-object-hash/objectSorter.._guessObjectType) ⇒ <code>string</code> ℗
* [~_guessType(obj)](#module_node-object-hash/objectSorter.._guessType) ⇒ <code>string</code> ℗
* [~makeObjectSorter([options])](#module_node-object-hash/objectSorter..makeObjectSorter) ⇒ [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ℗
* [~objectToString(obj)](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ⇒ <code>string</code> ℗
<a name="module_node-object-hash/objectSorter.._guessObjectType"></a>
### node-object-hash/objectSorter~_guessObjectType(obj) ⇒ <code>string</code> ℗
Guesses object's type
**Kind**: inner method of [<code>node-object-hash/objectSorter</code>](#module_node-object-hash/objectSorter)
**Returns**: <code>string</code> - Object type
**Access**: private
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>Object</code> | Object to guess type |
**Example**
```js
var a = [];
_guessObjectType(a) === 'array'; // true
```
<a name="module_node-object-hash/objectSorter.._guessType"></a>
### node-object-hash/objectSorter~_guessType(obj) ⇒ <code>string</code> ℗
Guesses variable type
**Kind**: inner method of [<code>node-object-hash/objectSorter</code>](#module_node-object-hash/objectSorter)
**Returns**: <code>string</code> - Variable type
**Access**: private
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>\*</code> | Variable to guess type |
**Example**
```js
var a = '';
_guessType(a) === 'string'; // true
```
<a name="module_node-object-hash/objectSorter..makeObjectSorter"></a>
### node-object-hash/objectSorter~makeObjectSorter([options]) ⇒ [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ℗
Creates object sorter function
**Kind**: inner method of [<code>node-object-hash/objectSorter</code>](#module_node-object-hash/objectSorter)
**Returns**: [<code>objectToString</code>](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) - Object sorting function
**Access**: private
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [options] | <code>Object</code> | | Sorter options |
| [options.coerce] | <code>boolean</code> | <code>true</code> | Performs type coercion |
| [options.sort] | <code>boolean</code> | <code>true</code> | Performs array, object, etc. sorting |
**Example**
```js
// with coercion
var sorter = makeObjectSorter({coerce: true, sort: false});
sorter(1) === "1"; // true
// with sort
var sorter = makeObjectSorter({coerce: false, sort: true});
sorter([2, 3, 1]) === [1, 2, 3]; // true
```
<a name="module_node-object-hash/objectSorter..makeObjectSorter..objectToString"></a>
#### makeObjectSorter~objectToString(obj) ⇒ <code>string</code> ℗
Object sorting function
**Kind**: inner method of [<code>makeObjectSorter</code>](#module_node-object-hash/objectSorter..makeObjectSorter)
**Returns**: <code>string</code> - Sorted string
**Access**: private
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>Object</code> | Object to sort |
<a name="module_node-object-hash"></a>
## node-object-hash : [<code>apiConstructor</code>](#module_node-object-hash..apiConstructor)
Node object hash module.
It provides a methods that return object hash or sorted object string.
* [node-object-hash](#module_node-object-hash) : [<code>apiConstructor</code>](#module_node-object-hash..apiConstructor)
* _instance_
* [.sort(obj)](#module_node-object-hash+sort) ⇒ <code>string</code>
* [.hash(obj, [opts])](#module_node-object-hash+hash) ⇒ <code>string</code>
* _inner_
* [~apiConstructor([options])](#module_node-object-hash..apiConstructor) ⇒ [<code>API</code>](#module_node-object-hash..API)
* [~API](#module_node-object-hash..API) : <code>Object</code>
<a name="module_node-object-hash+sort"></a>
### node-object-hash.sort(obj) ⇒ <code>string</code>
Creates sorted string from given object
**Kind**: instance method of [<code>node-object-hash</code>](#module_node-object-hash)
**Returns**: <code>string</code> - Sorted object string
**Access**: public
**See**: [objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
| Param | Type | Description |
| --- | --- | --- |
| obj | <code>\*</code> | JS object to be sorted |
**Example**
```js
var apiConstructor = require('node-object-hash');
var sorter = apiConstructor({sort:true, coerce:true}).sort;
sort({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
// "{a:[1,3,5],b:{b:1,d:x},c:2}"
```
<a name="module_node-object-hash+hash"></a>
### node-object-hash.hash(obj, [opts]) ⇒ <code>string</code>
Creates hash from given object
**Kind**: instance method of [<code>node-object-hash</code>](#module_node-object-hash)
**Returns**: <code>string</code> - Object hash value
**Access**: public
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| obj | <code>\*</code> | | JS object to hash |
| [opts] | <code>Object</code> | | Options |
| [opts.alg] | <code>string</code> | <code>&quot;sha256&quot;</code> | Crypto algorithm to use |
| [opts.enc] | <code>string</code> | <code>&quot;hex&quot;</code> | Hash string encoding |
**Example**
```js
var apiConstructor = require('node-object-hash');
var hasher = apiConstructor({sort:true, coerce:true}).hash;
hash({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
// "4c18ce0dcb1696b329c8568d94a9830da810437d8c9e6cecf5d969780335a26b"
```
<a name="module_node-object-hash..apiConstructor"></a>
### node-object-hash~apiConstructor([options]) ⇒ [<code>API</code>](#module_node-object-hash..API)
Generates node-object-hash API object
**Kind**: inner method of [<code>node-object-hash</code>](#module_node-object-hash)
**Returns**: [<code>API</code>](#module_node-object-hash..API) - Node object hash API instance
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [options] | <code>Object</code> | | Library options |
| [options.coerce] | <code>boolean</code> | <code>true</code> | Performs type coercion |
| [options.sort] | <code>boolean</code> | <code>true</code> | Performs array, object, etc. sorting |
| [options.alg] | <code>string</code> | <code>&quot;sha256&quot;</code> | Default crypto algorithm to use (can be overridden) |
| [options.enc] | <code>string</code> | <code>&quot;hex&quot;</code> | Hash string encoding (can be overridden) |
**Example**
```js
var apiConstructor = require('node-object-hash');
var hashSortCoerce = apiConstructor({sort:true, coerce:true});
// or
var hashSort = apiConstructor({sort:true, coerce:false});
// or
var hashCoerce = apiConstructor({sort:false, coerce:true});
var objects = {
a: {
a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
b: [1, 'a', {}, null],
},
b: {
b: ['a', 1, {}, undefined],
a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
},
c: ['4', true, 0, 2, 3]
};
hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
// returns true
hashSortCoerce.sort(object.c);
// returns '[0,1,2,3,4]'
```
<a name="module_node-object-hash..API"></a>
### node-object-hash~API : <code>Object</code>
Node object hash API object
**Kind**: inner typedef of [<code>node-object-hash</code>](#module_node-object-hash)
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| hash | <code>function</code> | Returns object hash string (see [hash](#module_node-object-hash+hash)) |
| sort | <code>function</code> | Returns sorted object string (see [sort](#module_node-object-hash+sort)) |
# Requirements
## version \>=1.0.0
- `>=nodejs-0.10.0`
## version \>=0.1.0 && <1.0.0
- `>=nodejs-6.0.0`
- `>=nodejs-4.0.0` (requires to run node with `--harmony` flag)
## browsers
- nodejs `crypto` module for browsers (e.g. [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify)).
# Example
```js
var hasher = require('node-object-hash');
var hashSortCoerce = hasher({sort:true, coerce:true});
// or
// var hashSortCoerce = hasher();
// or
// var hashSort = hasher({sort:true, coerce:false});
// or
// var hashCoerce = hasher({sort:false, coerce:true});
var objects = {
a: {
a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
b: [1, 'a', {}, null],
},
b: {
b: ['a', 1, {}, undefined],
a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
},
c: ['4', true, 0, 2, 3]
};
hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
// returns true
hashSortCoerce.sort(object.c);
// returns '[0,1,2,3,4]'
```
For more examples you can see [tests file](https://github.com/SkeLLLa/node-object-hash/blob/master/test/hash2.js)
or try it out online at [runkit](https://runkit.com/skellla/node-object-hash-example)
# Benchmarks
Bench data - array of 100000 complex objects
## Usage
* `npm run bench` to run custom benchmark
* `npm run bench2` to run benchmark suite
## Results
### Custom benchmark ([code](bench/index.js))
| Library | Time (ms) | Memory (Mb) |
|---------------------------------------|------------|--------------------|
| node-object-hash-0.2.1 | 5813.575 | 34 |
| node-object-hash-1.0.X | 2805.581 | 27 |
| node-object-hash-1.1.X (node v7) | 2555.583 | 27 |
| node-object-hash-1.2.X (node v7) | 2390.752 | 28 |
| object-hash-1.1.5 (node v7) | 28115.553 | 39 |
| object-hash-1.1.4 | 534528.254 | 41 |
| object-hash-1.1.3 | ERROR | Out of heap memory |
| hash-object-0.1.7 | 9219.826 | 42 |
### Benchmark suite module ([code](bench/bench.js))
| Library (node v7) | Perf (ops/s) |
|------------------------|--------------|
| node-object-hash-0.2.1 | 540 ±1.34% |
| node-object-hash-1.1.X | 844 ±2.51% |
| node-object-hash-1.2.X | 1021 ±1.81% |
| object-hash-1.1.5 | 106 ±0.88% |
| hash-object-0.1.7 | 305 ±1.66% |
| Library (node v10) | Perf (ops/s) |
|------------------------|--------------|
| node-object-hash-0.X.X | 758 ±1.40% |
| node-object-hash-1.4.X | 1266 ±1.44% |
| object-hash-1.3.0 | 132 ±4.08% |
| hash-object-0.1.7 | 378 ±1.36% |
## Links
* [object-hash](https://www.npmjs.com/package/object-hash) - Slow, useful for browsers because it not uses node's crypto library
* [hash-object](https://www.npmjs.com/package/hash-object) - no ES6 types support
# License
ISC
+23
View File
@@ -0,0 +1,23 @@
declare module 'node-object-hash' {
namespace apiConstructor {
interface HashOptions {
coerce?: boolean,
sort?: boolean,
alg?: string,
enc?: string,
}
interface API {
hash(object: any, opts?: {
alg?: string,
enc?: string,
}): string;
sortObject(object: any): string;
sort(object: any): string;
}
}
function apiConstructor(options?: apiConstructor.HashOptions): apiConstructor.API;
export = apiConstructor;
}
+123
View File
@@ -0,0 +1,123 @@
// / <reference types="node" />
'use strict';
var crypto = require('crypto');
var objectSorter = require('./objectSorter');
/**
* Node object hash API object
* @typedef {Object} API
* @memberOf module:node-object-hash
* @inner
* @property {Function} hash Returns object hash string (see {@link module:node-object-hash#hash})
* @property {Function} sort Returns sorted object string (see {@link module:node-object-hash#sort})
*/
/**
* Generates node-object-hash API object
* @param {Object} [options] Library options
* @param {boolean} [options.coerce=true] Performs type coercion
* @param {boolean} [options.sort=true] Performs array, object, etc. sorting
* @param {string} [options.alg=sha256] Default crypto algorithm to use (can be overridden)
* @param {string} [options.enc=hex] Hash string encoding (can be overridden)
* @return {module:node-object-hash~API} Node object hash API instance
* @memberOf module:node-object-hash
* @inner
* @example
* var apiConstructor = require('node-object-hash');
* var hashSortCoerce = apiConstructor({sort:true, coerce:true});
* // or
* var hashSort = apiConstructor({sort:true, coerce:false});
* // or
* var hashCoerce = apiConstructor({sort:false, coerce:true});
*
* var objects = {
* a: {
* a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
* b: [1, 'a', {}, null],
* },
* b: {
* b: ['a', 1, {}, undefined],
* a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
* },
* c: ['4', true, 0, 2, 3]
* };
* hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
* // returns true
*
* hashSortCoerce.sort(object.c);
* // returns '[0,1,2,3,4]'
*/
function apiConstructor(options) {
var defaults = options || {};
var _sortObject;
defaults.alg = defaults.alg || 'sha256';
defaults.enc = defaults.enc || 'hex';
_sortObject = objectSorter(options);
/**
* Creates sorted string from given object
* @param {*} obj JS object to be sorted
* @return {string} Sorted object string
* @see {@link module:node-object-hash/objectSorter~makeObjectSorter~objectToString}
* @memberOf module:node-object-hash
* @instance
* @public
* @alias sort
* @example
* var apiConstructor = require('node-object-hash');
* var sorter = apiConstructor({sort:true, coerce:true}).sort;
*
* sort({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
* // "{a:[1,3,5],b:{b:1,d:x},c:2}"
*/
function sortObject(obj) {
return _sortObject(obj);
}
/**
* Creates hash from given object
* @param {*} obj JS object to hash
* @param {Object} [opts] Options
* @param {string} [opts.alg=sha256] Crypto algorithm to use
* @param {string} [opts.enc=hex] Hash string encoding
* @return {string} Object hash value
* @memberOf module:node-object-hash
* @instance
* @public
* @alias hash
* @example
* var apiConstructor = require('node-object-hash');
* var hasher = apiConstructor({sort:true, coerce:true}).hash;
*
* hash({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
* // "4c18ce0dcb1696b329c8568d94a9830da810437d8c9e6cecf5d969780335a26b"
*/
function hashObject(obj, opts) {
opts = opts || {};
var alg = opts.alg || defaults.alg;
var enc = opts.enc || defaults.enc;
var sorted = sortObject(obj);
return crypto
.createHash(alg)
.update(sorted)
.digest(enc);
}
return {
hash: hashObject,
sortObject: sortObject,
sort: sortObject
};
}
/**
* Node object hash module.
* It provides a methods that return object hash or sorted object string.
* @module node-object-hash
* @type {module:node-object-hash~apiConstructor}
*/
module.exports = apiConstructor;
+8
View File
@@ -0,0 +1,8 @@
declare module 'node-object-hash.objectSorter' {
function makeObjectSorter(options?: {
coerce?: boolean,
sort?: boolean,
}): string;
export = makeObjectSorter;
}
+227
View File
@@ -0,0 +1,227 @@
// / <reference types="node" />
'use strict';
/**
* Guesses object's type
* @memberOf module:node-object-hash/objectSorter
* @inner
* @private
* @param {Object} obj Object to guess type
* @return {string} Object type
* @example
* var a = [];
* _guessObjectType(a) === 'array'; // true
*/
function _guessObjectType(obj) {
if (obj === null) {
return 'null';
}
switch (obj.constructor && obj.constructor.name) {
case 'Array':
case 'Int8Array':
case 'Uint8Array':
case 'Uint8ClampedArray':
case 'Int16Array':
case 'Uint16Array':
case 'Int32Array':
case 'Uint32Array':
case 'Float32Array':
case 'Float64Array':
case 'Buffer':
return 'array';
case 'Map':
return 'map';
case 'Set':
return 'set';
case 'Date':
return 'date';
case 'String':
return 'string';
case 'Number':
return 'number';
case 'Boolean':
return 'boolean';
case 'Object':
return 'object';
default:
return 'unknown';
}
}
/**
* Guesses variable type
* @memberOf module:node-object-hash/objectSorter
* @inner
* @private
* @param {*} obj Variable to guess type
* @return {string} Variable type
* @example
* var a = '';
* _guessType(a) === 'string'; // true
*/
function _guessType(obj) {
var type = typeof obj;
return type !== 'object' ? type : _guessObjectType(obj);
}
/**
* Creates object sorter function
* @memberOf module:node-object-hash/objectSorter
* @inner
* @private
* @param {Object} [options] Sorter options
* @param {boolean} [options.coerce=true] Performs type coercion
* @param {boolean} [options.sort=true] Performs array, object, etc. sorting
* @return {module:node-object-hash/objectSorter~makeObjectSorter~objectToString}
* Object sorting function
* @example
* // with coercion
* var sorter = makeObjectSorter({coerce: true, sort: false});
* sorter(1) === "1"; // true
* // with sort
* var sorter = makeObjectSorter({coerce: false, sort: true});
* sorter([2, 3, 1]) === [1, 2, 3]; // true
*/
function makeObjectSorter(options) {
options = options || {};
var coerce = typeof options.coerce === 'undefined' ? true : options.coerce;
var sort = typeof options.sort === 'undefined' ? true : options.sort;
var stringifier = {};
stringifier.string = function sortString(obj) {
if (coerce) {
return obj;
}
return '<:s>:' + obj;
};
stringifier.number = function sortNumber(obj) {
if (coerce) {
return obj.toString();
}
return '<:n>:' + obj;
};
stringifier.boolean = function sortBoolean(obj) {
if (coerce) {
return obj.valueOf() ? '1' : '0';
}
return obj.valueOf() ? '<:b>:true' : '<:b>:false';
};
stringifier.symbol = function sortSymbol() {
return '<:smbl>';
};
stringifier.undefined = function sortUndefined() {
if (coerce) {
return '';
}
return '<:undf>';
};
stringifier.null = function sortNull() {
if (coerce) {
return '';
}
return '<:null>';
};
stringifier.function = function sortFunction(obj) {
if (coerce) {
return obj.name + '=>' + obj.toString();
}
return '<:func>:' + obj.name + '=>' + obj.toString();
};
stringifier.array = function sortArray(obj) {
var item;
var itemType;
var result = [];
for (var i = 0; i < obj.length; i++) {
item = obj[i];
itemType = _guessType(item);
result.push(stringifier[itemType](item));
}
return sort ? '[' + result.sort().toString() + ']' : '[' + result.toString() + ']';
};
stringifier.set = function sortSet(obj) {
return stringifier.array(Array.from(obj));
};
stringifier.date = function sortDate(obj) {
var dateStr = obj.toISOString();
if (coerce) {
return dateStr;
}
return '<:date>:' + dateStr;
};
stringifier.object = function sortObject(obj) {
var keys = sort ? Object.keys(obj).sort() : Object.keys(obj);
var objArray = [];
var key;
var value;
var valueType;
var i;
for (i = 0; i < keys.length; i++) {
key = keys[i];
value = obj[key];
valueType = _guessType(value);
objArray.push(key + ':' + stringifier[valueType](value));
}
return '{' + objArray.toString() + '}';
};
stringifier.map = function sortMap(obj) {
var arr = Array.from(obj);
var key;
var value;
var item;
var i;
for (i = 0; i < arr.length; i++) {
item = arr[i];
key = item[0];
value = item[1];
item = [stringifier[_guessType(key)](key), stringifier[_guessType(value)](value)];
arr[i] = item;
}
return sort ? '[' + arr.sort().join(';') + ']' : '[' + arr.join(';') + ']';
};
stringifier.unknown = function unknownToString(obj) {
var constructorName = obj.constructor ? obj.constructor.name : 'unknonw';
var objectName = typeof obj.toString === 'function' ? obj.toString() : 'unknown';
return '<:' + constructorName + '>:' + objectName;
};
/**
* Object sorting function
* @private
* @param {Object} obj Object to sort
* @return {string} Sorted string
*/
function objectToString(obj) {
return stringifier[_guessType(obj)](obj);
}
return objectToString;
}
/**
* Object sorter module.
* It provides object sorter function constructor.
* @module node-object-hash/objectSorter
* @type {module:node-object-hash/objectSorter~makeObjectSorter~objectToString}
*/
module.exports = makeObjectSorter;
+86
View File
@@ -0,0 +1,86 @@
{
"_args": [
[
"node-object-hash@1.4.2",
"/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series"
]
],
"_from": "node-object-hash@1.4.2",
"_id": "node-object-hash@1.4.2",
"_inBundle": false,
"_integrity": "sha512-UdS4swXs85fCGWWf6t6DMGgpN/vnlKeSGEQ7hJcrs7PBFoxoKLmibc3QRb7fwiYsjdL7PX8iI/TMSlZ90dgHhQ==",
"_location": "/node-object-hash",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "node-object-hash@1.4.2",
"name": "node-object-hash",
"escapedName": "node-object-hash",
"rawSpec": "1.4.2",
"saveSpec": null,
"fetchSpec": "1.4.2"
},
"_requiredBy": [
"/hard-source-webpack-plugin"
],
"_resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-1.4.2.tgz",
"_spec": "1.4.2",
"_where": "/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series",
"author": {
"name": "Alexander Kureniov",
"email": "s@zxc.pp.ua",
"url": "https://github.com/SkeLLLa"
},
"bugs": {
"url": "https://github.com/SkeLLLa/node-object-hash/issues"
},
"description": "Node.js object hash library with properties/arrays sorting to provide constant hashes",
"devDependencies": {
"@types/node": "^10.0.0",
"benchmark": "^2.1.4",
"chai": "^4.1.2",
"eslint": "^4.19.1",
"eslint-config-google": "^0.9.1",
"faker": "^4.1.0",
"hash-object": "^0.1.7",
"istanbul": "^0.4.5",
"jsdoc-to-markdown": "^4.0.0",
"mocha": "^5.2.0",
"object-hash": "^1.3.0",
"typescript": "^3.2.4"
},
"directories": {
"test": "test"
},
"engines": {
"node": ">=0.10.0"
},
"homepage": "https://github.com/SkeLLLa/node-object-hash",
"keywords": [
"hash",
"object",
"hash-object",
"object-hash",
"es6",
"crypto"
],
"license": "ISC",
"main": "index.js",
"name": "node-object-hash",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/SkeLLLa/node-object-hash.git"
},
"scripts": {
"bench": "node --expose-gc ./bench/index.js",
"bench2": "node --expose-gc ./bench/bench.js",
"cover": "istanbul cover _mocha",
"jsdoc": "jsdoc2md -t ./README.hbs --private 'objectSorter.js' 'index.js' > README.md && jsdoc2md --private 'objectSorter.js' 'index.js' > API.md",
"lint": "eslint .",
"outdated": "npm outdate || true",
"test": "mocha",
"tsc": "tsc index.d.ts objectSorter.d.ts --noImplicitAny"
},
"version": "1.4.2"
}
+88
View File
@@ -0,0 +1,88 @@
/**
* Node.js constant object hash module.
* @exports node-object-hash
* @type {Function}
*/
'use strict';
const crypto = require('crypto');
/**
* Sorts object fields
* @param {Object|Array|string|function} obj Initial object
* @param {Object} options Options
* @param {boolean} [options.coerce=true] Perform coercion
* @param {boolean} [options.sort=true] Perform Array, Set, Object sorting
* @returns {string}
*/
exports.sortedObjectString = (obj, options) => {
const coerce = typeof options.coerce == 'undefined' ? true : options.coerce;
const sort = typeof options.sort == 'undefined' ? true : options.sort;
if (typeof obj == 'object') {
if (Array.isArray(obj)) {
let tmp = [...obj];
tmp.forEach((it, idx) => {
tmp[idx] = exports.sortedObjectString(it, {coerce, sort})
});
return sort ? `[${tmp.sort().toString()}]` : `[${tmp.toString()}]`;
}
if (obj === null) {
return `null`;
}
if (obj instanceof Map) {
return `Map[${[...obj].toString()}]`;
}
if (obj instanceof Set) {
return sort ? `Set[${[...obj].sort().toString()}]` : `Set[${[...obj].toString()}]`;
}
const sortedObj = new Map();
const keys = sort ? Object.keys(obj).sort() : Object.keys(obj);
keys.forEach((key) => {
sortedObj.set(key, exports.sortedObjectString(obj[key], {coerce, sort}));
});
return `{${[...sortedObj].toString()}}`;
}
if (typeof obj == 'function') {
return `${obj.name}=>${obj.toString()}`;
}
if (coerce) {
if (typeof obj == 'boolean') {
return `${Number(obj)}`;
}
} else {
if (typeof obj == 'string') {
return `"${obj}"`
}
}
if (coerce && typeof obj == 'boolean') {
return `${Number(obj)}`;
}
return obj;
};
/**
* Calculates object hash
* @param {Object} obj Object to hash
* @param {Object} [options] Options
* @param {string} [options.alg="sha256"] Crypto algorithm to use
* @param {string} [options.enc="hex"] Hash string encoding
* @param {boolean} [options.coerce=true] Perform coercion
* @param {boolean} [options.sort=true] Perform Array, Set, Object sorting
* @returns {string} Hash string
*/
exports.hash = (obj, options) => {
options = options || {};
const alg = options.alg || 'sha256';
const enc = options.enc || 'hex';
const coerce = typeof options.coerce == 'undefined' ? true : options.coerce;
const sort = typeof options.sort == 'undefined' ? true : options.sort;
if (~crypto.getHashes().indexOf(alg)) {
const sorted = exports.sortedObjectString(obj, {coerce, sort});
return crypto.createHash(alg)
.update(sorted)
.digest(enc);
} else {
throw new Error(`Algorithm ${alg} not supported by "ctypto" module`);
}
};