zudoku 0.33.1 → 0.34.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 (244) hide show
  1. package/dist/config/validators/common.d.ts +572 -354
  2. package/dist/config/validators/common.js +26 -8
  3. package/dist/config/validators/common.js.map +1 -1
  4. package/dist/config/validators/validate.d.ts +254 -167
  5. package/dist/lib/authentication/hook.d.ts +1 -0
  6. package/dist/lib/authentication/hook.js +11 -1
  7. package/dist/lib/authentication/hook.js.map +1 -1
  8. package/dist/lib/authentication/providers/clerk.js +6 -6
  9. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  10. package/dist/lib/components/AnchorLink.d.ts +2 -2
  11. package/dist/lib/components/AnchorLink.js +4 -4
  12. package/dist/lib/components/AnchorLink.js.map +1 -1
  13. package/dist/lib/components/Banner.js +1 -1
  14. package/dist/lib/components/Banner.js.map +1 -1
  15. package/dist/lib/components/Heading.d.ts +2 -2
  16. package/dist/lib/components/Layout.js +1 -1
  17. package/dist/lib/components/Layout.js.map +1 -1
  18. package/dist/lib/components/context/ZudokuContext.d.ts +1 -1
  19. package/dist/lib/components/index.d.ts +1 -0
  20. package/dist/lib/components/navigation/SidebarItem.js +6 -5
  21. package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
  22. package/dist/lib/core/RouteGuard.js +2 -1
  23. package/dist/lib/core/RouteGuard.js.map +1 -1
  24. package/dist/lib/core/ZudokuContext.d.ts +4 -0
  25. package/dist/lib/core/ZudokuContext.js.map +1 -1
  26. package/dist/lib/plugins/api-catalog/Catalog.d.ts +3 -1
  27. package/dist/lib/plugins/api-catalog/Catalog.js +7 -4
  28. package/dist/lib/plugins/api-catalog/Catalog.js.map +1 -1
  29. package/dist/lib/plugins/api-catalog/index.js +1 -1
  30. package/dist/lib/plugins/api-catalog/index.js.map +1 -1
  31. package/dist/lib/plugins/markdown/MdxPage.js +1 -1
  32. package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
  33. package/dist/lib/plugins/openapi/OperationList.d.ts +1 -1
  34. package/dist/lib/plugins/openapi/OperationList.js +5 -1
  35. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  36. package/dist/lib/plugins/openapi/OperationListItem.d.ts +1 -1
  37. package/dist/lib/plugins/openapi/OperationListItem.js +6 -3
  38. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  39. package/dist/lib/plugins/openapi/ParameterList.d.ts +2 -1
  40. package/dist/lib/plugins/openapi/ParameterList.js +3 -2
  41. package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
  42. package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js +3 -1
  43. package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js.map +1 -1
  44. package/dist/lib/plugins/openapi/Sidecar.js +1 -1
  45. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  46. package/dist/lib/plugins/openapi/graphql/gql.d.ts +1 -1
  47. package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
  48. package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
  49. package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
  50. package/dist/lib/plugins/openapi/graphql/graphql.js +2 -0
  51. package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
  52. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.d.ts +2 -2
  53. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +1 -5
  54. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
  55. package/dist/lib/plugins/openapi/playground/Headers.js +1 -1
  56. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  57. package/dist/lib/plugins/openapi/playground/IdentityDialog.d.ts +11 -0
  58. package/dist/lib/plugins/openapi/playground/IdentityDialog.js +14 -0
  59. package/dist/lib/plugins/openapi/playground/IdentityDialog.js.map +1 -0
  60. package/dist/lib/plugins/openapi/playground/IdentitySelector.d.ts +7 -0
  61. package/dist/lib/plugins/openapi/playground/IdentitySelector.js +10 -0
  62. package/dist/lib/plugins/openapi/playground/IdentitySelector.js.map +1 -0
  63. package/dist/lib/plugins/openapi/playground/PathParams.d.ts +3 -2
  64. package/dist/lib/plugins/openapi/playground/PathParams.js +3 -2
  65. package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
  66. package/dist/lib/plugins/openapi/playground/Playground.d.ts +13 -2
  67. package/dist/lib/plugins/openapi/playground/Playground.js +80 -26
  68. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  69. package/dist/lib/plugins/openapi/playground/QueryParams.js +1 -1
  70. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  71. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.d.ts +7 -0
  72. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js +8 -0
  73. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js.map +1 -0
  74. package/dist/lib/plugins/openapi/playground/rememberedIdentity.d.ts +17 -0
  75. package/dist/lib/plugins/openapi/playground/rememberedIdentity.js +11 -0
  76. package/dist/lib/plugins/openapi/playground/rememberedIdentity.js.map +1 -0
  77. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +19 -13
  78. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  79. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +6 -4
  80. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +4 -3
  81. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js.map +1 -1
  82. package/dist/lib/plugins/search-pagefind/PagefindSearch.d.ts +6 -0
  83. package/dist/lib/plugins/search-pagefind/PagefindSearch.js +66 -0
  84. package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -0
  85. package/dist/lib/plugins/search-pagefind/ResultList.d.ts +8 -0
  86. package/dist/lib/plugins/search-pagefind/ResultList.js +31 -0
  87. package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -0
  88. package/dist/lib/plugins/search-pagefind/get-results.d.ts +3 -0
  89. package/dist/lib/plugins/search-pagefind/get-results.js +37 -0
  90. package/dist/lib/plugins/search-pagefind/get-results.js.map +1 -0
  91. package/dist/lib/plugins/search-pagefind/index.d.ts +8 -0
  92. package/dist/lib/plugins/search-pagefind/index.js +9 -0
  93. package/dist/lib/plugins/search-pagefind/index.js.map +1 -0
  94. package/dist/lib/plugins/search-pagefind/types.d.ts +85 -0
  95. package/dist/lib/plugins/search-pagefind/types.js +2 -0
  96. package/dist/lib/plugins/search-pagefind/types.js.map +1 -0
  97. package/dist/lib/ui/Checkbox.d.ts +2 -8
  98. package/dist/lib/ui/Checkbox.js +1 -13
  99. package/dist/lib/ui/Checkbox.js.map +1 -1
  100. package/dist/lib/ui/Command.d.ts +13 -7
  101. package/dist/lib/ui/Command.js +2 -2
  102. package/dist/lib/ui/Command.js.map +1 -1
  103. package/dist/lib/ui/Select.js +1 -1
  104. package/dist/lib/ui/Select.js.map +1 -1
  105. package/dist/lib/ui/SyntaxHighlight.d.ts +2 -1
  106. package/dist/lib/ui/SyntaxHighlight.js +19 -15
  107. package/dist/lib/ui/SyntaxHighlight.js.map +1 -1
  108. package/dist/lib/util/MdxComponents.d.ts +1 -1
  109. package/dist/lib/util/MdxComponents.js +2 -2
  110. package/dist/lib/util/MdxComponents.js.map +1 -1
  111. package/dist/lib/util/useScrollToAnchor.js +6 -8
  112. package/dist/lib/util/useScrollToAnchor.js.map +1 -1
  113. package/dist/vite/build.js +4 -0
  114. package/dist/vite/build.js.map +1 -1
  115. package/dist/vite/config.js +7 -2
  116. package/dist/vite/config.js.map +1 -1
  117. package/dist/vite/dev-server.js +8 -0
  118. package/dist/vite/dev-server.js.map +1 -1
  119. package/dist/vite/pagefind.d.ts +4 -0
  120. package/dist/vite/pagefind.js +15 -0
  121. package/dist/vite/pagefind.js.map +1 -0
  122. package/dist/vite/plugin-component.js +4 -0
  123. package/dist/vite/plugin-component.js.map +1 -1
  124. package/dist/vite/plugin-search.js +4 -0
  125. package/dist/vite/plugin-search.js.map +1 -1
  126. package/dist/vite/prerender/prerender.js +1 -1
  127. package/dist/vite/prerender/prerender.js.map +1 -1
  128. package/dist/vite/sitemap.js +2 -1
  129. package/dist/vite/sitemap.js.map +1 -1
  130. package/lib/{AuthenticationPlugin-CiO1FM6Q.js → AuthenticationPlugin-4ip08maU.js} +3 -3
  131. package/lib/{AuthenticationPlugin-CiO1FM6Q.js.map → AuthenticationPlugin-4ip08maU.js.map} +1 -1
  132. package/lib/Callout-B_sEhkYd.js +211 -0
  133. package/lib/Callout-B_sEhkYd.js.map +1 -0
  134. package/lib/{Dialog-DIKGQxQc.js → Dialog-sbgekbjb.js} +47 -32
  135. package/lib/{Dialog-DIKGQxQc.js.map → Dialog-sbgekbjb.js.map} +1 -1
  136. package/lib/{Markdown-DePfm7oQ.js → Markdown-DZXjQjpH.js} +4099 -3848
  137. package/lib/Markdown-DZXjQjpH.js.map +1 -0
  138. package/lib/MdxPage-52vRwa_7.js +200 -0
  139. package/lib/MdxPage-52vRwa_7.js.map +1 -0
  140. package/lib/{OasProvider-SzD9mHJc.js → OasProvider-CR2nG1Eg.js} +4 -4
  141. package/lib/{OasProvider-SzD9mHJc.js.map → OasProvider-CR2nG1Eg.js.map} +1 -1
  142. package/lib/{OperationList-DDs9NblY.js → OperationList-DndcCJUG.js} +2069 -1983
  143. package/lib/OperationList-DndcCJUG.js.map +1 -0
  144. package/lib/{Select-Dqtcn53H.js → Select-FAYHOYTy.js} +4 -4
  145. package/lib/{Select-Dqtcn53H.js.map → Select-FAYHOYTy.js.map} +1 -1
  146. package/lib/{SlotletProvider-DdtIOUi6.js → SlotletProvider-TydSHROc.js} +4 -4
  147. package/lib/{SlotletProvider-DdtIOUi6.js.map → SlotletProvider-TydSHROc.js.map} +1 -1
  148. package/lib/{chunk-IR6S3I6Y-D_3UmFIn.js → chunk-HA7DTUK3-ZGg2W6yV.js} +277 -277
  149. package/lib/chunk-HA7DTUK3-ZGg2W6yV.js.map +1 -0
  150. package/lib/hook-CfCFKZ-2.js +350 -0
  151. package/lib/hook-CfCFKZ-2.js.map +1 -0
  152. package/lib/index-DK7IuUyR.js +2201 -0
  153. package/lib/index-DK7IuUyR.js.map +1 -0
  154. package/lib/{index.esm-CQHE3GEU.js → index.esm-CltAN0Tf.js} +259 -239
  155. package/lib/index.esm-CltAN0Tf.js.map +1 -0
  156. package/lib/{mutation-EclmI0is.js → mutation-B81DztCT.js} +2 -2
  157. package/lib/{mutation-EclmI0is.js.map → mutation-B81DztCT.js.map} +1 -1
  158. package/lib/objectEntries-BS7aAgOm.js +12 -0
  159. package/lib/objectEntries-BS7aAgOm.js.map +1 -0
  160. package/lib/ui/Checkbox.js +15 -25
  161. package/lib/ui/Checkbox.js.map +1 -1
  162. package/lib/ui/Command.js +96 -70
  163. package/lib/ui/Command.js.map +1 -1
  164. package/lib/ui/Select.js +1 -1
  165. package/lib/ui/Select.js.map +1 -1
  166. package/lib/ui/SyntaxHighlight.js +483 -502
  167. package/lib/ui/SyntaxHighlight.js.map +1 -1
  168. package/lib/{useExposedProps-RIvey2Oy.js → useExposedProps-BslIn-FE.js} +2 -2
  169. package/lib/{useExposedProps-RIvey2Oy.js.map → useExposedProps-BslIn-FE.js.map} +1 -1
  170. package/lib/useQuery-CQUwWR9i.js +1137 -0
  171. package/lib/useQuery-CQUwWR9i.js.map +1 -0
  172. package/lib/zudoku.auth-auth0.js +1 -1
  173. package/lib/zudoku.auth-clerk.js +29 -29
  174. package/lib/zudoku.auth-clerk.js.map +1 -1
  175. package/lib/zudoku.auth-openid.js +3 -3
  176. package/lib/zudoku.components.js +146 -149
  177. package/lib/zudoku.components.js.map +1 -1
  178. package/lib/zudoku.hooks.js +1 -1
  179. package/lib/zudoku.plugin-api-catalog.js +87 -71
  180. package/lib/zudoku.plugin-api-catalog.js.map +1 -1
  181. package/lib/zudoku.plugin-api-keys.js +16 -15
  182. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  183. package/lib/zudoku.plugin-custom-pages.js +2 -2
  184. package/lib/zudoku.plugin-markdown.js +1 -1
  185. package/lib/zudoku.plugin-openapi.js +3 -3
  186. package/lib/zudoku.plugin-redirect.js +1 -1
  187. package/lib/zudoku.plugin-search-pagefind.js +204 -0
  188. package/lib/zudoku.plugin-search-pagefind.js.map +1 -0
  189. package/package.json +10 -5
  190. package/src/lib/authentication/hook.ts +12 -1
  191. package/src/lib/authentication/providers/clerk.tsx +10 -6
  192. package/src/lib/components/AnchorLink.tsx +7 -7
  193. package/src/lib/components/Banner.tsx +1 -0
  194. package/src/lib/components/Heading.tsx +1 -1
  195. package/src/lib/components/Layout.tsx +1 -0
  196. package/src/lib/components/navigation/SidebarItem.tsx +8 -23
  197. package/src/lib/core/RouteGuard.tsx +2 -1
  198. package/src/lib/core/ZudokuContext.ts +4 -0
  199. package/src/lib/plugins/api-catalog/Catalog.tsx +23 -7
  200. package/src/lib/plugins/api-catalog/index.tsx +1 -0
  201. package/src/lib/plugins/markdown/MdxPage.tsx +5 -1
  202. package/src/lib/plugins/openapi/OperationList.tsx +83 -31
  203. package/src/lib/plugins/openapi/OperationListItem.tsx +107 -86
  204. package/src/lib/plugins/openapi/ParameterList.tsx +4 -0
  205. package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +7 -0
  206. package/src/lib/plugins/openapi/Sidecar.tsx +1 -0
  207. package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
  208. package/src/lib/plugins/openapi/graphql/graphql.ts +3 -0
  209. package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +30 -32
  210. package/src/lib/plugins/openapi/playground/Headers.tsx +0 -1
  211. package/src/lib/plugins/openapi/playground/IdentityDialog.tsx +74 -0
  212. package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +54 -0
  213. package/src/lib/plugins/openapi/playground/PathParams.tsx +8 -2
  214. package/src/lib/plugins/openapi/playground/Playground.tsx +175 -88
  215. package/src/lib/plugins/openapi/playground/QueryParams.tsx +0 -1
  216. package/src/lib/plugins/openapi/playground/RequestLoginDialog.tsx +51 -0
  217. package/src/lib/plugins/openapi/playground/rememberedIdentity.ts +26 -0
  218. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +24 -4
  219. package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +66 -45
  220. package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +135 -0
  221. package/src/lib/plugins/search-pagefind/ResultList.tsx +104 -0
  222. package/src/lib/plugins/search-pagefind/get-results.tsx +54 -0
  223. package/src/lib/plugins/search-pagefind/index.tsx +21 -0
  224. package/src/lib/plugins/search-pagefind/types.ts +118 -0
  225. package/src/lib/ui/Checkbox.tsx +8 -24
  226. package/src/lib/ui/Command.tsx +25 -3
  227. package/src/lib/ui/Select.tsx +1 -1
  228. package/src/lib/ui/SyntaxHighlight.tsx +94 -96
  229. package/src/lib/util/MdxComponents.tsx +2 -2
  230. package/src/lib/util/useScrollToAnchor.ts +8 -8
  231. package/lib/Markdown-DePfm7oQ.js.map +0 -1
  232. package/lib/MdxPage-DZTt9ld7.js +0 -193
  233. package/lib/MdxPage-DZTt9ld7.js.map +0 -1
  234. package/lib/OperationList-DDs9NblY.js.map +0 -1
  235. package/lib/chunk-IR6S3I6Y-D_3UmFIn.js.map +0 -1
  236. package/lib/hook-CN__aZIt.js +0 -1464
  237. package/lib/hook-CN__aZIt.js.map +0 -1
  238. package/lib/index-CibzSNks.js +0 -2100
  239. package/lib/index-CibzSNks.js.map +0 -1
  240. package/lib/index.esm-CQHE3GEU.js.map +0 -1
  241. package/lib/objectEntries-yMIkr2mI.js +0 -5
  242. package/lib/objectEntries-yMIkr2mI.js.map +0 -1
  243. package/lib/useScrollToAnchor-C7ilRSts.js +0 -290
  244. package/lib/useScrollToAnchor-C7ilRSts.js.map +0 -1
@@ -0,0 +1,204 @@
1
+ import { j as e } from "./jsx-runtime-CYK1ROHF.js";
2
+ import { C as x } from "./ClientOnly-E7hGysn1.js";
3
+ import { VisuallyHidden as y } from "@radix-ui/react-visually-hidden";
4
+ import { d as f, k as j } from "./useQuery-CQUwWR9i.js";
5
+ import { useCallback as S, useState as b } from "react";
6
+ import { C as k, a as u, b as h, c as C, d as N, e as v, f as w } from "./Callout-B_sEhkYd.js";
7
+ import { b as _ } from "./Dialog-sbgekbjb.js";
8
+ import { j as L } from "./joinUrl-10po2Jdj.js";
9
+ import { FileTextIcon as F } from "lucide-react";
10
+ import { a as T, L as g } from "./chunk-HA7DTUK3-ZGg2W6yV.js";
11
+ const q = async (r, o) => {
12
+ const s = o.maxResults ?? 10, n = o.transformResults ?? (() => !0), i = [], l = R(r, n);
13
+ for await (const a of l)
14
+ if (i.push(a), i.length >= s) break;
15
+ return i;
16
+ };
17
+ async function* R(r, o) {
18
+ let n = 0;
19
+ for (; n < r.results.length; ) {
20
+ const i = r.results.slice(
21
+ n,
22
+ n + 5
23
+ );
24
+ n += i.length;
25
+ const l = await Promise.all(i.map((a) => a.data()));
26
+ for (const a of l) {
27
+ const t = o(a);
28
+ t !== !1 && (t === !0 || t == null ? yield a : yield t);
29
+ }
30
+ }
31
+ }
32
+ const $ = (r, o) => {
33
+ const s = r.weighted_locations.reduce(
34
+ (i, l) => i + l.balanced_score,
35
+ 0
36
+ );
37
+ return o.weighted_locations.reduce(
38
+ (i, l) => i + l.balanced_score,
39
+ 0
40
+ ) - s;
41
+ }, p = "cursor-pointer border border-transparent data-[selected=true]:border-border", D = ({
42
+ basePath: r,
43
+ searchResults: o,
44
+ searchTerm: s,
45
+ onClose: n,
46
+ maxSubResults: i = 4
47
+ }) => {
48
+ const l = T(), a = S(
49
+ (t) => {
50
+ const c = t.replace(".html", "");
51
+ return r && c.startsWith(r) ? c.slice(r.length) : c;
52
+ },
53
+ [r]
54
+ );
55
+ return /* @__PURE__ */ e.jsxs(k, { className: "max-h-[450px]", children: [
56
+ s && o.length > 0 && /* @__PURE__ */ e.jsx(
57
+ u,
58
+ {
59
+ className: "text-sm text-muted-foreground",
60
+ heading: `${o.length} results for "${s}"`
61
+ }
62
+ ),
63
+ o.map((t) => /* @__PURE__ */ e.jsxs(
64
+ u,
65
+ {
66
+ children: [
67
+ /* @__PURE__ */ e.jsx(
68
+ h,
69
+ {
70
+ asChild: !0,
71
+ value: `${t.meta.title}-${t.url}`,
72
+ className: p,
73
+ onSelect: () => {
74
+ l(a(t.url)), n();
75
+ },
76
+ children: /* @__PURE__ */ e.jsxs(g, { to: a(t.url), children: [
77
+ /* @__PURE__ */ e.jsx(F, { size: 20, className: "text-muted-foreground" }),
78
+ t.meta.title
79
+ ] })
80
+ }
81
+ ),
82
+ t.sub_results.sort($).slice(0, i).map((c) => /* @__PURE__ */ e.jsx(
83
+ h,
84
+ {
85
+ asChild: !0,
86
+ value: `${t.meta.title}-${c.url}`,
87
+ className: p,
88
+ onSelect: () => {
89
+ l(a(c.url)), n();
90
+ },
91
+ children: /* @__PURE__ */ e.jsx(g, { to: a(c.url), onClick: n, children: /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col items-start gap-2 ms-2.5 ps-5 border-l border-muted-foreground/50", children: [
92
+ /* @__PURE__ */ e.jsx("span", { className: "font-bold", children: c.title }),
93
+ /* @__PURE__ */ e.jsx(
94
+ "span",
95
+ {
96
+ className: "text-[13px] [&_mark]:bg-primary [&_mark]:text-primary-foreground",
97
+ dangerouslySetInnerHTML: { __html: c.excerpt }
98
+ }
99
+ )
100
+ ] }) })
101
+ },
102
+ `${t.meta.title}-${c.url}`
103
+ ))
104
+ ]
105
+ },
106
+ [t.meta.title ?? t.excerpt, t.url].join("-")
107
+ ))
108
+ ] });
109
+ }, d = {
110
+ // Slightly lower than default because API docs tend to have repetitive terms (parameter names, HTTP methods, etc.)
111
+ termFrequency: 0.8,
112
+ // Lower than default because API documentation pages tend to be longer due to comprehensive endpoint documentation
113
+ pageLength: 0.6,
114
+ // Slightly higher than default because in technical documentation, exact matches should be prioritized
115
+ termSimilarity: 1.2,
116
+ // Slightly lower than default because API docs might have legitimate repetition of terms
117
+ termSaturation: 1.2
118
+ }, E = (r) => import(
119
+ /* @vite-ignore */
120
+ L(r, "/pagefind/pagefind.js")
121
+ ), I = (r) => {
122
+ const { data: o, ...s } = f({
123
+ queryKey: ["pagefind", r.ranking],
124
+ retry: !1,
125
+ queryFn: async () => {
126
+ var i, l, a, t;
127
+ const n = await E(r.basePath);
128
+ return await n.init(), await n.options({
129
+ ranking: {
130
+ termFrequency: ((i = r.ranking) == null ? void 0 : i.termFrequency) ?? d.termFrequency,
131
+ pageLength: ((l = r.ranking) == null ? void 0 : l.pageLength) ?? d.pageLength,
132
+ termSimilarity: ((a = r.ranking) == null ? void 0 : a.termSimilarity) ?? d.termSimilarity,
133
+ termSaturation: ((t = r.ranking) == null ? void 0 : t.termSaturation) ?? d.termSaturation
134
+ }
135
+ }), n;
136
+ },
137
+ enabled: typeof window < "u"
138
+ });
139
+ return s.isError && console.error(s.error), { ...s, pagefind: o };
140
+ }, P = ({
141
+ isOpen: r,
142
+ onClose: o,
143
+ options: s
144
+ }) => {
145
+ const { pagefind: n, error: i, isError: l } = I(s), [a, t] = b(""), { data: c } = f({
146
+ queryKey: ["pagefind-search", a],
147
+ queryFn: async () => {
148
+ const m = await (n == null ? void 0 : n.search(a));
149
+ return m ? q(m, s) : [];
150
+ },
151
+ placeholderData: j,
152
+ enabled: !!n && !!a
153
+ });
154
+ return /* @__PURE__ */ e.jsxs(
155
+ C,
156
+ {
157
+ command: { shouldFilter: !1 },
158
+ content: { className: "max-w-[750px]" },
159
+ open: r,
160
+ onOpenChange: o,
161
+ children: [
162
+ /* @__PURE__ */ e.jsx(y, { children: /* @__PURE__ */ e.jsx(_, { children: "Search" }) }),
163
+ /* @__PURE__ */ e.jsx(
164
+ N,
165
+ {
166
+ placeholder: "Search...",
167
+ value: a,
168
+ onValueChange: t,
169
+ disabled: l
170
+ }
171
+ ),
172
+ /* @__PURE__ */ e.jsx(v, { children: a ? "No results found." : "Start typing to search" }),
173
+ l ? /* @__PURE__ */ e.jsx("div", { className: "p-4 text-sm", children: i.message === "NOT_BUILT_YET" ? /* @__PURE__ */ e.jsxs(w, { type: "info", children: [
174
+ "Search is currently not available in development mode by default.",
175
+ /* @__PURE__ */ e.jsx("br", {}),
176
+ "To still use search in development, run ",
177
+ /* @__PURE__ */ e.jsx("code", { children: "zudoku build" }),
178
+ " ",
179
+ "and copy the ",
180
+ /* @__PURE__ */ e.jsx("code", { children: "dist/pagefind" }),
181
+ " directory to your",
182
+ " ",
183
+ /* @__PURE__ */ e.jsx("code", { children: "public" }),
184
+ " directory."
185
+ ] }) : "An error occurred while loading search." }) : /* @__PURE__ */ e.jsx(
186
+ D,
187
+ {
188
+ basePath: s.basePath,
189
+ searchResults: c ?? [],
190
+ searchTerm: a,
191
+ onClose: o,
192
+ maxSubResults: s.maxSubResults
193
+ }
194
+ )
195
+ ]
196
+ }
197
+ );
198
+ }, Q = (r) => ({
199
+ renderSearch: ({ isOpen: o, onClose: s }) => /* @__PURE__ */ e.jsx(x, { children: /* @__PURE__ */ e.jsx(P, { isOpen: o, onClose: s, options: r }) })
200
+ });
201
+ export {
202
+ Q as pagefindSearchPlugin
203
+ };
204
+ //# sourceMappingURL=zudoku.plugin-search-pagefind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zudoku.plugin-search-pagefind.js","sources":["../src/lib/plugins/search-pagefind/get-results.tsx","../src/lib/plugins/search-pagefind/ResultList.tsx","../src/lib/plugins/search-pagefind/PagefindSearch.tsx","../src/lib/plugins/search-pagefind/index.tsx"],"sourcesContent":["import type { PagefindOptions } from \"./index.js\";\nimport type { PagefindSearchFragment, PagefindSearchResults } from \"./types.js\";\n\nexport const getResults = async (\n search: PagefindSearchResults,\n options: PagefindOptions,\n) => {\n const maxResults = options.maxResults ?? 10;\n const transformFn = options.transformResults ?? (() => true);\n\n const transformedResults: PagefindSearchFragment[] = [];\n\n const generator = searchResultGenerator(search, transformFn);\n\n for await (const result of generator) {\n transformedResults.push(result);\n if (transformedResults.length >= maxResults) break;\n }\n\n return transformedResults;\n};\n\nasync function* searchResultGenerator(\n search: PagefindSearchResults,\n transformFn: NonNullable<PagefindOptions[\"transformResults\"]>,\n) {\n const batchSize = 5;\n let processedCount = 0;\n\n while (processedCount < search.results.length) {\n const batch = search.results.slice(\n processedCount,\n processedCount + batchSize,\n );\n processedCount += batch.length;\n\n const batchData = await Promise.all(batch.map((result) => result.data()));\n\n for (const result of batchData) {\n const transformed = transformFn(result);\n\n if (transformed === false) {\n // Skip this result\n continue;\n } else if (transformed === true || transformed == null) {\n // Keep the original result\n yield result;\n } else {\n // Return the transformed result\n yield transformed;\n }\n }\n }\n}\n","import { FileTextIcon } from \"lucide-react\";\nimport { useCallback } from \"react\";\nimport { Link, useNavigate } from \"react-router\";\nimport { CommandGroup, CommandItem, CommandList } from \"zudoku/ui/Command.js\";\nimport {\n type PagefindSearchFragment,\n type PagefindSubResult,\n} from \"./types.js\";\n\nconst sortSubResults = (a: PagefindSubResult, b: PagefindSubResult) => {\n const aScore = a.weighted_locations.reduce(\n (sum, loc) => sum + loc.balanced_score,\n 0,\n );\n const bScore = b.weighted_locations.reduce(\n (sum, loc) => sum + loc.balanced_score,\n 0,\n );\n return bScore - aScore;\n};\n\nconst hoverClassname = `cursor-pointer border border-transparent data-[selected=true]:border-border`;\n\nexport const ResultList = ({\n basePath,\n searchResults,\n searchTerm,\n onClose,\n maxSubResults = 4,\n}: {\n basePath?: string;\n searchResults: PagefindSearchFragment[];\n searchTerm: string;\n onClose: () => void;\n maxSubResults?: number;\n}) => {\n const navigate = useNavigate();\n\n const cleanResultUrl = useCallback(\n (url: string) => {\n const clean = url.replace(\".html\", \"\");\n return basePath && clean.startsWith(basePath)\n ? clean.slice(basePath.length)\n : clean;\n },\n [basePath],\n );\n\n return (\n <CommandList className=\"max-h-[450px]\">\n {searchTerm && searchResults.length > 0 && (\n <CommandGroup\n className=\"text-sm text-muted-foreground\"\n heading={`${searchResults.length} results for \"${searchTerm}\"`}\n />\n )}\n {searchResults.map((result) => (\n <CommandGroup\n key={[result.meta.title ?? result.excerpt, result.url].join(\"-\")}\n >\n <CommandItem\n asChild\n value={`${result.meta.title}-${result.url}`}\n className={hoverClassname}\n onSelect={() => {\n void navigate(cleanResultUrl(result.url));\n onClose();\n }}\n >\n <Link to={cleanResultUrl(result.url)}>\n <FileTextIcon size={20} className=\"text-muted-foreground\" />\n {result.meta.title}\n </Link>\n </CommandItem>\n {result.sub_results\n .sort(sortSubResults)\n .slice(0, maxSubResults)\n .map((subResult) => (\n <CommandItem\n asChild\n key={`${result.meta.title}-${subResult.url}`}\n value={`${result.meta.title}-${subResult.url}`}\n className={hoverClassname}\n onSelect={() => {\n void navigate(cleanResultUrl(subResult.url));\n onClose();\n }}\n >\n <Link to={cleanResultUrl(subResult.url)} onClick={onClose}>\n <div className=\"flex flex-col items-start gap-2 ms-2.5 ps-5 border-l border-muted-foreground/50\">\n <span className=\"font-bold\">{subResult.title}</span>\n <span\n className=\"text-[13px] [&_mark]:bg-primary [&_mark]:text-primary-foreground\"\n dangerouslySetInnerHTML={{ __html: subResult.excerpt }}\n />\n </div>\n </Link>\n </CommandItem>\n ))}\n </CommandGroup>\n ))}\n </CommandList>\n );\n};\n","import { VisuallyHidden } from \"@radix-ui/react-visually-hidden\";\nimport { keepPreviousData, useQuery } from \"@tanstack/react-query\";\nimport { useState } from \"react\";\nimport { Callout } from \"zudoku/ui/Callout.js\";\nimport {\n CommandDialog,\n CommandEmpty,\n CommandInput,\n} from \"zudoku/ui/Command.js\";\nimport { DialogTitle } from \"zudoku/ui/Dialog.js\";\nimport { joinUrl } from \"../../util/joinUrl.js\";\nimport { getResults } from \"./get-results.js\";\nimport type { PagefindOptions } from \"./index.js\";\nimport { ResultList } from \"./ResultList.js\";\nimport type { Pagefind } from \"./types.js\";\n\nconst DEFAULT_RANKING = {\n // Slightly lower than default because API docs tend to have repetitive terms (parameter names, HTTP methods, etc.)\n termFrequency: 0.8,\n // Lower than default because API documentation pages tend to be longer due to comprehensive endpoint documentation\n pageLength: 0.6,\n // Slightly higher than default because in technical documentation, exact matches should be prioritized\n termSimilarity: 1.2,\n // Slightly lower than default because API docs might have legitimate repetition of terms\n termSaturation: 1.2,\n};\n\nconst importPagefind = (basePath?: string): Promise<Pagefind> =>\n import.meta.env.DEV\n ? // @ts-expect-error TypeScript can't resolve the import\n import(/* @vite-ignore */ \"/pagefind/pagefind.js\")\n : import(/* @vite-ignore */ joinUrl(basePath, \"/pagefind/pagefind.js\"));\n\nconst usePagefind = (options: PagefindOptions) => {\n const { data: pagefind, ...result } = useQuery<Pagefind>({\n queryKey: [\"pagefind\", options.ranking],\n retry: false,\n queryFn: async () => {\n const pagefind = await importPagefind(options.basePath);\n await pagefind.init();\n await pagefind.options({\n ranking: {\n termFrequency:\n options.ranking?.termFrequency ?? DEFAULT_RANKING.termFrequency,\n pageLength: options.ranking?.pageLength ?? DEFAULT_RANKING.pageLength,\n termSimilarity:\n options.ranking?.termSimilarity ?? DEFAULT_RANKING.termSimilarity,\n termSaturation:\n options.ranking?.termSaturation ?? DEFAULT_RANKING.termSaturation,\n },\n });\n\n return pagefind;\n },\n enabled: typeof window !== \"undefined\",\n });\n\n if (result.isError) {\n // eslint-disable-next-line no-console\n console.error(result.error);\n }\n\n return { ...result, pagefind };\n};\n\nexport const PagefindSearch = ({\n isOpen,\n onClose,\n options,\n}: {\n isOpen: boolean;\n onClose: () => void;\n options: PagefindOptions;\n}) => {\n const { pagefind, error, isError } = usePagefind(options);\n const [searchTerm, setSearchTerm] = useState(\"\");\n\n const { data: searchResults } = useQuery({\n queryKey: [\"pagefind-search\", searchTerm],\n queryFn: async () => {\n const search = await pagefind?.search(searchTerm);\n if (!search) return [];\n return getResults(search, options);\n },\n placeholderData: keepPreviousData,\n enabled: !!pagefind && !!searchTerm,\n });\n\n return (\n <CommandDialog\n command={{ shouldFilter: false }}\n content={{ className: \"max-w-[750px]\" }}\n open={isOpen}\n onOpenChange={onClose}\n >\n <VisuallyHidden>\n <DialogTitle>Search</DialogTitle>\n </VisuallyHidden>\n <CommandInput\n placeholder=\"Search...\"\n value={searchTerm}\n onValueChange={setSearchTerm}\n disabled={isError}\n />\n <CommandEmpty>\n {searchTerm ? \"No results found.\" : \"Start typing to search\"}\n </CommandEmpty>\n {isError ? (\n <div className=\"p-4 text-sm\">\n {error.message === \"NOT_BUILT_YET\" ? (\n <Callout type=\"info\">\n Search is currently not available in development mode by default.\n <br />\n To still use search in development, run <code>\n zudoku build\n </code>{\" \"}\n and copy the <code>dist/pagefind</code> directory to your{\" \"}\n <code>public</code> directory.\n </Callout>\n ) : (\n \"An error occurred while loading search.\"\n )}\n </div>\n ) : (\n <ResultList\n basePath={options.basePath}\n searchResults={searchResults ?? []}\n searchTerm={searchTerm}\n onClose={onClose}\n maxSubResults={options.maxSubResults}\n />\n )}\n </CommandDialog>\n );\n};\n","import type { ZudokuConfig } from \"../../../config/validators/validate.js\";\nimport { ClientOnly } from \"../../components/ClientOnly.js\";\nimport type { ZudokuPlugin } from \"../../core/plugins.js\";\nimport { PagefindSearch } from \"./PagefindSearch.js\";\n\nexport type PagefindOptions = Extract<\n ZudokuConfig[\"search\"],\n { type: \"pagefind\" }\n> & { basePath?: string };\n\nexport const pagefindSearchPlugin = (\n options: PagefindOptions,\n): ZudokuPlugin => {\n return {\n renderSearch: ({ isOpen, onClose }) => (\n <ClientOnly>\n <PagefindSearch isOpen={isOpen} onClose={onClose} options={options} />\n </ClientOnly>\n ),\n };\n};\n"],"names":["getResults","search","options","maxResults","transformFn","transformedResults","generator","searchResultGenerator","result","processedCount","batch","batchData","transformed","sortSubResults","a","b","aScore","sum","loc","hoverClassname","ResultList","basePath","searchResults","searchTerm","onClose","maxSubResults","navigate","useNavigate","cleanResultUrl","useCallback","url","clean","jsxs","CommandList","jsx","CommandGroup","CommandItem","Link","FileTextIcon","subResult","DEFAULT_RANKING","importPagefind","joinUrl","usePagefind","pagefind","useQuery","_a","_b","_c","_d","PagefindSearch","isOpen","error","isError","setSearchTerm","useState","keepPreviousData","CommandDialog","VisuallyHidden","DialogTitle","CommandInput","CommandEmpty","Callout","pagefindSearchPlugin","ClientOnly"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.33.1",
3
+ "version": "0.34.0",
4
4
  "type": "module",
5
5
  "homepage": "https://zudoku.dev",
6
6
  "repository": {
@@ -86,6 +86,10 @@
86
86
  "import": "./lib/zudoku.plugin-search-inkeep.js",
87
87
  "types": "./dist/lib/plugins/search-inkeep/index.d.ts"
88
88
  },
89
+ "./plugins/search-pagefind": {
90
+ "import": "./lib/zudoku.plugin-search-pagefind.js",
91
+ "types": "./dist/lib/plugins/search-pagefind/index.d.ts"
92
+ },
89
93
  "./components": {
90
94
  "import": "./lib/zudoku.components.js",
91
95
  "types": "./dist/lib/components/index.d.ts"
@@ -167,6 +171,7 @@
167
171
  "devlop": "^1.1.0",
168
172
  "dotenv": "16.4.7",
169
173
  "embla-carousel-react": "8.5.2",
174
+ "esm-loader-css": "^1.0.3",
170
175
  "estree-util-value-to-estree": "3.3.2",
171
176
  "express": "4.21.2",
172
177
  "glob": "11.0.1",
@@ -186,16 +191,17 @@
186
191
  "oauth4webapi": "2.17.0",
187
192
  "object-hash": "3.0.0",
188
193
  "openapi-types": "12.1.3",
194
+ "pagefind": "1.4.0-alpha.1",
189
195
  "picocolors": "1.1.1",
190
196
  "piscina": "5.0.0-alpha.1",
191
197
  "postcss": "8.5.2",
192
- "posthog-node": "4.6.0",
198
+ "posthog-node": "4.8.1",
193
199
  "prism-react-renderer": "2.4.1",
194
200
  "prismjs": "1.29.0",
195
201
  "react-error-boundary": "5.0.0",
196
202
  "react-hook-form": "7.54.2",
197
203
  "react-is": "19.0.0",
198
- "react-router": "7.1.5",
204
+ "react-router": "7.2.0",
199
205
  "rehype-mdx-import-media": "1.2.0",
200
206
  "rehype-raw": "7.0.0",
201
207
  "rehype-slug": "6.0.0",
@@ -226,8 +232,7 @@
226
232
  "yargs": "17.7.2",
227
233
  "zod": "3.24.2",
228
234
  "zod-validation-error": "3.4.0",
229
- "zustand": "5.0.3",
230
- "esm-loader-css": "^1.0.3"
235
+ "zustand": "5.0.3"
231
236
  },
232
237
  "devDependencies": {
233
238
  "@graphql-codegen/cli": "5.0.5",
@@ -15,7 +15,9 @@ export const useAuth = () => {
15
15
  throw new Error("Authentication is not enabled.");
16
16
  }
17
17
  // TODO: Should handle errors/state
18
- await authentication.signIn();
18
+ await authentication.signIn({
19
+ redirectTo: window.location.href,
20
+ });
19
21
  },
20
22
 
21
23
  logout: async () => {
@@ -28,5 +30,14 @@ export const useAuth = () => {
28
30
  // Redirect to home
29
31
  window.location.href = "/";
30
32
  },
33
+
34
+ signup: async () => {
35
+ if (!isAuthEnabled) {
36
+ throw new Error("Authentication is not enabled.");
37
+ }
38
+ await authentication.signUp({
39
+ redirectTo: window.location.href,
40
+ });
41
+ },
31
42
  };
32
43
  };
@@ -106,18 +106,22 @@ const clerkAuth: AuthenticationProviderInitializer<
106
106
  providerData: null,
107
107
  });
108
108
  },
109
- signIn: async () => {
109
+ signIn: async ({ redirectTo }: { redirectTo?: string }) => {
110
110
  await ensureLoaded;
111
111
  await clerkApi?.redirectToSignIn({
112
- signInForceRedirectUrl: window.location.origin + redirectToAfterSignIn,
113
- signUpForceRedirectUrl: window.location.origin + redirectToAfterSignUp,
112
+ signInForceRedirectUrl:
113
+ redirectTo ?? window.location.origin + redirectToAfterSignIn,
114
+ signUpForceRedirectUrl:
115
+ redirectTo ?? window.location.origin + redirectToAfterSignUp,
114
116
  });
115
117
  },
116
- signUp: async () => {
118
+ signUp: async ({ redirectTo }: { redirectTo?: string }) => {
117
119
  await ensureLoaded;
118
120
  await clerkApi?.redirectToSignUp({
119
- signInForceRedirectUrl: window.location.origin + redirectToAfterSignIn,
120
- signUpForceRedirectUrl: window.location.origin + redirectToAfterSignUp,
121
+ signInForceRedirectUrl:
122
+ redirectTo ?? window.location.origin + redirectToAfterSignIn,
123
+ signUpForceRedirectUrl:
124
+ redirectTo ?? window.location.origin + redirectToAfterSignUp,
121
125
  });
122
126
  },
123
127
  getAuthenticationPlugin() {
@@ -1,22 +1,22 @@
1
- import React from "react";
2
- import { Link, type LinkProps, useLocation } from "react-router";
1
+ import { type MouseEvent } from "react";
2
+ import { NavLink, type NavLinkProps, useHref, useLocation } from "react-router";
3
3
  import { useScrollToHash } from "../util/useScrollToAnchor.js";
4
4
 
5
5
  /**
6
6
  * Link that scrolls to anchor even if the hash is already set in the URL.
7
7
  */
8
- export const AnchorLink = (props: LinkProps) => {
8
+ export const AnchorLink = (props: NavLinkProps) => {
9
9
  const location = useLocation();
10
10
  const scrollToHash = useScrollToHash();
11
- const hash = typeof props.to === "string" ? props.to : props.to.hash;
11
+ const hash = useHref(props.to).split("#")[1];
12
12
 
13
- const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
13
+ const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {
14
14
  props.onClick?.(event);
15
- if (!hash?.startsWith("#") || hash !== location.hash) return;
15
+ if (hash !== location.hash.slice(1)) return;
16
16
 
17
17
  event.preventDefault();
18
18
  scrollToHash(hash);
19
19
  };
20
20
 
21
- return <Link {...props} onClick={handleClick} />;
21
+ return <NavLink {...props} onClick={handleClick} />;
22
22
  };
@@ -34,6 +34,7 @@ export const Banner = () => {
34
34
  "relative text-primary-foreground text-sm font-medium px-4 py-2 flex gap-2 items-center",
35
35
  mappedColor,
36
36
  )}
37
+ data-pagefind-ignore="all"
37
38
  style={style}
38
39
  >
39
40
  <div className="w-full">{page.banner.message}</div>
@@ -38,7 +38,7 @@ const getComponent = (level: number) => {
38
38
  }
39
39
  };
40
40
 
41
- export type HeadingProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
41
+ export type HeadingProps = React.HTMLAttributes<HTMLHeadingElement> &
42
42
  VariantProps<typeof heading> & {
43
43
  children: ReactNode;
44
44
  className?: string;
@@ -89,6 +89,7 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
89
89
  </DrawerTrigger>
90
90
  </div>
91
91
  <main
92
+ data-pagefind-body
92
93
  className={cn(
93
94
  "h-full dark:border-white/10 translate-x-0",
94
95
  "lg:overflow-visible",
@@ -67,12 +67,16 @@ export const SidebarItem = ({
67
67
  </NavLink>
68
68
  );
69
69
  case "link":
70
- return item.href.startsWith("#") ? (
70
+ return !item.href.startsWith("http") ? (
71
71
  <AnchorLink
72
- to={{ hash: item.href, search: searchParams.toString() }}
73
- {...{ [DATA_ANCHOR_ATTR]: item.href.slice(1) }}
72
+ to={{
73
+ pathname: item.href.split("#")[0],
74
+ hash: item.href.split("#")[1],
75
+ search: searchParams.toString(),
76
+ }}
77
+ {...{ [DATA_ANCHOR_ATTR]: item.href.split("#")[1] }}
74
78
  className={navigationListItem({
75
- isActive: item.href.slice(1) === activeAnchor,
79
+ isActive: item.href.split("#")[1] === activeAnchor,
76
80
  className: item.badge?.placement !== "start" && "justify-between",
77
81
  })}
78
82
  onClick={onRequestClose}
@@ -88,25 +92,6 @@ export const SidebarItem = ({
88
92
  <span className="break-all">{item.label}</span>
89
93
  )}
90
94
  </AnchorLink>
91
- ) : !item.href.startsWith("http") ? (
92
- <NavLink
93
- className={navigationListItem({
94
- isActive: item.href.split("#")[1] === activeAnchor,
95
- className: item.badge?.placement !== "start" && "justify-between",
96
- })}
97
- to={item.href}
98
- >
99
- {item.badge ? (
100
- <>
101
- <span className="truncate" title={item.label}>
102
- {item.label}
103
- </span>
104
- <SidebarBadge {...item.badge} />
105
- </>
106
- ) : (
107
- <span className="break-all">{item.label}</span>
108
- )}
109
- </NavLink>
110
95
  ) : (
111
96
  <a
112
97
  className={navigationListItem()}
@@ -27,9 +27,10 @@ export const RouteGuard = () => {
27
27
  queryKey: ["login-redirect"],
28
28
  queryFn: async () => {
29
29
  await new Promise((resolve) => setTimeout(resolve, 1200));
30
- return zudoku.authentication?.signIn({
30
+ await zudoku.authentication?.signIn({
31
31
  redirectTo: latestPath.current,
32
32
  });
33
+ return true;
33
34
  },
34
35
  enabled:
35
36
  typeof window !== "undefined" &&
@@ -24,6 +24,10 @@ export interface ZudokuEvents {
24
24
 
25
25
  export interface ApiIdentity {
26
26
  authorizeRequest: (request: Request) => Promise<Request> | Request;
27
+ authorizationFields?: {
28
+ headers?: string[];
29
+ queryParams?: string[];
30
+ };
27
31
  label: string;
28
32
  id: string;
29
33
  }
@@ -1,6 +1,7 @@
1
1
  import { useSuspenseQuery } from "@tanstack/react-query";
2
+ import { Helmet } from "@zudoku/react-helmet-async";
2
3
  import { useMatch } from "react-router";
3
- import { Head, Link } from "zudoku/components";
4
+ import { Link } from "zudoku/components";
4
5
  import { useAuthState } from "../../authentication/state.js";
5
6
  import { Heading } from "../../components/Heading.js";
6
7
  import { Markdown } from "../../components/Markdown.js";
@@ -11,7 +12,10 @@ export const Catalog = ({
11
12
  items,
12
13
  filterCatalogItems = (items) => items,
13
14
  label = "API Library",
14
- }: Omit<ApiCatalogPluginOptions, "navigationId">) => {
15
+ categoryLabel,
16
+ }: Omit<ApiCatalogPluginOptions, "navigationId"> & {
17
+ categoryLabel?: string;
18
+ }) => {
15
19
  const auth = useAuthState();
16
20
  const match = useMatch({ path: "/catalog/:category" });
17
21
  const activeCategory = match?.params.category;
@@ -21,13 +25,25 @@ export const Catalog = ({
21
25
  queryKey: ["catalogItems", auth],
22
26
  });
23
27
 
28
+ // Only index the overview page, ignore the rest
29
+ const dataSet = activeCategory ? { "data-pagefind-ignore": "all" } : {};
30
+
24
31
  return (
25
- <section className="pt-[--padding-content-top] pb-[--padding-content-bottom]">
26
- <Head>
27
- <title>{label}</title>
28
- </Head>
32
+ <section
33
+ className="pt-[--padding-content-top] pb-[--padding-content-bottom]"
34
+ {...dataSet}
35
+ >
36
+ <Helmet>
37
+ <title>
38
+ {categoryLabel ? `${categoryLabel} - ` : ""}
39
+ {label}
40
+ </title>
41
+ </Helmet>
29
42
  <div className="grid gap-4">
30
- <Heading level={2}>{label}</Heading>
43
+ <Heading level={2}>
44
+ {label}
45
+ {categoryLabel && ` - ${categoryLabel}`}
46
+ </Heading>
31
47
 
32
48
  <div className="grid grid-cols-2 gap-4">
33
49
  {catalogItems.data
@@ -98,6 +98,7 @@ export const apiCatalogPlugin = ({
98
98
  element: (
99
99
  <Catalog
100
100
  label={label}
101
+ categoryLabel={tag}
101
102
  items={items}
102
103
  filterCatalogItems={filterCatalogItems}
103
104
  categories={categories}
@@ -90,7 +90,11 @@ export const MdxPage = ({
90
90
  }, [file]);
91
91
 
92
92
  return (
93
- <div className="xl:grid grid-cols-[--sidecar-grid-cols] gap-8 justify-between">
93
+ <div
94
+ className="xl:grid grid-cols-[--sidecar-grid-cols] gap-8 justify-between"
95
+ data-pagefind-filter="section:markdown"
96
+ data-pagefind-meta="section:markdown"
97
+ >
94
98
  <Helmet>
95
99
  <title>{pageTitle}</title>
96
100
  {excerpt && <meta name="description" content={excerpt} />}