jfather 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +275 -51
- package/package.json +9 -9
- package/src/index.js +2 -2
- package/src/jfather.js +27 -18
- package/types/index.d.ts +2 -0
- package/types/jfather.d.ts +2 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -10,100 +10,324 @@
|
|
|
10
10
|
[![coverage][img-coverage]][link-coverage]
|
|
11
11
|
[![semver][img-semver]][link-semver]
|
|
12
12
|
|
|
13
|
-
>
|
|
13
|
+
> _Boys use JSON; Men use JFather._
|
|
14
14
|
|
|
15
15
|
## Overview
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
[JSON](https://www.json.org/json-fr.html "JavaScript Object Notation")
|
|
19
|
-
features to merge, extend and override JSON objects.
|
|
17
|
+
JFather is a utility library to **merge**, **extend** and **override**
|
|
18
|
+
[JSON](https://www.json.org/json-fr.html "JavaScript Object Notation") objects.
|
|
20
19
|
|
|
21
20
|
```JavaScript
|
|
22
21
|
import JFather from "jfather";
|
|
23
22
|
|
|
23
|
+
// Merge two objects.
|
|
24
24
|
const merged = JFather.merge(
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
{ "foo": "a", "bar": "alpha" },
|
|
26
|
+
{ "foo": "b", "baz": "beta" }
|
|
27
27
|
);
|
|
28
|
-
|
|
29
28
|
console.log(merged);
|
|
30
|
-
// { foo: "b", bar: "alpha", baz: "beta" }
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Install
|
|
29
|
+
// { "foo": "b", "bar": "alpha", "baz": "beta" }
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
// Extend an object.
|
|
32
|
+
const extended = await JFather.extend({
|
|
33
|
+
"$extends": "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json#members[1]",
|
|
34
|
+
"age": 34,
|
|
35
|
+
"quote": "With great fist comes great KO"
|
|
36
|
+
});
|
|
37
|
+
console.log(extended);
|
|
38
|
+
// {
|
|
39
|
+
// "name": "Madame Uppercut",
|
|
40
|
+
// "age": 34,
|
|
41
|
+
// "secretIdentity": "Jane Wilson",
|
|
42
|
+
// "powers": [
|
|
43
|
+
// "Million tonne punch",
|
|
44
|
+
// "Damage resistance",
|
|
45
|
+
// "Superhuman reflexes"
|
|
46
|
+
// ],
|
|
47
|
+
// "quote": "With great fist comes great KO"
|
|
48
|
+
// }
|
|
36
49
|
|
|
37
|
-
|
|
50
|
+
// Override an object.
|
|
51
|
+
const overridden = await JFather.merge(
|
|
52
|
+
{ "foo": ["a", "alpha"] },
|
|
53
|
+
{ "$foo[0]": "A", "$foo[]": ["BETA"] }
|
|
54
|
+
);
|
|
55
|
+
console.log(overridden);
|
|
56
|
+
// {
|
|
57
|
+
// "foo": ["A", "alpha", "BETA"]
|
|
58
|
+
// }
|
|
38
59
|
|
|
39
|
-
|
|
40
|
-
|
|
60
|
+
// Extend, merge and override an object.
|
|
61
|
+
const allIn = await JFather.extend({
|
|
62
|
+
"$extends": "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json#members[0]",
|
|
63
|
+
"age": 27,
|
|
64
|
+
"$powers[2]": "Atomic breath",
|
|
65
|
+
"$powers[]": ["Matter Creation", "Reality Warping"],
|
|
66
|
+
"quote": "I'm no God. I'm not even a man. I'm just Molecule Man."
|
|
67
|
+
});
|
|
68
|
+
console.log(allIn);
|
|
69
|
+
// {
|
|
70
|
+
// "name": "Molecule Man",
|
|
71
|
+
// "age": 27,
|
|
72
|
+
// "secretIdentity": "Dan Jukes",
|
|
73
|
+
// "powers": [
|
|
74
|
+
// "Radiation resistance",
|
|
75
|
+
// "Turning tiny",
|
|
76
|
+
// "Atomic breath",
|
|
77
|
+
// "Matter Creation",
|
|
78
|
+
// "Reality Warping
|
|
79
|
+
// ],
|
|
80
|
+
// "quote": "I'm no God. I'm not even a man. I'm just Molecule Man."
|
|
81
|
+
// }
|
|
41
82
|
```
|
|
42
83
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
The library is available in [Deno](https://deno.land/x/jfather).
|
|
84
|
+
## Installation
|
|
46
85
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Browsers
|
|
52
|
-
|
|
53
|
-
It can also be accessed directly from the CDN
|
|
54
|
-
[esm.sh](https://esm.sh/jfather) (ou
|
|
86
|
+
JFather is published on [npm][link-npm] (its CDN:
|
|
87
|
+
[esm.sh](https://esm.sh/jfather),
|
|
55
88
|
[jsDelivr](https://www.jsdelivr.com/package/npm/jfather),
|
|
56
|
-
[UNPKG](https://unpkg.com/browse/jfather/))
|
|
89
|
+
[UNPKG](https://unpkg.com/browse/jfather/)) and
|
|
90
|
+
[Deno](https://deno.land/x/jfather).
|
|
57
91
|
|
|
58
92
|
```JavaScript
|
|
93
|
+
// Node.js and Bun (after `npm install jfather`):
|
|
94
|
+
import JFather from "jfather";
|
|
95
|
+
|
|
96
|
+
// Browsers:
|
|
59
97
|
import JFather from "https://esm.sh/jfather@0";
|
|
60
|
-
|
|
61
|
-
|
|
98
|
+
import JFather from "https://cdn.jsdelivr.net/npm/jfather@0";
|
|
99
|
+
import JFather from "https://unpkg.com/jfather@0";
|
|
100
|
+
|
|
101
|
+
// Deno:
|
|
102
|
+
import JFather from "https://deno.land/x/jfather/mod.js";
|
|
62
103
|
```
|
|
63
104
|
|
|
64
|
-
##
|
|
105
|
+
## Features
|
|
65
106
|
|
|
66
|
-
|
|
67
|
-
- [`load()`](#load)
|
|
68
|
-
- [`parse()`](#parse)
|
|
107
|
+
### Merge
|
|
69
108
|
|
|
70
|
-
|
|
109
|
+
<!-- markdownlint-disable no-inline-html -->
|
|
110
|
+
<table>
|
|
111
|
+
<tr>
|
|
112
|
+
<th><code>parent</code></th>
|
|
113
|
+
<th><code>child</code></th>
|
|
114
|
+
<th><code>JFather.merge(parent, child)</code></th>
|
|
115
|
+
</tr>
|
|
116
|
+
<tr>
|
|
117
|
+
<td><pre lang="JSON"><code>1</code></pre></td>
|
|
118
|
+
<td><pre lang="JSON"><code>2</code></pre></td>
|
|
119
|
+
<td><pre lang="JSON"><code>2</code></pre></td>
|
|
120
|
+
</tr>
|
|
121
|
+
<tr>
|
|
122
|
+
<td><pre lang="JSON"><code>{
|
|
123
|
+
"foo": "alpha",
|
|
124
|
+
"bar": "ALPHA"
|
|
125
|
+
}</code></pre></td>
|
|
126
|
+
<td><pre lang="JSON"><code>{
|
|
127
|
+
"foo": "beta",
|
|
128
|
+
"baz": "BETA"
|
|
129
|
+
}</code></pre></td>
|
|
130
|
+
<td><pre lang="JSON"><code>{
|
|
131
|
+
"foo": "beta",
|
|
132
|
+
"bar": "ALPHA",
|
|
133
|
+
"baz": "BETA"
|
|
134
|
+
}</code></pre></td>
|
|
135
|
+
</tr>
|
|
136
|
+
<tr>
|
|
137
|
+
<td><pre lang="JSON"><code>{
|
|
138
|
+
"foo": [1, 10, 11]
|
|
139
|
+
}</code></pre></td>
|
|
140
|
+
<td><pre lang="JSON"><code>{
|
|
141
|
+
"foo": [2, 20, 22]
|
|
142
|
+
}</code></pre></td>
|
|
143
|
+
<td><pre lang="JSON"><code>{
|
|
144
|
+
"foo": [2, 20, 22]
|
|
145
|
+
}</code></pre></td>
|
|
146
|
+
</tr>
|
|
147
|
+
</table>
|
|
148
|
+
<!-- markdownlint-enable no-inline-html -->
|
|
71
149
|
|
|
72
|
-
|
|
150
|
+
### Extend
|
|
73
151
|
|
|
74
152
|
<!-- markdownlint-disable no-inline-html -->
|
|
75
153
|
<table>
|
|
76
154
|
<tr>
|
|
77
|
-
<th><code>
|
|
78
|
-
<th><code>
|
|
79
|
-
<th><code>JFather.
|
|
155
|
+
<th><code>https://foo.bar/parent.json</code></th>
|
|
156
|
+
<th><code>child</code></th>
|
|
157
|
+
<th><code>await JFather.extend(child)</code></th>
|
|
80
158
|
</tr>
|
|
81
159
|
<tr>
|
|
82
|
-
<td><code>
|
|
83
|
-
|
|
84
|
-
|
|
160
|
+
<td><pre lang="JSON"><code>{
|
|
161
|
+
"baz": "qux"
|
|
162
|
+
}</code></pre></td>
|
|
163
|
+
<td><pre lang="JSON"><code>{
|
|
164
|
+
"$extends": "https://foo.bar/parent.json"
|
|
165
|
+
}</code></pre></td>
|
|
166
|
+
<td><pre lang="JSON"><code>{
|
|
167
|
+
"baz": "qux"
|
|
168
|
+
}</code></pre></td>
|
|
85
169
|
</tr>
|
|
86
170
|
<tr>
|
|
87
|
-
<td><
|
|
88
|
-
|
|
89
|
-
|
|
171
|
+
<td><pre lang="JSON"><code>{
|
|
172
|
+
"baz": "qux"
|
|
173
|
+
}</code></pre></td>
|
|
174
|
+
<td><pre lang="JSON"><code>{
|
|
175
|
+
"$extends": "https://foo.bar/parent.json",
|
|
176
|
+
"baz": "quux"
|
|
177
|
+
}</code></pre></td>
|
|
178
|
+
<td><pre lang="JSON"><code>{
|
|
179
|
+
"baz": "quux"
|
|
180
|
+
}</code></pre></td>
|
|
90
181
|
</tr>
|
|
182
|
+
<tr>
|
|
183
|
+
<td><pre lang="JSON"><code>{
|
|
184
|
+
"baz": "qux"
|
|
185
|
+
}</code></pre></td>
|
|
186
|
+
<td><pre lang="JSON"><code>{
|
|
187
|
+
"$extends": "https://foo.bar/parent.json",
|
|
188
|
+
"quux": "corge"
|
|
189
|
+
}</code></pre></td>
|
|
190
|
+
<td><pre lang="JSON"><code>{
|
|
191
|
+
"baz": "qux",
|
|
192
|
+
"quux": "corge"
|
|
193
|
+
}</code></pre></td>
|
|
91
194
|
</tr>
|
|
92
195
|
<tr>
|
|
93
|
-
<td><code>{
|
|
94
|
-
|
|
95
|
-
|
|
196
|
+
<td><pre lang="JSON"><code>{
|
|
197
|
+
"baz": "qux"
|
|
198
|
+
}</code></pre></td>
|
|
199
|
+
<td><pre lang="JSON"><code>{
|
|
200
|
+
"quux": {
|
|
201
|
+
"$extends": "https://foo.bar/parent.json",
|
|
202
|
+
"corge": "grault"
|
|
203
|
+
}
|
|
204
|
+
}</code></pre></td>
|
|
205
|
+
<td><pre lang="JSON"><code>{
|
|
206
|
+
"quux": {
|
|
207
|
+
"baz": "qux",
|
|
208
|
+
"corge": "grault"
|
|
209
|
+
}
|
|
210
|
+
}</code></pre></td>
|
|
211
|
+
</tr>
|
|
212
|
+
<tr>
|
|
213
|
+
<td><pre lang="JSON"><code>{
|
|
214
|
+
"baz": {
|
|
215
|
+
"qux": [1, 2],
|
|
216
|
+
"quux": "a"
|
|
217
|
+
},
|
|
218
|
+
"corge": true
|
|
219
|
+
}</code></pre></td>
|
|
220
|
+
<td><pre lang="JSON"><code>{
|
|
221
|
+
"$extends": "https://foo.bar/parent.json#baz"
|
|
222
|
+
}</code></pre></td>
|
|
223
|
+
<td><pre lang="JSON"><code>{
|
|
224
|
+
"qux": [1, 2],
|
|
225
|
+
"quux": "a"
|
|
226
|
+
}</code></pre></td>
|
|
96
227
|
</tr>
|
|
97
228
|
</table>
|
|
98
229
|
<!-- markdownlint-enable no-inline-html -->
|
|
99
230
|
|
|
100
|
-
###
|
|
231
|
+
### Override
|
|
101
232
|
|
|
102
|
-
|
|
233
|
+
<!-- markdownlint-disable no-inline-html -->
|
|
234
|
+
<table>
|
|
235
|
+
<tr>
|
|
236
|
+
<th><code>parent</code></th>
|
|
237
|
+
<th><code>child</code></th>
|
|
238
|
+
<th><code>JFather.merge(parent, child)</code></th>
|
|
239
|
+
</tr>
|
|
240
|
+
<tr>
|
|
241
|
+
<td><pre lang="JSON"><code>{
|
|
242
|
+
"foo": ["a", "Alpha"]
|
|
243
|
+
}</code></pre></td>
|
|
244
|
+
<td><pre lang="JSON"><code>{
|
|
245
|
+
"$foo[]": ["b", "Beta"]
|
|
246
|
+
}</code></pre></td>
|
|
247
|
+
<td><pre lang="JSON"><code>{
|
|
248
|
+
"foo": ["a", "Alpha", "b", "Beta"]
|
|
249
|
+
}</code></pre></td>
|
|
250
|
+
</tr>
|
|
251
|
+
<tr>
|
|
252
|
+
<td><pre lang="JSON"><code>{
|
|
253
|
+
"foo": ["a", "Alpha"]
|
|
254
|
+
}</code></pre></td>
|
|
255
|
+
<td><pre lang="JSON"><code>{
|
|
256
|
+
"$foo[0]": "A"
|
|
257
|
+
}</code></pre></td>
|
|
258
|
+
<td><pre lang="JSON"><code>{
|
|
259
|
+
"foo": ["A", "Alpha"]
|
|
260
|
+
}</code></pre></td>
|
|
261
|
+
</tr>
|
|
262
|
+
<tr>
|
|
263
|
+
<td><pre lang="JSON"><code>{
|
|
264
|
+
"foo": [{ "bar": ["a"] }]
|
|
265
|
+
}</code></pre></td>
|
|
266
|
+
<td><pre lang="JSON"><code>{
|
|
267
|
+
"$foo[0]": { "$bar[]": ["b", "c"] }
|
|
268
|
+
}</code></pre></td>
|
|
269
|
+
<td><pre lang="JSON"><code>{
|
|
270
|
+
"foo": [{ "bar": ["a", "b", "c"] }]
|
|
271
|
+
}</code></pre></td>
|
|
272
|
+
</tr>
|
|
273
|
+
</table>
|
|
274
|
+
<!-- markdownlint-enable no-inline-html -->
|
|
103
275
|
|
|
104
|
-
|
|
276
|
+
## API
|
|
277
|
+
|
|
278
|
+
- [`merge()`](#merge)
|
|
279
|
+
- [`extend()`](#extend)
|
|
280
|
+
- [`load()`](#load)
|
|
281
|
+
- [`parse()`](#parse)
|
|
282
|
+
|
|
283
|
+
### `merge()`
|
|
284
|
+
|
|
285
|
+
Merge and override `parent` with `child`.
|
|
286
|
+
|
|
287
|
+
```JavaScript
|
|
288
|
+
JFather.merge(parent, child);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
- Parameters:
|
|
292
|
+
- `parent`: The parent object.
|
|
293
|
+
- `child`: The child object.
|
|
294
|
+
- Returns: The merged object.
|
|
295
|
+
|
|
296
|
+
### `extend()`
|
|
297
|
+
|
|
298
|
+
Extend `obj`, merge and override.
|
|
299
|
+
|
|
300
|
+
```JavaScript
|
|
301
|
+
JFather.extend(obj);
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
- Parameter:
|
|
305
|
+
- `obj`: The object with any `$extends` properties.
|
|
306
|
+
- Returns: A promise with the extended object.
|
|
307
|
+
|
|
308
|
+
### `load()`
|
|
309
|
+
|
|
310
|
+
Load from a `url`, extend, merge and override.
|
|
311
|
+
|
|
312
|
+
```JavaScript
|
|
313
|
+
JFather.load(url);
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
- Parameter:
|
|
317
|
+
- `url`: The string containing the URL of a JSON file.
|
|
318
|
+
- Returns: A promise with the loaded object.
|
|
319
|
+
|
|
320
|
+
### `parse()`
|
|
321
|
+
|
|
322
|
+
Parse a `text`, extend, merge and override.
|
|
323
|
+
|
|
324
|
+
```JavaScript
|
|
325
|
+
JFather.parse(text);
|
|
326
|
+
```
|
|
105
327
|
|
|
106
|
-
|
|
328
|
+
- Parameter:
|
|
329
|
+
- `text`: The string containing a JSON object.
|
|
330
|
+
- Returns: A promise with the parsed object.
|
|
107
331
|
|
|
108
332
|
[img-npm]: https://img.shields.io/npm/dm/jfather?label=npm&logo=npm&logoColor=whitesmoke
|
|
109
333
|
[img-build]: https://img.shields.io/github/actions/workflow/status/regseb/jfather/ci.yml?branch=main&logo=github&logoColor=whitesmoke
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jfather",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "JSON with merge, extend and override.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jfather",
|
|
@@ -47,18 +47,18 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@prantlf/jsonlint": "14.0.3",
|
|
50
|
-
"@prettier/plugin-xml": "3.3.
|
|
51
|
-
"@stryker-mutator/core": "8.2.
|
|
52
|
-
"@stryker-mutator/mocha-runner": "8.2.
|
|
50
|
+
"@prettier/plugin-xml": "3.3.1",
|
|
51
|
+
"@stryker-mutator/core": "8.2.6",
|
|
52
|
+
"@stryker-mutator/mocha-runner": "8.2.6",
|
|
53
53
|
"@types/mocha": "10.0.6",
|
|
54
|
-
"@types/node": "20.11.
|
|
54
|
+
"@types/node": "20.11.24",
|
|
55
55
|
"@types/sinon": "17.0.3",
|
|
56
|
-
"eslint": "8.
|
|
56
|
+
"eslint": "8.57.0",
|
|
57
57
|
"eslint-plugin-array-func": "4.0.0",
|
|
58
58
|
"eslint-plugin-eslint-comments": "3.2.0",
|
|
59
59
|
"eslint-plugin-import": "2.29.1",
|
|
60
|
-
"eslint-plugin-jsdoc": "48.0
|
|
61
|
-
"eslint-plugin-mocha": "10.
|
|
60
|
+
"eslint-plugin-jsdoc": "48.2.0",
|
|
61
|
+
"eslint-plugin-mocha": "10.3.0",
|
|
62
62
|
"eslint-plugin-n": "16.6.2",
|
|
63
63
|
"eslint-plugin-no-unsanitized": "4.0.2",
|
|
64
64
|
"eslint-plugin-promise": "6.1.1",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"npm-package-json-lint": "7.1.0",
|
|
71
71
|
"prettier": "3.2.5",
|
|
72
72
|
"sinon": "17.0.1",
|
|
73
|
-
"typedoc": "0.25.
|
|
73
|
+
"typedoc": "0.25.10",
|
|
74
74
|
"typescript": "5.3.3",
|
|
75
75
|
"yaml-lint": "1.7.0"
|
|
76
76
|
},
|
package/src/index.js
CHANGED
package/src/jfather.js
CHANGED
|
@@ -38,7 +38,7 @@ export const walk = function (obj, fn) {
|
|
|
38
38
|
*/
|
|
39
39
|
export const walkAsync = async function (obj, fn) {
|
|
40
40
|
if (Object === obj?.constructor) {
|
|
41
|
-
return fn(
|
|
41
|
+
return await fn(
|
|
42
42
|
Object.fromEntries(
|
|
43
43
|
await Promise.all(
|
|
44
44
|
Object.entries(obj).map(async ([key, value]) => [
|
|
@@ -51,7 +51,7 @@ export const walkAsync = async function (obj, fn) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (Array.isArray(obj)) {
|
|
54
|
-
return Promise.all(obj.map((v) => walkAsync(v, fn)));
|
|
54
|
+
return await Promise.all(obj.map((v) => walkAsync(v, fn)));
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
return obj;
|
|
@@ -76,8 +76,16 @@ export const clone = function (obj) {
|
|
|
76
76
|
* @throws {TypeError} Si le chemin est invalide.
|
|
77
77
|
*/
|
|
78
78
|
export const query = function (obj, chain) {
|
|
79
|
+
if ("" === chain) {
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
|
|
79
83
|
const re = /^\.(?<prop>\w+)|^\[(?<index>\d+)\]/u;
|
|
80
|
-
const sub = {
|
|
84
|
+
const sub = {
|
|
85
|
+
obj,
|
|
86
|
+
// Préfixer le chemin avec un point si nécessaire.
|
|
87
|
+
chain: /^[.[]/u.test(chain) ? chain : "." + chain,
|
|
88
|
+
};
|
|
81
89
|
while (0 !== sub.chain.length) {
|
|
82
90
|
const result = re.exec(sub.chain);
|
|
83
91
|
if (undefined !== result?.groups?.prop) {
|
|
@@ -105,7 +113,7 @@ export const merge = function (parent, child) {
|
|
|
105
113
|
return clone(child);
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
const
|
|
116
|
+
const overridden = /** @type {Record<string, any>} */ ({});
|
|
109
117
|
for (const key of new Set([
|
|
110
118
|
...Object.keys(parent),
|
|
111
119
|
...Object.keys(child),
|
|
@@ -118,18 +126,18 @@ export const merge = function (parent, child) {
|
|
|
118
126
|
// Si la propriété est dans les deux objets : fusionner les deux
|
|
119
127
|
// valeurs.
|
|
120
128
|
if (key in parent && key in child) {
|
|
121
|
-
|
|
129
|
+
overridden[key] = merge(parent[key], child[key]);
|
|
122
130
|
// Si la propriété est seulement dans l'objet parent.
|
|
123
131
|
} else if (key in parent) {
|
|
124
|
-
|
|
132
|
+
overridden[key] = clone(parent[key]);
|
|
125
133
|
// Si la propriété est seulement dans l'objet enfant.
|
|
126
134
|
} else {
|
|
127
|
-
|
|
135
|
+
overridden[key] = clone(child[key]);
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
// Si la valeur est un tableau : chercher si l'objet enfant a des
|
|
131
139
|
// surcharges d'éléments.
|
|
132
|
-
if (Array.isArray(
|
|
140
|
+
if (Array.isArray(overridden[key])) {
|
|
133
141
|
const overelemRegex = new RegExp(
|
|
134
142
|
`^\\$${key}\\[(?<index>\\d*)\\]$`,
|
|
135
143
|
"u",
|
|
@@ -139,28 +147,28 @@ export const merge = function (parent, child) {
|
|
|
139
147
|
.filter(([i]) => undefined !== i);
|
|
140
148
|
for (const [index, value] of overelems) {
|
|
141
149
|
if ("" === index) {
|
|
142
|
-
|
|
150
|
+
overridden[key].push(...clone(value));
|
|
143
151
|
} else {
|
|
144
|
-
|
|
145
|
-
|
|
152
|
+
overridden[key][Number(index)] = merge(
|
|
153
|
+
overridden[key][Number(index)],
|
|
146
154
|
value,
|
|
147
155
|
);
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
158
|
}
|
|
151
159
|
}
|
|
152
|
-
return
|
|
160
|
+
return overridden;
|
|
153
161
|
};
|
|
154
162
|
|
|
155
163
|
/**
|
|
156
|
-
* Étendre un objet JSON en utilisant les
|
|
164
|
+
* Étendre un objet JSON en utilisant les propriétés <code>"$extends"</code>.
|
|
157
165
|
*
|
|
158
166
|
* @param {Record<string, any>} obj L'objet qui sera étendu.
|
|
159
167
|
* @returns {Promise<Record<string, any>>} Une promesse contenant l'objet
|
|
160
168
|
* étendu.
|
|
161
169
|
*/
|
|
162
170
|
export const inherit = async function (obj) {
|
|
163
|
-
if (undefined === obj
|
|
171
|
+
if (undefined === obj.$extends) {
|
|
164
172
|
return obj;
|
|
165
173
|
}
|
|
166
174
|
|
|
@@ -174,7 +182,7 @@ export const inherit = async function (obj) {
|
|
|
174
182
|
* @param {any} obj L'objet qui sera étendu.
|
|
175
183
|
* @returns {Promise<any>} Une promesse contenant l'objet étendu.
|
|
176
184
|
*/
|
|
177
|
-
export const
|
|
185
|
+
export const extend = function (obj) {
|
|
178
186
|
return walkAsync(obj, inherit);
|
|
179
187
|
};
|
|
180
188
|
|
|
@@ -187,15 +195,16 @@ export const transform = function (obj) {
|
|
|
187
195
|
export const load = async function (url) {
|
|
188
196
|
const response = await fetch(url);
|
|
189
197
|
const json = await response.json();
|
|
190
|
-
|
|
198
|
+
// Enlever le "#" dans le hash de l'URL.
|
|
199
|
+
return await extend(query(json, new URL(url).hash.slice(1)));
|
|
191
200
|
};
|
|
192
201
|
|
|
193
202
|
/**
|
|
194
203
|
* Parse une chaine de caractères.
|
|
195
204
|
*
|
|
196
205
|
* @param {string} text La chaine de caractères qui sera parsée.
|
|
197
|
-
* @returns {any} L'objet.
|
|
206
|
+
* @returns {Promise<any>} L'objet.
|
|
198
207
|
*/
|
|
199
208
|
export const parse = function (text) {
|
|
200
|
-
return
|
|
209
|
+
return extend(JSON.parse(text));
|
|
201
210
|
};
|
package/types/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
declare namespace _default {
|
|
2
|
+
export { extend };
|
|
2
3
|
export { load };
|
|
3
4
|
export { merge };
|
|
4
5
|
export { parse };
|
|
5
6
|
}
|
|
6
7
|
export default _default;
|
|
8
|
+
import { extend } from "./jfather.js";
|
|
7
9
|
import { load } from "./jfather.js";
|
|
8
10
|
import { merge } from "./jfather.js";
|
|
9
11
|
import { parse } from "./jfather.js";
|
package/types/jfather.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export function clone(obj: any): any;
|
|
|
4
4
|
export function query(obj: Record<string, any>, chain: string): any;
|
|
5
5
|
export function merge(parent: any, child: any): any;
|
|
6
6
|
export function inherit(obj: Record<string, any>): Promise<Record<string, any>>;
|
|
7
|
-
export function
|
|
7
|
+
export function extend(obj: any): Promise<any>;
|
|
8
8
|
export function load(url: string): Promise<any>;
|
|
9
|
-
export function parse(text: string): any
|
|
9
|
+
export function parse(text: string): Promise<any>;
|