@gqlkit-ts/cli 0.2.0 → 0.4.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 (235) hide show
  1. package/README.md +143 -0
  2. package/dist/auto-type-generator/auto-type-generator.d.ts +10 -4
  3. package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
  4. package/dist/auto-type-generator/auto-type-generator.js +656 -146
  5. package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
  6. package/dist/auto-type-generator/index.d.ts +8 -1
  7. package/dist/auto-type-generator/index.d.ts.map +1 -1
  8. package/dist/auto-type-generator/index.js +3 -0
  9. package/dist/auto-type-generator/index.js.map +1 -1
  10. package/dist/auto-type-generator/inline-enum-collector.d.ts +13 -5
  11. package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -1
  12. package/dist/auto-type-generator/inline-enum-collector.js +107 -71
  13. package/dist/auto-type-generator/inline-enum-collector.js.map +1 -1
  14. package/dist/auto-type-generator/inline-object-traverser.d.ts +20 -0
  15. package/dist/auto-type-generator/inline-object-traverser.d.ts.map +1 -0
  16. package/dist/auto-type-generator/inline-object-traverser.js +22 -0
  17. package/dist/auto-type-generator/inline-object-traverser.js.map +1 -0
  18. package/dist/auto-type-generator/inline-union-collector.d.ts +29 -0
  19. package/dist/auto-type-generator/inline-union-collector.d.ts.map +1 -0
  20. package/dist/auto-type-generator/inline-union-collector.js +216 -0
  21. package/dist/auto-type-generator/inline-union-collector.js.map +1 -0
  22. package/dist/auto-type-generator/inline-union-types.d.ts +29 -0
  23. package/dist/auto-type-generator/inline-union-types.d.ts.map +1 -0
  24. package/dist/auto-type-generator/inline-union-types.js +2 -0
  25. package/dist/auto-type-generator/inline-union-types.js.map +1 -0
  26. package/dist/auto-type-generator/inline-union-validator.d.ts +76 -0
  27. package/dist/auto-type-generator/inline-union-validator.d.ts.map +1 -0
  28. package/dist/auto-type-generator/inline-union-validator.js +329 -0
  29. package/dist/auto-type-generator/inline-union-validator.js.map +1 -0
  30. package/dist/auto-type-generator/naming-convention.d.ts +18 -1
  31. package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
  32. package/dist/auto-type-generator/naming-convention.js +16 -0
  33. package/dist/auto-type-generator/naming-convention.js.map +1 -1
  34. package/dist/auto-type-generator/resolve-type-generator.d.ts +20 -0
  35. package/dist/auto-type-generator/resolve-type-generator.d.ts.map +1 -0
  36. package/dist/auto-type-generator/resolve-type-generator.js +2 -0
  37. package/dist/auto-type-generator/resolve-type-generator.js.map +1 -0
  38. package/dist/auto-type-generator/resolver-field-iterator.d.ts +13 -0
  39. package/dist/auto-type-generator/resolver-field-iterator.d.ts.map +1 -0
  40. package/dist/auto-type-generator/resolver-field-iterator.js +22 -0
  41. package/dist/auto-type-generator/resolver-field-iterator.js.map +1 -0
  42. package/dist/auto-type-generator/typename-extractor.d.ts +26 -0
  43. package/dist/auto-type-generator/typename-extractor.d.ts.map +1 -0
  44. package/dist/auto-type-generator/typename-extractor.js +142 -0
  45. package/dist/auto-type-generator/typename-extractor.js.map +1 -0
  46. package/dist/auto-type-generator/typename-resolve-type-generator.d.ts +35 -0
  47. package/dist/auto-type-generator/typename-resolve-type-generator.d.ts.map +1 -0
  48. package/dist/auto-type-generator/typename-resolve-type-generator.js +177 -0
  49. package/dist/auto-type-generator/typename-resolve-type-generator.js.map +1 -0
  50. package/dist/auto-type-generator/typename-types.d.ts +43 -0
  51. package/dist/auto-type-generator/typename-types.d.ts.map +1 -0
  52. package/dist/auto-type-generator/typename-types.js +37 -0
  53. package/dist/auto-type-generator/typename-types.js.map +1 -0
  54. package/dist/auto-type-generator/typename-validator.d.ts +37 -0
  55. package/dist/auto-type-generator/typename-validator.d.ts.map +1 -0
  56. package/dist/auto-type-generator/typename-validator.js +206 -0
  57. package/dist/auto-type-generator/typename-validator.js.map +1 -0
  58. package/dist/cli.js +2 -0
  59. package/dist/cli.js.map +1 -1
  60. package/dist/commands/docs.d.ts +51 -0
  61. package/dist/commands/docs.d.ts.map +1 -0
  62. package/dist/commands/docs.js +154 -0
  63. package/dist/commands/docs.js.map +1 -0
  64. package/dist/config/types.d.ts +13 -0
  65. package/dist/config/types.d.ts.map +1 -1
  66. package/dist/config-loader/loader.d.ts +3 -0
  67. package/dist/config-loader/loader.d.ts.map +1 -1
  68. package/dist/config-loader/loader.js +1 -0
  69. package/dist/config-loader/loader.js.map +1 -1
  70. package/dist/config-loader/validator.d.ts.map +1 -1
  71. package/dist/config-loader/validator.js +23 -0
  72. package/dist/config-loader/validator.js.map +1 -1
  73. package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
  74. package/dist/gen-orchestrator/orchestrator.js +32 -12
  75. package/dist/gen-orchestrator/orchestrator.js.map +1 -1
  76. package/dist/resolver-extractor/extract-resolvers.d.ts +19 -1
  77. package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -1
  78. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +5 -0
  79. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
  80. package/dist/resolver-extractor/extractor/define-api-extractor.js +18 -65
  81. package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
  82. package/dist/resolver-extractor/index.d.ts +0 -1
  83. package/dist/resolver-extractor/index.d.ts.map +1 -1
  84. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +1 -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 +9 -5
  87. package/dist/resolver-extractor/validator/abstract-resolver-validator.js.map +1 -1
  88. package/dist/schema-generator/builder/ast-builder.d.ts +2 -2
  89. package/dist/schema-generator/builder/ast-builder.d.ts.map +1 -1
  90. package/dist/schema-generator/builder/ast-builder.js +12 -34
  91. package/dist/schema-generator/builder/ast-builder.js.map +1 -1
  92. package/dist/schema-generator/emitter/code-emitter.d.ts +3 -1
  93. package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
  94. package/dist/schema-generator/emitter/code-emitter.js +42 -12
  95. package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
  96. package/dist/schema-generator/emitter/sdl-emitter.d.ts +0 -4
  97. package/dist/schema-generator/emitter/sdl-emitter.d.ts.map +1 -1
  98. package/dist/schema-generator/emitter/sdl-emitter.js +0 -4
  99. package/dist/schema-generator/emitter/sdl-emitter.js.map +1 -1
  100. package/dist/schema-generator/generate-schema.d.ts +3 -0
  101. package/dist/schema-generator/generate-schema.d.ts.map +1 -1
  102. package/dist/schema-generator/generate-schema.js +83 -5
  103. package/dist/schema-generator/generate-schema.js.map +1 -1
  104. package/dist/schema-generator/integrator/result-integrator.d.ts +19 -9
  105. package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
  106. package/dist/schema-generator/integrator/result-integrator.js +60 -44
  107. package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
  108. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +2 -0
  109. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -1
  110. package/dist/schema-generator/resolver-collector/resolver-collector.js +22 -0
  111. package/dist/schema-generator/resolver-collector/resolver-collector.js.map +1 -1
  112. package/dist/shared/branded-type-detector.d.ts +43 -0
  113. package/dist/shared/branded-type-detector.d.ts.map +1 -0
  114. package/dist/shared/branded-type-detector.js +146 -0
  115. package/dist/shared/branded-type-detector.js.map +1 -0
  116. package/dist/shared/enum-prefix-detector.d.ts +63 -0
  117. package/dist/shared/enum-prefix-detector.d.ts.map +1 -0
  118. package/dist/shared/enum-prefix-detector.js +80 -0
  119. package/dist/shared/enum-prefix-detector.js.map +1 -0
  120. package/dist/shared/ignore-fields-detector.d.ts +26 -0
  121. package/dist/shared/ignore-fields-detector.d.ts.map +1 -0
  122. package/dist/shared/ignore-fields-detector.js +83 -0
  123. package/dist/shared/ignore-fields-detector.js.map +1 -0
  124. package/dist/shared/ignore-fields-validator.d.ts +29 -0
  125. package/dist/shared/ignore-fields-validator.d.ts.map +1 -0
  126. package/dist/shared/ignore-fields-validator.js +43 -0
  127. package/dist/shared/ignore-fields-validator.js.map +1 -0
  128. package/dist/shared/index.d.ts +2 -0
  129. package/dist/shared/index.d.ts.map +1 -1
  130. package/dist/shared/index.js.map +1 -1
  131. package/dist/shared/source-location.d.ts +5 -0
  132. package/dist/shared/source-location.d.ts.map +1 -1
  133. package/dist/shared/source-location.js +7 -0
  134. package/dist/shared/source-location.js.map +1 -1
  135. package/dist/shared/string-utils.d.ts +2 -0
  136. package/dist/shared/string-utils.d.ts.map +1 -0
  137. package/dist/shared/string-utils.js +8 -0
  138. package/dist/shared/string-utils.js.map +1 -0
  139. package/dist/type-extractor/converter/field-eligibility.d.ts +8 -6
  140. package/dist/type-extractor/converter/field-eligibility.d.ts.map +1 -1
  141. package/dist/type-extractor/converter/field-eligibility.js +7 -28
  142. package/dist/type-extractor/converter/field-eligibility.js.map +1 -1
  143. package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
  144. package/dist/type-extractor/converter/graphql-converter.js +27 -18
  145. package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
  146. package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -1
  147. package/dist/type-extractor/extractor/field-type-resolver.js +81 -7
  148. package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -1
  149. package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
  150. package/dist/type-extractor/extractor/type-extractor.js +88 -23
  151. package/dist/type-extractor/extractor/type-extractor.js.map +1 -1
  152. package/dist/type-extractor/types/diagnostics.d.ts +1 -1
  153. package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
  154. package/dist/type-extractor/types/ts-type-reference-factory.d.ts +10 -2
  155. package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -1
  156. package/dist/type-extractor/types/ts-type-reference-factory.js +8 -2
  157. package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -1
  158. package/dist/type-extractor/types/typescript.d.ts +4 -0
  159. package/dist/type-extractor/types/typescript.d.ts.map +1 -1
  160. package/dist/type-extractor/validator/type-validator.d.ts +1 -1
  161. package/dist/type-extractor/validator/type-validator.d.ts.map +1 -1
  162. package/dist/type-extractor/validator/type-validator.js +2 -10
  163. package/dist/type-extractor/validator/type-validator.js.map +1 -1
  164. package/docs/coding-agents.md +64 -0
  165. package/docs/configuration.md +15 -20
  166. package/docs/getting-started.md +15 -12
  167. package/docs/index.md +36 -22
  168. package/docs/integration/apollo.md +8 -40
  169. package/docs/integration/drizzle.md +6 -10
  170. package/docs/integration/prisma.md +196 -0
  171. package/docs/integration/yoga.md +8 -40
  172. package/docs/schema/abstract-resolvers.md +117 -0
  173. package/docs/schema/directives.md +5 -0
  174. package/docs/schema/documentation.md +5 -0
  175. package/docs/schema/enums.md +99 -0
  176. package/docs/schema/fields.md +64 -0
  177. package/docs/schema/index.md +21 -0
  178. package/docs/schema/inputs.md +115 -15
  179. package/docs/schema/interfaces.md +31 -1
  180. package/docs/schema/objects.md +40 -0
  181. package/docs/schema/queries-mutations.md +136 -22
  182. package/docs/schema/scalars.md +5 -0
  183. package/docs/schema/unions.md +208 -1
  184. package/docs/what-is-gqlkit.md +13 -8
  185. package/package.json +6 -4
  186. package/src/auto-type-generator/auto-type-generator.ts +969 -227
  187. package/src/auto-type-generator/index.ts +42 -0
  188. package/src/auto-type-generator/inline-enum-collector.ts +187 -139
  189. package/src/auto-type-generator/inline-object-traverser.ts +49 -0
  190. package/src/auto-type-generator/inline-union-collector.ts +402 -0
  191. package/src/auto-type-generator/inline-union-types.ts +33 -0
  192. package/src/auto-type-generator/inline-union-validator.ts +482 -0
  193. package/src/auto-type-generator/naming-convention.ts +38 -1
  194. package/src/auto-type-generator/resolve-type-generator.ts +21 -0
  195. package/src/auto-type-generator/resolver-field-iterator.ts +39 -0
  196. package/src/auto-type-generator/typename-extractor.ts +230 -0
  197. package/src/auto-type-generator/typename-resolve-type-generator.ts +281 -0
  198. package/src/auto-type-generator/typename-types.ts +66 -0
  199. package/src/auto-type-generator/typename-validator.ts +326 -0
  200. package/src/cli.ts +2 -0
  201. package/src/commands/docs.ts +211 -0
  202. package/src/config/types.ts +15 -0
  203. package/src/config-loader/loader.ts +4 -0
  204. package/src/config-loader/validator.ts +33 -0
  205. package/src/gen-orchestrator/orchestrator.ts +50 -17
  206. package/src/resolver-extractor/extract-resolvers.ts +19 -0
  207. package/src/resolver-extractor/extractor/define-api-extractor.ts +28 -94
  208. package/src/resolver-extractor/index.ts +0 -6
  209. package/src/resolver-extractor/validator/abstract-resolver-validator.ts +16 -8
  210. package/src/schema-generator/builder/ast-builder.ts +52 -81
  211. package/src/schema-generator/emitter/code-emitter.ts +82 -11
  212. package/src/schema-generator/emitter/sdl-emitter.ts +0 -4
  213. package/src/schema-generator/generate-schema.ts +109 -14
  214. package/src/schema-generator/integrator/result-integrator.ts +91 -63
  215. package/src/schema-generator/resolver-collector/resolver-collector.ts +34 -0
  216. package/src/shared/branded-type-detector.ts +182 -0
  217. package/src/shared/enum-prefix-detector.ts +99 -0
  218. package/src/shared/ignore-fields-detector.ts +109 -0
  219. package/src/shared/ignore-fields-validator.ts +66 -0
  220. package/src/shared/index.ts +2 -0
  221. package/src/shared/source-location.ts +11 -0
  222. package/src/shared/string-utils.ts +7 -0
  223. package/src/type-extractor/converter/field-eligibility.ts +13 -29
  224. package/src/type-extractor/converter/graphql-converter.ts +37 -23
  225. package/src/type-extractor/extractor/field-type-resolver.ts +97 -7
  226. package/src/type-extractor/extractor/type-extractor.ts +103 -26
  227. package/src/type-extractor/types/diagnostics.ts +13 -2
  228. package/src/type-extractor/types/ts-type-reference-factory.ts +18 -5
  229. package/src/type-extractor/types/typescript.ts +4 -0
  230. package/src/type-extractor/validator/type-validator.ts +2 -15
  231. package/dist/resolver-extractor/validator/only-validator.d.ts +0 -61
  232. package/dist/resolver-extractor/validator/only-validator.d.ts.map +0 -1
  233. package/dist/resolver-extractor/validator/only-validator.js +0 -76
  234. package/dist/resolver-extractor/validator/only-validator.js.map +0 -1
  235. package/src/resolver-extractor/validator/only-validator.ts +0 -158
@@ -48,13 +48,13 @@ import type {
48
48
  } from "../integrator/result-integrator.js";
49
49
 
50
50
  export interface BuildDocumentOptions {
51
- readonly sourceRoot?: string;
51
+ readonly sourceRoot: string | null;
52
52
  }
53
53
 
54
54
  function appendSourceLocation(
55
55
  description: string | null,
56
56
  sourceFile: string | null,
57
- sourceRoot: string | undefined,
57
+ sourceRoot: string | null,
58
58
  ): string | null {
59
59
  if (!sourceRoot || !sourceFile) {
60
60
  return description;
@@ -113,7 +113,7 @@ function buildOneOfDirective(): ConstDirectiveNode {
113
113
 
114
114
  function buildDirectiveArgumentValue(
115
115
  value: DirectiveArgumentValue,
116
- expectedTypeName?: string,
116
+ expectedTypeName: string | null,
117
117
  ): ConstValueNode {
118
118
  switch (value.kind) {
119
119
  case "string":
@@ -159,7 +159,7 @@ function buildDirectiveArgumentValue(
159
159
  fields: value.fields.map((f) => ({
160
160
  kind: Kind.OBJECT_FIELD as const,
161
161
  name: buildNameNode(f.name),
162
- value: buildDirectiveArgumentValue(f.value),
162
+ value: buildDirectiveArgumentValue(f.value, null),
163
163
  })),
164
164
  };
165
165
  }
@@ -167,7 +167,7 @@ function buildDirectiveArgumentValue(
167
167
 
168
168
  function buildDirectiveArgument(
169
169
  arg: DirectiveArgument,
170
- expectedTypeName?: string,
170
+ expectedTypeName: string | null,
171
171
  ): ConstArgumentNode {
172
172
  return {
173
173
  kind: Kind.ARGUMENT,
@@ -178,7 +178,7 @@ function buildDirectiveArgument(
178
178
 
179
179
  function buildCustomDirective(
180
180
  directive: DirectiveInfo,
181
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
181
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
182
182
  ): ConstDirectiveNode {
183
183
  const def = directiveDefMap?.get(directive.name);
184
184
  const argTypeMap = new Map<string, string>();
@@ -189,7 +189,7 @@ function buildCustomDirective(
189
189
  }
190
190
 
191
191
  const args = directive.args.map((arg) =>
192
- buildDirectiveArgument(arg, argTypeMap.get(arg.name)),
192
+ buildDirectiveArgument(arg, argTypeMap.get(arg.name) ?? null),
193
193
  );
194
194
 
195
195
  return {
@@ -202,7 +202,7 @@ function buildCustomDirective(
202
202
  function buildDirectives(
203
203
  directives: ReadonlyArray<DirectiveInfo> | null,
204
204
  deprecated: DeprecationInfo | null,
205
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
205
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
206
206
  ): ConstDirectiveNode[] {
207
207
  const result: ConstDirectiveNode[] = [];
208
208
 
@@ -278,7 +278,12 @@ function buildInputValueDefinitionNode(
278
278
  ? { description: buildStringValueNode(inputValue.description) }
279
279
  : {}),
280
280
  ...(inputValue.defaultValue
281
- ? { defaultValue: buildDirectiveArgumentValue(inputValue.defaultValue) }
281
+ ? {
282
+ defaultValue: buildDirectiveArgumentValue(
283
+ inputValue.defaultValue,
284
+ null,
285
+ ),
286
+ }
282
287
  : {}),
283
288
  ...(directives.length > 0 ? { directives } : {}),
284
289
  };
@@ -290,7 +295,7 @@ function sortByName<T extends { name: string }>(items: ReadonlyArray<T>): T[] {
290
295
 
291
296
  function buildBaseFieldDefinitionNode(
292
297
  field: BaseField,
293
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
298
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
294
299
  ): FieldDefinitionNode {
295
300
  const directives = buildDirectives(
296
301
  field.directives,
@@ -311,8 +316,8 @@ function buildBaseFieldDefinitionNode(
311
316
 
312
317
  function buildFieldDefinitionNode(
313
318
  field: ExtensionField,
314
- sourceRoot?: string,
315
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
319
+ sourceRoot: string | null,
320
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
316
321
  ): FieldDefinitionNode {
317
322
  const directives = buildDirectives(
318
323
  field.directives,
@@ -338,11 +343,14 @@ function buildFieldDefinitionNode(
338
343
  };
339
344
  }
340
345
 
341
- function buildObjectTypeDefinitionNode(
346
+ function buildTypeDefinitionNode(
342
347
  baseType: BaseType,
343
- sourceRoot?: string,
344
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
345
- ): ObjectTypeDefinitionNode {
348
+ kind:
349
+ | typeof Kind.OBJECT_TYPE_DEFINITION
350
+ | typeof Kind.INTERFACE_TYPE_DEFINITION,
351
+ sourceRoot: string | null,
352
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
353
+ ): ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode {
346
354
  const sortedFields = baseType.fields ? sortByName(baseType.fields) : [];
347
355
  const directives = buildDirectives(
348
356
  baseType.directives,
@@ -364,7 +372,7 @@ function buildObjectTypeDefinitionNode(
364
372
  : undefined;
365
373
 
366
374
  return {
367
- kind: Kind.OBJECT_TYPE_DEFINITION,
375
+ kind,
368
376
  name: buildNameNode(baseType.name),
369
377
  fields: sortedFields.map((f) =>
370
378
  buildBaseFieldDefinitionNode(f, directiveDefMap),
@@ -372,49 +380,12 @@ function buildObjectTypeDefinitionNode(
372
380
  ...(description ? { description: buildStringValueNode(description) } : {}),
373
381
  ...(directives.length > 0 ? { directives } : {}),
374
382
  ...(interfaces ? { interfaces } : {}),
375
- };
376
- }
377
-
378
- function buildInterfaceTypeDefinitionNode(
379
- baseType: BaseType,
380
- sourceRoot?: string,
381
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
382
- ): InterfaceTypeDefinitionNode {
383
- const sortedFields = baseType.fields ? sortByName(baseType.fields) : [];
384
- const directives = buildDirectives(
385
- baseType.directives,
386
- baseType.deprecated,
387
- directiveDefMap,
388
- );
389
-
390
- const description = appendSourceLocation(
391
- baseType.description,
392
- baseType.sourceFile,
393
- sourceRoot,
394
- );
395
-
396
- const interfaces =
397
- baseType.implementedInterfaces && baseType.implementedInterfaces.length > 0
398
- ? [...baseType.implementedInterfaces]
399
- .sort((a, b) => a.localeCompare(b))
400
- .map(buildNamedTypeNode)
401
- : undefined;
402
-
403
- return {
404
- kind: Kind.INTERFACE_TYPE_DEFINITION,
405
- name: buildNameNode(baseType.name),
406
- fields: sortedFields.map((f) =>
407
- buildBaseFieldDefinitionNode(f, directiveDefMap),
408
- ),
409
- ...(description ? { description: buildStringValueNode(description) } : {}),
410
- ...(directives.length > 0 ? { directives } : {}),
411
- ...(interfaces ? { interfaces } : {}),
412
- };
383
+ } as ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode;
413
384
  }
414
385
 
415
386
  function buildUnionTypeDefinitionNode(
416
387
  baseType: BaseType,
417
- sourceRoot?: string,
388
+ sourceRoot: string | null,
418
389
  ): UnionTypeDefinitionNode {
419
390
  const sortedMembers = baseType.unionMembers
420
391
  ? [...baseType.unionMembers].sort((a, b) => a.localeCompare(b))
@@ -454,7 +425,7 @@ function buildEnumValueDefinitionNode(
454
425
 
455
426
  function buildEnumTypeDefinitionNode(
456
427
  baseType: BaseType,
457
- sourceRoot?: string,
428
+ sourceRoot: string | null,
458
429
  ): EnumTypeDefinitionNode {
459
430
  const enumValues = baseType.enumValues ?? [];
460
431
 
@@ -474,7 +445,7 @@ function buildEnumTypeDefinitionNode(
474
445
 
475
446
  function buildScalarTypeDefinitionNode(
476
447
  name: string,
477
- description?: string,
448
+ description: string | null,
478
449
  ): ScalarTypeDefinitionNode {
479
450
  return {
480
451
  kind: Kind.SCALAR_TYPE_DEFINITION,
@@ -485,7 +456,7 @@ function buildScalarTypeDefinitionNode(
485
456
 
486
457
  function buildInputFieldDefinitionNode(
487
458
  field: BaseField,
488
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
459
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
489
460
  ): InputValueDefinitionNode {
490
461
  const directives = buildDirectives(
491
462
  field.directives,
@@ -501,7 +472,7 @@ function buildInputFieldDefinitionNode(
501
472
  ? { description: buildStringValueNode(field.description) }
502
473
  : {}),
503
474
  ...(field.defaultValue
504
- ? { defaultValue: buildDirectiveArgumentValue(field.defaultValue) }
475
+ ? { defaultValue: buildDirectiveArgumentValue(field.defaultValue, null) }
505
476
  : {}),
506
477
  ...(directives.length > 0 ? { directives } : {}),
507
478
  };
@@ -509,8 +480,8 @@ function buildInputFieldDefinitionNode(
509
480
 
510
481
  function buildInputObjectTypeDefinitionNode(
511
482
  inputType: InputType,
512
- sourceRoot?: string,
513
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
483
+ sourceRoot: string | null,
484
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
514
485
  ): InputObjectTypeDefinitionNode {
515
486
  const sortedFields = sortByName(inputType.fields);
516
487
 
@@ -538,8 +509,8 @@ function buildInputObjectTypeDefinitionNode(
538
509
 
539
510
  function buildObjectTypeExtensionNode(
540
511
  typeExtension: TypeExtension,
541
- sourceRoot?: string,
542
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
512
+ sourceRoot: string | null,
513
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
543
514
  ): ObjectTypeExtensionNode {
544
515
  const sortedFields = sortByName(typeExtension.fields);
545
516
  return {
@@ -553,8 +524,8 @@ function buildObjectTypeExtensionNode(
553
524
 
554
525
  function buildInterfaceTypeExtensionNode(
555
526
  typeExtension: TypeExtension,
556
- sourceRoot?: string,
557
- directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
527
+ sourceRoot: string | null,
528
+ directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
558
529
  ): InterfaceTypeExtensionNode {
559
530
  const sortedFields = sortByName(typeExtension.fields);
560
531
  return {
@@ -600,9 +571,9 @@ function buildDirectiveDefinitionNode(
600
571
 
601
572
  export function buildDocumentNode(
602
573
  integratedResult: IntegratedResult,
603
- options?: BuildDocumentOptions,
574
+ options: BuildDocumentOptions,
604
575
  ): DocumentNode {
605
- const sourceRoot = options?.sourceRoot;
576
+ const sourceRoot = options.sourceRoot;
606
577
  const definitions: DefinitionNode[] = [];
607
578
 
608
579
  // Build directive definition map for argument type lookup
@@ -628,19 +599,9 @@ export function buildDocumentNode(
628
599
  );
629
600
  for (const scalar of sortedScalars) {
630
601
  definitions.push(
631
- buildScalarTypeDefinitionNode(
632
- scalar.scalarName,
633
- scalar.description ?? undefined,
634
- ),
602
+ buildScalarTypeDefinitionNode(scalar.scalarName, scalar.description),
635
603
  );
636
604
  }
637
- } else if (integratedResult.customScalarNames) {
638
- const sortedScalarNames = [...integratedResult.customScalarNames].sort(
639
- (a, b) => a.localeCompare(b),
640
- );
641
- for (const scalarName of sortedScalarNames) {
642
- definitions.push(buildScalarTypeDefinitionNode(scalarName));
643
- }
644
605
  }
645
606
 
646
607
  const sortedBaseTypes = [...integratedResult.baseTypes].sort((a, b) =>
@@ -650,11 +611,21 @@ export function buildDocumentNode(
650
611
  for (const baseType of sortedBaseTypes) {
651
612
  if (baseType.kind === "Interface") {
652
613
  definitions.push(
653
- buildInterfaceTypeDefinitionNode(baseType, sourceRoot, directiveDefMap),
614
+ buildTypeDefinitionNode(
615
+ baseType,
616
+ Kind.INTERFACE_TYPE_DEFINITION,
617
+ sourceRoot,
618
+ directiveDefMap,
619
+ ),
654
620
  );
655
621
  } else if (baseType.kind === "Object") {
656
622
  definitions.push(
657
- buildObjectTypeDefinitionNode(baseType, sourceRoot, directiveDefMap),
623
+ buildTypeDefinitionNode(
624
+ baseType,
625
+ Kind.OBJECT_TYPE_DEFINITION,
626
+ sourceRoot,
627
+ directiveDefMap,
628
+ ),
658
629
  );
659
630
  } else if (baseType.kind === "Union") {
660
631
  definitions.push(buildUnionTypeDefinitionNode(baseType, sourceRoot));
@@ -1,4 +1,7 @@
1
1
  import path from "node:path";
2
+ import type { AutoGeneratedResolveType } from "../../auto-type-generator/resolve-type-generator.js";
3
+ import { TYPENAME_FIELD_NAMES } from "../../auto-type-generator/typename-types.js";
4
+ import type { ImportExtension } from "../../config/types.js";
2
5
  import { toPosixPath } from "../../shared/index.js";
3
6
  import type { CollectedScalarType } from "../../type-extractor/collector/scalar-collector.js";
4
7
  import {
@@ -21,7 +24,7 @@ const GENERATED_FILE_HEADER =
21
24
 
22
25
  function formatDocumentNodeAsCode(
23
26
  integratedResult: IntegratedResult,
24
- options?: BuildDocumentOptions,
27
+ options: BuildDocumentOptions,
25
28
  ): string {
26
29
  const doc = buildDocumentNode(integratedResult, options);
27
30
 
@@ -30,7 +33,7 @@ function formatDocumentNodeAsCode(
30
33
 
31
34
  export function emitTypeDefsCode(
32
35
  integratedResult: IntegratedResult,
33
- options?: BuildDocumentOptions,
36
+ options: BuildDocumentOptions,
34
37
  ): string {
35
38
  const documentNodeCode = formatDocumentNodeAsCode(integratedResult, options);
36
39
 
@@ -42,13 +45,31 @@ export const typeDefs: DocumentNode = ${documentNodeCode} as DocumentNode;
42
45
  `;
43
46
  }
44
47
 
45
- function computeRelativeImportPath(fromDir: string, toFile: string): string {
48
+ function applyExtension(
49
+ relativePath: string,
50
+ importExtension: ImportExtension,
51
+ ): string {
52
+ switch (importExtension) {
53
+ case "js":
54
+ return relativePath.replace(/\.ts$/, ".js");
55
+ case "ts":
56
+ return relativePath;
57
+ case "none":
58
+ return relativePath.replace(/\.ts$/, "");
59
+ }
60
+ }
61
+
62
+ function computeRelativeImportPath(
63
+ fromDir: string,
64
+ toFile: string,
65
+ importExtension: ImportExtension,
66
+ ): string {
46
67
  const relativePath = toPosixPath(path.relative(fromDir, toFile));
47
- const withoutExt = relativePath.replace(/\.ts$/, ".js");
48
- if (!withoutExt.startsWith(".")) {
49
- return `./${withoutExt}`;
68
+ const withExt = applyExtension(relativePath, importExtension);
69
+ if (!withExt.startsWith(".")) {
70
+ return `./${withExt}`;
50
71
  }
51
- return withoutExt;
72
+ return withExt;
52
73
  }
53
74
 
54
75
  interface ScalarTypeImport {
@@ -92,6 +113,7 @@ function collectScalarTypeImports(
92
113
  function buildScalarTypeImports(
93
114
  scalarTypeImports: ScalarTypeImport[],
94
115
  outputDir: string,
116
+ importExtension: ImportExtension,
95
117
  ): string[] {
96
118
  const importsByFile = new Map<string, string[]>();
97
119
 
@@ -106,7 +128,11 @@ function buildScalarTypeImports(
106
128
 
107
129
  for (const sourceFile of sortedFiles) {
108
130
  const typeNames = importsByFile.get(sourceFile) ?? [];
109
- const importPath = computeRelativeImportPath(outputDir, sourceFile);
131
+ const importPath = computeRelativeImportPath(
132
+ outputDir,
133
+ sourceFile,
134
+ importExtension,
135
+ );
110
136
  imports.push(
111
137
  `import type { ${typeNames.sort().join(", ")} } from "${importPath}";`,
112
138
  );
@@ -170,13 +196,18 @@ function collectResolverImportsByFile(
170
196
  function buildResolverImports(
171
197
  importsByFile: Map<string, Set<string>>,
172
198
  outputDir: string,
199
+ importExtension: ImportExtension,
173
200
  ): string[] {
174
201
  const imports: string[] = [];
175
202
  const sortedFiles = [...importsByFile.keys()].sort();
176
203
 
177
204
  for (const sourceFile of sortedFiles) {
178
205
  const valueNames = importsByFile.get(sourceFile) ?? new Set<string>();
179
- const importPath = computeRelativeImportPath(outputDir, sourceFile);
206
+ const importPath = computeRelativeImportPath(
207
+ outputDir,
208
+ sourceFile,
209
+ importExtension,
210
+ );
180
211
  const sortedValues = [...valueNames].sort();
181
212
 
182
213
  if (sortedValues.length > 0) {
@@ -248,6 +279,30 @@ function buildTypeResolverEntry(
248
279
  return ` ${type.typeName}: {\n${entries.join("\n")}\n },`;
249
280
  }
250
281
 
282
+ function getResolveTypeExpression(
283
+ fieldPattern: AutoGeneratedResolveType["fieldPattern"],
284
+ ): string {
285
+ const { usedFieldNames } = fieldPattern;
286
+
287
+ if (usedFieldNames.size === 1) {
288
+ const fieldName = [...usedFieldNames][0]!;
289
+ return `obj.${fieldName}`;
290
+ }
291
+
292
+ const expressions = TYPENAME_FIELD_NAMES.filter((name) =>
293
+ usedFieldNames.has(name),
294
+ ).map((name) => `obj.${name}`);
295
+
296
+ return expressions.join(" ?? ");
297
+ }
298
+
299
+ function buildAutoResolveTypeEntry(
300
+ autoResolveType: AutoGeneratedResolveType,
301
+ ): string {
302
+ const expression = getResolveTypeExpression(autoResolveType.fieldPattern);
303
+ return ` ${autoResolveType.unionTypeName}: {\n __resolveType: (obj) => ${expression},\n },`;
304
+ }
305
+
251
306
  function buildTypeEntries(
252
307
  resolverInfo: ResolverInfo,
253
308
  customScalars: ReadonlyArray<CollectedScalarType>,
@@ -269,15 +324,21 @@ function buildTypeEntries(
269
324
  abstractResolversByType.set(abstractResolver.typeName, abstractResolver);
270
325
  }
271
326
 
327
+ const autoResolveTypeByUnion = new Map<string, AutoGeneratedResolveType>(
328
+ resolverInfo.autoGeneratedResolveTypes.map((r) => [r.unionTypeName, r]),
329
+ );
330
+
272
331
  const allTypeNames = new Set<string>([
273
332
  ...typesWithFields.keys(),
274
333
  ...abstractResolversByType.keys(),
334
+ ...autoResolveTypeByUnion.keys(),
275
335
  ]);
276
336
  const sortedTypeNames = [...allTypeNames].sort();
277
337
 
278
338
  for (const typeName of sortedTypeNames) {
279
339
  const typeWithFields = typesWithFields.get(typeName);
280
340
  const abstractResolver = abstractResolversByType.get(typeName) ?? null;
341
+ const autoResolveType = autoResolveTypeByUnion.get(typeName);
281
342
 
282
343
  if (typeWithFields !== undefined) {
283
344
  typeEntries.push(
@@ -285,6 +346,8 @@ function buildTypeEntries(
285
346
  );
286
347
  } else if (abstractResolver !== null) {
287
348
  typeEntries.push(buildAbstractOnlyTypeEntry(abstractResolver));
349
+ } else if (autoResolveType !== undefined) {
350
+ typeEntries.push(buildAutoResolveTypeEntry(autoResolveType));
288
351
  }
289
352
  }
290
353
 
@@ -297,6 +360,7 @@ interface EmitResolversCodeParams {
297
360
  readonly customScalars: ReadonlyArray<CollectedScalarType>;
298
361
  readonly numericEnums: ReadonlyArray<NumericEnumInfo>;
299
362
  readonly stringEnumMappings: ReadonlyArray<StringEnumMappingInfo>;
363
+ readonly importExtension: ImportExtension;
300
364
  }
301
365
 
302
366
  export function emitResolversCode(params: EmitResolversCodeParams): string {
@@ -306,6 +370,7 @@ export function emitResolversCode(params: EmitResolversCodeParams): string {
306
370
  customScalars,
307
371
  numericEnums,
308
372
  stringEnumMappings,
373
+ importExtension,
309
374
  } = params;
310
375
  const hasCustomScalars = customScalars.length > 0;
311
376
  const imports: string[] = [];
@@ -315,11 +380,17 @@ export function emitResolversCode(params: EmitResolversCodeParams): string {
315
380
  }
316
381
 
317
382
  const importsByFile = collectResolverImportsByFile(resolverInfo);
318
- imports.push(...buildResolverImports(importsByFile, outputDir));
383
+ imports.push(
384
+ ...buildResolverImports(importsByFile, outputDir, importExtension),
385
+ );
319
386
 
320
387
  if (hasCustomScalars) {
321
388
  const scalarTypeImports = collectScalarTypeImports(customScalars);
322
- const scalarImports = buildScalarTypeImports(scalarTypeImports, outputDir);
389
+ const scalarImports = buildScalarTypeImports(
390
+ scalarTypeImports,
391
+ outputDir,
392
+ importExtension,
393
+ );
323
394
  imports.push(...scalarImports);
324
395
  }
325
396
 
@@ -3,10 +3,6 @@ import { type DocumentNode, print } from "graphql";
3
3
  const GENERATED_FILE_HEADER =
4
4
  "# This file is auto-generated by gqlkit. DO NOT EDIT.";
5
5
 
6
- /**
7
- * DocumentNode を SDL 形式の文字列に変換する。
8
- * graphql パッケージの print() 関数を使用して SDL を生成する。
9
- */
10
6
  export function emitSdlContent(documentNode: DocumentNode): string {
11
7
  const sdl = print(documentNode);
12
8
  return `${GENERATED_FILE_HEADER}\n\n${sdl}`;
@@ -1,7 +1,12 @@
1
1
  import {
2
+ collectTypenameExtractions,
3
+ collectTypenameResolveTypes,
2
4
  generateAutoTypes,
3
5
  validateNameCollisions,
6
+ validateSchemaTypenames,
7
+ validateTypenames,
4
8
  } from "../auto-type-generator/index.js";
9
+ import type { ImportExtension } from "../config/types.js";
5
10
  import type { ExtractResolversResult } from "../resolver-extractor/index.js";
6
11
  import type { DirectiveDefinitionInfo } from "../shared/directive-definition-extractor.js";
7
12
  import type { CollectedScalarType } from "../type-extractor/collector/scalar-collector.js";
@@ -28,6 +33,8 @@ export interface GenerateSchemaInput {
28
33
  readonly directiveDefinitions: ReadonlyArray<DirectiveDefinitionInfo> | null;
29
34
  readonly enablePruning: boolean | null;
30
35
  readonly sourceRoot: string | null;
36
+ readonly knownTypeNames: ReadonlySet<string> | null;
37
+ readonly importExtension: ImportExtension;
31
38
  }
32
39
 
33
40
  export interface GenerateSchemaResult {
@@ -52,11 +59,14 @@ export function generateSchema(
52
59
  directiveDefinitions,
53
60
  enablePruning,
54
61
  sourceRoot,
62
+ knownTypeNames,
63
+ importExtension,
55
64
  } = input;
56
65
 
57
66
  const autoTypeResult = generateAutoTypes({
58
67
  extractedTypes,
59
68
  resolversResult,
69
+ knownTypeNames: knownTypeNames ?? new Set(),
60
70
  });
61
71
 
62
72
  const autoTypeErrors = autoTypeResult.diagnostics.filter(
@@ -120,19 +130,106 @@ export function generateSchema(
120
130
  },
121
131
  };
122
132
 
123
- const integratedResult = integrate(
124
- updatedTypesResult,
125
- autoTypeResult.updatedResolversResult,
126
- customScalarNames,
127
- customScalars,
128
- directiveDefinitions,
129
- autoTypeResult.autoGeneratedTypes,
133
+ const typeMap = new Map(
134
+ autoTypeResult.updatedExtractedTypes.map((t) => [t.metadata.name, t]),
135
+ );
136
+
137
+ const manualResolveTypeNames = new Set(
138
+ autoTypeResult.updatedResolversResult.abstractTypeResolvers
139
+ .filter((r) => r.kind === "resolveType")
140
+ .map((r) => r.targetTypeName),
130
141
  );
131
142
 
132
- let documentNode = buildDocumentNode(
133
- integratedResult,
134
- sourceRoot !== null ? { sourceRoot } : undefined,
143
+ const typenameResolveTypesResult = collectTypenameResolveTypes({
144
+ extractedTypes: autoTypeResult.updatedExtractedTypes,
145
+ typeMap,
146
+ manualResolveTypeNames,
147
+ });
148
+
149
+ const typenameExtractions = collectTypenameExtractions({
150
+ extractedTypes: autoTypeResult.updatedExtractedTypes,
151
+ typeMap,
152
+ });
153
+
154
+ const typenameValidationDiagnostics: Diagnostic[] = [];
155
+
156
+ for (const extraction of typenameExtractions) {
157
+ const abstractType = typeMap.get(extraction.abstractTypeName);
158
+ if (!abstractType) {
159
+ continue;
160
+ }
161
+ const validationResult = validateTypenames({
162
+ extractionResult: extraction,
163
+ sourceLocation: abstractType.metadata.sourceLocation,
164
+ inlineObjectMembers: abstractType.inlineObjectMembers,
165
+ });
166
+ typenameValidationDiagnostics.push(...validationResult.diagnostics);
167
+ }
168
+
169
+ const schemaTypenameValidationResult = validateSchemaTypenames({
170
+ objectTypes: autoTypeResult.updatedExtractedTypes,
171
+ typeMap,
172
+ });
173
+ typenameValidationDiagnostics.push(
174
+ ...schemaTypenameValidationResult.diagnostics,
135
175
  );
176
+
177
+ if (typenameValidationDiagnostics.length > 0) {
178
+ return {
179
+ typeDefsCode: "",
180
+ sdlContent: "",
181
+ resolversCode: "",
182
+ diagnostics: typenameValidationDiagnostics,
183
+ hasErrors: true,
184
+ prunedTypes: null,
185
+ };
186
+ }
187
+
188
+ const generatedInlineObjectTypes =
189
+ typenameResolveTypesResult.generatedInlineObjectTypes;
190
+
191
+ const updatedTypesForIntegration: ExtractTypesResult =
192
+ generatedInlineObjectTypes.length > 0
193
+ ? {
194
+ types: updatedTypesResult.types.map((type) => {
195
+ if (type.kind !== "Union") {
196
+ return type;
197
+ }
198
+ const inlineTypes = generatedInlineObjectTypes.filter(
199
+ (g) => g.abstractTypeName === type.name,
200
+ );
201
+ if (inlineTypes.length === 0) {
202
+ return type;
203
+ }
204
+ const newMembers = inlineTypes.map((g) => g.typeName);
205
+ return {
206
+ ...type,
207
+ unionMembers: [
208
+ ...(type.unionMembers ?? []),
209
+ ...newMembers,
210
+ ].sort(),
211
+ };
212
+ }),
213
+ diagnostics: updatedTypesResult.diagnostics,
214
+ }
215
+ : updatedTypesResult;
216
+
217
+ const allAutoGeneratedTypes = [
218
+ ...autoTypeResult.autoGeneratedTypes,
219
+ ...typenameResolveTypesResult.generatedObjectTypes,
220
+ ];
221
+
222
+ const integratedResult = integrate({
223
+ typesResult: updatedTypesForIntegration,
224
+ resolversResult: autoTypeResult.updatedResolversResult,
225
+ customScalarNames,
226
+ collectedScalars: customScalars,
227
+ directiveDefinitions,
228
+ autoGeneratedTypes: allAutoGeneratedTypes,
229
+ typenameAutoResolveTypes: typenameResolveTypesResult.autoResolveTypes,
230
+ });
231
+
232
+ let documentNode = buildDocumentNode(integratedResult, { sourceRoot });
136
233
  let prunedTypes: ReadonlyArray<string> | null = null;
137
234
 
138
235
  if (enablePruning) {
@@ -144,10 +241,7 @@ export function generateSchema(
144
241
  prunedTypes = pruneResult.removedTypes;
145
242
  }
146
243
 
147
- const typeDefsCode = emitTypeDefsCode(
148
- integratedResult,
149
- sourceRoot !== null ? { sourceRoot } : undefined,
150
- );
244
+ const typeDefsCode = emitTypeDefsCode(integratedResult, { sourceRoot });
151
245
  const sdlContent = emitSdlContent(documentNode);
152
246
 
153
247
  const resolverInfo = collectResolverInfo(integratedResult);
@@ -157,6 +251,7 @@ export function generateSchema(
157
251
  customScalars: customScalars ?? [],
158
252
  numericEnums: integratedResult.numericEnums,
159
253
  stringEnumMappings: integratedResult.stringEnumMappings,
254
+ importExtension,
160
255
  });
161
256
 
162
257
  return {