@gqlkit-ts/cli 0.0.1 → 0.1.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 (325) hide show
  1. package/LICENSE +21 -0
  2. package/dist/auto-type-generator/auto-type-generator.d.ts +46 -0
  3. package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -0
  4. package/dist/auto-type-generator/auto-type-generator.js +353 -0
  5. package/dist/auto-type-generator/auto-type-generator.js.map +1 -0
  6. package/dist/auto-type-generator/auto-type-generator.test.d.ts +2 -0
  7. package/dist/auto-type-generator/auto-type-generator.test.d.ts.map +1 -0
  8. package/dist/auto-type-generator/auto-type-generator.test.js +613 -0
  9. package/dist/auto-type-generator/auto-type-generator.test.js.map +1 -0
  10. package/dist/auto-type-generator/index.d.ts +4 -0
  11. package/dist/auto-type-generator/index.d.ts.map +1 -0
  12. package/dist/auto-type-generator/index.js +3 -0
  13. package/dist/auto-type-generator/index.js.map +1 -0
  14. package/dist/auto-type-generator/name-collision-validator.d.ts +17 -0
  15. package/dist/auto-type-generator/name-collision-validator.d.ts.map +1 -0
  16. package/dist/auto-type-generator/name-collision-validator.js +68 -0
  17. package/dist/auto-type-generator/name-collision-validator.js.map +1 -0
  18. package/dist/auto-type-generator/name-collision-validator.test.d.ts +2 -0
  19. package/dist/auto-type-generator/name-collision-validator.test.d.ts.map +1 -0
  20. package/dist/auto-type-generator/name-collision-validator.test.js +358 -0
  21. package/dist/auto-type-generator/name-collision-validator.test.js.map +1 -0
  22. package/dist/auto-type-generator/naming-convention.d.ts +40 -0
  23. package/dist/auto-type-generator/naming-convention.d.ts.map +1 -0
  24. package/dist/auto-type-generator/naming-convention.js +59 -0
  25. package/dist/auto-type-generator/naming-convention.js.map +1 -0
  26. package/dist/auto-type-generator/naming-convention.test.d.ts +2 -0
  27. package/dist/auto-type-generator/naming-convention.test.d.ts.map +1 -0
  28. package/dist/auto-type-generator/naming-convention.test.js +132 -0
  29. package/dist/auto-type-generator/naming-convention.test.js.map +1 -0
  30. package/dist/cli.d.ts +2 -0
  31. package/dist/cli.d.ts.map +1 -0
  32. package/dist/cli.js +11 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/commands/gen.d.ts +32 -0
  35. package/dist/commands/gen.d.ts.map +1 -0
  36. package/dist/commands/gen.js +101 -0
  37. package/dist/commands/gen.js.map +1 -0
  38. package/dist/commands/gen.test.d.ts +2 -0
  39. package/dist/commands/gen.test.d.ts.map +1 -0
  40. package/dist/commands/gen.test.js +226 -0
  41. package/dist/commands/gen.test.js.map +1 -0
  42. package/dist/commands/main.d.ts +12 -0
  43. package/dist/commands/main.d.ts.map +1 -0
  44. package/dist/commands/main.js +5 -0
  45. package/dist/commands/main.js.map +1 -0
  46. package/dist/config/define-config.d.ts +26 -0
  47. package/dist/config/define-config.d.ts.map +1 -0
  48. package/dist/config/define-config.js +27 -0
  49. package/dist/config/define-config.js.map +1 -0
  50. package/dist/config/index.d.ts +3 -0
  51. package/dist/config/index.d.ts.map +1 -0
  52. package/dist/config/index.js +2 -0
  53. package/dist/config/index.js.map +1 -0
  54. package/dist/config/types.d.ts +131 -0
  55. package/dist/config/types.d.ts.map +1 -0
  56. package/dist/config/types.js +2 -0
  57. package/dist/config/types.js.map +1 -0
  58. package/dist/config-loader/index.d.ts +3 -0
  59. package/dist/config-loader/index.d.ts.map +1 -0
  60. package/dist/config-loader/index.js +2 -0
  61. package/dist/config-loader/index.js.map +1 -0
  62. package/dist/config-loader/loader.d.ts +50 -0
  63. package/dist/config-loader/loader.d.ts.map +1 -0
  64. package/dist/config-loader/loader.js +78 -0
  65. package/dist/config-loader/loader.js.map +1 -0
  66. package/dist/config-loader/loader.test.d.ts +2 -0
  67. package/dist/config-loader/loader.test.d.ts.map +1 -0
  68. package/dist/config-loader/loader.test.js +123 -0
  69. package/dist/config-loader/loader.test.js.map +1 -0
  70. package/dist/config-loader/validator.d.ts +13 -0
  71. package/dist/config-loader/validator.d.ts.map +1 -0
  72. package/dist/config-loader/validator.js +497 -0
  73. package/dist/config-loader/validator.js.map +1 -0
  74. package/dist/config-loader/validator.test.d.ts +2 -0
  75. package/dist/config-loader/validator.test.d.ts.map +1 -0
  76. package/dist/config-loader/validator.test.js +846 -0
  77. package/dist/config-loader/validator.test.js.map +1 -0
  78. package/dist/gen-orchestrator/golden.test.d.ts +2 -0
  79. package/dist/gen-orchestrator/golden.test.d.ts.map +1 -0
  80. package/dist/gen-orchestrator/golden.test.js +102 -0
  81. package/dist/gen-orchestrator/golden.test.js.map +1 -0
  82. package/dist/gen-orchestrator/hook-executor/hook-executor.d.ts +25 -0
  83. package/dist/gen-orchestrator/hook-executor/hook-executor.d.ts.map +1 -0
  84. package/dist/gen-orchestrator/hook-executor/hook-executor.js +68 -0
  85. package/dist/gen-orchestrator/hook-executor/hook-executor.js.map +1 -0
  86. package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts +2 -0
  87. package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts.map +1 -0
  88. package/dist/gen-orchestrator/hook-executor/hook-executor.test.js +167 -0
  89. package/dist/gen-orchestrator/hook-executor/hook-executor.test.js.map +1 -0
  90. package/dist/gen-orchestrator/orchestrator.d.ts +30 -0
  91. package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -0
  92. package/dist/gen-orchestrator/orchestrator.js +407 -0
  93. package/dist/gen-orchestrator/orchestrator.js.map +1 -0
  94. package/dist/gen-orchestrator/reporter/diagnostic-reporter.d.ts +9 -0
  95. package/dist/gen-orchestrator/reporter/diagnostic-reporter.d.ts.map +1 -0
  96. package/dist/gen-orchestrator/reporter/diagnostic-reporter.js +32 -0
  97. package/dist/gen-orchestrator/reporter/diagnostic-reporter.js.map +1 -0
  98. package/dist/gen-orchestrator/reporter/progress-reporter.d.ts +19 -0
  99. package/dist/gen-orchestrator/reporter/progress-reporter.d.ts.map +1 -0
  100. package/dist/gen-orchestrator/reporter/progress-reporter.js +38 -0
  101. package/dist/gen-orchestrator/reporter/progress-reporter.js.map +1 -0
  102. package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts +2 -0
  103. package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts.map +1 -0
  104. package/dist/gen-orchestrator/reporter/progress-reporter.test.js +74 -0
  105. package/dist/gen-orchestrator/reporter/progress-reporter.test.js.map +1 -0
  106. package/dist/gen-orchestrator/writer/file-writer.d.ts +13 -0
  107. package/dist/gen-orchestrator/writer/file-writer.d.ts.map +1 -0
  108. package/dist/gen-orchestrator/writer/file-writer.js +22 -0
  109. package/dist/gen-orchestrator/writer/file-writer.js.map +1 -0
  110. package/dist/index.d.ts +3 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +2 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/resolver-extractor/extract-resolvers.d.ts +40 -0
  115. package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -0
  116. package/dist/resolver-extractor/extract-resolvers.js +2 -0
  117. package/dist/resolver-extractor/extract-resolvers.js.map +1 -0
  118. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +50 -0
  119. package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -0
  120. package/dist/resolver-extractor/extractor/define-api-extractor.js +685 -0
  121. package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -0
  122. package/dist/resolver-extractor/index.d.ts +5 -0
  123. package/dist/resolver-extractor/index.d.ts.map +1 -0
  124. package/dist/resolver-extractor/index.js +2 -0
  125. package/dist/resolver-extractor/index.js.map +1 -0
  126. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +25 -0
  127. package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts.map +1 -0
  128. package/dist/resolver-extractor/validator/abstract-resolver-validator.js +172 -0
  129. package/dist/resolver-extractor/validator/abstract-resolver-validator.js.map +1 -0
  130. package/dist/resolver-extractor/validator/only-validator.d.ts +61 -0
  131. package/dist/resolver-extractor/validator/only-validator.d.ts.map +1 -0
  132. package/dist/resolver-extractor/validator/only-validator.js +76 -0
  133. package/dist/resolver-extractor/validator/only-validator.js.map +1 -0
  134. package/dist/resolver-extractor/validator/only-validator.test.d.ts +8 -0
  135. package/dist/resolver-extractor/validator/only-validator.test.d.ts.map +1 -0
  136. package/dist/resolver-extractor/validator/only-validator.test.js +352 -0
  137. package/dist/resolver-extractor/validator/only-validator.test.js.map +1 -0
  138. package/dist/schema-generator/builder/ast-builder.d.ts +7 -0
  139. package/dist/schema-generator/builder/ast-builder.d.ts.map +1 -0
  140. package/dist/schema-generator/builder/ast-builder.js +417 -0
  141. package/dist/schema-generator/builder/ast-builder.js.map +1 -0
  142. package/dist/schema-generator/builder/ast-builder.test.d.ts +2 -0
  143. package/dist/schema-generator/builder/ast-builder.test.d.ts.map +1 -0
  144. package/dist/schema-generator/builder/ast-builder.test.js +469 -0
  145. package/dist/schema-generator/builder/ast-builder.test.js.map +1 -0
  146. package/dist/schema-generator/emitter/code-emitter.d.ts +7 -0
  147. package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -0
  148. package/dist/schema-generator/emitter/code-emitter.js +201 -0
  149. package/dist/schema-generator/emitter/code-emitter.js.map +1 -0
  150. package/dist/schema-generator/emitter/sdl-emitter.d.ts +7 -0
  151. package/dist/schema-generator/emitter/sdl-emitter.d.ts.map +1 -0
  152. package/dist/schema-generator/emitter/sdl-emitter.js +11 -0
  153. package/dist/schema-generator/emitter/sdl-emitter.js.map +1 -0
  154. package/dist/schema-generator/generate-schema.d.ts +26 -0
  155. package/dist/schema-generator/generate-schema.d.ts.map +1 -0
  156. package/dist/schema-generator/generate-schema.js +76 -0
  157. package/dist/schema-generator/generate-schema.js.map +1 -0
  158. package/dist/schema-generator/index.d.ts +4 -0
  159. package/dist/schema-generator/index.d.ts.map +1 -0
  160. package/dist/schema-generator/index.js +2 -0
  161. package/dist/schema-generator/index.js.map +1 -0
  162. package/dist/schema-generator/integrator/result-integrator.d.ts +93 -0
  163. package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -0
  164. package/dist/schema-generator/integrator/result-integrator.js +396 -0
  165. package/dist/schema-generator/integrator/result-integrator.js.map +1 -0
  166. package/dist/schema-generator/pruner/schema-pruner.d.ts +16 -0
  167. package/dist/schema-generator/pruner/schema-pruner.d.ts.map +1 -0
  168. package/dist/schema-generator/pruner/schema-pruner.js +66 -0
  169. package/dist/schema-generator/pruner/schema-pruner.js.map +1 -0
  170. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +24 -0
  171. package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -0
  172. package/dist/schema-generator/resolver-collector/resolver-collector.js +61 -0
  173. package/dist/schema-generator/resolver-collector/resolver-collector.js.map +1 -0
  174. package/dist/shared/constants.d.ts +70 -0
  175. package/dist/shared/constants.d.ts.map +1 -0
  176. package/dist/shared/constants.js +128 -0
  177. package/dist/shared/constants.js.map +1 -0
  178. package/dist/shared/default-value-detector.d.ts +40 -0
  179. package/dist/shared/default-value-detector.d.ts.map +1 -0
  180. package/dist/shared/default-value-detector.js +124 -0
  181. package/dist/shared/default-value-detector.js.map +1 -0
  182. package/dist/shared/diagnostics.d.ts +4 -0
  183. package/dist/shared/diagnostics.d.ts.map +1 -0
  184. package/dist/shared/diagnostics.js +25 -0
  185. package/dist/shared/diagnostics.js.map +1 -0
  186. package/dist/shared/directive-definition-extractor.d.ts +64 -0
  187. package/dist/shared/directive-definition-extractor.d.ts.map +1 -0
  188. package/dist/shared/directive-definition-extractor.js +399 -0
  189. package/dist/shared/directive-definition-extractor.js.map +1 -0
  190. package/dist/shared/directive-detector.d.ts +102 -0
  191. package/dist/shared/directive-detector.d.ts.map +1 -0
  192. package/dist/shared/directive-detector.js +422 -0
  193. package/dist/shared/directive-detector.js.map +1 -0
  194. package/dist/shared/file-scanner.d.ts +25 -0
  195. package/dist/shared/file-scanner.d.ts.map +1 -0
  196. package/dist/shared/file-scanner.js +99 -0
  197. package/dist/shared/file-scanner.js.map +1 -0
  198. package/dist/shared/file-scanner.test.d.ts +2 -0
  199. package/dist/shared/file-scanner.test.d.ts.map +1 -0
  200. package/dist/shared/file-scanner.test.js +138 -0
  201. package/dist/shared/file-scanner.test.js.map +1 -0
  202. package/dist/shared/index.d.ts +10 -0
  203. package/dist/shared/index.d.ts.map +1 -0
  204. package/dist/shared/index.js +8 -0
  205. package/dist/shared/index.js.map +1 -0
  206. package/dist/shared/inline-object-extractor.d.ts +13 -0
  207. package/dist/shared/inline-object-extractor.d.ts.map +1 -0
  208. package/dist/shared/inline-object-extractor.js +65 -0
  209. package/dist/shared/inline-object-extractor.js.map +1 -0
  210. package/dist/shared/inline-object-utils.d.ts +7 -0
  211. package/dist/shared/inline-object-utils.d.ts.map +1 -0
  212. package/dist/shared/inline-object-utils.js +23 -0
  213. package/dist/shared/inline-object-utils.js.map +1 -0
  214. package/dist/shared/interface-detector.d.ts +22 -0
  215. package/dist/shared/interface-detector.d.ts.map +1 -0
  216. package/dist/shared/interface-detector.js +90 -0
  217. package/dist/shared/interface-detector.js.map +1 -0
  218. package/dist/shared/interface-validator.d.ts +9 -0
  219. package/dist/shared/interface-validator.d.ts.map +1 -0
  220. package/dist/shared/interface-validator.js +152 -0
  221. package/dist/shared/interface-validator.js.map +1 -0
  222. package/dist/shared/interface-validator.test.d.ts +2 -0
  223. package/dist/shared/interface-validator.test.d.ts.map +1 -0
  224. package/dist/shared/interface-validator.test.js +145 -0
  225. package/dist/shared/interface-validator.test.js.map +1 -0
  226. package/dist/shared/metadata-detector.d.ts +65 -0
  227. package/dist/shared/metadata-detector.d.ts.map +1 -0
  228. package/dist/shared/metadata-detector.js +333 -0
  229. package/dist/shared/metadata-detector.js.map +1 -0
  230. package/dist/shared/program-factory.d.ts +14 -0
  231. package/dist/shared/program-factory.d.ts.map +1 -0
  232. package/dist/shared/program-factory.js +29 -0
  233. package/dist/shared/program-factory.js.map +1 -0
  234. package/dist/shared/source-location.d.ts +11 -0
  235. package/dist/shared/source-location.d.ts.map +1 -0
  236. package/dist/shared/source-location.js +15 -0
  237. package/dist/shared/source-location.js.map +1 -0
  238. package/dist/shared/tsconfig-loader.d.ts +13 -0
  239. package/dist/shared/tsconfig-loader.d.ts.map +1 -0
  240. package/dist/shared/tsconfig-loader.js +90 -0
  241. package/dist/shared/tsconfig-loader.js.map +1 -0
  242. package/dist/shared/tsdoc-parser.d.ts +12 -0
  243. package/dist/shared/tsdoc-parser.d.ts.map +1 -0
  244. package/dist/shared/tsdoc-parser.js +101 -0
  245. package/dist/shared/tsdoc-parser.js.map +1 -0
  246. package/dist/shared/type-converter.d.ts +3 -0
  247. package/dist/shared/type-converter.d.ts.map +1 -0
  248. package/dist/shared/type-converter.js +72 -0
  249. package/dist/shared/type-converter.js.map +1 -0
  250. package/dist/shared/typescript-utils.d.ts +55 -0
  251. package/dist/shared/typescript-utils.d.ts.map +1 -0
  252. package/dist/shared/typescript-utils.js +149 -0
  253. package/dist/shared/typescript-utils.js.map +1 -0
  254. package/dist/type-extractor/collector/result-collector.d.ts +7 -0
  255. package/dist/type-extractor/collector/result-collector.d.ts.map +1 -0
  256. package/dist/type-extractor/collector/result-collector.js +35 -0
  257. package/dist/type-extractor/collector/result-collector.js.map +1 -0
  258. package/dist/type-extractor/collector/scalar-collector.d.ts +108 -0
  259. package/dist/type-extractor/collector/scalar-collector.d.ts.map +1 -0
  260. package/dist/type-extractor/collector/scalar-collector.js +133 -0
  261. package/dist/type-extractor/collector/scalar-collector.js.map +1 -0
  262. package/dist/type-extractor/converter/field-eligibility.d.ts +34 -0
  263. package/dist/type-extractor/converter/field-eligibility.d.ts.map +1 -0
  264. package/dist/type-extractor/converter/field-eligibility.js +89 -0
  265. package/dist/type-extractor/converter/field-eligibility.js.map +1 -0
  266. package/dist/type-extractor/converter/graphql-converter.d.ts +7 -0
  267. package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -0
  268. package/dist/type-extractor/converter/graphql-converter.js +299 -0
  269. package/dist/type-extractor/converter/graphql-converter.js.map +1 -0
  270. package/dist/type-extractor/extract-types.d.ts +2 -0
  271. package/dist/type-extractor/extract-types.d.ts.map +1 -0
  272. package/dist/type-extractor/extract-types.js +2 -0
  273. package/dist/type-extractor/extract-types.js.map +1 -0
  274. package/dist/type-extractor/extractor/type-extractor.d.ts +27 -0
  275. package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -0
  276. package/dist/type-extractor/extractor/type-extractor.js +1116 -0
  277. package/dist/type-extractor/extractor/type-extractor.js.map +1 -0
  278. package/dist/type-extractor/index.d.ts +4 -0
  279. package/dist/type-extractor/index.d.ts.map +1 -0
  280. package/dist/type-extractor/index.js +2 -0
  281. package/dist/type-extractor/index.js.map +1 -0
  282. package/dist/type-extractor/types/diagnostics.d.ts +17 -0
  283. package/dist/type-extractor/types/diagnostics.d.ts.map +1 -0
  284. package/dist/type-extractor/types/diagnostics.js +2 -0
  285. package/dist/type-extractor/types/diagnostics.js.map +1 -0
  286. package/dist/type-extractor/types/graphql.d.ts +40 -0
  287. package/dist/type-extractor/types/graphql.d.ts.map +1 -0
  288. package/dist/type-extractor/types/graphql.js +2 -0
  289. package/dist/type-extractor/types/graphql.js.map +1 -0
  290. package/dist/type-extractor/types/index.d.ts +5 -0
  291. package/dist/type-extractor/types/index.d.ts.map +1 -0
  292. package/dist/type-extractor/types/index.js +2 -0
  293. package/dist/type-extractor/types/index.js.map +1 -0
  294. package/dist/type-extractor/types/typescript.d.ts +86 -0
  295. package/dist/type-extractor/types/typescript.d.ts.map +1 -0
  296. package/dist/type-extractor/types/typescript.js +2 -0
  297. package/dist/type-extractor/types/typescript.js.map +1 -0
  298. package/dist/type-extractor/types/typescript.test.d.ts +2 -0
  299. package/dist/type-extractor/types/typescript.test.d.ts.map +1 -0
  300. package/dist/type-extractor/types/typescript.test.js +287 -0
  301. package/dist/type-extractor/types/typescript.test.js.map +1 -0
  302. package/dist/type-extractor/validator/type-validator.d.ts +11 -0
  303. package/dist/type-extractor/validator/type-validator.d.ts.map +1 -0
  304. package/dist/type-extractor/validator/type-validator.js +53 -0
  305. package/dist/type-extractor/validator/type-validator.js.map +1 -0
  306. package/docs/configuration.md +163 -0
  307. package/docs/getting-started.md +117 -0
  308. package/docs/index.md +32 -0
  309. package/docs/integration/apollo.md +109 -0
  310. package/docs/integration/yoga.md +108 -0
  311. package/docs/schema/abstract-resolvers.md +146 -0
  312. package/docs/schema/directives.md +196 -0
  313. package/docs/schema/documentation.md +176 -0
  314. package/docs/schema/enums.md +162 -0
  315. package/docs/schema/fields.md +184 -0
  316. package/docs/schema/index.md +38 -0
  317. package/docs/schema/inputs.md +277 -0
  318. package/docs/schema/interfaces.md +178 -0
  319. package/docs/schema/objects.md +186 -0
  320. package/docs/schema/queries-mutations.md +205 -0
  321. package/docs/schema/scalars.md +194 -0
  322. package/docs/schema/unions.md +90 -0
  323. package/docs/what-is-gqlkit.md +22 -0
  324. package/package.json +59 -7
  325. package/README.md +0 -45
@@ -0,0 +1,1116 @@
1
+ import { resolve } from "node:path";
2
+ import ts from "typescript";
3
+ import { isInternalTypeSymbol } from "../../shared/constants.js";
4
+ import { detectDefaultValueMetadata } from "../../shared/default-value-detector.js";
5
+ import { detectDirectiveMetadata, hasDirectiveMetadata, unwrapDirectiveType, } from "../../shared/directive-detector.js";
6
+ import { extractInlineObjectProperties as extractInlineObjectPropertiesShared } from "../../shared/inline-object-extractor.js";
7
+ import { isInlineObjectType } from "../../shared/inline-object-utils.js";
8
+ import { extractImplementsFromDefineInterface, extractImplementsFromGqlTypeDef, isDefineInterfaceTypeAlias, } from "../../shared/interface-detector.js";
9
+ import { detectScalarMetadata } from "../../shared/metadata-detector.js";
10
+ import { getSourceLocationFromNode, } from "../../shared/source-location.js";
11
+ import { extractTsDocFromSymbol, extractTsDocInfo, } from "../../shared/tsdoc-parser.js";
12
+ import { extractPropertySymbols, getNonNullableTypes, hasUndefinedInType, isAnonymousObjectType, isExported, isNullableUnion, isNullOrUndefined, shouldTreatIntersectionAsInline, } from "../../shared/typescript-utils.js";
13
+ /**
14
+ * Finds the parent enum symbol if all types belong to the same enum.
15
+ * Returns null if types are empty, don't have a common parent enum, or belong to different enums.
16
+ */
17
+ function findEnumParentSymbol(types) {
18
+ if (types.length === 0)
19
+ return null;
20
+ const firstSymbol = types[0].symbol;
21
+ const parentSymbol = firstSymbol?.parent;
22
+ if (!parentSymbol || !(parentSymbol.flags & ts.SymbolFlags.Enum)) {
23
+ return null;
24
+ }
25
+ const allBelongToSameEnum = types.every((t) => {
26
+ const sym = t.symbol;
27
+ return sym?.parent === parentSymbol;
28
+ });
29
+ return allBelongToSameEnum ? parentSymbol : null;
30
+ }
31
+ function isDefaultExport(node, sourceFile) {
32
+ let hasDefaultExport = false;
33
+ const nodeName = node.name?.getText(sourceFile);
34
+ ts.forEachChild(sourceFile, (child) => {
35
+ if (ts.isExportAssignment(child) &&
36
+ !child.isExportEquals &&
37
+ ts.isIdentifier(child.expression)) {
38
+ if (child.expression.text === nodeName) {
39
+ hasDefaultExport = true;
40
+ }
41
+ }
42
+ });
43
+ return hasDefaultExport;
44
+ }
45
+ function isBooleanUnion(type) {
46
+ if (!type.isUnion())
47
+ return false;
48
+ const nonNullTypes = getNonNullableTypes(type);
49
+ return (nonNullTypes.length === 2 &&
50
+ nonNullTypes.every((t) => t.flags & ts.TypeFlags.BooleanLiteral));
51
+ }
52
+ /**
53
+ * Attempts to extract a type as an inline object, with cycle detection.
54
+ * Returns a reference type if a cycle is detected, otherwise returns an inline object.
55
+ */
56
+ function tryExtractAsInlineObject(type, checker, globalTypeMappings, visitedTypes) {
57
+ if (visitedTypes.has(type)) {
58
+ const typeName = type.symbol?.getName() ?? "Object";
59
+ return {
60
+ tsType: {
61
+ kind: "reference",
62
+ name: typeName === "__type" ? "Object" : typeName,
63
+ elementType: null,
64
+ members: null,
65
+ nullable: false,
66
+ scalarInfo: null,
67
+ inlineObjectProperties: null,
68
+ },
69
+ };
70
+ }
71
+ visitedTypes.add(type);
72
+ const inlineProperties = extractInlineObjectPropertiesShared(type, checker, (t, c) => convertTsTypeToReference(t, c, globalTypeMappings, visitedTypes).tsType);
73
+ return {
74
+ tsType: {
75
+ kind: "inlineObject",
76
+ name: null,
77
+ elementType: null,
78
+ members: null,
79
+ nullable: false,
80
+ scalarInfo: null,
81
+ inlineObjectProperties: inlineProperties,
82
+ },
83
+ };
84
+ }
85
+ function findGlobalTypeMapping(typeName, globalTypeMappings) {
86
+ return globalTypeMappings.find((m) => m.typeName === typeName);
87
+ }
88
+ function convertTsTypeToReference(type, checker, globalTypeMappings = [], visitedTypes = new WeakSet()) {
89
+ const metadataResult = detectScalarMetadata(type, checker);
90
+ // Skip scalar detection if it's an array of scalars (e.g., Int[])
91
+ // Array types should be handled by the array handling logic below
92
+ if (metadataResult.scalarName &&
93
+ !metadataResult.isPrimitive &&
94
+ !metadataResult.isList) {
95
+ return {
96
+ tsType: {
97
+ kind: "scalar",
98
+ name: metadataResult.scalarName,
99
+ elementType: null,
100
+ members: null,
101
+ nullable: metadataResult.nullable,
102
+ scalarInfo: {
103
+ scalarName: metadataResult.scalarName,
104
+ typeName: metadataResult.scalarName,
105
+ baseType: undefined,
106
+ isCustom: true,
107
+ only: metadataResult.only,
108
+ },
109
+ inlineObjectProperties: null,
110
+ },
111
+ };
112
+ }
113
+ if (isBooleanUnion(type)) {
114
+ const nullable = isNullableUnion(type);
115
+ return {
116
+ tsType: {
117
+ kind: "primitive",
118
+ name: "boolean",
119
+ elementType: null,
120
+ members: null,
121
+ nullable,
122
+ scalarInfo: null,
123
+ inlineObjectProperties: null,
124
+ },
125
+ };
126
+ }
127
+ if (type.isUnion()) {
128
+ const nullable = isNullableUnion(type);
129
+ // Preserve type alias name for enum types (string literal unions)
130
+ const aliasSymbol = type.aliasSymbol;
131
+ if (aliasSymbol) {
132
+ const name = aliasSymbol.getName();
133
+ return {
134
+ tsType: {
135
+ kind: "reference",
136
+ name,
137
+ elementType: null,
138
+ members: null,
139
+ nullable,
140
+ scalarInfo: null,
141
+ inlineObjectProperties: null,
142
+ },
143
+ };
144
+ }
145
+ const nonNullTypes = getNonNullableTypes(type);
146
+ // Check if all non-null types belong to the same enum (for numeric enums)
147
+ const enumParentSymbol = findEnumParentSymbol(nonNullTypes);
148
+ if (enumParentSymbol) {
149
+ return {
150
+ tsType: {
151
+ kind: "reference",
152
+ name: enumParentSymbol.getName(),
153
+ elementType: null,
154
+ members: null,
155
+ nullable,
156
+ scalarInfo: null,
157
+ inlineObjectProperties: null,
158
+ },
159
+ };
160
+ }
161
+ if (nonNullTypes.length === 1) {
162
+ const innerResult = convertTsTypeToReference(nonNullTypes[0], checker, globalTypeMappings, visitedTypes);
163
+ return {
164
+ tsType: { ...innerResult.tsType, nullable },
165
+ };
166
+ }
167
+ const memberResults = nonNullTypes.map((t) => convertTsTypeToReference(t, checker, globalTypeMappings, visitedTypes));
168
+ return {
169
+ tsType: {
170
+ kind: "union",
171
+ name: null,
172
+ elementType: null,
173
+ members: memberResults.map((r) => r.tsType),
174
+ nullable,
175
+ scalarInfo: null,
176
+ inlineObjectProperties: null,
177
+ },
178
+ };
179
+ }
180
+ if (checker.isArrayType(type)) {
181
+ const typeArgs = type.typeArguments;
182
+ const elementType = typeArgs?.[0];
183
+ const elementResult = elementType
184
+ ? convertTsTypeToReference(elementType, checker, globalTypeMappings, visitedTypes)
185
+ : {
186
+ tsType: {
187
+ kind: "primitive",
188
+ name: "unknown",
189
+ elementType: null,
190
+ members: null,
191
+ nullable: false,
192
+ scalarInfo: null,
193
+ inlineObjectProperties: null,
194
+ },
195
+ };
196
+ return {
197
+ tsType: {
198
+ kind: "array",
199
+ name: null,
200
+ elementType: elementResult.tsType,
201
+ members: null,
202
+ nullable: false,
203
+ scalarInfo: null,
204
+ inlineObjectProperties: null,
205
+ },
206
+ };
207
+ }
208
+ const typeString = checker.typeToString(type);
209
+ if (type.flags & ts.TypeFlags.String) {
210
+ return {
211
+ tsType: {
212
+ kind: "primitive",
213
+ name: "string",
214
+ elementType: null,
215
+ members: null,
216
+ nullable: false,
217
+ scalarInfo: null,
218
+ inlineObjectProperties: null,
219
+ },
220
+ };
221
+ }
222
+ if (type.flags & ts.TypeFlags.Number) {
223
+ return {
224
+ tsType: {
225
+ kind: "primitive",
226
+ name: "number",
227
+ elementType: null,
228
+ members: null,
229
+ nullable: false,
230
+ scalarInfo: null,
231
+ inlineObjectProperties: null,
232
+ },
233
+ };
234
+ }
235
+ if (type.flags & ts.TypeFlags.Boolean ||
236
+ type.flags & ts.TypeFlags.BooleanLiteral) {
237
+ return {
238
+ tsType: {
239
+ kind: "primitive",
240
+ name: "boolean",
241
+ elementType: null,
242
+ members: null,
243
+ nullable: false,
244
+ scalarInfo: null,
245
+ inlineObjectProperties: null,
246
+ },
247
+ };
248
+ }
249
+ if (type.flags & ts.TypeFlags.StringLiteral) {
250
+ return {
251
+ tsType: {
252
+ kind: "literal",
253
+ name: typeString.replace(/"/g, ""),
254
+ elementType: null,
255
+ members: null,
256
+ nullable: false,
257
+ scalarInfo: null,
258
+ inlineObjectProperties: null,
259
+ },
260
+ };
261
+ }
262
+ if (type.flags & ts.TypeFlags.NumberLiteral) {
263
+ return {
264
+ tsType: {
265
+ kind: "literal",
266
+ name: typeString,
267
+ elementType: null,
268
+ members: null,
269
+ nullable: false,
270
+ scalarInfo: null,
271
+ inlineObjectProperties: null,
272
+ },
273
+ };
274
+ }
275
+ // Handle intersection types that should be treated as inline objects
276
+ // This includes intersections with anonymous members OR intersections of
277
+ // named object types (interfaces) that are not exported as GraphQL types
278
+ if (type.isIntersection()) {
279
+ // If the intersection type has an alias symbol (e.g., Comment = GqlObject<...>),
280
+ // treat it as a named reference to avoid infinite recursion with self-referential types
281
+ if (type.aliasSymbol) {
282
+ const aliasName = type.aliasSymbol.getName();
283
+ return {
284
+ tsType: {
285
+ kind: "reference",
286
+ name: aliasName,
287
+ elementType: null,
288
+ members: null,
289
+ nullable: false,
290
+ scalarInfo: null,
291
+ inlineObjectProperties: null,
292
+ },
293
+ };
294
+ }
295
+ const shouldTreatAsInline = shouldTreatIntersectionAsInline(type);
296
+ if (shouldTreatAsInline) {
297
+ return tryExtractAsInlineObject(type, checker, globalTypeMappings, visitedTypes);
298
+ }
299
+ }
300
+ if (isInlineObjectType(type)) {
301
+ return tryExtractAsInlineObject(type, checker, globalTypeMappings, visitedTypes);
302
+ }
303
+ // Check for utility types (Omit, Pick, Partial, Required, etc.)
304
+ // These create mapped types that should be treated as inline objects
305
+ if (type.flags & ts.TypeFlags.Object) {
306
+ const objectType = type;
307
+ if (objectType.objectFlags & ts.ObjectFlags.Mapped) {
308
+ return tryExtractAsInlineObject(type, checker, globalTypeMappings, visitedTypes);
309
+ }
310
+ }
311
+ if (type.symbol) {
312
+ const symbolName = type.symbol.getName();
313
+ // Skip internal TypeScript symbols (see constants.ts for details)
314
+ if (!isInternalTypeSymbol(symbolName)) {
315
+ const globalMapping = findGlobalTypeMapping(symbolName, globalTypeMappings);
316
+ if (globalMapping) {
317
+ return {
318
+ tsType: {
319
+ kind: "scalar",
320
+ name: globalMapping.scalarName,
321
+ elementType: null,
322
+ members: null,
323
+ nullable: false,
324
+ scalarInfo: {
325
+ scalarName: globalMapping.scalarName,
326
+ typeName: globalMapping.typeName,
327
+ baseType: undefined,
328
+ isCustom: true,
329
+ only: globalMapping.only,
330
+ },
331
+ inlineObjectProperties: null,
332
+ },
333
+ };
334
+ }
335
+ return {
336
+ tsType: {
337
+ kind: "reference",
338
+ name: symbolName,
339
+ elementType: null,
340
+ members: null,
341
+ nullable: false,
342
+ scalarInfo: null,
343
+ inlineObjectProperties: null,
344
+ },
345
+ };
346
+ }
347
+ }
348
+ return {
349
+ tsType: {
350
+ kind: "reference",
351
+ name: typeString,
352
+ elementType: null,
353
+ members: null,
354
+ nullable: false,
355
+ scalarInfo: null,
356
+ inlineObjectProperties: null,
357
+ },
358
+ };
359
+ }
360
+ function extractFieldsFromType(type, checker, globalTypeMappings = []) {
361
+ const fields = [];
362
+ const diagnostics = [];
363
+ const properties = extractPropertySymbols(type, checker);
364
+ for (const prop of properties) {
365
+ const propName = prop.getName();
366
+ if (propName.startsWith(" $")) {
367
+ continue;
368
+ }
369
+ const propType = checker.getTypeOfSymbol(prop);
370
+ const declarations = prop.getDeclarations();
371
+ const declaration = declarations?.[0];
372
+ const optional = hasUndefinedInType(propType);
373
+ const tsdocInfo = extractTsDocFromSymbol(prop, checker);
374
+ let actualPropType = propType;
375
+ let directives = null;
376
+ let directiveNullable = false;
377
+ let defaultValue = null;
378
+ if (hasDirectiveMetadata(propType)) {
379
+ const directiveResult = detectDirectiveMetadata(propType, checker);
380
+ if (directiveResult.directives.length > 0) {
381
+ directives = directiveResult.directives;
382
+ }
383
+ // Detect default value from $gqlkitFieldMeta
384
+ const defaultValueResult = detectDefaultValueMetadata(propType, checker);
385
+ if (defaultValueResult.defaultValue) {
386
+ defaultValue = defaultValueResult.defaultValue;
387
+ }
388
+ if (defaultValueResult.errors.length > 0) {
389
+ for (const error of defaultValueResult.errors) {
390
+ diagnostics.push({
391
+ code: error.code,
392
+ message: `Field '${propName}': ${error.message}`,
393
+ severity: "warning",
394
+ location: getSourceLocationFromNode(declaration),
395
+ });
396
+ }
397
+ }
398
+ // Check if the original type is nullable before unwrapping
399
+ // TypeScript normalizes WithDirectives<T | null, [...]> to (T & Directive) | null
400
+ if (isNullableUnion(propType)) {
401
+ directiveNullable = true;
402
+ }
403
+ actualPropType = unwrapDirectiveType(propType, checker);
404
+ // Check if the unwrapped type (from $gqlkitOriginalType) is nullable
405
+ // This handles cases where TypeScript normalizes intersection types
406
+ // and loses the null from the outer union
407
+ if (!directiveNullable && isNullableUnion(actualPropType)) {
408
+ directiveNullable = true;
409
+ }
410
+ }
411
+ const typeResult = convertTsTypeToReference(actualPropType, checker, globalTypeMappings);
412
+ // Preserve nullability from original WithDirectives type
413
+ const tsType = directiveNullable && !typeResult.tsType.nullable
414
+ ? { ...typeResult.tsType, nullable: true }
415
+ : typeResult.tsType;
416
+ fields.push({
417
+ name: propName,
418
+ tsType,
419
+ optional,
420
+ description: tsdocInfo.description ?? null,
421
+ deprecated: tsdocInfo.deprecated ?? null,
422
+ directives,
423
+ defaultValue,
424
+ sourceLocation: getSourceLocationFromNode(declaration),
425
+ });
426
+ }
427
+ return { fields, diagnostics };
428
+ }
429
+ function isHeterogeneousEnum(node) {
430
+ if (!ts.isEnumDeclaration(node))
431
+ return false;
432
+ const members = node.members;
433
+ if (members.length <= 1)
434
+ return false;
435
+ let hasString = false;
436
+ let hasNumeric = false;
437
+ for (const member of members) {
438
+ const initializer = member.initializer;
439
+ if (initializer === undefined) {
440
+ hasNumeric = true;
441
+ }
442
+ else if (ts.isStringLiteral(initializer)) {
443
+ hasString = true;
444
+ }
445
+ else if (ts.isNumericLiteral(initializer) ||
446
+ ts.isPrefixUnaryExpression(initializer)) {
447
+ hasNumeric = true;
448
+ }
449
+ if (hasString && hasNumeric)
450
+ return true;
451
+ }
452
+ return false;
453
+ }
454
+ function isConstEnum(node) {
455
+ if (!ts.isEnumDeclaration(node))
456
+ return false;
457
+ const modifiers = ts.getCombinedModifierFlags(node);
458
+ return (modifiers & ts.ModifierFlags.Const) !== 0;
459
+ }
460
+ function isStringLiteralUnion(type) {
461
+ if (!type.isUnion())
462
+ return false;
463
+ const nonNullTypes = getNonNullableTypes(type);
464
+ if (nonNullTypes.length === 0)
465
+ return false;
466
+ return nonNullTypes.every((t) => t.flags & ts.TypeFlags.StringLiteral);
467
+ }
468
+ function getEnumMemberName(memberName) {
469
+ if (ts.isIdentifier(memberName) || ts.isStringLiteral(memberName)) {
470
+ return memberName.text;
471
+ }
472
+ return memberName.getText();
473
+ }
474
+ function extractEnumMembers(node, checker) {
475
+ const members = [];
476
+ for (const member of node.members) {
477
+ const name = getEnumMemberName(member.name);
478
+ const initializer = member.initializer;
479
+ const symbol = checker.getSymbolAtLocation(member.name);
480
+ const tsdocInfo = symbol
481
+ ? extractTsDocFromSymbol(symbol, checker)
482
+ : { description: undefined, deprecated: undefined };
483
+ if (initializer && ts.isStringLiteral(initializer)) {
484
+ members.push({
485
+ name,
486
+ value: initializer.text,
487
+ numericValue: null,
488
+ description: tsdocInfo.description ?? null,
489
+ deprecated: tsdocInfo.deprecated ?? null,
490
+ sourceLocation: getSourceLocationFromNode(member),
491
+ });
492
+ }
493
+ else {
494
+ const constantValue = checker.getConstantValue(member);
495
+ if (typeof constantValue === "number") {
496
+ members.push({
497
+ name,
498
+ value: name,
499
+ numericValue: constantValue,
500
+ description: tsdocInfo.description ?? null,
501
+ deprecated: tsdocInfo.deprecated ?? null,
502
+ sourceLocation: getSourceLocationFromNode(member),
503
+ });
504
+ }
505
+ }
506
+ }
507
+ return members;
508
+ }
509
+ const GRAPHQL_NAME_REGEX = /^[_A-Za-z][_0-9A-Za-z]*$/;
510
+ function isValidGraphQLName(name) {
511
+ return GRAPHQL_NAME_REGEX.test(name);
512
+ }
513
+ function validateNumericEnumMembers(members, enumName, enumLocation) {
514
+ const diagnostics = [];
515
+ const numericMembers = members.filter((m) => m.numericValue !== null);
516
+ if (numericMembers.length === 0) {
517
+ return diagnostics;
518
+ }
519
+ const valueToMembers = new Map();
520
+ for (const member of numericMembers) {
521
+ const value = member.numericValue;
522
+ const existing = valueToMembers.get(value) ?? [];
523
+ existing.push(member.name);
524
+ valueToMembers.set(value, existing);
525
+ }
526
+ for (const [value, memberNames] of valueToMembers) {
527
+ if (memberNames.length > 1) {
528
+ diagnostics.push({
529
+ code: "DUPLICATE_ENUM_VALUE",
530
+ message: `Enum '${enumName}' has duplicate numeric value ${value} (used by ${memberNames.join(" and ")})`,
531
+ severity: "error",
532
+ location: enumLocation,
533
+ });
534
+ }
535
+ }
536
+ for (const member of members) {
537
+ if (!isValidGraphQLName(member.name)) {
538
+ diagnostics.push({
539
+ code: "INVALID_ENUM_MEMBER_NAME",
540
+ message: `Enum member '${enumName}.${member.name}' is not a valid GraphQL identifier`,
541
+ severity: "error",
542
+ location: member.sourceLocation ?? enumLocation,
543
+ });
544
+ }
545
+ }
546
+ return diagnostics;
547
+ }
548
+ function extractStringLiteralUnionMembers(type, checker) {
549
+ if (!type.isUnion())
550
+ return [];
551
+ const members = [];
552
+ for (const t of type.types) {
553
+ if (isNullOrUndefined(t)) {
554
+ continue;
555
+ }
556
+ if (t.flags & ts.TypeFlags.StringLiteral) {
557
+ const value = checker.typeToString(t).replace(/^"|"$/g, "");
558
+ members.push({
559
+ name: value,
560
+ value: value,
561
+ numericValue: null,
562
+ description: null,
563
+ deprecated: null,
564
+ sourceLocation: null,
565
+ });
566
+ }
567
+ }
568
+ return members;
569
+ }
570
+ function determineTypeKind(node, type, sourceFile) {
571
+ if (ts.isInterfaceDeclaration(node)) {
572
+ return "interface";
573
+ }
574
+ if (ts.isTypeAliasDeclaration(node)) {
575
+ if (isDefineInterfaceTypeAlias(node, sourceFile)) {
576
+ return "graphqlInterface";
577
+ }
578
+ const unionKind = determineTypeKindFromUnion(type);
579
+ if (unionKind) {
580
+ return unionKind;
581
+ }
582
+ return "object";
583
+ }
584
+ return "object";
585
+ }
586
+ function determineTypeKindFromUnion(type) {
587
+ if (!type.isUnion()) {
588
+ return null;
589
+ }
590
+ const nonNullTypes = getNonNullableTypes(type);
591
+ if (isStringLiteralUnion(type)) {
592
+ return "enum";
593
+ }
594
+ const allObjectTypes = nonNullTypes.every((t) => (t.flags & ts.TypeFlags.Object) !== 0 ||
595
+ (t.flags & ts.TypeFlags.Intersection) !== 0 ||
596
+ t.symbol !== undefined);
597
+ if (nonNullTypes.length > 1 && allObjectTypes) {
598
+ return "union";
599
+ }
600
+ return null;
601
+ }
602
+ function determineTypeKindFromType(type, originalSymbol) {
603
+ const declarations = originalSymbol.getDeclarations();
604
+ const declaration = declarations?.[0];
605
+ if (declaration && ts.isInterfaceDeclaration(declaration)) {
606
+ return "interface";
607
+ }
608
+ if (declaration && ts.isEnumDeclaration(declaration)) {
609
+ return "enum";
610
+ }
611
+ const unionKind = determineTypeKindFromUnion(type);
612
+ if (unionKind) {
613
+ return unionKind;
614
+ }
615
+ return "object";
616
+ }
617
+ function isDeclarationInScannedFiles(declaration, scannedSourceFiles) {
618
+ const declSourceFileName = resolve(declaration.getSourceFile().fileName);
619
+ return Array.from(scannedSourceFiles).some((sf) => resolve(sf) === declSourceFileName);
620
+ }
621
+ function createGenericTypeDiagnostic(declaration, exportedName, location) {
622
+ if ((ts.isTypeAliasDeclaration(declaration) ||
623
+ ts.isInterfaceDeclaration(declaration)) &&
624
+ declaration.typeParameters &&
625
+ declaration.typeParameters.length > 0) {
626
+ return {
627
+ code: "UNSUPPORTED_SYNTAX",
628
+ message: `Generic type '${exportedName}' is not supported. Consider using a concrete type instead.`,
629
+ severity: "warning",
630
+ location,
631
+ };
632
+ }
633
+ return null;
634
+ }
635
+ function processReexportedSymbol(params) {
636
+ const { exportedName, resolvedSymbol, type, location, filePath, checker, globalTypeMappings, scannedSourceFiles, } = params;
637
+ const diagnostics = [];
638
+ const scalarMetadataResult = detectScalarMetadata(type, checker);
639
+ if (scalarMetadataResult.scalarName && !scalarMetadataResult.isPrimitive) {
640
+ const tsdocInfo = extractTsDocFromSymbol(resolvedSymbol, checker);
641
+ return {
642
+ typeInfo: null,
643
+ diagnostics: [],
644
+ scalarName: scalarMetadataResult.scalarName,
645
+ scalarMetadata: {
646
+ scalarName: scalarMetadataResult.scalarName,
647
+ typeName: exportedName,
648
+ only: scalarMetadataResult.only,
649
+ sourceFile: filePath,
650
+ line: location.line,
651
+ description: tsdocInfo.description ?? null,
652
+ },
653
+ skip: false,
654
+ };
655
+ }
656
+ const declarations = resolvedSymbol.getDeclarations();
657
+ const declaration = declarations?.[0];
658
+ if (declaration) {
659
+ if (isDeclarationInScannedFiles(declaration, scannedSourceFiles) &&
660
+ (ts.isTypeAliasDeclaration(declaration) ||
661
+ ts.isInterfaceDeclaration(declaration) ||
662
+ ts.isEnumDeclaration(declaration))) {
663
+ return {
664
+ typeInfo: null,
665
+ diagnostics: [],
666
+ scalarName: null,
667
+ scalarMetadata: null,
668
+ skip: true,
669
+ };
670
+ }
671
+ const genericDiagnostic = createGenericTypeDiagnostic(declaration, exportedName, location);
672
+ if (genericDiagnostic) {
673
+ diagnostics.push(genericDiagnostic);
674
+ }
675
+ }
676
+ const kind = determineTypeKindFromType(type, resolvedSymbol);
677
+ const tsdocInfo = extractTsDocFromSymbol(resolvedSymbol, checker);
678
+ const metadata = {
679
+ name: exportedName,
680
+ kind,
681
+ sourceFile: filePath,
682
+ sourceLocation: location,
683
+ exportKind: "named",
684
+ description: tsdocInfo.description ?? null,
685
+ deprecated: tsdocInfo.deprecated ?? null,
686
+ directives: null,
687
+ };
688
+ if (kind === "enum") {
689
+ const declarations = resolvedSymbol.getDeclarations();
690
+ const declaration = declarations?.[0];
691
+ let enumMembers;
692
+ if (declaration && ts.isEnumDeclaration(declaration)) {
693
+ enumMembers = extractEnumMembers(declaration, checker);
694
+ }
695
+ else {
696
+ enumMembers = extractStringLiteralUnionMembers(type, checker);
697
+ }
698
+ return {
699
+ typeInfo: {
700
+ metadata,
701
+ fields: [],
702
+ unionMembers: null,
703
+ inlineObjectMembers: null,
704
+ enumMembers,
705
+ implementedInterfaces: null,
706
+ },
707
+ diagnostics,
708
+ scalarName: null,
709
+ scalarMetadata: null,
710
+ skip: false,
711
+ };
712
+ }
713
+ const unionMembers = extractUnionMembers(type);
714
+ const fieldResult = kind === "union"
715
+ ? { fields: [], diagnostics: [] }
716
+ : extractFieldsFromType(type, checker, globalTypeMappings);
717
+ diagnostics.push(...fieldResult.diagnostics);
718
+ return {
719
+ typeInfo: {
720
+ metadata,
721
+ fields: fieldResult.fields,
722
+ unionMembers: unionMembers ?? null,
723
+ inlineObjectMembers: null,
724
+ enumMembers: null,
725
+ implementedInterfaces: null,
726
+ },
727
+ diagnostics,
728
+ scalarName: null,
729
+ scalarMetadata: null,
730
+ skip: false,
731
+ };
732
+ }
733
+ function processExportDeclaration(node, sourceFile, filePath, checker, globalTypeMappings, scannedSourceFiles) {
734
+ const types = [];
735
+ const diagnostics = [];
736
+ const detectedScalarNames = [];
737
+ const detectedScalars = [];
738
+ if (!node.isTypeOnly) {
739
+ return { types, diagnostics, detectedScalarNames, detectedScalars };
740
+ }
741
+ const exportClause = node.exportClause;
742
+ const symbolsToProcess = [];
743
+ if (exportClause && ts.isNamedExports(exportClause)) {
744
+ for (const specifier of exportClause.elements) {
745
+ const exportedName = specifier.name.text;
746
+ const localTargetSymbol = checker.getExportSpecifierLocalTargetSymbol(specifier);
747
+ if (!localTargetSymbol)
748
+ continue;
749
+ const originalSymbol = localTargetSymbol.flags & ts.SymbolFlags.Alias
750
+ ? checker.getAliasedSymbol(localTargetSymbol)
751
+ : localTargetSymbol;
752
+ if (!originalSymbol)
753
+ continue;
754
+ const type = checker.getDeclaredTypeOfSymbol(originalSymbol);
755
+ symbolsToProcess.push({
756
+ exportedName,
757
+ resolvedSymbol: originalSymbol,
758
+ type,
759
+ });
760
+ }
761
+ }
762
+ else if (!exportClause && node.moduleSpecifier) {
763
+ const moduleSymbol = checker.getSymbolAtLocation(node.moduleSpecifier);
764
+ if (!moduleSymbol) {
765
+ const location = getSourceLocationFromNode(node);
766
+ const modulePath = ts.isStringLiteral(node.moduleSpecifier)
767
+ ? node.moduleSpecifier.text
768
+ : node.moduleSpecifier.getText(sourceFile);
769
+ diagnostics.push({
770
+ code: "MODULE_RESOLUTION_ERROR",
771
+ message: `Could not resolve module '${modulePath}'`,
772
+ severity: "error",
773
+ location,
774
+ });
775
+ return { types, diagnostics, detectedScalarNames, detectedScalars };
776
+ }
777
+ const exports = checker.getExportsOfModule(moduleSymbol);
778
+ for (const exportedSymbol of exports) {
779
+ const resolvedSymbol = exportedSymbol.flags & ts.SymbolFlags.Alias
780
+ ? checker.getAliasedSymbol(exportedSymbol)
781
+ : exportedSymbol;
782
+ if (!(resolvedSymbol.flags & ts.SymbolFlags.TypeAlias ||
783
+ resolvedSymbol.flags & ts.SymbolFlags.Interface ||
784
+ resolvedSymbol.flags & ts.SymbolFlags.Enum)) {
785
+ continue;
786
+ }
787
+ const type = checker.getDeclaredTypeOfSymbol(resolvedSymbol);
788
+ symbolsToProcess.push({
789
+ exportedName: exportedSymbol.getName(),
790
+ resolvedSymbol,
791
+ type,
792
+ });
793
+ }
794
+ }
795
+ const location = getSourceLocationFromNode(node);
796
+ for (const { exportedName, resolvedSymbol, type } of symbolsToProcess) {
797
+ const result = processReexportedSymbol({
798
+ exportedName,
799
+ resolvedSymbol,
800
+ type,
801
+ location,
802
+ filePath,
803
+ checker,
804
+ globalTypeMappings,
805
+ scannedSourceFiles,
806
+ });
807
+ if (result.skip)
808
+ continue;
809
+ if (result.scalarName && result.scalarMetadata) {
810
+ detectedScalarNames.push(result.scalarName);
811
+ detectedScalars.push(result.scalarMetadata);
812
+ continue;
813
+ }
814
+ diagnostics.push(...result.diagnostics);
815
+ if (result.typeInfo) {
816
+ types.push(result.typeInfo);
817
+ }
818
+ }
819
+ return { types, diagnostics, detectedScalarNames, detectedScalars };
820
+ }
821
+ function getNamedTypeName(memberType) {
822
+ // For type aliases (e.g., GqlObject<...>), use aliasSymbol
823
+ if (memberType.aliasSymbol) {
824
+ return memberType.aliasSymbol.getName();
825
+ }
826
+ // For regular types, use symbol
827
+ return memberType.symbol?.getName() ?? "";
828
+ }
829
+ function extractInlineObjectMembers(type, checker, globalTypeMappings = []) {
830
+ if (!type.isUnion()) {
831
+ return null;
832
+ }
833
+ const nonNullTypes = getNonNullableTypes(type);
834
+ const allObjectTypes = nonNullTypes.every((t) => (t.flags & ts.TypeFlags.Object) !== 0 ||
835
+ (t.flags & ts.TypeFlags.Intersection) !== 0);
836
+ if (nonNullTypes.length < 2 || !allObjectTypes) {
837
+ return null;
838
+ }
839
+ let hasInlineObjects = false;
840
+ let hasNamedTypes = false;
841
+ const members = [];
842
+ for (const memberType of nonNullTypes) {
843
+ if (isAnonymousObjectType(memberType)) {
844
+ hasInlineObjects = true;
845
+ const properties = memberType.getProperties();
846
+ const memberProperties = [];
847
+ for (const prop of properties) {
848
+ const propType = checker.getTypeOfSymbol(prop);
849
+ const tsdocInfo = extractTsDocFromSymbol(prop, checker);
850
+ const typeResult = convertTsTypeToReference(propType, checker, globalTypeMappings);
851
+ memberProperties.push({
852
+ propertyName: prop.getName(),
853
+ propertyType: typeResult.tsType,
854
+ description: tsdocInfo.description ?? null,
855
+ deprecated: tsdocInfo.deprecated ?? null,
856
+ });
857
+ }
858
+ members.push({ properties: memberProperties });
859
+ }
860
+ else {
861
+ hasNamedTypes = true;
862
+ }
863
+ }
864
+ return { members, hasInlineObjects, hasNamedTypes };
865
+ }
866
+ function extractUnionMembers(type) {
867
+ if (!type.isUnion()) {
868
+ return undefined;
869
+ }
870
+ const nonNullTypes = getNonNullableTypes(type);
871
+ const allObjectTypes = nonNullTypes.every((t) => (t.flags & ts.TypeFlags.Object) !== 0 ||
872
+ (t.flags & ts.TypeFlags.Intersection) !== 0 ||
873
+ t.symbol !== undefined);
874
+ if (nonNullTypes.length > 1 && allObjectTypes) {
875
+ const namedMembers = nonNullTypes
876
+ .filter((t) => !isAnonymousObjectType(t))
877
+ .map((t) => getNamedTypeName(t))
878
+ .filter((name) => name !== "" && name !== "__type");
879
+ if (namedMembers.length > 0) {
880
+ return namedMembers.sort();
881
+ }
882
+ }
883
+ return undefined;
884
+ }
885
+ export function extractTypesFromProgram(program, sourceFiles, options = {}) {
886
+ const checker = program.getTypeChecker();
887
+ const types = [];
888
+ const diagnostics = [];
889
+ const detectedScalarNames = new Set();
890
+ const detectedScalars = [];
891
+ const globalTypeMappings = options.globalTypeMappings ?? [];
892
+ const scannedSourceFilesSet = new Set(sourceFiles);
893
+ for (const filePath of sourceFiles) {
894
+ const sourceFile = program.getSourceFile(filePath);
895
+ if (!sourceFile) {
896
+ diagnostics.push({
897
+ code: "PARSE_ERROR",
898
+ message: `Could not load source file: ${filePath}`,
899
+ severity: "error",
900
+ location: { file: filePath, line: 1, column: 1 },
901
+ });
902
+ continue;
903
+ }
904
+ ts.forEachChild(sourceFile, (node) => {
905
+ if (ts.isEnumDeclaration(node)) {
906
+ const hasExport = isExported(node);
907
+ const hasDefaultExport = isDefaultExport(node, sourceFile);
908
+ if (!hasExport && !hasDefaultExport) {
909
+ return;
910
+ }
911
+ const name = node.name.getText(sourceFile);
912
+ const location = getSourceLocationFromNode(node);
913
+ if (isConstEnum(node)) {
914
+ diagnostics.push({
915
+ code: "UNSUPPORTED_ENUM_TYPE",
916
+ message: `Const enum '${name}' is not supported. Use a regular enum instead.`,
917
+ severity: "error",
918
+ location,
919
+ });
920
+ return;
921
+ }
922
+ if (isHeterogeneousEnum(node)) {
923
+ diagnostics.push({
924
+ code: "UNSUPPORTED_ENUM_TYPE",
925
+ message: `Heterogeneous enum '${name}' is not supported. Use a string enum instead.`,
926
+ severity: "error",
927
+ location,
928
+ });
929
+ return;
930
+ }
931
+ const enumMembers = extractEnumMembers(node, checker);
932
+ const validationDiagnostics = validateNumericEnumMembers(enumMembers, name, location);
933
+ if (validationDiagnostics.length > 0) {
934
+ diagnostics.push(...validationDiagnostics);
935
+ return;
936
+ }
937
+ const tsdocInfo = extractTsDocInfo(node, checker);
938
+ const metadata = {
939
+ name,
940
+ kind: "enum",
941
+ sourceFile: filePath,
942
+ sourceLocation: location,
943
+ exportKind: hasDefaultExport ? "default" : "named",
944
+ description: tsdocInfo.description,
945
+ deprecated: tsdocInfo.deprecated,
946
+ directives: null,
947
+ };
948
+ types.push({
949
+ metadata,
950
+ fields: [],
951
+ unionMembers: null,
952
+ inlineObjectMembers: null,
953
+ enumMembers,
954
+ implementedInterfaces: null,
955
+ });
956
+ return;
957
+ }
958
+ if (ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) {
959
+ const hasExport = isExported(node);
960
+ const hasDefaultExport = isDefaultExport(node, sourceFile);
961
+ if (!hasExport && !hasDefaultExport) {
962
+ return;
963
+ }
964
+ const name = node.name.getText(sourceFile);
965
+ const typeSourceLocation = getSourceLocationFromNode(node);
966
+ if (node.typeParameters && node.typeParameters.length > 0) {
967
+ diagnostics.push({
968
+ code: "UNSUPPORTED_SYNTAX",
969
+ message: `Generic type '${name}' is not supported. Consider using a concrete type instead.`,
970
+ severity: "warning",
971
+ location: typeSourceLocation,
972
+ });
973
+ }
974
+ const symbol = checker.getSymbolAtLocation(node.name);
975
+ if (!symbol) {
976
+ return;
977
+ }
978
+ const type = checker.getDeclaredTypeOfSymbol(symbol);
979
+ const scalarMetadata = detectScalarMetadata(type, checker);
980
+ if (scalarMetadata.scalarName && !scalarMetadata.isPrimitive) {
981
+ detectedScalarNames.add(scalarMetadata.scalarName);
982
+ const tsdocInfo = extractTsDocInfo(node, checker);
983
+ detectedScalars.push({
984
+ scalarName: scalarMetadata.scalarName,
985
+ typeName: name,
986
+ only: scalarMetadata.only,
987
+ sourceFile: filePath,
988
+ line: typeSourceLocation.line,
989
+ description: tsdocInfo.description ?? null,
990
+ });
991
+ return;
992
+ }
993
+ let typeDirectives = null;
994
+ let actualType = type;
995
+ if (hasDirectiveMetadata(type)) {
996
+ const directiveResult = detectDirectiveMetadata(type, checker);
997
+ if (directiveResult.directives.length > 0) {
998
+ typeDirectives = directiveResult.directives;
999
+ }
1000
+ if (directiveResult.errors.length > 0) {
1001
+ for (const error of directiveResult.errors) {
1002
+ diagnostics.push({
1003
+ code: error.code,
1004
+ message: `Type '${name}': ${error.message}`,
1005
+ severity: "error",
1006
+ location: typeSourceLocation,
1007
+ });
1008
+ }
1009
+ }
1010
+ actualType = type;
1011
+ }
1012
+ const kind = determineTypeKind(node, actualType, sourceFile);
1013
+ const unionMembers = extractUnionMembers(actualType);
1014
+ const inlineObjectResult = extractInlineObjectMembers(actualType, checker, globalTypeMappings);
1015
+ const tsdocInfo = extractTsDocInfo(node, checker);
1016
+ let implementedInterfaces = null;
1017
+ if (ts.isTypeAliasDeclaration(node)) {
1018
+ if (kind === "graphqlInterface") {
1019
+ const interfaces = extractImplementsFromDefineInterface(node, sourceFile, checker);
1020
+ if (interfaces.length > 0) {
1021
+ implementedInterfaces = interfaces;
1022
+ }
1023
+ }
1024
+ else {
1025
+ const interfaces = extractImplementsFromGqlTypeDef(node, sourceFile, checker);
1026
+ if (interfaces.length > 0) {
1027
+ implementedInterfaces = interfaces;
1028
+ }
1029
+ }
1030
+ }
1031
+ const metadata = {
1032
+ name,
1033
+ kind,
1034
+ sourceFile: filePath,
1035
+ sourceLocation: typeSourceLocation,
1036
+ exportKind: hasDefaultExport ? "default" : "named",
1037
+ description: tsdocInfo.description,
1038
+ deprecated: tsdocInfo.deprecated,
1039
+ directives: typeDirectives,
1040
+ };
1041
+ if (kind === "enum") {
1042
+ const enumMembers = extractStringLiteralUnionMembers(actualType, checker);
1043
+ types.push({
1044
+ metadata,
1045
+ fields: [],
1046
+ unionMembers: null,
1047
+ inlineObjectMembers: null,
1048
+ enumMembers,
1049
+ implementedInterfaces: null,
1050
+ });
1051
+ return;
1052
+ }
1053
+ const fieldResult = kind === "union"
1054
+ ? { fields: [], diagnostics: [] }
1055
+ : extractFieldsFromType(actualType, checker, globalTypeMappings);
1056
+ const fields = fieldResult.fields;
1057
+ diagnostics.push(...fieldResult.diagnostics);
1058
+ if (name.endsWith("Input") && kind === "union") {
1059
+ if (inlineObjectResult?.hasInlineObjects &&
1060
+ inlineObjectResult.hasNamedTypes) {
1061
+ diagnostics.push({
1062
+ code: "ONEOF_MIXED_MEMBERS",
1063
+ message: `Input union type '${name}' mixes inline object literals with named type references. Use only inline object literals for oneOf input types.`,
1064
+ severity: "error",
1065
+ location: {
1066
+ ...typeSourceLocation,
1067
+ column: 1,
1068
+ },
1069
+ });
1070
+ }
1071
+ else if (inlineObjectResult?.hasNamedTypes &&
1072
+ !inlineObjectResult.hasInlineObjects) {
1073
+ diagnostics.push({
1074
+ code: "ONEOF_NAMED_TYPE_UNION",
1075
+ message: `Input union type '${name}' uses named type references instead of inline object literals. Use inline object pattern: type ${name} = { field1: Type1 } | { field2: Type2 }`,
1076
+ severity: "error",
1077
+ location: {
1078
+ ...typeSourceLocation,
1079
+ column: 1,
1080
+ },
1081
+ });
1082
+ }
1083
+ }
1084
+ const inlineObjectMembers = inlineObjectResult?.hasInlineObjects &&
1085
+ !inlineObjectResult.hasNamedTypes
1086
+ ? inlineObjectResult.members
1087
+ : null;
1088
+ const typeInfo = {
1089
+ metadata,
1090
+ fields,
1091
+ unionMembers: unionMembers ?? null,
1092
+ inlineObjectMembers,
1093
+ enumMembers: null,
1094
+ implementedInterfaces,
1095
+ };
1096
+ types.push(typeInfo);
1097
+ }
1098
+ if (ts.isExportDeclaration(node)) {
1099
+ const result = processExportDeclaration(node, sourceFile, filePath, checker, globalTypeMappings, scannedSourceFilesSet);
1100
+ types.push(...result.types);
1101
+ diagnostics.push(...result.diagnostics);
1102
+ for (const scalarName of result.detectedScalarNames) {
1103
+ detectedScalarNames.add(scalarName);
1104
+ }
1105
+ detectedScalars.push(...result.detectedScalars);
1106
+ }
1107
+ });
1108
+ }
1109
+ return {
1110
+ types,
1111
+ diagnostics,
1112
+ detectedScalarNames: [...detectedScalarNames],
1113
+ detectedScalars,
1114
+ };
1115
+ }
1116
+ //# sourceMappingURL=type-extractor.js.map