@auto-engineer/server-generator-apollo-emmett 0.1.1

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 (272) hide show
  1. package/.tmp/server-test-output/server/package.json +26 -0
  2. package/.tmp/server-test-output/server/scripts/generate-schema.ts +31 -0
  3. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/commands.ts +8 -0
  4. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/decide.specs.ts +36 -0
  5. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/decide.ts +33 -0
  6. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/events.ts +10 -0
  7. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/evolve.ts +28 -0
  8. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/handle.ts +24 -0
  9. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/mutation.resolver.ts +25 -0
  10. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/register.ts +7 -0
  11. package/.tmp/server-test-output/server/src/domain/flows/add-item/create-item/state.ts +47 -0
  12. package/.tmp/server-test-output/server/src/domain/flows/add-item/get-available-items/projection.specs.ts +46 -0
  13. package/.tmp/server-test-output/server/src/domain/flows/add-item/get-available-items/projection.ts +38 -0
  14. package/.tmp/server-test-output/server/src/domain/flows/add-item/get-available-items/query.resolver.ts +39 -0
  15. package/.tmp/server-test-output/server/src/domain/flows/add-item/get-available-items/state.ts +5 -0
  16. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/commands.ts +8 -0
  17. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/decide.specs.ts +36 -0
  18. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/decide.ts +33 -0
  19. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/events.ts +3 -0
  20. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/evolve.ts +28 -0
  21. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/handle.ts +24 -0
  22. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/mutation.resolver.ts +25 -0
  23. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/register.ts +7 -0
  24. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-new-item/state.ts +47 -0
  25. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-on-new-item/react.specs.ts +49 -0
  26. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-on-new-item/react.ts +43 -0
  27. package/.tmp/server-test-output/server/src/domain/flows/add-item/notify-on-new-item/register.ts +24 -0
  28. package/.tmp/server-test-output/server/src/domain/shared/ReadModel.ts +26 -0
  29. package/.tmp/server-test-output/server/src/domain/shared/index.ts +4 -0
  30. package/.tmp/server-test-output/server/src/domain/shared/reactorSpecification.ts +257 -0
  31. package/.tmp/server-test-output/server/src/domain/shared/sendCommand.ts +21 -0
  32. package/.tmp/server-test-output/server/src/domain/shared/types.ts +31 -0
  33. package/.tmp/server-test-output/server/src/server.ts +43 -0
  34. package/.tmp/server-test-output/server/src/utils/index.ts +3 -0
  35. package/.tmp/server-test-output/server/src/utils/loadProjections.ts +30 -0
  36. package/.tmp/server-test-output/server/src/utils/loadRegisterFiles.ts +41 -0
  37. package/.tmp/server-test-output/server/src/utils/loadResolvers.ts +36 -0
  38. package/.tmp/server-test-output/server/tsconfig.json +19 -0
  39. package/.tmp/server-test-output/server/vitest.config.ts +7 -0
  40. package/.turbo/turbo-build.log +5 -0
  41. package/.turbo/turbo-format.log +57 -0
  42. package/.turbo/turbo-lint.log +5 -0
  43. package/.turbo/turbo-test.log +113 -0
  44. package/.turbo/turbo-type-check.log +4 -0
  45. package/CHANGELOG.md +141 -0
  46. package/DEBUG.md +177 -0
  47. package/LICENSE +10 -0
  48. package/README.md +185 -0
  49. package/dist/cli-manifest.d.ts +3 -0
  50. package/dist/cli-manifest.d.ts.map +1 -0
  51. package/dist/cli-manifest.js +8 -0
  52. package/dist/cli-manifest.js.map +1 -0
  53. package/dist/codegen/extract/commands.d.ts +19 -0
  54. package/dist/codegen/extract/commands.d.ts.map +1 -0
  55. package/dist/codegen/extract/commands.js +52 -0
  56. package/dist/codegen/extract/commands.js.map +1 -0
  57. package/dist/codegen/extract/data-sink.d.ts +6 -0
  58. package/dist/codegen/extract/data-sink.d.ts.map +1 -0
  59. package/dist/codegen/extract/data-sink.js +39 -0
  60. package/dist/codegen/extract/data-sink.js.map +1 -0
  61. package/dist/codegen/extract/events.d.ts +10 -0
  62. package/dist/codegen/extract/events.d.ts.map +1 -0
  63. package/dist/codegen/extract/events.js +32 -0
  64. package/dist/codegen/extract/events.js.map +1 -0
  65. package/dist/codegen/extract/fields.d.ts +3 -0
  66. package/dist/codegen/extract/fields.d.ts.map +1 -0
  67. package/dist/codegen/extract/fields.js +9 -0
  68. package/dist/codegen/extract/fields.js.map +1 -0
  69. package/dist/codegen/extract/graphql.d.ts +14 -0
  70. package/dist/codegen/extract/graphql.d.ts.map +1 -0
  71. package/dist/codegen/extract/graphql.js +81 -0
  72. package/dist/codegen/extract/graphql.js.map +1 -0
  73. package/dist/codegen/extract/gwt.d.ts +6 -0
  74. package/dist/codegen/extract/gwt.d.ts.map +1 -0
  75. package/dist/codegen/extract/gwt.js +61 -0
  76. package/dist/codegen/extract/gwt.js.map +1 -0
  77. package/dist/codegen/extract/index.d.ts +8 -0
  78. package/dist/codegen/extract/index.d.ts.map +1 -0
  79. package/dist/codegen/extract/index.js +8 -0
  80. package/dist/codegen/extract/index.js.map +1 -0
  81. package/dist/codegen/extract/messages.d.ts +24 -0
  82. package/dist/codegen/extract/messages.d.ts.map +1 -0
  83. package/dist/codegen/extract/messages.js +131 -0
  84. package/dist/codegen/extract/messages.js.map +1 -0
  85. package/dist/codegen/extract/projection.d.ts +4 -0
  86. package/dist/codegen/extract/projection.d.ts.map +1 -0
  87. package/dist/codegen/extract/projection.js +30 -0
  88. package/dist/codegen/extract/projection.js.map +1 -0
  89. package/dist/codegen/extract/query.d.ts +11 -0
  90. package/dist/codegen/extract/query.d.ts.map +1 -0
  91. package/dist/codegen/extract/query.js +11 -0
  92. package/dist/codegen/extract/query.js.map +1 -0
  93. package/dist/codegen/extract/states.d.ts +5 -0
  94. package/dist/codegen/extract/states.d.ts.map +1 -0
  95. package/dist/codegen/extract/states.js +35 -0
  96. package/dist/codegen/extract/states.js.map +1 -0
  97. package/dist/codegen/scaffoldFromSchema.d.ts +9 -0
  98. package/dist/codegen/scaffoldFromSchema.d.ts.map +1 -0
  99. package/dist/codegen/scaffoldFromSchema.integration.specs.d.ts +2 -0
  100. package/dist/codegen/scaffoldFromSchema.integration.specs.d.ts.map +1 -0
  101. package/dist/codegen/scaffoldFromSchema.integration.specs.js +59 -0
  102. package/dist/codegen/scaffoldFromSchema.integration.specs.js.map +1 -0
  103. package/dist/codegen/scaffoldFromSchema.js +326 -0
  104. package/dist/codegen/scaffoldFromSchema.js.map +1 -0
  105. package/dist/codegen/templates/command/commands.specs.ts +90 -0
  106. package/dist/codegen/templates/command/commands.ts.ejs +11 -0
  107. package/dist/codegen/templates/command/decide.specs.specs.ts +265 -0
  108. package/dist/codegen/templates/command/decide.specs.ts +542 -0
  109. package/dist/codegen/templates/command/decide.specs.ts.ejs +51 -0
  110. package/dist/codegen/templates/command/decide.ts.ejs +107 -0
  111. package/dist/codegen/templates/command/events.specs.ts +106 -0
  112. package/dist/codegen/templates/command/events.ts.ejs +14 -0
  113. package/dist/codegen/templates/command/evolve.specs.ts +102 -0
  114. package/dist/codegen/templates/command/evolve.ts.ejs +39 -0
  115. package/dist/codegen/templates/command/handle.specs.ts +313 -0
  116. package/dist/codegen/templates/command/handle.ts.ejs +111 -0
  117. package/dist/codegen/templates/command/mutation.resolver.specs.ts +115 -0
  118. package/dist/codegen/templates/command/mutation.resolver.ts.ejs +25 -0
  119. package/dist/codegen/templates/command/register.specs.ts +107 -0
  120. package/dist/codegen/templates/command/register.ts.ejs +12 -0
  121. package/dist/codegen/templates/command/state.specs.ts +127 -0
  122. package/dist/codegen/templates/command/state.ts.ejs +47 -0
  123. package/dist/codegen/templates/query/projection.specs.specs..ts +276 -0
  124. package/dist/codegen/templates/query/projection.specs.ts +348 -0
  125. package/dist/codegen/templates/query/projection.specs.ts.ejs +71 -0
  126. package/dist/codegen/templates/query/projection.ts.ejs +121 -0
  127. package/dist/codegen/templates/query/query.resolver.specs.ts +254 -0
  128. package/dist/codegen/templates/query/query.resolver.ts.ejs +98 -0
  129. package/dist/codegen/templates/query/state.specs.ts +70 -0
  130. package/dist/codegen/templates/query/state.ts.ejs +7 -0
  131. package/dist/codegen/templates/react/react.specs.specs.ts +214 -0
  132. package/dist/codegen/templates/react/react.specs.ts +241 -0
  133. package/dist/codegen/templates/react/react.specs.ts.ejs +80 -0
  134. package/dist/codegen/templates/react/react.ts.ejs +56 -0
  135. package/dist/codegen/templates/react/register.specs.ts +222 -0
  136. package/dist/codegen/templates/react/register.ts.ejs +39 -0
  137. package/dist/codegen/test-data/specVariant1.d.ts +4 -0
  138. package/dist/codegen/test-data/specVariant1.d.ts.map +1 -0
  139. package/dist/codegen/test-data/specVariant1.js +185 -0
  140. package/dist/codegen/test-data/specVariant1.js.map +1 -0
  141. package/dist/codegen/types.d.ts +35 -0
  142. package/dist/codegen/types.d.ts.map +1 -0
  143. package/dist/codegen/types.js +2 -0
  144. package/dist/codegen/types.js.map +1 -0
  145. package/dist/codegen/utils/path.d.ts +4 -0
  146. package/dist/codegen/utils/path.d.ts.map +1 -0
  147. package/dist/codegen/utils/path.js +18 -0
  148. package/dist/codegen/utils/path.js.map +1 -0
  149. package/dist/commands/generate-server.d.ts +81 -0
  150. package/dist/commands/generate-server.d.ts.map +1 -0
  151. package/dist/commands/generate-server.js +383 -0
  152. package/dist/commands/generate-server.js.map +1 -0
  153. package/dist/domain/shared/ReadModel.d.ts +10 -0
  154. package/dist/domain/shared/ReadModel.d.ts.map +1 -0
  155. package/dist/domain/shared/ReadModel.js +19 -0
  156. package/dist/domain/shared/ReadModel.js.map +1 -0
  157. package/dist/domain/shared/ReadModel.ts +26 -0
  158. package/dist/domain/shared/index.d.ts +5 -0
  159. package/dist/domain/shared/index.d.ts.map +1 -0
  160. package/dist/domain/shared/index.js +5 -0
  161. package/dist/domain/shared/index.js.map +1 -0
  162. package/dist/domain/shared/index.ts +4 -0
  163. package/dist/domain/shared/reactorSpecification.d.ts +35 -0
  164. package/dist/domain/shared/reactorSpecification.d.ts.map +1 -0
  165. package/dist/domain/shared/reactorSpecification.js +155 -0
  166. package/dist/domain/shared/reactorSpecification.js.map +1 -0
  167. package/dist/domain/shared/reactorSpecification.ts +257 -0
  168. package/dist/domain/shared/sendCommand.d.ts +4 -0
  169. package/dist/domain/shared/sendCommand.d.ts.map +1 -0
  170. package/dist/domain/shared/sendCommand.js +17 -0
  171. package/dist/domain/shared/sendCommand.js.map +1 -0
  172. package/dist/domain/shared/sendCommand.ts +21 -0
  173. package/dist/domain/shared/types.d.ts +19 -0
  174. package/dist/domain/shared/types.d.ts.map +1 -0
  175. package/dist/domain/shared/types.js +39 -0
  176. package/dist/domain/shared/types.js.map +1 -0
  177. package/dist/domain/shared/types.ts +31 -0
  178. package/dist/index.d.ts +3 -0
  179. package/dist/index.d.ts.map +1 -0
  180. package/dist/index.js +3 -0
  181. package/dist/index.js.map +1 -0
  182. package/dist/server.d.ts +2 -0
  183. package/dist/server.d.ts.map +1 -0
  184. package/dist/server.js +33 -0
  185. package/dist/server.js.map +1 -0
  186. package/dist/server.ts +43 -0
  187. package/dist/utils/index.d.ts +4 -0
  188. package/dist/utils/index.d.ts.map +1 -0
  189. package/dist/utils/index.js +4 -0
  190. package/dist/utils/index.js.map +1 -0
  191. package/dist/utils/index.ts +3 -0
  192. package/dist/utils/loadProjections.d.ts +3 -0
  193. package/dist/utils/loadProjections.d.ts.map +1 -0
  194. package/dist/utils/loadProjections.js +23 -0
  195. package/dist/utils/loadProjections.js.map +1 -0
  196. package/dist/utils/loadProjections.ts +30 -0
  197. package/dist/utils/loadRegisterFiles.d.ts +6 -0
  198. package/dist/utils/loadRegisterFiles.d.ts.map +1 -0
  199. package/dist/utils/loadRegisterFiles.js +28 -0
  200. package/dist/utils/loadRegisterFiles.js.map +1 -0
  201. package/dist/utils/loadRegisterFiles.ts +41 -0
  202. package/dist/utils/loadResolvers.d.ts +5 -0
  203. package/dist/utils/loadResolvers.d.ts.map +1 -0
  204. package/dist/utils/loadResolvers.js +27 -0
  205. package/dist/utils/loadResolvers.js.map +1 -0
  206. package/dist/utils/loadResolvers.ts +36 -0
  207. package/package.json +55 -0
  208. package/src/cli-manifest.ts +9 -0
  209. package/src/codegen/extract/commands.ts +79 -0
  210. package/src/codegen/extract/data-sink.ts +45 -0
  211. package/src/codegen/extract/events.ts +46 -0
  212. package/src/codegen/extract/fields.ts +17 -0
  213. package/src/codegen/extract/graphql.ts +103 -0
  214. package/src/codegen/extract/gwt.ts +75 -0
  215. package/src/codegen/extract/index.ts +7 -0
  216. package/src/codegen/extract/messages.ts +196 -0
  217. package/src/codegen/extract/projection.ts +47 -0
  218. package/src/codegen/extract/query.ts +18 -0
  219. package/src/codegen/extract/states.ts +45 -0
  220. package/src/codegen/scaffoldFromSchema.integration.specs.ts +71 -0
  221. package/src/codegen/scaffoldFromSchema.ts +440 -0
  222. package/src/codegen/templates/command/commands.specs.ts +90 -0
  223. package/src/codegen/templates/command/commands.ts.ejs +11 -0
  224. package/src/codegen/templates/command/decide.specs.specs.ts +265 -0
  225. package/src/codegen/templates/command/decide.specs.ts +542 -0
  226. package/src/codegen/templates/command/decide.specs.ts.ejs +51 -0
  227. package/src/codegen/templates/command/decide.ts.ejs +107 -0
  228. package/src/codegen/templates/command/events.specs.ts +106 -0
  229. package/src/codegen/templates/command/events.ts.ejs +14 -0
  230. package/src/codegen/templates/command/evolve.specs.ts +102 -0
  231. package/src/codegen/templates/command/evolve.ts.ejs +39 -0
  232. package/src/codegen/templates/command/handle.specs.ts +313 -0
  233. package/src/codegen/templates/command/handle.ts.ejs +111 -0
  234. package/src/codegen/templates/command/mutation.resolver.specs.ts +115 -0
  235. package/src/codegen/templates/command/mutation.resolver.ts.ejs +25 -0
  236. package/src/codegen/templates/command/register.specs.ts +107 -0
  237. package/src/codegen/templates/command/register.ts.ejs +12 -0
  238. package/src/codegen/templates/command/state.specs.ts +127 -0
  239. package/src/codegen/templates/command/state.ts.ejs +47 -0
  240. package/src/codegen/templates/query/projection.specs.specs..ts +276 -0
  241. package/src/codegen/templates/query/projection.specs.ts +348 -0
  242. package/src/codegen/templates/query/projection.specs.ts.ejs +71 -0
  243. package/src/codegen/templates/query/projection.ts.ejs +121 -0
  244. package/src/codegen/templates/query/query.resolver.specs.ts +254 -0
  245. package/src/codegen/templates/query/query.resolver.ts.ejs +98 -0
  246. package/src/codegen/templates/query/state.specs.ts +70 -0
  247. package/src/codegen/templates/query/state.ts.ejs +7 -0
  248. package/src/codegen/templates/react/react.specs.specs.ts +214 -0
  249. package/src/codegen/templates/react/react.specs.ts +241 -0
  250. package/src/codegen/templates/react/react.specs.ts.ejs +80 -0
  251. package/src/codegen/templates/react/react.ts.ejs +56 -0
  252. package/src/codegen/templates/react/register.specs.ts +222 -0
  253. package/src/codegen/templates/react/register.ts.ejs +39 -0
  254. package/src/codegen/test-data/specVariant1.json +212 -0
  255. package/src/codegen/test-data/specVariant1.ts +188 -0
  256. package/src/codegen/test-data/specVariant2.json +396 -0
  257. package/src/codegen/types.ts +35 -0
  258. package/src/codegen/utils/path.ts +20 -0
  259. package/src/commands/generate-server.ts +517 -0
  260. package/src/domain/shared/ReadModel.ts +26 -0
  261. package/src/domain/shared/index.ts +4 -0
  262. package/src/domain/shared/reactorSpecification.ts +257 -0
  263. package/src/domain/shared/sendCommand.ts +21 -0
  264. package/src/domain/shared/types.ts +31 -0
  265. package/src/index.ts +2 -0
  266. package/src/server.ts +43 -0
  267. package/src/utils/index.ts +3 -0
  268. package/src/utils/loadProjections.ts +30 -0
  269. package/src/utils/loadRegisterFiles.ts +41 -0
  270. package/src/utils/loadResolvers.ts +36 -0
  271. package/tsconfig.json +12 -0
  272. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,115 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateScaffoldFilePlans } from '../../scaffoldFromSchema';
3
+ import { SpecsSchemaType as SpecsSchema } from '@auto-engineer/flow';
4
+
5
+ describe('mutation.resolver.ts.ejs', () => {
6
+ it('should generate a valid mutation resolver file', async () => {
7
+ const spec: SpecsSchema = {
8
+ variant: 'specs',
9
+ flows: [
10
+ {
11
+ name: 'Host creates a listing',
12
+ slices: [
13
+ {
14
+ type: 'command',
15
+ name: 'Create listing',
16
+ client: {
17
+ description: 'A form that allows users to add a new listing',
18
+ specs: [],
19
+ },
20
+ server: {
21
+ description: 'Handles listing creation',
22
+ gwt: [
23
+ {
24
+ when: {
25
+ commandRef: 'CreateListing',
26
+ exampleData: {
27
+ propertyId: 'listing_123',
28
+ title: 'Modern Downtown Apartment',
29
+ pricePerNight: 250,
30
+ maxGuests: 4,
31
+ amenities: ['wifi', 'kitchen'],
32
+ available: true,
33
+ tags: ['sea view', 'balcony'],
34
+ rating: 4.8,
35
+ metadata: { petsAllowed: true },
36
+ listedAt: '2024-01-15T10:00:00Z',
37
+ },
38
+ },
39
+ then: [],
40
+ },
41
+ ],
42
+ },
43
+ },
44
+ ],
45
+ },
46
+ ],
47
+ messages: [
48
+ {
49
+ type: 'command',
50
+ name: 'CreateListing',
51
+ fields: [
52
+ { name: 'propertyId', type: 'string', required: true },
53
+ { name: 'title', type: 'string', required: true },
54
+ { name: 'pricePerNight', type: 'number', required: true },
55
+ { name: 'maxGuests', type: 'number', required: true },
56
+ { name: 'amenities', type: 'string[]', required: true },
57
+ { name: 'available', type: 'boolean', required: true },
58
+ { name: 'tags', type: 'string[]', required: true },
59
+ { name: 'rating', type: 'number', required: true },
60
+ { name: 'metadata', type: 'object', required: true },
61
+ { name: 'listedAt', type: 'Date', required: true },
62
+ ],
63
+ },
64
+ ],
65
+ };
66
+
67
+ const plans = await generateScaffoldFilePlans(spec.flows, spec.messages, undefined, 'src/domain/flows');
68
+ const mutationFile = plans.find((p) => p.outputPath.endsWith('mutation.resolver.ts'));
69
+
70
+ expect(mutationFile?.contents).toMatchInlineSnapshot(`
71
+ "import { Mutation, Resolver, Arg, Ctx, Field, InputType } from 'type-graphql';
72
+ import { type GraphQLContext, sendCommand, MutationResponse } from '../../../shared';
73
+
74
+ @InputType()
75
+ export class CreateListingInput {
76
+ @Field(() => String)
77
+ propertyId!: string;
78
+ @Field(() => String)
79
+ title!: string;
80
+ @Field(() => Number)
81
+ pricePerNight!: number;
82
+ @Field(() => Number)
83
+ maxGuests!: number;
84
+ @Field(() => [String])
85
+ amenities!: string[];
86
+ @Field(() => Boolean)
87
+ available!: boolean;
88
+ @Field(() => [String])
89
+ tags!: string[];
90
+ @Field(() => Number)
91
+ rating!: number;
92
+ @Field(() => Object)
93
+ metadata!: object;
94
+ @Field(() => Date)
95
+ listedAt!: Date;
96
+ }
97
+
98
+ @Resolver()
99
+ export class CreateListingResolver {
100
+ @Mutation(() => MutationResponse)
101
+ async createListing(
102
+ @Arg('input', () => CreateListingInput) input: CreateListingInput,
103
+ @Ctx() ctx: GraphQLContext,
104
+ ): Promise<MutationResponse> {
105
+ return await sendCommand(ctx.messageBus, {
106
+ type: 'CreateListing',
107
+ kind: 'Command',
108
+ data: { ...input },
109
+ });
110
+ }
111
+ }
112
+ "
113
+ `);
114
+ });
115
+ });
@@ -0,0 +1,25 @@
1
+ import { Mutation, Resolver, Arg, Ctx, Field, InputType } from 'type-graphql';
2
+ import { type GraphQLContext, sendCommand, MutationResponse } from '../../../shared';
3
+
4
+ @InputType()
5
+ export class <%= pascalCase(commands[0].type) %>Input {
6
+ <% for (const field of commands[0].fields) { -%>
7
+ @Field(() => <%= graphqlType(field.tsType) %><%= field.required === false ? ', { nullable: true }' : '' %>)
8
+ <%= field.name %><%= field.required === false ? '?' : '' %><%= field.required !== false ? '!' : '' %>: <%- field.tsType %>;
9
+ <% } -%>
10
+ }
11
+
12
+ @Resolver()
13
+ export class <%= pascalCase(commands[0].type) %>Resolver {
14
+ @Mutation(() => MutationResponse)
15
+ async <%= camelCase(commands[0].type) %>(
16
+ @Arg('input', () => <%= pascalCase(commands[0].type) %>Input) input: <%= pascalCase(commands[0].type) %>Input,
17
+ @Ctx() ctx: GraphQLContext
18
+ ): Promise<MutationResponse> {
19
+ return await sendCommand(ctx.messageBus, {
20
+ type: '<%= commands[0].type %>',
21
+ kind: 'Command',
22
+ data: { ...input },
23
+ });
24
+ }
25
+ }
@@ -0,0 +1,107 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateScaffoldFilePlans } from '../../scaffoldFromSchema';
3
+ import { SpecsSchemaType as SpecsSchema } from '@auto-engineer/flow';
4
+
5
+ describe('generateScaffoldFilePlans', () => {
6
+ it('should generate a valid register file', async () => {
7
+ const spec: SpecsSchema = {
8
+ variant: 'specs',
9
+ flows: [
10
+ {
11
+ name: 'Host creates a listing',
12
+ slices: [
13
+ {
14
+ type: 'command',
15
+ name: 'Create listing',
16
+ stream: 'listings-${propertyId}',
17
+ client: {
18
+ description: 'test',
19
+ specs: [],
20
+ },
21
+ server: {
22
+ description: 'test',
23
+ gwt: [
24
+ {
25
+ when: {
26
+ commandRef: 'CreateListing',
27
+ exampleData: {
28
+ propertyId: 'listing_123',
29
+ title: 'Modern Downtown Apartment',
30
+ listedAt: '2024-01-15T10:00:00Z',
31
+ rating: 4.8,
32
+ metadata: { foo: 'bar' },
33
+ },
34
+ },
35
+ then: [
36
+ {
37
+ eventRef: 'ListingCreated',
38
+ exampleData: {
39
+ propertyId: 'listing_123',
40
+ title: 'Modern Downtown Apartment',
41
+ listedAt: '2024-01-15T10:00:00Z',
42
+ rating: 4.8,
43
+ metadata: { foo: 'bar' },
44
+ },
45
+ },
46
+ ],
47
+ },
48
+ ],
49
+ data: [
50
+ {
51
+ target: {
52
+ type: 'Event',
53
+ name: 'ListingCreated',
54
+ },
55
+ destination: {
56
+ type: 'stream',
57
+ pattern: 'listings-${propertyId}',
58
+ },
59
+ },
60
+ ],
61
+ },
62
+ },
63
+ ],
64
+ },
65
+ ],
66
+ messages: [
67
+ {
68
+ type: 'command',
69
+ name: 'CreateListing',
70
+ fields: [
71
+ { name: 'propertyId', type: 'string', required: true },
72
+ { name: 'title', type: 'string', required: true },
73
+ { name: 'listedAt', type: 'Date', required: true },
74
+ { name: 'rating', type: 'number', required: true },
75
+ { name: 'metadata', type: 'object', required: true },
76
+ ],
77
+ },
78
+ {
79
+ type: 'event',
80
+ name: 'ListingCreated',
81
+ source: 'internal',
82
+ fields: [
83
+ { name: 'propertyId', type: 'string', required: true },
84
+ { name: 'title', type: 'string', required: true },
85
+ { name: 'listedAt', type: 'Date', required: true },
86
+ { name: 'rating', type: 'number', required: true },
87
+ { name: 'metadata', type: 'object', required: true },
88
+ ],
89
+ },
90
+ ],
91
+ };
92
+
93
+ const plans = await generateScaffoldFilePlans(spec.flows, spec.messages, undefined, 'src/domain/flows');
94
+ const registerFile = plans.find((p) => p.outputPath.endsWith('register.ts'));
95
+
96
+ expect(registerFile?.contents).toMatchInlineSnapshot(`
97
+ "import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
98
+ import { handle } from './handle';
99
+ import type { CreateListing } from './commands';
100
+
101
+ export function register(messageBus: CommandProcessor, eventStore: EventStore) {
102
+ messageBus.handle((command: CreateListing) => handle(eventStore, command), 'CreateListing');
103
+ }
104
+ "
105
+ `);
106
+ });
107
+ });
@@ -0,0 +1,12 @@
1
+ import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
2
+ import { handle } from './handle';
3
+ import type { <%= commands.map(c => pascalCase(c.type)).join(', ') %> } from './commands';
4
+
5
+ export function register(messageBus: CommandProcessor, eventStore: EventStore) {
6
+ <% for (const command of commands) { -%>
7
+ messageBus.handle(
8
+ (command: <%= pascalCase(command.type) %>) => handle(eventStore, command),
9
+ '<%= command.type %>'
10
+ );
11
+ <% } -%>
12
+ }
@@ -0,0 +1,127 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateScaffoldFilePlans } from '../../scaffoldFromSchema';
3
+ import { SpecsSchemaType as SpecsSchema } from '@auto-engineer/flow';
4
+
5
+ describe('state.ts.ejs', () => {
6
+ it('should generate an initial state', async () => {
7
+ const spec: SpecsSchema = {
8
+ variant: 'specs',
9
+ flows: [
10
+ {
11
+ name: 'Host creates a listing',
12
+ slices: [
13
+ {
14
+ type: 'command',
15
+ name: 'Create listing',
16
+ client: {
17
+ description: 'test',
18
+ specs: [],
19
+ },
20
+ server: {
21
+ description: 'test',
22
+ gwt: [
23
+ {
24
+ when: {
25
+ commandRef: 'CreateListing',
26
+ exampleData: {
27
+ propertyId: 'listing_123',
28
+ title: 'nice apartment',
29
+ pricePerNight: 250,
30
+ available: true,
31
+ rating: 4.8,
32
+ metadata: { foo: 'bar' },
33
+ },
34
+ },
35
+ then: [
36
+ {
37
+ eventRef: 'ListingCreated',
38
+ exampleData: {
39
+ propertyId: 'listing_123',
40
+ listedAt: '2024-01-15T10:00:00Z',
41
+ rating: 4.8,
42
+ metadata: { foo: 'bar' },
43
+ },
44
+ },
45
+ ],
46
+ },
47
+ ],
48
+ },
49
+ },
50
+ ],
51
+ },
52
+ ],
53
+ messages: [
54
+ {
55
+ type: 'command',
56
+ name: 'CreateListing',
57
+ fields: [],
58
+ },
59
+ {
60
+ type: 'event',
61
+ name: 'ListingCreated',
62
+ source: 'internal',
63
+ fields: [
64
+ { name: 'propertyId', type: 'string', required: true },
65
+ { name: 'listedAt', type: 'Date', required: true },
66
+ { name: 'rating', type: 'number', required: true },
67
+ { name: 'metadata', type: 'object', required: true },
68
+ ],
69
+ },
70
+ ],
71
+ };
72
+
73
+ const plans = await generateScaffoldFilePlans(spec.flows, spec.messages, undefined, 'src/domain/flows');
74
+ const stateFile = plans.find((p) => p.outputPath.endsWith('state.ts'));
75
+
76
+ expect(stateFile?.contents).toMatchInlineSnapshot(`
77
+ "/**
78
+ * ## IMPLEMENTATION INSTRUCTIONS ##
79
+ *
80
+ * Define the shape of the domain state for the current slice below. This state is used by \`decide.ts\`
81
+ * to determine whether a command is valid.
82
+ *
83
+ * The state is evolved over time by applying domain events (in \`evolve.ts\`).
84
+ * Each event updates the state incrementally based on business rules.
85
+ *
86
+ * Guidelines:
87
+ * - Include only fields that are **read** during command validation.
88
+ * - Use discriminated unions (e.g., \`status: 'Pending' | 'Done'\`) to model state transitions.
89
+ * - Prefer primitive types: \`string\`, \`boolean\`, \`number\`.
90
+ * - Use objects or maps only when structure is essential for decision logic.
91
+ *
92
+ * Do NOT include:
93
+ * - Redundant data already emitted in events unless required to enforce business rules.
94
+ * - Fields used only for projections, UI, or query purposes.
95
+ *
96
+ * ### Example (for a Task domain):
97
+ *
98
+ * \`\`\`ts
99
+ * export type PendingTask = {
100
+ * status: 'Pending';
101
+ * };
102
+ *
103
+ * export type InProgressTask = {
104
+ * status: 'InProgress';
105
+ * startedAt: string;
106
+ * };
107
+ *
108
+ * export type CompletedTask = {
109
+ * status: 'Completed';
110
+ * completedAt: string;
111
+ * };
112
+ *
113
+ * export type State = PendingTask | InProgressTask | CompletedTask;
114
+ * \`\`\`
115
+ */
116
+
117
+ // TODO: Replace with a discriminated union of domain states for the current slice
118
+ export type State = {};
119
+
120
+ // TODO: Replace the Return with the initial domain state of the current slice
121
+ export const initialState = (): State => {
122
+ return {};
123
+ };
124
+ "
125
+ `);
126
+ });
127
+ });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * ## IMPLEMENTATION INSTRUCTIONS ##
3
+ *
4
+ * Define the shape of the domain state for the current slice below. This state is used by `decide.ts`
5
+ * to determine whether a command is valid.
6
+ *
7
+ * The state is evolved over time by applying domain events (in `evolve.ts`).
8
+ * Each event updates the state incrementally based on business rules.
9
+ *
10
+ * Guidelines:
11
+ * - Include only fields that are **read** during command validation.
12
+ * - Use discriminated unions (e.g., `status: 'Pending' | 'Done'`) to model state transitions.
13
+ * - Prefer primitive types: `string`, `boolean`, `number`.
14
+ * - Use objects or maps only when structure is essential for decision logic.
15
+ *
16
+ * Do NOT include:
17
+ * - Redundant data already emitted in events unless required to enforce business rules.
18
+ * - Fields used only for projections, UI, or query purposes.
19
+ *
20
+ * ### Example (for a Task domain):
21
+ *
22
+ * ```ts
23
+ * export type PendingTask = {
24
+ * status: 'Pending';
25
+ * };
26
+ *
27
+ * export type InProgressTask = {
28
+ * status: 'InProgress';
29
+ * startedAt: string;
30
+ * };
31
+ *
32
+ * export type CompletedTask = {
33
+ * status: 'Completed';
34
+ * completedAt: string;
35
+ * };
36
+ *
37
+ * export type State = PendingTask | InProgressTask | CompletedTask;
38
+ * ```
39
+ */
40
+
41
+ // TODO: Replace with a discriminated union of domain states for the current slice
42
+ export type State = {};
43
+
44
+ // TODO: Replace the Return with the initial domain state of the current slice
45
+ export const initialState = (): State => {
46
+ return {};
47
+ };