@edirect/template 1.5.2 → 11.0.17

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/dist/README.md ADDED
@@ -0,0 +1,1081 @@
1
+ # @edirect/template
2
+
3
+ TemplateModule is a library that provides methods to transform a payload based on a given template. The transformation includes mapping fields, applying transformers, setting default values and so on.
4
+
5
+ ### Installation
6
+
7
+ ```shell
8
+ $ npm i --save @edirect/template
9
+ ```
10
+
11
+ ### Import
12
+
13
+ ```javascript
14
+ import { TemplateModule } from './TemplateModule';
15
+ ```
16
+
17
+ ### Methods
18
+
19
+ #### `Constructor`
20
+
21
+ The TemplateModule class does not have a constructor.
22
+
23
+ #### `setContext(context): void`
24
+
25
+ Sets the context object to be used during the transformation.
26
+
27
+ #### `setTemplate(template): void`
28
+
29
+ Sets the template object that describes the transformation to be performed.
30
+
31
+ #### `setTransformers(transformers: ITransformer): void`
32
+
33
+ Sets the transformers to be used during the transformation.
34
+
35
+ #### `setOptions(transformers: ITemplateOptions): void`
36
+
37
+ Sets the options to be used during and after the transformation.
38
+
39
+ #### `verifyTransformer(transformer: ITransformer, methodName: string): boolean`
40
+
41
+ Verifies if a given transformer method exists.
42
+
43
+ #### `runTransformer(transformer: string, value?: unknown): unknown | null`
44
+
45
+ Runs a transformer on a given value.
46
+
47
+ - transformer - The name of the transformer to be used.
48
+ - value - The value to be transformed.
49
+
50
+ #### `checkValue(value: any): boolean`
51
+
52
+ Checks if a given value is not null, undefined, or an empty string.
53
+
54
+ #### `setValueByCondition(object, key: string, value: unknown)`
55
+
56
+ Sets a value in an object after verify using the checkValue() method.
57
+
58
+ - object - The object to be modified.
59
+ - key - The key of the value to be set.
60
+ - value - The value to be set.
61
+
62
+ #### `transformPayload<T, U>(obj: T, template = this.template): U`
63
+
64
+ Transforms a payload object on a given template.
65
+
66
+ ### Simple example
67
+
68
+ ```javascript
69
+ import { TemplateModule } from '@edirect/template';
70
+
71
+ const template = {
72
+ edirect_firstname: 'subscriber.firstName',
73
+ edirect_lastname: 'subscriber.lastName',
74
+ };
75
+
76
+ const dataSource = {
77
+ subscriber: {
78
+ firstName: 'template',
79
+ lastName: 'service',
80
+ },
81
+ };
82
+
83
+ const templateModule = new TemplateModule();
84
+ templateModule.setTemplate(template);
85
+
86
+ const result = templateModule.transformPayload(dataSource);
87
+
88
+ console.log(result);
89
+
90
+ // {
91
+ // edirect_firstname: "template",
92
+ // edirect_lastname: "service",
93
+ // }
94
+ ```
95
+
96
+ ### Example with transformers
97
+
98
+ #### First of all, what's a transformer?
99
+
100
+ A transformer is a way to handle values with more detail and freedom.
101
+
102
+ For example:
103
+
104
+ - Mapping
105
+ - Validation
106
+ - Formatting
107
+ - Business rules
108
+ - and so on ...
109
+
110
+ Each transformer receives two parameters:
111
+
112
+ - `value`: specific value that you want to handle
113
+ - `context`: all context (payload) that you can use to build any logical
114
+
115
+ To map a value that you'd like to use some transformer feature, you can use these options:
116
+
117
+ - `fields`: it's an array with a data source path, and the first value that is found will be used.
118
+ - `transformer`: it's a JS function, where you receive value and context as parameters and have all freedom to handle and return a value
119
+ - `defaultValue` it's an option if the engine doesn't find any value in the fields data source array or the transformer doesn't return a value.
120
+
121
+ ##### File name: baseTransformers.ts
122
+
123
+ ```javascript
124
+ import { ITransformer, ITransformerParams } from "@edirect/template";
125
+
126
+ const upperCase = ({ value }: ITransformerParams): string | null => {
127
+ return value ? String(value).toUpperCase() : null;
128
+ };
129
+
130
+ const fullName = ({ context }: ITransformerParams): string | null => {
131
+ try {
132
+ const { firstName, lastName } = context.subscriber;
133
+ return `${firstName} ${lastName}`;
134
+ } catch (error) {
135
+ return null;
136
+ }
137
+ };
138
+
139
+ const transformers: ITransformer = {
140
+ upperCase,
141
+ fullName,
142
+ };
143
+
144
+ export default transformers;
145
+ ```
146
+
147
+ ##### File name: index.ts
148
+
149
+ ```javascript
150
+ import { TemplateModule } from '@edirect/template';
151
+ import baseTransformers from './baseTransformers';
152
+
153
+ const template = {
154
+ edirect_firstname: {
155
+ fields: ['firstName', 'subscriber.firstName'],
156
+ transformer: 'upperCase',
157
+ defaultValue: 'First Name - Default',
158
+ },
159
+ edirect_lastname: {
160
+ fields: ['lastName', 'subscriber.lastName'],
161
+ },
162
+ edirect_fullname: {
163
+ transformer: 'fullName',
164
+ },
165
+ edirect_phone: {
166
+ fields: ['phoneNumber', 'subscriber.phoneNumber'],
167
+ defaultValue: '999999999',
168
+ },
169
+ timeZone: {
170
+ defaultValue: 'Time zone in Porto (GMT+1)',
171
+ },
172
+ };
173
+
174
+ const dataSource = {
175
+ subscriber: {
176
+ firstName: 'template',
177
+ lastName: 'service',
178
+ },
179
+ };
180
+
181
+ const templateModule = new TemplateModule();
182
+
183
+ templateModule.setTemplate(template);
184
+ templateModule.setContext(dataSource);
185
+ templateModule.setTransformers(baseTransformers);
186
+
187
+ const result = templateModule.transformPayload(dataSource);
188
+ console.log(result);
189
+
190
+ // {
191
+ // edirect_firstname: "TEMPLATE",
192
+ // edirect_lastname: "service",
193
+ // edirect_fullname: "template service",
194
+ // edirect_phone: "999999999",
195
+ // timeZone: "Time zone in Porto (GMT+1)",
196
+ // }
197
+ ```
198
+
199
+ ### Example with nested object + transformers
200
+
201
+ `Note`: the transformer notation uses three keys to identify an object as being a transformer: fields, transformer, and defaultValue, if there are at least 1 of these keys, the engine will consider the object as being a transformer, on the other hand, if there isn't, the engine will consider as a nested object to mapper all information.
202
+
203
+ ##### File name: baseTransformers.ts
204
+
205
+ ```javascript
206
+ import { ITransformer, ITransformerParams } from "@edirect/template";
207
+
208
+ const upperCase = ({ value }: ITransformerParams): string | null => {
209
+ return value ? String(value).toUpperCase() : null;
210
+ };
211
+
212
+ const transformers: ITransformer = {
213
+ upperCase,
214
+ };
215
+
216
+ export default transformers;
217
+ ```
218
+
219
+ ##### File name: index.ts
220
+
221
+ ```javascript
222
+ import { TemplateModule } from '@edirect/template';
223
+ import baseTransformers from './baseTransformers';
224
+
225
+ const template = {
226
+ order: {
227
+ date: 'order.date',
228
+ value: 'order.value',
229
+ subscriber: {
230
+ name: 'sub.name',
231
+ phone: 'sub.phone',
232
+ email: {
233
+ fields: ['email', 'sub.email'],
234
+ },
235
+ address: {
236
+ street: 'sub.add.stt',
237
+ number: 'sub.add.num',
238
+ city: {
239
+ fields: ['sub.add.city'],
240
+ transformer: 'upperCase',
241
+ },
242
+ state: {
243
+ fields: ['sub.add.stt'],
244
+ transformer: 'upperCase',
245
+ },
246
+ zip: {
247
+ fields: ['sub.add.zip'],
248
+ defaultValue: '0000-000',
249
+ },
250
+ },
251
+ },
252
+ },
253
+ };
254
+
255
+ const dataSource = {
256
+ order: {
257
+ value: 1000.0,
258
+ date: '2000-01-01',
259
+ },
260
+ sub: {
261
+ name: 'name-test',
262
+ phone: '999999999',
263
+ email: 'template.service@bolltech.io',
264
+ add: {
265
+ st: 'st-test',
266
+ num: 100,
267
+ city: 'city-test',
268
+ stt: 'state-test',
269
+ zip: 'zip-test',
270
+ },
271
+ },
272
+ };
273
+
274
+ const templateModule = new TemplateModule();
275
+
276
+ templateModule.setTemplate(template);
277
+ templateModule.setContext(dataSource);
278
+ templateModule.setTransformers(baseTransformers);
279
+
280
+ const result = templateModule.transformPayload(dataSource);
281
+ console.log(result);
282
+
283
+ // {
284
+ // order: {
285
+ // date: "2000-01-01",
286
+ // value: 1000,
287
+ // subscriber: {
288
+ // name: "name-test",
289
+ // phone: "999999999",
290
+ // email: "template.service@bolltech.io",
291
+ // address: {
292
+ // street: "state-test",
293
+ // number: 100,
294
+ // city: "CITY-TEST",
295
+ // state: "STATE-TEST",
296
+ // zip: "zip-test",
297
+ // },
298
+ // },
299
+ // },
300
+ // }
301
+ ```
302
+
303
+ ### Example with arrays + transformers
304
+
305
+ `Note`: When it comes to arrays mapper, we need to have in mind that is required use this two keys: arraySource and arrayTemplate.
306
+
307
+ - `arraySource`: source path where the engine will seek the information to mapper
308
+ - `arrayTemplate`: template that will be used for each object within the array
309
+
310
+ ##### File name: baseTransformers.ts
311
+
312
+ ```javascript
313
+ import { ITransformer, ITransformerParams } from "@edirect/template";
314
+
315
+ const upperCase = ({ value }: ITransformerParams): string | null => {
316
+ return value ? String(value).toUpperCase() : null;
317
+ };
318
+
319
+ const transformers: ITransformer = {
320
+ upperCase,
321
+ };
322
+
323
+ export default transformers;
324
+ ```
325
+
326
+ ##### File name: index.ts
327
+
328
+ ```javascript
329
+ import { TemplateModule } from '@edirect/template';
330
+ import baseTransformers from './baseTransformers';
331
+
332
+ const template = {
333
+ quote: {
334
+ orders: {
335
+ arraySource: 'order',
336
+ arrayTemplate: {
337
+ value: 'value',
338
+ date: 'date',
339
+ products: {
340
+ arraySource: 'products',
341
+ arrayTemplate: {
342
+ id: 'id',
343
+ value: 'value',
344
+ description: {
345
+ fields: ['description'],
346
+ transformer: 'upperCase',
347
+ defaultValue: 'Default description',
348
+ },
349
+ categories: 'categories',
350
+ },
351
+ },
352
+ },
353
+ },
354
+ },
355
+ };
356
+
357
+ const dataSource = {
358
+ order: [
359
+ {
360
+ value: 1000.0,
361
+ date: '2000-01-01',
362
+ products: [
363
+ {
364
+ id: 'id-test-1',
365
+ value: 1000,
366
+ description: 'description-test 1',
367
+ categories: ['category-1'],
368
+ },
369
+ {
370
+ id: 'id-test-2',
371
+ value: 2000,
372
+ description: 'description-test 2',
373
+ categories: ['category-1', 'category-2'],
374
+ },
375
+ {
376
+ id: 'id-test-3',
377
+ value: 3000,
378
+ categories: ['category-1', 'category-2', 'category-3'],
379
+ },
380
+ ],
381
+ },
382
+ ],
383
+ };
384
+
385
+ const templateModule = new TemplateModule();
386
+
387
+ templateModule.setTemplate(template);
388
+ templateModule.setContext(dataSource);
389
+ templateModule.setTransformers(baseTransformers);
390
+
391
+ const result = templateModule.transformPayload(dataSource);
392
+ console.log(result);
393
+
394
+ //{
395
+ // quote: {
396
+ // orders: [
397
+ // {
398
+ // value: 1000,
399
+ // date: "2000-01-01",
400
+ // products: [
401
+ // {
402
+ // id: "id-test-1",
403
+ // value: 1000,
404
+ // description: "DESCRIPTION-TEST 1",
405
+ // categories: ["category-1"],
406
+ // },
407
+ // {
408
+ // id: "id-test-2",
409
+ // value: 2000,
410
+ // description: "DESCRIPTION-TEST 2",
411
+ // categories: ["category-1", "category-2"],
412
+ // },
413
+ // {
414
+ // id: "id-test-3",
415
+ // value: 3000,
416
+ // description: "Default description",
417
+ // categories: ["category-1", "category-2", "category-3"],
418
+ // },
419
+ // ],
420
+ // },
421
+ // ],
422
+ // },
423
+ // }
424
+ ```
425
+
426
+ ### Example with arrays + ignoreIndexs
427
+
428
+ `Note`: When it comes to arrays mapper, we need to have in mind that is required use this two keys: arraySource and arrayTemplate.
429
+
430
+ - `arraySource`: source path where the engine will seek the information to mapper
431
+ - `arrayTemplate`: template that will be used for each object within the array
432
+ - `ignoreIndexs`: array with the index position that must be ignore
433
+
434
+ ##### File name: baseTransformers.ts
435
+
436
+ ```javascript
437
+ import { ITransformer, ITransformerParams } from "@edirect/template";
438
+
439
+ const upperCase = ({ value }: ITransformerParams): string | null => {
440
+ return value ? String(value).toUpperCase() : null;
441
+ };
442
+
443
+ const transformers: ITransformer = {
444
+ upperCase,
445
+ };
446
+
447
+ export default transformers;
448
+ ```
449
+
450
+ ##### File name: index.ts
451
+
452
+ ```javascript
453
+ import { TemplateModule } from '@edirect/template';
454
+ import baseTransformers from './baseTransformers';
455
+
456
+ const template = {
457
+ quote: {
458
+ orders: {
459
+ arraySource: 'order',
460
+ arrayTemplate: {
461
+ value: 'value',
462
+ date: 'date',
463
+ products: {
464
+ arraySource: 'products',
465
+ arrayTemplate: {
466
+ id: 'id',
467
+ value: 'value',
468
+ description: {
469
+ fields: ['description'],
470
+ transformer: 'upperCase',
471
+ defaultValue: 'Default description',
472
+ },
473
+ categories: 'categories',
474
+ },
475
+ ignoreIndexs: [0],
476
+ },
477
+ },
478
+ },
479
+ },
480
+ };
481
+
482
+ const dataSource = {
483
+ order: [
484
+ {
485
+ value: 1000.0,
486
+ date: '2000-01-01',
487
+ products: [
488
+ {
489
+ id: 'id-test-1',
490
+ value: 1000,
491
+ description: 'description-test 1',
492
+ categories: ['category-1'],
493
+ },
494
+ {
495
+ id: 'id-test-2',
496
+ value: 2000,
497
+ description: 'description-test 2',
498
+ categories: ['category-1', 'category-2'],
499
+ },
500
+ {
501
+ id: 'id-test-3',
502
+ value: 3000,
503
+ categories: ['category-1', 'category-2', 'category-3'],
504
+ },
505
+ ],
506
+ },
507
+ ],
508
+ };
509
+
510
+ const templateModule = new TemplateModule();
511
+
512
+ templateModule.setTemplate(template);
513
+ templateModule.setContext(dataSource);
514
+ templateModule.setTransformers(baseTransformers);
515
+
516
+ const result = templateModule.transformPayload(dataSource);
517
+ console.log(result);
518
+
519
+ //{
520
+ // quote: {
521
+ // orders: [
522
+ // {
523
+ // value: 1000,
524
+ // date: "2000-01-01",
525
+ // products: [
526
+ // {
527
+ // id: "id-test-2",
528
+ // value: 2000,
529
+ // description: "DESCRIPTION-TEST 2",
530
+ // categories: ["category-1", "category-2"],
531
+ // },
532
+ // {
533
+ // id: "id-test-3",
534
+ // value: 3000,
535
+ // description: "Default description",
536
+ // categories: ["category-1", "category-2", "category-3"],
537
+ // },
538
+ // ],
539
+ // },
540
+ // ],
541
+ // },
542
+ // }
543
+ ```
544
+
545
+ ### Template example with transformer + transformerParams
546
+
547
+ ##### File name: baseTransformers.ts
548
+
549
+ ```javascript
550
+ import { ITransformer, ITransformerParams } from "@edirect/template";
551
+
552
+ const concat = (
553
+ { value }: ITransformerParams,
554
+ ...itensToConcat: string[]
555
+ ): string => {
556
+ const arrayToConcat = [value, ...itensToConcat];
557
+ return arrayToConcat.join("");
558
+ };
559
+
560
+ const concatWithSeparator = (
561
+ { value }: ITransformerParams,
562
+ separator: string,
563
+ ...itensToConcat: string[]
564
+ ): string => {
565
+ const arrayToConcat = [value, ...itensToConcat];
566
+ return arrayToConcat.join(separator);
567
+ };
568
+
569
+ const transformers: ITransformer = {
570
+ concat,
571
+ concatWithSeparator,
572
+ };
573
+
574
+ export default transformers;
575
+ ```
576
+
577
+ ##### File name: index.ts
578
+
579
+ ```javascript
580
+ import { TemplateModule } from '@edirect/template';
581
+ import baseTransformers from './baseTransformers';
582
+
583
+ const template = {
584
+ status: 'status',
585
+ concatenated_result: {
586
+ fields: ['lead_id'],
587
+ transformer: 'concat',
588
+ transformerParams: [
589
+ '-',
590
+ '${person_number}',
591
+ '/',
592
+ '${person_number2}',
593
+ '_',
594
+ '${person_number3}',
595
+ ],
596
+ },
597
+ concatenated_result2: {
598
+ fields: ['lead_id'],
599
+ transformer: 'concatWithSeparator',
600
+ transformerParams: [
601
+ '-',
602
+ '${person_number}',
603
+ '${person_number2}',
604
+ '${person_number3}',
605
+ ],
606
+ },
607
+ };
608
+
609
+ const dataSource = {
610
+ status: true,
611
+ lead_id: 'FR-14af3f',
612
+ person_number: 123,
613
+ person_number2: 456,
614
+ person_number3: 789,
615
+ };
616
+
617
+ const templateModule = new TemplateModule();
618
+
619
+ templateModule.setTemplate(template);
620
+ templateModule.setContext(dataSource);
621
+ templateModule.setTransformers(baseTransformers);
622
+
623
+ const result = templateModule.transformPayload(dataSource);
624
+ console.log(result);
625
+
626
+ // {
627
+ // status: true,
628
+ // concatenated_result: "FR-14af3f-123/456_789",
629
+ // concatenated_result2: "FR-14af3f-123-456-789"
630
+ // }
631
+ ```
632
+
633
+ ### Template example with transformer + transformerParams + complexParams
634
+
635
+ ##### File name: baseTransformers.ts
636
+
637
+ ```javascript
638
+ import { ITransformer, ITransformerParams } from "@edirect/template";
639
+
640
+ const translator = ({ value }: ITransformerParams, translateDict: Record<string, string>): string => {
641
+ const translated = translateDict.?[value];
642
+ if (!translated) return null;
643
+ return translated;
644
+ };
645
+
646
+ const transformers: ITransformer = {
647
+ translator,
648
+ };
649
+
650
+ export default transformers;
651
+ ```
652
+
653
+ ##### File name: index.ts
654
+
655
+ ```javascript
656
+ import { TemplateModule } from '@edirect/template';
657
+ import baseTransformers from './baseTransformers';
658
+
659
+ const template = {
660
+ status: {
661
+ fields: ['status'],
662
+ transformer: 'translator',
663
+ transformerParams: [
664
+ {
665
+ ERROR: 'ERROR',
666
+ RECHAZADA: 'REJECTED',
667
+ },
668
+ ],
669
+ },
670
+ };
671
+
672
+ const dataSource = {
673
+ status: 'RECHAZADA',
674
+ };
675
+
676
+ const templateModule = new TemplateModule();
677
+
678
+ templateModule.setTemplate(template);
679
+ templateModule.setContext(dataSource);
680
+ templateModule.setTransformers(baseTransformers);
681
+
682
+ const result = templateModule.transformPayload(dataSource);
683
+ console.log(result);
684
+
685
+ // {
686
+ // status: "REJECTED",
687
+ // }
688
+ ```
689
+
690
+ ### Example with Sequential Transformers
691
+
692
+ The library now supports applying multiple transformers sequentially to a single field. This is particularly useful for more complex transformations that require multiple steps.
693
+
694
+ Each transformer in the sequence will receive the output of the previous transformer as its input value. The `allowNull` property of the last transformer in the sequence determines whether null values are allowed in the final output.
695
+
696
+ ##### File name: baseTransformers.ts
697
+
698
+ ```javascript
699
+ import { ITransformer, ITransformerParams } from "@edirect/template";
700
+
701
+ const findKeyInArrayGetField = (
702
+ { value, context }: ITransformerParams,
703
+ key: string,
704
+ valueToFind: string,
705
+ field: string,
706
+ transformer: any,
707
+ ...params: any
708
+ ): any | null => {
709
+ const listToFind = findKeyInArray({ value }, key, valueToFind);
710
+ if (typeof transformer !== "undefined") {
711
+ value = _.get(listToFind, field, null);
712
+ let transformerParams = params;
713
+ if (field === "#") {
714
+ transformerParams = [];
715
+ for (const fieldItem of params) {
716
+ let item = fieldItem;
717
+ if (fieldItem.includes("#")) {
718
+ item = _.get(listToFind, fieldItem.replace(/\#\{(.*)\}/, "$1"), null);
719
+ }
720
+ transformerParams.push(item);
721
+ }
722
+ }
723
+ if (typeof baseTransformers[transformer] !== "undefined") {
724
+ return baseTransformers[transformer]({ value, context }, ...transformerParams);
725
+ }
726
+ }
727
+ return _.get(listToFind, field, null);
728
+ };
729
+
730
+ const calculateAgeByBirthdate = ({ value }: ITransformerParams, ...formatDate: string[]): string | null => {
731
+ if (!value) return null;
732
+
733
+ if (!formatDate.length) formatDate.push("dd/MM/yyyy");
734
+
735
+ for (const format of formatDate) {
736
+ const date = parse(value, format, new Date());
737
+ if (isValid(date)) {
738
+ return differenceInYears(new Date(), date).toString();
739
+ }
740
+ }
741
+ return null;
742
+ };
743
+
744
+ const transformers: ITransformer = {
745
+ findKeyInArrayGetField,
746
+ calculateAgeByBirthdate
747
+ };
748
+
749
+ export default transformers;
750
+ ```
751
+
752
+ ##### File name: index.ts
753
+
754
+ ```javascript
755
+ import { TemplateModule } from '@edirect/template';
756
+ import baseTransformers from './baseTransformers';
757
+
758
+ const template = {
759
+ age: {
760
+ transformers: [
761
+ {
762
+ fields: ['data.externalReferences'],
763
+ transformer: 'findKeyInArrayGetField',
764
+ transformerParams: ['type', 'birthDate', 'value'],
765
+ },
766
+ {
767
+ transformer: 'calculateAgeByBirthdate',
768
+ transformerParams: ["yyyy-MM-dd'T'HH:mm:ss.SSSXXX"],
769
+ },
770
+ ],
771
+ },
772
+ };
773
+
774
+ const dataSource = {
775
+ data: {
776
+ externalReferences: [
777
+ {
778
+ type: 'randomKey',
779
+ value: 'randomValue',
780
+ },
781
+ {
782
+ type: 'birthDate',
783
+ value: '1995-12-27T15:22:32.511+00:00',
784
+ },
785
+ ],
786
+ },
787
+ };
788
+
789
+ const templateModule = new TemplateModule();
790
+
791
+ templateModule.setTemplate(template);
792
+ templateModule.setContext(dataSource);
793
+ templateModule.setTransformers(baseTransformers);
794
+
795
+ const result = templateModule.transformPayload(dataSource);
796
+ console.log(result);
797
+
798
+ // {
799
+ // age: "29"
800
+ // }
801
+ ```
802
+
803
+ In this example:
804
+
805
+ 1. The first transformer (`findKeyInArrayGetField`) extracts the birthdate value from the array of external references
806
+ 2. The second transformer (`calculateAgeByBirthdate`) calculates the age from the birthdate
807
+
808
+ The transformers are applied sequentially, with each one receiving the result of the previous transformation as its input value.
809
+
810
+ ### Example with DynamicArrayMapper in transformers array
811
+
812
+ The library now supports using DynamicArrayMapper as an element in the transformers array. This allows you to dynamically process arrays within a transformation sequence.
813
+
814
+ ##### File name: baseTransformers.ts
815
+
816
+ ```javascript
817
+ import { ITransformer, ITransformerParams } from "@edirect/template";
818
+
819
+ const addAdditionalDriver = ({ context, value }: ITransformerParams): any => {
820
+ if (!value || (value as any[]).length === 0) {
821
+ return;
822
+ }
823
+ const drivers: any[] = value;
824
+ const result = drivers.reduce((acc, driver) => {
825
+ acc.push(driver);
826
+ const type = driver.type;
827
+ if (type === "ID") {
828
+ const newDriver = cloneDeep(driver);
829
+ newDriver.type = "ND";
830
+ acc.push(newDriver);
831
+ }
832
+ return acc;
833
+ }, []);
834
+
835
+ return result;
836
+ };
837
+
838
+ const transformers: ITransformer = {
839
+ addAdditionalDriver,
840
+ };
841
+
842
+ export default transformers;
843
+ ```
844
+
845
+ ##### File name: index.ts
846
+
847
+ ```javascript
848
+ import { TemplateModule } from "@edirect/template";
849
+ import baseTransformers from "./baseTransformers";
850
+
851
+ const data = {
852
+ drivers: [
853
+ {value: 'john.doe@example.com', type:"ID" },
854
+ {value: '1234567890', type:"ND" },
855
+ {value: '123 Main St, City, Country', type:"ND" }
856
+ ]
857
+ };
858
+
859
+ const template = {
860
+ userInfo: {
861
+ name: {
862
+ transformers: [
863
+ {
864
+ "fields": [
865
+ "drivers"
866
+ ],
867
+ "transformer": "addAdditionalDriver"
868
+ },
869
+ arraySource: 'drivers',
870
+ {
871
+ arrayTemplate: {
872
+ contactType: 'type',
873
+ contactValue: {
874
+ fields: ['value'],
875
+ transformer: 'upperCase',
876
+ allowNull: false
877
+ }
878
+ }
879
+ }
880
+ ]
881
+ },
882
+ }
883
+ };
884
+
885
+ const templateModule = new TemplateModule();
886
+ templateModule.setTemplate(template);
887
+ templateModule.setTransformers(baseTransformers);
888
+ templateModule.setContext(data);
889
+
890
+ const result = templateModule.transformPayload(data);
891
+ console.log(JSON.stringify(result, null, 2));
892
+
893
+ /*
894
+ Expected output:
895
+ {
896
+ "userInfo": {
897
+ "name": [
898
+ {
899
+ "contactType": "ID",
900
+ "contactValue": "JOHN.DOE@EXAMPLE.COM"
901
+ },
902
+ {
903
+ "contactType": "ND",
904
+ "contactValue": "JOHN.DOE@EXAMPLE.COM"
905
+ },
906
+ {
907
+ "contactType": "ND",
908
+ "contactValue": "1234567890"
909
+ },
910
+ {
911
+ "contactType": "ND",
912
+ "contactValue": "123 MAIN ST, CITY, COUNTRY"
913
+ }
914
+ ]
915
+ }
916
+ }
917
+ */
918
+ ```
919
+
920
+ In this example:
921
+
922
+ 1. We have a regular transformer that capitalizes the user's name
923
+ 2. The second transformer in the sequence is a DynamicArrayMapper that processes the contacts array
924
+ 3. The result is a transformed array of contact information
925
+
926
+ You can also combine DynamicArrayMapper with subsequent transformers:
927
+
928
+ ```javascript
929
+ const templateWithMultipleTransformers = {
930
+ contactInfo: {
931
+ transformers: [
932
+ // DynamicArrayMapper to process contacts
933
+ {
934
+ arraySource: 'contacts',
935
+ arrayTemplate: {
936
+ type: 'type',
937
+ value: 'value',
938
+ },
939
+ },
940
+ // Format phone numbers in the array
941
+ {
942
+ fields: ['1.value'], // Access the phone number (index 1 in the array)
943
+ transformer: 'formatPhone',
944
+ allowNull: false,
945
+ },
946
+ ],
947
+ },
948
+ };
949
+ ```
950
+
951
+ This combination allows for powerful and flexible data transformations.
952
+
953
+ ### Example inferring types to transformPayload
954
+
955
+ ```typescript
956
+ import { TemplateModule } from '@edirect/template';
957
+
958
+ interface DataSource {
959
+ subscriber: {
960
+ firstName: string;
961
+ lastName: string;
962
+ };
963
+ }
964
+
965
+ interface TransformedData {
966
+ edirect_firstname: string;
967
+ edirect_lastname: string;
968
+ }
969
+
970
+ function transformData(dataSource: DataSource): TransformedData {
971
+ const template = {
972
+ edirect_firstname: 'subscriber.firstName',
973
+ edirect_lastname: 'subscriber.lastName',
974
+ };
975
+
976
+ const templateModule = new TemplateModule();
977
+ templateModule.setTemplate(template);
978
+
979
+ return templateModule.transformPayload<TransformedData>(dataSource);
980
+ }
981
+
982
+ const dataSource = {
983
+ subscriber: {
984
+ firstName: 'template',
985
+ lastName: 'service',
986
+ },
987
+ };
988
+
989
+ console.log(transformData(dataSource));
990
+
991
+ // {
992
+ // edirect_firstname: "template",
993
+ // edirect_lastname: "service",
994
+ // }
995
+ ```
996
+
997
+ ### Example with Options
998
+
999
+ Options:
1000
+
1001
+ - omitEmptyFields?: boolean;
1002
+
1003
+ ```js
1004
+ import { TemplateModule } from '@edirect/template';
1005
+
1006
+ const template = {
1007
+ edirect_firstname: 'subscriber.firstName',
1008
+ edirect_lastname: 'subscriber.lastName',
1009
+ edirect_age: 'subscriber.age',
1010
+ };
1011
+
1012
+ const dataSource = {
1013
+ subscriber: {
1014
+ firstName: 'template',
1015
+ lastName: 'service',
1016
+ age: '',
1017
+ },
1018
+ };
1019
+
1020
+ const options = { omitEmptyFields: true };
1021
+
1022
+ const templateModule = new TemplateModule();
1023
+ templateModule.setTemplate(template);
1024
+ templateModule.setOptions(options);
1025
+
1026
+ const result = templateModule.transformPayload(dataSource);
1027
+
1028
+ console.log(result);
1029
+
1030
+ // {
1031
+ // edirect_firstname: "template",
1032
+ // edirect_lastname: "service",
1033
+ // }
1034
+ ```
1035
+
1036
+ ### Example using simple arrays
1037
+
1038
+ ```js
1039
+ import { TemplateModule } from '@edirect/template';
1040
+
1041
+ const template = {
1042
+ emails: {
1043
+ arraySource: 'subscriber.emails',
1044
+ simpleArray: true,
1045
+ arrayTemplate: {
1046
+ type: {
1047
+ defaultValue: 'personal',
1048
+ },
1049
+ value: 'value',
1050
+ },
1051
+ },
1052
+ };
1053
+
1054
+ const dataSource = {
1055
+ subscriber: {
1056
+ emails: ['johndoe@example.com', 'janedoe@example.com'],
1057
+ },
1058
+ };
1059
+
1060
+ const templateModule = new TemplateModule();
1061
+ templateModule.setTemplate(template);
1062
+
1063
+ const result = templateModule.transformPayload(dataSource);
1064
+
1065
+ console.log(result);
1066
+
1067
+ /*
1068
+ {
1069
+ "emails": [
1070
+ {
1071
+ "type": "personal",
1072
+ "value": "johndoe@example.com"
1073
+ },
1074
+ {
1075
+ "type": "personal",
1076
+ "value": "janedoe@example.com"
1077
+ }
1078
+ ]
1079
+ }
1080
+ */
1081
+ ```