map-transform 1.6.0-rc.6 → 1.6.0-rc.8
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/NEXT.md +123 -0
- package/README.md +187 -52
- package/WRITING_PIPELINES.md +279 -106
- package/dist/legacy/createPathMapper.d.ts +4 -0
- package/dist/legacy/createPathMapper.js +21 -2
- package/dist/legacy/createPathMapper.js.map +1 -1
- package/dist/legacy/operations/lookup.js +2 -2
- package/dist/legacy/operations/lookup.js.map +1 -1
- package/dist/legacy/performance/apply.d.ts +1 -0
- package/dist/legacy/performance/apply.js +50 -0
- package/dist/legacy/performance/apply.js.map +1 -0
- package/dist/legacy/transformers/bucket.js +2 -1
- package/dist/legacy/transformers/bucket.js.map +1 -1
- package/dist/legacy/transformers/compare.js +3 -3
- package/dist/legacy/transformers/compare.js.map +1 -1
- package/dist/legacy/transformers/get.js +2 -2
- package/dist/legacy/transformers/get.js.map +1 -1
- package/dist/legacy/transformers/project.js +2 -2
- package/dist/legacy/transformers/project.js.map +1 -1
- package/dist/legacy/transformers/sort.js +2 -2
- package/dist/legacy/transformers/sort.js.map +1 -1
- package/dist/legacy/utils/preparedPipelines.js +9 -1
- package/dist/legacy/utils/preparedPipelines.js.map +1 -1
- package/dist/mapTransform.d.ts +1 -0
- package/dist/mapTransform.js +14 -22
- package/dist/mapTransform.js.map +1 -1
- package/dist/prep/alt.js +6 -0
- package/dist/prep/alt.js.map +1 -1
- package/dist/prep/apply.js +15 -3
- package/dist/prep/apply.js.map +1 -1
- package/dist/prep/array.js +6 -0
- package/dist/prep/array.js.map +1 -1
- package/dist/prep/filter.js +4 -1
- package/dist/prep/filter.js.map +1 -1
- package/dist/prep/index.d.ts +1 -1
- package/dist/prep/index.js +33 -12
- package/dist/prep/index.js.map +1 -1
- package/dist/prep/iterate.d.ts +1 -1
- package/dist/prep/iterate.js +2 -1
- package/dist/prep/iterate.js.map +1 -1
- package/dist/prep/mutation.js +17 -6
- package/dist/prep/mutation.js.map +1 -1
- package/dist/prep/path.js +3 -9
- package/dist/prep/path.js.map +1 -1
- package/dist/prep/transform.d.ts +1 -0
- package/dist/prep/transform.js +5 -4
- package/dist/prep/transform.js.map +1 -1
- package/dist/prepareOptions.d.ts +9 -0
- package/dist/prepareOptions.js +24 -0
- package/dist/prepareOptions.js.map +1 -0
- package/dist/run/alt.js +7 -5
- package/dist/run/alt.js.map +1 -1
- package/dist/run/index.d.ts +0 -5
- package/dist/run/index.js +33 -27
- package/dist/run/index.js.map +1 -1
- package/dist/run/iterate.js +2 -22
- package/dist/run/iterate.js.map +1 -1
- package/dist/run/mutation.d.ts +2 -1
- package/dist/run/mutation.js +2 -2
- package/dist/run/mutation.js.map +1 -1
- package/dist/run/path.d.ts +2 -1
- package/dist/run/path.js +11 -6
- package/dist/run/path.js.map +1 -1
- package/dist/run/resolveParentSets.d.ts +2 -0
- package/dist/run/resolveParentSets.js +46 -0
- package/dist/run/resolveParentSets.js.map +1 -0
- package/dist/run/transform.d.ts +3 -1
- package/dist/run/transform.js +9 -1
- package/dist/run/transform.js.map +1 -1
- package/dist/state.d.ts +2 -0
- package/dist/state.js +2 -0
- package/dist/state.js.map +1 -1
- package/dist/typesNext.d.ts +1 -1
- package/dist/utils/is.d.ts +1 -0
- package/dist/utils/is.js +1 -0
- package/dist/utils/is.js.map +1 -1
- package/package.json +3 -3
package/NEXT.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Proposals for MapTransform v2 (`next`)
|
|
2
|
+
|
|
3
|
+
A list of suggested changes to the `next` mutation language, to be taken on one
|
|
4
|
+
at a time. Each section is self-contained: what the problem is, what the change
|
|
5
|
+
is, and which verified findings it addresses. Findings marked _(verified)_ were
|
|
6
|
+
reproduced by running `mapTransform` from `src/mapTransform.ts` on small inputs.
|
|
7
|
+
|
|
8
|
+
## Background: how the engine models context and reverse today
|
|
9
|
+
|
|
10
|
+
**Context is structural.** Only drilling down adds a level, operations are
|
|
11
|
+
opaque, set steps don't move, `^^` is depth zero of the current tree and `^^^`
|
|
12
|
+
the original input. In reverse, a target context mirrors the context, so parent
|
|
13
|
+
and root paths set on the parent or root target
|
|
14
|
+
(`src/run/resolveParentSets.ts`). See "Parent and root paths" in the README.
|
|
15
|
+
|
|
16
|
+
**Reverse is a syntactic reversal.** `adjustPipelineToDirection`
|
|
17
|
+
(`src/run/index.ts`) reverses the prepped steps. Pipelines whose first step is
|
|
18
|
+
not a path are silently prefixed with `.` or given a reverse plug
|
|
19
|
+
(`src/prep/mutation.ts`).
|
|
20
|
+
|
|
21
|
+
**`flip` is runtime state.** `isRev = xor(rev, flip)`. `$apply` clears it, `$if`
|
|
22
|
+
conditions force forward, `$array` forces a direction per branch, `$direction`
|
|
23
|
+
ignores it, and `lookup` special-cases it.
|
|
24
|
+
|
|
25
|
+
## Reverse by rule, not by heuristic
|
|
26
|
+
|
|
27
|
+
### Problem
|
|
28
|
+
|
|
29
|
+
- `$flip: false` is dropped at prep time, so a nested object cannot un-flip.
|
|
30
|
+
- `$direction` ignores `flip`, but paths honor it.
|
|
31
|
+
- Pipelines that do not start with a path are silently plugged or prefixed with
|
|
32
|
+
`.` in reverse (`addStepWhenNoGetStep` in `src/prep/mutation.ts`).
|
|
33
|
+
|
|
34
|
+
### Change
|
|
35
|
+
|
|
36
|
+
- Add an explicit two-sided form for the hard cases, JSON-friendly:
|
|
37
|
+
`{ "$fwd": [...], "$rev": [...] }`. This replaces legacy `divide`, `fwd`, and
|
|
38
|
+
`rev`, and most uses of `$direction` on two adjacent steps.
|
|
39
|
+
- `$alt` in reverse: set with the first pipeline; if the value is a nonvalue,
|
|
40
|
+
use the last `$default`. Losing pipelines are never run as setters.
|
|
41
|
+
- `$flip` becomes a prep-time rewrite: swap key and value, reverse each
|
|
42
|
+
pipeline, toggle `>`. `flip` leaves `State`. Transformers that need to know,
|
|
43
|
+
such as `lookup`, get a flag on the transform step at prep time.
|
|
44
|
+
|
|
45
|
+
## One modifier for "the other direction"
|
|
46
|
+
|
|
47
|
+
### Problem
|
|
48
|
+
|
|
49
|
+
Direction pairs are spelled five ways: `$concat`/`$concatRev`,
|
|
50
|
+
`merge`/`mergeRev`, `$lookup`/`$lookdown`, `explode`/`implode`, and `$array`
|
|
51
|
+
with `$flip`.
|
|
52
|
+
|
|
53
|
+
### Change
|
|
54
|
+
|
|
55
|
+
Allow `$flip: true` on any operation object, and drop `$concatRev`, `mergeRev`,
|
|
56
|
+
`$lookdown`, `implode`, and the special `$flip` handling on `$array`. Keep
|
|
57
|
+
`explode`/`implode` names only if they read better than `explode` + `$flip`.
|
|
58
|
+
|
|
59
|
+
## Constants vs defaults
|
|
60
|
+
|
|
61
|
+
### Problem
|
|
62
|
+
|
|
63
|
+
Two concepts have five spellings: `$value`, `$fixed`, `$value` with
|
|
64
|
+
`fixed: true`, and the `value` and `fixed` transformers. `$value` being
|
|
65
|
+
suppressed by `noDefaults` is surprising when it is used as a constant, which is
|
|
66
|
+
why `fixed` exists.
|
|
67
|
+
|
|
68
|
+
### Change
|
|
69
|
+
|
|
70
|
+
- `$value: x` is a constant and is never suppressed.
|
|
71
|
+
- `$default: x` is a fallback and is suppressed by `noDefaults`.
|
|
72
|
+
- Drop `$fixed`, `fixed: true`, and the `fixed` transformer.
|
|
73
|
+
|
|
74
|
+
`$alt: ['fullname', { $default: 'Anon' }]` then reads as intended.
|
|
75
|
+
|
|
76
|
+
## Reverse-only props without slashed keys
|
|
77
|
+
|
|
78
|
+
### Problem
|
|
79
|
+
|
|
80
|
+
Reverse-only props use the lexical trick `name/1`, with `\/` escaping for
|
|
81
|
+
literal slashes.
|
|
82
|
+
|
|
83
|
+
### Change
|
|
84
|
+
|
|
85
|
+
A `$rev: { name: [...] }` block on a mutation object holds props that only apply
|
|
86
|
+
in reverse, merged over the main props. `$fwd: { ... }` for symmetry. `name/1`
|
|
87
|
+
and its escaping go away.
|
|
88
|
+
|
|
89
|
+
## Fail loudly at prep time
|
|
90
|
+
|
|
91
|
+
### Problem
|
|
92
|
+
|
|
93
|
+
Bad input is accepted silently:
|
|
94
|
+
|
|
95
|
+
- Unknown `$direction` values, including typos, mean "both" _(verified)_.
|
|
96
|
+
- `[1:3]` and `[abc]` go through `parseInt` and become `[1]` and `[NaN]`
|
|
97
|
+
_(verified)_.
|
|
98
|
+
- Unknown `$`-keys on a mutation object, boolean values, `$alt: []`, non-array
|
|
99
|
+
`$nonvalues`, and unknown `compare` operators are dropped or ignored without a
|
|
100
|
+
message.
|
|
101
|
+
- Setting to parent or root degrades silently instead of failing.
|
|
102
|
+
|
|
103
|
+
### Change
|
|
104
|
+
|
|
105
|
+
Throw at prep time on all of the above. Prep runs once, so this costs nothing at
|
|
106
|
+
run time.
|
|
107
|
+
|
|
108
|
+
## Trim compatibility leftovers
|
|
109
|
+
|
|
110
|
+
### Problem
|
|
111
|
+
|
|
112
|
+
Kept for compatibility but pure noise in v2: the `<` get prefix, the
|
|
113
|
+
`$undefined` alias of `$nonvalues`, `fwdAlias`/`revAlias`, `$value` accepting a
|
|
114
|
+
function, and `$if` using unprefixed `then`/`else` while everything else is
|
|
115
|
+
`$`-prefixed.
|
|
116
|
+
|
|
117
|
+
`$alwaysApply` is not inherited, so it must be repeated on every nested mutation
|
|
118
|
+
object.
|
|
119
|
+
|
|
120
|
+
### Change
|
|
121
|
+
|
|
122
|
+
Drop the leftovers listed above. Make `$alwaysApply` inherited by nested
|
|
123
|
+
mutation objects.
|
package/README.md
CHANGED
|
@@ -197,6 +197,12 @@ it won't happen again on the next call. `prepareOptions` is idempotent, so
|
|
|
197
197
|
passing already prepared options to `mapTransform` -- or calling
|
|
198
198
|
`prepareOptions` on them again -- costs nothing.
|
|
199
199
|
|
|
200
|
+
`map-transform/next` exports its own `prepareOptions` alongside `mapTransform`.
|
|
201
|
+
Options prepared with one API cannot be handed to the other. Note that the sync
|
|
202
|
+
`mapTransform()` and the async `mapTransformAsync()` cache their prepared
|
|
203
|
+
pipelines separately, so mixing both on the same prepared options will prepare
|
|
204
|
+
each pipeline twice.
|
|
205
|
+
|
|
200
206
|
> [!NOTE] We are preparing for an upcoming 2.0 version, which will include
|
|
201
207
|
> breaking changes.
|
|
202
208
|
>
|
|
@@ -221,6 +227,27 @@ passing already prepared options to `mapTransform` -- or calling
|
|
|
221
227
|
> new `mapTransformSync` and `mapTransformAsync`, but there might still be gaps
|
|
222
228
|
> in the documentation here.
|
|
223
229
|
|
|
230
|
+
#### Deviations from v1 behaviour in `next`
|
|
231
|
+
|
|
232
|
+
The following behaviours of `mapTransformSync` and `mapTransformAsync` differ
|
|
233
|
+
from the default export, on purpose:
|
|
234
|
+
|
|
235
|
+
- The root form without a dot after a single caret, `^path`, is removed. Write
|
|
236
|
+
`^^.path`.
|
|
237
|
+
- `$alt` no longer changes the levels for parent paths after it. Before, a
|
|
238
|
+
`$alt` that found no value added a level, so the next step needed `^.^` to
|
|
239
|
+
reach the parent. After, the next step sees the same levels as before the
|
|
240
|
+
`$alt`, so `^` is enough.
|
|
241
|
+
- Parent and root paths in reverse set on the parent or root level of the target
|
|
242
|
+
instead of on the current level. Before, `section: '^.^.meta.section'` inside
|
|
243
|
+
an iteration reversed to `items[].section`, and a root path in reverse set
|
|
244
|
+
nothing. After, the same definition sets `meta.section` on the object holding
|
|
245
|
+
`items`. When the parent level does not exist, the value is dropped.
|
|
246
|
+
- Mutation objects iterate arrays by default, just like get paths map over
|
|
247
|
+
arrays. Before, you had to set `$iterate: true`, and without it the entire
|
|
248
|
+
array was passed to the mutation object, giving one object with an array of
|
|
249
|
+
values on every property. Set `$iterate: false` to get that behaviour back.
|
|
250
|
+
|
|
224
251
|
### The mutation object
|
|
225
252
|
|
|
226
253
|
Think of a mutation object as a description of the object structure you want.
|
|
@@ -267,6 +294,10 @@ mutation object. If you don't, the entire array will be passed to the mutation
|
|
|
267
294
|
object. This will in most cases have the (propably unwanted) effect of returning
|
|
268
295
|
one object with an array of values on every property.
|
|
269
296
|
|
|
297
|
+
> [!NOTE] In the next version, mutation objects iterate arrays by default, so
|
|
298
|
+
> `$iterate: true` is not needed. Set `$iterate: false` to pass the entire array
|
|
299
|
+
> to the mutation object instead.
|
|
300
|
+
|
|
270
301
|
```javascript
|
|
271
302
|
const def = {
|
|
272
303
|
$iterate: true,
|
|
@@ -307,8 +338,9 @@ as its value, this mutation object will be iterated by default (no need to set
|
|
|
307
338
|
the `$iterate` property). This does not happen to pipelines, paths, or
|
|
308
339
|
operations.
|
|
309
340
|
|
|
310
|
-
> [!NOTE] This
|
|
311
|
-
>
|
|
341
|
+
> [!NOTE] This changes slightly in the next version, as mutation objects iterate
|
|
342
|
+
> by default. A key with the `[]` suffix will still be iterated, but not because
|
|
343
|
+
> of that suffix.
|
|
312
344
|
|
|
313
345
|
#### Values on the mutation object
|
|
314
346
|
|
|
@@ -395,6 +427,25 @@ This will essentially make MapTransform treat `null` the same way as
|
|
|
395
427
|
You could in principle include any primitive value in `nonvalues` and it will be
|
|
396
428
|
treated as `undefined`, e.g. an empty string or the number `0`.
|
|
397
429
|
|
|
430
|
+
You may also set `$nonvalues` on an operation or mutation object, to use another
|
|
431
|
+
set of non-values for that operation and any pipelines within it. This overrides
|
|
432
|
+
the `nonvalues` option for that part of the definition. `$undefined` is an alias
|
|
433
|
+
of `$nonvalues`, and when both are set, `$nonvalues` is used. As a definition
|
|
434
|
+
may be written in JSON, where `undefined` cannot be expressed, the value
|
|
435
|
+
`'**undefined**'` is treated as `undefined` in these lists:
|
|
436
|
+
|
|
437
|
+
```javascript
|
|
438
|
+
const def = {
|
|
439
|
+
// Treat an empty string as `undefined` when picking a default here
|
|
440
|
+
name: [
|
|
441
|
+
{
|
|
442
|
+
$alt: ['data.name', { $value: 'Anonymous' }],
|
|
443
|
+
$nonvalues: ['**undefined**', ''],
|
|
444
|
+
},
|
|
445
|
+
],
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
398
449
|
A mutation object will be skipped in its entirety when it encounters a non-value
|
|
399
450
|
in the pipeline. This is not always wanted, e.g. when the mutation object has
|
|
400
451
|
defaults that we want to set in the mutation object. In these cases, you may set
|
|
@@ -459,8 +510,11 @@ const def = {
|
|
|
459
510
|
|
|
460
511
|
The `$modify: true` notation is actually an alias for `$modify: '.'`.
|
|
461
512
|
|
|
462
|
-
|
|
463
|
-
|
|
513
|
+
`$modify` works like a path segment that merges instead of replacing, and it
|
|
514
|
+
takes effect on the side of the prop that is being set. When it is in a key, it
|
|
515
|
+
modifies going forward. When it is in a value, it modifies in reverse. This is
|
|
516
|
+
the way to set it for reverse direction (this is the exact same as the example
|
|
517
|
+
above, just reversed):
|
|
464
518
|
|
|
465
519
|
```javascript
|
|
466
520
|
const def = {
|
|
@@ -479,6 +533,18 @@ const def = {
|
|
|
479
533
|
}
|
|
480
534
|
```
|
|
481
535
|
|
|
536
|
+
> [!NOTE] In the next version, you may put `$modify` on both sides of a prop to
|
|
537
|
+
> modify in both directions. `$modify: '$modify'` modifies the pipeline value
|
|
538
|
+
> both going forward and in reverse, and `$modify: 'response.$modify'` does the
|
|
539
|
+
> same with the object at `response`:
|
|
540
|
+
>
|
|
541
|
+
> ```javascript
|
|
542
|
+
> const def = {
|
|
543
|
+
> $modify: 'response.$modify',
|
|
544
|
+
> data: 'response.data.deeply.placed.items',
|
|
545
|
+
> }
|
|
546
|
+
> ```
|
|
547
|
+
|
|
482
548
|
### Transform pipelines
|
|
483
549
|
|
|
484
550
|
The idea of the transform pipeline, or "pipeline" for short, is that you
|
|
@@ -544,6 +610,10 @@ specified. In the example above, we have set `$iterate: true` on the mutation
|
|
|
544
610
|
object, to signal that we want the mutation to be applied to each item of any
|
|
545
611
|
array. See also [the `iterate` operation](#iteratepipeline-operation) for more.
|
|
546
612
|
|
|
613
|
+
> [!NOTE] In the next version, mutation objects will iterate by default, so to
|
|
614
|
+
> get the behavior described as default for mutation objects above, you will
|
|
615
|
+
> have to set `$iterate: false`.
|
|
616
|
+
|
|
547
617
|
> Editors note: We should think through how we use the word "pipeline", as it is
|
|
548
618
|
> sometimes ment to refer to an array of operations that a value may be
|
|
549
619
|
> transformed through, other times any operation that could have been a part of
|
|
@@ -654,41 +724,68 @@ In the example with the `content` path, you may access the `id` with the path
|
|
|
654
724
|
much the same way as `../` in file paths on any computer. You may go up several
|
|
655
725
|
levels with e.g. `^.^.^.prop` (not applicable to our example).
|
|
656
726
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
727
|
+
The number of carets you need follows from the structure of the definition
|
|
728
|
+
alone, by these rules:
|
|
729
|
+
|
|
730
|
+
1. **Only drilling down adds a level.** A key segment like `content` adds one
|
|
731
|
+
level, and so does an index like `[0]`. Entering an item in an array adds one
|
|
732
|
+
level too, whether you get there by iterating a path with `[]`, by a mutation
|
|
733
|
+
object iterating an array, or by an `$iterate` operation. A bare `[]` that
|
|
734
|
+
only makes sure you have an array, adds nothing. So when iterating the
|
|
735
|
+
`tags[]` array from our example above, you would use `^.^.id` to get to the
|
|
736
|
+
id: one caret to the array and one more to the object holding it. You could
|
|
737
|
+
also use `^.[0]` to get the first item in the array you're iterating.
|
|
738
|
+
2. **Operations are opaque.** After a `$transform`, a mutation object, `$alt`,
|
|
739
|
+
`$if`, `$filter`, `$apply`, or `$array`, the levels are what they were before
|
|
740
|
+
the operation, no matter what the operation did on the inside. Inside an
|
|
741
|
+
operation, you inherit the levels from where the operation is used.
|
|
742
|
+
3. **Set paths don't move.** A `>prop` step does not add a level, so `^` after
|
|
743
|
+
it is the same as `^` before it.
|
|
744
|
+
4. **`^^` is the top of the tree you're in, `^^^` is the original data.** The
|
|
745
|
+
root notation `^^.id` goes to the base level of the data structure,
|
|
746
|
+
regardless of how many levels down you have moved.
|
|
747
|
+
5. **In reverse, parent and root paths set on the parent or root level.** See
|
|
748
|
+
[Setting on parent and root](#setting-on-parent-and-root) below.
|
|
749
|
+
|
|
750
|
+
The parents you move up in, are the data you moved down in. When you first
|
|
751
|
+
mutate the data with a mutation object and then move into the result with a
|
|
752
|
+
path, going up again with a parent path takes you up in the mutated data:
|
|
753
|
+
|
|
754
|
+
```javascript
|
|
755
|
+
const def = [
|
|
756
|
+
{ id: 'key', item: { title: 'content.heading' } },
|
|
757
|
+
{ title: 'item.title', id: ['item.title', '^.^.id'] },
|
|
758
|
+
]
|
|
759
|
+
// From { key: 'ent1', content: { heading: 'The heading' } }
|
|
760
|
+
// we get { title: 'The heading', id: 'ent1' }
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
Here, `item.title` in the second mutation object moves two levels down into the
|
|
764
|
+
object from the first, and `^.^.id` goes back up to the mutated object and gets
|
|
765
|
+
the `id` we set there. Note that within a mutation object, all pipelines start
|
|
766
|
+
from the same object, so the pipeline for `id` is not affected by the pipeline
|
|
767
|
+
for `title`.
|
|
768
|
+
|
|
769
|
+
Rule 2 means you don't have to know what an operation did to get the levels
|
|
770
|
+
right after it. In this example, `$alt` may find the article on different
|
|
771
|
+
depths, but the mutation object after it sees the same levels either way:
|
|
772
|
+
|
|
773
|
+
```javascript
|
|
774
|
+
const def = [
|
|
775
|
+
'items[]',
|
|
776
|
+
{
|
|
777
|
+
$iterate: true,
|
|
778
|
+
article: [
|
|
779
|
+
{ $alt: ['content', 'original.content'] },
|
|
780
|
+
{ title: 'title', section: '^.^.meta.section' },
|
|
781
|
+
],
|
|
782
|
+
},
|
|
783
|
+
]
|
|
784
|
+
// From { meta: { section: 'news' }, items: [{ content: { title: 'A' } }] }
|
|
785
|
+
// we get [{ article: { title: 'A', section: 'news' } }]
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
Rule 4 in a multi-step pipeline, where the first step mutates the root:
|
|
692
789
|
|
|
693
790
|
```javascript
|
|
694
791
|
const def = [
|
|
@@ -703,22 +800,43 @@ const def = [
|
|
|
703
800
|
]
|
|
704
801
|
```
|
|
705
802
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
source data in all cases.
|
|
803
|
+
The same holds inside a named pipeline applied with `$apply`: `^^` is the top of
|
|
804
|
+
the tree the pipeline is applied in, mutated or not, and `^^^` is the original
|
|
805
|
+
source data.
|
|
710
806
|
|
|
711
|
-
|
|
712
|
-
the data above where you are isn't transformed yet. As long as you are within a
|
|
713
|
-
mutation object, you're referencing the data as it was before entering that
|
|
714
|
-
mutation object. But as soon as you move to the next step in the pipeline –
|
|
715
|
-
after the mutation object, you are left with the results of that mutation
|
|
716
|
-
object.
|
|
807
|
+
##### Setting on parent and root
|
|
717
808
|
|
|
718
|
-
|
|
809
|
+
When you go in reverse, a parent or root path becomes a set path, and it sets on
|
|
810
|
+
the parent or root level of the target, with the same number of carets as going
|
|
811
|
+
forward. In this example, `section` is read from two levels up going forward,
|
|
812
|
+
and in reverse it is set two levels up: on the object holding `items`.
|
|
719
813
|
|
|
720
|
-
|
|
721
|
-
|
|
814
|
+
```javascript
|
|
815
|
+
const def = [
|
|
816
|
+
'items[]',
|
|
817
|
+
{ $iterate: true, id: 'key', section: '^.^.meta.section' },
|
|
818
|
+
]
|
|
819
|
+
// Forward, from { meta: { section: 'news' }, items: [{ key: 'ent1' }] }
|
|
820
|
+
// we get [{ id: 'ent1', section: 'news' }]
|
|
821
|
+
// In reverse, from [{ id: 'ent1', section: 'news' }]
|
|
822
|
+
// we get { meta: { section: 'news' }, items: [{ key: 'ent1' }] }
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
A root path sets on the root level of the target in the same way, so
|
|
826
|
+
`'^^.meta.section'` in the example above would give the same result in reverse.
|
|
827
|
+
When you set on a parent level, nothing is set on the current level, so `id` is
|
|
828
|
+
the only prop on the items here.
|
|
829
|
+
|
|
830
|
+
Set paths may also use parent and root notation going forward, with a `>` prefix
|
|
831
|
+
or as a key on a mutation object. `{ '^.^.meta.section': 'section' }` sets
|
|
832
|
+
`meta.section` two levels up in the target.
|
|
833
|
+
|
|
834
|
+
When there is no parent level to set on, e.g. when a mutation object with
|
|
835
|
+
`section: '^.section'` is run in reverse at the top level, the value is dropped.
|
|
836
|
+
|
|
837
|
+
A parent path _within_ a path is different from these cases. The path
|
|
838
|
+
`item.^.count` moves down into `item` and up again, and is the same as `count`.
|
|
839
|
+
In reverse, it sets `count`, not `item.count`.
|
|
722
840
|
|
|
723
841
|
#### Setting on a path
|
|
724
842
|
|
|
@@ -927,6 +1045,12 @@ would be a truly pure function.
|
|
|
927
1045
|
> call the outer function yourself with any relevant props. This option will be
|
|
928
1046
|
> removed in v2.0, but is still available to the regular MapTransform function.
|
|
929
1047
|
|
|
1048
|
+
Transformers may be asynchronous, but only when you run the transformation with
|
|
1049
|
+
`mapTransformAsync`. When you run it with `mapTransformSync` and a transformer
|
|
1050
|
+
returns a promise, MapTransform will throw, telling you the id of the offending
|
|
1051
|
+
transformer. This also applies to transformers used by other operations, like
|
|
1052
|
+
`filter`.
|
|
1053
|
+
|
|
930
1054
|
#### `filter` operation
|
|
931
1055
|
|
|
932
1056
|
The `filter` operation will use a transformer function or a pipeline to decide
|
|
@@ -1087,6 +1211,9 @@ const def = [
|
|
|
1087
1211
|
For mutation objects, you may set `$iterate: true` to apply the mutation to each
|
|
1088
1212
|
item in an array.
|
|
1089
1213
|
|
|
1214
|
+
> [!NOTE] In the next version, mutation objects do this by default, and
|
|
1215
|
+
> `$iterate: false` turns it off.
|
|
1216
|
+
|
|
1090
1217
|
When you need to iterate a pipeline or an operation that is not a mutation
|
|
1091
1218
|
object or an operation that supports the `$iterate` flag direction, you may wrap
|
|
1092
1219
|
it in an `$iterate` operation object like this:
|
|
@@ -1238,6 +1365,10 @@ don't think too much about it. See
|
|
|
1238
1365
|
[the `get` and `set` operations](#getpath-and-setpath-operation) for more on how
|
|
1239
1366
|
`get` works in reverse.
|
|
1240
1367
|
|
|
1368
|
+
When the value is `undefined` in reverse, the alternative pipelines are used to
|
|
1369
|
+
look for a default value. Only pipelines without set paths (e.g. a `$value`
|
|
1370
|
+
pipeline) are used for this, so put the default in its own pipeline.
|
|
1371
|
+
|
|
1241
1372
|
To apply the `alt` operation to each item in an array, set `$iterate: true` on
|
|
1242
1373
|
the operation object. You may also set `$direction: 'fwd'` or
|
|
1243
1374
|
`$direction: 'rev'` to limit it to one direction only.
|
|
@@ -1829,6 +1960,10 @@ except that the value set with `fixed` will be included even when
|
|
|
1829
1960
|
`state.noDefaults` is `true`. Use `value` for default values, and `fixed` for
|
|
1830
1961
|
values that should be set no matter what.
|
|
1831
1962
|
|
|
1963
|
+
Like the `value` transformer, `fixed` has its own short-hand operation object
|
|
1964
|
+
notation, so `{ $transform: 'fixed', value: 'customer' }` may be written
|
|
1965
|
+
`{ $fixed: 'customer' }`.
|
|
1966
|
+
|
|
1832
1967
|
#### `flatten` transformer
|
|
1833
1968
|
|
|
1834
1969
|
Will flatten an array in the pipeline. The default is to flatten one layer deep,
|