zudoku 0.26.1 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/dist/app/main.d.ts +1 -1
  2. package/dist/app/main.js +19 -7
  3. package/dist/app/main.js.map +1 -1
  4. package/dist/config/loader.js +1 -1
  5. package/dist/config/loader.js.map +1 -1
  6. package/dist/config/validators/InputSidebarSchema.d.ts +2 -2
  7. package/dist/config/validators/common.d.ts +67 -0
  8. package/dist/config/validators/common.js +5 -0
  9. package/dist/config/validators/common.js.map +1 -1
  10. package/dist/config/validators/validate.d.ts +29 -0
  11. package/dist/lib/components/AnchorLink.js +5 -2
  12. package/dist/lib/components/AnchorLink.js.map +1 -1
  13. package/dist/lib/components/Header.js +1 -1
  14. package/dist/lib/components/Header.js.map +1 -1
  15. package/dist/lib/components/Heading.d.ts +1 -1
  16. package/dist/lib/components/Markdown.d.ts +2 -2
  17. package/dist/lib/components/Markdown.js +3 -1
  18. package/dist/lib/components/Markdown.js.map +1 -1
  19. package/dist/lib/components/StatusPage.d.ts +7 -0
  20. package/dist/lib/components/StatusPage.js +71 -0
  21. package/dist/lib/components/StatusPage.js.map +1 -0
  22. package/dist/lib/components/SyntaxHighlight.d.ts +2 -1
  23. package/dist/lib/components/SyntaxHighlight.js +2 -2
  24. package/dist/lib/components/SyntaxHighlight.js.map +1 -1
  25. package/dist/lib/components/ThemeSwitch.js +4 -4
  26. package/dist/lib/components/ThemeSwitch.js.map +1 -1
  27. package/dist/lib/components/cache.d.ts +6 -0
  28. package/dist/lib/components/cache.js +13 -0
  29. package/dist/lib/components/cache.js.map +1 -0
  30. package/dist/lib/components/context/ViewportAnchorContext.js +16 -4
  31. package/dist/lib/components/context/ViewportAnchorContext.js.map +1 -1
  32. package/dist/lib/components/context/ZudokuContext.js +2 -1
  33. package/dist/lib/components/context/ZudokuContext.js.map +1 -1
  34. package/dist/lib/components/index.d.ts +9 -2
  35. package/dist/lib/components/index.js +3 -0
  36. package/dist/lib/components/index.js.map +1 -1
  37. package/dist/lib/components/navigation/SidebarCategory.js +3 -3
  38. package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
  39. package/dist/lib/core/RouteGuard.d.ts +1 -0
  40. package/dist/lib/core/RouteGuard.js +28 -0
  41. package/dist/lib/core/RouteGuard.js.map +1 -0
  42. package/dist/lib/core/ZudokuContext.d.ts +4 -2
  43. package/dist/lib/core/ZudokuContext.js +9 -7
  44. package/dist/lib/core/ZudokuContext.js.map +1 -1
  45. package/dist/lib/oas/graphql/circular.d.ts +3 -0
  46. package/dist/lib/oas/graphql/circular.js +27 -0
  47. package/dist/lib/oas/graphql/circular.js.map +1 -0
  48. package/dist/lib/oas/graphql/index.d.ts +1 -0
  49. package/dist/lib/oas/graphql/index.js +46 -29
  50. package/dist/lib/oas/graphql/index.js.map +1 -1
  51. package/dist/lib/oas/parser/dereference/index.d.ts +0 -1
  52. package/dist/lib/oas/parser/dereference/index.js +1 -1
  53. package/dist/lib/oas/parser/dereference/index.js.map +1 -1
  54. package/dist/lib/plugins/openapi/Endpoint.js +2 -2
  55. package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
  56. package/dist/lib/plugins/openapi/{Route.d.ts → OpenApiRoute.d.ts} +2 -1
  57. package/dist/lib/plugins/openapi/{Route.js → OpenApiRoute.js} +3 -4
  58. package/dist/lib/plugins/openapi/OpenApiRoute.js.map +1 -0
  59. package/dist/lib/plugins/openapi/OperationList.d.ts +4 -1
  60. package/dist/lib/plugins/openapi/OperationList.js +20 -14
  61. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  62. package/dist/lib/plugins/openapi/OperationListItem.js +1 -1
  63. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  64. package/dist/lib/plugins/openapi/ParameterListItem.js +1 -1
  65. package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
  66. package/dist/lib/plugins/openapi/RequestBodySidecarBox.d.ts +1 -1
  67. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +2 -0
  68. package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
  69. package/dist/lib/plugins/openapi/Sidecar.js +3 -3
  70. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  71. package/dist/lib/plugins/openapi/SidecarExamples.js +17 -14
  72. package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
  73. package/dist/lib/plugins/openapi/graphql/gql.d.ts +6 -2
  74. package/dist/lib/plugins/openapi/graphql/gql.js +3 -2
  75. package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
  76. package/dist/lib/plugins/openapi/graphql/graphql.d.ts +47 -26
  77. package/dist/lib/plugins/openapi/graphql/graphql.js +20 -16
  78. package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
  79. package/dist/lib/plugins/openapi/index.js +101 -65
  80. package/dist/lib/plugins/openapi/index.js.map +1 -1
  81. package/dist/lib/plugins/openapi/interfaces.d.ts +8 -2
  82. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +5 -5
  83. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
  84. package/dist/lib/plugins/openapi/playground/Headers.js +17 -16
  85. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  86. package/dist/lib/plugins/openapi/playground/ParamsGrid.d.ts +5 -0
  87. package/dist/lib/plugins/openapi/playground/ParamsGrid.js +4 -0
  88. package/dist/lib/plugins/openapi/playground/ParamsGrid.js.map +1 -0
  89. package/dist/lib/plugins/openapi/playground/PathParams.js +4 -12
  90. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
  91. package/dist/lib/plugins/openapi/playground/Playground.d.ts +13 -0
  92. package/dist/lib/plugins/openapi/playground/Playground.js +19 -31
  93. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  94. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +1 -1
  95. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
  96. package/dist/lib/plugins/openapi/playground/QueryParams.js +4 -3
  97. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  98. package/dist/lib/plugins/openapi/playground/SubmitButton.d.ts +7 -0
  99. package/dist/lib/plugins/openapi/playground/SubmitButton.js +22 -0
  100. package/dist/lib/plugins/openapi/playground/SubmitButton.js.map +1 -0
  101. package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.d.ts +7 -0
  102. package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.js +11 -0
  103. package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.js.map +1 -0
  104. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.d.ts +8 -0
  105. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +95 -0
  106. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -0
  107. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +7 -0
  108. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +16 -0
  109. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js.map +1 -0
  110. package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.d.ts +10 -0
  111. package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.js +32 -0
  112. package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.js.map +1 -0
  113. package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.test.d.ts +1 -0
  114. package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.test.js +56 -0
  115. package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.test.js.map +1 -0
  116. package/dist/lib/plugins/openapi/schema/SchemaComponents.js +1 -1
  117. package/dist/lib/plugins/openapi/schema/SchemaComponents.js.map +1 -1
  118. package/dist/lib/ui/Command.js +1 -1
  119. package/dist/lib/ui/Command.js.map +1 -1
  120. package/dist/lib/ui/Select.js +2 -2
  121. package/dist/lib/ui/Select.js.map +1 -1
  122. package/dist/lib/util/MdxComponents.js +2 -2
  123. package/dist/lib/util/MdxComponents.js.map +1 -1
  124. package/dist/lib/util/joinUrl.js +1 -1
  125. package/dist/lib/util/joinUrl.js.map +1 -1
  126. package/dist/lib/util/joinUrl.test.d.ts +1 -0
  127. package/dist/lib/util/joinUrl.test.js +43 -0
  128. package/dist/lib/util/joinUrl.test.js.map +1 -0
  129. package/dist/lib/util/useScrollToAnchor.d.ts +1 -0
  130. package/dist/lib/util/useScrollToAnchor.js +26 -15
  131. package/dist/lib/util/useScrollToAnchor.js.map +1 -1
  132. package/dist/vite/plugin-api.js +15 -3
  133. package/dist/vite/plugin-api.js.map +1 -1
  134. package/dist/vite/prerender.js +1 -0
  135. package/dist/vite/prerender.js.map +1 -1
  136. package/dist/zuplo/enrich-with-zuplo.js +1 -1
  137. package/dist/zuplo/enrich-with-zuplo.js.map +1 -1
  138. package/dist/zuplo/with-zuplo.d.ts +2 -1
  139. package/dist/zuplo/with-zuplo.js +3 -1
  140. package/dist/zuplo/with-zuplo.js.map +1 -1
  141. package/lib/{AuthenticationPlugin-C9SwOxkc.js → AuthenticationPlugin-Du8cLBSr.js} +3 -3
  142. package/lib/{AuthenticationPlugin-C9SwOxkc.js.map → AuthenticationPlugin-Du8cLBSr.js.map} +1 -1
  143. package/lib/{Markdown-DFN6p0J-.js → Markdown-Cyrx_JrO.js} +1195 -1185
  144. package/lib/{Markdown-DFN6p0J-.js.map → Markdown-Cyrx_JrO.js.map} +1 -1
  145. package/lib/{MdxPage-D9c4z09Q.js → MdxPage-DewragjB.js} +6 -6
  146. package/lib/{MdxPage-D9c4z09Q.js.map → MdxPage-DewragjB.js.map} +1 -1
  147. package/lib/OpenApiRoute-UrC_t0e5.js +36 -0
  148. package/lib/OpenApiRoute-UrC_t0e5.js.map +1 -0
  149. package/lib/{OperationList-DGJWDx1G.js → OperationList-D_ejrepA.js} +1970 -1957
  150. package/lib/OperationList-D_ejrepA.js.map +1 -0
  151. package/lib/{Select-D3O7wISy.js → Select-CnCZ4WhS.js} +61 -61
  152. package/lib/Select-CnCZ4WhS.js.map +1 -0
  153. package/lib/{SlotletProvider-_3zzX_g_.js → SlotletProvider-mQiPDQIH.js} +4 -4
  154. package/lib/{SlotletProvider-_3zzX_g_.js.map → SlotletProvider-mQiPDQIH.js.map} +1 -1
  155. package/lib/{SyntaxHighlight-CJCSPG1F.js → SyntaxHighlight-B0L4SC_N.js} +309 -298
  156. package/lib/SyntaxHighlight-B0L4SC_N.js.map +1 -0
  157. package/lib/{ZudokuContext-DeQZEp-x.js → ZudokuContext-BTUJPpQl.js} +257 -246
  158. package/lib/ZudokuContext-BTUJPpQl.js.map +1 -0
  159. package/lib/{chunk-SYFQ2XB5-BF5IDYrB.js → chunk-SYFQ2XB5-BPvC-soB.js} +5 -5
  160. package/lib/{chunk-SYFQ2XB5-BF5IDYrB.js.map → chunk-SYFQ2XB5-BPvC-soB.js.map} +1 -1
  161. package/lib/circular-Dgpd6AN-.js +15397 -0
  162. package/lib/circular-Dgpd6AN-.js.map +1 -0
  163. package/lib/{createServer-BcaswoFO.js → createServer-BydbkTsd.js} +3487 -5601
  164. package/lib/createServer-BydbkTsd.js.map +1 -0
  165. package/lib/{hook-BRQEDRbn.js → hook-FT3SJLe_.js} +2 -2
  166. package/lib/{hook-BRQEDRbn.js.map → hook-FT3SJLe_.js.map} +1 -1
  167. package/lib/{index-LNp6rxyU.js → index-CjJS0l4l.js} +2 -2
  168. package/lib/{index-LNp6rxyU.js.map → index-CjJS0l4l.js.map} +1 -1
  169. package/lib/index-DGugJOLc.js +1974 -0
  170. package/lib/index-DGugJOLc.js.map +1 -0
  171. package/lib/{joinUrl-BTy9bvoK.js → joinUrl-nLx9pD-Z.js} +2 -2
  172. package/lib/joinUrl-nLx9pD-Z.js.map +1 -0
  173. package/lib/ui/Command.js +27 -27
  174. package/lib/ui/Command.js.map +1 -1
  175. package/lib/ui/Select.js +2 -2
  176. package/lib/ui/Select.js.map +1 -1
  177. package/lib/{useExposedProps-CetwhZpP.js → useExposedProps-BLKFBylA.js} +2 -2
  178. package/lib/{useExposedProps-CetwhZpP.js.map → useExposedProps-BLKFBylA.js.map} +1 -1
  179. package/lib/useScrollToAnchor-eRM9tVvD.js +289 -0
  180. package/lib/useScrollToAnchor-eRM9tVvD.js.map +1 -0
  181. package/lib/zudoku.auth-clerk.js +1 -1
  182. package/lib/zudoku.auth-openid.js +4 -4
  183. package/lib/zudoku.components.js +740 -979
  184. package/lib/zudoku.components.js.map +1 -1
  185. package/lib/zudoku.plugin-api-catalog.js +4 -4
  186. package/lib/zudoku.plugin-api-keys.js +5 -5
  187. package/lib/zudoku.plugin-custom-pages.js +2 -2
  188. package/lib/zudoku.plugin-markdown.js +1 -1
  189. package/lib/zudoku.plugin-openapi.js +6 -5
  190. package/lib/zudoku.plugin-openapi.js.map +1 -1
  191. package/lib/zudoku.plugin-redirect.js +1 -1
  192. package/package.json +2 -2
  193. package/src/app/main.tsx +26 -7
  194. package/src/lib/components/AnchorLink.tsx +5 -2
  195. package/src/lib/components/Header.tsx +1 -1
  196. package/src/lib/components/Markdown.tsx +14 -15
  197. package/src/lib/components/StatusPage.tsx +91 -0
  198. package/src/lib/components/SyntaxHighlight.tsx +14 -0
  199. package/src/lib/components/ThemeSwitch.tsx +14 -15
  200. package/src/lib/components/cache.ts +15 -0
  201. package/src/lib/components/context/ViewportAnchorContext.tsx +20 -6
  202. package/src/lib/components/context/ZudokuContext.ts +3 -1
  203. package/src/lib/components/index.ts +7 -0
  204. package/src/lib/components/navigation/SidebarCategory.tsx +3 -2
  205. package/src/lib/core/RouteGuard.tsx +35 -0
  206. package/src/lib/core/ZudokuContext.ts +9 -8
  207. package/src/lib/oas/graphql/circular.ts +29 -0
  208. package/src/lib/oas/graphql/index.ts +72 -44
  209. package/src/lib/oas/parser/dereference/index.ts +1 -2
  210. package/src/lib/plugins/openapi/Endpoint.tsx +2 -2
  211. package/src/lib/plugins/openapi/{Route.tsx → OpenApiRoute.tsx} +3 -3
  212. package/src/lib/plugins/openapi/OperationList.tsx +34 -12
  213. package/src/lib/plugins/openapi/OperationListItem.tsx +0 -2
  214. package/src/lib/plugins/openapi/ParameterListItem.tsx +1 -0
  215. package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +2 -0
  216. package/src/lib/plugins/openapi/Sidecar.tsx +4 -3
  217. package/src/lib/plugins/openapi/SidecarExamples.tsx +24 -24
  218. package/src/lib/plugins/openapi/graphql/gql.ts +12 -4
  219. package/src/lib/plugins/openapi/graphql/graphql.ts +66 -43
  220. package/src/lib/plugins/openapi/index.tsx +134 -82
  221. package/src/lib/plugins/openapi/interfaces.ts +11 -2
  222. package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +30 -27
  223. package/src/lib/plugins/openapi/playground/Headers.tsx +65 -65
  224. package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +8 -0
  225. package/src/lib/plugins/openapi/playground/PathParams.tsx +34 -74
  226. package/src/lib/plugins/openapi/playground/Playground.tsx +64 -116
  227. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +1 -1
  228. package/src/lib/plugins/openapi/playground/QueryParams.tsx +46 -45
  229. package/src/lib/plugins/openapi/playground/SubmitButton.tsx +75 -0
  230. package/src/lib/plugins/openapi/playground/result-panel/RequestTab.tsx +73 -0
  231. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +210 -0
  232. package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +101 -0
  233. package/src/lib/plugins/openapi/playground/result-panel/convertToTypes.test.ts +64 -0
  234. package/src/lib/plugins/openapi/playground/result-panel/convertToTypes.ts +36 -0
  235. package/src/lib/plugins/openapi/schema/SchemaComponents.tsx +1 -1
  236. package/src/lib/ui/Command.tsx +1 -1
  237. package/src/lib/ui/Select.tsx +1 -1
  238. package/src/lib/util/MdxComponents.tsx +2 -1
  239. package/src/lib/util/joinUrl.test.ts +62 -0
  240. package/src/lib/util/joinUrl.ts +1 -1
  241. package/src/lib/util/useScrollToAnchor.ts +32 -15
  242. package/dist/lib/plugins/openapi/Route.js.map +0 -1
  243. package/dist/lib/plugins/openapi/playground/ResponseTab.d.ts +0 -4
  244. package/dist/lib/plugins/openapi/playground/ResponseTab.js +0 -42
  245. package/dist/lib/plugins/openapi/playground/ResponseTab.js.map +0 -1
  246. package/lib/AnchorLink-bObQitZv.js +0 -34
  247. package/lib/AnchorLink-bObQitZv.js.map +0 -1
  248. package/lib/OperationList-DGJWDx1G.js.map +0 -1
  249. package/lib/Route-VdmEyOD0.js +0 -35
  250. package/lib/Route-VdmEyOD0.js.map +0 -1
  251. package/lib/Select-D3O7wISy.js.map +0 -1
  252. package/lib/StaggeredRender-DgsamH_G.js +0 -17
  253. package/lib/StaggeredRender-DgsamH_G.js.map +0 -1
  254. package/lib/SyntaxHighlight-CJCSPG1F.js.map +0 -1
  255. package/lib/ZudokuContext-DeQZEp-x.js.map +0 -1
  256. package/lib/createServer-BcaswoFO.js.map +0 -1
  257. package/lib/index-Bn6Lc9tq.js +0 -9
  258. package/lib/index-Bn6Lc9tq.js.map +0 -1
  259. package/lib/index-CXRrqOIl.js +0 -1750
  260. package/lib/index-CXRrqOIl.js.map +0 -1
  261. package/lib/index-TaRXY2w1.js +0 -43
  262. package/lib/index-TaRXY2w1.js.map +0 -1
  263. package/lib/joinUrl-BTy9bvoK.js.map +0 -1
  264. package/src/lib/plugins/openapi/playground/ResponseTab.tsx +0 -76
@@ -1,10 +1,10 @@
1
1
  import { j as e } from "./jsx-runtime-Bdg6XQ1m.js";
2
- import { s as j } from "./index-LNp6rxyU.js";
3
- import { u as b } from "./ZudokuContext-DeQZEp-x.js";
4
- import { b as y } from "./chunk-SYFQ2XB5-BF5IDYrB.js";
2
+ import { s as j } from "./index-CjJS0l4l.js";
3
+ import { u as b } from "./ZudokuContext-BTUJPpQl.js";
4
+ import { b as y } from "./chunk-SYFQ2XB5-BPvC-soB.js";
5
5
  import { Head as v, Link as N } from "./zudoku.components.js";
6
6
  import { u as w } from "./state-mM7uaXTW.js";
7
- import { M as C } from "./Markdown-DFN6p0J-.js";
7
+ import { M as C } from "./Markdown-Cyrx_JrO.js";
8
8
  import { c as h } from "./cn-qaFjX9_3.js";
9
9
  const f = (r, n) => j(`${r}-${n}`), k = ({
10
10
  items: r,
@@ -1,14 +1,14 @@
1
1
  import { j as e } from "./jsx-runtime-Bdg6XQ1m.js";
2
2
  import { RotateCwIcon as g, TrashIcon as f, EyeOffIcon as j, EyeIcon as v, CheckIcon as w, CopyIcon as b, FileKey2Icon as K } from "lucide-react";
3
- import { D as k, S as m, R as N } from "./SlotletProvider-_3zzX_g_.js";
3
+ import { D as k, S as m, R as N } from "./SlotletProvider-mQiPDQIH.js";
4
4
  import { i as c } from "./invariant-Caa8-XvF.js";
5
- import { u as d, S as I, a as S, b as A, c as C, d as E, e as x } from "./Select-D3O7wISy.js";
5
+ import { u as d, S as I, a as S, b as A, c as C, d as E, e as x } from "./Select-CnCZ4WhS.js";
6
6
  import { a as P } from "./index.esm-CrSoEshU.js";
7
- import { a as D, L as u, O as R } from "./chunk-SYFQ2XB5-BF5IDYrB.js";
8
- import { a as y, e as q, u as O } from "./ZudokuContext-DeQZEp-x.js";
7
+ import { a as D, L as u, O as R } from "./chunk-SYFQ2XB5-BPvC-soB.js";
8
+ import { a as y, e as q, u as O } from "./ZudokuContext-BTUJPpQl.js";
9
9
  import { Button as l } from "./ui/Button.js";
10
10
  import { Input as z } from "./ui/Input.js";
11
- import { u as F } from "./hook-BRQEDRbn.js";
11
+ import { u as F } from "./hook-FT3SJLe_.js";
12
12
  import { useState as p } from "react";
13
13
  import { c as T } from "./cn-qaFjX9_3.js";
14
14
  const L = ({ service: t }) => {
@@ -1,8 +1,8 @@
1
1
  import { j as o } from "./jsx-runtime-Bdg6XQ1m.js";
2
2
  import a from "react";
3
- import { P as n } from "./Markdown-DFN6p0J-.js";
3
+ import { P as n } from "./Markdown-Cyrx_JrO.js";
4
4
  import { c } from "./cn-qaFjX9_3.js";
5
- import { u as p } from "./useExposedProps-CetwhZpP.js";
5
+ import { u as p } from "./useExposedProps-BLKFBylA.js";
6
6
  const u = ({
7
7
  element: t,
8
8
  render: s,
@@ -74,7 +74,7 @@ const C = (n) => ({
74
74
  const h = {
75
75
  path: r,
76
76
  lazy: async () => {
77
- const { MdxPage: l } = await import("./MdxPage-D9c4z09Q.js"), { default: p, ...g } = await a();
77
+ const { MdxPage: l } = await import("./MdxPage-DewragjB.js"), { default: p, ...g } = await a();
78
78
  return {
79
79
  element: /* @__PURE__ */ P.jsx(
80
80
  l,
@@ -1,11 +1,12 @@
1
1
  import "./jsx-runtime-Bdg6XQ1m.js";
2
- import "./chunk-SYFQ2XB5-BF5IDYrB.js";
3
- import { o as a } from "./index-CXRrqOIl.js";
4
- import "./ZudokuContext-DeQZEp-x.js";
2
+ import "./index-CjJS0l4l.js";
5
3
  import "lucide-react";
6
- import "./hook-BRQEDRbn.js";
4
+ import "./chunk-SYFQ2XB5-BPvC-soB.js";
5
+ import "./hook-FT3SJLe_.js";
7
6
  import "./ui/Button.js";
7
+ import "./joinUrl-nLx9pD-Z.js";
8
+ import { o as f } from "./index-DGugJOLc.js";
8
9
  export {
9
- a as openApiPlugin
10
+ f as openApiPlugin
10
11
  };
11
12
  //# sourceMappingURL=zudoku.plugin-openapi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
1
+ {"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { r as o } from "./chunk-SYFQ2XB5-BF5IDYrB.js";
1
+ import { r as o } from "./chunk-SYFQ2XB5-BPvC-soB.js";
2
2
  const a = (r) => ({
3
3
  getRoutes: () => r.redirects.map(({ from: e, to: t }) => ({
4
4
  path: e,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.26.1",
3
+ "version": "0.28.0",
4
4
  "type": "module",
5
5
  "homepage": "https://zudoku.dev",
6
6
  "repository": {
@@ -131,7 +131,7 @@
131
131
  "@radix-ui/react-progress": "1.1.1",
132
132
  "@radix-ui/react-radio-group": "1.2.2",
133
133
  "@radix-ui/react-scroll-area": "1.2.2",
134
- "@radix-ui/react-select": "2.1.4",
134
+ "@radix-ui/react-select": "2.1.5",
135
135
  "@radix-ui/react-slider": "1.2.2",
136
136
  "@radix-ui/react-slot": "1.1.1",
137
137
  "@radix-ui/react-switch": "1.1.2",
package/src/app/main.tsx CHANGED
@@ -13,8 +13,10 @@ import { configuredSidebar } from "virtual:zudoku-sidebar";
13
13
  import "virtual:zudoku-theme.css";
14
14
  import { Layout, RouterError, Zudoku } from "zudoku/components";
15
15
  import type { ZudokuConfig } from "../config/config.js";
16
+ import { StatusPage } from "../lib/components/StatusPage.js";
16
17
  import type { ZudokuContextOptions } from "../lib/core/ZudokuContext.js";
17
18
  import { isNavigationPlugin } from "../lib/core/plugins.js";
19
+ import { RouteGuard } from "../lib/core/RouteGuard.js";
18
20
 
19
21
  export const convertZudokuConfigToOptions = (
20
22
  config: ZudokuConfig,
@@ -32,6 +34,7 @@ export const convertZudokuConfigToOptions = (
32
34
  !config.page?.logo?.src?.dark;
33
35
 
34
36
  return {
37
+ protectedRoutes: config.protectedRoutes,
35
38
  page: {
36
39
  ...config.page,
37
40
  logo: {
@@ -69,7 +72,10 @@ export const convertZudokuConfigToOptions = (
69
72
  };
70
73
  };
71
74
 
72
- export const getRoutesByOptions = (options: ZudokuContextOptions) => {
75
+ export const getRoutesByOptions = (
76
+ options: ZudokuContextOptions,
77
+ enableStatusPages = false,
78
+ ) => {
73
79
  const allPlugins = [
74
80
  ...(options.plugins ? options.plugins : []),
75
81
  ...(options.authentication?.getAuthenticationPlugin
@@ -79,19 +85,31 @@ export const getRoutesByOptions = (options: ZudokuContextOptions) => {
79
85
 
80
86
  const routes = allPlugins
81
87
  .flatMap((plugin) => (isNavigationPlugin(plugin) ? plugin.getRoutes() : []))
82
- .concat({
83
- path: "*",
84
- loader: () => {
85
- throw new Response("Not Found", { status: 404 });
88
+ .concat(
89
+ enableStatusPages
90
+ ? [400, 403, 404, 405, 414, 416, 500, 501, 502, 503, 504].map(
91
+ (statusCode) => ({
92
+ path: `/.static/${statusCode}`,
93
+ element: <StatusPage statusCode={statusCode} />,
94
+ }),
95
+ )
96
+ : [],
97
+ )
98
+ .concat([
99
+ {
100
+ path: "*",
101
+ loader: () => {
102
+ throw new Response("Not Found", { status: 404 });
103
+ },
86
104
  },
87
- });
105
+ ]);
88
106
 
89
107
  return routes;
90
108
  };
91
109
 
92
110
  export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
93
111
  const options = convertZudokuConfigToOptions(config);
94
- const routes = getRoutesByOptions(options);
112
+ const routes = getRoutesByOptions(options, config.enableStatusPages);
95
113
 
96
114
  return [
97
115
  {
@@ -102,6 +120,7 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
102
120
  ),
103
121
  children: [
104
122
  {
123
+ element: <RouteGuard />,
105
124
  errorElement: <RouterError />,
106
125
  children: routes,
107
126
  },
@@ -1,19 +1,22 @@
1
1
  import React from "react";
2
2
  import { Link, type LinkProps, useLocation } from "react-router";
3
+ import { useScrollToHash } from "../util/useScrollToAnchor.js";
3
4
 
4
5
  /**
5
6
  * Link that scrolls to anchor even if the hash is already set in the URL.
6
7
  */
7
8
  export const AnchorLink = (props: LinkProps) => {
8
9
  const location = useLocation();
10
+ const scrollToHash = useScrollToHash();
9
11
  const hash = typeof props.to === "string" ? props.to : props.to.hash;
10
12
 
11
13
  const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
14
+ props.onClick?.(event);
12
15
  if (!hash?.startsWith("#") || hash !== location.hash) return;
13
16
 
14
17
  event.preventDefault();
15
- document.getElementById(hash.slice(1))?.scrollIntoView();
18
+ scrollToHash(hash);
16
19
  };
17
20
 
18
- return <Link onClick={handleClick} {...props} />;
21
+ return <Link {...props} onClick={handleClick} />;
19
22
  };
@@ -171,8 +171,8 @@ export const Header = memo(function HeaderInner() {
171
171
  )}
172
172
  </ClientOnly>
173
173
  )}
174
- <ThemeSwitch />
175
174
  <Slotlet name="head-navigation-end" />
175
+ <ThemeSwitch />
176
176
  </div>
177
177
  </div>
178
178
  </div>
@@ -1,3 +1,4 @@
1
+ import { memo } from "react";
1
2
  import rehypeRaw from "rehype-raw";
2
3
  import remarkGfm from "remark-gfm";
3
4
  import { visit } from "unist-util-visit";
@@ -20,19 +21,17 @@ const rehypePlugins = [rehypeCodeBlockPlugin, rehypeRaw];
20
21
  // other styles are defined in main.css .prose
21
22
  export const ProseClasses = "prose dark:prose-invert prose-neutral";
22
23
 
23
- export const Markdown = ({
24
- content,
25
- className,
26
- }: {
27
- content: string;
28
- className?: string;
29
- }) => (
30
- <ReactMarkdown
31
- remarkPlugins={remarkPlugins}
32
- rehypePlugins={rehypePlugins}
33
- components={MdxComponents}
34
- className={className}
35
- >
36
- {content}
37
- </ReactMarkdown>
24
+ export const Markdown = memo(
25
+ ({ content, className }: { content: string; className?: string }) => (
26
+ <ReactMarkdown
27
+ remarkPlugins={remarkPlugins}
28
+ rehypePlugins={rehypePlugins}
29
+ components={MdxComponents}
30
+ className={className}
31
+ >
32
+ {content}
33
+ </ReactMarkdown>
34
+ ),
38
35
  );
36
+
37
+ Markdown.displayName = "Markdown";
@@ -0,0 +1,91 @@
1
+ import type { ReactNode } from "react";
2
+ import { ErrorPage } from "./ErrorPage.js";
3
+
4
+ type StatusPageProps = {
5
+ statusCode: number;
6
+ message?: ReactNode;
7
+ };
8
+
9
+ const getDefaultContent = (
10
+ statusCode: number,
11
+ ): { title: string; message: string } => {
12
+ switch (statusCode) {
13
+ case 400:
14
+ return {
15
+ title: "Bad Request",
16
+ message:
17
+ "The request could not be understood by the server due to malformed syntax.",
18
+ };
19
+ case 403:
20
+ return {
21
+ title: "Forbidden",
22
+ message: "You don't have permission to access this resource.",
23
+ };
24
+ case 404:
25
+ return {
26
+ title: "Not Found",
27
+ message: "The requested resource could not be found.",
28
+ };
29
+ case 405:
30
+ return {
31
+ title: "Method Not Allowed",
32
+ message:
33
+ "The request method is not supported for the requested resource.",
34
+ };
35
+ case 414:
36
+ return {
37
+ title: "Request URI Too Large",
38
+ message: "The request URI is too large.",
39
+ };
40
+ case 416:
41
+ return {
42
+ title: "Range Not Satisfiable",
43
+ message: "The server cannot satisfy the request range.",
44
+ };
45
+ case 500:
46
+ return {
47
+ title: "Internal Server Error",
48
+ message: "An unexpected error occurred while processing your request.",
49
+ };
50
+ case 501:
51
+ return {
52
+ title: "Not Implemented",
53
+ message:
54
+ "The server does not support the functionality required to fulfill the request.",
55
+ };
56
+ case 502:
57
+ return {
58
+ title: "Bad Gateway",
59
+ message:
60
+ "The server received an invalid response from the upstream server.",
61
+ };
62
+ case 503:
63
+ return {
64
+ title: "Service Unavailable",
65
+ message: "The server is temporarily unable to handle the request.",
66
+ };
67
+ case 504:
68
+ return {
69
+ title: "Gateway Timeout",
70
+ message:
71
+ "The server did not receive a timely response from the upstream server.",
72
+ };
73
+ default:
74
+ return {
75
+ title: "An error occurred",
76
+ message: "Something went wrong while processing your request.",
77
+ };
78
+ }
79
+ };
80
+
81
+ export const StatusPage = ({ statusCode, message }: StatusPageProps) => {
82
+ const defaultContent = getDefaultContent(statusCode);
83
+
84
+ return (
85
+ <ErrorPage
86
+ title={defaultContent.title}
87
+ message={message ?? defaultContent.message}
88
+ category={statusCode}
89
+ />
90
+ );
91
+ };
@@ -41,6 +41,7 @@ type SyntaxHighlightProps = {
41
41
  copyable?: boolean;
42
42
  showLanguageIndicator?: boolean;
43
43
  language?: string;
44
+ title?: string;
44
45
  } & Omit<HighlightProps, "children" | "language">;
45
46
 
46
47
  const remapLang = {
@@ -50,6 +51,7 @@ const remapLang = {
50
51
  export const SyntaxHighlight = ({
51
52
  copyable = true,
52
53
  language = "plain",
54
+ title,
53
55
  ...props
54
56
  }: SyntaxHighlightProps) => {
55
57
  const { resolvedTheme } = useTheme();
@@ -70,12 +72,18 @@ export const SyntaxHighlight = ({
70
72
  <ClientOnly
71
73
  fallback={
72
74
  <div className="relative group">
75
+ {title && (
76
+ <div className="text-xs text-muted-foreground absolute top-2 font-mono border-b w-full pb-2 px-4 ">
77
+ {title}
78
+ </div>
79
+ )}
73
80
  <pre
74
81
  className={cn(
75
82
  "relative scrollbar overflow-x-auto",
76
83
  props.className,
77
84
  props.noBackground ? "!bg-transparent" : themeColorClasses,
78
85
  props.wrapLines && "whitespace-pre-wrap break-words",
86
+ title && "pt-10",
79
87
  )}
80
88
  >
81
89
  {props.code}
@@ -95,6 +103,11 @@ export const SyntaxHighlight = ({
95
103
  >
96
104
  {({ className, style, tokens, getLineProps, getTokenProps }) => (
97
105
  <div className="relative group">
106
+ {title && (
107
+ <div className="text-xs text-muted-foreground absolute top-2 font-mono border-b w-full pb-2 px-4 ">
108
+ {title}
109
+ </div>
110
+ )}
98
111
  <pre
99
112
  className={cn(
100
113
  "relative scrollbar overflow-x-auto",
@@ -102,6 +115,7 @@ export const SyntaxHighlight = ({
102
115
  props.className,
103
116
  props.noBackground && "!bg-transparent",
104
117
  props.wrapLines && "whitespace-pre-wrap break-words",
118
+ title && "pt-10",
105
119
  )}
106
120
  style={style}
107
121
  >
@@ -1,26 +1,25 @@
1
1
  import { MoonStarIcon, SunIcon } from "lucide-react";
2
2
  import { useTheme } from "next-themes";
3
3
  import { Button } from "zudoku/ui/Button.js";
4
- import { ClientOnly } from "./ClientOnly.js";
4
+ import { cn } from "../util/cn.js";
5
5
 
6
6
  export const ThemeSwitch = () => {
7
7
  const { resolvedTheme, setTheme } = useTheme();
8
8
  const ThemeIcon = resolvedTheme === "dark" ? MoonStarIcon : SunIcon;
9
9
 
10
10
  return (
11
- <ClientOnly>
12
- <Button
13
- variant="ghost"
14
- aria-label={
15
- resolvedTheme === "dark"
16
- ? "Switch to light mode"
17
- : "Switch to dark mode"
18
- }
19
- className="p-2.5 -m-2.5 rounded-full"
20
- onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
21
- >
22
- <ThemeIcon size={18} />
23
- </Button>
24
- </ClientOnly>
11
+ <Button
12
+ variant="ghost"
13
+ size="icon"
14
+ aria-label={
15
+ resolvedTheme === "dark"
16
+ ? "Switch to light mode"
17
+ : "Switch to dark mode"
18
+ }
19
+ className={cn(resolvedTheme ? "opacity-100" : "opacity-0")}
20
+ onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
21
+ >
22
+ <ThemeIcon size={18} />
23
+ </Button>
25
24
  );
26
25
  };
@@ -0,0 +1,15 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+
3
+ export const CACHE_KEYS = Object.freeze({
4
+ API_IDENTITIES: ["api-identities"],
5
+ });
6
+
7
+ export const useCache = () => {
8
+ const queryClient = useQueryClient();
9
+
10
+ return {
11
+ invalidateCache: async (key: keyof typeof CACHE_KEYS) => {
12
+ await queryClient.invalidateQueries({ queryKey: CACHE_KEYS[key] });
13
+ },
14
+ };
15
+ };
@@ -63,6 +63,7 @@ export const ViewportAnchorProvider = ({
63
63
  const [activeAnchor, setActiveAnchor] = useState("");
64
64
  const observerRef = useRef<IntersectionObserver | null>(null);
65
65
  const registeredElements = useRef(new Set<HTMLElement>());
66
+ const pendingElements = useRef(new Set<HTMLElement>());
66
67
 
67
68
  useEffect(() => {
68
69
  observerRef.current = new IntersectionObserver(
@@ -81,6 +82,13 @@ export const ViewportAnchorProvider = ({
81
82
  },
82
83
  );
83
84
 
85
+ // Process any elements that tried to register before observer was ready
86
+ pendingElements.current.forEach((element) => {
87
+ registeredElements.current.add(element);
88
+ observerRef.current?.observe(element);
89
+ });
90
+ pendingElements.current.clear();
91
+
84
92
  return () => observerRef.current?.disconnect();
85
93
  }, []);
86
94
 
@@ -114,14 +122,22 @@ export const ViewportAnchorProvider = ({
114
122
  const observeFns = useMemo(() => {
115
123
  return {
116
124
  observe: (element: HTMLElement | null) => {
117
- if (!element || !observerRef.current) return;
125
+ if (!element) return;
126
+
127
+ if (!observerRef.current) {
128
+ pendingElements.current.add(element);
129
+ return;
130
+ }
131
+
118
132
  registeredElements.current.add(element);
119
133
  observerRef.current.observe(element);
120
134
  },
121
135
  unobserve: (element: HTMLElement | null) => {
122
- if (!element || !observerRef.current) return;
136
+ if (!element) return;
137
+
138
+ pendingElements.current.delete(element);
123
139
  registeredElements.current.delete(element);
124
- observerRef.current.unobserve(element);
140
+ observerRef.current?.unobserve(element);
125
141
  },
126
142
  };
127
143
  }, []);
@@ -132,8 +148,6 @@ export const ViewportAnchorProvider = ({
132
148
  );
133
149
 
134
150
  return (
135
- <ViewportAnchorContext.Provider value={value}>
136
- {children}
137
- </ViewportAnchorContext.Provider>
151
+ <ViewportAnchorContext value={value}>{children}</ViewportAnchorContext>
138
152
  );
139
153
  };
@@ -3,6 +3,7 @@ import { createContext, useContext } from "react";
3
3
  import { matchPath, useLocation } from "react-router";
4
4
  import { ZudokuContext } from "../../core/ZudokuContext.js";
5
5
  import { joinPath } from "../../util/joinPath.js";
6
+ import { CACHE_KEYS } from "../cache.js";
6
7
  import { traverseSidebar } from "../navigation/utils.js";
7
8
 
8
9
  export const ZudokuReactContext = createContext<ZudokuContext | undefined>(
@@ -21,9 +22,10 @@ export const useZudoku = () => {
21
22
 
22
23
  export const useApiIdentities = () => {
23
24
  const { getApiIdentities } = useZudoku();
25
+
24
26
  return useQuery({
25
27
  queryFn: getApiIdentities,
26
- queryKey: ["api-identities"],
28
+ queryKey: [CACHE_KEYS.API_IDENTITIES],
27
29
  });
28
30
  };
29
31
 
@@ -15,7 +15,12 @@ import { Layout as LayoutImport } from "./Layout.js";
15
15
  import { Markdown as MarkdownImport } from "./Markdown.js";
16
16
  import { Spinner as SpinnerImport } from "./Spinner.js";
17
17
  import { Zudoku as ZudokuImport } from "./Zudoku.js";
18
+ import {
19
+ CACHE_KEYS as CACHE_KEYS_IMPORT,
20
+ useCache as useCacheImport,
21
+ } from "./cache.js";
18
22
  import { useZudoku as useZudokuImport } from "./context/ZudokuContext.js";
23
+
19
24
  export const useMDXComponents = /*@__PURE__*/ useMDXComponentsImport;
20
25
  export const Layout = /*@__PURE__*/ LayoutImport;
21
26
  export const RouterError = /*@__PURE__*/ RouterErrorImport;
@@ -27,6 +32,8 @@ export const Head = /*@__PURE__*/ Helmet;
27
32
 
28
33
  export const useZudoku = /*@__PURE__*/ useZudokuImport;
29
34
  export const useAuth = /*@__PURE__*/ useAuthImport;
35
+ export const useCache = /*@__PURE__*/ useCacheImport;
36
+ export const CACHE_KEYS = /*@__PURE__*/ CACHE_KEYS_IMPORT;
30
37
  export const Zudoku = /*@__PURE__*/ ZudokuImport;
31
38
 
32
39
  export const Callout = /*@__PURE__*/ CalloutImport;
@@ -67,7 +67,7 @@ export const SidebarCategory = ({
67
67
  isActive: false,
68
68
  className: [
69
69
  "text-start font-medium",
70
- isCollapsible
70
+ isCollapsible || typeof category.link !== "undefined"
71
71
  ? "cursor-pointer"
72
72
  : "cursor-default hover:bg-transparent",
73
73
  ],
@@ -82,7 +82,7 @@ export const SidebarCategory = ({
82
82
  {category.link?.type === "doc" ? (
83
83
  <NavLink
84
84
  to={joinPath(category.link.id)}
85
- className="flex-1"
85
+ className="flex-1 truncate"
86
86
  onClick={() => {
87
87
  // if it is the current path and closed then open it because there's no path change to trigger the open
88
88
  if (isActive && !open) {
@@ -112,6 +112,7 @@ export const SidebarCategory = ({
112
112
  className={cn(
113
113
  // CollapsibleContent class is used to animate and it should only be applied when the user has triggered the toggle
114
114
  hasInteracted && "CollapsibleContent",
115
+ category.items.length === 0 && "hidden",
115
116
  "ms-6 my-1",
116
117
  )}
117
118
  >
@@ -0,0 +1,35 @@
1
+ import { useEffect } from "react";
2
+ import { matchPath, Outlet, useLocation } from "react-router";
3
+ import { useAuth } from "../authentication/hook.js";
4
+ import { useZudoku } from "../components/context/ZudokuContext.js";
5
+ import { ZudokuError } from "../util/invariant.js";
6
+
7
+ export const RouteGuard = () => {
8
+ const auth = useAuth();
9
+ const zudoku = useZudoku();
10
+ const location = useLocation();
11
+
12
+ const isProtected = zudoku.options.protectedRoutes?.some((path) =>
13
+ matchPath({ path, end: true }, location.pathname),
14
+ );
15
+
16
+ useEffect(() => {
17
+ if (isProtected && !auth.isAuthenticated) {
18
+ void zudoku.authentication?.signIn();
19
+ }
20
+ }, [isProtected, auth.isAuthenticated, zudoku.authentication]);
21
+
22
+ if (isProtected && !auth.isAuthenticated) {
23
+ return null;
24
+ }
25
+
26
+ if (isProtected && !auth.isAuthEnabled) {
27
+ throw new ZudokuError("Authentication is not enabled", {
28
+ title: "Authentication is not enabled",
29
+ developerHint:
30
+ "To use protectedRoutes you need authentication to be enabled",
31
+ });
32
+ }
33
+
34
+ return <Outlet />;
35
+ };
@@ -65,6 +65,7 @@ export type ZudokuContextOptions = {
65
65
  components?: MdxComponentsType;
66
66
  };
67
67
  overrides?: ComponentsContextType;
68
+ protectedRoutes?: string[];
68
69
  };
69
70
 
70
71
  export class ZudokuContext {
@@ -74,16 +75,16 @@ export class ZudokuContext {
74
75
  public meta: ZudokuContextOptions["metadata"];
75
76
  public page: ZudokuContextOptions["page"];
76
77
  public authentication?: ZudokuContextOptions["authentication"];
77
- private navigationPlugins: NavigationPlugin[];
78
+ private readonly navigationPlugins: NavigationPlugin[];
78
79
 
79
- constructor(config: ZudokuContextOptions) {
80
- this.plugins = config.plugins ?? [];
81
- this.topNavigation = config.topNavigation ?? [];
82
- this.sidebars = config.sidebars ?? {};
80
+ constructor(public readonly options: ZudokuContextOptions) {
81
+ this.plugins = options.plugins ?? [];
82
+ this.topNavigation = options.topNavigation ?? [];
83
+ this.sidebars = options.sidebars ?? {};
83
84
  this.navigationPlugins = this.plugins.filter(isNavigationPlugin);
84
- this.authentication = config.authentication;
85
- this.meta = config.metadata;
86
- this.page = config.page;
85
+ this.authentication = options.authentication;
86
+ this.meta = options.metadata;
87
+ this.page = options.page;
87
88
  }
88
89
 
89
90
  initialize = async (): Promise<void> => {