zudoku 0.26.0 → 0.27.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/main.d.ts +1 -1
- package/dist/app/main.js +19 -7
- package/dist/app/main.js.map +1 -1
- package/dist/config/config.d.ts +1 -0
- package/dist/config/validators/InputSidebarSchema.d.ts +2 -2
- package/dist/config/validators/common.d.ts +78 -0
- package/dist/config/validators/common.js +6 -0
- package/dist/config/validators/common.js.map +1 -1
- package/dist/config/validators/validate.d.ts +34 -0
- package/dist/lib/authentication/providers/auth0.js +1 -1
- package/dist/lib/authentication/providers/auth0.js.map +1 -1
- package/dist/lib/authentication/providers/openid.d.ts +1 -1
- package/dist/lib/authentication/providers/openid.js +10 -6
- package/dist/lib/authentication/providers/openid.js.map +1 -1
- package/dist/lib/components/AnchorLink.js +5 -2
- package/dist/lib/components/AnchorLink.js.map +1 -1
- package/dist/lib/components/Autocomplete.d.ts +12 -0
- package/dist/lib/components/Autocomplete.js +47 -0
- package/dist/lib/components/Autocomplete.js.map +1 -0
- package/dist/lib/components/Header.js +4 -4
- package/dist/lib/components/Header.js.map +1 -1
- package/dist/lib/components/Heading.d.ts +1 -1
- package/dist/lib/components/Markdown.d.ts +2 -2
- package/dist/lib/components/Markdown.js +3 -1
- package/dist/lib/components/Markdown.js.map +1 -1
- package/dist/lib/components/StatusPage.d.ts +7 -0
- package/dist/lib/components/StatusPage.js +71 -0
- package/dist/lib/components/StatusPage.js.map +1 -0
- package/dist/lib/components/SyntaxHighlight.d.ts +2 -1
- package/dist/lib/components/SyntaxHighlight.js +2 -2
- package/dist/lib/components/SyntaxHighlight.js.map +1 -1
- package/dist/lib/components/ThemeSwitch.js +4 -4
- package/dist/lib/components/ThemeSwitch.js.map +1 -1
- package/dist/lib/components/cache.d.ts +6 -0
- package/dist/lib/components/cache.js +13 -0
- package/dist/lib/components/cache.js.map +1 -0
- package/dist/lib/components/context/ViewportAnchorContext.js +16 -4
- package/dist/lib/components/context/ViewportAnchorContext.js.map +1 -1
- package/dist/lib/components/context/ZudokuContext.js +2 -1
- package/dist/lib/components/context/ZudokuContext.js.map +1 -1
- package/dist/lib/components/index.d.ts +9 -2
- package/dist/lib/components/index.js +5 -2
- package/dist/lib/components/index.js.map +1 -1
- package/dist/lib/core/RouteGuard.d.ts +1 -0
- package/dist/lib/core/RouteGuard.js +28 -0
- package/dist/lib/core/RouteGuard.js.map +1 -0
- package/dist/lib/core/ZudokuContext.d.ts +4 -2
- package/dist/lib/core/ZudokuContext.js +9 -7
- package/dist/lib/core/ZudokuContext.js.map +1 -1
- package/dist/lib/oas/graphql/circular.d.ts +3 -0
- package/dist/lib/oas/graphql/circular.js +27 -0
- package/dist/lib/oas/graphql/circular.js.map +1 -0
- package/dist/lib/oas/graphql/index.js +5 -6
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/oas/parser/dereference/index.d.ts +0 -1
- package/dist/lib/oas/parser/dereference/index.js +1 -1
- package/dist/lib/oas/parser/dereference/index.js.map +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js +8 -2
- package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js +1 -1
- package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.d.ts +3 -1
- package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js +3 -2
- package/dist/lib/plugins/openapi/PlaygroundDialogWrapper.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +3 -3
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +4 -11
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/interfaces.d.ts +7 -2
- package/dist/lib/plugins/openapi/playground/ExamplesDropdown.d.ts +6 -0
- package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js +12 -0
- package/dist/lib/plugins/openapi/playground/ExamplesDropdown.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/Headers.js +67 -4
- package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/ParamsGrid.d.ts +5 -0
- package/dist/lib/plugins/openapi/playground/ParamsGrid.js +4 -0
- package/dist/lib/plugins/openapi/playground/ParamsGrid.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/PathParams.js +4 -12
- package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.d.ts +18 -1
- package/dist/lib/plugins/openapi/playground/Playground.js +53 -40
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +1 -1
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.js +21 -30
- package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/SubmitButton.d.ts +7 -0
- package/dist/lib/plugins/openapi/playground/SubmitButton.js +22 -0
- package/dist/lib/plugins/openapi/playground/SubmitButton.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.d.ts +7 -0
- package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.js +11 -0
- package/dist/lib/plugins/openapi/playground/result-panel/RequestTab.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.d.ts +8 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js +95 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResponseTab.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +7 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js +16 -0
- package/dist/lib/plugins/openapi/playground/result-panel/ResultPanel.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.d.ts +10 -0
- package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.js +32 -0
- package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.js.map +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.test.d.ts +1 -0
- package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.test.js +56 -0
- package/dist/lib/plugins/openapi/playground/result-panel/convertToTypes.test.js.map +1 -0
- package/dist/lib/plugins/openapi/post-processors/removeExtensions.d.ts +2 -1
- package/dist/lib/plugins/openapi/post-processors/removeExtensions.js +5 -3
- package/dist/lib/plugins/openapi/post-processors/removeExtensions.js.map +1 -1
- package/dist/lib/plugins/openapi/post-processors/removeExtensions.test.js +49 -0
- package/dist/lib/plugins/openapi/post-processors/removeExtensions.test.js.map +1 -1
- package/dist/lib/plugins/openapi/post-processors/removeParameters.d.ts +10 -0
- package/dist/lib/plugins/openapi/post-processors/removeParameters.js +66 -0
- package/dist/lib/plugins/openapi/post-processors/removeParameters.js.map +1 -0
- package/dist/lib/plugins/openapi/post-processors/removeParameters.test.d.ts +1 -0
- package/dist/lib/plugins/openapi/post-processors/removeParameters.test.js +131 -0
- package/dist/lib/plugins/openapi/post-processors/removeParameters.test.js.map +1 -0
- package/dist/lib/plugins/openapi/schema/SchemaComponents.js +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaComponents.js.map +1 -1
- package/dist/lib/ui/Command.d.ts +9 -1
- package/dist/lib/ui/Command.js +5 -1
- package/dist/lib/ui/Command.js.map +1 -1
- package/dist/lib/ui/Select.js +2 -2
- package/dist/lib/ui/Select.js.map +1 -1
- package/dist/lib/util/MdxComponents.js +2 -2
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/lib/util/joinUrl.d.ts +1 -0
- package/dist/lib/util/joinUrl.js +40 -0
- package/dist/lib/util/joinUrl.js.map +1 -0
- package/dist/lib/util/useScrollToAnchor.d.ts +1 -0
- package/dist/lib/util/useScrollToAnchor.js +26 -15
- package/dist/lib/util/useScrollToAnchor.js.map +1 -1
- package/dist/vite/build.js +10 -10
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/config.js +4 -1
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/dev-server.js +4 -1
- package/dist/vite/dev-server.js.map +1 -1
- package/dist/vite/plugin-api.d.ts +1 -1
- package/dist/vite/plugin-api.js +31 -7
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/plugin-auth.js +4 -1
- package/dist/vite/plugin-auth.js.map +1 -1
- package/dist/vite/plugin-mdx.js +9 -4
- package/dist/vite/plugin-mdx.js.map +1 -1
- package/dist/vite/prerender.d.ts +2 -2
- package/dist/vite/prerender.js +5 -4
- package/dist/vite/prerender.js.map +1 -1
- package/dist/zuplo/enrich-with-zuplo.d.ts +5 -0
- package/dist/zuplo/enrich-with-zuplo.js +184 -0
- package/dist/zuplo/enrich-with-zuplo.js.map +1 -0
- package/dist/zuplo/env.d.ts +1 -0
- package/dist/zuplo/env.js +3 -0
- package/dist/zuplo/env.js.map +1 -1
- package/dist/zuplo/policy-types.d.ts +33 -0
- package/dist/zuplo/policy-types.js +8 -0
- package/dist/zuplo/policy-types.js.map +1 -0
- package/dist/zuplo/with-zuplo-processors.d.ts +3 -0
- package/dist/zuplo/with-zuplo-processors.js +26 -0
- package/dist/zuplo/with-zuplo-processors.js.map +1 -0
- package/dist/zuplo/with-zuplo.d.ts +1 -1
- package/dist/zuplo/with-zuplo.js +7 -26
- package/dist/zuplo/with-zuplo.js.map +1 -1
- package/lib/{AuthenticationPlugin-DNXBcsVN.js → AuthenticationPlugin-CO_YCd2x.js} +3 -3
- package/lib/{AuthenticationPlugin-DNXBcsVN.js.map → AuthenticationPlugin-CO_YCd2x.js.map} +1 -1
- package/lib/{Markdown-BrfrjEk_.js → Markdown-B8o9Qz4q.js} +1197 -1186
- package/lib/{Markdown-BrfrjEk_.js.map → Markdown-B8o9Qz4q.js.map} +1 -1
- package/lib/{MdxPage-LNZLj_A5.js → MdxPage-BxRt3Ly7.js} +63 -58
- package/lib/MdxPage-BxRt3Ly7.js.map +1 -0
- package/lib/OperationList-DH-zIgtq.js +5160 -0
- package/lib/OperationList-DH-zIgtq.js.map +1 -0
- package/lib/{Route-Pzk6qwIk.js → Route-DJ0ZlVq1.js} +3 -3
- package/lib/{Route-Pzk6qwIk.js.map → Route-DJ0ZlVq1.js.map} +1 -1
- package/lib/{Select-DkOpAG0c.js → Select-B7UXR0SB.js} +61 -61
- package/lib/Select-B7UXR0SB.js.map +1 -0
- package/lib/{SlotletProvider-DPbx9KdU.js → SlotletProvider-CtIp8rP3.js} +4 -4
- package/lib/{SlotletProvider-DPbx9KdU.js.map → SlotletProvider-CtIp8rP3.js.map} +1 -1
- package/lib/{Button-oroWHXAy.js → Spinner-BlzrEEk1.js} +15 -12
- package/lib/Spinner-BlzrEEk1.js.map +1 -0
- package/lib/{SyntaxHighlight-CJCSPG1F.js → SyntaxHighlight-C1w1QPdY.js} +300 -295
- package/lib/{SyntaxHighlight-CJCSPG1F.js.map → SyntaxHighlight-C1w1QPdY.js.map} +1 -1
- package/lib/{ZudokuContext-D3ayHjP-.js → ZudokuContext-8jts0fF3.js} +259 -248
- package/lib/ZudokuContext-8jts0fF3.js.map +1 -0
- package/lib/{chunk-SYFQ2XB5-KWlHsT7t.js → chunk-SYFQ2XB5-BPvC-soB.js} +6 -5
- package/lib/{chunk-SYFQ2XB5-KWlHsT7t.js.map → chunk-SYFQ2XB5-BPvC-soB.js.map} +1 -1
- package/lib/circular-Dgpd6AN-.js +15397 -0
- package/lib/circular-Dgpd6AN-.js.map +1 -0
- package/lib/{createServer-BcaswoFO.js → createServer-BV0tHzLK.js} +3450 -5577
- package/lib/createServer-BV0tHzLK.js.map +1 -0
- package/lib/{hook-DUyACbIK.js → hook-BG02esyv.js} +2 -2
- package/lib/{hook-DUyACbIK.js.map → hook-BG02esyv.js.map} +1 -1
- package/lib/index-B7mqiOei.js +509 -0
- package/lib/index-B7mqiOei.js.map +1 -0
- package/lib/index-DmqsUPcm.js +1915 -0
- package/lib/index-DmqsUPcm.js.map +1 -0
- package/lib/joinUrl-BTy9bvoK.js +20 -0
- package/lib/joinUrl-BTy9bvoK.js.map +1 -0
- package/lib/post-processors/removeExtensions.js +7 -7
- package/lib/post-processors/removeExtensions.js.map +1 -1
- package/lib/post-processors/removeParameters.js +48 -0
- package/lib/post-processors/removeParameters.js.map +1 -0
- package/lib/ui/ActionButton.js +10 -11
- package/lib/ui/ActionButton.js.map +1 -1
- package/lib/ui/Command.js +125 -13
- package/lib/ui/Command.js.map +1 -1
- package/lib/ui/Select.js +2 -2
- package/lib/ui/Select.js.map +1 -1
- package/lib/{useExposedProps-BBHR7aLM.js → useExposedProps-BLKFBylA.js} +2 -2
- package/lib/{useExposedProps-BBHR7aLM.js.map → useExposedProps-BLKFBylA.js.map} +1 -1
- package/lib/useScrollToAnchor-Bl6mz9_x.js +288 -0
- package/lib/useScrollToAnchor-Bl6mz9_x.js.map +1 -0
- package/lib/zudoku.auth-auth0.js +7 -9
- package/lib/zudoku.auth-auth0.js.map +1 -1
- package/lib/zudoku.auth-clerk.js +1 -1
- package/lib/zudoku.auth-openid.js +223 -219
- package/lib/zudoku.auth-openid.js.map +1 -1
- package/lib/zudoku.components.js +754 -992
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.plugin-api-catalog.js +3 -3
- package/lib/zudoku.plugin-api-keys.js +5 -5
- package/lib/zudoku.plugin-custom-pages.js +2 -2
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +4 -4
- package/lib/zudoku.plugin-redirect.js +1 -1
- package/package.json +2 -2
- package/src/app/main.css +50 -50
- package/src/app/main.tsx +26 -7
- package/src/lib/authentication/providers/auth0.tsx +1 -4
- package/src/lib/authentication/providers/openid.tsx +12 -5
- package/src/lib/components/AnchorLink.tsx +5 -2
- package/src/lib/components/Autocomplete.tsx +111 -0
- package/src/lib/components/Header.tsx +4 -4
- package/src/lib/components/Markdown.tsx +14 -15
- package/src/lib/components/StatusPage.tsx +91 -0
- package/src/lib/components/SyntaxHighlight.tsx +14 -0
- package/src/lib/components/ThemeSwitch.tsx +14 -15
- package/src/lib/components/cache.ts +15 -0
- package/src/lib/components/context/ViewportAnchorContext.tsx +20 -6
- package/src/lib/components/context/ZudokuContext.ts +3 -1
- package/src/lib/components/index.ts +9 -2
- package/src/lib/core/RouteGuard.tsx +35 -0
- package/src/lib/core/ZudokuContext.ts +9 -8
- package/src/lib/oas/graphql/circular.ts +29 -0
- package/src/lib/oas/graphql/index.ts +9 -9
- package/src/lib/oas/parser/dereference/index.ts +1 -2
- package/src/lib/plugins/markdown/MdxPage.tsx +9 -1
- package/src/lib/plugins/openapi/OperationListItem.tsx +0 -2
- package/src/lib/plugins/openapi/ParameterListItem.tsx +1 -0
- package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +5 -0
- package/src/lib/plugins/openapi/Sidecar.tsx +4 -2
- package/src/lib/plugins/openapi/index.tsx +9 -15
- package/src/lib/plugins/openapi/interfaces.ts +10 -2
- package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +54 -0
- package/src/lib/plugins/openapi/playground/Headers.tsx +136 -39
- package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +8 -0
- package/src/lib/plugins/openapi/playground/PathParams.tsx +34 -74
- package/src/lib/plugins/openapi/playground/Playground.tsx +219 -177
- package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +1 -1
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +90 -122
- package/src/lib/plugins/openapi/playground/SubmitButton.tsx +75 -0
- package/src/lib/plugins/openapi/playground/result-panel/RequestTab.tsx +73 -0
- package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +210 -0
- package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +101 -0
- package/src/lib/plugins/openapi/playground/result-panel/convertToTypes.test.ts +64 -0
- package/src/lib/plugins/openapi/playground/result-panel/convertToTypes.ts +36 -0
- package/src/lib/plugins/openapi/post-processors/removeExtensions.test.ts +58 -0
- package/src/lib/plugins/openapi/post-processors/removeExtensions.ts +7 -4
- package/src/lib/plugins/openapi/post-processors/removeParameters.test.ts +148 -0
- package/src/lib/plugins/openapi/post-processors/removeParameters.ts +101 -0
- package/src/lib/plugins/openapi/schema/SchemaComponents.tsx +1 -1
- package/src/lib/ui/Command.tsx +20 -0
- package/src/lib/ui/Select.tsx +1 -1
- package/src/lib/util/MdxComponents.tsx +2 -1
- package/src/lib/util/joinUrl.ts +57 -0
- package/src/lib/util/useScrollToAnchor.ts +32 -15
- package/dist/lib/plugins/openapi/playground/EnumSelector.d.ts +0 -8
- package/dist/lib/plugins/openapi/playground/EnumSelector.js +0 -21
- package/dist/lib/plugins/openapi/playground/EnumSelector.js.map +0 -1
- package/dist/lib/plugins/openapi/playground/ResponseTab.d.ts +0 -4
- package/dist/lib/plugins/openapi/playground/ResponseTab.js +0 -42
- package/dist/lib/plugins/openapi/playground/ResponseTab.js.map +0 -1
- package/lib/AnchorLink-_Vu02ceN.js +0 -34
- package/lib/AnchorLink-_Vu02ceN.js.map +0 -1
- package/lib/Button-oroWHXAy.js.map +0 -1
- package/lib/Command-D5DE0DD7.js +0 -611
- package/lib/Command-D5DE0DD7.js.map +0 -1
- package/lib/MdxPage-LNZLj_A5.js.map +0 -1
- package/lib/OperationList-PCwzTp1r.js +0 -5144
- package/lib/OperationList-PCwzTp1r.js.map +0 -1
- package/lib/Select-DkOpAG0c.js.map +0 -1
- package/lib/Spinner-C5gHXrVz.js +0 -7
- package/lib/Spinner-C5gHXrVz.js.map +0 -1
- package/lib/ZudokuContext-D3ayHjP-.js.map +0 -1
- package/lib/createServer-BcaswoFO.js.map +0 -1
- package/lib/index-CaILD1AV.js +0 -1292
- package/lib/index-CaILD1AV.js.map +0 -1
- package/lib/index-TaRXY2w1.js +0 -43
- package/lib/index-TaRXY2w1.js.map +0 -1
- package/src/lib/plugins/openapi/playground/EnumSelector.tsx +0 -86
- package/src/lib/plugins/openapi/playground/ResponseTab.tsx +0 -76
|
@@ -41,6 +41,7 @@ type SyntaxHighlightProps = {
|
|
|
41
41
|
copyable?: boolean;
|
|
42
42
|
showLanguageIndicator?: boolean;
|
|
43
43
|
language?: string;
|
|
44
|
+
title?: string;
|
|
44
45
|
} & Omit<HighlightProps, "children" | "language">;
|
|
45
46
|
|
|
46
47
|
const remapLang = {
|
|
@@ -50,6 +51,7 @@ const remapLang = {
|
|
|
50
51
|
export const SyntaxHighlight = ({
|
|
51
52
|
copyable = true,
|
|
52
53
|
language = "plain",
|
|
54
|
+
title,
|
|
53
55
|
...props
|
|
54
56
|
}: SyntaxHighlightProps) => {
|
|
55
57
|
const { resolvedTheme } = useTheme();
|
|
@@ -70,12 +72,18 @@ export const SyntaxHighlight = ({
|
|
|
70
72
|
<ClientOnly
|
|
71
73
|
fallback={
|
|
72
74
|
<div className="relative group">
|
|
75
|
+
{title && (
|
|
76
|
+
<div className="text-xs text-muted-foreground absolute top-2 font-mono border-b w-full pb-2 px-4 ">
|
|
77
|
+
{title}
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
73
80
|
<pre
|
|
74
81
|
className={cn(
|
|
75
82
|
"relative scrollbar overflow-x-auto",
|
|
76
83
|
props.className,
|
|
77
84
|
props.noBackground ? "!bg-transparent" : themeColorClasses,
|
|
78
85
|
props.wrapLines && "whitespace-pre-wrap break-words",
|
|
86
|
+
title && "pt-10",
|
|
79
87
|
)}
|
|
80
88
|
>
|
|
81
89
|
{props.code}
|
|
@@ -95,6 +103,11 @@ export const SyntaxHighlight = ({
|
|
|
95
103
|
>
|
|
96
104
|
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
|
97
105
|
<div className="relative group">
|
|
106
|
+
{title && (
|
|
107
|
+
<div className="text-xs text-muted-foreground absolute top-2 font-mono border-b w-full pb-2 px-4 ">
|
|
108
|
+
{title}
|
|
109
|
+
</div>
|
|
110
|
+
)}
|
|
98
111
|
<pre
|
|
99
112
|
className={cn(
|
|
100
113
|
"relative scrollbar overflow-x-auto",
|
|
@@ -102,6 +115,7 @@ export const SyntaxHighlight = ({
|
|
|
102
115
|
props.className,
|
|
103
116
|
props.noBackground && "!bg-transparent",
|
|
104
117
|
props.wrapLines && "whitespace-pre-wrap break-words",
|
|
118
|
+
title && "pt-10",
|
|
105
119
|
)}
|
|
106
120
|
style={style}
|
|
107
121
|
>
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { MoonStarIcon, SunIcon } from "lucide-react";
|
|
2
2
|
import { useTheme } from "next-themes";
|
|
3
3
|
import { Button } from "zudoku/ui/Button.js";
|
|
4
|
-
import {
|
|
4
|
+
import { cn } from "../util/cn.js";
|
|
5
5
|
|
|
6
6
|
export const ThemeSwitch = () => {
|
|
7
7
|
const { resolvedTheme, setTheme } = useTheme();
|
|
8
8
|
const ThemeIcon = resolvedTheme === "dark" ? MoonStarIcon : SunIcon;
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
</ClientOnly>
|
|
11
|
+
<Button
|
|
12
|
+
variant="ghost"
|
|
13
|
+
size="icon"
|
|
14
|
+
aria-label={
|
|
15
|
+
resolvedTheme === "dark"
|
|
16
|
+
? "Switch to light mode"
|
|
17
|
+
: "Switch to dark mode"
|
|
18
|
+
}
|
|
19
|
+
className={cn(resolvedTheme ? "opacity-100" : "opacity-0")}
|
|
20
|
+
onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
|
|
21
|
+
>
|
|
22
|
+
<ThemeIcon size={18} />
|
|
23
|
+
</Button>
|
|
25
24
|
);
|
|
26
25
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
|
|
3
|
+
export const CACHE_KEYS = Object.freeze({
|
|
4
|
+
API_IDENTITIES: ["api-identities"],
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
export const useCache = () => {
|
|
8
|
+
const queryClient = useQueryClient();
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
invalidateCache: async (key: keyof typeof CACHE_KEYS) => {
|
|
12
|
+
await queryClient.invalidateQueries({ queryKey: CACHE_KEYS[key] });
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -63,6 +63,7 @@ export const ViewportAnchorProvider = ({
|
|
|
63
63
|
const [activeAnchor, setActiveAnchor] = useState("");
|
|
64
64
|
const observerRef = useRef<IntersectionObserver | null>(null);
|
|
65
65
|
const registeredElements = useRef(new Set<HTMLElement>());
|
|
66
|
+
const pendingElements = useRef(new Set<HTMLElement>());
|
|
66
67
|
|
|
67
68
|
useEffect(() => {
|
|
68
69
|
observerRef.current = new IntersectionObserver(
|
|
@@ -81,6 +82,13 @@ export const ViewportAnchorProvider = ({
|
|
|
81
82
|
},
|
|
82
83
|
);
|
|
83
84
|
|
|
85
|
+
// Process any elements that tried to register before observer was ready
|
|
86
|
+
pendingElements.current.forEach((element) => {
|
|
87
|
+
registeredElements.current.add(element);
|
|
88
|
+
observerRef.current?.observe(element);
|
|
89
|
+
});
|
|
90
|
+
pendingElements.current.clear();
|
|
91
|
+
|
|
84
92
|
return () => observerRef.current?.disconnect();
|
|
85
93
|
}, []);
|
|
86
94
|
|
|
@@ -114,14 +122,22 @@ export const ViewportAnchorProvider = ({
|
|
|
114
122
|
const observeFns = useMemo(() => {
|
|
115
123
|
return {
|
|
116
124
|
observe: (element: HTMLElement | null) => {
|
|
117
|
-
if (!element
|
|
125
|
+
if (!element) return;
|
|
126
|
+
|
|
127
|
+
if (!observerRef.current) {
|
|
128
|
+
pendingElements.current.add(element);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
118
132
|
registeredElements.current.add(element);
|
|
119
133
|
observerRef.current.observe(element);
|
|
120
134
|
},
|
|
121
135
|
unobserve: (element: HTMLElement | null) => {
|
|
122
|
-
if (!element
|
|
136
|
+
if (!element) return;
|
|
137
|
+
|
|
138
|
+
pendingElements.current.delete(element);
|
|
123
139
|
registeredElements.current.delete(element);
|
|
124
|
-
observerRef.current
|
|
140
|
+
observerRef.current?.unobserve(element);
|
|
125
141
|
},
|
|
126
142
|
};
|
|
127
143
|
}, []);
|
|
@@ -132,8 +148,6 @@ export const ViewportAnchorProvider = ({
|
|
|
132
148
|
);
|
|
133
149
|
|
|
134
150
|
return (
|
|
135
|
-
<ViewportAnchorContext
|
|
136
|
-
{children}
|
|
137
|
-
</ViewportAnchorContext.Provider>
|
|
151
|
+
<ViewportAnchorContext value={value}>{children}</ViewportAnchorContext>
|
|
138
152
|
);
|
|
139
153
|
};
|
|
@@ -3,6 +3,7 @@ import { createContext, useContext } from "react";
|
|
|
3
3
|
import { matchPath, useLocation } from "react-router";
|
|
4
4
|
import { ZudokuContext } from "../../core/ZudokuContext.js";
|
|
5
5
|
import { joinPath } from "../../util/joinPath.js";
|
|
6
|
+
import { CACHE_KEYS } from "../cache.js";
|
|
6
7
|
import { traverseSidebar } from "../navigation/utils.js";
|
|
7
8
|
|
|
8
9
|
export const ZudokuReactContext = createContext<ZudokuContext | undefined>(
|
|
@@ -21,9 +22,10 @@ export const useZudoku = () => {
|
|
|
21
22
|
|
|
22
23
|
export const useApiIdentities = () => {
|
|
23
24
|
const { getApiIdentities } = useZudoku();
|
|
25
|
+
|
|
24
26
|
return useQuery({
|
|
25
27
|
queryFn: getApiIdentities,
|
|
26
|
-
queryKey: [
|
|
28
|
+
queryKey: [CACHE_KEYS.API_IDENTITIES],
|
|
27
29
|
});
|
|
28
30
|
};
|
|
29
31
|
|
|
@@ -6,16 +6,21 @@ import { RouterError as RouterErrorImport } from "../errors/RouterError.js";
|
|
|
6
6
|
import { ServerError as ServerErrorImport } from "../errors/ServerError.js";
|
|
7
7
|
import { Button as ButtonImport } from "../ui/Button.js";
|
|
8
8
|
import { Callout as CalloutImport } from "../ui/Callout.js";
|
|
9
|
-
import { Spinner as SpinnerImport } from "./Spinner.js";
|
|
10
|
-
import { Markdown as MarkdownImport } from "./Markdown.js";
|
|
11
9
|
import {
|
|
12
10
|
Bootstrap as BootstrapImport,
|
|
13
11
|
BootstrapStatic as BootstrapStaticImport,
|
|
14
12
|
} from "./Bootstrap.js";
|
|
15
13
|
import { ClientOnly as ClientOnlyImport } from "./ClientOnly.js";
|
|
16
14
|
import { Layout as LayoutImport } from "./Layout.js";
|
|
15
|
+
import { Markdown as MarkdownImport } from "./Markdown.js";
|
|
16
|
+
import { Spinner as SpinnerImport } from "./Spinner.js";
|
|
17
17
|
import { Zudoku as ZudokuImport } from "./Zudoku.js";
|
|
18
|
+
import {
|
|
19
|
+
CACHE_KEYS as CACHE_KEYS_IMPORT,
|
|
20
|
+
useCache as useCacheImport,
|
|
21
|
+
} from "./cache.js";
|
|
18
22
|
import { useZudoku as useZudokuImport } from "./context/ZudokuContext.js";
|
|
23
|
+
|
|
19
24
|
export const useMDXComponents = /*@__PURE__*/ useMDXComponentsImport;
|
|
20
25
|
export const Layout = /*@__PURE__*/ LayoutImport;
|
|
21
26
|
export const RouterError = /*@__PURE__*/ RouterErrorImport;
|
|
@@ -27,6 +32,8 @@ export const Head = /*@__PURE__*/ Helmet;
|
|
|
27
32
|
|
|
28
33
|
export const useZudoku = /*@__PURE__*/ useZudokuImport;
|
|
29
34
|
export const useAuth = /*@__PURE__*/ useAuthImport;
|
|
35
|
+
export const useCache = /*@__PURE__*/ useCacheImport;
|
|
36
|
+
export const CACHE_KEYS = /*@__PURE__*/ CACHE_KEYS_IMPORT;
|
|
30
37
|
export const Zudoku = /*@__PURE__*/ ZudokuImport;
|
|
31
38
|
|
|
32
39
|
export const Callout = /*@__PURE__*/ CalloutImport;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { matchPath, Outlet, useLocation } from "react-router";
|
|
3
|
+
import { useAuth } from "../authentication/hook.js";
|
|
4
|
+
import { useZudoku } from "../components/context/ZudokuContext.js";
|
|
5
|
+
import { ZudokuError } from "../util/invariant.js";
|
|
6
|
+
|
|
7
|
+
export const RouteGuard = () => {
|
|
8
|
+
const auth = useAuth();
|
|
9
|
+
const zudoku = useZudoku();
|
|
10
|
+
const location = useLocation();
|
|
11
|
+
|
|
12
|
+
const isProtected = zudoku.options.protectedRoutes?.some((path) =>
|
|
13
|
+
matchPath({ path, end: true }, location.pathname),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (isProtected && !auth.isAuthenticated) {
|
|
18
|
+
void zudoku.authentication?.signIn();
|
|
19
|
+
}
|
|
20
|
+
}, [isProtected, auth.isAuthenticated, zudoku.authentication]);
|
|
21
|
+
|
|
22
|
+
if (isProtected && !auth.isAuthenticated) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (isProtected && !auth.isAuthEnabled) {
|
|
27
|
+
throw new ZudokuError("Authentication is not enabled", {
|
|
28
|
+
title: "Authentication is not enabled",
|
|
29
|
+
developerHint:
|
|
30
|
+
"To use protectedRoutes you need authentication to be enabled",
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return <Outlet />;
|
|
35
|
+
};
|
|
@@ -65,6 +65,7 @@ export type ZudokuContextOptions = {
|
|
|
65
65
|
components?: MdxComponentsType;
|
|
66
66
|
};
|
|
67
67
|
overrides?: ComponentsContextType;
|
|
68
|
+
protectedRoutes?: string[];
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
export class ZudokuContext {
|
|
@@ -74,16 +75,16 @@ export class ZudokuContext {
|
|
|
74
75
|
public meta: ZudokuContextOptions["metadata"];
|
|
75
76
|
public page: ZudokuContextOptions["page"];
|
|
76
77
|
public authentication?: ZudokuContextOptions["authentication"];
|
|
77
|
-
private navigationPlugins: NavigationPlugin[];
|
|
78
|
+
private readonly navigationPlugins: NavigationPlugin[];
|
|
78
79
|
|
|
79
|
-
constructor(
|
|
80
|
-
this.plugins =
|
|
81
|
-
this.topNavigation =
|
|
82
|
-
this.sidebars =
|
|
80
|
+
constructor(public readonly options: ZudokuContextOptions) {
|
|
81
|
+
this.plugins = options.plugins ?? [];
|
|
82
|
+
this.topNavigation = options.topNavigation ?? [];
|
|
83
|
+
this.sidebars = options.sidebars ?? {};
|
|
83
84
|
this.navigationPlugins = this.plugins.filter(isNavigationPlugin);
|
|
84
|
-
this.authentication =
|
|
85
|
-
this.meta =
|
|
86
|
-
this.page =
|
|
85
|
+
this.authentication = options.authentication;
|
|
86
|
+
this.meta = options.metadata;
|
|
87
|
+
this.page = options.page;
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
initialize = async (): Promise<void> => {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { GraphQLJSON } from "graphql-type-json";
|
|
2
|
+
import { GraphQLScalarType } from "graphql/index.js";
|
|
3
|
+
|
|
4
|
+
export const CIRCULAR_REF = "$[Circular Reference]";
|
|
5
|
+
const handleCircularRefs = (obj: any, visited = new WeakSet()): any => {
|
|
6
|
+
if (obj === CIRCULAR_REF) return CIRCULAR_REF;
|
|
7
|
+
if (obj === null || typeof obj !== "object") return obj;
|
|
8
|
+
|
|
9
|
+
if (visited.has(obj)) return CIRCULAR_REF;
|
|
10
|
+
|
|
11
|
+
visited.add(obj);
|
|
12
|
+
|
|
13
|
+
if (Array.isArray(obj)) {
|
|
14
|
+
return obj.map((item) => handleCircularRefs(item, visited));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const result: Record<string, any> = {};
|
|
18
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
19
|
+
result[key] = handleCircularRefs(value, visited);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
export const GraphQLJSONSchema = new GraphQLScalarType({
|
|
24
|
+
...GraphQLJSON,
|
|
25
|
+
name: "JSONSchema",
|
|
26
|
+
description: "OpenAPI schema scalar type that handles circular references",
|
|
27
|
+
serialize: (value: unknown) =>
|
|
28
|
+
GraphQLJSON.serialize(handleCircularRefs(value)),
|
|
29
|
+
});
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import SchemaBuilder from "@pothos/core";
|
|
3
3
|
import {
|
|
4
|
-
slugifyWithCounter,
|
|
5
4
|
type CountableSlugify,
|
|
5
|
+
slugifyWithCounter,
|
|
6
6
|
} from "@sindresorhus/slugify";
|
|
7
7
|
import { GraphQLJSON, GraphQLJSONObject } from "graphql-type-json";
|
|
8
8
|
import { createYoga, type YogaServerOptions } from "graphql-yoga";
|
|
9
9
|
import {
|
|
10
|
-
HttpMethods,
|
|
11
|
-
validate,
|
|
12
10
|
type EncodingObject,
|
|
13
11
|
type ExampleObject,
|
|
12
|
+
HttpMethods,
|
|
14
13
|
type OpenAPIDocument,
|
|
15
14
|
type OperationObject,
|
|
16
15
|
type ParameterObject,
|
|
@@ -18,7 +17,9 @@ import {
|
|
|
18
17
|
type SchemaObject,
|
|
19
18
|
type ServerObject,
|
|
20
19
|
type TagObject,
|
|
20
|
+
validate,
|
|
21
21
|
} from "../parser/index.js";
|
|
22
|
+
import { GraphQLJSONSchema } from "./circular.js";
|
|
22
23
|
|
|
23
24
|
export type {
|
|
24
25
|
EncodingObject,
|
|
@@ -45,10 +46,7 @@ export const createOperationSlug = (
|
|
|
45
46
|
) => {
|
|
46
47
|
const summary =
|
|
47
48
|
(operation.summary ?? "") +
|
|
48
|
-
(operation.operationId
|
|
49
|
-
? "-" +
|
|
50
|
-
operation.operationId.slice(0, operation.summary ? Infinity : Infinity)
|
|
51
|
-
: "");
|
|
49
|
+
(operation.operationId ? "-" + operation.operationId : "");
|
|
52
50
|
|
|
53
51
|
return slugify(
|
|
54
52
|
(tag ? tag + "-" : "") +
|
|
@@ -65,6 +63,7 @@ const builder = new SchemaBuilder<{
|
|
|
65
63
|
Scalars: {
|
|
66
64
|
JSON: any;
|
|
67
65
|
JSONObject: any;
|
|
66
|
+
JSONSchema: any;
|
|
68
67
|
};
|
|
69
68
|
Context: {
|
|
70
69
|
schema: OpenAPIDocument;
|
|
@@ -74,6 +73,7 @@ const builder = new SchemaBuilder<{
|
|
|
74
73
|
|
|
75
74
|
const JSONScalar = builder.addScalarType("JSON", GraphQLJSON);
|
|
76
75
|
const JSONObjectScalar = builder.addScalarType("JSONObject", GraphQLJSONObject);
|
|
76
|
+
const JSONSchemaScalar = builder.addScalarType("JSONSchema", GraphQLJSONSchema);
|
|
77
77
|
|
|
78
78
|
const getAllTags = (schema: OpenAPIDocument): TagObject[] => {
|
|
79
79
|
const tags = schema.tags ?? [];
|
|
@@ -238,7 +238,7 @@ const ParameterItem = builder
|
|
|
238
238
|
})),
|
|
239
239
|
nullable: true,
|
|
240
240
|
}),
|
|
241
|
-
schema: t.expose("schema", { type:
|
|
241
|
+
schema: t.expose("schema", { type: JSONSchemaScalar, nullable: true }),
|
|
242
242
|
}),
|
|
243
243
|
});
|
|
244
244
|
|
|
@@ -252,7 +252,7 @@ const MediaTypeItem = builder
|
|
|
252
252
|
.implement({
|
|
253
253
|
fields: (t) => ({
|
|
254
254
|
mediaType: t.exposeString("mediaType"),
|
|
255
|
-
schema: t.expose("schema", { type:
|
|
255
|
+
schema: t.expose("schema", { type: JSONSchemaScalar, nullable: true }),
|
|
256
256
|
examples: t.expose("examples", { type: [ExampleItem], nullable: true }),
|
|
257
257
|
encoding: t.expose("encoding", { type: [EncodingItem], nullable: true }),
|
|
258
258
|
}),
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { JSONSchema4, JSONSchema6 } from "json-schema";
|
|
2
|
+
import { CIRCULAR_REF } from "../../graphql/circular.js";
|
|
2
3
|
import { resolveLocalRef } from "./resolveRef.js";
|
|
3
4
|
|
|
4
5
|
export type JSONSchema = JSONSchema4 | JSONSchema6;
|
|
5
6
|
|
|
6
|
-
export const CIRCULAR_REF = "$[Circular Reference]";
|
|
7
|
-
|
|
8
7
|
type CustomResolver = (ref: string) => Promise<JSONSchema | undefined>;
|
|
9
8
|
|
|
10
9
|
const cache = new Map<JSONSchema, JSONSchema>();
|
|
@@ -2,7 +2,7 @@ import { useMDXComponents } from "@mdx-js/react";
|
|
|
2
2
|
import slugify from "@sindresorhus/slugify";
|
|
3
3
|
import { Helmet } from "@zudoku/react-helmet-async";
|
|
4
4
|
import { type PropsWithChildren, useEffect } from "react";
|
|
5
|
-
import { Link } from "react-router";
|
|
5
|
+
import { Link, useHref } from "react-router";
|
|
6
6
|
import { CategoryHeading } from "../../components/CategoryHeading.js";
|
|
7
7
|
import { Heading } from "../../components/Heading.js";
|
|
8
8
|
import { ProseClasses } from "../../components/Markdown.js";
|
|
@@ -51,6 +51,13 @@ export const MdxPage = ({
|
|
|
51
51
|
}
|
|
52
52
|
>) => {
|
|
53
53
|
const categoryTitle = useCurrentItem()?.categoryLabel;
|
|
54
|
+
let canonicalUrl = null;
|
|
55
|
+
const path = useHref("");
|
|
56
|
+
if (typeof window !== "undefined") {
|
|
57
|
+
const domain = window.location.origin;
|
|
58
|
+
canonicalUrl = `${domain}${path}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
const title = frontmatter.title;
|
|
55
62
|
const category = frontmatter.category ?? categoryTitle;
|
|
56
63
|
const hideToc = frontmatter.toc === false || defaultOptions?.toc === false;
|
|
@@ -87,6 +94,7 @@ export const MdxPage = ({
|
|
|
87
94
|
<Helmet>
|
|
88
95
|
<title>{pageTitle}</title>
|
|
89
96
|
{excerpt && <meta name="description" content={excerpt} />}
|
|
97
|
+
{canonicalUrl && <link rel="canonical" href={canonicalUrl} />}
|
|
90
98
|
</Helmet>
|
|
91
99
|
<div
|
|
92
100
|
className={cn(
|
|
@@ -95,7 +95,6 @@ export const OperationListItem = ({
|
|
|
95
95
|
level={3}
|
|
96
96
|
className="capitalize"
|
|
97
97
|
id={`${operation.slug}/request-body`}
|
|
98
|
-
registerSidebarAnchor
|
|
99
98
|
>
|
|
100
99
|
Request Body
|
|
101
100
|
</Heading>
|
|
@@ -108,7 +107,6 @@ export const OperationListItem = ({
|
|
|
108
107
|
level={3}
|
|
109
108
|
className="capitalize mt-8 pt-8 border-t"
|
|
110
109
|
id={`${operation.slug}/responses`}
|
|
111
|
-
registerSidebarAnchor
|
|
112
110
|
>
|
|
113
111
|
Responses
|
|
114
112
|
</Heading>
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import type { OperationListItemResult } from "./OperationList.js";
|
|
2
2
|
import { PlaygroundDialog } from "./playground/PlaygroundDialog.js";
|
|
3
|
+
import { Content } from "./SidecarExamples.js";
|
|
3
4
|
|
|
4
5
|
export const PlaygroundDialogWrapper = ({
|
|
5
6
|
server,
|
|
6
7
|
servers,
|
|
7
8
|
operation,
|
|
9
|
+
examples,
|
|
8
10
|
}: {
|
|
9
11
|
server: string;
|
|
10
12
|
servers?: string[];
|
|
11
13
|
operation: OperationListItemResult;
|
|
14
|
+
examples?: Content;
|
|
12
15
|
}) => {
|
|
13
16
|
const headers = operation.parameters
|
|
14
17
|
?.filter((p) => p.in === "header")
|
|
15
18
|
.map((p) => ({
|
|
16
19
|
name: p.name,
|
|
17
20
|
defaultValue: p.examples?.find((x) => x.value)?.value ?? "",
|
|
21
|
+
defaultActive: false,
|
|
18
22
|
}));
|
|
19
23
|
const queryParams = operation.parameters
|
|
20
24
|
?.filter((p) => p.in === "query")
|
|
@@ -39,6 +43,7 @@ export const PlaygroundDialogWrapper = ({
|
|
|
39
43
|
headers={headers}
|
|
40
44
|
queryParams={queryParams}
|
|
41
45
|
pathParams={pathParams}
|
|
46
|
+
examples={examples}
|
|
42
47
|
/>
|
|
43
48
|
);
|
|
44
49
|
};
|
|
@@ -99,7 +99,7 @@ export const Sidecar = ({
|
|
|
99
99
|
selectedResponse?: string;
|
|
100
100
|
onSelectResponse: (response: string) => void;
|
|
101
101
|
}) => {
|
|
102
|
-
const { input, type } = useOasConfig();
|
|
102
|
+
const { input, type, options } = useOasConfig();
|
|
103
103
|
const query = useCreateQuery(GetServerQuery, { input, type });
|
|
104
104
|
const result = useSuspenseQuery(query);
|
|
105
105
|
|
|
@@ -109,7 +109,8 @@ export const Sidecar = ({
|
|
|
109
109
|
const [, startTransition] = useTransition();
|
|
110
110
|
const [selectedExample, setSelectedExample] = useState<unknown>();
|
|
111
111
|
|
|
112
|
-
const selectedLang =
|
|
112
|
+
const selectedLang =
|
|
113
|
+
searchParams.get("lang") ?? options?.examplesDefaultLanguage ?? "shell";
|
|
113
114
|
|
|
114
115
|
const requestBodyContent = operation.requestBody?.content;
|
|
115
116
|
|
|
@@ -198,6 +199,7 @@ export const Sidecar = ({
|
|
|
198
199
|
server={result.data.schema.url}
|
|
199
200
|
servers={result.data.schema.servers.map((server) => server.url)}
|
|
200
201
|
operation={operation}
|
|
202
|
+
examples={requestBodyContent ?? undefined}
|
|
201
203
|
/>
|
|
202
204
|
)}
|
|
203
205
|
</SidecarBox.Head>
|
|
@@ -2,7 +2,6 @@ import { matchPath } from "react-router";
|
|
|
2
2
|
import { type ZudokuPlugin } from "../../core/plugins.js";
|
|
3
3
|
import { graphql } from "./graphql/index.js";
|
|
4
4
|
|
|
5
|
-
import { useQuery } from "@tanstack/react-query";
|
|
6
5
|
import { CirclePlayIcon, LogInIcon } from "lucide-react";
|
|
7
6
|
import type { SidebarItem } from "../../../config/validators/SidebarSchema.js";
|
|
8
7
|
import { useAuth } from "../../authentication/hook.js";
|
|
@@ -81,18 +80,15 @@ export const openApiPlugin = (config: OpenApiPluginOptions): ZudokuPlugin => {
|
|
|
81
80
|
method,
|
|
82
81
|
url,
|
|
83
82
|
...props
|
|
84
|
-
}: Partial<PlaygroundContentProps> &
|
|
83
|
+
}: Partial<PlaygroundContentProps> &
|
|
84
|
+
Pick<PlaygroundContentProps, "server"> & {
|
|
85
|
+
requireAuth: boolean;
|
|
86
|
+
}) => {
|
|
85
87
|
const auth = useAuth();
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
type: config.type,
|
|
91
|
-
input: config.input,
|
|
92
|
-
}),
|
|
93
|
-
enabled: !server,
|
|
94
|
-
queryKey: ["playground-server"],
|
|
95
|
-
});
|
|
88
|
+
|
|
89
|
+
if (!server) {
|
|
90
|
+
throw new Error("Server is required");
|
|
91
|
+
}
|
|
96
92
|
|
|
97
93
|
if (requireAuth && !auth.isAuthenticated) {
|
|
98
94
|
return (
|
|
@@ -110,9 +106,7 @@ export const openApiPlugin = (config: OpenApiPluginOptions): ZudokuPlugin => {
|
|
|
110
106
|
<PlaygroundDialog
|
|
111
107
|
url={url ?? "/"}
|
|
112
108
|
method={method ?? "get"}
|
|
113
|
-
server={
|
|
114
|
-
server ?? serverQuery.data?.schema.url ?? "https://example.com"
|
|
115
|
-
}
|
|
109
|
+
server={server}
|
|
116
110
|
{...props}
|
|
117
111
|
>
|
|
118
112
|
<Button className="gap-2 items-center" variant="outline">
|
|
@@ -20,7 +20,14 @@ export type OasPluginConfig = {
|
|
|
20
20
|
server?: string;
|
|
21
21
|
navigationId?: string;
|
|
22
22
|
skipPreload?: boolean;
|
|
23
|
-
} &
|
|
23
|
+
} & OasPluginConfigOptions &
|
|
24
|
+
OasSource;
|
|
25
|
+
|
|
26
|
+
export type OasPluginConfigOptions = {
|
|
27
|
+
options?: {
|
|
28
|
+
examplesDefaultLanguage?: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
24
31
|
|
|
25
32
|
export type OasPluginContext = {
|
|
26
33
|
server?: string;
|
|
@@ -28,4 +35,5 @@ export type OasPluginContext = {
|
|
|
28
35
|
skipPreload?: boolean;
|
|
29
36
|
version?: string;
|
|
30
37
|
versions: Record<string, string>;
|
|
31
|
-
} & ContextOasSource
|
|
38
|
+
} & ContextOasSource &
|
|
39
|
+
OasPluginConfigOptions;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Button } from "zudoku/ui/Button.js";
|
|
2
|
+
import {
|
|
3
|
+
DropdownMenu,
|
|
4
|
+
DropdownMenuContent,
|
|
5
|
+
DropdownMenuGroup,
|
|
6
|
+
DropdownMenuItem,
|
|
7
|
+
DropdownMenuLabel,
|
|
8
|
+
DropdownMenuSeparator,
|
|
9
|
+
DropdownMenuTrigger,
|
|
10
|
+
} from "zudoku/ui/DropdownMenu.js";
|
|
11
|
+
import { Content, Example } from "../SidecarExamples.js";
|
|
12
|
+
|
|
13
|
+
const ExamplesDropdown = ({
|
|
14
|
+
examples,
|
|
15
|
+
onSelect,
|
|
16
|
+
}: {
|
|
17
|
+
examples: Content;
|
|
18
|
+
onSelect: (example: Example) => void;
|
|
19
|
+
}) => {
|
|
20
|
+
return (
|
|
21
|
+
<div className="flex flex-col gap-2 mt-2 items-end">
|
|
22
|
+
<DropdownMenu>
|
|
23
|
+
<DropdownMenuTrigger asChild>
|
|
24
|
+
<Button variant="outline">Use Example</Button>
|
|
25
|
+
</DropdownMenuTrigger>
|
|
26
|
+
<DropdownMenuContent className="w-56">
|
|
27
|
+
{examples.map((example) => {
|
|
28
|
+
return (
|
|
29
|
+
<div key={example.mediaType}>
|
|
30
|
+
<DropdownMenuLabel>{example.mediaType}</DropdownMenuLabel>
|
|
31
|
+
<DropdownMenuSeparator />
|
|
32
|
+
<DropdownMenuGroup>
|
|
33
|
+
{example.examples?.map((example) => {
|
|
34
|
+
return (
|
|
35
|
+
<DropdownMenuItem
|
|
36
|
+
key={example.name}
|
|
37
|
+
onSelect={() => onSelect(example)}
|
|
38
|
+
className="line-clamp-1"
|
|
39
|
+
>
|
|
40
|
+
{example.summary ?? example.name}
|
|
41
|
+
</DropdownMenuItem>
|
|
42
|
+
);
|
|
43
|
+
})}
|
|
44
|
+
</DropdownMenuGroup>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
})}
|
|
48
|
+
</DropdownMenuContent>
|
|
49
|
+
</DropdownMenu>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default ExamplesDropdown;
|