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.
- package/dist/config/validators/common.d.ts +572 -354
- package/dist/config/validators/common.js +26 -8
- package/dist/config/validators/common.js.map +1 -1
- package/dist/config/validators/validate.d.ts +254 -167
- package/dist/lib/authentication/hook.d.ts +1 -0
- package/dist/lib/authentication/hook.js +11 -1
- package/dist/lib/authentication/hook.js.map +1 -1
- package/dist/lib/authentication/providers/clerk.js +6 -6
- package/dist/lib/authentication/providers/clerk.js.map +1 -1
- package/dist/lib/components/AnchorLink.d.ts +2 -2
- package/dist/lib/components/AnchorLink.js +4 -4
- package/dist/lib/components/AnchorLink.js.map +1 -1
- package/dist/lib/components/Banner.js +1 -1
- package/dist/lib/components/Banner.js.map +1 -1
- package/dist/lib/components/Heading.d.ts +2 -2
- package/dist/lib/components/Layout.js +1 -1
- package/dist/lib/components/Layout.js.map +1 -1
- package/dist/lib/components/context/ZudokuContext.d.ts +1 -1
- package/dist/lib/components/index.d.ts +1 -0
- package/dist/lib/components/navigation/SidebarItem.js +6 -5
- package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
- package/dist/lib/core/RouteGuard.js +2 -1
- package/dist/lib/core/RouteGuard.js.map +1 -1
- package/dist/lib/core/ZudokuContext.d.ts +4 -0
- package/dist/lib/core/ZudokuContext.js.map +1 -1
- package/dist/lib/plugins/api-catalog/Catalog.d.ts +3 -1
- package/dist/lib/plugins/api-catalog/Catalog.js +7 -4
- package/dist/lib/plugins/api-catalog/Catalog.js.map +1 -1
- package/dist/lib/plugins/api-catalog/index.js +1 -1
- package/dist/lib/plugins/api-catalog/index.js.map +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.d.ts +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +5 -1
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.d.ts +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +6 -3
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterList.d.ts +2 -1
- package/dist/lib/plugins/openapi/ParameterList.js +3 -2
- package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
- package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js +3 -1
- package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.d.ts +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.js +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/graphql.d.ts +1 -0
- package/dist/lib/plugins/openapi/graphql/graphql.js +2 -0
- package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/ExamplesDropdown.d.ts +2 -2
- package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +1 -5
- package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Headers.js +1 -1
- package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/IdentityDialog.d.ts +11 -0
- package/dist/lib/plugins/openapi/playground/IdentityDialog.js +14 -0
- package/dist/lib/plugins/openapi/playground/IdentityDialog.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/IdentitySelector.d.ts +7 -0
- package/dist/lib/plugins/openapi/playground/IdentitySelector.js +10 -0
- package/dist/lib/plugins/openapi/playground/IdentitySelector.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/PathParams.d.ts +3 -2
- package/dist/lib/plugins/openapi/playground/PathParams.js +3 -2
- package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.d.ts +13 -2
- package/dist/lib/plugins/openapi/playground/Playground.js +80 -26
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.js +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/RequestLoginDialog.d.ts +7 -0
- package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js +8 -0
- package/dist/lib/plugins/openapi/playground/RequestLoginDialog.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/rememberedIdentity.d.ts +17 -0
- package/dist/lib/plugins/openapi/playground/rememberedIdentity.js +11 -0
- package/dist/lib/plugins/openapi/playground/rememberedIdentity.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +19 -13
- package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +6 -4
- package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +4 -3
- package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js.map +1 -1
- package/dist/lib/plugins/search-pagefind/PagefindSearch.d.ts +6 -0
- package/dist/lib/plugins/search-pagefind/PagefindSearch.js +66 -0
- package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -0
- package/dist/lib/plugins/search-pagefind/ResultList.d.ts +8 -0
- package/dist/lib/plugins/search-pagefind/ResultList.js +31 -0
- package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -0
- package/dist/lib/plugins/search-pagefind/get-results.d.ts +3 -0
- package/dist/lib/plugins/search-pagefind/get-results.js +37 -0
- package/dist/lib/plugins/search-pagefind/get-results.js.map +1 -0
- package/dist/lib/plugins/search-pagefind/index.d.ts +8 -0
- package/dist/lib/plugins/search-pagefind/index.js +9 -0
- package/dist/lib/plugins/search-pagefind/index.js.map +1 -0
- package/dist/lib/plugins/search-pagefind/types.d.ts +85 -0
- package/dist/lib/plugins/search-pagefind/types.js +2 -0
- package/dist/lib/plugins/search-pagefind/types.js.map +1 -0
- package/dist/lib/ui/Checkbox.d.ts +2 -8
- package/dist/lib/ui/Checkbox.js +1 -13
- package/dist/lib/ui/Checkbox.js.map +1 -1
- package/dist/lib/ui/Command.d.ts +13 -7
- package/dist/lib/ui/Command.js +2 -2
- package/dist/lib/ui/Command.js.map +1 -1
- package/dist/lib/ui/Select.js +1 -1
- package/dist/lib/ui/Select.js.map +1 -1
- package/dist/lib/ui/SyntaxHighlight.d.ts +2 -1
- package/dist/lib/ui/SyntaxHighlight.js +19 -15
- package/dist/lib/ui/SyntaxHighlight.js.map +1 -1
- package/dist/lib/util/MdxComponents.d.ts +1 -1
- package/dist/lib/util/MdxComponents.js +2 -2
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/useScrollToAnchor.js +6 -8
- package/dist/lib/util/useScrollToAnchor.js.map +1 -1
- package/dist/vite/build.js +4 -0
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/config.js +7 -2
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/dev-server.js +8 -0
- package/dist/vite/dev-server.js.map +1 -1
- package/dist/vite/pagefind.d.ts +4 -0
- package/dist/vite/pagefind.js +15 -0
- package/dist/vite/pagefind.js.map +1 -0
- package/dist/vite/plugin-component.js +4 -0
- package/dist/vite/plugin-component.js.map +1 -1
- package/dist/vite/plugin-search.js +4 -0
- package/dist/vite/plugin-search.js.map +1 -1
- package/dist/vite/prerender/prerender.js +1 -1
- package/dist/vite/prerender/prerender.js.map +1 -1
- package/dist/vite/sitemap.js +2 -1
- package/dist/vite/sitemap.js.map +1 -1
- package/lib/{AuthenticationPlugin-CiO1FM6Q.js → AuthenticationPlugin-4ip08maU.js} +3 -3
- package/lib/{AuthenticationPlugin-CiO1FM6Q.js.map → AuthenticationPlugin-4ip08maU.js.map} +1 -1
- package/lib/Callout-B_sEhkYd.js +211 -0
- package/lib/Callout-B_sEhkYd.js.map +1 -0
- package/lib/{Dialog-DIKGQxQc.js → Dialog-sbgekbjb.js} +47 -32
- package/lib/{Dialog-DIKGQxQc.js.map → Dialog-sbgekbjb.js.map} +1 -1
- package/lib/{Markdown-DePfm7oQ.js → Markdown-DZXjQjpH.js} +4099 -3848
- package/lib/Markdown-DZXjQjpH.js.map +1 -0
- package/lib/MdxPage-52vRwa_7.js +200 -0
- package/lib/MdxPage-52vRwa_7.js.map +1 -0
- package/lib/{OasProvider-SzD9mHJc.js → OasProvider-CR2nG1Eg.js} +4 -4
- package/lib/{OasProvider-SzD9mHJc.js.map → OasProvider-CR2nG1Eg.js.map} +1 -1
- package/lib/{OperationList-DDs9NblY.js → OperationList-DndcCJUG.js} +2069 -1983
- package/lib/OperationList-DndcCJUG.js.map +1 -0
- package/lib/{Select-Dqtcn53H.js → Select-FAYHOYTy.js} +4 -4
- package/lib/{Select-Dqtcn53H.js.map → Select-FAYHOYTy.js.map} +1 -1
- package/lib/{SlotletProvider-DdtIOUi6.js → SlotletProvider-TydSHROc.js} +4 -4
- package/lib/{SlotletProvider-DdtIOUi6.js.map → SlotletProvider-TydSHROc.js.map} +1 -1
- package/lib/{chunk-IR6S3I6Y-D_3UmFIn.js → chunk-HA7DTUK3-ZGg2W6yV.js} +277 -277
- package/lib/chunk-HA7DTUK3-ZGg2W6yV.js.map +1 -0
- package/lib/hook-CfCFKZ-2.js +350 -0
- package/lib/hook-CfCFKZ-2.js.map +1 -0
- package/lib/index-DK7IuUyR.js +2201 -0
- package/lib/index-DK7IuUyR.js.map +1 -0
- package/lib/{index.esm-CQHE3GEU.js → index.esm-CltAN0Tf.js} +259 -239
- package/lib/index.esm-CltAN0Tf.js.map +1 -0
- package/lib/{mutation-EclmI0is.js → mutation-B81DztCT.js} +2 -2
- package/lib/{mutation-EclmI0is.js.map → mutation-B81DztCT.js.map} +1 -1
- package/lib/objectEntries-BS7aAgOm.js +12 -0
- package/lib/objectEntries-BS7aAgOm.js.map +1 -0
- package/lib/ui/Checkbox.js +15 -25
- package/lib/ui/Checkbox.js.map +1 -1
- package/lib/ui/Command.js +96 -70
- package/lib/ui/Command.js.map +1 -1
- package/lib/ui/Select.js +1 -1
- package/lib/ui/Select.js.map +1 -1
- package/lib/ui/SyntaxHighlight.js +483 -502
- package/lib/ui/SyntaxHighlight.js.map +1 -1
- package/lib/{useExposedProps-RIvey2Oy.js → useExposedProps-BslIn-FE.js} +2 -2
- package/lib/{useExposedProps-RIvey2Oy.js.map → useExposedProps-BslIn-FE.js.map} +1 -1
- package/lib/useQuery-CQUwWR9i.js +1137 -0
- package/lib/useQuery-CQUwWR9i.js.map +1 -0
- package/lib/zudoku.auth-auth0.js +1 -1
- package/lib/zudoku.auth-clerk.js +29 -29
- package/lib/zudoku.auth-clerk.js.map +1 -1
- package/lib/zudoku.auth-openid.js +3 -3
- package/lib/zudoku.components.js +146 -149
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.hooks.js +1 -1
- package/lib/zudoku.plugin-api-catalog.js +87 -71
- package/lib/zudoku.plugin-api-catalog.js.map +1 -1
- package/lib/zudoku.plugin-api-keys.js +16 -15
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-custom-pages.js +2 -2
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +3 -3
- package/lib/zudoku.plugin-redirect.js +1 -1
- package/lib/zudoku.plugin-search-pagefind.js +204 -0
- package/lib/zudoku.plugin-search-pagefind.js.map +1 -0
- package/package.json +10 -5
- package/src/lib/authentication/hook.ts +12 -1
- package/src/lib/authentication/providers/clerk.tsx +10 -6
- package/src/lib/components/AnchorLink.tsx +7 -7
- package/src/lib/components/Banner.tsx +1 -0
- package/src/lib/components/Heading.tsx +1 -1
- package/src/lib/components/Layout.tsx +1 -0
- package/src/lib/components/navigation/SidebarItem.tsx +8 -23
- package/src/lib/core/RouteGuard.tsx +2 -1
- package/src/lib/core/ZudokuContext.ts +4 -0
- package/src/lib/plugins/api-catalog/Catalog.tsx +23 -7
- package/src/lib/plugins/api-catalog/index.tsx +1 -0
- package/src/lib/plugins/markdown/MdxPage.tsx +5 -1
- package/src/lib/plugins/openapi/OperationList.tsx +83 -31
- package/src/lib/plugins/openapi/OperationListItem.tsx +107 -86
- package/src/lib/plugins/openapi/ParameterList.tsx +4 -0
- package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +7 -0
- package/src/lib/plugins/openapi/Sidecar.tsx +1 -0
- package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
- package/src/lib/plugins/openapi/graphql/graphql.ts +3 -0
- package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +30 -32
- package/src/lib/plugins/openapi/playground/Headers.tsx +0 -1
- package/src/lib/plugins/openapi/playground/IdentityDialog.tsx +74 -0
- package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +54 -0
- package/src/lib/plugins/openapi/playground/PathParams.tsx +8 -2
- package/src/lib/plugins/openapi/playground/Playground.tsx +175 -88
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +0 -1
- package/src/lib/plugins/openapi/playground/RequestLoginDialog.tsx +51 -0
- package/src/lib/plugins/openapi/playground/rememberedIdentity.ts +26 -0
- package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +24 -4
- package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +66 -45
- package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +135 -0
- package/src/lib/plugins/search-pagefind/ResultList.tsx +104 -0
- package/src/lib/plugins/search-pagefind/get-results.tsx +54 -0
- package/src/lib/plugins/search-pagefind/index.tsx +21 -0
- package/src/lib/plugins/search-pagefind/types.ts +118 -0
- package/src/lib/ui/Checkbox.tsx +8 -24
- package/src/lib/ui/Command.tsx +25 -3
- package/src/lib/ui/Select.tsx +1 -1
- package/src/lib/ui/SyntaxHighlight.tsx +94 -96
- package/src/lib/util/MdxComponents.tsx +2 -2
- package/src/lib/util/useScrollToAnchor.ts +8 -8
- package/lib/Markdown-DePfm7oQ.js.map +0 -1
- package/lib/MdxPage-DZTt9ld7.js +0 -193
- package/lib/MdxPage-DZTt9ld7.js.map +0 -1
- package/lib/OperationList-DDs9NblY.js.map +0 -1
- package/lib/chunk-IR6S3I6Y-D_3UmFIn.js.map +0 -1
- package/lib/hook-CN__aZIt.js +0 -1464
- package/lib/hook-CN__aZIt.js.map +0 -1
- package/lib/index-CibzSNks.js +0 -2100
- package/lib/index-CibzSNks.js.map +0 -1
- package/lib/index.esm-CQHE3GEU.js.map +0 -1
- package/lib/objectEntries-yMIkr2mI.js +0 -5
- package/lib/objectEntries-yMIkr2mI.js.map +0 -1
- package/lib/useScrollToAnchor-C7ilRSts.js +0 -290
- package/lib/useScrollToAnchor-C7ilRSts.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query";
|
|
2
2
|
import { ChevronRightIcon } from "lucide-react";
|
|
3
3
|
import { Fragment, useState } from "react";
|
|
4
|
+
import { Callout } from "zudoku/ui/Callout.js";
|
|
4
5
|
import {
|
|
5
6
|
Collapsible,
|
|
6
7
|
CollapsibleContent,
|
|
@@ -30,6 +31,14 @@ const statusCodeMap: Record<number, string> = {
|
|
|
30
31
|
500: "Internal Server Error",
|
|
31
32
|
};
|
|
32
33
|
|
|
34
|
+
const humanFileSize = (bytes: number) => {
|
|
35
|
+
const exponent = Math.floor(Math.log(bytes) / Math.log(1000.0));
|
|
36
|
+
const decimal = (bytes / Math.pow(1000.0, exponent)).toFixed(
|
|
37
|
+
exponent ? 2 : 0,
|
|
38
|
+
);
|
|
39
|
+
return `${decimal} ${exponent ? `${"kMGTPEZY"[exponent - 1]}B` : "B"}`;
|
|
40
|
+
};
|
|
41
|
+
|
|
33
42
|
const mimeTypeToLanguage = (mimeType: string) => {
|
|
34
43
|
const mimeTypeMapping = {
|
|
35
44
|
"application/json": "json",
|
|
@@ -83,6 +92,8 @@ const sortHeadersByRelevance = (
|
|
|
83
92
|
});
|
|
84
93
|
};
|
|
85
94
|
|
|
95
|
+
const SYNTAX_HIGHLIGHT_MAX_SIZE_THRESHOLD = 64_000;
|
|
96
|
+
|
|
86
97
|
export const ResponseTab = ({
|
|
87
98
|
body = "",
|
|
88
99
|
headers,
|
|
@@ -114,9 +125,10 @@ export const ResponseTab = ({
|
|
|
114
125
|
});
|
|
115
126
|
|
|
116
127
|
const sortedHeaders = sortHeadersByRelevance([...headers]);
|
|
128
|
+
const shouldDisableHighlighting = size > SYNTAX_HIGHLIGHT_MAX_SIZE_THRESHOLD;
|
|
117
129
|
|
|
118
130
|
return (
|
|
119
|
-
<div className="flex flex-col gap-2 h-full overflow-
|
|
131
|
+
<div className="flex flex-col gap-2 h-full overflow-auto max-h-[calc(100vh-220px)] ">
|
|
120
132
|
<Collapsible defaultOpen>
|
|
121
133
|
<CollapsibleTrigger className="flex items-center gap-2 hover:text-primary group">
|
|
122
134
|
<ChevronRightIcon className="h-4 w-4 transition-transform duration-200 group-data-[state=open]:rotate-[90deg]" />
|
|
@@ -151,6 +163,12 @@ export const ResponseTab = ({
|
|
|
151
163
|
</Collapsible>
|
|
152
164
|
|
|
153
165
|
<Card className="shadow-none">
|
|
166
|
+
{shouldDisableHighlighting && (
|
|
167
|
+
<Callout type="info" className="my-0 p-2">
|
|
168
|
+
Code highlight is disabled for responses larger than{" "}
|
|
169
|
+
{humanFileSize(SYNTAX_HIGHLIGHT_MAX_SIZE_THRESHOLD)}
|
|
170
|
+
</Callout>
|
|
171
|
+
)}
|
|
154
172
|
<SyntaxHighlight
|
|
155
173
|
language={
|
|
156
174
|
view === "types"
|
|
@@ -161,8 +179,9 @@ export const ResponseTab = ({
|
|
|
161
179
|
: detectedLanguage
|
|
162
180
|
: "json"
|
|
163
181
|
}
|
|
182
|
+
showCopy="always"
|
|
183
|
+
disabled={shouldDisableHighlighting}
|
|
164
184
|
noBackground
|
|
165
|
-
// playground dialog has h-5/6 ≈ 83.333vh
|
|
166
185
|
className="overflow-x-auto p-4 text-xs max-h-[calc(83.333vh-180px)]"
|
|
167
186
|
code={
|
|
168
187
|
(view === "raw"
|
|
@@ -173,7 +192,7 @@ export const ResponseTab = ({
|
|
|
173
192
|
}
|
|
174
193
|
/>
|
|
175
194
|
</Card>
|
|
176
|
-
<div className="flex gap-2 justify-between">
|
|
195
|
+
<div className="flex gap-2 justify-between items-center">
|
|
177
196
|
<div className="flex text-xs gap-2 border bg-muted rounded-md p-2 items-center h-8 font-mono divide-x">
|
|
178
197
|
<div>
|
|
179
198
|
<span className="text-muted-foreground">Status</span> {status}{" "}
|
|
@@ -184,7 +203,8 @@ export const ResponseTab = ({
|
|
|
184
203
|
{time.toFixed(0)}ms
|
|
185
204
|
</div>
|
|
186
205
|
<div>
|
|
187
|
-
<span className="text-muted-foreground">Size</span>
|
|
206
|
+
<span className="text-muted-foreground">Size</span>{" "}
|
|
207
|
+
{humanFileSize(size)}
|
|
188
208
|
</div>
|
|
189
209
|
</div>
|
|
190
210
|
{jsonContent && (
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { UseMutationResult } from "@tanstack/react-query";
|
|
1
|
+
import { type UseMutationResult } from "@tanstack/react-query";
|
|
2
2
|
import { Spinner } from "../../../../components/Spinner.js";
|
|
3
|
+
import { Button } from "../../../../ui/Button.js";
|
|
3
4
|
import { Callout } from "../../../../ui/Callout.js";
|
|
4
5
|
import {
|
|
5
6
|
Card,
|
|
@@ -14,20 +15,24 @@ import {
|
|
|
14
15
|
TabsTrigger,
|
|
15
16
|
} from "../../../../ui/Tabs.js";
|
|
16
17
|
import { cn } from "../../../../util/cn.js";
|
|
17
|
-
import { PlaygroundResult } from "../Playground.js";
|
|
18
|
+
import { type PlaygroundResult } from "../Playground.js";
|
|
18
19
|
import { RequestTab } from "./RequestTab.js";
|
|
19
20
|
import { ResponseTab } from "./ResponseTab.js";
|
|
20
21
|
|
|
21
22
|
export const ResultPanel = ({
|
|
22
23
|
queryMutation,
|
|
23
24
|
showPathParamsWarning,
|
|
25
|
+
showLongRunningWarning,
|
|
26
|
+
onCancel,
|
|
24
27
|
}: {
|
|
25
|
-
queryMutation: UseMutationResult<PlaygroundResult, Error, any
|
|
28
|
+
queryMutation: UseMutationResult<PlaygroundResult, Error, any>;
|
|
26
29
|
showPathParamsWarning: boolean;
|
|
30
|
+
showLongRunningWarning?: boolean;
|
|
31
|
+
onCancel?: () => void;
|
|
27
32
|
}) => {
|
|
28
33
|
const status = ((queryMutation.data?.status ?? 0) / 100).toFixed(0);
|
|
29
34
|
return (
|
|
30
|
-
<div className="min-w-0 p-
|
|
35
|
+
<div className="min-w-0 p-4 bg-muted/50">
|
|
31
36
|
{queryMutation.error ? (
|
|
32
37
|
<div className="flex flex-col gap-2">
|
|
33
38
|
{showPathParamsWarning && (
|
|
@@ -49,49 +54,65 @@ export const ResultPanel = ({
|
|
|
49
54
|
</Card>
|
|
50
55
|
</div>
|
|
51
56
|
) : queryMutation.data ? (
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
</Tabs>
|
|
85
|
-
</div>
|
|
57
|
+
<Tabs defaultValue="response">
|
|
58
|
+
<TabsList>
|
|
59
|
+
<TabsTrigger value="request">Request</TabsTrigger>
|
|
60
|
+
<TabsTrigger value="response">
|
|
61
|
+
Response
|
|
62
|
+
<span
|
|
63
|
+
className={cn(
|
|
64
|
+
"text-xs font-mono ml-1",
|
|
65
|
+
status === "2" && "text-green-500",
|
|
66
|
+
status === "3" && "text-blue-500",
|
|
67
|
+
status === "4" && "text-yellow-500",
|
|
68
|
+
status === "5" && "text-red-500",
|
|
69
|
+
)}
|
|
70
|
+
>
|
|
71
|
+
({queryMutation.data.status})
|
|
72
|
+
</span>
|
|
73
|
+
</TabsTrigger>
|
|
74
|
+
</TabsList>
|
|
75
|
+
<TabsContent value="request">
|
|
76
|
+
<RequestTab {...queryMutation.data.request} />
|
|
77
|
+
</TabsContent>
|
|
78
|
+
<TabsContent value="response">
|
|
79
|
+
<ResponseTab
|
|
80
|
+
status={queryMutation.data.status}
|
|
81
|
+
time={queryMutation.data.time}
|
|
82
|
+
size={queryMutation.data.size}
|
|
83
|
+
headers={queryMutation.data.headers}
|
|
84
|
+
body={queryMutation.data.body}
|
|
85
|
+
url={queryMutation.data.request.url}
|
|
86
|
+
/>
|
|
87
|
+
</TabsContent>
|
|
88
|
+
</Tabs>
|
|
86
89
|
) : (
|
|
87
90
|
<div className="grid place-items-center h-full">
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<Spinner />
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
{queryMutation.isPending ? (
|
|
92
|
+
<div className="flex flex-col gap-2 items-center mt-20">
|
|
93
|
+
<Spinner size={20} />
|
|
94
|
+
<div
|
|
95
|
+
className={cn(
|
|
96
|
+
"opacity-0 pointer-events-none transition-opacity h-20 text-sm text-muted-foreground duration-300 flex flex-col gap-2 items-center",
|
|
97
|
+
showLongRunningWarning && "opacity-100 pointer-events-auto",
|
|
98
|
+
)}
|
|
99
|
+
>
|
|
100
|
+
Looks like the request is taking longer than expected.
|
|
101
|
+
<Button
|
|
102
|
+
onClick={onCancel}
|
|
103
|
+
size="sm"
|
|
104
|
+
className="w-fit"
|
|
105
|
+
variant="outline"
|
|
106
|
+
>
|
|
107
|
+
Cancel
|
|
108
|
+
</Button>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
) : (
|
|
112
|
+
<span className="text-[16px] font-semibold text-muted-foreground">
|
|
113
|
+
Send a request first to see the response here
|
|
114
|
+
</span>
|
|
115
|
+
)}
|
|
95
116
|
</div>
|
|
96
117
|
)}
|
|
97
118
|
</div>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
|
|
2
|
+
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Callout } from "zudoku/ui/Callout.js";
|
|
5
|
+
import {
|
|
6
|
+
CommandDialog,
|
|
7
|
+
CommandEmpty,
|
|
8
|
+
CommandInput,
|
|
9
|
+
} from "zudoku/ui/Command.js";
|
|
10
|
+
import { DialogTitle } from "zudoku/ui/Dialog.js";
|
|
11
|
+
import { joinUrl } from "../../util/joinUrl.js";
|
|
12
|
+
import { getResults } from "./get-results.js";
|
|
13
|
+
import type { PagefindOptions } from "./index.js";
|
|
14
|
+
import { ResultList } from "./ResultList.js";
|
|
15
|
+
import type { Pagefind } from "./types.js";
|
|
16
|
+
|
|
17
|
+
const DEFAULT_RANKING = {
|
|
18
|
+
// Slightly lower than default because API docs tend to have repetitive terms (parameter names, HTTP methods, etc.)
|
|
19
|
+
termFrequency: 0.8,
|
|
20
|
+
// Lower than default because API documentation pages tend to be longer due to comprehensive endpoint documentation
|
|
21
|
+
pageLength: 0.6,
|
|
22
|
+
// Slightly higher than default because in technical documentation, exact matches should be prioritized
|
|
23
|
+
termSimilarity: 1.2,
|
|
24
|
+
// Slightly lower than default because API docs might have legitimate repetition of terms
|
|
25
|
+
termSaturation: 1.2,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const importPagefind = (basePath?: string): Promise<Pagefind> =>
|
|
29
|
+
import.meta.env.DEV
|
|
30
|
+
? // @ts-expect-error TypeScript can't resolve the import
|
|
31
|
+
import(/* @vite-ignore */ "/pagefind/pagefind.js")
|
|
32
|
+
: import(/* @vite-ignore */ joinUrl(basePath, "/pagefind/pagefind.js"));
|
|
33
|
+
|
|
34
|
+
const usePagefind = (options: PagefindOptions) => {
|
|
35
|
+
const { data: pagefind, ...result } = useQuery<Pagefind>({
|
|
36
|
+
queryKey: ["pagefind", options.ranking],
|
|
37
|
+
retry: false,
|
|
38
|
+
queryFn: async () => {
|
|
39
|
+
const pagefind = await importPagefind(options.basePath);
|
|
40
|
+
await pagefind.init();
|
|
41
|
+
await pagefind.options({
|
|
42
|
+
ranking: {
|
|
43
|
+
termFrequency:
|
|
44
|
+
options.ranking?.termFrequency ?? DEFAULT_RANKING.termFrequency,
|
|
45
|
+
pageLength: options.ranking?.pageLength ?? DEFAULT_RANKING.pageLength,
|
|
46
|
+
termSimilarity:
|
|
47
|
+
options.ranking?.termSimilarity ?? DEFAULT_RANKING.termSimilarity,
|
|
48
|
+
termSaturation:
|
|
49
|
+
options.ranking?.termSaturation ?? DEFAULT_RANKING.termSaturation,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return pagefind;
|
|
54
|
+
},
|
|
55
|
+
enabled: typeof window !== "undefined",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (result.isError) {
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.error(result.error);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { ...result, pagefind };
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const PagefindSearch = ({
|
|
67
|
+
isOpen,
|
|
68
|
+
onClose,
|
|
69
|
+
options,
|
|
70
|
+
}: {
|
|
71
|
+
isOpen: boolean;
|
|
72
|
+
onClose: () => void;
|
|
73
|
+
options: PagefindOptions;
|
|
74
|
+
}) => {
|
|
75
|
+
const { pagefind, error, isError } = usePagefind(options);
|
|
76
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
77
|
+
|
|
78
|
+
const { data: searchResults } = useQuery({
|
|
79
|
+
queryKey: ["pagefind-search", searchTerm],
|
|
80
|
+
queryFn: async () => {
|
|
81
|
+
const search = await pagefind?.search(searchTerm);
|
|
82
|
+
if (!search) return [];
|
|
83
|
+
return getResults(search, options);
|
|
84
|
+
},
|
|
85
|
+
placeholderData: keepPreviousData,
|
|
86
|
+
enabled: !!pagefind && !!searchTerm,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<CommandDialog
|
|
91
|
+
command={{ shouldFilter: false }}
|
|
92
|
+
content={{ className: "max-w-[750px]" }}
|
|
93
|
+
open={isOpen}
|
|
94
|
+
onOpenChange={onClose}
|
|
95
|
+
>
|
|
96
|
+
<VisuallyHidden>
|
|
97
|
+
<DialogTitle>Search</DialogTitle>
|
|
98
|
+
</VisuallyHidden>
|
|
99
|
+
<CommandInput
|
|
100
|
+
placeholder="Search..."
|
|
101
|
+
value={searchTerm}
|
|
102
|
+
onValueChange={setSearchTerm}
|
|
103
|
+
disabled={isError}
|
|
104
|
+
/>
|
|
105
|
+
<CommandEmpty>
|
|
106
|
+
{searchTerm ? "No results found." : "Start typing to search"}
|
|
107
|
+
</CommandEmpty>
|
|
108
|
+
{isError ? (
|
|
109
|
+
<div className="p-4 text-sm">
|
|
110
|
+
{error.message === "NOT_BUILT_YET" ? (
|
|
111
|
+
<Callout type="info">
|
|
112
|
+
Search is currently not available in development mode by default.
|
|
113
|
+
<br />
|
|
114
|
+
To still use search in development, run <code>
|
|
115
|
+
zudoku build
|
|
116
|
+
</code>{" "}
|
|
117
|
+
and copy the <code>dist/pagefind</code> directory to your{" "}
|
|
118
|
+
<code>public</code> directory.
|
|
119
|
+
</Callout>
|
|
120
|
+
) : (
|
|
121
|
+
"An error occurred while loading search."
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
) : (
|
|
125
|
+
<ResultList
|
|
126
|
+
basePath={options.basePath}
|
|
127
|
+
searchResults={searchResults ?? []}
|
|
128
|
+
searchTerm={searchTerm}
|
|
129
|
+
onClose={onClose}
|
|
130
|
+
maxSubResults={options.maxSubResults}
|
|
131
|
+
/>
|
|
132
|
+
)}
|
|
133
|
+
</CommandDialog>
|
|
134
|
+
);
|
|
135
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { FileTextIcon } from "lucide-react";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { Link, useNavigate } from "react-router";
|
|
4
|
+
import { CommandGroup, CommandItem, CommandList } from "zudoku/ui/Command.js";
|
|
5
|
+
import {
|
|
6
|
+
type PagefindSearchFragment,
|
|
7
|
+
type PagefindSubResult,
|
|
8
|
+
} from "./types.js";
|
|
9
|
+
|
|
10
|
+
const sortSubResults = (a: PagefindSubResult, b: PagefindSubResult) => {
|
|
11
|
+
const aScore = a.weighted_locations.reduce(
|
|
12
|
+
(sum, loc) => sum + loc.balanced_score,
|
|
13
|
+
0,
|
|
14
|
+
);
|
|
15
|
+
const bScore = b.weighted_locations.reduce(
|
|
16
|
+
(sum, loc) => sum + loc.balanced_score,
|
|
17
|
+
0,
|
|
18
|
+
);
|
|
19
|
+
return bScore - aScore;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const hoverClassname = `cursor-pointer border border-transparent data-[selected=true]:border-border`;
|
|
23
|
+
|
|
24
|
+
export const ResultList = ({
|
|
25
|
+
basePath,
|
|
26
|
+
searchResults,
|
|
27
|
+
searchTerm,
|
|
28
|
+
onClose,
|
|
29
|
+
maxSubResults = 4,
|
|
30
|
+
}: {
|
|
31
|
+
basePath?: string;
|
|
32
|
+
searchResults: PagefindSearchFragment[];
|
|
33
|
+
searchTerm: string;
|
|
34
|
+
onClose: () => void;
|
|
35
|
+
maxSubResults?: number;
|
|
36
|
+
}) => {
|
|
37
|
+
const navigate = useNavigate();
|
|
38
|
+
|
|
39
|
+
const cleanResultUrl = useCallback(
|
|
40
|
+
(url: string) => {
|
|
41
|
+
const clean = url.replace(".html", "");
|
|
42
|
+
return basePath && clean.startsWith(basePath)
|
|
43
|
+
? clean.slice(basePath.length)
|
|
44
|
+
: clean;
|
|
45
|
+
},
|
|
46
|
+
[basePath],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<CommandList className="max-h-[450px]">
|
|
51
|
+
{searchTerm && searchResults.length > 0 && (
|
|
52
|
+
<CommandGroup
|
|
53
|
+
className="text-sm text-muted-foreground"
|
|
54
|
+
heading={`${searchResults.length} results for "${searchTerm}"`}
|
|
55
|
+
/>
|
|
56
|
+
)}
|
|
57
|
+
{searchResults.map((result) => (
|
|
58
|
+
<CommandGroup
|
|
59
|
+
key={[result.meta.title ?? result.excerpt, result.url].join("-")}
|
|
60
|
+
>
|
|
61
|
+
<CommandItem
|
|
62
|
+
asChild
|
|
63
|
+
value={`${result.meta.title}-${result.url}`}
|
|
64
|
+
className={hoverClassname}
|
|
65
|
+
onSelect={() => {
|
|
66
|
+
void navigate(cleanResultUrl(result.url));
|
|
67
|
+
onClose();
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<Link to={cleanResultUrl(result.url)}>
|
|
71
|
+
<FileTextIcon size={20} className="text-muted-foreground" />
|
|
72
|
+
{result.meta.title}
|
|
73
|
+
</Link>
|
|
74
|
+
</CommandItem>
|
|
75
|
+
{result.sub_results
|
|
76
|
+
.sort(sortSubResults)
|
|
77
|
+
.slice(0, maxSubResults)
|
|
78
|
+
.map((subResult) => (
|
|
79
|
+
<CommandItem
|
|
80
|
+
asChild
|
|
81
|
+
key={`${result.meta.title}-${subResult.url}`}
|
|
82
|
+
value={`${result.meta.title}-${subResult.url}`}
|
|
83
|
+
className={hoverClassname}
|
|
84
|
+
onSelect={() => {
|
|
85
|
+
void navigate(cleanResultUrl(subResult.url));
|
|
86
|
+
onClose();
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<Link to={cleanResultUrl(subResult.url)} onClick={onClose}>
|
|
90
|
+
<div className="flex flex-col items-start gap-2 ms-2.5 ps-5 border-l border-muted-foreground/50">
|
|
91
|
+
<span className="font-bold">{subResult.title}</span>
|
|
92
|
+
<span
|
|
93
|
+
className="text-[13px] [&_mark]:bg-primary [&_mark]:text-primary-foreground"
|
|
94
|
+
dangerouslySetInnerHTML={{ __html: subResult.excerpt }}
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
</Link>
|
|
98
|
+
</CommandItem>
|
|
99
|
+
))}
|
|
100
|
+
</CommandGroup>
|
|
101
|
+
))}
|
|
102
|
+
</CommandList>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { PagefindOptions } from "./index.js";
|
|
2
|
+
import type { PagefindSearchFragment, PagefindSearchResults } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export const getResults = async (
|
|
5
|
+
search: PagefindSearchResults,
|
|
6
|
+
options: PagefindOptions,
|
|
7
|
+
) => {
|
|
8
|
+
const maxResults = options.maxResults ?? 10;
|
|
9
|
+
const transformFn = options.transformResults ?? (() => true);
|
|
10
|
+
|
|
11
|
+
const transformedResults: PagefindSearchFragment[] = [];
|
|
12
|
+
|
|
13
|
+
const generator = searchResultGenerator(search, transformFn);
|
|
14
|
+
|
|
15
|
+
for await (const result of generator) {
|
|
16
|
+
transformedResults.push(result);
|
|
17
|
+
if (transformedResults.length >= maxResults) break;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return transformedResults;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
async function* searchResultGenerator(
|
|
24
|
+
search: PagefindSearchResults,
|
|
25
|
+
transformFn: NonNullable<PagefindOptions["transformResults"]>,
|
|
26
|
+
) {
|
|
27
|
+
const batchSize = 5;
|
|
28
|
+
let processedCount = 0;
|
|
29
|
+
|
|
30
|
+
while (processedCount < search.results.length) {
|
|
31
|
+
const batch = search.results.slice(
|
|
32
|
+
processedCount,
|
|
33
|
+
processedCount + batchSize,
|
|
34
|
+
);
|
|
35
|
+
processedCount += batch.length;
|
|
36
|
+
|
|
37
|
+
const batchData = await Promise.all(batch.map((result) => result.data()));
|
|
38
|
+
|
|
39
|
+
for (const result of batchData) {
|
|
40
|
+
const transformed = transformFn(result);
|
|
41
|
+
|
|
42
|
+
if (transformed === false) {
|
|
43
|
+
// Skip this result
|
|
44
|
+
continue;
|
|
45
|
+
} else if (transformed === true || transformed == null) {
|
|
46
|
+
// Keep the original result
|
|
47
|
+
yield result;
|
|
48
|
+
} else {
|
|
49
|
+
// Return the transformed result
|
|
50
|
+
yield transformed;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ZudokuConfig } from "../../../config/validators/validate.js";
|
|
2
|
+
import { ClientOnly } from "../../components/ClientOnly.js";
|
|
3
|
+
import type { ZudokuPlugin } from "../../core/plugins.js";
|
|
4
|
+
import { PagefindSearch } from "./PagefindSearch.js";
|
|
5
|
+
|
|
6
|
+
export type PagefindOptions = Extract<
|
|
7
|
+
ZudokuConfig["search"],
|
|
8
|
+
{ type: "pagefind" }
|
|
9
|
+
> & { basePath?: string };
|
|
10
|
+
|
|
11
|
+
export const pagefindSearchPlugin = (
|
|
12
|
+
options: PagefindOptions,
|
|
13
|
+
): ZudokuPlugin => {
|
|
14
|
+
return {
|
|
15
|
+
renderSearch: ({ isOpen, onClose }) => (
|
|
16
|
+
<ClientOnly>
|
|
17
|
+
<PagefindSearch isOpen={isOpen} onClose={onClose} options={options} />
|
|
18
|
+
</ClientOnly>
|
|
19
|
+
),
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
interface PagefindIndexOptions {
|
|
2
|
+
basePath?: string;
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
excerptLength?: number;
|
|
5
|
+
indexWeight?: number;
|
|
6
|
+
mergeFilter?: Record<string, unknown>;
|
|
7
|
+
highlightParam?: string;
|
|
8
|
+
language?: string;
|
|
9
|
+
primary?: boolean;
|
|
10
|
+
ranking?: PagefindRankingWeights;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface PagefindRankingWeights {
|
|
14
|
+
termSimilarity?: number;
|
|
15
|
+
pageLength?: number;
|
|
16
|
+
termSaturation?: number;
|
|
17
|
+
termFrequency?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface PagefindSearchOptions {
|
|
21
|
+
preload?: boolean;
|
|
22
|
+
verbose?: boolean;
|
|
23
|
+
filters?: Record<string, unknown>;
|
|
24
|
+
sort?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type PagefindFilterCounts = Record<string, Record<string, number>> & {};
|
|
28
|
+
|
|
29
|
+
interface PagefindSearchResults {
|
|
30
|
+
results: PagefindSearchResult[];
|
|
31
|
+
unfilteredResultCount: number;
|
|
32
|
+
filters: PagefindFilterCounts;
|
|
33
|
+
totalFilters: PagefindFilterCounts;
|
|
34
|
+
timings: {
|
|
35
|
+
preload: number;
|
|
36
|
+
search: number;
|
|
37
|
+
total: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface PagefindSearchResult {
|
|
42
|
+
id: string;
|
|
43
|
+
score: number;
|
|
44
|
+
words: number[];
|
|
45
|
+
data: () => Promise<PagefindSearchFragment>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface PagefindSearchFragment {
|
|
49
|
+
url: string;
|
|
50
|
+
raw_url?: string;
|
|
51
|
+
content: string;
|
|
52
|
+
raw_content?: string;
|
|
53
|
+
excerpt: string;
|
|
54
|
+
sub_results: PagefindSubResult[];
|
|
55
|
+
word_count: number;
|
|
56
|
+
locations: number[];
|
|
57
|
+
weighted_locations: PagefindWordLocation[];
|
|
58
|
+
filters: Record<string, string[]>;
|
|
59
|
+
meta: Record<string, string>;
|
|
60
|
+
anchors: PagefindSearchAnchor[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface PagefindSubResult {
|
|
64
|
+
title: string;
|
|
65
|
+
url: string;
|
|
66
|
+
locations: number[];
|
|
67
|
+
weighted_locations: PagefindWordLocation[];
|
|
68
|
+
excerpt: string;
|
|
69
|
+
anchor?: PagefindSearchAnchor;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface PagefindWordLocation {
|
|
73
|
+
weight: number;
|
|
74
|
+
balanced_score: number;
|
|
75
|
+
location: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface PagefindSearchAnchor {
|
|
79
|
+
element: string;
|
|
80
|
+
id: string;
|
|
81
|
+
text?: string;
|
|
82
|
+
location: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface Pagefind {
|
|
86
|
+
debouncedSearch: (
|
|
87
|
+
query: string,
|
|
88
|
+
options?: PagefindSearchOptions,
|
|
89
|
+
duration?: number,
|
|
90
|
+
) => Promise<PagefindSearchResults>;
|
|
91
|
+
destroy: () => Promise<void>;
|
|
92
|
+
filters: () => Promise<PagefindFilterCounts>;
|
|
93
|
+
init: () => Promise<void>;
|
|
94
|
+
mergeIndex: (
|
|
95
|
+
indexPath: string,
|
|
96
|
+
options?: Record<string, unknown>,
|
|
97
|
+
) => Promise<void>;
|
|
98
|
+
options: (options: PagefindIndexOptions) => Promise<void>;
|
|
99
|
+
preload: (term: string, options?: PagefindIndexOptions) => Promise<void>;
|
|
100
|
+
search: (
|
|
101
|
+
term: string,
|
|
102
|
+
options?: PagefindSearchOptions,
|
|
103
|
+
) => Promise<PagefindSearchResults>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type {
|
|
107
|
+
Pagefind,
|
|
108
|
+
PagefindFilterCounts,
|
|
109
|
+
PagefindIndexOptions,
|
|
110
|
+
PagefindRankingWeights,
|
|
111
|
+
PagefindSearchAnchor,
|
|
112
|
+
PagefindSearchFragment,
|
|
113
|
+
PagefindSearchOptions,
|
|
114
|
+
PagefindSearchResult,
|
|
115
|
+
PagefindSearchResults,
|
|
116
|
+
PagefindSubResult,
|
|
117
|
+
PagefindWordLocation,
|
|
118
|
+
};
|