zudoku 0.33.2-local.4 → 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 (145) hide show
  1. package/README.md +121 -0
  2. package/dist/config/validators/common.d.ts +346 -346
  3. package/dist/config/validators/validate.d.ts +165 -165
  4. package/dist/lib/components/AnchorLink.d.ts +2 -2
  5. package/dist/lib/components/AnchorLink.js +4 -4
  6. package/dist/lib/components/AnchorLink.js.map +1 -1
  7. package/dist/lib/components/Heading.d.ts +1 -1
  8. package/dist/lib/components/context/ZudokuContext.d.ts +1 -1
  9. package/dist/lib/components/navigation/SidebarItem.js +6 -5
  10. package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
  11. package/dist/lib/core/ZudokuContext.d.ts +4 -0
  12. package/dist/lib/core/ZudokuContext.js.map +1 -1
  13. package/dist/lib/plugins/openapi/OperationList.js +4 -1
  14. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  15. package/dist/lib/plugins/openapi/OperationListItem.d.ts +1 -1
  16. package/dist/lib/plugins/openapi/OperationListItem.js +5 -3
  17. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  18. package/dist/lib/plugins/openapi/graphql/gql.d.ts +1 -1
  19. package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
  20. package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
  21. package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
  22. package/dist/lib/plugins/openapi/graphql/graphql.js +2 -0
  23. package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
  24. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.d.ts +2 -2
  25. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +1 -5
  26. package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
  27. package/dist/lib/plugins/openapi/playground/Headers.js +1 -1
  28. package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
  29. package/dist/lib/plugins/openapi/playground/IdentityDialog.d.ts +11 -0
  30. package/dist/lib/plugins/openapi/playground/IdentityDialog.js +14 -0
  31. package/dist/lib/plugins/openapi/playground/IdentityDialog.js.map +1 -0
  32. package/dist/lib/plugins/openapi/playground/IdentitySelector.d.ts +7 -0
  33. package/dist/lib/plugins/openapi/playground/IdentitySelector.js +10 -0
  34. package/dist/lib/plugins/openapi/playground/IdentitySelector.js.map +1 -0
  35. package/dist/lib/plugins/openapi/playground/Playground.d.ts +9 -1
  36. package/dist/lib/plugins/openapi/playground/Playground.js +75 -24
  37. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  38. package/dist/lib/plugins/openapi/playground/QueryParams.js +1 -1
  39. package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
  40. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.d.ts +7 -0
  41. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js +8 -0
  42. package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js.map +1 -0
  43. package/dist/lib/plugins/openapi/playground/rememberedIdentity.d.ts +17 -0
  44. package/dist/lib/plugins/openapi/playground/rememberedIdentity.js +11 -0
  45. package/dist/lib/plugins/openapi/playground/rememberedIdentity.js.map +1 -0
  46. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +19 -13
  47. package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
  48. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +6 -4
  49. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +4 -3
  50. package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js.map +1 -1
  51. package/dist/lib/ui/Checkbox.d.ts +2 -8
  52. package/dist/lib/ui/Checkbox.js +1 -13
  53. package/dist/lib/ui/Checkbox.js.map +1 -1
  54. package/dist/lib/ui/Command.d.ts +6 -6
  55. package/dist/lib/ui/Select.js +1 -1
  56. package/dist/lib/ui/Select.js.map +1 -1
  57. package/dist/lib/ui/SyntaxHighlight.d.ts +2 -1
  58. package/dist/lib/ui/SyntaxHighlight.js +19 -15
  59. package/dist/lib/ui/SyntaxHighlight.js.map +1 -1
  60. package/dist/lib/util/MdxComponents.d.ts +1 -1
  61. package/dist/lib/util/MdxComponents.js +2 -2
  62. package/dist/lib/util/MdxComponents.js.map +1 -1
  63. package/lib/{AuthenticationPlugin-BCYuduZ9.js → AuthenticationPlugin-4ip08maU.js} +3 -3
  64. package/lib/{AuthenticationPlugin-BCYuduZ9.js.map → AuthenticationPlugin-4ip08maU.js.map} +1 -1
  65. package/lib/Callout-B_sEhkYd.js +211 -0
  66. package/lib/Callout-B_sEhkYd.js.map +1 -0
  67. package/lib/{Dialog-mi6BrnrM.js → Dialog-sbgekbjb.js} +48 -33
  68. package/lib/{Dialog-mi6BrnrM.js.map → Dialog-sbgekbjb.js.map} +1 -1
  69. package/lib/{Markdown-DofXBcqg.js → Markdown-DZXjQjpH.js} +4099 -3848
  70. package/lib/Markdown-DZXjQjpH.js.map +1 -0
  71. package/lib/{MdxPage-KJcNWIgt.js → MdxPage-52vRwa_7.js} +13 -13
  72. package/lib/{MdxPage-KJcNWIgt.js.map → MdxPage-52vRwa_7.js.map} +1 -1
  73. package/lib/{OasProvider-HcqBeC4H.js → OasProvider-CR2nG1Eg.js} +4 -4
  74. package/lib/{OasProvider-HcqBeC4H.js.map → OasProvider-CR2nG1Eg.js.map} +1 -1
  75. package/lib/{OperationList-C3wnbFxp.js → OperationList-DndcCJUG.js} +1097 -1052
  76. package/lib/{OperationList-C3wnbFxp.js.map → OperationList-DndcCJUG.js.map} +1 -1
  77. package/lib/{Select-Co6MuS4j.js → Select-FAYHOYTy.js} +35 -35
  78. package/lib/{Select-Co6MuS4j.js.map → Select-FAYHOYTy.js.map} +1 -1
  79. package/lib/{SlotletProvider-CYFNHuok.js → SlotletProvider-TydSHROc.js} +4 -4
  80. package/lib/{SlotletProvider-CYFNHuok.js.map → SlotletProvider-TydSHROc.js.map} +1 -1
  81. package/lib/{chunk-IR6S3I6Y-CRDBmIgK.js → chunk-HA7DTUK3-ZGg2W6yV.js} +276 -276
  82. package/lib/chunk-HA7DTUK3-ZGg2W6yV.js.map +1 -0
  83. package/lib/{hook-LTe5qHSc.js → hook-CfCFKZ-2.js} +10 -7
  84. package/lib/{hook-LTe5qHSc.js.map → hook-CfCFKZ-2.js.map} +1 -1
  85. package/lib/index-DK7IuUyR.js +2201 -0
  86. package/lib/index-DK7IuUyR.js.map +1 -0
  87. package/lib/index.esm-CltAN0Tf.js +711 -0
  88. package/lib/index.esm-CltAN0Tf.js.map +1 -0
  89. package/lib/objectEntries-BS7aAgOm.js +12 -0
  90. package/lib/objectEntries-BS7aAgOm.js.map +1 -0
  91. package/lib/ui/Checkbox.js +15 -25
  92. package/lib/ui/Checkbox.js.map +1 -1
  93. package/lib/ui/Command.js +1 -1
  94. package/lib/ui/Select.js +1 -1
  95. package/lib/ui/Select.js.map +1 -1
  96. package/lib/ui/SyntaxHighlight.js +483 -502
  97. package/lib/ui/SyntaxHighlight.js.map +1 -1
  98. package/lib/{useExposedProps-D76yras4.js → useExposedProps-BslIn-FE.js} +2 -2
  99. package/lib/{useExposedProps-D76yras4.js.map → useExposedProps-BslIn-FE.js.map} +1 -1
  100. package/lib/zudoku.auth-auth0.js +1 -1
  101. package/lib/zudoku.auth-clerk.js +2 -2
  102. package/lib/zudoku.auth-openid.js +3 -3
  103. package/lib/zudoku.components.js +1390 -32
  104. package/lib/zudoku.components.js.map +1 -1
  105. package/lib/zudoku.hooks.js +1 -1
  106. package/lib/zudoku.plugin-api-catalog.js +5 -5
  107. package/lib/zudoku.plugin-api-keys.js +4 -4
  108. package/lib/zudoku.plugin-custom-pages.js +2 -2
  109. package/lib/zudoku.plugin-markdown.js +1 -1
  110. package/lib/zudoku.plugin-openapi.js +3 -3
  111. package/lib/zudoku.plugin-redirect.js +1 -1
  112. package/lib/zudoku.plugin-search-pagefind.js +84 -154
  113. package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
  114. package/package.json +3 -3
  115. package/src/lib/components/AnchorLink.tsx +7 -7
  116. package/src/lib/components/navigation/SidebarItem.tsx +8 -23
  117. package/src/lib/core/ZudokuContext.ts +4 -0
  118. package/src/lib/plugins/openapi/OperationList.tsx +73 -33
  119. package/src/lib/plugins/openapi/OperationListItem.tsx +105 -92
  120. package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
  121. package/src/lib/plugins/openapi/graphql/graphql.ts +3 -0
  122. package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +30 -32
  123. package/src/lib/plugins/openapi/playground/Headers.tsx +0 -1
  124. package/src/lib/plugins/openapi/playground/IdentityDialog.tsx +74 -0
  125. package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +54 -0
  126. package/src/lib/plugins/openapi/playground/Playground.tsx +164 -133
  127. package/src/lib/plugins/openapi/playground/QueryParams.tsx +0 -1
  128. package/src/lib/plugins/openapi/playground/RequestLoginDialog.tsx +51 -0
  129. package/src/lib/plugins/openapi/playground/rememberedIdentity.ts +26 -0
  130. package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +24 -4
  131. package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +66 -45
  132. package/src/lib/ui/Checkbox.tsx +8 -24
  133. package/src/lib/ui/Select.tsx +1 -1
  134. package/src/lib/ui/SyntaxHighlight.tsx +94 -96
  135. package/src/lib/util/MdxComponents.tsx +2 -2
  136. package/lib/Command-CrTA1FX0.js +0 -140
  137. package/lib/Command-CrTA1FX0.js.map +0 -1
  138. package/lib/Markdown-DofXBcqg.js.map +0 -1
  139. package/lib/chunk-IR6S3I6Y-CRDBmIgK.js.map +0 -1
  140. package/lib/index-CtkRMvMw.js +0 -2052
  141. package/lib/index-CtkRMvMw.js.map +0 -1
  142. package/lib/index-vn5bsvmU.js +0 -1399
  143. package/lib/index-vn5bsvmU.js.map +0 -1
  144. package/lib/useScrollToAnchor-DKyrbZoy.js +0 -977
  145. package/lib/useScrollToAnchor-DKyrbZoy.js.map +0 -1
@@ -1,164 +1,94 @@
1
1
  import { j as e } from "./jsx-runtime-CYK1ROHF.js";
2
- import { C as y } from "./ClientOnly-E7hGysn1.js";
3
- import { VisuallyHidden as k } from "@radix-ui/react-visually-hidden";
4
- import { d as p, k as j } from "./useQuery-CQUwWR9i.js";
5
- import { useCallback as C, useState as S } from "react";
6
- import { ShieldAlertIcon as w, AlertTriangleIcon as _, InfoIcon as g, LightbulbIcon as N, FileTextIcon as v } from "lucide-react";
7
- import { c as m } from "./cn-qaFjX9_3.js";
8
- import { C as I, a as x, b, c as L, d as z, e as F } from "./Command-CrTA1FX0.js";
9
- import { b as T } from "./Dialog-mi6BrnrM.js";
10
- import { j as q } from "./joinUrl-10po2Jdj.js";
11
- import { a as R, L as h } from "./chunk-IR6S3I6Y-CRDBmIgK.js";
12
- const $ = {
13
- note: {
14
- border: "border-gray-300 dark:border-zinc-800",
15
- bg: "bg-gray-100 dark:bg-zinc-800/50",
16
- iconColor: "text-gray-600 dark:text-zinc-300",
17
- titleColor: "text-gray-600 dark:text-zinc-300",
18
- textColor: "text-gray-600 dark:text-zinc-300",
19
- Icon: g
20
- },
21
- tip: {
22
- border: "border-green-500 dark:border-green-800",
23
- bg: "bg-green-200/25 dark:bg-green-950/70",
24
- iconColor: "text-green-600 dark:text-green-200",
25
- titleColor: "text-green-700 dark:text-green-200",
26
- textColor: "text-green-600 dark:text-green-50",
27
- Icon: N
28
- },
29
- info: {
30
- border: "border-blue-400 dark:border-blue-900/60",
31
- bg: "bg-blue-50 dark:bg-blue-950/40",
32
- iconColor: "text-blue-400 dark:text-blue-200",
33
- titleColor: "text-blue-700 dark:text-blue-200",
34
- textColor: "text-blue-600 dark:text-blue-100",
35
- Icon: g
36
- },
37
- caution: {
38
- border: "border-yellow-400 dark:border-yellow-400/25",
39
- bg: "bg-yellow-100/60 dark:bg-yellow-400/10",
40
- iconColor: "text-yellow-500 dark:text-yellow-300",
41
- titleColor: "text-yellow-600 dark:text-yellow-300",
42
- textColor: "text-yellow-700 dark:text-yellow-200",
43
- Icon: _
44
- },
45
- danger: {
46
- border: "border-rose-400 dark:border-rose-800",
47
- bg: "bg-rose-50 dark:bg-rose-950/40",
48
- iconColor: "text-rose-400 dark:text-rose-300",
49
- titleColor: "text-rose-800 dark:text-rose-300",
50
- textColor: "text-rose-700 dark:text-rose-100",
51
- Icon: w
52
- }
53
- }, D = ({ type: r, children: s, title: a, className: n }) => {
54
- const { border: l, bg: i, iconColor: o, titleColor: t, textColor: c, Icon: d } = $[r];
55
- return /* @__PURE__ */ e.jsxs(
56
- "div",
57
- {
58
- className: m(
59
- "not-prose grid grid-cols-[min-content_1fr] grid-rows-[fit-content_1fr] gap-x-4 gap-y-2 text-md rounded-md border p-4",
60
- "[&_a]:underline [&_a]:decoration-current [&_a]:decoration-from-font [&_a]:underline-offset-4 hover:[&_a]:decoration-1",
61
- "[&_code]:!bg-gray-50 [&_code]:dark:!bg-gray-800 [&_code]:!border-none my-2",
62
- a && "items-center",
63
- l,
64
- i,
65
- n
66
- ),
67
- children: [
68
- /* @__PURE__ */ e.jsx(
69
- d,
70
- {
71
- className: m(!a && "translate-y-px", o),
72
- size: 20,
73
- "aria-hidden": "true"
74
- }
75
- ),
76
- a && /* @__PURE__ */ e.jsx("h3", { className: m("font-medium", t), children: a }),
77
- /* @__PURE__ */ e.jsx("div", { className: m("col-start-2", !a && "row-start-1", c), children: s })
78
- ]
79
- }
80
- );
81
- }, E = async (r, s) => {
82
- const a = s.maxResults ?? 10, n = s.transformResults ?? (() => !0), l = [], i = P(r, n);
83
- for await (const o of i)
84
- if (l.push(o), l.length >= a) break;
85
- return l;
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;
86
16
  };
87
- async function* P(r, s) {
17
+ async function* R(r, o) {
88
18
  let n = 0;
89
19
  for (; n < r.results.length; ) {
90
- const l = r.results.slice(
20
+ const i = r.results.slice(
91
21
  n,
92
22
  n + 5
93
23
  );
94
- n += l.length;
95
- const i = await Promise.all(l.map((o) => o.data()));
96
- for (const o of i) {
97
- const t = s(o);
98
- t !== !1 && (t === !0 || t == null ? yield o : yield t);
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);
99
29
  }
100
30
  }
101
31
  }
102
- const A = (r, s) => {
103
- const a = r.weighted_locations.reduce(
104
- (l, i) => l + i.balanced_score,
32
+ const $ = (r, o) => {
33
+ const s = r.weighted_locations.reduce(
34
+ (i, l) => i + l.balanced_score,
105
35
  0
106
36
  );
107
- return s.weighted_locations.reduce(
108
- (l, i) => l + i.balanced_score,
37
+ return o.weighted_locations.reduce(
38
+ (i, l) => i + l.balanced_score,
109
39
  0
110
- ) - a;
111
- }, f = "cursor-pointer border border-transparent data-[selected=true]:border-border", U = ({
40
+ ) - s;
41
+ }, p = "cursor-pointer border border-transparent data-[selected=true]:border-border", D = ({
112
42
  basePath: r,
113
- searchResults: s,
114
- searchTerm: a,
43
+ searchResults: o,
44
+ searchTerm: s,
115
45
  onClose: n,
116
- maxSubResults: l = 4
46
+ maxSubResults: i = 4
117
47
  }) => {
118
- const i = R(), o = C(
48
+ const l = T(), a = S(
119
49
  (t) => {
120
50
  const c = t.replace(".html", "");
121
51
  return r && c.startsWith(r) ? c.slice(r.length) : c;
122
52
  },
123
53
  [r]
124
54
  );
125
- return /* @__PURE__ */ e.jsxs(I, { className: "max-h-[450px]", children: [
126
- a && s.length > 0 && /* @__PURE__ */ e.jsx(
127
- x,
55
+ return /* @__PURE__ */ e.jsxs(k, { className: "max-h-[450px]", children: [
56
+ s && o.length > 0 && /* @__PURE__ */ e.jsx(
57
+ u,
128
58
  {
129
59
  className: "text-sm text-muted-foreground",
130
- heading: `${s.length} results for "${a}"`
60
+ heading: `${o.length} results for "${s}"`
131
61
  }
132
62
  ),
133
- s.map((t) => /* @__PURE__ */ e.jsxs(
134
- x,
63
+ o.map((t) => /* @__PURE__ */ e.jsxs(
64
+ u,
135
65
  {
136
66
  children: [
137
67
  /* @__PURE__ */ e.jsx(
138
- b,
68
+ h,
139
69
  {
140
70
  asChild: !0,
141
71
  value: `${t.meta.title}-${t.url}`,
142
- className: f,
72
+ className: p,
143
73
  onSelect: () => {
144
- i(o(t.url)), n();
74
+ l(a(t.url)), n();
145
75
  },
146
- children: /* @__PURE__ */ e.jsxs(h, { to: o(t.url), children: [
147
- /* @__PURE__ */ e.jsx(v, { size: 20, className: "text-muted-foreground" }),
76
+ children: /* @__PURE__ */ e.jsxs(g, { to: a(t.url), children: [
77
+ /* @__PURE__ */ e.jsx(F, { size: 20, className: "text-muted-foreground" }),
148
78
  t.meta.title
149
79
  ] })
150
80
  }
151
81
  ),
152
- t.sub_results.sort(A).slice(0, l).map((c) => /* @__PURE__ */ e.jsx(
153
- b,
82
+ t.sub_results.sort($).slice(0, i).map((c) => /* @__PURE__ */ e.jsx(
83
+ h,
154
84
  {
155
85
  asChild: !0,
156
86
  value: `${t.meta.title}-${c.url}`,
157
- className: f,
87
+ className: p,
158
88
  onSelect: () => {
159
- i(o(c.url)), n();
89
+ l(a(c.url)), n();
160
90
  },
161
- children: /* @__PURE__ */ e.jsx(h, { to: o(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: [
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: [
162
92
  /* @__PURE__ */ e.jsx("span", { className: "font-bold", children: c.title }),
163
93
  /* @__PURE__ */ e.jsx(
164
94
  "span",
@@ -176,7 +106,7 @@ const A = (r, s) => {
176
106
  [t.meta.title ?? t.excerpt, t.url].join("-")
177
107
  ))
178
108
  ] });
179
- }, u = {
109
+ }, d = {
180
110
  // Slightly lower than default because API docs tend to have repetitive terms (parameter names, HTTP methods, etc.)
181
111
  termFrequency: 0.8,
182
112
  // Lower than default because API documentation pages tend to be longer due to comprehensive endpoint documentation
@@ -185,62 +115,62 @@ const A = (r, s) => {
185
115
  termSimilarity: 1.2,
186
116
  // Slightly lower than default because API docs might have legitimate repetition of terms
187
117
  termSaturation: 1.2
188
- }, G = (r) => import(
118
+ }, E = (r) => import(
189
119
  /* @vite-ignore */
190
- q(r, "/pagefind/pagefind.js")
191
- ), K = (r) => {
192
- const { data: s, ...a } = p({
120
+ L(r, "/pagefind/pagefind.js")
121
+ ), I = (r) => {
122
+ const { data: o, ...s } = f({
193
123
  queryKey: ["pagefind", r.ranking],
194
124
  retry: !1,
195
125
  queryFn: async () => {
196
- var l, i, o, t;
197
- const n = await G(r.basePath);
126
+ var i, l, a, t;
127
+ const n = await E(r.basePath);
198
128
  return await n.init(), await n.options({
199
129
  ranking: {
200
- termFrequency: ((l = r.ranking) == null ? void 0 : l.termFrequency) ?? u.termFrequency,
201
- pageLength: ((i = r.ranking) == null ? void 0 : i.pageLength) ?? u.pageLength,
202
- termSimilarity: ((o = r.ranking) == null ? void 0 : o.termSimilarity) ?? u.termSimilarity,
203
- termSaturation: ((t = r.ranking) == null ? void 0 : t.termSaturation) ?? u.termSaturation
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
204
134
  }
205
135
  }), n;
206
136
  },
207
137
  enabled: typeof window < "u"
208
138
  });
209
- return a.isError && console.error(a.error), { ...a, pagefind: s };
210
- }, O = ({
139
+ return s.isError && console.error(s.error), { ...s, pagefind: o };
140
+ }, P = ({
211
141
  isOpen: r,
212
- onClose: s,
213
- options: a
142
+ onClose: o,
143
+ options: s
214
144
  }) => {
215
- const { pagefind: n, error: l, isError: i } = K(a), [o, t] = S(""), { data: c } = p({
216
- queryKey: ["pagefind-search", o],
145
+ const { pagefind: n, error: i, isError: l } = I(s), [a, t] = b(""), { data: c } = f({
146
+ queryKey: ["pagefind-search", a],
217
147
  queryFn: async () => {
218
- const d = await (n == null ? void 0 : n.search(o));
219
- return d ? E(d, a) : [];
148
+ const m = await (n == null ? void 0 : n.search(a));
149
+ return m ? q(m, s) : [];
220
150
  },
221
151
  placeholderData: j,
222
- enabled: !!n && !!o
152
+ enabled: !!n && !!a
223
153
  });
224
154
  return /* @__PURE__ */ e.jsxs(
225
- L,
155
+ C,
226
156
  {
227
157
  command: { shouldFilter: !1 },
228
158
  content: { className: "max-w-[750px]" },
229
159
  open: r,
230
- onOpenChange: s,
160
+ onOpenChange: o,
231
161
  children: [
232
- /* @__PURE__ */ e.jsx(k, { children: /* @__PURE__ */ e.jsx(T, { children: "Search" }) }),
162
+ /* @__PURE__ */ e.jsx(y, { children: /* @__PURE__ */ e.jsx(_, { children: "Search" }) }),
233
163
  /* @__PURE__ */ e.jsx(
234
- z,
164
+ N,
235
165
  {
236
166
  placeholder: "Search...",
237
- value: o,
167
+ value: a,
238
168
  onValueChange: t,
239
- disabled: i
169
+ disabled: l
240
170
  }
241
171
  ),
242
- /* @__PURE__ */ e.jsx(F, { children: o ? "No results found." : "Start typing to search" }),
243
- i ? /* @__PURE__ */ e.jsx("div", { className: "p-4 text-sm", children: l.message === "NOT_BUILT_YET" ? /* @__PURE__ */ e.jsxs(D, { type: "info", children: [
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: [
244
174
  "Search is currently not available in development mode by default.",
245
175
  /* @__PURE__ */ e.jsx("br", {}),
246
176
  "To still use search in development, run ",
@@ -253,22 +183,22 @@ const A = (r, s) => {
253
183
  /* @__PURE__ */ e.jsx("code", { children: "public" }),
254
184
  " directory."
255
185
  ] }) : "An error occurred while loading search." }) : /* @__PURE__ */ e.jsx(
256
- U,
186
+ D,
257
187
  {
258
- basePath: a.basePath,
188
+ basePath: s.basePath,
259
189
  searchResults: c ?? [],
260
- searchTerm: o,
261
- onClose: s,
262
- maxSubResults: a.maxSubResults
190
+ searchTerm: a,
191
+ onClose: o,
192
+ maxSubResults: s.maxSubResults
263
193
  }
264
194
  )
265
195
  ]
266
196
  }
267
197
  );
268
- }, re = (r) => ({
269
- renderSearch: ({ isOpen: s, onClose: a }) => /* @__PURE__ */ e.jsx(y, { children: /* @__PURE__ */ e.jsx(O, { isOpen: s, onClose: a, options: r }) })
198
+ }, Q = (r) => ({
199
+ renderSearch: ({ isOpen: o, onClose: s }) => /* @__PURE__ */ e.jsx(x, { children: /* @__PURE__ */ e.jsx(P, { isOpen: o, onClose: s, options: r }) })
270
200
  });
271
201
  export {
272
- re as pagefindSearchPlugin
202
+ Q as pagefindSearchPlugin
273
203
  };
274
204
  //# sourceMappingURL=zudoku.plugin-search-pagefind.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-search-pagefind.js","sources":["../src/lib/ui/Callout.tsx","../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 {\n AlertTriangleIcon,\n InfoIcon,\n LightbulbIcon,\n type LucideIcon,\n ShieldAlertIcon,\n} from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../util/cn.js\";\n\nconst stylesMap = {\n note: {\n border: \"border-gray-300 dark:border-zinc-800\",\n bg: \"bg-gray-100 dark:bg-zinc-800/50\",\n iconColor: \"text-gray-600 dark:text-zinc-300\",\n titleColor: \"text-gray-600 dark:text-zinc-300\",\n textColor: \"text-gray-600 dark:text-zinc-300\",\n Icon: InfoIcon as LucideIcon,\n },\n tip: {\n border: \"border-green-500 dark:border-green-800\",\n bg: \"bg-green-200/25 dark:bg-green-950/70\",\n iconColor: \"text-green-600 dark:text-green-200\",\n titleColor: \"text-green-700 dark:text-green-200\",\n textColor: \"text-green-600 dark:text-green-50\",\n Icon: LightbulbIcon as LucideIcon,\n },\n info: {\n border: \"border-blue-400 dark:border-blue-900/60\",\n bg: \"bg-blue-50 dark:bg-blue-950/40\",\n iconColor: \"text-blue-400 dark:text-blue-200\",\n titleColor: \"text-blue-700 dark:text-blue-200\",\n textColor: \"text-blue-600 dark:text-blue-100\",\n Icon: InfoIcon as LucideIcon,\n },\n caution: {\n border: \"border-yellow-400 dark:border-yellow-400/25\",\n bg: \"bg-yellow-100/60 dark:bg-yellow-400/10\",\n iconColor: \"text-yellow-500 dark:text-yellow-300\",\n titleColor: \"text-yellow-600 dark:text-yellow-300\",\n textColor: \"text-yellow-700 dark:text-yellow-200\",\n Icon: AlertTriangleIcon as LucideIcon,\n },\n danger: {\n border: \"border-rose-400 dark:border-rose-800\",\n bg: \"bg-rose-50 dark:bg-rose-950/40\",\n iconColor: \"text-rose-400 dark:text-rose-300\",\n titleColor: \"text-rose-800 dark:text-rose-300\",\n textColor: \"text-rose-700 dark:text-rose-100\",\n Icon: ShieldAlertIcon as LucideIcon,\n },\n} as const;\n\ntype CalloutProps = {\n type: keyof typeof stylesMap;\n title?: string;\n children: ReactNode;\n className?: string;\n};\n\nexport const Callout = ({ type, children, title, className }: CalloutProps) => {\n const { border, bg, iconColor, titleColor, textColor, Icon } =\n stylesMap[type];\n\n return (\n <div\n className={cn(\n \"not-prose grid grid-cols-[min-content_1fr] grid-rows-[fit-content_1fr] gap-x-4 gap-y-2 text-md rounded-md border p-4\",\n \"[&_a]:underline [&_a]:decoration-current [&_a]:decoration-from-font [&_a]:underline-offset-4 hover:[&_a]:decoration-1\",\n \"[&_code]:!bg-gray-50 [&_code]:dark:!bg-gray-800 [&_code]:!border-none my-2\",\n title && \"items-center\",\n border,\n bg,\n className,\n )}\n >\n <Icon\n className={cn(!title && \"translate-y-px\", iconColor)}\n size={20}\n aria-hidden=\"true\"\n />\n {title && <h3 className={cn(\"font-medium\", titleColor)}>{title}</h3>}\n <div className={cn(\"col-start-2\", !title && \"row-start-1\", textColor)}>\n {children}\n </div>\n </div>\n );\n};\n","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":["stylesMap","InfoIcon","LightbulbIcon","AlertTriangleIcon","ShieldAlertIcon","Callout","type","children","title","className","border","bg","iconColor","titleColor","textColor","Icon","jsxs","cn","jsx","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","CommandList","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","pagefindSearchPlugin","ClientOnly"],"mappings":"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"}
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":";;;;;;;;;;AAGa,MAAAA,IAAa,OACxBC,GACAC,MACG;AACG,QAAAC,IAAaD,EAAQ,cAAc,IACnCE,IAAcF,EAAQ,qBAAqB,MAAM,KAEjDG,IAA+C,CAAC,GAEhDC,IAAYC,EAAsBN,GAAQG,CAAW;AAE3D,mBAAiBI,KAAUF;AAErB,QADJD,EAAmB,KAAKG,CAAM,GAC1BH,EAAmB,UAAUF,EAAY;AAGxC,SAAAE;AACT;AAEA,gBAAgBE,EACdN,GACAG,GACA;AAEA,MAAIK,IAAiB;AAEd,SAAAA,IAAiBR,EAAO,QAAQ,UAAQ;AACvC,UAAAS,IAAQT,EAAO,QAAQ;AAAA,MAC3BQ;AAAA,MACAA,IAAiB;AAAA,IACnB;AACA,IAAAA,KAAkBC,EAAM;AAElB,UAAAC,IAAY,MAAM,QAAQ,IAAID,EAAM,IAAI,CAACF,MAAWA,EAAO,KAAK,CAAC,CAAC;AAExE,eAAWA,KAAUG,GAAW;AACxB,YAAAC,IAAcR,EAAYI,CAAM;AAEtC,MAAII,MAAgB,OAGTA,MAAgB,MAAQA,KAAe,OAE1C,MAAAJ,IAGA,MAAAI;AAAA,IACR;AAAA,EACF;AAEJ;AC5CA,MAAMC,IAAiB,CAACC,GAAsBC,MAAyB;AAC/D,QAAAC,IAASF,EAAE,mBAAmB;AAAA,IAClC,CAACG,GAAKC,MAAQD,IAAMC,EAAI;AAAA,IACxB;AAAA,EACF;AAKA,SAJeH,EAAE,mBAAmB;AAAA,IAClC,CAACE,GAAKC,MAAQD,IAAMC,EAAI;AAAA,IACxB;AAAA,EACF,IACgBF;AAClB,GAEMG,IAAiB,+EAEVC,IAAa,CAAC;AAAA,EACzB,UAAAC;AAAA,EACA,eAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,eAAAC,IAAgB;AAClB,MAMM;AACJ,QAAMC,IAAWC,EAAY,GAEvBC,IAAiBC;AAAA,IACrB,CAACC,MAAgB;AACf,YAAMC,IAAQD,EAAI,QAAQ,SAAS,EAAE;AAC9B,aAAAT,KAAYU,EAAM,WAAWV,CAAQ,IACxCU,EAAM,MAAMV,EAAS,MAAM,IAC3BU;AAAA,IACN;AAAA,IACA,CAACV,CAAQ;AAAA,EACX;AAGE,SAAAW,gBAAAA,EAAA,KAACC,GAAY,EAAA,WAAU,iBACpB,UAAA;AAAA,IAAcV,KAAAD,EAAc,SAAS,KACpCY,gBAAAA,EAAA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS,GAAGb,EAAc,MAAM,iBAAiBC,CAAU;AAAA,MAAA;AAAA,IAC7D;AAAA,IAEDD,EAAc,IAAI,CAACd,MAClBwB,gBAAAA,EAAA;AAAA,MAACG;AAAA,MAAA;AAAA,QAGC,UAAA;AAAA,UAAAD,gBAAAA,EAAA;AAAA,YAACE;AAAA,YAAA;AAAA,cACC,SAAO;AAAA,cACP,OAAO,GAAG5B,EAAO,KAAK,KAAK,IAAIA,EAAO,GAAG;AAAA,cACzC,WAAWW;AAAA,cACX,UAAU,MAAM;AACd,gBAAKO,EAASE,EAAepB,EAAO,GAAG,CAAC,GAChCgB,EAAA;AAAA,cACV;AAAA,cAEA,iCAACa,GAAK,EAAA,IAAIT,EAAepB,EAAO,GAAG,GACjC,UAAA;AAAA,gBAAA0B,gBAAAA,EAAA,IAACI,GAAa,EAAA,MAAM,IAAI,WAAU,yBAAwB;AAAA,gBACzD9B,EAAO,KAAK;AAAA,cAAA,EACf,CAAA;AAAA,YAAA;AAAA,UACF;AAAA,UACCA,EAAO,YACL,KAAKK,CAAc,EACnB,MAAM,GAAGY,CAAa,EACtB,IAAI,CAACc,MACJL,gBAAAA,EAAA;AAAA,YAACE;AAAA,YAAA;AAAA,cACC,SAAO;AAAA,cAEP,OAAO,GAAG5B,EAAO,KAAK,KAAK,IAAI+B,EAAU,GAAG;AAAA,cAC5C,WAAWpB;AAAA,cACX,UAAU,MAAM;AACd,gBAAKO,EAASE,EAAeW,EAAU,GAAG,CAAC,GACnCf,EAAA;AAAA,cACV;AAAA,cAEA,UAACU,gBAAAA,EAAA,IAAAG,GAAA,EAAK,IAAIT,EAAeW,EAAU,GAAG,GAAG,SAASf,GAChD,UAAAQ,gBAAAA,OAAC,OAAI,EAAA,WAAU,mFACb,UAAA;AAAA,gBAAAE,gBAAAA,EAAA,IAAC,QAAK,EAAA,WAAU,aAAa,UAAAK,EAAU,OAAM;AAAA,gBAC7CL,gBAAAA,EAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,yBAAyB,EAAE,QAAQK,EAAU,QAAQ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACvD,EAAA,CACF,EACF,CAAA;AAAA,YAAA;AAAA,YAhBK,GAAG/B,EAAO,KAAK,KAAK,IAAI+B,EAAU,GAAG;AAAA,UAkB7C,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAxCE,CAAC/B,EAAO,KAAK,SAASA,EAAO,SAASA,EAAO,GAAG,EAAE,KAAK,GAAG;AAAA,IA0ClE,CAAA;AAAA,EAAA,GACH;AAEJ,GCvFMgC,IAAkB;AAAA;AAAA,EAEtB,eAAe;AAAA;AAAA,EAEf,YAAY;AAAA;AAAA,EAEZ,gBAAgB;AAAA;AAAA,EAEhB,gBAAgB;AAClB,GAEMC,IAAiB,CAACpB,MAIlB;AAAA;AAAA,EAA0BqB,EAAQrB,GAAU,uBAAuB;AAAA,GAEnEsB,IAAc,CAACzC,MAA6B;AAChD,QAAM,EAAE,MAAM0C,GAAU,GAAGpC,EAAA,IAAWqC,EAAmB;AAAA,IACvD,UAAU,CAAC,YAAY3C,EAAQ,OAAO;AAAA,IACtC,OAAO;AAAA,IACP,SAAS,YAAY;;AACnB,YAAM0C,IAAW,MAAMH,EAAevC,EAAQ,QAAQ;AACtD,mBAAM0C,EAAS,KAAK,GACpB,MAAMA,EAAS,QAAQ;AAAA,QACrB,SAAS;AAAA,UACP,iBACEE,IAAA5C,EAAQ,YAAR,gBAAA4C,EAAiB,kBAAiBN,EAAgB;AAAA,UACpD,cAAYO,IAAA7C,EAAQ,YAAR,gBAAA6C,EAAiB,eAAcP,EAAgB;AAAA,UAC3D,kBACEQ,IAAA9C,EAAQ,YAAR,gBAAA8C,EAAiB,mBAAkBR,EAAgB;AAAA,UACrD,kBACES,IAAA/C,EAAQ,YAAR,gBAAA+C,EAAiB,mBAAkBT,EAAgB;AAAA,QAAA;AAAA,MACvD,CACD,GAEMI;AAAAA,IACT;AAAA,IACA,SAAS,OAAO,SAAW;AAAA,EAAA,CAC5B;AAED,SAAIpC,EAAO,WAED,QAAA,MAAMA,EAAO,KAAK,GAGrB,EAAE,GAAGA,GAAQ,UAAAoC,EAAS;AAC/B,GAEaM,IAAiB,CAAC;AAAA,EAC7B,QAAAC;AAAA,EACA,SAAA3B;AAAA,EACA,SAAAtB;AACF,MAIM;AACJ,QAAM,EAAE,UAAA0C,GAAU,OAAAQ,GAAO,SAAAC,EAAQ,IAAIV,EAAYzC,CAAO,GAClD,CAACqB,GAAY+B,CAAa,IAAIC,EAAS,EAAE,GAEzC,EAAE,MAAMjC,EAAc,IAAIuB,EAAS;AAAA,IACvC,UAAU,CAAC,mBAAmBtB,CAAU;AAAA,IACxC,SAAS,YAAY;AACnB,YAAMtB,IAAS,OAAM2C,KAAA,gBAAAA,EAAU,OAAOrB;AAClC,aAACtB,IACED,EAAWC,GAAQC,CAAO,IADb,CAAC;AAAA,IAEvB;AAAA,IACA,iBAAiBsD;AAAA,IACjB,SAAS,CAAC,CAACZ,KAAY,CAAC,CAACrB;AAAA,EAAA,CAC1B;AAGC,SAAAS,gBAAAA,EAAA;AAAA,IAACyB;AAAA,IAAA;AAAA,MACC,SAAS,EAAE,cAAc,GAAM;AAAA,MAC/B,SAAS,EAAE,WAAW,gBAAgB;AAAA,MACtC,MAAMN;AAAA,MACN,cAAc3B;AAAA,MAEd,UAAA;AAAA,QAAAU,gBAAAA,MAACwB,GACC,EAAA,UAAAxB,gBAAAA,EAAA,IAACyB,GAAY,EAAA,UAAA,SAAM,CAAA,GACrB;AAAA,QACAzB,gBAAAA,EAAA;AAAA,UAAC0B;AAAA,UAAA;AAAA,YACC,aAAY;AAAA,YACZ,OAAOrC;AAAA,YACP,eAAe+B;AAAA,YACf,UAAUD;AAAA,UAAA;AAAA,QACZ;AAAA,8BACCQ,GAAA,EACE,UAAatC,IAAA,sBAAsB,0BACtC;AAAA,QACC8B,IACEnB,gBAAAA,EAAA,IAAA,OAAA,EAAI,WAAU,eACZ,UAAMkB,EAAA,YAAY,kBAChBpB,gBAAAA,EAAAA,KAAA8B,GAAQ,EAAA,MAAK,QAAO,UAAA;AAAA,UAAA;AAAA,gCAElB,MAAG,EAAA;AAAA,UAAE;AAAA,UACmC5B,gBAAAA,EAAAA,IAAA,UAAK,UAE9C,gBAAA;AAAA,UAAQ;AAAA,UAAI;AAAA,UACEA,gBAAAA,EAAAA,IAAA,UAAK,UAAa,iBAAA;AAAA,UAAO;AAAA,UAAmB;AAAA,UACzDA,gBAAAA,EAAAA,IAAA,UAAK,UAAM,UAAA;AAAA,UAAO;AAAA,QAAA,GACrB,IAEA,0CAEJ,CAAA,IAEAA,gBAAAA,EAAA;AAAA,UAACd;AAAA,UAAA;AAAA,YACC,UAAUlB,EAAQ;AAAA,YAClB,eAAeoB,KAAiB,CAAC;AAAA,YACjC,YAAAC;AAAA,YACA,SAAAC;AAAA,YACA,eAAetB,EAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACzB;AAAA,IAAA;AAAA,EAEJ;AAEJ,GC5Ha6D,IAAuB,CAClC7D,OAEO;AAAA,EACL,cAAc,CAAC,EAAE,QAAAiD,GAAQ,SAAA3B,EAAQ,MAC9BU,gBAAAA,EAAAA,IAAA8B,GAAA,EACC,UAAC9B,gBAAAA,EAAA,IAAAgB,GAAA,EAAe,QAAAC,GAAgB,SAAA3B,GAAkB,SAAAtB,EAAkB,CAAA,EACtE,CAAA;AAEJ;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.33.2-local.4",
3
+ "version": "0.34.0",
4
4
  "type": "module",
5
5
  "homepage": "https://zudoku.dev",
6
6
  "repository": {
@@ -195,13 +195,13 @@
195
195
  "picocolors": "1.1.1",
196
196
  "piscina": "5.0.0-alpha.1",
197
197
  "postcss": "8.5.2",
198
- "posthog-node": "4.6.0",
198
+ "posthog-node": "4.8.1",
199
199
  "prism-react-renderer": "2.4.1",
200
200
  "prismjs": "1.29.0",
201
201
  "react-error-boundary": "5.0.0",
202
202
  "react-hook-form": "7.54.2",
203
203
  "react-is": "19.0.0",
204
- "react-router": "7.1.5",
204
+ "react-router": "7.2.0",
205
205
  "rehype-mdx-import-media": "1.2.0",
206
206
  "rehype-raw": "7.0.0",
207
207
  "rehype-slug": "6.0.0",
@@ -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
  };
@@ -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()}
@@ -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
  }