@auto-engineer/server-generator-apollo-emmett 1.55.0 → 1.56.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.
Files changed (51) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +5 -5
  3. package/.turbo/turbo-type-check.log +1 -1
  4. package/CHANGELOG.md +17 -0
  5. package/dist/src/codegen/scaffoldFromSchema.d.ts +10 -1
  6. package/dist/src/codegen/scaffoldFromSchema.d.ts.map +1 -1
  7. package/dist/src/codegen/scaffoldFromSchema.js +38 -9
  8. package/dist/src/codegen/scaffoldFromSchema.js.map +1 -1
  9. package/dist/src/codegen/templates/command/commands.specs.ts +1 -1
  10. package/dist/src/codegen/templates/command/decide.specs.specs.ts +5 -5
  11. package/dist/src/codegen/templates/command/decide.specs.ts +4 -4
  12. package/dist/src/codegen/templates/command/events.specs.ts +1 -1
  13. package/dist/src/codegen/templates/command/evolve.specs.ts +1 -1
  14. package/dist/src/codegen/templates/command/handle.specs.ts +2 -2
  15. package/dist/src/codegen/templates/command/mutation.resolver.specs.ts +5 -5
  16. package/dist/src/codegen/templates/command/register.specs.ts +1 -1
  17. package/dist/src/codegen/templates/command/state.specs.ts +1 -1
  18. package/dist/src/codegen/templates/query/projection.specs.specs.ts +11 -11
  19. package/dist/src/codegen/templates/query/projection.specs.ts +5 -5
  20. package/dist/src/codegen/templates/query/query.resolver.specs.ts +11 -11
  21. package/dist/src/codegen/templates/query/state.specs.ts +2 -2
  22. package/dist/src/codegen/templates/react/react.specs.specs.ts +2 -2
  23. package/dist/src/codegen/templates/react/react.specs.ts +4 -4
  24. package/dist/src/codegen/templates/react/react.ts.specs.ts +3 -3
  25. package/dist/src/codegen/templates/react/register.specs.ts +1 -1
  26. package/dist/src/commands/generate-server.d.ts +11 -3
  27. package/dist/src/commands/generate-server.d.ts.map +1 -1
  28. package/dist/src/commands/generate-server.js +42 -8
  29. package/dist/src/commands/generate-server.js.map +1 -1
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +4 -4
  32. package/src/codegen/scaffoldFromSchema.filter.specs.ts +66 -2
  33. package/src/codegen/scaffoldFromSchema.ts +64 -10
  34. package/src/codegen/templates/command/commands.specs.ts +1 -1
  35. package/src/codegen/templates/command/decide.specs.specs.ts +5 -5
  36. package/src/codegen/templates/command/decide.specs.ts +4 -4
  37. package/src/codegen/templates/command/events.specs.ts +1 -1
  38. package/src/codegen/templates/command/evolve.specs.ts +1 -1
  39. package/src/codegen/templates/command/handle.specs.ts +2 -2
  40. package/src/codegen/templates/command/mutation.resolver.specs.ts +5 -5
  41. package/src/codegen/templates/command/register.specs.ts +1 -1
  42. package/src/codegen/templates/command/state.specs.ts +1 -1
  43. package/src/codegen/templates/query/projection.specs.specs.ts +11 -11
  44. package/src/codegen/templates/query/projection.specs.ts +5 -5
  45. package/src/codegen/templates/query/query.resolver.specs.ts +11 -11
  46. package/src/codegen/templates/query/state.specs.ts +2 -2
  47. package/src/codegen/templates/react/react.specs.specs.ts +2 -2
  48. package/src/codegen/templates/react/react.specs.ts +4 -4
  49. package/src/codegen/templates/react/react.ts.specs.ts +3 -3
  50. package/src/codegen/templates/react/register.specs.ts +1 -1
  51. package/src/commands/generate-server.ts +75 -8
package/package.json CHANGED
@@ -32,8 +32,8 @@
32
32
  "uuid": "^11.0.0",
33
33
  "web-streams-polyfill": "^4.1.0",
34
34
  "zod": "^3.22.4",
35
- "@auto-engineer/narrative": "1.55.0",
36
- "@auto-engineer/message-bus": "1.55.0"
35
+ "@auto-engineer/narrative": "1.56.0",
36
+ "@auto-engineer/message-bus": "1.56.0"
37
37
  },
38
38
  "publishConfig": {
39
39
  "access": "public"
@@ -44,9 +44,9 @@
44
44
  "typescript": "^5.8.3",
45
45
  "vitest": "^3.2.4",
46
46
  "tsx": "^4.19.2",
47
- "@auto-engineer/cli": "1.55.0"
47
+ "@auto-engineer/cli": "1.56.0"
48
48
  },
49
- "version": "1.55.0",
49
+ "version": "1.56.0",
50
50
  "scripts": {
51
51
  "generate:server": "tsx src/cli/index.ts",
52
52
  "build": "tsc && tsx ../../scripts/fix-esm-imports.ts && rm -rf dist/src/codegen/templates && mkdir -p dist/src/codegen && cp -r src/codegen/templates dist/src/codegen/templates && cp src/server.ts dist/src && cp -r src/utils dist/src && cp -r src/domain dist/src",
@@ -47,11 +47,40 @@ const flows: Narrative[] = [
47
47
  },
48
48
  ];
49
49
 
50
+ const makeSliceWithCommand = (name: string, commandName: string): CommandSlice => ({
51
+ name,
52
+ type: 'command',
53
+ client: { specs: [] },
54
+ server: {
55
+ description: `Handle ${name}`,
56
+ specs: [
57
+ {
58
+ type: 'gherkin',
59
+ feature: name,
60
+ rules: [
61
+ {
62
+ name: 'rule',
63
+ examples: [
64
+ {
65
+ name: 'example',
66
+ steps: [
67
+ { keyword: 'When', text: commandName },
68
+ { keyword: 'Then', text: `${commandName}Done` },
69
+ ],
70
+ },
71
+ ],
72
+ },
73
+ ],
74
+ },
75
+ ],
76
+ },
77
+ });
78
+
50
79
  describe('generateScaffoldFilePlans with affectedSliceIds filter', () => {
51
80
  const baseDir = join(tmpdir(), `scaffold-filter-test-${Date.now()}`);
52
81
 
53
82
  it('generates plans for all slices when no filter is provided', async () => {
54
- const plans = await generateScaffoldFilePlans(flows, messages, undefined, baseDir);
83
+ const { plans } = await generateScaffoldFilePlans(flows, messages, undefined, baseDir);
55
84
  const sliceDirs = new Set(plans.map((p) => p.outputPath.split('/').slice(-3, -1).join('/')));
56
85
  expect(sliceDirs.has('todo/add-todo')).toBe(true);
57
86
  expect(sliceDirs.has('todo/remove-todo')).toBe(true);
@@ -59,9 +88,44 @@ describe('generateScaffoldFilePlans with affectedSliceIds filter', () => {
59
88
 
60
89
  it('generates plans only for affected slices when filter is provided', async () => {
61
90
  const affectedSliceIds = new Set(['todo/add-todo']);
62
- const plans = await generateScaffoldFilePlans(flows, messages, undefined, baseDir, affectedSliceIds);
91
+ const { plans } = await generateScaffoldFilePlans(flows, messages, undefined, baseDir, affectedSliceIds);
63
92
  const sliceDirs = new Set(plans.map((p) => p.outputPath.split('/').slice(-3, -1).join('/')));
64
93
  expect(sliceDirs.has('todo/add-todo')).toBe(true);
65
94
  expect(sliceDirs.has('todo/remove-todo')).toBe(false);
66
95
  });
67
96
  });
97
+
98
+ describe('generateScaffoldFilePlans with duplicate command handlers', () => {
99
+ const baseDir = join(tmpdir(), `scaffold-duplicate-test-${Date.now()}`);
100
+
101
+ it('skips register.ts for slices with duplicate command handlers across flows', async () => {
102
+ const duplicateMessages: Message[] = [
103
+ { name: 'DoAction', type: 'command', fields: [{ name: 'id', type: 'string', required: true }] },
104
+ { name: 'DoActionDone', type: 'event', fields: [{ name: 'id', type: 'string', required: true }] },
105
+ ];
106
+
107
+ const duplicateFlows: Narrative[] = [
108
+ { name: 'FlowA', slices: [makeSliceWithCommand('HandleAction', 'DoAction')] },
109
+ { name: 'FlowB', slices: [makeSliceWithCommand('ProcessAction', 'DoAction')] },
110
+ ];
111
+
112
+ const result = await generateScaffoldFilePlans(duplicateFlows, duplicateMessages, undefined, baseDir);
113
+
114
+ const flowAFiles = result.plans.filter((p) => p.outputPath.includes('flow-a/handle-action'));
115
+ const flowBFiles = result.plans.filter((p) => p.outputPath.includes('flow-b/process-action'));
116
+
117
+ const flowAHasRegister = flowAFiles.some((p) => p.outputPath.endsWith('register.ts'));
118
+ const flowBHasRegister = flowBFiles.some((p) => p.outputPath.endsWith('register.ts'));
119
+
120
+ expect(flowAHasRegister).toBe(true);
121
+ expect(flowBHasRegister).toBe(false);
122
+
123
+ expect(result.duplicateCommands).toEqual([
124
+ {
125
+ command: 'DoAction',
126
+ existingFlow: 'FlowA',
127
+ existingSlice: 'HandleAction',
128
+ },
129
+ ]);
130
+ });
131
+ });
@@ -262,6 +262,17 @@ export interface FilePlan {
262
262
  contents: string;
263
263
  }
264
264
 
265
+ export interface DuplicateCommandInfo {
266
+ command: string;
267
+ existingFlow: string;
268
+ existingSlice: string;
269
+ }
270
+
271
+ export interface ScaffoldResult {
272
+ plans: FilePlan[];
273
+ duplicateCommands: DuplicateCommandInfo[];
274
+ }
275
+
265
276
  async function renderTemplate(
266
277
  templatePath: string,
267
278
  data: Record<string, unknown>,
@@ -724,15 +735,18 @@ async function generateFilesForSlice(
724
735
  flows: Narrative[],
725
736
  unionToEnumName: Map<string, string>,
726
737
  integrations?: Model['integrations'],
727
- ): Promise<FilePlan[]> {
738
+ registeredCommands?: Map<string, { flowName: string; sliceName: string }>,
739
+ ): Promise<{ plans: FilePlan[]; duplicateCommands: DuplicateCommandInfo[] }> {
728
740
  debugSlice('Generating files for slice: %s (type: %s)', slice.name, slice.type);
729
741
  debugSlice(' Flow: %s', flow.name);
730
742
  debugSlice(' Output directory: %s', sliceDir);
731
743
 
744
+ const duplicateCommands: DuplicateCommandInfo[] = [];
745
+
732
746
  const templates = defaultFilesByType[slice.type];
733
747
  if (!templates?.length) {
734
748
  debugSlice(' No templates found for slice type: %s', slice.type);
735
- return [];
749
+ return { plans: [], duplicateCommands };
736
750
  }
737
751
  debugSlice(' Found %d templates for slice type', templates.length);
738
752
 
@@ -741,7 +755,7 @@ async function generateFilesForSlice(
741
755
  !slice.server?.specs?.some((spec) => spec.rules?.some((rule) => rule.examples?.length > 0))
742
756
  ) {
743
757
  debugSlice(' Skipping react slice with no examples: %s', slice.name);
744
- return [];
758
+ return { plans: [], duplicateCommands };
745
759
  }
746
760
 
747
761
  const extracted = extractMessagesFromSpecs(slice, messages);
@@ -757,6 +771,40 @@ async function generateFilesForSlice(
757
771
  annotateEventSources(extracted.events, flows, flow.name, slice.name, slice.type);
758
772
  annotateCommandSources(extracted.commands, flows, flow.name, slice.name, slice.type);
759
773
 
774
+ let filteredTemplates = templates;
775
+
776
+ if (slice.type === 'command' && registeredCommands) {
777
+ const commandTypes = extracted.commands.map((c) => c.type);
778
+ const isDuplicate = commandTypes.some((ct) => registeredCommands.has(ct));
779
+
780
+ if (isDuplicate) {
781
+ for (const ct of commandTypes) {
782
+ const existing = registeredCommands.get(ct);
783
+ if (existing) {
784
+ debugSlice(
785
+ ' Duplicate command handler detected: %s (already in %s/%s)',
786
+ ct,
787
+ existing.flowName,
788
+ existing.sliceName,
789
+ );
790
+ duplicateCommands.push({
791
+ command: ct,
792
+ existingFlow: existing.flowName,
793
+ existingSlice: existing.sliceName,
794
+ });
795
+ }
796
+ }
797
+ filteredTemplates = templates.filter((t) => t !== 'register.ts.ejs');
798
+ debugSlice(' Filtered out register.ts.ejs for duplicate command slice');
799
+ }
800
+
801
+ for (const ct of commandTypes) {
802
+ if (!registeredCommands.has(ct)) {
803
+ registeredCommands.set(ct, { flowName: flow.name, sliceName: slice.name });
804
+ }
805
+ }
806
+ }
807
+
760
808
  const templateData = await prepareTemplateData(
761
809
  slice,
762
810
  flow,
@@ -770,12 +818,14 @@ async function generateFilesForSlice(
770
818
  integrations,
771
819
  );
772
820
 
773
- debugSlice(' Generating %d files from templates', templates.length);
821
+ debugSlice(' Generating %d files from templates', filteredTemplates.length);
774
822
  const plans = await Promise.all(
775
- templates.map((template) => generateFileForTemplate(template, slice, sliceDir, templateData, unionToEnumName)),
823
+ filteredTemplates.map((template) =>
824
+ generateFileForTemplate(template, slice, sliceDir, templateData, unionToEnumName),
825
+ ),
776
826
  );
777
827
  debugSlice(' Generated %d file plans for slice: %s', plans.length, slice.name);
778
- return plans;
828
+ return { plans, duplicateCommands };
779
829
  }
780
830
 
781
831
  export async function generateScaffoldFilePlans(
@@ -784,7 +834,7 @@ export async function generateScaffoldFilePlans(
784
834
  integrations?: Model['integrations'],
785
835
  baseDir = 'src/domain/flows',
786
836
  affectedSliceIds?: Set<string>,
787
- ): Promise<FilePlan[]> {
837
+ ): Promise<ScaffoldResult> {
788
838
  debug('Generating scaffold file plans');
789
839
  debug(' Number of flows: %d', flows.length);
790
840
  debug(' Number of messages: %d', messages?.length ?? 0);
@@ -797,6 +847,8 @@ export async function generateScaffoldFilePlans(
797
847
  await appendEnumsToSharedTypes(domainBaseDir, enums);
798
848
 
799
849
  const allPlans: FilePlan[] = [];
850
+ const allDuplicateCommands: DuplicateCommandInfo[] = [];
851
+ const registeredCommands = new Map<string, { flowName: string; sliceName: string }>();
800
852
 
801
853
  for (const flow of flows) {
802
854
  debugFlow('Processing flow: %s', flow.name);
@@ -812,7 +864,7 @@ export async function generateScaffoldFilePlans(
812
864
  debugFlow(' Processing slice: %s (type: %s)', slice.name, slice.type);
813
865
  const sliceDir = ensureDirPath(flowDir, toKebabCase(slice.name));
814
866
  debugFlow(' Slice directory: %s', sliceDir);
815
- const plans = await generateFilesForSlice(
867
+ const { plans, duplicateCommands } = await generateFilesForSlice(
816
868
  slice,
817
869
  flow,
818
870
  sliceDir,
@@ -820,15 +872,17 @@ export async function generateScaffoldFilePlans(
820
872
  flows,
821
873
  unionToEnumName,
822
874
  integrations,
875
+ registeredCommands,
823
876
  );
824
877
  debugFlow(' Generated %d plans for slice', plans.length);
825
878
  allPlans.push(...plans);
879
+ allDuplicateCommands.push(...duplicateCommands);
826
880
  }
827
881
  debugFlow(' Completed flow: %s', flow.name);
828
882
  }
829
883
 
830
884
  debug('Total file plans generated: %d', allPlans.length);
831
- return allPlans;
885
+ return { plans: allPlans, duplicateCommands: allDuplicateCommands };
832
886
  }
833
887
 
834
888
  export async function writeScaffoldFilePlans(plans: FilePlan[]) {
@@ -861,7 +915,7 @@ export async function scaffoldFromSchema(
861
915
  debug(' Messages: %d', messages?.length ?? 0);
862
916
  debug(' Base directory: %s', baseDir);
863
917
 
864
- const plans = await generateScaffoldFilePlans(flows, messages, undefined, baseDir);
918
+ const { plans } = await generateScaffoldFilePlans(flows, messages, undefined, baseDir);
865
919
  debug('Generated %d file plans, writing to disk...', plans.length);
866
920
 
867
921
  await writeScaffoldFilePlans(plans);
@@ -77,7 +77,7 @@ describe('commands.ts.ejs', () => {
77
77
  ],
78
78
  };
79
79
 
80
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
80
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
81
81
  const commandFile = plans.find((p) => p.outputPath.endsWith('commands.ts'));
82
82
 
83
83
  expect(commandFile?.contents).toMatchInlineSnapshot(`
@@ -96,7 +96,7 @@ describe('spec.ts.ejs', () => {
96
96
  ],
97
97
  };
98
98
 
99
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
99
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
100
100
  const specFile = plans.find((p) => p.outputPath.endsWith('specs.ts'));
101
101
 
102
102
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -242,7 +242,7 @@ describe('spec.ts.ejs', () => {
242
242
  ],
243
243
  };
244
244
 
245
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
245
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
246
246
  const specFile = plans.find((p) => p.outputPath.endsWith('specs.ts'));
247
247
 
248
248
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -436,7 +436,7 @@ describe('spec.ts.ejs', () => {
436
436
  ],
437
437
  };
438
438
 
439
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
439
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
440
440
  const specFile = plans.find((p) => p.outputPath.endsWith('specs.ts'));
441
441
 
442
442
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -596,7 +596,7 @@ describe('spec.ts.ejs', () => {
596
596
  ],
597
597
  };
598
598
 
599
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
599
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
600
600
  const specFile = plans.find((p) => p.outputPath.endsWith('specs.ts'));
601
601
  const contents = specFile?.contents ?? '';
602
602
 
@@ -665,7 +665,7 @@ describe('spec.ts.ejs', () => {
665
665
  ],
666
666
  };
667
667
 
668
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
668
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
669
669
  const decideFile = plans.find((p) => p.outputPath.endsWith('decide.ts'));
670
670
  expect(decideFile?.contents).toBeDefined();
671
671
 
@@ -77,7 +77,7 @@ describe('decide.ts.ejs', () => {
77
77
  ],
78
78
  };
79
79
 
80
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
80
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
81
81
  const decideFile = plans.find((p) => p.outputPath.endsWith('decide.ts'));
82
82
 
83
83
  expect(decideFile?.contents).toMatchInlineSnapshot(`
@@ -210,7 +210,7 @@ describe('decide.ts.ejs', () => {
210
210
  ],
211
211
  };
212
212
 
213
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
213
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
214
214
  const decideFile = plans.find((p) => p.outputPath.endsWith('decide.ts'));
215
215
 
216
216
  expect(decideFile?.contents).toMatchInlineSnapshot(`
@@ -363,7 +363,7 @@ describe('decide.ts.ejs', () => {
363
363
  ],
364
364
  };
365
365
 
366
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
366
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
367
367
  const decideFile = plans.find((p) => p.outputPath.endsWith('decide.ts'));
368
368
 
369
369
  expect(decideFile?.contents).toMatchInlineSnapshot(`
@@ -559,7 +559,7 @@ describe('decide.ts.ejs', () => {
559
559
  ],
560
560
  };
561
561
 
562
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, spec.integrations);
562
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, spec.integrations);
563
563
  const decideFile = plans.find((p) => p.outputPath.endsWith('decide.ts'));
564
564
 
565
565
  expect(decideFile?.contents).toMatchInlineSnapshot(`
@@ -98,7 +98,7 @@ describe('events.ts.ejs', () => {
98
98
  ],
99
99
  };
100
100
 
101
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
101
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
102
102
  const eventFile = plans.find((p) => p.outputPath.endsWith('events.ts'));
103
103
 
104
104
  expect(eventFile?.contents).toMatchInlineSnapshot(`
@@ -77,7 +77,7 @@ describe('evolve.ts.ejs', () => {
77
77
  ],
78
78
  };
79
79
 
80
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
80
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
81
81
  const evolveFile = plans.find((p) => p.outputPath.endsWith('evolve.ts'));
82
82
 
83
83
  expect(evolveFile?.contents).toMatchInlineSnapshot(`
@@ -104,7 +104,7 @@ describe('generateScaffoldFilePlans', () => {
104
104
  ],
105
105
  };
106
106
 
107
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
107
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
108
108
  const handleFile = plans.find((p) => p.outputPath.endsWith('handle.ts'));
109
109
 
110
110
  expect(handleFile?.contents).toMatchInlineSnapshot(`
@@ -282,7 +282,7 @@ describe('generateScaffoldFilePlans', () => {
282
282
  ],
283
283
  };
284
284
 
285
- const plans = await generateScaffoldFilePlans(
285
+ const { plans } = await generateScaffoldFilePlans(
286
286
  spec.narratives,
287
287
  spec.messages,
288
288
  spec.integrations,
@@ -77,7 +77,7 @@ describe('mutation.resolver.ts.ejs', () => {
77
77
  ],
78
78
  };
79
79
 
80
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
80
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
81
81
  const mutationFile = plans.find((p) => p.outputPath.endsWith('mutation.resolver.ts'));
82
82
 
83
83
  expect(mutationFile?.contents).toMatchInlineSnapshot(`
@@ -225,7 +225,7 @@ describe('mutation.resolver.ts.ejs', () => {
225
225
  integrations: [],
226
226
  };
227
227
 
228
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
228
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
229
229
  const mutationFile = plans.find(
230
230
  (p) =>
231
231
  p.outputPath.endsWith('mutation.resolver.ts') && p.contents.includes('export class AnswerQuestionResolver'),
@@ -325,7 +325,7 @@ describe('mutation.resolver.ts.ejs', () => {
325
325
  ],
326
326
  };
327
327
 
328
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
328
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
329
329
  const mutationFile = plans.find(
330
330
  (p) =>
331
331
  p.outputPath.endsWith('mutation.resolver.ts') && p.contents.includes('export class AddItemsToCartResolver'),
@@ -432,7 +432,7 @@ export class AddItemsToCartResolver {
432
432
  ],
433
433
  };
434
434
 
435
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
435
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
436
436
  const mutationFile = plans.find((p) => p.outputPath.endsWith('mutation.resolver.ts'));
437
437
 
438
438
  expect(mutationFile?.contents).toContain(
@@ -505,7 +505,7 @@ export class AddItemsToCartResolver {
505
505
  ],
506
506
  };
507
507
 
508
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
508
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
509
509
  const mutationFile = plans.find(
510
510
  (p) => p.outputPath.endsWith('mutation.resolver.ts') && p.contents.includes('export class PlaceOrderResolver'),
511
511
  );
@@ -105,7 +105,7 @@ describe('generateScaffoldFilePlans', () => {
105
105
  ],
106
106
  };
107
107
 
108
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
108
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
109
109
  const registerFile = plans.find((p) => p.outputPath.endsWith('register.ts'));
110
110
 
111
111
  expect(registerFile?.contents).toMatchInlineSnapshot(`
@@ -83,7 +83,7 @@ describe('state.ts.ejs', () => {
83
83
  ],
84
84
  };
85
85
 
86
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
86
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
87
87
  const stateFile = plans.find((p) => p.outputPath.endsWith('state.ts'));
88
88
 
89
89
  expect(stateFile?.contents).toMatchInlineSnapshot(`
@@ -192,7 +192,7 @@ describe('projection.specs.ts.ejs', () => {
192
192
  ],
193
193
  } as SpecsSchema;
194
194
 
195
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
195
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
196
196
  const specFile = plans.find((p) => p.outputPath.endsWith('projection.specs.ts'));
197
197
 
198
198
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -378,7 +378,7 @@ describe('projection.specs.ts.ejs', () => {
378
378
  ],
379
379
  } as SpecsSchema;
380
380
 
381
- const plans = await generateScaffoldFilePlans(
381
+ const { plans } = await generateScaffoldFilePlans(
382
382
  questionnaireSpec.narratives,
383
383
  questionnaireSpec.messages,
384
384
  undefined,
@@ -598,7 +598,7 @@ describe('projection.specs.ts.ejs', () => {
598
598
  ],
599
599
  } as SpecsSchema;
600
600
 
601
- const plans = await generateScaffoldFilePlans(
601
+ const { plans } = await generateScaffoldFilePlans(
602
602
  spec.narratives,
603
603
  [
604
604
  {
@@ -787,7 +787,7 @@ describe('projection.specs.ts.ejs', () => {
787
787
  ],
788
788
  } as SpecsSchema;
789
789
 
790
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
790
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
791
791
  const specFile = plans.find((p) => p.outputPath.endsWith('view-summary/projection.specs.ts'));
792
792
 
793
793
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -983,7 +983,7 @@ describe('projection.specs.ts.ejs', () => {
983
983
  ],
984
984
  } as SpecsSchema;
985
985
 
986
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
986
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
987
987
  const specFile = plans.find((p) => p.outputPath.endsWith('view-user-projects/projection.specs.ts'));
988
988
 
989
989
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -1162,7 +1162,7 @@ describe('projection.specs.ts.ejs', () => {
1162
1162
  ],
1163
1163
  } as SpecsSchema;
1164
1164
 
1165
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1165
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1166
1166
  const specFile = plans.find((p) => p.outputPath.endsWith('view-workout-history/projection.specs.ts'));
1167
1167
 
1168
1168
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -1355,7 +1355,7 @@ describe('projection.specs.ts.ejs', () => {
1355
1355
  ],
1356
1356
  } as SpecsSchema;
1357
1357
 
1358
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1358
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1359
1359
  const specFile = plans.find((p) => p.outputPath.endsWith('view-member-stats/projection.specs.ts'));
1360
1360
 
1361
1361
  expect(specFile?.contents).toMatchInlineSnapshot(`
@@ -1541,7 +1541,7 @@ describe('projection.specs.ts.ejs', () => {
1541
1541
  ],
1542
1542
  } as SpecsSchema;
1543
1543
 
1544
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1544
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1545
1545
  const projectionFile = plans.find((p) => p.outputPath.endsWith('view-workout-history/projection.ts'));
1546
1546
 
1547
1547
  expect(projectionFile?.contents).toMatchInlineSnapshot(`
@@ -1772,7 +1772,7 @@ describe('projection.specs.ts.ejs', () => {
1772
1772
  ],
1773
1773
  } as SpecsSchema;
1774
1774
 
1775
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1775
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1776
1776
  const projectionFile = plans.find((p) => p.outputPath.endsWith('view-items/projection.ts'));
1777
1777
  expect(projectionFile?.contents).toBeDefined();
1778
1778
 
@@ -1960,7 +1960,7 @@ describe('projection.specs.ts.ejs', () => {
1960
1960
  ],
1961
1961
  } as SpecsSchema;
1962
1962
 
1963
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1963
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
1964
1964
  const projectionFile = plans.find((p) => p.outputPath.endsWith('view-orders/projection.ts'));
1965
1965
  expect(projectionFile?.contents).toBeDefined();
1966
1966
 
@@ -2086,7 +2086,7 @@ describe('projection.specs.ts.ejs', () => {
2086
2086
  ],
2087
2087
  } as SpecsSchema;
2088
2088
 
2089
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
2089
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
2090
2090
  const specFile = plans.find((p) => p.outputPath.endsWith('view-appointments/projection.specs.ts'));
2091
2091
 
2092
2092
  expect(specFile?.contents).toContain("appointmentId: 'appt_789'");
@@ -213,7 +213,7 @@ describe('projection.ts.ejs', () => {
213
213
  ],
214
214
  };
215
215
 
216
- const plans = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
216
+ const { plans } = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
217
217
  const projectionFile = plans.find((p) => p.outputPath.endsWith('projection.ts'));
218
218
 
219
219
  expect(projectionFile?.contents).toMatchInlineSnapshot(`
@@ -349,7 +349,7 @@ describe('projection.ts.ejs', () => {
349
349
  ],
350
350
  };
351
351
 
352
- const plans = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
352
+ const { plans } = await generateScaffoldFilePlans(spec.narratives, spec.messages, undefined, 'src/domain/flows');
353
353
  const resolverFile = plans.find((p) => p.outputPath.endsWith('query.resolver.ts'));
354
354
 
355
355
  expect(resolverFile?.contents).toMatchInlineSnapshot(`
@@ -538,7 +538,7 @@ describe('projection.ts.ejs', () => {
538
538
  ],
539
539
  };
540
540
 
541
- const plans = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
541
+ const { plans } = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
542
542
  const projectionFile = plans.find((p) => p.outputPath.endsWith('view-summary/projection.ts'));
543
543
 
544
544
  expect(projectionFile?.contents).toMatchInlineSnapshot(`
@@ -767,7 +767,7 @@ describe('projection.ts.ejs', () => {
767
767
  ],
768
768
  };
769
769
 
770
- const plans = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
770
+ const { plans } = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
771
771
  const projectionFile = plans.find((p) => p.outputPath.endsWith('view-user-projects/projection.ts'));
772
772
 
773
773
  expect(projectionFile?.contents).toMatchInlineSnapshot(`
@@ -957,7 +957,7 @@ describe('projection.ts.ejs', () => {
957
957
  ],
958
958
  };
959
959
 
960
- const plans = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
960
+ const { plans } = await generateScaffoldFilePlans(flows.narratives, flows.messages, undefined, 'src/domain/flows');
961
961
  const projectionFile = plans.find((p) => p.outputPath.endsWith('view-order-status/projection.ts'));
962
962
 
963
963
  expect(projectionFile?.contents).not.toContain('number | "pending"');