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.
- package/README.md +197 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/templates/.gitkeep +0 -0
- package/templates/shopping-app/.context/schema.json +389 -218
- package/templates/shopping-app/.context/server/.context/auto-ia-scheme.json +79 -0
- package/templates/shopping-app/.context/server/server/package.json +26 -0
- package/templates/shopping-app/.context/server/server/scripts/generate-schema.ts +34 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/commands.ts +8 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.specs.ts +46 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.ts +33 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/events.ts +10 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/evolve.ts +28 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/handle.ts +24 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/mutation.resolver.ts +25 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/register.ts +7 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/state.ts +47 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.specs.ts +51 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/react.ts +43 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session/register.ts +24 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.specs.ts +51 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.ts +43 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/register.ts +24 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/commands.ts +8 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.specs.ts +38 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.ts +33 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/events.ts +10 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/evolve.ts +28 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/handle.ts +24 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/mutation.resolver.ts +25 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/register.ts +7 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/state.ts +47 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/commands.ts +8 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.specs.ts +101 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/decide.ts +42 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/events.ts +9 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/evolve.ts +28 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/handle.ts +52 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/mutation.resolver.ts +25 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/register.ts +7 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria/state.ts +47 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/commands.ts +8 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.specs.ts +101 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.ts +43 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/events.ts +9 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/evolve.ts +28 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/handle.ts +52 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/mutation.resolver.ts +25 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/register.ts +7 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/state.ts +47 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.specs.ts +56 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.ts +24 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/query.resolver.ts +56 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/state.ts +4 -0
- package/templates/shopping-app/.context/server/server/src/domain/shared/ReadModel.ts +26 -0
- package/templates/shopping-app/{server/src/domain/shared/index.d.ts → .context/server/server/src/domain/shared/index.ts} +0 -1
- package/templates/shopping-app/{server/src/domain/shared/reactorSpecification.js → .context/server/server/src/domain/shared/reactorSpecification.ts} +116 -22
- package/templates/shopping-app/.context/server/server/src/domain/shared/sendCommand.ts +21 -0
- package/templates/shopping-app/{server/src/domain/shared/types.d.ts → .context/server/server/src/domain/shared/types.ts} +17 -5
- package/templates/shopping-app/.context/server/server/src/server.ts +43 -0
- package/templates/shopping-app/{server/src/utils/index.d.ts → .context/server/server/src/utils/index.ts} +0 -1
- package/templates/shopping-app/{server/src/utils/loadProjections.js → .context/server/server/src/utils/loadProjections.ts} +11 -6
- package/templates/shopping-app/.context/server/server/src/utils/loadRegisterFiles.ts +41 -0
- package/templates/shopping-app/{server/src/utils/loadResolvers.js → .context/server/server/src/utils/loadResolvers.ts} +16 -7
- package/templates/shopping-app/.context/server/server/tsconfig.json +13 -0
- package/templates/shopping-app/.context/server/server/vitest.config.ts +7 -0
- package/templates/shopping-app/auto.config.ts +78 -45
- package/templates/shopping-app/client/package.json +4 -4
- package/templates/shopping-app/client/src/App.tsx +13 -13
- package/templates/shopping-app/client/src/components/molecules/QuantitySelector.tsx +4 -4
- package/templates/shopping-app/client/src/components/molecules/ShoppingCriteriaForm.tsx +4 -4
- package/templates/shopping-app/client/src/components/molecules/SuggestedItemCard.tsx +6 -6
- package/templates/shopping-app/client/src/components/organisms/AssistantChatInterface.tsx +3 -3
- package/templates/shopping-app/client/src/components/organisms/PageHeader.tsx +2 -3
- package/templates/shopping-app/client/src/components/organisms/SuggestedItemsList.tsx +3 -3
- package/templates/shopping-app/client/src/index.css +10 -14
- package/templates/shopping-app/client/src/pages/AssistantChatPage.tsx +4 -4
- package/templates/shopping-app/client/src/pages/SuggestedItemsPage.tsx +4 -4
- package/templates/shopping-app/example-integrations/ai-chat-completion/package.json +5 -6
- package/templates/shopping-app/example-integrations/ai-chat-completion/src/ai-integration.ts +2 -2
- package/templates/shopping-app/example-integrations/cart/package.json +5 -6
- package/templates/shopping-app/example-integrations/cart-api/package.json +3 -3
- package/templates/shopping-app/example-integrations/product-catalogue/package.json +5 -5
- package/templates/shopping-app/example-integrations/product-catalogue/src/product-catalogue-integration.ts +3 -128
- package/templates/shopping-app/example-integrations/product-catalogue-api/package.json +3 -3
- package/templates/shopping-app/flows/shopping-assistant.flow.ts +195 -196
- package/templates/shopping-app/package.json +16 -11
- package/templates/shopping-app/server/package.json +4 -4
- package/templates/shopping-app/server/src/integrations/ai-integration.ts +2 -2
- package/templates/shopping-app/tsconfig.json +2 -2
- package/templates/shopping-app/.env +0 -8
- package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-build.log +0 -4
- package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-format.log +0 -12
- package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-lint.log +0 -4
- package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-test.log +0 -12
- package/templates/shopping-app/example-integrations/ai-chat-completion/.turbo/turbo-type-check.log +0 -5
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.d.ts +0 -23
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.js +0 -41
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/ai-integration.js.map +0 -1
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.d.ts +0 -2
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.js +0 -2
- package/templates/shopping-app/example-integrations/ai-chat-completion/dist/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/eslint +0 -21
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/jiti +0 -21
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/msw +0 -21
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/tsc +0 -21
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/tsserver +0 -21
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/vite +0 -21
- package/templates/shopping-app/example-integrations/ai-chat-completion/node_modules/.bin/vitest +0 -21
- package/templates/shopping-app/example-integrations/cart/.turbo/turbo-build.log +0 -4
- package/templates/shopping-app/example-integrations/cart/.turbo/turbo-format.log +0 -12
- package/templates/shopping-app/example-integrations/cart/.turbo/turbo-lint.log +0 -5
- package/templates/shopping-app/example-integrations/cart/.turbo/turbo-test.log +0 -12
- package/templates/shopping-app/example-integrations/cart/.turbo/turbo-type-check.log +0 -5
- package/templates/shopping-app/example-integrations/cart/dist/cart-integration.d.ts +0 -30
- package/templates/shopping-app/example-integrations/cart/dist/cart-integration.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/cart-integration.js +0 -134
- package/templates/shopping-app/example-integrations/cart/dist/cart-integration.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.d.ts +0 -3
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.js +0 -149
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/client.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.d.ts +0 -8
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.js +0 -6
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.d.ts +0 -123
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.js +0 -3
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/types.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.d.ts +0 -46
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.js +0 -285
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client/utils.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.d.ts +0 -13
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.js +0 -6
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/client.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.d.ts +0 -19
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.js +0 -15
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/auth.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.d.ts +0 -18
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.js +0 -58
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/bodySerializer.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.d.ts +0 -34
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.js +0 -89
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/params.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.d.ts +0 -34
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.js +0 -115
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/pathSerializer.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.d.ts +0 -79
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.js +0 -3
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/core/types.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.d.ts +0 -2
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.js +0 -3
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.d.ts +0 -158
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.js +0 -3
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/types.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.d.ts +0 -382
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.js +0 -68
- package/templates/shopping-app/example-integrations/cart/dist/generated/cart/zod.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/index.d.ts +0 -2
- package/templates/shopping-app/example-integrations/cart/dist/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart/dist/index.js +0 -2
- package/templates/shopping-app/example-integrations/cart/dist/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart/node_modules/.bin/eslint +0 -21
- package/templates/shopping-app/example-integrations/cart/node_modules/.bin/jiti +0 -21
- package/templates/shopping-app/example-integrations/cart/node_modules/.bin/msw +0 -21
- package/templates/shopping-app/example-integrations/cart/node_modules/.bin/tsc +0 -21
- package/templates/shopping-app/example-integrations/cart/node_modules/.bin/tsserver +0 -21
- package/templates/shopping-app/example-integrations/cart/node_modules/.bin/vitest +0 -21
- package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-build.log +0 -4
- package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-format.log +0 -10
- package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-lint.log +0 -4
- package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-test.log +0 -12
- package/templates/shopping-app/example-integrations/cart-api/.turbo/turbo-type-check.log +0 -4
- package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.d.ts +0 -18
- package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.js +0 -28
- package/templates/shopping-app/example-integrations/cart-api/dist/data/cart.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart-api/dist/index.d.ts +0 -4
- package/templates/shopping-app/example-integrations/cart-api/dist/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart-api/dist/index.js +0 -49
- package/templates/shopping-app/example-integrations/cart-api/dist/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.d.ts +0 -4
- package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.js +0 -261
- package/templates/shopping-app/example-integrations/cart-api/dist/routes/cart.js.map +0 -1
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/nodemon +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/swagger-jsdoc +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-cwd +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-esm +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-script +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-node-transpile-only +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/ts-script +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/tsc +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/tsserver +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/tsx +0 -21
- package/templates/shopping-app/example-integrations/cart-api/node_modules/.bin/vitest +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-build.log +0 -4
- package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-format.log +0 -12
- package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-lint.log +0 -5
- package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-test.log +0 -12
- package/templates/shopping-app/example-integrations/product-catalogue/.turbo/turbo-type-check.log +0 -5
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.d.ts +0 -3
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.js +0 -149
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/client.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.d.ts +0 -8
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.js +0 -6
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.d.ts +0 -123
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.js +0 -3
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/types.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.d.ts +0 -46
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.js +0 -285
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client/utils.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.d.ts +0 -13
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.js +0 -6
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/client.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.d.ts +0 -19
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.js +0 -15
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/auth.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.d.ts +0 -18
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.js +0 -58
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/bodySerializer.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.d.ts +0 -34
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.js +0 -89
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/params.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.d.ts +0 -34
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.js +0 -115
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/pathSerializer.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.d.ts +0 -79
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.js +0 -3
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/core/types.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.d.ts +0 -2
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.js +0 -3
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.d.ts +0 -115
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.js +0 -3
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/types.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.d.ts +0 -206
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.js +0 -53
- package/templates/shopping-app/example-integrations/product-catalogue/dist/generated/product-catalog/zod.gen.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/index.d.ts +0 -2
- package/templates/shopping-app/example-integrations/product-catalogue/dist/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/index.js +0 -2
- package/templates/shopping-app/example-integrations/product-catalogue/dist/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.d.ts +0 -32
- package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.js +0 -163
- package/templates/shopping-app/example-integrations/product-catalogue/dist/product-catalogue-integration.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/eslint +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/jiti +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/msw +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/tsc +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/tsserver +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue/node_modules/.bin/vitest +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-build.log +0 -4
- package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-format.log +0 -10
- package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-lint.log +0 -5
- package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-test.log +0 -13
- package/templates/shopping-app/example-integrations/product-catalogue-api/.turbo/turbo-type-check.log +0 -5
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.d.ts +0 -10
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.js +0 -75
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/data/products.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.d.ts +0 -4
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.js +0 -49
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/index.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.d.ts +0 -4
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.d.ts.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.js +0 -170
- package/templates/shopping-app/example-integrations/product-catalogue-api/dist/routes/products.js.map +0 -1
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/nodemon +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/swagger-jsdoc +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-cwd +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-esm +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-script +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-node-transpile-only +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/ts-script +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/tsc +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/tsserver +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/tsx +0 -21
- package/templates/shopping-app/example-integrations/product-catalogue-api/node_modules/.bin/vitest +0 -21
- package/templates/shopping-app/pnpm-workspace.yaml +0 -2
- package/templates/shopping-app/server/src/domain/shared/ReadModel.d.ts +0 -10
- package/templates/shopping-app/server/src/domain/shared/ReadModel.d.ts.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/ReadModel.js +0 -19
- package/templates/shopping-app/server/src/domain/shared/ReadModel.js.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/index.d.ts.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/index.js +0 -5
- package/templates/shopping-app/server/src/domain/shared/index.js.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/reactorSpecification.d.ts +0 -56
- package/templates/shopping-app/server/src/domain/shared/reactorSpecification.d.ts.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/reactorSpecification.js.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/sendCommand.d.ts +0 -7
- package/templates/shopping-app/server/src/domain/shared/sendCommand.d.ts.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/sendCommand.js +0 -16
- package/templates/shopping-app/server/src/domain/shared/sendCommand.js.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/types.d.ts.map +0 -1
- package/templates/shopping-app/server/src/domain/shared/types.js +0 -40
- package/templates/shopping-app/server/src/domain/shared/types.js.map +0 -1
- package/templates/shopping-app/server/src/utils/index.d.ts.map +0 -1
- package/templates/shopping-app/server/src/utils/index.js +0 -4
- package/templates/shopping-app/server/src/utils/index.js.map +0 -1
- package/templates/shopping-app/server/src/utils/loadProjections.d.ts +0 -3
- package/templates/shopping-app/server/src/utils/loadProjections.d.ts.map +0 -1
- package/templates/shopping-app/server/src/utils/loadProjections.js.map +0 -1
- package/templates/shopping-app/server/src/utils/loadRegisterFiles.d.ts +0 -6
- package/templates/shopping-app/server/src/utils/loadRegisterFiles.d.ts.map +0 -1
- package/templates/shopping-app/server/src/utils/loadRegisterFiles.js +0 -26
- package/templates/shopping-app/server/src/utils/loadRegisterFiles.js.map +0 -1
- package/templates/shopping-app/server/src/utils/loadResolvers.d.ts +0 -5
- package/templates/shopping-app/server/src/utils/loadResolvers.d.ts.map +0 -1
- 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,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,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
|
+
}
|
|
@@ -1,35 +1,98 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
}
|