create-auto-app 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/templates/.gitkeep +0 -0
- package/templates/shopping-app/.context/schema.json +11 -51
- 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/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 +61 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.ts +35 -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 +49 -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 +94 -0
- package/templates/shopping-app/.context/server/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.ts +37 -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 +162 -4
- package/templates/shopping-app/client/package.json +1 -1
- 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 +1 -1
- package/templates/shopping-app/example-integrations/cart/package.json +1 -1
- package/templates/shopping-app/example-integrations/product-catalogue/package.json +1 -1
- package/templates/shopping-app/example-integrations/product-catalogue/src/product-catalogue-integration.ts +122 -115
- package/templates/shopping-app/flows/shopping-assistant.flow.ts +0 -1
- package/templates/shopping-app/package.json +13 -10
- package/templates/shopping-app/server/package.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,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
|
+
}
|
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
import { CommandSender, InMemoryEventStore } from '@event-driven-io/emmett';
|
|
2
|
+
import { Field, ObjectType } from 'type-graphql';
|
|
3
|
+
|
|
2
4
|
export interface ReactorContext {
|
|
3
5
|
eventStore: InMemoryEventStore;
|
|
4
6
|
commandSender: CommandSender;
|
|
5
7
|
[key: string]: unknown;
|
|
6
8
|
}
|
|
9
|
+
|
|
7
10
|
export interface GraphQLContext {
|
|
8
11
|
eventStore: InMemoryEventStore;
|
|
9
12
|
messageBus: CommandSender;
|
|
10
13
|
}
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
@ObjectType()
|
|
16
|
+
export class MutationError {
|
|
17
|
+
@Field(() => String)
|
|
18
|
+
type!: string;
|
|
19
|
+
|
|
20
|
+
@Field(() => String, { nullable: true })
|
|
13
21
|
message?: string;
|
|
14
22
|
}
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
|
|
24
|
+
@ObjectType()
|
|
25
|
+
export class MutationResponse {
|
|
26
|
+
@Field(() => Boolean)
|
|
27
|
+
success!: boolean;
|
|
28
|
+
|
|
29
|
+
@Field(() => MutationError, { nullable: true })
|
|
17
30
|
error?: MutationError;
|
|
18
31
|
}
|
|
19
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { ApolloServer } from 'apollo-server';
|
|
3
|
+
import { buildSchema } from 'type-graphql';
|
|
4
|
+
import { loadProjections, loadRegisterFiles, loadResolvers } from './utils';
|
|
5
|
+
import {
|
|
6
|
+
getInMemoryEventStore,
|
|
7
|
+
getInMemoryMessageBus,
|
|
8
|
+
projections,
|
|
9
|
+
forwardToMessageBus,
|
|
10
|
+
} from '@event-driven-io/emmett';
|
|
11
|
+
|
|
12
|
+
async function start() {
|
|
13
|
+
const loadedProjections = await loadProjections('src/domain/flows/**/projection.{ts,js}');
|
|
14
|
+
const registrations = await loadRegisterFiles('src/domain/flows/**/register.{ts,js}');
|
|
15
|
+
|
|
16
|
+
const messageBus = getInMemoryMessageBus();
|
|
17
|
+
|
|
18
|
+
const eventStore = getInMemoryEventStore({
|
|
19
|
+
projections: projections.inline(loadedProjections),
|
|
20
|
+
hooks: {
|
|
21
|
+
onAfterCommit: forwardToMessageBus(messageBus),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
await Promise.all(registrations.map((r) => r.register(messageBus, eventStore)));
|
|
26
|
+
|
|
27
|
+
const resolvers = await loadResolvers('src/domain/flows/**/*.resolver.{ts,js}');
|
|
28
|
+
const schema = await buildSchema({
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
resolvers: resolvers as unknown as [(...args: any[]) => any, ...Array<(...args: any[]) => any>],
|
|
31
|
+
});
|
|
32
|
+
const server = new ApolloServer({
|
|
33
|
+
schema,
|
|
34
|
+
context: () => ({
|
|
35
|
+
eventStore,
|
|
36
|
+
messageBus,
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
const { url } = await server.listen({ port: 4000 });
|
|
40
|
+
console.log(`🚀 GraphQL server ready at ${url}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void start();
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import fg from 'fast-glob';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
|
|
3
|
+
import type { ProjectionDefinition } from '@event-driven-io/emmett';
|
|
4
|
+
|
|
5
|
+
export async function loadProjections(source: string): Promise<ProjectionDefinition[]> {
|
|
4
6
|
const files = await fg(source, { absolute: true });
|
|
7
|
+
|
|
5
8
|
const modules = await Promise.all(
|
|
6
9
|
files.map(async (file) => {
|
|
7
|
-
const mod = await import(pathToFileUrl(file).href);
|
|
10
|
+
const mod: unknown = await import(pathToFileUrl(file).href);
|
|
11
|
+
|
|
8
12
|
if (typeof mod === 'object' && mod !== null && 'projection' in mod) {
|
|
9
|
-
const projectionModule = mod;
|
|
13
|
+
const projectionModule = mod as { projection?: ProjectionDefinition };
|
|
10
14
|
if (projectionModule.projection == null) {
|
|
11
15
|
console.warn(`⚠️ Projection file "${file}" does not export "projection"`);
|
|
12
16
|
}
|
|
@@ -16,10 +20,11 @@ export async function loadProjections(source) {
|
|
|
16
20
|
return undefined;
|
|
17
21
|
}),
|
|
18
22
|
);
|
|
19
|
-
|
|
23
|
+
|
|
24
|
+
return modules.filter((p): p is ProjectionDefinition => p != null);
|
|
20
25
|
}
|
|
21
|
-
|
|
26
|
+
|
|
27
|
+
function pathToFileUrl(filePath: string): URL {
|
|
22
28
|
const resolved = path.resolve(filePath);
|
|
23
29
|
return new URL(`file://${resolved}`);
|
|
24
30
|
}
|
|
25
|
-
//# sourceMappingURL=loadProjections.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fg from 'fast-glob';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
|
|
4
|
+
|
|
5
|
+
export interface SliceRegistration {
|
|
6
|
+
register: (messageBus: CommandProcessor, eventStore: EventStore) => Promise<unknown> | void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function loadRegisterFiles(source: string): Promise<SliceRegistration[]> {
|
|
10
|
+
const files = await fg(source, { absolute: true });
|
|
11
|
+
|
|
12
|
+
const modules = await Promise.all(
|
|
13
|
+
files.map(async (file) => {
|
|
14
|
+
try {
|
|
15
|
+
const mod: unknown = await import(pathToFileUrl(file).href);
|
|
16
|
+
|
|
17
|
+
if (
|
|
18
|
+
typeof mod === 'object' &&
|
|
19
|
+
mod !== null &&
|
|
20
|
+
'register' in mod &&
|
|
21
|
+
typeof (mod as SliceRegistration).register === 'function'
|
|
22
|
+
) {
|
|
23
|
+
return mod as SliceRegistration;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.warn('⚠️ Skipping invalid register.ts at', file);
|
|
27
|
+
return null;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error('❌ Failed to import', file, ':', error);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return modules.filter((m): m is SliceRegistration => m !== null);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function pathToFileUrl(filePath: string): URL {
|
|
39
|
+
const resolved = path.resolve(filePath);
|
|
40
|
+
return new URL(`file://${resolved}`);
|
|
41
|
+
}
|
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import fg from 'fast-glob';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
export interface Resolver {
|
|
4
|
+
(...args: unknown[]): unknown;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export async function loadResolvers(source: string): Promise<Resolver[]> {
|
|
3
8
|
const files = await fg(source, {
|
|
4
9
|
absolute: true,
|
|
5
10
|
});
|
|
6
|
-
const modules = await Promise.all(files.map((file) => import(file)));
|
|
7
|
-
const allResolvers = [];
|
|
11
|
+
const modules: unknown[] = await Promise.all(files.map((file) => import(file)));
|
|
12
|
+
const allResolvers: Resolver[] = [];
|
|
13
|
+
|
|
8
14
|
for (const mod of modules) {
|
|
9
15
|
if (typeof mod !== 'object' || mod === null) {
|
|
10
16
|
continue;
|
|
11
17
|
}
|
|
18
|
+
|
|
12
19
|
for (const key of Object.keys(mod)) {
|
|
13
|
-
const exported = mod[key];
|
|
20
|
+
const exported = (mod as Record<string, unknown>)[key];
|
|
21
|
+
|
|
14
22
|
if (typeof exported === 'function') {
|
|
15
|
-
allResolvers.push(exported);
|
|
23
|
+
allResolvers.push(exported as Resolver);
|
|
16
24
|
}
|
|
25
|
+
|
|
17
26
|
if (Array.isArray(exported) && exported.every((r) => typeof r === 'function')) {
|
|
18
|
-
allResolvers.push(...exported);
|
|
27
|
+
allResolvers.push(...(exported as Resolver[]));
|
|
19
28
|
}
|
|
20
29
|
}
|
|
21
30
|
}
|
|
31
|
+
|
|
22
32
|
if (allResolvers.length === 0) {
|
|
23
33
|
throw new Error('❌ No resolvers found for any slices.');
|
|
24
34
|
}
|
|
25
35
|
return allResolvers;
|
|
26
36
|
}
|
|
27
|
-
//# sourceMappingURL=loadResolvers.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"emitDecoratorMetadata": true,
|
|
9
|
+
"experimentalDecorators": true
|
|
10
|
+
},
|
|
11
|
+
"include": ["src/**/*", "vitest.config.ts"],
|
|
12
|
+
"exclude": ["dist", "node_modules"]
|
|
13
|
+
}
|