|
1 |
| -[copy-props][repo-url] [![NPM][npm-img]][npm-url] [![MIT License][mit-img]][mit-url] [![Build Status][travis-img]][travis-url] [![Build Status][appveyor-img]][appveyor-url] [![Coverage Status][coverage-img]][coverage-url] |
2 |
| -============ |
| 1 | +# [copy-props][repo-url] [![NPM][npm-img]][npm-url] [![MIT License][mit-img]][mit-url] [![Build Status][travis-img]][travis-url] [![Build Status][appveyor-img]][appveyor-url] [![Coverage Status][coverage-img]][coverage-url] |
3 | 2 |
|
4 |
| -Copy properties deeply between two objects. |
| 3 | +Copy properties between two objects deeply. |
5 | 4 |
|
6 |
| -Install |
7 |
| -------- |
| 5 | +## Install |
8 | 6 |
|
9 |
| -``` |
| 7 | +To install from npm: |
| 8 | + |
| 9 | +```sh |
10 | 10 | $ npm i copy-props --save
|
11 | 11 | ```
|
12 | 12 |
|
13 |
| -Usage |
14 |
| ------ |
15 |
| - |
16 |
| -* Load this module : |
17 |
| - |
18 |
| - ```js |
19 |
| - const copyProps = require('copy-props'); |
20 |
| - ``` |
21 |
| - |
22 |
| -* Copy *src* to *dst* simply (and return *dst*) : |
23 |
| - |
24 |
| - ```js |
25 |
| - var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc' }; |
26 |
| - var dst = { a: 2, b: { b1: 'xxx', b2: 'yyy' } }; |
27 |
| -
|
28 |
| - copyProps(src, dst); |
29 |
| - // => { a: 1, b: { b1: 'bbb', b2: 'yyy' }, c: 'ccc' } |
30 |
| - ``` |
31 |
| - |
32 |
| -* Copy *src* to *dst* with property mapping (and return *dst*) : |
| 13 | +## Load this module |
33 | 14 |
|
34 |
| - ```js |
35 |
| - var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc', d: 'ddd' }; |
36 |
| - var dst = { f: { a: 2, b1: 'xxx', b2: 'yyy' }, e: 'zzz' }; |
37 |
| -
|
38 |
| - copyProps(src, dst, { |
39 |
| - a: 'f.a', |
40 |
| - 'b.b1': 'f.b1', |
41 |
| - 'b.b2': 'f.b2', |
42 |
| - 'c': 'f.c', |
43 |
| - }); |
44 |
| - // => { f: { a: 1, b1: 'bbb', b2: 'yyy', c: 'ccc' }, e: 'zzz' } |
45 |
| - ``` |
| 15 | +For Node.js: |
46 | 16 |
|
47 |
| -* Copy *src* to *dst* with convert function (and return *dst*) : |
| 17 | +```js |
| 18 | +const copyProps = require('copy-props'); |
| 19 | +``` |
48 | 20 |
|
49 |
| - ```js |
50 |
| - var src = { a: 1, b: { b1: 'bbb' } }; |
51 |
| - var dst = { a: 0 }; |
52 |
| - |
53 |
| - copyProps(src, dst, function(srcInfo) { |
54 |
| - if (srcInfo.keyChain === 'a') { |
55 |
| - return srcInfo.value * 2; |
56 |
| - } |
57 |
| - if (srcInfo.keyChain === 'b.b1') { |
58 |
| - return srcInfo.value.toUpperCase(); |
59 |
| - } |
60 |
| - }); |
61 |
| - // => { a: 2, b: { b1: 'BBB' } } |
62 |
| - ``` |
| 21 | +For Web browser: |
63 | 22 |
|
64 |
| -* Can use an array instead of a map as property mapping : |
| 23 | +```html |
| 24 | +<script src="copy-props.min.js"></script> |
| 25 | +``` |
65 | 26 |
|
66 |
| - ```js |
67 |
| - var src = { a: 1, b: { c: 'CCC' }, d: { e: 'EEE' } }; |
68 |
| - var dst = { a: 9, b: { c: 'xxx' }, d: { e: 'yyy' } }; |
69 |
| - var fromto = [ 'b.c', 'd.e' ]; |
70 |
| - copyProps(src, dst, fromto); |
71 |
| - // => { a: 9, b: { c: 'CCC' }, d: { e: 'EEE' } } |
72 |
| - ``` |
| 27 | +## Usage |
73 | 28 |
|
74 |
| -* Can copy reversively (from *dst* to *src*) by reverse flag (and return *src*): |
| 29 | +Copy *src* to *dst* simply (and return *dst*) : |
75 | 30 |
|
76 |
| - ```js |
77 |
| - var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc' }; |
78 |
| - var dst = { a: 2, b: { b1: 'xxx', b2: 'yyy' } }; |
| 31 | +```js |
| 32 | +var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc' }; |
| 33 | +var dst = { a: 2, b: { b1: 'xxx', b2: 'yyy' } }; |
79 | 34 |
|
80 |
| - copyProps(src, dst, true); |
81 |
| - // => { a: 2, b: { b1: 'xxx', b2: 'yyy' }, c: 'ccc' } |
82 |
| - ``` |
| 35 | +copyProps(src, dst); |
| 36 | +// => { a: 1, b: { b1: 'bbb', b2: 'yyy' }, c: 'ccc' } |
| 37 | +``` |
83 | 38 |
|
84 |
| - ```js |
85 |
| - var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc', d: 'ddd' }; |
86 |
| - var dst = { f: { a: 2, b1: 'xxx', b2: 'yyy' }, e: 'zzz' }; |
| 39 | +Copy *src* to *dst* with property mapping (and return *dst*) : |
87 | 40 |
|
88 |
| - copyProps(src, dst, { |
89 |
| - a: 'f.a', |
90 |
| - 'b.b2': 'f.b2', |
91 |
| - 'c': 'f.c', |
92 |
| - }, true); |
93 |
| - // => { a: 2, b: { b1: 'bbb', b2: 'yyy' }, c: 'ccc', d: 'ddd' } |
94 |
| - ``` |
| 41 | +```js |
| 42 | +var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc', d: 'ddd' }; |
| 43 | +var dst = { f: { a: 2, b1: 'xxx', b2: 'yyy' }, e: 'zzz' }; |
95 | 44 |
|
96 |
| -* If a value of source property is undefined (when not using converter), or a result of converter is undefined (when using converter), the value is not copied. |
| 45 | +copyProps(src, dst, { |
| 46 | + a: 'f.a', |
| 47 | + 'b.b1': 'f.b1', |
| 48 | + 'b.b2': 'f.b2', |
| 49 | + 'c': 'f.c', |
| 50 | +}); |
| 51 | +// => { f: { a: 1, b1: 'bbb', b2: 'yyy', c: 'ccc' }, e: 'zzz' } |
| 52 | +``` |
97 | 53 |
|
98 |
| - ```js |
99 |
| - var src = { a: 'A', b: undefined, c: null, d: 1 }; |
100 |
| - var dst = { a: 'a', b: 'b', c: 'c' }; |
101 |
| -
|
102 |
| - copyProps(src, dst, function(srcInfo) { |
103 |
| - if (srcInfo.keyChain === 'd') { |
104 |
| - return undefined; |
105 |
| - } else { |
106 |
| - return srcInfo.value; |
107 |
| - } |
108 |
| - }); |
109 |
| - // => { a: 'A', b: 'b', c: null } |
110 |
| - ``` |
| 54 | +Copy *src* to *dst* with convert function (and return *dst*) : |
111 | 55 |
|
112 |
| -* You can operate the parent node object directly in converter. |
| 56 | +```js |
| 57 | +var src = { a: 1, b: { b1: 'bbb' } }; |
| 58 | +var dst = { a: 0 }; |
| 59 | + |
| 60 | +copyProps(src, dst, function(srcInfo) { |
| 61 | + if (srcInfo.keyChain === 'a') { |
| 62 | + return srcInfo.value * 2; |
| 63 | + } |
| 64 | + if (srcInfo.keyChain === 'b.b1') { |
| 65 | + return srcInfo.value.toUpperCase(); |
| 66 | + } |
| 67 | +}); |
| 68 | +// => { a: 2, b: { b1: 'BBB' } } |
| 69 | +``` |
113 | 70 |
|
114 |
| - ```js |
115 |
| - var src = { a: 1, b: 2 }; |
116 |
| - var dst = {}; |
117 |
| -
|
118 |
| - copyProps(src, dst, function(srcInfo, dstInfo) { |
119 |
| - Object.defineProperty(dstInfo.parent, dstInfo.key, { |
120 |
| - writable: false, |
121 |
| - enumerable: true, |
122 |
| - configurable: false, |
123 |
| - value: srcInfo.value * 2 |
124 |
| - }) |
125 |
| - }); // => { a: 2, b: 4 } |
126 |
| -
|
127 |
| - dst // => { a: 2, b: 4 } |
128 |
| - dst.a = 9 |
129 |
| - dst // -> { a: 2, b: 4 } |
130 |
| - ``` |
| 71 | +Can use an array instead of a map as property mapping : |
131 | 72 |
|
132 |
| -API |
133 |
| ---- |
| 73 | +```js |
| 74 | +var src = { a: 1, b: { c: 'CCC' }, d: { e: 'EEE' } }; |
| 75 | +var dst = { a: 9, b: { c: 'xxx' }, d: { e: 'yyy' } }; |
| 76 | +var fromto = [ 'b.c', 'd.e' ]; |
| 77 | +copyProps(src, dst, fromto); |
| 78 | +// => { a: 9, b: { c: 'CCC' }, d: { e: 'EEE' } } |
| 79 | +``` |
134 | 80 |
|
135 |
| -### <u>copyProps(src, dst [, fromto] [, converter] [, reverse]) => object</u> |
| 81 | +Can copy reversively (from *dst* to *src*) by reverse flag (and return *src*): |
136 | 82 |
|
137 |
| -Copy properties of *src* to *dst* deeply. |
138 |
| -If *fromto* is given, it is able to copy between different properties. |
139 |
| -If *converter* is given, it is able to convert the terminal values. |
| 83 | +```js |
| 84 | +var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc' }; |
| 85 | +var dst = { a: 2, b: { b1: 'xxx', b2: 'yyy' } }; |
140 | 86 |
|
141 |
| -**Arguments:** |
| 87 | +copyProps(src, dst, true); |
| 88 | +// => { a: 2, b: { b1: 'xxx', b2: 'yyy' }, c: 'ccc' } |
| 89 | +``` |
142 | 90 |
|
143 |
| -* **src** [object] : a source object of copy. |
144 |
| -* **dst** [object] : a destinate object of copy. |
145 |
| -* **fromto** [object | array] : an object mapping properties between *src* and *dst*. (optional) |
146 |
| -* **converter** [function] : a function to convert terminal values in *src*. (optional) |
147 |
| -* **reverse** [boolean] : copys reversively from dst to src and returns src object. `fromto` is also reversively used from value to key. This default value is `false`. (optional) |
| 91 | +```js |
| 92 | +var src = { a: 1, b: { b1: 'bbb' }, c: 'ccc', d: 'ddd' }; |
| 93 | +var dst = { f: { a: 2, b1: 'xxx', b2: 'yyy' }, e: 'zzz' }; |
148 | 94 |
|
149 |
| -**Return** [object] : *dst* object after copying. |
| 95 | +copyProps(src, dst, { |
| 96 | + a: 'f.a', |
| 97 | + 'b.b2': 'f.b2', |
| 98 | + 'c': 'f.c', |
| 99 | +}, true); |
| 100 | +// => { a: 2, b: { b1: 'bbb', b2: 'yyy' }, c: 'ccc', d: 'ddd' } |
| 101 | +``` |
150 | 102 |
|
151 |
| -#### *Format of fromto* |
| 103 | +If a value of source property is undefined (when not using converter), or a result of converter is undefined (when using converter), the value is not copied. |
152 | 104 |
|
153 |
| -*fromto* is a non-nested key-value object. And the *key*s are property key chains of *src* and the *value*s are property key chains of *dst*. |
154 |
| -The key chain is a string which is concatenated property keys on each level with dots, like `'aaa.bbb.ccc'`. |
| 105 | +```js |
| 106 | +var src = { a: 'A', b: undefined, c: null, d: 1 }; |
| 107 | +var dst = { a: 'a', b: 'b', c: 'c' }; |
| 108 | + |
| 109 | +copyProps(src, dst, function(srcInfo) { |
| 110 | + if (srcInfo.keyChain === 'd') { |
| 111 | + return undefined; |
| 112 | + } else { |
| 113 | + return srcInfo.value; |
| 114 | + } |
| 115 | +}); |
| 116 | +// => { a: 'A', b: 'b', c: null } |
| 117 | +``` |
155 | 118 |
|
156 |
| -The following example copys the value of `src.aaa.bbb.ccc` to `dst.xxx.yyy`. |
| 119 | +You can operate the parent node object directly in converter. |
157 | 120 |
|
158 | 121 | ```js
|
159 |
| -copyProps(src, dst, { |
160 |
| - 'aaa.bbb.ccc' : 'xxx.yyy' |
161 |
| -}) |
| 122 | +var src = { a: 1, b: 2 }; |
| 123 | +var dst = {}; |
| 124 | + |
| 125 | +copyProps(src, dst, function(srcInfo, dstInfo) { |
| 126 | + Object.defineProperty(dstInfo.parent, dstInfo.key, { |
| 127 | + writable: false, |
| 128 | + enumerable: true, |
| 129 | + configurable: false, |
| 130 | + value: srcInfo.value * 2 |
| 131 | + }) |
| 132 | +}); // => { a: 2, b: 4 } |
| 133 | + |
| 134 | +dst // => { a: 2, b: 4 } |
| 135 | +dst.a = 9 |
| 136 | +dst // -> { a: 2, b: 4 } |
162 | 137 | ```
|
163 | 138 |
|
164 |
| -*fromto* can be an array. In that case, the array works as a map which has pairs of same key and value. |
| 139 | +## API |
165 | 140 |
|
166 |
| -#### *API of converter* |
| 141 | +### <u>copyProps(src, dst [, fromto] [, converter] [, reverse]) => object</u> |
167 | 142 |
|
168 |
| -**<u>converter(srcInfo, dstInfo) => any</u>** |
| 143 | +Copy properties of *src* to *dst* deeply. |
| 144 | +If *fromto* is given, it is able to copy between different properties. |
| 145 | +If *converter* is given, it is able to convert the terminal values. |
| 146 | + |
| 147 | +#### Parameters: |
169 | 148 |
|
170 |
| -*converter* is a function to convert terminal values of propeerties of *src*. |
| 149 | +| Parameter | Type | Description | |
| 150 | +|:------------|:------:|:-------------------------------------------------| |
| 151 | +| *src* | object | A source object of copy. | |
| 152 | +| *dst* | object | A destinate object of copy. | |
| 153 | +| *fromto* | object | array | An object mapping properties between *src* and *dst*. (Optional) | |
| 154 | +| *converter* |function| A function to convert terminal values in *src*. (Optional) | |
| 155 | +| *reverse* |boolean | True, if copying reversively from dst to src and returns src object. `fromto` is also reversively used from value to key. This default value is `false`. (Optional) | |
171 | 156 |
|
172 |
| -**Arguments:** |
| 157 | +#### Returns: |
173 | 158 |
|
174 |
| -* **srcInfo** [object] : an object which has informations about the current node of *src*. This object has following properties: |
| 159 | +*dst* object after copying. |
175 | 160 |
|
176 |
| - * **value** : The value of the current node. |
177 |
| - * **key** : The key name of the current node. |
178 |
| - * **keyChain** : The full key of the current node concatenated with dot. |
179 |
| - * **depth** : The depth of the current node. |
180 |
| - * **parent** : The parent node of the current node. |
| 161 | +**Type:** object |
181 | 162 |
|
182 |
| -* **dstInfo** [object] : an object which has informations about the current node of *dst*. This object has following properties: |
| 163 | +* **Format of <i>fromto</i>** |
183 | 164 |
|
184 |
| - * **value** : The value of the current node. |
185 |
| - * **key** : The key name of the current node. |
186 |
| - * **keyChain** : The full key of the current node concatenated with dot. |
187 |
| - * **depth** : The depth of the current node. |
188 |
| - * **parent** : The parent node of the current node. |
| 165 | + *fromto* is a non-nested key-value object. And the *key*s are property key chains of *src* and the *value*s are property key chains of *dst*. |
| 166 | + The key chain is a string which is concatenated property keys on each level with dots, like `'aaa.bbb.ccc'`. |
189 | 167 |
|
| 168 | + The following example copys the value of `src.aaa.bbb.ccc` to `dst.xxx.yyy`. |
190 | 169 |
|
191 |
| -**Return:** [any] : converted value to be set as a destination property value. If this value is undefined, the destination property is not set to the destination node object. |
| 170 | + ```js |
| 171 | + copyProps(src, dst, { |
| 172 | + 'aaa.bbb.ccc' : 'xxx.yyy' |
| 173 | + }) |
| 174 | + ``` |
192 | 175 |
|
193 |
| -License |
194 |
| -------- |
| 176 | + *fromto* can be an array. In that case, the array works as a map which has pairs of same key and value. |
| 177 | + |
| 178 | +* **API of <i>converter</i>** |
| 179 | + |
| 180 | + **<u>converter(srcInfo, dstInfo) : Any</u>** |
| 181 | + |
| 182 | + *converter* is a function to convert terminal values of propeerties of *src*. |
| 183 | + |
| 184 | + **Parameters:** |
| 185 | + |
| 186 | + | Parameter | Type | Description | |
| 187 | + |:------------|:------:|:---------------------------------------------| |
| 188 | + | *srcInfo* | object | An object which has informations about the current node of *src*. | |
| 189 | + | *dstInfo* | object | An object which has informations about the current node of *dst*. | |
| 190 | + |
| 191 | + **Return:** |
| 192 | + |
| 193 | + The converted value to be set as a destination property value. If this value is undefined, the destination property is not set to the destination node object. |
| 194 | + |
| 195 | + **Type:** *Any* |
| 196 | + |
| 197 | + * **Properties of <i>srcInfo</i> and <i>dstInfo</i>** |
| 198 | + |
| 199 | + *srcInfo* and *dstInfo* has same properties, as follows: |
| 200 | + |
| 201 | + | Property | Type | Description | |
| 202 | + |:-----------|:------:|:------------------------------------------| |
| 203 | + | *value* | *Any* | The value of the current node. | |
| 204 | + | *key* | string | The key name of the current node. | |
| 205 | + | *keyChain* | string | The full key of the current node concatenated with dot. | |
| 206 | + | *depth* | number | The depth of the current node. | |
| 207 | + | *parent* | object | The parent node of the current node. | |
| 208 | + |
| 209 | + |
| 210 | +## License |
195 | 211 |
|
196 | 212 | Copyright (C) 2016-2018 Takayuki Sato
|
197 | 213 |
|
|
0 commit comments