Skip to content

Commit 5509661

Browse files
committedOct 2, 2021
feat: improve ts notation and upgrade dependencies
1 parent 9e87e69 commit 5509661

16 files changed

+2783
-4288
lines changed
 

‎.husky/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_

‎.husky/commit-msg

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
yarn commitlint --edit $1

‎.husky/post-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
git update-index --again

‎.husky/pre-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
yarn lint-staged

‎.husky/pre-push

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
yarn test

‎.huskyrc

-8
This file was deleted.

‎AUTHORS.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
### @cookbook/mapper-js is authored by:
22
* Marcos <contact@themgoncalves.com>
33
* Marcos Gonçalves <contact@themgoncalves.com>
4+
* semantic-release-bot <semantic-release-bot@martynus.net>

‎README.md

+47-54
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# @cookbook/mapper-js
2+
23
> Fast, reliable and intuitive object mapping.
34
45
[![NPM Version][npm-image]][npm-url]
@@ -41,7 +42,7 @@ const source = {
4142
person: {
4243
name: {
4344
firstName: 'John',
44-
lastName: 'Doe'
45+
lastName: 'Doe',
4546
},
4647
age: 32,
4748
drinks: ['beer', 'whiskey'],
@@ -51,7 +52,7 @@ const source = {
5152
city: 'Cupertino',
5253
state: 'CA',
5354
postalCode: 95014,
54-
country: 'United States'
55+
country: 'United States',
5556
},
5657
{
5758
street: '1600 Amphitheatre',
@@ -60,12 +61,11 @@ const source = {
6061
postalCode: 94043,
6162
country: 'United States',
6263
},
63-
]
64-
}
65-
}
64+
],
65+
},
66+
};
6667
```
6768

68-
6969
### 2) Create your mapping using dot notation
7070

7171
At this step, we need to create our `mapping` against our data `source`.
@@ -81,14 +81,14 @@ For that, `map()` accepts `single dot notation` path or
8181
`an array of dot notation paths`. E.g.: `map('person.name.firstName')`, `map([person.name.firstName, person.name.lastName]);`'
8282

8383
Those values can be _transformed_ by using the `.transform()` method, which expects a `function` as argument and provides
84-
the selected values as array in the `parameter`.
84+
the selected values as array in the `parameter`.
8585

8686
> For more information about the usage, check the [API Documentation](#api-documentation).
8787
88-
8988
Now let's create our `mapping`!
9089

9190
```js
91+
// mapping.ts
9292
import mapper from '@cookbook/mapper-js';
9393

9494
...
@@ -106,15 +106,14 @@ const mapping = mapper((map) => ({
106106
}));
107107
```
108108

109-
110109
### 3) Create your mapped object
111110

112111
```js
113-
import mapper from '@cookbook/mapper-js';
112+
import mapping from './mapping';
114113
...
115114

116115
const result = mapping(source);
117-
/* outputs
116+
/* outputs
118117
{
119118
person: {
120119
name: 'John Doe',
@@ -151,11 +150,10 @@ const result = mapping(source);
151150
**Return:** `<T>(source: object | object[], options?: Options) => T extends [] ? T[] : T`,
152151
**Signature:** `(mapping: Mapping) => <T>(source: object | object[], options?: Options) => T extends [] ? T[] : T`
153152

154-
155153
**Description:**
156154

157-
`mapper()` is the main method and responsible for mapping the _values_ from your _data source_ against the _mapping instructions_.
158-
It accepts `dot notation` path(s) as `key(s)`.
155+
`mapper()` is the main method and responsible for mapping the _values_ from your _data source_ against the _mapping instructions_.
156+
It accepts `dot notation` path(s) as `key(s)`.
159157

160158
Example:
161159

@@ -173,9 +171,9 @@ const mapping = mapper((map) => ({
173171
}));
174172
```
175173

176-
As a result from the above implementation, `mapper()` return a new `function` to map and compile your _source data_ against your _mapping_.
174+
As a result from the above implementation, `mapper()` return a new `function` to map and compile your _source data_ against your _mapping_.
177175

178-
It accepts an extra (_optional_) argument defining the [_global mapping options_](#mapper-options).
176+
It accepts an extra (_optional_) argument defining the [_global mapping options_](#mapper-options).
179177

180178
Example:
181179

@@ -184,7 +182,7 @@ Example:
184182

185183
mapping(source, options);
186184

187-
/* outputs
185+
/* outputs
188186
{
189187
employee: {
190188
name: 'John',
@@ -203,77 +201,72 @@ mapping(source, options);
203201
}
204202
*/
205203
```
206-
___
207204

205+
---
208206

209207
## map
210208

211209
**Type:** `function`
212-
**Parameter:** `keys: string | string[], options?: Options`
210+
**Parameter:** `keys: string | string[], options?: Options`
213211
**Return:** `MapMethods<T>`,
214212
**Signature:** `<T = unknown>(keys: string | string[], options?: Options) => MapMethods<T>`
215213

216-
**Description:**
214+
**Description:**
217215

218-
`root` method retrieves values from your _source data_ using `dot notation` path, it accepts a string or array of string.
216+
`root` method retrieves values from your _source data_ using `dot notation` path, it accepts a string or array of string.
219217

220-
It accepts an extra (_optional_) argument to define the [_mapping options for current entry_](#mapper-options), _overriding_ the _global mapping options_.
218+
It accepts an extra (_optional_) argument to define the [_mapping options for current entry_](#mapper-options), _overriding_ the _global mapping options_.
221219

222220
Example:
221+
223222
```ts
224223
map('person.name.firstName');
225224
map(['person.name.firstName', 'person.name.lastName']);
226225
map(['person.name.firstName', 'person.name.lastName'], options);
227226
```
228227

229-
230228
#### `transform`
231229

232230
**Type:** `function`
233231
**Parameter:** `...unknown[]`
234232
**Return:** `unknown | unknown[]`,
235233
**Signature:** `(...args: unknown[]) => unknown | unknown[]`
236234

237-
**Description:**
235+
**Description:**
238236

239-
`.transform` method provides you the ability to _transform_ the retrieved value(s) from `map()` according to your needs, and for that, it expects a return value.
237+
`.transform` method provides you the ability to _transform_ the retrieved value(s) from `map()` according to your needs, and for that, it expects a return value.
240238

241-
`.transform` provides you as _parameter_, the retrieved value(s) in the **same order** as defined in the `map()` method, otherwise
239+
`.transform` provides you as _parameter_, the retrieved value(s) in the **same order** as defined in the `map()` method, otherwise
242240

243241
Example:
242+
244243
```ts
245244
// single value
246-
map('person.name.firstName')
247-
.transform((firstName) => firstName.toLoweCase());
245+
map('person.name.firstName').transform((firstName) => firstName.toLoweCase());
248246

249247
// multiple values
250-
map(['person.name.firstName', 'person.name.lastName'])
251-
.transform((firstName, lastName) => `${firstName} ${lastName}`);
248+
map(['person.name.firstName', 'person.name.lastName']).transform((firstName, lastName) => `${firstName} ${lastName}`);
252249
```
253250

254-
255251
#### `value`
256252

257253
**Type:** `readonly`
258254
**Return:** `T`
259-
**Description:**
255+
**Description:**
260256

261-
`.value` returns the value of your `dot notation` query. If transformed, returns the transformed value.
257+
`.value` returns the value of your `dot notation` query. If transformed, returns the transformed value.
262258

263259
Example:
260+
264261
```ts
265262
// single value
266-
map('person.name.firstName')
267-
.transform((firstName) => firstName.toLoweCase())
268-
.value;
263+
map('person.name.firstName').transform((firstName) => firstName.toLoweCase()).value;
269264

270265
// multiple values
271-
map(['person.name.firstName', 'person.name.lastName'])
272-
.transform((firstName, lastName) => `${firstName} ${lastName}`)
273-
.value;
266+
map(['person.name.firstName', 'person.name.lastName']).transform((firstName, lastName) => `${firstName} ${lastName}`)
267+
.value;
274268
```
275269

276-
277270
## Mapper Options
278271

279272
### defaults
@@ -292,9 +285,9 @@ map(['person.name.firstName', 'person.name.lastName'])
292285
**Type:** `boolean`
293286
**default value:** `false`
294287

295-
**Description:**
288+
**Description:**
296289

297-
Removes `null` or `undefined` entries from the _mapped_ object.
290+
Removes `null` or `undefined` entries from the _mapped_ object.
298291

299292
Example:
300293

@@ -309,11 +302,11 @@ Example:
309302
}
310303
*/
311304
const mapping = mapper((map) => ({
312-
'name': map('person.name').value,
313-
'age': map('person.age').value,
314-
// source doesn't have property 'address',
315-
// therefore will return "undefined"
316-
'address': map('person.address').value,
305+
name: map('person.name').value,
306+
age: map('person.age').value,
307+
// source doesn't have property 'address',
308+
// therefore will return "undefined"
309+
address: map('person.address').value,
317310
}));
318311

319312
mapping(source, { omitNullUndefined: true });
@@ -323,7 +316,6 @@ mapping(source, { omitNullUndefined: true });
323316
age: 32,
324317
}
325318
*/
326-
327319
```
328320

329321
**`omitStrategy`**
@@ -333,11 +325,12 @@ mapping(source, { omitNullUndefined: true });
333325
**Return:** `boolean`
334326
**Signature:** `(value: unknown | unknown[]) => boolean`
335327

336-
**Description:**
328+
**Description:**
337329

338-
Defines a _custom strategy_ to omit (_suppress_) entries from the _mapped object_.
330+
Defines a _custom strategy_ to omit (_suppress_) entries from the _mapped object_.
339331

340332
Example:
333+
341334
```tsx
342335
/* source object
343336
{
@@ -359,9 +352,9 @@ Example:
359352
const customOmitStrategy = (address: Record<string, string>): boolean => address && address.city === 'Cupertino';
360353

361354
const mapping = mapper((map) => ({
362-
'name': map('person.name').value,
363-
'age': map('person.age').value,
364-
'address': map('person.address').value,
355+
name: map('person.name').value,
356+
age: map('person.age').value,
357+
address: map('person.address').value,
365358
}));
366359

367360
mapping(source, { omitStrategy: customOmitStrategy });
@@ -371,10 +364,10 @@ mapping(source, { omitStrategy: customOmitStrategy });
371364
age: 32,
372365
}
373366
*/
374-
375367
```
376368

377369
<!-- Markdown link & img dfn's -->
370+
378371
[npm-image]: https://img.shields.io/npm/v/@cookbook/mapper-js.svg?style=flat-square
379372
[npm-url]: https://npmjs.org/package/@cookbook/mapper-js
380373
[npm-downloads]: https://img.shields.io/npm/dm/@cookbook/mapper-js.svg?style=flat-square

‎configurations/eslint/config.js

-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ module.exports = {
4646
'plugin:react/recommended',
4747
'eslint-config-prettier',
4848
'prettier',
49-
'prettier/react',
50-
'prettier/@typescript-eslint',
5149
],
5250
rules: {
5351
'@typescript-eslint/explicit-function-return-type': [

‎configurations/jest/config.js

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ module.exports = {
88
moduleDirectories: ['node_modules', 'src'],
99
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'md'],
1010
moduleNameMapper: {
11-
'^.+\\.(jpg|jpeg|png|gif||otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
12-
'./configurations/jest/__mocks__/file.js',
1311
'^configurations(.*)$': '<rootDir>/configurations$1',
1412
},
1513
collectCoverageFrom: [

‎configurations/prettier/config.js

-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ module.exports = {
55
arrowParens: 'always',
66
singleQuote: true,
77
tabWidth: 2,
8-
jsxBracketSameLine: false,
98
};

‎package.json

+65-58
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,17 @@
2020
"homepage": "https://github.com/the-cookbook/mapper-js#readme",
2121
"keywords": [
2222
"library",
23-
"javascript"
23+
"javascript",
24+
"typescript",
25+
"mapper",
26+
"mapping",
27+
"data-mapping",
28+
"object-mapping",
29+
"dot-notation"
2430
],
2531
"scripts": {
2632
"authors": "node ./scripts/authors.js",
33+
"postinstall": "husky install",
2734
"prepare": "npm run build && npm run authors",
2835
"prepublishOnly": "npm test && npm run lint",
2936
"preversion": "npm run lint",
@@ -46,84 +53,84 @@
4653
"prettier": "prettier -c --write 'src/**/*'"
4754
},
4855
"devDependencies": {
49-
"@babel/cli": "7.12.16",
50-
"@babel/core": "7.12.16",
51-
"@babel/plugin-proposal-class-properties": "7.12.13",
52-
"@babel/plugin-proposal-export-default-from": "7.12.13",
56+
"@babel/cli": "7.15.7",
57+
"@babel/core": "7.15.5",
58+
"@babel/plugin-proposal-class-properties": "7.14.5",
59+
"@babel/plugin-proposal-export-default-from": "7.14.5",
5360
"@babel/plugin-syntax-dynamic-import": "7.8.3",
54-
"@babel/preset-env": "7.12.16",
55-
"@babel/preset-react": "7.12.13",
56-
"@babel/preset-typescript": "7.12.16",
57-
"@commitlint/cli": "11.0.0",
58-
"@commitlint/config-conventional": "11.0.0",
59-
"@semantic-release/git": "9.0.0",
60-
"@semantic-release/github": "7.2.0",
61-
"@types/chai": "4.2.15",
62-
"@types/core-js": "2.5.4",
61+
"@babel/preset-env": "7.15.6",
62+
"@babel/preset-react": "7.14.5",
63+
"@babel/preset-typescript": "7.15.0",
64+
"@commitlint/cli": "13.2.0",
65+
"@commitlint/config-conventional": "13.2.0",
66+
"@semantic-release/git": "v9.0.1",
67+
"@semantic-release/github": "7.2.3",
68+
"@types/chai": "4.2.22",
69+
"@types/core-js": "2.5.5",
6370
"@types/expect": "24.3.0",
64-
"@types/jest": "26.0.20",
65-
"@types/react": "17.0.1",
66-
"@types/react-dom": "17.0.0",
67-
"@types/react-test-renderer": "17.0.0",
68-
"@types/webpack-env": "1.16.0",
69-
"@typescript-eslint/eslint-plugin": "4.15.0",
70-
"@typescript-eslint/parser": "4.15.0",
71+
"@types/jest": "27.0.2",
72+
"@types/react": "17.0.26",
73+
"@types/react-dom": "17.0.9",
74+
"@types/react-test-renderer": "17.0.1",
75+
"@types/webpack-env": "1.16.2",
76+
"@typescript-eslint/eslint-plugin": "4.32.0",
77+
"@typescript-eslint/parser": "4.32.0",
7178
"babel-loader": "8.2.2",
7279
"babel-plugin-dynamic-import-node": "2.3.3",
7380
"babel-plugin-module-resolver": "4.1.0",
7481
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
7582
"babel-plugin-transform-remove-console": "6.9.4",
76-
"chai": "4.3.0",
77-
"commitizen": "4.2.3",
78-
"commitlint": "11.0.0",
79-
"copy-webpack-plugin": "7.0.0",
83+
"chai": "4.3.4",
84+
"commitizen": "4.2.4",
85+
"commitlint": "13.2.0",
86+
"copy-webpack-plugin": "9.0.1",
8087
"cz-conventional-changelog": "3.3.0",
8188
"deepmerge": "4.2.2",
82-
"eslint": "7.19.0",
89+
"eslint": "7.32.0",
8390
"eslint-config-airbnb": "18.2.1",
84-
"eslint-config-prettier": "7.2.0",
91+
"eslint-config-prettier": "8.3.0",
8592
"eslint-plugin-eslint-comments": "3.2.0",
8693
"eslint-plugin-filenames": "1.3.2",
87-
"eslint-plugin-import": "2.22.1",
88-
"eslint-plugin-jest": "24.1.3",
94+
"eslint-plugin-import": "2.24.2",
95+
"eslint-plugin-jest": "24.5.0",
8996
"eslint-plugin-jsx-a11y": "6.4.1",
90-
"eslint-plugin-no-only-tests": "2.4.0",
91-
"eslint-plugin-no-unsanitized": "3.1.4",
92-
"eslint-plugin-optimize-regex": "1.2.0",
93-
"eslint-plugin-prettier": "3.3.1",
94-
"eslint-plugin-react": "7.22.0",
97+
"eslint-plugin-no-only-tests": "2.6.0",
98+
"eslint-plugin-no-unsanitized": "3.1.5",
99+
"eslint-plugin-optimize-regex": "1.2.1",
100+
"eslint-plugin-prettier": "4.0.0",
101+
"eslint-plugin-react": "7.26.1",
95102
"eslint-plugin-react-hooks": "4.2.0",
96-
"eslint-plugin-testing-library": "3.10.1",
97-
"html-webpack-plugin": "5.1.0",
98-
"husky": "4.3.8",
99-
"jest": "26.6.3",
100-
"lint-staged": "10.5.4",
103+
"eslint-plugin-testing-library": "4.12.4",
104+
"html-webpack-plugin": "5.3.2",
105+
"husky": "7.0.2",
106+
"jest": "27.2.4",
107+
"lint-staged": "11.1.2",
101108
"npm-run-all": "4.1.5",
102-
"prettier": "2.2.1",
109+
"prettier": "2.4.1",
103110
"prop-types": "15.7.2",
104-
"react": "17.0.1",
105-
"react-docgen": "5.3.1",
106-
"react-docgen-typescript": "1.21.0",
107-
"react-dom": "17.0.1",
111+
"react": "17.0.2",
112+
"react-docgen": "5.4.0",
113+
"react-docgen-typescript": "2.1.0",
114+
"react-dom": "17.0.2",
108115
"react-hot-loader": "4.13.0",
109-
"react-json-view": "1.21.1",
110-
"react-test-renderer": "17.0.1",
116+
"react-json-view": "1.21.3",
117+
"react-test-renderer": "17.0.2",
111118
"require-all": "3.0.0",
112-
"rollup": "2.38.5",
119+
"rollup": "2.58.0",
113120
"rollup-plugin-commonjs": "10.1.0",
114121
"rollup-plugin-node-resolve": "5.2.0",
115122
"rollup-plugin-terser": "7.0.2",
116-
"source-map-loader": "2.0.1",
117-
"standard-version": "9.1.0",
118-
"start-server-and-test": "1.12.0",
119-
"terser-webpack-plugin": "5.1.1",
120-
"ts-jest": "26.5.1",
121-
"typescript": "4.1.5",
122-
"webpack": "5.21.2",
123-
"webpack-bundle-analyzer": "4.4.0",
124-
"webpack-cli": "4.5.0",
125-
"webpack-dev-server": "3.11.2",
126-
"webpack-merge": "5.7.3"
123+
"source-map-loader": "3.0.0",
124+
"standard-version": "9.3.1",
125+
"start-server-and-test": "1.14.0",
126+
"terser-webpack-plugin": "5.2.4",
127+
"ts-jest": "27.0.5",
128+
"typescript": "4.4.3",
129+
"webpack": "5.56.0",
130+
"webpack-bundle-analyzer": "4.4.2",
131+
"webpack-cli": "4.8.0",
132+
"webpack-dev-server": "4.3.0",
133+
"webpack-merge": "5.8.0"
127134
},
128135
"peerDependencies": {},
129136
"dependencies": {

‎src/map.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type Map = <T = unknown>(keys: string | string[], options?: Options) => MapMetho
1616

1717
const suppress = Symbol('map-suppress');
1818

19-
const map = (source: Record<string, unknown | unknown[]>, mapperOptions: Options = {}): Map => {
19+
const map = (source: Record<string, unknown>, mapperOptions: Options = {}): Map => {
2020
if (!is.object(source)) {
2121
throw new TypeError(`Instance of "source" must be an object, but instead got "${typeOf(source)}"`);
2222
}
@@ -37,7 +37,7 @@ const map = (source: Record<string, unknown | unknown[]>, mapperOptions: Options
3737
const { omitNullUndefined, omitStrategy } = OPTIONS;
3838

3939
if ((is.nullOrUndefined(result) && omitNullUndefined) || (omitStrategy && omitStrategy(result))) {
40-
return (suppress as unknown) as T extends [] ? T[] : T;
40+
return suppress as unknown as T extends [] ? T[] : T;
4141
}
4242

4343
return result as T extends [] ? T[] : T;
@@ -46,11 +46,9 @@ const map = (source: Record<string, unknown | unknown[]>, mapperOptions: Options
4646
};
4747
};
4848

49-
map.omitEntries = (
50-
entries: Record<string, unknown | unknown[]> | Record<string, unknown | unknown[]>[],
51-
): Record<string, unknown | unknown[]> | Record<string, unknown | unknown[]>[] => {
49+
map.omitEntries = <T extends Record<string, unknown>>(entries: T | T[]): T => {
5250
const result = toArray(entries).map((entry) => {
53-
const values: Record<string, unknown | unknown[]> = {};
51+
const values: Record<string, unknown> = {};
5452
const keys = Object.keys(entry);
5553

5654
for (let i = 0; i < keys.length; i += 1) {
@@ -64,7 +62,7 @@ map.omitEntries = (
6462
return values;
6563
});
6664

67-
return is.array(entries) ? result : result[0];
65+
return (is.array(entries) ? result : result[0]) as T;
6866
};
6967

7068
map.suppress = suppress;

‎src/utils/is.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export default {
22
nullOrUndefined: (value: unknown): boolean => value === null || value === undefined,
3-
object: <T>(value: unknown): value is Record<string, T> =>
3+
object: <T = Record<string, unknown>>(value: unknown): value is T =>
44
value !== null && typeof value === 'object' && Object.prototype.toString.call(value) === '[object Object]',
5-
array: <T = unknown>(value: unknown): value is Array<T> => Array.isArray(value),
5+
array: <T>(value: T | Array<T>): value is Array<T> => Array.isArray(value),
66
};

‎src/utils/to-array.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
* Ensure that given value is array, if not, convert it.
33
* @param value
44
*/
5-
const toArray = <T = unknown>(value: T | T[]): Array<T> => (Array.isArray(value) ? value : [value]);
5+
const toArray = <T>(value: T): Array<T> => (Array.isArray(value) ? value : [value]);
66

77
export default toArray;

‎yarn.lock

+2,645-4,153
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.