@gqlkit-ts/cli 0.1.0 → 0.2.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 (234) hide show
  1. package/dist/auto-type-generator/auto-type-generator.d.ts +19 -3
  2. package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
  3. package/dist/auto-type-generator/auto-type-generator.js +236 -49
  4. package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
  5. package/dist/auto-type-generator/index.d.ts +1 -1
  6. package/dist/auto-type-generator/index.d.ts.map +1 -1
  7. package/dist/auto-type-generator/index.js.map +1 -1
  8. package/dist/auto-type-generator/inline-enum-collector.d.ts +31 -0
  9. package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -0
  10. package/dist/auto-type-generator/inline-enum-collector.js +157 -0
  11. package/dist/auto-type-generator/inline-enum-collector.js.map +1 -0
  12. package/dist/auto-type-generator/naming-convention.d.ts +4 -0
  13. package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
  14. package/dist/auto-type-generator/naming-convention.js +8 -0
  15. package/dist/auto-type-generator/naming-convention.js.map +1 -1
  16. package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
  17. package/dist/gen-orchestrator/orchestrator.js +106 -8
  18. package/dist/gen-orchestrator/orchestrator.js.map +1 -1
  19. package/dist/resolver-extractor/extract-resolvers.d.ts +10 -1
  20. package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -1
  21. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +11 -1
  22. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
  23. package/dist/resolver-extractor/extractor/define-api-extractor.js +88 -264
  24. package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
  25. package/dist/schema-generator/emitter/code-emitter.d.ts +10 -2
  26. package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
  27. package/dist/schema-generator/emitter/code-emitter.js +19 -4
  28. package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
  29. package/dist/schema-generator/generate-schema.d.ts.map +1 -1
  30. package/dist/schema-generator/generate-schema.js +18 -1
  31. package/dist/schema-generator/generate-schema.js.map +1 -1
  32. package/dist/schema-generator/integrator/result-integrator.d.ts +20 -0
  33. package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
  34. package/dist/schema-generator/integrator/result-integrator.js +42 -0
  35. package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
  36. package/dist/shared/constants.d.ts +0 -16
  37. package/dist/shared/constants.d.ts.map +1 -1
  38. package/dist/shared/constants.js +0 -19
  39. package/dist/shared/constants.js.map +1 -1
  40. package/dist/shared/directive-detector.d.ts.map +1 -1
  41. package/dist/shared/directive-detector.js +8 -15
  42. package/dist/shared/directive-detector.js.map +1 -1
  43. package/dist/shared/file-scanner.d.ts.map +1 -1
  44. package/dist/shared/file-scanner.js +5 -3
  45. package/dist/shared/file-scanner.js.map +1 -1
  46. package/dist/shared/index.d.ts +1 -1
  47. package/dist/shared/index.d.ts.map +1 -1
  48. package/dist/shared/index.js +1 -3
  49. package/dist/shared/index.js.map +1 -1
  50. package/dist/shared/interface-detector.d.ts +3 -2
  51. package/dist/shared/interface-detector.d.ts.map +1 -1
  52. package/dist/shared/interface-detector.js +54 -11
  53. package/dist/shared/interface-detector.js.map +1 -1
  54. package/dist/shared/path-utils.d.ts +2 -0
  55. package/dist/shared/path-utils.d.ts.map +1 -0
  56. package/dist/shared/path-utils.js +4 -0
  57. package/dist/shared/path-utils.js.map +1 -0
  58. package/dist/shared/type-converter.d.ts.map +1 -1
  59. package/dist/shared/type-converter.js +11 -0
  60. package/dist/shared/type-converter.js.map +1 -1
  61. package/dist/shared/typescript-utils.d.ts +34 -7
  62. package/dist/shared/typescript-utils.d.ts.map +1 -1
  63. package/dist/shared/typescript-utils.js +72 -24
  64. package/dist/shared/typescript-utils.js.map +1 -1
  65. package/dist/type-extractor/collector/scalar-collector.d.ts.map +1 -1
  66. package/dist/type-extractor/collector/scalar-collector.js +4 -14
  67. package/dist/type-extractor/collector/scalar-collector.js.map +1 -1
  68. package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
  69. package/dist/type-extractor/converter/graphql-converter.js +42 -3
  70. package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
  71. package/dist/type-extractor/extractor/field-type-resolver.d.ts +28 -0
  72. package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -0
  73. package/dist/type-extractor/extractor/field-type-resolver.js +394 -0
  74. package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -0
  75. package/dist/type-extractor/extractor/type-extractor.d.ts +12 -3
  76. package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
  77. package/dist/type-extractor/extractor/type-extractor.js +176 -210
  78. package/dist/type-extractor/extractor/type-extractor.js.map +1 -1
  79. package/dist/type-extractor/extractor/type-name-collector.d.ts +24 -0
  80. package/dist/type-extractor/extractor/type-name-collector.d.ts.map +1 -0
  81. package/dist/type-extractor/extractor/type-name-collector.js +102 -0
  82. package/dist/type-extractor/extractor/type-name-collector.js.map +1 -0
  83. package/dist/type-extractor/mapper/scalar-base-type-mapper.d.ts +89 -0
  84. package/dist/type-extractor/mapper/scalar-base-type-mapper.d.ts.map +1 -0
  85. package/dist/type-extractor/mapper/scalar-base-type-mapper.js +158 -0
  86. package/dist/type-extractor/mapper/scalar-base-type-mapper.js.map +1 -0
  87. package/dist/type-extractor/types/diagnostics.d.ts +1 -1
  88. package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
  89. package/dist/type-extractor/types/graphql.d.ts +2 -0
  90. package/dist/type-extractor/types/graphql.d.ts.map +1 -1
  91. package/dist/type-extractor/types/index.d.ts +2 -1
  92. package/dist/type-extractor/types/index.d.ts.map +1 -1
  93. package/dist/type-extractor/types/index.js +1 -1
  94. package/dist/type-extractor/types/index.js.map +1 -1
  95. package/dist/type-extractor/types/ts-type-reference-factory.d.ts +39 -0
  96. package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -0
  97. package/dist/type-extractor/types/ts-type-reference-factory.js +69 -0
  98. package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -0
  99. package/dist/type-extractor/types/typescript.d.ts +21 -1
  100. package/dist/type-extractor/types/typescript.d.ts.map +1 -1
  101. package/dist/type-extractor/validator/type-validator.js +1 -1
  102. package/dist/type-extractor/validator/type-validator.js.map +1 -1
  103. package/docs/index.md +1 -0
  104. package/docs/integration/drizzle.md +191 -0
  105. package/docs/schema/enums.md +208 -0
  106. package/docs/schema/fields.md +2 -0
  107. package/docs/schema/inputs.md +2 -0
  108. package/docs/schema/objects.md +2 -0
  109. package/docs/schema/queries-mutations.md +2 -0
  110. package/package.json +10 -3
  111. package/src/auto-type-generator/auto-type-generator.ts +925 -0
  112. package/src/auto-type-generator/index.ts +21 -0
  113. package/src/auto-type-generator/inline-enum-collector.ts +290 -0
  114. package/src/auto-type-generator/name-collision-validator.ts +119 -0
  115. package/src/auto-type-generator/naming-convention.ts +126 -0
  116. package/src/cli.ts +11 -0
  117. package/src/commands/gen.ts +141 -0
  118. package/src/commands/main.ts +5 -0
  119. package/src/config/define-config.ts +28 -0
  120. package/src/config/index.ts +7 -0
  121. package/src/config/types.ts +144 -0
  122. package/src/config-loader/index.ts +14 -0
  123. package/src/config-loader/loader.ts +143 -0
  124. package/src/config-loader/validator.ts +672 -0
  125. package/src/gen-orchestrator/hook-executor/hook-executor.ts +117 -0
  126. package/src/gen-orchestrator/orchestrator.ts +784 -0
  127. package/src/gen-orchestrator/reporter/diagnostic-reporter.ts +44 -0
  128. package/src/gen-orchestrator/reporter/progress-reporter.ts +61 -0
  129. package/src/gen-orchestrator/writer/file-writer.ts +38 -0
  130. package/src/index.ts +2 -0
  131. package/src/resolver-extractor/extract-resolvers.ts +63 -0
  132. package/src/resolver-extractor/extractor/define-api-extractor.ts +806 -0
  133. package/src/resolver-extractor/index.ts +19 -0
  134. package/src/resolver-extractor/validator/abstract-resolver-validator.ts +251 -0
  135. package/src/resolver-extractor/validator/only-validator.ts +158 -0
  136. package/src/schema-generator/builder/ast-builder.ts +706 -0
  137. package/src/schema-generator/emitter/code-emitter.ts +351 -0
  138. package/src/schema-generator/emitter/sdl-emitter.ts +13 -0
  139. package/src/schema-generator/generate-schema.ts +170 -0
  140. package/src/schema-generator/index.ts +19 -0
  141. package/src/schema-generator/integrator/result-integrator.ts +690 -0
  142. package/src/schema-generator/pruner/schema-pruner.ts +112 -0
  143. package/src/schema-generator/resolver-collector/resolver-collector.ts +123 -0
  144. package/src/shared/constants.ts +122 -0
  145. package/src/shared/default-value-detector.ts +172 -0
  146. package/src/shared/diagnostics.ts +35 -0
  147. package/src/shared/directive-definition-extractor.ts +564 -0
  148. package/src/shared/directive-detector.ts +556 -0
  149. package/src/shared/file-scanner.ts +170 -0
  150. package/src/shared/index.ts +32 -0
  151. package/src/shared/inline-object-extractor.ts +102 -0
  152. package/src/shared/inline-object-utils.ts +23 -0
  153. package/src/shared/interface-detector.ts +176 -0
  154. package/src/shared/interface-validator.ts +211 -0
  155. package/src/shared/metadata-detector.ts +443 -0
  156. package/src/shared/path-utils.ts +3 -0
  157. package/src/shared/program-factory.ts +51 -0
  158. package/src/shared/source-location.ts +27 -0
  159. package/src/shared/tsconfig-loader.ts +126 -0
  160. package/src/shared/tsdoc-parser.ts +155 -0
  161. package/src/shared/type-converter.ts +99 -0
  162. package/src/shared/typescript-utils.ts +246 -0
  163. package/src/type-extractor/collector/result-collector.ts +57 -0
  164. package/src/type-extractor/collector/scalar-collector.ts +254 -0
  165. package/src/type-extractor/converter/field-eligibility.ts +112 -0
  166. package/src/type-extractor/converter/graphql-converter.ts +459 -0
  167. package/src/type-extractor/extract-types.ts +1 -0
  168. package/src/type-extractor/extractor/field-type-resolver.ts +569 -0
  169. package/src/type-extractor/extractor/type-extractor.ts +1567 -0
  170. package/src/type-extractor/extractor/type-name-collector.ts +130 -0
  171. package/src/type-extractor/index.ts +20 -0
  172. package/src/type-extractor/mapper/scalar-base-type-mapper.ts +265 -0
  173. package/src/type-extractor/types/diagnostics.ts +99 -0
  174. package/src/type-extractor/types/graphql.ts +55 -0
  175. package/src/type-extractor/types/index.ts +37 -0
  176. package/src/type-extractor/types/ts-type-reference-factory.ts +137 -0
  177. package/src/type-extractor/types/typescript.ts +133 -0
  178. package/src/type-extractor/validator/type-validator.ts +77 -0
  179. package/dist/auto-type-generator/auto-type-generator.test.d.ts +0 -2
  180. package/dist/auto-type-generator/auto-type-generator.test.d.ts.map +0 -1
  181. package/dist/auto-type-generator/auto-type-generator.test.js +0 -613
  182. package/dist/auto-type-generator/auto-type-generator.test.js.map +0 -1
  183. package/dist/auto-type-generator/name-collision-validator.test.d.ts +0 -2
  184. package/dist/auto-type-generator/name-collision-validator.test.d.ts.map +0 -1
  185. package/dist/auto-type-generator/name-collision-validator.test.js +0 -358
  186. package/dist/auto-type-generator/name-collision-validator.test.js.map +0 -1
  187. package/dist/auto-type-generator/naming-convention.test.d.ts +0 -2
  188. package/dist/auto-type-generator/naming-convention.test.d.ts.map +0 -1
  189. package/dist/auto-type-generator/naming-convention.test.js +0 -132
  190. package/dist/auto-type-generator/naming-convention.test.js.map +0 -1
  191. package/dist/commands/gen.test.d.ts +0 -2
  192. package/dist/commands/gen.test.d.ts.map +0 -1
  193. package/dist/commands/gen.test.js +0 -226
  194. package/dist/commands/gen.test.js.map +0 -1
  195. package/dist/config-loader/loader.test.d.ts +0 -2
  196. package/dist/config-loader/loader.test.d.ts.map +0 -1
  197. package/dist/config-loader/loader.test.js +0 -123
  198. package/dist/config-loader/loader.test.js.map +0 -1
  199. package/dist/config-loader/validator.test.d.ts +0 -2
  200. package/dist/config-loader/validator.test.d.ts.map +0 -1
  201. package/dist/config-loader/validator.test.js +0 -846
  202. package/dist/config-loader/validator.test.js.map +0 -1
  203. package/dist/gen-orchestrator/golden.test.d.ts +0 -2
  204. package/dist/gen-orchestrator/golden.test.d.ts.map +0 -1
  205. package/dist/gen-orchestrator/golden.test.js +0 -102
  206. package/dist/gen-orchestrator/golden.test.js.map +0 -1
  207. package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts +0 -2
  208. package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts.map +0 -1
  209. package/dist/gen-orchestrator/hook-executor/hook-executor.test.js +0 -167
  210. package/dist/gen-orchestrator/hook-executor/hook-executor.test.js.map +0 -1
  211. package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts +0 -2
  212. package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts.map +0 -1
  213. package/dist/gen-orchestrator/reporter/progress-reporter.test.js +0 -74
  214. package/dist/gen-orchestrator/reporter/progress-reporter.test.js.map +0 -1
  215. package/dist/resolver-extractor/validator/only-validator.test.d.ts +0 -8
  216. package/dist/resolver-extractor/validator/only-validator.test.d.ts.map +0 -1
  217. package/dist/resolver-extractor/validator/only-validator.test.js +0 -352
  218. package/dist/resolver-extractor/validator/only-validator.test.js.map +0 -1
  219. package/dist/schema-generator/builder/ast-builder.test.d.ts +0 -2
  220. package/dist/schema-generator/builder/ast-builder.test.d.ts.map +0 -1
  221. package/dist/schema-generator/builder/ast-builder.test.js +0 -469
  222. package/dist/schema-generator/builder/ast-builder.test.js.map +0 -1
  223. package/dist/shared/file-scanner.test.d.ts +0 -2
  224. package/dist/shared/file-scanner.test.d.ts.map +0 -1
  225. package/dist/shared/file-scanner.test.js +0 -138
  226. package/dist/shared/file-scanner.test.js.map +0 -1
  227. package/dist/shared/interface-validator.test.d.ts +0 -2
  228. package/dist/shared/interface-validator.test.d.ts.map +0 -1
  229. package/dist/shared/interface-validator.test.js +0 -145
  230. package/dist/shared/interface-validator.test.js.map +0 -1
  231. package/dist/type-extractor/types/typescript.test.d.ts +0 -2
  232. package/dist/type-extractor/types/typescript.test.d.ts.map +0 -1
  233. package/dist/type-extractor/types/typescript.test.js +0 -287
  234. package/dist/type-extractor/types/typescript.test.js.map +0 -1
@@ -0,0 +1,706 @@
1
+ import path from "node:path";
2
+ import {
3
+ type ConstArgumentNode,
4
+ type ConstDirectiveNode,
5
+ type ConstValueNode,
6
+ type DefinitionNode,
7
+ type DirectiveDefinitionNode,
8
+ type DocumentNode,
9
+ type EnumTypeDefinitionNode,
10
+ type EnumValueDefinitionNode,
11
+ type FieldDefinitionNode,
12
+ type InputObjectTypeDefinitionNode,
13
+ type InputValueDefinitionNode,
14
+ type InterfaceTypeDefinitionNode,
15
+ type InterfaceTypeExtensionNode,
16
+ Kind,
17
+ type ListTypeNode,
18
+ type NamedTypeNode,
19
+ type NameNode,
20
+ type NonNullTypeNode,
21
+ type ObjectTypeDefinitionNode,
22
+ type ObjectTypeExtensionNode,
23
+ type ScalarTypeDefinitionNode,
24
+ type StringValueNode,
25
+ type TypeNode,
26
+ type UnionTypeDefinitionNode,
27
+ } from "graphql";
28
+ import type { GraphQLInputValue } from "../../resolver-extractor/index.js";
29
+ import type { DirectiveDefinitionInfo } from "../../shared/directive-definition-extractor.js";
30
+ import type {
31
+ DirectiveArgument,
32
+ DirectiveArgumentValue,
33
+ DirectiveInfo,
34
+ } from "../../shared/directive-detector.js";
35
+ import { toPosixPath } from "../../shared/index.js";
36
+ import type { DeprecationInfo } from "../../shared/tsdoc-parser.js";
37
+ import type {
38
+ EnumValueInfo,
39
+ GraphQLFieldType,
40
+ } from "../../type-extractor/types/index.js";
41
+ import type {
42
+ BaseField,
43
+ BaseType,
44
+ ExtensionField,
45
+ InputType,
46
+ IntegratedResult,
47
+ TypeExtension,
48
+ } from "../integrator/result-integrator.js";
49
+
50
+ export interface BuildDocumentOptions {
51
+ readonly sourceRoot?: string;
52
+ }
53
+
54
+ function appendSourceLocation(
55
+ description: string | null,
56
+ sourceFile: string | null,
57
+ sourceRoot: string | undefined,
58
+ ): string | null {
59
+ if (!sourceRoot || !sourceFile) {
60
+ return description;
61
+ }
62
+
63
+ const relativePath = toPosixPath(path.relative(sourceRoot, sourceFile));
64
+ const sourceLocation = `Defined in: ${relativePath}`;
65
+
66
+ if (description) {
67
+ return `${description}\n\n${sourceLocation}`;
68
+ }
69
+ return sourceLocation;
70
+ }
71
+
72
+ function buildNameNode(value: string): NameNode {
73
+ return {
74
+ kind: Kind.NAME,
75
+ value,
76
+ };
77
+ }
78
+
79
+ function buildStringValueNode(value: string): StringValueNode {
80
+ return {
81
+ kind: Kind.STRING,
82
+ value,
83
+ block: true,
84
+ };
85
+ }
86
+
87
+ const DEFAULT_DEPRECATION_REASON = "No longer supported";
88
+
89
+ function buildDeprecatedDirective(
90
+ deprecated: DeprecationInfo,
91
+ ): ConstDirectiveNode {
92
+ const reason = deprecated.reason ?? DEFAULT_DEPRECATION_REASON;
93
+
94
+ return {
95
+ kind: Kind.DIRECTIVE,
96
+ name: buildNameNode("deprecated"),
97
+ arguments: [
98
+ {
99
+ kind: Kind.ARGUMENT,
100
+ name: buildNameNode("reason"),
101
+ value: buildStringValueNode(reason),
102
+ },
103
+ ],
104
+ };
105
+ }
106
+
107
+ function buildOneOfDirective(): ConstDirectiveNode {
108
+ return {
109
+ kind: Kind.DIRECTIVE,
110
+ name: buildNameNode("oneOf"),
111
+ };
112
+ }
113
+
114
+ function buildDirectiveArgumentValue(
115
+ value: DirectiveArgumentValue,
116
+ expectedTypeName?: string,
117
+ ): ConstValueNode {
118
+ switch (value.kind) {
119
+ case "string":
120
+ return {
121
+ kind: Kind.STRING,
122
+ value: value.value,
123
+ };
124
+ case "number":
125
+ return Number.isInteger(value.value)
126
+ ? { kind: Kind.INT, value: String(value.value) }
127
+ : { kind: Kind.FLOAT, value: String(value.value) };
128
+ case "boolean":
129
+ return {
130
+ kind: Kind.BOOLEAN,
131
+ value: value.value,
132
+ };
133
+ case "null":
134
+ return {
135
+ kind: Kind.NULL,
136
+ };
137
+ case "enum":
138
+ // If the expected type is String, output as string literal with quotes
139
+ if (expectedTypeName === "String") {
140
+ return {
141
+ kind: Kind.STRING,
142
+ value: value.value,
143
+ };
144
+ }
145
+ return {
146
+ kind: Kind.ENUM,
147
+ value: value.value,
148
+ };
149
+ case "list":
150
+ return {
151
+ kind: Kind.LIST,
152
+ values: value.values.map((v) =>
153
+ buildDirectiveArgumentValue(v, expectedTypeName),
154
+ ),
155
+ };
156
+ case "object":
157
+ return {
158
+ kind: Kind.OBJECT,
159
+ fields: value.fields.map((f) => ({
160
+ kind: Kind.OBJECT_FIELD as const,
161
+ name: buildNameNode(f.name),
162
+ value: buildDirectiveArgumentValue(f.value),
163
+ })),
164
+ };
165
+ }
166
+ }
167
+
168
+ function buildDirectiveArgument(
169
+ arg: DirectiveArgument,
170
+ expectedTypeName?: string,
171
+ ): ConstArgumentNode {
172
+ return {
173
+ kind: Kind.ARGUMENT,
174
+ name: buildNameNode(arg.name),
175
+ value: buildDirectiveArgumentValue(arg.value, expectedTypeName),
176
+ };
177
+ }
178
+
179
+ function buildCustomDirective(
180
+ directive: DirectiveInfo,
181
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
182
+ ): ConstDirectiveNode {
183
+ const def = directiveDefMap?.get(directive.name);
184
+ const argTypeMap = new Map<string, string>();
185
+ if (def) {
186
+ for (const argDef of def.args) {
187
+ argTypeMap.set(argDef.name, argDef.type.typeName);
188
+ }
189
+ }
190
+
191
+ const args = directive.args.map((arg) =>
192
+ buildDirectiveArgument(arg, argTypeMap.get(arg.name)),
193
+ );
194
+
195
+ return {
196
+ kind: Kind.DIRECTIVE,
197
+ name: buildNameNode(directive.name),
198
+ ...(args.length > 0 ? { arguments: args } : {}),
199
+ };
200
+ }
201
+
202
+ function buildDirectives(
203
+ directives: ReadonlyArray<DirectiveInfo> | null,
204
+ deprecated: DeprecationInfo | null,
205
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
206
+ ): ConstDirectiveNode[] {
207
+ const result: ConstDirectiveNode[] = [];
208
+
209
+ if (deprecated) {
210
+ result.push(buildDeprecatedDirective(deprecated));
211
+ }
212
+
213
+ if (directives) {
214
+ for (const directive of directives) {
215
+ result.push(buildCustomDirective(directive, directiveDefMap));
216
+ }
217
+ }
218
+
219
+ return result;
220
+ }
221
+
222
+ function buildNamedTypeNode(typeName: string): NamedTypeNode {
223
+ return {
224
+ kind: Kind.NAMED_TYPE,
225
+ name: buildNameNode(typeName),
226
+ };
227
+ }
228
+
229
+ function buildListTypeNode(
230
+ innerType: NamedTypeNode | NonNullTypeNode,
231
+ ): ListTypeNode {
232
+ return {
233
+ kind: Kind.LIST_TYPE,
234
+ type: innerType,
235
+ };
236
+ }
237
+
238
+ function buildNonNullTypeNode(
239
+ innerType: NamedTypeNode | ListTypeNode,
240
+ ): NonNullTypeNode {
241
+ return {
242
+ kind: Kind.NON_NULL_TYPE,
243
+ type: innerType,
244
+ };
245
+ }
246
+
247
+ function buildFieldTypeNode(fieldType: GraphQLFieldType): TypeNode {
248
+ const { typeName, nullable, list, listItemNullable } = fieldType;
249
+
250
+ if (list) {
251
+ const namedType = buildNamedTypeNode(typeName);
252
+
253
+ const itemType =
254
+ listItemNullable === true ? namedType : buildNonNullTypeNode(namedType);
255
+
256
+ const listType = buildListTypeNode(itemType);
257
+
258
+ return nullable ? listType : buildNonNullTypeNode(listType);
259
+ }
260
+
261
+ const namedType = buildNamedTypeNode(typeName);
262
+ return nullable ? namedType : buildNonNullTypeNode(namedType);
263
+ }
264
+
265
+ function buildInputValueDefinitionNode(
266
+ inputValue: GraphQLInputValue,
267
+ ): InputValueDefinitionNode {
268
+ const directives: ConstDirectiveNode[] = [];
269
+ if (inputValue.deprecated) {
270
+ directives.push(buildDeprecatedDirective(inputValue.deprecated));
271
+ }
272
+
273
+ return {
274
+ kind: Kind.INPUT_VALUE_DEFINITION,
275
+ name: buildNameNode(inputValue.name),
276
+ type: buildFieldTypeNode(inputValue.type),
277
+ ...(inputValue.description
278
+ ? { description: buildStringValueNode(inputValue.description) }
279
+ : {}),
280
+ ...(inputValue.defaultValue
281
+ ? { defaultValue: buildDirectiveArgumentValue(inputValue.defaultValue) }
282
+ : {}),
283
+ ...(directives.length > 0 ? { directives } : {}),
284
+ };
285
+ }
286
+
287
+ function sortByName<T extends { name: string }>(items: ReadonlyArray<T>): T[] {
288
+ return [...items].sort((a, b) => a.name.localeCompare(b.name));
289
+ }
290
+
291
+ function buildBaseFieldDefinitionNode(
292
+ field: BaseField,
293
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
294
+ ): FieldDefinitionNode {
295
+ const directives = buildDirectives(
296
+ field.directives,
297
+ field.deprecated,
298
+ directiveDefMap,
299
+ );
300
+
301
+ return {
302
+ kind: Kind.FIELD_DEFINITION,
303
+ name: buildNameNode(field.name),
304
+ type: buildFieldTypeNode(field.type),
305
+ ...(field.description
306
+ ? { description: buildStringValueNode(field.description) }
307
+ : {}),
308
+ ...(directives.length > 0 ? { directives } : {}),
309
+ };
310
+ }
311
+
312
+ function buildFieldDefinitionNode(
313
+ field: ExtensionField,
314
+ sourceRoot?: string,
315
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
316
+ ): FieldDefinitionNode {
317
+ const directives = buildDirectives(
318
+ field.directives,
319
+ field.deprecated,
320
+ directiveDefMap,
321
+ );
322
+
323
+ const args = field.args?.map(buildInputValueDefinitionNode);
324
+
325
+ const description = appendSourceLocation(
326
+ field.description,
327
+ field.resolverSourceFile,
328
+ sourceRoot,
329
+ );
330
+
331
+ return {
332
+ kind: Kind.FIELD_DEFINITION,
333
+ name: buildNameNode(field.name),
334
+ ...(args && args.length > 0 ? { arguments: args } : {}),
335
+ type: buildFieldTypeNode(field.type),
336
+ ...(description ? { description: buildStringValueNode(description) } : {}),
337
+ ...(directives.length > 0 ? { directives } : {}),
338
+ };
339
+ }
340
+
341
+ function buildObjectTypeDefinitionNode(
342
+ baseType: BaseType,
343
+ sourceRoot?: string,
344
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
345
+ ): ObjectTypeDefinitionNode {
346
+ const sortedFields = baseType.fields ? sortByName(baseType.fields) : [];
347
+ const directives = buildDirectives(
348
+ baseType.directives,
349
+ baseType.deprecated,
350
+ directiveDefMap,
351
+ );
352
+
353
+ const description = appendSourceLocation(
354
+ baseType.description,
355
+ baseType.sourceFile,
356
+ sourceRoot,
357
+ );
358
+
359
+ const interfaces =
360
+ baseType.implementedInterfaces && baseType.implementedInterfaces.length > 0
361
+ ? [...baseType.implementedInterfaces]
362
+ .sort((a, b) => a.localeCompare(b))
363
+ .map(buildNamedTypeNode)
364
+ : undefined;
365
+
366
+ return {
367
+ kind: Kind.OBJECT_TYPE_DEFINITION,
368
+ name: buildNameNode(baseType.name),
369
+ fields: sortedFields.map((f) =>
370
+ buildBaseFieldDefinitionNode(f, directiveDefMap),
371
+ ),
372
+ ...(description ? { description: buildStringValueNode(description) } : {}),
373
+ ...(directives.length > 0 ? { directives } : {}),
374
+ ...(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
+ };
413
+ }
414
+
415
+ function buildUnionTypeDefinitionNode(
416
+ baseType: BaseType,
417
+ sourceRoot?: string,
418
+ ): UnionTypeDefinitionNode {
419
+ const sortedMembers = baseType.unionMembers
420
+ ? [...baseType.unionMembers].sort((a, b) => a.localeCompare(b))
421
+ : [];
422
+
423
+ const description = appendSourceLocation(
424
+ baseType.description,
425
+ baseType.sourceFile,
426
+ sourceRoot,
427
+ );
428
+
429
+ return {
430
+ kind: Kind.UNION_TYPE_DEFINITION,
431
+ name: buildNameNode(baseType.name),
432
+ types: sortedMembers.map(buildNamedTypeNode),
433
+ ...(description ? { description: buildStringValueNode(description) } : {}),
434
+ };
435
+ }
436
+
437
+ function buildEnumValueDefinitionNode(
438
+ value: EnumValueInfo,
439
+ ): EnumValueDefinitionNode {
440
+ const directives: ConstDirectiveNode[] = [];
441
+ if (value.deprecated) {
442
+ directives.push(buildDeprecatedDirective(value.deprecated));
443
+ }
444
+
445
+ return {
446
+ kind: Kind.ENUM_VALUE_DEFINITION,
447
+ name: buildNameNode(value.name),
448
+ ...(value.description
449
+ ? { description: buildStringValueNode(value.description) }
450
+ : {}),
451
+ ...(directives.length > 0 ? { directives } : {}),
452
+ };
453
+ }
454
+
455
+ function buildEnumTypeDefinitionNode(
456
+ baseType: BaseType,
457
+ sourceRoot?: string,
458
+ ): EnumTypeDefinitionNode {
459
+ const enumValues = baseType.enumValues ?? [];
460
+
461
+ const description = appendSourceLocation(
462
+ baseType.description,
463
+ baseType.sourceFile,
464
+ sourceRoot,
465
+ );
466
+
467
+ return {
468
+ kind: Kind.ENUM_TYPE_DEFINITION,
469
+ name: buildNameNode(baseType.name),
470
+ values: enumValues.map(buildEnumValueDefinitionNode),
471
+ ...(description ? { description: buildStringValueNode(description) } : {}),
472
+ };
473
+ }
474
+
475
+ function buildScalarTypeDefinitionNode(
476
+ name: string,
477
+ description?: string,
478
+ ): ScalarTypeDefinitionNode {
479
+ return {
480
+ kind: Kind.SCALAR_TYPE_DEFINITION,
481
+ name: buildNameNode(name),
482
+ ...(description ? { description: buildStringValueNode(description) } : {}),
483
+ };
484
+ }
485
+
486
+ function buildInputFieldDefinitionNode(
487
+ field: BaseField,
488
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
489
+ ): InputValueDefinitionNode {
490
+ const directives = buildDirectives(
491
+ field.directives,
492
+ field.deprecated,
493
+ directiveDefMap,
494
+ );
495
+
496
+ return {
497
+ kind: Kind.INPUT_VALUE_DEFINITION,
498
+ name: buildNameNode(field.name),
499
+ type: buildFieldTypeNode(field.type),
500
+ ...(field.description
501
+ ? { description: buildStringValueNode(field.description) }
502
+ : {}),
503
+ ...(field.defaultValue
504
+ ? { defaultValue: buildDirectiveArgumentValue(field.defaultValue) }
505
+ : {}),
506
+ ...(directives.length > 0 ? { directives } : {}),
507
+ };
508
+ }
509
+
510
+ function buildInputObjectTypeDefinitionNode(
511
+ inputType: InputType,
512
+ sourceRoot?: string,
513
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
514
+ ): InputObjectTypeDefinitionNode {
515
+ const sortedFields = sortByName(inputType.fields);
516
+
517
+ const description = appendSourceLocation(
518
+ inputType.description,
519
+ inputType.sourceFile,
520
+ sourceRoot,
521
+ );
522
+
523
+ const directives: ConstDirectiveNode[] = [];
524
+ if (inputType.isOneOf) {
525
+ directives.push(buildOneOfDirective());
526
+ }
527
+
528
+ return {
529
+ kind: Kind.INPUT_OBJECT_TYPE_DEFINITION,
530
+ name: buildNameNode(inputType.name),
531
+ fields: sortedFields.map((f) =>
532
+ buildInputFieldDefinitionNode(f, directiveDefMap),
533
+ ),
534
+ ...(description ? { description: buildStringValueNode(description) } : {}),
535
+ ...(directives.length > 0 ? { directives } : {}),
536
+ };
537
+ }
538
+
539
+ function buildObjectTypeExtensionNode(
540
+ typeExtension: TypeExtension,
541
+ sourceRoot?: string,
542
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
543
+ ): ObjectTypeExtensionNode {
544
+ const sortedFields = sortByName(typeExtension.fields);
545
+ return {
546
+ kind: Kind.OBJECT_TYPE_EXTENSION,
547
+ name: buildNameNode(typeExtension.targetTypeName),
548
+ fields: sortedFields.map((field) =>
549
+ buildFieldDefinitionNode(field, sourceRoot, directiveDefMap),
550
+ ),
551
+ };
552
+ }
553
+
554
+ function buildInterfaceTypeExtensionNode(
555
+ typeExtension: TypeExtension,
556
+ sourceRoot?: string,
557
+ directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
558
+ ): InterfaceTypeExtensionNode {
559
+ const sortedFields = sortByName(typeExtension.fields);
560
+ return {
561
+ kind: Kind.INTERFACE_TYPE_EXTENSION,
562
+ name: buildNameNode(typeExtension.targetTypeName),
563
+ fields: sortedFields.map((field) =>
564
+ buildFieldDefinitionNode(field, sourceRoot, directiveDefMap),
565
+ ),
566
+ };
567
+ }
568
+
569
+ function buildDirectiveDefinitionNode(
570
+ directiveDef: DirectiveDefinitionInfo,
571
+ ): DirectiveDefinitionNode {
572
+ const sortedArgs = [...directiveDef.args].sort((a, b) =>
573
+ a.name.localeCompare(b.name),
574
+ );
575
+
576
+ const args: InputValueDefinitionNode[] = sortedArgs.map((arg) => ({
577
+ kind: Kind.INPUT_VALUE_DEFINITION,
578
+ name: buildNameNode(arg.name),
579
+ type: buildFieldTypeNode(arg.type),
580
+ ...(arg.description
581
+ ? { description: buildStringValueNode(arg.description) }
582
+ : {}),
583
+ }));
584
+
585
+ const sortedLocations = [...directiveDef.locations].sort((a, b) =>
586
+ a.localeCompare(b),
587
+ );
588
+
589
+ return {
590
+ kind: Kind.DIRECTIVE_DEFINITION,
591
+ name: buildNameNode(directiveDef.name),
592
+ repeatable: false,
593
+ locations: sortedLocations.map(buildNameNode),
594
+ ...(args.length > 0 ? { arguments: args } : {}),
595
+ ...(directiveDef.description
596
+ ? { description: buildStringValueNode(directiveDef.description) }
597
+ : {}),
598
+ };
599
+ }
600
+
601
+ export function buildDocumentNode(
602
+ integratedResult: IntegratedResult,
603
+ options?: BuildDocumentOptions,
604
+ ): DocumentNode {
605
+ const sourceRoot = options?.sourceRoot;
606
+ const definitions: DefinitionNode[] = [];
607
+
608
+ // Build directive definition map for argument type lookup
609
+ const directiveDefMap = new Map<string, DirectiveDefinitionInfo>();
610
+ if (integratedResult.directiveDefinitions) {
611
+ for (const def of integratedResult.directiveDefinitions) {
612
+ directiveDefMap.set(def.name, def);
613
+ }
614
+ }
615
+
616
+ if (integratedResult.directiveDefinitions) {
617
+ const sortedDirectives = [...integratedResult.directiveDefinitions].sort(
618
+ (a, b) => a.name.localeCompare(b.name),
619
+ );
620
+ for (const directiveDef of sortedDirectives) {
621
+ definitions.push(buildDirectiveDefinitionNode(directiveDef));
622
+ }
623
+ }
624
+
625
+ if (integratedResult.customScalars) {
626
+ const sortedScalars = [...integratedResult.customScalars].sort((a, b) =>
627
+ a.scalarName.localeCompare(b.scalarName),
628
+ );
629
+ for (const scalar of sortedScalars) {
630
+ definitions.push(
631
+ buildScalarTypeDefinitionNode(
632
+ scalar.scalarName,
633
+ scalar.description ?? undefined,
634
+ ),
635
+ );
636
+ }
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
+ }
645
+
646
+ const sortedBaseTypes = [...integratedResult.baseTypes].sort((a, b) =>
647
+ a.name.localeCompare(b.name),
648
+ );
649
+
650
+ for (const baseType of sortedBaseTypes) {
651
+ if (baseType.kind === "Interface") {
652
+ definitions.push(
653
+ buildInterfaceTypeDefinitionNode(baseType, sourceRoot, directiveDefMap),
654
+ );
655
+ } else if (baseType.kind === "Object") {
656
+ definitions.push(
657
+ buildObjectTypeDefinitionNode(baseType, sourceRoot, directiveDefMap),
658
+ );
659
+ } else if (baseType.kind === "Union") {
660
+ definitions.push(buildUnionTypeDefinitionNode(baseType, sourceRoot));
661
+ } else if (baseType.kind === "Enum") {
662
+ definitions.push(buildEnumTypeDefinitionNode(baseType, sourceRoot));
663
+ }
664
+ }
665
+
666
+ const sortedInputTypes = [...integratedResult.inputTypes].sort((a, b) =>
667
+ a.name.localeCompare(b.name),
668
+ );
669
+
670
+ for (const inputType of sortedInputTypes) {
671
+ definitions.push(
672
+ buildInputObjectTypeDefinitionNode(
673
+ inputType,
674
+ sourceRoot,
675
+ directiveDefMap,
676
+ ),
677
+ );
678
+ }
679
+
680
+ const interfaceTypeNames = new Set(
681
+ integratedResult.baseTypes
682
+ .filter((t) => t.kind === "Interface")
683
+ .map((t) => t.name),
684
+ );
685
+
686
+ const sortedExtensions = [...integratedResult.typeExtensions].sort((a, b) =>
687
+ a.targetTypeName.localeCompare(b.targetTypeName),
688
+ );
689
+
690
+ for (const ext of sortedExtensions) {
691
+ if (interfaceTypeNames.has(ext.targetTypeName)) {
692
+ definitions.push(
693
+ buildInterfaceTypeExtensionNode(ext, sourceRoot, directiveDefMap),
694
+ );
695
+ } else {
696
+ definitions.push(
697
+ buildObjectTypeExtensionNode(ext, sourceRoot, directiveDefMap),
698
+ );
699
+ }
700
+ }
701
+
702
+ return {
703
+ kind: Kind.DOCUMENT,
704
+ definitions,
705
+ };
706
+ }