@auto-engineer/server-generator-apollo-emmett 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 +4 -4
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +39 -0
- package/DEBUG.md +4 -4
- package/dist/src/codegen/extract/data-sink.d.ts +2 -2
- package/dist/src/codegen/extract/data-sink.d.ts.map +1 -1
- package/dist/src/codegen/extract/data-sink.js +2 -2
- package/dist/src/codegen/extract/data-sink.js.map +1 -1
- package/dist/src/codegen/extract/events.d.ts +3 -3
- package/dist/src/codegen/extract/events.d.ts.map +1 -1
- package/dist/src/codegen/extract/events.js +11 -11
- package/dist/src/codegen/extract/events.js.map +1 -1
- package/dist/src/codegen/extract/gwt.d.ts +2 -2
- package/dist/src/codegen/extract/gwt.d.ts.map +1 -1
- package/dist/src/codegen/extract/gwt.js +2 -2
- package/dist/src/codegen/extract/gwt.js.map +1 -1
- package/dist/src/codegen/extract/imports.d.ts +4 -4
- package/dist/src/codegen/extract/imports.d.ts.map +1 -1
- package/dist/src/codegen/extract/imports.js +8 -8
- package/dist/src/codegen/extract/imports.js.map +1 -1
- package/dist/src/codegen/extract/messages.d.ts +2 -2
- package/dist/src/codegen/extract/messages.d.ts.map +1 -1
- package/dist/src/codegen/extract/messages.js +9 -9
- package/dist/src/codegen/extract/messages.js.map +1 -1
- package/dist/src/codegen/extract/projection.d.ts +7 -7
- package/dist/src/codegen/extract/projection.d.ts.map +1 -1
- package/dist/src/codegen/extract/projection.js +3 -3
- package/dist/src/codegen/extract/projection.js.map +1 -1
- package/dist/src/codegen/extract/query.d.ts +2 -2
- package/dist/src/codegen/extract/query.d.ts.map +1 -1
- package/dist/src/codegen/extract/query.js.map +1 -1
- package/dist/src/codegen/extract/slice-normalizer.d.ts +4 -4
- package/dist/src/codegen/extract/slice-normalizer.d.ts.map +1 -1
- package/dist/src/codegen/extract/slice-normalizer.js +7 -7
- package/dist/src/codegen/extract/slice-normalizer.js.map +1 -1
- package/dist/src/codegen/extract/states.d.ts +3 -3
- package/dist/src/codegen/extract/states.d.ts.map +1 -1
- package/dist/src/codegen/extract/states.js.map +1 -1
- package/dist/src/codegen/extract/step-converter.d.ts +7 -7
- package/dist/src/codegen/extract/step-converter.d.ts.map +1 -1
- package/dist/src/codegen/extract/step-converter.js +12 -12
- package/dist/src/codegen/extract/step-converter.js.map +1 -1
- package/dist/src/codegen/extract/step-types.d.ts +4 -4
- package/dist/src/codegen/extract/step-types.d.ts.map +1 -1
- package/dist/src/codegen/extract/step-types.js +1 -1
- package/dist/src/codegen/extract/step-types.js.map +1 -1
- package/dist/src/codegen/scaffoldFromSchema.d.ts +12 -12
- package/dist/src/codegen/scaffoldFromSchema.d.ts.map +1 -1
- package/dist/src/codegen/scaffoldFromSchema.js +113 -101
- package/dist/src/codegen/scaffoldFromSchema.js.map +1 -1
- package/dist/src/codegen/templates/command/commands.specs.ts +3 -3
- package/dist/src/codegen/templates/command/decide.specs.specs.ts +52 -52
- package/dist/src/codegen/templates/command/decide.specs.ts +12 -12
- package/dist/src/codegen/templates/command/decide.specs.ts.ejs +1 -1
- package/dist/src/codegen/templates/command/events.specs.ts +3 -3
- package/dist/src/codegen/templates/command/evolve.specs.ts +3 -3
- package/dist/src/codegen/templates/command/handle.specs.ts +13 -13
- package/dist/src/codegen/templates/command/mutation.resolver.specs.ts +19 -19
- package/dist/src/codegen/templates/command/register.specs.ts +3 -3
- package/dist/src/codegen/templates/command/state.specs.ts +3 -3
- package/dist/src/codegen/templates/query/events.specs.ts +4 -4
- package/dist/src/codegen/templates/query/projection.specs.specs.ts +60 -60
- package/dist/src/codegen/templates/query/projection.specs.ts +54 -29
- package/dist/src/codegen/templates/query/projection.specs.ts.ejs +2 -2
- package/dist/src/codegen/templates/query/query.resolver.specs.ts +63 -63
- package/dist/src/codegen/templates/query/query.resolver.ts.ejs +1 -1
- package/dist/src/codegen/templates/query/state.specs.ts +9 -9
- package/dist/src/codegen/templates/react/react.specs.specs.ts +15 -15
- package/dist/src/codegen/templates/react/react.specs.ts +16 -16
- package/dist/src/codegen/templates/react/react.specs.ts.ejs +9 -9
- package/dist/src/codegen/templates/react/react.ts.ejs +5 -5
- package/dist/src/codegen/templates/react/react.ts.specs.ts +33 -33
- package/dist/src/codegen/templates/react/register.specs.ts +7 -7
- package/dist/src/codegen/templates/react/register.ts.ejs +4 -4
- package/dist/src/codegen/test-data/specVariant1.d.ts.map +1 -1
- package/dist/src/codegen/test-data/specVariant1.js +3 -2
- package/dist/src/codegen/test-data/specVariant1.js.map +1 -1
- package/dist/src/codegen/types.d.ts +2 -2
- package/dist/src/codegen/types.d.ts.map +1 -1
- package/dist/src/commands/generate-server.d.ts +21 -21
- package/dist/src/commands/generate-server.d.ts.map +1 -1
- package/dist/src/commands/generate-server.js +81 -63
- package/dist/src/commands/generate-server.js.map +1 -1
- package/dist/src/commands/initialize-server.d.ts.map +1 -1
- package/dist/src/commands/initialize-server.js +2 -2
- package/dist/src/commands/initialize-server.js.map +1 -1
- package/dist/src/domain/flows/shared/types.d.ts +14 -0
- package/dist/src/domain/flows/shared/types.d.ts.map +1 -0
- package/dist/src/domain/flows/shared/types.js +2 -0
- package/dist/src/domain/flows/shared/types.js.map +1 -0
- package/dist/src/domain/flows/shared/types.ts +15 -0
- package/dist/src/domain/narratives/shared/types.d.ts +14 -0
- package/dist/src/domain/narratives/shared/types.d.ts.map +1 -0
- package/dist/src/domain/narratives/shared/types.js +2 -0
- package/dist/src/domain/narratives/shared/types.js.map +1 -0
- package/dist/src/domain/narratives/shared/types.ts +15 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/server.js.map +1 -1
- package/dist/src/server.ts +3 -3
- package/dist/src/utils/loadRegisterFiles.d.ts +2 -2
- package/dist/src/utils/loadRegisterFiles.d.ts.map +1 -1
- package/dist/src/utils/loadRegisterFiles.js.map +1 -1
- package/dist/src/utils/loadRegisterFiles.ts +5 -5
- package/dist/src/utils/loadResolvers.js +1 -1
- package/dist/src/utils/loadResolvers.js.map +1 -1
- package/dist/src/utils/loadResolvers.ts +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/codegen/extract/data-sink.ts +5 -5
- package/src/codegen/extract/events.ts +15 -15
- package/src/codegen/extract/gwt.ts +4 -4
- package/src/codegen/extract/imports.specs.ts +19 -19
- package/src/codegen/extract/imports.ts +13 -13
- package/src/codegen/extract/messages.specs.ts +30 -30
- package/src/codegen/extract/messages.ts +16 -16
- package/src/codegen/extract/projection.specs.ts +22 -22
- package/src/codegen/extract/projection.ts +9 -9
- package/src/codegen/extract/query.ts +2 -2
- package/src/codegen/extract/slice-normalizer.specs.ts +11 -11
- package/src/codegen/extract/slice-normalizer.ts +14 -14
- package/src/codegen/extract/states.ts +4 -4
- package/src/codegen/extract/step-converter.specs.ts +9 -9
- package/src/codegen/extract/step-converter.ts +15 -15
- package/src/codegen/extract/step-types.specs.ts +12 -12
- package/src/codegen/extract/step-types.ts +4 -4
- package/src/codegen/findEventSource.specs.ts +23 -23
- package/src/codegen/scaffoldErrors.specs.ts +4 -4
- package/src/codegen/scaffoldFromSchema.filter.specs.ts +32 -32
- package/src/codegen/scaffoldFromSchema.ts +146 -132
- package/src/codegen/templates/command/commands.specs.ts +3 -3
- package/src/codegen/templates/command/decide.specs.specs.ts +52 -52
- package/src/codegen/templates/command/decide.specs.ts +12 -12
- package/src/codegen/templates/command/decide.specs.ts.ejs +1 -1
- package/src/codegen/templates/command/events.specs.ts +3 -3
- package/src/codegen/templates/command/evolve.specs.ts +3 -3
- package/src/codegen/templates/command/handle.specs.ts +13 -13
- package/src/codegen/templates/command/mutation.resolver.specs.ts +19 -19
- package/src/codegen/templates/command/register.specs.ts +3 -3
- package/src/codegen/templates/command/state.specs.ts +3 -3
- package/src/codegen/templates/query/events.specs.ts +4 -4
- package/src/codegen/templates/query/projection.specs.specs.ts +60 -60
- package/src/codegen/templates/query/projection.specs.ts +54 -29
- package/src/codegen/templates/query/projection.specs.ts.ejs +2 -2
- package/src/codegen/templates/query/query.resolver.specs.ts +63 -63
- package/src/codegen/templates/query/query.resolver.ts.ejs +1 -1
- package/src/codegen/templates/query/state.specs.ts +9 -9
- package/src/codegen/templates/react/react.specs.specs.ts +15 -15
- package/src/codegen/templates/react/react.specs.ts +16 -16
- package/src/codegen/templates/react/react.specs.ts.ejs +9 -9
- package/src/codegen/templates/react/react.ts.ejs +5 -5
- package/src/codegen/templates/react/react.ts.specs.ts +33 -33
- package/src/codegen/templates/react/register.specs.ts +7 -7
- package/src/codegen/templates/react/register.ts.ejs +4 -4
- package/src/codegen/test-data/specVariant1.json +1 -1
- package/src/codegen/test-data/specVariant1.ts +3 -2
- package/src/codegen/test-data/specVariant2.json +1 -1
- package/src/codegen/types.ts +2 -2
- package/src/commands/generate-server.specs.ts +81 -79
- package/src/commands/generate-server.ts +110 -88
- package/src/commands/initialize-server.specs.ts +4 -4
- package/src/commands/initialize-server.ts +5 -2
- package/src/domain/flows/shared/types.ts +15 -0
- package/src/domain/narratives/shared/types.ts +15 -0
- package/src/index.ts +1 -1
- package/src/server.ts +3 -3
- package/src/utils/loadRegisterFiles.ts +5 -5
- package/src/utils/loadResolvers.ts +1 -1
package/package.json
CHANGED
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"uuid": "^13.0.0",
|
|
33
33
|
"web-streams-polyfill": "^4.1.0",
|
|
34
34
|
"zod": "^3.22.4",
|
|
35
|
-
"@auto-engineer/narrative": "1.
|
|
36
|
-
"@auto-engineer/message-bus": "1.
|
|
35
|
+
"@auto-engineer/narrative": "1.140.0",
|
|
36
|
+
"@auto-engineer/message-bus": "1.140.0"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"typescript": "^5.8.3",
|
|
45
45
|
"vitest": "^3.2.4",
|
|
46
46
|
"tsx": "^4.19.2",
|
|
47
|
-
"@auto-engineer/cli": "1.
|
|
47
|
+
"@auto-engineer/cli": "1.140.0"
|
|
48
48
|
},
|
|
49
|
-
"version": "1.
|
|
49
|
+
"version": "1.140.0",
|
|
50
50
|
"scripts": {
|
|
51
51
|
"generate:server": "tsx src/cli/index.ts",
|
|
52
52
|
"build": "tsc && tsx ../../scripts/fix-esm-imports.ts && rm -rf dist/src/codegen/templates && mkdir -p dist/src/codegen && cp -r src/codegen/templates dist/src/codegen/templates && cp src/server.ts dist/src && cp -r src/utils dist/src && cp -r src/domain dist/src",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Moment } from '@auto-engineer/narrative';
|
|
2
2
|
import type { CommandRef, ErrorRef } from '../types';
|
|
3
|
-
import {
|
|
3
|
+
import { extractGwtSpecsFromMoment, type GwtResult } from './step-converter';
|
|
4
4
|
|
|
5
5
|
function resolveStreamId(stream: string, exampleData: Record<string, unknown>): string {
|
|
6
6
|
return stream.replace(/\$\{([^}]+)\}/g, (_, key: string) => String(exampleData?.[key] ?? 'unknown'));
|
|
@@ -20,7 +20,7 @@ function extractExampleDataFromCommand(firstSpec: GwtResult): Record<string, unk
|
|
|
20
20
|
return firstExample?.exampleData ?? {};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function extractExampleDataFromSpecs(slice:
|
|
23
|
+
function extractExampleDataFromSpecs(slice: Moment, gwtSpecs: GwtResult[]): Record<string, unknown> {
|
|
24
24
|
if (gwtSpecs.length === 0) {
|
|
25
25
|
return {};
|
|
26
26
|
}
|
|
@@ -72,12 +72,12 @@ export function extractStreamIdFields(pattern: string): string[] {
|
|
|
72
72
|
return fields;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export function getStreamFromSink(slice:
|
|
75
|
+
export function getStreamFromSink(slice: Moment): { streamPattern?: string; streamId?: string } {
|
|
76
76
|
if (!('server' in slice)) return {};
|
|
77
77
|
if (slice.server?.data?.items == null || !Array.isArray(slice.server.data.items)) {
|
|
78
78
|
return {};
|
|
79
79
|
}
|
|
80
|
-
const gwtSpecs =
|
|
80
|
+
const gwtSpecs = extractGwtSpecsFromMoment(slice);
|
|
81
81
|
const exampleData = extractExampleDataFromSpecs(slice, gwtSpecs);
|
|
82
82
|
const serverData = slice.server.data.items;
|
|
83
83
|
|
|
@@ -6,35 +6,35 @@ function createEventMessage(
|
|
|
6
6
|
eventRef: string | undefined,
|
|
7
7
|
source: 'given' | 'then' | 'when',
|
|
8
8
|
allMessages: MessageDefinition[],
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
currentMomentName?: string,
|
|
10
|
+
currentSceneName?: string,
|
|
11
11
|
): Message | undefined {
|
|
12
12
|
if (eventRef == null) return undefined;
|
|
13
13
|
const fields = extractFieldsFromMessage(eventRef, 'event', allMessages);
|
|
14
14
|
const messageDef = allMessages.find((m) => m.type === 'event' && m.name === eventRef);
|
|
15
|
-
const metadata = messageDef?.metadata as {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
15
|
+
const metadata = messageDef?.metadata as { sourceSceneName?: string; sourceMomentName?: string } | undefined;
|
|
16
|
+
const sourceSceneName = metadata?.sourceSceneName ?? currentSceneName;
|
|
17
|
+
const sourceMomentName = metadata?.sourceMomentName ?? currentMomentName;
|
|
18
18
|
|
|
19
19
|
return {
|
|
20
20
|
type: eventRef,
|
|
21
21
|
fields,
|
|
22
22
|
source,
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
sourceSceneName,
|
|
24
|
+
sourceMomentName,
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export function extractEventsFromThen(
|
|
29
29
|
thenItems: Array<EventRef | ErrorRef>,
|
|
30
30
|
allMessages: MessageDefinition[],
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
currentMomentName?: string,
|
|
32
|
+
currentSceneName?: string,
|
|
33
33
|
): Message[] {
|
|
34
34
|
return thenItems
|
|
35
35
|
.map((then): Message | undefined => {
|
|
36
36
|
if (!('eventRef' in then)) return undefined;
|
|
37
|
-
return createEventMessage(then.eventRef, 'then', allMessages,
|
|
37
|
+
return createEventMessage(then.eventRef, 'then', allMessages, currentMomentName, currentSceneName);
|
|
38
38
|
})
|
|
39
39
|
.filter((event): event is Message => event !== undefined);
|
|
40
40
|
}
|
|
@@ -42,25 +42,25 @@ export function extractEventsFromThen(
|
|
|
42
42
|
export function extractEventsFromGiven(
|
|
43
43
|
givenEvents: EventRef[] | undefined,
|
|
44
44
|
allMessages: MessageDefinition[],
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
currentMomentName?: string,
|
|
46
|
+
currentSceneName?: string,
|
|
47
47
|
): Message[] {
|
|
48
48
|
if (!givenEvents) return [];
|
|
49
49
|
|
|
50
50
|
return givenEvents
|
|
51
|
-
.map((given) => createEventMessage(given.eventRef, 'given', allMessages,
|
|
51
|
+
.map((given) => createEventMessage(given.eventRef, 'given', allMessages, currentMomentName, currentSceneName))
|
|
52
52
|
.filter((event): event is Message => event !== undefined);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export function extractEventsFromWhen(
|
|
56
56
|
gwtSpecs: ReactGwtSpec[],
|
|
57
57
|
allMessages: MessageDefinition[],
|
|
58
|
-
|
|
58
|
+
currentMomentName?: string,
|
|
59
59
|
): Message[] {
|
|
60
60
|
return gwtSpecs.flatMap((gwt) => {
|
|
61
61
|
if (!Array.isArray(gwt.when)) {
|
|
62
62
|
return [];
|
|
63
63
|
}
|
|
64
|
-
return gwt.when.flatMap((eventExample) => extractEventsFromGiven([eventExample], allMessages,
|
|
64
|
+
return gwt.when.flatMap((eventExample) => extractEventsFromGiven([eventExample], allMessages, currentMomentName));
|
|
65
65
|
});
|
|
66
66
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Moment } from '@auto-engineer/narrative';
|
|
2
2
|
import type { CommandRef, EventRef, GwtCondition } from '../types';
|
|
3
|
-
import {
|
|
3
|
+
import { extractGwtSpecsFromMoment, type GwtConditionWithRule, type QueryActionRef } from './step-converter';
|
|
4
4
|
|
|
5
|
-
export function buildCommandGwtMapping(slice:
|
|
5
|
+
export function buildCommandGwtMapping(slice: Moment): Record<string, (GwtCondition & { failingFields?: string[] })[]> {
|
|
6
6
|
if (slice.type !== 'command') {
|
|
7
7
|
return {};
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const gwtSpecs =
|
|
10
|
+
const gwtSpecs = extractGwtSpecsFromMoment(slice);
|
|
11
11
|
const mapping = buildCommandMapping(gwtSpecs);
|
|
12
12
|
return enhanceMapping(mapping);
|
|
13
13
|
}
|
|
@@ -7,48 +7,48 @@ describe('groupEventImports', () => {
|
|
|
7
7
|
const events: Message[] = [{ type: 'OrderCreated', fields: [], source: 'then' }];
|
|
8
8
|
|
|
9
9
|
const result = groupEventImports({
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
currentMomentName: 'create order',
|
|
11
|
+
currentSceneName: 'order management',
|
|
12
12
|
events,
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
expect(result).toEqual([{ importPath: './events', eventTypes: ['OrderCreated'] }]);
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it('groups cross-slice same-
|
|
18
|
+
it('groups cross-slice same-scene events as ../other-slice/events', () => {
|
|
19
19
|
const events: Message[] = [
|
|
20
20
|
{
|
|
21
21
|
type: 'OrderCreated',
|
|
22
22
|
fields: [],
|
|
23
23
|
source: 'when',
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
sourceSceneName: 'order management',
|
|
25
|
+
sourceMomentName: 'create order',
|
|
26
26
|
},
|
|
27
27
|
];
|
|
28
28
|
|
|
29
29
|
const result = groupEventImports({
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
currentMomentName: 'notify customer',
|
|
31
|
+
currentSceneName: 'order management',
|
|
32
32
|
events,
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
expect(result).toEqual([{ importPath: '../create-order/events', eventTypes: ['OrderCreated'] }]);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
it('groups cross-
|
|
38
|
+
it('groups cross-scene events as ../../other-scene/other-slice/events', () => {
|
|
39
39
|
const events: Message[] = [
|
|
40
40
|
{
|
|
41
41
|
type: 'WorkoutCreated',
|
|
42
42
|
fields: [],
|
|
43
43
|
source: 'when',
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
sourceSceneName: 'gym workout creation',
|
|
45
|
+
sourceMomentName: 'create workout',
|
|
46
46
|
},
|
|
47
47
|
];
|
|
48
48
|
|
|
49
49
|
const result = groupEventImports({
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
currentMomentName: 'view workout progress',
|
|
51
|
+
currentSceneName: 'gym workout completion',
|
|
52
52
|
events,
|
|
53
53
|
});
|
|
54
54
|
|
|
@@ -60,27 +60,27 @@ describe('groupEventImports', () => {
|
|
|
60
60
|
]);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
it('handles mixed same-
|
|
63
|
+
it('handles mixed same-scene and cross-scene events', () => {
|
|
64
64
|
const events: Message[] = [
|
|
65
65
|
{
|
|
66
66
|
type: 'WorkoutCompleted',
|
|
67
67
|
fields: [],
|
|
68
68
|
source: 'when',
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
sourceSceneName: 'gym workout completion',
|
|
70
|
+
sourceMomentName: 'complete workout',
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
type: 'WorkoutCreated',
|
|
74
74
|
fields: [],
|
|
75
75
|
source: 'when',
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
sourceSceneName: 'gym workout creation',
|
|
77
|
+
sourceMomentName: 'create workout',
|
|
78
78
|
},
|
|
79
79
|
];
|
|
80
80
|
|
|
81
81
|
const result = groupEventImports({
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
currentMomentName: 'view workout progress',
|
|
83
|
+
currentSceneName: 'gym workout completion',
|
|
84
84
|
events,
|
|
85
85
|
});
|
|
86
86
|
|
|
@@ -6,9 +6,9 @@ export interface ImportGroup {
|
|
|
6
6
|
eventTypes: string[];
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export interface
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export interface CrossMomentImportContext {
|
|
10
|
+
currentMomentName: string;
|
|
11
|
+
currentSceneName: string;
|
|
12
12
|
events: Message[];
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -17,24 +17,24 @@ export interface CrossSliceImportContext {
|
|
|
17
17
|
* Events from the current slice are imported from './events',
|
|
18
18
|
* while cross-slice events are imported from '../other-slice/events'.
|
|
19
19
|
*/
|
|
20
|
-
export function groupEventImports(context:
|
|
21
|
-
const {
|
|
20
|
+
export function groupEventImports(context: CrossMomentImportContext): ImportGroup[] {
|
|
21
|
+
const { currentMomentName, currentSceneName, events } = context;
|
|
22
22
|
const importGroups = new Map<string, string[]>();
|
|
23
23
|
|
|
24
24
|
for (const event of events) {
|
|
25
25
|
if (!event.type) continue;
|
|
26
26
|
let importPath: string;
|
|
27
|
-
const
|
|
28
|
-
event.source === 'then' || event.
|
|
27
|
+
const isFromCurrentMoment =
|
|
28
|
+
event.source === 'then' || event.sourceMomentName === currentMomentName || event.sourceMomentName == null;
|
|
29
29
|
|
|
30
|
-
if (
|
|
30
|
+
if (isFromCurrentMoment) {
|
|
31
31
|
importPath = './events';
|
|
32
32
|
} else {
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const sliceSegment = toKebabCase(event.
|
|
36
|
-
importPath =
|
|
37
|
-
? `../../${toKebabCase(
|
|
33
|
+
const sourceSceneName = event.sourceSceneName;
|
|
34
|
+
const isCrossScene = sourceSceneName != null && sourceSceneName !== currentSceneName;
|
|
35
|
+
const sliceSegment = toKebabCase(event.sourceMomentName ?? currentMomentName);
|
|
36
|
+
importPath = isCrossScene
|
|
37
|
+
? `../../${toKebabCase(sourceSceneName)}/${sliceSegment}/events`
|
|
38
38
|
: `../${sliceSegment}/events`;
|
|
39
39
|
}
|
|
40
40
|
if (!importGroups.has(importPath)) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Moment } from '@auto-engineer/narrative';
|
|
2
2
|
import { describe, expect, it } from 'vitest';
|
|
3
3
|
import type { MessageDefinition } from '../types';
|
|
4
4
|
import { extractMessagesFromSpecs } from './messages';
|
|
5
5
|
|
|
6
6
|
describe('extractMessagesFromSpecs (react slice)', () => {
|
|
7
7
|
it('should extract given events and states, filtering phantom refs', () => {
|
|
8
|
-
const slice:
|
|
8
|
+
const slice: Moment = {
|
|
9
9
|
type: 'react',
|
|
10
10
|
name: 'adjust inventory on payment',
|
|
11
11
|
server: {
|
|
@@ -88,8 +88,8 @@ describe('extractMessagesFromSpecs (react slice)', () => {
|
|
|
88
88
|
{ name: 'orderId', tsType: 'string', required: true },
|
|
89
89
|
],
|
|
90
90
|
source: 'given',
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
sourceSceneName: undefined,
|
|
92
|
+
sourceMomentName: 'adjust inventory on payment',
|
|
93
93
|
},
|
|
94
94
|
]);
|
|
95
95
|
|
|
@@ -108,7 +108,7 @@ describe('extractMessagesFromSpecs (react slice)', () => {
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
it('should extract commands from normalized react when-command pattern', () => {
|
|
111
|
-
const slice:
|
|
111
|
+
const slice: Moment = {
|
|
112
112
|
type: 'react',
|
|
113
113
|
name: 'update workout progress',
|
|
114
114
|
server: {
|
|
@@ -174,8 +174,8 @@ describe('extractMessagesFromSpecs (react slice)', () => {
|
|
|
174
174
|
type: 'GymSessionLogged',
|
|
175
175
|
fields: [{ name: 'sessionId', tsType: 'string', required: true }],
|
|
176
176
|
source: 'given',
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
sourceSceneName: undefined,
|
|
178
|
+
sourceMomentName: 'update workout progress',
|
|
179
179
|
},
|
|
180
180
|
]);
|
|
181
181
|
|
|
@@ -191,7 +191,7 @@ describe('extractMessagesFromSpecs (react slice)', () => {
|
|
|
191
191
|
|
|
192
192
|
describe('extractMessagesFromSpecs (command slice)', () => {
|
|
193
193
|
it('should create state-as-event with source then for Given-step state refs', () => {
|
|
194
|
-
const slice:
|
|
194
|
+
const slice: Moment = {
|
|
195
195
|
type: 'command',
|
|
196
196
|
name: 'book barber appointment',
|
|
197
197
|
server: {
|
|
@@ -269,7 +269,7 @@ describe('extractMessagesFromSpecs (command slice)', () => {
|
|
|
269
269
|
{ name: 'appointments', tsType: 'object[]', required: true },
|
|
270
270
|
],
|
|
271
271
|
source: 'then',
|
|
272
|
-
|
|
272
|
+
sourceMomentName: 'book barber appointment',
|
|
273
273
|
},
|
|
274
274
|
{
|
|
275
275
|
type: 'BarberAppointmentBooked',
|
|
@@ -278,14 +278,14 @@ describe('extractMessagesFromSpecs (command slice)', () => {
|
|
|
278
278
|
{ name: 'barberId', tsType: 'string', required: true },
|
|
279
279
|
],
|
|
280
280
|
source: 'then',
|
|
281
|
-
|
|
282
|
-
|
|
281
|
+
sourceSceneName: undefined,
|
|
282
|
+
sourceMomentName: 'book barber appointment',
|
|
283
283
|
},
|
|
284
284
|
]);
|
|
285
285
|
});
|
|
286
286
|
|
|
287
287
|
it('should still extract Given-step event refs with source given', () => {
|
|
288
|
-
const slice:
|
|
288
|
+
const slice: Moment = {
|
|
289
289
|
type: 'command',
|
|
290
290
|
name: 'update order',
|
|
291
291
|
server: {
|
|
@@ -357,8 +357,8 @@ describe('extractMessagesFromSpecs (command slice)', () => {
|
|
|
357
357
|
type: 'OrderPlaced',
|
|
358
358
|
fields: [{ name: 'orderId', tsType: 'string', required: true }],
|
|
359
359
|
source: 'given',
|
|
360
|
-
|
|
361
|
-
|
|
360
|
+
sourceSceneName: undefined,
|
|
361
|
+
sourceMomentName: 'update order',
|
|
362
362
|
},
|
|
363
363
|
{
|
|
364
364
|
type: 'OrderUpdated',
|
|
@@ -367,8 +367,8 @@ describe('extractMessagesFromSpecs (command slice)', () => {
|
|
|
367
367
|
{ name: 'status', tsType: 'string', required: true },
|
|
368
368
|
],
|
|
369
369
|
source: 'then',
|
|
370
|
-
|
|
371
|
-
|
|
370
|
+
sourceSceneName: undefined,
|
|
371
|
+
sourceMomentName: 'update order',
|
|
372
372
|
},
|
|
373
373
|
]);
|
|
374
374
|
});
|
|
@@ -376,7 +376,7 @@ describe('extractMessagesFromSpecs (command slice)', () => {
|
|
|
376
376
|
|
|
377
377
|
describe('extractMessagesFromSpecs (query slice)', () => {
|
|
378
378
|
it('should not include non-event When steps in the events list', () => {
|
|
379
|
-
const slice:
|
|
379
|
+
const slice: Moment = {
|
|
380
380
|
type: 'query',
|
|
381
381
|
name: 'views workout details',
|
|
382
382
|
server: {
|
|
@@ -461,8 +461,8 @@ describe('extractMessagesFromSpecs (query slice)', () => {
|
|
|
461
461
|
{ name: 'exercise', tsType: 'string', required: true },
|
|
462
462
|
],
|
|
463
463
|
source: 'given',
|
|
464
|
-
|
|
465
|
-
|
|
464
|
+
sourceSceneName: undefined,
|
|
465
|
+
sourceMomentName: undefined,
|
|
466
466
|
},
|
|
467
467
|
]);
|
|
468
468
|
|
|
@@ -472,7 +472,7 @@ describe('extractMessagesFromSpecs (query slice)', () => {
|
|
|
472
472
|
|
|
473
473
|
describe('extractMessagesFromSpecs (react slice with data target events)', () => {
|
|
474
474
|
it('should extract data target events with source then', () => {
|
|
475
|
-
const slice:
|
|
475
|
+
const slice: Moment = {
|
|
476
476
|
type: 'react',
|
|
477
477
|
name: 'notify barber of new booking',
|
|
478
478
|
server: {
|
|
@@ -551,7 +551,7 @@ describe('extractMessagesFromSpecs (react slice with data target events)', () =>
|
|
|
551
551
|
{ name: 'notifiedAt', tsType: 'Date', required: true },
|
|
552
552
|
],
|
|
553
553
|
source: 'then',
|
|
554
|
-
|
|
554
|
+
sourceMomentName: 'notify barber of new booking',
|
|
555
555
|
},
|
|
556
556
|
]),
|
|
557
557
|
);
|
|
@@ -560,7 +560,7 @@ describe('extractMessagesFromSpecs (react slice with data target events)', () =>
|
|
|
560
560
|
|
|
561
561
|
describe('extractMessagesFromSpecs (command slice with data target events)', () => {
|
|
562
562
|
it('should extract data.items Event not in GWT Then', () => {
|
|
563
|
-
const slice:
|
|
563
|
+
const slice: Moment = {
|
|
564
564
|
type: 'command',
|
|
565
565
|
name: 'submit workout log',
|
|
566
566
|
server: {
|
|
@@ -644,15 +644,15 @@ describe('extractMessagesFromSpecs (command slice with data target events)', ()
|
|
|
644
644
|
type: 'WorkoutLogged',
|
|
645
645
|
fields: [{ name: 'workoutId', tsType: 'string', required: true }],
|
|
646
646
|
source: 'then',
|
|
647
|
-
|
|
648
|
-
|
|
647
|
+
sourceSceneName: undefined,
|
|
648
|
+
sourceMomentName: 'submit workout log',
|
|
649
649
|
},
|
|
650
650
|
{
|
|
651
651
|
type: 'WorkoutLogRejected',
|
|
652
652
|
fields: [{ name: 'workoutId', tsType: 'string', required: true }],
|
|
653
653
|
source: 'then',
|
|
654
|
-
|
|
655
|
-
|
|
654
|
+
sourceSceneName: undefined,
|
|
655
|
+
sourceMomentName: 'submit workout log',
|
|
656
656
|
},
|
|
657
657
|
{
|
|
658
658
|
type: 'PointsEarned',
|
|
@@ -661,13 +661,13 @@ describe('extractMessagesFromSpecs (command slice with data target events)', ()
|
|
|
661
661
|
{ name: 'points', tsType: 'number', required: true },
|
|
662
662
|
],
|
|
663
663
|
source: 'then',
|
|
664
|
-
|
|
664
|
+
sourceMomentName: 'submit workout log',
|
|
665
665
|
},
|
|
666
666
|
]);
|
|
667
667
|
});
|
|
668
668
|
|
|
669
669
|
it('should deduplicate events present in both GWT Then and data.items', () => {
|
|
670
|
-
const slice:
|
|
670
|
+
const slice: Moment = {
|
|
671
671
|
type: 'command',
|
|
672
672
|
name: 'place order',
|
|
673
673
|
server: {
|
|
@@ -723,8 +723,8 @@ describe('extractMessagesFromSpecs (command slice with data target events)', ()
|
|
|
723
723
|
type: 'OrderPlaced',
|
|
724
724
|
fields: [{ name: 'orderId', tsType: 'string', required: true }],
|
|
725
725
|
source: 'then',
|
|
726
|
-
|
|
727
|
-
|
|
726
|
+
sourceSceneName: undefined,
|
|
727
|
+
sourceMomentName: 'place order',
|
|
728
728
|
},
|
|
729
729
|
]);
|
|
730
730
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Moment } from '@auto-engineer/narrative';
|
|
2
2
|
import createDebug from 'debug';
|
|
3
3
|
import type { CommandRef, EventRef, Message, MessageDefinition } from '../types';
|
|
4
4
|
import { extractCommandsFromGwt, extractCommandsFromThen } from './commands';
|
|
@@ -52,7 +52,7 @@ function deduplicateMessages<T extends Message>(messages: T[]): T[] {
|
|
|
52
52
|
return result;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function extractDataTargetEvents(slice:
|
|
55
|
+
function extractDataTargetEvents(slice: Moment, allMessages: MessageDefinition[]): Message[] {
|
|
56
56
|
const events: Message[] = [];
|
|
57
57
|
if ('server' in slice && slice.server?.data?.items) {
|
|
58
58
|
for (const item of slice.server.data.items) {
|
|
@@ -61,7 +61,7 @@ function extractDataTargetEvents(slice: Slice, allMessages: MessageDefinition[])
|
|
|
61
61
|
type: item.target.name,
|
|
62
62
|
fields: extractFieldsFromMessage(item.target.name, 'event', allMessages),
|
|
63
63
|
source: 'then' as const,
|
|
64
|
-
|
|
64
|
+
sourceMomentName: slice.name,
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -69,11 +69,11 @@ function extractDataTargetEvents(slice: Slice, allMessages: MessageDefinition[])
|
|
|
69
69
|
return events;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
function extractMessagesForCommand(slice:
|
|
72
|
+
function extractMessagesForCommand(slice: Moment, allMessages: MessageDefinition[]): ExtractedMessages {
|
|
73
73
|
debugCommand('Extracting messages for command slice: %s', slice.name);
|
|
74
74
|
|
|
75
75
|
if (slice.type !== 'command') {
|
|
76
|
-
debugCommand('
|
|
76
|
+
debugCommand(' Moment type is not command, returning empty');
|
|
77
77
|
return EMPTY_EXTRACTED_MESSAGES;
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -98,7 +98,7 @@ function extractMessagesForCommand(slice: Slice, allMessages: MessageDefinition[
|
|
|
98
98
|
type: ref.eventRef,
|
|
99
99
|
fields: extractFieldsFromMessage(ref.eventRef, 'state', allMessages),
|
|
100
100
|
source: 'then' as const,
|
|
101
|
-
|
|
101
|
+
sourceMomentName: slice.name,
|
|
102
102
|
}));
|
|
103
103
|
debugCommand(' State-as-events from Given: %d', stateAsEvents.length);
|
|
104
104
|
|
|
@@ -129,11 +129,11 @@ function extractMessagesForCommand(slice: Slice, allMessages: MessageDefinition[
|
|
|
129
129
|
return result;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
function extractMessagesForQuery(slice:
|
|
132
|
+
function extractMessagesForQuery(slice: Moment, allMessages: MessageDefinition[]): ExtractedMessages {
|
|
133
133
|
debugQuery('Extracting messages for query slice: %s', slice.name);
|
|
134
134
|
|
|
135
135
|
if (slice.type !== 'query') {
|
|
136
|
-
debugQuery('
|
|
136
|
+
debugQuery(' Moment type is not query, returning empty');
|
|
137
137
|
return EMPTY_EXTRACTED_MESSAGES;
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -157,14 +157,14 @@ function extractMessagesForQuery(slice: Slice, allMessages: MessageDefinition[])
|
|
|
157
157
|
.map((eventExample) => {
|
|
158
158
|
const fields = extractFieldsFromMessage(eventExample.eventRef, 'event', allMessages);
|
|
159
159
|
const messageDef = allMessages.find((m) => m.type === 'event' && m.name === eventExample.eventRef);
|
|
160
|
-
const metadata = messageDef?.metadata as {
|
|
160
|
+
const metadata = messageDef?.metadata as { sourceSceneName?: string; sourceMomentName?: string } | undefined;
|
|
161
161
|
|
|
162
162
|
return {
|
|
163
163
|
type: eventExample.eventRef,
|
|
164
164
|
fields,
|
|
165
165
|
source: 'when',
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
sourceSceneName: metadata?.sourceSceneName,
|
|
167
|
+
sourceMomentName: metadata?.sourceMomentName,
|
|
168
168
|
};
|
|
169
169
|
});
|
|
170
170
|
|
|
@@ -188,11 +188,11 @@ function extractMessagesForQuery(slice: Slice, allMessages: MessageDefinition[])
|
|
|
188
188
|
return result;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
function extractMessagesForReact(slice:
|
|
191
|
+
function extractMessagesForReact(slice: Moment, allMessages: MessageDefinition[]): ExtractedMessages {
|
|
192
192
|
debugReact('Extracting messages for react slice: %s', slice.name);
|
|
193
193
|
|
|
194
194
|
if (slice.type !== 'react') {
|
|
195
|
-
debugReact('
|
|
195
|
+
debugReact(' Moment type is not react, returning empty');
|
|
196
196
|
return EMPTY_EXTRACTED_MESSAGES;
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -254,7 +254,7 @@ function extractMessagesForReact(slice: Slice, allMessages: MessageDefinition[])
|
|
|
254
254
|
return result;
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
export function extractMessagesFromSpecs(slice:
|
|
257
|
+
export function extractMessagesFromSpecs(slice: Moment, allMessages: MessageDefinition[]): ExtractedMessages {
|
|
258
258
|
debug('Extracting messages from slice: %s (type: %s)', slice.name, slice.type);
|
|
259
259
|
debug(' Total message definitions available: %d', allMessages.length);
|
|
260
260
|
|
|
@@ -271,8 +271,8 @@ export function extractMessagesFromSpecs(slice: Slice, allMessages: MessageDefin
|
|
|
271
271
|
result = extractMessagesForReact(slice, allMessages);
|
|
272
272
|
break;
|
|
273
273
|
default: {
|
|
274
|
-
const
|
|
275
|
-
debug(' Unknown slice type: %s, returning empty',
|
|
274
|
+
const unknownMoment = slice as Moment;
|
|
275
|
+
debug(' Unknown slice type: %s, returning empty', unknownMoment.type);
|
|
276
276
|
result = EMPTY_EXTRACTED_MESSAGES;
|
|
277
277
|
}
|
|
278
278
|
}
|