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