@auto-engineer/narrative 0.13.3 → 0.15.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 +26 -0
- package/README.md +151 -99
- package/dist/scripts/convert-flow-exec.js +2 -2
- package/dist/scripts/convert-flow-exec.js.map +1 -1
- package/dist/scripts/convert-flow-helper.js +3 -4
- package/dist/scripts/convert-flow-helper.js.map +1 -1
- package/dist/scripts/convert-flow.js +4 -4
- package/dist/scripts/convert-flow.js.map +1 -1
- package/dist/scripts/print-schema.js +1 -1
- package/dist/scripts/print-schema.js.map +1 -1
- package/dist/src/commands/export-schema-helper.js +9 -9
- package/dist/src/commands/export-schema-helper.js.map +1 -1
- package/dist/src/commands/export-schema.d.ts.map +1 -1
- package/dist/src/commands/export-schema.js +49 -68
- package/dist/src/commands/export-schema.js.map +1 -1
- package/dist/src/data-narrative-builders.d.ts +1 -1
- package/dist/src/data-narrative-builders.d.ts.map +1 -1
- package/dist/src/data-narrative-builders.js +13 -19
- package/dist/src/data-narrative-builders.js.map +1 -1
- package/dist/src/fluent-builder.d.ts.map +1 -1
- package/dist/src/fluent-builder.js +2 -2
- package/dist/src/fluent-builder.js.map +1 -1
- package/dist/src/fluent-builder.specs.js +2 -2
- package/dist/src/fluent-builder.specs.js.map +1 -1
- package/dist/src/getNarratives.cache.specs.js +5 -5
- package/dist/src/getNarratives.cache.specs.js.map +1 -1
- package/dist/src/getNarratives.d.ts +1 -1
- package/dist/src/getNarratives.d.ts.map +1 -1
- package/dist/src/getNarratives.js +6 -3
- package/dist/src/getNarratives.js.map +1 -1
- package/dist/src/getNarratives.specs.js +6 -6
- package/dist/src/getNarratives.specs.js.map +1 -1
- package/dist/src/id/addAutoIds.d.ts +1 -1
- package/dist/src/id/addAutoIds.d.ts.map +1 -1
- package/dist/src/id/addAutoIds.js.map +1 -1
- package/dist/src/id/addAutoIds.specs.js +1 -1
- package/dist/src/id/addAutoIds.specs.js.map +1 -1
- package/dist/src/id/hasAllIds.d.ts +1 -1
- package/dist/src/id/hasAllIds.d.ts.map +1 -1
- package/dist/src/id/hasAllIds.specs.js +1 -1
- package/dist/src/id/hasAllIds.specs.js.map +1 -1
- package/dist/src/id/index.d.ts +1 -1
- package/dist/src/id/index.d.ts.map +1 -1
- package/dist/src/id/index.js +1 -1
- package/dist/src/id/index.js.map +1 -1
- package/dist/src/index.d.ts +14 -17
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -10
- package/dist/src/index.js.map +1 -1
- package/dist/src/integration-export-registry.d.ts +2 -2
- package/dist/src/integration-export-registry.d.ts.map +1 -1
- package/dist/src/integration-registry.d.ts +1 -1
- package/dist/src/integration-registry.d.ts.map +1 -1
- package/dist/src/integration-registry.js +1 -0
- package/dist/src/integration-registry.js.map +1 -1
- package/dist/src/loader/fs-path.js +2 -2
- package/dist/src/loader/fs-path.js.map +1 -1
- package/dist/src/loader/graph.d.ts +2 -2
- package/dist/src/loader/graph.d.ts.map +1 -1
- package/dist/src/loader/graph.js +2 -2
- package/dist/src/loader/graph.js.map +1 -1
- package/dist/src/loader/index.d.ts +1 -1
- package/dist/src/loader/index.d.ts.map +1 -1
- package/dist/src/loader/index.js +5 -5
- package/dist/src/loader/index.js.map +1 -1
- package/dist/src/loader/resolver.js +1 -1
- package/dist/src/loader/resolver.js.map +1 -1
- package/dist/src/loader/runtime-cjs.d.ts.map +1 -1
- package/dist/src/loader/runtime-cjs.js +2 -2
- package/dist/src/loader/runtime-cjs.js.map +1 -1
- package/dist/src/loader/ts-utils.js +5 -5
- package/dist/src/loader/ts-utils.js.map +1 -1
- package/dist/src/model-to-narrative.specs.js +73 -98
- package/dist/src/model-to-narrative.specs.js.map +1 -1
- package/dist/src/narrative-context.d.ts +4 -4
- package/dist/src/narrative-context.d.ts.map +1 -1
- package/dist/src/narrative-context.js +2 -2
- package/dist/src/narrative-context.js.map +1 -1
- package/dist/src/narrative-context.specs.js +118 -3
- package/dist/src/narrative-context.specs.js.map +1 -1
- package/dist/src/narrative-registry.d.ts +1 -1
- package/dist/src/narrative-registry.d.ts.map +1 -1
- package/dist/src/narrative-registry.js +1 -1
- package/dist/src/narrative-registry.js.map +1 -1
- package/dist/src/narrative.d.ts +3 -3
- package/dist/src/narrative.d.ts.map +1 -1
- package/dist/src/narrative.js +15 -17
- package/dist/src/narrative.js.map +1 -1
- package/dist/src/node.d.ts +1 -1
- package/dist/src/node.d.ts.map +1 -1
- package/dist/src/node.js +1 -1
- package/dist/src/node.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 +1 -1
- package/dist/src/samples/mixed-given-types.narrative.js.map +1 -1
- package/dist/src/samples/place-order.narrative.js +1 -1
- package/dist/src/samples/place-order.narrative.js.map +1 -1
- package/dist/src/samples/questionnaires.narrative.js +1 -1
- package/dist/src/samples/questionnaires.narrative.js.map +1 -1
- package/dist/src/samples/test-with-ids.narrative.js +1 -1
- package/dist/src/samples/test-with-ids.narrative.js.map +1 -1
- package/dist/src/schema-test.js +1 -1
- package/dist/src/schema-test.js.map +1 -1
- package/dist/src/schema.d.ts +264 -264
- package/dist/src/slice-builder.d.ts.map +1 -1
- package/dist/src/slice-builder.js +1 -1
- package/dist/src/slice-builder.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/ast/emit-helpers.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/ast/emit-helpers.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/formatting/sort-types.js +1 -1
- package/dist/src/transformers/model-to-narrative/formatting/sort-types.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/compose.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/generators/compose.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/compose.js +4 -4
- package/dist/src/transformers/model-to-narrative/generators/compose.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts +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.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.js +47 -57
- package/dist/src/transformers/model-to-narrative/generators/gwt.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.specs.d.ts +2 -0
- package/dist/src/transformers/model-to-narrative/generators/gwt.specs.d.ts.map +1 -0
- package/dist/src/transformers/model-to-narrative/generators/gwt.specs.js +142 -0
- package/dist/src/transformers/model-to-narrative/generators/gwt.specs.js.map +1 -0
- 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 +0 -4
- package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/types.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/generators/types.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/index.d.ts +1 -1
- 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/index.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/assemble.d.ts +1 -1
- package/dist/src/transformers/narrative-to-model/assemble.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/example-shapes.d.ts +1 -1
- package/dist/src/transformers/narrative-to-model/example-shapes.d.ts.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 +5 -5
- package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/inlining.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/inlining.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/integrations.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/integrations.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/integrations.js +3 -3
- package/dist/src/transformers/narrative-to-model/integrations.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/messages.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/messages.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/messages.js +1 -1
- package/dist/src/transformers/narrative-to-model/messages.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/normalize.d.ts +1 -1
- package/dist/src/transformers/narrative-to-model/normalize.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/spec-processors.d.ts +3 -3
- package/dist/src/transformers/narrative-to-model/spec-processors.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/spec-processors.js +2 -2
- package/dist/src/transformers/narrative-to-model/spec-processors.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.d.ts +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.js +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/zod-adapter.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/zod-adapter.d.ts.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -12
- package/scripts/convert-flow-exec.ts +2 -2
- package/scripts/convert-flow-helper.ts +3 -4
- package/scripts/convert-flow.ts +4 -4
- package/scripts/print-schema.ts +2 -2
- package/src/commands/export-schema-helper.ts +10 -12
- package/src/commands/export-schema.ts +50 -70
- package/src/data-narrative-builders.ts +8 -11
- package/src/fluent-builder.specs.ts +2 -2
- package/src/fluent-builder.ts +6 -6
- package/src/getNarratives.cache.specs.ts +6 -6
- package/src/getNarratives.specs.ts +6 -6
- package/src/getNarratives.ts +13 -5
- package/src/id/addAutoIds.specs.ts +2 -2
- package/src/id/addAutoIds.ts +1 -1
- package/src/id/hasAllIds.specs.ts +1 -1
- package/src/id/hasAllIds.ts +1 -1
- package/src/id/index.ts +1 -1
- package/src/index.ts +61 -54
- package/src/integration-export-registry.ts +2 -2
- package/src/integration-registry.ts +2 -1
- package/src/loader/fs-path.ts +2 -2
- package/src/loader/graph.ts +9 -9
- package/src/loader/index.ts +7 -7
- package/src/loader/resolver.ts +1 -1
- package/src/loader/runtime-cjs.ts +3 -3
- package/src/loader/ts-utils.ts +5 -5
- package/src/model-to-narrative.specs.ts +76 -99
- package/src/narrative-context.specs.ts +138 -4
- package/src/narrative-context.ts +6 -7
- package/src/narrative-registry.ts +2 -2
- package/src/narrative.ts +27 -33
- package/src/node.ts +1 -2
- package/src/samples/items.narrative.ts +3 -3
- package/src/samples/mixed-given-types.narrative.ts +2 -2
- package/src/samples/place-order.narrative.ts +1 -1
- package/src/samples/questionnaires.narrative.ts +10 -10
- package/src/samples/test-with-ids.narrative.ts +2 -2
- package/src/schema-test.ts +1 -1
- package/src/slice-builder.ts +2 -2
- package/src/transformers/model-to-narrative/ast/emit-helpers.ts +1 -1
- package/src/transformers/model-to-narrative/formatting/sort-types.ts +1 -1
- package/src/transformers/model-to-narrative/generators/compose.ts +5 -5
- package/src/transformers/model-to-narrative/generators/flow.ts +9 -9
- package/src/transformers/model-to-narrative/generators/gwt.specs.ts +157 -0
- package/src/transformers/model-to-narrative/generators/gwt.ts +80 -122
- package/src/transformers/model-to-narrative/generators/imports.ts +0 -4
- package/src/transformers/model-to-narrative/generators/types.ts +1 -1
- package/src/transformers/model-to-narrative/index.ts +2 -2
- package/src/transformers/narrative-to-model/assemble.ts +1 -1
- package/src/transformers/narrative-to-model/example-shapes.ts +1 -1
- package/src/transformers/narrative-to-model/index.ts +7 -7
- package/src/transformers/narrative-to-model/inlining.ts +2 -2
- package/src/transformers/narrative-to-model/integrations.ts +5 -5
- package/src/transformers/narrative-to-model/messages.ts +3 -3
- package/src/transformers/narrative-to-model/normalize.ts +1 -1
- package/src/transformers/narrative-to-model/spec-processors.ts +4 -4
- package/src/transformers/narrative-to-model/type-inference.specs.ts +2 -2
- package/src/transformers/narrative-to-model/type-inference.ts +2 -2
- package/src/transformers/narrative-to-model/zod-adapter.ts +2 -2
- package/src/types.ts +1 -1
- 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/eslint.config.ts +0 -12
- package/src/commands/export-schema-runner.ts +0 -74
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
3
|
import { command } from './fluent-builder';
|
|
4
|
-
import
|
|
4
|
+
import type { CommandSlice } from './index';
|
|
5
|
+
import { example, flow, describe as narrativeDescribe, it as narrativeIt, rule, should, specs } from './narrative';
|
|
6
|
+
import { registry } from './narrative-registry';
|
|
7
|
+
import type { Event, State } from './types';
|
|
5
8
|
|
|
6
9
|
type QuestionnaireLinkSent = Event<
|
|
7
10
|
'QuestionnaireLinkSent',
|
|
@@ -36,9 +39,140 @@ type QuestionnaireProgress = State<
|
|
|
36
39
|
}
|
|
37
40
|
>;
|
|
38
41
|
|
|
42
|
+
describe('it and should with id parameter', () => {
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
registry.clearAll();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should record it with title only', () => {
|
|
48
|
+
flow('test it title only', () => {
|
|
49
|
+
command('test command').client(() => {
|
|
50
|
+
narrativeDescribe('Test Section', () => {
|
|
51
|
+
narrativeIt('displays todo list');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const narratives = registry.getAllNarratives();
|
|
57
|
+
const slice = narratives[0].slices[0] as CommandSlice;
|
|
58
|
+
const describeNode = slice.client.specs[0];
|
|
59
|
+
|
|
60
|
+
expect(describeNode.type).toBe('describe');
|
|
61
|
+
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
62
|
+
expect(describeNode.children).toHaveLength(1);
|
|
63
|
+
|
|
64
|
+
const itNode = describeNode.children![0];
|
|
65
|
+
expect(itNode.type).toBe('it');
|
|
66
|
+
expect(itNode.title).toBe('displays todo list');
|
|
67
|
+
expect(itNode.id).toBeUndefined();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should record it with title and id (id at end)', () => {
|
|
71
|
+
flow('test it with id', () => {
|
|
72
|
+
command('test command').client(() => {
|
|
73
|
+
narrativeDescribe('Test Section', () => {
|
|
74
|
+
narrativeIt('displays todo list', 'IT-001');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const narratives = registry.getAllNarratives();
|
|
80
|
+
const slice = narratives[0].slices[0] as CommandSlice;
|
|
81
|
+
const describeNode = slice.client.specs[0];
|
|
82
|
+
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
83
|
+
const itNode = describeNode.children![0];
|
|
84
|
+
|
|
85
|
+
expect(itNode.type).toBe('it');
|
|
86
|
+
expect(itNode.title).toBe('displays todo list');
|
|
87
|
+
expect(itNode.id).toBe('IT-001');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should record should with title only', () => {
|
|
91
|
+
flow('test should title only', () => {
|
|
92
|
+
command('test command').client(() => {
|
|
93
|
+
narrativeDescribe('Test Section', () => {
|
|
94
|
+
should('display todo list');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const narratives = registry.getAllNarratives();
|
|
100
|
+
const slice = narratives[0].slices[0] as CommandSlice;
|
|
101
|
+
const describeNode = slice.client.specs[0];
|
|
102
|
+
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
103
|
+
const itNode = describeNode.children![0];
|
|
104
|
+
|
|
105
|
+
expect(itNode.type).toBe('it');
|
|
106
|
+
expect(itNode.title).toBe('display todo list');
|
|
107
|
+
expect(itNode.id).toBeUndefined();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should record should with title and id (id at end)', () => {
|
|
111
|
+
flow('test should with id', () => {
|
|
112
|
+
command('test command').client(() => {
|
|
113
|
+
narrativeDescribe('Test Section', () => {
|
|
114
|
+
should('display todo list', 'SH-001');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const narratives = registry.getAllNarratives();
|
|
120
|
+
const slice = narratives[0].slices[0] as CommandSlice;
|
|
121
|
+
const describeNode = slice.client.specs[0];
|
|
122
|
+
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
123
|
+
const itNode = describeNode.children![0];
|
|
124
|
+
|
|
125
|
+
expect(itNode.type).toBe('it');
|
|
126
|
+
expect(itNode.title).toBe('display todo list');
|
|
127
|
+
expect(itNode.id).toBe('SH-001');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('describe with id parameter', () => {
|
|
132
|
+
afterEach(() => {
|
|
133
|
+
registry.clearAll();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should record describe with title and callback', () => {
|
|
137
|
+
flow('test describe title', () => {
|
|
138
|
+
command('test command').client(() => {
|
|
139
|
+
narrativeDescribe('Todo List', () => {
|
|
140
|
+
narrativeIt('shows items');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const narratives = registry.getAllNarratives();
|
|
146
|
+
const slice = narratives[0].slices[0] as CommandSlice;
|
|
147
|
+
const describeNode = slice.client.specs[0];
|
|
148
|
+
|
|
149
|
+
expect(describeNode.type).toBe('describe');
|
|
150
|
+
expect(describeNode.title).toBe('Todo List');
|
|
151
|
+
expect(describeNode.id).toBeUndefined();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should record describe with title, id, and callback (id at end)', () => {
|
|
155
|
+
flow('test describe with id', () => {
|
|
156
|
+
command('test command').client(() => {
|
|
157
|
+
narrativeDescribe('Todo List', 'DESC-001', () => {
|
|
158
|
+
narrativeIt('shows items');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const narratives = registry.getAllNarratives();
|
|
164
|
+
const slice = narratives[0].slices[0] as CommandSlice;
|
|
165
|
+
const describeNode = slice.client.specs[0];
|
|
166
|
+
|
|
167
|
+
expect(describeNode.type).toBe('describe');
|
|
168
|
+
expect(describeNode.title).toBe('Todo List');
|
|
169
|
+
expect(describeNode.id).toBe('DESC-001');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
39
173
|
describe('Narrative DSL', () => {
|
|
40
174
|
beforeEach(async () => {
|
|
41
|
-
|
|
175
|
+
registry.clearAll();
|
|
42
176
|
});
|
|
43
177
|
|
|
44
178
|
it('should support given() method in builder', () => {
|
package/src/narrative-context.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import createDebug from 'debug';
|
|
2
|
-
import type { DataSinkItem, DataSourceItem, DataItem, DataSink, DataSource } from './types';
|
|
3
|
-
import type { GivenTypeInfo } from './loader/ts-utils';
|
|
4
|
-
import { Narrative, Slice, CommandSlice, QuerySlice, ExperienceSlice } from './index';
|
|
5
|
-
import type { ClientSpecNode } from './schema';
|
|
6
2
|
import type { z } from 'zod';
|
|
7
|
-
import type {
|
|
3
|
+
import type { CommandSlice, ExperienceSlice, Narrative, QuerySlice, Slice } from './index';
|
|
4
|
+
import type { GivenTypeInfo } from './loader/ts-utils';
|
|
5
|
+
import type { ClientSpecNode, ExampleSchema, RuleSchema, SpecSchema, StepSchema } from './schema';
|
|
6
|
+
import type { DataItem, DataSink, DataSinkItem, DataSource, DataSourceItem } from './types';
|
|
8
7
|
|
|
9
8
|
type Step = z.infer<typeof StepSchema>;
|
|
10
9
|
type Example = z.infer<typeof ExampleSchema>;
|
|
@@ -213,7 +212,7 @@ export function pushSpec(feature: string): void {
|
|
|
213
212
|
}
|
|
214
213
|
}
|
|
215
214
|
|
|
216
|
-
export function pushDescribe(
|
|
215
|
+
export function pushDescribe(title?: string, id?: string): void {
|
|
217
216
|
if (!context) throw new Error('No active narrative context');
|
|
218
217
|
|
|
219
218
|
const describeNode: ClientSpecNode = {
|
|
@@ -260,7 +259,7 @@ export function popDescribe(): void {
|
|
|
260
259
|
addNodeToParentOrRoot(completedDescribe, slice as CommandSlice | QuerySlice | ExperienceSlice);
|
|
261
260
|
}
|
|
262
261
|
|
|
263
|
-
export function recordIt(
|
|
262
|
+
export function recordIt(title: string, id?: string): void {
|
|
264
263
|
if (!context) throw new Error('No active narrative context');
|
|
265
264
|
|
|
266
265
|
const itNode: ClientSpecNode = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NarrativeSchema } from './schema';
|
|
2
|
-
import { Narrative } from './index';
|
|
3
1
|
import createDebug from 'debug';
|
|
2
|
+
import type { Narrative } from './index';
|
|
3
|
+
import { NarrativeSchema } from './schema';
|
|
4
4
|
|
|
5
5
|
const debug = createDebug('auto:narrative:registry');
|
|
6
6
|
// Set non-error-like colors for debug namespace
|
package/src/narrative.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import createDebug from 'debug';
|
|
2
2
|
import {
|
|
3
|
-
startNarrative,
|
|
4
3
|
clearCurrentNarrative,
|
|
5
|
-
getCurrentSlice,
|
|
6
|
-
startClientBlock,
|
|
7
4
|
endClientBlock,
|
|
8
|
-
startServerBlock,
|
|
9
5
|
endServerBlock,
|
|
10
|
-
|
|
11
|
-
pushDescribe,
|
|
6
|
+
getCurrentSlice,
|
|
12
7
|
popDescribe,
|
|
8
|
+
pushDescribe,
|
|
9
|
+
pushSpec,
|
|
10
|
+
recordErrorStep,
|
|
11
|
+
recordExample,
|
|
13
12
|
recordIt,
|
|
14
|
-
setSliceData,
|
|
15
13
|
recordRule,
|
|
16
|
-
recordExample,
|
|
17
14
|
recordStep,
|
|
18
|
-
|
|
15
|
+
setSliceData,
|
|
16
|
+
startClientBlock,
|
|
17
|
+
startNarrative,
|
|
18
|
+
startServerBlock,
|
|
19
19
|
} from './narrative-context';
|
|
20
|
+
import { registry } from './narrative-registry';
|
|
20
21
|
import type { DataItem } from './types';
|
|
21
|
-
import createDebug from 'debug';
|
|
22
22
|
|
|
23
23
|
const debug = createDebug('auto:narrative:narrative');
|
|
24
24
|
if ('color' in debug && typeof debug === 'object') {
|
|
@@ -65,43 +65,37 @@ export const request = (_query: unknown) => ({
|
|
|
65
65
|
|
|
66
66
|
export function describe(fn: () => void): void;
|
|
67
67
|
export function describe(title: string, fn: () => void): void;
|
|
68
|
-
export function describe(
|
|
69
|
-
export function describe(
|
|
70
|
-
|
|
71
|
-
titleOrFn?: string | (() => void),
|
|
72
|
-
fn?: () => void,
|
|
73
|
-
): void {
|
|
74
|
-
if (typeof idOrTitleOrFn === 'function') {
|
|
68
|
+
export function describe(title: string, id: string, fn: () => void): void;
|
|
69
|
+
export function describe(titleOrFn: string | (() => void), idOrFn?: string | (() => void), fn?: () => void): void {
|
|
70
|
+
if (typeof titleOrFn === 'function') {
|
|
75
71
|
const slice = getCurrentSlice();
|
|
76
72
|
const inferredTitle = slice?.name ?? '';
|
|
77
|
-
pushDescribe(
|
|
78
|
-
|
|
73
|
+
pushDescribe(inferredTitle, undefined);
|
|
74
|
+
titleOrFn();
|
|
79
75
|
popDescribe();
|
|
80
76
|
return;
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
const callback = hasId ? fn! : (
|
|
79
|
+
const title = titleOrFn;
|
|
80
|
+
const hasId = typeof idOrFn === 'string';
|
|
81
|
+
const id = hasId ? idOrFn : undefined;
|
|
82
|
+
const callback = hasId ? fn! : (idOrFn as () => void);
|
|
87
83
|
|
|
88
|
-
pushDescribe(
|
|
84
|
+
pushDescribe(title, id);
|
|
89
85
|
callback();
|
|
90
86
|
popDescribe();
|
|
91
87
|
}
|
|
92
88
|
|
|
93
89
|
export function it(title: string): void;
|
|
94
|
-
export function it(
|
|
95
|
-
export function it(
|
|
96
|
-
|
|
97
|
-
recordIt(hasId ? idOrTitle : undefined, hasId ? title : idOrTitle);
|
|
90
|
+
export function it(title: string, id: string): void;
|
|
91
|
+
export function it(title: string, id?: string): void {
|
|
92
|
+
recordIt(title, id);
|
|
98
93
|
}
|
|
99
94
|
|
|
100
95
|
export function should(title: string): void;
|
|
101
|
-
export function should(
|
|
102
|
-
export function should(
|
|
103
|
-
|
|
104
|
-
recordIt(hasId ? idOrTitle : undefined, hasId ? title : idOrTitle);
|
|
96
|
+
export function should(title: string, id: string): void;
|
|
97
|
+
export function should(title: string, id?: string): void {
|
|
98
|
+
recordIt(title, id);
|
|
105
99
|
}
|
|
106
100
|
|
|
107
101
|
export function specs(feature: string, fn: () => void): void;
|
package/src/node.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export * from './index.js';
|
|
2
|
-
|
|
3
1
|
export {
|
|
4
2
|
commandHandler as exportSchemaCommandHandler,
|
|
5
3
|
type ExportSchemaCommand,
|
|
@@ -7,6 +5,7 @@ export {
|
|
|
7
5
|
type SchemaExportedEvent,
|
|
8
6
|
type SchemaExportFailedEvent,
|
|
9
7
|
} from './commands/export-schema.js';
|
|
8
|
+
export * from './index.js';
|
|
10
9
|
|
|
11
10
|
import { commandHandler as exportSchemaHandler } from './commands/export-schema.js';
|
|
12
11
|
export const COMMANDS = [exportSchemaHandler];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { data, flow, describe, it, specs, rule, example } from '../narrative';
|
|
2
|
-
import { command, query } from '../fluent-builder';
|
|
3
1
|
import gql from 'graphql-tag';
|
|
4
2
|
import { source } from '../data-narrative-builders';
|
|
5
|
-
import {
|
|
3
|
+
import { command, query } from '../fluent-builder';
|
|
4
|
+
import { data, describe, example, flow, it, rule, specs } from '../narrative';
|
|
5
|
+
import type { Command, Event, State } from '../types';
|
|
6
6
|
|
|
7
7
|
type ItemCreated = Event<
|
|
8
8
|
'ItemCreated',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { flow, specs, rule, example } from '../narrative';
|
|
2
1
|
import { query } from '../fluent-builder';
|
|
3
|
-
import {
|
|
2
|
+
import { example, flow, rule, specs } from '../narrative';
|
|
3
|
+
import type { Event, State } from '../types';
|
|
4
4
|
|
|
5
5
|
type ConfigState = State<
|
|
6
6
|
'ConfigState',
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type Command,
|
|
2
3
|
command,
|
|
3
|
-
|
|
4
|
+
data,
|
|
5
|
+
describe,
|
|
6
|
+
type Event,
|
|
7
|
+
example,
|
|
4
8
|
experience,
|
|
5
9
|
flow,
|
|
10
|
+
gql,
|
|
6
11
|
it,
|
|
7
|
-
|
|
8
|
-
specs,
|
|
12
|
+
query,
|
|
9
13
|
rule,
|
|
10
|
-
example,
|
|
11
|
-
gql,
|
|
12
|
-
source,
|
|
13
|
-
data,
|
|
14
|
-
sink,
|
|
15
|
-
type Command,
|
|
16
|
-
type Event,
|
|
17
14
|
type State,
|
|
15
|
+
sink,
|
|
16
|
+
source,
|
|
17
|
+
specs,
|
|
18
18
|
} from '@auto-engineer/narrative';
|
|
19
19
|
|
|
20
20
|
type QuestionnaireLinkSent = Event<
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { flow, specs, rule, example, thenError } from '../narrative';
|
|
2
1
|
import { command, query, react } from '../fluent-builder';
|
|
3
|
-
import {
|
|
2
|
+
import { example, flow, rule, specs, thenError } from '../narrative';
|
|
3
|
+
import type { Command, Event, State } from '../types';
|
|
4
4
|
|
|
5
5
|
type TestItemCreated = Event<
|
|
6
6
|
'TestItemCreated',
|
package/src/schema-test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DataSinkSchema, DataSourceSchema, MessageTargetSchema } from './schema';
|
|
2
1
|
import { sink, source } from './data-narrative-builders';
|
|
2
|
+
import { DataSinkSchema, DataSourceSchema, MessageTargetSchema } from './schema';
|
|
3
3
|
|
|
4
4
|
// Test that the builders produce output compatible with the schema
|
|
5
5
|
const testSink = sink().event('TestEvent').fields({ id: true }).toStream('test-${id}');
|
package/src/slice-builder.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Integration } from './types';
|
|
2
|
-
import { getCurrentNarrative, addSlice } from './narrative-context';
|
|
3
1
|
import type { CommandSlice, QuerySlice, ReactSlice } from './index';
|
|
2
|
+
import { addSlice, getCurrentNarrative } from './narrative-context';
|
|
3
|
+
import type { Integration } from './types';
|
|
4
4
|
|
|
5
5
|
export interface SliceConfig {
|
|
6
6
|
integration?: Integration;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { collectTypeDeclarations } from '../analysis/type-decls';
|
|
2
1
|
import { findCodeBoundaries, reconstructCode } from '../analysis/lint-helpers';
|
|
2
|
+
import { collectTypeDeclarations } from '../analysis/type-decls';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Sorts TypeScript type declarations alphabetically, adds line breaks between them, and removes unused types.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { buildFlowStatements } from './flow';
|
|
2
|
+
import type { Model } from '../../../index';
|
|
3
|
+
import { analyzeCodeUsage } from '../analysis/usage';
|
|
5
4
|
import { extractTypeIntegrationNames } from '../utils/integration-extractor';
|
|
6
5
|
import { integrationNameToPascalCase } from '../utils/strings';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { buildFlowStatements } from './flow';
|
|
7
|
+
import { ALL_FLOW_FUNCTION_NAMES, buildImports } from './imports';
|
|
8
|
+
import { buildTypeAliases } from './types';
|
|
9
9
|
|
|
10
10
|
export function generateTypeScriptCode(schema: Model, opts: { flowImport: string; integrationImport: string }): string {
|
|
11
11
|
const f = ts.factory;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import type tsNS from 'typescript';
|
|
2
2
|
import type { z } from 'zod';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
3
|
+
import type {
|
|
4
|
+
ClientSpecNode,
|
|
6
5
|
CommandSliceSchema,
|
|
7
|
-
QuerySliceSchema,
|
|
8
|
-
ReactSliceSchema,
|
|
9
|
-
ExperienceSliceSchema,
|
|
10
|
-
ExampleSchema,
|
|
11
|
-
NarrativeSchema,
|
|
12
6
|
DataSinkSchema,
|
|
13
7
|
DataSourceSchema,
|
|
14
8
|
DestinationSchema,
|
|
9
|
+
ExampleSchema,
|
|
10
|
+
ExperienceSliceSchema,
|
|
11
|
+
NarrativeSchema,
|
|
15
12
|
OriginSchema,
|
|
16
|
-
|
|
13
|
+
QuerySliceSchema,
|
|
14
|
+
ReactSliceSchema,
|
|
17
15
|
} from '../../../schema';
|
|
16
|
+
import { jsonToExpr } from '../ast/emit-helpers';
|
|
17
|
+
import { buildConsolidatedGwtSpecBlock, type GWTBlock } from './gwt';
|
|
18
18
|
|
|
19
19
|
type CommandSlice = z.infer<typeof CommandSliceSchema>;
|
|
20
20
|
type QuerySlice = z.infer<typeof QuerySliceSchema>;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { buildConsolidatedGwtSpecBlock, buildGwtSpecBlock, type GWTBlock } from './gwt';
|
|
4
|
+
|
|
5
|
+
function printNode(node: ts.Node): string {
|
|
6
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
7
|
+
const sourceFile = ts.createSourceFile('test.ts', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
8
|
+
return printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('buildGwtSpecBlock', () => {
|
|
12
|
+
it('generates builder chain pattern for when+then (no given)', () => {
|
|
13
|
+
const gwtBlock: GWTBlock & { ruleDescription: string; exampleDescription: string; ruleId: string } = {
|
|
14
|
+
when: { commandRef: 'AddTodo', exampleData: { todoId: 'todo-001', description: 'Buy groceries' } },
|
|
15
|
+
then: [
|
|
16
|
+
{
|
|
17
|
+
eventRef: 'TodoAdded',
|
|
18
|
+
exampleData: {
|
|
19
|
+
todoId: 'todo-001',
|
|
20
|
+
description: 'Buy groceries',
|
|
21
|
+
status: 'pending',
|
|
22
|
+
addedAt: '2030-01-01T09:00:00.000Z',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
ruleDescription: 'todos can be added to the list',
|
|
27
|
+
exampleDescription: 'adds a new todo successfully',
|
|
28
|
+
ruleId: 'r1B2Cp8Y',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const result = buildGwtSpecBlock(ts, ts.factory, gwtBlock, 'command');
|
|
32
|
+
const code = printNode(result);
|
|
33
|
+
|
|
34
|
+
expect(code).toContain('rule("todos can be added to the list"');
|
|
35
|
+
expect(code).toContain('"r1B2Cp8Y"');
|
|
36
|
+
expect(code).toContain('example("adds a new todo successfully")');
|
|
37
|
+
expect(code).toContain('.when<AddTodo>');
|
|
38
|
+
expect(code).toContain('.then<TodoAdded>');
|
|
39
|
+
expect(code).not.toMatch(/example\("[^"]+",\s*\(\)/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('generates builder chain pattern for given+when+then', () => {
|
|
43
|
+
const gwtBlock: GWTBlock & { ruleDescription: string; exampleDescription: string; ruleId: string } = {
|
|
44
|
+
given: [
|
|
45
|
+
{
|
|
46
|
+
eventRef: 'TodoAdded',
|
|
47
|
+
exampleData: {
|
|
48
|
+
todoId: 'todo-001',
|
|
49
|
+
description: 'Buy groceries',
|
|
50
|
+
status: 'pending',
|
|
51
|
+
addedAt: '2030-01-01T09:00:00.000Z',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
when: { commandRef: 'MarkTodoInProgress', exampleData: { todoId: 'todo-001' } },
|
|
56
|
+
then: [
|
|
57
|
+
{
|
|
58
|
+
eventRef: 'TodoMarkedInProgress',
|
|
59
|
+
exampleData: { todoId: 'todo-001', markedAt: '2030-01-01T10:00:00.000Z' },
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
ruleDescription: 'todos can be moved to in progress',
|
|
63
|
+
exampleDescription: 'moves a pending todo to in progress',
|
|
64
|
+
ruleId: 'r2C3Dq9Z',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const result = buildGwtSpecBlock(ts, ts.factory, gwtBlock, 'command');
|
|
68
|
+
const code = printNode(result);
|
|
69
|
+
|
|
70
|
+
expect(code).toContain('example("moves a pending todo to in progress")');
|
|
71
|
+
expect(code).toContain('.given<TodoAdded>');
|
|
72
|
+
expect(code).toContain('.when<MarkTodoInProgress>');
|
|
73
|
+
expect(code).toContain('.then<TodoMarkedInProgress>');
|
|
74
|
+
expect(code).not.toMatch(/example\("[^"]+",\s*\(\)/);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('generates builder chain with .and() for multiple given events', () => {
|
|
78
|
+
const gwtBlock: GWTBlock & { ruleDescription: string; exampleDescription: string; ruleId: string } = {
|
|
79
|
+
given: [
|
|
80
|
+
{
|
|
81
|
+
eventRef: 'TodoAdded',
|
|
82
|
+
exampleData: { todoId: 'todo-001', description: 'Buy groceries', status: 'pending' },
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
eventRef: 'TodoMarkedInProgress',
|
|
86
|
+
exampleData: { todoId: 'todo-001', markedAt: '2030-01-01T10:00:00.000Z' },
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
when: { commandRef: 'MarkTodoComplete', exampleData: { todoId: 'todo-001' } },
|
|
90
|
+
then: [
|
|
91
|
+
{
|
|
92
|
+
eventRef: 'TodoMarkedComplete',
|
|
93
|
+
exampleData: { todoId: 'todo-001', completedAt: '2030-01-01T11:00:00.000Z' },
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
ruleDescription: 'todos can be marked as complete',
|
|
97
|
+
exampleDescription: 'marks an in-progress todo as complete',
|
|
98
|
+
ruleId: 'r3D4Eq0A',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const result = buildGwtSpecBlock(ts, ts.factory, gwtBlock, 'command');
|
|
102
|
+
const code = printNode(result);
|
|
103
|
+
|
|
104
|
+
expect(code).toContain('.given<TodoAdded>');
|
|
105
|
+
expect(code).toContain('.and<TodoMarkedInProgress>');
|
|
106
|
+
expect(code).toContain('.when<MarkTodoComplete>');
|
|
107
|
+
expect(code).toContain('.then<TodoMarkedComplete>');
|
|
108
|
+
expect(code).not.toMatch(/example\("[^"]+",\s*\(\)/);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('still wraps example in rule callback', () => {
|
|
112
|
+
const gwtBlock: GWTBlock & { ruleDescription: string; exampleDescription: string; ruleId: string } = {
|
|
113
|
+
when: { commandRef: 'AddTodo', exampleData: { todoId: 'todo-001' } },
|
|
114
|
+
then: [{ eventRef: 'TodoAdded', exampleData: { todoId: 'todo-001' } }],
|
|
115
|
+
ruleDescription: 'test rule',
|
|
116
|
+
exampleDescription: 'test example',
|
|
117
|
+
ruleId: 'testId',
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const result = buildGwtSpecBlock(ts, ts.factory, gwtBlock, 'command');
|
|
121
|
+
const code = printNode(result);
|
|
122
|
+
|
|
123
|
+
expect(code).toMatch(/rule\([^)]+\)\s*=>/);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('buildConsolidatedGwtSpecBlock', () => {
|
|
128
|
+
it('generates multiple examples with builder chain pattern', () => {
|
|
129
|
+
const rule = { id: 'r3D4Eq0A', description: 'todos can be marked as complete' };
|
|
130
|
+
const gwtBlocks: Array<GWTBlock & { exampleDescription: string }> = [
|
|
131
|
+
{
|
|
132
|
+
given: [{ eventRef: 'TodoAdded', exampleData: { todoId: 'todo-001' } }],
|
|
133
|
+
when: { commandRef: 'MarkTodoComplete', exampleData: { todoId: 'todo-001' } },
|
|
134
|
+
then: [{ eventRef: 'TodoMarkedComplete', exampleData: { todoId: 'todo-001' } }],
|
|
135
|
+
exampleDescription: 'marks an in-progress todo as complete',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
given: [{ eventRef: 'TodoAdded', exampleData: { todoId: 'todo-002' } }],
|
|
139
|
+
when: { commandRef: 'MarkTodoComplete', exampleData: { todoId: 'todo-002' } },
|
|
140
|
+
then: [{ eventRef: 'TodoMarkedComplete', exampleData: { todoId: 'todo-002' } }],
|
|
141
|
+
exampleDescription: 'marks a pending todo directly as complete',
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
const result = buildConsolidatedGwtSpecBlock(ts, ts.factory, rule, gwtBlocks, 'command');
|
|
146
|
+
const code = printNode(result);
|
|
147
|
+
|
|
148
|
+
expect(code).toContain('rule("todos can be marked as complete"');
|
|
149
|
+
expect(code).toContain('"r3D4Eq0A"');
|
|
150
|
+
expect(code).toContain('example("marks an in-progress todo as complete")');
|
|
151
|
+
expect(code).toContain('example("marks a pending todo directly as complete")');
|
|
152
|
+
expect(code).toContain('.given<TodoAdded>');
|
|
153
|
+
expect(code).toContain('.when<MarkTodoComplete>');
|
|
154
|
+
expect(code).toContain('.then<TodoMarkedComplete>');
|
|
155
|
+
expect(code).not.toMatch(/example\("[^"]+",\s*\(\)/);
|
|
156
|
+
});
|
|
157
|
+
});
|