zudoku 0.65.3 → 0.66.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/app/sentry.js +1 -1
- package/dist/config/validators/BuildSchema.js +18 -3
- package/dist/config/validators/BuildSchema.js.map +1 -1
- package/dist/config/validators/validate.d.ts +45 -3
- package/dist/config/validators/validate.js +7 -1
- package/dist/config/validators/validate.js.map +1 -1
- package/dist/flat-config.d.ts +9 -2
- package/dist/lib/components/Mermaid.d.ts +7 -0
- package/dist/lib/components/Mermaid.js +42 -0
- package/dist/lib/components/Mermaid.js.map +1 -0
- package/dist/lib/components/PagefindSearchMeta.d.ts +8 -0
- package/dist/lib/components/PagefindSearchMeta.js +7 -0
- package/dist/lib/components/PagefindSearchMeta.js.map +1 -0
- package/dist/lib/components/Zudoku.js +2 -5
- package/dist/lib/components/Zudoku.js.map +1 -1
- package/dist/lib/core/RouteGuard.js +1 -1
- package/dist/lib/core/RouteGuard.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +3 -3
- package/dist/lib/oas/parser/index.d.ts +1 -0
- package/dist/lib/oas/parser/index.js.map +1 -1
- package/dist/lib/plugins/openapi/DownloadSchemaButton.d.ts +3 -0
- package/dist/lib/plugins/openapi/DownloadSchemaButton.js +47 -0
- package/dist/lib/plugins/openapi/DownloadSchemaButton.js.map +1 -0
- package/dist/lib/plugins/openapi/Endpoint.js +3 -6
- package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
- package/dist/lib/plugins/openapi/OasProvider.js +22 -13
- package/dist/lib/plugins/openapi/OasProvider.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +12 -6
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +2 -2
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/SchemaList.js +2 -1
- package/dist/lib/plugins/openapi/SchemaList.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +11 -5
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/interfaces.d.ts +16 -13
- package/dist/lib/plugins/openapi/playground/Playground.js +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaView.js +14 -6
- package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/utils.d.ts +2 -2
- package/dist/lib/plugins/openapi/schema/utils.js.map +1 -1
- package/dist/lib/plugins/openapi/util/getRoutes.d.ts +6 -1
- package/dist/lib/plugins/openapi/util/getRoutes.js +29 -2
- package/dist/lib/plugins/openapi/util/getRoutes.js.map +1 -1
- package/dist/lib/plugins/search-pagefind/IndexingDialog.d.ts +3 -0
- package/dist/lib/plugins/search-pagefind/IndexingDialog.js +64 -0
- package/dist/lib/plugins/search-pagefind/IndexingDialog.js.map +1 -0
- package/dist/lib/plugins/search-pagefind/PagefindSearch.js +22 -5
- package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -1
- package/dist/lib/plugins/search-pagefind/ResultList.js +5 -4
- package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -1
- package/dist/lib/shiki.d.ts +1 -1
- package/dist/lib/shiki.js +18 -12
- package/dist/lib/shiki.js.map +1 -1
- package/dist/lib/ui/Button.d.ts +2 -2
- package/dist/lib/ui/Button.js +9 -8
- package/dist/lib/ui/Button.js.map +1 -1
- package/dist/lib/ui/ButtonGroup.d.ts +11 -0
- package/dist/lib/ui/ButtonGroup.js +28 -0
- package/dist/lib/ui/ButtonGroup.js.map +1 -0
- package/dist/lib/ui/Command.js +2 -2
- package/dist/lib/ui/Command.js.map +1 -1
- package/dist/lib/ui/DropdownMenu.d.ts +21 -23
- package/dist/lib/ui/DropdownMenu.js +47 -32
- package/dist/lib/ui/DropdownMenu.js.map +1 -1
- package/dist/lib/ui/Kbd.d.ts +3 -0
- package/dist/lib/ui/Kbd.js +10 -0
- package/dist/lib/ui/Kbd.js.map +1 -0
- package/dist/lib/util/MdxComponents.d.ts +1 -0
- package/dist/lib/util/MdxComponents.js +2 -0
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/flattenAllOf.js +27 -4
- package/dist/lib/util/flattenAllOf.js.map +1 -1
- package/dist/lib/util/flattenAllOf.test.js +67 -12
- package/dist/lib/util/flattenAllOf.test.js.map +1 -1
- package/dist/vite/api/SchemaManager.d.ts +5 -0
- package/dist/vite/api/SchemaManager.js +24 -0
- package/dist/vite/api/SchemaManager.js.map +1 -1
- package/dist/vite/api/SchemaManager.test.js +67 -0
- package/dist/vite/api/SchemaManager.test.js.map +1 -1
- package/dist/vite/config.js +8 -2
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/dev-server.js +25 -0
- package/dist/vite/dev-server.js.map +1 -1
- package/dist/vite/pagefind-dev-index.d.ts +16 -0
- package/dist/vite/pagefind-dev-index.js +68 -0
- package/dist/vite/pagefind-dev-index.js.map +1 -0
- package/dist/vite/plugin-api.js +41 -3
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/prerender/prerender.js +1 -19
- package/dist/vite/prerender/prerender.js.map +1 -1
- package/dist/vite/prerender/utils.d.ts +2 -0
- package/dist/vite/prerender/utils.js +24 -0
- package/dist/vite/prerender/utils.js.map +1 -0
- package/lib/Button-CynVW1JV.js +53 -0
- package/lib/Button-CynVW1JV.js.map +1 -0
- package/lib/ClaudeLogo-PxFjou9w.js +69 -0
- package/lib/ClaudeLogo-PxFjou9w.js.map +1 -0
- package/lib/{Command-CUcrW3qs.js → Command-BpT1iBE6.js} +25 -25
- package/lib/Command-BpT1iBE6.js.map +1 -0
- package/lib/Drawer-Ci7XwhqT.js.map +1 -1
- package/lib/DropdownMenu-C8SX_-S_.js +104 -0
- package/lib/DropdownMenu-C8SX_-S_.js.map +1 -0
- package/lib/{ErrorAlert-D5LKLFOd.js → ErrorAlert-BqjbNHIn.js} +1017 -1015
- package/lib/{ErrorAlert-D5LKLFOd.js.map → ErrorAlert-BqjbNHIn.js.map} +1 -1
- package/lib/IndexingDialog-B5zCiUKr.js +100 -0
- package/lib/IndexingDialog-B5zCiUKr.js.map +1 -0
- package/lib/MdxPage-CVFatbHw.js +210 -0
- package/lib/MdxPage-CVFatbHw.js.map +1 -0
- package/lib/Mermaid-CIFixY6C.js +102 -0
- package/lib/Mermaid-CIFixY6C.js.map +1 -0
- package/lib/{OAuthErrorPage-oXnxcJg4.js → OAuthErrorPage-Dup79DJk.js} +7 -7
- package/lib/{OAuthErrorPage-oXnxcJg4.js.map → OAuthErrorPage-Dup79DJk.js.map} +1 -1
- package/lib/OasProvider-BJeMq29o.js +40 -0
- package/lib/OasProvider-BJeMq29o.js.map +1 -0
- package/lib/{OperationList-CmMoKpGu.js → OperationList-ff3ZvQsO.js} +1701 -1585
- package/lib/OperationList-ff3ZvQsO.js.map +1 -0
- package/lib/{RouteGuard-Brz95MSt.js → RouteGuard-BXy13JSz.js} +19 -19
- package/lib/{RouteGuard-Brz95MSt.js.map → RouteGuard-BXy13JSz.js.map} +1 -1
- package/lib/{RouterError-VGZB_wg4.js → RouterError-CKOZTsDD.js} +3 -3
- package/lib/{RouterError-VGZB_wg4.js.map → RouterError-CKOZTsDD.js.map} +1 -1
- package/lib/{SchemaList-BykD27ga.js → SchemaList-BSC1KM3v.js} +28 -27
- package/lib/SchemaList-BSC1KM3v.js.map +1 -0
- package/lib/{SchemaView-Dt6hbCAt.js → SchemaView-CgwJ9gtb.js} +198 -187
- package/lib/SchemaView-CgwJ9gtb.js.map +1 -0
- package/lib/Select-VmDZ-nKe.js +337 -0
- package/lib/Select-VmDZ-nKe.js.map +1 -0
- package/lib/{SignUp-D2mmQOkg.js → SignUp-Pm_LGm6T.js} +13 -13
- package/lib/{SignUp-D2mmQOkg.js.map → SignUp-Pm_LGm6T.js.map} +1 -1
- package/lib/{SyntaxHighlight-C19vH0V_.js → SyntaxHighlight-bkmst3oV.js} +654 -622
- package/lib/SyntaxHighlight-bkmst3oV.js.map +1 -0
- package/lib/{Toc-CBWfFCVf.js → Toc-TUXNFbKl.js} +2 -2
- package/lib/{Toc-CBWfFCVf.js.map → Toc-TUXNFbKl.js.map} +1 -1
- package/lib/{ZudokuContext-BUZ5hkWB.js → ZudokuContext-np1wheDl.js} +8 -8
- package/lib/{ZudokuContext-BUZ5hkWB.js.map → ZudokuContext-np1wheDl.js.map} +1 -1
- package/lib/___vite-browser-external_commonjs-proxy-Cga3HsWk.js +9 -0
- package/lib/___vite-browser-external_commonjs-proxy-Cga3HsWk.js.map +1 -0
- package/lib/{chunk-PVWAREVJ-BMhpCH5D.js → chunk-PVWAREVJ-dLIqswPy.js} +5 -5
- package/lib/{chunk-PVWAREVJ-BMhpCH5D.js.map → chunk-PVWAREVJ-dLIqswPy.js.map} +1 -1
- package/lib/{circular-CNHs4gAz.js → circular-XPj_dwqA.js} +2 -2
- package/lib/{circular-CNHs4gAz.js.map → circular-XPj_dwqA.js.map} +1 -1
- package/lib/createServer-D01nCTNp.js +16693 -0
- package/lib/createServer-D01nCTNp.js.map +1 -0
- package/lib/{errors-D7xzOd8X.js → errors-B0hNTPFO.js} +3 -3
- package/lib/{errors-D7xzOd8X.js.map → errors-B0hNTPFO.js.map} +1 -1
- package/lib/{hook-CMeoxziF.js → hook-CvSwcbk6.js} +3 -3
- package/lib/{hook-CMeoxziF.js.map → hook-CvSwcbk6.js.map} +1 -1
- package/lib/{index-unv8c40u.js → index-Bjc_QsUR.js} +754 -738
- package/lib/{index-unv8c40u.js.map → index-Bjc_QsUR.js.map} +1 -1
- package/lib/index-CrcNWbel.js.map +1 -1
- package/lib/index-DnMgJWrI.js +133 -0
- package/lib/index-DnMgJWrI.js.map +1 -0
- package/lib/{index-CF7_erXq.js → index-DscsS121.js} +2 -2
- package/lib/{index-CF7_erXq.js.map → index-DscsS121.js.map} +1 -1
- package/lib/{index-CPws05Tb.js → index-mfkNWYG-.js} +10 -10
- package/lib/{index-CPws05Tb.js.map → index-mfkNWYG-.js.map} +1 -1
- package/lib/{index.esm-BnYHxCYC.js → index.esm-DtzT_KoE.js} +20 -20
- package/lib/{index.esm-BnYHxCYC.js.map → index.esm-DtzT_KoE.js.map} +1 -1
- package/lib/{invariant-Bm-FVUQE.js → invariant-CGOLuIIz.js} +3 -3
- package/lib/{invariant-Bm-FVUQE.js.map → invariant-CGOLuIIz.js.map} +1 -1
- package/lib/{mutation-BSU0xu4m.js → mutation-BlmnL5qL.js} +2 -2
- package/lib/{mutation-BSU0xu4m.js.map → mutation-BlmnL5qL.js.map} +1 -1
- package/lib/ui/ActionButton.js +1 -1
- package/lib/ui/Button.js +25 -24
- package/lib/ui/Button.js.map +1 -1
- package/lib/ui/ButtonGroup.js +77 -0
- package/lib/ui/ButtonGroup.js.map +1 -0
- package/lib/ui/Command.js +3 -3
- package/lib/ui/Command.js.map +1 -1
- package/lib/ui/DropdownMenu.js +227 -140
- package/lib/ui/DropdownMenu.js.map +1 -1
- package/lib/ui/Kbd.js +32 -0
- package/lib/ui/Kbd.js.map +1 -0
- package/lib/ui/SyntaxHighlight.js +3 -3
- package/lib/zudoku.__internal.js +8 -8
- package/lib/zudoku.auth-auth0.js +1 -1
- package/lib/zudoku.auth-azureb2c.js +4 -4
- package/lib/zudoku.auth-clerk.js +2 -2
- package/lib/zudoku.auth-openid.js +5 -5
- package/lib/zudoku.auth-supabase.js +5 -5
- package/lib/zudoku.components.js +7 -7
- package/lib/zudoku.hooks.js +11 -24
- package/lib/zudoku.hooks.js.map +1 -1
- package/lib/zudoku.mermaid.js +10 -0
- package/lib/zudoku.mermaid.js.map +1 -0
- package/lib/zudoku.plugin-api-catalog.js +6 -6
- package/lib/zudoku.plugin-api-keys.js +223 -198
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- 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 +184 -226
- package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
- package/lib/zudoku.plugins.js.map +1 -1
- package/lib/zudoku.router.js +2 -2
- package/package.json +29 -21
- package/src/app/sentry.ts +1 -1
- package/src/lib/components/Mermaid.tsx +68 -0
- package/src/lib/components/PagefindSearchMeta.tsx +14 -0
- package/src/lib/components/Zudoku.tsx +4 -7
- package/src/lib/core/RouteGuard.tsx +1 -1
- package/src/lib/core/plugins.ts +2 -2
- package/src/lib/oas/parser/index.ts +2 -0
- package/src/lib/plugins/openapi/DownloadSchemaButton.tsx +115 -0
- package/src/lib/plugins/openapi/Endpoint.tsx +20 -27
- package/src/lib/plugins/openapi/OasProvider.tsx +30 -17
- package/src/lib/plugins/openapi/OperationList.tsx +39 -21
- package/src/lib/plugins/openapi/OperationListItem.tsx +5 -5
- package/src/lib/plugins/openapi/SchemaList.tsx +4 -0
- package/src/lib/plugins/openapi/index.tsx +16 -7
- package/src/lib/plugins/openapi/interfaces.ts +16 -7
- package/src/lib/plugins/openapi/playground/Playground.tsx +1 -1
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +36 -27
- package/src/lib/plugins/openapi/schema/utils.ts +5 -2
- package/src/lib/plugins/openapi/util/getRoutes.tsx +35 -3
- package/src/lib/plugins/search-pagefind/IndexingDialog.tsx +163 -0
- package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +61 -22
- package/src/lib/plugins/search-pagefind/ResultList.tsx +8 -3
- package/src/lib/shiki.ts +21 -12
- package/src/lib/ui/Button.tsx +10 -10
- package/src/lib/ui/ButtonGroup.tsx +82 -0
- package/src/lib/ui/Command.tsx +3 -3
- package/src/lib/ui/DropdownMenu.tsx +226 -170
- package/src/lib/ui/Kbd.tsx +28 -0
- package/src/lib/util/MdxComponents.tsx +2 -0
- package/src/lib/util/flattenAllOf.test.ts +71 -19
- package/src/lib/util/flattenAllOf.ts +29 -8
- package/src/shiki/langs/markdown-nix.js +1 -0
- package/src/shiki/langs/openscad.js +1 -0
- package/dist/vite/create-pagefind-index.d.ts +0 -4
- package/dist/vite/create-pagefind-index.js +0 -12
- package/dist/vite/create-pagefind-index.js.map +0 -1
- package/lib/Button-B3ucvvQw.js +0 -52
- package/lib/Button-B3ucvvQw.js.map +0 -1
- package/lib/Command-CUcrW3qs.js.map +0 -1
- package/lib/DropdownMenu-BZ2NKQ3K.js +0 -126
- package/lib/DropdownMenu-BZ2NKQ3K.js.map +0 -1
- package/lib/MdxPage-hOCN-u-L.js +0 -240
- package/lib/MdxPage-hOCN-u-L.js.map +0 -1
- package/lib/OasProvider-CpniNNrW.js +0 -36
- package/lib/OasProvider-CpniNNrW.js.map +0 -1
- package/lib/OperationList-CmMoKpGu.js.map +0 -1
- package/lib/Pagination-lLSoHnxa.js +0 -37
- package/lib/Pagination-lLSoHnxa.js.map +0 -1
- package/lib/SchemaList-BykD27ga.js.map +0 -1
- package/lib/SchemaView-Dt6hbCAt.js.map +0 -1
- package/lib/Select-DFRCS31-.js +0 -399
- package/lib/Select-DFRCS31-.js.map +0 -1
- package/lib/SyntaxHighlight-C19vH0V_.js.map +0 -1
- package/lib/createServer-BmcVQAOQ.js +0 -13018
- package/lib/createServer-BmcVQAOQ.js.map +0 -1
- package/lib/useExposedProps-U3pmsHaG.js +0 -113
- package/lib/useExposedProps-U3pmsHaG.js.map +0 -1
|
@@ -18,9 +18,12 @@ import { CategoryHeading } from "../../components/CategoryHeading.js";
|
|
|
18
18
|
import { useApiIdentities } from "../../components/context/ZudokuContext.js";
|
|
19
19
|
import { Heading } from "../../components/Heading.js";
|
|
20
20
|
import { Markdown } from "../../components/Markdown.js";
|
|
21
|
+
import { PagefindSearchMeta } from "../../components/PagefindSearchMeta.js";
|
|
21
22
|
import { Pagination } from "../../components/Pagination.js";
|
|
23
|
+
import { joinUrl } from "../../util/joinUrl.js";
|
|
22
24
|
import { useCreateQuery } from "./client/useCreateQuery.js";
|
|
23
25
|
import { useOasConfig } from "./context.js";
|
|
26
|
+
import { DownloadSchemaButton } from "./DownloadSchemaButton.js";
|
|
24
27
|
import { Endpoint } from "./Endpoint.js";
|
|
25
28
|
import { graphql } from "./graphql/index.js";
|
|
26
29
|
import { UNTAGGED_PATH } from "./index.js";
|
|
@@ -155,7 +158,7 @@ export const OperationList = ({
|
|
|
155
158
|
tag?: string;
|
|
156
159
|
untagged?: boolean;
|
|
157
160
|
}) => {
|
|
158
|
-
const { input, type, versions, version, options } = useOasConfig();
|
|
161
|
+
const { path, input, type, versions, version, options } = useOasConfig();
|
|
159
162
|
const { tag: tagFromParams } = useParams<"tag">();
|
|
160
163
|
const query = useCreateQuery(OperationsForTagQuery, {
|
|
161
164
|
input,
|
|
@@ -244,12 +247,20 @@ export const OperationList = ({
|
|
|
244
247
|
const tagTitle = schema.tag.extensions?.["x-displayName"] ?? schema.tag.name;
|
|
245
248
|
const helmetTitle = [tagTitle, title].filter(Boolean).join(" - ");
|
|
246
249
|
|
|
250
|
+
const downloadUrl =
|
|
251
|
+
typeof input === "string"
|
|
252
|
+
? type === "url"
|
|
253
|
+
? input
|
|
254
|
+
: joinUrl(path, version, input.split("/").pop())
|
|
255
|
+
: undefined;
|
|
256
|
+
|
|
247
257
|
return (
|
|
248
258
|
<div
|
|
249
259
|
className="pt-(--padding-content-top)"
|
|
250
260
|
data-pagefind-filter="section:openapi"
|
|
251
261
|
data-pagefind-meta="section:openapi"
|
|
252
262
|
>
|
|
263
|
+
<PagefindSearchMeta name="category">{title}</PagefindSearchMeta>
|
|
253
264
|
<Helmet>
|
|
254
265
|
{helmetTitle && <title>{helmetTitle}</title>}
|
|
255
266
|
{metaDescription && (
|
|
@@ -262,7 +273,7 @@ export const OperationList = ({
|
|
|
262
273
|
className="w-full"
|
|
263
274
|
defaultOpen={options?.expandApiInformation}
|
|
264
275
|
>
|
|
265
|
-
<div className="flex flex-col gap-
|
|
276
|
+
<div className="flex flex-col gap-4 sm:flex-row justify-around items-start sm:items-end">
|
|
266
277
|
<div className="flex flex-col flex-1 gap-2">
|
|
267
278
|
<CategoryHeading>{title}</CategoryHeading>
|
|
268
279
|
<Heading
|
|
@@ -282,25 +293,32 @@ export const OperationList = ({
|
|
|
282
293
|
<Endpoint />
|
|
283
294
|
</div>
|
|
284
295
|
<div className="flex flex-col gap-4 sm:items-end">
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
296
|
+
<div className="flex gap-2 items-center">
|
|
297
|
+
{showVersions && (
|
|
298
|
+
<Select
|
|
299
|
+
onValueChange={(version) =>
|
|
300
|
+
// biome-ignore lint/style/noNonNullAssertion: is guaranteed to be defined
|
|
301
|
+
navigate(versions[version]!.path)
|
|
302
|
+
}
|
|
303
|
+
defaultValue={version}
|
|
304
|
+
disabled={!hasMultipleVersions}
|
|
305
|
+
>
|
|
306
|
+
<SelectTrigger className="w-[180px]" size="sm">
|
|
307
|
+
<SelectValue placeholder="Select version" />
|
|
308
|
+
</SelectTrigger>
|
|
309
|
+
<SelectContent>
|
|
310
|
+
{Object.entries(versions).map(([version, { label }]) => (
|
|
311
|
+
<SelectItem key={version} value={version}>
|
|
312
|
+
{label}
|
|
313
|
+
</SelectItem>
|
|
314
|
+
))}
|
|
315
|
+
</SelectContent>
|
|
316
|
+
</Select>
|
|
317
|
+
)}
|
|
318
|
+
{options?.schemaDownload?.enabled && downloadUrl && (
|
|
319
|
+
<DownloadSchemaButton downloadUrl={downloadUrl} />
|
|
320
|
+
)}
|
|
321
|
+
</div>
|
|
304
322
|
{schema.description && (
|
|
305
323
|
<CollapsibleTrigger className="flex items-center gap-1 text-sm font-medium text-muted-foreground group">
|
|
306
324
|
<span>API information</span>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
|
|
2
1
|
import { useState } from "react";
|
|
3
2
|
import { Badge } from "zudoku/ui/Badge.js";
|
|
4
3
|
import { Separator } from "zudoku/ui/Separator.js";
|
|
5
4
|
import { Heading } from "../../components/Heading.js";
|
|
6
5
|
import { Markdown } from "../../components/Markdown.js";
|
|
6
|
+
import { PagefindSearchMeta } from "../../components/PagefindSearchMeta.js";
|
|
7
7
|
import { cn } from "../../util/cn.js";
|
|
8
8
|
import { groupBy } from "../../util/groupBy.js";
|
|
9
9
|
import { renderIf } from "../../util/renderIf.js";
|
|
@@ -134,9 +134,9 @@ export const OperationListItem = ({
|
|
|
134
134
|
id={`${operation.slug}/request-body`}
|
|
135
135
|
>
|
|
136
136
|
{operation.summary && (
|
|
137
|
-
<
|
|
137
|
+
<PagefindSearchMeta>
|
|
138
138
|
{operation.summary} ›{" "}
|
|
139
|
-
</
|
|
139
|
+
</PagefindSearchMeta>
|
|
140
140
|
)}
|
|
141
141
|
Request Body{" "}
|
|
142
142
|
{operation.requestBody?.required === false ? (
|
|
@@ -154,9 +154,9 @@ export const OperationListItem = ({
|
|
|
154
154
|
<>
|
|
155
155
|
<Heading level={3} id={`${operation.slug}/responses`}>
|
|
156
156
|
{operation.summary && (
|
|
157
|
-
<
|
|
157
|
+
<PagefindSearchMeta>
|
|
158
158
|
{operation.summary} ›{" "}
|
|
159
|
-
</
|
|
159
|
+
</PagefindSearchMeta>
|
|
160
160
|
)}
|
|
161
161
|
Responses
|
|
162
162
|
</Heading>
|
|
@@ -16,6 +16,7 @@ import { CategoryHeading } from "../../components/CategoryHeading.js";
|
|
|
16
16
|
import { Heading } from "../../components/Heading.js";
|
|
17
17
|
import { Markdown } from "../../components/Markdown.js";
|
|
18
18
|
import { Toc } from "../../components/navigation/Toc.js";
|
|
19
|
+
import { PagefindSearchMeta } from "../../components/PagefindSearchMeta.js";
|
|
19
20
|
import { useCreateQuery } from "./client/useCreateQuery.js";
|
|
20
21
|
import { useOasConfig } from "./context.js";
|
|
21
22
|
import { graphql } from "./graphql/gql.js";
|
|
@@ -70,6 +71,9 @@ export function SchemaList() {
|
|
|
70
71
|
data-pagefind-filter="section:openapi"
|
|
71
72
|
data-pagefind-meta="section:openapi"
|
|
72
73
|
>
|
|
74
|
+
<PagefindSearchMeta name="category">
|
|
75
|
+
{data.schema.title}
|
|
76
|
+
</PagefindSearchMeta>
|
|
73
77
|
<Helmet>
|
|
74
78
|
<title>Schemas {showVersions ? version : ""}</title>
|
|
75
79
|
<meta name="description" content="List of schemas used by the API." />
|
|
@@ -13,7 +13,7 @@ import type { OasPluginConfig } from "./interfaces.js";
|
|
|
13
13
|
import type { PlaygroundContentProps } from "./playground/Playground.js";
|
|
14
14
|
import { PlaygroundDialog } from "./playground/PlaygroundDialog.js";
|
|
15
15
|
import { createNavigationCategory } from "./util/createNavigationCategory.js";
|
|
16
|
-
import { getRoutes,
|
|
16
|
+
import { getRoutes, getVersionMetadata } from "./util/getRoutes.js";
|
|
17
17
|
|
|
18
18
|
export const GetNavigationOperationsQuery = graphql(`
|
|
19
19
|
query GetNavigationOperations($input: JSON!, $type: SchemaType!) {
|
|
@@ -54,14 +54,19 @@ export const openApiPlugin = (config: OasPluginConfig): ZudokuPlugin => {
|
|
|
54
54
|
return {
|
|
55
55
|
getHead: () => {
|
|
56
56
|
if (config.type === "url" && !config.skipPreload) {
|
|
57
|
-
|
|
57
|
+
const urls = Array.isArray(config.input)
|
|
58
|
+
? config.input.map((v) => v.input)
|
|
59
|
+
: [config.input];
|
|
60
|
+
|
|
61
|
+
return urls.map((url) => (
|
|
58
62
|
<link
|
|
63
|
+
key={url}
|
|
64
|
+
href={url}
|
|
59
65
|
rel="preload"
|
|
60
|
-
href={config.input}
|
|
61
66
|
as="fetch"
|
|
62
67
|
crossOrigin="anonymous"
|
|
63
68
|
/>
|
|
64
|
-
);
|
|
69
|
+
));
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
if (config.server) {
|
|
@@ -111,10 +116,14 @@ export const openApiPlugin = (config: OasPluginConfig): ZudokuPlugin => {
|
|
|
111
116
|
|
|
112
117
|
try {
|
|
113
118
|
const versionParam = match?.params.version;
|
|
114
|
-
const
|
|
119
|
+
const { versions } = getVersionMetadata(config);
|
|
120
|
+
const version = versionParam ?? versions.at(0);
|
|
115
121
|
const { type } = config;
|
|
116
|
-
|
|
117
|
-
const input =
|
|
122
|
+
|
|
123
|
+
const input = Array.isArray(config.input)
|
|
124
|
+
? (config.input.find((v) => v.path === version)?.input ??
|
|
125
|
+
config.input[0]?.input)
|
|
126
|
+
: config.input;
|
|
118
127
|
|
|
119
128
|
const query = createQuery(client, GetNavigationOperationsQuery, {
|
|
120
129
|
type,
|
|
@@ -5,15 +5,21 @@ import type { OperationsFragmentFragment } from "./graphql/graphql.js";
|
|
|
5
5
|
|
|
6
6
|
type DynamicInput = () => Promise<unknown>;
|
|
7
7
|
|
|
8
|
+
export type VersionedInput<T> = Array<{
|
|
9
|
+
path: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
input: T;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
8
14
|
type OasSource =
|
|
9
|
-
| { type: "url"; input: string }
|
|
10
|
-
| { type: "file"; input:
|
|
15
|
+
| { type: "url"; input: string | VersionedInput<string> }
|
|
16
|
+
| { type: "file"; input: VersionedInput<DynamicInput> }
|
|
11
17
|
| { type: "raw"; input: string };
|
|
12
18
|
|
|
13
|
-
export type ContextOasSource =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
export type ContextOasSource = {
|
|
20
|
+
type: "url" | "file" | "raw";
|
|
21
|
+
input: string | DynamicInput;
|
|
22
|
+
};
|
|
17
23
|
|
|
18
24
|
type Example = {
|
|
19
25
|
name: string;
|
|
@@ -66,6 +72,9 @@ type BaseOasConfig = {
|
|
|
66
72
|
showVersionSelect?: "always" | "if-available" | "hide";
|
|
67
73
|
expandAllTags?: boolean;
|
|
68
74
|
expandApiInformation?: boolean;
|
|
75
|
+
schemaDownload?: {
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
};
|
|
69
78
|
transformExamples?: TransformExamplesFn;
|
|
70
79
|
generateCodeSnippet?: GenerateCodeSnippetFn;
|
|
71
80
|
};
|
|
@@ -76,5 +85,5 @@ export type OasPluginConfig = BaseOasConfig & OasSource;
|
|
|
76
85
|
export type OasPluginContext = BaseOasConfig &
|
|
77
86
|
ContextOasSource & {
|
|
78
87
|
version?: string;
|
|
79
|
-
versions: Record<string, string>;
|
|
88
|
+
versions: Record<string, { path: string; label: string }>;
|
|
80
89
|
};
|
|
@@ -387,7 +387,7 @@ export const Playground = ({
|
|
|
387
387
|
value={selectedServer}
|
|
388
388
|
defaultValue={selectedServer}
|
|
389
389
|
>
|
|
390
|
-
<SelectTrigger className="p-0 border-none flex-row-reverse bg-transparent text-xs gap-0.5
|
|
390
|
+
<SelectTrigger className="p-0 h-fit shadow-none border-none flex-row-reverse bg-transparent text-xs gap-0.5 translate-y-[4px]">
|
|
391
391
|
<SelectValue />
|
|
392
392
|
</SelectTrigger>
|
|
393
393
|
<SelectContent>
|
|
@@ -17,7 +17,7 @@ import { ParamInfos } from "../ParamInfos.js";
|
|
|
17
17
|
import { SchemaExampleAndDefault } from "./SchemaExampleAndDefault.js";
|
|
18
18
|
import { SchemaPropertyItem } from "./SchemaPropertyItem.js";
|
|
19
19
|
import { UnionView } from "./UnionView.js";
|
|
20
|
-
import { isBasicType } from "./utils.js";
|
|
20
|
+
import { isArrayType, isBasicType } from "./utils.js";
|
|
21
21
|
|
|
22
22
|
const renderMarkdown = (content?: string) =>
|
|
23
23
|
content && (
|
|
@@ -91,10 +91,20 @@ export const SchemaView = ({
|
|
|
91
91
|
return renderBasicSchema(schema, cardHeader, embedded);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
if (schema
|
|
95
|
-
|
|
94
|
+
if (isArrayType(schema) && typeof schema.items === "object") {
|
|
95
|
+
const wrappedSchema: SchemaObject = {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: { "": schema },
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<SchemaView schema={wrappedSchema} cardHeader={cardHeader} defaultOpen />
|
|
102
|
+
);
|
|
96
103
|
}
|
|
97
104
|
|
|
105
|
+
const additionalObjectProperties = typeof schema.additionalProperties ===
|
|
106
|
+
"object" && <SchemaView schema={schema.additionalProperties} embedded />;
|
|
107
|
+
|
|
98
108
|
if (schema.type === "object") {
|
|
99
109
|
const groupedProperties = groupBy(
|
|
100
110
|
Object.entries(schema.properties ?? {}),
|
|
@@ -106,32 +116,31 @@ export const SchemaView = ({
|
|
|
106
116
|
: "optional";
|
|
107
117
|
},
|
|
108
118
|
);
|
|
119
|
+
|
|
109
120
|
const groupNames = ["required", "optional", "deprecated"] as const;
|
|
121
|
+
const groups = groupNames.flatMap((group) => {
|
|
122
|
+
const properties = groupedProperties[group];
|
|
123
|
+
return properties ? { group, properties } : [];
|
|
124
|
+
});
|
|
110
125
|
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
</Fragment>
|
|
130
|
-
))}
|
|
131
|
-
</ItemGroup>
|
|
132
|
-
</Fragment>
|
|
133
|
-
),
|
|
134
|
-
);
|
|
126
|
+
const itemsList = groups.map(({ group, properties }, index) => (
|
|
127
|
+
<Fragment key={group}>
|
|
128
|
+
{index > 0 && <ItemSeparator />}
|
|
129
|
+
<ItemGroup className="overflow-clip">
|
|
130
|
+
{properties.map(([name, schema], index) => (
|
|
131
|
+
<Fragment key={name}>
|
|
132
|
+
{index > 0 && <ItemSeparator />}
|
|
133
|
+
<SchemaPropertyItem
|
|
134
|
+
name={name}
|
|
135
|
+
schema={schema}
|
|
136
|
+
group={group}
|
|
137
|
+
defaultOpen={defaultOpen}
|
|
138
|
+
/>
|
|
139
|
+
</Fragment>
|
|
140
|
+
))}
|
|
141
|
+
</ItemGroup>
|
|
142
|
+
</Fragment>
|
|
143
|
+
));
|
|
135
144
|
|
|
136
145
|
if (embedded) {
|
|
137
146
|
return itemsList;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { CIRCULAR_REF } from "../../../oas/graphql/circular.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
ArraySchemaObject,
|
|
4
|
+
SchemaObject,
|
|
5
|
+
} from "../../../oas/parser/index.js";
|
|
3
6
|
|
|
4
7
|
export const isBasicType = (
|
|
5
8
|
type: unknown,
|
|
@@ -8,7 +11,7 @@ export const isBasicType = (
|
|
|
8
11
|
["string", "number", "boolean", "integer", "null"].includes(type)) ||
|
|
9
12
|
(Array.isArray(type) && type.every(isBasicType));
|
|
10
13
|
|
|
11
|
-
export const isArrayType = (value: SchemaObject) =>
|
|
14
|
+
export const isArrayType = (value: SchemaObject): value is ArraySchemaObject =>
|
|
12
15
|
value.type === "array" ||
|
|
13
16
|
// schema.type might be an array of types, so we need to check if "array" is one of them
|
|
14
17
|
(Array.isArray(value.type) && value.type.includes("array"));
|
|
@@ -148,8 +148,18 @@ const createVersionRoutes = (
|
|
|
148
148
|
];
|
|
149
149
|
};
|
|
150
150
|
|
|
151
|
-
export const
|
|
152
|
-
config.type === "
|
|
151
|
+
export const getVersionMetadata = (config: OasPluginConfig) => {
|
|
152
|
+
if (config.type === "raw" || !Array.isArray(config.input)) {
|
|
153
|
+
return { versions: [], labels: {} };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
versions: config.input.map((v) => v.path),
|
|
158
|
+
labels: Object.fromEntries(
|
|
159
|
+
config.input.map((v) => [v.path, v.label ?? v.path]),
|
|
160
|
+
),
|
|
161
|
+
};
|
|
162
|
+
};
|
|
153
163
|
|
|
154
164
|
export const getRoutes = ({
|
|
155
165
|
basePath,
|
|
@@ -161,10 +171,33 @@ export const getRoutes = ({
|
|
|
161
171
|
basePath: string;
|
|
162
172
|
}): RouteObject[] => {
|
|
163
173
|
const tagPages = config.tagPages;
|
|
174
|
+
const { versions } = getVersionMetadata(config);
|
|
164
175
|
|
|
165
176
|
// If the config does not provide tag pages the catch-all
|
|
166
177
|
// route handles all operations on a single page
|
|
167
178
|
if (!tagPages) {
|
|
179
|
+
// If there are versions, create versioned routes even without tag pages
|
|
180
|
+
if (versions.length > 0) {
|
|
181
|
+
const versionsInPath =
|
|
182
|
+
versions.length > 1 ? [undefined, ...versions] : [undefined];
|
|
183
|
+
|
|
184
|
+
return versionsInPath.map((version) => {
|
|
185
|
+
const versionPath = joinUrl(basePath, version);
|
|
186
|
+
return createOasProvider({
|
|
187
|
+
basePath,
|
|
188
|
+
version,
|
|
189
|
+
routePath: versionPath,
|
|
190
|
+
routes: [
|
|
191
|
+
createNonTagPagesRoute({ path: `${versionPath}/:tag?` }),
|
|
192
|
+
...createAdditionalRoutes(versionPath),
|
|
193
|
+
],
|
|
194
|
+
client,
|
|
195
|
+
config,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// No versions, single route
|
|
168
201
|
return [
|
|
169
202
|
createOasProvider({
|
|
170
203
|
basePath,
|
|
@@ -179,7 +212,6 @@ export const getRoutes = ({
|
|
|
179
212
|
];
|
|
180
213
|
}
|
|
181
214
|
|
|
182
|
-
const versions = getVersions(config);
|
|
183
215
|
// The latest version always is added as index path
|
|
184
216
|
const versionsInPath =
|
|
185
217
|
versions.length > 1 ? [undefined, ...versions] : [undefined];
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { DialogTrigger } from "@radix-ui/react-dialog";
|
|
2
|
+
import {
|
|
3
|
+
type PropsWithChildren,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useState,
|
|
7
|
+
} from "react";
|
|
8
|
+
import { Button } from "zudoku/ui/Button.js";
|
|
9
|
+
import {
|
|
10
|
+
Dialog,
|
|
11
|
+
DialogContent,
|
|
12
|
+
DialogDescription,
|
|
13
|
+
DialogFooter,
|
|
14
|
+
DialogHeader,
|
|
15
|
+
DialogTitle,
|
|
16
|
+
} from "zudoku/ui/Dialog.js";
|
|
17
|
+
|
|
18
|
+
type IndexingState =
|
|
19
|
+
| { status: "idle" }
|
|
20
|
+
| { status: "indexing"; total: number; current: number; path: string }
|
|
21
|
+
| { status: "complete"; indexed: number }
|
|
22
|
+
| { status: "error"; message: string };
|
|
23
|
+
|
|
24
|
+
const ProgressBar = ({
|
|
25
|
+
total,
|
|
26
|
+
current,
|
|
27
|
+
barLength = 25,
|
|
28
|
+
emptyChar = "░",
|
|
29
|
+
filledChar = "█",
|
|
30
|
+
}: {
|
|
31
|
+
total: number;
|
|
32
|
+
current: number;
|
|
33
|
+
barLength?: number;
|
|
34
|
+
emptyChar?: string;
|
|
35
|
+
filledChar?: string;
|
|
36
|
+
}) => {
|
|
37
|
+
const percent = Math.round((current / total) * 100);
|
|
38
|
+
const filled = Math.round((percent / 100) * barLength);
|
|
39
|
+
const empty = barLength - filled;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<>
|
|
43
|
+
{filledChar.repeat(filled)}
|
|
44
|
+
{emptyChar.repeat(empty)} {percent}% ({current}/{total})
|
|
45
|
+
</>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const IndexingDialog = ({ children }: PropsWithChildren) => {
|
|
50
|
+
const [indexingState, setIndexingState] = useState<IndexingState>({
|
|
51
|
+
status: "idle",
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const startIndexing = useCallback(() => {
|
|
55
|
+
setIndexingState({ status: "indexing", total: 0, current: 0, path: "" });
|
|
56
|
+
|
|
57
|
+
const eventSource = new EventSource("/__z/pagefind-reindex");
|
|
58
|
+
|
|
59
|
+
eventSource.onmessage = (event) => {
|
|
60
|
+
const data = JSON.parse(event.data);
|
|
61
|
+
|
|
62
|
+
if (data.type === "progress") {
|
|
63
|
+
setIndexingState({
|
|
64
|
+
status: "indexing",
|
|
65
|
+
total: data.total,
|
|
66
|
+
current: data.current,
|
|
67
|
+
path: data.path,
|
|
68
|
+
});
|
|
69
|
+
} else if (data.type === "complete") {
|
|
70
|
+
eventSource.close();
|
|
71
|
+
if (data.success) {
|
|
72
|
+
setIndexingState({ status: "complete", indexed: data.indexed });
|
|
73
|
+
} else {
|
|
74
|
+
setIndexingState({
|
|
75
|
+
status: "error",
|
|
76
|
+
message: data.error ?? "Indexing failed",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
eventSource.onerror = () => {
|
|
83
|
+
eventSource.close();
|
|
84
|
+
setIndexingState({
|
|
85
|
+
status: "error",
|
|
86
|
+
message: "Connection lost during indexing",
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return () => eventSource.close();
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (indexingState.status !== "idle") return;
|
|
95
|
+
return startIndexing();
|
|
96
|
+
}, [indexingState.status, startIndexing]);
|
|
97
|
+
|
|
98
|
+
const handleDone = () => {
|
|
99
|
+
if (indexingState.status !== "complete") return;
|
|
100
|
+
window.location.reload();
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Dialog>
|
|
105
|
+
<DialogTrigger asChild>{children}</DialogTrigger>
|
|
106
|
+
<DialogContent
|
|
107
|
+
className="max-w-sm! top-1/3"
|
|
108
|
+
showCloseButton={false}
|
|
109
|
+
onInteractOutside={(e) => e.preventDefault()}
|
|
110
|
+
>
|
|
111
|
+
<DialogHeader>
|
|
112
|
+
<DialogTitle>
|
|
113
|
+
{indexingState.status === "indexing" && "Building Search Index"}
|
|
114
|
+
{indexingState.status === "complete" && "Indexing Complete"}
|
|
115
|
+
{indexingState.status === "error" && "Indexing Failed"}
|
|
116
|
+
{indexingState.status === "idle" && "Build Search Index"}
|
|
117
|
+
</DialogTitle>
|
|
118
|
+
<DialogDescription>
|
|
119
|
+
{indexingState.status === "indexing" && (
|
|
120
|
+
<>
|
|
121
|
+
{indexingState.total > 0 && (
|
|
122
|
+
<div className="font-mono text-sm mb-2">
|
|
123
|
+
<ProgressBar {...indexingState} />
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
{indexingState.path && (
|
|
127
|
+
<span className="block text-xs truncate">
|
|
128
|
+
{indexingState.path}
|
|
129
|
+
</span>
|
|
130
|
+
)}
|
|
131
|
+
</>
|
|
132
|
+
)}
|
|
133
|
+
{indexingState.status === "complete" && (
|
|
134
|
+
<>Successfully indexed {indexingState.indexed} pages.</>
|
|
135
|
+
)}
|
|
136
|
+
{indexingState.status === "error" && (
|
|
137
|
+
<span className="text-destructive">{indexingState.message}</span>
|
|
138
|
+
)}
|
|
139
|
+
</DialogDescription>
|
|
140
|
+
</DialogHeader>
|
|
141
|
+
<DialogFooter>
|
|
142
|
+
<div className="flex justify-end gap-2">
|
|
143
|
+
{indexingState.status === "complete" && (
|
|
144
|
+
<Button size="sm" onClick={handleDone}>
|
|
145
|
+
Close and reload
|
|
146
|
+
</Button>
|
|
147
|
+
)}
|
|
148
|
+
{indexingState.status === "error" && (
|
|
149
|
+
<>
|
|
150
|
+
<Button variant="outline" onClick={handleDone}>
|
|
151
|
+
Cancel
|
|
152
|
+
</Button>
|
|
153
|
+
<Button onClick={startIndexing}>Retry</Button>
|
|
154
|
+
</>
|
|
155
|
+
)}
|
|
156
|
+
</div>
|
|
157
|
+
</DialogFooter>
|
|
158
|
+
</DialogContent>
|
|
159
|
+
</Dialog>
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export default IndexingDialog;
|