create-auto-app 0.2.3 → 0.8.4

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 (343) hide show
  1. package/README.md +197 -0
  2. package/dist/index.js +5 -0
  3. package/dist/index.js.map +1 -1
  4. package/package.json +4 -4
  5. package/templates/.gitkeep +0 -0
  6. package/templates/shopping-app/.context/schema.json +389 -218
  7. package/templates/shopping-app/.context/server/.context/auto-ia-scheme.json +79 -0
  8. package/templates/shopping-app/.context/server/server/package.json +26 -0
  9. package/templates/shopping-app/.context/server/server/scripts/generate-schema.ts +34 -0
  10. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/commands.ts +8 -0
  11. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.specs.ts +46 -0
  12. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.ts +33 -0
  13. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/events.ts +10 -0
  14. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/evolve.ts +28 -0
  15. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/handle.ts +24 -0
  16. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/mutation.resolver.ts +25 -0
  17. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/register.ts +7 -0
  18. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/state.ts +47 -0
  19. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.specs.ts +51 -0
  20. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.ts +43 -0
  21. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/register.ts +24 -0
  22. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.specs.ts +51 -0
  23. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.ts +43 -0
  24. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/register.ts +24 -0
  25. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/commands.ts +8 -0
  26. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.specs.ts +38 -0
  27. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.ts +33 -0
  28. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/events.ts +10 -0
  29. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/evolve.ts +28 -0
  30. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/handle.ts +24 -0
  31. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/mutation.resolver.ts +25 -0
  32. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/register.ts +7 -0
  33. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/state.ts +47 -0
  34. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/commands.ts +8 -0
  35. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.specs.ts +101 -0
  36. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.ts +42 -0
  37. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/events.ts +9 -0
  38. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/evolve.ts +28 -0
  39. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/handle.ts +52 -0
  40. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/mutation.resolver.ts +25 -0
  41. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/register.ts +7 -0
  42. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/state.ts +47 -0
  43. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/commands.ts +8 -0
  44. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.specs.ts +101 -0
  45. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.ts +43 -0
  46. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/events.ts +9 -0
  47. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/evolve.ts +28 -0
  48. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/handle.ts +52 -0
  49. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/mutation.resolver.ts +25 -0
  50. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/register.ts +7 -0
  51. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/state.ts +47 -0
  52. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.specs.ts +56 -0
  53. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.ts +24 -0
  54. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/query.resolver.ts +56 -0
  55. package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/state.ts +4 -0
  56. package/templates/shopping-app/.context/server/server/src/domain/shared/ReadModel.ts +26 -0
  57. package/templates/shopping-app/{server/src/domain/shared/index.d.ts → .context/server/server/src/domain/shared/index.ts} +0 -1
  58. package/templates/shopping-app/{server/src/domain/shared/reactorSpecification.js → .context/server/server/src/domain/shared/reactorSpecification.ts} +116 -22
  59. package/templates/shopping-app/.context/server/server/src/domain/shared/sendCommand.ts +21 -0
  60. package/templates/shopping-app/{server/src/domain/shared/types.d.ts → .context/server/server/src/domain/shared/types.ts} +17 -5
  61. package/templates/shopping-app/.context/server/server/src/server.ts +43 -0
  62. package/templates/shopping-app/{server/src/utils/index.d.ts → .context/server/server/src/utils/index.ts} +0 -1
  63. package/templates/shopping-app/{server/src/utils/loadProjections.js → .context/server/server/src/utils/loadProjections.ts} +11 -6
  64. package/templates/shopping-app/.context/server/server/src/utils/loadRegisterFiles.ts +41 -0
  65. package/templates/shopping-app/{server/src/utils/loadResolvers.js → .context/server/server/src/utils/loadResolvers.ts} +16 -7
  66. package/templates/shopping-app/.context/server/server/tsconfig.json +13 -0
  67. package/templates/shopping-app/.context/server/server/vitest.config.ts +7 -0
  68. package/templates/shopping-app/auto.config.ts +78 -45
  69. package/templates/shopping-app/client/package.json +4 -4
  70. package/templates/shopping-app/client/src/App.tsx +13 -13
  71. package/templates/shopping-app/client/src/components/molecules/QuantitySelector.tsx +4 -4
  72. package/templates/shopping-app/client/src/components/molecules/ShoppingCriteriaForm.tsx +4 -4
  73. package/templates/shopping-app/client/src/components/molecules/SuggestedItemCard.tsx +6 -6
  74. package/templates/shopping-app/client/src/components/organisms/AssistantChatInterface.tsx +3 -3
  75. package/templates/shopping-app/client/src/components/organisms/PageHeader.tsx +2 -3
  76. package/templates/shopping-app/client/src/components/organisms/SuggestedItemsList.tsx +3 -3
  77. package/templates/shopping-app/client/src/index.css +10 -14
  78. package/templates/shopping-app/client/src/pages/AssistantChatPage.tsx +4 -4
  79. package/templates/shopping-app/client/src/pages/SuggestedItemsPage.tsx +4 -4
  80. package/templates/shopping-app/example-integrations/ai-chat-completion/package.json +5 -6
  81. package/templates/shopping-app/example-integrations/ai-chat-completion/src/ai-integration.ts +2 -2
  82. package/templates/shopping-app/example-integrations/cart/package.json +5 -6
  83. package/templates/shopping-app/example-integrations/cart-api/package.json +3 -3
  84. package/templates/shopping-app/example-integrations/product-catalogue/package.json +5 -5
  85. package/templates/shopping-app/example-integrations/product-catalogue/src/product-catalogue-integration.ts +3 -128
  86. package/templates/shopping-app/example-integrations/product-catalogue-api/package.json +3 -3
  87. package/templates/shopping-app/flows/shopping-assistant.flow.ts +195 -196
  88. package/templates/shopping-app/package.json +16 -11
  89. package/templates/shopping-app/server/package.json +4 -4
  90. package/templates/shopping-app/server/src/integrations/ai-integration.ts +2 -2
  91. package/templates/shopping-app/tsconfig.json +2 -2
  92. package/templates/shopping-app/.env +0 -8
  93. package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-build.log +0 -4
  94. package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-format.log +0 -12
  95. package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-lint.log +0 -4
  96. package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-test.log +0 -12
  97. package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-type-check.log +0 -5
  98. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.d.ts +0 -23
  99. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.d.ts.map +0 -1
  100. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.js +0 -41
  101. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.js.map +0 -1
  102. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.d.ts +0 -2
  103. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.d.ts.map +0 -1
  104. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.js +0 -2
  105. package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.js.map +0 -1
  106. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/eslint +0 -21
  107. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/jiti +0 -21
  108. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/msw +0 -21
  109. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/tsc +0 -21
  110. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/tsserver +0 -21
  111. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/vite +0 -21
  112. package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/vitest +0 -21
  113. package/templates/shopping-app/example-integrations/cart/.turbo/turbo-build.log +0 -4
  114. package/templates/shopping-app/example-integrations/cart/.turbo/turbo-format.log +0 -12
  115. package/templates/shopping-app/example-integrations/cart/.turbo/turbo-lint.log +0 -5
  116. package/templates/shopping-app/example-integrations/cart/.turbo/turbo-test.log +0 -12
  117. package/templates/shopping-app/example-integrations/cart/.turbo/turbo-type-check.log +0 -5
  118. package/templates/shopping-app/example-integrations/cart/dist/cart-integration.d.ts +0 -30
  119. package/templates/shopping-app/example-integrations/cart/dist/cart-integration.d.ts.map +0 -1
  120. package/templates/shopping-app/example-integrations/cart/dist/cart-integration.js +0 -134
  121. package/templates/shopping-app/example-integrations/cart/dist/cart-integration.js.map +0 -1
  122. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.d.ts +0 -3
  123. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.d.ts.map +0 -1
  124. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.js +0 -149
  125. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.js.map +0 -1
  126. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.d.ts +0 -8
  127. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.d.ts.map +0 -1
  128. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.js +0 -6
  129. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.js.map +0 -1
  130. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.d.ts +0 -123
  131. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.d.ts.map +0 -1
  132. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.js +0 -3
  133. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.js.map +0 -1
  134. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.d.ts +0 -46
  135. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.d.ts.map +0 -1
  136. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.js +0 -285
  137. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.js.map +0 -1
  138. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.d.ts +0 -13
  139. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.d.ts.map +0 -1
  140. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.js +0 -6
  141. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.js.map +0 -1
  142. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.d.ts +0 -19
  143. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.d.ts.map +0 -1
  144. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.js +0 -15
  145. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.js.map +0 -1
  146. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.d.ts +0 -18
  147. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.d.ts.map +0 -1
  148. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.js +0 -58
  149. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.js.map +0 -1
  150. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.d.ts +0 -34
  151. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.d.ts.map +0 -1
  152. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.js +0 -89
  153. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.js.map +0 -1
  154. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.d.ts +0 -34
  155. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.d.ts.map +0 -1
  156. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.js +0 -115
  157. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.js.map +0 -1
  158. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.d.ts +0 -79
  159. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.d.ts.map +0 -1
  160. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.js +0 -3
  161. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.js.map +0 -1
  162. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.d.ts +0 -2
  163. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.d.ts.map +0 -1
  164. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.js +0 -3
  165. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.js.map +0 -1
  166. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.d.ts +0 -158
  167. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.d.ts.map +0 -1
  168. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.js +0 -3
  169. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.js.map +0 -1
  170. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.d.ts +0 -382
  171. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.d.ts.map +0 -1
  172. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.js +0 -68
  173. package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.js.map +0 -1
  174. package/templates/shopping-app/example-integrations/cart/dist/index.d.ts +0 -2
  175. package/templates/shopping-app/example-integrations/cart/dist/index.d.ts.map +0 -1
  176. package/templates/shopping-app/example-integrations/cart/dist/index.js +0 -2
  177. package/templates/shopping-app/example-integrations/cart/dist/index.js.map +0 -1
  178. package/templates/shopping-app/example-integrations/cart/node_modules/.bin/eslint +0 -21
  179. package/templates/shopping-app/example-integrations/cart/node_modules/.bin/jiti +0 -21
  180. package/templates/shopping-app/example-integrations/cart/node_modules/.bin/msw +0 -21
  181. package/templates/shopping-app/example-integrations/cart/node_modules/.bin/tsc +0 -21
  182. package/templates/shopping-app/example-integrations/cart/node_modules/.bin/tsserver +0 -21
  183. package/templates/shopping-app/example-integrations/cart/node_modules/.bin/vitest +0 -21
  184. package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-build.log +0 -4
  185. package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-format.log +0 -10
  186. package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-lint.log +0 -4
  187. package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-test.log +0 -12
  188. package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-type-check.log +0 -4
  189. package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.d.ts +0 -18
  190. package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.d.ts.map +0 -1
  191. package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.js +0 -28
  192. package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.js.map +0 -1
  193. package/templates/shopping-app/example-integrations/cart-api/dist/index.d.ts +0 -4
  194. package/templates/shopping-app/example-integrations/cart-api/dist/index.d.ts.map +0 -1
  195. package/templates/shopping-app/example-integrations/cart-api/dist/index.js +0 -49
  196. package/templates/shopping-app/example-integrations/cart-api/dist/index.js.map +0 -1
  197. package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.d.ts +0 -4
  198. package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.d.ts.map +0 -1
  199. package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.js +0 -261
  200. package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.js.map +0 -1
  201. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/nodemon +0 -21
  202. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/swagger-jsdoc +0 -21
  203. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node +0 -21
  204. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-cwd +0 -21
  205. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-esm +0 -21
  206. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-script +0 -21
  207. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-transpile-only +0 -21
  208. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-script +0 -21
  209. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/tsc +0 -21
  210. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/tsserver +0 -21
  211. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/tsx +0 -21
  212. package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/vitest +0 -21
  213. package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-build.log +0 -4
  214. package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-format.log +0 -12
  215. package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-lint.log +0 -5
  216. package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-test.log +0 -12
  217. package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-type-check.log +0 -5
  218. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.d.ts +0 -3
  219. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.d.ts.map +0 -1
  220. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.js +0 -149
  221. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.js.map +0 -1
  222. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.d.ts +0 -8
  223. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.d.ts.map +0 -1
  224. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.js +0 -6
  225. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.js.map +0 -1
  226. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.d.ts +0 -123
  227. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.d.ts.map +0 -1
  228. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.js +0 -3
  229. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.js.map +0 -1
  230. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.d.ts +0 -46
  231. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.d.ts.map +0 -1
  232. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.js +0 -285
  233. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.js.map +0 -1
  234. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.d.ts +0 -13
  235. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.d.ts.map +0 -1
  236. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.js +0 -6
  237. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.js.map +0 -1
  238. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.d.ts +0 -19
  239. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.d.ts.map +0 -1
  240. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.js +0 -15
  241. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.js.map +0 -1
  242. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.d.ts +0 -18
  243. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.d.ts.map +0 -1
  244. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.js +0 -58
  245. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.js.map +0 -1
  246. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.d.ts +0 -34
  247. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.d.ts.map +0 -1
  248. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.js +0 -89
  249. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.js.map +0 -1
  250. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.d.ts +0 -34
  251. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.d.ts.map +0 -1
  252. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.js +0 -115
  253. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.js.map +0 -1
  254. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.d.ts +0 -79
  255. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.d.ts.map +0 -1
  256. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.js +0 -3
  257. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.js.map +0 -1
  258. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.d.ts +0 -2
  259. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.d.ts.map +0 -1
  260. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.js +0 -3
  261. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.js.map +0 -1
  262. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.d.ts +0 -115
  263. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.d.ts.map +0 -1
  264. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.js +0 -3
  265. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.js.map +0 -1
  266. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.d.ts +0 -206
  267. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.d.ts.map +0 -1
  268. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.js +0 -53
  269. package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.js.map +0 -1
  270. package/templates/shopping-app/example-integrations/product-catalogue/dist/index.d.ts +0 -2
  271. package/templates/shopping-app/example-integrations/product-catalogue/dist/index.d.ts.map +0 -1
  272. package/templates/shopping-app/example-integrations/product-catalogue/dist/index.js +0 -2
  273. package/templates/shopping-app/example-integrations/product-catalogue/dist/index.js.map +0 -1
  274. package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.d.ts +0 -32
  275. package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.d.ts.map +0 -1
  276. package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.js +0 -163
  277. package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.js.map +0 -1
  278. package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/eslint +0 -21
  279. package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/jiti +0 -21
  280. package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/msw +0 -21
  281. package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/tsc +0 -21
  282. package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/tsserver +0 -21
  283. package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/vitest +0 -21
  284. package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-build.log +0 -4
  285. package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-format.log +0 -10
  286. package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-lint.log +0 -5
  287. package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-test.log +0 -13
  288. package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-type-check.log +0 -5
  289. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.d.ts +0 -10
  290. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.d.ts.map +0 -1
  291. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.js +0 -75
  292. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.js.map +0 -1
  293. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.d.ts +0 -4
  294. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.d.ts.map +0 -1
  295. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.js +0 -49
  296. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.js.map +0 -1
  297. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.d.ts +0 -4
  298. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.d.ts.map +0 -1
  299. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.js +0 -170
  300. package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.js.map +0 -1
  301. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/nodemon +0 -21
  302. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/swagger-jsdoc +0 -21
  303. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node +0 -21
  304. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-cwd +0 -21
  305. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-esm +0 -21
  306. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-script +0 -21
  307. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-transpile-only +0 -21
  308. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-script +0 -21
  309. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/tsc +0 -21
  310. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/tsserver +0 -21
  311. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/tsx +0 -21
  312. package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/vitest +0 -21
  313. package/templates/shopping-app/pnpm-workspace.yaml +0 -2
  314. package/templates/shopping-app/server/src/domain/shared/ReadModel.d.ts +0 -10
  315. package/templates/shopping-app/server/src/domain/shared/ReadModel.d.ts.map +0 -1
  316. package/templates/shopping-app/server/src/domain/shared/ReadModel.js +0 -19
  317. package/templates/shopping-app/server/src/domain/shared/ReadModel.js.map +0 -1
  318. package/templates/shopping-app/server/src/domain/shared/index.d.ts.map +0 -1
  319. package/templates/shopping-app/server/src/domain/shared/index.js +0 -5
  320. package/templates/shopping-app/server/src/domain/shared/index.js.map +0 -1
  321. package/templates/shopping-app/server/src/domain/shared/reactorSpecification.d.ts +0 -56
  322. package/templates/shopping-app/server/src/domain/shared/reactorSpecification.d.ts.map +0 -1
  323. package/templates/shopping-app/server/src/domain/shared/reactorSpecification.js.map +0 -1
  324. package/templates/shopping-app/server/src/domain/shared/sendCommand.d.ts +0 -7
  325. package/templates/shopping-app/server/src/domain/shared/sendCommand.d.ts.map +0 -1
  326. package/templates/shopping-app/server/src/domain/shared/sendCommand.js +0 -16
  327. package/templates/shopping-app/server/src/domain/shared/sendCommand.js.map +0 -1
  328. package/templates/shopping-app/server/src/domain/shared/types.d.ts.map +0 -1
  329. package/templates/shopping-app/server/src/domain/shared/types.js +0 -40
  330. package/templates/shopping-app/server/src/domain/shared/types.js.map +0 -1
  331. package/templates/shopping-app/server/src/utils/index.d.ts.map +0 -1
  332. package/templates/shopping-app/server/src/utils/index.js +0 -4
  333. package/templates/shopping-app/server/src/utils/index.js.map +0 -1
  334. package/templates/shopping-app/server/src/utils/loadProjections.d.ts +0 -3
  335. package/templates/shopping-app/server/src/utils/loadProjections.d.ts.map +0 -1
  336. package/templates/shopping-app/server/src/utils/loadProjections.js.map +0 -1
  337. package/templates/shopping-app/server/src/utils/loadRegisterFiles.d.ts +0 -6
  338. package/templates/shopping-app/server/src/utils/loadRegisterFiles.d.ts.map +0 -1
  339. package/templates/shopping-app/server/src/utils/loadRegisterFiles.js +0 -26
  340. package/templates/shopping-app/server/src/utils/loadRegisterFiles.js.map +0 -1
  341. package/templates/shopping-app/server/src/utils/loadResolvers.d.ts +0 -5
  342. package/templates/shopping-app/server/src/utils/loadResolvers.d.ts.map +0 -1
  343. package/templates/shopping-app/server/src/utils/loadResolvers.js.map +0 -1
@@ -0,0 +1,43 @@
1
+ import { IllegalStateError } from '@event-driven-io/emmett';
2
+ import type { State } from './state';
3
+ import type { SuggestShoppingItems } from './commands';
4
+ import type { ShoppingItemsSuggested } from './events';
5
+ import type { Products } from '@auto-engineer/product-catalog-integration';
6
+
7
+ export const decide = (command: SuggestShoppingItems, state: State, products?: Products): ShoppingItemsSuggested => {
8
+ switch (command.type) {
9
+ case 'SuggestShoppingItems': {
10
+ /**
11
+ * ## IMPLEMENTATION INSTRUCTIONS ##
12
+ *
13
+ * This command requires evaluating prior state to determine if it can proceed.
14
+ *
15
+ * You should:
16
+ * - Validate the command input fields
17
+ * - Inspect the current domain `state` to determine if the command is allowed
18
+ * - Use `products` (integration result) to enrich or filter the output
19
+ * - If invalid, throw one of the following domain errors: `NotFoundError`, `ValidationError`, or `IllegalStateError`
20
+ * - If valid, return one or more events with the correct structure
21
+ *
22
+ * ⚠️ Only read from inputs — never mutate them. `evolve.ts` handles state updates.
23
+ *
24
+ * Integration result shape (Products):
25
+ * products?.data = {
26
+ * type: "Products";
27
+ * products: Array<{
28
+ * productId: string; name;
29
+ * }>;
30
+ * }
31
+ */
32
+
33
+ // return {
34
+ // type: 'ShoppingItemsSuggested',
35
+ // data: { ...command.data },
36
+ // } as ShoppingItemsSuggested;
37
+
38
+ throw new IllegalStateError('Not yet implemented: ' + command.type);
39
+ }
40
+ default:
41
+ throw new IllegalStateError('Unexpected command type: ' + command.type);
42
+ }
43
+ };
@@ -0,0 +1,9 @@
1
+ import type { Event } from '@event-driven-io/emmett';
2
+
3
+ export type ShoppingItemsSuggested = Event<
4
+ 'ShoppingItemsSuggested',
5
+ {
6
+ sessionId: string;
7
+ suggestedItems: Array<{ productId: string; name: string; quantity: number; reason: string }>;
8
+ }
9
+ >;
@@ -0,0 +1,28 @@
1
+ import type { State } from './state';
2
+ import type { ShoppingItemsSuggested } from './events';
3
+
4
+ /**
5
+ * ## IMPLEMENTATION INSTRUCTIONS ##
6
+ *
7
+ * This function defines how the domain state evolves in response to events.
8
+ *
9
+ * Guidelines:
10
+ * - Apply only the **minimal** necessary changes for future decisions in `decide.ts`.
11
+ * - Ignore any event fields not required for decision-making logic.
12
+ * - If the event doesn’t change decision-relevant state, return the existing `state`.
13
+ * - Prefer immutability: always return a **new state object**.
14
+ * - Avoid spreading all of `event.data` unless all fields are relevant.
15
+ */
16
+
17
+ export const evolve = (state: State, event: ShoppingItemsSuggested): State => {
18
+ switch (event.type) {
19
+ case 'ShoppingItemsSuggested': {
20
+ // TODO: Update state based on ShoppingItemsSuggested
21
+ return {
22
+ ...state,
23
+ };
24
+ }
25
+ default:
26
+ return state;
27
+ }
28
+ };
@@ -0,0 +1,52 @@
1
+ import '@auto-engineer/product-catalog-integration';
2
+
3
+ import { AI } from '@auto-engineer/ai-integration';
4
+
5
+ import { Products } from '@auto-engineer/product-catalog-integration';
6
+
7
+ import { CommandHandler, type EventStore, type MessageHandlerResult } from '@event-driven-io/emmett';
8
+ import { evolve } from './evolve';
9
+ import { initialState } from './state';
10
+ import { decide } from './decide';
11
+ import type { SuggestShoppingItems } from './commands';
12
+
13
+ /**
14
+ * ## IMPLEMENTATION INSTRUCTIONS ##
15
+ * add the following to the DoChat: schemaName: Products, systemPrompt: use the PRODUCT_CATALOGUE_PRODUCTS MCP tool to get product data
16
+ */
17
+
18
+ const handler = CommandHandler({
19
+ evolve,
20
+ initialState,
21
+ });
22
+
23
+ export const handle = async (eventStore: EventStore, command: SuggestShoppingItems): Promise<MessageHandlerResult> => {
24
+ const streamId = `shopping-session-${command.data.sessionId}`;
25
+
26
+ try {
27
+ // TODO: Map fields from the incoming command to this integration input.
28
+ // - Use relevant fields from `command.data` to populate the required inputs below.
29
+ // - Some fields may require transformation or enrichment.
30
+ // - If additional context is needed, construct it here.
31
+ // const products: Products | undefined = await AI.Commands?.DoChat<Products>({
32
+ // type: 'DoChat',
33
+ // data: {
34
+ // // sessionId: ???
35
+ // prompt: ???
36
+ // systemPrompt: ???
37
+ // schemaName: ???
38
+ // },
39
+ // });
40
+
41
+ await handler(eventStore, streamId, (state) =>
42
+ // TODO: add products as a parameter to decide once implemented above
43
+ decide(command, state /* products */),
44
+ );
45
+ return; // success (returns void)
46
+ } catch (error: any) {
47
+ return {
48
+ type: 'SKIP',
49
+ reason: `Command failed: ${error?.message ?? 'Unknown'}`,
50
+ };
51
+ }
52
+ };
@@ -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 SuggestShoppingItemsInput {
6
+ @Field(() => String)
7
+ sessionId!: string;
8
+ @Field(() => String)
9
+ prompt!: string;
10
+ }
11
+
12
+ @Resolver()
13
+ export class SuggestShoppingItemsResolver {
14
+ @Mutation(() => MutationResponse)
15
+ async suggestShoppingItems(
16
+ @Arg('input', () => SuggestShoppingItemsInput) input: SuggestShoppingItemsInput,
17
+ @Ctx() ctx: GraphQLContext,
18
+ ): Promise<MutationResponse> {
19
+ return await sendCommand(ctx.messageBus, {
20
+ type: 'SuggestShoppingItems',
21
+ kind: 'Command',
22
+ data: { ...input },
23
+ });
24
+ }
25
+ }
@@ -0,0 +1,7 @@
1
+ import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
2
+ import { handle } from './handle';
3
+ import type { SuggestShoppingItems } from './commands';
4
+
5
+ export function register(messageBus: CommandProcessor, eventStore: EventStore) {
6
+ messageBus.handle((command: SuggestShoppingItems) => handle(eventStore, command), 'SuggestShoppingItems');
7
+ }
@@ -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
+ };
@@ -0,0 +1,56 @@
1
+ import { describe, it, beforeEach, expect } from 'vitest';
2
+ import { InMemoryProjectionSpec } from '@event-driven-io/emmett';
3
+ import { projection } from './projection';
4
+ import type {} from '../unknown/events';
5
+ import { SuggestedItems } from './state';
6
+
7
+ type ProjectionEvent = never;
8
+
9
+ describe('SuggestedItemsProjection Projection', () => {
10
+ let given: InMemoryProjectionSpec<ProjectionEvent>;
11
+
12
+ beforeEach(() => {
13
+ given = InMemoryProjectionSpec.for({ projection });
14
+ });
15
+
16
+ it('creates or updates SuggestedItems document - case 1', () =>
17
+ given([])
18
+ .when([])
19
+ .then(async (state) => {
20
+ const document = await state.database
21
+ .collection<SuggestedItems>('SuggestedItemsProjection')
22
+ .findOne((doc) => doc.sessionId === 'session-abc');
23
+
24
+ const expected: SuggestedItems = {
25
+ sessionId: 'session-abc',
26
+ items: [
27
+ {
28
+ productId: 'prod-soccer-ball',
29
+ name: 'Super Soccer Ball',
30
+ quantity: 1,
31
+ reason: 'Perfect for your daughter who loves soccer',
32
+ },
33
+ {
34
+ productId: 'prod-craft-kit',
35
+ name: 'Deluxe Craft Kit',
36
+ quantity: 1,
37
+ reason: 'Great for creative activities and crafts',
38
+ },
39
+ {
40
+ productId: 'prod-laptop-bag',
41
+ name: 'Tech Laptop Backpack',
42
+ quantity: 1,
43
+ reason: "Essential for your son's school computer needs",
44
+ },
45
+ {
46
+ productId: 'prod-mtg-starter',
47
+ name: 'Magic the Gathering Starter Set',
48
+ quantity: 1,
49
+ reason: 'Ideal starter set for Magic the Gathering enthusiasts',
50
+ },
51
+ ],
52
+ };
53
+
54
+ expect(document).toMatchObject(expected);
55
+ }));
56
+ });
@@ -0,0 +1,24 @@
1
+ import {
2
+ inMemorySingleStreamProjection,
3
+ type ReadEvent,
4
+ type InMemoryReadEventMetadata,
5
+ } from '@event-driven-io/emmett';
6
+ import type { SuggestedItems } from './state';
7
+ type AllEvents = never;
8
+
9
+ export const projection = inMemorySingleStreamProjection<SuggestedItems, AllEvents>({
10
+ collectionName: 'SuggestedItemsProjection',
11
+ canHandle: [],
12
+ getDocumentId: (event) => event.data.sessionId,
13
+ evolve: (
14
+ document: SuggestedItems | null,
15
+ event: ReadEvent<AllEvents, InMemoryReadEventMetadata>,
16
+ ): SuggestedItems | null => {
17
+ switch (event.type) {
18
+ default:
19
+ return document;
20
+ }
21
+ },
22
+ });
23
+
24
+ export default projection;
@@ -0,0 +1,56 @@
1
+ import { Query, Resolver, Arg, Ctx, ObjectType, Field, ID } from 'type-graphql';
2
+ import { type GraphQLContext, ReadModel } from '../../../shared';
3
+
4
+ @ObjectType()
5
+ export class SuggestedItems {
6
+ @Field(() => String)
7
+ sessionId!: string;
8
+
9
+ @Field(() => [SuggestedItemsItems])
10
+ items!: SuggestedItemsItems[];
11
+
12
+ [key: string]: unknown;
13
+ }
14
+
15
+ @ObjectType()
16
+ export class SuggestedItemsItems {
17
+ @Field(() => String)
18
+ productId!: string;
19
+
20
+ @Field(() => String)
21
+ name!: string;
22
+
23
+ @Field(() => Number)
24
+ quantity!: number;
25
+
26
+ @Field(() => String)
27
+ reason!: string;
28
+ }
29
+
30
+ @Resolver()
31
+ export class ViewsSuggestedItemsQueryResolver {
32
+ @Query(() => [SuggestedItems])
33
+ async suggestedItems(
34
+ @Ctx() ctx: GraphQLContext,
35
+ @Arg('sessionId', () => ID, { nullable: true }) sessionId?: string,
36
+ ): Promise<SuggestedItems[]> {
37
+ const model = new ReadModel<SuggestedItems>(ctx.eventStore, 'SuggestedItemsProjection');
38
+
39
+ // ## IMPLEMENTATION INSTRUCTIONS ##
40
+ // You can query the projection using the ReadModel API:
41
+ //
42
+ // - model.getAll() — fetch all documents
43
+ // - model.getById(id) — fetch a single document by ID (default key: 'id')
44
+ // - model.find(filterFn) — filter documents using a predicate
45
+ // - model.first(filterFn) — fetch the first document matching a predicate
46
+ //
47
+ // Example below uses `.find()` to filter
48
+ // change the logic for the query as needed to meet the requirements for the current slice.
49
+
50
+ return model.find((item) => {
51
+ if (sessionId !== undefined && item.sessionId !== sessionId) return false;
52
+
53
+ return true;
54
+ });
55
+ }
56
+ }
@@ -0,0 +1,4 @@
1
+ export type SuggestedItems = {
2
+ sessionId: string;
3
+ items: Array<{ productId: string; name: string; quantity: number; reason: string }>;
4
+ };
@@ -0,0 +1,26 @@
1
+ import type { InMemoryEventStore } from '@event-driven-io/emmett';
2
+
3
+ export class ReadModel<T extends Record<string, unknown>> {
4
+ private collection;
5
+
6
+ constructor(eventStore: InMemoryEventStore, collectionName: string) {
7
+ this.collection = eventStore.database.collection<T>(collectionName);
8
+ }
9
+
10
+ async getAll(): Promise<T[]> {
11
+ return this.collection.find();
12
+ }
13
+
14
+ async getById(id: string, idField: keyof T = 'id' as keyof T): Promise<T | null> {
15
+ return this.collection.findOne((doc) => doc[idField] === id);
16
+ }
17
+
18
+ async find(filterFn: (item: T) => boolean): Promise<T[]> {
19
+ return this.collection.find(filterFn);
20
+ }
21
+
22
+ async first(filterFn: (item: T) => boolean): Promise<T | null> {
23
+ const all = await this.collection.find(filterFn);
24
+ return all[0] ?? null;
25
+ }
26
+ }
@@ -2,4 +2,3 @@ export * from './types';
2
2
  export * from './ReadModel';
3
3
  export * from './reactorSpecification';
4
4
  export * from './sendCommand';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1,35 +1,98 @@
1
- import { isErrorConstructor, AssertionError, assertTrue } from '@event-driven-io/emmett';
1
+ import {
2
+ CommandSender,
3
+ isErrorConstructor,
4
+ type ErrorConstructor,
5
+ AssertionError,
6
+ assertTrue,
7
+ type MessageProcessor,
8
+ } from '@event-driven-io/emmett';
9
+
10
+ interface CommandCheck<CommandType> {
11
+ (command: CommandType): boolean;
12
+ }
13
+
14
+ interface ErrorCheck<ErrorType> {
15
+ (error: ErrorType): boolean;
16
+ }
17
+
18
+ export type ThenThrows<ErrorType extends Error> =
19
+ | (() => void)
20
+ | ((errorConstructor: ErrorConstructor<ErrorType>) => void)
21
+ | ((errorCheck: ErrorCheck<ErrorType>) => void)
22
+ | ((errorConstructor: ErrorConstructor<ErrorType>, errorCheck?: ErrorCheck<ErrorType>) => void);
23
+
24
+ interface ReactorSpecificationReturn<Event, Command, Context> {
25
+ when: (
26
+ event: Event | Event[],
27
+ context?: Context,
28
+ ) => {
29
+ then: (expectedCommand: Command | Command[] | CommandCheck<Command> | CommandCheck<Command[]>) => Promise<void>;
30
+ thenNothingHappened: () => Promise<void>;
31
+ thenThrows: <ErrorType extends Error = Error>(...args: Parameters<ThenThrows<ErrorType>>) => Promise<void>;
32
+ };
33
+ }
34
+
35
+ export interface ReactorSpecification<
36
+ Event,
37
+ Command,
38
+ Context extends { commandSender: CommandSender } = { commandSender: CommandSender },
39
+ > {
40
+ (givenEvents: Event | Event[]): ReactorSpecificationReturn<Event, Command, Context>;
41
+ }
42
+
2
43
  export const ReactorSpecification = {
3
44
  for: reactorSpecificationFor,
4
45
  };
5
- function createMockCommandSender() {
6
- const sentCommands = [];
7
- const send = async (command) => {
46
+
47
+ interface MockCommandSender<Command> extends CommandSender {
48
+ sentCommands: Command[];
49
+ reset: () => void;
50
+ }
51
+
52
+ function createMockCommandSender<Command>(): MockCommandSender<Command> {
53
+ const sentCommands: Command[] = [];
54
+
55
+ const send = async <CommandType extends Command = Command>(command: CommandType): Promise<void> => {
8
56
  sentCommands.push(command);
9
57
  };
58
+
10
59
  return {
11
60
  send,
12
61
  sentCommands,
13
62
  reset: () => {
14
63
  sentCommands.length = 0;
15
64
  },
16
- };
65
+ } as MockCommandSender<Command>;
17
66
  }
18
- function reactorSpecificationFor(processorOrReactor, createContext) {
19
- return (givenEvents) => {
67
+
68
+ type ReactorLike<Event, Context> =
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ | { handle: (events: Event[], context: Context) => Promise<any> }
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ | { eachMessage: (event: Event, context: Context) => Promise<any> }
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ | MessageProcessor<any, any, any>;
75
+
76
+ function reactorSpecificationFor<Event, Command, Context extends { commandSender: CommandSender }>(
77
+ processorOrReactor: ReactorLike<Event, Context> | (() => ReactorLike<Event, Context>),
78
+ createContext: (commandSender: CommandSender) => Context,
79
+ ): ReactorSpecification<Event, Command, Context> {
80
+ return (givenEvents: Event | Event[]) => {
20
81
  return {
21
- when: (whenEvent, contextOverride) => {
22
- const mockCommandSender = createMockCommandSender();
82
+ when: (whenEvent: Event | Event[], contextOverride?: Context) => {
83
+ const mockCommandSender = createMockCommandSender<Command>();
23
84
  const defaultContext = createContext(mockCommandSender);
24
85
  const context = contextOverride || defaultContext;
86
+
25
87
  const handle = async () => {
26
88
  const givenArray = Array.isArray(givenEvents) ? givenEvents : givenEvents != null ? [givenEvents] : [];
27
89
  const whenArray = Array.isArray(whenEvent) ? whenEvent : [whenEvent];
28
90
  const allEvents = [...givenArray, ...whenArray];
91
+
29
92
  // Transform events to have metadata
30
93
  const eventsWithMetadata = allEvents.map((event, index) => ({
31
94
  ...event,
32
- kind: 'Event',
95
+ kind: 'Event' as const,
33
96
  metadata: {
34
97
  streamName: 'test-stream',
35
98
  messageId: `test-${index}`,
@@ -37,9 +100,12 @@ function reactorSpecificationFor(processorOrReactor, createContext) {
37
100
  globalPosition: BigInt(index + 1),
38
101
  },
39
102
  }));
103
+
40
104
  const contextWithMock = { ...context, commandSender: mockCommandSender };
105
+
41
106
  // Get the actual reactor instance
42
107
  const reactor = typeof processorOrReactor === 'function' ? processorOrReactor() : processorOrReactor;
108
+
43
109
  // Handle different reactor types
44
110
  if ('handle' in reactor && typeof reactor.handle === 'function') {
45
111
  // It's a MessageProcessor or has a handle method
@@ -52,50 +118,61 @@ function reactorSpecificationFor(processorOrReactor, createContext) {
52
118
  } else {
53
119
  throw new Error('Reactor must have either a handle or eachMessage method');
54
120
  }
121
+
55
122
  return mockCommandSender.sentCommands;
56
123
  };
124
+
57
125
  return {
58
- then: async (expectedCommand) => {
126
+ then: async (
127
+ expectedCommand: Command | Command[] | CommandCheck<Command> | CommandCheck<Command[]>,
128
+ ): Promise<void> => {
59
129
  try {
60
130
  const sentCommands = await handle();
131
+
61
132
  if (typeof expectedCommand === 'function') {
62
133
  const checkFn = expectedCommand;
63
134
  if (sentCommands.length === 1) {
64
135
  assertTrue(
65
- checkFn(sentCommands[0]),
136
+ (checkFn as CommandCheck<Command>)(sentCommands[0]),
66
137
  `Sent command did not match the expected condition: ${JSON.stringify(sentCommands[0])}`,
67
138
  );
68
139
  } else {
69
140
  assertTrue(
70
- checkFn(sentCommands),
141
+ (checkFn as CommandCheck<Command[]>)(sentCommands),
71
142
  `Sent commands did not match the expected condition: ${JSON.stringify(sentCommands)}`,
72
143
  );
73
144
  }
74
145
  return;
75
146
  }
147
+
76
148
  if (Array.isArray(expectedCommand)) {
77
149
  assertTrue(
78
150
  sentCommands.length === expectedCommand.length,
79
151
  `Expected ${expectedCommand.length} command(s) to be sent, but ${sentCommands.length} were sent`,
80
152
  );
153
+
81
154
  expectedCommand.forEach((expected, index) => {
82
155
  const sent = sentCommands[index];
83
156
  assertCommandsMatch(sent, expected, index);
84
157
  });
85
158
  return;
86
159
  }
160
+
87
161
  if (sentCommands.length === 0) {
88
162
  throw new AssertionError('No commands were sent');
89
163
  }
164
+
90
165
  if (sentCommands.length > 1) {
91
166
  throw new AssertionError(`Expected 1 command to be sent, but ${sentCommands.length} were sent`);
92
167
  }
168
+
93
169
  assertCommandsMatch(sentCommands[0], expectedCommand);
94
170
  } finally {
95
171
  mockCommandSender.reset();
96
172
  }
97
173
  },
98
- thenNothingHappened: async () => {
174
+
175
+ thenNothingHappened: async (): Promise<void> => {
99
176
  try {
100
177
  const sentCommands = await handle();
101
178
  if (sentCommands.length > 0) {
@@ -107,7 +184,8 @@ function reactorSpecificationFor(processorOrReactor, createContext) {
107
184
  mockCommandSender.reset();
108
185
  }
109
186
  },
110
- thenThrows: async (...args) => {
187
+
188
+ thenThrows: async <ErrorType extends Error>(...args: Parameters<ThenThrows<ErrorType>>): Promise<void> => {
111
189
  try {
112
190
  await handle();
113
191
  throw new AssertionError('Reactor did not fail as expected');
@@ -122,17 +200,25 @@ function reactorSpecificationFor(processorOrReactor, createContext) {
122
200
  };
123
201
  };
124
202
  }
203
+
204
+ interface CommandWithMetadata {
205
+ metadata?: Record<string, unknown>;
206
+ }
207
+
125
208
  // eslint-disable-next-line complexity
126
- function assertCommandsMatch(actual, expected, index) {
127
- const actualCopy = { ...actual };
128
- const expectedCopy = { ...expected };
209
+ function assertCommandsMatch<Command>(actual: Command, expected: Command, index?: number): void {
210
+ const actualCopy = { ...actual } as CommandWithMetadata & Record<string, unknown>;
211
+ const expectedCopy = { ...expected } as CommandWithMetadata & Record<string, unknown>;
212
+
129
213
  if (actualCopy.metadata !== undefined && expectedCopy.metadata !== undefined) {
130
214
  for (const key in expectedCopy.metadata) {
131
215
  const expectedValue = expectedCopy.metadata[key];
132
216
  const actualValue = actualCopy.metadata[key];
217
+
133
218
  const expectedStr =
134
219
  expectedValue === undefined ? 'undefined' : expectedValue === null ? 'null' : String(expectedValue);
135
220
  const actualStr = actualValue === undefined ? 'undefined' : actualValue === null ? 'null' : String(actualValue);
221
+
136
222
  assertTrue(
137
223
  actualValue === expectedValue,
138
224
  `Command${index !== undefined ? ` at index ${index}` : ''} metadata.${key} does not match.\nExpected: ${expectedStr}\nActual: ${actualStr}`,
@@ -143,21 +229,29 @@ function assertCommandsMatch(actual, expected, index) {
143
229
  } else if (actualCopy.metadata !== undefined && expectedCopy.metadata === undefined) {
144
230
  delete actualCopy.metadata;
145
231
  }
232
+
146
233
  assertTrue(
147
234
  JSON.stringify(actualCopy) === JSON.stringify(expectedCopy),
148
235
  `Command${index !== undefined ? ` at index ${index}` : ''} does not match.\nExpected: ${JSON.stringify(expected)}\nActual: ${JSON.stringify(actual)}`,
149
236
  );
150
237
  }
151
- function thenThrowsErrorHandler(error, args) {
238
+
239
+ function thenThrowsErrorHandler<ErrorType extends Error>(
240
+ error: unknown,
241
+ args: Parameters<ThenThrows<ErrorType>>,
242
+ ): void {
152
243
  if (error instanceof AssertionError) throw error;
244
+
153
245
  if (args.length === 0) return;
246
+
154
247
  if (!isErrorConstructor(args[0])) {
155
- assertTrue(args[0](error), `Error didn't match the error condition: ${error?.toString()}`);
248
+ assertTrue(args[0](error as ErrorType), `Error didn't match the error condition: ${error?.toString()}`);
156
249
  return;
157
250
  }
251
+
158
252
  assertTrue(error instanceof args[0], `Caught error is not an instance of the expected type: ${error?.toString()}`);
253
+
159
254
  if (args[1]) {
160
- assertTrue(args[1](error), `Error didn't match the error condition: ${error?.toString()}`);
255
+ assertTrue(args[1](error as ErrorType), `Error didn't match the error condition: ${error?.toString()}`);
161
256
  }
162
257
  }
163
- //# sourceMappingURL=reactorSpecification.js.map
@@ -0,0 +1,21 @@
1
+ import type { Command, CommandSender } from '@event-driven-io/emmett';
2
+ import type { MutationResponse } from './types';
3
+
4
+ export async function sendCommand<T extends Command>(
5
+ commandSender: CommandSender,
6
+ command: T,
7
+ ): Promise<MutationResponse> {
8
+ try {
9
+ await commandSender.send(command);
10
+ return { success: true };
11
+ } catch (error: unknown) {
12
+ const err = error as { name?: string; message?: string };
13
+ return {
14
+ success: false,
15
+ error: {
16
+ type: err?.name ?? 'UnknownError',
17
+ message: err?.message ?? 'An unexpected error occurred',
18
+ },
19
+ };
20
+ }
21
+ }