@auto-engineer/narrative 1.138.0 → 1.140.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +5 -5
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +41 -0
- package/dist/scripts/convert-flow-exec.js +2 -2
- package/dist/scripts/convert-flow-exec.js.map +1 -1
- package/dist/scripts/print-schema.js +5 -5
- package/dist/scripts/print-schema.js.map +1 -1
- package/dist/src/fluent-builder.d.ts +29 -29
- package/dist/src/fluent-builder.d.ts.map +1 -1
- package/dist/src/fluent-builder.js +81 -81
- package/dist/src/fluent-builder.js.map +1 -1
- package/dist/src/{getNarratives.d.ts → getScenes.d.ts} +6 -6
- package/dist/src/getScenes.d.ts.map +1 -0
- package/dist/src/{getNarratives.js → getScenes.js} +16 -16
- package/dist/src/getScenes.js.map +1 -0
- package/dist/src/id/addAutoIds.d.ts.map +1 -1
- package/dist/src/id/addAutoIds.js +22 -22
- 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 +2 -2
- package/dist/src/id/hasAllIds.js.map +1 -1
- package/dist/src/index.d.ts +8 -8
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/loader/index.js +1 -1
- package/dist/src/loader/index.js.map +1 -1
- package/dist/src/loader/runtime-cjs.js +1 -1
- package/dist/src/loader/runtime-cjs.js.map +1 -1
- package/dist/src/narrative-context.d.ts +9 -9
- package/dist/src/narrative-context.d.ts.map +1 -1
- package/dist/src/narrative-context.js +47 -47
- package/dist/src/narrative-context.js.map +1 -1
- package/dist/src/narrative-registry.d.ts +6 -6
- package/dist/src/narrative-registry.d.ts.map +1 -1
- package/dist/src/narrative-registry.js +26 -26
- package/dist/src/narrative-registry.js.map +1 -1
- package/dist/src/narrative.d.ts +5 -5
- package/dist/src/narrative.d.ts.map +1 -1
- package/dist/src/narrative.js +26 -27
- package/dist/src/narrative.js.map +1 -1
- package/dist/src/parse-graphql-request.d.ts +1 -1
- package/dist/src/parse-graphql-request.d.ts.map +1 -1
- package/dist/src/parse-graphql-request.js +3 -3
- package/dist/src/parse-graphql-request.js.map +1 -1
- package/dist/src/samples/items.narrative.js +2 -2
- package/dist/src/samples/items.narrative.js.map +1 -1
- package/dist/src/samples/mixed-given-types.narrative.js +2 -2
- package/dist/src/samples/mixed-given-types.narrative.js.map +1 -1
- package/dist/src/samples/place-order.narrative.js +2 -2
- package/dist/src/samples/place-order.narrative.js.map +1 -1
- package/dist/src/samples/questionnaires.narrative.js +2 -2
- package/dist/src/samples/questionnaires.narrative.js.map +1 -1
- package/dist/src/samples/seasonal-assistant.schema.json +2 -2
- package/dist/src/samples/test-with-ids.narrative.js +2 -2
- package/dist/src/samples/test-with-ids.narrative.js.map +1 -1
- package/dist/src/schema.d.ts +136 -136
- package/dist/src/schema.d.ts.map +1 -1
- package/dist/src/schema.js +76 -76
- package/dist/src/schema.js.map +1 -1
- package/dist/src/slice-builder.d.ts +6 -6
- package/dist/src/slice-builder.d.ts.map +1 -1
- package/dist/src/slice-builder.js +21 -21
- package/dist/src/slice-builder.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/analysis/lint-helpers.js +1 -1
- package/dist/src/transformers/model-to-narrative/analysis/lint-helpers.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/cross-module-imports.js +4 -4
- package/dist/src/transformers/model-to-narrative/cross-module-imports.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/compose.js +3 -3
- package/dist/src/transformers/model-to-narrative/generators/compose.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts +2 -2
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.js +20 -20
- package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.js +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/module-code.js +14 -14
- package/dist/src/transformers/model-to-narrative/generators/module-code.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/index.d.ts +4 -4
- package/dist/src/transformers/model-to-narrative/index.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/index.js +1 -1
- package/dist/src/transformers/model-to-narrative/spec-traversal.d.ts +2 -2
- package/dist/src/transformers/model-to-narrative/spec-traversal.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/spec-traversal.js +5 -5
- package/dist/src/transformers/model-to-narrative/spec-traversal.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/types.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/types.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.js +4 -4
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/validate-modules.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/validate-modules.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/validate-modules.js +19 -19
- package/dist/src/transformers/model-to-narrative/validate-modules.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/assemble.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/assemble.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/assemble.js +10 -3
- package/dist/src/transformers/narrative-to-model/assemble.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/debug.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/debug.js +1 -1
- package/dist/src/transformers/narrative-to-model/debug.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/derive-modules.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/derive-modules.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/derive-modules.js +9 -9
- package/dist/src/transformers/narrative-to-model/derive-modules.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.js +39 -39
- package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/spec-processors.js +1 -1
- package/dist/src/transformers/narrative-to-model/spec-processors.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/strings.d.ts +1 -1
- package/dist/src/transformers/narrative-to-model/strings.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/strings.js +6 -6
- package/dist/src/transformers/narrative-to-model/strings.js.map +1 -1
- package/dist/src/validate-slice-requests.d.ts +4 -4
- package/dist/src/validate-slice-requests.d.ts.map +1 -1
- package/dist/src/validate-slice-requests.js +34 -34
- package/dist/src/validate-slice-requests.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/scripts/convert-flow-exec.ts +2 -2
- package/scripts/print-schema.ts +8 -8
- package/src/fluent-builder.specs.ts +3 -3
- package/src/fluent-builder.ts +141 -141
- package/src/{getNarratives.cache.specs.ts → getScenes.cache.specs.ts} +45 -45
- package/src/{getNarratives.specs.ts → getScenes.specs.ts} +302 -300
- package/src/{getNarratives.ts → getScenes.ts} +20 -20
- package/src/id/addAutoIds.specs.ts +105 -105
- package/src/id/addAutoIds.ts +26 -26
- package/src/id/hasAllIds.specs.ts +59 -59
- package/src/id/hasAllIds.ts +6 -6
- package/src/index.ts +12 -13
- package/src/loader/index.ts +1 -1
- package/src/loader/runtime-cjs.ts +1 -1
- package/src/model-to-narrative.specs.ts +133 -135
- package/src/narrative-context.specs.ts +24 -24
- package/src/narrative-context.ts +61 -61
- package/src/narrative-registry.ts +31 -31
- package/src/narrative.ts +31 -33
- package/src/parse-graphql-request.specs.ts +5 -5
- package/src/parse-graphql-request.ts +3 -3
- package/src/samples/items.narrative.ts +2 -2
- package/src/samples/mixed-given-types.narrative.ts +2 -2
- package/src/samples/place-order.narrative.ts +2 -2
- package/src/samples/questionnaires.narrative.ts +2 -2
- package/src/samples/seasonal-assistant.schema.json +2 -2
- package/src/samples/test-with-ids.narrative.ts +2 -2
- package/src/schema.specs.ts +99 -91
- package/src/schema.ts +89 -89
- package/src/slice-builder.ts +30 -30
- package/src/transformers/model-to-narrative/analysis/lint-helpers.ts +1 -1
- package/src/transformers/model-to-narrative/cross-module-imports.specs.ts +43 -43
- package/src/transformers/model-to-narrative/cross-module-imports.ts +4 -4
- package/src/transformers/model-to-narrative/generators/compose.ts +4 -4
- package/src/transformers/model-to-narrative/generators/flow.ts +36 -36
- package/src/transformers/model-to-narrative/generators/imports.ts +1 -1
- package/src/transformers/model-to-narrative/generators/module-code.ts +15 -15
- package/src/transformers/model-to-narrative/index.ts +4 -4
- package/src/transformers/model-to-narrative/modules.specs.ts +58 -58
- package/src/transformers/model-to-narrative/spec-traversal.specs.ts +43 -43
- package/src/transformers/model-to-narrative/spec-traversal.ts +6 -6
- package/src/transformers/model-to-narrative/types.ts +1 -1
- package/src/transformers/model-to-narrative/utils/integration-extractor.ts +5 -5
- package/src/transformers/model-to-narrative/validate-modules.ts +22 -22
- package/src/transformers/narrative-to-model/assemble.ts +12 -4
- package/src/transformers/narrative-to-model/debug.ts +1 -1
- package/src/transformers/narrative-to-model/derive-modules.specs.ts +35 -35
- package/src/transformers/narrative-to-model/derive-modules.ts +11 -11
- package/src/transformers/narrative-to-model/index.ts +47 -47
- package/src/transformers/narrative-to-model/spec-processors.ts +1 -1
- package/src/transformers/narrative-to-model/strings.ts +6 -6
- package/src/transformers/narrative-to-model/type-inference.specs.ts +11 -11
- package/src/validate-slice-requests.specs.ts +113 -113
- package/src/validate-slice-requests.ts +49 -49
- package/dist/src/getNarratives.d.ts.map +0 -1
- package/dist/src/getNarratives.js.map +0 -1
|
@@ -19,10 +19,10 @@ describe('modelToNarrative', () => {
|
|
|
19
19
|
example,
|
|
20
20
|
gql,
|
|
21
21
|
it,
|
|
22
|
-
narrative,
|
|
23
22
|
query,
|
|
24
23
|
react,
|
|
25
24
|
rule,
|
|
25
|
+
scene,
|
|
26
26
|
sink,
|
|
27
27
|
source,
|
|
28
28
|
specs,
|
|
@@ -107,7 +107,7 @@ type ItemsAddedToCart = Event<
|
|
|
107
107
|
}[];
|
|
108
108
|
}
|
|
109
109
|
>;
|
|
110
|
-
|
|
110
|
+
scene('Seasonal Assistant', () => {
|
|
111
111
|
command('enters shopping criteria into assistant')
|
|
112
112
|
.client(() => {
|
|
113
113
|
describe('Assistant Chat Interface', () => {
|
|
@@ -382,11 +382,11 @@ narrative('Seasonal Assistant', () => {
|
|
|
382
382
|
it('should handle experience slices in model to flow conversion', async () => {
|
|
383
383
|
const experienceModel: Model = {
|
|
384
384
|
variant: 'specs',
|
|
385
|
-
|
|
385
|
+
scenes: [
|
|
386
386
|
{
|
|
387
387
|
name: 'Test Experience Flow',
|
|
388
388
|
id: 'TEST-001',
|
|
389
|
-
|
|
389
|
+
moments: [
|
|
390
390
|
{
|
|
391
391
|
name: 'Homepage',
|
|
392
392
|
id: 'EXP-001',
|
|
@@ -408,8 +408,8 @@ narrative('Seasonal Assistant', () => {
|
|
|
408
408
|
|
|
409
409
|
const code = getCode(await modelToNarrative(experienceModel));
|
|
410
410
|
|
|
411
|
-
expect(code).toEqual(`import { experience, it,
|
|
412
|
-
|
|
411
|
+
expect(code).toEqual(`import { experience, it, scene } from '@auto-engineer/narrative';
|
|
412
|
+
scene('Test Experience Flow', 'TEST-001', () => {
|
|
413
413
|
experience('Homepage', 'EXP-001').client(() => {
|
|
414
414
|
it('show a hero section with a welcome message');
|
|
415
415
|
it('allow user to start the questionnaire');
|
|
@@ -421,11 +421,11 @@ narrative('Test Experience Flow', 'TEST-001', () => {
|
|
|
421
421
|
it('should handle flows and slices without IDs', async () => {
|
|
422
422
|
const modelWithoutIds: Model = {
|
|
423
423
|
variant: 'specs',
|
|
424
|
-
|
|
424
|
+
scenes: [
|
|
425
425
|
{
|
|
426
426
|
name: 'Test Flow without IDs',
|
|
427
427
|
// id: undefined - no ID
|
|
428
|
-
|
|
428
|
+
moments: [
|
|
429
429
|
{
|
|
430
430
|
name: 'Homepage',
|
|
431
431
|
// id: undefined - no ID
|
|
@@ -453,8 +453,8 @@ narrative('Test Experience Flow', 'TEST-001', () => {
|
|
|
453
453
|
|
|
454
454
|
const code = getCode(await modelToNarrative(modelWithoutIds));
|
|
455
455
|
|
|
456
|
-
expect(code).toEqual(`import { describe, experience, it,
|
|
457
|
-
|
|
456
|
+
expect(code).toEqual(`import { describe, experience, it, scene } from '@auto-engineer/narrative';
|
|
457
|
+
scene('Test Flow without IDs', () => {
|
|
458
458
|
experience('Homepage').client(() => {
|
|
459
459
|
describe('Homepage specs', () => {
|
|
460
460
|
it('show welcome message');
|
|
@@ -468,11 +468,11 @@ narrative('Test Flow without IDs', () => {
|
|
|
468
468
|
it('should include flow and slice IDs in generated code', async () => {
|
|
469
469
|
const modelWithIds: Model = {
|
|
470
470
|
variant: 'specs',
|
|
471
|
-
|
|
471
|
+
scenes: [
|
|
472
472
|
{
|
|
473
473
|
name: 'Test Flow with IDs',
|
|
474
474
|
id: 'FLOW-123',
|
|
475
|
-
|
|
475
|
+
moments: [
|
|
476
476
|
{
|
|
477
477
|
name: 'Homepage',
|
|
478
478
|
id: 'SLICE-ABC',
|
|
@@ -527,8 +527,8 @@ narrative('Test Flow without IDs', () => {
|
|
|
527
527
|
|
|
528
528
|
const code = getCode(await modelToNarrative(modelWithIds));
|
|
529
529
|
|
|
530
|
-
expect(code).toEqual(`import { describe, experience, it,
|
|
531
|
-
|
|
530
|
+
expect(code).toEqual(`import { describe, experience, it, query, scene, specs } from '@auto-engineer/narrative';
|
|
531
|
+
scene('Test Flow with IDs', 'FLOW-123', () => {
|
|
532
532
|
experience('Homepage', 'SLICE-ABC').client(() => {
|
|
533
533
|
describe('Homepage specs', () => {
|
|
534
534
|
it('show welcome message');
|
|
@@ -552,11 +552,11 @@ narrative('Test Flow with IDs', 'FLOW-123', () => {
|
|
|
552
552
|
it('should include rule IDs in server specs when present', async () => {
|
|
553
553
|
const modelWithRuleIds: Model = {
|
|
554
554
|
variant: 'specs',
|
|
555
|
-
|
|
555
|
+
scenes: [
|
|
556
556
|
{
|
|
557
557
|
name: 'Test Flow with Rule IDs',
|
|
558
558
|
id: 'FLOW-456',
|
|
559
|
-
|
|
559
|
+
moments: [
|
|
560
560
|
{
|
|
561
561
|
name: 'process command',
|
|
562
562
|
id: 'SLICE-789',
|
|
@@ -628,7 +628,7 @@ narrative('Test Flow with IDs', 'FLOW-123', () => {
|
|
|
628
628
|
|
|
629
629
|
const code = getCode(await modelToNarrative(modelWithRuleIds));
|
|
630
630
|
|
|
631
|
-
expect(code).toEqual(`import { command, example,
|
|
631
|
+
expect(code).toEqual(`import { command, example, rule, scene, specs } from '@auto-engineer/narrative';
|
|
632
632
|
import type { Command, Event } from '@auto-engineer/narrative';
|
|
633
633
|
type ProcessCommand = Command<
|
|
634
634
|
'ProcessCommand',
|
|
@@ -644,7 +644,7 @@ type CommandProcessed = Event<
|
|
|
644
644
|
status: string;
|
|
645
645
|
}
|
|
646
646
|
>;
|
|
647
|
-
|
|
647
|
+
scene('Test Flow with Rule IDs', 'FLOW-456', () => {
|
|
648
648
|
command('process command', 'SLICE-789').server(() => {
|
|
649
649
|
specs('Command Processing', () => {
|
|
650
650
|
rule('Valid commands should be processed', 'RULE-ABC', () => {
|
|
@@ -661,11 +661,11 @@ narrative('Test Flow with Rule IDs', 'FLOW-456', () => {
|
|
|
661
661
|
it('should correctly generate Query type alias for query messages', async () => {
|
|
662
662
|
const modelWithQueryMessage: Model = {
|
|
663
663
|
variant: 'specs',
|
|
664
|
-
|
|
664
|
+
scenes: [
|
|
665
665
|
{
|
|
666
666
|
name: 'Workout Flow',
|
|
667
667
|
id: 'FLOW-001',
|
|
668
|
-
|
|
668
|
+
moments: [],
|
|
669
669
|
},
|
|
670
670
|
],
|
|
671
671
|
messages: [
|
|
@@ -692,7 +692,7 @@ narrative('Test Flow with Rule IDs', 'FLOW-456', () => {
|
|
|
692
692
|
|
|
693
693
|
const code = getCode(await modelToNarrative(modelWithQueryMessage));
|
|
694
694
|
|
|
695
|
-
expect(code).toEqual(`import {
|
|
695
|
+
expect(code).toEqual(`import { scene } from '@auto-engineer/narrative';
|
|
696
696
|
import type { Event, Query } from '@auto-engineer/narrative';
|
|
697
697
|
type GetWorkoutHistory = Query<
|
|
698
698
|
'GetWorkoutHistory',
|
|
@@ -707,18 +707,18 @@ type WorkoutRecorded = Event<
|
|
|
707
707
|
workoutId: string;
|
|
708
708
|
}
|
|
709
709
|
>;
|
|
710
|
-
|
|
710
|
+
scene('Workout Flow', 'FLOW-001', () => {});
|
|
711
711
|
`);
|
|
712
712
|
});
|
|
713
713
|
|
|
714
714
|
it('should correctly resolve Date types in messages', async () => {
|
|
715
715
|
const modelWithDateTypes: Model = {
|
|
716
716
|
variant: 'specs',
|
|
717
|
-
|
|
717
|
+
scenes: [
|
|
718
718
|
{
|
|
719
719
|
name: 'Questionnaire Flow',
|
|
720
720
|
id: 'QUEST-001',
|
|
721
|
-
|
|
721
|
+
moments: [],
|
|
722
722
|
},
|
|
723
723
|
],
|
|
724
724
|
messages: [
|
|
@@ -754,7 +754,7 @@ narrative('Workout Flow', 'FLOW-001', () => {});
|
|
|
754
754
|
|
|
755
755
|
const code = getCode(await modelToNarrative(modelWithDateTypes));
|
|
756
756
|
|
|
757
|
-
expect(code).toEqual(`import {
|
|
757
|
+
expect(code).toEqual(`import { scene } from '@auto-engineer/narrative';
|
|
758
758
|
import type { Event } from '@auto-engineer/narrative';
|
|
759
759
|
type QuestionnaireLinkSent = Event<
|
|
760
760
|
'QuestionnaireLinkSent',
|
|
@@ -775,18 +775,18 @@ type QuestionAnswered = Event<
|
|
|
775
775
|
savedAt: Date;
|
|
776
776
|
}
|
|
777
777
|
>;
|
|
778
|
-
|
|
778
|
+
scene('Questionnaire Flow', 'QUEST-001', () => {});
|
|
779
779
|
`);
|
|
780
780
|
});
|
|
781
781
|
|
|
782
782
|
it('should generate browser-compatible imports without mixing values and types', async () => {
|
|
783
783
|
const questionnairesModel: Model = {
|
|
784
784
|
variant: 'specs',
|
|
785
|
-
|
|
785
|
+
scenes: [
|
|
786
786
|
{
|
|
787
787
|
name: 'Questionnaires',
|
|
788
788
|
id: 'Q9m2Kp4Lx',
|
|
789
|
-
|
|
789
|
+
moments: [
|
|
790
790
|
{
|
|
791
791
|
name: 'Homepage',
|
|
792
792
|
id: 'H1a4Bn6Cy',
|
|
@@ -1017,9 +1017,9 @@ narrative('Questionnaire Flow', 'QUEST-001', () => {});
|
|
|
1017
1017
|
experience,
|
|
1018
1018
|
gql,
|
|
1019
1019
|
it,
|
|
1020
|
-
narrative,
|
|
1021
1020
|
query,
|
|
1022
1021
|
rule,
|
|
1022
|
+
scene,
|
|
1023
1023
|
source,
|
|
1024
1024
|
specs,
|
|
1025
1025
|
} from '@auto-engineer/narrative';
|
|
@@ -1057,7 +1057,7 @@ type QuestionnaireProgress = State<
|
|
|
1057
1057
|
}[];
|
|
1058
1058
|
}
|
|
1059
1059
|
>;
|
|
1060
|
-
|
|
1060
|
+
scene('Questionnaires', 'Q9m2Kp4Lx', () => {
|
|
1061
1061
|
experience('Homepage', 'H1a4Bn6Cy').client(() => {
|
|
1062
1062
|
it('show a hero section with a welcome message');
|
|
1063
1063
|
it('allow user to start the questionnaire');
|
|
@@ -1126,11 +1126,11 @@ narrative('Questionnaires', 'Q9m2Kp4Lx', () => {
|
|
|
1126
1126
|
it('should consolidate duplicate rules with multiple examples into single rule blocks', async () => {
|
|
1127
1127
|
const modelWithDuplicateRules: Model = {
|
|
1128
1128
|
variant: 'specs',
|
|
1129
|
-
|
|
1129
|
+
scenes: [
|
|
1130
1130
|
{
|
|
1131
1131
|
name: 'Test Flow',
|
|
1132
1132
|
id: 'TEST-FLOW',
|
|
1133
|
-
|
|
1133
|
+
moments: [
|
|
1134
1134
|
{
|
|
1135
1135
|
name: 'test slice',
|
|
1136
1136
|
id: 'TEST-SLICE',
|
|
@@ -1255,7 +1255,7 @@ narrative('Questionnaires', 'Q9m2Kp4Lx', () => {
|
|
|
1255
1255
|
|
|
1256
1256
|
const code = getCode(await modelToNarrative(modelWithDuplicateRules));
|
|
1257
1257
|
|
|
1258
|
-
expect(code).toEqual(`import { example,
|
|
1258
|
+
expect(code).toEqual(`import { example, query, rule, scene, specs } from '@auto-engineer/narrative';
|
|
1259
1259
|
import type { Event, State } from '@auto-engineer/narrative';
|
|
1260
1260
|
type QuestionnaireLinkSent = Event<
|
|
1261
1261
|
'QuestionnaireLinkSent',
|
|
@@ -1279,7 +1279,7 @@ type QuestionnaireProgress = State<
|
|
|
1279
1279
|
status: string;
|
|
1280
1280
|
}
|
|
1281
1281
|
>;
|
|
1282
|
-
|
|
1282
|
+
scene('Test Flow', 'TEST-FLOW', () => {
|
|
1283
1283
|
query('test slice', 'TEST-SLICE').server(() => {
|
|
1284
1284
|
specs('Test Rules', () => {
|
|
1285
1285
|
rule('questionnaires show current progress', 'r1A3Bp9W', () => {
|
|
@@ -1300,11 +1300,11 @@ narrative('Test Flow', 'TEST-FLOW', () => {
|
|
|
1300
1300
|
it('should chain multiple given examples with and() syntax', async () => {
|
|
1301
1301
|
const modelWithMultiGiven: Model = {
|
|
1302
1302
|
variant: 'specs',
|
|
1303
|
-
|
|
1303
|
+
scenes: [
|
|
1304
1304
|
{
|
|
1305
1305
|
name: 'Multi Given Flow',
|
|
1306
1306
|
id: 'MULTI-GIVEN',
|
|
1307
|
-
|
|
1307
|
+
moments: [
|
|
1308
1308
|
{
|
|
1309
1309
|
name: 'multi given slice',
|
|
1310
1310
|
id: 'MULTI-SLICE',
|
|
@@ -1460,7 +1460,7 @@ narrative('Test Flow', 'TEST-FLOW', () => {
|
|
|
1460
1460
|
|
|
1461
1461
|
const code = getCode(await modelToNarrative(modelWithMultiGiven));
|
|
1462
1462
|
|
|
1463
|
-
expect(code).toEqual(`import { example,
|
|
1463
|
+
expect(code).toEqual(`import { example, query, rule, scene, specs } from '@auto-engineer/narrative';
|
|
1464
1464
|
import type { Event, State } from '@auto-engineer/narrative';
|
|
1465
1465
|
type QuestionnaireConfig = State<
|
|
1466
1466
|
'QuestionnaireConfig',
|
|
@@ -1502,7 +1502,7 @@ type QuestionnaireProgress = State<
|
|
|
1502
1502
|
}[];
|
|
1503
1503
|
}
|
|
1504
1504
|
>;
|
|
1505
|
-
|
|
1505
|
+
scene('Multi Given Flow', 'MULTI-GIVEN', () => {
|
|
1506
1506
|
query('multi given slice', 'MULTI-SLICE').server(() => {
|
|
1507
1507
|
specs('Multi Given Rules', () => {
|
|
1508
1508
|
rule('all questions have been answered', 'MultiGiven', () => {
|
|
@@ -1556,11 +1556,11 @@ narrative('Multi Given Flow', 'MULTI-GIVEN', () => {
|
|
|
1556
1556
|
it('should generate types for states referenced in data origins', async () => {
|
|
1557
1557
|
const modelWithReferencedStates: Model = {
|
|
1558
1558
|
variant: 'specs',
|
|
1559
|
-
|
|
1559
|
+
scenes: [
|
|
1560
1560
|
{
|
|
1561
1561
|
name: 'Referenced States Flow',
|
|
1562
1562
|
id: 'REF-STATES',
|
|
1563
|
-
|
|
1563
|
+
moments: [
|
|
1564
1564
|
{
|
|
1565
1565
|
name: 'query with database states',
|
|
1566
1566
|
id: 'REF-SLICE',
|
|
@@ -1674,9 +1674,7 @@ narrative('Multi Given Flow', 'MULTI-GIVEN', () => {
|
|
|
1674
1674
|
|
|
1675
1675
|
const code = getCode(await modelToNarrative(modelWithReferencedStates));
|
|
1676
1676
|
|
|
1677
|
-
expect(
|
|
1678
|
-
code,
|
|
1679
|
-
).toEqual(`import { data, example, narrative, query, rule, source, specs } from '@auto-engineer/narrative';
|
|
1677
|
+
expect(code).toEqual(`import { data, example, query, rule, scene, source, specs } from '@auto-engineer/narrative';
|
|
1680
1678
|
import type { State } from '@auto-engineer/narrative';
|
|
1681
1679
|
type QuestionnaireProgress = State<
|
|
1682
1680
|
'QuestionnaireProgress',
|
|
@@ -1695,7 +1693,7 @@ type QuestionnaireConfig = State<
|
|
|
1695
1693
|
title: string;
|
|
1696
1694
|
}
|
|
1697
1695
|
>;
|
|
1698
|
-
|
|
1696
|
+
scene('Referenced States Flow', 'REF-STATES', () => {
|
|
1699
1697
|
query('query with database states', 'REF-SLICE').server(() => {
|
|
1700
1698
|
data({
|
|
1701
1699
|
items: [
|
|
@@ -1727,11 +1725,11 @@ narrative('Referenced States Flow', 'REF-STATES', () => {
|
|
|
1727
1725
|
it('should generate new Date() constructors for Date fields', async () => {
|
|
1728
1726
|
const modelWithDateFields: Model = {
|
|
1729
1727
|
variant: 'specs',
|
|
1730
|
-
|
|
1728
|
+
scenes: [
|
|
1731
1729
|
{
|
|
1732
1730
|
name: 'Date Handling Flow',
|
|
1733
1731
|
id: 'DATE-FLOW',
|
|
1734
|
-
|
|
1732
|
+
moments: [
|
|
1735
1733
|
{
|
|
1736
1734
|
name: 'date handling slice',
|
|
1737
1735
|
id: 'DATE-SLICE',
|
|
@@ -1831,7 +1829,7 @@ narrative('Referenced States Flow', 'REF-STATES', () => {
|
|
|
1831
1829
|
|
|
1832
1830
|
const code = getCode(await modelToNarrative(modelWithDateFields));
|
|
1833
1831
|
|
|
1834
|
-
expect(code).toEqual(`import { example,
|
|
1832
|
+
expect(code).toEqual(`import { example, query, rule, scene, specs } from '@auto-engineer/narrative';
|
|
1835
1833
|
import type { Event, State } from '@auto-engineer/narrative';
|
|
1836
1834
|
type TimestampedEvent = Event<
|
|
1837
1835
|
'TimestampedEvent',
|
|
@@ -1857,7 +1855,7 @@ type ProcessState = State<
|
|
|
1857
1855
|
status: string;
|
|
1858
1856
|
}
|
|
1859
1857
|
>;
|
|
1860
|
-
|
|
1858
|
+
scene('Date Handling Flow', 'DATE-FLOW', () => {
|
|
1861
1859
|
query('date handling slice', 'DATE-SLICE').server(() => {
|
|
1862
1860
|
specs('Date Field Rules', () => {
|
|
1863
1861
|
rule('handles Date fields correctly', 'DateRule', () => {
|
|
@@ -1885,11 +1883,11 @@ narrative('Date Handling Flow', 'DATE-FLOW', () => {
|
|
|
1885
1883
|
it('should generate multiple flows when multiple flows have the same sourceFile', async () => {
|
|
1886
1884
|
const modelWithMultipleFlowsSameSource: Model = {
|
|
1887
1885
|
variant: 'specs',
|
|
1888
|
-
|
|
1886
|
+
scenes: [
|
|
1889
1887
|
{
|
|
1890
1888
|
name: 'Home Screen',
|
|
1891
1889
|
sourceFile: '/path/to/homepage.narrative.ts',
|
|
1892
|
-
|
|
1890
|
+
moments: [
|
|
1893
1891
|
{
|
|
1894
1892
|
name: 'Active Surveys Summary',
|
|
1895
1893
|
id: 'aifPcU3hw',
|
|
@@ -1903,7 +1901,7 @@ narrative('Date Handling Flow', 'DATE-FLOW', () => {
|
|
|
1903
1901
|
{
|
|
1904
1902
|
name: 'Create Survey',
|
|
1905
1903
|
sourceFile: '/path/to/homepage.narrative.ts',
|
|
1906
|
-
|
|
1904
|
+
moments: [
|
|
1907
1905
|
{
|
|
1908
1906
|
name: 'Create Survey Form',
|
|
1909
1907
|
id: 'MPviTMrQC',
|
|
@@ -1917,7 +1915,7 @@ narrative('Date Handling Flow', 'DATE-FLOW', () => {
|
|
|
1917
1915
|
{
|
|
1918
1916
|
name: 'Response Analytics',
|
|
1919
1917
|
sourceFile: '/path/to/homepage.narrative.ts',
|
|
1920
|
-
|
|
1918
|
+
moments: [
|
|
1921
1919
|
{
|
|
1922
1920
|
name: 'Response Rate Charts',
|
|
1923
1921
|
id: 'eME978Euk',
|
|
@@ -1936,18 +1934,18 @@ narrative('Date Handling Flow', 'DATE-FLOW', () => {
|
|
|
1936
1934
|
|
|
1937
1935
|
const code = getCode(await modelToNarrative(modelWithMultipleFlowsSameSource));
|
|
1938
1936
|
|
|
1939
|
-
expect(code).toEqual(`import { experience, it,
|
|
1940
|
-
|
|
1937
|
+
expect(code).toEqual(`import { experience, it, scene } from '@auto-engineer/narrative';
|
|
1938
|
+
scene('Home Screen', () => {
|
|
1941
1939
|
experience('Active Surveys Summary', 'aifPcU3hw').client(() => {
|
|
1942
1940
|
it('show active surveys summary');
|
|
1943
1941
|
});
|
|
1944
1942
|
});
|
|
1945
|
-
|
|
1943
|
+
scene('Create Survey', () => {
|
|
1946
1944
|
experience('Create Survey Form', 'MPviTMrQC').client(() => {
|
|
1947
1945
|
it('allow entering survey title');
|
|
1948
1946
|
});
|
|
1949
1947
|
});
|
|
1950
|
-
|
|
1948
|
+
scene('Response Analytics', () => {
|
|
1951
1949
|
experience('Response Rate Charts', 'eME978Euk').client(() => {
|
|
1952
1950
|
it('show daily response rate charts');
|
|
1953
1951
|
});
|
|
@@ -1958,11 +1956,11 @@ narrative('Response Analytics', () => {
|
|
|
1958
1956
|
it('should omit .when({}) when given has multiple items and when is empty', async () => {
|
|
1959
1957
|
const modelWithEmptyWhen: Model = {
|
|
1960
1958
|
variant: 'specs',
|
|
1961
|
-
|
|
1959
|
+
scenes: [
|
|
1962
1960
|
{
|
|
1963
1961
|
name: 'Todo List Summary',
|
|
1964
1962
|
id: 'TODO-001',
|
|
1965
|
-
|
|
1963
|
+
moments: [
|
|
1966
1964
|
{
|
|
1967
1965
|
name: 'views completion summary',
|
|
1968
1966
|
id: 'SUMMARY-001',
|
|
@@ -2098,7 +2096,7 @@ narrative('Response Analytics', () => {
|
|
|
2098
2096
|
|
|
2099
2097
|
const code = getCode(await modelToNarrative(modelWithEmptyWhen));
|
|
2100
2098
|
|
|
2101
|
-
expect(code).toEqual(`import { example,
|
|
2099
|
+
expect(code).toEqual(`import { example, query, rule, scene, specs } from '@auto-engineer/narrative';
|
|
2102
2100
|
import type { Event, State } from '@auto-engineer/narrative';
|
|
2103
2101
|
type TodoAdded = Event<
|
|
2104
2102
|
'TodoAdded',
|
|
@@ -2134,7 +2132,7 @@ type TodoListSummary = State<
|
|
|
2134
2132
|
completionPercentage: number;
|
|
2135
2133
|
}
|
|
2136
2134
|
>;
|
|
2137
|
-
|
|
2135
|
+
scene('Todo List Summary', 'TODO-001', () => {
|
|
2138
2136
|
query('views completion summary', 'SUMMARY-001').server(() => {
|
|
2139
2137
|
specs('Summary Statistics', () => {
|
|
2140
2138
|
rule('summary shows overall todo list statistics', 'RULE-SUMMARY', () => {
|
|
@@ -2175,11 +2173,11 @@ narrative('Todo List Summary', 'TODO-001', () => {
|
|
|
2175
2173
|
it('should generate fromSingletonProjection for singleton projections', async () => {
|
|
2176
2174
|
const modelWithSingletonProjection: Model = {
|
|
2177
2175
|
variant: 'specs',
|
|
2178
|
-
|
|
2176
|
+
scenes: [
|
|
2179
2177
|
{
|
|
2180
2178
|
name: 'Todo Summary Flow',
|
|
2181
2179
|
id: 'TODO-SUMMARY',
|
|
2182
|
-
|
|
2180
|
+
moments: [
|
|
2183
2181
|
{
|
|
2184
2182
|
name: 'views todo summary',
|
|
2185
2183
|
id: 'SUMMARY-SLICE',
|
|
@@ -2233,7 +2231,7 @@ narrative('Todo List Summary', 'TODO-001', () => {
|
|
|
2233
2231
|
|
|
2234
2232
|
const code = getCode(await modelToNarrative(modelWithSingletonProjection));
|
|
2235
2233
|
|
|
2236
|
-
expect(code).toEqual(`import { data,
|
|
2234
|
+
expect(code).toEqual(`import { data, query, scene, source, specs } from '@auto-engineer/narrative';
|
|
2237
2235
|
import type { State } from '@auto-engineer/narrative';
|
|
2238
2236
|
type TodoListSummary = State<
|
|
2239
2237
|
'TodoListSummary',
|
|
@@ -2242,7 +2240,7 @@ type TodoListSummary = State<
|
|
|
2242
2240
|
totalTodos: number;
|
|
2243
2241
|
}
|
|
2244
2242
|
>;
|
|
2245
|
-
|
|
2243
|
+
scene('Todo Summary Flow', 'TODO-SUMMARY', () => {
|
|
2246
2244
|
query('views todo summary', 'SUMMARY-SLICE').server(() => {
|
|
2247
2245
|
data({ items: [source().state('TodoListSummary').fromSingletonProjection('TodoSummary')] });
|
|
2248
2246
|
specs('Summary Rules', () => {});
|
|
@@ -2254,11 +2252,11 @@ narrative('Todo Summary Flow', 'TODO-SUMMARY', () => {
|
|
|
2254
2252
|
it('should generate fromProjection with single idField for regular projections', async () => {
|
|
2255
2253
|
const modelWithRegularProjection: Model = {
|
|
2256
2254
|
variant: 'specs',
|
|
2257
|
-
|
|
2255
|
+
scenes: [
|
|
2258
2256
|
{
|
|
2259
2257
|
name: 'Todo Flow',
|
|
2260
2258
|
id: 'TODO-FLOW',
|
|
2261
|
-
|
|
2259
|
+
moments: [
|
|
2262
2260
|
{
|
|
2263
2261
|
name: 'views todo',
|
|
2264
2262
|
id: 'TODO-SLICE',
|
|
@@ -2312,7 +2310,7 @@ narrative('Todo Summary Flow', 'TODO-SUMMARY', () => {
|
|
|
2312
2310
|
|
|
2313
2311
|
const code = getCode(await modelToNarrative(modelWithRegularProjection));
|
|
2314
2312
|
|
|
2315
|
-
expect(code).toEqual(`import { data,
|
|
2313
|
+
expect(code).toEqual(`import { data, query, scene, source, specs } from '@auto-engineer/narrative';
|
|
2316
2314
|
import type { State } from '@auto-engineer/narrative';
|
|
2317
2315
|
type TodoState = State<
|
|
2318
2316
|
'TodoState',
|
|
@@ -2321,7 +2319,7 @@ type TodoState = State<
|
|
|
2321
2319
|
description: string;
|
|
2322
2320
|
}
|
|
2323
2321
|
>;
|
|
2324
|
-
|
|
2322
|
+
scene('Todo Flow', 'TODO-FLOW', () => {
|
|
2325
2323
|
query('views todo', 'TODO-SLICE').server(() => {
|
|
2326
2324
|
data({ items: [source().state('TodoState').fromProjection('Todos', 'todoId')] });
|
|
2327
2325
|
specs('Todo Rules', () => {});
|
|
@@ -2333,11 +2331,11 @@ narrative('Todo Flow', 'TODO-FLOW', () => {
|
|
|
2333
2331
|
it('should generate fromCompositeProjection with array idField for composite key projections', async () => {
|
|
2334
2332
|
const modelWithCompositeProjection: Model = {
|
|
2335
2333
|
variant: 'specs',
|
|
2336
|
-
|
|
2334
|
+
scenes: [
|
|
2337
2335
|
{
|
|
2338
2336
|
name: 'User Project Flow',
|
|
2339
2337
|
id: 'USER-PROJECT-FLOW',
|
|
2340
|
-
|
|
2338
|
+
moments: [
|
|
2341
2339
|
{
|
|
2342
2340
|
name: 'views user project',
|
|
2343
2341
|
id: 'USER-PROJECT-SLICE',
|
|
@@ -2392,7 +2390,7 @@ narrative('Todo Flow', 'TODO-FLOW', () => {
|
|
|
2392
2390
|
|
|
2393
2391
|
const code = getCode(await modelToNarrative(modelWithCompositeProjection));
|
|
2394
2392
|
|
|
2395
|
-
expect(code).toEqual(`import { data,
|
|
2393
|
+
expect(code).toEqual(`import { data, query, scene, source, specs } from '@auto-engineer/narrative';
|
|
2396
2394
|
import type { State } from '@auto-engineer/narrative';
|
|
2397
2395
|
type UserProjectState = State<
|
|
2398
2396
|
'UserProjectState',
|
|
@@ -2402,7 +2400,7 @@ type UserProjectState = State<
|
|
|
2402
2400
|
role: string;
|
|
2403
2401
|
}
|
|
2404
2402
|
>;
|
|
2405
|
-
|
|
2403
|
+
scene('User Project Flow', 'USER-PROJECT-FLOW', () => {
|
|
2406
2404
|
query('views user project', 'USER-PROJECT-SLICE').server(() => {
|
|
2407
2405
|
data({
|
|
2408
2406
|
items: [source().state('UserProjectState').fromCompositeProjection('UserProjects', ['userId', 'projectId'])],
|
|
@@ -2416,11 +2414,11 @@ narrative('User Project Flow', 'USER-PROJECT-FLOW', () => {
|
|
|
2416
2414
|
it('should generate all three projection types in a single narrative', async () => {
|
|
2417
2415
|
const modelWithAllProjectionTypes: Model = {
|
|
2418
2416
|
variant: 'specs',
|
|
2419
|
-
|
|
2417
|
+
scenes: [
|
|
2420
2418
|
{
|
|
2421
2419
|
name: 'All Projection Types',
|
|
2422
2420
|
id: 'ALL-PROJ',
|
|
2423
|
-
|
|
2421
|
+
moments: [
|
|
2424
2422
|
{
|
|
2425
2423
|
name: 'views summary',
|
|
2426
2424
|
id: 'SUMMARY-SLICE',
|
|
@@ -2559,7 +2557,7 @@ narrative('User Project Flow', 'USER-PROJECT-FLOW', () => {
|
|
|
2559
2557
|
|
|
2560
2558
|
const code = getCode(await modelToNarrative(modelWithAllProjectionTypes));
|
|
2561
2559
|
|
|
2562
|
-
expect(code).toEqual(`import { data,
|
|
2560
|
+
expect(code).toEqual(`import { data, query, scene, source, specs } from '@auto-engineer/narrative';
|
|
2563
2561
|
import type { State } from '@auto-engineer/narrative';
|
|
2564
2562
|
type TodoListSummary = State<
|
|
2565
2563
|
'TodoListSummary',
|
|
@@ -2583,7 +2581,7 @@ type UserProjectTodos = State<
|
|
|
2583
2581
|
todos: string[];
|
|
2584
2582
|
}
|
|
2585
2583
|
>;
|
|
2586
|
-
|
|
2584
|
+
scene('All Projection Types', 'ALL-PROJ', () => {
|
|
2587
2585
|
query('views summary', 'SUMMARY-SLICE').server(() => {
|
|
2588
2586
|
data({ items: [source().state('TodoListSummary').fromSingletonProjection('TodoSummary')] });
|
|
2589
2587
|
specs('Summary Rules', () => {});
|
|
@@ -2607,9 +2605,9 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2607
2605
|
it('generates multiple files for derived modules with different sourceFiles', async () => {
|
|
2608
2606
|
const model: Model = {
|
|
2609
2607
|
variant: 'specs',
|
|
2610
|
-
|
|
2611
|
-
{ name: 'Orders', id: 'orders-flow', sourceFile: 'orders.narrative.ts',
|
|
2612
|
-
{ name: 'Users', id: 'users-flow', sourceFile: 'users.narrative.ts',
|
|
2608
|
+
scenes: [
|
|
2609
|
+
{ name: 'Orders', id: 'orders-flow', sourceFile: 'orders.narrative.ts', moments: [] },
|
|
2610
|
+
{ name: 'Users', id: 'users-flow', sourceFile: 'users.narrative.ts', moments: [] },
|
|
2613
2611
|
],
|
|
2614
2612
|
messages: [],
|
|
2615
2613
|
integrations: [],
|
|
@@ -2617,13 +2615,13 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2617
2615
|
{
|
|
2618
2616
|
sourceFile: 'orders.narrative.ts',
|
|
2619
2617
|
isDerived: true,
|
|
2620
|
-
contains: {
|
|
2618
|
+
contains: { sceneIds: ['orders-flow'] },
|
|
2621
2619
|
declares: { messages: [] },
|
|
2622
2620
|
},
|
|
2623
2621
|
{
|
|
2624
2622
|
sourceFile: 'users.narrative.ts',
|
|
2625
2623
|
isDerived: true,
|
|
2626
|
-
contains: {
|
|
2624
|
+
contains: { sceneIds: ['users-flow'] },
|
|
2627
2625
|
declares: { messages: [] },
|
|
2628
2626
|
},
|
|
2629
2627
|
],
|
|
@@ -2637,16 +2635,16 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2637
2635
|
const ordersFile = result.files.find((f) => f.path === 'orders.narrative.ts');
|
|
2638
2636
|
const usersFile = result.files.find((f) => f.path === 'users.narrative.ts');
|
|
2639
2637
|
|
|
2640
|
-
expect(ordersFile?.code).toContain("
|
|
2641
|
-
expect(usersFile?.code).toContain("
|
|
2638
|
+
expect(ordersFile?.code).toContain("scene('Orders', 'orders-flow'");
|
|
2639
|
+
expect(usersFile?.code).toContain("scene('Users', 'users-flow'");
|
|
2642
2640
|
});
|
|
2643
2641
|
|
|
2644
2642
|
it('duplicates types in each derived module file (no cross-module imports)', async () => {
|
|
2645
2643
|
const model: Model = {
|
|
2646
2644
|
variant: 'specs',
|
|
2647
|
-
|
|
2648
|
-
{ name: 'Flow A', id: 'flow-a', sourceFile: 'a.narrative.ts',
|
|
2649
|
-
{ name: 'Flow B', id: 'flow-b', sourceFile: 'b.narrative.ts',
|
|
2645
|
+
scenes: [
|
|
2646
|
+
{ name: 'Flow A', id: 'flow-a', sourceFile: 'a.narrative.ts', moments: [] },
|
|
2647
|
+
{ name: 'Flow B', id: 'flow-b', sourceFile: 'b.narrative.ts', moments: [] },
|
|
2650
2648
|
],
|
|
2651
2649
|
messages: [
|
|
2652
2650
|
{
|
|
@@ -2661,13 +2659,13 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2661
2659
|
{
|
|
2662
2660
|
sourceFile: 'a.narrative.ts',
|
|
2663
2661
|
isDerived: true,
|
|
2664
|
-
contains: {
|
|
2662
|
+
contains: { sceneIds: ['flow-a'] },
|
|
2665
2663
|
declares: { messages: [{ kind: 'event', name: 'SharedEvent' }] },
|
|
2666
2664
|
},
|
|
2667
2665
|
{
|
|
2668
2666
|
sourceFile: 'b.narrative.ts',
|
|
2669
2667
|
isDerived: true,
|
|
2670
|
-
contains: {
|
|
2668
|
+
contains: { sceneIds: ['flow-b'] },
|
|
2671
2669
|
declares: { messages: [{ kind: 'event', name: 'SharedEvent' }] },
|
|
2672
2670
|
},
|
|
2673
2671
|
],
|
|
@@ -2686,12 +2684,12 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2686
2684
|
it('generates cross-module type imports for authored modules', async () => {
|
|
2687
2685
|
const model: Model = {
|
|
2688
2686
|
variant: 'specs',
|
|
2689
|
-
|
|
2690
|
-
{ name: 'Shared Types', id: 'shared-types',
|
|
2687
|
+
scenes: [
|
|
2688
|
+
{ name: 'Shared Types', id: 'shared-types', moments: [] },
|
|
2691
2689
|
{
|
|
2692
2690
|
name: 'Orders',
|
|
2693
2691
|
id: 'orders-flow',
|
|
2694
|
-
|
|
2692
|
+
moments: [
|
|
2695
2693
|
{
|
|
2696
2694
|
name: 'create order',
|
|
2697
2695
|
type: 'command',
|
|
@@ -2741,13 +2739,13 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2741
2739
|
{
|
|
2742
2740
|
sourceFile: 'shared/types.narrative.ts',
|
|
2743
2741
|
isDerived: false,
|
|
2744
|
-
contains: {
|
|
2742
|
+
contains: { sceneIds: ['shared-types'] },
|
|
2745
2743
|
declares: { messages: [{ kind: 'event', name: 'OrderCreated' }] },
|
|
2746
2744
|
},
|
|
2747
2745
|
{
|
|
2748
2746
|
sourceFile: 'features/orders.narrative.ts',
|
|
2749
2747
|
isDerived: false,
|
|
2750
|
-
contains: {
|
|
2748
|
+
contains: { sceneIds: ['orders-flow'] },
|
|
2751
2749
|
declares: { messages: [{ kind: 'command', name: 'CreateOrder' }] },
|
|
2752
2750
|
},
|
|
2753
2751
|
],
|
|
@@ -2768,12 +2766,12 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2768
2766
|
it('generates correct relative import paths for nested directories', async () => {
|
|
2769
2767
|
const model: Model = {
|
|
2770
2768
|
variant: 'specs',
|
|
2771
|
-
|
|
2772
|
-
{ name: 'Core Types', id: 'core',
|
|
2769
|
+
scenes: [
|
|
2770
|
+
{ name: 'Core Types', id: 'core', moments: [] },
|
|
2773
2771
|
{
|
|
2774
2772
|
name: 'Feature',
|
|
2775
2773
|
id: 'feature',
|
|
2776
|
-
|
|
2774
|
+
moments: [
|
|
2777
2775
|
{
|
|
2778
2776
|
name: 'do something',
|
|
2779
2777
|
type: 'command',
|
|
@@ -2815,13 +2813,13 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2815
2813
|
{
|
|
2816
2814
|
sourceFile: 'src/core/types.narrative.ts',
|
|
2817
2815
|
isDerived: false,
|
|
2818
|
-
contains: {
|
|
2816
|
+
contains: { sceneIds: ['core'] },
|
|
2819
2817
|
declares: { messages: [{ kind: 'event', name: 'CoreEvent' }] },
|
|
2820
2818
|
},
|
|
2821
2819
|
{
|
|
2822
2820
|
sourceFile: 'src/features/sub/feature.narrative.ts',
|
|
2823
2821
|
isDerived: false,
|
|
2824
|
-
contains: {
|
|
2822
|
+
contains: { sceneIds: ['feature'] },
|
|
2825
2823
|
declares: { messages: [] },
|
|
2826
2824
|
},
|
|
2827
2825
|
],
|
|
@@ -2837,12 +2835,12 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2837
2835
|
it('groups multiple imported types from same module into single import', async () => {
|
|
2838
2836
|
const model: Model = {
|
|
2839
2837
|
variant: 'specs',
|
|
2840
|
-
|
|
2841
|
-
{ name: 'Shared', id: 'shared',
|
|
2838
|
+
scenes: [
|
|
2839
|
+
{ name: 'Shared', id: 'shared', moments: [] },
|
|
2842
2840
|
{
|
|
2843
2841
|
name: 'Consumer',
|
|
2844
2842
|
id: 'consumer',
|
|
2845
|
-
|
|
2843
|
+
moments: [
|
|
2846
2844
|
{
|
|
2847
2845
|
name: 'process',
|
|
2848
2846
|
type: 'command',
|
|
@@ -2883,7 +2881,7 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2883
2881
|
{
|
|
2884
2882
|
sourceFile: 'shared.narrative.ts',
|
|
2885
2883
|
isDerived: false,
|
|
2886
|
-
contains: {
|
|
2884
|
+
contains: { sceneIds: ['shared'] },
|
|
2887
2885
|
declares: {
|
|
2888
2886
|
messages: [
|
|
2889
2887
|
{ kind: 'event', name: 'EventA' },
|
|
@@ -2894,7 +2892,7 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2894
2892
|
{
|
|
2895
2893
|
sourceFile: 'consumer.narrative.ts',
|
|
2896
2894
|
isDerived: false,
|
|
2897
|
-
contains: {
|
|
2895
|
+
contains: { sceneIds: ['consumer'] },
|
|
2898
2896
|
declares: { messages: [] },
|
|
2899
2897
|
},
|
|
2900
2898
|
],
|
|
@@ -2912,13 +2910,13 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2912
2910
|
it('sorts cross-module imports alphabetically by path', async () => {
|
|
2913
2911
|
const model: Model = {
|
|
2914
2912
|
variant: 'specs',
|
|
2915
|
-
|
|
2916
|
-
{ name: 'Types Z', id: 'z-types',
|
|
2917
|
-
{ name: 'Types A', id: 'a-types',
|
|
2913
|
+
scenes: [
|
|
2914
|
+
{ name: 'Types Z', id: 'z-types', moments: [] },
|
|
2915
|
+
{ name: 'Types A', id: 'a-types', moments: [] },
|
|
2918
2916
|
{
|
|
2919
2917
|
name: 'Consumer',
|
|
2920
2918
|
id: 'consumer',
|
|
2921
|
-
|
|
2919
|
+
moments: [
|
|
2922
2920
|
{
|
|
2923
2921
|
name: 'process',
|
|
2924
2922
|
type: 'command',
|
|
@@ -2959,19 +2957,19 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2959
2957
|
{
|
|
2960
2958
|
sourceFile: 'z-types.narrative.ts',
|
|
2961
2959
|
isDerived: false,
|
|
2962
|
-
contains: {
|
|
2960
|
+
contains: { sceneIds: ['z-types'] },
|
|
2963
2961
|
declares: { messages: [{ kind: 'event', name: 'ZEvent' }] },
|
|
2964
2962
|
},
|
|
2965
2963
|
{
|
|
2966
2964
|
sourceFile: 'a-types.narrative.ts',
|
|
2967
2965
|
isDerived: false,
|
|
2968
|
-
contains: {
|
|
2966
|
+
contains: { sceneIds: ['a-types'] },
|
|
2969
2967
|
declares: { messages: [{ kind: 'event', name: 'AEvent' }] },
|
|
2970
2968
|
},
|
|
2971
2969
|
{
|
|
2972
2970
|
sourceFile: 'consumer.narrative.ts',
|
|
2973
2971
|
isDerived: false,
|
|
2974
|
-
contains: {
|
|
2972
|
+
contains: { sceneIds: ['consumer'] },
|
|
2975
2973
|
declares: { messages: [] },
|
|
2976
2974
|
},
|
|
2977
2975
|
],
|
|
@@ -2992,9 +2990,9 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
2992
2990
|
it('derives modules when model has empty modules array', async () => {
|
|
2993
2991
|
const model: Model = {
|
|
2994
2992
|
variant: 'specs',
|
|
2995
|
-
|
|
2996
|
-
{ name: 'Flow A', id: 'flow-a', sourceFile: 'a.narrative.ts',
|
|
2997
|
-
{ name: 'Flow B', id: 'flow-b', sourceFile: 'b.narrative.ts',
|
|
2993
|
+
scenes: [
|
|
2994
|
+
{ name: 'Flow A', id: 'flow-a', sourceFile: 'a.narrative.ts', moments: [] },
|
|
2995
|
+
{ name: 'Flow B', id: 'flow-b', sourceFile: 'b.narrative.ts', moments: [] },
|
|
2998
2996
|
],
|
|
2999
2997
|
messages: [
|
|
3000
2998
|
{
|
|
@@ -3023,11 +3021,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3023
3021
|
it('should generate sink id when provided', async () => {
|
|
3024
3022
|
const modelWithSinkId: Model = {
|
|
3025
3023
|
variant: 'specs',
|
|
3026
|
-
|
|
3024
|
+
scenes: [
|
|
3027
3025
|
{
|
|
3028
3026
|
name: 'Order Flow',
|
|
3029
3027
|
id: 'ORDER-FLOW',
|
|
3030
|
-
|
|
3028
|
+
moments: [
|
|
3031
3029
|
{
|
|
3032
3030
|
name: 'places order',
|
|
3033
3031
|
id: 'ORDER-SLICE',
|
|
@@ -3069,11 +3067,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3069
3067
|
it('should generate source id when provided', async () => {
|
|
3070
3068
|
const modelWithSourceId: Model = {
|
|
3071
3069
|
variant: 'specs',
|
|
3072
|
-
|
|
3070
|
+
scenes: [
|
|
3073
3071
|
{
|
|
3074
3072
|
name: 'Order Flow',
|
|
3075
3073
|
id: 'ORDER-FLOW',
|
|
3076
|
-
|
|
3074
|
+
moments: [
|
|
3077
3075
|
{
|
|
3078
3076
|
name: 'views order',
|
|
3079
3077
|
id: 'ORDER-SLICE',
|
|
@@ -3114,11 +3112,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3114
3112
|
it('should not generate id when not provided', async () => {
|
|
3115
3113
|
const modelWithoutId: Model = {
|
|
3116
3114
|
variant: 'specs',
|
|
3117
|
-
|
|
3115
|
+
scenes: [
|
|
3118
3116
|
{
|
|
3119
3117
|
name: 'Order Flow',
|
|
3120
3118
|
id: 'ORDER-FLOW',
|
|
3121
|
-
|
|
3119
|
+
moments: [
|
|
3122
3120
|
{
|
|
3123
3121
|
name: 'places order',
|
|
3124
3122
|
id: 'ORDER-SLICE',
|
|
@@ -3160,11 +3158,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3160
3158
|
it('should generate target-only event items without destination', async () => {
|
|
3161
3159
|
const modelWithTarget: Model = {
|
|
3162
3160
|
variant: 'specs',
|
|
3163
|
-
|
|
3161
|
+
scenes: [
|
|
3164
3162
|
{
|
|
3165
3163
|
name: 'React Flow',
|
|
3166
3164
|
id: 'REACT-FLOW',
|
|
3167
|
-
|
|
3165
|
+
moments: [
|
|
3168
3166
|
{
|
|
3169
3167
|
name: 'reacts to event',
|
|
3170
3168
|
id: 'REACT-SLICE',
|
|
@@ -3199,11 +3197,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3199
3197
|
it('should generate target-only event items with id', async () => {
|
|
3200
3198
|
const modelWithTargetId: Model = {
|
|
3201
3199
|
variant: 'specs',
|
|
3202
|
-
|
|
3200
|
+
scenes: [
|
|
3203
3201
|
{
|
|
3204
3202
|
name: 'React Flow',
|
|
3205
3203
|
id: 'REACT-FLOW',
|
|
3206
|
-
|
|
3204
|
+
moments: [
|
|
3207
3205
|
{
|
|
3208
3206
|
name: 'reacts to event',
|
|
3209
3207
|
id: 'REACT-SLICE',
|
|
@@ -3238,11 +3236,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3238
3236
|
it('should generate _additionalInstructions on source items', async () => {
|
|
3239
3237
|
const modelWithSourceInstructions: Model = {
|
|
3240
3238
|
variant: 'specs',
|
|
3241
|
-
|
|
3239
|
+
scenes: [
|
|
3242
3240
|
{
|
|
3243
3241
|
name: 'Order Flow',
|
|
3244
3242
|
id: 'ORDER-FLOW',
|
|
3245
|
-
|
|
3243
|
+
moments: [
|
|
3246
3244
|
{
|
|
3247
3245
|
name: 'views order',
|
|
3248
3246
|
id: 'ORDER-SLICE',
|
|
@@ -3283,11 +3281,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3283
3281
|
it('should generate 3 narrative files for gym membership model', async () => {
|
|
3284
3282
|
const gymModel: Model = {
|
|
3285
3283
|
variant: 'specs',
|
|
3286
|
-
|
|
3284
|
+
scenes: [
|
|
3287
3285
|
{
|
|
3288
3286
|
id: 'mrwDfHhDi',
|
|
3289
3287
|
name: 'Gym Membership Registration',
|
|
3290
|
-
|
|
3288
|
+
moments: [
|
|
3291
3289
|
{
|
|
3292
3290
|
type: 'command',
|
|
3293
3291
|
name: 'Register New Member',
|
|
@@ -3348,7 +3346,7 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3348
3346
|
{
|
|
3349
3347
|
id: 'exByqGILR',
|
|
3350
3348
|
name: 'Gym Class Booking',
|
|
3351
|
-
|
|
3349
|
+
moments: [
|
|
3352
3350
|
{
|
|
3353
3351
|
type: 'command',
|
|
3354
3352
|
name: 'Book Gym Class',
|
|
@@ -3409,7 +3407,7 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3409
3407
|
{
|
|
3410
3408
|
id: 'o0odruqZA',
|
|
3411
3409
|
name: 'Gym Check-In',
|
|
3412
|
-
|
|
3410
|
+
moments: [
|
|
3413
3411
|
{
|
|
3414
3412
|
type: 'command',
|
|
3415
3413
|
name: 'Perform Check-In',
|
|
@@ -3491,9 +3489,9 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3491
3489
|
|
|
3492
3490
|
// Verify each narrative has proper content
|
|
3493
3491
|
const code = getCode(result);
|
|
3494
|
-
expect(code).toContain("
|
|
3495
|
-
expect(code).toContain("
|
|
3496
|
-
expect(code).toContain("
|
|
3492
|
+
expect(code).toContain("scene('Gym Membership Registration'");
|
|
3493
|
+
expect(code).toContain("scene('Gym Class Booking'");
|
|
3494
|
+
expect(code).toContain("scene('Gym Check-In'");
|
|
3497
3495
|
|
|
3498
3496
|
// Check slices are generated for each narrative
|
|
3499
3497
|
expect(code).toContain("command('Register New Member'");
|
|
@@ -3505,11 +3503,11 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3505
3503
|
it('generates all declared types for authored modules regardless of usage analysis', async () => {
|
|
3506
3504
|
const model: Model = {
|
|
3507
3505
|
variant: 'specs',
|
|
3508
|
-
|
|
3506
|
+
scenes: [
|
|
3509
3507
|
{
|
|
3510
3508
|
id: 'narrative-1',
|
|
3511
3509
|
name: 'Gym Goal Setting',
|
|
3512
|
-
|
|
3510
|
+
moments: [
|
|
3513
3511
|
{
|
|
3514
3512
|
type: 'command',
|
|
3515
3513
|
name: 'Set Fitness Goal',
|
|
@@ -3551,7 +3549,7 @@ narrative('All Projection Types', 'ALL-PROJ', () => {
|
|
|
3551
3549
|
{
|
|
3552
3550
|
sourceFile: '/narratives/goal-setting.narrative.ts',
|
|
3553
3551
|
isDerived: false,
|
|
3554
|
-
contains: {
|
|
3552
|
+
contains: { sceneIds: ['narrative-1'] },
|
|
3555
3553
|
declares: {
|
|
3556
3554
|
messages: [
|
|
3557
3555
|
{ kind: 'command', name: 'SetFitnessGoal' },
|