@auto-engineer/server-generator-apollo-emmett 0.10.4 → 0.10.5

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 (70) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/src/codegen/extract/events.d.ts +2 -2
  3. package/dist/src/codegen/extract/events.d.ts.map +1 -1
  4. package/dist/src/codegen/extract/events.js +16 -6
  5. package/dist/src/codegen/extract/events.js.map +1 -1
  6. package/dist/src/codegen/extract/gwt.js +7 -22
  7. package/dist/src/codegen/extract/gwt.js.map +1 -1
  8. package/dist/src/codegen/extract/imports.d.ts +29 -0
  9. package/dist/src/codegen/extract/imports.d.ts.map +1 -0
  10. package/dist/src/codegen/extract/imports.js +55 -0
  11. package/dist/src/codegen/extract/imports.js.map +1 -0
  12. package/dist/src/codegen/extract/index.d.ts +1 -0
  13. package/dist/src/codegen/extract/index.d.ts.map +1 -1
  14. package/dist/src/codegen/extract/index.js +1 -0
  15. package/dist/src/codegen/extract/index.js.map +1 -1
  16. package/dist/src/codegen/extract/messages.d.ts.map +1 -1
  17. package/dist/src/codegen/extract/messages.js +33 -7
  18. package/dist/src/codegen/extract/messages.js.map +1 -1
  19. package/dist/src/codegen/extract/query.d.ts +3 -1
  20. package/dist/src/codegen/extract/query.d.ts.map +1 -1
  21. package/dist/src/codegen/extract/query.js +12 -12
  22. package/dist/src/codegen/extract/query.js.map +1 -1
  23. package/dist/src/codegen/scaffoldFromSchema.d.ts.map +1 -1
  24. package/dist/src/codegen/scaffoldFromSchema.js +9 -1
  25. package/dist/src/codegen/scaffoldFromSchema.js.map +1 -1
  26. package/dist/src/codegen/templates/command/decide.specs.specs.ts +235 -8
  27. package/dist/src/codegen/templates/command/decide.specs.ts +8 -8
  28. package/dist/src/codegen/templates/command/decide.specs.ts.ejs +95 -30
  29. package/dist/src/codegen/templates/command/decide.ts.ejs +2 -2
  30. package/dist/src/codegen/templates/command/events.ts.ejs +2 -2
  31. package/dist/src/codegen/templates/command/evolve.ts.ejs +3 -3
  32. package/dist/src/codegen/templates/command/handle.specs.ts +6 -6
  33. package/dist/src/codegen/templates/command/handle.ts.ejs +3 -3
  34. package/dist/src/codegen/templates/query/projection.specs.specs.ts +623 -0
  35. package/dist/src/codegen/templates/query/projection.specs.ts.ejs +174 -52
  36. package/dist/src/codegen/templates/query/projection.ts.ejs +30 -29
  37. package/dist/src/codegen/templates/react/react.specs.specs.ts +7 -4
  38. package/dist/src/codegen/templates/react/react.specs.ts.ejs +118 -67
  39. package/dist/src/codegen/types.d.ts +2 -0
  40. package/dist/src/codegen/types.d.ts.map +1 -1
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +4 -4
  43. package/src/codegen/extract/events.ts +20 -3
  44. package/src/codegen/extract/gwt.ts +10 -26
  45. package/src/codegen/extract/imports.ts +71 -0
  46. package/src/codegen/extract/index.ts +1 -0
  47. package/src/codegen/extract/messages.ts +34 -7
  48. package/src/codegen/extract/query.ts +17 -19
  49. package/src/codegen/scaffoldFromSchema.ts +13 -0
  50. package/src/codegen/templates/command/decide.specs.specs.ts +235 -8
  51. package/src/codegen/templates/command/decide.specs.ts +8 -8
  52. package/src/codegen/templates/command/decide.specs.ts.ejs +95 -30
  53. package/src/codegen/templates/command/decide.ts.ejs +2 -2
  54. package/src/codegen/templates/command/events.ts.ejs +2 -2
  55. package/src/codegen/templates/command/evolve.ts.ejs +3 -3
  56. package/src/codegen/templates/command/handle.specs.ts +6 -6
  57. package/src/codegen/templates/command/handle.ts.ejs +3 -3
  58. package/src/codegen/templates/query/projection.specs.specs.ts +623 -0
  59. package/src/codegen/templates/query/projection.specs.ts.ejs +174 -52
  60. package/src/codegen/templates/query/projection.ts.ejs +30 -29
  61. package/src/codegen/templates/react/react.specs.specs.ts +7 -4
  62. package/src/codegen/templates/react/react.specs.ts.ejs +118 -67
  63. package/src/codegen/types.ts +2 -0
  64. package/dist/src/codegen/scaffoldFromSchema.query-slice-register.specs.d.ts +0 -2
  65. package/dist/src/codegen/scaffoldFromSchema.query-slice-register.specs.d.ts.map +0 -1
  66. package/dist/src/codegen/scaffoldFromSchema.query-slice-register.specs.js +0 -168
  67. package/dist/src/codegen/scaffoldFromSchema.query-slice-register.specs.js.map +0 -1
  68. package/dist/src/codegen/templates/query/projection.specs.specs..ts +0 -296
  69. package/src/codegen/scaffoldFromSchema.query-slice-register.specs.ts +0 -179
  70. package/src/codegen/templates/query/projection.specs.specs..ts +0 -296
@@ -99,16 +99,20 @@ describe('spec.ts.ejs', () => {
99
99
  import { DeciderSpecification } from '@event-driven-io/emmett';
100
100
  import { decide } from './decide';
101
101
  import { evolve } from './evolve';
102
- import { initialState } from './state';
102
+ import { initialState, State } from './state';
103
+ import type { ListingCreated } from './events';
104
+ import type { CreateListing } from './commands';
103
105
 
104
- describe('Host creates a listing | Create listing', () => {
105
- const given = DeciderSpecification.for({
106
+ describe('Should create listing successfully', () => {
107
+ type Events = ListingCreated;
108
+
109
+ const given = DeciderSpecification.for<CreateListing, Events, State>({
106
110
  decide,
107
111
  evolve,
108
112
  initialState,
109
113
  });
110
114
 
111
- it('should emit ListingCreated for valid CreateListing', () => {
115
+ it('User creates listing with valid data', () => {
112
116
  given([])
113
117
  .when({
114
118
  type: 'CreateListing',
@@ -237,16 +241,20 @@ describe('spec.ts.ejs', () => {
237
241
  import { DeciderSpecification } from '@event-driven-io/emmett';
238
242
  import { decide } from './decide';
239
243
  import { evolve } from './evolve';
240
- import { initialState } from './state';
244
+ import { initialState, State } from './state';
245
+ import type { ListingCreated, ListingRemoved } from './events';
246
+ import type { RemoveListing } from './commands';
247
+
248
+ describe('Should remove existing listing', () => {
249
+ type Events = ListingCreated | ListingRemoved;
241
250
 
242
- describe('Guest removes a listing | Remove listing', () => {
243
- const given = DeciderSpecification.for({
251
+ const given = DeciderSpecification.for<RemoveListing, Events, State>({
244
252
  decide,
245
253
  evolve,
246
254
  initialState,
247
255
  });
248
256
 
249
- it('should emit ListingRemoved for valid RemoveListing', () => {
257
+ it('Existing listing can be removed', () => {
250
258
  given([
251
259
  {
252
260
  type: 'ListingCreated',
@@ -280,4 +288,223 @@ describe('spec.ts.ejs', () => {
280
288
  "
281
289
  `);
282
290
  });
291
+
292
+ it('should generate separate tests for multiple examples with different scenarios', async () => {
293
+ const spec: SpecsSchema = {
294
+ variant: 'specs',
295
+ flows: [
296
+ {
297
+ name: 'Questionnaires',
298
+ slices: [
299
+ {
300
+ type: 'command',
301
+ name: 'submits a questionnaire answer',
302
+ client: { description: '' },
303
+ server: {
304
+ description: '',
305
+ specs: {
306
+ name: 'Answer question spec',
307
+ rules: [
308
+ {
309
+ description: 'answers are allowed while the questionnaire has not been submitted',
310
+ examples: [
311
+ {
312
+ description: 'no questions have been answered yet',
313
+ when: {
314
+ commandRef: 'AnswerQuestion',
315
+ exampleData: {
316
+ questionnaireId: 'q-001',
317
+ participantId: 'participant-abc',
318
+ questionId: 'q1',
319
+ answer: 'Yes',
320
+ },
321
+ },
322
+ then: [
323
+ {
324
+ eventRef: 'QuestionAnswered',
325
+ exampleData: {
326
+ questionnaireId: 'q-001',
327
+ participantId: 'participant-abc',
328
+ questionId: 'q1',
329
+ answer: 'Yes',
330
+ savedAt: '2030-01-01T09:05:00.000Z',
331
+ },
332
+ },
333
+ ],
334
+ },
335
+ {
336
+ description: 'all questions have already been answered and submitted',
337
+ given: [
338
+ {
339
+ eventRef: 'QuestionnaireSubmitted',
340
+ exampleData: {
341
+ questionnaireId: 'q-001',
342
+ participantId: 'participant-abc',
343
+ submittedAt: '2030-01-01T09:00:00.000Z',
344
+ },
345
+ },
346
+ ],
347
+ when: {
348
+ commandRef: 'AnswerQuestion',
349
+ exampleData: {
350
+ questionnaireId: 'q-001',
351
+ participantId: 'participant-abc',
352
+ questionId: 'q1',
353
+ answer: 'Yes',
354
+ },
355
+ },
356
+ then: [
357
+ {
358
+ eventRef: 'QuestionnaireEditRejected',
359
+ exampleData: {
360
+ questionnaireId: 'q-001',
361
+ participantId: 'participant-abc',
362
+ reason: 'Questionnaire already submitted',
363
+ attemptedAt: '2030-01-01T09:05:00.000Z',
364
+ },
365
+ },
366
+ ],
367
+ },
368
+ ],
369
+ },
370
+ ],
371
+ },
372
+ },
373
+ },
374
+ ],
375
+ },
376
+ ],
377
+ messages: [
378
+ {
379
+ type: 'command',
380
+ name: 'AnswerQuestion',
381
+ fields: [
382
+ { name: 'questionnaireId', type: 'string', required: true },
383
+ { name: 'participantId', type: 'string', required: true },
384
+ { name: 'questionId', type: 'string', required: true },
385
+ { name: 'answer', type: 'unknown', required: true },
386
+ ],
387
+ },
388
+ {
389
+ type: 'event',
390
+ name: 'QuestionAnswered',
391
+ source: 'internal',
392
+ fields: [
393
+ { name: 'questionnaireId', type: 'string', required: true },
394
+ { name: 'participantId', type: 'string', required: true },
395
+ { name: 'questionId', type: 'string', required: true },
396
+ { name: 'answer', type: 'unknown', required: true },
397
+ { name: 'savedAt', type: 'Date', required: true },
398
+ ],
399
+ },
400
+ {
401
+ type: 'event',
402
+ name: 'QuestionnaireSubmitted',
403
+ source: 'internal',
404
+ fields: [
405
+ { name: 'questionnaireId', type: 'string', required: true },
406
+ { name: 'participantId', type: 'string', required: true },
407
+ { name: 'submittedAt', type: 'Date', required: true },
408
+ ],
409
+ },
410
+ {
411
+ type: 'event',
412
+ name: 'QuestionnaireEditRejected',
413
+ source: 'internal',
414
+ fields: [
415
+ { name: 'questionnaireId', type: 'string', required: true },
416
+ { name: 'participantId', type: 'string', required: true },
417
+ { name: 'reason', type: 'string', required: true },
418
+ { name: 'attemptedAt', type: 'Date', required: true },
419
+ ],
420
+ },
421
+ ],
422
+ };
423
+
424
+ const plans = await generateScaffoldFilePlans(spec.flows, spec.messages, undefined, 'src/domain/flows');
425
+ const specFile = plans.find((p) => p.outputPath.endsWith('specs.ts'));
426
+
427
+ expect(specFile?.contents).toMatchInlineSnapshot(`
428
+ "import { describe, it } from 'vitest';
429
+ import { DeciderSpecification } from '@event-driven-io/emmett';
430
+ import { decide } from './decide';
431
+ import { evolve } from './evolve';
432
+ import { initialState, State } from './state';
433
+ import type { QuestionAnswered, QuestionnaireEditRejected, QuestionnaireSubmitted } from './events';
434
+ import type { AnswerQuestion } from './commands';
435
+
436
+ describe('answers are allowed while the questionnaire has not been submitted', () => {
437
+ type Events = QuestionAnswered | QuestionnaireEditRejected | QuestionnaireSubmitted;
438
+
439
+ const given = DeciderSpecification.for<AnswerQuestion, Events, State>({
440
+ decide,
441
+ evolve,
442
+ initialState,
443
+ });
444
+
445
+ it('no questions have been answered yet', () => {
446
+ given([])
447
+ .when({
448
+ type: 'AnswerQuestion',
449
+ data: {
450
+ questionnaireId: 'q-001',
451
+ participantId: 'participant-abc',
452
+ questionId: 'q1',
453
+ answer: 'Yes',
454
+ },
455
+ metadata: { now: new Date() },
456
+ })
457
+
458
+ .then([
459
+ {
460
+ type: 'QuestionAnswered',
461
+ data: {
462
+ questionnaireId: 'q-001',
463
+ participantId: 'participant-abc',
464
+ questionId: 'q1',
465
+ answer: 'Yes',
466
+ savedAt: new Date('2030-01-01T09:05:00.000Z'),
467
+ },
468
+ },
469
+ ]);
470
+ });
471
+
472
+ it('all questions have already been answered and submitted', () => {
473
+ given([
474
+ {
475
+ type: 'QuestionnaireSubmitted',
476
+ data: {
477
+ questionnaireId: 'q-001',
478
+ participantId: 'participant-abc',
479
+ submittedAt: new Date('2030-01-01T09:00:00.000Z'),
480
+ },
481
+ },
482
+ ])
483
+ .when({
484
+ type: 'AnswerQuestion',
485
+ data: {
486
+ questionnaireId: 'q-001',
487
+ participantId: 'participant-abc',
488
+ questionId: 'q1',
489
+ answer: 'Yes',
490
+ },
491
+ metadata: { now: new Date() },
492
+ })
493
+
494
+ .then([
495
+ {
496
+ type: 'QuestionnaireEditRejected',
497
+ data: {
498
+ questionnaireId: 'q-001',
499
+ participantId: 'participant-abc',
500
+ reason: 'Questionnaire already submitted',
501
+ attemptedAt: new Date('2030-01-01T09:05:00.000Z'),
502
+ },
503
+ },
504
+ ]);
505
+ });
506
+ });
507
+ "
508
+ `);
509
+ });
283
510
  });
@@ -81,7 +81,7 @@ describe('decide.ts.ejs', () => {
81
81
  import type { CreateListing } from './commands';
82
82
  import type { ListingCreated } from './events';
83
83
 
84
- export const decide = (command: CreateListing, state: State): ListingCreated => {
84
+ export const decide = (command: CreateListing, _state: State): ListingCreated => {
85
85
  switch (command.type) {
86
86
  case 'CreateListing': {
87
87
  /**
@@ -106,7 +106,7 @@ describe('decide.ts.ejs', () => {
106
106
  throw new IllegalStateError('Not yet implemented: ' + command.type);
107
107
  }
108
108
  default:
109
- throw new IllegalStateError('Unexpected command type: ' + command.type);
109
+ throw new IllegalStateError(\`Unexpected command type: \${String(command.type)}\`);
110
110
  }
111
111
  };
112
112
  "
@@ -206,7 +206,7 @@ describe('decide.ts.ejs', () => {
206
206
  import type { RemoveListing } from './commands';
207
207
  import type { ListingRemoved } from './events';
208
208
 
209
- export const decide = (command: RemoveListing, state: State): ListingRemoved => {
209
+ export const decide = (command: RemoveListing, _state: State): ListingRemoved => {
210
210
  switch (command.type) {
211
211
  case 'RemoveListing': {
212
212
  /**
@@ -231,7 +231,7 @@ describe('decide.ts.ejs', () => {
231
231
  throw new IllegalStateError('Not yet implemented: ' + command.type);
232
232
  }
233
233
  default:
234
- throw new IllegalStateError('Unexpected command type: ' + command.type);
234
+ throw new IllegalStateError(\`Unexpected command type: \${String(command.type)}\`);
235
235
  }
236
236
  };
237
237
  "
@@ -346,7 +346,7 @@ describe('decide.ts.ejs', () => {
346
346
  import type { CreateListing } from './commands';
347
347
  import type { ListingCreated } from './events';
348
348
 
349
- export const decide = (command: CreateListing, state: State): ListingCreated => {
349
+ export const decide = (command: CreateListing, _state: State): ListingCreated => {
350
350
  switch (command.type) {
351
351
  case 'CreateListing': {
352
352
  /**
@@ -375,7 +375,7 @@ describe('decide.ts.ejs', () => {
375
375
  throw new IllegalStateError('Not yet implemented: ' + command.type);
376
376
  }
377
377
  default:
378
- throw new IllegalStateError('Unexpected command type: ' + command.type);
378
+ throw new IllegalStateError(\`Unexpected command type: \${String(command.type)}\`);
379
379
  }
380
380
  };
381
381
  "
@@ -532,7 +532,7 @@ describe('decide.ts.ejs', () => {
532
532
  import type { ItemsSuggested } from './events';
533
533
  import type { Products } from '@auto-engineer/product-catalogue-integration';
534
534
 
535
- export const decide = (command: SuggestItems, state: State, products?: Products): ItemsSuggested => {
535
+ export const decide = (command: SuggestItems, _state: State, products?: Products): ItemsSuggested => {
536
536
  switch (command.type) {
537
537
  case 'SuggestItems': {
538
538
  /**
@@ -566,7 +566,7 @@ describe('decide.ts.ejs', () => {
566
566
  throw new IllegalStateError('Not yet implemented: ' + command.type);
567
567
  }
568
568
  default:
569
- throw new IllegalStateError('Unexpected command type: ' + command.type);
569
+ throw new IllegalStateError(\`Unexpected command type: \${String(command.type)}\`);
570
570
  }
571
571
  };
572
572
  "
@@ -1,51 +1,116 @@
1
+ <%
2
+ const allEvents = [];
3
+ const ruleGroups = new Map();
4
+ for (const commandName in gwtMapping) {
5
+ const cases = gwtMapping[commandName];
6
+ for (const gwt of cases) {
7
+ const ruleDescription = gwt.ruleDescription || `${flowName} | ${sliceName}`;
8
+ if (!ruleGroups.has(ruleDescription)) {
9
+ ruleGroups.set(ruleDescription, []);
10
+ }
11
+ ruleGroups.get(ruleDescription).push({ commandName, gwt });
12
+ if (gwt.given && gwt.given.length) {
13
+ for (const g of gwt.given) {
14
+ if (g.eventRef) {
15
+ const event = events.find(e => e.type === g.eventRef);
16
+ if (event) allEvents.push(event);
17
+ }
18
+ }
19
+ }
20
+ if (gwt.then) {
21
+ for (const t of gwt.then) {
22
+ if (t.eventRef) {
23
+ const event = events.find(e => e.type === t.eventRef);
24
+ if (event) allEvents.push(event);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
30
+
31
+ const testEventImportGroups = [];
32
+ const testEventsByPath = new Map();
33
+
34
+ for (const event of allEvents) {
35
+ if (!event.type) continue;
36
+ const importGroup = eventImportGroups.find(group =>
37
+ group.eventTypes.includes(event.type)
38
+ );
39
+
40
+ if (importGroup) {
41
+ const path = importGroup.importPath;
42
+ if (!testEventsByPath.has(path)) {
43
+ testEventsByPath.set(path, []);
44
+ }
45
+ if (!testEventsByPath.get(path).includes(event.type)) {
46
+ testEventsByPath.get(path).push(event.type);
47
+ }
48
+ }
49
+ }
50
+
51
+ for (const [importPath, eventTypes] of testEventsByPath.entries()) {
52
+ testEventImportGroups.push({ importPath, eventTypes: eventTypes.sort() });
53
+ }
54
+
55
+ const uniqueEventTypes = Array.from(new Set(allEvents.map(e => e?.type).filter(Boolean))).sort();
56
+ _%>
1
57
  import { describe, it } from 'vitest';
2
58
  import { DeciderSpecification } from '@event-driven-io/emmett';
3
59
  import { decide } from './decide';
4
60
  import { evolve } from './evolve';
5
- import { initialState } from './state';
61
+ import { initialState, State } from './state';
62
+ <% for (const group of testEventImportGroups) { -%>
63
+ import type { <%= group.eventTypes.join(', ') %> } from '<%= group.importPath %>';
64
+ <% } -%>
65
+ import type { <%= Object.keys(commandSchemasByName).join(', ') %> } from './commands';
66
+ <% for (const [ruleDescription, ruleGwts] of ruleGroups.entries()) { %>
67
+ describe('<%= ruleDescription %>', () => {
6
68
 
7
- describe('<%= flowName %> | <%= sliceName %>', () => {
8
- const given = DeciderSpecification.for({
9
- decide,
10
- evolve,
11
- initialState,
12
- });
69
+ type Events = <%= uniqueEventTypes.length > 0 ? uniqueEventTypes.join(' | ') : 'never' %>;
13
70
 
14
- <% for (const commandName in gwtMapping) {
15
- const cases = gwtMapping[commandName];
71
+ const given = DeciderSpecification.for<<%= Object.keys(commandSchemasByName).length === 1 ? Object.keys(commandSchemasByName)[0] : `(${Object.keys(commandSchemasByName).join(' | ')})` %>, Events, State>({
72
+ decide,
73
+ evolve,
74
+ initialState,
75
+ });
76
+
77
+ <% for (const { commandName, gwt } of ruleGwts) {
16
78
  const schema = commandSchemasByName[commandName];
17
- for (const [i, gwt] of cases.entries()) {
18
79
  const example = gwt.when;
19
80
  const eventResults = gwt.then.filter(t => 'eventRef' in t);
20
81
  const errorResult = gwt.then.find(t => 'errorType' in t);
21
- const testName = errorResult
82
+
83
+ const testDescription = gwt.description ||
84
+ (errorResult
22
85
  ? `should throw ${errorResult.errorType} when ${gwt.failingFields?.join(', ') || 'invalid input'}`
23
- : `should emit ${eventResults.map(e => e.eventRef).join(', ')} for valid ${commandName}`;
86
+ : `should emit ${eventResults.map(e => e.eventRef).join(', ')} for valid ${commandName}`);
24
87
  %>
25
- it('<%- testName %>', () => {
26
- given([
88
+ it('<%= testDescription %>', () => {
89
+ given([
27
90
  <%_ if (gwt.given && gwt.given.length) { _%>
28
- <%- gwt.given.map(g => `{
91
+ <%- gwt.given.map(g => `{
29
92
  type: '${g.eventRef}',
30
93
  data: ${formatDataObject(g.exampleData, events.find(e => e.type === g.eventRef))}
31
94
  }`).join(',\n ') %>
32
95
  <%_ } _%>
33
- ])
34
- .when({
35
- type: '<%= example.commandRef %>',
36
- data: <%- formatDataObject(example.exampleData, schema) %>,
37
- metadata: { now: new Date() }
38
- })
96
+ ])
97
+ .when({
98
+ type: '<%= example.commandRef %>',
99
+ data: <%- formatDataObject(example.exampleData, schema) %>,
100
+ metadata: { now: new Date() },
101
+ })
39
102
  <% if (errorResult) { %>
40
- .thenThrows((err) => err instanceof <%= errorResult.errorType %> && err.message === '<%= errorResult.message || '' %>');
103
+ .thenThrows((err) => err instanceof <%= errorResult.errorType %> && err.message === '<%= errorResult.message || '' %>');
41
104
  <% } else { %>
42
- .then([
43
- <%- eventResults.map(e => `{
44
- type: '${e.eventRef}',
45
- data: ${formatDataObject(e.exampleData, events.find(evt => evt.type === e.eventRef))}
46
- }`).join(',\n ') %>
47
- ]);
105
+
106
+ .then([
107
+ <%- eventResults.map(e => `{
108
+ type: '${e.eventRef}',
109
+ data: ${formatDataObject(e.exampleData, events.find(evt => evt.type === e.eventRef))}
110
+ }`).join(',\n ') %>
111
+ ]);
112
+ <% } %>
113
+ });
48
114
  <% } %>
49
115
  });
50
- <% }} %>
51
- });
116
+ <% } %>
@@ -45,7 +45,7 @@ function formatFieldDocLine(field) {
45
45
 
46
46
  export const decide = (
47
47
  command: <%= Object.keys(gwtMapping).map(pascalCase).join(' | ') %>,
48
- state: State<%= integrationReturnType ? `,\n ${camelCase(integrationReturnType)}?: ${integrationReturnType}` : '' %>
48
+ _state: State<%= integrationReturnType ? `,\n ${camelCase(integrationReturnType)}?: ${integrationReturnType}` : '' %>
49
49
  ): <%= uniqueEventTypes.length === 0
50
50
  ? 'never'
51
51
  : uniqueEventTypes.length === 1
@@ -102,6 +102,6 @@ throw new IllegalStateError('Not yet implemented: ' + command.type);
102
102
  }
103
103
  <% } -%>
104
104
  default:
105
- throw new IllegalStateError('Unexpected command type: ' + command.type);
105
+ throw new IllegalStateError(`Unexpected command type: ${String(command.type)}`);
106
106
  }
107
107
  };
@@ -1,7 +1,7 @@
1
- <% if (events.length) { -%>
1
+ <% if (localEvents.length) { -%>
2
2
  import type { Event } from '@event-driven-io/emmett';
3
3
 
4
- <% for (const event of events) { -%>
4
+ <% for (const event of localEvents) { -%>
5
5
  export type <%= pascalCase(event.type) %> = Event<
6
6
  '<%= event.type %>',
7
7
  {
@@ -1,8 +1,8 @@
1
1
  <% if (events.length) { -%>
2
2
  import type { State } from './state';
3
- <% events.forEach(event => { -%>
4
- import type { <%= pascalCase(event.type) %> } from './events';
5
- <% }); -%>
3
+ <% for (const group of eventImportGroups) { -%>
4
+ import type { <%= group.eventTypes.map(name => pascalCase(name)).join(', ') %> } from '<%= group.importPath %>';
5
+ <% } -%>
6
6
 
7
7
  /**
8
8
  * ## IMPLEMENTATION INSTRUCTIONS ##
@@ -117,11 +117,11 @@ describe('generateScaffoldFilePlans', () => {
117
117
 
118
118
  try {
119
119
  await handler(eventStore, streamId, (state) => decide(command, state));
120
- return; // success (returns void)
121
- } catch (error: any) {
120
+ return undefined; // success
121
+ } catch (error: unknown) {
122
122
  return {
123
123
  type: 'SKIP',
124
- reason: \`Command failed: \${error?.message ?? 'Unknown'}\`,
124
+ reason: \`Command failed: \${error instanceof Error ? error.message : 'Unknown'}\`,
125
125
  };
126
126
  }
127
127
  };
@@ -315,11 +315,11 @@ describe('generateScaffoldFilePlans', () => {
315
315
  // TODO: add products as a parameter to decide once implemented above
316
316
  decide(command, state /* products */),
317
317
  );
318
- return; // success (returns void)
319
- } catch (error: any) {
318
+ return undefined; // success
319
+ } catch (error: unknown) {
320
320
  return {
321
321
  type: 'SKIP',
322
- reason: \`Command failed: \${error?.message ?? 'Unknown'}\`,
322
+ reason: \`Command failed: \${error instanceof Error ? error.message : 'Unknown'}\`,
323
323
  };
324
324
  }
325
325
  };
@@ -101,11 +101,11 @@ command: <%= commands.map(c => pascalCase(c.type)).join(' | ') %>
101
101
  ? ` // TODO: add ${resultVarName} as a parameter to decide once implemented above\n decide(command, state, /* ${resultVarName} */)`
102
102
  : ` decide(command, state)` %>
103
103
  );
104
- return; // success (returns void)
105
- } catch (error: any) {
104
+ return undefined; // success
105
+ } catch (error: unknown) {
106
106
  return {
107
107
  type: 'SKIP',
108
- reason: `Command failed: ${error?.message ?? 'Unknown'}`,
108
+ reason: `Command failed: ${error instanceof Error ? error.message : 'Unknown'}`,
109
109
  };
110
110
  }
111
111
  };