Verified Commit 450471ee authored by m03geek's avatar m03geek 🚧
Browse files

feat: major refactor

BREAKING CHANGE: See readme
parent 2ce615da
Pipeline #79657696 failed with stages
in 1 minute and 16 seconds
version: "2"
checks:
argument-count:
enabled: true
complex-logic:
enabled: true
config:
threshold: 50
file-lines:
enabled: true
config:
threshold: 250
method-complexity:
enabled: true
config:
threshold: 50
method-count:
enabled: true
method-lines:
enabled: true
config:
threshold: 128
nested-control-flow:
enabled: true
return-statements:
enabled: false
similar-code:
enabled: true
identical-code:
enabled: true
plugins:
duplication:
enabled: true
config:
languages:
- javascript
nodesecurity:
enabled: true
eslint:
enabled: true
channel: "stable"
checks:
complexity:
enabled: false
exclude_patterns:
- "**/test/"
- "**/bench/"
- "**/v0/"
- "**/node_modules/"
module.exports = {extends: ['@commitlint/config-conventional']};
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
tab_width = 2
# Indentation override for all JS under lib directory
[*.js]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
bench/
v0/
node_modules/
logs/
coverage/
node_modules/
.idea/
.vscode/
static/
**/*.xxx.*
dist/
benchmark/
module.exports = {
extends: ['eslint:recommended', 'google'],
parserOptions: {
ecmaVersion: 5
ecmaVersion: 2018,
},
env: {
es6: true,
node: true
node: true,
jest: false,
},
rules: {
'indent': ['error', 2],
'spaced-comment': ['error', 'always', {markers: ['/']}],
'no-console': 'warn',
'no-var': 'off',
'comma-dangle': ['error', 'never'],
'new-cap': ['error', {capIsNewExceptions: ['ObjectId', 'Fastify']}],
'max-len': [
'error',
{
code: 100,
ignoreComments: true
}
]
// 'valid-jsdoc': 'off',
// 'require-jsdoc': 'off',
}
code: 80,
comments: 999,
ignoreComments: true,
ignoreStrings: true,
ignoreTrailingComments: true,
ignoreUrls: true,
ignoreTemplateLiterals: true,
},
],
indent: ['error', 2, {SwitchCase: 1}],
'spaced-comment': ['error', 'always', {markers: ['/']}],
'no-console': 'warn',
'valid-jsdoc': 'off',
'require-jsdoc': 'off',
},
};
.idea
node_modules
.npmrc
npm-debug.log
coverage/
deploy
build
coverage
config/local.*
**/*.xxx.js
**/*.xxx.ts
dist
browser
image: node:latest
cache:
key: "$CI_BUILD_REF_NAME"
untracked: true
paths:
- node_modules/
stages:
- verify
- test
- publish
codestyle:
stage: verify
script:
- npm ci
- npm run lint
# - npm audit
- npm run build
node:8:
stage: test
image: node:8
only:
- /^v\d+\.\d+\.\d+(-rc.\d+|)$/
script:
- npm i
- npm run unit
coverage: /^All files[^|]*\|[^|]*\s+([\d\.]+)/
node:10:
stage: test
image: node:10
only:
- /^v\d+\.\d+\.\d+(-rc.\d+|)$/
script:
- npm i
- npm run unit
coverage: /^All files[^|]*\|[^|]*\s+([\d\.]+)/
node:latest:
stage: test
image: node:latest
script:
- npm i
- npm run unit
coverage: /^All files[^|]*\|[^|]*\s+([\d\.]+)/
npm:
stage: publish
script:
- VERSION_TAG=$([[ $CI_COMMIT_TAG == *"-rc"* ]] && echo "next" || echo "latest")
- echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > .npmrc
- npm ci
- npm run build
- npm publish --tag $VERSION_TAG
environment:
name: npm
url: https://www.npmjs.com/package/${CI_PROJECT_NAME}
when: manual
only:
- /^v\d+\.\d+\.\d+(-rc.\d+|)$/
.vscode
test
tsconfig.json
tslint.json
coverage
.*
*.config.js
docs/
src/
example/
benchmark/
test/
bench/
coverage/
.idea/
.eslintrc
.eslintignore
.*.yml
jest.config.js
language: node_js
node_js:
- "4.0"
- "4"
- "5.0"
- "5"
- "6.0"
- "6"
- "7.0"
- "7"
- "8.0"
- "8"
- "9.0"
- "9"
- "10.0"
- "10"
- "11.0"
- "11"
addons:
code_climate:
repo_token: aa8e46e24b3cb246433fba82c654cee400c6220bf1dc0202d73ca2b2c9e6b101
before_script:
- npm install codeclimate-test-reporter -g
- npm install typescript
script:
- npm run lint
- npm run tsc
- npm run cover
after_script:
- CODECLIMATE_REPO_TOKEN=aa8e46e24b3cb246433fba82c654cee400c6220bf1dc0202d73ca2b2c9e6b101 codeclimate-test-reporter < ./coverage/lcov.info
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"name": "vscode-jest-tests",
"request": "launch",
"args": ["--runInBand"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
},
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/jest",
"--runInBand",
"--coverage",
"false"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
{
"name": "Node Inspector",
"type": "node",
"request": "launch",
"args": ["${workspaceRoot}/test.xxx.ts"],
"runtimeArgs": ["-r", "ts-node/register"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart",
"env": {
"TS_NODE_IGNORE": "false"
}
}
]
}
## 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)) |
# 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.
......@@ -7,5 +7,5 @@ Feel free to contribute to this repo. Changes that improve overall performance,
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`).
4. Update the README.md if necessary and regenerate docs via provided script (`npm run typedoc`).
5. Optionally run benchmarks to ensure that your update does no harm to performance.
ISC License
MIT License
Copyright (c) 2017, Alexander Kureniov
Copyright (c) 2019 m03geek
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.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
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.
\ No newline at end of file
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# 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