zudoku 0.0.0-f40ea27 → 0.0.0-f42e3678

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 (420) hide show
  1. package/README.md +2 -2
  2. package/dist/app/demo.js +16 -1
  3. package/dist/app/demo.js.map +1 -1
  4. package/dist/app/main.js +3 -9
  5. package/dist/app/main.js.map +1 -1
  6. package/dist/cli/build/handler.js +9 -1
  7. package/dist/cli/build/handler.js.map +1 -1
  8. package/dist/config/config.d.ts +1 -0
  9. package/dist/config/loader.js +2 -5
  10. package/dist/config/loader.js.map +1 -1
  11. package/dist/config/validators/BuildSchema.js +5 -0
  12. package/dist/config/validators/BuildSchema.js.map +1 -1
  13. package/dist/config/validators/InputNavigationSchema.d.ts +254 -163
  14. package/dist/config/validators/InputNavigationSchema.js +4 -4
  15. package/dist/config/validators/InputNavigationSchema.js.map +1 -1
  16. package/dist/config/validators/InputNavigationSchema.test-d.js +0 -1
  17. package/dist/config/validators/InputNavigationSchema.test-d.js.map +1 -1
  18. package/dist/config/validators/NavigationSchema.js +3 -2
  19. package/dist/config/validators/NavigationSchema.js.map +1 -1
  20. package/dist/config/validators/ProtectedRoutesSchema.d.ts +12 -0
  21. package/dist/config/validators/ProtectedRoutesSchema.js +19 -0
  22. package/dist/config/validators/ProtectedRoutesSchema.js.map +1 -0
  23. package/dist/config/validators/icon-types.d.ts +1 -1
  24. package/dist/config/validators/icon-types.js +16 -0
  25. package/dist/config/validators/icon-types.js.map +1 -1
  26. package/dist/config/validators/validate.d.ts +36 -20
  27. package/dist/config/validators/validate.js +18 -4
  28. package/dist/config/validators/validate.js.map +1 -1
  29. package/dist/config/validators/validate.test.js +65 -2
  30. package/dist/config/validators/validate.test.js.map +1 -1
  31. package/dist/flat-config.d.ts +8 -6
  32. package/dist/lib/authentication/authentication.d.ts +2 -0
  33. package/dist/lib/authentication/components/CallbackHandler.js +11 -9
  34. package/dist/lib/authentication/components/CallbackHandler.js.map +1 -1
  35. package/dist/lib/authentication/components/OAuthErrorPage.d.ts +3 -0
  36. package/dist/lib/authentication/components/OAuthErrorPage.js +99 -0
  37. package/dist/lib/authentication/components/OAuthErrorPage.js.map +1 -0
  38. package/dist/lib/authentication/components/SignIn.js +4 -3
  39. package/dist/lib/authentication/components/SignIn.js.map +1 -1
  40. package/dist/lib/authentication/errors.d.ts +6 -12
  41. package/dist/lib/authentication/errors.js +2 -1
  42. package/dist/lib/authentication/errors.js.map +1 -1
  43. package/dist/lib/authentication/hook.d.ts +1 -0
  44. package/dist/lib/authentication/hook.js.map +1 -1
  45. package/dist/lib/authentication/providers/azureb2c.js +4 -2
  46. package/dist/lib/authentication/providers/azureb2c.js.map +1 -1
  47. package/dist/lib/authentication/providers/clerk.js +4 -2
  48. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  49. package/dist/lib/authentication/providers/openid.d.ts +4 -2
  50. package/dist/lib/authentication/providers/openid.js +14 -6
  51. package/dist/lib/authentication/providers/openid.js.map +1 -1
  52. package/dist/lib/components/Banner.js +1 -1
  53. package/dist/lib/components/Banner.js.map +1 -1
  54. package/dist/lib/components/CategoryHeading.js +1 -1
  55. package/dist/lib/components/CategoryHeading.js.map +1 -1
  56. package/dist/lib/components/Header.js +1 -1
  57. package/dist/lib/components/Header.js.map +1 -1
  58. package/dist/lib/components/Heading.js +1 -1
  59. package/dist/lib/components/Heading.js.map +1 -1
  60. package/dist/lib/components/Markdown.js +2 -2
  61. package/dist/lib/components/Markdown.js.map +1 -1
  62. package/dist/lib/components/MobileTopNavigation.js +11 -6
  63. package/dist/lib/components/MobileTopNavigation.js.map +1 -1
  64. package/dist/lib/components/NotFoundPage.js +1 -1
  65. package/dist/lib/components/NotFoundPage.js.map +1 -1
  66. package/dist/lib/components/Pagination.js +1 -1
  67. package/dist/lib/components/Pagination.js.map +1 -1
  68. package/dist/lib/components/StatusPage.js +4 -0
  69. package/dist/lib/components/StatusPage.js.map +1 -1
  70. package/dist/lib/components/TopNavigation.d.ts +5 -0
  71. package/dist/lib/components/TopNavigation.js +20 -15
  72. package/dist/lib/components/TopNavigation.js.map +1 -1
  73. package/dist/lib/components/Typography.d.ts +1 -1
  74. package/dist/lib/components/Typography.js +1 -1
  75. package/dist/lib/components/Typography.js.map +1 -1
  76. package/dist/lib/components/context/ZudokuContext.js +21 -13
  77. package/dist/lib/components/context/ZudokuContext.js.map +1 -1
  78. package/dist/lib/components/navigation/NavigationItem.d.ts +1 -1
  79. package/dist/lib/components/navigation/NavigationItem.js +8 -1
  80. package/dist/lib/components/navigation/NavigationItem.js.map +1 -1
  81. package/dist/lib/components/navigation/NavigationWrapper.js +1 -1
  82. package/dist/lib/components/navigation/NavigationWrapper.js.map +1 -1
  83. package/dist/lib/components/navigation/utils.d.ts +3 -1
  84. package/dist/lib/components/navigation/utils.js +6 -3
  85. package/dist/lib/components/navigation/utils.js.map +1 -1
  86. package/dist/lib/core/RouteGuard.js +9 -9
  87. package/dist/lib/core/RouteGuard.js.map +1 -1
  88. package/dist/lib/core/ZudokuContext.d.ts +5 -2
  89. package/dist/lib/core/ZudokuContext.js +27 -2
  90. package/dist/lib/core/ZudokuContext.js.map +1 -1
  91. package/dist/lib/core/plugins.d.ts +2 -1
  92. package/dist/lib/core/plugins.js.map +1 -1
  93. package/dist/lib/errors/ErrorAlert.js +1 -1
  94. package/dist/lib/errors/ErrorAlert.js.map +1 -1
  95. package/dist/lib/plugins/api-keys/CreateApiKey.js +7 -3
  96. package/dist/lib/plugins/api-keys/CreateApiKey.js.map +1 -1
  97. package/dist/lib/plugins/api-keys/SettingsApiKeys.js +6 -4
  98. package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
  99. package/dist/lib/plugins/api-keys/index.d.ts +1 -0
  100. package/dist/lib/plugins/api-keys/index.js +4 -8
  101. package/dist/lib/plugins/api-keys/index.js.map +1 -1
  102. package/dist/lib/plugins/markdown/MdxPage.js +4 -3
  103. package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
  104. package/dist/lib/plugins/openapi/OperationList.js +2 -1
  105. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  106. package/dist/lib/plugins/openapi/Sidecar.js +1 -1
  107. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  108. package/dist/lib/plugins/openapi/SidecarExamples.js +1 -1
  109. package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
  110. package/dist/lib/plugins/openapi/graphql/gql.d.ts +1 -1
  111. package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
  112. package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
  113. package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
  114. package/dist/lib/plugins/openapi/graphql/graphql.js +1 -0
  115. package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
  116. package/dist/lib/plugins/openapi/index.js +43 -11
  117. package/dist/lib/plugins/openapi/index.js.map +1 -1
  118. package/dist/lib/plugins/openapi/playground/PathParams.js +1 -1
  119. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
  120. package/dist/lib/plugins/openapi/playground/Playground.js +4 -2
  121. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  122. package/dist/lib/plugins/search-inkeep/index.d.ts +5 -22
  123. package/dist/lib/plugins/search-inkeep/index.js +35 -29
  124. package/dist/lib/plugins/search-inkeep/index.js.map +1 -1
  125. package/dist/lib/plugins/search-inkeep/inkeep.d.ts +5 -21
  126. package/dist/lib/plugins/search-inkeep/inkeep.js +10 -19
  127. package/dist/lib/plugins/search-inkeep/inkeep.js.map +1 -1
  128. package/dist/lib/plugins/search-pagefind/PagefindSearch.js +1 -1
  129. package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -1
  130. package/dist/lib/plugins/search-pagefind/ResultList.d.ts +1 -1
  131. package/dist/lib/plugins/search-pagefind/ResultList.js +12 -5
  132. package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -1
  133. package/dist/lib/ui/ActionButton.js +1 -1
  134. package/dist/lib/ui/ActionButton.js.map +1 -1
  135. package/dist/lib/ui/Alert.d.ts +1 -1
  136. package/dist/lib/ui/Badge.d.ts +1 -1
  137. package/dist/lib/ui/Button.d.ts +2 -2
  138. package/dist/lib/ui/CodeBlock.js +1 -1
  139. package/dist/lib/ui/CodeBlock.js.map +1 -1
  140. package/dist/lib/ui/Command.d.ts +1 -1
  141. package/dist/lib/ui/EmbeddedCodeBlock.js +1 -1
  142. package/dist/lib/ui/EmbeddedCodeBlock.js.map +1 -1
  143. package/dist/lib/util/invariant.d.ts +6 -5
  144. package/dist/lib/util/invariant.js +1 -1
  145. package/dist/lib/util/invariant.js.map +1 -1
  146. package/dist/vite/build.js +7 -1
  147. package/dist/vite/build.js.map +1 -1
  148. package/dist/vite/dev-server.js +9 -1
  149. package/dist/vite/dev-server.js.map +1 -1
  150. package/dist/vite/mdx/remark-last-modified.js +1 -28
  151. package/dist/vite/mdx/remark-last-modified.js.map +1 -1
  152. package/dist/vite/plugin-docs.js +20 -13
  153. package/dist/vite/plugin-docs.js.map +1 -1
  154. package/dist/vite/plugin-mdx.js +2 -3
  155. package/dist/vite/plugin-mdx.js.map +1 -1
  156. package/dist/vite/plugin-theme.js +88 -49
  157. package/dist/vite/plugin-theme.js.map +1 -1
  158. package/dist/vite/plugin-theme.test.js +25 -4
  159. package/dist/vite/plugin-theme.test.js.map +1 -1
  160. package/dist/vite/prerender/worker.js +5 -1
  161. package/dist/vite/prerender/worker.js.map +1 -1
  162. package/dist/vite/shadcn-registry.d.ts +8 -8
  163. package/lib/{Button-BE9IVkWV.js → Button-B3o-2Xdf.js} +2 -2
  164. package/lib/{Button-BE9IVkWV.js.map → Button-B3o-2Xdf.js.map} +1 -1
  165. package/lib/{Card-DPhGbYUM.js → Card-CMDQUPM4.js} +2 -2
  166. package/lib/{Card-DPhGbYUM.js.map → Card-CMDQUPM4.js.map} +1 -1
  167. package/lib/ClientOnly-E7hGysn1.js.map +1 -1
  168. package/lib/{CodeBlock-DAKxs_Tu.js → CodeBlock-B-G0eKtw.js} +3 -3
  169. package/lib/{CodeBlock-DAKxs_Tu.js.map → CodeBlock-B-G0eKtw.js.map} +1 -1
  170. package/lib/{Command-xsbs2uhf.js → Command-BYukybsa.js} +3 -3
  171. package/lib/{Command-xsbs2uhf.js.map → Command-BYukybsa.js.map} +1 -1
  172. package/lib/{Dialog-CiIdyz6a.js → Dialog-u9Uz9sTt.js} +5 -5
  173. package/lib/{Dialog-CiIdyz6a.js.map → Dialog-u9Uz9sTt.js.map} +1 -1
  174. package/lib/{Drawer-BzkOKwgC.js → Drawer-DJ05s2pH.js} +86 -86
  175. package/lib/{Drawer-BzkOKwgC.js.map → Drawer-DJ05s2pH.js.map} +1 -1
  176. package/lib/{MdxPage-swXPJ0gf.js → MdxPage-Bsko6_kb.js} +34 -34
  177. package/lib/MdxPage-Bsko6_kb.js.map +1 -0
  178. package/lib/OAuthErrorPage-DJzGiIBt.js +150 -0
  179. package/lib/OAuthErrorPage-DJzGiIBt.js.map +1 -0
  180. package/lib/{OasProvider-CDAM3TB1.js → OasProvider-DQQRt3oS.js} +3 -3
  181. package/lib/{OasProvider-CDAM3TB1.js.map → OasProvider-DQQRt3oS.js.map} +1 -1
  182. package/lib/{OperationList-C9Hb9ql8.js → OperationList-DpmkHf26.js} +212 -210
  183. package/lib/OperationList-DpmkHf26.js.map +1 -0
  184. package/lib/{Pagination-VGlgeCmS.js → Pagination-kqFNgtnI.js} +10 -9
  185. package/lib/Pagination-kqFNgtnI.js.map +1 -0
  186. package/lib/{RouteGuard-CbKd7_9h.js → RouteGuard-0wPUKdxJ.js} +166 -165
  187. package/lib/{RouteGuard-CbKd7_9h.js.map → RouteGuard-0wPUKdxJ.js.map} +1 -1
  188. package/lib/{SchemaList-BAbh1BXO.js → SchemaList-DS-pMd6B.js} +9 -9
  189. package/lib/{SchemaList-BAbh1BXO.js.map → SchemaList-DS-pMd6B.js.map} +1 -1
  190. package/lib/{SchemaView-C2Io712T.js → SchemaView-BnN6WHjw.js} +6 -6
  191. package/lib/{SchemaView-C2Io712T.js.map → SchemaView-BnN6WHjw.js.map} +1 -1
  192. package/lib/Select-BmTTKNPp.js +273 -0
  193. package/lib/Select-BmTTKNPp.js.map +1 -0
  194. package/lib/SignUp-BwOSCD-6.js +56 -0
  195. package/lib/SignUp-BwOSCD-6.js.map +1 -0
  196. package/lib/{Slot-DwZlQ-vX.js → Slot-DAyXieeZ.js} +1634 -1643
  197. package/lib/Slot-DAyXieeZ.js.map +1 -0
  198. package/lib/Spinner-mNLZ6awP.js.map +1 -1
  199. package/lib/{SyntaxHighlight-CrjhGEwT.js → SyntaxHighlight-BMKR4pl6.js} +757 -757
  200. package/lib/SyntaxHighlight-BMKR4pl6.js.map +1 -0
  201. package/lib/{Toc-WCmwFkX-.js → Toc-BKDRCQzU.js} +3 -3
  202. package/lib/{Toc-WCmwFkX-.js.map → Toc-BKDRCQzU.js.map} +1 -1
  203. package/lib/ZudokuContext-CLl5w57E.js +1278 -0
  204. package/lib/ZudokuContext-CLl5w57E.js.map +1 -0
  205. package/lib/{chunk-DQRVZFIR-DHK7_Ilc.js → chunk-QMGIS6GS-CEOk3lro.js} +3 -3
  206. package/lib/chunk-QMGIS6GS-CEOk3lro.js.map +1 -0
  207. package/lib/{circular-B42RaanD.js → circular-8GWQDvCW.js} +2 -2
  208. package/lib/{circular-B42RaanD.js.map → circular-8GWQDvCW.js.map} +1 -1
  209. package/lib/{cn-wvCW-ho6.js → cn-dYga0KKN.js} +2 -2
  210. package/lib/cn-dYga0KKN.js.map +1 -0
  211. package/lib/{createServer-BKFsRuuk.js → createServer-BsezSzvV.js} +3398 -3552
  212. package/lib/createServer-BsezSzvV.js.map +1 -0
  213. package/lib/errors-Cs7hKmdL.js +45 -0
  214. package/lib/errors-Cs7hKmdL.js.map +1 -0
  215. package/lib/hook-DbUCLQNg.js +247 -0
  216. package/lib/hook-DbUCLQNg.js.map +1 -0
  217. package/lib/index-A5Qdwj1B.js +4081 -0
  218. package/lib/index-A5Qdwj1B.js.map +1 -0
  219. package/lib/{index-B6Re5_cx.js → index-Bg7Js3jB.js} +873 -951
  220. package/lib/index-Bg7Js3jB.js.map +1 -0
  221. package/lib/{index-CcV90rin.js → index-BkW9tJ6j.js} +2 -2
  222. package/lib/{index-CcV90rin.js.map → index-BkW9tJ6j.js.map} +1 -1
  223. package/lib/index-Bm35Tkgf.js +107 -0
  224. package/lib/index-Bm35Tkgf.js.map +1 -0
  225. package/lib/index-CrcNWbel.js.map +1 -1
  226. package/lib/index-DI5SPFK9.js.map +1 -1
  227. package/lib/index-DmNq2fbN.js.map +1 -1
  228. package/lib/index.esm-CdzlRw50.js +1254 -0
  229. package/lib/index.esm-CdzlRw50.js.map +1 -0
  230. package/lib/{invariant-DAFpPywt.js → invariant-Bm-FVUQE.js} +2 -6
  231. package/lib/invariant-Bm-FVUQE.js.map +1 -0
  232. package/lib/jsx-runtime-C5mzlN2N.js.map +1 -1
  233. package/lib/processors/removeExtensions.js.map +1 -1
  234. package/lib/processors/removeParameters.js.map +1 -1
  235. package/lib/processors/removePaths.js.map +1 -1
  236. package/lib/processors/traverse.js.map +1 -1
  237. package/lib/ui/Accordion.js +1 -1
  238. package/lib/ui/Accordion.js.map +1 -1
  239. package/lib/ui/ActionButton.js +10 -10
  240. package/lib/ui/ActionButton.js.map +1 -1
  241. package/lib/ui/Alert.js +1 -1
  242. package/lib/ui/Alert.js.map +1 -1
  243. package/lib/ui/AlertDialog.js +1 -1
  244. package/lib/ui/AlertDialog.js.map +1 -1
  245. package/lib/ui/Badge.js +1 -1
  246. package/lib/ui/Badge.js.map +1 -1
  247. package/lib/ui/Breadcrumb.js +1 -1
  248. package/lib/ui/Breadcrumb.js.map +1 -1
  249. package/lib/ui/Button.js +1 -1
  250. package/lib/ui/Button.js.map +1 -1
  251. package/lib/ui/Callout.js +1 -1
  252. package/lib/ui/Callout.js.map +1 -1
  253. package/lib/ui/Card.js +1 -1
  254. package/lib/ui/Card.js.map +1 -1
  255. package/lib/ui/Carousel.js +1 -1
  256. package/lib/ui/Carousel.js.map +1 -1
  257. package/lib/ui/Checkbox.js +1 -1
  258. package/lib/ui/Checkbox.js.map +1 -1
  259. package/lib/ui/CodeBlock.js +2 -2
  260. package/lib/ui/Command.js +2 -2
  261. package/lib/ui/Command.js.map +1 -1
  262. package/lib/ui/Dialog.js +1 -1
  263. package/lib/ui/Dialog.js.map +1 -1
  264. package/lib/ui/Drawer.js +2 -2
  265. package/lib/ui/DropdownMenu.js +1 -1
  266. package/lib/ui/DropdownMenu.js.map +1 -1
  267. package/lib/ui/EmbeddedCodeBlock.js +2 -2
  268. package/lib/ui/EmbeddedCodeBlock.js.map +1 -1
  269. package/lib/ui/Form.js +2 -2
  270. package/lib/ui/Form.js.map +1 -1
  271. package/lib/ui/HoverCard.js +1 -1
  272. package/lib/ui/HoverCard.js.map +1 -1
  273. package/lib/ui/Input.js +1 -1
  274. package/lib/ui/Input.js.map +1 -1
  275. package/lib/ui/Label.js +1 -1
  276. package/lib/ui/Label.js.map +1 -1
  277. package/lib/ui/Pagination.js +1 -1
  278. package/lib/ui/Pagination.js.map +1 -1
  279. package/lib/ui/Popover.js +1 -1
  280. package/lib/ui/Popover.js.map +1 -1
  281. package/lib/ui/Progress.js +1 -1
  282. package/lib/ui/Progress.js.map +1 -1
  283. package/lib/ui/RadioGroup.js +1 -1
  284. package/lib/ui/RadioGroup.js.map +1 -1
  285. package/lib/ui/ScrollArea.js +1 -1
  286. package/lib/ui/ScrollArea.js.map +1 -1
  287. package/lib/ui/Select.js +1 -1
  288. package/lib/ui/Select.js.map +1 -1
  289. package/lib/ui/Skeleton.js +1 -1
  290. package/lib/ui/Skeleton.js.map +1 -1
  291. package/lib/ui/Slider.js +1 -1
  292. package/lib/ui/Slider.js.map +1 -1
  293. package/lib/ui/Stepper.js.map +1 -1
  294. package/lib/ui/Switch.js +1 -1
  295. package/lib/ui/Switch.js.map +1 -1
  296. package/lib/ui/SyntaxHighlight.js +4 -4
  297. package/lib/ui/Tabs.js +1 -1
  298. package/lib/ui/Tabs.js.map +1 -1
  299. package/lib/ui/Textarea.js +1 -1
  300. package/lib/ui/Textarea.js.map +1 -1
  301. package/lib/ui/Toggle.js +1 -1
  302. package/lib/ui/Toggle.js.map +1 -1
  303. package/lib/ui/ToggleGroup.js +1 -1
  304. package/lib/ui/ToggleGroup.js.map +1 -1
  305. package/lib/ui/Tooltip.js +1 -1
  306. package/lib/ui/Tooltip.js.map +1 -1
  307. package/lib/ui/util.js +1 -1
  308. package/lib/{useExposedProps-BIYjecPD.js → useExposedProps-KcgXHKeE.js} +2 -2
  309. package/lib/{useExposedProps-BIYjecPD.js.map → useExposedProps-KcgXHKeE.js.map} +1 -1
  310. package/lib/zudoku.auth-auth0.js +1 -1
  311. package/lib/zudoku.auth-auth0.js.map +1 -1
  312. package/lib/zudoku.auth-azureb2c.js +46 -9883
  313. package/lib/zudoku.auth-azureb2c.js.map +1 -1
  314. package/lib/zudoku.auth-clerk.js +25 -22
  315. package/lib/zudoku.auth-clerk.js.map +1 -1
  316. package/lib/zudoku.auth-openid.js +249 -231
  317. package/lib/zudoku.auth-openid.js.map +1 -1
  318. package/lib/zudoku.auth-supabase.js +97 -0
  319. package/lib/zudoku.auth-supabase.js.map +1 -0
  320. package/lib/zudoku.components.js +30 -29
  321. package/lib/zudoku.components.js.map +1 -1
  322. package/lib/zudoku.hooks.js +17 -16
  323. package/lib/zudoku.hooks.js.map +1 -1
  324. package/lib/zudoku.icons.js.map +1 -1
  325. package/lib/zudoku.plugin-api-catalog.js +26 -25
  326. package/lib/zudoku.plugin-api-catalog.js.map +1 -1
  327. package/lib/zudoku.plugin-api-keys.js +428 -299
  328. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  329. package/lib/zudoku.plugin-custom-pages.js +1 -1
  330. package/lib/zudoku.plugin-custom-pages.js.map +1 -1
  331. package/lib/zudoku.plugin-markdown.js +1 -1
  332. package/lib/zudoku.plugin-markdown.js.map +1 -1
  333. package/lib/zudoku.plugin-openapi.js +7 -6
  334. package/lib/zudoku.plugin-openapi.js.map +1 -1
  335. package/lib/zudoku.plugin-redirect.js +1 -1
  336. package/lib/zudoku.plugin-redirect.js.map +1 -1
  337. package/lib/zudoku.plugin-search-inkeep.js +54 -57
  338. package/lib/zudoku.plugin-search-inkeep.js.map +1 -1
  339. package/lib/zudoku.plugin-search-pagefind.js +123 -118
  340. package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
  341. package/lib/zudoku.plugins.js.map +1 -1
  342. package/package.json +34 -33
  343. package/src/app/demo.tsx +19 -2
  344. package/src/app/main.css +26 -5
  345. package/src/app/main.tsx +6 -14
  346. package/src/lib/authentication/authentication.ts +2 -2
  347. package/src/lib/authentication/components/CallbackHandler.tsx +22 -15
  348. package/src/lib/authentication/components/OAuthErrorPage.tsx +171 -0
  349. package/src/lib/authentication/components/SignIn.tsx +5 -12
  350. package/src/lib/authentication/errors.ts +27 -13
  351. package/src/lib/authentication/hook.ts +2 -0
  352. package/src/lib/authentication/providers/azureb2c.tsx +8 -3
  353. package/src/lib/authentication/providers/clerk.tsx +4 -1
  354. package/src/lib/authentication/providers/openid.tsx +30 -5
  355. package/src/lib/components/Banner.tsx +0 -1
  356. package/src/lib/components/CategoryHeading.tsx +4 -1
  357. package/src/lib/components/Header.tsx +5 -2
  358. package/src/lib/components/Heading.tsx +1 -1
  359. package/src/lib/components/Markdown.tsx +3 -3
  360. package/src/lib/components/MobileTopNavigation.tsx +60 -8
  361. package/src/lib/components/NotFoundPage.tsx +3 -2
  362. package/src/lib/components/Pagination.tsx +1 -0
  363. package/src/lib/components/StatusPage.tsx +5 -0
  364. package/src/lib/components/TopNavigation.tsx +34 -18
  365. package/src/lib/components/Typography.tsx +1 -1
  366. package/src/lib/components/context/ZudokuContext.ts +25 -18
  367. package/src/lib/components/navigation/NavigationItem.tsx +9 -1
  368. package/src/lib/components/navigation/NavigationWrapper.tsx +4 -1
  369. package/src/lib/components/navigation/utils.ts +9 -3
  370. package/src/lib/core/RouteGuard.tsx +13 -13
  371. package/src/lib/core/ZudokuContext.ts +40 -5
  372. package/src/lib/core/plugins.ts +2 -1
  373. package/src/lib/errors/ErrorAlert.tsx +5 -7
  374. package/src/lib/plugins/api-keys/CreateApiKey.tsx +12 -1
  375. package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +37 -13
  376. package/src/lib/plugins/api-keys/index.tsx +8 -9
  377. package/src/lib/plugins/markdown/MdxPage.tsx +4 -3
  378. package/src/lib/plugins/openapi/OperationList.tsx +4 -2
  379. package/src/lib/plugins/openapi/Sidecar.tsx +1 -1
  380. package/src/lib/plugins/openapi/SidecarExamples.tsx +1 -1
  381. package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
  382. package/src/lib/plugins/openapi/graphql/graphql.ts +2 -0
  383. package/src/lib/plugins/openapi/index.tsx +67 -17
  384. package/src/lib/plugins/openapi/playground/PathParams.tsx +1 -1
  385. package/src/lib/plugins/openapi/playground/Playground.tsx +8 -2
  386. package/src/lib/plugins/search-inkeep/index.tsx +54 -58
  387. package/src/lib/plugins/search-inkeep/inkeep.ts +19 -21
  388. package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +1 -0
  389. package/src/lib/plugins/search-pagefind/ResultList.tsx +13 -4
  390. package/src/lib/ui/ActionButton.tsx +3 -1
  391. package/src/lib/ui/Alert.tsx +1 -1
  392. package/src/lib/ui/CodeBlock.tsx +1 -1
  393. package/src/lib/ui/EmbeddedCodeBlock.tsx +1 -1
  394. package/src/lib/util/invariant.ts +7 -5
  395. package/lib/Alert-CT_ViLrJ.js +0 -161
  396. package/lib/Alert-CT_ViLrJ.js.map +0 -1
  397. package/lib/MdxPage-swXPJ0gf.js.map +0 -1
  398. package/lib/OperationList-C9Hb9ql8.js.map +0 -1
  399. package/lib/Pagination-VGlgeCmS.js.map +0 -1
  400. package/lib/SignUp-5RUdVhnq.js +0 -63
  401. package/lib/SignUp-5RUdVhnq.js.map +0 -1
  402. package/lib/Slot-DwZlQ-vX.js.map +0 -1
  403. package/lib/SyntaxHighlight-CrjhGEwT.js.map +0 -1
  404. package/lib/chunk-DQRVZFIR-DHK7_Ilc.js.map +0 -1
  405. package/lib/clerk-BDZ31hjU.js +0 -25190
  406. package/lib/clerk-BDZ31hjU.js.map +0 -1
  407. package/lib/cn-wvCW-ho6.js.map +0 -1
  408. package/lib/createServer-BKFsRuuk.js.map +0 -1
  409. package/lib/errors-CF2X_x5o.js +0 -78
  410. package/lib/errors-CF2X_x5o.js.map +0 -1
  411. package/lib/hook-Bd0yS8M0.js +0 -1503
  412. package/lib/hook-Bd0yS8M0.js.map +0 -1
  413. package/lib/index-B6Re5_cx.js.map +0 -1
  414. package/lib/index-CLy1XyH0.js +0 -3919
  415. package/lib/index-CLy1XyH0.js.map +0 -1
  416. package/lib/index-ClhS5TxS.js +0 -107
  417. package/lib/index-ClhS5TxS.js.map +0 -1
  418. package/lib/index.esm-Cp4wkyud.js +0 -1236
  419. package/lib/index.esm-Cp4wkyud.js.map +0 -1
  420. package/lib/invariant-DAFpPywt.js.map +0 -1
@@ -5,6 +5,10 @@ import type { Location } from "react-router";
5
5
  import type { BundledTheme, HighlighterCore } from "shiki";
6
6
  import type { z } from "zod/v4";
7
7
  import type { Navigation } from "../../config/validators/NavigationSchema.js";
8
+ import {
9
+ type ProtectedRoutesInput,
10
+ ProtectedRoutesSchema,
11
+ } from "../../config/validators/ProtectedRoutesSchema.js";
8
12
  import type { FooterSchema } from "../../config/validators/validate.js";
9
13
  import type { AuthenticationPlugin } from "../authentication/authentication.js";
10
14
  import { type AuthState, useAuthState } from "../authentication/state.js";
@@ -18,8 +22,10 @@ import {
18
22
  isAuthenticationPlugin,
19
23
  isEventConsumerPlugin,
20
24
  isNavigationPlugin,
25
+ isProfileMenuPlugin,
21
26
  type NavigationPlugin,
22
27
  needsInitialization,
28
+ type ProfileNavigationItem,
23
29
  type ZudokuPlugin,
24
30
  } from "./plugins.js";
25
31
 
@@ -65,6 +71,7 @@ type Site = Partial<{
65
71
  };
66
72
  width?: string | number;
67
73
  alt?: string;
74
+ href?: string;
68
75
  };
69
76
  banner?: {
70
77
  message: ReactNode;
@@ -91,7 +98,7 @@ export type ZudokuContextOptions = {
91
98
  components?: MdxComponentsType;
92
99
  };
93
100
  overrides?: ComponentsContextType;
94
- protectedRoutes?: string[];
101
+ protectedRoutes?: ProtectedRoutesInput;
95
102
  syntaxHighlighting?: {
96
103
  highlighter: HighlighterCore;
97
104
  themes?: { light: BundledTheme; dark: BundledTheme };
@@ -110,12 +117,21 @@ export class ZudokuContext {
110
117
  private emitter = createNanoEvents<ZudokuEvents>();
111
118
 
112
119
  constructor(options: ZudokuContextOptions, queryClient: QueryClient) {
113
- const protectedRoutes = (options.protectedRoutes ?? []).concat(
114
- options.plugins?.flatMap((plugin) =>
115
- isNavigationPlugin(plugin) ? (plugin.getProtectedRoutes?.() ?? []) : [],
116
- ) ?? [],
120
+ const pluginProtectedRoutes = Object.fromEntries(
121
+ (options.plugins ?? []).flatMap((plugin) => {
122
+ if (!isNavigationPlugin(plugin)) return [];
123
+ const routes = plugin.getProtectedRoutes?.();
124
+ if (!routes) return [];
125
+
126
+ return Object.entries(ProtectedRoutesSchema.parse(routes) ?? {});
127
+ }),
117
128
  );
118
129
 
130
+ const protectedRoutes = {
131
+ ...pluginProtectedRoutes,
132
+ ...ProtectedRoutesSchema.parse(options.protectedRoutes),
133
+ };
134
+
119
135
  this.queryClient = queryClient;
120
136
  this.options = { ...options, protectedRoutes };
121
137
  this.plugins = options.plugins ?? [];
@@ -182,6 +198,16 @@ export class ZudokuContext {
182
198
  return navigations.flatMap((nav) => nav ?? []);
183
199
  };
184
200
 
201
+ getProfileMenuItems = () => {
202
+ const accountItems = this.plugins
203
+ .filter((p) => isProfileMenuPlugin(p))
204
+ .flatMap((p) => p.getProfileMenuItems(this))
205
+ .sort(sortByCategory(["top", "middle", "bottom"]))
206
+ .sort((i) => i.weight ?? 0);
207
+
208
+ return accountItems;
209
+ };
210
+
185
211
  signRequest = async (request: Request) => {
186
212
  if (!this.authentication) {
187
213
  throw new Error("No authentication provider configured");
@@ -190,3 +216,12 @@ export class ZudokuContext {
190
216
  return await this.authentication.signRequest(request);
191
217
  };
192
218
  }
219
+
220
+ const sortByCategory =
221
+ (categories: string[]) =>
222
+ (a: ProfileNavigationItem, b: ProfileNavigationItem) => {
223
+ const aIndex = categories.indexOf(a.category ?? "middle");
224
+ const bIndex = categories.indexOf(b.category ?? "middle");
225
+
226
+ return aIndex - bIndex;
227
+ };
@@ -2,6 +2,7 @@ import type { LucideIcon } from "lucide-react";
2
2
  import type { ReactElement } from "react";
3
3
  import type { Location, RouteObject } from "react-router";
4
4
  import type { Navigation } from "../../config/validators/NavigationSchema.js";
5
+ import type { ProtectedRoutesInput } from "../../config/validators/ProtectedRoutesSchema.js";
5
6
  import type { AuthenticationPlugin } from "../authentication/authentication.js";
6
7
  import type { MdxComponentsType } from "../util/MdxComponents.js";
7
8
  import type {
@@ -24,7 +25,7 @@ export type { AuthenticationPlugin, RouteObject };
24
25
  export interface NavigationPlugin {
25
26
  getRoutes: () => RouteObject[];
26
27
  getNavigation?: (path: string, context: ZudokuContext) => Promise<Navigation>;
27
- getProtectedRoutes?: () => string[];
28
+ getProtectedRoutes?: () => ProtectedRoutesInput;
28
29
  }
29
30
 
30
31
  export const createApiIdentityPlugin = (
@@ -23,13 +23,11 @@ export function ErrorAlert({ error }: { error: unknown }) {
23
23
  Error: {message}
24
24
  {hint && <DeveloperHint className="mb-4">{hint}</DeveloperHint>}
25
25
  {stringError && (
26
- <div>
27
- <SyntaxHighlight
28
- className="max-h-[400px] border mt-2"
29
- language="js"
30
- code={stringError}
31
- />
32
- </div>
26
+ <SyntaxHighlight
27
+ className="max-h-[400px] [&>pre]:p-4"
28
+ language="js"
29
+ code={stringError}
30
+ />
33
31
  )}
34
32
  </Typography>
35
33
  );
@@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
2
2
  import { useForm } from "react-hook-form";
3
3
  import { useNavigate } from "react-router";
4
4
  import { ActionButton } from "zudoku/ui/ActionButton.js";
5
+ import { Alert, AlertDescription, AlertTitle } from "zudoku/ui/Alert.js";
5
6
  import { DialogClose, DialogFooter } from "zudoku/ui/Dialog.js";
6
7
  import {
7
8
  Select,
@@ -33,6 +34,7 @@ export const CreateApiKey = ({
33
34
  expiresOn: "30",
34
35
  },
35
36
  });
37
+
36
38
  const createKeyMutation = useMutation({
37
39
  mutationFn: ({ description, expiresOn }: CreateApiKey) => {
38
40
  if (!service.createKey) {
@@ -43,7 +45,10 @@ export const CreateApiKey = ({
43
45
  expiresOn !== "never" ? addDaysToDate(Number(expiresOn)) : undefined;
44
46
 
45
47
  return service.createKey(
46
- { description: description || "Secret Key", expiresOn: expiresOnDate },
48
+ {
49
+ description: description || "Secret Key",
50
+ expiresOn: expiresOnDate,
51
+ },
47
52
  context,
48
53
  );
49
54
  },
@@ -68,6 +73,12 @@ export const CreateApiKey = ({
68
73
  ),
69
74
  )}
70
75
  >
76
+ {createKeyMutation.error && (
77
+ <Alert variant="destructive" className="mb-4">
78
+ <AlertTitle>Error</AlertTitle>
79
+ <AlertDescription>{createKeyMutation.error.message}</AlertDescription>
80
+ </Alert>
81
+ )}
71
82
  <div className="flex gap-2 flex-col text-sm font-medium">
72
83
  Name
73
84
  <Input {...form.register("description")} />
@@ -35,6 +35,7 @@ import { Button } from "../../ui/Button.js";
35
35
  import { Input } from "../../ui/Input.js";
36
36
  import { cn } from "../../util/cn.js";
37
37
  import { useCopyToClipboard } from "../../util/useCopyToClipboard.js";
38
+ import { CreateApiKey } from "./CreateApiKey.js";
38
39
  import { type ApiConsumer, type ApiKey, type ApiKeyService } from "./index.js";
39
40
 
40
41
  export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
@@ -50,6 +51,8 @@ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
50
51
  retry: false,
51
52
  });
52
53
 
54
+ const [isCreateApiKeyOpen, setIsCreateApiKeyOpen] = useState(false);
55
+
53
56
  const deleteKeyMutation = useMutation({
54
57
  mutationFn: ({
55
58
  consumerId,
@@ -180,11 +183,28 @@ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
180
183
  <Slot.Target name="api-keys-list-page" />
181
184
 
182
185
  <div className="flex justify-between pb-3">
183
- <h1 className="font-medium text-2xl">API Keys</h1>
186
+ <h1 className="font-medium text-2xl">
187
+ API Keys {typeof service.createKey}
188
+ </h1>
189
+
184
190
  {service.createKey && (
185
- <Button asChild>
186
- <Link to="/settings/api-keys/new">Create API Key</Link>
187
- </Button>
191
+ <Dialog
192
+ open={isCreateApiKeyOpen}
193
+ onOpenChange={setIsCreateApiKeyOpen}
194
+ >
195
+ <DialogTrigger asChild>
196
+ <Button variant="outline">Create API Key</Button>
197
+ </DialogTrigger>
198
+ <DialogContent>
199
+ <DialogHeader>
200
+ <DialogTitle>Create API Key</DialogTitle>
201
+ </DialogHeader>
202
+ <CreateApiKey
203
+ service={service}
204
+ onOpenChange={setIsCreateApiKeyOpen}
205
+ />
206
+ </DialogContent>
207
+ </Dialog>
188
208
  )}
189
209
  </div>
190
210
  <p>Create, manage, and monitor your API keys</p>
@@ -226,8 +246,7 @@ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
226
246
  ) : (
227
247
  <ul
228
248
  className={cn(
229
- "grid grid-cols-1 divide-y divide-border col-span-6",
230
- "lg:grid-cols-[1fr_min-content]",
249
+ "grid grid-cols-[1fr_min-content] divide-y divide-border col-span-6",
231
250
  )}
232
251
  >
233
252
  {data.map((consumers) => (
@@ -310,7 +329,7 @@ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
310
329
  disabled={editingConsumerId === consumers.id}
311
330
  >
312
331
  <PencilLineIcon size={16} />
313
- Edit label
332
+ <span className="hidden md:block">Edit label</span>
314
333
  </Button>
315
334
  )}
316
335
  {service.rollKey && (
@@ -330,7 +349,7 @@ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
330
349
  : undefined
331
350
  }
332
351
  />
333
- Roll key
352
+ <span className="hidden md:block">Roll key</span>
334
353
  </Button>
335
354
  </DialogTrigger>
336
355
  <DialogContent>
@@ -436,21 +455,26 @@ const RevealApiKey = ({
436
455
  return (
437
456
  <div className={cn("grid col-span-full grid-cols-subgrid p-6", className)}>
438
457
  <div className="flex flex-col gap-1">
439
- <div className="flex gap-2 items-center text-sm border rounded-md w-fit px-1">
440
- <div className="font-mono truncate h-9 items-center flex px-2 text-xs gap-2">
458
+ <div className="flex gap-2 items-center text-sm border rounded-md w-full max-w-fit px-1">
459
+ <div className="font-mono w-full h-9 items-center flex px-2 text-xs gap-2">
441
460
  <div
442
461
  className={cn(
443
462
  "rounded-full w-2 h-2 bg-emerald-400 mr-2",
444
463
  (expiresSoon || isExpired) && "bg-neutral-200",
445
464
  )}
446
465
  ></div>
447
- <span>
448
- <span className={revealed ? "" : "opacity-20"}>
466
+ <span className="w-full truncate">
467
+ <div
468
+ className={cn(
469
+ "w-40 inline-block md:w-full truncate",
470
+ revealed ? "" : "opacity-20",
471
+ )}
472
+ >
449
473
  {revealed
450
474
  ? key.slice(0, -5)
451
475
  : "**** ".repeat(key.slice(0, -5).length / 5) +
452
476
  "*".repeat(key.slice(0, -5).length % 5)}
453
- </span>
477
+ </div>
454
478
  <span>{key.slice(-5)}</span>
455
479
  </span>
456
480
  </div>
@@ -27,7 +27,7 @@ export type ApiKeyService = {
27
27
  ) => Promise<void>;
28
28
  getUsage?: (apiKeys: string[], context: ZudokuContext) => Promise<void>;
29
29
  createKey?: (
30
- apiKey: { description: string; expiresOn?: string },
30
+ apiKey: { description: string; expiresOn?: string; expiresValue?: string },
31
31
  context: ZudokuContext,
32
32
  ) => Promise<void>;
33
33
  };
@@ -74,7 +74,10 @@ const throwIfProblemJson = async (response: Response) => {
74
74
  }
75
75
  };
76
76
 
77
- const createDefaultHandler = (deploymentName: string): ApiKeyService => {
77
+ const createDefaultHandler = (
78
+ deploymentName: string,
79
+ options: ApiKeyPluginOptions,
80
+ ): ApiKeyService => {
78
81
  return {
79
82
  deleteKey: async (consumerId, keyId, context) => {
80
83
  const request = new Request(
@@ -154,11 +157,12 @@ const createDefaultHandler = (deploymentName: string): ApiKeyService => {
154
157
 
155
158
  return data.data.map((consumer) => ({
156
159
  id: consumer.id,
157
- label: consumer.label ?? consumer.subject ?? "API Key",
160
+ label: consumer.label || consumer.subject || "API Key",
158
161
  apiKeys: consumer.apiKeys.data,
159
162
  key: consumer.apiKeys.data.at(0),
160
163
  }));
161
164
  },
165
+ ...options,
162
166
  };
163
167
  };
164
168
 
@@ -170,7 +174,7 @@ export const apiKeyPlugin = (
170
174
  ): ZudokuPlugin & ApiIdentityPlugin & ProfileMenuPlugin => {
171
175
  const service: ApiKeyService =
172
176
  "deploymentName" in options
173
- ? createDefaultHandler(options.deploymentName)
177
+ ? createDefaultHandler(options.deploymentName, options)
174
178
  : options;
175
179
 
176
180
  return {
@@ -203,7 +207,6 @@ export const apiKeyPlugin = (
203
207
  }
204
208
  },
205
209
  getRoutes: (): RouteObject[] => {
206
- // TODO: Make lazy
207
210
  return [
208
211
  {
209
212
  element: <ProtectedRoute />,
@@ -213,10 +216,6 @@ export const apiKeyPlugin = (
213
216
  path: "/settings/api-keys",
214
217
  element: <SettingsApiKeys service={service} />,
215
218
  },
216
- // {
217
- // path: "/settings/api-keys/new",
218
- // element: <CreateApiKey service={service} />,
219
- // },
220
219
  ],
221
220
  },
222
221
  ];
@@ -53,10 +53,11 @@ export const MdxPage = ({
53
53
  const categoryTitle = useCurrentItem()?.categoryLabel;
54
54
 
55
55
  const title = frontmatter.title;
56
+ const description = frontmatter.description ?? excerpt;
56
57
  const category = frontmatter.category ?? categoryTitle;
57
58
  const hideToc = frontmatter.toc === false || defaultOptions?.toc === false;
58
59
  const pageTitle =
59
- tableOfContents.find((item) => item.depth === 1)?.value ?? title;
60
+ title ?? tableOfContents.find((item) => item.depth === 1)?.value;
60
61
  const hidePager =
61
62
  frontmatter.disable_pager ??
62
63
  frontmatter.disablePager ??
@@ -110,7 +111,7 @@ export const MdxPage = ({
110
111
  >
111
112
  <Helmet>
112
113
  <title>{pageTitle}</title>
113
- {excerpt && <meta name="description" content={excerpt} />}
114
+ {description && <meta name="description" content={description} />}
114
115
  </Helmet>
115
116
  <Typography className="max-w-full xl:w-full xl:max-w-3xl flex-1 shrink pt-(--padding-content-top)">
116
117
  {(category || title) && (
@@ -177,7 +178,7 @@ export const MdxPage = ({
177
178
  </>
178
179
  )}
179
180
  </Typography>
180
- <div className="hidden xl:block">
181
+ <div className="hidden xl:block" data-pagefind-ignore="all">
181
182
  {showToc && <Toc entries={tocEntries} />}
182
183
  </div>
183
184
  </div>
@@ -220,6 +220,8 @@ export const OperationList = ({
220
220
  : undefined,
221
221
  };
222
222
 
223
+ const helmetTitle = [schema.tag.name, title].filter(Boolean).join(" - ");
224
+
223
225
  return (
224
226
  <div
225
227
  className="pt-(--padding-content-top)"
@@ -227,7 +229,7 @@ export const OperationList = ({
227
229
  data-pagefind-meta="section:openapi"
228
230
  >
229
231
  <Helmet>
230
- <title>{[schema.tag.name, title].filter(Boolean).join(" - ")}</title>
232
+ {helmetTitle && <title>{helmetTitle}</title>}
231
233
  {metaDescription && (
232
234
  <meta name="description" content={metaDescription} />
233
235
  )}
@@ -243,7 +245,7 @@ export const OperationList = ({
243
245
  registerNavigationAnchor
244
246
  className="mb-0"
245
247
  >
246
- {schema.tag.name ?? "Other endpoints"}
248
+ {schema.tag.name ?? "Documentation"}
247
249
  {showVersions && (
248
250
  <span className="text-xl text-muted-foreground ms-1.5">
249
251
  {" "}
@@ -173,7 +173,7 @@ export const Sidecar = ({
173
173
  embedded
174
174
  language={selectedLang}
175
175
  noBackground
176
- className="[--scrollbar-color:gray] rounded-none text-xs max-h-[500px] p-2"
176
+ className="[--scrollbar-color:gray] rounded-none text-xs max-h-[500px]"
177
177
  code={code!}
178
178
  />
179
179
  </CollapsibleCode>
@@ -104,7 +104,7 @@ export const SidecarExamples = ({
104
104
  embedded
105
105
  language={language}
106
106
  noBackground
107
- className="[--scrollbar-color:gray] rounded-none text-xs max-h-[500px] p-2"
107
+ className="[--scrollbar-color:gray] rounded-none text-xs max-h-[500px]"
108
108
  code={formattedExample}
109
109
  />
110
110
  </CollapsibleCode>
@@ -19,7 +19,7 @@ type Documents = {
19
19
  "\n query OperationsForTag(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n servers {\n url\n }\n description\n summary\n title\n url\n version\n tag(slug: $tag, untagged: $untagged) {\n name\n description\n operations {\n slug\n ...OperationsFragment\n }\n next {\n name\n slug\n }\n prev {\n name\n slug\n }\n }\n }\n }\n": typeof types.OperationsForTagDocument;
20
20
  "\n query GetSchemas($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n title\n description\n summary\n components {\n schemas {\n name\n schema\n extensions\n }\n }\n }\n }\n": typeof types.GetSchemasDocument;
21
21
  "\n query getServerQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n": typeof types.GetServerQueryDocument;
22
- "\n query GetNavigationOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n slug\n name\n extensions\n operations {\n summary\n slug\n method\n operationId\n path\n }\n }\n components {\n schemas {\n __typename\n }\n }\n }\n }\n": typeof types.GetNavigationOperationsDocument;
22
+ "\n query GetNavigationOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n extensions\n tags {\n slug\n name\n extensions\n operations {\n summary\n slug\n method\n operationId\n path\n }\n }\n components {\n schemas {\n __typename\n }\n }\n }\n }\n": typeof types.GetNavigationOperationsDocument;
23
23
  };
24
24
  const documents: Documents = {
25
25
  "\n query ServersQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n":
@@ -34,7 +34,7 @@ const documents: Documents = {
34
34
  types.GetSchemasDocument,
35
35
  "\n query getServerQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n":
36
36
  types.GetServerQueryDocument,
37
- "\n query GetNavigationOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n slug\n name\n extensions\n operations {\n summary\n slug\n method\n operationId\n path\n }\n }\n components {\n schemas {\n __typename\n }\n }\n }\n }\n":
37
+ "\n query GetNavigationOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n extensions\n tags {\n slug\n name\n extensions\n operations {\n summary\n slug\n method\n operationId\n path\n }\n }\n components {\n schemas {\n __typename\n }\n }\n }\n }\n":
38
38
  types.GetNavigationOperationsDocument,
39
39
  };
40
40
 
@@ -78,7 +78,7 @@ export function graphql(
78
78
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
79
79
  */
80
80
  export function graphql(
81
- source: "\n query GetNavigationOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n tags {\n slug\n name\n extensions\n operations {\n summary\n slug\n method\n operationId\n path\n }\n }\n components {\n schemas {\n __typename\n }\n }\n }\n }\n",
81
+ source: "\n query GetNavigationOperations($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n extensions\n tags {\n slug\n name\n extensions\n operations {\n summary\n slug\n method\n operationId\n path\n }\n }\n components {\n schemas {\n __typename\n }\n }\n }\n }\n",
82
82
  ): typeof import("./graphql.js").GetNavigationOperationsDocument;
83
83
 
84
84
  export function graphql(source: string) {
@@ -383,6 +383,7 @@ export type GetNavigationOperationsQuery = {
383
383
  __typename?: "Query";
384
384
  schema: {
385
385
  __typename?: "Schema";
386
+ extensions?: any | null;
386
387
  tags: Array<{
387
388
  __typename?: "SchemaTag";
388
389
  slug?: string | null;
@@ -645,6 +646,7 @@ export const GetServerQueryDocument = new TypedDocumentString(`
645
646
  export const GetNavigationOperationsDocument = new TypedDocumentString(`
646
647
  query GetNavigationOperations($input: JSON!, $type: SchemaType!) {
647
648
  schema(input: $input, type: $type) {
649
+ extensions
648
650
  tags {
649
651
  slug
650
652
  name
@@ -1,6 +1,7 @@
1
1
  import { CirclePlayIcon, LogInIcon } from "lucide-react";
2
2
  import { type ReactNode } from "react";
3
3
  import { matchPath } from "react-router";
4
+ import type { NavigationItem } from "../../../config/validators/NavigationSchema.js";
4
5
  import { useAuth } from "../../authentication/hook.js";
5
6
  import { type ZudokuPlugin } from "../../core/plugins.js";
6
7
  import { Button } from "../../ui/Button.js";
@@ -18,6 +19,7 @@ import { getRoutes, getVersions } from "./util/getRoutes.js";
18
19
  export const GetNavigationOperationsQuery = graphql(`
19
20
  query GetNavigationOperations($input: JSON!, $type: SchemaType!) {
20
21
  schema(input: $input, type: $type) {
22
+ extensions
21
23
  tags {
22
24
  slug
23
25
  name
@@ -139,25 +141,73 @@ export const openApiPlugin = (config: OasPluginConfig): ZudokuPlugin => {
139
141
  });
140
142
  const data = await context.queryClient.ensureQueryData(query);
141
143
 
142
- const categories = data.schema.tags.flatMap((tag) => {
143
- if (!tag.name || tag.operations.length === 0) return [];
144
+ const tagCategories = new Map(
145
+ data.schema.tags
146
+ .filter((tag) => tag.name && tag.operations.length > 0)
147
+ .map((tag) => {
148
+ if (!tag.name) {
149
+ throw new Error(`Tag ${tag.slug} has no name`);
150
+ }
151
+
152
+ const categoryPath = joinUrl(basePath, versionParam, tag.slug);
153
+
154
+ const isCollapsed =
155
+ tag.extensions?.["x-zudoku-collapsed"] ??
156
+ !config.options?.expandAllTags;
157
+ const isCollapsible =
158
+ tag.extensions?.["x-zudoku-collapsible"] ?? true;
159
+
160
+ return [
161
+ tag.name,
162
+ createNavigationCategory({
163
+ label: tag.name,
164
+ path: categoryPath,
165
+ operations: tag.operations,
166
+ collapsed: isCollapsed,
167
+ collapsible: isCollapsible,
168
+ }),
169
+ ];
170
+ }),
171
+ );
144
172
 
145
- const categoryPath = joinUrl(basePath, versionParam, tag.slug);
173
+ const tagGroups =
174
+ (data.schema.extensions?.["x-tagGroups"] as
175
+ | { name: string; tags: string[] }[]
176
+ | undefined) ?? [];
146
177
 
147
- const isCollapsed =
148
- tag.extensions?.["x-zudoku-collapsed"] ??
149
- !config.options?.expandAllTags;
150
- const isCollapsible =
151
- tag.extensions?.["x-zudoku-collapsible"] ?? true;
178
+ const groupedTags = new Set(
179
+ tagGroups.flatMap((group) =>
180
+ group.tags.filter((name) => tagCategories.has(name)),
181
+ ),
182
+ );
152
183
 
153
- return createNavigationCategory({
154
- label: tag.name,
155
- path: categoryPath,
156
- operations: tag.operations,
157
- collapsed: isCollapsed,
158
- collapsible: isCollapsible,
159
- });
160
- });
184
+ const groupedCategories: NavigationItem[] = tagGroups.flatMap(
185
+ (group) => {
186
+ const items = group.tags
187
+ .map((name) => tagCategories.get(name))
188
+ .filter(Boolean) as NavigationItem[];
189
+
190
+ if (items.length === 0) {
191
+ return [];
192
+ }
193
+ return [
194
+ {
195
+ type: "category",
196
+ label: group.name,
197
+ items,
198
+ collapsible: true,
199
+ collapsed: !config.options?.expandAllTags,
200
+ },
201
+ ];
202
+ },
203
+ );
204
+
205
+ const categories: NavigationItem[] = [
206
+ ...groupedCategories,
207
+ ...Array.from(tagCategories.entries())
208
+ .filter(([name]) => !groupedTags.has(name))
209
+ .map(([, cat]) => cat),
210
+ ];
161
211
 
162
212
  const untaggedOperations = data.schema.tags.find(
163
213
  (tag) => !tag.name,
@@ -166,7 +216,7 @@ export const openApiPlugin = (config: OasPluginConfig): ZudokuPlugin => {
166
216
  if (untaggedOperations) {
167
217
  categories.push(
168
218
  createNavigationCategory({
169
- label: "Other endpoints",
219
+ label: categories.length === 0 ? "Endpoints" : "Other endpoints",
170
220
  path: joinUrl(basePath, versionParam, UNTAGGED_PATH),
171
221
  operations: untaggedOperations,
172
222
  collapsed: !config.options?.expandAllTags,
@@ -39,7 +39,7 @@ export const PathParams = ({
39
39
  )}
40
40
  />
41
41
 
42
- <div className="flex justify-between items-center">
42
+ <div className="flex justify-between items-center col-span-2">
43
43
  <Controller
44
44
  control={control}
45
45
  name={`pathParams.${i}.value`}
@@ -154,6 +154,12 @@ export const Playground = ({
154
154
  formRef.current?.requestSubmit();
155
155
  });
156
156
 
157
+ const pathParamOrder =
158
+ url.match(/\{([^}]+)\}/g)?.map((match) => match.slice(1, -1)) ?? [];
159
+ const sortedPathParams = [...pathParams].sort(
160
+ (a, b) => pathParamOrder.indexOf(a.name) - pathParamOrder.indexOf(b.name),
161
+ );
162
+
157
163
  const { register, control, handleSubmit, watch, setValue, ...form } =
158
164
  useForm<PlaygroundForm>({
159
165
  defaultValues: {
@@ -174,7 +180,7 @@ export const Playground = ({
174
180
  enum: [],
175
181
  },
176
182
  ],
177
- pathParams: pathParams.map((param) => ({
183
+ pathParams: sortedPathParams.map((param) => ({
178
184
  name: param.name,
179
185
  value: param.defaultValue ?? "",
180
186
  })),
@@ -472,7 +478,7 @@ export const Playground = ({
472
478
  </Collapsible>
473
479
  )}
474
480
 
475
- {pathParams.length > 0 && (
481
+ {sortedPathParams.length > 0 && (
476
482
  <Collapsible defaultOpen>
477
483
  <CollapsibleHeaderTrigger>
478
484
  <ShapesIcon size={16} />