@auto-engineer/narrative 0.19.0 → 0.19.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +12 -0
- package/dist/src/data-narrative-builders.d.ts +13 -8
- package/dist/src/data-narrative-builders.d.ts.map +1 -1
- package/dist/src/data-narrative-builders.js +47 -20
- package/dist/src/data-narrative-builders.js.map +1 -1
- package/dist/src/id/addAutoIds.d.ts.map +1 -1
- package/dist/src/id/addAutoIds.js +18 -0
- package/dist/src/id/addAutoIds.js.map +1 -1
- package/dist/src/id/hasAllIds.d.ts.map +1 -1
- package/dist/src/id/hasAllIds.js +13 -1
- package/dist/src/id/hasAllIds.js.map +1 -1
- package/dist/src/schema.d.ts +231 -0
- package/dist/src/schema.d.ts.map +1 -1
- package/dist/src/schema.js +2 -0
- package/dist/src/schema.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.js +10 -5
- package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
- package/dist/src/types.d.ts +2 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/data-narrative-builders.ts +57 -20
- package/src/getNarratives.specs.ts +69 -0
- package/src/id/addAutoIds.specs.ts +268 -0
- package/src/id/addAutoIds.ts +19 -0
- package/src/id/hasAllIds.specs.ts +223 -0
- package/src/id/hasAllIds.ts +13 -1
- package/src/model-to-narrative.specs.ts +176 -0
- package/src/schema.ts +2 -0
- package/src/transformers/model-to-narrative/generators/flow.ts +16 -4
- package/src/types.ts +2 -0
package/src/id/addAutoIds.ts
CHANGED
|
@@ -77,11 +77,30 @@ function processClientSpecs(slice: Slice): Slice {
|
|
|
77
77
|
return modifiedSlice;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
function processDataItems(slice: Slice): Slice {
|
|
81
|
+
if (!('server' in slice) || !slice.server?.data || !Array.isArray(slice.server.data)) return slice;
|
|
82
|
+
|
|
83
|
+
const modifiedSlice = structuredClone(slice);
|
|
84
|
+
if ('server' in modifiedSlice && modifiedSlice.server?.data && Array.isArray(modifiedSlice.server.data)) {
|
|
85
|
+
modifiedSlice.server.data = modifiedSlice.server.data.map((item) => {
|
|
86
|
+
const itemCopy = { ...item };
|
|
87
|
+
ensureId(itemCopy);
|
|
88
|
+
if ('destination' in itemCopy && itemCopy._withState) {
|
|
89
|
+
itemCopy._withState = { ...itemCopy._withState };
|
|
90
|
+
ensureId(itemCopy._withState);
|
|
91
|
+
}
|
|
92
|
+
return itemCopy;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return modifiedSlice;
|
|
96
|
+
}
|
|
97
|
+
|
|
80
98
|
function processSlice(slice: Slice): Slice {
|
|
81
99
|
let sliceCopy = { ...slice };
|
|
82
100
|
ensureId(sliceCopy);
|
|
83
101
|
sliceCopy = processServerSpecs(sliceCopy);
|
|
84
102
|
sliceCopy = processClientSpecs(sliceCopy);
|
|
103
|
+
sliceCopy = processDataItems(sliceCopy);
|
|
85
104
|
return sliceCopy;
|
|
86
105
|
}
|
|
87
106
|
|
|
@@ -451,6 +451,229 @@ describe('hasAllIds', () => {
|
|
|
451
451
|
expect(hasAllIds(model)).toBe(true);
|
|
452
452
|
});
|
|
453
453
|
|
|
454
|
+
describe('data item ID validation', () => {
|
|
455
|
+
it('should return false when data sink is missing an ID', () => {
|
|
456
|
+
const model: Model = {
|
|
457
|
+
variant: 'specs',
|
|
458
|
+
narratives: [
|
|
459
|
+
{
|
|
460
|
+
name: 'Test Flow',
|
|
461
|
+
id: 'FLOW-001',
|
|
462
|
+
slices: [
|
|
463
|
+
{
|
|
464
|
+
type: 'command',
|
|
465
|
+
name: 'Test slice',
|
|
466
|
+
id: 'SLICE-001',
|
|
467
|
+
client: { specs: [] },
|
|
468
|
+
server: {
|
|
469
|
+
description: 'Test server',
|
|
470
|
+
specs: [],
|
|
471
|
+
data: [
|
|
472
|
+
{
|
|
473
|
+
__type: 'sink',
|
|
474
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
475
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
476
|
+
},
|
|
477
|
+
],
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
],
|
|
481
|
+
},
|
|
482
|
+
],
|
|
483
|
+
messages: [],
|
|
484
|
+
integrations: [],
|
|
485
|
+
modules: [],
|
|
486
|
+
};
|
|
487
|
+
expect(hasAllIds(model)).toBe(false);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('should return false when data source is missing an ID', () => {
|
|
491
|
+
const model: Model = {
|
|
492
|
+
variant: 'specs',
|
|
493
|
+
narratives: [
|
|
494
|
+
{
|
|
495
|
+
name: 'Test Flow',
|
|
496
|
+
id: 'FLOW-001',
|
|
497
|
+
slices: [
|
|
498
|
+
{
|
|
499
|
+
type: 'query',
|
|
500
|
+
name: 'Test slice',
|
|
501
|
+
id: 'SLICE-001',
|
|
502
|
+
client: { specs: [] },
|
|
503
|
+
server: {
|
|
504
|
+
description: 'Test server',
|
|
505
|
+
specs: [],
|
|
506
|
+
data: [
|
|
507
|
+
{
|
|
508
|
+
__type: 'source',
|
|
509
|
+
target: { type: 'State', name: 'TestState' },
|
|
510
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
511
|
+
},
|
|
512
|
+
],
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
},
|
|
517
|
+
],
|
|
518
|
+
messages: [],
|
|
519
|
+
integrations: [],
|
|
520
|
+
modules: [],
|
|
521
|
+
};
|
|
522
|
+
expect(hasAllIds(model)).toBe(false);
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it('should return false when nested _withState source is missing an ID', () => {
|
|
526
|
+
const model: Model = {
|
|
527
|
+
variant: 'specs',
|
|
528
|
+
narratives: [
|
|
529
|
+
{
|
|
530
|
+
name: 'Test Flow',
|
|
531
|
+
id: 'FLOW-001',
|
|
532
|
+
slices: [
|
|
533
|
+
{
|
|
534
|
+
type: 'command',
|
|
535
|
+
name: 'Test slice',
|
|
536
|
+
id: 'SLICE-001',
|
|
537
|
+
client: { specs: [] },
|
|
538
|
+
server: {
|
|
539
|
+
description: 'Test server',
|
|
540
|
+
specs: [],
|
|
541
|
+
data: [
|
|
542
|
+
{
|
|
543
|
+
__type: 'sink',
|
|
544
|
+
id: 'SINK-001',
|
|
545
|
+
target: { type: 'Command', name: 'TestCommand' },
|
|
546
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
547
|
+
_withState: {
|
|
548
|
+
target: { type: 'State', name: 'TestState' },
|
|
549
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
550
|
+
},
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
},
|
|
557
|
+
],
|
|
558
|
+
messages: [],
|
|
559
|
+
integrations: [],
|
|
560
|
+
modules: [],
|
|
561
|
+
};
|
|
562
|
+
expect(hasAllIds(model)).toBe(false);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it('should return true when all data items have IDs', () => {
|
|
566
|
+
const model: Model = {
|
|
567
|
+
variant: 'specs',
|
|
568
|
+
narratives: [
|
|
569
|
+
{
|
|
570
|
+
name: 'Test Flow',
|
|
571
|
+
id: 'FLOW-001',
|
|
572
|
+
slices: [
|
|
573
|
+
{
|
|
574
|
+
type: 'command',
|
|
575
|
+
name: 'Test slice',
|
|
576
|
+
id: 'SLICE-001',
|
|
577
|
+
client: { specs: [] },
|
|
578
|
+
server: {
|
|
579
|
+
description: 'Test server',
|
|
580
|
+
specs: [],
|
|
581
|
+
data: [
|
|
582
|
+
{
|
|
583
|
+
__type: 'sink',
|
|
584
|
+
id: 'SINK-001',
|
|
585
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
586
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
__type: 'source',
|
|
590
|
+
id: 'SOURCE-001',
|
|
591
|
+
target: { type: 'State', name: 'TestState' },
|
|
592
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
593
|
+
},
|
|
594
|
+
],
|
|
595
|
+
},
|
|
596
|
+
},
|
|
597
|
+
],
|
|
598
|
+
},
|
|
599
|
+
],
|
|
600
|
+
messages: [],
|
|
601
|
+
integrations: [],
|
|
602
|
+
modules: [],
|
|
603
|
+
};
|
|
604
|
+
expect(hasAllIds(model)).toBe(true);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it('should return true when sink with _withState both have IDs', () => {
|
|
608
|
+
const model: Model = {
|
|
609
|
+
variant: 'specs',
|
|
610
|
+
narratives: [
|
|
611
|
+
{
|
|
612
|
+
name: 'Test Flow',
|
|
613
|
+
id: 'FLOW-001',
|
|
614
|
+
slices: [
|
|
615
|
+
{
|
|
616
|
+
type: 'command',
|
|
617
|
+
name: 'Test slice',
|
|
618
|
+
id: 'SLICE-001',
|
|
619
|
+
client: { specs: [] },
|
|
620
|
+
server: {
|
|
621
|
+
description: 'Test server',
|
|
622
|
+
specs: [],
|
|
623
|
+
data: [
|
|
624
|
+
{
|
|
625
|
+
__type: 'sink',
|
|
626
|
+
id: 'SINK-001',
|
|
627
|
+
target: { type: 'Command', name: 'TestCommand' },
|
|
628
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
629
|
+
_withState: {
|
|
630
|
+
id: 'SOURCE-001',
|
|
631
|
+
target: { type: 'State', name: 'TestState' },
|
|
632
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
],
|
|
639
|
+
},
|
|
640
|
+
],
|
|
641
|
+
messages: [],
|
|
642
|
+
integrations: [],
|
|
643
|
+
modules: [],
|
|
644
|
+
};
|
|
645
|
+
expect(hasAllIds(model)).toBe(true);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
it('should return true when slice has no data array', () => {
|
|
649
|
+
const model: Model = {
|
|
650
|
+
variant: 'specs',
|
|
651
|
+
narratives: [
|
|
652
|
+
{
|
|
653
|
+
name: 'Test Flow',
|
|
654
|
+
id: 'FLOW-001',
|
|
655
|
+
slices: [
|
|
656
|
+
{
|
|
657
|
+
type: 'command',
|
|
658
|
+
name: 'Test slice',
|
|
659
|
+
id: 'SLICE-001',
|
|
660
|
+
client: { specs: [] },
|
|
661
|
+
server: {
|
|
662
|
+
description: 'Test server',
|
|
663
|
+
specs: [],
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
},
|
|
668
|
+
],
|
|
669
|
+
messages: [],
|
|
670
|
+
integrations: [],
|
|
671
|
+
modules: [],
|
|
672
|
+
};
|
|
673
|
+
expect(hasAllIds(model)).toBe(true);
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
|
|
454
677
|
describe('module ID validation', () => {
|
|
455
678
|
it('should return true when all modules have IDs', () => {
|
|
456
679
|
const model: Model = {
|
package/src/id/hasAllIds.ts
CHANGED
|
@@ -40,8 +40,20 @@ function hasClientSpecIds(slice: Slice): boolean {
|
|
|
40
40
|
return hasClientSpecNodeIds(slice.client.specs);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function hasDataIds(slice: Slice): boolean {
|
|
44
|
+
if (!('server' in slice) || !slice.server?.data || !Array.isArray(slice.server.data)) return true;
|
|
45
|
+
|
|
46
|
+
return slice.server.data.every((item) => {
|
|
47
|
+
if (!hasValidId(item)) return false;
|
|
48
|
+
if ('destination' in item && item._withState) {
|
|
49
|
+
return hasValidId(item._withState);
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
43
55
|
function hasSliceIds(slice: Slice): boolean {
|
|
44
|
-
return hasValidId(slice) && hasServerSpecIds(slice) && hasClientSpecIds(slice);
|
|
56
|
+
return hasValidId(slice) && hasServerSpecIds(slice) && hasClientSpecIds(slice) && hasDataIds(slice);
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
function hasModuleIds(modules: Module[]): boolean {
|
|
@@ -2938,4 +2938,180 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2938
2938
|
}
|
|
2939
2939
|
});
|
|
2940
2940
|
});
|
|
2941
|
+
|
|
2942
|
+
describe('data item IDs', () => {
|
|
2943
|
+
it('should generate sink id when provided', async () => {
|
|
2944
|
+
const modelWithSinkId: Model = {
|
|
2945
|
+
variant: 'specs',
|
|
2946
|
+
narratives: [
|
|
2947
|
+
{
|
|
2948
|
+
name: 'Order Flow',
|
|
2949
|
+
id: 'ORDER-FLOW',
|
|
2950
|
+
slices: [
|
|
2951
|
+
{
|
|
2952
|
+
name: 'places order',
|
|
2953
|
+
id: 'ORDER-SLICE',
|
|
2954
|
+
type: 'command',
|
|
2955
|
+
client: { specs: [] },
|
|
2956
|
+
server: {
|
|
2957
|
+
description: 'Order server',
|
|
2958
|
+
data: [
|
|
2959
|
+
{
|
|
2960
|
+
id: 'SINK-001',
|
|
2961
|
+
target: { type: 'Event', name: 'OrderPlaced' },
|
|
2962
|
+
destination: { type: 'stream', pattern: 'orders-stream' },
|
|
2963
|
+
},
|
|
2964
|
+
],
|
|
2965
|
+
specs: [],
|
|
2966
|
+
},
|
|
2967
|
+
},
|
|
2968
|
+
],
|
|
2969
|
+
},
|
|
2970
|
+
],
|
|
2971
|
+
messages: [
|
|
2972
|
+
{
|
|
2973
|
+
type: 'event',
|
|
2974
|
+
source: 'internal',
|
|
2975
|
+
name: 'OrderPlaced',
|
|
2976
|
+
fields: [{ name: 'orderId', type: 'string', required: true }],
|
|
2977
|
+
},
|
|
2978
|
+
],
|
|
2979
|
+
integrations: [],
|
|
2980
|
+
modules: [],
|
|
2981
|
+
};
|
|
2982
|
+
|
|
2983
|
+
const code = getCode(await modelToNarrative(modelWithSinkId));
|
|
2984
|
+
expect(code).toContain("sink('SINK-001').event('OrderPlaced').toStream('orders-stream')");
|
|
2985
|
+
});
|
|
2986
|
+
|
|
2987
|
+
it('should generate source id when provided', async () => {
|
|
2988
|
+
const modelWithSourceId: Model = {
|
|
2989
|
+
variant: 'specs',
|
|
2990
|
+
narratives: [
|
|
2991
|
+
{
|
|
2992
|
+
name: 'Order Flow',
|
|
2993
|
+
id: 'ORDER-FLOW',
|
|
2994
|
+
slices: [
|
|
2995
|
+
{
|
|
2996
|
+
name: 'views order',
|
|
2997
|
+
id: 'ORDER-SLICE',
|
|
2998
|
+
type: 'query',
|
|
2999
|
+
client: { specs: [] },
|
|
3000
|
+
server: {
|
|
3001
|
+
description: 'Order server',
|
|
3002
|
+
data: [
|
|
3003
|
+
{
|
|
3004
|
+
id: 'SOURCE-001',
|
|
3005
|
+
target: { type: 'State', name: 'OrderState' },
|
|
3006
|
+
origin: { type: 'projection', name: 'Orders', idField: 'orderId' },
|
|
3007
|
+
},
|
|
3008
|
+
],
|
|
3009
|
+
specs: [],
|
|
3010
|
+
},
|
|
3011
|
+
},
|
|
3012
|
+
],
|
|
3013
|
+
},
|
|
3014
|
+
],
|
|
3015
|
+
messages: [
|
|
3016
|
+
{
|
|
3017
|
+
type: 'state',
|
|
3018
|
+
name: 'OrderState',
|
|
3019
|
+
fields: [{ name: 'orderId', type: 'string', required: true }],
|
|
3020
|
+
},
|
|
3021
|
+
],
|
|
3022
|
+
integrations: [],
|
|
3023
|
+
modules: [],
|
|
3024
|
+
};
|
|
3025
|
+
|
|
3026
|
+
const code = getCode(await modelToNarrative(modelWithSourceId));
|
|
3027
|
+
expect(code).toContain("source('SOURCE-001').state('OrderState').fromProjection('Orders', 'orderId')");
|
|
3028
|
+
});
|
|
3029
|
+
|
|
3030
|
+
it('should not generate id when not provided', async () => {
|
|
3031
|
+
const modelWithoutId: Model = {
|
|
3032
|
+
variant: 'specs',
|
|
3033
|
+
narratives: [
|
|
3034
|
+
{
|
|
3035
|
+
name: 'Order Flow',
|
|
3036
|
+
id: 'ORDER-FLOW',
|
|
3037
|
+
slices: [
|
|
3038
|
+
{
|
|
3039
|
+
name: 'places order',
|
|
3040
|
+
id: 'ORDER-SLICE',
|
|
3041
|
+
type: 'command',
|
|
3042
|
+
client: { specs: [] },
|
|
3043
|
+
server: {
|
|
3044
|
+
description: 'Order server',
|
|
3045
|
+
data: [
|
|
3046
|
+
{
|
|
3047
|
+
target: { type: 'Event', name: 'OrderPlaced' },
|
|
3048
|
+
destination: { type: 'stream', pattern: 'orders-stream' },
|
|
3049
|
+
},
|
|
3050
|
+
],
|
|
3051
|
+
specs: [],
|
|
3052
|
+
},
|
|
3053
|
+
},
|
|
3054
|
+
],
|
|
3055
|
+
},
|
|
3056
|
+
],
|
|
3057
|
+
messages: [
|
|
3058
|
+
{
|
|
3059
|
+
type: 'event',
|
|
3060
|
+
source: 'internal',
|
|
3061
|
+
name: 'OrderPlaced',
|
|
3062
|
+
fields: [{ name: 'orderId', type: 'string', required: true }],
|
|
3063
|
+
},
|
|
3064
|
+
],
|
|
3065
|
+
integrations: [],
|
|
3066
|
+
modules: [],
|
|
3067
|
+
};
|
|
3068
|
+
|
|
3069
|
+
const code = getCode(await modelToNarrative(modelWithoutId));
|
|
3070
|
+
expect(code).toContain("sink().event('OrderPlaced').toStream('orders-stream')");
|
|
3071
|
+
expect(code).not.toContain("sink('')");
|
|
3072
|
+
});
|
|
3073
|
+
|
|
3074
|
+
it('should generate _additionalInstructions on source items', async () => {
|
|
3075
|
+
const modelWithSourceInstructions: Model = {
|
|
3076
|
+
variant: 'specs',
|
|
3077
|
+
narratives: [
|
|
3078
|
+
{
|
|
3079
|
+
name: 'Order Flow',
|
|
3080
|
+
id: 'ORDER-FLOW',
|
|
3081
|
+
slices: [
|
|
3082
|
+
{
|
|
3083
|
+
name: 'views order',
|
|
3084
|
+
id: 'ORDER-SLICE',
|
|
3085
|
+
type: 'query',
|
|
3086
|
+
client: { specs: [] },
|
|
3087
|
+
server: {
|
|
3088
|
+
description: 'Order server',
|
|
3089
|
+
data: [
|
|
3090
|
+
{
|
|
3091
|
+
target: { type: 'State', name: 'OrderState' },
|
|
3092
|
+
origin: { type: 'projection', name: 'Orders', idField: 'orderId' },
|
|
3093
|
+
_additionalInstructions: 'Filter by active orders only',
|
|
3094
|
+
},
|
|
3095
|
+
],
|
|
3096
|
+
specs: [],
|
|
3097
|
+
},
|
|
3098
|
+
},
|
|
3099
|
+
],
|
|
3100
|
+
},
|
|
3101
|
+
],
|
|
3102
|
+
messages: [
|
|
3103
|
+
{
|
|
3104
|
+
type: 'state',
|
|
3105
|
+
name: 'OrderState',
|
|
3106
|
+
fields: [{ name: 'orderId', type: 'string', required: true }],
|
|
3107
|
+
},
|
|
3108
|
+
],
|
|
3109
|
+
integrations: [],
|
|
3110
|
+
modules: [],
|
|
3111
|
+
};
|
|
3112
|
+
|
|
3113
|
+
const code = getCode(await modelToNarrative(modelWithSourceInstructions));
|
|
3114
|
+
expect(code).toContain(".additionalInstructions('Filter by active orders only')");
|
|
3115
|
+
});
|
|
3116
|
+
});
|
|
2941
3117
|
});
|
package/src/schema.ts
CHANGED
|
@@ -112,6 +112,7 @@ export const OriginSchema = z
|
|
|
112
112
|
|
|
113
113
|
const DataSinkSchema = z
|
|
114
114
|
.object({
|
|
115
|
+
id: z.string().optional().describe('Optional unique identifier for the data sink'),
|
|
115
116
|
target: MessageTargetSchema,
|
|
116
117
|
destination: DestinationSchema,
|
|
117
118
|
transform: z.string().optional().describe('Optional transformation function name'),
|
|
@@ -125,6 +126,7 @@ const DataSinkSchema = z
|
|
|
125
126
|
|
|
126
127
|
const DataSourceSchema = z
|
|
127
128
|
.object({
|
|
129
|
+
id: z.string().optional().describe('Optional unique identifier for the data source'),
|
|
128
130
|
target: MessageTargetSchema,
|
|
129
131
|
origin: OriginSchema,
|
|
130
132
|
transform: z.string().optional().describe('Optional transformation function name'),
|
|
@@ -84,13 +84,15 @@ function buildInitialChain(
|
|
|
84
84
|
ts: typeof import('typescript'),
|
|
85
85
|
f: tsNS.NodeFactory,
|
|
86
86
|
target: DataSinkItem['target'] | DataSourceItem['target'],
|
|
87
|
+
id?: string,
|
|
87
88
|
): tsNS.Expression {
|
|
88
89
|
const op = target.type === 'Event' ? 'event' : target.type === 'Command' ? 'command' : 'state';
|
|
90
|
+
const sinkOrSourceArgs: tsNS.Expression[] = id != null && id !== '' ? [f.createStringLiteral(id)] : [];
|
|
89
91
|
return f.createCallExpression(
|
|
90
92
|
f.createPropertyAccessExpression(
|
|
91
93
|
target.type === 'State'
|
|
92
|
-
? f.createCallExpression(f.createIdentifier('source'), undefined,
|
|
93
|
-
: f.createCallExpression(f.createIdentifier('sink'), undefined,
|
|
94
|
+
? f.createCallExpression(f.createIdentifier('source'), undefined, sinkOrSourceArgs)
|
|
95
|
+
: f.createCallExpression(f.createIdentifier('sink'), undefined, sinkOrSourceArgs),
|
|
94
96
|
ts.factory.createIdentifier(op),
|
|
95
97
|
),
|
|
96
98
|
undefined,
|
|
@@ -309,7 +311,7 @@ function buildSingleDataItem(
|
|
|
309
311
|
f: tsNS.NodeFactory,
|
|
310
312
|
it: DataSinkItem | DataSourceItem,
|
|
311
313
|
): tsNS.Expression {
|
|
312
|
-
let chain = buildInitialChain(ts, f, it.target);
|
|
314
|
+
let chain = buildInitialChain(ts, f, it.target, it.id);
|
|
313
315
|
|
|
314
316
|
if ('destination' in it) {
|
|
315
317
|
const sinkItem = it;
|
|
@@ -333,11 +335,13 @@ function buildSingleDataItem(
|
|
|
333
335
|
}
|
|
334
336
|
} else if ('origin' in it) {
|
|
335
337
|
const sourceItem = it;
|
|
338
|
+
const sourceArgs: tsNS.Expression[] =
|
|
339
|
+
sourceItem.id != null && sourceItem.id !== '' ? [f.createStringLiteral(sourceItem.id)] : [];
|
|
336
340
|
chain = f.createCallExpression(
|
|
337
341
|
f.createPropertyAccessExpression(
|
|
338
342
|
f.createCallExpression(
|
|
339
343
|
f.createPropertyAccessExpression(
|
|
340
|
-
f.createCallExpression(f.createIdentifier('source'), undefined,
|
|
344
|
+
f.createCallExpression(f.createIdentifier('source'), undefined, sourceArgs),
|
|
341
345
|
f.createIdentifier('state'),
|
|
342
346
|
),
|
|
343
347
|
undefined,
|
|
@@ -348,6 +352,14 @@ function buildSingleDataItem(
|
|
|
348
352
|
undefined,
|
|
349
353
|
buildOriginArgs(ts, f, sourceItem.origin),
|
|
350
354
|
);
|
|
355
|
+
|
|
356
|
+
if (sourceItem._additionalInstructions != null && sourceItem._additionalInstructions !== '') {
|
|
357
|
+
chain = f.createCallExpression(
|
|
358
|
+
f.createPropertyAccessExpression(chain, f.createIdentifier('additionalInstructions')),
|
|
359
|
+
undefined,
|
|
360
|
+
[f.createStringLiteral(sourceItem._additionalInstructions)],
|
|
361
|
+
);
|
|
362
|
+
}
|
|
351
363
|
}
|
|
352
364
|
|
|
353
365
|
return chain;
|
package/src/types.ts
CHANGED
|
@@ -130,6 +130,7 @@ export const createApiOrigin = (endpoint: string, method?: string): ApiOrigin =>
|
|
|
130
130
|
export const createIntegrationOrigin = (systems: string[]): IntegrationOrigin => ({ type: 'integration', systems });
|
|
131
131
|
|
|
132
132
|
export interface DataSink {
|
|
133
|
+
id?: string;
|
|
133
134
|
target: MessageTarget;
|
|
134
135
|
destination: Destination;
|
|
135
136
|
transform?: string;
|
|
@@ -138,6 +139,7 @@ export interface DataSink {
|
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
export interface DataSource {
|
|
142
|
+
id?: string;
|
|
141
143
|
target: MessageTarget;
|
|
142
144
|
origin: Origin;
|
|
143
145
|
transform?: string;
|