@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.
Files changed (240) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +26 -0
  3. package/README.md +151 -99
  4. package/dist/scripts/convert-flow-exec.js +2 -2
  5. package/dist/scripts/convert-flow-exec.js.map +1 -1
  6. package/dist/scripts/convert-flow-helper.js +3 -4
  7. package/dist/scripts/convert-flow-helper.js.map +1 -1
  8. package/dist/scripts/convert-flow.js +4 -4
  9. package/dist/scripts/convert-flow.js.map +1 -1
  10. package/dist/scripts/print-schema.js +1 -1
  11. package/dist/scripts/print-schema.js.map +1 -1
  12. package/dist/src/commands/export-schema-helper.js +9 -9
  13. package/dist/src/commands/export-schema-helper.js.map +1 -1
  14. package/dist/src/commands/export-schema.d.ts.map +1 -1
  15. package/dist/src/commands/export-schema.js +49 -68
  16. package/dist/src/commands/export-schema.js.map +1 -1
  17. package/dist/src/data-narrative-builders.d.ts +1 -1
  18. package/dist/src/data-narrative-builders.d.ts.map +1 -1
  19. package/dist/src/data-narrative-builders.js +13 -19
  20. package/dist/src/data-narrative-builders.js.map +1 -1
  21. package/dist/src/fluent-builder.d.ts.map +1 -1
  22. package/dist/src/fluent-builder.js +2 -2
  23. package/dist/src/fluent-builder.js.map +1 -1
  24. package/dist/src/fluent-builder.specs.js +2 -2
  25. package/dist/src/fluent-builder.specs.js.map +1 -1
  26. package/dist/src/getNarratives.cache.specs.js +5 -5
  27. package/dist/src/getNarratives.cache.specs.js.map +1 -1
  28. package/dist/src/getNarratives.d.ts +1 -1
  29. package/dist/src/getNarratives.d.ts.map +1 -1
  30. package/dist/src/getNarratives.js +6 -3
  31. package/dist/src/getNarratives.js.map +1 -1
  32. package/dist/src/getNarratives.specs.js +6 -6
  33. package/dist/src/getNarratives.specs.js.map +1 -1
  34. package/dist/src/id/addAutoIds.d.ts +1 -1
  35. package/dist/src/id/addAutoIds.d.ts.map +1 -1
  36. package/dist/src/id/addAutoIds.js.map +1 -1
  37. package/dist/src/id/addAutoIds.specs.js +1 -1
  38. package/dist/src/id/addAutoIds.specs.js.map +1 -1
  39. package/dist/src/id/hasAllIds.d.ts +1 -1
  40. package/dist/src/id/hasAllIds.d.ts.map +1 -1
  41. package/dist/src/id/hasAllIds.specs.js +1 -1
  42. package/dist/src/id/hasAllIds.specs.js.map +1 -1
  43. package/dist/src/id/index.d.ts +1 -1
  44. package/dist/src/id/index.d.ts.map +1 -1
  45. package/dist/src/id/index.js +1 -1
  46. package/dist/src/id/index.js.map +1 -1
  47. package/dist/src/index.d.ts +14 -17
  48. package/dist/src/index.d.ts.map +1 -1
  49. package/dist/src/index.js +8 -10
  50. package/dist/src/index.js.map +1 -1
  51. package/dist/src/integration-export-registry.d.ts +2 -2
  52. package/dist/src/integration-export-registry.d.ts.map +1 -1
  53. package/dist/src/integration-registry.d.ts +1 -1
  54. package/dist/src/integration-registry.d.ts.map +1 -1
  55. package/dist/src/integration-registry.js +1 -0
  56. package/dist/src/integration-registry.js.map +1 -1
  57. package/dist/src/loader/fs-path.js +2 -2
  58. package/dist/src/loader/fs-path.js.map +1 -1
  59. package/dist/src/loader/graph.d.ts +2 -2
  60. package/dist/src/loader/graph.d.ts.map +1 -1
  61. package/dist/src/loader/graph.js +2 -2
  62. package/dist/src/loader/graph.js.map +1 -1
  63. package/dist/src/loader/index.d.ts +1 -1
  64. package/dist/src/loader/index.d.ts.map +1 -1
  65. package/dist/src/loader/index.js +5 -5
  66. package/dist/src/loader/index.js.map +1 -1
  67. package/dist/src/loader/resolver.js +1 -1
  68. package/dist/src/loader/resolver.js.map +1 -1
  69. package/dist/src/loader/runtime-cjs.d.ts.map +1 -1
  70. package/dist/src/loader/runtime-cjs.js +2 -2
  71. package/dist/src/loader/runtime-cjs.js.map +1 -1
  72. package/dist/src/loader/ts-utils.js +5 -5
  73. package/dist/src/loader/ts-utils.js.map +1 -1
  74. package/dist/src/model-to-narrative.specs.js +73 -98
  75. package/dist/src/model-to-narrative.specs.js.map +1 -1
  76. package/dist/src/narrative-context.d.ts +4 -4
  77. package/dist/src/narrative-context.d.ts.map +1 -1
  78. package/dist/src/narrative-context.js +2 -2
  79. package/dist/src/narrative-context.js.map +1 -1
  80. package/dist/src/narrative-context.specs.js +118 -3
  81. package/dist/src/narrative-context.specs.js.map +1 -1
  82. package/dist/src/narrative-registry.d.ts +1 -1
  83. package/dist/src/narrative-registry.d.ts.map +1 -1
  84. package/dist/src/narrative-registry.js +1 -1
  85. package/dist/src/narrative-registry.js.map +1 -1
  86. package/dist/src/narrative.d.ts +3 -3
  87. package/dist/src/narrative.d.ts.map +1 -1
  88. package/dist/src/narrative.js +15 -17
  89. package/dist/src/narrative.js.map +1 -1
  90. package/dist/src/node.d.ts +1 -1
  91. package/dist/src/node.d.ts.map +1 -1
  92. package/dist/src/node.js +1 -1
  93. package/dist/src/node.js.map +1 -1
  94. package/dist/src/samples/items.narrative.js +2 -2
  95. package/dist/src/samples/items.narrative.js.map +1 -1
  96. package/dist/src/samples/mixed-given-types.narrative.js +1 -1
  97. package/dist/src/samples/mixed-given-types.narrative.js.map +1 -1
  98. package/dist/src/samples/place-order.narrative.js +1 -1
  99. package/dist/src/samples/place-order.narrative.js.map +1 -1
  100. package/dist/src/samples/questionnaires.narrative.js +1 -1
  101. package/dist/src/samples/questionnaires.narrative.js.map +1 -1
  102. package/dist/src/samples/test-with-ids.narrative.js +1 -1
  103. package/dist/src/samples/test-with-ids.narrative.js.map +1 -1
  104. package/dist/src/schema-test.js +1 -1
  105. package/dist/src/schema-test.js.map +1 -1
  106. package/dist/src/schema.d.ts +264 -264
  107. package/dist/src/slice-builder.d.ts.map +1 -1
  108. package/dist/src/slice-builder.js +1 -1
  109. package/dist/src/slice-builder.js.map +1 -1
  110. package/dist/src/transformers/model-to-narrative/ast/emit-helpers.d.ts +1 -1
  111. package/dist/src/transformers/model-to-narrative/ast/emit-helpers.d.ts.map +1 -1
  112. package/dist/src/transformers/model-to-narrative/formatting/sort-types.js +1 -1
  113. package/dist/src/transformers/model-to-narrative/formatting/sort-types.js.map +1 -1
  114. package/dist/src/transformers/model-to-narrative/generators/compose.d.ts +1 -1
  115. package/dist/src/transformers/model-to-narrative/generators/compose.d.ts.map +1 -1
  116. package/dist/src/transformers/model-to-narrative/generators/compose.js +4 -4
  117. package/dist/src/transformers/model-to-narrative/generators/compose.js.map +1 -1
  118. package/dist/src/transformers/model-to-narrative/generators/flow.d.ts +1 -1
  119. package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
  120. package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
  121. package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts +1 -1
  122. package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts.map +1 -1
  123. package/dist/src/transformers/model-to-narrative/generators/gwt.js +47 -57
  124. package/dist/src/transformers/model-to-narrative/generators/gwt.js.map +1 -1
  125. package/dist/src/transformers/model-to-narrative/generators/gwt.specs.d.ts +2 -0
  126. package/dist/src/transformers/model-to-narrative/generators/gwt.specs.d.ts.map +1 -0
  127. package/dist/src/transformers/model-to-narrative/generators/gwt.specs.js +142 -0
  128. package/dist/src/transformers/model-to-narrative/generators/gwt.specs.js.map +1 -0
  129. package/dist/src/transformers/model-to-narrative/generators/imports.d.ts +1 -1
  130. package/dist/src/transformers/model-to-narrative/generators/imports.d.ts.map +1 -1
  131. package/dist/src/transformers/model-to-narrative/generators/imports.js +0 -4
  132. package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
  133. package/dist/src/transformers/model-to-narrative/generators/types.d.ts +1 -1
  134. package/dist/src/transformers/model-to-narrative/generators/types.d.ts.map +1 -1
  135. package/dist/src/transformers/model-to-narrative/index.d.ts +1 -1
  136. package/dist/src/transformers/model-to-narrative/index.d.ts.map +1 -1
  137. package/dist/src/transformers/model-to-narrative/index.js +1 -1
  138. package/dist/src/transformers/model-to-narrative/index.js.map +1 -1
  139. package/dist/src/transformers/narrative-to-model/assemble.d.ts +1 -1
  140. package/dist/src/transformers/narrative-to-model/assemble.d.ts.map +1 -1
  141. package/dist/src/transformers/narrative-to-model/example-shapes.d.ts +1 -1
  142. package/dist/src/transformers/narrative-to-model/example-shapes.d.ts.map +1 -1
  143. package/dist/src/transformers/narrative-to-model/index.d.ts +2 -2
  144. package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
  145. package/dist/src/transformers/narrative-to-model/index.js +5 -5
  146. package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
  147. package/dist/src/transformers/narrative-to-model/inlining.d.ts +2 -2
  148. package/dist/src/transformers/narrative-to-model/inlining.d.ts.map +1 -1
  149. package/dist/src/transformers/narrative-to-model/integrations.d.ts +2 -2
  150. package/dist/src/transformers/narrative-to-model/integrations.d.ts.map +1 -1
  151. package/dist/src/transformers/narrative-to-model/integrations.js +3 -3
  152. package/dist/src/transformers/narrative-to-model/integrations.js.map +1 -1
  153. package/dist/src/transformers/narrative-to-model/messages.d.ts +2 -2
  154. package/dist/src/transformers/narrative-to-model/messages.d.ts.map +1 -1
  155. package/dist/src/transformers/narrative-to-model/messages.js +1 -1
  156. package/dist/src/transformers/narrative-to-model/messages.js.map +1 -1
  157. package/dist/src/transformers/narrative-to-model/normalize.d.ts +1 -1
  158. package/dist/src/transformers/narrative-to-model/normalize.d.ts.map +1 -1
  159. package/dist/src/transformers/narrative-to-model/spec-processors.d.ts +3 -3
  160. package/dist/src/transformers/narrative-to-model/spec-processors.d.ts.map +1 -1
  161. package/dist/src/transformers/narrative-to-model/spec-processors.js +2 -2
  162. package/dist/src/transformers/narrative-to-model/spec-processors.js.map +1 -1
  163. package/dist/src/transformers/narrative-to-model/type-inference.d.ts +1 -1
  164. package/dist/src/transformers/narrative-to-model/type-inference.d.ts.map +1 -1
  165. package/dist/src/transformers/narrative-to-model/type-inference.js +1 -1
  166. package/dist/src/transformers/narrative-to-model/type-inference.js.map +1 -1
  167. package/dist/src/transformers/narrative-to-model/type-inference.specs.js +1 -1
  168. package/dist/src/transformers/narrative-to-model/type-inference.specs.js.map +1 -1
  169. package/dist/src/transformers/narrative-to-model/zod-adapter.d.ts +2 -2
  170. package/dist/src/transformers/narrative-to-model/zod-adapter.d.ts.map +1 -1
  171. package/dist/src/types.d.ts +1 -1
  172. package/dist/src/types.d.ts.map +1 -1
  173. package/dist/tsconfig.tsbuildinfo +1 -1
  174. package/package.json +5 -12
  175. package/scripts/convert-flow-exec.ts +2 -2
  176. package/scripts/convert-flow-helper.ts +3 -4
  177. package/scripts/convert-flow.ts +4 -4
  178. package/scripts/print-schema.ts +2 -2
  179. package/src/commands/export-schema-helper.ts +10 -12
  180. package/src/commands/export-schema.ts +50 -70
  181. package/src/data-narrative-builders.ts +8 -11
  182. package/src/fluent-builder.specs.ts +2 -2
  183. package/src/fluent-builder.ts +6 -6
  184. package/src/getNarratives.cache.specs.ts +6 -6
  185. package/src/getNarratives.specs.ts +6 -6
  186. package/src/getNarratives.ts +13 -5
  187. package/src/id/addAutoIds.specs.ts +2 -2
  188. package/src/id/addAutoIds.ts +1 -1
  189. package/src/id/hasAllIds.specs.ts +1 -1
  190. package/src/id/hasAllIds.ts +1 -1
  191. package/src/id/index.ts +1 -1
  192. package/src/index.ts +61 -54
  193. package/src/integration-export-registry.ts +2 -2
  194. package/src/integration-registry.ts +2 -1
  195. package/src/loader/fs-path.ts +2 -2
  196. package/src/loader/graph.ts +9 -9
  197. package/src/loader/index.ts +7 -7
  198. package/src/loader/resolver.ts +1 -1
  199. package/src/loader/runtime-cjs.ts +3 -3
  200. package/src/loader/ts-utils.ts +5 -5
  201. package/src/model-to-narrative.specs.ts +76 -99
  202. package/src/narrative-context.specs.ts +138 -4
  203. package/src/narrative-context.ts +6 -7
  204. package/src/narrative-registry.ts +2 -2
  205. package/src/narrative.ts +27 -33
  206. package/src/node.ts +1 -2
  207. package/src/samples/items.narrative.ts +3 -3
  208. package/src/samples/mixed-given-types.narrative.ts +2 -2
  209. package/src/samples/place-order.narrative.ts +1 -1
  210. package/src/samples/questionnaires.narrative.ts +10 -10
  211. package/src/samples/test-with-ids.narrative.ts +2 -2
  212. package/src/schema-test.ts +1 -1
  213. package/src/slice-builder.ts +2 -2
  214. package/src/transformers/model-to-narrative/ast/emit-helpers.ts +1 -1
  215. package/src/transformers/model-to-narrative/formatting/sort-types.ts +1 -1
  216. package/src/transformers/model-to-narrative/generators/compose.ts +5 -5
  217. package/src/transformers/model-to-narrative/generators/flow.ts +9 -9
  218. package/src/transformers/model-to-narrative/generators/gwt.specs.ts +157 -0
  219. package/src/transformers/model-to-narrative/generators/gwt.ts +80 -122
  220. package/src/transformers/model-to-narrative/generators/imports.ts +0 -4
  221. package/src/transformers/model-to-narrative/generators/types.ts +1 -1
  222. package/src/transformers/model-to-narrative/index.ts +2 -2
  223. package/src/transformers/narrative-to-model/assemble.ts +1 -1
  224. package/src/transformers/narrative-to-model/example-shapes.ts +1 -1
  225. package/src/transformers/narrative-to-model/index.ts +7 -7
  226. package/src/transformers/narrative-to-model/inlining.ts +2 -2
  227. package/src/transformers/narrative-to-model/integrations.ts +5 -5
  228. package/src/transformers/narrative-to-model/messages.ts +3 -3
  229. package/src/transformers/narrative-to-model/normalize.ts +1 -1
  230. package/src/transformers/narrative-to-model/spec-processors.ts +4 -4
  231. package/src/transformers/narrative-to-model/type-inference.specs.ts +2 -2
  232. package/src/transformers/narrative-to-model/type-inference.ts +2 -2
  233. package/src/transformers/narrative-to-model/zod-adapter.ts +2 -2
  234. package/src/types.ts +1 -1
  235. package/dist/src/commands/export-schema-runner.d.ts +0 -3
  236. package/dist/src/commands/export-schema-runner.d.ts.map +0 -1
  237. package/dist/src/commands/export-schema-runner.js +0 -53
  238. package/dist/src/commands/export-schema-runner.js.map +0 -1
  239. package/eslint.config.ts +0 -12
  240. package/src/commands/export-schema-runner.ts +0 -74
@@ -1,5 +1,5 @@
1
- import tsNS from 'typescript';
2
- import { jsonToExpr, type FieldTypeInfo } from '../ast/emit-helpers';
1
+ import type tsNS from 'typescript';
2
+ import { type FieldTypeInfo, jsonToExpr } from '../ast/emit-helpers';
3
3
 
4
4
  /**
5
5
  * Build a single specs() block for a GWT entry, adapting to slice type:
@@ -35,78 +35,37 @@ export type GWTBlock = {
35
35
  >;
36
36
  };
37
37
 
38
- function buildStandaloneGivenStatements(
38
+ function chainGivenCalls(
39
39
  ts: typeof import('typescript'),
40
40
  f: tsNS.NodeFactory,
41
+ base: tsNS.Expression,
41
42
  g: GWTBlock,
42
43
  messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
43
- ): tsNS.Statement[] {
44
- const statements: tsNS.Statement[] = [];
45
-
46
- if (hasGivenEvents(g) && g.given !== null && g.given !== undefined && g.given.length > 0) {
47
- const firstGiven = g.given[0];
48
- const firstTypeInfo = messages ? getFieldTypeInfo(messages, firstGiven.eventRef) : undefined;
49
- statements.push(
50
- f.createExpressionStatement(
51
- f.createCallExpression(
52
- f.createIdentifier('given'),
53
- [f.createTypeReferenceNode(firstGiven.eventRef, undefined)],
54
- [jsonToExpr(ts, f, firstGiven.exampleData, firstTypeInfo)],
55
- ),
56
- ),
57
- );
58
-
59
- for (let i = 1; i < g.given.length; i++) {
60
- const givenEvent = g.given[i];
61
- const typeInfo = messages ? getFieldTypeInfo(messages, givenEvent.eventRef) : undefined;
62
- statements.push(
63
- f.createExpressionStatement(
64
- f.createCallExpression(
65
- f.createIdentifier('and'),
66
- [f.createTypeReferenceNode(givenEvent.eventRef, undefined)],
67
- [jsonToExpr(ts, f, givenEvent.exampleData, typeInfo)],
68
- ),
69
- ),
70
- );
71
- }
44
+ ): tsNS.Expression {
45
+ if (!hasGivenEvents(g) || g.given === null || g.given === undefined || g.given.length === 0) {
46
+ return base;
72
47
  }
73
48
 
74
- return statements;
75
- }
49
+ const firstGiven = g.given[0];
50
+ const firstTypeInfo = messages ? getFieldTypeInfo(messages, firstGiven.eventRef) : undefined;
76
51
 
77
- function createWhenCallExpression(
78
- ts: typeof import('typescript'),
79
- f: tsNS.NodeFactory,
80
- typeRef: string,
81
- exampleData: Record<string, unknown>,
82
- messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
83
- ): tsNS.Statement {
84
- const typeInfo = messages !== undefined ? getFieldTypeInfo(messages, typeRef) : undefined;
85
- return f.createExpressionStatement(
86
- f.createCallExpression(
87
- f.createIdentifier('when'),
88
- typeRef !== '' ? [f.createTypeReferenceNode(typeRef, undefined)] : undefined,
89
- [jsonToExpr(ts, f, exampleData, typeInfo)],
90
- ),
52
+ let result = f.createCallExpression(
53
+ f.createPropertyAccessExpression(base, f.createIdentifier('given')),
54
+ [f.createTypeReferenceNode(firstGiven.eventRef, undefined)],
55
+ [jsonToExpr(ts, f, firstGiven.exampleData, firstTypeInfo)],
91
56
  );
92
- }
93
57
 
94
- function buildCommandWhenStatement(
95
- ts: typeof import('typescript'),
96
- f: tsNS.NodeFactory,
97
- when: { commandRef: string; exampleData: Record<string, unknown> },
98
- messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
99
- ): tsNS.Statement {
100
- return createWhenCallExpression(ts, f, when.commandRef, when.exampleData, messages);
101
- }
58
+ for (let i = 1; i < g.given.length; i++) {
59
+ const givenEvent = g.given[i];
60
+ const typeInfo = messages ? getFieldTypeInfo(messages, givenEvent.eventRef) : undefined;
61
+ result = f.createCallExpression(
62
+ f.createPropertyAccessExpression(result, f.createIdentifier('and')),
63
+ [f.createTypeReferenceNode(givenEvent.eventRef, undefined)],
64
+ [jsonToExpr(ts, f, givenEvent.exampleData, typeInfo)],
65
+ );
66
+ }
102
67
 
103
- function buildEventWhenStatement(
104
- ts: typeof import('typescript'),
105
- f: tsNS.NodeFactory,
106
- event: { eventRef: string; exampleData: Record<string, unknown> },
107
- messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
108
- ): tsNS.Statement {
109
- return createWhenCallExpression(ts, f, event.eventRef, event.exampleData, messages);
68
+ return result;
110
69
  }
111
70
 
112
71
  function isQueryWithSingleEvent(
@@ -120,43 +79,59 @@ function isReactOrQueryWithEvents(sliceKind: string): boolean {
120
79
  return sliceKind === 'react' || sliceKind === 'query';
121
80
  }
122
81
 
123
- function buildStandaloneWhenStatement(
82
+ function chainWhenCall(
124
83
  ts: typeof import('typescript'),
125
84
  f: tsNS.NodeFactory,
85
+ base: tsNS.Expression,
126
86
  g: GWTBlock,
127
87
  sliceKind: 'command' | 'react' | 'query' | 'experience',
128
88
  messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
129
- ): tsNS.Statement | null {
89
+ ): tsNS.Expression {
130
90
  if (isEmptyWhen(g.when)) {
131
- return null;
91
+ return base;
132
92
  }
133
93
 
134
94
  const when = g.when;
95
+ let typeRef = '';
96
+ let exampleData: Record<string, unknown> = {};
97
+
135
98
  if (sliceKind === 'command' && isWhenCommand(when)) {
136
- return buildCommandWhenStatement(ts, f, when, messages);
137
- }
138
- if (isReactOrQueryWithEvents(sliceKind) && isWhenEvents(when) && when.length > 0) {
139
- return buildEventWhenStatement(ts, f, when[0], messages);
140
- }
141
- if (isQueryWithSingleEvent(sliceKind, when)) {
142
- return buildEventWhenStatement(ts, f, when, messages);
99
+ typeRef = when.commandRef;
100
+ exampleData = when.exampleData;
101
+ } else if (isReactOrQueryWithEvents(sliceKind) && isWhenEvents(when) && when.length > 0) {
102
+ typeRef = when[0].eventRef;
103
+ exampleData = when[0].exampleData;
104
+ } else if (isQueryWithSingleEvent(sliceKind, when)) {
105
+ typeRef = when.eventRef;
106
+ exampleData = when.exampleData;
107
+ } else {
108
+ return base;
143
109
  }
144
- return null;
110
+
111
+ const typeInfo = messages !== undefined ? getFieldTypeInfo(messages, typeRef) : undefined;
112
+ return f.createCallExpression(
113
+ f.createPropertyAccessExpression(base, f.createIdentifier('when')),
114
+ typeRef !== '' ? [f.createTypeReferenceNode(typeRef, undefined)] : undefined,
115
+ [jsonToExpr(ts, f, exampleData, typeInfo)],
116
+ );
145
117
  }
146
118
 
147
- function buildStandaloneThenStatement(
119
+ function chainThenCall(
148
120
  ts: typeof import('typescript'),
149
121
  f: tsNS.NodeFactory,
122
+ base: tsNS.Expression,
150
123
  g: GWTBlock,
151
124
  messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
152
- ): tsNS.Statement {
125
+ ): tsNS.Expression {
153
126
  const firstThenItem = g.then[0];
154
127
  const thenTypeRef = getThenTypeRef(firstThenItem);
155
128
  const typeInfo = messages && thenTypeRef ? getFieldTypeInfo(messages, thenTypeRef) : undefined;
156
129
  const thenArg = buildThenItem(ts, f, firstThenItem, typeInfo);
157
130
  const thenTypeParams = thenTypeRef ? [f.createTypeReferenceNode(thenTypeRef, undefined)] : undefined;
158
131
 
159
- return f.createExpressionStatement(f.createCallExpression(f.createIdentifier('then'), thenTypeParams, [thenArg]));
132
+ return f.createCallExpression(f.createPropertyAccessExpression(base, f.createIdentifier('then')), thenTypeParams, [
133
+ thenArg,
134
+ ]);
160
135
  }
161
136
 
162
137
  function buildThenItem(
@@ -257,6 +232,28 @@ function getThenTypeRef(firstThenItem: GWTBlock['then'][0]): string {
257
232
  return '';
258
233
  }
259
234
 
235
+ function buildExampleChain(
236
+ ts: typeof import('typescript'),
237
+ f: tsNS.NodeFactory,
238
+ g: GWTBlock & { description?: string; exampleDescription?: string },
239
+ sliceKind: 'command' | 'react' | 'query' | 'experience',
240
+ messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
241
+ ): tsNS.Expression {
242
+ const { exampleDesc } = getDescriptions(
243
+ g as GWTBlock & { description?: string; ruleDescription?: string; exampleDescription?: string },
244
+ );
245
+
246
+ let chain: tsNS.Expression = f.createCallExpression(f.createIdentifier('example'), undefined, [
247
+ f.createStringLiteral(exampleDesc),
248
+ ]);
249
+
250
+ chain = chainGivenCalls(ts, f, chain, g, messages);
251
+ chain = chainWhenCall(ts, f, chain, g, sliceKind, messages);
252
+ chain = chainThenCall(ts, f, chain, g, messages);
253
+
254
+ return chain;
255
+ }
256
+
260
257
  export function buildGwtSpecBlock(
261
258
  ts: typeof import('typescript'),
262
259
  f: tsNS.NodeFactory,
@@ -264,27 +261,9 @@ export function buildGwtSpecBlock(
264
261
  sliceKind: 'command' | 'react' | 'query' | 'experience',
265
262
  messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
266
263
  ): tsNS.Statement {
267
- const { ruleDesc, exampleDesc } = getDescriptions(g);
268
-
269
- const bodyStatements: tsNS.Statement[] = [];
270
- bodyStatements.push(...buildStandaloneGivenStatements(ts, f, g, messages));
271
- const whenStmt = buildStandaloneWhenStatement(ts, f, g, sliceKind, messages);
272
- if (whenStmt) {
273
- bodyStatements.push(whenStmt);
274
- }
275
- bodyStatements.push(buildStandaloneThenStatement(ts, f, g, messages));
264
+ const { ruleDesc } = getDescriptions(g);
276
265
 
277
- const exampleCall = f.createCallExpression(f.createIdentifier('example'), undefined, [
278
- f.createStringLiteral(exampleDesc),
279
- f.createArrowFunction(
280
- undefined,
281
- undefined,
282
- [],
283
- undefined,
284
- f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
285
- f.createBlock(bodyStatements, true),
286
- ),
287
- ]);
266
+ const exampleChain = buildExampleChain(ts, f, g, sliceKind, messages);
288
267
 
289
268
  const ruleArgs: tsNS.Expression[] = [f.createStringLiteral(ruleDesc)];
290
269
 
@@ -299,7 +278,7 @@ export function buildGwtSpecBlock(
299
278
  [],
300
279
  undefined,
301
280
  f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
302
- f.createBlock([f.createExpressionStatement(exampleCall)], true),
281
+ f.createBlock([f.createExpressionStatement(exampleChain)], true),
303
282
  ),
304
283
  );
305
284
 
@@ -340,29 +319,8 @@ export function buildConsolidatedGwtSpecBlock(
340
319
  const exampleStatements: tsNS.Statement[] = [];
341
320
 
342
321
  for (const g of gwtBlocks) {
343
- const { exampleDesc } = getDescriptions(g);
344
-
345
- const bodyStatements: tsNS.Statement[] = [];
346
- bodyStatements.push(...buildStandaloneGivenStatements(ts, f, g, messages));
347
- const whenStmt = buildStandaloneWhenStatement(ts, f, g, sliceKind, messages);
348
- if (whenStmt) {
349
- bodyStatements.push(whenStmt);
350
- }
351
- bodyStatements.push(buildStandaloneThenStatement(ts, f, g, messages));
352
-
353
- const exampleCall = f.createCallExpression(f.createIdentifier('example'), undefined, [
354
- f.createStringLiteral(exampleDesc),
355
- f.createArrowFunction(
356
- undefined,
357
- undefined,
358
- [],
359
- undefined,
360
- f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
361
- f.createBlock(bodyStatements, true),
362
- ),
363
- ]);
364
-
365
- exampleStatements.push(f.createExpressionStatement(exampleCall));
322
+ const exampleChain = buildExampleChain(ts, f, g, sliceKind, messages);
323
+ exampleStatements.push(f.createExpressionStatement(exampleChain));
366
324
  }
367
325
 
368
326
  const ruleArgs: tsNS.Expression[] = [f.createStringLiteral(rule.description)];
@@ -1,13 +1,11 @@
1
1
  type BuildImportsOpts = { flowImport: string; integrationImport: string };
2
2
 
3
3
  export const ALL_FLOW_FUNCTION_NAMES = [
4
- 'and',
5
4
  'command',
6
5
  'data',
7
6
  'describe',
8
7
  'example',
9
8
  'experience',
10
- 'given',
11
9
  'gql',
12
10
  'it',
13
11
  'narrative',
@@ -17,8 +15,6 @@ export const ALL_FLOW_FUNCTION_NAMES = [
17
15
  'sink',
18
16
  'source',
19
17
  'specs',
20
- 'then',
21
- 'when',
22
18
  ] as const;
23
19
 
24
20
  export function buildImports(
@@ -1,4 +1,4 @@
1
- import tsNS from 'typescript';
1
+ import type tsNS from 'typescript';
2
2
  import { typeFromString } from '../ast/emit-helpers';
3
3
 
4
4
  type Message = {
@@ -1,6 +1,6 @@
1
- import { generateTypeScriptCode } from './generators/compose';
1
+ import type { Model } from '../../index';
2
2
  import { formatWithPrettier } from './formatting/prettier';
3
- import { Model } from '../../index';
3
+ import { generateTypeScriptCode } from './generators/compose';
4
4
 
5
5
  /**
6
6
  * Converts a schema specification to TypeScript flow DSL code.
@@ -1,4 +1,4 @@
1
- import { Narrative, Model } from '../../index';
1
+ import type { Model, Narrative } from '../../index';
2
2
 
3
3
  export function assembleSpecs(narratives: Narrative[], messages: unknown[], integrations: unknown[]): Model {
4
4
  return {
@@ -1,4 +1,4 @@
1
- import { Message } from '../../index';
1
+ import type { Message } from '../../index';
2
2
 
3
3
  export type ExampleShapeHints = Map<
4
4
  string, // message name, e.g. "Products"
@@ -1,14 +1,14 @@
1
- import { Narrative, Message, Model, Slice } from '../../index';
2
- import { globalIntegrationRegistry } from '../../integration-registry';
1
+ import type { Message, Model, Narrative, Slice } from '../../index';
3
2
  import { integrationExportRegistry } from '../../integration-export-registry';
4
- import { TypeInfo } from '../../loader/ts-utils';
5
- import { resolveInferredType } from './type-inference';
3
+ import { globalIntegrationRegistry } from '../../integration-registry';
4
+ import type { TypeInfo } from '../../loader/ts-utils';
5
+ import { assembleSpecs } from './assemble';
6
+ import { applyExampleShapeHints, type ExampleShapeHints } from './example-shapes';
6
7
  import { inlineAllMessageFieldTypes } from './inlining';
7
- import { ExampleShapeHints, applyExampleShapeHints } from './example-shapes';
8
8
  import { extractMessagesFromIntegrations, processDataItemIntegrations } from './integrations';
9
+ import { processGiven, processThen, processWhen } from './spec-processors';
9
10
  import { matchesNarrativePattern } from './strings';
10
- import { assembleSpecs } from './assemble';
11
- import { processGiven, processWhen, processThen } from './spec-processors';
11
+ import { resolveInferredType } from './type-inference';
12
12
 
13
13
  type TypeResolver = (
14
14
  t: string,
@@ -1,5 +1,5 @@
1
- import { TypeInfo } from '../../loader/ts-utils';
2
- import { Message } from '../../index';
1
+ import type { Message } from '../../index';
2
+ import type { TypeInfo } from '../../loader/ts-utils';
3
3
 
4
4
  function inlineIdentifier(name: string, lookup: Map<string, TypeInfo>, seen = new Set<string>()): string | undefined {
5
5
  // avoid infinite recursion on cyclical type graphs
@@ -1,10 +1,10 @@
1
- import { Integration } from '../../types';
2
- import { Message } from '../../index';
3
- import { zodSchemaToFields } from './zod-adapter';
1
+ import type { Message } from '../../index';
2
+ import { integrationExportRegistry } from '../../integration-export-registry';
3
+ import type { Integration } from '../../types';
4
4
  import { debugIntegrations } from './debug';
5
5
  import { hasDestination, hasOrigin, hasWithState, isValidIntegration } from './guards';
6
6
  import { processDestinationMessage } from './messages';
7
- import { integrationExportRegistry } from '../../integration-export-registry';
7
+ import { zodSchemaToFields } from './zod-adapter';
8
8
 
9
9
  const integrationImportPaths = new Map<string, string>();
10
10
 
@@ -103,7 +103,7 @@ function flattenStateEnvelope(fields: Message['fields']): Message['fields'] {
103
103
  if (dataIdx !== -1) {
104
104
  const src = fields[dataIdx].type; // "{ a: T, b?: U }" or "{ a: T; b?: U }"
105
105
  const bodyMatch = src.match(/^\{\s*([^}]*)\s*\}$/);
106
- if (bodyMatch && bodyMatch[1]) {
106
+ if (bodyMatch?.[1]) {
107
107
  const body = bodyMatch[1];
108
108
  const inner: { name: string; type: string; required: boolean }[] = [];
109
109
  // support comma OR semicolon separators
@@ -1,5 +1,5 @@
1
- import { TypeInfo } from '../../loader/ts-utils';
2
- import { Message } from '../../index';
1
+ import type { Message } from '../../index';
2
+ import type { TypeInfo } from '../../loader/ts-utils';
3
3
 
4
4
  function mapKindToMessageType(k: 'command' | 'query' | 'reaction'): 'command' | 'event' | 'state' {
5
5
  if (k === 'command') return 'command';
@@ -20,7 +20,7 @@ function buildInitialFields(typeInfo: TypeInfo | undefined) {
20
20
  function parseEnvelopeFields(src: string) {
21
21
  const inner: { name: string; type: string; required: boolean }[] = [];
22
22
  const m = src.match(/^\{\s*([^}]*)\s*\}$/);
23
- if (m && m[1]) {
23
+ if (m?.[1]) {
24
24
  const body = m[1];
25
25
  const re = /(\w+)(\?)?\s*:\s*([^;,]+)(?=[;,]|$)/g;
26
26
  let match: RegExpExecArray | null;
@@ -1,4 +1,4 @@
1
- import { Message } from '../../index';
1
+ import type { Message } from '../../index';
2
2
 
3
3
  function hasEnvelope(fields: { name: string }[] = []): boolean {
4
4
  const names = new Set(fields.map((f) => f.name));
@@ -1,9 +1,9 @@
1
- import { TypeInfo } from '../../loader/ts-utils';
2
- import { Message } from '../../index';
1
+ import debug from 'debug';
2
+ import type { Message } from '../../index';
3
+ import type { TypeInfo } from '../../loader/ts-utils';
4
+ import { collectExampleHintsForData, type ExampleShapeHints } from './example-shapes';
3
5
  import { createMessage } from './messages';
4
6
  import { preferNewFields } from './normalize';
5
- import { ExampleShapeHints, collectExampleHintsForData } from './example-shapes';
6
- import debug from 'debug';
7
7
 
8
8
  const log = debug('auto:flow:spec-processors');
9
9
 
@@ -1,6 +1,6 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { narrativesToModel } from './index';
1
+ import { describe, expect, it } from 'vitest';
3
2
  import type { Narrative } from '../../index';
3
+ import { narrativesToModel } from './index';
4
4
 
5
5
  describe('Type inference in narrative-to-model transformer', () => {
6
6
  it('should correctly extract command types from when clauses', () => {
@@ -1,4 +1,4 @@
1
- import { TypeInfo } from '../../loader/ts-utils';
1
+ import type { TypeInfo } from '../../loader/ts-utils';
2
2
 
3
3
  function tryDataFieldMatch(typeInfo: TypeInfo, dataKeys: Set<string>): boolean {
4
4
  const dataField = typeInfo.dataFields?.find((f) => f.name === 'data');
@@ -9,7 +9,7 @@ function tryDataFieldMatch(typeInfo: TypeInfo, dataKeys: Set<string>): boolean {
9
9
  dataField.type.endsWith('}')
10
10
  ) {
11
11
  const bodyMatch = dataField.type.match(/^\{\s*([^}]*)\s*\}$/);
12
- if (bodyMatch && bodyMatch[1]) {
12
+ if (bodyMatch?.[1]) {
13
13
  const body = bodyMatch[1];
14
14
  const innerKeys = new Set<string>();
15
15
  const re = /(\w+)(\?)?\s*:\s*([^;,]+)(?=[;,]|$)/g;
@@ -1,5 +1,5 @@
1
- import { z } from 'zod';
2
- import { Message } from '../../index';
1
+ import type { z } from 'zod';
2
+ import type { Message } from '../../index';
3
3
 
4
4
  function hasZodDef(obj: unknown): obj is { _def: unknown } {
5
5
  return typeof obj === 'object' && obj !== null && '_def' in obj;
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ZodTypeAny } from 'zod';
1
+ import type { ZodTypeAny } from 'zod';
2
2
 
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
4
  type IntegrationHandler = (...args: any[]) => Promise<any>;
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=export-schema-runner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export-schema-runner.d.ts","sourceRoot":"","sources":["../../../src/commands/export-schema-runner.ts"],"names":[],"mappings":""}
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env node
2
- // This runner is executed in the target directory context to avoid module resolution issues
3
- import { resolve } from 'path';
4
- import { writeFileSync, mkdirSync } from 'fs';
5
- import createDebug from 'debug';
6
- import { NodeFileStore } from '@auto-engineer/file-store/node';
7
- const debug = createDebug('auto:narrative:export-schema-runner');
8
- if ('color' in debug && typeof debug === 'object') {
9
- debug.color = '4';
10
- } // blue
11
- const main = async () => {
12
- const contextDir = process.argv[2] || './.context';
13
- const narrativesDir = process.argv[3] || './narratives';
14
- debug('Starting export-schema-runner');
15
- debug(' Context dir: %s', contextDir);
16
- debug(' Flows dir: %s', narrativesDir);
17
- try {
18
- // Import from the installed package in the target directory
19
- // This ensures we use the same module instance as the flow files
20
- const narrative = (await import('@auto-engineer/narrative'));
21
- const { getNarratives } = narrative;
22
- if (typeof getNarratives !== 'function') {
23
- throw new Error('getNarratives not found in @auto-engineer/narrative exports');
24
- }
25
- const narrativesPath = resolve(process.cwd(), narrativesDir);
26
- debug('Resolved narratives path: %s', narrativesPath);
27
- const result = await getNarratives({ vfs: new NodeFileStore(), root: narrativesPath });
28
- const schema = result.toModel();
29
- debug('Schema generated with %d narratives, %d messages, %d integrations', schema.narratives.length, schema.messages.length, schema.integrations?.length ?? 0);
30
- const json = JSON.stringify(schema, null, 2);
31
- const resolvedContextDir = resolve(process.cwd(), contextDir);
32
- const outPath = resolve(resolvedContextDir, 'schema.json');
33
- mkdirSync(resolvedContextDir, { recursive: true });
34
- writeFileSync(outPath, json);
35
- debug('Schema written to: %s', outPath);
36
- // Output success as JSON for parent process
37
- console.log(JSON.stringify({
38
- success: true,
39
- outputPath: outPath,
40
- }));
41
- }
42
- catch (error) {
43
- debug('Error occurred: %o', error);
44
- // Output error as JSON for parent process
45
- console.log(JSON.stringify({
46
- success: false,
47
- error: error instanceof Error ? error.message : 'Unknown error occurred',
48
- }));
49
- process.exit(1);
50
- }
51
- };
52
- void main();
53
- //# sourceMappingURL=export-schema-runner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export-schema-runner.js","sourceRoot":"","sources":["../../../src/commands/export-schema-runner.ts"],"names":[],"mappings":"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"}
package/eslint.config.ts DELETED
@@ -1,12 +0,0 @@
1
- import rootConfig from '../../eslint.config.ts';
2
- import tseslint from 'typescript-eslint';
3
-
4
- export default tseslint.config(...rootConfig, {
5
- ignores: ['eslint.config.ts', 'bin/**/*'],
6
- languageOptions: {
7
- parserOptions: {
8
- project: ['./tsconfig.json', './tsconfig.test.json'],
9
- tsconfigRootDir: import.meta.dirname,
10
- },
11
- },
12
- });
@@ -1,74 +0,0 @@
1
- #!/usr/bin/env node
2
- // This runner is executed in the target directory context to avoid module resolution issues
3
- import { resolve } from 'path';
4
- import { writeFileSync, mkdirSync } from 'fs';
5
- import createDebug from 'debug';
6
- import { NodeFileStore } from '@auto-engineer/file-store/node';
7
-
8
- const debug = createDebug('auto:narrative:export-schema-runner');
9
- if ('color' in debug && typeof debug === 'object') {
10
- (debug as { color: string }).color = '4';
11
- } // blue
12
-
13
- const main = async () => {
14
- const contextDir = process.argv[2] || './.context';
15
- const narrativesDir = process.argv[3] || './narratives';
16
-
17
- debug('Starting export-schema-runner');
18
- debug(' Context dir: %s', contextDir);
19
- debug(' Flows dir: %s', narrativesDir);
20
-
21
- try {
22
- // Import from the installed package in the target directory
23
- // This ensures we use the same module instance as the flow files
24
- const narrative = (await import('@auto-engineer/narrative')) as {
25
- getNarratives: typeof import('../getNarratives').getNarratives;
26
- };
27
- const { getNarratives } = narrative;
28
-
29
- if (typeof getNarratives !== 'function') {
30
- throw new Error('getNarratives not found in @auto-engineer/narrative exports');
31
- }
32
-
33
- const narrativesPath = resolve(process.cwd(), narrativesDir);
34
- debug('Resolved narratives path: %s', narrativesPath);
35
-
36
- const result = await getNarratives({ vfs: new NodeFileStore(), root: narrativesPath });
37
- const schema = result.toModel();
38
- debug(
39
- 'Schema generated with %d narratives, %d messages, %d integrations',
40
- schema.narratives.length,
41
- schema.messages.length,
42
- schema.integrations?.length ?? 0,
43
- );
44
-
45
- const json = JSON.stringify(schema, null, 2);
46
- const resolvedContextDir = resolve(process.cwd(), contextDir);
47
- const outPath = resolve(resolvedContextDir, 'schema.json');
48
-
49
- mkdirSync(resolvedContextDir, { recursive: true });
50
- writeFileSync(outPath, json);
51
- debug('Schema written to: %s', outPath);
52
-
53
- // Output success as JSON for parent process
54
- console.log(
55
- JSON.stringify({
56
- success: true,
57
- outputPath: outPath,
58
- }),
59
- );
60
- } catch (error) {
61
- debug('Error occurred: %o', error);
62
-
63
- // Output error as JSON for parent process
64
- console.log(
65
- JSON.stringify({
66
- success: false,
67
- error: error instanceof Error ? error.message : 'Unknown error occurred',
68
- }),
69
- );
70
- process.exit(1);
71
- }
72
- };
73
-
74
- void main();