@auto-engineer/narrative 0.12.1 → 0.13.1

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 (95) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +24 -0
  3. package/dist/src/commands/export-schema-runner.js +1 -1
  4. package/dist/src/commands/export-schema-runner.js.map +1 -1
  5. package/dist/src/fluent-builder.js +3 -3
  6. package/dist/src/fluent-builder.js.map +1 -1
  7. package/dist/src/getNarratives.specs.js +157 -161
  8. package/dist/src/getNarratives.specs.js.map +1 -1
  9. package/dist/src/id/addAutoIds.d.ts.map +1 -1
  10. package/dist/src/id/addAutoIds.js +23 -10
  11. package/dist/src/id/addAutoIds.js.map +1 -1
  12. package/dist/src/id/addAutoIds.specs.js +55 -46
  13. package/dist/src/id/addAutoIds.specs.js.map +1 -1
  14. package/dist/src/id/generators.js +1 -1
  15. package/dist/src/id/generators.js.map +1 -1
  16. package/dist/src/id/hasAllIds.d.ts.map +1 -1
  17. package/dist/src/id/hasAllIds.js +8 -3
  18. package/dist/src/id/hasAllIds.js.map +1 -1
  19. package/dist/src/id/hasAllIds.specs.js +142 -215
  20. package/dist/src/id/hasAllIds.specs.js.map +1 -1
  21. package/dist/src/index.d.ts +7 -8
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/dist/src/index.js +3 -3
  24. package/dist/src/index.js.map +1 -1
  25. package/dist/src/loader/graph.d.ts.map +1 -1
  26. package/dist/src/loader/graph.js +13 -6
  27. package/dist/src/loader/graph.js.map +1 -1
  28. package/dist/src/loader/ts-utils.d.ts +1 -0
  29. package/dist/src/loader/ts-utils.d.ts.map +1 -1
  30. package/dist/src/loader/ts-utils.js +95 -16
  31. package/dist/src/loader/ts-utils.js.map +1 -1
  32. package/dist/src/model-to-narrative.specs.js +548 -466
  33. package/dist/src/model-to-narrative.specs.js.map +1 -1
  34. package/dist/src/narrative-context.d.ts +8 -8
  35. package/dist/src/narrative-context.d.ts.map +1 -1
  36. package/dist/src/narrative-context.js +111 -301
  37. package/dist/src/narrative-context.js.map +1 -1
  38. package/dist/src/narrative-context.specs.js +15 -55
  39. package/dist/src/narrative-context.specs.js.map +1 -1
  40. package/dist/src/narrative.d.ts +19 -22
  41. package/dist/src/narrative.d.ts.map +1 -1
  42. package/dist/src/narrative.js +42 -71
  43. package/dist/src/narrative.js.map +1 -1
  44. package/dist/src/samples/questionnaires.narrative.js +10 -10
  45. package/dist/src/samples/questionnaires.narrative.js.map +1 -1
  46. package/dist/src/samples/test-with-ids.narrative.js +13 -29
  47. package/dist/src/samples/test-with-ids.narrative.js.map +1 -1
  48. package/dist/src/schema.d.ts +2704 -8293
  49. package/dist/src/schema.d.ts.map +1 -1
  50. package/dist/src/schema.js +26 -47
  51. package/dist/src/schema.js.map +1 -1
  52. package/dist/src/slice-builder.js +3 -3
  53. package/dist/src/slice-builder.js.map +1 -1
  54. package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
  55. package/dist/src/transformers/model-to-narrative/generators/flow.js +118 -74
  56. package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
  57. package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts +9 -1
  58. package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts.map +1 -1
  59. package/dist/src/transformers/model-to-narrative/generators/gwt.js +112 -112
  60. package/dist/src/transformers/model-to-narrative/generators/gwt.js.map +1 -1
  61. package/dist/src/transformers/model-to-narrative/generators/imports.d.ts +1 -1
  62. package/dist/src/transformers/model-to-narrative/generators/imports.d.ts.map +1 -1
  63. package/dist/src/transformers/model-to-narrative/generators/imports.js +13 -9
  64. package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
  65. package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
  66. package/dist/src/transformers/narrative-to-model/index.js +50 -23
  67. package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
  68. package/dist/src/transformers/narrative-to-model/type-inference.specs.js +100 -90
  69. package/dist/src/transformers/narrative-to-model/type-inference.specs.js.map +1 -1
  70. package/dist/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +5 -5
  72. package/src/commands/export-schema-runner.ts +3 -1
  73. package/src/fluent-builder.ts +3 -3
  74. package/src/getNarratives.specs.ts +176 -184
  75. package/src/id/addAutoIds.specs.ts +55 -48
  76. package/src/id/addAutoIds.ts +28 -11
  77. package/src/id/generators.ts +1 -1
  78. package/src/id/hasAllIds.specs.ts +147 -245
  79. package/src/id/hasAllIds.ts +11 -4
  80. package/src/index.ts +11 -12
  81. package/src/loader/graph.ts +23 -6
  82. package/src/loader/ts-utils.ts +169 -26
  83. package/src/model-to-narrative.specs.ts +548 -466
  84. package/src/narrative-context.specs.ts +73 -116
  85. package/src/narrative-context.ts +127 -374
  86. package/src/narrative.ts +70 -120
  87. package/src/samples/questionnaires.narrative.ts +10 -10
  88. package/src/samples/test-with-ids.narrative.ts +23 -31
  89. package/src/schema.ts +33 -52
  90. package/src/slice-builder.ts +3 -3
  91. package/src/transformers/model-to-narrative/generators/flow.ts +191 -85
  92. package/src/transformers/model-to-narrative/generators/gwt.ts +195 -178
  93. package/src/transformers/model-to-narrative/generators/imports.ts +13 -9
  94. package/src/transformers/narrative-to-model/index.ts +87 -26
  95. package/src/transformers/narrative-to-model/type-inference.specs.ts +100 -90
@@ -1,16 +1,23 @@
1
- import { Model, Slice } from '../index';
1
+ import { Model, Slice, Spec, Rule } from '../index';
2
2
 
3
3
  function hasValidId(item: { id?: string }): boolean {
4
4
  return item.id !== undefined && item.id !== '';
5
5
  }
6
6
 
7
+ function hasRuleIds(rules: Rule[]): boolean {
8
+ return rules.every((rule) => hasValidId(rule));
9
+ }
10
+
11
+ function hasSpecIds(specs: Spec[]): boolean {
12
+ return specs.every((spec) => hasRuleIds(spec.rules));
13
+ }
14
+
7
15
  function hasServerSpecIds(slice: Slice): boolean {
8
- if (!('server' in slice) || slice.server?.specs?.rules === undefined) return true;
9
- return slice.server.specs.rules.every(hasValidId);
16
+ if (!('server' in slice) || slice.server?.specs === undefined || !Array.isArray(slice.server.specs)) return true;
17
+ return hasSpecIds(slice.server.specs);
10
18
  }
11
19
 
12
20
  function hasClientSpecIds(_slice: Slice): boolean {
13
- // Client specs use string rules (no IDs needed), so always valid
14
21
  return true;
15
22
  }
16
23
 
package/src/index.ts CHANGED
@@ -44,7 +44,8 @@ export type { FieldSelector } from './data-narrative-builders';
44
44
 
45
45
  // Narrative language functions
46
46
  export { narrative, narrative as flow } from './narrative';
47
- export { client, server, specs, describe, it, should, request, data, rule, example } from './narrative';
47
+ export { client, server, specs, describe, it, should, request, data, rule, example, thenError } from './narrative';
48
+ export type { ExampleBuilder, GivenBuilder, WhenBuilder, ThenBuilder } from './narrative';
48
49
  export type { SliceTypeValueInterface } from './narrative';
49
50
  export { SliceType } from './narrative';
50
51
 
@@ -52,8 +53,10 @@ export { SliceType } from './narrative';
52
53
  export { getNarratives } from './getNarratives';
53
54
  export { modelToNarrative } from './transformers/model-to-narrative';
54
55
 
56
+ export type { ExportSchemaEvents } from './commands/export-schema';
57
+
55
58
  // Testing helpers
56
- export { createNarrativeSpec, given, when } from './testing';
59
+ export { createNarrativeSpec, given as testGiven, when as testWhen } from './testing';
57
60
 
58
61
  // Schema definitions for progressive narrative creation
59
62
  export {
@@ -74,21 +77,19 @@ export {
74
77
  SliceSchema,
75
78
  NarrativeSchema,
76
79
  modelSchema,
77
- EventExampleSchema,
78
- CommandExampleSchema,
79
80
  ExampleSchema,
80
81
  RuleSchema,
81
82
  SpecSchema,
83
+ StepSchema,
84
+ StepErrorSchema,
85
+ StepWithDocStringSchema,
86
+ StepWithErrorSchema,
82
87
  } from './schema';
83
88
 
84
89
  import {
85
- CommandExampleSchema,
86
- ErrorExampleSchema,
87
- EventExampleSchema,
88
90
  NarrativeSchema,
89
91
  SliceSchema,
90
92
  modelSchema,
91
- StateExampleSchema,
92
93
  QuerySliceSchema,
93
94
  ReactSliceSchema,
94
95
  ExperienceSliceSchema,
@@ -98,14 +99,11 @@ import {
98
99
  ExampleSchema,
99
100
  RuleSchema,
100
101
  SpecSchema,
102
+ StepSchema,
101
103
  } from './schema';
102
104
  export type Model = z.infer<typeof modelSchema>;
103
105
  export type Narrative = z.infer<typeof NarrativeSchema>;
104
- export type CommandExample = z.infer<typeof CommandExampleSchema>;
105
- export type EventExample = z.infer<typeof EventExampleSchema>;
106
106
  export type Slice = z.infer<typeof SliceSchema>;
107
- export type StateExample = z.infer<typeof StateExampleSchema>;
108
- export type ErrorExample = z.infer<typeof ErrorExampleSchema>;
109
107
  export type QuerySlice = z.infer<typeof QuerySliceSchema>;
110
108
  export type ReactSlice = z.infer<typeof ReactSliceSchema>;
111
109
  export type CommandSlice = z.infer<typeof CommandSliceSchema>;
@@ -115,6 +113,7 @@ export type Example = z.infer<typeof ExampleSchema>;
115
113
  export type MessageField = z.infer<typeof MessageFieldSchema>;
116
114
  export type Rule = z.infer<typeof RuleSchema>;
117
115
  export type Spec = z.infer<typeof SpecSchema>;
116
+ export type Step = z.infer<typeof StepSchema>;
118
117
  export type { ClientSpecNode } from './schema';
119
118
 
120
119
  // ID assignment utilities
@@ -8,6 +8,7 @@ import {
8
8
  parseIntegrationImports,
9
9
  parseGivenTypeArguments,
10
10
  parseWhenTypeArguments,
11
+ parseThenTypeArguments,
11
12
  patchImportMeta,
12
13
  transpileToCjs,
13
14
  TypeInfo,
@@ -312,8 +313,12 @@ export async function buildGraph(
312
313
  function extractTypeInfoFromProgram(
313
314
  program: import('typescript').Program,
314
315
  checker: import('typescript').TypeChecker,
315
- ): Map<string, import('./ts-utils').GivenTypeInfo[]> {
316
+ ): {
317
+ whenTypes: Map<string, import('./ts-utils').GivenTypeInfo[]>;
318
+ thenTypes: Map<string, import('./ts-utils').GivenTypeInfo[]>;
319
+ } {
316
320
  const whenTypesByFile: Map<string, import('./ts-utils').GivenTypeInfo[]> = new Map();
321
+ const thenTypesByFile: Map<string, import('./ts-utils').GivenTypeInfo[]> = new Map();
317
322
 
318
323
  for (const sourceFile of program.getSourceFiles()) {
319
324
  const posixPath = toPosix(sourceFile.fileName);
@@ -322,24 +327,35 @@ export async function buildGraph(
322
327
  const fileTypeMap = typesByFile.get(posixPath) || new Map();
323
328
  const extractedGivenTypes = parseGivenTypeArguments(ts, checker, sourceFile, fileTypeMap, typesByFile);
324
329
  const extractedWhenTypes = parseWhenTypeArguments(ts, checker, sourceFile, fileTypeMap, typesByFile);
330
+ const extractedThenTypes = parseThenTypeArguments(ts, checker, sourceFile, fileTypeMap, typesByFile);
325
331
 
326
332
  if (extractedGivenTypes.length > 0) {
327
333
  givenTypesByFile.set(posixPath, extractedGivenTypes);
328
- debug('[given-types] extracted %d .given<T>() calls from %s', extractedGivenTypes.length, posixPath);
334
+ debug('[given-types] extracted %d given<T>() calls from %s', extractedGivenTypes.length, posixPath);
329
335
  }
330
336
 
331
337
  if (extractedWhenTypes.length > 0) {
332
338
  whenTypesByFile.set(posixPath, extractedWhenTypes);
333
339
  debug(
334
- '[when-types] extracted %d .when<T>() calls from %s: %o',
340
+ '[when-types] extracted %d when<T>() calls from %s: %o',
335
341
  extractedWhenTypes.length,
336
342
  posixPath,
337
343
  extractedWhenTypes.map((t) => ({ typeName: t.typeName, classification: t.classification })),
338
344
  );
339
345
  }
346
+
347
+ if (extractedThenTypes.length > 0) {
348
+ thenTypesByFile.set(posixPath, extractedThenTypes);
349
+ debug(
350
+ '[then-types] extracted %d then<T>() calls from %s: %o',
351
+ extractedThenTypes.length,
352
+ posixPath,
353
+ extractedThenTypes.map((t) => ({ typeName: t.typeName, classification: t.classification })),
354
+ );
355
+ }
340
356
  }
341
357
 
342
- return whenTypesByFile;
358
+ return { whenTypes: whenTypesByFile, thenTypes: thenTypesByFile };
343
359
  }
344
360
 
345
361
  for (const entry of entryFiles) {
@@ -352,9 +368,10 @@ export async function buildGraph(
352
368
  const program = ts.createProgram([...sourceFiles.keys()], compilerOptions, host);
353
369
  const checker = program.getTypeChecker();
354
370
 
355
- const whenTypesByFile = extractTypeInfoFromProgram(program, checker);
371
+ const { whenTypes, thenTypes } = extractTypeInfoFromProgram(program, checker);
356
372
 
357
- givenTypesByFile.set('__whenTypes', whenTypesByFile as unknown as import('./ts-utils').GivenTypeInfo[]);
373
+ givenTypesByFile.set('__whenTypes', whenTypes as unknown as import('./ts-utils').GivenTypeInfo[]);
374
+ givenTypesByFile.set('__thenTypes', thenTypes as unknown as import('./ts-utils').GivenTypeInfo[]);
358
375
 
359
376
  const result: BuildGraphResult = {
360
377
  graph,
@@ -660,14 +660,13 @@ export function parseWhenTypeArguments(
660
660
  const whenTypes: GivenTypeInfo[] = [];
661
661
 
662
662
  const visit = (node: import('typescript').Node): void => {
663
- if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
664
- const method = node.expression.name.getText();
665
- if (method === 'when') {
663
+ if (ts.isCallExpression(node)) {
664
+ if (ts.isIdentifier(node.expression) && node.expression.text === 'when') {
666
665
  if (node.typeArguments && node.typeArguments.length > 0) {
667
666
  const typeArg = node.typeArguments[0];
668
667
  const typeArgText = typeArg.getText(sourceFile);
669
668
  debug(
670
- '[when-types] found .when<%s> at line %d, will process as ordinal %d',
669
+ '[when-types] found when<%s> at line %d, will process as ordinal %d',
671
670
  typeArgText,
672
671
  sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1,
673
672
  whenTypes.length,
@@ -676,7 +675,7 @@ export function parseWhenTypeArguments(
676
675
  } else {
677
676
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
678
677
  debug(
679
- '[when-types] found .when() without type argument at line %d, adding placeholder at ordinal %d',
678
+ '[when-types] found when() without type argument at line %d, adding placeholder at ordinal %d',
680
679
  line + 1,
681
680
  whenTypes.length,
682
681
  );
@@ -690,6 +689,38 @@ export function parseWhenTypeArguments(
690
689
  });
691
690
  }
692
691
  }
692
+ // Handle property access (fluent API): .when<T>({...})
693
+ else if (ts.isPropertyAccessExpression(node.expression)) {
694
+ const method = node.expression.name.getText();
695
+ if (method === 'when') {
696
+ if (node.typeArguments && node.typeArguments.length > 0) {
697
+ const typeArg = node.typeArguments[0];
698
+ const typeArgText = typeArg.getText(sourceFile);
699
+ debug(
700
+ '[when-types] found .when<%s> at line %d, will process as ordinal %d',
701
+ typeArgText,
702
+ sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1,
703
+ whenTypes.length,
704
+ );
705
+ processWhenCallExpression(ts, node, checker, sourceFile, typeMap, typesByFile, whenTypes, whenTypes.length);
706
+ } else {
707
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
708
+ debug(
709
+ '[when-types] found .when() without type argument at line %d, adding placeholder at ordinal %d',
710
+ line + 1,
711
+ whenTypes.length,
712
+ );
713
+ whenTypes.push({
714
+ fileName: sourceFile.fileName,
715
+ line: line + 1,
716
+ column: character + 1,
717
+ ordinal: whenTypes.length,
718
+ typeName: '',
719
+ classification: 'command',
720
+ });
721
+ }
722
+ }
723
+ }
693
724
  }
694
725
  ts.forEachChild(node, visit);
695
726
  };
@@ -699,6 +730,43 @@ export function parseWhenTypeArguments(
699
730
  return whenTypes;
700
731
  }
701
732
 
733
+ function processStandaloneGivenCall(
734
+ ts: typeof import('typescript'),
735
+ node: import('typescript').CallExpression,
736
+ checker: import('typescript').TypeChecker,
737
+ sourceFile: import('typescript').SourceFile,
738
+ typeMap: Map<string, TypeInfo>,
739
+ typesByFile: Map<string, Map<string, TypeInfo>>,
740
+ givenTypes: GivenTypeInfo[],
741
+ processedNodes: Set<import('typescript').CallExpression>,
742
+ ): void {
743
+ if (node.typeArguments !== undefined && node.typeArguments.length > 0) {
744
+ processGivenOrAndCallExpression(ts, node, checker, sourceFile, typeMap, typesByFile, givenTypes, givenTypes.length);
745
+ processedNodes.add(node);
746
+ }
747
+ }
748
+
749
+ function processFluentGivenChain(
750
+ ts: typeof import('typescript'),
751
+ node: import('typescript').CallExpression,
752
+ checker: import('typescript').TypeChecker,
753
+ sourceFile: import('typescript').SourceFile,
754
+ typeMap: Map<string, TypeInfo>,
755
+ typesByFile: Map<string, Map<string, TypeInfo>>,
756
+ givenTypes: GivenTypeInfo[],
757
+ processedNodes: Set<import('typescript').CallExpression>,
758
+ ): void {
759
+ const chain = collectChainFromStart(ts, node);
760
+ let ordinal = givenTypes.length;
761
+
762
+ for (const chainNode of chain) {
763
+ if (chainNode.typeArguments !== undefined && chainNode.typeArguments.length > 0) {
764
+ processGivenOrAndCallExpression(ts, chainNode, checker, sourceFile, typeMap, typesByFile, givenTypes, ordinal++);
765
+ processedNodes.add(chainNode);
766
+ }
767
+ }
768
+ }
769
+
702
770
  export function parseGivenTypeArguments(
703
771
  ts: typeof import('typescript'),
704
772
  checker: import('typescript').TypeChecker,
@@ -709,31 +777,14 @@ export function parseGivenTypeArguments(
709
777
  const givenTypes: GivenTypeInfo[] = [];
710
778
  const processedNodes = new Set<import('typescript').CallExpression>();
711
779
 
712
- // First pass: find all given/and chain starts
713
780
  const visit = (node: import('typescript').Node): void => {
714
781
  if (ts.isCallExpression(node) && !processedNodes.has(node)) {
715
- if (ts.isPropertyAccessExpression(node.expression)) {
782
+ if (ts.isIdentifier(node.expression) && node.expression.text === 'given') {
783
+ processStandaloneGivenCall(ts, node, checker, sourceFile, typeMap, typesByFile, givenTypes, processedNodes);
784
+ } else if (ts.isPropertyAccessExpression(node.expression)) {
716
785
  const method = node.expression.name.getText();
717
786
  if (method === 'given' && isChainStart(ts, node)) {
718
- // Found a chain start, collect the entire chain
719
- const chain = collectChainFromStart(ts, node);
720
- let ordinal = givenTypes.length;
721
-
722
- for (const chainNode of chain) {
723
- if (chainNode.typeArguments !== undefined && chainNode.typeArguments.length > 0) {
724
- processGivenOrAndCallExpression(
725
- ts,
726
- chainNode,
727
- checker,
728
- sourceFile,
729
- typeMap,
730
- typesByFile,
731
- givenTypes,
732
- ordinal++,
733
- );
734
- processedNodes.add(chainNode);
735
- }
736
- }
787
+ processFluentGivenChain(ts, node, checker, sourceFile, typeMap, typesByFile, givenTypes, processedNodes);
737
788
  }
738
789
  }
739
790
  }
@@ -744,6 +795,98 @@ export function parseGivenTypeArguments(
744
795
  return givenTypes;
745
796
  }
746
797
 
798
+ function processThenCallWithTypeArg(
799
+ ts: typeof import('typescript'),
800
+ node: import('typescript').CallExpression,
801
+ checker: import('typescript').TypeChecker,
802
+ sourceFile: import('typescript').SourceFile,
803
+ typeMap: Map<string, TypeInfo>,
804
+ typesByFile: Map<string, Map<string, TypeInfo>>,
805
+ thenTypes: GivenTypeInfo[],
806
+ debugPrefix: string,
807
+ ): void {
808
+ const typeArg = node.typeArguments![0];
809
+ const typeArgText = typeArg.getText(sourceFile);
810
+ debug(
811
+ '[then-types] found %s<%s> at line %d, will process as ordinal %d',
812
+ debugPrefix,
813
+ typeArgText,
814
+ sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1,
815
+ thenTypes.length,
816
+ );
817
+ const genericResult = tryUnwrapGeneric(ts, typeArg, checker, typeMap, typesByFile);
818
+ if (genericResult !== undefined && genericResult !== null) {
819
+ thenTypes.push(
820
+ createGivenTypeInfo(sourceFile, node, thenTypes.length, genericResult.typeName, genericResult.classification),
821
+ );
822
+ }
823
+ }
824
+
825
+ function processThenCallWithoutTypeArg(
826
+ sourceFile: import('typescript').SourceFile,
827
+ node: import('typescript').CallExpression,
828
+ thenTypes: GivenTypeInfo[],
829
+ debugPrefix: string,
830
+ ): void {
831
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
832
+ debug(
833
+ '[then-types] found %s without type argument at line %d, adding placeholder at ordinal %d',
834
+ debugPrefix,
835
+ line + 1,
836
+ thenTypes.length,
837
+ );
838
+ thenTypes.push({
839
+ fileName: sourceFile.fileName,
840
+ line: line + 1,
841
+ column: character + 1,
842
+ ordinal: thenTypes.length,
843
+ typeName: '',
844
+ classification: 'event',
845
+ });
846
+ }
847
+
848
+ function processThenCall(
849
+ ts: typeof import('typescript'),
850
+ node: import('typescript').CallExpression,
851
+ checker: import('typescript').TypeChecker,
852
+ sourceFile: import('typescript').SourceFile,
853
+ typeMap: Map<string, TypeInfo>,
854
+ typesByFile: Map<string, Map<string, TypeInfo>>,
855
+ thenTypes: GivenTypeInfo[],
856
+ debugPrefix: string,
857
+ ): void {
858
+ if (node.typeArguments !== undefined && node.typeArguments.length > 0) {
859
+ processThenCallWithTypeArg(ts, node, checker, sourceFile, typeMap, typesByFile, thenTypes, debugPrefix);
860
+ } else {
861
+ processThenCallWithoutTypeArg(sourceFile, node, thenTypes, debugPrefix);
862
+ }
863
+ }
864
+
865
+ export function parseThenTypeArguments(
866
+ ts: typeof import('typescript'),
867
+ checker: import('typescript').TypeChecker,
868
+ sourceFile: import('typescript').SourceFile,
869
+ typeMap: Map<string, TypeInfo>,
870
+ typesByFile: Map<string, Map<string, TypeInfo>>,
871
+ ): GivenTypeInfo[] {
872
+ const thenTypes: GivenTypeInfo[] = [];
873
+
874
+ const visit = (node: import('typescript').Node): void => {
875
+ if (ts.isCallExpression(node)) {
876
+ if (ts.isIdentifier(node.expression) && node.expression.text === 'then') {
877
+ processThenCall(ts, node, checker, sourceFile, typeMap, typesByFile, thenTypes, 'then');
878
+ } else if (ts.isPropertyAccessExpression(node.expression) && node.expression.name.getText() === 'then') {
879
+ processThenCall(ts, node, checker, sourceFile, typeMap, typesByFile, thenTypes, '.then');
880
+ }
881
+ }
882
+ ts.forEachChild(node, visit);
883
+ };
884
+
885
+ visit(sourceFile);
886
+ debug('[then-types] total then types extracted: %d', thenTypes.length);
887
+ return thenTypes;
888
+ }
889
+
747
890
  export function transpileToCjs(ts: typeof import('typescript'), fileName: string, source: string): string {
748
891
  const out = ts.transpileModule(source, {
749
892
  compilerOptions: {