zudoku 0.0.0-e88b02e → 0.0.0-e8a949d

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 (435) hide show
  1. package/dist/app/demo.js +1 -1
  2. package/dist/app/demo.js.map +1 -1
  3. package/dist/app/entry.client.js +1 -15
  4. package/dist/app/entry.client.js.map +1 -1
  5. package/dist/app/entry.server.js +1 -2
  6. package/dist/app/entry.server.js.map +1 -1
  7. package/dist/app/main.d.ts +1 -1
  8. package/dist/app/sentry.js +1 -1
  9. package/dist/app/sentry.js.map +1 -1
  10. package/dist/app/standalone.js +1 -1
  11. package/dist/app/standalone.js.map +1 -1
  12. package/dist/cli/cli.js +0 -2
  13. package/dist/cli/cli.js.map +1 -1
  14. package/dist/cli/cmds/build.js +1 -0
  15. package/dist/cli/cmds/build.js.map +1 -1
  16. package/dist/cli/cmds/dev.js +5 -0
  17. package/dist/cli/cmds/dev.js.map +1 -1
  18. package/dist/cli/dev/handler.d.ts +1 -0
  19. package/dist/cli/dev/handler.js +1 -1
  20. package/dist/cli/dev/handler.js.map +1 -1
  21. package/dist/config/loader.d.ts +9 -1
  22. package/dist/config/loader.js +44 -7
  23. package/dist/config/loader.js.map +1 -1
  24. package/dist/config/validators/common.d.ts +186 -152
  25. package/dist/config/validators/common.js +6 -2
  26. package/dist/config/validators/common.js.map +1 -1
  27. package/dist/config/validators/icon-types.d.ts +1 -1
  28. package/dist/config/validators/validate.d.ts +123 -109
  29. package/dist/lib/authentication/components/CallbackHandler.js +1 -1
  30. package/dist/lib/authentication/components/CallbackHandler.js.map +1 -1
  31. package/dist/lib/authentication/components/SignIn.js +1 -1
  32. package/dist/lib/authentication/components/SignIn.js.map +1 -1
  33. package/dist/lib/authentication/components/SignOut.js +1 -1
  34. package/dist/lib/authentication/components/SignOut.js.map +1 -1
  35. package/dist/lib/authentication/providers/openid.d.ts +7 -0
  36. package/dist/lib/authentication/providers/openid.js +1 -0
  37. package/dist/lib/authentication/providers/openid.js.map +1 -1
  38. package/dist/lib/components/AnchorLink.d.ts +1 -1
  39. package/dist/lib/components/AnchorLink.js +1 -1
  40. package/dist/lib/components/AnchorLink.js.map +1 -1
  41. package/dist/lib/components/Bootstrap.d.ts +1 -2
  42. package/dist/lib/components/Bootstrap.js +3 -3
  43. package/dist/lib/components/Bootstrap.js.map +1 -1
  44. package/dist/lib/components/Header.js +2 -2
  45. package/dist/lib/components/Header.js.map +1 -1
  46. package/dist/lib/components/Layout.js +2 -2
  47. package/dist/lib/components/Layout.js.map +1 -1
  48. package/dist/lib/components/Markdown.js +1 -1
  49. package/dist/lib/components/Markdown.js.map +1 -1
  50. package/dist/lib/components/MobileTopNavigation.js +1 -1
  51. package/dist/lib/components/NotFoundPage.js +1 -1
  52. package/dist/lib/components/NotFoundPage.js.map +1 -1
  53. package/dist/lib/components/ReactMarkdown.d.ts +29 -0
  54. package/dist/lib/components/ReactMarkdown.js +182 -0
  55. package/dist/lib/components/ReactMarkdown.js.map +1 -0
  56. package/dist/lib/components/SlotletProvider.d.ts +2 -2
  57. package/dist/lib/components/TopNavigation.js +1 -1
  58. package/dist/lib/components/TopNavigation.js.map +1 -1
  59. package/dist/lib/components/Zudoku.js +1 -1
  60. package/dist/lib/components/Zudoku.js.map +1 -1
  61. package/dist/lib/components/context/ZudokuContext.js +1 -1
  62. package/dist/lib/components/context/ZudokuContext.js.map +1 -1
  63. package/dist/lib/components/index.d.ts +20 -16
  64. package/dist/lib/components/index.js +7 -3
  65. package/dist/lib/components/index.js.map +1 -1
  66. package/dist/lib/components/navigation/Sidebar.js +1 -1
  67. package/dist/lib/components/navigation/SidebarBadge.d.ts +0 -9
  68. package/dist/lib/components/navigation/SidebarBadge.js +0 -9
  69. package/dist/lib/components/navigation/SidebarBadge.js.map +1 -1
  70. package/dist/lib/components/navigation/SidebarCategory.js +1 -1
  71. package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
  72. package/dist/lib/components/navigation/SidebarItem.js +1 -1
  73. package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
  74. package/dist/lib/components/navigation/utils.js +1 -1
  75. package/dist/lib/components/navigation/utils.js.map +1 -1
  76. package/dist/lib/core/plugins.d.ts +3 -5
  77. package/dist/lib/core/plugins.js.map +1 -1
  78. package/dist/lib/errors/RouterError.js +1 -1
  79. package/dist/lib/errors/RouterError.js.map +1 -1
  80. package/dist/lib/oas/parser/dereference/index.d.ts +1 -0
  81. package/dist/lib/oas/parser/dereference/index.js +6 -3
  82. package/dist/lib/oas/parser/dereference/index.js.map +1 -1
  83. package/dist/lib/plugins/api-catalog/Catalog.d.ts +2 -6
  84. package/dist/lib/plugins/api-catalog/Catalog.js +22 -15
  85. package/dist/lib/plugins/api-catalog/Catalog.js.map +1 -1
  86. package/dist/lib/plugins/api-catalog/index.d.ts +8 -1
  87. package/dist/lib/plugins/api-catalog/index.js +2 -2
  88. package/dist/lib/plugins/api-catalog/index.js.map +1 -1
  89. package/dist/lib/plugins/api-keys/CreateApiKey.js +1 -1
  90. package/dist/lib/plugins/api-keys/CreateApiKey.js.map +1 -1
  91. package/dist/lib/plugins/api-keys/ProtectedRoute.js +1 -1
  92. package/dist/lib/plugins/api-keys/ProtectedRoute.js.map +1 -1
  93. package/dist/lib/plugins/api-keys/SettingsApiKeys.js +1 -1
  94. package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
  95. package/dist/lib/plugins/markdown/MdxPage.js +1 -1
  96. package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
  97. package/dist/lib/plugins/markdown/index.d.ts +1 -0
  98. package/dist/lib/plugins/markdown/index.js.map +1 -1
  99. package/dist/lib/plugins/openapi/OperationList.js +10 -34
  100. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  101. package/dist/lib/plugins/openapi/OperationListItem.d.ts +2 -1
  102. package/dist/lib/plugins/openapi/OperationListItem.js +14 -4
  103. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  104. package/dist/lib/plugins/openapi/Route.d.ts +4 -2
  105. package/dist/lib/plugins/openapi/Route.js +22 -2
  106. package/dist/lib/plugins/openapi/Route.js.map +1 -1
  107. package/dist/lib/plugins/openapi/Sidecar.js +3 -13
  108. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  109. package/dist/lib/plugins/openapi/client/useCreateQuery.js +10 -1
  110. package/dist/lib/plugins/openapi/client/useCreateQuery.js.map +1 -1
  111. package/dist/lib/plugins/openapi/context.d.ts +3 -3
  112. package/dist/lib/plugins/openapi/index.js +18 -17
  113. package/dist/lib/plugins/openapi/index.js.map +1 -1
  114. package/dist/lib/plugins/openapi/interfaces.d.ts +19 -0
  115. package/dist/lib/plugins/openapi/schema/SchemaComponents.js +7 -1
  116. package/dist/lib/plugins/openapi/schema/SchemaComponents.js.map +1 -1
  117. package/dist/lib/plugins/openapi/util/methodToColor.d.ts +20 -0
  118. package/dist/lib/plugins/openapi/util/methodToColor.js +24 -0
  119. package/dist/lib/plugins/openapi/util/methodToColor.js.map +1 -0
  120. package/dist/lib/plugins/openapi/util/sanitizeMarkdownForMetatag.d.ts +1 -0
  121. package/dist/lib/plugins/openapi/util/sanitizeMarkdownForMetatag.js +27 -0
  122. package/dist/lib/plugins/openapi/util/sanitizeMarkdownForMetatag.js.map +1 -0
  123. package/dist/lib/plugins/redirect/index.js +1 -1
  124. package/dist/lib/plugins/redirect/index.js.map +1 -1
  125. package/dist/lib/plugins/search-inkeep/index.d.ts +22 -3
  126. package/dist/lib/plugins/search-inkeep/index.js +41 -5
  127. package/dist/lib/plugins/search-inkeep/index.js.map +1 -1
  128. package/dist/lib/plugins/search-inkeep/inkeep.d.ts +3 -4
  129. package/dist/lib/plugins/search-inkeep/inkeep.js.map +1 -1
  130. package/dist/lib/util/MdxComponents.d.ts +16 -16
  131. package/dist/lib/util/MdxComponents.js +1 -3
  132. package/dist/lib/util/MdxComponents.js.map +1 -1
  133. package/dist/lib/util/createVariantComponent.d.ts +2 -2
  134. package/dist/lib/util/useExposedProps.js +1 -1
  135. package/dist/lib/util/useExposedProps.js.map +1 -1
  136. package/dist/lib/util/useOnScreen.d.ts +1 -1
  137. package/dist/lib/util/useScrollToAnchor.js +1 -1
  138. package/dist/lib/util/useScrollToAnchor.js.map +1 -1
  139. package/dist/lib/util/useScrollToTop.js +1 -1
  140. package/dist/lib/util/useScrollToTop.js.map +1 -1
  141. package/dist/vite/build.js +4 -1
  142. package/dist/vite/build.js.map +1 -1
  143. package/dist/vite/config.d.ts +5 -1
  144. package/dist/vite/config.js +50 -25
  145. package/dist/vite/config.js.map +1 -1
  146. package/dist/vite/config.test.js +4 -1
  147. package/dist/vite/config.test.js.map +1 -1
  148. package/dist/vite/css/collect.d.ts +2 -0
  149. package/dist/vite/css/collect.js +27 -0
  150. package/dist/vite/css/collect.js.map +1 -0
  151. package/dist/vite/css/plugin.d.ts +5 -0
  152. package/dist/vite/css/plugin.js +79 -0
  153. package/dist/vite/css/plugin.js.map +1 -0
  154. package/dist/vite/dev-server.d.ts +1 -0
  155. package/dist/vite/dev-server.js +16 -6
  156. package/dist/vite/dev-server.js.map +1 -1
  157. package/dist/vite/plugin-api.js +52 -19
  158. package/dist/vite/plugin-api.js.map +1 -1
  159. package/dist/vite/plugin-mdx.js +2 -0
  160. package/dist/vite/plugin-mdx.js.map +1 -1
  161. package/dist/vite/plugin-theme-css.js +53 -1
  162. package/dist/vite/plugin-theme-css.js.map +1 -1
  163. package/dist/vite/plugin.js +4 -0
  164. package/dist/vite/plugin.js.map +1 -1
  165. package/lib/{AnchorLink-BR0MvI7n.js → AnchorLink-DFZZbmvr.js} +13 -14
  166. package/lib/AnchorLink-DFZZbmvr.js.map +1 -0
  167. package/lib/{AuthenticationPlugin-D0Em0SwR.js → AuthenticationPlugin-DVLEc6cm.js} +15 -16
  168. package/lib/AuthenticationPlugin-DVLEc6cm.js.map +1 -0
  169. package/lib/{Button-jK0EsymC.js → Button-DeAoTouo.js} +4 -4
  170. package/lib/{Button-jK0EsymC.js.map → Button-DeAoTouo.js.map} +1 -1
  171. package/lib/{CategoryHeading-Bb9dqxD3.js → CategoryHeading-CBconmtI.js} +3 -3
  172. package/lib/{CategoryHeading-Bb9dqxD3.js.map → CategoryHeading-CBconmtI.js.map} +1 -1
  173. package/lib/ClientOnly-E7hGysn1.js.map +1 -1
  174. package/lib/{Dialog-k70Qfukb.js → Dialog-Bxv1yEIg.js} +3 -3
  175. package/lib/{Dialog-k70Qfukb.js.map → Dialog-Bxv1yEIg.js.map} +1 -1
  176. package/lib/{Markdown-CdkU5HcM.js → Markdown-CZDLNOFc.js} +13235 -13225
  177. package/lib/Markdown-CZDLNOFc.js.map +1 -0
  178. package/lib/{MdxPage-ChziqNPp.js → MdxPage-DKMbBROv.js} +25 -25
  179. package/lib/MdxPage-DKMbBROv.js.map +1 -0
  180. package/lib/OperationList-CqLL5P5l.js +5068 -0
  181. package/lib/OperationList-CqLL5P5l.js.map +1 -0
  182. package/lib/Route-DYwKZ_c_.js +35 -0
  183. package/lib/Route-DYwKZ_c_.js.map +1 -0
  184. package/lib/{Select-O9ZM3ZgX.js → Select-B_IxRUUC.js} +5 -5
  185. package/lib/{Select-O9ZM3ZgX.js.map → Select-B_IxRUUC.js.map} +1 -1
  186. package/lib/SlotletProvider-pfc9oejW.js +221 -0
  187. package/lib/SlotletProvider-pfc9oejW.js.map +1 -0
  188. package/lib/{Spinner-3cQDBVGr.js → Spinner-DuxJLLNE.js} +2 -2
  189. package/lib/{Spinner-3cQDBVGr.js.map → Spinner-DuxJLLNE.js.map} +1 -1
  190. package/lib/StaggeredRender-DgsamH_G.js +17 -0
  191. package/lib/StaggeredRender-DgsamH_G.js.map +1 -0
  192. package/lib/{SyntaxHighlight-C31iouiO.js → SyntaxHighlight-Bz-lOJtH.js} +8 -10
  193. package/lib/{SyntaxHighlight-C31iouiO.js.map → SyntaxHighlight-Bz-lOJtH.js.map} +1 -1
  194. package/lib/{utils-DcpDOncX.js → ZudokuContext-hmLMUdf2.js} +54 -55
  195. package/lib/ZudokuContext-hmLMUdf2.js.map +1 -0
  196. package/lib/assets/{index-B_Jk_Yzp.js → index-C7jnHK4b.js} +218 -197
  197. package/lib/assets/index-C7jnHK4b.js.map +1 -0
  198. package/lib/assets/{worker-C_2va8B8.js → worker-DV9Ecqy9.js} +5267 -4887
  199. package/lib/assets/worker-DV9Ecqy9.js.map +1 -0
  200. package/lib/chunk-D52XG6IA-Dl7HLe6j.js +1823 -0
  201. package/lib/chunk-D52XG6IA-Dl7HLe6j.js.map +1 -0
  202. package/lib/{cn-BmFQLtkS.js → cn-qaFjX9_3.js} +2 -2
  203. package/lib/cn-qaFjX9_3.js.map +1 -0
  204. package/lib/{context-D1nXWxm7.js → context-h_UkBLvr.js} +2 -2
  205. package/lib/context-h_UkBLvr.js.map +1 -0
  206. package/lib/{createServer-BCAHdrpE.js → createServer-C4C0OO0m.js} +4804 -4462
  207. package/lib/createServer-C4C0OO0m.js.map +1 -0
  208. package/lib/{hook-hEqe7fPB.js → hook-CHq7pFyz.js} +3 -3
  209. package/lib/{hook-hEqe7fPB.js.map → hook-CHq7pFyz.js.map} +1 -1
  210. package/lib/{index-CkwDvuPt.js → index-CBXSgjaE.js} +259 -238
  211. package/lib/index-CBXSgjaE.js.map +1 -0
  212. package/lib/index-CPNSgwSb.js +36 -0
  213. package/lib/index-CPNSgwSb.js.map +1 -0
  214. package/lib/index-DyBL--Kz.js +826 -0
  215. package/lib/index-DyBL--Kz.js.map +1 -0
  216. package/lib/{index-DjB6H4GT.js → index-DzRORsY1.js} +444 -441
  217. package/lib/index-DzRORsY1.js.map +1 -0
  218. package/lib/index-LNp6rxyU.js.map +1 -1
  219. package/lib/index.esm-BSV1C092.js +692 -0
  220. package/lib/{index.esm-Bm8pj-bc.js.map → index.esm-BSV1C092.js.map} +1 -1
  221. package/lib/index.esm-BnnBRKJX.js +1214 -0
  222. package/lib/index.esm-BnnBRKJX.js.map +1 -0
  223. package/lib/invariant-Caa8-XvF.js.map +1 -1
  224. package/lib/jsx-runtime-Dx-03ztt.js +446 -0
  225. package/lib/jsx-runtime-Dx-03ztt.js.map +1 -0
  226. package/lib/post-processors/removeExtensions.js.map +1 -1
  227. package/lib/post-processors/removePaths.js.map +1 -1
  228. package/lib/post-processors/traverse.js.map +1 -1
  229. package/lib/prism-csharp.min-DUwvItt4.js +63 -0
  230. package/lib/{prism-csharp.min-Yizuc34Y.js.map → prism-csharp.min-DUwvItt4.js.map} +1 -1
  231. package/lib/prism-java.min-BtgBR4yd.js +35 -0
  232. package/lib/{prism-java.min-d5iT_mOd.js.map → prism-java.min-BtgBR4yd.js.map} +1 -1
  233. package/lib/prism-markup-BNGj0Tvm.js.map +1 -1
  234. package/lib/prism-ruby.min-DeDXCp1r.js +38 -0
  235. package/lib/{prism-ruby.min-C7LwcKyz.js.map → prism-ruby.min-DeDXCp1r.js.map} +1 -1
  236. package/lib/prism-typescript.min-CD7H2IYQ.js +34 -0
  237. package/lib/{prism-typescript.min-oSVeWCAd.js.map → prism-typescript.min-CD7H2IYQ.js.map} +1 -1
  238. package/lib/state-CFQsUZUP.js +202 -0
  239. package/lib/state-CFQsUZUP.js.map +1 -0
  240. package/lib/ui/Accordion.js +2 -2
  241. package/lib/ui/Accordion.js.map +1 -1
  242. package/lib/ui/ActionButton.js +4 -4
  243. package/lib/ui/ActionButton.js.map +1 -1
  244. package/lib/ui/Alert.js +3 -3
  245. package/lib/ui/Alert.js.map +1 -1
  246. package/lib/ui/AlertDialog.js +2 -2
  247. package/lib/ui/AlertDialog.js.map +1 -1
  248. package/lib/ui/Badge.js +3 -3
  249. package/lib/ui/Badge.js.map +1 -1
  250. package/lib/ui/Breadcrumb.js +2 -2
  251. package/lib/ui/Breadcrumb.js.map +1 -1
  252. package/lib/ui/Button.js +3 -3
  253. package/lib/ui/Button.js.map +1 -1
  254. package/lib/ui/Callout.js +2 -2
  255. package/lib/ui/Callout.js.map +1 -1
  256. package/lib/ui/Card.js +2 -2
  257. package/lib/ui/Card.js.map +1 -1
  258. package/lib/ui/Carousel.js +407 -401
  259. package/lib/ui/Carousel.js.map +1 -1
  260. package/lib/ui/Checkbox.js +2 -2
  261. package/lib/ui/Checkbox.js.map +1 -1
  262. package/lib/ui/Command.js +111 -108
  263. package/lib/ui/Command.js.map +1 -1
  264. package/lib/ui/Dialog.js +2 -2
  265. package/lib/ui/Dialog.js.map +1 -1
  266. package/lib/ui/Drawer.js +2 -2
  267. package/lib/ui/Drawer.js.map +1 -1
  268. package/lib/ui/DropdownMenu.js +2 -2
  269. package/lib/ui/DropdownMenu.js.map +1 -1
  270. package/lib/ui/Form.js +3 -3
  271. package/lib/ui/Form.js.map +1 -1
  272. package/lib/ui/HoverCard.js +2 -2
  273. package/lib/ui/Input.js +2 -2
  274. package/lib/ui/Input.js.map +1 -1
  275. package/lib/ui/Label.js +3 -3
  276. package/lib/ui/Pagination.js +2 -2
  277. package/lib/ui/Pagination.js.map +1 -1
  278. package/lib/ui/Popover.js +2 -2
  279. package/lib/ui/Popover.js.map +1 -1
  280. package/lib/ui/Progress.js +2 -2
  281. package/lib/ui/Progress.js.map +1 -1
  282. package/lib/ui/RadioGroup.js +2 -2
  283. package/lib/ui/RadioGroup.js.map +1 -1
  284. package/lib/ui/ScrollArea.js +2 -2
  285. package/lib/ui/ScrollArea.js.map +1 -1
  286. package/lib/ui/Select.js +2 -2
  287. package/lib/ui/Select.js.map +1 -1
  288. package/lib/ui/Skeleton.js +2 -2
  289. package/lib/ui/Skeleton.js.map +1 -1
  290. package/lib/ui/Slider.js +2 -2
  291. package/lib/ui/Switch.js +2 -2
  292. package/lib/ui/Switch.js.map +1 -1
  293. package/lib/ui/Tabs.js +2 -2
  294. package/lib/ui/Textarea.js +2 -2
  295. package/lib/ui/Textarea.js.map +1 -1
  296. package/lib/ui/Toggle.js +3 -3
  297. package/lib/ui/Toggle.js.map +1 -1
  298. package/lib/ui/ToggleGroup.js +2 -2
  299. package/lib/ui/ToggleGroup.js.map +1 -1
  300. package/lib/ui/Tooltip.js +2 -2
  301. package/lib/useExposedProps-DE9lR6MF.js +9 -0
  302. package/lib/useExposedProps-DE9lR6MF.js.map +1 -0
  303. package/lib/zudoku.auth-auth0.js +1 -1
  304. package/lib/zudoku.auth-auth0.js.map +1 -1
  305. package/lib/zudoku.auth-clerk.js +2 -2
  306. package/lib/zudoku.auth-clerk.js.map +1 -1
  307. package/lib/zudoku.auth-openid.js +369 -366
  308. package/lib/zudoku.auth-openid.js.map +1 -1
  309. package/lib/zudoku.components.js +722 -959
  310. package/lib/zudoku.components.js.map +1 -1
  311. package/lib/zudoku.openapi-worker.js +1 -1
  312. package/lib/zudoku.openapi-worker.js.map +1 -1
  313. package/lib/zudoku.plugin-api-catalog.js +81 -79
  314. package/lib/zudoku.plugin-api-catalog.js.map +1 -1
  315. package/lib/zudoku.plugin-api-keys.js +15 -16
  316. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  317. package/lib/zudoku.plugin-custom-pages.js +4 -4
  318. package/lib/zudoku.plugin-custom-pages.js.map +1 -1
  319. package/lib/zudoku.plugin-markdown.js +2 -2
  320. package/lib/zudoku.plugin-markdown.js.map +1 -1
  321. package/lib/zudoku.plugin-openapi.js +5 -5
  322. package/lib/zudoku.plugin-redirect.js +1 -1
  323. package/lib/zudoku.plugin-redirect.js.map +1 -1
  324. package/lib/zudoku.plugin-search-inkeep.js +53 -24
  325. package/lib/zudoku.plugin-search-inkeep.js.map +1 -1
  326. package/package.json +52 -47
  327. package/src/app/demo.tsx +1 -1
  328. package/src/app/entry.client.tsx +1 -15
  329. package/src/app/entry.server.tsx +2 -2
  330. package/src/app/main.tsx +1 -1
  331. package/src/app/sentry.ts +1 -1
  332. package/src/app/standalone.tsx +1 -1
  333. package/src/lib/authentication/components/CallbackHandler.tsx +1 -1
  334. package/src/lib/authentication/components/SignIn.tsx +1 -1
  335. package/src/lib/authentication/components/SignOut.tsx +1 -1
  336. package/src/lib/authentication/providers/openid.tsx +5 -3
  337. package/src/lib/components/AnchorLink.tsx +1 -1
  338. package/src/lib/components/Bootstrap.tsx +4 -6
  339. package/src/lib/components/Header.tsx +2 -2
  340. package/src/lib/components/Layout.tsx +2 -2
  341. package/src/lib/components/Markdown.tsx +1 -1
  342. package/src/lib/components/MobileTopNavigation.tsx +1 -1
  343. package/src/lib/components/NotFoundPage.tsx +1 -1
  344. package/src/lib/components/ReactMarkdown.license.txt +21 -0
  345. package/src/lib/components/ReactMarkdown.tsx +264 -0
  346. package/src/lib/components/SlotletProvider.tsx +1 -1
  347. package/src/lib/components/TopNavigation.tsx +1 -1
  348. package/src/lib/components/Zudoku.tsx +1 -1
  349. package/src/lib/components/context/ZudokuContext.ts +1 -1
  350. package/src/lib/components/index.ts +8 -4
  351. package/src/lib/components/navigation/Sidebar.tsx +1 -1
  352. package/src/lib/components/navigation/SidebarBadge.tsx +0 -10
  353. package/src/lib/components/navigation/SidebarCategory.tsx +1 -1
  354. package/src/lib/components/navigation/SidebarItem.tsx +1 -1
  355. package/src/lib/components/navigation/utils.ts +1 -1
  356. package/src/lib/core/plugins.ts +3 -7
  357. package/src/lib/errors/RouterError.tsx +1 -1
  358. package/src/lib/oas/parser/dereference/index.ts +9 -4
  359. package/src/lib/plugins/api-catalog/Catalog.tsx +59 -60
  360. package/src/lib/plugins/api-catalog/index.tsx +14 -0
  361. package/src/lib/plugins/api-keys/CreateApiKey.tsx +1 -1
  362. package/src/lib/plugins/api-keys/ProtectedRoute.tsx +1 -1
  363. package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +1 -1
  364. package/src/lib/plugins/api-keys/index.tsx +1 -1
  365. package/src/lib/plugins/custom-pages/index.tsx +1 -1
  366. package/src/lib/plugins/markdown/MdxPage.tsx +1 -1
  367. package/src/lib/plugins/markdown/index.tsx +2 -1
  368. package/src/lib/plugins/openapi/OperationList.tsx +45 -50
  369. package/src/lib/plugins/openapi/OperationListItem.tsx +31 -2
  370. package/src/lib/plugins/openapi/Route.tsx +41 -9
  371. package/src/lib/plugins/openapi/Sidecar.tsx +3 -17
  372. package/src/lib/plugins/openapi/client/useCreateQuery.ts +13 -1
  373. package/src/lib/plugins/openapi/context.tsx +2 -2
  374. package/src/lib/plugins/openapi/index.tsx +37 -28
  375. package/src/lib/plugins/openapi/interfaces.ts +22 -1
  376. package/src/lib/plugins/openapi/schema/SchemaComponents.tsx +25 -1
  377. package/src/lib/plugins/openapi/util/methodToColor.ts +27 -0
  378. package/src/lib/plugins/openapi/util/sanitizeMarkdownForMetatag.tsx +32 -0
  379. package/src/lib/plugins/redirect/index.tsx +1 -1
  380. package/src/lib/plugins/search-inkeep/index.tsx +78 -23
  381. package/src/lib/plugins/search-inkeep/inkeep.ts +3 -9
  382. package/src/lib/util/MdxComponents.tsx +1 -3
  383. package/src/lib/util/createVariantComponent.tsx +2 -2
  384. package/src/lib/util/useExposedProps.tsx +1 -1
  385. package/src/lib/util/useScrollToAnchor.ts +1 -1
  386. package/src/lib/util/useScrollToTop.ts +1 -1
  387. package/dist/lib/plugins/search-inkeep/InkeepCustomTrigger.d.ts +0 -2
  388. package/dist/lib/plugins/search-inkeep/InkeepCustomTrigger.js +0 -3
  389. package/dist/lib/plugins/search-inkeep/InkeepCustomTrigger.js.map +0 -1
  390. package/lib/AnchorLink-BR0MvI7n.js.map +0 -1
  391. package/lib/AuthenticationPlugin-D0Em0SwR.js.map +0 -1
  392. package/lib/InkeepCustomTrigger-CE5-K5ex.js +0 -6
  393. package/lib/InkeepCustomTrigger-CE5-K5ex.js.map +0 -1
  394. package/lib/Markdown-CdkU5HcM.js.map +0 -1
  395. package/lib/MdxPage-ChziqNPp.js.map +0 -1
  396. package/lib/OperationList-CQKkyrZH.js +0 -4706
  397. package/lib/OperationList-CQKkyrZH.js.map +0 -1
  398. package/lib/Route-DlG_HTMu.js +0 -11
  399. package/lib/Route-DlG_HTMu.js.map +0 -1
  400. package/lib/SidebarBadge-DxFJcJ6V.js +0 -51
  401. package/lib/SidebarBadge-DxFJcJ6V.js.map +0 -1
  402. package/lib/SlotletProvider-D77pO-fA.js +0 -252
  403. package/lib/SlotletProvider-D77pO-fA.js.map +0 -1
  404. package/lib/assets/index-B_Jk_Yzp.js.map +0 -1
  405. package/lib/assets/worker-C_2va8B8.js.map +0 -1
  406. package/lib/cn-BmFQLtkS.js.map +0 -1
  407. package/lib/context-D1nXWxm7.js.map +0 -1
  408. package/lib/createServer-BCAHdrpE.js.map +0 -1
  409. package/lib/index-BuAyrJe3.js +0 -46
  410. package/lib/index-BuAyrJe3.js.map +0 -1
  411. package/lib/index-CkwDvuPt.js.map +0 -1
  412. package/lib/index-Czzd9rjU.js +0 -899
  413. package/lib/index-Czzd9rjU.js.map +0 -1
  414. package/lib/index-DjB6H4GT.js.map +0 -1
  415. package/lib/index-Yn8c3UWE.js +0 -921
  416. package/lib/index-Yn8c3UWE.js.map +0 -1
  417. package/lib/index.esm-Bm8pj-bc.js +0 -675
  418. package/lib/index.esm-C5mr_sKO.js +0 -1193
  419. package/lib/index.esm-C5mr_sKO.js.map +0 -1
  420. package/lib/jsx-runtime-B6kdoens.js +0 -635
  421. package/lib/jsx-runtime-B6kdoens.js.map +0 -1
  422. package/lib/object_hash-CvlLgU-M.js +0 -785
  423. package/lib/object_hash-CvlLgU-M.js.map +0 -1
  424. package/lib/prism-csharp.min-Yizuc34Y.js +0 -35
  425. package/lib/prism-java.min-d5iT_mOd.js +0 -7
  426. package/lib/prism-ruby.min-C7LwcKyz.js +0 -10
  427. package/lib/prism-typescript.min-oSVeWCAd.js +0 -6
  428. package/lib/router-lfyopgBI.js +0 -3024
  429. package/lib/router-lfyopgBI.js.map +0 -1
  430. package/lib/state-tsXBLONe.js +0 -203
  431. package/lib/state-tsXBLONe.js.map +0 -1
  432. package/lib/useExposedProps-CTPtylCV.js +0 -10
  433. package/lib/useExposedProps-CTPtylCV.js.map +0 -1
  434. package/lib/utils-DcpDOncX.js.map +0 -1
  435. package/src/lib/plugins/search-inkeep/InkeepCustomTrigger.tsx +0 -3
@@ -1,3 +1,4 @@
1
+ import type { AuthState } from "../../authentication/state.js";
1
2
  import type { ZudokuPlugin } from "../../core/plugins.js";
2
3
  import { Catalog } from "./Catalog.js";
3
4
 
@@ -18,18 +19,30 @@ export type ApiCatalogPluginOptions = {
18
19
  label: string;
19
20
  categories?: CatalogCategory[];
20
21
  items: ApiCatalogItem[];
22
+ filterCatalogItems?: filterCatalogItems;
21
23
  };
22
24
 
25
+ export type CatalogContext<ProviderData = unknown> = {
26
+ auth: AuthState<ProviderData>;
27
+ };
28
+
29
+ export type filterCatalogItems<ProviderData = unknown> = (
30
+ items: ApiCatalogItem[],
31
+ { auth }: CatalogContext<ProviderData>,
32
+ ) => ApiCatalogItem[];
33
+
23
34
  export const apiCatalogPlugin = ({
24
35
  navigationId,
25
36
  items,
26
37
  label,
27
38
  categories,
39
+ filterCatalogItems,
28
40
  }: {
29
41
  navigationId: string;
30
42
  label: string;
31
43
  categories?: CatalogCategory[];
32
44
  items: ApiCatalogItem[];
45
+ filterCatalogItems?: filterCatalogItems;
33
46
  }): ZudokuPlugin => {
34
47
  return {
35
48
  getRoutes: () => {
@@ -40,6 +53,7 @@ export const apiCatalogPlugin = ({
40
53
  <Catalog
41
54
  label={label}
42
55
  items={items}
56
+ filterCatalogItems={filterCatalogItems}
43
57
  categories={categories ?? []}
44
58
  />
45
59
  ),
@@ -1,6 +1,6 @@
1
1
  import { useMutation } from "@tanstack/react-query";
2
2
  import { useForm } from "react-hook-form";
3
- import { Link, useNavigate } from "react-router-dom";
3
+ import { Link, useNavigate } from "react-router";
4
4
  import {
5
5
  Select,
6
6
  SelectContent,
@@ -1,4 +1,4 @@
1
- import { Outlet } from "react-router-dom";
1
+ import { Outlet } from "react-router";
2
2
  import { useAuth } from "../../authentication/hook.js";
3
3
  import { DeveloperHint } from "../../components/DeveloperHint.js";
4
4
  import { Button } from "../../ui/Button.js";
@@ -12,7 +12,7 @@ import {
12
12
  TrashIcon,
13
13
  } from "lucide-react";
14
14
  import { useState } from "react";
15
- import { Link } from "react-router-dom";
15
+ import { Link } from "react-router";
16
16
  import { useZudoku } from "../../components/context/ZudokuContext.js";
17
17
  import { Slotlet } from "../../components/SlotletProvider.js";
18
18
  import { Button } from "../../ui/Button.js";
@@ -1,5 +1,5 @@
1
1
  import { FileKey2Icon } from "lucide-react";
2
- import { type RouteObject } from "react-router-dom";
2
+ import { type RouteObject } from "react-router";
3
3
  import { ZudokuContext } from "../../core/ZudokuContext.js";
4
4
  import {
5
5
  type ApiIdentityPlugin,
@@ -1,5 +1,5 @@
1
1
  import { type ComponentType, type ReactNode } from "react";
2
- import type { RouteObject } from "react-router-dom";
2
+ import type { RouteObject } from "react-router";
3
3
  import { type ExposedComponentProps } from "../../components/SlotletProvider.js";
4
4
  import type { NavigationPlugin, ZudokuPlugin } from "../../core/plugins.js";
5
5
  import { CustomPage } from "./CustomPage.js";
@@ -2,7 +2,7 @@ import { useMDXComponents } from "@mdx-js/react";
2
2
  import slugify from "@sindresorhus/slugify";
3
3
  import { Helmet } from "@zudoku/react-helmet-async";
4
4
  import { type PropsWithChildren, useEffect } from "react";
5
- import { Link } from "react-router-dom";
5
+ import { Link } from "react-router";
6
6
  import { CategoryHeading } from "../../components/CategoryHeading.js";
7
7
  import { Heading } from "../../components/Heading.js";
8
8
  import { ProseClasses } from "../../components/Markdown.js";
@@ -1,6 +1,7 @@
1
1
  import type { Toc } from "@stefanprobst/rehype-extract-toc";
2
2
  import type { MDXProps } from "mdx/types.js";
3
- import { RouteObject } from "react-router-dom";
3
+ import { type JSX } from "react";
4
+ import { RouteObject } from "react-router";
4
5
  import { ZudokuDocsConfig } from "../../../config/validators/common.js";
5
6
  import type { ZudokuPlugin } from "../../core/plugins.js";
6
7
  import { DocResolver } from "./resolver.js";
@@ -1,6 +1,15 @@
1
1
  import { ResultOf } from "@graphql-typed-document-node/core";
2
2
  import { useSuspenseQuery } from "@tanstack/react-query";
3
3
  import { Helmet } from "@zudoku/react-helmet-async";
4
+ import { useNavigate } from "react-router";
5
+ import {
6
+ Select,
7
+ SelectContent,
8
+ SelectItem,
9
+ SelectTrigger,
10
+ SelectValue,
11
+ } from "zudoku/ui/Select.js";
12
+ import { useSelectedServerStore } from "../../authentication/state.js";
4
13
  import { CategoryHeading } from "../../components/CategoryHeading.js";
5
14
  import { Heading } from "../../components/Heading.js";
6
15
  import { Markdown, ProseClasses } from "../../components/Markdown.js";
@@ -11,6 +20,7 @@ import StaggeredRender from "./StaggeredRender.js";
11
20
  import { useCreateQuery } from "./client/useCreateQuery.js";
12
21
  import { useOasConfig } from "./context.js";
13
22
  import { graphql } from "./graphql/index.js";
23
+ import { sanitizeMarkdownForMetatag } from "./util/sanitizeMarkdownForMetatag.js";
14
24
 
15
25
  export const OperationsFragment = graphql(/* GraphQL */ `
16
26
  fragment OperationsFragment on OperationItem {
@@ -98,63 +108,25 @@ const AllOperationsQuery = graphql(/* GraphQL */ `
98
108
  }
99
109
  `);
100
110
 
101
- /**
102
- * @description Clean up a commonmark formatted description for use in the meta
103
- * description.
104
- */
105
- function cleanDescription(
106
- description: string,
107
- maxLength: number = 160,
108
- ): string {
109
- if (!description) {
110
- return "";
111
- }
112
-
113
- // Replace Markdown links [text](url) with just "text"
114
- description = description.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
115
-
116
- // Remove Markdown image syntax: ![alt](url)
117
- description = description.replace(/!\[.*?\]\(.*?\)/g, "");
118
-
119
- // Remove other Markdown syntax (e.g., **bold**, _italic_, `code`)
120
- description = description.replace(/[_*`~]/g, "");
121
-
122
- // Remove headings (# Heading), blockquotes (> Quote), and horizontal rules (--- or ***)
123
- description = description.replace(/^(?:>|\s*#+|-{3,}|\*{3,})/gm, "");
124
-
125
- // Remove any remaining formatting characters
126
- description = description.replace(/[|>{}[\]]/g, "");
127
-
128
- // Collapse multiple spaces and trim the text
129
- description = description.replace(/\s+/g, " ").trim();
130
-
131
- // Limit to the specified maximum length
132
- description = description.substring(0, maxLength);
133
-
134
- // Escape for HTML safety
135
- return description
136
- .replace(/&/g, "&amp;")
137
- .replace(/</g, "&lt;")
138
- .replace(/>/g, "&gt;")
139
- .replace(/"/g, "&quot;")
140
- .replace(/'/g, "&#039;");
141
- }
142
-
143
111
  export const OperationList = () => {
144
- const { input, type } = useOasConfig();
112
+ const { input, type, versions, version } = useOasConfig();
145
113
  const query = useCreateQuery(AllOperationsQuery, { input, type });
114
+ const { selectedServer } = useSelectedServerStore();
146
115
  const result = useSuspenseQuery(query);
147
116
  const title = result.data.schema.title;
148
117
  const summary = result.data.schema.summary;
149
118
  const description = result.data.schema.description;
119
+ const navigate = useNavigate();
120
+
150
121
  // The summary property is preferable here as it is a short description of
151
122
  // the API, whereas the description property is typically longer and supports
152
123
  // commonmark formatting, making it ill-suited for use in the meta description
153
124
  const metaDescription = summary
154
125
  ? summary
155
126
  : description
156
- ? cleanDescription(description)
127
+ ? sanitizeMarkdownForMetatag(description)
157
128
  : undefined;
129
+
158
130
  return (
159
131
  <div className="pt-[--padding-content-top]">
160
132
  <Helmet>
@@ -166,17 +138,39 @@ export const OperationList = () => {
166
138
  <div
167
139
  className={cn(ProseClasses, "mb-16 max-w-full prose-img:max-w-prose")}
168
140
  >
169
- <CategoryHeading>Overview</CategoryHeading>
170
- <Heading level={1} id="description" registerSidebarAnchor>
171
- {title}
172
- </Heading>
141
+ <div className="flex">
142
+ <div className="flex-1">
143
+ <CategoryHeading>Overview</CategoryHeading>
144
+ <Heading level={1} id="description" registerSidebarAnchor>
145
+ {title}
146
+ </Heading>
147
+ </div>
148
+ <div>
149
+ {Object.entries(versions).length > 1 && (
150
+ <Select
151
+ onValueChange={(version) => navigate(versions[version]!)}
152
+ defaultValue={version}
153
+ >
154
+ <SelectTrigger className="w-[180px]">
155
+ <SelectValue placeholder="Select version" />
156
+ </SelectTrigger>
157
+ <SelectContent>
158
+ {Object.entries(versions).map(([version]) => (
159
+ <SelectItem key={version} value={version}>
160
+ {version}
161
+ </SelectItem>
162
+ ))}
163
+ </SelectContent>
164
+ </Select>
165
+ )}
166
+ </div>
167
+ </div>
173
168
  <Markdown content={result.data.schema.description ?? ""} />
174
169
  </div>
175
170
  <hr />
176
- <div className="my-4 flex justify-end">
171
+ <div className="my-4 flex items-center justify-end gap-4">
177
172
  <Endpoint />
178
173
  </div>
179
-
180
174
  {result.data.schema.tags
181
175
  .filter((tag) => tag.operations.length > 0)
182
176
  .map((tag) => (
@@ -193,6 +187,7 @@ export const OperationList = () => {
193
187
  <StaggeredRender>
194
188
  {tag.operations.map((fragment) => (
195
189
  <OperationListItem
190
+ serverUrl={selectedServer ?? result.data.schema.url}
196
191
  key={fragment.slug}
197
192
  operationFragment={fragment}
198
193
  />
@@ -1,4 +1,4 @@
1
- import { useState } from "react";
1
+ import { useRef, useState } from "react";
2
2
  import { Heading } from "../../components/Heading.js";
3
3
  import { Markdown, ProseClasses } from "../../components/Markdown.js";
4
4
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/Tabs.js";
@@ -9,20 +9,24 @@ import { ParameterList } from "./ParameterList.js";
9
9
  import { Sidecar } from "./Sidecar.js";
10
10
  import { FragmentType, useFragment } from "./graphql/index.js";
11
11
  import { SchemaView } from "./schema/SchemaView.js";
12
+ import { methodForColor } from "./util/methodToColor.js";
12
13
 
13
14
  export const PARAM_GROUPS = ["path", "query", "header", "cookie"] as const;
14
15
  export type ParameterGroup = (typeof PARAM_GROUPS)[number];
15
16
 
16
17
  export const OperationListItem = ({
17
18
  operationFragment,
19
+ serverUrl,
18
20
  }: {
19
21
  operationFragment: FragmentType<typeof OperationsFragment>;
22
+ serverUrl?: string;
20
23
  }) => {
21
24
  const operation = useFragment(OperationsFragment, operationFragment);
22
25
  const groupedParameters = groupBy(
23
26
  operation.parameters ?? [],
24
27
  (param) => param.in,
25
28
  );
29
+ const parentRef = useRef<HTMLDivElement>(null);
26
30
 
27
31
  const first = operation.responses.at(0);
28
32
  const [selectedResponse, setSelectedResponse] = useState(first?.statusCode);
@@ -30,12 +34,37 @@ export const OperationListItem = ({
30
34
  return (
31
35
  <div
32
36
  key={operation.operationId}
33
- className="grid grid-cols-1 lg:grid-cols-[4fr_3fr] gap-8 items-start border-b-2 mb-16 pb-16"
37
+ className="grid grid-cols-1 lg:grid-cols-[minmax(0,4fr)_minmax(0,3fr)] gap-8 items-start border-b-2 mb-16 pb-16"
34
38
  >
35
39
  <div className="flex flex-col gap-4">
36
40
  <Heading level={2} id={operation.slug} registerSidebarAnchor>
37
41
  {operation.summary}
38
42
  </Heading>
43
+ <div className="text-sm flex gap-2 font-mono">
44
+ <span className={methodForColor(operation.method)}>
45
+ {operation.method.toUpperCase()}
46
+ </span>
47
+ <div
48
+ ref={parentRef}
49
+ className="max-w-full truncate flex cursor-pointer"
50
+ onClick={() => {
51
+ if (parentRef.current) {
52
+ const range = document.createRange();
53
+ range.selectNodeContents(parentRef.current);
54
+ const selection = window.getSelection();
55
+ selection?.removeAllRanges();
56
+ selection?.addRange(range);
57
+ }
58
+ }}
59
+ >
60
+ <div className="text-neutral-400 dark:text-neutral-500 truncate">
61
+ {serverUrl}
62
+ </div>
63
+ <div className="text-neutral-900 dark:text-neutral-200">
64
+ {operation.path}
65
+ </div>
66
+ </div>
67
+ </div>
39
68
  {operation.description && (
40
69
  <Markdown
41
70
  className={`${ProseClasses} max-w-full prose-img:max-w-prose`}
@@ -1,19 +1,51 @@
1
- import { Outlet } from "react-router-dom";
1
+ import { Outlet, useParams } from "react-router";
2
+ import { joinPath } from "../../util/joinPath.js";
2
3
  import type { GraphQLClient } from "./client/GraphQLClient.js";
3
4
  import { GraphQLProvider } from "./client/GraphQLContext.js";
4
5
  import { OasConfigProvider } from "./context.js";
5
- import { OasPluginConfig } from "./interfaces.js";
6
+ import { type OasPluginConfig } from "./interfaces.js";
6
7
 
7
8
  export const OpenApiRoute = ({
9
+ basePath,
10
+ versions,
8
11
  config,
9
12
  client,
10
13
  }: {
14
+ basePath: string;
15
+ versions: string[];
11
16
  config: OasPluginConfig;
12
17
  client: GraphQLClient;
13
- }) => (
14
- <OasConfigProvider value={{ config }}>
15
- <GraphQLProvider client={client}>
16
- <Outlet />
17
- </GraphQLProvider>
18
- </OasConfigProvider>
19
- );
18
+ }) => {
19
+ const { version } = useParams<"version">();
20
+
21
+ const input =
22
+ config.type === "file"
23
+ ? {
24
+ type: config.type,
25
+ input: version
26
+ ? config.input[version]!
27
+ : Object.values(config.input).at(0)!,
28
+ }
29
+ : { type: config.type, input: config.input };
30
+
31
+ const currentVersion = version ?? versions.at(0);
32
+
33
+ return (
34
+ <OasConfigProvider
35
+ value={{
36
+ config: {
37
+ ...config,
38
+ version: currentVersion,
39
+ versions: Object.fromEntries(
40
+ versions.map((version) => [version, joinPath(basePath, version)]),
41
+ ),
42
+ ...input,
43
+ },
44
+ }}
45
+ >
46
+ <GraphQLProvider client={client}>
47
+ <Outlet />
48
+ </GraphQLProvider>
49
+ </OasConfigProvider>
50
+ );
51
+ };
@@ -1,9 +1,8 @@
1
1
  import { useSuspenseQuery } from "@tanstack/react-query";
2
2
  import { HTTPSnippet } from "@zudoku/httpsnippet";
3
3
  import { Fragment, useMemo, useTransition } from "react";
4
- import { useSearchParams } from "react-router-dom";
4
+ import { useSearchParams } from "react-router";
5
5
  import { useSelectedServerStore } from "../../authentication/state.js";
6
- import { TextColorMap } from "../../components/navigation/SidebarBadge.js";
7
6
  import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
8
7
  import type { SchemaObject } from "../../oas/parser/index.js";
9
8
  import { cn } from "../../util/cn.js";
@@ -20,6 +19,7 @@ import { ResponsesSidecarBox } from "./ResponsesSidecarBox.js";
20
19
  import * as SidecarBox from "./SidecarBox.js";
21
20
  import { SimpleSelect } from "./SimpleSelect.js";
22
21
  import { generateSchemaExample } from "./util/generateSchemaExample.js";
22
+ import { methodForColor } from "./util/methodToColor.js";
23
23
 
24
24
  const getConverted = (snippet: HTTPSnippet, option: string) => {
25
25
  let converted;
@@ -76,17 +76,6 @@ export const GetServerQuery = graphql(/* GraphQL */ `
76
76
  }
77
77
  `);
78
78
 
79
- const methodToColor = {
80
- get: TextColorMap.green,
81
- post: TextColorMap.blue,
82
- put: TextColorMap.yellow,
83
- delete: TextColorMap.red,
84
- patch: TextColorMap.purple,
85
- options: TextColorMap.indigo,
86
- head: TextColorMap.gray,
87
- trace: TextColorMap.gray,
88
- };
89
-
90
79
  const EXAMPLE_LANGUAGES = [
91
80
  { value: "shell", label: "cURL" },
92
81
  { value: "js", label: "JavaScript" },
@@ -114,10 +103,7 @@ export const Sidecar = ({
114
103
  const query = useCreateQuery(GetServerQuery, { input, type });
115
104
  const result = useSuspenseQuery(query);
116
105
 
117
- const methodTextColor =
118
- methodToColor[
119
- operation.method.toLocaleLowerCase() as keyof typeof methodToColor
120
- ] ?? TextColorMap.gray;
106
+ const methodTextColor = methodForColor(operation.method);
121
107
 
122
108
  const [searchParams, setSearchParams] = useSearchParams();
123
109
  const [, startTransition] = useTransition();
@@ -12,7 +12,19 @@ export const useCreateQuery = <TResult, TVariables>(
12
12
  throw new Error("useGraphQL must be used within a GraphQLProvider");
13
13
  }
14
14
 
15
- const hash = useMemo(() => hashit(variables[0] ?? {}), [variables]);
15
+ const hash = useMemo(() => {
16
+ if (
17
+ typeof variables[0] === "object" &&
18
+ variables[0] != null &&
19
+ "input" in variables[0] &&
20
+ typeof variables[0].input === "function"
21
+ ) {
22
+ // This is a pre-hashed name to ensure that the query key is consistent across server and client
23
+ return variables[0].input.name;
24
+ }
25
+
26
+ return hashit(variables[0] ?? {});
27
+ }, [variables]);
16
28
 
17
29
  return {
18
30
  queryFn: () => graphQLClient.fetch(query, ...variables),
@@ -1,7 +1,7 @@
1
1
  import { createContext, useContext } from "react";
2
- import { OasPluginConfig } from "./interfaces.js";
2
+ import { type OasPluginContext } from "./interfaces.js";
3
3
 
4
- const OasContext = createContext<{ config: OasPluginConfig } | undefined>(
4
+ const OasContext = createContext<{ config: OasPluginContext } | undefined>(
5
5
  undefined,
6
6
  );
7
7
 
@@ -1,4 +1,4 @@
1
- import { matchPath, type RouteObject } from "react-router-dom";
1
+ import { matchPath } from "react-router";
2
2
  import { type ZudokuPlugin } from "../../core/plugins.js";
3
3
  import { graphql } from "./graphql/index.js";
4
4
 
@@ -52,6 +52,8 @@ export type OpenApiPluginOptions = OasPluginConfig & InternalOasPluginConfig;
52
52
  export const openApiPlugin = (config: OpenApiPluginOptions): ZudokuPlugin => {
53
53
  const basePath = joinPath(config.navigationId ?? "/reference");
54
54
 
55
+ const versions = config.type === "file" ? Object.keys(config.input) : [];
56
+
55
57
  const client = new GraphQLClient(config);
56
58
 
57
59
  return {
@@ -125,9 +127,14 @@ export const openApiPlugin = (config: OpenApiPluginOptions): ZudokuPlugin => {
125
127
  }
126
128
 
127
129
  try {
130
+ const version =
131
+ versions.find((v) => path === joinPath(basePath, v)) ??
132
+ Object.keys(config.input).at(0);
133
+
128
134
  const data = await client.fetch(GetCategoriesQuery, {
129
135
  type: config.type,
130
- input: config.input,
136
+ input: config.type === "file" ? config.input[version!] : config.input,
137
+ version,
131
138
  });
132
139
 
133
140
  const categories = data.schema.tags
@@ -159,32 +166,34 @@ export const openApiPlugin = (config: OpenApiPluginOptions): ZudokuPlugin => {
159
166
  return [];
160
167
  }
161
168
  },
162
- getRoutes: () =>
163
- [
164
- {
165
- async lazy() {
166
- const { OpenApiRoute } = await import("./Route.js");
167
- return {
168
- element: <OpenApiRoute client={client} config={config} />,
169
- };
170
- },
171
- children: [
172
- {
173
- path: basePath,
174
- children: [
175
- {
176
- index: true,
177
- async lazy() {
178
- const { OperationList } = await import(
179
- "./OperationList.js"
180
- );
181
- return { element: <OperationList /> };
182
- },
183
- },
184
- ],
185
- },
186
- ],
169
+ getRoutes: () => {
170
+ const versionsInPath = [null, ...versions];
171
+
172
+ return versionsInPath.map((version) => ({
173
+ path: basePath + (version ? `/${version}` : ""),
174
+ async lazy() {
175
+ const { OpenApiRoute } = await import("./Route.js");
176
+ return {
177
+ element: (
178
+ <OpenApiRoute
179
+ basePath={basePath}
180
+ versions={versions}
181
+ client={client}
182
+ config={config}
183
+ />
184
+ ),
185
+ };
187
186
  },
188
- ] satisfies RouteObject[],
187
+ children: [
188
+ {
189
+ index: true,
190
+ async lazy() {
191
+ const { OperationList } = await import("./OperationList.js");
192
+ return { element: <OperationList /> };
193
+ },
194
+ },
195
+ ],
196
+ }));
197
+ },
189
198
  };
190
199
  };
@@ -1,6 +1,19 @@
1
1
  type OasSource =
2
2
  | { type: "url"; input: string }
3
- | { type: "file"; input: () => Promise<unknown> }
3
+ | {
4
+ type: "file";
5
+ input: {
6
+ [version: string]: () => Promise<unknown>;
7
+ };
8
+ }
9
+ | { type: "raw"; input: string };
10
+
11
+ export type ContextOasSource =
12
+ | { type: "url"; input: string }
13
+ | {
14
+ type: "file";
15
+ input: () => Promise<unknown>;
16
+ }
4
17
  | { type: "raw"; input: string };
5
18
 
6
19
  export type OasPluginConfig = {
@@ -8,3 +21,11 @@ export type OasPluginConfig = {
8
21
  navigationId?: string;
9
22
  skipPreload?: boolean;
10
23
  } & OasSource;
24
+
25
+ export type OasPluginContext = {
26
+ server?: string;
27
+ navigationId?: string;
28
+ skipPreload?: boolean;
29
+ version?: string;
30
+ versions: Record<string, string>;
31
+ } & ContextOasSource;
@@ -1,7 +1,8 @@
1
1
  import * as Collapsible from "@radix-ui/react-collapsible";
2
- import { ListPlusIcon } from "lucide-react";
2
+ import { ListPlusIcon, RefreshCcwDotIcon } from "lucide-react";
3
3
  import { useCallback, useState } from "react";
4
4
  import { Markdown, ProseClasses } from "../../../components/Markdown.js";
5
+ import { CIRCULAR_REF } from "../../../oas/parser/dereference/index.js";
5
6
  import type { SchemaObject } from "../../../oas/parser/index.js";
6
7
  import { Button } from "../../../ui/Button.js";
7
8
  import { cn } from "../../../util/cn.js";
@@ -39,6 +40,16 @@ export const SchemaLogicalGroup = ({
39
40
  }
40
41
  };
41
42
 
43
+ const isCircularRef = (schema: unknown): schema is string =>
44
+ schema === CIRCULAR_REF;
45
+
46
+ const RecursiveIndicator = () => (
47
+ <div className="flex items-center gap-2 italic text-sm text-muted-foreground font-mono bg-muted px-2 py-0.5 rounded-md">
48
+ <RefreshCcwDotIcon size={16} />
49
+ <span>recursive</span>
50
+ </div>
51
+ );
52
+
42
53
  export const SchemaPropertyItem = ({
43
54
  name,
44
55
  schema,
@@ -56,6 +67,19 @@ export const SchemaPropertyItem = ({
56
67
  }) => {
57
68
  const [isOpen, setIsOpen] = useState(defaultOpen);
58
69
 
70
+ if (isCircularRef(schema)) {
71
+ return (
72
+ <li className="p-4 bg-border/20 hover:bg-border/30">
73
+ <div className="flex flex-col gap-1 justify-between text-sm">
74
+ <div className="flex gap-2 items-center">
75
+ <code>{name}</code>
76
+ <RecursiveIndicator />
77
+ </div>
78
+ </div>
79
+ </li>
80
+ );
81
+ }
82
+
59
83
  return (
60
84
  <li className="p-4 bg-border/20 hover:bg-border/30">
61
85
  <div className="flex flex-col gap-1 justify-between text-sm">
@@ -0,0 +1,27 @@
1
+ export const TextColorMap = {
2
+ green: "text-green-600",
3
+ blue: "text-sky-600",
4
+ yellow: "text-yellow-600",
5
+ red: "text-red-600",
6
+ purple: "text-purple-600",
7
+ indigo: "text-indigo-600",
8
+ gray: "text-gray-600",
9
+ };
10
+
11
+ export const methodToColor = {
12
+ get: TextColorMap.green,
13
+ post: TextColorMap.blue,
14
+ put: TextColorMap.yellow,
15
+ delete: TextColorMap.red,
16
+ patch: TextColorMap.purple,
17
+ options: TextColorMap.indigo,
18
+ head: TextColorMap.gray,
19
+ trace: TextColorMap.gray,
20
+ };
21
+
22
+ export const methodForColor = (method: string) => {
23
+ return (
24
+ methodToColor[method.toLocaleLowerCase() as keyof typeof methodToColor] ??
25
+ TextColorMap.gray
26
+ );
27
+ };