create-auto-app 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/index.js +125 -111
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -2
  4. package/templates/shopping-app/.context/auto-ia-scheme.json +8 -29
  5. package/templates/shopping-app/.context/design-system.md +59 -35
  6. package/templates/shopping-app/.context/figma-variables.json +335 -1024
  7. package/templates/shopping-app/.context/schema.json +3 -7
  8. package/templates/shopping-app/.context/shadcn-filter.ts +2 -4
  9. package/templates/shopping-app/auto.config.ts +2 -2
  10. package/templates/shopping-app/client/src/gql/fragment-masking.ts +22 -22
  11. package/templates/shopping-app/client/src/gql/gql.ts +12 -5
  12. package/templates/shopping-app/client/src/gql/graphql.ts +125 -11
  13. package/templates/shopping-app/client/src/gql/index.ts +2 -2
  14. package/templates/shopping-app/client/src/graphql/mutations.ts +9 -9
  15. package/templates/shopping-app/client/src/graphql/queries.ts +10 -10
  16. package/templates/shopping-app/flows/shopping-assistant.flow.ts +2 -2
  17. package/templates/shopping-app/package.json +1 -1
  18. package/templates/shopping-app/pnpm-workspace.yaml +2 -2
  19. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/commands.ts +2 -2
  20. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.specs.ts +20 -20
  21. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/decide.ts +8 -11
  22. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/events.ts +2 -2
  23. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/evolve.ts +3 -3
  24. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/handle.ts +8 -15
  25. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/mutation.resolver.ts +5 -9
  26. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/accepts-items-and-adds-to-their-cart/register.ts +4 -7
  27. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.specs.ts +19 -31
  28. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/react.ts +6 -12
  29. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/creates-a-chat-session-/register.ts +4 -11
  30. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/commands.ts +2 -2
  31. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.specs.ts +14 -14
  32. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/decide.ts +8 -11
  33. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/events.ts +2 -2
  34. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/evolve.ts +3 -3
  35. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/handle.ts +8 -15
  36. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/mutation.resolver.ts +5 -9
  37. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant/register.ts +4 -7
  38. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/commands.ts +2 -2
  39. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.specs.ts +23 -23
  40. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/decide.ts +9 -13
  41. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/events.ts +2 -2
  42. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/evolve.ts +3 -3
  43. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/handle.ts +11 -18
  44. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/mutation.resolver.ts +5 -9
  45. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/selects-items-relevant-to-the-shopping-criteria-/register.ts +4 -7
  46. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.specs.ts +35 -35
  47. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/views-suggested-items/projection.ts +8 -11
  48. package/templates/shopping-app/server/src/domain/flows/seasonal-assistant/views-suggested-items/query.resolver.ts +4 -7
  49. package/templates/shopping-app/server/src/domain/shared/ReadModel.d.ts +7 -7
  50. package/templates/shopping-app/server/src/domain/shared/ReadModel.js +17 -17
  51. package/templates/shopping-app/server/src/domain/shared/index.d.ts +1 -1
  52. package/templates/shopping-app/server/src/domain/shared/index.js +1 -1
  53. package/templates/shopping-app/server/src/domain/shared/reactorSpecification.d.ts +42 -21
  54. package/templates/shopping-app/server/src/domain/shared/reactorSpecification.js +148 -140
  55. package/templates/shopping-app/server/src/domain/shared/sendCommand.d.ts +5 -2
  56. package/templates/shopping-app/server/src/domain/shared/sendCommand.js +14 -15
  57. package/templates/shopping-app/server/src/domain/shared/types.d.ts +10 -10
  58. package/templates/shopping-app/server/src/domain/shared/types.js +37 -36
  59. package/templates/shopping-app/server/src/integrations/ai-integration.ts +1 -1
  60. package/templates/shopping-app/server/src/integrations/cart-integration.ts +1 -1
  61. package/templates/shopping-app/server/src/integrations/index.ts +1 -1
  62. package/templates/shopping-app/server/src/integrations/product-catalogue-integration.ts +1 -1
  63. package/templates/shopping-app/server/src/utils/index.d.ts +1 -1
  64. package/templates/shopping-app/server/src/utils/index.js +1 -1
  65. package/templates/shopping-app/server/src/utils/loadProjections.d.ts +1 -1
  66. package/templates/shopping-app/server/src/utils/loadProjections.js +18 -16
  67. package/templates/shopping-app/server/src/utils/loadRegisterFiles.d.ts +2 -2
  68. package/templates/shopping-app/server/src/utils/loadRegisterFiles.js +19 -21
  69. package/templates/shopping-app/server/src/utils/loadResolvers.d.ts +2 -2
  70. package/templates/shopping-app/server/src/utils/loadResolvers.js +22 -22
  71. package/templates/shopping-app/server/tsconfig.json +2 -8
  72. package/templates/shopping-app/tsconfig.json +2 -8
@@ -1,31 +1,19 @@
1
- import { describe, it, beforeEach } from "vitest";
2
- import "reflect-metadata";
3
- import {
4
- getInMemoryEventStore,
5
- type InMemoryEventStore,
6
- type CommandSender,
7
- } from "@event-driven-io/emmett";
8
- import { type ReactorContext, ReactorSpecification } from "../../../shared";
9
- import { react } from "./react";
10
- import type { ShoppingCriteriaEntered } from "../enters-shopping-criteria-into-assistant/events";
11
- import type { SuggestShoppingItems } from "../selects-items-relevant-to-the-shopping-criteria-/commands";
1
+ import { describe, it, beforeEach } from 'vitest';
2
+ import 'reflect-metadata';
3
+ import { getInMemoryEventStore, type InMemoryEventStore, type CommandSender } from '@event-driven-io/emmett';
4
+ import { type ReactorContext, ReactorSpecification } from '../../../shared';
5
+ import { react } from './react';
6
+ import type { ShoppingCriteriaEntered } from '../enters-shopping-criteria-into-assistant/events';
7
+ import type { SuggestShoppingItems } from '../selects-items-relevant-to-the-shopping-criteria-/commands';
12
8
 
13
- describe("SeasonalAssistant | CreatesAChatSession", () => {
9
+ describe('SeasonalAssistant | CreatesAChatSession', () => {
14
10
  let eventStore: InMemoryEventStore;
15
- let given: ReactorSpecification<
16
- ShoppingCriteriaEntered,
17
- SuggestShoppingItems,
18
- ReactorContext
19
- >;
11
+ let given: ReactorSpecification<ShoppingCriteriaEntered, SuggestShoppingItems, ReactorContext>;
20
12
  let messageBus: CommandSender;
21
13
 
22
14
  beforeEach(() => {
23
15
  eventStore = getInMemoryEventStore({});
24
- given = ReactorSpecification.for<
25
- ShoppingCriteriaEntered,
26
- SuggestShoppingItems,
27
- ReactorContext
28
- >(
16
+ given = ReactorSpecification.for<ShoppingCriteriaEntered, SuggestShoppingItems, ReactorContext>(
29
17
  () => react({ eventStore, commandSender: messageBus }),
30
18
  (commandSender) => {
31
19
  messageBus = commandSender;
@@ -38,25 +26,25 @@ describe("SeasonalAssistant | CreatesAChatSession", () => {
38
26
  );
39
27
  });
40
28
 
41
- it("should send SuggestShoppingItems when ShoppingCriteriaEntered is received", async () => {
29
+ it('should send SuggestShoppingItems when ShoppingCriteriaEntered is received', async () => {
42
30
  await given([])
43
31
  .when({
44
- type: "ShoppingCriteriaEntered",
32
+ type: 'ShoppingCriteriaEntered',
45
33
  data: {
46
- sessionId: "session-abc",
34
+ sessionId: 'session-abc',
47
35
  criteria:
48
- "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
49
- timestamp: new Date("2025-08-28T04:56:47.408Z"),
36
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
37
+ timestamp: new Date('2025-08-28T04:56:47.408Z'),
50
38
  },
51
39
  })
52
40
 
53
41
  .then({
54
- type: "SuggestShoppingItems",
55
- kind: "Command",
42
+ type: 'SuggestShoppingItems',
43
+ kind: 'Command',
56
44
  data: {
57
- sessionId: "session-abc",
45
+ sessionId: 'session-abc',
58
46
  prompt:
59
- "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
47
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
60
48
  },
61
49
  });
62
50
  });
@@ -1,15 +1,11 @@
1
- import {
2
- inMemoryReactor,
3
- type MessageHandlerResult,
4
- IllegalStateError,
5
- } from "@event-driven-io/emmett";
6
- import type { ShoppingCriteriaEntered } from "../enters-shopping-criteria-into-assistant/events";
7
- import type { ReactorContext } from "../../../shared";
1
+ import { inMemoryReactor, type MessageHandlerResult, IllegalStateError } from '@event-driven-io/emmett';
2
+ import type { ShoppingCriteriaEntered } from '../enters-shopping-criteria-into-assistant/events';
3
+ import type { ReactorContext } from '../../../shared';
8
4
 
9
5
  export const react = ({ eventStore, commandSender }: ReactorContext) =>
10
6
  inMemoryReactor<ShoppingCriteriaEntered>({
11
- processorId: "seasonal-assistant-creates-a-chat-session-",
12
- canHandle: ["ShoppingCriteriaEntered"],
7
+ processorId: 'seasonal-assistant-creates-a-chat-session-',
8
+ canHandle: ['ShoppingCriteriaEntered'],
13
9
  connectionOptions: {
14
10
  database: eventStore.database,
15
11
  },
@@ -23,9 +19,7 @@ export const react = ({ eventStore, commandSender }: ReactorContext) =>
23
19
  * - Optionally return a MessageHandlerResult for SKIP or error cases.
24
20
  */
25
21
 
26
- throw new IllegalStateError(
27
- "Not yet implemented: react in response to ShoppingCriteriaEntered",
28
- );
22
+ throw new IllegalStateError('Not yet implemented: react in response to ShoppingCriteriaEntered');
29
23
 
30
24
  // Example:
31
25
  // if (event.data.status !== 'expected') {
@@ -1,14 +1,7 @@
1
- import {
2
- type CommandSender,
3
- type EventSubscription,
4
- type InMemoryEventStore,
5
- } from "@event-driven-io/emmett";
6
- import type { ShoppingCriteriaEntered } from "../enters-shopping-criteria-into-assistant/events";
1
+ import { type CommandSender, type EventSubscription, type InMemoryEventStore } from '@event-driven-io/emmett';
2
+ import type { ShoppingCriteriaEntered } from '../enters-shopping-criteria-into-assistant/events';
7
3
 
8
- export async function register(
9
- messageBus: CommandSender & EventSubscription,
10
- eventStore: InMemoryEventStore,
11
- ) {
4
+ export async function register(messageBus: CommandSender & EventSubscription, eventStore: InMemoryEventStore) {
12
5
  messageBus.subscribe(async (event: ShoppingCriteriaEntered) => {
13
6
  /**
14
7
  * ## IMPLEMENTATION INSTRUCTIONS ##
@@ -27,5 +20,5 @@ export async function register(
27
20
  // });
28
21
 
29
22
  return;
30
- }, "ShoppingCriteriaEntered");
23
+ }, 'ShoppingCriteriaEntered');
31
24
  }
@@ -1,6 +1,6 @@
1
- import { Command } from "@event-driven-io/emmett";
1
+ import { Command } from '@event-driven-io/emmett';
2
2
  export type EnterShoppingCriteria = Command<
3
- "EnterShoppingCriteria",
3
+ 'EnterShoppingCriteria',
4
4
  {
5
5
  sessionId: string;
6
6
  criteria: string;
@@ -1,36 +1,36 @@
1
- import { describe, it } from "vitest";
2
- import { DeciderSpecification } from "@event-driven-io/emmett";
3
- import { decide } from "./decide";
4
- import { evolve } from "./evolve";
5
- import { initialState } from "./state";
1
+ import { describe, it } from 'vitest';
2
+ import { DeciderSpecification } from '@event-driven-io/emmett';
3
+ import { decide } from './decide';
4
+ import { evolve } from './evolve';
5
+ import { initialState } from './state';
6
6
 
7
- describe("Seasonal Assistant | enters shopping criteria into assistant", () => {
7
+ describe('Seasonal Assistant | enters shopping criteria into assistant', () => {
8
8
  const given = DeciderSpecification.for({
9
9
  decide,
10
10
  evolve,
11
11
  initialState,
12
12
  });
13
13
 
14
- it("should emit ShoppingCriteriaEntered for valid EnterShoppingCriteria", () => {
14
+ it('should emit ShoppingCriteriaEntered for valid EnterShoppingCriteria', () => {
15
15
  given([])
16
16
  .when({
17
- type: "EnterShoppingCriteria",
17
+ type: 'EnterShoppingCriteria',
18
18
  data: {
19
- sessionId: "shopper-123",
19
+ sessionId: 'shopper-123',
20
20
  criteria:
21
- "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
21
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
22
22
  },
23
23
  metadata: { now: new Date() },
24
24
  })
25
25
 
26
26
  .then([
27
27
  {
28
- type: "ShoppingCriteriaEntered",
28
+ type: 'ShoppingCriteriaEntered',
29
29
  data: {
30
- sessionId: "shopper-123",
30
+ sessionId: 'shopper-123',
31
31
  criteria:
32
- "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
33
- timestamp: new Date("2025-08-28T04:56:47.408Z"),
32
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
33
+ timestamp: new Date('2025-08-28T04:56:47.408Z'),
34
34
  },
35
35
  },
36
36
  ]);
@@ -1,14 +1,11 @@
1
- import { IllegalStateError } from "@event-driven-io/emmett";
2
- import type { State } from "./state";
3
- import type { EnterShoppingCriteria } from "./commands";
4
- import type { ShoppingCriteriaEntered } from "./events";
1
+ import { IllegalStateError } from '@event-driven-io/emmett';
2
+ import type { State } from './state';
3
+ import type { EnterShoppingCriteria } from './commands';
4
+ import type { ShoppingCriteriaEntered } from './events';
5
5
 
6
- export const decide = (
7
- command: EnterShoppingCriteria,
8
- state: State,
9
- ): ShoppingCriteriaEntered => {
6
+ export const decide = (command: EnterShoppingCriteria, state: State): ShoppingCriteriaEntered => {
10
7
  switch (command.type) {
11
- case "EnterShoppingCriteria": {
8
+ case 'EnterShoppingCriteria': {
12
9
  /**
13
10
  * ## IMPLEMENTATION INSTRUCTIONS ##
14
11
  *
@@ -28,9 +25,9 @@ export const decide = (
28
25
  // data: { ...command.data },
29
26
  // } as ShoppingCriteriaEntered;
30
27
 
31
- throw new IllegalStateError("Not yet implemented: " + command.type);
28
+ throw new IllegalStateError('Not yet implemented: ' + command.type);
32
29
  }
33
30
  default:
34
- throw new IllegalStateError("Unexpected command type: " + command.type);
31
+ throw new IllegalStateError('Unexpected command type: ' + command.type);
35
32
  }
36
33
  };
@@ -1,7 +1,7 @@
1
- import type { Event } from "@event-driven-io/emmett";
1
+ import type { Event } from '@event-driven-io/emmett';
2
2
 
3
3
  export type ShoppingCriteriaEntered = Event<
4
- "ShoppingCriteriaEntered",
4
+ 'ShoppingCriteriaEntered',
5
5
  {
6
6
  sessionId: string;
7
7
  criteria: string;
@@ -1,5 +1,5 @@
1
- import type { State } from "./state";
2
- import type { ShoppingCriteriaEntered } from "./events";
1
+ import type { State } from './state';
2
+ import type { ShoppingCriteriaEntered } from './events';
3
3
 
4
4
  /**
5
5
  * ## IMPLEMENTATION INSTRUCTIONS ##
@@ -16,7 +16,7 @@ import type { ShoppingCriteriaEntered } from "./events";
16
16
 
17
17
  export const evolve = (state: State, event: ShoppingCriteriaEntered): State => {
18
18
  switch (event.type) {
19
- case "ShoppingCriteriaEntered": {
19
+ case 'ShoppingCriteriaEntered': {
20
20
  // TODO: Update state based on ShoppingCriteriaEntered
21
21
  return {
22
22
  ...state,
@@ -1,22 +1,15 @@
1
- import {
2
- CommandHandler,
3
- type EventStore,
4
- type MessageHandlerResult,
5
- } from "@event-driven-io/emmett";
6
- import { evolve } from "./evolve";
7
- import { initialState } from "./state";
8
- import { decide } from "./decide";
9
- import type { EnterShoppingCriteria } from "./commands";
1
+ import { CommandHandler, type EventStore, type MessageHandlerResult } from '@event-driven-io/emmett';
2
+ import { evolve } from './evolve';
3
+ import { initialState } from './state';
4
+ import { decide } from './decide';
5
+ import type { EnterShoppingCriteria } from './commands';
10
6
 
11
7
  const handler = CommandHandler({
12
8
  evolve,
13
9
  initialState,
14
10
  });
15
11
 
16
- export const handle = async (
17
- eventStore: EventStore,
18
- command: EnterShoppingCriteria,
19
- ): Promise<MessageHandlerResult> => {
12
+ export const handle = async (eventStore: EventStore, command: EnterShoppingCriteria): Promise<MessageHandlerResult> => {
20
13
  const streamId = `shopping-session-${command.data.sessionId}`;
21
14
 
22
15
  try {
@@ -24,8 +17,8 @@ export const handle = async (
24
17
  return; // success (returns void)
25
18
  } catch (error: any) {
26
19
  return {
27
- type: "SKIP",
28
- reason: `Command failed: ${error?.message ?? "Unknown"}`,
20
+ type: 'SKIP',
21
+ reason: `Command failed: ${error?.message ?? 'Unknown'}`,
29
22
  };
30
23
  }
31
24
  };
@@ -1,9 +1,5 @@
1
- import { Mutation, Resolver, Arg, Ctx, Field, InputType } from "type-graphql";
2
- import {
3
- type GraphQLContext,
4
- sendCommand,
5
- MutationResponse,
6
- } from "../../../shared";
1
+ import { Mutation, Resolver, Arg, Ctx, Field, InputType } from 'type-graphql';
2
+ import { type GraphQLContext, sendCommand, MutationResponse } from '../../../shared';
7
3
 
8
4
  @InputType()
9
5
  export class EnterShoppingCriteriaInput {
@@ -17,13 +13,13 @@ export class EnterShoppingCriteriaInput {
17
13
  export class EnterShoppingCriteriaResolver {
18
14
  @Mutation(() => MutationResponse)
19
15
  async enterShoppingCriteria(
20
- @Arg("input", () => EnterShoppingCriteriaInput)
16
+ @Arg('input', () => EnterShoppingCriteriaInput)
21
17
  input: EnterShoppingCriteriaInput,
22
18
  @Ctx() ctx: GraphQLContext,
23
19
  ): Promise<MutationResponse> {
24
20
  return await sendCommand(ctx.messageBus, {
25
- type: "EnterShoppingCriteria",
26
- kind: "Command",
21
+ type: 'EnterShoppingCriteria',
22
+ kind: 'Command',
27
23
  data: { ...input },
28
24
  });
29
25
  }
@@ -1,10 +1,7 @@
1
- import type { CommandProcessor, EventStore } from "@event-driven-io/emmett";
2
- import { handle } from "./handle";
3
- import type { EnterShoppingCriteria } from "./commands";
1
+ import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
2
+ import { handle } from './handle';
3
+ import type { EnterShoppingCriteria } from './commands';
4
4
 
5
5
  export function register(messageBus: CommandProcessor, eventStore: EventStore) {
6
- messageBus.handle(
7
- (command: EnterShoppingCriteria) => handle(eventStore, command),
8
- "EnterShoppingCriteria",
9
- );
6
+ messageBus.handle((command: EnterShoppingCriteria) => handle(eventStore, command), 'EnterShoppingCriteria');
10
7
  }
@@ -1,6 +1,6 @@
1
- import { Command } from "@event-driven-io/emmett";
1
+ import { Command } from '@event-driven-io/emmett';
2
2
  export type SuggestShoppingItems = Command<
3
- "SuggestShoppingItems",
3
+ 'SuggestShoppingItems',
4
4
  {
5
5
  sessionId: string;
6
6
  prompt: string;
@@ -1,57 +1,57 @@
1
- import { describe, it } from "vitest";
2
- import { DeciderSpecification } from "@event-driven-io/emmett";
3
- import { decide } from "./decide";
4
- import { evolve } from "./evolve";
5
- import { initialState } from "./state";
1
+ import { describe, it } from 'vitest';
2
+ import { DeciderSpecification } from '@event-driven-io/emmett';
3
+ import { decide } from './decide';
4
+ import { evolve } from './evolve';
5
+ import { initialState } from './state';
6
6
 
7
- describe("Seasonal Assistant | selects items relevant to the shopping criteria ", () => {
7
+ describe('Seasonal Assistant | selects items relevant to the shopping criteria ', () => {
8
8
  const given = DeciderSpecification.for({
9
9
  decide,
10
10
  evolve,
11
11
  initialState,
12
12
  });
13
13
 
14
- it("should emit ShoppingItemsSuggested for valid SuggestShoppingItems", () => {
14
+ it('should emit ShoppingItemsSuggested for valid SuggestShoppingItems', () => {
15
15
  given([])
16
16
  .when({
17
- type: "SuggestShoppingItems",
17
+ type: 'SuggestShoppingItems',
18
18
  data: {
19
- sessionId: "session-abc",
19
+ sessionId: 'session-abc',
20
20
  prompt:
21
- "I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.",
21
+ 'I need back-to-school items for my 7-year-old daughter who loves soccer and crafts, and my 12-year-old son who is into computers and Magic the Gathering.',
22
22
  },
23
23
  metadata: { now: new Date() },
24
24
  })
25
25
 
26
26
  .then([
27
27
  {
28
- type: "ShoppingItemsSuggested",
28
+ type: 'ShoppingItemsSuggested',
29
29
  data: {
30
- sessionId: "session-abc",
30
+ sessionId: 'session-abc',
31
31
  suggestedItems: [
32
32
  {
33
- productId: "prod-soccer-ball",
34
- name: "Super Soccer Ball",
33
+ productId: 'prod-soccer-ball',
34
+ name: 'Super Soccer Ball',
35
35
  quantity: 1,
36
- reason: "Perfect for your daughter who loves soccer",
36
+ reason: 'Perfect for your daughter who loves soccer',
37
37
  },
38
38
  {
39
- productId: "prod-craft-kit",
40
- name: "Deluxe Craft Kit",
39
+ productId: 'prod-craft-kit',
40
+ name: 'Deluxe Craft Kit',
41
41
  quantity: 1,
42
- reason: "Great for creative activities and crafts",
42
+ reason: 'Great for creative activities and crafts',
43
43
  },
44
44
  {
45
- productId: "prod-laptop-bag",
46
- name: "Tech Laptop Backpack",
45
+ productId: 'prod-laptop-bag',
46
+ name: 'Tech Laptop Backpack',
47
47
  quantity: 1,
48
48
  reason: "Essential for your son's school computer needs",
49
49
  },
50
50
  {
51
- productId: "prod-mtg-starter",
52
- name: "Magic the Gathering Starter Set",
51
+ productId: 'prod-mtg-starter',
52
+ name: 'Magic the Gathering Starter Set',
53
53
  quantity: 1,
54
- reason: "Ideal starter set for Magic the Gathering enthusiasts",
54
+ reason: 'Ideal starter set for Magic the Gathering enthusiasts',
55
55
  },
56
56
  ],
57
57
  },
@@ -1,16 +1,12 @@
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";
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
6
 
7
- export const decide = (
8
- command: SuggestShoppingItems,
9
- state: State,
10
- products?: Products,
11
- ): ShoppingItemsSuggested => {
7
+ export const decide = (command: SuggestShoppingItems, state: State, products?: Products): ShoppingItemsSuggested => {
12
8
  switch (command.type) {
13
- case "SuggestShoppingItems": {
9
+ case 'SuggestShoppingItems': {
14
10
  /**
15
11
  * ## IMPLEMENTATION INSTRUCTIONS ##
16
12
  *
@@ -37,9 +33,9 @@ export const decide = (
37
33
  // data: { ...command.data },
38
34
  // } as ShoppingItemsSuggested;
39
35
 
40
- throw new IllegalStateError("Not yet implemented: " + command.type);
36
+ throw new IllegalStateError('Not yet implemented: ' + command.type);
41
37
  }
42
38
  default:
43
- throw new IllegalStateError("Unexpected command type: " + command.type);
39
+ throw new IllegalStateError('Unexpected command type: ' + command.type);
44
40
  }
45
41
  };
@@ -1,7 +1,7 @@
1
- import type { Event } from "@event-driven-io/emmett";
1
+ import type { Event } from '@event-driven-io/emmett';
2
2
 
3
3
  export type ShoppingItemsSuggested = Event<
4
- "ShoppingItemsSuggested",
4
+ 'ShoppingItemsSuggested',
5
5
  {
6
6
  sessionId: string;
7
7
  suggestedItems: Array<{
@@ -1,5 +1,5 @@
1
- import type { State } from "./state";
2
- import type { ShoppingItemsSuggested } from "./events";
1
+ import type { State } from './state';
2
+ import type { ShoppingItemsSuggested } from './events';
3
3
 
4
4
  /**
5
5
  * ## IMPLEMENTATION INSTRUCTIONS ##
@@ -16,7 +16,7 @@ import type { ShoppingItemsSuggested } from "./events";
16
16
 
17
17
  export const evolve = (state: State, event: ShoppingItemsSuggested): State => {
18
18
  switch (event.type) {
19
- case "ShoppingItemsSuggested": {
19
+ case 'ShoppingItemsSuggested': {
20
20
  // TODO: Update state based on ShoppingItemsSuggested
21
21
  return {
22
22
  ...state,
@@ -1,18 +1,14 @@
1
- import "@auto-engineer/product-catalog-integration";
1
+ import '@auto-engineer/product-catalog-integration';
2
2
 
3
- import { AI } from "@auto-engineer/ai-integration";
3
+ import { AI } from '@auto-engineer/ai-integration';
4
4
 
5
- import { Products } from "@auto-engineer/product-catalog-integration";
5
+ import { Products } from '@auto-engineer/product-catalog-integration';
6
6
 
7
- import {
8
- CommandHandler,
9
- type EventStore,
10
- type MessageHandlerResult,
11
- } from "@event-driven-io/emmett";
12
- import { evolve } from "./evolve";
13
- import { initialState } from "./state";
14
- import { decide } from "./decide";
15
- import type { SuggestShoppingItems } from "./commands";
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';
16
12
 
17
13
  /**
18
14
  * ## IMPLEMENTATION INSTRUCTIONS ##
@@ -24,10 +20,7 @@ const handler = CommandHandler({
24
20
  initialState,
25
21
  });
26
22
 
27
- export const handle = async (
28
- eventStore: EventStore,
29
- command: SuggestShoppingItems,
30
- ): Promise<MessageHandlerResult> => {
23
+ export const handle = async (eventStore: EventStore, command: SuggestShoppingItems): Promise<MessageHandlerResult> => {
31
24
  const streamId = `shopping-session-${command.data.sessionId}`;
32
25
 
33
26
  try {
@@ -52,8 +45,8 @@ export const handle = async (
52
45
  return; // success (returns void)
53
46
  } catch (error: any) {
54
47
  return {
55
- type: "SKIP",
56
- reason: `Command failed: ${error?.message ?? "Unknown"}`,
48
+ type: 'SKIP',
49
+ reason: `Command failed: ${error?.message ?? 'Unknown'}`,
57
50
  };
58
51
  }
59
52
  };
@@ -1,9 +1,5 @@
1
- import { Mutation, Resolver, Arg, Ctx, Field, InputType } from "type-graphql";
2
- import {
3
- type GraphQLContext,
4
- sendCommand,
5
- MutationResponse,
6
- } from "../../../shared";
1
+ import { Mutation, Resolver, Arg, Ctx, Field, InputType } from 'type-graphql';
2
+ import { type GraphQLContext, sendCommand, MutationResponse } from '../../../shared';
7
3
 
8
4
  @InputType()
9
5
  export class SuggestShoppingItemsInput {
@@ -17,13 +13,13 @@ export class SuggestShoppingItemsInput {
17
13
  export class SuggestShoppingItemsResolver {
18
14
  @Mutation(() => MutationResponse)
19
15
  async suggestShoppingItems(
20
- @Arg("input", () => SuggestShoppingItemsInput)
16
+ @Arg('input', () => SuggestShoppingItemsInput)
21
17
  input: SuggestShoppingItemsInput,
22
18
  @Ctx() ctx: GraphQLContext,
23
19
  ): Promise<MutationResponse> {
24
20
  return await sendCommand(ctx.messageBus, {
25
- type: "SuggestShoppingItems",
26
- kind: "Command",
21
+ type: 'SuggestShoppingItems',
22
+ kind: 'Command',
27
23
  data: { ...input },
28
24
  });
29
25
  }
@@ -1,10 +1,7 @@
1
- import type { CommandProcessor, EventStore } from "@event-driven-io/emmett";
2
- import { handle } from "./handle";
3
- import type { SuggestShoppingItems } from "./commands";
1
+ import type { CommandProcessor, EventStore } from '@event-driven-io/emmett';
2
+ import { handle } from './handle';
3
+ import type { SuggestShoppingItems } from './commands';
4
4
 
5
5
  export function register(messageBus: CommandProcessor, eventStore: EventStore) {
6
- messageBus.handle(
7
- (command: SuggestShoppingItems) => handle(eventStore, command),
8
- "SuggestShoppingItems",
9
- );
6
+ messageBus.handle((command: SuggestShoppingItems) => handle(eventStore, command), 'SuggestShoppingItems');
10
7
  }