Skip to content

Commit df3adc4

Browse files
committed
Merge branch 'upgrade/typescript'
2 parents 936d281 + 154c9fb commit df3adc4

16 files changed

+385
-230
lines changed

.eslintrc.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/coverage/
2+
/lib/
23
/node_modules/
4+
/typings/
35
/npm-debug.log

.npmignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/coverage/
2-
/test/
2+
/typings/
3+
/src/
4+
/lib/*.test.*
35
/.editorconfig
4-
/.eslintrc.yml
56
/.gitignore
67
/.travis.yml
8+
/tsconfig.json
9+
/tslint.json

.travis.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ node_js:
44
- "4"
55
- "0.12"
66
- "0.10"
7+
before_script:
8+
- npm run ci:typings
79
after_success:
8-
- npm run coveralls
10+
- npm run ci:coveralls
11+
before_deploy:
12+
- npm run build
913
deploy:
1014
provider: npm
1115
email:
@@ -17,3 +21,5 @@ deploy:
1721
repo: akim-mcmath/deep-map-keys
1822
node: "4"
1923
tags: true
24+
after_deploy:
25+
- npm run build:remove

README.md

Lines changed: 70 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
# deep-map-keys
1+
# Deep Map Keys
22

33
[![Version][version-badge]][npm]
44
[![License][license-badge]][license]
55
[![Build][build-badge]][travis]
66
[![Coverage][coverage-badge]][coveralls]
77
[![Dependencies][dependencies-badge]][gemnasium]
88

9-
Recurses through a JSON-like object and transforms its keys, returning a new object.
9+
**Deep Map Keys** recurses through an object and transforms its keys – and
10+
the keys of any nested objects – according to some function.
1011

1112
## Install
1213

13-
Install via [npm][npm].
14+
Install Deep Map Keys via [npm][npm].
1415

1516
```sh
1617
npm install --save deep-map-keys
@@ -38,8 +39,11 @@ let comment = {
3839
let result = deepMapKeys(comment, key => {
3940
return key.replace(/_(\w)/g, (match, char) => char.toUpperCase());
4041
});
42+
```
43+
44+
And the result will look like this:
4145

42-
console.log(result); /*
46+
```js
4347
{
4448
commentId: 42,
4549
userId: 1024,
@@ -49,46 +53,75 @@ console.log(result); /*
4953
{ userId: 3820, userName: 'Rafiki' },
5054
{ userId: 8391, userName: 'Zazu' }
5155
]
52-
};
53-
*/
56+
}
5457
```
5558

5659
## API
5760

58-
### `deepMapKeys(object, transformFn, [options])`
59-
60-
Applies `transformFn` to each key in an object. Keys are visited recursively,
61-
so nested keys will be transformed. A new object is always returned; the
62-
original object is unmodified.
63-
64-
##### object
65-
66-
`object`
67-
68-
The object whose keys are to be transformed. This object may be an `Array`.
69-
70-
##### transformFn
71-
72-
`function`
73-
74-
The function to call for each key. The return value of the function
75-
determines the transformed value. The function is called with a single
76-
argument:
77-
78-
* **key**: The key being transformed.
79-
80-
##### options
81-
82-
`object` (optional)
83-
84-
An options object. The following options are accepted:
85-
86-
* **thisArg**: Sets the value of `this` within `transformFn`.
61+
#### `deepMapKeys(object, mapFn, [options])`
62+
63+
#### Parameters
64+
65+
<table>
66+
<thead>
67+
<tr>
68+
<th align="left">Param</th>
69+
<th align="left">Type</th>
70+
<th align="left">Description</th>
71+
</tr>
72+
</thead>
73+
<tbody>
74+
<tr>
75+
<td>object</td>
76+
<td><code>any</code></td>
77+
<td>
78+
The object whose keys are to be transformed. Typically, this will be
79+
a complex object containing other nested objects. This object may be an
80+
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">
81+
<code>Array</code></a>, in which case the keys of any objects it
82+
contains will be transformed.
83+
</td>
84+
</tr>
85+
<tr>
86+
<td>mapFn</td>
87+
<td><code>function</code></td>
88+
<td>
89+
The function used to transform each key. The function is
90+
called with two arguments:
91+
<ul>
92+
<li>
93+
<strong>key</strong> &lt;<code>string</code>&gt;
94+
The key being transformed
95+
</li>
96+
<li>
97+
<strong>value</strong> &lt;<code>any</code>&gt;
98+
The value of the node whose key is being transformed
99+
</li>
100+
</ul>
101+
The return value determines the new name of the key, and must therefore
102+
be a string.
103+
</td>
104+
</tr>
105+
<tr>
106+
<td>[options]</td>
107+
<td><code>object</code></td>
108+
<td>
109+
An optional options object. The following option is accepted:
110+
<ul>
111+
<li>
112+
<strong>thisArg</strong> &lt;<code>any = undefined</code>&gt;
113+
Sets the value of
114+
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this"><code>this</code></a>
115+
within <code>mapFn()</code>
116+
</li>
117+
</ul>
118+
</td>
119+
</tr>
120+
</tbody>
121+
</table>
87122

88123
#### Returns
89124

90-
`object`
91-
92125
Returns a new object.
93126

94127
## License

lib/index.js

Lines changed: 4 additions & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
{
22
"name": "deep-map-keys",
33
"version": "1.0.0",
4-
"description": "Transforms keys of a JSON-like object",
4+
"description": "Transforms nested keys of complex objects",
55
"main": "lib/index.js",
6+
"typings": "lib/index.d.ts",
67
"scripts": {
7-
"test:lint": "eslint lib",
8-
"test:unit": "istanbul cover _mocha",
8+
"build:compile": "tsc",
9+
"build:remove": "rimraf lib",
10+
"build": "npm run build:remove && npm run build:compile",
11+
"test:lint": "tslint 'src/**/*.ts'",
12+
"test:unit": "istanbul cover -e .ts -x '*.test.ts' _mocha -- 'src/**/*.test.ts' --compilers ts:ts-node/register",
13+
"test:report": "npm test && open coverage/lcov-report/index.html",
914
"test": "npm run test:lint && npm run test:unit",
10-
"coveralls": "cat coverage/lcov.info | coveralls"
15+
"ci:typings": "typings install",
16+
"ci:coveralls": "cat coverage/lcov.info | coveralls"
1117
},
1218
"engines": {
1319
"node": ">=0.10"
@@ -20,19 +26,24 @@
2026
"nested",
2127
"object",
2228
"array",
23-
"json"
29+
"json",
30+
"typescript",
31+
"typings"
2432
],
2533
"author": "Akim McMath <[email protected]>",
2634
"license": "MIT",
2735
"devDependencies": {
2836
"chai": "^3.5.0",
29-
"coffee-script": "^1.10.0",
3037
"coveralls": "^2.11.9",
31-
"eslint": "^2.12.0",
32-
"istanbul": "^0.4.3",
38+
"istanbul": "1.0.0-alpha.2",
3339
"mocha": "^2.5.3",
40+
"rimraf": "^2.5.2",
3441
"sinon": "^1.17.4",
35-
"sinon-chai": "^2.8.0"
42+
"sinon-chai": "^2.8.0",
43+
"ts-node": "^0.9.1",
44+
"tslint": "^3.11.0",
45+
"typescript": "^1.8.10",
46+
"typings": "^1.1.0"
3647
},
3748
"dependencies": {},
3849
"repository": {

src/deep-map-keys.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {isArray, isFunction, isObject, isVoid} from './lang';
2+
3+
export interface MapFn {
4+
(key: string, value: any): string;
5+
}
6+
7+
export interface Options {
8+
thisArg?: any;
9+
}
10+
11+
export function deepMapKeys<T>(object: any, mapFn: MapFn, options?: Options): T {
12+
options = isVoid(options) ? {} : options;
13+
14+
if (!mapFn) {
15+
throw new Error('mapFn is required');
16+
} else if (!isFunction(mapFn)) {
17+
throw new TypeError('mapFn must be a function');
18+
} else if (!isObject(options)) {
19+
throw new TypeError('options must be an object');
20+
}
21+
22+
return map(object, mapFn, options);
23+
}
24+
25+
function map(value: any, fn: MapFn, opts: Options): any {
26+
return isArray(value) ? mapArray(value, fn, opts) :
27+
isObject(value) ? mapObject(value, fn, opts) :
28+
value;
29+
}
30+
31+
function mapArray(arr: any[], fn: MapFn, opts: Options): any[] {
32+
let result: any[] = [];
33+
let len = arr.length;
34+
35+
for (let i = 0; i < len; i++) {
36+
result.push(map(arr[i], fn, opts));
37+
}
38+
39+
return result;
40+
}
41+
42+
function mapObject(obj: {[key: string]: any}, fn: MapFn, opts: Options): {[key: string]: any} {
43+
let result: {[key: string]: any} = {};
44+
45+
for (let key in obj) {
46+
let value = obj[key];
47+
result[fn.call(opts.thisArg, key, value)] = map(value, fn, opts);
48+
}
49+
50+
return result;
51+
}

0 commit comments

Comments
 (0)