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,188 @@
1
+ /**
2
+ * Unit tests for GraphQL Document component logic
3
+ *
4
+ * Tests the core functionality without rendering React components
5
+ */
6
+
7
+ import { buildSchema } from 'graphql'
8
+ import { describe, expect, it } from 'vitest'
9
+ import { analyze } from '../analysis.ts'
10
+ import { createSimplePositionCalculator } from '../positioning-simple.ts'
11
+ import { analyzeWithSchema, createPolenSchemaResolver } from '../schema-integration.ts'
12
+
13
+ describe('GraphQLDocument logic', () => {
14
+ const testSchema = buildSchema(`
15
+ type Query {
16
+ user(id: ID!): User
17
+ users: [User!]!
18
+ }
19
+
20
+ type User {
21
+ id: ID!
22
+ name: String!
23
+ email: String!
24
+ posts: [Post!]!
25
+ }
26
+
27
+ type Post {
28
+ id: ID!
29
+ title: String!
30
+ content: String!
31
+ author: User!
32
+ }
33
+ `)
34
+
35
+ const testQuery = `
36
+ query GetUser($id: ID!) {
37
+ user(id: $id) {
38
+ id
39
+ name
40
+ email
41
+ posts {
42
+ title
43
+ }
44
+ }
45
+ }`
46
+
47
+ describe('analysis integration', () => {
48
+ it('should analyze GraphQL document and extract identifiers', () => {
49
+ const result = analyze(testQuery)
50
+
51
+ expect(result.identifiers.byKind.get('Field')).toBeDefined()
52
+ expect(result.identifiers.byKind.get('Variable')).toBeDefined()
53
+ expect(result.identifiers.byKind.get('Type')).toBeDefined()
54
+
55
+ // Check specific identifiers
56
+ const fields = result.identifiers.byKind.get('Field') || []
57
+ const fieldNames = fields.map(f => f.name)
58
+ expect(fieldNames).toContain('user')
59
+ expect(fieldNames).toContain('id')
60
+ expect(fieldNames).toContain('name')
61
+ expect(fieldNames).toContain('email')
62
+ expect(fieldNames).toContain('posts')
63
+ expect(fieldNames).toContain('title')
64
+ })
65
+
66
+ it('should handle empty document', () => {
67
+ const result = analyze('')
68
+ expect(result.identifiers.byPosition.size).toBe(0)
69
+ // Empty string is technically parseable as an empty document
70
+ expect(result.ast).toBeDefined()
71
+ })
72
+ })
73
+
74
+ describe('schema resolution integration', () => {
75
+ it('should resolve identifiers against schema', () => {
76
+ // Use analyzeWithSchema for proper schema-aware analysis
77
+ const { analysis, resolutions } = analyzeWithSchema(testQuery, testSchema)
78
+
79
+ // Check that analysis found identifiers
80
+ expect(analysis.identifiers.all.length).toBeGreaterThan(0)
81
+
82
+ // Check that we have resolutions
83
+ expect(resolutions.size).toBeGreaterThan(0)
84
+
85
+ // Check that analysis is valid
86
+ expect(analysis.isValid).toBe(true)
87
+
88
+ // Basic check that resolutions were created
89
+ const hasValidResolutions = Array.from(resolutions.values()).some(
90
+ res => res.exists && res.referenceUrl.includes('/reference/'),
91
+ )
92
+ expect(hasValidResolutions).toBe(true)
93
+ })
94
+
95
+ it('should detect non-existent fields', () => {
96
+ const invalidQuery = `query { nonExistentField }`
97
+ const result = analyze(invalidQuery)
98
+ const resolver = createPolenSchemaResolver(testSchema)
99
+
100
+ const field = Array.from(result.identifiers.byPosition.values())[0]
101
+ const resolution = resolver.resolveIdentifier(field!)
102
+
103
+ expect(resolution).toBeDefined()
104
+ expect(resolution!.exists).toBe(false)
105
+ })
106
+ })
107
+
108
+ describe('position calculation', () => {
109
+ it('should create position calculator', () => {
110
+ const calculator = createSimplePositionCalculator()
111
+ expect(calculator).toBeDefined()
112
+ expect(calculator.prepareCodeBlock).toBeDefined()
113
+ expect(calculator.getIdentifierPositions).toBeDefined()
114
+ })
115
+ })
116
+
117
+ describe('options handling', () => {
118
+ it('should skip analysis when plain option is true', () => {
119
+ const options = { plain: true }
120
+ // When plain is true, no analysis should be performed
121
+ expect(options.plain).toBe(true)
122
+ })
123
+
124
+ it('should enable debug mode', () => {
125
+ const options = { debug: true }
126
+ expect(options.debug).toBe(true)
127
+ })
128
+
129
+ it('should handle custom navigation', () => {
130
+ const onNavigate = (url: string) => {
131
+ expect(url).toContain('/reference/')
132
+ }
133
+ const options = { onNavigate }
134
+ expect(options.onNavigate).toBeDefined()
135
+ })
136
+
137
+ it('should handle validation option', () => {
138
+ const options = { validate: true }
139
+ expect(options.validate).toBe(true)
140
+ })
141
+
142
+ it('should handle custom className', () => {
143
+ const options = { className: 'custom-graphql-block' }
144
+ expect(options.className).toBe('custom-graphql-block')
145
+ })
146
+ })
147
+
148
+ describe('validation', () => {
149
+ it('should validate valid queries', () => {
150
+ const { analysis, resolutions } = analyzeWithSchema(testQuery, testSchema)
151
+
152
+ // Check that validation passed
153
+ expect(analysis.isValid).toBe(true)
154
+
155
+ // Check that we have resolutions
156
+ expect(resolutions.size).toBeGreaterThan(0)
157
+
158
+ // Check that the user field resolved correctly
159
+ const userResolution = Array.from(resolutions.values()).find(
160
+ res => res.referenceUrl.includes('query') && res.referenceUrl.includes('user'),
161
+ )
162
+
163
+ if (userResolution) {
164
+ expect(userResolution.exists).toBe(true)
165
+ }
166
+ })
167
+
168
+ it('should detect validation errors', () => {
169
+ const invalidQuery = `
170
+ query {
171
+ user {
172
+ nonExistentField
173
+ }
174
+ }
175
+ `
176
+
177
+ const result = analyze(invalidQuery)
178
+ const resolver = createPolenSchemaResolver(testSchema)
179
+
180
+ const resolutions = Array.from(result.identifiers.byPosition.values())
181
+ .map(id => ({ id, resolution: resolver.resolveIdentifier(id) }))
182
+
183
+ const invalidField = resolutions.find(r => r.id.name === 'nonExistentField')
184
+ expect(invalidField).toBeDefined()
185
+ expect(invalidField!.resolution!.exists).toBe(false)
186
+ })
187
+ })
188
+ })
@@ -0,0 +1,70 @@
1
+ import type { React } from '#dep/react/index'
2
+ import { useEffect, useState } from 'react'
3
+ import { useGraphQLSchema } from '../schema-context.tsx'
4
+ import { GraphQLDocument, type GraphQLDocumentProps } from './GraphQLDocument.tsx'
5
+
6
+ // Cache for highlighter
7
+ let highlighterCache: any = null
8
+
9
+ /**
10
+ * GraphQL Document component that uses the schema context and handles syntax highlighting
11
+ */
12
+ export const GraphQLDocumentWithSchema: React.FC<Omit<GraphQLDocumentProps, 'schema' | 'highlightedHtml'>> = (
13
+ props,
14
+ ) => {
15
+ const schema = useGraphQLSchema()
16
+ const [mounted, setMounted] = useState(false)
17
+ const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)
18
+
19
+ useEffect(() => {
20
+ setMounted(true)
21
+
22
+ const loadHighlighter = async () => {
23
+ try {
24
+ // Load highlighter if not cached
25
+ if (!highlighterCache) {
26
+ const { highlightCode } = await import('#lib/shiki/index')
27
+ highlighterCache = highlightCode
28
+ }
29
+
30
+ // Generate highlighted HTML
31
+ const highlighted = await highlighterCache({
32
+ code: props['children'],
33
+ lang: 'graphql',
34
+ theme: 'light',
35
+ })
36
+
37
+ setHighlightedHtml(highlighted)
38
+ } catch (error) {
39
+ console.error('Failed to load GraphQL document highlighter:', error)
40
+ }
41
+ }
42
+
43
+ loadHighlighter()
44
+ }, [props['children']])
45
+
46
+ // Always render the same structure to avoid hydration issues
47
+ const isInteractive = mounted && schema && highlightedHtml
48
+
49
+ if (!isInteractive) {
50
+ // Static fallback that looks like Shiki output
51
+ return (
52
+ <div className='graphql-document graphql-document-static' data-testid='graphql-document'>
53
+ <pre
54
+ className='shiki shiki-themes github-light tokyo-night'
55
+ style={{ backgroundColor: 'var(--shiki-light-bg)', color: 'var(--shiki-light)' }}
56
+ >
57
+ <code className="language-graphql">{props['children']}</code>
58
+ </pre>
59
+ </div>
60
+ )
61
+ }
62
+
63
+ return (
64
+ <GraphQLDocument
65
+ {...props}
66
+ schema={schema}
67
+ highlightedHtml={highlightedHtml}
68
+ />
69
+ )
70
+ }
@@ -0,0 +1,282 @@
1
+ import type { React } from '#dep/react/index'
2
+ import { Badge, Box, Card, Flex, Text } from '@radix-ui/themes'
3
+ import { useEffect, useRef, useState } from 'react'
4
+ import type { DOMPosition } from '../positioning-simple.ts'
5
+ import type { Documentation } from '../schema-integration.ts'
6
+ import type { Identifier } from '../types.ts'
7
+
8
+ /**
9
+ * Props for the HoverTooltip component
10
+ */
11
+ export interface HoverTooltipProps {
12
+ /** The identifier being hovered */
13
+ identifier: Identifier
14
+ /** Documentation from schema */
15
+ documentation: Documentation
16
+ /** Position of the identifier */
17
+ position: DOMPosition
18
+ /** Whether this identifier has an error */
19
+ hasError?: boolean
20
+ /** Reference URL for "View docs" link */
21
+ referenceUrl: string
22
+ /** Callback to close the tooltip */
23
+ onClose?: () => void
24
+ /** Callback to navigate to docs */
25
+ onNavigate?: () => void
26
+ }
27
+
28
+ /**
29
+ * Tooltip shown on hover over GraphQL identifiers
30
+ *
31
+ * Displays type information, descriptions, deprecation warnings,
32
+ * and links to full documentation.
33
+ */
34
+ export const HoverTooltip: React.FC<HoverTooltipProps> = ({
35
+ identifier,
36
+ documentation,
37
+ position,
38
+ hasError = false,
39
+ referenceUrl,
40
+ onClose,
41
+ onNavigate,
42
+ }) => {
43
+ const tooltipRef = useRef<HTMLDivElement>(null)
44
+ const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 })
45
+
46
+ // Calculate tooltip position to avoid viewport edges
47
+ useEffect(() => {
48
+ if (!tooltipRef.current) return
49
+
50
+ const tooltip = tooltipRef.current
51
+ const rect = tooltip.getBoundingClientRect()
52
+ const viewportWidth = window.innerWidth
53
+ const viewportHeight = window.innerHeight
54
+
55
+ // Default position: above the identifier
56
+ let top = position.top - rect.height - 8
57
+ let left = position.left
58
+
59
+ // Adjust if tooltip would go off screen
60
+ if (top < 0) {
61
+ // Show below if not enough space above
62
+ top = position.top + position.height + 8
63
+ }
64
+
65
+ if (left + rect.width > viewportWidth) {
66
+ // Align right edge with identifier if too wide
67
+ left = position.left + position.width - rect.width
68
+ }
69
+
70
+ if (left < 0) {
71
+ // Keep on screen
72
+ left = 8
73
+ }
74
+
75
+ setTooltipPosition({ top, left })
76
+ }, [position])
77
+
78
+ // Determine badge color based on identifier kind
79
+ const getBadgeColor = () => {
80
+ switch (identifier.kind) {
81
+ case 'Type':
82
+ return 'blue'
83
+ case 'Field':
84
+ return 'green'
85
+ case 'Argument':
86
+ return 'orange'
87
+ case 'Variable':
88
+ return 'purple'
89
+ case 'Directive':
90
+ return 'amber'
91
+ case 'Fragment':
92
+ return 'cyan'
93
+ default:
94
+ return 'gray'
95
+ }
96
+ }
97
+
98
+ return (
99
+ <div
100
+ ref={tooltipRef}
101
+ className='graphql-hover-tooltip'
102
+ style={{
103
+ position: 'absolute',
104
+ top: tooltipPosition.top,
105
+ left: tooltipPosition.left,
106
+ zIndex: 100,
107
+ maxWidth: '400px',
108
+ pointerEvents: 'auto', // Make tooltip interactive
109
+ }}
110
+ >
111
+ <Card size='2' variant='surface'>
112
+ <Flex direction='column' gap='2'>
113
+ {/* Header with name, kind, and close button */}
114
+ <Flex justify='between' align='center'>
115
+ <Flex align='center' gap='2'>
116
+ <Text size='2' weight='bold'>
117
+ {identifier.name}
118
+ </Text>
119
+ <Badge color={getBadgeColor()} size='1'>
120
+ {identifier.kind}
121
+ </Badge>
122
+ </Flex>
123
+ {onClose && (
124
+ <button
125
+ onClick={onClose}
126
+ style={{
127
+ background: 'none',
128
+ border: 'none',
129
+ cursor: 'pointer',
130
+ padding: '4px',
131
+ color: 'var(--gray-11)',
132
+ fontSize: '18px',
133
+ lineHeight: '1',
134
+ fontWeight: 'bold',
135
+ borderRadius: '4px',
136
+ transition: 'background-color 0.2s',
137
+ }}
138
+ onMouseEnter={(e) => {
139
+ e.currentTarget.style.backgroundColor = 'var(--gray-a3)'
140
+ }}
141
+ onMouseLeave={(e) => {
142
+ e.currentTarget.style.backgroundColor = 'transparent'
143
+ }}
144
+ aria-label='Close tooltip'
145
+ >
146
+ ×
147
+ </button>
148
+ )}
149
+ </Flex>
150
+
151
+ {/* Type signature */}
152
+ <Box>
153
+ <Text size='1' color='gray'>
154
+ Type: <Text as='span' size='1' style={{ fontFamily: 'monospace' }}>{documentation.typeInfo}</Text>
155
+ </Text>
156
+ </Box>
157
+
158
+ {/* Description */}
159
+ {documentation.description && (
160
+ <Box>
161
+ <Text size='1'>
162
+ {documentation.description}
163
+ </Text>
164
+ </Box>
165
+ )}
166
+
167
+ {/* Default value for arguments */}
168
+ {documentation.defaultValue && (
169
+ <Box>
170
+ <Text size='1' color='gray'>
171
+ Default:{' '}
172
+ <Text as='span' size='1' style={{ fontFamily: 'monospace' }}>{documentation.defaultValue}</Text>
173
+ </Text>
174
+ </Box>
175
+ )}
176
+
177
+ {/* Deprecation warning */}
178
+ {documentation.deprecated && (
179
+ <Box
180
+ style={{
181
+ padding: '8px',
182
+ backgroundColor: 'var(--amber-2)',
183
+ borderRadius: '4px',
184
+ border: '1px solid var(--amber-6)',
185
+ }}
186
+ >
187
+ <Text size='1' color='amber'>
188
+ ⚠️ Deprecated: {documentation.deprecated.reason}
189
+ </Text>
190
+ {documentation.deprecated.replacement && (
191
+ <Text size='1' color='amber'>
192
+ Use {documentation.deprecated.replacement} instead.
193
+ </Text>
194
+ )}
195
+ </Box>
196
+ )}
197
+
198
+ {/* Error message */}
199
+ {hasError && (
200
+ <Box
201
+ style={{
202
+ padding: '8px',
203
+ backgroundColor: 'var(--red-2)',
204
+ borderRadius: '4px',
205
+ border: '1px solid var(--red-6)',
206
+ }}
207
+ >
208
+ <Text size='1' color='red'>
209
+ ❌ {identifier.kind} not found in schema
210
+ </Text>
211
+ </Box>
212
+ )}
213
+
214
+ {/* Schema path */}
215
+ <Box>
216
+ <Text size='1' color='gray'>
217
+ Path: {identifier.schemaPath.join(' → ')}
218
+ </Text>
219
+ </Box>
220
+
221
+ {/* View docs link */}
222
+ {onNavigate && (
223
+ <Box>
224
+ <Text size='1'>
225
+ <a
226
+ href={referenceUrl}
227
+ onClick={(e) => {
228
+ e.preventDefault()
229
+ onNavigate()
230
+ onClose?.()
231
+ }}
232
+ style={{
233
+ color: 'var(--accent-9)',
234
+ textDecoration: 'none',
235
+ borderBottom: '1px solid transparent',
236
+ transition: 'border-color 0.2s',
237
+ cursor: 'pointer',
238
+ }}
239
+ onMouseEnter={(e) => {
240
+ e.currentTarget.style.borderBottomColor = 'var(--accent-9)'
241
+ }}
242
+ onMouseLeave={(e) => {
243
+ e.currentTarget.style.borderBottomColor = 'transparent'
244
+ }}
245
+ >
246
+ View full documentation →
247
+ </a>
248
+ </Text>
249
+ </Box>
250
+ )}
251
+ </Flex>
252
+ </Card>
253
+ </div>
254
+ )
255
+ }
256
+
257
+ /**
258
+ * Default styles for hover tooltips
259
+ */
260
+ export const hoverTooltipStyles = `
261
+ .graphql-hover-tooltip {
262
+ /* Tooltip animation */
263
+ animation: graphql-tooltip-fade-in 0.2s ease-out;
264
+ }
265
+
266
+ @keyframes graphql-tooltip-fade-in {
267
+ from {
268
+ opacity: 0;
269
+ transform: translateY(4px);
270
+ }
271
+ to {
272
+ opacity: 1;
273
+ transform: translateY(0);
274
+ }
275
+ }
276
+
277
+ /* Ensure tooltips appear above other content */
278
+ .graphql-hover-tooltip .rt-Card {
279
+ box-shadow: 0 10px 38px -10px rgba(22, 23, 24, 0.35),
280
+ 0 10px 20px -15px rgba(22, 23, 24, 0.2);
281
+ }
282
+ `