@auto-engineer/narrative 0.21.0 → 0.22.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/CHANGELOG.md +23 -0
- package/dist/src/id/addAutoIds.d.ts.map +1 -1
- package/dist/src/id/addAutoIds.js +16 -11
- 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 +8 -2
- package/dist/src/id/hasAllIds.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/narrative-context.d.ts +2 -2
- package/dist/src/narrative-context.d.ts.map +1 -1
- package/dist/src/narrative-context.js +18 -15
- package/dist/src/narrative-context.js.map +1 -1
- package/dist/src/narrative.d.ts +2 -2
- package/dist/src/narrative.d.ts.map +1 -1
- package/dist/src/narrative.js +6 -3
- package/dist/src/narrative.js.map +1 -1
- package/dist/src/samples/seasonal-assistant.schema.json +73 -65
- package/dist/src/schema.d.ts +13937 -7286
- package/dist/src/schema.d.ts.map +1 -1
- package/dist/src/schema.js +9 -6
- 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 -4
- package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.js +6 -3
- package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
- package/dist/src/types.d.ts +4 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/getNarratives.specs.ts +30 -30
- package/src/id/addAutoIds.specs.ts +79 -61
- package/src/id/addAutoIds.ts +17 -11
- package/src/id/hasAllIds.specs.ts +100 -54
- package/src/id/hasAllIds.ts +8 -2
- package/src/index.ts +2 -1
- package/src/model-to-narrative.specs.ts +206 -158
- package/src/narrative-context.ts +22 -16
- package/src/narrative.ts +8 -4
- package/src/samples/seasonal-assistant.schema.json +73 -65
- package/src/schema.ts +10 -6
- package/src/transformers/model-to-narrative/generators/flow.ts +14 -5
- package/src/transformers/narrative-to-model/index.ts +6 -3
- package/src/types.ts +5 -0
- package/.turbo/turbo-format.log +0 -4
- package/.turbo/turbo-lint.log +0 -4
- package/.turbo/turbo-test.log +0 -14
- package/.turbo/turbo-type-check.log +0 -5
- package/dist/src/commands/export-schema-runner.d.ts +0 -3
- package/dist/src/commands/export-schema-runner.d.ts.map +0 -1
- package/dist/src/commands/export-schema-runner.js +0 -53
- package/dist/src/commands/export-schema-runner.js.map +0 -1
- package/dist/src/fluent-builder.specs.d.ts +0 -2
- package/dist/src/fluent-builder.specs.d.ts.map +0 -1
- package/dist/src/fluent-builder.specs.js +0 -28
- package/dist/src/fluent-builder.specs.js.map +0 -1
- package/dist/src/getNarratives.cache.specs.d.ts +0 -2
- package/dist/src/getNarratives.cache.specs.d.ts.map +0 -1
- package/dist/src/getNarratives.cache.specs.js +0 -234
- package/dist/src/getNarratives.cache.specs.js.map +0 -1
- package/dist/src/getNarratives.specs.d.ts +0 -2
- package/dist/src/getNarratives.specs.d.ts.map +0 -1
- package/dist/src/getNarratives.specs.js +0 -1294
- package/dist/src/getNarratives.specs.js.map +0 -1
- package/dist/src/id/addAutoIds.specs.d.ts +0 -2
- package/dist/src/id/addAutoIds.specs.d.ts.map +0 -1
- package/dist/src/id/addAutoIds.specs.js +0 -265
- package/dist/src/id/addAutoIds.specs.js.map +0 -1
- package/dist/src/id/hasAllIds.specs.d.ts +0 -2
- package/dist/src/id/hasAllIds.specs.d.ts.map +0 -1
- package/dist/src/id/hasAllIds.specs.js +0 -231
- package/dist/src/id/hasAllIds.specs.js.map +0 -1
- package/dist/src/model-to-narrative.specs.d.ts +0 -2
- package/dist/src/model-to-narrative.specs.d.ts.map +0 -1
- package/dist/src/model-to-narrative.specs.js +0 -2378
- package/dist/src/model-to-narrative.specs.js.map +0 -1
- package/dist/src/narrative-context.specs.d.ts +0 -2
- package/dist/src/narrative-context.specs.d.ts.map +0 -1
- package/dist/src/narrative-context.specs.js +0 -185
- package/dist/src/narrative-context.specs.js.map +0 -1
- package/dist/src/transformers/narrative-to-model/type-inference.specs.d.ts +0 -2
- package/dist/src/transformers/narrative-to-model/type-inference.specs.d.ts.map +0 -1
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js +0 -167
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js.map +0 -1
package/package.json
CHANGED
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"typescript": "^5.9.2",
|
|
24
24
|
"zod": "^3.22.4",
|
|
25
25
|
"zod-to-json-schema": "^3.22.3",
|
|
26
|
-
"@auto-engineer/
|
|
27
|
-
"@auto-engineer/
|
|
28
|
-
"@auto-engineer/
|
|
26
|
+
"@auto-engineer/id": "0.22.0",
|
|
27
|
+
"@auto-engineer/message-bus": "0.22.0",
|
|
28
|
+
"@auto-engineer/file-store": "0.22.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^20.0.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
|
-
"version": "0.
|
|
38
|
+
"version": "0.22.0",
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "tsx scripts/build.ts",
|
|
41
41
|
"test": "vitest run --reporter=dot",
|
|
@@ -4,7 +4,7 @@ import { InMemoryFileStore } from '@auto-engineer/file-store';
|
|
|
4
4
|
import { NodeFileStore } from '@auto-engineer/file-store/node';
|
|
5
5
|
import { beforeEach, describe, expect, it } from 'vitest';
|
|
6
6
|
import { getNarratives } from './getNarratives';
|
|
7
|
-
import { type
|
|
7
|
+
import { type Example, type Model, modelToNarrative, type Narrative, type QuerySlice } from './index';
|
|
8
8
|
import { modelSchema } from './schema';
|
|
9
9
|
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -112,12 +112,12 @@ describe('getNarratives', (_mode) => {
|
|
|
112
112
|
/query items\(\$itemId: String!\) {\s+items\(itemId: \$itemId\) {\s+id\s+description\s+}/,
|
|
113
113
|
);
|
|
114
114
|
|
|
115
|
-
const data = viewItemSlice?.server?.data
|
|
116
|
-
if (!data || !Array.isArray(data)) throw new Error('No data found in view items slice');
|
|
115
|
+
const data = viewItemSlice?.server?.data;
|
|
116
|
+
if (!data || !Array.isArray(data.items)) throw new Error('No data found in view items slice');
|
|
117
117
|
|
|
118
|
-
expect(data).toHaveLength(1);
|
|
119
|
-
expect(data[0].target).toMatchObject({ type: 'State', name: 'items' });
|
|
120
|
-
expect(data[0].origin).toMatchObject({ name: 'ItemsProjection', type: 'projection' });
|
|
118
|
+
expect(data.items).toHaveLength(1);
|
|
119
|
+
expect(data.items[0].target).toMatchObject({ type: 'State', name: 'items' });
|
|
120
|
+
expect(data.items[0].origin).toMatchObject({ name: 'ItemsProjection', type: 'projection' });
|
|
121
121
|
|
|
122
122
|
const specs = viewItemSlice?.server?.specs;
|
|
123
123
|
if (specs == null || specs.length === 0 || specs[0].feature === '')
|
|
@@ -224,7 +224,7 @@ describe('getNarratives', (_mode) => {
|
|
|
224
224
|
f.slices.some((s) => {
|
|
225
225
|
if (s.type === 'command' || s.type === 'query') {
|
|
226
226
|
return (
|
|
227
|
-
s.server.data?.some(
|
|
227
|
+
s.server.data?.items?.some(
|
|
228
228
|
(d) =>
|
|
229
229
|
('destination' in d && d.destination?.type === 'integration') ||
|
|
230
230
|
('origin' in d && d.origin?.type === 'integration'),
|
|
@@ -1494,17 +1494,17 @@ flow('Projection Test', () => {
|
|
|
1494
1494
|
|
|
1495
1495
|
if (summarySlice?.type !== 'query') return;
|
|
1496
1496
|
|
|
1497
|
-
const data = summarySlice.server.data
|
|
1497
|
+
const data = summarySlice.server.data;
|
|
1498
1498
|
expect(data).toBeDefined();
|
|
1499
|
-
expect(data).toHaveLength(1);
|
|
1499
|
+
expect(data?.items).toHaveLength(1);
|
|
1500
1500
|
|
|
1501
|
-
expect(data?.[0].origin).toMatchObject({
|
|
1501
|
+
expect(data?.items?.[0].origin).toMatchObject({
|
|
1502
1502
|
type: 'projection',
|
|
1503
1503
|
name: 'TodoSummary',
|
|
1504
1504
|
singleton: true,
|
|
1505
1505
|
});
|
|
1506
1506
|
|
|
1507
|
-
expect(data?.[0].origin).not.toHaveProperty('idField');
|
|
1507
|
+
expect(data?.items?.[0].origin).not.toHaveProperty('idField');
|
|
1508
1508
|
});
|
|
1509
1509
|
|
|
1510
1510
|
it('should generate correct origin for regular projection with single idField', async () => {
|
|
@@ -1546,17 +1546,17 @@ flow('Projection Test', () => {
|
|
|
1546
1546
|
|
|
1547
1547
|
if (todoSlice?.type !== 'query') return;
|
|
1548
1548
|
|
|
1549
|
-
const data = todoSlice.server.data
|
|
1549
|
+
const data = todoSlice.server.data;
|
|
1550
1550
|
expect(data).toBeDefined();
|
|
1551
|
-
expect(data).toHaveLength(1);
|
|
1551
|
+
expect(data?.items).toHaveLength(1);
|
|
1552
1552
|
|
|
1553
|
-
expect(data?.[0].origin).toMatchObject({
|
|
1553
|
+
expect(data?.items?.[0].origin).toMatchObject({
|
|
1554
1554
|
type: 'projection',
|
|
1555
1555
|
name: 'Todos',
|
|
1556
1556
|
idField: 'todoId',
|
|
1557
1557
|
});
|
|
1558
1558
|
|
|
1559
|
-
expect(data?.[0].origin).not.toHaveProperty('singleton');
|
|
1559
|
+
expect(data?.items?.[0].origin).not.toHaveProperty('singleton');
|
|
1560
1560
|
});
|
|
1561
1561
|
|
|
1562
1562
|
it('should generate correct origin for composite projection with multiple idFields', async () => {
|
|
@@ -1598,17 +1598,17 @@ flow('Projection Test', () => {
|
|
|
1598
1598
|
|
|
1599
1599
|
if (userProjectSlice?.type !== 'query') return;
|
|
1600
1600
|
|
|
1601
|
-
const data = userProjectSlice.server.data
|
|
1601
|
+
const data = userProjectSlice.server.data;
|
|
1602
1602
|
expect(data).toBeDefined();
|
|
1603
|
-
expect(data).toHaveLength(1);
|
|
1603
|
+
expect(data?.items).toHaveLength(1);
|
|
1604
1604
|
|
|
1605
|
-
expect(data?.[0].origin).toMatchObject({
|
|
1605
|
+
expect(data?.items?.[0].origin).toMatchObject({
|
|
1606
1606
|
type: 'projection',
|
|
1607
1607
|
name: 'UserProjects',
|
|
1608
1608
|
idField: ['userId', 'projectId'],
|
|
1609
1609
|
});
|
|
1610
1610
|
|
|
1611
|
-
expect(data?.[0].origin).not.toHaveProperty('singleton');
|
|
1611
|
+
expect(data?.items?.[0].origin).not.toHaveProperty('singleton');
|
|
1612
1612
|
});
|
|
1613
1613
|
|
|
1614
1614
|
it('should validate all three projection patterns together', async () => {
|
|
@@ -1684,8 +1684,8 @@ flow('All Projection Patterns', () => {
|
|
|
1684
1684
|
|
|
1685
1685
|
const summarySlice = projectionFlow.slices.find((s) => s.name === 'views summary');
|
|
1686
1686
|
if (summarySlice?.type === 'query') {
|
|
1687
|
-
const data = summarySlice.server.data
|
|
1688
|
-
expect(data?.[0].origin).toMatchObject({
|
|
1687
|
+
const data = summarySlice.server.data;
|
|
1688
|
+
expect(data?.items?.[0].origin).toMatchObject({
|
|
1689
1689
|
type: 'projection',
|
|
1690
1690
|
name: 'TodoSummary',
|
|
1691
1691
|
singleton: true,
|
|
@@ -1694,8 +1694,8 @@ flow('All Projection Patterns', () => {
|
|
|
1694
1694
|
|
|
1695
1695
|
const todoSlice = projectionFlow.slices.find((s) => s.name === 'views todo');
|
|
1696
1696
|
if (todoSlice?.type === 'query') {
|
|
1697
|
-
const data = todoSlice.server.data
|
|
1698
|
-
expect(data?.[0].origin).toMatchObject({
|
|
1697
|
+
const data = todoSlice.server.data;
|
|
1698
|
+
expect(data?.items?.[0].origin).toMatchObject({
|
|
1699
1699
|
type: 'projection',
|
|
1700
1700
|
name: 'Todos',
|
|
1701
1701
|
idField: 'todoId',
|
|
@@ -1704,8 +1704,8 @@ flow('All Projection Patterns', () => {
|
|
|
1704
1704
|
|
|
1705
1705
|
const userProjectSlice = projectionFlow.slices.find((s) => s.name === 'views user project todos');
|
|
1706
1706
|
if (userProjectSlice?.type === 'query') {
|
|
1707
|
-
const data = userProjectSlice.server.data
|
|
1708
|
-
expect(data?.[0].origin).toMatchObject({
|
|
1707
|
+
const data = userProjectSlice.server.data;
|
|
1708
|
+
expect(data?.items?.[0].origin).toMatchObject({
|
|
1709
1709
|
type: 'projection',
|
|
1710
1710
|
name: 'UserProjectTodos',
|
|
1711
1711
|
idField: ['userId', 'projectId'],
|
|
@@ -1770,15 +1770,15 @@ flow('Data Item IDs', () => {
|
|
|
1770
1770
|
const commandSlice = dataIdsFlow.slices.find((s) => s.name === 'places order');
|
|
1771
1771
|
if (commandSlice?.type === 'command') {
|
|
1772
1772
|
const sinkData = commandSlice.server.data;
|
|
1773
|
-
expect(sinkData).toHaveLength(1);
|
|
1774
|
-
expect(sinkData?.[0].id).toBe('SINK-001');
|
|
1773
|
+
expect(sinkData?.items).toHaveLength(1);
|
|
1774
|
+
expect(sinkData?.items?.[0].id).toBe('SINK-001');
|
|
1775
1775
|
}
|
|
1776
1776
|
|
|
1777
1777
|
const querySlice = dataIdsFlow.slices.find((s) => s.name === 'views order status');
|
|
1778
1778
|
if (querySlice?.type === 'query') {
|
|
1779
|
-
const sourceData = querySlice.server.data
|
|
1780
|
-
expect(sourceData).toHaveLength(1);
|
|
1781
|
-
expect(sourceData?.[0].id).toBe('SOURCE-001');
|
|
1779
|
+
const sourceData = querySlice.server.data;
|
|
1780
|
+
expect(sourceData?.items).toHaveLength(1);
|
|
1781
|
+
expect(sourceData?.items?.[0].id).toBe('SOURCE-001');
|
|
1782
1782
|
}
|
|
1783
1783
|
});
|
|
1784
1784
|
});
|
|
@@ -688,12 +688,14 @@ describe('addAutoIds', () => {
|
|
|
688
688
|
server: {
|
|
689
689
|
description: 'Test server',
|
|
690
690
|
specs: [],
|
|
691
|
-
data:
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
691
|
+
data: {
|
|
692
|
+
items: [
|
|
693
|
+
{
|
|
694
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
695
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
696
|
+
},
|
|
697
|
+
],
|
|
698
|
+
},
|
|
697
699
|
},
|
|
698
700
|
},
|
|
699
701
|
],
|
|
@@ -708,7 +710,8 @@ describe('addAutoIds', () => {
|
|
|
708
710
|
const slice = result.narratives[0].slices[0];
|
|
709
711
|
|
|
710
712
|
if ('server' in slice && slice.server?.data) {
|
|
711
|
-
expect(slice.server.data
|
|
713
|
+
expect(slice.server.data.id).toMatch(AUTO_ID_REGEX);
|
|
714
|
+
expect(slice.server.data.items[0].id).toMatch(AUTO_ID_REGEX);
|
|
712
715
|
}
|
|
713
716
|
});
|
|
714
717
|
|
|
@@ -728,12 +731,14 @@ describe('addAutoIds', () => {
|
|
|
728
731
|
server: {
|
|
729
732
|
description: 'Test server',
|
|
730
733
|
specs: [],
|
|
731
|
-
data:
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
734
|
+
data: {
|
|
735
|
+
items: [
|
|
736
|
+
{
|
|
737
|
+
target: { type: 'State', name: 'TestState' },
|
|
738
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
739
|
+
},
|
|
740
|
+
],
|
|
741
|
+
},
|
|
737
742
|
},
|
|
738
743
|
},
|
|
739
744
|
],
|
|
@@ -748,7 +753,8 @@ describe('addAutoIds', () => {
|
|
|
748
753
|
const slice = result.narratives[0].slices[0];
|
|
749
754
|
|
|
750
755
|
if ('server' in slice && slice.server?.data) {
|
|
751
|
-
expect(slice.server.data
|
|
756
|
+
expect(slice.server.data.id).toMatch(AUTO_ID_REGEX);
|
|
757
|
+
expect(slice.server.data.items[0].id).toMatch(AUTO_ID_REGEX);
|
|
752
758
|
}
|
|
753
759
|
});
|
|
754
760
|
|
|
@@ -768,17 +774,19 @@ describe('addAutoIds', () => {
|
|
|
768
774
|
server: {
|
|
769
775
|
description: 'Test server',
|
|
770
776
|
specs: [],
|
|
771
|
-
data:
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
777
|
+
data: {
|
|
778
|
+
items: [
|
|
779
|
+
{
|
|
780
|
+
id: 'SINK-001',
|
|
781
|
+
target: { type: 'Command', name: 'TestCommand' },
|
|
782
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
783
|
+
_withState: {
|
|
784
|
+
target: { type: 'State', name: 'TestState' },
|
|
785
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
786
|
+
},
|
|
779
787
|
},
|
|
780
|
-
|
|
781
|
-
|
|
788
|
+
],
|
|
789
|
+
},
|
|
782
790
|
},
|
|
783
791
|
},
|
|
784
792
|
],
|
|
@@ -793,7 +801,7 @@ describe('addAutoIds', () => {
|
|
|
793
801
|
const slice = result.narratives[0].slices[0];
|
|
794
802
|
|
|
795
803
|
if ('server' in slice && slice.server?.data) {
|
|
796
|
-
const sink = slice.server.data[0];
|
|
804
|
+
const sink = slice.server.data.items[0];
|
|
797
805
|
expect(sink.id).toBe('SINK-001');
|
|
798
806
|
if ('destination' in sink && sink._withState) {
|
|
799
807
|
expect(sink._withState.id).toMatch(AUTO_ID_REGEX);
|
|
@@ -815,18 +823,21 @@ describe('addAutoIds', () => {
|
|
|
815
823
|
id: 'SLICE-001',
|
|
816
824
|
server: {
|
|
817
825
|
specs: [],
|
|
818
|
-
data:
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
826
|
+
data: {
|
|
827
|
+
id: 'EXISTING-DATA-001',
|
|
828
|
+
items: [
|
|
829
|
+
{
|
|
830
|
+
id: 'EXISTING-SINK-001',
|
|
831
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
832
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
id: 'EXISTING-SOURCE-001',
|
|
836
|
+
target: { type: 'State', name: 'TestState' },
|
|
837
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
838
|
+
},
|
|
839
|
+
],
|
|
840
|
+
},
|
|
830
841
|
},
|
|
831
842
|
},
|
|
832
843
|
],
|
|
@@ -841,8 +852,9 @@ describe('addAutoIds', () => {
|
|
|
841
852
|
const slice = result.narratives[0].slices[0];
|
|
842
853
|
|
|
843
854
|
if ('server' in slice && slice.server?.data) {
|
|
844
|
-
expect(slice.server.data
|
|
845
|
-
expect(slice.server.data[
|
|
855
|
+
expect(slice.server.data.id).toBe('EXISTING-DATA-001');
|
|
856
|
+
expect(slice.server.data.items[0].id).toBe('EXISTING-SINK-001');
|
|
857
|
+
expect(slice.server.data.items[1].id).toBe('EXISTING-SOURCE-001');
|
|
846
858
|
}
|
|
847
859
|
});
|
|
848
860
|
|
|
@@ -862,12 +874,14 @@ describe('addAutoIds', () => {
|
|
|
862
874
|
server: {
|
|
863
875
|
description: 'Test server',
|
|
864
876
|
specs: [],
|
|
865
|
-
data:
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
877
|
+
data: {
|
|
878
|
+
items: [
|
|
879
|
+
{
|
|
880
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
881
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
882
|
+
},
|
|
883
|
+
],
|
|
884
|
+
},
|
|
871
885
|
},
|
|
872
886
|
},
|
|
873
887
|
],
|
|
@@ -882,7 +896,8 @@ describe('addAutoIds', () => {
|
|
|
882
896
|
addAutoIds(model);
|
|
883
897
|
|
|
884
898
|
if ('server' in originalSlice && originalSlice.server?.data) {
|
|
885
|
-
expect(originalSlice.server.data
|
|
899
|
+
expect(originalSlice.server.data.id).toBeUndefined();
|
|
900
|
+
expect(originalSlice.server.data.items[0].id).toBeUndefined();
|
|
886
901
|
}
|
|
887
902
|
});
|
|
888
903
|
|
|
@@ -900,20 +915,22 @@ describe('addAutoIds', () => {
|
|
|
900
915
|
id: 'SLICE-001',
|
|
901
916
|
server: {
|
|
902
917
|
specs: [],
|
|
903
|
-
data:
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
918
|
+
data: {
|
|
919
|
+
items: [
|
|
920
|
+
{
|
|
921
|
+
target: { type: 'Event', name: 'Event1' },
|
|
922
|
+
destination: { type: 'stream', pattern: 'stream1' },
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
target: { type: 'Event', name: 'Event2' },
|
|
926
|
+
destination: { type: 'stream', pattern: 'stream2' },
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
target: { type: 'State', name: 'State1' },
|
|
930
|
+
origin: { type: 'projection', name: 'Proj1' },
|
|
931
|
+
},
|
|
932
|
+
],
|
|
933
|
+
},
|
|
917
934
|
},
|
|
918
935
|
},
|
|
919
936
|
],
|
|
@@ -928,7 +945,8 @@ describe('addAutoIds', () => {
|
|
|
928
945
|
const slice = result.narratives[0].slices[0];
|
|
929
946
|
|
|
930
947
|
if ('server' in slice && slice.server?.data) {
|
|
931
|
-
|
|
948
|
+
expect(slice.server.data.id).toMatch(AUTO_ID_REGEX);
|
|
949
|
+
const ids = slice.server.data.items.map((d) => d.id);
|
|
932
950
|
expect(ids[0]).toMatch(AUTO_ID_REGEX);
|
|
933
951
|
expect(ids[1]).toMatch(AUTO_ID_REGEX);
|
|
934
952
|
expect(ids[2]).toMatch(AUTO_ID_REGEX);
|
package/src/id/addAutoIds.ts
CHANGED
|
@@ -78,19 +78,25 @@ function processClientSpecs(slice: Slice): Slice {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
function processDataItems(slice: Slice): Slice {
|
|
81
|
-
if (!('server' in slice) || !slice.server?.data
|
|
81
|
+
if (!('server' in slice) || !slice.server?.data) return slice;
|
|
82
82
|
|
|
83
83
|
const modifiedSlice = structuredClone(slice);
|
|
84
|
-
if ('server' in modifiedSlice && modifiedSlice.server?.data
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
if ('server' in modifiedSlice && modifiedSlice.server?.data) {
|
|
85
|
+
// Ensure the data wrapper has an ID
|
|
86
|
+
ensureId(modifiedSlice.server.data);
|
|
87
|
+
|
|
88
|
+
// Process items array if it exists
|
|
89
|
+
if (Array.isArray(modifiedSlice.server.data.items)) {
|
|
90
|
+
modifiedSlice.server.data.items = modifiedSlice.server.data.items.map((item) => {
|
|
91
|
+
const itemCopy = { ...item };
|
|
92
|
+
ensureId(itemCopy);
|
|
93
|
+
if ('destination' in itemCopy && itemCopy._withState) {
|
|
94
|
+
itemCopy._withState = { ...itemCopy._withState };
|
|
95
|
+
ensureId(itemCopy._withState);
|
|
96
|
+
}
|
|
97
|
+
return itemCopy;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
return modifiedSlice;
|
|
96
102
|
}
|
|
@@ -452,7 +452,7 @@ describe('hasAllIds', () => {
|
|
|
452
452
|
});
|
|
453
453
|
|
|
454
454
|
describe('data item ID validation', () => {
|
|
455
|
-
it('should return false when data
|
|
455
|
+
it('should return false when data wrapper is missing an ID', () => {
|
|
456
456
|
const model: Model = {
|
|
457
457
|
variant: 'specs',
|
|
458
458
|
narratives: [
|
|
@@ -468,13 +468,52 @@ describe('hasAllIds', () => {
|
|
|
468
468
|
server: {
|
|
469
469
|
description: 'Test server',
|
|
470
470
|
specs: [],
|
|
471
|
-
data:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
471
|
+
data: {
|
|
472
|
+
items: [
|
|
473
|
+
{
|
|
474
|
+
id: 'SINK-001',
|
|
475
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
476
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
],
|
|
483
|
+
},
|
|
484
|
+
],
|
|
485
|
+
messages: [],
|
|
486
|
+
integrations: [],
|
|
487
|
+
modules: [],
|
|
488
|
+
};
|
|
489
|
+
expect(hasAllIds(model)).toBe(false);
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('should return false when data sink item is missing an ID', () => {
|
|
493
|
+
const model: Model = {
|
|
494
|
+
variant: 'specs',
|
|
495
|
+
narratives: [
|
|
496
|
+
{
|
|
497
|
+
name: 'Test Flow',
|
|
498
|
+
id: 'FLOW-001',
|
|
499
|
+
slices: [
|
|
500
|
+
{
|
|
501
|
+
type: 'command',
|
|
502
|
+
name: 'Test slice',
|
|
503
|
+
id: 'SLICE-001',
|
|
504
|
+
client: { specs: [] },
|
|
505
|
+
server: {
|
|
506
|
+
description: 'Test server',
|
|
507
|
+
specs: [],
|
|
508
|
+
data: {
|
|
509
|
+
id: 'DATA-001',
|
|
510
|
+
items: [
|
|
511
|
+
{
|
|
512
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
513
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
},
|
|
478
517
|
},
|
|
479
518
|
},
|
|
480
519
|
],
|
|
@@ -487,7 +526,7 @@ describe('hasAllIds', () => {
|
|
|
487
526
|
expect(hasAllIds(model)).toBe(false);
|
|
488
527
|
});
|
|
489
528
|
|
|
490
|
-
it('should return false when data source is missing an ID', () => {
|
|
529
|
+
it('should return false when data source item is missing an ID', () => {
|
|
491
530
|
const model: Model = {
|
|
492
531
|
variant: 'specs',
|
|
493
532
|
narratives: [
|
|
@@ -503,13 +542,15 @@ describe('hasAllIds', () => {
|
|
|
503
542
|
server: {
|
|
504
543
|
description: 'Test server',
|
|
505
544
|
specs: [],
|
|
506
|
-
data:
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
545
|
+
data: {
|
|
546
|
+
id: 'DATA-001',
|
|
547
|
+
items: [
|
|
548
|
+
{
|
|
549
|
+
target: { type: 'State', name: 'TestState' },
|
|
550
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
},
|
|
513
554
|
},
|
|
514
555
|
},
|
|
515
556
|
],
|
|
@@ -538,18 +579,20 @@ describe('hasAllIds', () => {
|
|
|
538
579
|
server: {
|
|
539
580
|
description: 'Test server',
|
|
540
581
|
specs: [],
|
|
541
|
-
data:
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
582
|
+
data: {
|
|
583
|
+
id: 'DATA-001',
|
|
584
|
+
items: [
|
|
585
|
+
{
|
|
586
|
+
id: 'SINK-001',
|
|
587
|
+
target: { type: 'Command', name: 'TestCommand' },
|
|
588
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
589
|
+
_withState: {
|
|
590
|
+
target: { type: 'State', name: 'TestState' },
|
|
591
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
592
|
+
},
|
|
550
593
|
},
|
|
551
|
-
|
|
552
|
-
|
|
594
|
+
],
|
|
595
|
+
},
|
|
553
596
|
},
|
|
554
597
|
},
|
|
555
598
|
],
|
|
@@ -578,20 +621,21 @@ describe('hasAllIds', () => {
|
|
|
578
621
|
server: {
|
|
579
622
|
description: 'Test server',
|
|
580
623
|
specs: [],
|
|
581
|
-
data:
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
624
|
+
data: {
|
|
625
|
+
id: 'DATA-001',
|
|
626
|
+
items: [
|
|
627
|
+
{
|
|
628
|
+
id: 'SINK-001',
|
|
629
|
+
target: { type: 'Event', name: 'TestEvent' },
|
|
630
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
id: 'SOURCE-001',
|
|
634
|
+
target: { type: 'State', name: 'TestState' },
|
|
635
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
636
|
+
},
|
|
637
|
+
],
|
|
638
|
+
},
|
|
595
639
|
},
|
|
596
640
|
},
|
|
597
641
|
],
|
|
@@ -620,19 +664,21 @@ describe('hasAllIds', () => {
|
|
|
620
664
|
server: {
|
|
621
665
|
description: 'Test server',
|
|
622
666
|
specs: [],
|
|
623
|
-
data:
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
667
|
+
data: {
|
|
668
|
+
id: 'DATA-001',
|
|
669
|
+
items: [
|
|
670
|
+
{
|
|
671
|
+
id: 'SINK-001',
|
|
672
|
+
target: { type: 'Command', name: 'TestCommand' },
|
|
673
|
+
destination: { type: 'stream', pattern: 'test-stream' },
|
|
674
|
+
_withState: {
|
|
675
|
+
id: 'SOURCE-001',
|
|
676
|
+
target: { type: 'State', name: 'TestState' },
|
|
677
|
+
origin: { type: 'projection', name: 'TestProjection' },
|
|
678
|
+
},
|
|
633
679
|
},
|
|
634
|
-
|
|
635
|
-
|
|
680
|
+
],
|
|
681
|
+
},
|
|
636
682
|
},
|
|
637
683
|
},
|
|
638
684
|
],
|
|
@@ -645,7 +691,7 @@ describe('hasAllIds', () => {
|
|
|
645
691
|
expect(hasAllIds(model)).toBe(true);
|
|
646
692
|
});
|
|
647
693
|
|
|
648
|
-
it('should return true when slice has no data
|
|
694
|
+
it('should return true when slice has no data', () => {
|
|
649
695
|
const model: Model = {
|
|
650
696
|
variant: 'specs',
|
|
651
697
|
narratives: [
|