Skip to content

Commit 777bcda

Browse files
docs(mapping-kit): update README to match current implementation (#3714)
* docs(mapping-kit): update README to match current implementation - Fix @if `blank` conditional description (runs `then` when NOT blank, not when blank) - Fix @if `blank` example result for undefined path - Fix @replace examples to include the required `value` key - Document @replace `pattern2`/`replacement2` dual-pattern feature - Add missing @flatten directive documentation - Add missing @JSON directive documentation - Add missing @liquid directive documentation with disabled tags/filters note - Update table of contents with new directives - Fix broken link to test suite (was pointing to old fab-5-engine repo) * docs(mapping-kit): clarify @if blank coercion behavior for 0 and false
1 parent 38e4ee2 commit 777bcda

1 file changed

Lines changed: 186 additions & 21 deletions

File tree

packages/core/src/mapping-kit/README.md

Lines changed: 186 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ Output:
6767
- [@replace](#replace)
6868
- [@merge](#merge)
6969
- [@transform](#transform)
70+
- [@flatten](#flatten)
71+
- [@json](#json)
72+
- [@liquid](#liquid)
7073
- [@excludeWhenNull](#excludewhennull)
7174

7275
<!-- tocstop -->
@@ -208,9 +211,7 @@ Valid:
208211
## Validation
209212

210213
Mapping configurations can be validated using JSON Schema. The [test
211-
suite][schema.test.js] is a good source-of-truth for current implementation behavior.
212-
213-
[schema.test.js]: https://github.com/segmentio/fab-5-engine/blob/master/packages/destination-actions/src/lib/mapping-kit/__tests__
214+
suite](./__tests__/index.iso.test.ts) is a good source-of-truth for current implementation behavior.
214215

215216
## Removing values from object
216217

@@ -252,7 +253,10 @@ The supported conditional values are:
252253

253254
- "exists": If the given value is not undefined or null, the @if directive resolves to the "then"
254255
value. Otherwise, the "else" value is used.
255-
- "blank": If the given value is undefined or null, the @if directive resolves to the "then" value. Otherwise, the "else" value is used.
256+
- "blank": If the given value is not undefined, not null, and does not loosely equal an empty
257+
string (`''`) (i.e., is not blank), the @if directive resolves to the "then" value. Otherwise,
258+
the "else" value is used. Because this check uses JavaScript loose equality semantics, values
259+
such as `0` and `false` are currently treated as blank and will use the "else" branch.
256260

257261
```json
258262
Input:
@@ -292,7 +296,7 @@ Mappings:
292296
}
293297
}
294298
=>
295-
"yep"
299+
"nope"
296300
```
297301

298302
If "then" or "else" are not defined and the conditional indicates that their value should be used,
@@ -490,57 +494,55 @@ Result:
490494

491495
### @replace
492496

493-
The @replace directive replaces to the given pattern value with a replacement string. Both "pattern" and "replacement"
494-
fields are required but replacement can be an empty string.
497+
The @replace directive replaces occurrences of a pattern in a string with a replacement string.
498+
The `value` field specifies the input string (may be a directive or raw value). The `pattern` field
499+
is required; `replacement` defaults to an empty string if omitted.
500+
501+
By default, replacement is global (all occurrences) and case-sensitive. Use `global: false` to
502+
replace only the first occurrence, and `ignorecase: true` for case-insensitive matching.
495503

496-
````json
504+
```json
497505
Input:
498506

499507
{
500-
"a": "cool-story",
508+
"a": "cool-story"
501509
}
502510

503511
Mappings:
504512

505513
{
506514
"@replace": {
515+
"value": { "@path": "$.a" },
507516
"pattern": "-",
508517
"replacement": ""
509518
}
510519
}
511520
=>
512521
"coolstory"
513522

514-
```json
515-
Input:
516-
517-
{
518-
"a": "cool-story",
519-
}
520-
521-
Mappings:
522-
523523
{
524524
"@replace": {
525+
"value": { "@path": "$.a" },
525526
"pattern": "-",
526527
"replacement": "nice"
527528
}
528529
}
529530
=>
530531
"coolnicestory"
531-
````
532+
```
532533

533534
```json
534535
Input:
535536

536537
{
537-
"a": "cWWl-story-ww",
538+
"a": "cWWl-story-ww"
538539
}
539540

540541
Mappings:
541542

542543
{
543544
"@replace": {
545+
"value": { "@path": "$.a" },
544546
"pattern": "WW",
545547
"replacement": "oo",
546548
"ignorecase": false
@@ -554,13 +556,14 @@ Mappings:
554556
Input:
555557

556558
{
557-
"a": "just-the-first",
559+
"a": "just-the-first"
558560
}
559561

560562
Mappings:
561563

562564
{
563565
"@replace": {
566+
"value": { "@path": "$.a" },
564567
"pattern": "-",
565568
"replacement": "@",
566569
"global": false
@@ -570,6 +573,33 @@ Mappings:
570573
"just@the-first"
571574
```
572575

576+
A second pattern/replacement pair (`pattern2` / `replacement2`) can be provided to apply a second
577+
substitution on the result of the first:
578+
579+
```json
580+
Input:
581+
582+
{
583+
"a": "something-great!"
584+
}
585+
586+
Mapping:
587+
588+
{
589+
"@replace": {
590+
"value": { "@path": "$.a" },
591+
"pattern": "-",
592+
"replacement": " ",
593+
"pattern2": "great",
594+
"replacement2": "awesome"
595+
}
596+
}
597+
598+
Output:
599+
600+
"something awesome!"
601+
```
602+
573603
### @merge
574604

575605
The @merge directive resolves a list of objects to a single object. It accepts a list of one or more objects (either raw objects or directives that resolve to objects), and a direction that determines how overwrites will be applied for duplicate keys. The resolved object is built by combining each object in turn, moving in the specified direction, overwriting any duplicate keys.
@@ -689,6 +719,141 @@ Mappings:
689719
}
690720
```
691721

722+
### @flatten
723+
724+
The @flatten directive flattens a nested object into a single-level object using a separator string
725+
for the keys. The `value` field specifies the object to flatten and the `separator` field (required)
726+
specifies the string used to join nested keys. Set `omitArrays: true` to leave array values
727+
un-flattened.
728+
729+
```json
730+
Input:
731+
732+
{
733+
"foo": {
734+
"bar": "baz",
735+
"aces": { "a": 1, "b": 2 }
736+
}
737+
}
738+
739+
Mapping:
740+
741+
{
742+
"@flatten": {
743+
"value": { "@path": "$.foo" },
744+
"separator": "."
745+
}
746+
}
747+
748+
Output:
749+
750+
{
751+
"bar": "baz",
752+
"aces.a": 1,
753+
"aces.b": 2
754+
}
755+
```
756+
757+
With `omitArrays: true`, array values are preserved as-is instead of being flattened:
758+
759+
```json
760+
Input:
761+
762+
{
763+
"foo": {
764+
"bar": "baz",
765+
"tags": [1, 2]
766+
}
767+
}
768+
769+
Mapping:
770+
771+
{
772+
"@flatten": {
773+
"value": { "@path": "$.foo" },
774+
"separator": ".",
775+
"omitArrays": true
776+
}
777+
}
778+
779+
Output:
780+
781+
{
782+
"bar": "baz",
783+
"tags": [1, 2]
784+
}
785+
```
786+
787+
### @json
788+
789+
The @json directive encodes a value to a JSON string or decodes a JSON string to a value. The `mode`
790+
field must be either `"encode"` or `"decode"`, and the `value` field specifies the input.
791+
792+
```json
793+
Input:
794+
795+
{
796+
"foo": { "bar": "baz" }
797+
}
798+
799+
Mappings:
800+
801+
{ "@json": { "mode": "encode", "value": { "@path": "$.foo" } } }
802+
=>
803+
"{\"bar\":\"baz\"}"
804+
```
805+
806+
```json
807+
Input:
808+
809+
{
810+
"foo": "[\"bar\",\"baz\"]"
811+
}
812+
813+
Mappings:
814+
815+
{ "@json": { "mode": "decode", "value": { "@path": "$.foo" } } }
816+
=>
817+
["bar", "baz"]
818+
```
819+
820+
If `mode` is `"decode"` and the value is not valid JSON, the original string is returned unchanged.
821+
822+
### @liquid
823+
824+
The @liquid directive evaluates a [Liquid](https://liquidjs.com/) template string against the input
825+
payload and returns the rendered result. The directive value must be a string of at most 1000
826+
characters.
827+
828+
```json
829+
Input:
830+
831+
{
832+
"properties": {
833+
"name": "SpongeBob",
834+
"world": "Bikini Bottom"
835+
}
836+
}
837+
838+
Mappings:
839+
840+
{ "@liquid": "Hello, {{ properties.name }}!" }
841+
=>
842+
"Hello, SpongeBob!"
843+
844+
{ "@liquid": "{% if properties.world == \"Bikini Bottom\" %}Under the sea{% endif %}" }
845+
=>
846+
"Under the sea"
847+
848+
{ "@liquid": "{{ properties.name | upcase }}" }
849+
=>
850+
"SPONGEBOB"
851+
```
852+
853+
**Restrictions:** The following Liquid tags are disabled: `case`, `for`, `include`, `layout`,
854+
`render`, `tablerow`. Several array-manipulation filters (e.g. `sort`, `map`, `reverse`) are also
855+
disabled.
856+
692857
### @excludeWhenNull
693858

694859
The @excludeWhenNull directive will exclude the field from the output if the resolved value is `null`.

0 commit comments

Comments
 (0)