@gqlkit-ts/cli 0.6.0 → 0.7.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 (190) hide show
  1. package/dist/auto-type-generator/auto-type-generator.d.ts +7 -0
  2. package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
  3. package/dist/auto-type-generator/auto-type-generator.js +375 -55
  4. package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
  5. package/dist/auto-type-generator/discriminator-field-validator.d.ts +26 -0
  6. package/dist/auto-type-generator/discriminator-field-validator.d.ts.map +1 -0
  7. package/dist/auto-type-generator/discriminator-field-validator.js +242 -0
  8. package/dist/auto-type-generator/discriminator-field-validator.js.map +1 -0
  9. package/dist/auto-type-generator/discriminator-naming.d.ts +11 -0
  10. package/dist/auto-type-generator/discriminator-naming.d.ts.map +1 -0
  11. package/dist/auto-type-generator/discriminator-naming.js +15 -0
  12. package/dist/auto-type-generator/discriminator-naming.js.map +1 -0
  13. package/dist/auto-type-generator/discriminator-resolve-type-generator.d.ts +44 -0
  14. package/dist/auto-type-generator/discriminator-resolve-type-generator.d.ts.map +1 -0
  15. package/dist/auto-type-generator/discriminator-resolve-type-generator.js +77 -0
  16. package/dist/auto-type-generator/discriminator-resolve-type-generator.js.map +1 -0
  17. package/dist/auto-type-generator/index.d.ts +3 -0
  18. package/dist/auto-type-generator/index.d.ts.map +1 -1
  19. package/dist/auto-type-generator/index.js +3 -0
  20. package/dist/auto-type-generator/index.js.map +1 -1
  21. package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -1
  22. package/dist/auto-type-generator/inline-enum-collector.js +14 -7
  23. package/dist/auto-type-generator/inline-enum-collector.js.map +1 -1
  24. package/dist/auto-type-generator/inline-object-converter.d.ts +12 -0
  25. package/dist/auto-type-generator/inline-object-converter.d.ts.map +1 -0
  26. package/dist/auto-type-generator/inline-object-converter.js +72 -0
  27. package/dist/auto-type-generator/inline-object-converter.js.map +1 -0
  28. package/dist/auto-type-generator/inline-object-traverser.d.ts +2 -1
  29. package/dist/auto-type-generator/inline-object-traverser.d.ts.map +1 -1
  30. package/dist/auto-type-generator/inline-object-traverser.js +22 -4
  31. package/dist/auto-type-generator/inline-object-traverser.js.map +1 -1
  32. package/dist/auto-type-generator/inline-union-collector.d.ts.map +1 -1
  33. package/dist/auto-type-generator/inline-union-collector.js +20 -6
  34. package/dist/auto-type-generator/inline-union-collector.js.map +1 -1
  35. package/dist/auto-type-generator/inline-union-types.d.ts +2 -0
  36. package/dist/auto-type-generator/inline-union-types.d.ts.map +1 -1
  37. package/dist/auto-type-generator/inline-union-validator.js +3 -3
  38. package/dist/auto-type-generator/inline-union-validator.js.map +1 -1
  39. package/dist/auto-type-generator/intersection-flattener.d.ts +44 -0
  40. package/dist/auto-type-generator/intersection-flattener.d.ts.map +1 -0
  41. package/dist/auto-type-generator/intersection-flattener.js +398 -0
  42. package/dist/auto-type-generator/intersection-flattener.js.map +1 -0
  43. package/dist/auto-type-generator/naming-convention.d.ts +21 -0
  44. package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
  45. package/dist/auto-type-generator/naming-convention.js +145 -1
  46. package/dist/auto-type-generator/naming-convention.js.map +1 -1
  47. package/dist/auto-type-generator/typename-extractor.d.ts +2 -0
  48. package/dist/auto-type-generator/typename-extractor.d.ts.map +1 -1
  49. package/dist/auto-type-generator/typename-extractor.js +11 -3
  50. package/dist/auto-type-generator/typename-extractor.js.map +1 -1
  51. package/dist/auto-type-generator/typename-resolve-type-generator.d.ts +2 -0
  52. package/dist/auto-type-generator/typename-resolve-type-generator.d.ts.map +1 -1
  53. package/dist/auto-type-generator/typename-resolve-type-generator.js +12 -84
  54. package/dist/auto-type-generator/typename-resolve-type-generator.js.map +1 -1
  55. package/dist/auto-type-generator/typename-types.d.ts +4 -0
  56. package/dist/auto-type-generator/typename-types.d.ts.map +1 -1
  57. package/dist/auto-type-generator/typename-types.js +6 -0
  58. package/dist/auto-type-generator/typename-types.js.map +1 -1
  59. package/dist/auto-type-generator/typename-validator.d.ts.map +1 -1
  60. package/dist/auto-type-generator/typename-validator.js +4 -3
  61. package/dist/auto-type-generator/typename-validator.js.map +1 -1
  62. package/dist/commands/gen.d.ts.map +1 -1
  63. package/dist/commands/gen.js +2 -1
  64. package/dist/commands/gen.js.map +1 -1
  65. package/dist/config/types.d.ts +7 -0
  66. package/dist/config/types.d.ts.map +1 -1
  67. package/dist/config-loader/index.d.ts +1 -1
  68. package/dist/config-loader/index.d.ts.map +1 -1
  69. package/dist/config-loader/index.js.map +1 -1
  70. package/dist/config-loader/loader.d.ts +6 -0
  71. package/dist/config-loader/loader.d.ts.map +1 -1
  72. package/dist/config-loader/loader.js +1 -0
  73. package/dist/config-loader/loader.js.map +1 -1
  74. package/dist/config-loader/validator.d.ts.map +1 -1
  75. package/dist/config-loader/validator.js +84 -1
  76. package/dist/config-loader/validator.js.map +1 -1
  77. package/dist/gen-orchestrator/orchestrator.d.ts +2 -1
  78. package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
  79. package/dist/gen-orchestrator/orchestrator.js +15 -2
  80. package/dist/gen-orchestrator/orchestrator.js.map +1 -1
  81. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
  82. package/dist/resolver-extractor/extractor/define-api-extractor.js +4 -0
  83. package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
  84. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +2 -0
  85. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts.map +1 -1
  86. package/dist/resolver-extractor/validator/abstract-resolver-validator.js +16 -3
  87. package/dist/resolver-extractor/validator/abstract-resolver-validator.js.map +1 -1
  88. package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
  89. package/dist/schema-generator/emitter/code-emitter.js +13 -1
  90. package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
  91. package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.d.ts +18 -0
  92. package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.d.ts.map +1 -0
  93. package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.js +89 -0
  94. package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.js.map +1 -0
  95. package/dist/schema-generator/generate-schema.d.ts +2 -0
  96. package/dist/schema-generator/generate-schema.d.ts.map +1 -1
  97. package/dist/schema-generator/generate-schema.js +69 -10
  98. package/dist/schema-generator/generate-schema.js.map +1 -1
  99. package/dist/schema-generator/integrator/result-integrator.d.ts +4 -0
  100. package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
  101. package/dist/schema-generator/integrator/result-integrator.js +18 -2
  102. package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
  103. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +2 -0
  104. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -1
  105. package/dist/schema-generator/resolver-collector/resolver-collector.js +4 -0
  106. package/dist/schema-generator/resolver-collector/resolver-collector.js.map +1 -1
  107. package/dist/shared/constants.d.ts.map +1 -1
  108. package/dist/shared/constants.js +14 -1
  109. package/dist/shared/constants.js.map +1 -1
  110. package/dist/shared/enum-prefix-detector.d.ts.map +1 -1
  111. package/dist/shared/enum-prefix-detector.js +78 -8
  112. package/dist/shared/enum-prefix-detector.js.map +1 -1
  113. package/dist/shared/inline-object-utils.js +1 -1
  114. package/dist/shared/inline-object-utils.js.map +1 -1
  115. package/dist/shared/type-converter.d.ts.map +1 -1
  116. package/dist/shared/type-converter.js +55 -0
  117. package/dist/shared/type-converter.js.map +1 -1
  118. package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
  119. package/dist/type-extractor/converter/graphql-converter.js +11 -1
  120. package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
  121. package/dist/type-extractor/extractor/field-type-resolver.d.ts +18 -0
  122. package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -1
  123. package/dist/type-extractor/extractor/field-type-resolver.js +198 -15
  124. package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -1
  125. package/dist/type-extractor/extractor/type-extractor.d.ts +1 -0
  126. package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
  127. package/dist/type-extractor/extractor/type-extractor.js +100 -9
  128. package/dist/type-extractor/extractor/type-extractor.js.map +1 -1
  129. package/dist/type-extractor/types/diagnostics.d.ts +1 -1
  130. package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
  131. package/dist/type-extractor/types/index.d.ts +1 -1
  132. package/dist/type-extractor/types/index.d.ts.map +1 -1
  133. package/dist/type-extractor/types/index.js +1 -1
  134. package/dist/type-extractor/types/index.js.map +1 -1
  135. package/dist/type-extractor/types/ts-type-reference-factory.d.ts +7 -1
  136. package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -1
  137. package/dist/type-extractor/types/ts-type-reference-factory.js +18 -3
  138. package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -1
  139. package/dist/type-extractor/types/typescript.d.ts +3 -1
  140. package/dist/type-extractor/types/typescript.d.ts.map +1 -1
  141. package/dist/type-extractor/validator/type-validator.d.ts.map +1 -1
  142. package/dist/type-extractor/validator/type-validator.js +6 -1
  143. package/dist/type-extractor/validator/type-validator.js.map +1 -1
  144. package/docs/configuration.md +19 -0
  145. package/docs/index.md +1 -0
  146. package/docs/integration/ai-sdk.md +189 -0
  147. package/docs/schema/unions.md +117 -0
  148. package/package.json +2 -2
  149. package/src/auto-type-generator/auto-type-generator.ts +576 -58
  150. package/src/auto-type-generator/discriminator-field-validator.ts +368 -0
  151. package/src/auto-type-generator/discriminator-naming.ts +24 -0
  152. package/src/auto-type-generator/discriminator-resolve-type-generator.ts +136 -0
  153. package/src/auto-type-generator/index.ts +17 -0
  154. package/src/auto-type-generator/inline-enum-collector.ts +19 -4
  155. package/src/auto-type-generator/inline-object-converter.ts +100 -0
  156. package/src/auto-type-generator/inline-object-traverser.ts +33 -7
  157. package/src/auto-type-generator/inline-union-collector.ts +26 -4
  158. package/src/auto-type-generator/inline-union-types.ts +2 -0
  159. package/src/auto-type-generator/inline-union-validator.ts +3 -3
  160. package/src/auto-type-generator/intersection-flattener.ts +554 -0
  161. package/src/auto-type-generator/naming-convention.ts +205 -1
  162. package/src/auto-type-generator/typename-extractor.ts +17 -3
  163. package/src/auto-type-generator/typename-resolve-type-generator.ts +19 -108
  164. package/src/auto-type-generator/typename-types.ts +7 -0
  165. package/src/auto-type-generator/typename-validator.ts +4 -3
  166. package/src/commands/gen.ts +9 -2
  167. package/src/config/types.ts +10 -0
  168. package/src/config-loader/index.ts +1 -0
  169. package/src/config-loader/loader.ts +11 -0
  170. package/src/config-loader/validator.ts +100 -1
  171. package/src/gen-orchestrator/orchestrator.ts +19 -2
  172. package/src/resolver-extractor/extractor/define-api-extractor.ts +4 -0
  173. package/src/resolver-extractor/validator/abstract-resolver-validator.ts +20 -6
  174. package/src/schema-generator/emitter/code-emitter.ts +26 -1
  175. package/src/schema-generator/emitter/discriminator-resolve-type-emitter.ts +125 -0
  176. package/src/schema-generator/generate-schema.ts +100 -13
  177. package/src/schema-generator/integrator/result-integrator.ts +25 -1
  178. package/src/schema-generator/resolver-collector/resolver-collector.ts +7 -0
  179. package/src/shared/constants.ts +15 -1
  180. package/src/shared/enum-prefix-detector.ts +96 -8
  181. package/src/shared/inline-object-utils.ts +1 -1
  182. package/src/shared/type-converter.ts +63 -0
  183. package/src/type-extractor/converter/graphql-converter.ts +17 -1
  184. package/src/type-extractor/extractor/field-type-resolver.ts +241 -16
  185. package/src/type-extractor/extractor/type-extractor.ts +119 -5
  186. package/src/type-extractor/types/diagnostics.ts +10 -1
  187. package/src/type-extractor/types/index.ts +2 -1
  188. package/src/type-extractor/types/ts-type-reference-factory.ts +24 -3
  189. package/src/type-extractor/types/typescript.ts +6 -2
  190. package/src/type-extractor/validator/type-validator.ts +6 -1
@@ -1,4 +1,5 @@
1
1
  import type ts from "typescript";
2
+ import type { ResolvedDiscriminatorFieldsMap } from "../config-loader/index.js";
2
3
  import type {
3
4
  ExtractResolversResult,
4
5
  GraphQLFieldDefinition,
@@ -25,6 +26,7 @@ import {
25
26
  type InlineEnumMemberInfo,
26
27
  type InlineObjectPropertyDef,
27
28
  type SourceLocation,
29
+ type TSTypeReference,
28
30
  } from "../type-extractor/types/index.js";
29
31
  import {
30
32
  collectInlineEnumsFromPayloads,
@@ -45,8 +47,13 @@ import {
45
47
  validateUnionMembers,
46
48
  validateUnionMemberTypenames,
47
49
  } from "./inline-union-validator.js";
50
+ import {
51
+ flattenInlineUnionMembers,
52
+ type InlineDiscriminatorResolveType,
53
+ } from "./intersection-flattener.js";
48
54
  import {
49
55
  type AutoTypeNameContext,
56
+ appendFieldPath,
50
57
  buildFieldContext,
51
58
  generateAutoTypeName,
52
59
  isInputTypeName,
@@ -59,6 +66,7 @@ import {
59
66
  import {
60
67
  createFieldNameSet,
61
68
  findTypenameProperty,
69
+ isTypenameFieldName,
62
70
  type TypenameFieldInfo,
63
71
  type TypenameFieldName,
64
72
  } from "./typename-types.js";
@@ -130,6 +138,7 @@ export interface AutoTypeGeneratorInput {
130
138
  readonly extractedTypes: ReadonlyArray<ExtractedTypeInfo>;
131
139
  readonly resolversResult: ExtractResolversResult;
132
140
  readonly knownTypeNames: ReadonlySet<string>;
141
+ readonly discriminatorFields: ResolvedDiscriminatorFieldsMap;
133
142
  }
134
143
 
135
144
  export interface AutoTypeGeneratorResult {
@@ -137,6 +146,10 @@ export interface AutoTypeGeneratorResult {
137
146
  readonly updatedExtractedTypes: ReadonlyArray<ExtractedTypeInfo>;
138
147
  readonly updatedResolversResult: ExtractResolversResult;
139
148
  readonly diagnostics: ReadonlyArray<Diagnostic>;
149
+ /** Mapping from TypeScript type alias names to auto-generated GraphQL union names */
150
+ readonly tsAliasToGraphQLNameMap: ReadonlyMap<string, string>;
151
+ /** Discriminator resolveType info for inline unions that were flattened by discriminator fields */
152
+ readonly inlineDiscriminatorResolveTypes: ReadonlyArray<InlineDiscriminatorResolveType>;
140
153
  }
141
154
 
142
155
  interface InlineObjectWithContext {
@@ -163,6 +176,41 @@ interface ExtractNestedInlineObjectsParams {
163
176
  readonly results: InlineObjectWithContext[];
164
177
  }
165
178
 
179
+ interface InlineObjectTypeInfo {
180
+ readonly properties: ReadonlyArray<InlineObjectPropertyDef>;
181
+ readonly nullable: boolean;
182
+ readonly description: string | null;
183
+ readonly deprecated: DeprecationInfo | null;
184
+ }
185
+
186
+ function getInlineObjectTypeInfo(
187
+ tsType: TSTypeReference,
188
+ ): InlineObjectTypeInfo | null {
189
+ if (tsType.kind === "inlineObject" && tsType.inlineObjectProperties) {
190
+ return {
191
+ properties: tsType.inlineObjectProperties,
192
+ nullable: tsType.nullable,
193
+ description: tsType.inlineObjectDescription,
194
+ deprecated: tsType.inlineObjectDeprecated,
195
+ };
196
+ }
197
+
198
+ if (
199
+ tsType.kind === "array" &&
200
+ tsType.elementType?.kind === "inlineObject" &&
201
+ tsType.elementType.inlineObjectProperties
202
+ ) {
203
+ return {
204
+ properties: tsType.elementType.inlineObjectProperties,
205
+ nullable: tsType.elementType.nullable,
206
+ description: tsType.elementType.inlineObjectDescription,
207
+ deprecated: tsType.elementType.inlineObjectDeprecated,
208
+ };
209
+ }
210
+
211
+ return null;
212
+ }
213
+
166
214
  function extractNestedInlineObjectsRecursively(
167
215
  params: ExtractNestedInlineObjectsParams,
168
216
  ): void {
@@ -174,32 +222,37 @@ function extractNestedInlineObjectsRecursively(
174
222
  preserveDocumentation,
175
223
  results,
176
224
  } = params;
225
+ const siblingFieldNames = new Set(properties.map((prop) => prop.name));
177
226
 
178
227
  for (const prop of properties) {
179
- if (
180
- prop.tsType.kind === "inlineObject" &&
181
- prop.tsType.inlineObjectProperties
182
- ) {
183
- const nestedPath = [...currentPath, prop.name];
228
+ const inlineObjectTypeInfo = getInlineObjectTypeInfo(prop.tsType);
229
+
230
+ if (inlineObjectTypeInfo) {
231
+ const nestedPath = appendFieldPath({
232
+ parentPath: currentPath,
233
+ fieldName: prop.name,
234
+ singularize: prop.tsType.kind === "array",
235
+ siblingFieldNames,
236
+ });
184
237
  const nestedContext = buildContext(nestedPath);
185
238
  // Use property's source location if available for more accurate diagnostics
186
239
  const nestedSourceLocation = prop.sourceLocation ?? sourceLocation;
187
240
 
188
241
  results.push({
189
- properties: prop.tsType.inlineObjectProperties,
242
+ properties: inlineObjectTypeInfo.properties,
190
243
  context: nestedContext,
191
244
  sourceLocation: nestedSourceLocation,
192
- nullable: prop.tsType.nullable,
245
+ nullable: inlineObjectTypeInfo.nullable,
193
246
  description: preserveDocumentation
194
- ? prop.tsType.inlineObjectDescription
247
+ ? inlineObjectTypeInfo.description
195
248
  : null,
196
249
  deprecated: preserveDocumentation
197
- ? prop.tsType.inlineObjectDeprecated
250
+ ? inlineObjectTypeInfo.deprecated
198
251
  : null,
199
252
  });
200
253
 
201
254
  extractNestedInlineObjectsRecursively({
202
- properties: prop.tsType.inlineObjectProperties,
255
+ properties: inlineObjectTypeInfo.properties,
203
256
  currentPath: nestedPath,
204
257
  sourceLocation: nestedSourceLocation,
205
258
  buildContext,
@@ -258,6 +311,7 @@ function collectInlineObjectsFromType(
258
311
  ): InlineObjectWithContext[] {
259
312
  const results: InlineObjectWithContext[] = [];
260
313
  const isInput = isInputTypeName(typeInfo.metadata.name);
314
+ const siblingFieldNames = new Set(typeInfo.fields.map((field) => field.name));
261
315
 
262
316
  for (const field of typeInfo.fields) {
263
317
  collectInlineObjectsFromField({
@@ -266,6 +320,7 @@ function collectInlineObjectsFromType(
266
320
  parentPath: [],
267
321
  isInput,
268
322
  sourceFile: typeInfo.metadata.sourceFile,
323
+ siblingFieldNames,
269
324
  results,
270
325
  });
271
326
  }
@@ -279,21 +334,34 @@ interface CollectInlineObjectsFromFieldParams {
279
334
  readonly parentPath: ReadonlyArray<string>;
280
335
  readonly isInput: boolean;
281
336
  readonly sourceFile: string;
337
+ readonly siblingFieldNames: ReadonlySet<string>;
282
338
  readonly results: InlineObjectWithContext[];
283
339
  }
284
340
 
285
341
  function collectInlineObjectsFromField(
286
342
  params: CollectInlineObjectsFromFieldParams,
287
343
  ): void {
288
- const { field, parentTypeName, parentPath, isInput, sourceFile, results } =
289
- params;
290
- const tsType = field.tsType;
344
+ const {
345
+ field,
346
+ parentTypeName,
347
+ parentPath,
348
+ isInput,
349
+ sourceFile,
350
+ siblingFieldNames,
351
+ results,
352
+ } = params;
353
+ const inlineObjectTypeInfo = getInlineObjectTypeInfo(field.tsType);
291
354
 
292
- if (tsType.kind !== "inlineObject" || !tsType.inlineObjectProperties) {
355
+ if (!inlineObjectTypeInfo) {
293
356
  return;
294
357
  }
295
358
 
296
- const fieldPath = [...parentPath, field.name];
359
+ const fieldPath = appendFieldPath({
360
+ parentPath,
361
+ fieldName: field.name,
362
+ singularize: field.tsType.kind === "array",
363
+ siblingFieldNames,
364
+ });
297
365
 
298
366
  const context: AutoTypeNameContext = isInput
299
367
  ? {
@@ -313,16 +381,16 @@ function collectInlineObjectsFromField(
313
381
  );
314
382
 
315
383
  results.push({
316
- properties: tsType.inlineObjectProperties,
384
+ properties: inlineObjectTypeInfo.properties,
317
385
  context,
318
386
  sourceLocation,
319
- nullable: tsType.nullable,
320
- description: tsType.inlineObjectDescription,
321
- deprecated: tsType.inlineObjectDeprecated,
387
+ nullable: inlineObjectTypeInfo.nullable,
388
+ description: inlineObjectTypeInfo.description,
389
+ deprecated: inlineObjectTypeInfo.deprecated,
322
390
  });
323
391
 
324
392
  extractNestedInlineObjectsRecursively({
325
- properties: tsType.inlineObjectProperties,
393
+ properties: inlineObjectTypeInfo.properties,
326
394
  currentPath: fieldPath,
327
395
  sourceLocation,
328
396
  buildContext: (nestedPath) =>
@@ -486,8 +554,16 @@ function generateAutoType(
486
554
 
487
555
  const fields: AutoGeneratedField[] = [];
488
556
  const diagnostics: Diagnostic[] = [];
557
+ const siblingFieldNames = new Set(
558
+ inlineObj.properties.map((prop) => prop.name),
559
+ );
489
560
 
490
561
  for (const prop of inlineObj.properties) {
562
+ // Typename discrimination fields are silently excluded from the schema
563
+ if (isTypenameFieldName(prop.name)) {
564
+ continue;
565
+ }
566
+
491
567
  const eligibility = isEligibleField({
492
568
  fieldName: prop.name,
493
569
  kind: isInput ? "input" : "object",
@@ -509,7 +585,14 @@ function generateAutoType(
509
585
  enumTypeNames,
510
586
  unionTypeNames,
511
587
  parentContext: inlineObj.context,
588
+ siblingFieldNames,
512
589
  });
590
+
591
+ // Skip fields with never type — they represent impossible values
592
+ if (fieldType.typeName === "__NEVER__") {
593
+ continue;
594
+ }
595
+
513
596
  fields.push({
514
597
  name: prop.name,
515
598
  type: fieldType,
@@ -543,14 +626,21 @@ interface ResolveFieldTypeParams {
543
626
  readonly enumTypeNames: Map<string, string>;
544
627
  readonly unionTypeNames: Map<string, string>;
545
628
  readonly parentContext: AutoTypeNameContext;
629
+ readonly siblingFieldNames: ReadonlySet<string>;
546
630
  }
547
631
 
548
632
  function tryResolveNestedType(
549
633
  prop: InlineObjectPropertyDef,
550
634
  parentContext: AutoTypeNameContext,
551
635
  typeNamesMap: ReadonlyMap<string, string>,
636
+ siblingFieldNames: ReadonlySet<string>,
552
637
  ): GraphQLFieldType | null {
553
- const nestedPath = [...parentContext.fieldPath, prop.name];
638
+ const nestedPath = appendFieldPath({
639
+ parentPath: parentContext.fieldPath,
640
+ fieldName: prop.name,
641
+ singularize: prop.tsType.kind === "array",
642
+ siblingFieldNames,
643
+ });
554
644
  const nestedContext: AutoTypeNameContext = {
555
645
  ...parentContext,
556
646
  fieldPath: nestedPath,
@@ -560,10 +650,8 @@ function tryResolveNestedType(
560
650
 
561
651
  if (resolvedTypeName) {
562
652
  return {
653
+ ...convertTsTypeToGraphQLType(prop.tsType, prop.optional),
563
654
  typeName: resolvedTypeName,
564
- nullable: prop.tsType.nullable || prop.optional,
565
- list: false,
566
- listItemNullable: null,
567
655
  };
568
656
  }
569
657
  return null;
@@ -576,27 +664,52 @@ function resolveFieldType(params: ResolveFieldTypeParams): GraphQLFieldType {
576
664
  enumTypeNames,
577
665
  unionTypeNames,
578
666
  parentContext,
667
+ siblingFieldNames,
579
668
  } = params;
580
669
 
581
670
  if (
582
- prop.tsType.kind === "inlineObject" &&
583
- prop.tsType.inlineObjectProperties
671
+ (prop.tsType.kind === "inlineObject" &&
672
+ prop.tsType.inlineObjectProperties) ||
673
+ (prop.tsType.kind === "array" &&
674
+ prop.tsType.elementType?.kind === "inlineObject" &&
675
+ prop.tsType.elementType.inlineObjectProperties)
584
676
  ) {
585
677
  const result = tryResolveNestedType(
586
678
  prop,
587
679
  parentContext,
588
680
  generatedTypeNames,
681
+ siblingFieldNames,
589
682
  );
590
683
  if (result) return result;
591
684
  }
592
685
 
593
- if (prop.tsType.kind === "inlineEnum" && prop.tsType.inlineEnumMembers) {
594
- const result = tryResolveNestedType(prop, parentContext, enumTypeNames);
686
+ if (
687
+ (prop.tsType.kind === "inlineEnum" && prop.tsType.inlineEnumMembers) ||
688
+ (prop.tsType.kind === "array" &&
689
+ prop.tsType.elementType?.kind === "inlineEnum" &&
690
+ prop.tsType.elementType.inlineEnumMembers)
691
+ ) {
692
+ const result = tryResolveNestedType(
693
+ prop,
694
+ parentContext,
695
+ enumTypeNames,
696
+ siblingFieldNames,
697
+ );
595
698
  if (result) return result;
596
699
  }
597
700
 
598
- if (prop.tsType.kind === "union" && prop.tsType.members) {
599
- const result = tryResolveNestedType(prop, parentContext, unionTypeNames);
701
+ if (
702
+ (prop.tsType.kind === "union" && prop.tsType.members) ||
703
+ (prop.tsType.kind === "array" &&
704
+ prop.tsType.elementType?.kind === "union" &&
705
+ prop.tsType.elementType.members)
706
+ ) {
707
+ const result = tryResolveNestedType(
708
+ prop,
709
+ parentContext,
710
+ unionTypeNames,
711
+ siblingFieldNames,
712
+ );
600
713
  if (result) return result;
601
714
  }
602
715
 
@@ -615,10 +728,19 @@ function updateExtractedTypes(
615
728
  ): ExtractedTypeInfo[] {
616
729
  return extractedTypes.map((typeInfo) => {
617
730
  const isInput = isInputTypeName(typeInfo.metadata.name);
731
+ const siblingFieldNames = new Set(
732
+ typeInfo.fields.map((field) => field.name),
733
+ );
618
734
  return {
619
735
  ...typeInfo,
620
736
  fields: typeInfo.fields.map((field) =>
621
- updateField(field, params, typeInfo.metadata.name, isInput),
737
+ updateField(
738
+ field,
739
+ params,
740
+ typeInfo.metadata.name,
741
+ isInput,
742
+ siblingFieldNames,
743
+ ),
622
744
  ),
623
745
  };
624
746
  });
@@ -629,9 +751,19 @@ function updateField(
629
751
  params: UpdateTypeNamesParams,
630
752
  parentTypeName: string,
631
753
  isInput: boolean,
754
+ siblingFieldNames: ReadonlySet<string>,
632
755
  ): FieldDefinition {
633
756
  const { generatedTypeNames, enumTypeNames, unionTypeNames } = params;
634
- const context = buildFieldContext(parentTypeName, [field.name], isInput);
757
+ const context = buildFieldContext(
758
+ parentTypeName,
759
+ appendFieldPath({
760
+ parentPath: [],
761
+ fieldName: field.name,
762
+ singularize: field.tsType.kind === "array",
763
+ siblingFieldNames,
764
+ }),
765
+ isInput,
766
+ );
635
767
  const contextKey = getContextKey(context);
636
768
 
637
769
  // Handle inline objects
@@ -651,6 +783,27 @@ function updateField(
651
783
  }
652
784
  }
653
785
 
786
+ // Handle array of inline objects
787
+ if (
788
+ field.tsType.kind === "array" &&
789
+ field.tsType.elementType?.kind === "inlineObject" &&
790
+ field.tsType.elementType.inlineObjectProperties
791
+ ) {
792
+ const resolvedTypeName = generatedTypeNames.get(contextKey);
793
+ if (resolvedTypeName) {
794
+ return {
795
+ ...field,
796
+ tsType: {
797
+ ...field.tsType,
798
+ elementType: createReferenceType({
799
+ name: resolvedTypeName,
800
+ nullable: field.tsType.elementType.nullable,
801
+ }),
802
+ },
803
+ };
804
+ }
805
+ }
806
+
654
807
  // Handle inline enums
655
808
  if (field.tsType.kind === "inlineEnum" && field.tsType.inlineEnumMembers) {
656
809
  const resolvedTypeName = enumTypeNames.get(contextKey);
@@ -700,6 +853,27 @@ function updateField(
700
853
  }
701
854
  }
702
855
 
856
+ // Handle array of inline union types
857
+ if (
858
+ field.tsType.kind === "array" &&
859
+ field.tsType.elementType?.kind === "union" &&
860
+ field.tsType.elementType.members
861
+ ) {
862
+ const resolvedTypeName = unionTypeNames.get(contextKey);
863
+ if (resolvedTypeName) {
864
+ return {
865
+ ...field,
866
+ tsType: {
867
+ ...field.tsType,
868
+ elementType: createReferenceType({
869
+ name: resolvedTypeName,
870
+ nullable: field.tsType.elementType.nullable,
871
+ }),
872
+ },
873
+ };
874
+ }
875
+ }
876
+
703
877
  return field;
704
878
  }
705
879
 
@@ -1290,6 +1464,9 @@ function generateOneOfFields(
1290
1464
  prop.tsType,
1291
1465
  prop.optional,
1292
1466
  );
1467
+ if (fieldType.typeName === "__NEVER__") {
1468
+ continue;
1469
+ }
1293
1470
  fields.push({
1294
1471
  name: prop.name,
1295
1472
  type: {
@@ -1358,13 +1535,306 @@ function extractTypenameFromInlineObject(
1358
1535
  const { property, fieldName } = found;
1359
1536
  const { tsType } = property;
1360
1537
 
1361
- if (tsType.kind === "literal" && tsType.name !== null) {
1538
+ if (tsType.kind === "stringLiteral" && tsType.name !== null) {
1362
1539
  return { typeName: tsType.name, fieldName };
1363
1540
  }
1364
1541
 
1365
1542
  return null;
1366
1543
  }
1367
1544
 
1545
+ /**
1546
+ * Shared parameters for resolving inline types within union member properties.
1547
+ */
1548
+ interface MemberFieldResolutionContext {
1549
+ readonly types: AutoGeneratedType[];
1550
+ readonly generatedTypeNames: Map<string, string>;
1551
+ readonly diagnostics: Diagnostic[];
1552
+ readonly sourceLocation: SourceLocation;
1553
+ readonly knownTypeNames: ReadonlySet<string>;
1554
+ }
1555
+
1556
+ /**
1557
+ * Convert inline object/enum/union properties within a union member to AutoGeneratedFields.
1558
+ * Handles __INLINE_OBJECT__, __INLINE_ENUM__, and inline union (kind: "union") sentinels
1559
+ * by generating appropriate auto types and replacing sentinel type names.
1560
+ */
1561
+ function convertMemberPropertiesToFields(
1562
+ properties: ReadonlyArray<InlineObjectPropertyDef>,
1563
+ parentTypeName: string,
1564
+ ctx: MemberFieldResolutionContext,
1565
+ ): AutoGeneratedField[] {
1566
+ const siblingFieldNames = new Set(properties.map((prop) => prop.name));
1567
+ return properties.flatMap((prop) => {
1568
+ const fieldType = convertTsTypeToGraphQLType(prop.tsType, prop.optional);
1569
+ if (fieldType.typeName === "__NEVER__") {
1570
+ return [];
1571
+ }
1572
+
1573
+ const resolvedTypeName = resolveInlineTypeInMember(
1574
+ prop,
1575
+ fieldType,
1576
+ parentTypeName,
1577
+ siblingFieldNames,
1578
+ ctx,
1579
+ );
1580
+
1581
+ return {
1582
+ name: prop.name,
1583
+ type: resolvedTypeName
1584
+ ? { ...fieldType, typeName: resolvedTypeName }
1585
+ : fieldType,
1586
+ description: prop.description,
1587
+ deprecated: prop.deprecated,
1588
+ directives: prop.directives,
1589
+ defaultValue: prop.defaultValue,
1590
+ };
1591
+ });
1592
+ }
1593
+
1594
+ /**
1595
+ * Resolve an inline type (object, enum, or union) within a union member property.
1596
+ * Returns the generated type name if resolved, or null if no resolution is needed.
1597
+ */
1598
+ function resolveInlineTypeInMember(
1599
+ prop: InlineObjectPropertyDef,
1600
+ fieldType: GraphQLFieldType,
1601
+ parentTypeName: string,
1602
+ siblingFieldNames: ReadonlySet<string>,
1603
+ ctx: MemberFieldResolutionContext,
1604
+ ): string | null {
1605
+ // Determine the inline TS type (direct or array element)
1606
+ const inlineTsType =
1607
+ prop.tsType.kind === "array" ? prop.tsType.elementType : prop.tsType;
1608
+ const singularizeArrayFieldName = prop.tsType.kind === "array";
1609
+ if (!inlineTsType) return null;
1610
+
1611
+ // Resolve nested inline objects
1612
+ if (
1613
+ fieldType.typeName === "__INLINE_OBJECT__" &&
1614
+ inlineTsType.kind === "inlineObject" &&
1615
+ inlineTsType.inlineObjectProperties
1616
+ ) {
1617
+ return resolveNestedInlineObjectInMember(
1618
+ inlineTsType.inlineObjectProperties,
1619
+ prop.name,
1620
+ singularizeArrayFieldName,
1621
+ parentTypeName,
1622
+ siblingFieldNames,
1623
+ ctx,
1624
+ inlineTsType.inlineObjectDescription,
1625
+ );
1626
+ }
1627
+
1628
+ // Resolve inline enums (string literal unions)
1629
+ if (
1630
+ fieldType.typeName === "__INLINE_ENUM__" &&
1631
+ inlineTsType.kind === "inlineEnum" &&
1632
+ inlineTsType.inlineEnumMembers
1633
+ ) {
1634
+ return resolveInlineEnumInMember(
1635
+ inlineTsType.inlineEnumMembers,
1636
+ prop.name,
1637
+ singularizeArrayFieldName,
1638
+ parentTypeName,
1639
+ siblingFieldNames,
1640
+ ctx,
1641
+ inlineTsType.externalEnumDescription,
1642
+ );
1643
+ }
1644
+
1645
+ // Resolve inline unions (reference type unions like User | Bot)
1646
+ if (inlineTsType.kind === "union" && inlineTsType.members) {
1647
+ return resolveInlineUnionInMember(
1648
+ inlineTsType.members,
1649
+ prop.name,
1650
+ singularizeArrayFieldName,
1651
+ parentTypeName,
1652
+ siblingFieldNames,
1653
+ ctx,
1654
+ );
1655
+ }
1656
+
1657
+ return null;
1658
+ }
1659
+
1660
+ /**
1661
+ * Resolve a nested inline object within an inline union member.
1662
+ * Generates an AutoGeneratedType using objectField context and recurses
1663
+ * into deeper nesting levels.
1664
+ */
1665
+ function resolveNestedInlineObjectInMember(
1666
+ properties: ReadonlyArray<InlineObjectPropertyDef>,
1667
+ fieldName: string,
1668
+ singularizeArrayFieldName: boolean,
1669
+ parentTypeName: string,
1670
+ siblingFieldNames: ReadonlySet<string>,
1671
+ ctx: MemberFieldResolutionContext,
1672
+ description: string | null,
1673
+ ): string {
1674
+ const context: AutoTypeNameContext = {
1675
+ kind: "objectField",
1676
+ parentTypeName,
1677
+ fieldPath: appendFieldPath({
1678
+ parentPath: [],
1679
+ fieldName,
1680
+ singularize: singularizeArrayFieldName,
1681
+ siblingFieldNames,
1682
+ }),
1683
+ };
1684
+ const typeName = generateAutoTypeName(context);
1685
+ const contextKey = getContextKey(context);
1686
+
1687
+ if (ctx.generatedTypeNames.has(contextKey)) {
1688
+ return ctx.generatedTypeNames.get(contextKey)!;
1689
+ }
1690
+
1691
+ const fields = convertMemberPropertiesToFields(properties, typeName, ctx);
1692
+
1693
+ ctx.types.push({
1694
+ name: typeName,
1695
+ kind: "Object",
1696
+ fields,
1697
+ enumValues: null,
1698
+ unionMembers: null,
1699
+ needsStringEnumMapping: false,
1700
+ sourceLocation: ctx.sourceLocation,
1701
+ generatedFrom: buildGeneratedFromInfo(context),
1702
+ description,
1703
+ resolveTypeFieldPattern: null,
1704
+ });
1705
+
1706
+ ctx.generatedTypeNames.set(contextKey, typeName);
1707
+
1708
+ return typeName;
1709
+ }
1710
+
1711
+ /**
1712
+ * Resolve an inline enum (string literal union) within an inline union member.
1713
+ */
1714
+ function resolveInlineEnumInMember(
1715
+ members: ReadonlyArray<InlineEnumMemberInfo>,
1716
+ fieldName: string,
1717
+ singularizeArrayFieldName: boolean,
1718
+ parentTypeName: string,
1719
+ siblingFieldNames: ReadonlySet<string>,
1720
+ ctx: MemberFieldResolutionContext,
1721
+ description: string | null,
1722
+ ): string {
1723
+ const context: AutoTypeNameContext = {
1724
+ kind: "objectField",
1725
+ parentTypeName,
1726
+ fieldPath: appendFieldPath({
1727
+ parentPath: [],
1728
+ fieldName,
1729
+ singularize: singularizeArrayFieldName,
1730
+ siblingFieldNames,
1731
+ }),
1732
+ };
1733
+ const typeName = generateAutoTypeName(context);
1734
+ const contextKey = getContextKey(context);
1735
+
1736
+ if (ctx.generatedTypeNames.has(contextKey)) {
1737
+ return ctx.generatedTypeNames.get(contextKey)!;
1738
+ }
1739
+
1740
+ const {
1741
+ enumValues,
1742
+ needsStringEnumMapping,
1743
+ diagnostics: enumDiagnostics,
1744
+ } = convertInlineEnumMembers({
1745
+ members,
1746
+ enumName: typeName,
1747
+ sourceLocation: ctx.sourceLocation,
1748
+ });
1749
+
1750
+ ctx.diagnostics.push(...enumDiagnostics);
1751
+
1752
+ ctx.types.push({
1753
+ name: typeName,
1754
+ kind: "Enum",
1755
+ fields: null,
1756
+ enumValues,
1757
+ unionMembers: null,
1758
+ needsStringEnumMapping,
1759
+ sourceLocation: ctx.sourceLocation,
1760
+ generatedFrom: buildGeneratedFromInfo(context),
1761
+ description,
1762
+ resolveTypeFieldPattern: null,
1763
+ });
1764
+
1765
+ ctx.generatedTypeNames.set(contextKey, typeName);
1766
+
1767
+ return typeName;
1768
+ }
1769
+
1770
+ /**
1771
+ * Resolve an inline union of reference types within an inline union member.
1772
+ */
1773
+ function resolveInlineUnionInMember(
1774
+ members: ReadonlyArray<TSTypeReference>,
1775
+ fieldName: string,
1776
+ singularizeArrayFieldName: boolean,
1777
+ parentTypeName: string,
1778
+ siblingFieldNames: ReadonlySet<string>,
1779
+ ctx: MemberFieldResolutionContext,
1780
+ ): string {
1781
+ const context: AutoTypeNameContext = {
1782
+ kind: "objectField",
1783
+ parentTypeName,
1784
+ fieldPath: appendFieldPath({
1785
+ parentPath: [],
1786
+ fieldName,
1787
+ singularize: singularizeArrayFieldName,
1788
+ siblingFieldNames,
1789
+ }),
1790
+ };
1791
+ const typeName = generateAutoTypeName(context);
1792
+ const contextKey = getContextKey(context);
1793
+
1794
+ if (ctx.generatedTypeNames.has(contextKey)) {
1795
+ return ctx.generatedTypeNames.get(contextKey)!;
1796
+ }
1797
+
1798
+ const memberNames: string[] = [];
1799
+ for (const member of members) {
1800
+ if (member.kind === "reference" && member.name) {
1801
+ if (ctx.knownTypeNames.has(member.name)) {
1802
+ memberNames.push(member.name);
1803
+ }
1804
+ }
1805
+ }
1806
+
1807
+ if (memberNames.length === 0) {
1808
+ const memberDescriptions = members
1809
+ .map((m) => m.name ?? "(anonymous)")
1810
+ .join(", ");
1811
+ ctx.diagnostics.push({
1812
+ code: "INLINE_UNION_UNRESOLVABLE_MEMBER",
1813
+ message: `Could not resolve any members of inline union '${typeName}' in '${parentTypeName}.${fieldName}'. None of the member types [${memberDescriptions}] are known schema types.`,
1814
+ severity: "error",
1815
+ location: ctx.sourceLocation,
1816
+ });
1817
+ return typeName;
1818
+ }
1819
+
1820
+ ctx.types.push({
1821
+ name: typeName,
1822
+ kind: "Union",
1823
+ fields: null,
1824
+ enumValues: null,
1825
+ unionMembers: memberNames,
1826
+ needsStringEnumMapping: false,
1827
+ sourceLocation: ctx.sourceLocation,
1828
+ generatedFrom: buildGeneratedFromInfo(context),
1829
+ description: null,
1830
+ resolveTypeFieldPattern: null,
1831
+ });
1832
+
1833
+ ctx.generatedTypeNames.set(contextKey, typeName);
1834
+
1835
+ return typeName;
1836
+ }
1837
+
1368
1838
  function resolveMemberNames(params: ResolveMemberNamesParams): string[] {
1369
1839
  const {
1370
1840
  members,
@@ -1406,38 +1876,47 @@ function resolveMemberNames(params: ResolveMemberNamesParams): string[] {
1406
1876
  fieldPath: [...parentContext.fieldPath, extractedInfo.typeName],
1407
1877
  };
1408
1878
  contextKey = getContextKey(nestedContext);
1409
- } else {
1879
+ } else if (memberType.inlineObjectHintName !== null) {
1410
1880
  const nestedContext: AutoTypeNameContext = {
1411
1881
  ...parentContext,
1412
- fieldPath: [...parentContext.fieldPath, `member${i}`],
1882
+ fieldPath: [
1883
+ ...parentContext.fieldPath,
1884
+ memberType.inlineObjectHintName,
1885
+ ],
1413
1886
  };
1414
- memberTypeName = generateAutoTypeName(nestedContext);
1887
+ memberTypeName = memberType.inlineObjectHintName;
1415
1888
  contextKey = getContextKey(nestedContext);
1889
+ } else {
1890
+ diagnostics.push({
1891
+ code: "UNNAMEABLE_UNION_MEMBER",
1892
+ message: `Inline object union member at index ${i} cannot be named. Use a named type (type alias or interface) for each union member, or add a '__typename' property with a string literal type.`,
1893
+ severity: "error",
1894
+ location: sourceLocation,
1895
+ });
1896
+ continue;
1416
1897
  }
1417
1898
 
1418
1899
  // Only filter out __typename or $typeName for resolverPayload context
1419
1900
  // For other contexts, these are regular fields that should be preserved
1420
1901
  const typenameFieldToFilter = extractedInfo?.fieldName ?? null;
1421
- const fields: AutoGeneratedField[] = memberType.inlineObjectProperties
1422
- .filter(
1423
- (prop) =>
1424
- parentContext.kind !== "resolverPayload" ||
1425
- prop.name !== typenameFieldToFilter,
1426
- )
1427
- .map((prop) => {
1428
- const fieldType = convertTsTypeToGraphQLType(
1429
- prop.tsType,
1430
- prop.optional,
1431
- );
1432
- return {
1433
- name: prop.name,
1434
- type: fieldType,
1435
- description: prop.description,
1436
- deprecated: prop.deprecated,
1437
- directives: prop.directives,
1438
- defaultValue: prop.defaultValue,
1439
- };
1440
- });
1902
+ const filteredProperties = memberType.inlineObjectProperties.filter(
1903
+ (prop) =>
1904
+ parentContext.kind !== "resolverPayload" ||
1905
+ prop.name !== typenameFieldToFilter,
1906
+ );
1907
+
1908
+ const fieldCtx: MemberFieldResolutionContext = {
1909
+ types,
1910
+ generatedTypeNames,
1911
+ diagnostics,
1912
+ sourceLocation,
1913
+ knownTypeNames: params.knownTypeNames,
1914
+ };
1915
+ const fields = convertMemberPropertiesToFields(
1916
+ filteredProperties,
1917
+ memberTypeName,
1918
+ fieldCtx,
1919
+ );
1441
1920
 
1442
1921
  // Check if this typename was already seen with a different field structure
1443
1922
  if (extractedInfo !== null) {
@@ -1466,7 +1945,7 @@ function resolveMemberNames(params: ResolveMemberNamesParams): string[] {
1466
1945
  ...parentContext,
1467
1946
  fieldPath: [
1468
1947
  ...parentContext.fieldPath,
1469
- extractedInfo?.typeName ?? `member${i}`,
1948
+ extractedInfo?.typeName ?? memberType.inlineObjectHintName!,
1470
1949
  ],
1471
1950
  };
1472
1951
 
@@ -1606,12 +2085,21 @@ export function generateAutoTypes(
1606
2085
  resolversResult: input.resolversResult,
1607
2086
  knownTypeNames: input.knownTypeNames,
1608
2087
  });
1609
- const allInlineUnions = [
2088
+ const allInlineUnionsRaw = [
1610
2089
  ...inlineUnionsFromTypes,
1611
2090
  ...inlineUnionsFromResolvers,
1612
2091
  ...inlineUnionsFromPayloads,
1613
2092
  ];
1614
2093
 
2094
+ // Apply discriminator-aware flattening to inline unions before processing.
2095
+ // This resolves the case where TypeScript distributes intersections over unions
2096
+ // within field types, creating many anonymous inline objects.
2097
+ const flattenResult = flattenInlineUnionMembers({
2098
+ inlineUnions: allInlineUnionsRaw,
2099
+ discriminatorFields: input.discriminatorFields,
2100
+ });
2101
+ const allInlineUnions = [...flattenResult.inlineUnions];
2102
+
1615
2103
  // Build union type names map before generating auto types
1616
2104
  const unionTypeNames = buildUnionTypeNamesMap(allInlineUnions);
1617
2105
 
@@ -1666,10 +2154,40 @@ export function generateAutoTypes(
1666
2154
  updateParams,
1667
2155
  );
1668
2156
 
2157
+ // Build mapping from TS type alias names to auto-generated GraphQL union names
2158
+ const tsAliasToGraphQLNameMap = buildTsAliasToGraphQLNameMap(
2159
+ allInlineUnions,
2160
+ unionTypeNames,
2161
+ );
2162
+
1669
2163
  return {
1670
2164
  autoGeneratedTypes,
1671
2165
  updatedExtractedTypes,
1672
2166
  updatedResolversResult,
1673
2167
  diagnostics,
2168
+ tsAliasToGraphQLNameMap,
2169
+ inlineDiscriminatorResolveTypes:
2170
+ flattenResult.inlineDiscriminatorResolveTypes,
1674
2171
  };
1675
2172
  }
2173
+
2174
+ function buildTsAliasToGraphQLNameMap(
2175
+ inlineUnions: ReadonlyArray<InlineUnionWithContext>,
2176
+ unionTypeNames: ReadonlyMap<string, string>,
2177
+ ): ReadonlyMap<string, string> {
2178
+ const result = new Map<string, string>();
2179
+
2180
+ for (const inlineUnion of inlineUnions) {
2181
+ if (inlineUnion.unionAliasName === null) {
2182
+ continue;
2183
+ }
2184
+
2185
+ const contextKey = getContextKey(inlineUnion.context);
2186
+ const generatedName = unionTypeNames.get(contextKey);
2187
+ if (generatedName !== undefined) {
2188
+ result.set(inlineUnion.unionAliasName, generatedName);
2189
+ }
2190
+ }
2191
+
2192
+ return result;
2193
+ }