zudoku 0.55.1 → 0.57.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 (172) hide show
  1. package/dist/app/demo.js +1 -1
  2. package/dist/app/entry.client.js +1 -1
  3. package/dist/app/entry.server.js +1 -1
  4. package/dist/app/main.js +12 -4
  5. package/dist/app/main.js.map +1 -1
  6. package/dist/app/standalone.js +1 -1
  7. package/dist/config/validators/InputNavigationSchema.d.ts +4 -0
  8. package/dist/config/validators/InputNavigationSchema.js +1 -0
  9. package/dist/config/validators/InputNavigationSchema.js.map +1 -1
  10. package/dist/config/validators/ProtectedRoutesSchema.d.ts +5 -4
  11. package/dist/config/validators/ProtectedRoutesSchema.js +4 -13
  12. package/dist/config/validators/ProtectedRoutesSchema.js.map +1 -1
  13. package/dist/config/validators/validate.d.ts +2 -13
  14. package/dist/config/validators/validate.js +1 -0
  15. package/dist/config/validators/validate.js.map +1 -1
  16. package/dist/flat-config.d.ts +329 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.js +1 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/lib/components/BuildCheck.js +7 -0
  21. package/dist/lib/components/BuildCheck.js.map +1 -1
  22. package/dist/lib/components/Header.js +1 -1
  23. package/dist/lib/components/Header.js.map +1 -1
  24. package/dist/lib/components/Layout.js +4 -7
  25. package/dist/lib/components/Layout.js.map +1 -1
  26. package/dist/lib/components/Meta.d.ts +2 -0
  27. package/dist/lib/components/Meta.js +11 -0
  28. package/dist/lib/components/Meta.js.map +1 -0
  29. package/dist/lib/components/context/ZudokuContext.js +1 -1
  30. package/dist/lib/components/context/ZudokuContext.js.map +1 -1
  31. package/dist/lib/components/index.d.ts +0 -28
  32. package/dist/lib/components/index.js +0 -15
  33. package/dist/lib/components/index.js.map +1 -1
  34. package/dist/lib/components/navigation/NavigationItem.js +3 -2
  35. package/dist/lib/components/navigation/NavigationItem.js.map +1 -1
  36. package/dist/lib/components/navigation/utils.js +12 -11
  37. package/dist/lib/components/navigation/utils.js.map +1 -1
  38. package/dist/lib/core/ZudokuContext.d.ts +3 -1
  39. package/dist/lib/core/ZudokuContext.js +13 -3
  40. package/dist/lib/core/ZudokuContext.js.map +1 -1
  41. package/dist/lib/core/__internal.d.ts +37 -0
  42. package/dist/lib/core/__internal.js +26 -0
  43. package/dist/lib/core/__internal.js.map +1 -0
  44. package/dist/lib/core/router.d.ts +1 -0
  45. package/dist/lib/core/router.js +2 -0
  46. package/dist/lib/core/router.js.map +1 -0
  47. package/dist/lib/plugins/custom-pages/index.js +3 -0
  48. package/dist/lib/plugins/custom-pages/index.js.map +1 -1
  49. package/dist/lib/ui/CodeBlock.js +2 -2
  50. package/dist/lib/ui/CodeBlock.js.map +1 -1
  51. package/dist/lib/ui/Dialog.js +2 -2
  52. package/dist/lib/ui/Dialog.js.map +1 -1
  53. package/dist/vite/plugin-mdx.js +1 -1
  54. package/dist/vite/plugin-mdx.js.map +1 -1
  55. package/dist/vite/sitemap.js +10 -9
  56. package/dist/vite/sitemap.js.map +1 -1
  57. package/lib/CategoryHeading-DCpZu3yG.js +17 -0
  58. package/lib/CategoryHeading-DCpZu3yG.js.map +1 -0
  59. package/lib/{CodeBlock-CVT6z0PP.js → CodeBlock-yJjjRwj-.js} +3 -3
  60. package/lib/CodeBlock-yJjjRwj-.js.map +1 -0
  61. package/lib/{Command-BYukybsa.js → Command-CDn17s8X.js} +2 -2
  62. package/lib/{Command-BYukybsa.js.map → Command-CDn17s8X.js.map} +1 -1
  63. package/lib/Dialog-BrIjMmUK.js +114 -0
  64. package/lib/Dialog-BrIjMmUK.js.map +1 -0
  65. package/lib/{MdxPage-BKyikAKk.js → MdxPage-BmOQ5m5g.js} +16 -15
  66. package/lib/{MdxPage-BKyikAKk.js.map → MdxPage-BmOQ5m5g.js.map} +1 -1
  67. package/lib/{OAuthErrorPage--neTdY8H.js → OAuthErrorPage-Jv3r8wnL.js} +7 -7
  68. package/lib/{OAuthErrorPage--neTdY8H.js.map → OAuthErrorPage-Jv3r8wnL.js.map} +1 -1
  69. package/lib/{OasProvider-yysXhMVI.js → OasProvider-CA_lpILt.js} +3 -3
  70. package/lib/{OasProvider-yysXhMVI.js.map → OasProvider-CA_lpILt.js.map} +1 -1
  71. package/lib/{OperationList-CSYrpcpD.js → OperationList-C-TObVw6.js} +17 -16
  72. package/lib/{OperationList-CSYrpcpD.js.map → OperationList-C-TObVw6.js.map} +1 -1
  73. package/lib/{Pagination-QsyyJuoq.js → Pagination-CBiRGddW.js} +3 -3
  74. package/lib/{Pagination-QsyyJuoq.js.map → Pagination-CBiRGddW.js.map} +1 -1
  75. package/lib/RouteGuard-JLH6tCY8.js +56 -0
  76. package/lib/RouteGuard-JLH6tCY8.js.map +1 -0
  77. package/lib/RouterError-DcVonMP1.js +41 -0
  78. package/lib/RouterError-DcVonMP1.js.map +1 -0
  79. package/lib/{SchemaList-CSZkqmwI.js → SchemaList-BeYWvBC7.js} +15 -14
  80. package/lib/{SchemaList-CSZkqmwI.js.map → SchemaList-BeYWvBC7.js.map} +1 -1
  81. package/lib/{SchemaView-bhJ_U4vL.js → SchemaView-CRcShewo.js} +4 -4
  82. package/lib/{SchemaView-bhJ_U4vL.js.map → SchemaView-CRcShewo.js.map} +1 -1
  83. package/lib/{Select-DlfI9FFO.js → Select-C3efYI1n.js} +8 -8
  84. package/lib/{Select-DlfI9FFO.js.map → Select-C3efYI1n.js.map} +1 -1
  85. package/lib/{SignUp-C6ogvx5s.js → SignUp-CxBGHgba.js} +11 -11
  86. package/lib/{SignUp-C6ogvx5s.js.map → SignUp-CxBGHgba.js.map} +1 -1
  87. package/lib/{Slot-Dgy8tqef.js → Slot-DOtTvoyj.js} +1634 -1868
  88. package/lib/{Slot-Dgy8tqef.js.map → Slot-DOtTvoyj.js.map} +1 -1
  89. package/lib/{SyntaxHighlight-BD_Z_Csq.js → SyntaxHighlight-GR0eix_L.js} +313 -313
  90. package/lib/SyntaxHighlight-GR0eix_L.js.map +1 -0
  91. package/lib/{Toc-CjX59Ljo.js → Toc-BlcGIkXc.js} +2 -2
  92. package/lib/{Toc-CjX59Ljo.js.map → Toc-BlcGIkXc.js.map} +1 -1
  93. package/lib/{ZudokuContext-Coxa0DfE.js → ZudokuContext-BuJD7yIX.js} +100 -92
  94. package/lib/{ZudokuContext-Coxa0DfE.js.map → ZudokuContext-BuJD7yIX.js.map} +1 -1
  95. package/lib/chunk-QMGIS6GS-DqecZ6nq.js +9204 -0
  96. package/lib/chunk-QMGIS6GS-DqecZ6nq.js.map +1 -0
  97. package/lib/{circular-Q4G1nwyb.js → circular-CGTcsqA3.js} +2 -2
  98. package/lib/{circular-Q4G1nwyb.js.map → circular-CGTcsqA3.js.map} +1 -1
  99. package/lib/{createServer-Dtstxqn7.js → createServer-DjgpuLne.js} +4 -4
  100. package/lib/{createServer-Dtstxqn7.js.map → createServer-DjgpuLne.js.map} +1 -1
  101. package/lib/{errors-BoJYHL2E.js → errors-CrI3s7mR.js} +2 -2
  102. package/lib/{errors-BoJYHL2E.js.map → errors-CrI3s7mR.js.map} +1 -1
  103. package/lib/{hook-DEPqwjke.js → hook-bv3iuX7X.js} +2 -2
  104. package/lib/{hook-DEPqwjke.js.map → hook-bv3iuX7X.js.map} +1 -1
  105. package/lib/{index-DRkS-pvf.js → index-CvTWnHZF.js} +18 -18
  106. package/lib/{index-DRkS-pvf.js.map → index-CvTWnHZF.js.map} +1 -1
  107. package/lib/index-DzO-Qh6S.js +1061 -0
  108. package/lib/index-DzO-Qh6S.js.map +1 -0
  109. package/lib/{index-Bl1W774G.js → index-HarEI51d.js} +2 -2
  110. package/lib/{index-Bl1W774G.js.map → index-HarEI51d.js.map} +1 -1
  111. package/lib/{RouteGuard-D17dUEM_.js → index.esm-BnYHxCYC.js} +226 -281
  112. package/lib/index.esm-BnYHxCYC.js.map +1 -0
  113. package/lib/mutation-Dy_5up8v.js +196 -0
  114. package/lib/mutation-Dy_5up8v.js.map +1 -0
  115. package/lib/ui/CodeBlock.js +1 -1
  116. package/lib/ui/Command.js +1 -1
  117. package/lib/ui/Dialog.js +56 -41
  118. package/lib/ui/Dialog.js.map +1 -1
  119. package/lib/ui/SyntaxHighlight.js +3 -3
  120. package/lib/{useExposedProps-DUoV7MCU.js → useExposedProps-BH9aq4MD.js} +32 -32
  121. package/lib/{useExposedProps-DUoV7MCU.js.map → useExposedProps-BH9aq4MD.js.map} +1 -1
  122. package/lib/useLatest-hmRS46UF.js +11 -0
  123. package/lib/useLatest-hmRS46UF.js.map +1 -0
  124. package/lib/zudoku.__internal.js +2965 -0
  125. package/lib/zudoku.__internal.js.map +1 -0
  126. package/lib/zudoku.auth-auth0.js +1 -1
  127. package/lib/zudoku.auth-azureb2c.js +5 -5
  128. package/lib/zudoku.auth-clerk.js +2 -2
  129. package/lib/zudoku.auth-openid.js +5 -5
  130. package/lib/zudoku.auth-supabase.js +2 -2
  131. package/lib/zudoku.components.js +20 -28
  132. package/lib/zudoku.hooks.js +4 -4
  133. package/lib/zudoku.plugin-api-catalog.js +18 -18
  134. package/lib/zudoku.plugin-api-keys.js +28 -27
  135. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  136. package/lib/zudoku.plugin-custom-pages.js +8 -5
  137. package/lib/zudoku.plugin-custom-pages.js.map +1 -1
  138. package/lib/zudoku.plugin-markdown.js +1 -1
  139. package/lib/zudoku.plugin-openapi.js +4 -4
  140. package/lib/zudoku.plugin-redirect.js +3 -3
  141. package/lib/zudoku.plugin-search-pagefind.js +14 -14
  142. package/lib/zudoku.router.js +123 -0
  143. package/lib/zudoku.router.js.map +1 -0
  144. package/package.json +14 -6
  145. package/src/app/demo.tsx +1 -1
  146. package/src/app/entry.client.tsx +1 -1
  147. package/src/app/entry.server.tsx +1 -1
  148. package/src/app/main.tsx +20 -5
  149. package/src/app/standalone.tsx +1 -1
  150. package/src/lib/components/BuildCheck.tsx +10 -0
  151. package/src/lib/components/Header.tsx +3 -2
  152. package/src/lib/components/Layout.tsx +2 -21
  153. package/src/lib/components/Meta.tsx +32 -0
  154. package/src/lib/components/context/ZudokuContext.ts +1 -1
  155. package/src/lib/components/index.ts +0 -18
  156. package/src/lib/components/navigation/NavigationItem.tsx +4 -2
  157. package/src/lib/components/navigation/utils.ts +12 -12
  158. package/src/lib/core/ZudokuContext.ts +23 -5
  159. package/src/lib/core/__internal.tsx +30 -0
  160. package/src/lib/core/router.ts +1 -0
  161. package/src/lib/plugins/custom-pages/index.tsx +3 -0
  162. package/src/lib/ui/CodeBlock.tsx +2 -2
  163. package/src/lib/ui/Dialog.tsx +12 -3
  164. package/lib/CodeBlock-CVT6z0PP.js.map +0 -1
  165. package/lib/Dialog-u9Uz9sTt.js +0 -99
  166. package/lib/Dialog-u9Uz9sTt.js.map +0 -1
  167. package/lib/RouteGuard-D17dUEM_.js.map +0 -1
  168. package/lib/SyntaxHighlight-BD_Z_Csq.js.map +0 -1
  169. package/lib/chunk-QMGIS6GS-CdEm9pzB.js +0 -1839
  170. package/lib/chunk-QMGIS6GS-CdEm9pzB.js.map +0 -1
  171. package/lib/index-DYs8gxKX.js +0 -4082
  172. package/lib/index-DYs8gxKX.js.map +0 -1
@@ -0,0 +1,123 @@
1
+ import { A as s, B as t, F as r, H as o, I as u, a as i, b as n, L as S, c, M as R, d as F, N as E, e as N, f as _, O as A, P as l, R as U, g as d, h, i as m, S as C, j as v, k as P, l as g, m as p, D as y, n as x, E as H, o as L, p as k, q as D, r as b, s as w, t as M, u as O, v as B, V as T, w as I, x as f, y as V, z as W, C as q, G as z, J as G, K, Q as j, T as J, U as Q, W as X, X as Y, Y as Z, Z as $, _ as aa, $ as ea, a0 as sa, a1 as ta, a2 as ra, a3 as oa, a4 as ua, a5 as ia, a6 as na, a7 as Sa, a8 as ca, a9 as Ra, aa as Fa, ab as Ea, ac as Na, ad as _a, ae as Aa, af as la, ag as Ua, ah as da, ai as ha, aj as ma, ak as Ca, al as va, am as Pa, an as ga, ao as pa, ap as ya, aq as xa, ar as Ha, as as La, at as ka, au as Da, av as ba, aw as wa, ax as Ma, ay as Oa, az as Ba, aA as Ta, aB as Ia, aC as fa, aD as Va, aE as Wa, aF as qa, aG as za, aH as Ga, aI as Ka, aJ as ja, aK as Ja, aL as Qa, aM as Xa, aN as Ya, aO as Za, aP as $a, aQ as ae, aR as ee, aS as se, aT as te, aU as re, aV as oe, aW as ue, aX as ie, aY as ne, aZ as Se, a_ as ce, a$ as Re, b0 as Fe } from "./chunk-QMGIS6GS-DqecZ6nq.js";
2
+ export {
3
+ s as Await,
4
+ t as BrowserRouter,
5
+ r as Form,
6
+ o as HashRouter,
7
+ u as IDLE_BLOCKER,
8
+ i as IDLE_FETCHER,
9
+ n as IDLE_NAVIGATION,
10
+ S as Link,
11
+ c as Links,
12
+ R as MemoryRouter,
13
+ F as Meta,
14
+ E as NavLink,
15
+ N as Navigate,
16
+ _ as NavigationType,
17
+ A as Outlet,
18
+ l as PrefetchPageLinks,
19
+ U as Route,
20
+ d as Router,
21
+ h as RouterProvider,
22
+ m as Routes,
23
+ C as Scripts,
24
+ v as ScrollRestoration,
25
+ P as ServerRouter,
26
+ g as StaticRouter,
27
+ p as StaticRouterProvider,
28
+ y as UNSAFE_DataRouterContext,
29
+ x as UNSAFE_DataRouterStateContext,
30
+ H as UNSAFE_ErrorResponseImpl,
31
+ L as UNSAFE_FetchersContext,
32
+ k as UNSAFE_FrameworkContext,
33
+ D as UNSAFE_LocationContext,
34
+ b as UNSAFE_NavigationContext,
35
+ w as UNSAFE_RemixErrorBoundary,
36
+ M as UNSAFE_RouteContext,
37
+ O as UNSAFE_ServerMode,
38
+ B as UNSAFE_SingleFetchRedirectSymbol,
39
+ T as UNSAFE_ViewTransitionContext,
40
+ I as UNSAFE_createBrowserHistory,
41
+ f as UNSAFE_createClientRoutes,
42
+ V as UNSAFE_createClientRoutesWithHMRRevalidationOptOut,
43
+ W as UNSAFE_createRouter,
44
+ q as UNSAFE_decodeViaTurboStream,
45
+ z as UNSAFE_deserializeErrors,
46
+ G as UNSAFE_getHydrationData,
47
+ K as UNSAFE_getPatchRoutesOnNavigationFunction,
48
+ j as UNSAFE_getTurboStreamSingleFetchDataStrategy,
49
+ J as UNSAFE_hydrationRouteProperties,
50
+ Q as UNSAFE_invariant,
51
+ X as UNSAFE_mapRouteProperties,
52
+ Y as UNSAFE_shouldHydrateRouteLoader,
53
+ Z as UNSAFE_useFogOFWarDiscovery,
54
+ $ as UNSAFE_useScrollRestoration,
55
+ aa as UNSAFE_withComponentProps,
56
+ ea as UNSAFE_withErrorBoundaryProps,
57
+ sa as UNSAFE_withHydrateFallbackProps,
58
+ ta as createBrowserRouter,
59
+ ra as createCookie,
60
+ oa as createCookieSessionStorage,
61
+ ua as createHashRouter,
62
+ ia as createMemoryRouter,
63
+ na as createMemorySessionStorage,
64
+ Sa as createPath,
65
+ ca as createRequestHandler,
66
+ Ra as createRoutesFromChildren,
67
+ Fa as createRoutesFromElements,
68
+ Ea as createRoutesStub,
69
+ Na as createSearchParams,
70
+ _a as createSession,
71
+ Aa as createSessionStorage,
72
+ la as createStaticHandler,
73
+ Ua as createStaticRouter,
74
+ da as data,
75
+ ha as generatePath,
76
+ ma as href,
77
+ Ca as isCookie,
78
+ va as isRouteErrorResponse,
79
+ Pa as isSession,
80
+ ga as matchPath,
81
+ pa as matchRoutes,
82
+ ya as parsePath,
83
+ xa as redirect,
84
+ Ha as redirectDocument,
85
+ La as renderMatches,
86
+ ka as replace,
87
+ Da as resolvePath,
88
+ ba as unstable_HistoryRouter,
89
+ wa as unstable_RouterContextProvider,
90
+ Ma as unstable_createContext,
91
+ Oa as unstable_setDevServerHooks,
92
+ Ba as unstable_usePrompt,
93
+ Ta as useActionData,
94
+ Ia as useAsyncError,
95
+ fa as useAsyncValue,
96
+ Va as useBeforeUnload,
97
+ Wa as useBlocker,
98
+ qa as useFetcher,
99
+ za as useFetchers,
100
+ Ga as useFormAction,
101
+ Ka as useHref,
102
+ ja as useInRouterContext,
103
+ Ja as useLinkClickHandler,
104
+ Qa as useLoaderData,
105
+ Xa as useLocation,
106
+ Ya as useMatch,
107
+ Za as useMatches,
108
+ $a as useNavigate,
109
+ ae as useNavigation,
110
+ ee as useNavigationType,
111
+ se as useOutlet,
112
+ te as useOutletContext,
113
+ re as useParams,
114
+ oe as useResolvedPath,
115
+ ue as useRevalidator,
116
+ ie as useRouteError,
117
+ ne as useRouteLoaderData,
118
+ Se as useRoutes,
119
+ ce as useSearchParams,
120
+ Re as useSubmit,
121
+ Fe as useViewTransitionState
122
+ };
123
+ //# sourceMappingURL=zudoku.router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zudoku.router.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.55.1",
3
+ "version": "0.57.0",
4
4
  "type": "module",
5
5
  "homepage": "https://zudoku.dev",
6
6
  "repository": {
@@ -103,6 +103,14 @@
103
103
  "import": "./lib/zudoku.components.js",
104
104
  "types": "./dist/lib/components/index.d.ts"
105
105
  },
106
+ "./__internal": {
107
+ "import": "./lib/zudoku.__internal.js",
108
+ "types": "./dist/lib/__internal.d.ts"
109
+ },
110
+ "./router": {
111
+ "import": "./lib/zudoku.router.js",
112
+ "types": "./dist/lib/core/router.d.ts"
113
+ },
106
114
  "./processors/*": {
107
115
  "import": "./lib/processors/*.js",
108
116
  "types": "./dist/lib/plugins/openapi/processors/*.d.ts"
@@ -164,10 +172,10 @@
164
172
  "@radix-ui/react-visually-hidden": "1.2.3",
165
173
  "@scalar/openapi-parser": "0.18.0",
166
174
  "@sentry/node": "9.26.0",
167
- "@shikijs/langs": "3.8.0",
168
- "@shikijs/rehype": "3.8.0",
169
- "@shikijs/themes": "3.8.0",
170
- "@shikijs/transformers": "3.8.0",
175
+ "@shikijs/langs": "3.8.1",
176
+ "@shikijs/rehype": "3.8.1",
177
+ "@shikijs/themes": "3.8.1",
178
+ "@shikijs/transformers": "3.8.1",
171
179
  "@sindresorhus/slugify": "2.2.1",
172
180
  "@stefanprobst/rehype-extract-toc": "3.0.0",
173
181
  "@tailwindcss/typography": "0.5.16",
@@ -234,7 +242,7 @@
234
242
  "remark-rehype": "^11.1.2",
235
243
  "rollup": "4.45.0",
236
244
  "semver": "7.7.2",
237
- "shiki": "3.8.0",
245
+ "shiki": "3.8.1",
238
246
  "sitemap": "8.0.0",
239
247
  "spin-delay": "2.0.1",
240
248
  "strip-ansi": "7.1.0",
package/src/app/demo.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import logger from "loglevel";
2
2
  import { createRoot } from "react-dom/client";
3
3
  import { createBrowserRouter } from "react-router";
4
- import { Bootstrap } from "zudoku/components";
4
+ import { Bootstrap } from "zudoku/__internal";
5
5
  import type { ZudokuConfig } from "../config/validators/validate.js";
6
6
  import DemoAnnouncement from "../lib/demo/DemoAnnouncement.js";
7
7
  import { openApiPlugin } from "../lib/plugins/openapi/index.js";
@@ -6,7 +6,7 @@ import {
6
6
  } from "react-router";
7
7
  import config from "virtual:zudoku-config";
8
8
  import "vite/modulepreload-polyfill";
9
- import { Bootstrap } from "zudoku/components";
9
+ import { Bootstrap } from "zudoku/__internal";
10
10
  import { getRoutesByConfig } from "./main.js";
11
11
 
12
12
  const routes = getRoutesByConfig(config);
@@ -11,7 +11,7 @@ import {
11
11
  type RouteObject,
12
12
  } from "react-router";
13
13
  import "vite/modulepreload-polyfill";
14
- import { BootstrapStatic, ServerError } from "zudoku/components";
14
+ import { BootstrapStatic, ServerError } from "zudoku/__internal";
15
15
  import { NO_DEHYDRATE } from "../lib/components/cache.js";
16
16
  import type { PrerenderResponse } from "../vite/prerender/PrerenderResponse.js";
17
17
  import { getRoutesByConfig } from "./main.js";
package/src/app/main.tsx CHANGED
@@ -15,11 +15,13 @@ import "virtual:zudoku-theme.css";
15
15
  import {
16
16
  BuildCheck,
17
17
  Layout,
18
+ Meta,
18
19
  RouteGuard,
19
20
  RouterError,
20
21
  StatusPage,
21
- Zudoku,
22
- } from "zudoku/components";
22
+ } from "zudoku/__internal";
23
+ import { Zudoku } from "zudoku/components";
24
+ import { Outlet } from "zudoku/router";
23
25
  import type { ZudokuConfig } from "../config/config.js";
24
26
  import type { ZudokuContextOptions } from "../lib/core/ZudokuContext.js";
25
27
  import { isNavigationPlugin } from "../lib/core/plugins.js";
@@ -110,17 +112,30 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
110
112
  buildId={import.meta.env.ZUPLO_BUILD_ID}
111
113
  environmentType={import.meta.env.ZUPLO_ENVIRONMENT_TYPE}
112
114
  />
113
- <Layout />
115
+ <Outlet />
114
116
  </Zudoku>
115
117
  ),
116
118
  hydrateFallbackElement: <div>Loading...</div>,
117
119
  children: [
118
120
  {
119
- element: <RouteGuard />,
121
+ element: (
122
+ <Meta>
123
+ <RouteGuard />
124
+ </Meta>
125
+ ),
120
126
  errorElement: <RouterError />,
121
- children: routes,
127
+ children: routes.map((r) =>
128
+ r.handle?.layout === "none" ? r : wrapWithLayout(r),
129
+ ),
122
130
  },
123
131
  ],
124
132
  },
125
133
  ];
126
134
  };
135
+
136
+ const wrapWithLayout = (route: RouteObject) => {
137
+ return {
138
+ element: <Layout />,
139
+ children: [route],
140
+ };
141
+ };
@@ -1,6 +1,6 @@
1
1
  import { createRoot } from "react-dom/client";
2
2
  import { createBrowserRouter } from "react-router";
3
- import { Bootstrap } from "zudoku/components";
3
+ import { Bootstrap } from "zudoku/__internal";
4
4
  import type { ZudokuConfig } from "../config/validators/validate.js";
5
5
  import { openApiPlugin } from "../lib/plugins/openapi/index.js";
6
6
  import "../lib/util/logInit.js";
@@ -1,5 +1,6 @@
1
1
  import { useQuery } from "@tanstack/react-query";
2
2
  import { CircleFadingArrowUpIcon, LoaderCircleIcon } from "lucide-react";
3
+ import { useEffect } from "react";
3
4
  import { z } from "zod/v4";
4
5
  import { Button } from "../ui/Button.js";
5
6
 
@@ -32,6 +33,15 @@ export const BuildCheck = ({
32
33
  .then((data) => BuildStatusSchema.parse(data)),
33
34
  });
34
35
 
36
+ useEffect(() => {
37
+ if (
38
+ buildStatusQuery.data?.status === "success" &&
39
+ buildStatusQuery.data.buildId
40
+ ) {
41
+ document.cookie = `zuplo-build=${buildStatusQuery.data.buildId}; path=/; max-age=300; secure; SameSite=None`;
42
+ }
43
+ }, [buildStatusQuery.data]);
44
+
35
45
  if (
36
46
  buildStatusQuery.isError ||
37
47
  !buildStatusQuery.data ||
@@ -92,7 +92,7 @@ export const Header = memo(function HeaderInner() {
92
92
  <div className="flex">
93
93
  <Link to={site?.logo?.href ?? "/"}>
94
94
  <div className="flex items-center gap-3.5">
95
- {site?.logo && (
95
+ {site?.logo ? (
96
96
  <>
97
97
  <img
98
98
  src={logoLightSrc}
@@ -109,8 +109,9 @@ export const Header = memo(function HeaderInner() {
109
109
  loading="lazy"
110
110
  />
111
111
  </>
112
+ ) : (
113
+ <span className="font-semibold text-2xl">{site?.title}</span>
112
114
  )}
113
- <span className="font-semibold text-2xl">{site?.title}</span>
114
115
  </div>
115
116
  </Link>
116
117
  </div>
@@ -1,8 +1,6 @@
1
- import { Helmet } from "@zudoku/react-helmet-async";
2
1
  import { Suspense, useEffect, type ReactNode } from "react";
3
- import { Outlet, useLocation } from "react-router";
2
+ import { Outlet } from "react-router";
4
3
  import { cn } from "../util/cn.js";
5
- import { joinUrl } from "../util/joinUrl.js";
6
4
  import { useScrollToAnchor } from "../util/useScrollToAnchor.js";
7
5
  import { useScrollToTop } from "../util/useScrollToTop.js";
8
6
  import { useZudoku } from "./context/ZudokuContext.js";
@@ -19,8 +17,7 @@ const LoadingFallback = () => (
19
17
  );
20
18
 
21
19
  export const Layout = ({ children }: { children?: ReactNode }) => {
22
- const { meta, authentication, options } = useZudoku();
23
- const location = useLocation();
20
+ const { authentication } = useZudoku();
24
21
 
25
22
  useScrollToAnchor();
26
23
  useScrollToTop();
@@ -32,22 +29,6 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
32
29
 
33
30
  return (
34
31
  <>
35
- <Helmet titleTemplate={meta?.title}>
36
- {options.canonicalUrlOrigin && (
37
- <link
38
- rel="canonical"
39
- href={joinUrl(
40
- options.canonicalUrlOrigin,
41
- options.basePath,
42
- location.pathname,
43
- )}
44
- />
45
- )}
46
- {meta?.description && (
47
- <meta name="description" content={meta.description} />
48
- )}
49
- {meta?.favicon && <link rel="icon" href={meta.favicon} />}
50
- </Helmet>
51
32
  <Slot.Target name="layout-before-head" />
52
33
  <Header />
53
34
  <Slot.Target name="layout-after-head" />
@@ -0,0 +1,32 @@
1
+ import { Helmet } from "@zudoku/react-helmet-async";
2
+ import type { PropsWithChildren } from "react";
3
+ import { useLocation } from "react-router";
4
+ import { joinUrl } from "../util/joinUrl.js";
5
+ import { useZudoku } from "./context/ZudokuContext.js";
6
+
7
+ export const Meta = ({ children }: PropsWithChildren) => {
8
+ const { meta, options } = useZudoku();
9
+ const location = useLocation();
10
+
11
+ return (
12
+ <>
13
+ <Helmet titleTemplate={meta?.title} defaultTitle={meta?.defaultTitle}>
14
+ {options.canonicalUrlOrigin && (
15
+ <link
16
+ rel="canonical"
17
+ href={joinUrl(
18
+ options.canonicalUrlOrigin,
19
+ options.basePath,
20
+ location.pathname,
21
+ )}
22
+ />
23
+ )}
24
+ {meta?.description && (
25
+ <meta name="description" content={meta.description} />
26
+ )}
27
+ {meta?.favicon && <link rel="icon" href={meta.favicon} />}
28
+ </Helmet>
29
+ {children}
30
+ </>
31
+ );
32
+ };
@@ -39,7 +39,7 @@ const getItemPath = (item: NavigationItem) => {
39
39
  case "link":
40
40
  return item.to;
41
41
  case "custom-page":
42
- return item.path;
42
+ return joinUrl(item.path);
43
43
  default:
44
44
  return undefined;
45
45
  }
@@ -3,44 +3,26 @@ import { Helmet } from "@zudoku/react-helmet-async";
3
3
  import { useTheme as useThemeImport } from "next-themes";
4
4
  import { Link as LinkImport } from "react-router";
5
5
  import { useAuth as useAuthImport } from "../authentication/hook.js";
6
- import { RouteGuard as RouteGuardImport } from "../core/RouteGuard.js";
7
- import { RouterError as RouterErrorImport } from "../errors/RouterError.js";
8
- import { ServerError as ServerErrorImport } from "../errors/ServerError.js";
9
6
  import { Button as ButtonImport } from "../ui/Button.js";
10
7
  import { Callout as CalloutImport } from "../ui/Callout.js";
11
- import {
12
- Bootstrap as BootstrapImport,
13
- BootstrapStatic as BootstrapStaticImport,
14
- } from "./Bootstrap.js";
15
- import { BuildCheck as BuildCheckImport } from "./BuildCheck.js";
16
8
  import {
17
9
  CACHE_KEYS as CACHE_KEYS_IMPORT,
18
10
  useCache as useCacheImport,
19
11
  } from "./cache.js";
20
12
  import { ClientOnly as ClientOnlyImport } from "./ClientOnly.js";
21
13
  import { useZudoku as useZudokuImport } from "./context/ZudokuContext.js";
22
- import { Layout as LayoutImport } from "./Layout.js";
23
14
  import { Markdown as MarkdownImport } from "./Markdown.js";
24
15
  import { Spinner as SpinnerImport } from "./Spinner.js";
25
- import { StatusPage as StatusPageImport } from "./StatusPage.js";
26
16
  import { Typography as TypographyImport } from "./Typography.js";
27
17
  import { Zudoku as ZudokuImport } from "./Zudoku.js";
28
18
 
29
- export const Layout = /*@__PURE__*/ LayoutImport;
30
- export const RouterError = /*@__PURE__*/ RouterErrorImport;
31
- export const ServerError = /*@__PURE__*/ ServerErrorImport;
32
- export const Bootstrap = /*@__PURE__*/ BootstrapImport;
33
- export const BootstrapStatic = /*@__PURE__*/ BootstrapStaticImport;
34
- export const RouteGuard = /*@__PURE__*/ RouteGuardImport;
35
19
  export const Head = /*@__PURE__*/ Helmet;
36
- export const StatusPage = /*@__PURE__*/ StatusPageImport;
37
20
  export const Callout = /*@__PURE__*/ CalloutImport;
38
21
  export const Markdown = /*@__PURE__*/ MarkdownImport;
39
22
  export const Spinner = /*@__PURE__*/ SpinnerImport;
40
23
  export const ClientOnly = /*@__PURE__*/ ClientOnlyImport;
41
24
  export const Button = /*@__PURE__*/ ButtonImport;
42
25
  export const Link = /*@__PURE__*/ LinkImport;
43
- export const BuildCheck = /*@__PURE__*/ BuildCheckImport;
44
26
  export const Zudoku = /*@__PURE__*/ ZudokuImport;
45
27
  export const Typography = /*@__PURE__*/ TypographyImport;
46
28
 
@@ -114,7 +114,7 @@ export const NavigationItem = ({
114
114
  );
115
115
  case "link":
116
116
  case "custom-page": {
117
- const href = item.type === "link" ? item.to : item.path;
117
+ const href = item.type === "link" ? item.to : joinUrl(item.path);
118
118
  return !href.startsWith("http") ? (
119
119
  <AnchorLink
120
120
  to={{
@@ -124,7 +124,9 @@ export const NavigationItem = ({
124
124
  }}
125
125
  {...{ [DATA_ANCHOR_ATTR]: href.split("#")[1] }}
126
126
  className={navigationListItem({
127
- isActive: href === [location.pathname, activeAnchor].join("#"),
127
+ isActive:
128
+ href ===
129
+ [location.pathname, activeAnchor].filter(Boolean).join("#"),
128
130
  })}
129
131
  onClick={onRequestClose}
130
132
  >
@@ -58,18 +58,18 @@ export const useIsCategoryOpen = (category: NavigationCategory) => {
58
58
  const location = useLocation();
59
59
 
60
60
  return traverseNavigationItem(category, (item) => {
61
- if (item.type === "category" && item.link) {
62
- const categoryLinkPath = joinUrl(item.link.path);
63
- if (categoryLinkPath === location.pathname) {
64
- return true;
65
- }
66
- }
67
-
68
- if (item.type === "doc") {
69
- const docPath = joinUrl(item.path);
70
- if (docPath === location.pathname) {
71
- return true;
72
- }
61
+ switch (item.type) {
62
+ case "category":
63
+ if (!item.link) {
64
+ return undefined;
65
+ }
66
+ return joinUrl(item.link.path) === location.pathname ? true : undefined;
67
+ case "custom-page":
68
+ case "doc":
69
+ return joinUrl(item.path) === location.pathname ? true : undefined;
70
+ case "link":
71
+ default:
72
+ return undefined;
73
73
  }
74
74
  });
75
75
  };
@@ -5,9 +5,9 @@ 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,
8
+ import type {
9
+ CallbackContext,
10
+ ProtectedRoutesInput,
11
11
  } from "../../config/validators/ProtectedRoutesSchema.js";
12
12
  import type { FooterSchema } from "../../config/validators/validate.js";
13
13
  import type { AuthenticationPlugin } from "../authentication/authentication.js";
@@ -48,6 +48,7 @@ export type ApiKeyCache = "api-keys";
48
48
 
49
49
  type Metadata = Partial<{
50
50
  title: string;
51
+ defaultTitle?: string;
51
52
  description: string;
52
53
  logo: string;
53
54
  favicon: string;
@@ -105,6 +106,23 @@ export type ZudokuContextOptions = {
105
106
  };
106
107
  };
107
108
 
109
+ export const transformProtectedRoutes = (
110
+ val: ProtectedRoutesInput,
111
+ ): Record<string, (c: CallbackContext) => boolean> | undefined => {
112
+ if (!val) return undefined;
113
+
114
+ if (Array.isArray(val)) {
115
+ return Object.fromEntries(
116
+ val.map((route) => [
117
+ route,
118
+ (c: CallbackContext) => c.auth.isAuthenticated,
119
+ ]),
120
+ );
121
+ }
122
+
123
+ return val;
124
+ };
125
+
108
126
  export class ZudokuContext {
109
127
  public plugins: NonNullable<ZudokuContextOptions["plugins"]>;
110
128
  public navigation: Navigation;
@@ -123,13 +141,13 @@ export class ZudokuContext {
123
141
  const routes = plugin.getProtectedRoutes?.();
124
142
  if (!routes) return [];
125
143
 
126
- return Object.entries(ProtectedRoutesSchema.parse(routes) ?? {});
144
+ return Object.entries(transformProtectedRoutes(routes) ?? {});
127
145
  }),
128
146
  );
129
147
 
130
148
  const protectedRoutes = {
131
149
  ...pluginProtectedRoutes,
132
- ...ProtectedRoutesSchema.parse(options.protectedRoutes),
150
+ ...transformProtectedRoutes(options.protectedRoutes),
133
151
  };
134
152
 
135
153
  this.queryClient = queryClient;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ⚠️
3
+ * These are re-exports consumed from the main entry point in `src/app/main.tsx`
4
+ * This is to ensure that they share the exact same context in React.
5
+ * ⚠️
6
+ **/
7
+
8
+ import { Helmet } from "@zudoku/react-helmet-async";
9
+ import {
10
+ Bootstrap as BootstrapImport,
11
+ BootstrapStatic as BootstrapStaticImport,
12
+ } from "../components/Bootstrap.js";
13
+ import { BuildCheck as BuildCheckImport } from "../components/BuildCheck.js";
14
+ import { Layout as LayoutImport } from "../components/Layout.js";
15
+ import { Meta as MetaImport } from "../components/Meta.js";
16
+ import { StatusPage as StatusPageImport } from "../components/StatusPage.js";
17
+ import { RouterError as RouterErrorImport } from "../errors/RouterError.js";
18
+ import { ServerError as ServerErrorImport } from "../errors/ServerError.js";
19
+ import { RouteGuard as RouteGuardImport } from "./RouteGuard.js";
20
+
21
+ export const Layout = LayoutImport;
22
+ export const RouterError = RouterErrorImport;
23
+ export const ServerError = ServerErrorImport;
24
+ export const Bootstrap = BootstrapImport;
25
+ export const BootstrapStatic = BootstrapStaticImport;
26
+ export const RouteGuard = RouteGuardImport;
27
+ export const Head = Helmet;
28
+ export const StatusPage = StatusPageImport;
29
+ export const BuildCheck = BuildCheckImport;
30
+ export const Meta = MetaImport;
@@ -0,0 +1 @@
1
+ export * from "react-router";
@@ -20,6 +20,9 @@ export const customPagesPlugin = (
20
20
  customPages.push({
21
21
  path: item.path,
22
22
  element: item.element,
23
+ handle: {
24
+ layout: item.layout ?? "default",
25
+ },
23
26
  });
24
27
  }
25
28
  });
@@ -28,7 +28,7 @@ const IconToLanguageMap: Record<string, RegExp> = {
28
28
  toml: /toml/,
29
29
  gnubash: /(shell|bash|sh|zsh)/,
30
30
  python: /(py|python)/,
31
- dotnet: /(cs|csharp|vb)/,
31
+ dotnet: /(^cs$|csharp|vb)/,
32
32
  rust: /(rs|rust)/,
33
33
  ruby: /(rb|ruby)/,
34
34
  php: /php/,
@@ -101,7 +101,7 @@ export const CodeBlock = ({
101
101
  </div>
102
102
  <div
103
103
  className={cn(
104
- "code-block text-sm not-prose scrollbar overflow-x-auto scrollbar [&>code]:p-3 [&>code]:py-2",
104
+ "code-block text-sm not-prose scrollbar overflow-x-auto scrollbar [&_code]:p-3 [&_code]:py-2",
105
105
  props.className,
106
106
  )}
107
107
  ref={ref}
@@ -1,7 +1,7 @@
1
1
  import * as DialogPrimitive from "@radix-ui/react-dialog";
2
2
  import * as React from "react";
3
3
 
4
- import { XIcon } from "lucide-react";
4
+ import { CircleIcon, XIcon } from "lucide-react";
5
5
  import { cn } from "../util/cn.js";
6
6
 
7
7
  const Dialog = DialogPrimitive.Root;
@@ -45,8 +45,17 @@ const DialogContent = React.forwardRef<
45
45
  >
46
46
  {children}
47
47
  {showCloseButton && (
48
- <DialogPrimitive.Close className="absolute left-1 top-1 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
49
- <XIcon className="h-3 w-3" strokeWidth={2} />
48
+ <DialogPrimitive.Close className="absolute p-3 group -left-1.5 -top-1.5 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
49
+ <CircleIcon
50
+ className="h-2 w-2 transition-all border border-transparent group-hover:border-white/20 rounded-full group-hover:scale-180 group-hover:text-red-400"
51
+ strokeWidth={2}
52
+ fill="currentColor"
53
+ />
54
+ <XIcon
55
+ className="h-2 w-2 absolute top-3 left-3 text-transparent group-hover:text-red-800 transition-colors"
56
+ strokeWidth={2}
57
+ fill="currentColor"
58
+ />
50
59
  <span className="sr-only">Close</span>
51
60
  </DialogPrimitive.Close>
52
61
  )}