polen 0.10.0-next.10 → 0.10.0-next.12

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 (328) hide show
  1. package/build/api/builder/builder.js +1 -1
  2. package/build/api/builder/builder.js.map +1 -1
  3. package/build/api/config/load.js +1 -1
  4. package/build/api/config/load.js.map +1 -1
  5. package/build/api/vite/plugins/build.js +1 -1
  6. package/build/api/vite/plugins/build.js.map +1 -1
  7. package/build/api/vite/plugins/core.d.ts.map +1 -1
  8. package/build/api/vite/plugins/core.js +0 -2
  9. package/build/api/vite/plugins/core.js.map +1 -1
  10. package/build/api/vite/plugins/pages.js +1 -1
  11. package/build/api/vite/plugins/pages.js.map +1 -1
  12. package/build/exports/components.d.ts +4 -1
  13. package/build/exports/components.d.ts.map +1 -1
  14. package/build/exports/components.js +4 -1
  15. package/build/exports/components.js.map +1 -1
  16. package/build/lib/demos/config-schema.d.ts +6 -6
  17. package/build/lib/github-actions/runner.js +2 -2
  18. package/build/lib/github-actions/runner.js.map +1 -1
  19. package/build/lib/graphql-document/$$.d.ts +5 -0
  20. package/build/lib/graphql-document/$$.d.ts.map +1 -0
  21. package/build/lib/graphql-document/$$.js +5 -0
  22. package/build/lib/graphql-document/$$.js.map +1 -0
  23. package/build/lib/graphql-document/$.d.ts +2 -0
  24. package/build/lib/graphql-document/$.d.ts.map +1 -0
  25. package/build/lib/graphql-document/$.js +2 -0
  26. package/build/lib/graphql-document/$.js.map +1 -0
  27. package/build/lib/graphql-document/analysis.d.ts +44 -0
  28. package/build/lib/graphql-document/analysis.d.ts.map +1 -0
  29. package/build/lib/graphql-document/analysis.js +361 -0
  30. package/build/lib/graphql-document/analysis.js.map +1 -0
  31. package/build/lib/graphql-document/components/GraphQLDocument.d.ts +42 -0
  32. package/build/lib/graphql-document/components/GraphQLDocument.d.ts.map +1 -0
  33. package/build/lib/graphql-document/components/GraphQLDocument.js +173 -0
  34. package/build/lib/graphql-document/components/GraphQLDocument.js.map +1 -0
  35. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.d.ts +7 -0
  36. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.d.ts.map +1 -0
  37. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.js +45 -0
  38. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.js.map +1 -0
  39. package/build/lib/graphql-document/components/HoverTooltip.d.ts +35 -0
  40. package/build/lib/graphql-document/components/HoverTooltip.d.ts.map +1 -0
  41. package/build/lib/graphql-document/components/HoverTooltip.js +132 -0
  42. package/build/lib/graphql-document/components/HoverTooltip.js.map +1 -0
  43. package/build/lib/graphql-document/components/IdentifierLink.d.ts +37 -0
  44. package/build/lib/graphql-document/components/IdentifierLink.d.ts.map +1 -0
  45. package/build/lib/graphql-document/components/IdentifierLink.js +141 -0
  46. package/build/lib/graphql-document/components/IdentifierLink.js.map +1 -0
  47. package/build/lib/graphql-document/components/index.d.ts +5 -0
  48. package/build/lib/graphql-document/components/index.d.ts.map +1 -0
  49. package/build/lib/graphql-document/components/index.js +5 -0
  50. package/build/lib/graphql-document/components/index.js.map +1 -0
  51. package/build/lib/graphql-document/example.d.ts +25 -0
  52. package/build/lib/graphql-document/example.d.ts.map +1 -0
  53. package/build/lib/graphql-document/example.js +140 -0
  54. package/build/lib/graphql-document/example.js.map +1 -0
  55. package/build/lib/graphql-document/graphql-document.d.ts +35 -0
  56. package/build/lib/graphql-document/graphql-document.d.ts.map +1 -0
  57. package/build/lib/graphql-document/graphql-document.js +36 -0
  58. package/build/lib/graphql-document/graphql-document.js.map +1 -0
  59. package/build/lib/graphql-document/positioning-simple.d.ts +68 -0
  60. package/build/lib/graphql-document/positioning-simple.d.ts.map +1 -0
  61. package/build/lib/graphql-document/positioning-simple.js +197 -0
  62. package/build/lib/graphql-document/positioning-simple.js.map +1 -0
  63. package/build/lib/graphql-document/schema-context.d.ts +8 -0
  64. package/build/lib/graphql-document/schema-context.d.ts.map +1 -0
  65. package/build/lib/graphql-document/schema-context.js +11 -0
  66. package/build/lib/graphql-document/schema-context.js.map +1 -0
  67. package/build/lib/graphql-document/schema-integration-example.d.ts +27 -0
  68. package/build/lib/graphql-document/schema-integration-example.d.ts.map +1 -0
  69. package/build/lib/graphql-document/schema-integration-example.js +297 -0
  70. package/build/lib/graphql-document/schema-integration-example.js.map +1 -0
  71. package/build/lib/graphql-document/schema-integration.d.ts +135 -0
  72. package/build/lib/graphql-document/schema-integration.d.ts.map +1 -0
  73. package/build/lib/graphql-document/schema-integration.js +328 -0
  74. package/build/lib/graphql-document/schema-integration.js.map +1 -0
  75. package/build/lib/graphql-document/types.d.ts +117 -0
  76. package/build/lib/graphql-document/types.d.ts.map +1 -0
  77. package/build/lib/graphql-document/types.js +2 -0
  78. package/build/lib/graphql-document/types.js.map +1 -0
  79. package/build/template/components/ArgumentAnnotation.js +10 -0
  80. package/build/template/components/ArgumentAnnotation.js.map +1 -0
  81. package/build/template/components/ArgumentList.js +9 -0
  82. package/build/template/components/ArgumentList.js.map +1 -0
  83. package/build/template/components/ArgumentListAnnotation.js +15 -0
  84. package/build/template/components/ArgumentListAnnotation.js.map +1 -0
  85. package/build/template/components/Changelog.js +44 -0
  86. package/build/template/components/Changelog.js.map +1 -0
  87. package/build/template/components/{CodeBlock.jsx → CodeBlock.js} +4 -5
  88. package/build/template/components/{CodeBlock.jsx.map → CodeBlock.js.map} +1 -1
  89. package/build/template/components/CodeBlockEnhancer.d.ts +2 -0
  90. package/build/template/components/CodeBlockEnhancer.d.ts.map +1 -0
  91. package/build/template/components/CodeBlockEnhancer.js +175 -0
  92. package/build/template/components/CodeBlockEnhancer.js.map +1 -0
  93. package/build/template/components/DeprecationReason.js +9 -0
  94. package/build/template/components/DeprecationReason.js.map +1 -0
  95. package/build/template/components/Description.js +9 -0
  96. package/build/template/components/Description.js.map +1 -0
  97. package/build/template/components/Field.js +14 -0
  98. package/build/template/components/Field.js.map +1 -0
  99. package/build/template/components/{FieldList.jsx → FieldList.js} +4 -5
  100. package/build/template/components/FieldList.js.map +1 -0
  101. package/build/template/components/{FieldListSection.jsx → FieldListSection.js} +4 -6
  102. package/build/template/components/FieldListSection.js.map +1 -0
  103. package/build/template/components/HamburgerMenu.js +30 -0
  104. package/build/template/components/HamburgerMenu.js.map +1 -0
  105. package/build/template/components/Link.d.ts +1 -1
  106. package/build/template/components/{Link.jsx → Link.js} +4 -5
  107. package/build/template/components/Link.js.map +1 -0
  108. package/build/template/components/Logo.js +20 -0
  109. package/build/template/components/Logo.js.map +1 -0
  110. package/build/template/components/MDXComponents.d.ts +11 -0
  111. package/build/template/components/MDXComponents.d.ts.map +1 -0
  112. package/build/template/components/MDXComponents.js +70 -0
  113. package/build/template/components/MDXComponents.js.map +1 -0
  114. package/build/template/components/{Markdown.jsx → Markdown.js} +3 -2
  115. package/build/template/components/Markdown.js.map +1 -0
  116. package/build/template/components/MissingSchema.d.ts +1 -1
  117. package/build/template/components/MissingSchema.d.ts.map +1 -1
  118. package/build/template/components/MissingSchema.js +5 -0
  119. package/build/template/components/MissingSchema.js.map +1 -0
  120. package/build/template/components/NamedType.js +12 -0
  121. package/build/template/components/NamedType.js.map +1 -0
  122. package/build/template/components/NotFound.js +7 -0
  123. package/build/template/components/NotFound.js.map +1 -0
  124. package/build/template/components/{RadixLink.jsx → RadixLink.js} +1 -1
  125. package/build/template/components/RadixLink.js.map +1 -0
  126. package/build/template/components/TestComponent.d.ts +5 -0
  127. package/build/template/components/TestComponent.d.ts.map +1 -0
  128. package/build/template/components/TestComponent.js +7 -0
  129. package/build/template/components/TestComponent.js.map +1 -0
  130. package/build/template/components/Texts/{MinorHeading.jsx → MinorHeading.js} +4 -3
  131. package/build/template/components/Texts/MinorHeading.js.map +1 -0
  132. package/build/template/components/Texts/texts.js +1 -1
  133. package/build/template/components/Texts/texts.js.map +1 -1
  134. package/build/template/components/ThemeToggle.js +9 -0
  135. package/build/template/components/ThemeToggle.js.map +1 -0
  136. package/build/template/components/{TypeAnnotation.jsx → TypeAnnotation.js} +8 -18
  137. package/build/template/components/TypeAnnotation.js.map +1 -0
  138. package/build/template/components/TypeFieldsLinkList.js +9 -0
  139. package/build/template/components/TypeFieldsLinkList.js.map +1 -0
  140. package/build/template/components/TypeIndex.js +17 -0
  141. package/build/template/components/TypeIndex.js.map +1 -0
  142. package/build/template/components/content/$$.d.ts +1 -0
  143. package/build/template/components/content/$$.d.ts.map +1 -1
  144. package/build/template/components/content/$$.js +1 -0
  145. package/build/template/components/content/$$.js.map +1 -1
  146. package/build/template/components/content/GraphQLDocumentWithSchema.d.ts +8 -0
  147. package/build/template/components/content/GraphQLDocumentWithSchema.d.ts.map +1 -0
  148. package/build/template/components/content/GraphQLDocumentWithSchema.js +16 -0
  149. package/build/template/components/content/GraphQLDocumentWithSchema.js.map +1 -0
  150. package/build/template/components/content/GraphQLDocumentWrapper.d.ts +7 -0
  151. package/build/template/components/content/GraphQLDocumentWrapper.d.ts.map +1 -0
  152. package/build/template/components/content/GraphQLDocumentWrapper.js +62 -0
  153. package/build/template/components/content/GraphQLDocumentWrapper.js.map +1 -0
  154. package/build/template/components/graphql/graphql.d.ts +2 -2
  155. package/build/template/components/graphql/graphql.js +3 -0
  156. package/build/template/components/graphql/graphql.js.map +1 -0
  157. package/build/template/components/graphql/index.d.ts +1 -1
  158. package/build/template/components/graphql/index.js +1 -1
  159. package/build/template/components/graphql/index.js.map +1 -1
  160. package/build/template/components/graphql/{type-kind-icon.jsx → type-kind-icon.js} +3 -2
  161. package/build/template/components/graphql/type-kind-icon.js.map +1 -0
  162. package/build/template/components/graphql/type-link.js +11 -0
  163. package/build/template/components/graphql/type-link.js.map +1 -0
  164. package/build/template/components/sidebar/Sidebar.d.ts +1 -1
  165. package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
  166. package/build/template/components/sidebar/Sidebar.js +11 -0
  167. package/build/template/components/sidebar/Sidebar.js.map +1 -0
  168. package/build/template/components/sidebar/{SidebarItem.jsx → SidebarItem.js} +15 -32
  169. package/build/template/components/sidebar/SidebarItem.js.map +1 -0
  170. package/build/template/components/sidebar/ToggleButton.d.ts +1 -1
  171. package/build/template/components/sidebar/ToggleButton.d.ts.map +1 -1
  172. package/build/template/components/sidebar/ToggleButton.js +5 -0
  173. package/build/template/components/sidebar/ToggleButton.js.map +1 -0
  174. package/build/template/contexts/{ThemeContext.jsx → ThemeContext.js} +3 -4
  175. package/build/template/contexts/{ThemeContext.jsx.map → ThemeContext.js.map} +1 -1
  176. package/build/template/entry.client.d.ts +1 -0
  177. package/build/template/entry.client.d.ts.map +1 -1
  178. package/build/template/{entry.client.jsx → entry.client.js} +5 -6
  179. package/build/template/entry.client.js.map +1 -0
  180. package/build/template/routes/changelog.d.ts +1 -1
  181. package/build/template/routes/{changelog.jsx → changelog.js} +5 -4
  182. package/build/template/routes/changelog.js.map +1 -0
  183. package/build/template/routes/{index.jsx → index.js} +3 -2
  184. package/build/template/routes/index.js.map +1 -0
  185. package/build/template/routes/reference.$type.$field.d.ts +1 -1
  186. package/build/template/routes/{reference.$type.$field.jsx → reference.$type.$field.js} +6 -5
  187. package/build/template/routes/reference.$type.$field.js.map +1 -0
  188. package/build/template/routes/reference.$type.d.ts +1 -1
  189. package/build/template/routes/{reference.$type.jsx → reference.$type.js} +6 -5
  190. package/build/template/routes/reference.$type.js.map +1 -0
  191. package/build/template/routes/reference.d.ts +2 -2
  192. package/build/template/routes/reference.d.ts.map +1 -1
  193. package/build/template/routes/{reference.jsx → reference.js} +7 -12
  194. package/build/template/routes/reference.js.map +1 -0
  195. package/build/template/routes/root.d.ts +2 -2
  196. package/build/template/routes/root.d.ts.map +1 -1
  197. package/build/template/routes/root.js +286 -0
  198. package/build/template/routes/root.js.map +1 -0
  199. package/build/template/routes.js +5 -0
  200. package/build/template/routes.js.map +1 -0
  201. package/build/template/server/app.js +1 -1
  202. package/build/template/server/app.js.map +1 -1
  203. package/build/template/server/{render-page.jsx → render-page.js} +3 -4
  204. package/build/template/server/render-page.js.map +1 -0
  205. package/build/template/server/ssg/generate.js +1 -1
  206. package/build/template/server/ssg/generate.js.map +1 -1
  207. package/build/template/server/ssg/get-route-paths.js +1 -1
  208. package/build/template/server/ssg/get-route-paths.js.map +1 -1
  209. package/build/template/server/view.js +1 -1
  210. package/build/template/server/view.js.map +1 -1
  211. package/package.json +56 -8
  212. package/src/api/vite/plugins/core.ts +0 -3
  213. package/src/api/vite/plugins/pages.ts +1 -1
  214. package/src/exports/components.ts +4 -1
  215. package/src/lib/graphql-document/$$.ts +4 -0
  216. package/src/lib/graphql-document/$.test.ts +132 -0
  217. package/src/lib/graphql-document/$.ts +1 -0
  218. package/src/lib/graphql-document/README.md +102 -0
  219. package/src/lib/graphql-document/analysis.ts +415 -0
  220. package/src/lib/graphql-document/components/GraphQLDocument.tsx +284 -0
  221. package/src/lib/graphql-document/components/GraphQLDocument.unit.test.ts +188 -0
  222. package/src/lib/graphql-document/components/GraphQLDocumentWithSchema.tsx +70 -0
  223. package/src/lib/graphql-document/components/HoverTooltip.tsx +282 -0
  224. package/src/lib/graphql-document/components/IdentifierLink.tsx +221 -0
  225. package/src/lib/graphql-document/components/index.ts +4 -0
  226. package/src/lib/graphql-document/demo.md +155 -0
  227. package/src/lib/graphql-document/example.ts +163 -0
  228. package/src/lib/graphql-document/graphql-document.ts +37 -0
  229. package/src/lib/graphql-document/positioning-simple.test.ts +252 -0
  230. package/src/lib/graphql-document/positioning-simple.ts +271 -0
  231. package/src/lib/graphql-document/schema-context.tsx +20 -0
  232. package/src/lib/graphql-document/schema-integration-example.ts +341 -0
  233. package/src/lib/graphql-document/schema-integration.test.ts +365 -0
  234. package/src/lib/graphql-document/schema-integration.ts +497 -0
  235. package/src/lib/graphql-document/types.ts +129 -0
  236. package/src/template/components/ArgumentAnnotation.tsx +1 -1
  237. package/src/template/components/ArgumentList.tsx +1 -1
  238. package/src/template/components/ArgumentListAnnotation.tsx +2 -2
  239. package/src/template/components/CodeBlockEnhancer.tsx +192 -0
  240. package/src/template/components/DeprecationReason.tsx +1 -1
  241. package/src/template/components/Description.tsx +1 -1
  242. package/src/template/components/Field.tsx +4 -4
  243. package/src/template/components/FieldList.tsx +1 -1
  244. package/src/template/components/FieldListSection.tsx +1 -1
  245. package/src/template/components/Link.tsx +2 -2
  246. package/src/template/components/MDXComponents.tsx +101 -0
  247. package/src/template/components/NamedType.tsx +2 -2
  248. package/src/template/components/TestComponent.tsx +6 -0
  249. package/src/template/components/TypeAnnotation.tsx +1 -1
  250. package/src/template/components/TypeFieldsLinkList.tsx +1 -1
  251. package/src/template/components/TypeIndex.tsx +1 -1
  252. package/src/template/components/content/$$.ts +1 -0
  253. package/src/template/components/content/GraphQLDocumentWithSchema.tsx +18 -0
  254. package/src/template/components/content/GraphQLDocumentWrapper.tsx +82 -0
  255. package/src/template/components/graphql/graphql.tsx +2 -2
  256. package/src/template/components/graphql/index.ts +1 -1
  257. package/src/template/components/graphql/type-link.tsx +2 -2
  258. package/src/template/components/sidebar/SidebarItem.tsx +4 -4
  259. package/src/template/entry.client.tsx +2 -2
  260. package/src/template/routes/changelog.tsx +1 -1
  261. package/src/template/routes/reference.$type.$field.tsx +3 -3
  262. package/src/template/routes/reference.$type.tsx +3 -3
  263. package/src/template/routes/reference.tsx +6 -10
  264. package/src/template/routes/root.tsx +145 -5
  265. package/src/template/routes.tsx +1 -1
  266. package/src/template/server/app.ts +1 -1
  267. package/src/template/server/ssg/generate.ts +1 -1
  268. package/src/template/server/ssg/get-route-paths.ts +1 -1
  269. package/src/template/server/view.ts +1 -1
  270. package/src/template/styles/code-block.css +32 -0
  271. package/build/template/components/ArgumentAnnotation.jsx +0 -16
  272. package/build/template/components/ArgumentAnnotation.jsx.map +0 -1
  273. package/build/template/components/ArgumentList.jsx +0 -16
  274. package/build/template/components/ArgumentList.jsx.map +0 -1
  275. package/build/template/components/ArgumentListAnnotation.jsx +0 -23
  276. package/build/template/components/ArgumentListAnnotation.jsx.map +0 -1
  277. package/build/template/components/Changelog.jsx +0 -68
  278. package/build/template/components/Changelog.jsx.map +0 -1
  279. package/build/template/components/DeprecationReason.jsx +0 -10
  280. package/build/template/components/DeprecationReason.jsx.map +0 -1
  281. package/build/template/components/Description.jsx +0 -10
  282. package/build/template/components/Description.jsx.map +0 -1
  283. package/build/template/components/Field.jsx +0 -22
  284. package/build/template/components/Field.jsx.map +0 -1
  285. package/build/template/components/FieldList.jsx.map +0 -1
  286. package/build/template/components/FieldListSection.jsx.map +0 -1
  287. package/build/template/components/HamburgerMenu.jsx +0 -53
  288. package/build/template/components/HamburgerMenu.jsx.map +0 -1
  289. package/build/template/components/Link.jsx.map +0 -1
  290. package/build/template/components/Logo.jsx +0 -29
  291. package/build/template/components/Logo.jsx.map +0 -1
  292. package/build/template/components/Markdown.jsx.map +0 -1
  293. package/build/template/components/MissingSchema.jsx +0 -4
  294. package/build/template/components/MissingSchema.jsx.map +0 -1
  295. package/build/template/components/NamedType.jsx +0 -17
  296. package/build/template/components/NamedType.jsx.map +0 -1
  297. package/build/template/components/NotFound.jsx +0 -26
  298. package/build/template/components/NotFound.jsx.map +0 -1
  299. package/build/template/components/RadixLink.jsx.map +0 -1
  300. package/build/template/components/Texts/MinorHeading.jsx.map +0 -1
  301. package/build/template/components/ThemeToggle.jsx +0 -10
  302. package/build/template/components/ThemeToggle.jsx.map +0 -1
  303. package/build/template/components/TypeAnnotation.jsx.map +0 -1
  304. package/build/template/components/TypeFieldsLinkList.jsx +0 -17
  305. package/build/template/components/TypeFieldsLinkList.jsx.map +0 -1
  306. package/build/template/components/TypeIndex.jsx +0 -27
  307. package/build/template/components/TypeIndex.jsx.map +0 -1
  308. package/build/template/components/graphql/graphql.jsx +0 -3
  309. package/build/template/components/graphql/graphql.jsx.map +0 -1
  310. package/build/template/components/graphql/type-kind-icon.jsx.map +0 -1
  311. package/build/template/components/graphql/type-link.jsx +0 -16
  312. package/build/template/components/graphql/type-link.jsx.map +0 -1
  313. package/build/template/components/sidebar/Sidebar.jsx +0 -15
  314. package/build/template/components/sidebar/Sidebar.jsx.map +0 -1
  315. package/build/template/components/sidebar/SidebarItem.jsx.map +0 -1
  316. package/build/template/components/sidebar/ToggleButton.jsx +0 -6
  317. package/build/template/components/sidebar/ToggleButton.jsx.map +0 -1
  318. package/build/template/entry.client.jsx.map +0 -1
  319. package/build/template/routes/changelog.jsx.map +0 -1
  320. package/build/template/routes/index.jsx.map +0 -1
  321. package/build/template/routes/reference.$type.$field.jsx.map +0 -1
  322. package/build/template/routes/reference.$type.jsx.map +0 -1
  323. package/build/template/routes/reference.jsx.map +0 -1
  324. package/build/template/routes/root.jsx +0 -204
  325. package/build/template/routes/root.jsx.map +0 -1
  326. package/build/template/routes.jsx +0 -5
  327. package/build/template/routes.jsx.map +0 -1
  328. package/build/template/server/render-page.jsx.map +0 -1
@@ -0,0 +1,415 @@
1
+ import {
2
+ type ArgumentNode,
3
+ type ASTNode,
4
+ type DirectiveNode,
5
+ type DocumentNode,
6
+ type FieldNode,
7
+ type FragmentDefinitionNode,
8
+ type GraphQLError,
9
+ type GraphQLSchema,
10
+ type OperationDefinitionNode,
11
+ parse,
12
+ validate,
13
+ type VariableDefinitionNode,
14
+ visit,
15
+ } from 'graphql'
16
+ import type {
17
+ AnalysisConfig,
18
+ AnalysisError,
19
+ AnalysisResult,
20
+ GraphQLAnalyzer,
21
+ Identifier,
22
+ IdentifierContext,
23
+ IdentifierMap,
24
+ } from './types.ts'
25
+
26
+ /**
27
+ * Default GraphQL document analyzer implementation
28
+ */
29
+ export class DefaultGraphQLAnalyzer implements GraphQLAnalyzer {
30
+ /**
31
+ * Parse a GraphQL document string into an AST
32
+ */
33
+ parse(source: string): DocumentNode {
34
+ try {
35
+ return parse(source, {
36
+ noLocation: false, // We need location info for positioning
37
+ })
38
+ } catch (error) {
39
+ throw new Error(`Failed to parse GraphQL document: ${error instanceof Error ? error.message : 'Unknown error'}`)
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Validate a GraphQL document against a schema
45
+ */
46
+ validateAgainstSchema(ast: DocumentNode, schema: GraphQLSchema): GraphQLError[] {
47
+ return [...validate(schema, ast)]
48
+ }
49
+
50
+ /**
51
+ * Extract all identifiers from a GraphQL AST
52
+ */
53
+ extractIdentifiers(ast: DocumentNode, config: AnalysisConfig = {}): IdentifierMap {
54
+ const identifiers: Identifier[] = []
55
+ const errors: AnalysisError[] = []
56
+ const schema = config.schema
57
+
58
+ // Context tracking during traversal
59
+ let currentOperationType: 'query' | 'mutation' | 'subscription' | undefined
60
+ let currentOperationName: string | undefined
61
+ let currentFragment: string | undefined
62
+ let selectionPath: string[] = []
63
+ let parentTypes: string[] = []
64
+
65
+ // Helper function to create context
66
+ const createContext = (): IdentifierContext => {
67
+ return {
68
+ operationType: currentOperationType,
69
+ operationName: currentOperationName,
70
+ inFragment: currentFragment,
71
+ selectionPath: [...selectionPath],
72
+ }
73
+ }
74
+
75
+ visit(ast, {
76
+ OperationDefinition: {
77
+ enter: (node: OperationDefinitionNode) => {
78
+ currentOperationType = node.operation
79
+ currentOperationName = node.name?.value
80
+ selectionPath = []
81
+
82
+ // Set the root type based on operation type
83
+ if (schema) {
84
+ if (node.operation === 'query' && schema.getQueryType()) {
85
+ parentTypes = [schema.getQueryType()!.name]
86
+ } else if (node.operation === 'mutation' && schema.getMutationType()) {
87
+ parentTypes = [schema.getMutationType()!.name]
88
+ } else if (node.operation === 'subscription' && schema.getSubscriptionType()) {
89
+ parentTypes = [schema.getSubscriptionType()!.name]
90
+ } else {
91
+ parentTypes = []
92
+ }
93
+ } else {
94
+ // Fallback to default root type names
95
+ if (node.operation === 'query') {
96
+ parentTypes = ['Query']
97
+ } else if (node.operation === 'mutation') {
98
+ parentTypes = ['Mutation']
99
+ } else if (node.operation === 'subscription') {
100
+ parentTypes = ['Subscription']
101
+ } else {
102
+ parentTypes = []
103
+ }
104
+ }
105
+ },
106
+ leave: () => {
107
+ currentOperationType = undefined
108
+ currentOperationName = undefined
109
+ parentTypes = []
110
+ },
111
+ },
112
+
113
+ FragmentDefinition: {
114
+ enter: (node: FragmentDefinitionNode) => {
115
+ currentFragment = node.name.value
116
+ selectionPath = []
117
+ parentTypes = [node.typeCondition.name.value]
118
+
119
+ // Add fragment name as identifier
120
+ this.addIdentifier(identifiers, {
121
+ name: node.name.value,
122
+ kind: 'Fragment',
123
+ position: this.getPosition(node.name),
124
+ schemaPath: [node.name.value],
125
+ context: createContext(),
126
+ })
127
+
128
+ // Add type condition as identifier
129
+ this.addIdentifier(identifiers, {
130
+ name: node.typeCondition.name.value,
131
+ kind: 'Type',
132
+ position: this.getPosition(node.typeCondition.name),
133
+ schemaPath: [node.typeCondition.name.value],
134
+ context: createContext(),
135
+ })
136
+ },
137
+ leave: () => {
138
+ currentFragment = undefined
139
+ parentTypes = []
140
+ },
141
+ },
142
+
143
+ Field: {
144
+ enter: (node: FieldNode) => {
145
+ const fieldName = node.name.value
146
+ const parentType = parentTypes[parentTypes.length - 1]
147
+
148
+ selectionPath.push(fieldName)
149
+
150
+ this.addIdentifier(identifiers, {
151
+ name: fieldName,
152
+ kind: 'Field',
153
+ position: this.getPosition(node.name),
154
+ parentType,
155
+ schemaPath: parentType ? [parentType, fieldName] : [fieldName],
156
+ context: createContext(),
157
+ })
158
+
159
+ // Track parent type for nested selections
160
+ // Resolve the field's return type from schema if available
161
+ let pushedType = false
162
+ if (schema && parentType) {
163
+ const type = schema.getType(parentType)
164
+ if (type && ('getFields' in type)) {
165
+ const fields = (type as any).getFields()
166
+ const field = fields[fieldName]
167
+ if (field) {
168
+ // Get the base type name (unwrap NonNull and List wrappers)
169
+ let fieldType = field.type
170
+ while (fieldType.ofType) {
171
+ fieldType = fieldType.ofType
172
+ }
173
+ if (fieldType.name) {
174
+ parentTypes.push(fieldType.name)
175
+ pushedType = true
176
+ }
177
+ }
178
+ }
179
+ } else if (this.isObjectField(fieldName)) {
180
+ // Fallback to inference if no schema
181
+ const inferredType = this.inferReturnType(parentType, fieldName)
182
+ parentTypes.push(inferredType)
183
+ pushedType = true
184
+ } // Store whether we pushed a type for this field
185
+
186
+ ;(node as any)._pushedType = pushedType
187
+ },
188
+ leave: (node: FieldNode) => {
189
+ selectionPath.pop()
190
+
191
+ // Remove parent type if we added one in enter
192
+ if ((node as any)._pushedType) {
193
+ parentTypes.pop()
194
+ }
195
+ },
196
+ },
197
+
198
+ Argument: {
199
+ enter: (node: ArgumentNode) => {
200
+ const argName = node.name.value
201
+ const parentType = parentTypes[parentTypes.length - 1]
202
+ const fieldName = selectionPath[selectionPath.length - 1]
203
+
204
+ this.addIdentifier(identifiers, {
205
+ name: argName,
206
+ kind: 'Argument',
207
+ position: this.getPosition(node.name),
208
+ parentType,
209
+ schemaPath: parentType && fieldName
210
+ ? [parentType, fieldName, argName]
211
+ : [argName],
212
+ context: createContext(),
213
+ })
214
+ },
215
+ },
216
+
217
+ VariableDefinition: {
218
+ enter: (node: VariableDefinitionNode) => {
219
+ this.addIdentifier(identifiers, {
220
+ name: node.variable.name.value,
221
+ kind: 'Variable',
222
+ position: this.getPosition(node.variable.name),
223
+ schemaPath: [node.variable.name.value],
224
+ context: createContext(),
225
+ })
226
+
227
+ // Also add the type reference
228
+ const typeName = this.extractTypeName(node.type)
229
+ if (typeName) {
230
+ this.addIdentifier(identifiers, {
231
+ name: typeName,
232
+ kind: 'Type',
233
+ position: this.getTypePosition(node.type),
234
+ schemaPath: [typeName],
235
+ context: createContext(),
236
+ })
237
+ }
238
+ },
239
+ },
240
+
241
+ Directive: {
242
+ enter: (node: DirectiveNode) => {
243
+ this.addIdentifier(identifiers, {
244
+ name: node.name.value,
245
+ kind: 'Directive',
246
+ position: this.getPosition(node.name),
247
+ schemaPath: [node.name.value],
248
+ context: createContext(),
249
+ })
250
+ },
251
+ },
252
+ })
253
+
254
+ return this.createIdentifierMap(identifiers, errors)
255
+ }
256
+
257
+ /**
258
+ * Perform complete analysis of a GraphQL document
259
+ */
260
+ analyze(source: string, config: AnalysisConfig = {}): AnalysisResult {
261
+ try {
262
+ const ast = this.parse(source)
263
+ const identifiers = this.extractIdentifiers(ast, config)
264
+
265
+ let validationErrors: GraphQLError[] = []
266
+ if (config.validateAgainstSchema && config.schema) {
267
+ validationErrors = this.validateAgainstSchema(ast, config.schema)
268
+ }
269
+
270
+ return {
271
+ ast,
272
+ identifiers,
273
+ isValid: validationErrors.length === 0,
274
+ errors: validationErrors,
275
+ }
276
+ } catch (error) {
277
+ return {
278
+ ast: { kind: 'Document', definitions: [] } as DocumentNode,
279
+ identifiers: this.createIdentifierMap([], [{
280
+ message: error instanceof Error ? error.message : 'Unknown parsing error',
281
+ severity: 'error',
282
+ }]),
283
+ isValid: false,
284
+ errors: [],
285
+ }
286
+ }
287
+ }
288
+
289
+ // Private helper methods
290
+
291
+ private addIdentifier(identifiers: Identifier[], identifier: Identifier): void {
292
+ identifiers.push(identifier)
293
+ }
294
+
295
+ private getPosition(node: ASTNode): Identifier['position'] {
296
+ const loc = node.loc
297
+ if (!loc) {
298
+ return { start: 0, end: 0, line: 1, column: 1 }
299
+ }
300
+
301
+ return {
302
+ start: loc.start,
303
+ end: loc.end,
304
+ line: loc.startToken.line,
305
+ column: loc.startToken.column,
306
+ }
307
+ }
308
+
309
+ private getTypePosition(node: ASTNode): Identifier['position'] {
310
+ // For type nodes, we need to extract the base type name position
311
+ // This is a simplified implementation
312
+ return this.getPosition(node)
313
+ }
314
+
315
+ private extractTypeName(typeNode: any): string | null {
316
+ // Recursively extract the base type name from wrapped types (NonNull, List)
317
+ if (typeNode.kind === 'NamedType') {
318
+ return typeNode.name.value
319
+ }
320
+ if (typeNode.kind === 'NonNullType' || typeNode.kind === 'ListType') {
321
+ return this.extractTypeName(typeNode.type)
322
+ }
323
+ return null
324
+ }
325
+
326
+ private isObjectField(fieldName: string): boolean {
327
+ // This is only used as a fallback when no schema is available
328
+ // Common patterns for object-returning fields
329
+ const objectFieldPatterns = [
330
+ 'user',
331
+ 'users',
332
+ 'post',
333
+ 'posts',
334
+ 'comment',
335
+ 'comments',
336
+ 'profile',
337
+ 'settings',
338
+ 'organization',
339
+ 'project',
340
+ 'target',
341
+ 'member',
342
+ 'members',
343
+ 'node',
344
+ 'nodes',
345
+ 'edge',
346
+ 'edges',
347
+ ]
348
+ return objectFieldPatterns.some(pattern => fieldName.toLowerCase().includes(pattern))
349
+ }
350
+
351
+ private inferReturnType(parentType: string | undefined, fieldName: string): string {
352
+ // Simplified type inference - in real implementation would use schema
353
+ if (fieldName === 'user') return 'User'
354
+ if (fieldName === 'posts') return 'Post'
355
+ if (fieldName === 'comments') return 'Comment'
356
+ return fieldName.charAt(0).toUpperCase() + fieldName.slice(1)
357
+ }
358
+
359
+ private createContext(
360
+ operationType?: 'query' | 'mutation' | 'subscription',
361
+ operationName?: string,
362
+ inFragment?: string,
363
+ selectionPath: string[] = [],
364
+ ): IdentifierContext {
365
+ return {
366
+ operationType,
367
+ operationName,
368
+ inFragment,
369
+ selectionPath: [...selectionPath],
370
+ }
371
+ }
372
+
373
+ private createIdentifierMap(identifiers: Identifier[], errors: AnalysisError[]): IdentifierMap {
374
+ const byPosition = new Map<number, Identifier>()
375
+ const byKind = new Map<Identifier['kind'], Identifier[]>()
376
+
377
+ for (const identifier of identifiers) {
378
+ // Index by position
379
+ byPosition.set(identifier.position.start, identifier)
380
+
381
+ // Group by kind
382
+ if (!byKind.has(identifier.kind)) {
383
+ byKind.set(identifier.kind, [])
384
+ }
385
+ byKind.get(identifier.kind)!.push(identifier)
386
+ }
387
+
388
+ return {
389
+ byPosition,
390
+ byKind,
391
+ errors,
392
+ all: identifiers,
393
+ }
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Default analyzer instance
399
+ */
400
+ export const analyzer = new DefaultGraphQLAnalyzer()
401
+
402
+ /**
403
+ * Convenience function to analyze a GraphQL document
404
+ */
405
+ export const analyze = (source: string, config?: AnalysisConfig): AnalysisResult => {
406
+ return analyzer.analyze(source, config)
407
+ }
408
+
409
+ /**
410
+ * Convenience function to extract identifiers from a GraphQL document
411
+ */
412
+ export const extractIdentifiers = (source: string, config?: AnalysisConfig): IdentifierMap => {
413
+ const ast = analyzer.parse(source)
414
+ return analyzer.extractIdentifiers(ast, config)
415
+ }
@@ -0,0 +1,284 @@
1
+ import type { React } from '#dep/react/index'
2
+ import type { GraphQLSchema } from 'graphql'
3
+ import { useEffect, useMemo, useRef, useState } from 'react'
4
+ import { useNavigate } from 'react-router'
5
+ import { analyze } from '../analysis.ts'
6
+ import { createSimplePositionCalculator } from '../positioning-simple.ts'
7
+ import { createPolenSchemaResolver } from '../schema-integration.ts'
8
+ import type { Identifier } from '../types.ts'
9
+ import { hoverTooltipStyles } from './HoverTooltip.tsx'
10
+ import { IdentifierLink } from './IdentifierLink.tsx'
11
+ import { identifierLinkStyles } from './IdentifierLink.tsx'
12
+
13
+ /**
14
+ * Options for the GraphQL document component
15
+ */
16
+ export interface GraphQLDocumentOptions {
17
+ /** Whether to show debug overlays */
18
+ debug?: boolean
19
+ /** Whether to disable interactive features */
20
+ plain?: boolean
21
+ /** Custom navigation handler */
22
+ onNavigate?: (url: string) => void
23
+ /** Whether to validate against schema */
24
+ validate?: boolean
25
+ /** Custom class name for the container */
26
+ className?: string
27
+ }
28
+
29
+ /**
30
+ * Props for the GraphQL document component
31
+ */
32
+ export interface GraphQLDocumentProps {
33
+ /** The GraphQL document source code */
34
+ children: string
35
+ /** GraphQL schema for validation and linking */
36
+ schema?: GraphQLSchema
37
+ /** Component options */
38
+ options?: GraphQLDocumentOptions
39
+ /** Pre-rendered Shiki HTML (from build time) */
40
+ highlightedHtml?: string
41
+ }
42
+
43
+ /**
44
+ * Interactive GraphQL document component
45
+ *
46
+ * Transforms static GraphQL code blocks into interactive documentation
47
+ * with hyperlinks, tooltips, and schema validation.
48
+ */
49
+ export const GraphQLDocument: React.FC<GraphQLDocumentProps> = ({
50
+ children,
51
+ schema,
52
+ options = {},
53
+ highlightedHtml,
54
+ }) => {
55
+ const {
56
+ debug = false,
57
+ plain = false,
58
+ onNavigate,
59
+ validate = true,
60
+ className = '',
61
+ } = options
62
+
63
+ const navigate = useNavigate()
64
+ const handleNavigate = onNavigate || ((url: string) => navigate(url))
65
+
66
+ // Container ref for positioning calculations
67
+ const containerRef = useRef<HTMLDivElement>(null)
68
+ const [isReady, setIsReady] = useState(false)
69
+ const [openTooltipId, setOpenTooltipId] = useState<string | null>(null)
70
+
71
+ // Handle click outside to close tooltips
72
+ useEffect(() => {
73
+ if (!openTooltipId) return
74
+
75
+ const handleClickOutside = (event: MouseEvent) => {
76
+ // Check if click is outside the tooltip and identifier links
77
+ const target = event.target as HTMLElement
78
+
79
+ // Don't close if clicking on an identifier link or tooltip
80
+ if (
81
+ target.closest('.graphql-identifier-overlay')
82
+ || target.closest('.graphql-hover-tooltip')
83
+ ) {
84
+ return
85
+ }
86
+
87
+ // Close the tooltip
88
+ setOpenTooltipId(null)
89
+ }
90
+
91
+ // Add event listener
92
+ document.addEventListener('mousedown', handleClickOutside)
93
+
94
+ return () => {
95
+ document.removeEventListener('mousedown', handleClickOutside)
96
+ }
97
+ }, [openTooltipId])
98
+
99
+ // Layer 1: Parse and analyze
100
+ const analysisResult = useMemo(() => {
101
+ if (plain) return null
102
+ const result = analyze(children, { schema })
103
+ return result
104
+ }, [children, plain, schema])
105
+
106
+ // Layer 2: Schema resolution
107
+ const resolver = useMemo(() => {
108
+ if (!schema || plain) return null
109
+ return createPolenSchemaResolver(schema)
110
+ }, [schema, plain])
111
+
112
+ const resolutions = useMemo(() => {
113
+ if (!analysisResult || !resolver) {
114
+ return new Map()
115
+ }
116
+
117
+ const results = new Map()
118
+ for (const [position, identifier] of analysisResult.identifiers.byPosition) {
119
+ const resolution = resolver.resolveIdentifier(identifier)
120
+ if (resolution) {
121
+ results.set(position, resolution)
122
+ }
123
+ }
124
+ return results
125
+ }, [analysisResult, resolver])
126
+
127
+ // Layer 3: Position calculation
128
+ const positionCalculator = useMemo(() => {
129
+ if (plain) return null
130
+ return createSimplePositionCalculator()
131
+ }, [plain])
132
+
133
+ const [positions, setPositions] = useState<Map<string, { position: any; identifier: Identifier }>>(new Map())
134
+
135
+ // Prepare code block and calculate positions after render
136
+ useEffect(() => {
137
+ if (!containerRef.current || !analysisResult || !positionCalculator || plain) {
138
+ return
139
+ }
140
+
141
+ // Get the code element within the container
142
+ const codeElement = containerRef.current.querySelector('pre.shiki code')
143
+ || containerRef.current.querySelector('pre code')
144
+ || containerRef.current.querySelector('code')
145
+ if (!codeElement) {
146
+ return
147
+ }
148
+
149
+ // Prepare the code block (wrap identifiers)
150
+ const identifiers = Array.from(analysisResult.identifiers.byPosition.values())
151
+ positionCalculator.prepareCodeBlock(codeElement as Element, identifiers)
152
+
153
+ // Get positions after DOM update
154
+ requestAnimationFrame(() => {
155
+ // Pass containerRef.current as the reference element for positioning
156
+ if (containerRef.current) {
157
+ const newPositions = positionCalculator.getIdentifierPositions(codeElement as Element, containerRef.current)
158
+ setPositions(newPositions)
159
+ setIsReady(true)
160
+ }
161
+ })
162
+ }, [analysisResult, positionCalculator, plain, highlightedHtml])
163
+
164
+ // Handle resize events
165
+ useEffect(() => {
166
+ if (!containerRef.current || !positionCalculator || plain) return
167
+
168
+ const handleResize = () => {
169
+ const codeElement = containerRef.current?.querySelector('pre.shiki code')
170
+ || containerRef.current?.querySelector('pre code')
171
+ || containerRef.current?.querySelector('code')
172
+ if (codeElement && containerRef.current) {
173
+ const newPositions = positionCalculator.getIdentifierPositions(codeElement as Element, containerRef.current)
174
+ setPositions(newPositions)
175
+ }
176
+ }
177
+
178
+ window.addEventListener('resize', handleResize)
179
+ return () => window.removeEventListener('resize', handleResize)
180
+ }, [positionCalculator, plain])
181
+
182
+ // Validation errors
183
+ const validationErrors = useMemo(() => {
184
+ if (!validate || !analysisResult || !schema) return []
185
+ return analysisResult.errors
186
+ }, [validate, analysisResult, schema])
187
+
188
+ return (
189
+ <>
190
+ {/* Inject styles */}
191
+ <style dangerouslySetInnerHTML={{ __html: identifierLinkStyles + '\n' + hoverTooltipStyles }} />
192
+
193
+ <div
194
+ ref={containerRef}
195
+ className={`graphql-document ${className} ${debug ? 'graphql-debug-mode' : ''}`}
196
+ style={{ position: 'relative' }}
197
+ >
198
+ {/* Base syntax highlighting */}
199
+ {highlightedHtml ? <div dangerouslySetInnerHTML={{ __html: highlightedHtml }} /> : (
200
+ <pre className='shiki'>
201
+ <code>{children}</code>
202
+ </pre>
203
+ )}
204
+
205
+ {/* Interactive overlay layer */}
206
+ {!plain && isReady && (
207
+ <div className='graphql-interaction-layer' style={{ pointerEvents: 'none' }}>
208
+ {Array.from(positions.entries()).map(([id, { position, identifier }]) => {
209
+ const startPos = identifier.position.start
210
+ const resolution = resolutions.get(startPos)
211
+
212
+ if (!resolution) return null
213
+
214
+ return (
215
+ <IdentifierLink
216
+ key={id}
217
+ identifier={identifier}
218
+ resolution={resolution}
219
+ position={position}
220
+ onNavigate={handleNavigate}
221
+ debug={debug}
222
+ isOpen={openTooltipId === id}
223
+ onToggle={(open) => setOpenTooltipId(open ? id : null)}
224
+ />
225
+ )
226
+ })}
227
+ </div>
228
+ )}
229
+
230
+ {/* Validation errors overlay */}
231
+ {validationErrors.length > 0 && (
232
+ <div className='graphql-validation-errors'>
233
+ {validationErrors.map((error: any, index: number) => (
234
+ <div key={index} className='graphql-error'>
235
+ {error.message}
236
+ </div>
237
+ ))}
238
+ </div>
239
+ )}
240
+ </div>
241
+ </>
242
+ )
243
+ }
244
+
245
+ /**
246
+ * Default styles for the GraphQL document component
247
+ */
248
+ export const graphqlDocumentStyles = `
249
+ .graphql-document {
250
+ position: relative;
251
+ }
252
+
253
+ .graphql-interaction-layer {
254
+ position: absolute;
255
+ top: 0;
256
+ left: 0;
257
+ right: 0;
258
+ bottom: 0;
259
+ pointer-events: none;
260
+ }
261
+
262
+ .graphql-interaction-layer > * {
263
+ pointer-events: auto;
264
+ }
265
+
266
+ .graphql-validation-errors {
267
+ margin-top: 1rem;
268
+ padding: 0.5rem;
269
+ background-color: var(--red-2);
270
+ border: 1px solid var(--red-6);
271
+ border-radius: 4px;
272
+ }
273
+
274
+ .graphql-error {
275
+ color: var(--red-11);
276
+ font-size: 0.875rem;
277
+ margin: 0.25rem 0;
278
+ }
279
+
280
+ .graphql-debug-mode [data-graphql-id] {
281
+ background-color: rgba(59, 130, 246, 0.1);
282
+ outline: 1px solid rgba(59, 130, 246, 0.3);
283
+ }
284
+ `