Skip to content

Commit

Permalink
Merge branch 'master' of github.com:matdurand/smart-diff
Browse files Browse the repository at this point in the history
  • Loading branch information
matdurand committed Oct 19, 2020
2 parents 9ee1778 + 64bea86 commit 2a86512
Show file tree
Hide file tree
Showing 9 changed files with 749 additions and 240 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on: [push]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setup Node.js 10.15.0
uses: actions/setup-node@v1
with:
node-version: 10.15.0
- name: install
run: npm ci
- name: lint
run: npm run lint
- name: test
run: npm run test:cov
- name: build
run: npm run build
30 changes: 30 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: RELEASE

on:
create:
tags:
- v*

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10.15.0
- name: install
run: npm ci
- name: lint
run: npm run lint
- name: test
run: npm run test:cov
- name: build
run: npm run build
- name: publish
env:
CI: true
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
npm publish
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,56 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [1.5.1](https://github.com/matdurand/smart-diff/compare/v1.5.0...v1.5.1) (2020-03-31)


### Bug Fixes

* apply transformations for new and deleted properties ([af35dc1](https://github.com/matdurand/smart-diff/commit/af35dc1b66171c815cd4842391ca34d46138803d))

## [1.5.0](https://github.com/matdurand/smart-diff/compare/v1.4.2...v1.5.0) (2020-03-31)


### Features

* added the deepCompare option to control nested flattening ([3e69e79](https://github.com/matdurand/smart-diff/commit/3e69e79f78b61d2e6d088ef6660cc22c52cda661))

### [1.4.2](https://github.com/matdurand/smart-diff/compare/v1.4.1...v1.4.2) (2020-03-31)


### Bug Fixes

* remove core-js and added flatMap as a polyfill ([e6558a1](https://github.com/matdurand/smart-diff/commit/e6558a10378aff6dc95c900ef4fd8fb3229a93e6))

### [1.4.1](https://github.com/matdurand/smart-diff/compare/v1.4.0...v1.4.1) (2020-03-31)


### Bug Fixes

* output nested objects vs null when using pathFilter ([859037c](https://github.com/matdurand/smart-diff/commit/859037c2043052c99b394e601e3a2af6bf3cbfd4))

## [1.4.0](https://github.com/matdurand/smart-diff/compare/v1.3.1...v1.4.0) (2020-03-31)


### Features

* output nested objects vs null as list of differences ([591d16d](https://github.com/matdurand/smart-diff/commit/591d16d25fdb0db260ae77f4188c1b8cf92b834a))

### [1.3.1](https://github.com/matdurand/smart-diff/compare/v1.3.0...v1.3.1) (2020-03-29)


### Bug Fixes

* github action npm publish ([c028803](https://github.com/matdurand/smart-diff/commit/c028803431183db85a6af803e93b31962983de71))

## [1.3.0](https://github.com/matdurand/smart-diff/compare/v1.2.0...v1.3.0) (2020-03-29)


### Features

* added support for dates transformations ([1f235cc](https://github.com/matdurand/smart-diff/commit/1f235ccc15898164a1b0bbc728f363b6edb595ae))
* setup github actions ([9eec664](https://github.com/matdurand/smart-diff/commit/9eec6646b99a61a1ebdd4e5ef1775c3fdad4268a))

## 1.2.0 (2020-03-28)


Expand Down
183 changes: 183 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,186 @@ For yarn
```
yarn add smart-differences
```

## Usage

Here is an example of how to use the library:

```
const johnProfile = { age: 19, name: "john", emails: { primary: "john@example.com" } };
const fredProfile = { age: 32, name: "fred",
emails: { primary: "fred@example.com", work: "fred@mycompany.com" }
};
const diffs = getDifferences(johnProfile, fredProfile);
console.log(diffs);
```

This would print the following:
```
{
'age': { left: 19, right: 32 },
'name': { left: 'john', right: 'fred' },
'emails.primary': { left: 'john@example.com', right: 'fred@example.com' },
'emails.work': { left: undefined, right: 'fred@mycompany.com' }
}
```

### Customizing the comparaison

There is 3 main ways to customize the comparaison using the options:

#### pathFilter

Used to include or exclude some path from the comparaison. Using the same objects as above (fred and john):
```
const whitelistProperties = (properties: string[]): PathFilter => {
return (paths: string[]) => {
return paths.filter(x => properties.includes(x)).length > 0;
};
};
const blacklistProperties = (properties: string[]): PathFilter => {
return (paths: string[]) => {
return paths.filter(x => properties.includes(x)).length === 0;
};
};
const diffsWhitelist = getDifferences(johnProfile, fredProfile, {
pathFilter: whitelistProperties(["age", "name"])
});
const diffsBlacklist = getDifferences(johnProfile, fredProfile, {
pathFilter: blacklistProperties(["age", "name"])
});
console.log(diffsWhitelist);
console.log(diffsBlacklist);
```

would return

```
//whitelist
{
age: { left: 19, right: 32 },
name: { left: 'john', right: 'fred' }
}
/blacklist
{
'emails.primary': { left: 'john@example.com', right: 'fred@example.com' },
'emails.work': { left: undefined, right: 'fred@mycompany.com' }
}
```

Beware when using pathFiltering and not using the deepCompare option below, you will
receive the head property of a nested object, not not the properties below. For example
(based on the deepCompare example below), your filter would receive:
```
[name, favoriteSong]
```

When using deepCompare, it would receive:
```
[name, favoriteSong.name, favoriteSong.artist.name, favoriteSong.year]
```

#### deepCompare

Deep compare is an option used when one side of the comparaison is null or undefined, and the other side is an
object.

Here is two output of the same compare with and without deepCompare.

```
const object1 = {
name: "John",
favoriteSong: {
name: "Winter Wonderland",
artist: {
name: "Felix Bernard"
},
year: 1934
}
};
const object2 = {
name: "Fred"
};
```

```
//with deepCompare, the differences would be
{
name: { left: 'John', right: 'Fred' },
'favoriteSong.name': { left: 'Winter Wonderland', right: undefined },
'favoriteSong.artist.name': { left: 'Felix Bernard', right: undefined },
'favoriteSong.year': { left: 1934, right: undefined }
}
//without deepCompare
{
name: { left: 'John', right: 'Fred' },
favoriteSong: {
left: {
name: 'Winter Wonderland',
artist: {
name: "Felix Bernard"
},
year: 1934
},
right: undefined
}
}
```

#### Transformations

You can also apply transformations to the values before compare, for example to ignore case or extra spaces.

The first way to do it is globally using the `compareTransformations` option. The library export an object named
`StringTransformations` with a couple of predefined function, but you can build your own.

```
const diffs = getDifferences(
johnProfile,
{ ...johnProfile, name: "JOHn", emails: { primary: "JOHn@example.COM" } },
{
compareTransformations: [StringTransformations.uppercase]
}
);
```
would return no differences.

You can also apply the transformations for each property individually using the `pathCompareTransformationsProvider`.

```
const diffs = getDifferences(
johnProfile,
{ ...johnProfile, name: " john", emails: { primary: " john@example.com" } },
{
pathCompareTransformationsProvider: (pathElements: string[]) => {
const property = pathElements.join(".");
//trim, but only for emails.primary
if (property === "emails.primary") {
return [StringTransformations.trim];
}
return null;
}
}
);
```

would only trim the spaces for the primary email, and would still detect a difference for the extra spaces in the name
property. It would print

```
{
name: { left: 'john', right: ' john' }
}
```

When you return null or undefined in the `pathCompareTransformationsProvider` function, no transformations are applied.
If you defined some transformations in the `compareTransformations` option, they are only applied if the
`pathCompareTransformationsProvider` function returns null or undefined.

## Known issues

Right now, this library doesn't work when comparing `Array` properties. This is gonna be
available in the next release.
27 changes: 18 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "smart-differences",
"version": "1.2.0",
"version": "1.5.1",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -44,6 +44,7 @@
"jest-expect-message": "^1.0.2",
"lint-staged": "10.0.9",
"lodash": "4.17.15",
"moment": "2.24.0",
"prettier": "1.19.1",
"rollup-plugin-typescript2": "0.27.0",
"standard-version": "^7.1.0",
Expand All @@ -58,12 +59,13 @@
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
"pre-commit": "lint-staged",
"pre-push": "lint-staged && npm run test:cov"
}
},
"lint-staged": {
"*.{ts,js,json}": [
"prettier --write",
"*.{ts}": [
"npm run lint -- --fix",
"git add"
]
},
Expand Down
Loading

0 comments on commit 2a86512

Please sign in to comment.