zudoku 0.28.3 → 0.29.1
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/entry.server.d.ts +1 -1
- package/dist/cli/common/output.js.map +1 -1
- package/dist/cli/dev/handler.js +5 -0
- package/dist/cli/dev/handler.js.map +1 -1
- package/dist/config/validators/common.d.ts +111 -0
- package/dist/config/validators/common.js +9 -6
- package/dist/config/validators/common.js.map +1 -1
- package/dist/config/validators/validate.d.ts +42 -0
- package/dist/lib/authentication/state.d.ts +9 -0
- package/dist/lib/authentication/state.js +11 -0
- package/dist/lib/authentication/state.js.map +1 -1
- package/dist/lib/components/Autocomplete.d.ts +4 -3
- package/dist/lib/components/Autocomplete.js +2 -2
- package/dist/lib/components/Autocomplete.js.map +1 -1
- package/dist/lib/components/PathRenderer.js +23 -20
- package/dist/lib/components/PathRenderer.js.map +1 -1
- package/dist/lib/components/navigation/SidebarItem.js +1 -0
- package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
- package/dist/lib/oas/graphql/index.d.ts +7 -0
- package/dist/lib/oas/graphql/index.js +7 -6
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/plugins/openapi/Endpoint.js +6 -7
- package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationList.js +11 -7
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +4 -4
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.d.ts +2 -2
- package/dist/lib/plugins/openapi/graphql/gql.js +2 -2
- package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/graphql.d.ts +20 -4
- package/dist/lib/plugins/openapi/graphql/graphql.js +16 -2
- package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +57 -28
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/interfaces.d.ts +4 -2
- package/dist/lib/plugins/openapi/playground/Headers.d.ts +3 -2
- package/dist/lib/plugins/openapi/playground/Headers.js +42 -26
- package/dist/lib/plugins/openapi/playground/Headers.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/ParamsGrid.d.ts +4 -0
- package/dist/lib/plugins/openapi/playground/ParamsGrid.js +2 -1
- package/dist/lib/plugins/openapi/playground/ParamsGrid.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/PathParams.js +3 -3
- package/dist/lib/plugins/openapi/playground/PathParams.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.d.ts +1 -0
- package/dist/lib/plugins/openapi/playground/Playground.js +4 -4
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/QueryParams.js +21 -21
- package/dist/lib/plugins/openapi/playground/QueryParams.js.map +1 -1
- package/dist/lib/ui/Input.d.ts +1 -2
- package/dist/lib/ui/Input.js.map +1 -1
- package/dist/lib/util/useScrollToAnchor.js +1 -1
- package/dist/lib/util/useScrollToAnchor.js.map +1 -1
- package/dist/lib/util/useScrollToTop.js +6 -4
- package/dist/lib/util/useScrollToTop.js.map +1 -1
- package/dist/vite/build.js +1 -1
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/plugin-api.js +13 -6
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/plugin-config.js +2 -1
- package/dist/vite/plugin-config.js.map +1 -1
- package/dist/vite/plugin-mdx.js +18 -12
- package/dist/vite/plugin-mdx.js.map +1 -1
- package/dist/vite/plugin.js.map +1 -1
- package/dist/vite/{prerender.d.ts → prerender/FileWritingResponse.d.ts} +0 -6
- package/dist/vite/prerender/FileWritingResponse.js +42 -0
- package/dist/vite/prerender/FileWritingResponse.js.map +1 -0
- package/dist/vite/prerender/prerender.d.ts +6 -0
- package/dist/vite/prerender/prerender.js +68 -0
- package/dist/vite/prerender/prerender.js.map +1 -0
- package/dist/vite/prerender/worker.d.ts +9 -0
- package/dist/vite/prerender/worker.js +27 -0
- package/dist/vite/prerender/worker.js.map +1 -0
- package/lib/{Markdown-LcMEZ0Sn.js → Markdown-8mv9nhGd.js} +3338 -3360
- package/lib/Markdown-8mv9nhGd.js.map +1 -0
- package/lib/{MdxPage-DkH3V4hV.js → MdxPage-BalfwlsD.js} +3 -3
- package/lib/{MdxPage-DkH3V4hV.js.map → MdxPage-BalfwlsD.js.map} +1 -1
- package/lib/{OperationList-wzZNceUl.js → OperationList-B3VX94x4.js} +500 -493
- package/lib/OperationList-B3VX94x4.js.map +1 -0
- package/lib/{Select-DJkXPPD0.js → Select-BcAbBUmk.js} +2 -2
- package/lib/{Select-DJkXPPD0.js.map → Select-BcAbBUmk.js.map} +1 -1
- package/lib/{SlotletProvider-D1t2ePCI.js → SlotletProvider-D0mFmGJu.js} +2 -2
- package/lib/{SlotletProvider-D1t2ePCI.js.map → SlotletProvider-D0mFmGJu.js.map} +1 -1
- package/lib/{createServer-DIztAu7i.js → createServer-E3cXjB0P.js} +4 -6
- package/lib/{createServer-DIztAu7i.js.map → createServer-E3cXjB0P.js.map} +1 -1
- package/lib/{hook-CiX69UZ6.js → hook-NIpDSpau.js} +2 -2
- package/lib/{hook-CiX69UZ6.js.map → hook-NIpDSpau.js.map} +1 -1
- package/lib/{index-DrR58fsJ.js → index-P0YUtHIb.js} +802 -745
- package/lib/index-P0YUtHIb.js.map +1 -0
- package/lib/state-bfQxaDxU.js +211 -0
- package/lib/{state-mM7uaXTW.js.map → state-bfQxaDxU.js.map} +1 -1
- package/lib/ui/Input.js.map +1 -1
- package/lib/{useScrollToAnchor-DYGn1MT9.js → useScrollToAnchor-BVCQSeKB.js} +29 -28
- package/lib/{useScrollToAnchor-DYGn1MT9.js.map → useScrollToAnchor-BVCQSeKB.js.map} +1 -1
- package/lib/zudoku.auth-auth0.js +1 -1
- package/lib/zudoku.auth-clerk.js +1 -1
- package/lib/zudoku.auth-openid.js +1 -1
- package/lib/zudoku.components.js +348 -347
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.plugin-api-catalog.js +2 -2
- package/lib/zudoku.plugin-api-keys.js +3 -3
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +2 -2
- package/package.json +3 -1
- package/src/app/demo-cdn.html +31 -31
- package/src/app/entry.server.tsx +1 -1
- package/src/lib/authentication/state.ts +18 -0
- package/src/lib/components/Autocomplete.tsx +6 -4
- package/src/lib/components/PathRenderer.tsx +6 -4
- package/src/lib/components/navigation/SidebarItem.tsx +1 -0
- package/src/lib/oas/graphql/index.ts +10 -9
- package/src/lib/plugins/openapi/Endpoint.tsx +11 -9
- package/src/lib/plugins/openapi/OperationList.tsx +16 -10
- package/src/lib/plugins/openapi/Sidecar.tsx +4 -4
- package/src/lib/plugins/openapi/graphql/gql.ts +4 -4
- package/src/lib/plugins/openapi/graphql/graphql.ts +30 -6
- package/src/lib/plugins/openapi/index.tsx +74 -41
- package/src/lib/plugins/openapi/interfaces.ts +5 -10
- package/src/lib/plugins/openapi/playground/Headers.tsx +125 -89
- package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +6 -1
- package/src/lib/plugins/openapi/playground/PathParams.tsx +9 -9
- package/src/lib/plugins/openapi/playground/Playground.tsx +7 -4
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +88 -86
- package/src/lib/ui/Input.tsx +1 -2
- package/src/lib/util/useScrollToAnchor.ts +1 -1
- package/src/lib/util/useScrollToTop.ts +8 -3
- package/dist/vite/prerender.js +0 -89
- package/dist/vite/prerender.js.map +0 -1
- package/lib/Markdown-LcMEZ0Sn.js.map +0 -1
- package/lib/OperationList-wzZNceUl.js.map +0 -1
- package/lib/index-DrR58fsJ.js.map +0 -1
- package/lib/state-mM7uaXTW.js +0 -202
|
@@ -3,8 +3,8 @@ import { s as j } from "./index-CjJS0l4l.js";
|
|
|
3
3
|
import { u as b } from "./ZudokuContext-dUyBGMap.js";
|
|
4
4
|
import { b as y } from "./chunk-SYFQ2XB5-QijJrSf0.js";
|
|
5
5
|
import { Head as v, Link as N } from "./zudoku.components.js";
|
|
6
|
-
import { u as w } from "./state-
|
|
7
|
-
import { M as C } from "./Markdown-
|
|
6
|
+
import { u as w } from "./state-bfQxaDxU.js";
|
|
7
|
+
import { M as C } from "./Markdown-8mv9nhGd.js";
|
|
8
8
|
import { c as h } from "./cn-qaFjX9_3.js";
|
|
9
9
|
const f = (r, n) => j(`${r}-${n}`), k = ({
|
|
10
10
|
items: r,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-Bdg6XQ1m.js";
|
|
2
2
|
import { RotateCwIcon as g, TrashIcon as f, EyeOffIcon as j, EyeIcon as v, CheckIcon as w, CopyIcon as b, FileKey2Icon as K } from "lucide-react";
|
|
3
|
-
import { D as k, S as m, R as N } from "./SlotletProvider-
|
|
3
|
+
import { D as k, S as m, R as N } from "./SlotletProvider-D0mFmGJu.js";
|
|
4
4
|
import { i as c } from "./invariant-Caa8-XvF.js";
|
|
5
|
-
import { u as d, S as I, a as S, b as A, c as C, d as E, e as x } from "./Select-
|
|
5
|
+
import { u as d, S as I, a as S, b as A, c as C, d as E, e as x } from "./Select-BcAbBUmk.js";
|
|
6
6
|
import { a as P } from "./index.esm-CrSoEshU.js";
|
|
7
7
|
import { a as D, L as u, O as R } from "./chunk-SYFQ2XB5-QijJrSf0.js";
|
|
8
8
|
import { a as y, e as q, u as O } from "./ZudokuContext-dUyBGMap.js";
|
|
9
9
|
import { Button as l } from "./ui/Button.js";
|
|
10
10
|
import { Input as z } from "./ui/Input.js";
|
|
11
|
-
import { u as F } from "./hook-
|
|
11
|
+
import { u as F } from "./hook-NIpDSpau.js";
|
|
12
12
|
import { useState as p } from "react";
|
|
13
13
|
import { c as T } from "./cn-qaFjX9_3.js";
|
|
14
14
|
const L = ({ service: t }) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as o } from "./jsx-runtime-Bdg6XQ1m.js";
|
|
2
2
|
import a from "react";
|
|
3
|
-
import { P as n } from "./Markdown-
|
|
3
|
+
import { P as n } from "./Markdown-8mv9nhGd.js";
|
|
4
4
|
import { c } from "./cn-qaFjX9_3.js";
|
|
5
5
|
import { u as p } from "./useExposedProps-Bbf99zic.js";
|
|
6
6
|
const u = ({
|
|
@@ -74,7 +74,7 @@ const C = (n) => ({
|
|
|
74
74
|
const h = {
|
|
75
75
|
path: r,
|
|
76
76
|
lazy: async () => {
|
|
77
|
-
const { MdxPage: l } = await import("./MdxPage-
|
|
77
|
+
const { MdxPage: l } = await import("./MdxPage-BalfwlsD.js"), { default: p, ...g } = await a();
|
|
78
78
|
return {
|
|
79
79
|
element: /* @__PURE__ */ P.jsx(
|
|
80
80
|
l,
|
|
@@ -2,10 +2,10 @@ import "./jsx-runtime-Bdg6XQ1m.js";
|
|
|
2
2
|
import "./index-CjJS0l4l.js";
|
|
3
3
|
import "lucide-react";
|
|
4
4
|
import "./chunk-SYFQ2XB5-QijJrSf0.js";
|
|
5
|
-
import "./hook-
|
|
5
|
+
import "./hook-NIpDSpau.js";
|
|
6
6
|
import "./ui/Button.js";
|
|
7
7
|
import "./joinUrl-nLx9pD-Z.js";
|
|
8
|
-
import { o as f } from "./index-
|
|
8
|
+
import { o as f } from "./index-P0YUtHIb.js";
|
|
9
9
|
export {
|
|
10
10
|
f as openApiPlugin
|
|
11
11
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://zudoku.dev",
|
|
6
6
|
"repository": {
|
|
@@ -177,6 +177,7 @@
|
|
|
177
177
|
"object-hash": "3.0.0",
|
|
178
178
|
"openapi-types": "12.1.3",
|
|
179
179
|
"picocolors": "1.1.1",
|
|
180
|
+
"piscina": "5.0.0-alpha.1",
|
|
180
181
|
"postcss": "8.5.1",
|
|
181
182
|
"posthog-node": "4.4.1",
|
|
182
183
|
"prism-react-renderer": "2.4.1",
|
|
@@ -185,6 +186,7 @@
|
|
|
185
186
|
"react-hook-form": "7.54.2",
|
|
186
187
|
"react-is": "19.0.0",
|
|
187
188
|
"react-router": "7.1.3",
|
|
189
|
+
"rehype-mdx-import-media": "1.2.0",
|
|
188
190
|
"rehype-raw": "7.0.0",
|
|
189
191
|
"rehype-slug": "6.0.0",
|
|
190
192
|
"remark-comment": "1.0.0",
|
package/src/app/demo-cdn.html
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link
|
|
6
|
+
rel="icon"
|
|
7
|
+
type="image/svg+xml"
|
|
8
|
+
href="https://cdn.zudoku.dev/logos/favicon.svg"
|
|
9
|
+
/>
|
|
10
|
+
<meta
|
|
11
|
+
name="viewport"
|
|
12
|
+
content="width=device-width, initial-scale=1.0, minimum-scale=1.0"
|
|
13
|
+
/>
|
|
14
|
+
<title>Zudoku Demo</title>
|
|
15
|
+
<script
|
|
16
|
+
type="module"
|
|
17
|
+
crossorigin
|
|
18
|
+
src="https://cdn.zudoku.dev/latest/demo.js"
|
|
19
|
+
></script>
|
|
20
|
+
<link
|
|
21
|
+
rel="stylesheet"
|
|
22
|
+
crossorigin
|
|
23
|
+
href="https://cdn.zudoku.dev/latest/style.css"
|
|
24
|
+
/>
|
|
25
|
+
<script>
|
|
26
|
+
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init push capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
27
|
+
posthog.init('phc_l8rjm0vHBMwNdGeBRDrK8UIYjyVxZyBAtnYo2hS18OY',{api_host:'https://us.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well
|
|
28
|
+
})
|
|
29
|
+
</script>
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
<div id="root"></div>
|
|
33
|
+
</body>
|
|
34
34
|
</html>
|
package/src/app/entry.server.tsx
CHANGED
|
@@ -13,7 +13,7 @@ import "virtual:zudoku-theme.css";
|
|
|
13
13
|
import "vite/modulepreload-polyfill";
|
|
14
14
|
import { BootstrapStatic, ServerError } from "zudoku/components";
|
|
15
15
|
import type { ZudokuConfig } from "../config/config.js";
|
|
16
|
-
import type { FileWritingResponse } from "../vite/prerender.js";
|
|
16
|
+
import type { FileWritingResponse } from "../vite/prerender/FileWritingResponse.js";
|
|
17
17
|
import "./main.css";
|
|
18
18
|
import { getRoutesByConfig } from "./main.js";
|
|
19
19
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
1
2
|
import { create, type Mutate, type StoreApi } from "zustand";
|
|
2
3
|
import { createJSONStorage, persist } from "zustand/middleware";
|
|
3
4
|
|
|
@@ -77,3 +78,20 @@ export const useSelectedServerStore = create<SelectedServerState>()(
|
|
|
77
78
|
{ name: "zudoku-selected-server" },
|
|
78
79
|
),
|
|
79
80
|
);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Simple wrapper for `useSelectedServerStore` to fall back to first of the provided servers
|
|
84
|
+
*/
|
|
85
|
+
export const useSelectedServer = (servers: Array<{ url: string }>) => {
|
|
86
|
+
const { selectedServer, setSelectedServer } = useSelectedServerStore();
|
|
87
|
+
|
|
88
|
+
const finalSelectedServer = useMemo(
|
|
89
|
+
() =>
|
|
90
|
+
selectedServer && servers.some((s) => s.url === selectedServer)
|
|
91
|
+
? selectedServer
|
|
92
|
+
: (servers.at(0)?.url ?? ""),
|
|
93
|
+
[selectedServer, servers],
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
return { selectedServer: finalSelectedServer, setSelectedServer };
|
|
97
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PopoverAnchor } from "@radix-ui/react-popover";
|
|
2
2
|
import { useCommandState } from "cmdk";
|
|
3
|
-
import { useRef, useState, type Ref } from "react";
|
|
3
|
+
import { useRef, useState, type KeyboardEvent, type Ref } from "react";
|
|
4
4
|
import {
|
|
5
5
|
Command,
|
|
6
6
|
CommandInlineInput,
|
|
@@ -16,8 +16,9 @@ type AutocompleteProps = {
|
|
|
16
16
|
onChange: (e: string) => void;
|
|
17
17
|
className?: string;
|
|
18
18
|
placeholder?: string;
|
|
19
|
-
onEnterPress?: (e:
|
|
19
|
+
onEnterPress?: (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
20
20
|
ref?: Ref<HTMLInputElement>;
|
|
21
|
+
shouldFilter?: boolean;
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
const AutocompletePopover = ({
|
|
@@ -33,6 +34,7 @@ const AutocompletePopover = ({
|
|
|
33
34
|
const [dontClose, setDontClose] = useState(false);
|
|
34
35
|
const count = useCommandState((state) => state.filtered.count);
|
|
35
36
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
37
|
+
|
|
36
38
|
return (
|
|
37
39
|
<Popover open={open}>
|
|
38
40
|
<PopoverAnchor>
|
|
@@ -102,9 +104,9 @@ const AutocompletePopover = ({
|
|
|
102
104
|
);
|
|
103
105
|
};
|
|
104
106
|
|
|
105
|
-
export const Autocomplete = (props: AutocompleteProps) => {
|
|
107
|
+
export const Autocomplete = ({ shouldFilter, ...props }: AutocompleteProps) => {
|
|
106
108
|
return (
|
|
107
|
-
<Command className="bg-transparent">
|
|
109
|
+
<Command className="bg-transparent" shouldFilter={shouldFilter}>
|
|
108
110
|
<AutocompletePopover {...props} />
|
|
109
111
|
</Command>
|
|
110
112
|
);
|
|
@@ -12,13 +12,14 @@ export const PathRenderer = ({
|
|
|
12
12
|
}: {
|
|
13
13
|
path: string;
|
|
14
14
|
renderParam: (props: PathParamProps) => ReactNode;
|
|
15
|
-
}) =>
|
|
16
|
-
|
|
15
|
+
}) => {
|
|
16
|
+
let paramIndex = 0;
|
|
17
|
+
return path.split("/").map((part, i, arr) => {
|
|
17
18
|
const matches = Array.from(part.matchAll(/{([^}]+)}/g));
|
|
18
19
|
const elements: ReactNode[] = [];
|
|
19
20
|
let lastIndex = 0;
|
|
20
21
|
|
|
21
|
-
matches.forEach((match
|
|
22
|
+
matches.forEach((match) => {
|
|
22
23
|
const [originalValue, name] = match;
|
|
23
24
|
if (!name) return;
|
|
24
25
|
const startIndex = match.index!;
|
|
@@ -33,7 +34,7 @@ export const PathRenderer = ({
|
|
|
33
34
|
|
|
34
35
|
elements.push(
|
|
35
36
|
<Fragment key={`param-${name}`}>
|
|
36
|
-
{renderParam({ name, originalValue, index:
|
|
37
|
+
{renderParam({ name, originalValue, index: paramIndex++ })}
|
|
37
38
|
</Fragment>,
|
|
38
39
|
);
|
|
39
40
|
|
|
@@ -57,3 +58,4 @@ export const PathRenderer = ({
|
|
|
57
58
|
</Fragment>
|
|
58
59
|
);
|
|
59
60
|
});
|
|
61
|
+
};
|
|
@@ -90,6 +90,7 @@ export const SidebarItem = ({
|
|
|
90
90
|
) : !item.href.startsWith("http") ? (
|
|
91
91
|
<NavLink
|
|
92
92
|
className={navigationListItem({
|
|
93
|
+
isActive: item.href.split("#")[1] === activeAnchor,
|
|
93
94
|
className: item.badge?.placement !== "start" && "justify-between",
|
|
94
95
|
})}
|
|
95
96
|
to={item.href}
|
|
@@ -45,13 +45,12 @@ export const createOperationSlug = (
|
|
|
45
45
|
tag?: string,
|
|
46
46
|
) => {
|
|
47
47
|
const summary =
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
operation.summary ||
|
|
49
|
+
operation.operationId ||
|
|
50
|
+
`${operation.method}-${operation.path}`;
|
|
51
|
+
const prefix = tag ? `${tag}-` : "";
|
|
50
52
|
|
|
51
|
-
return slugify(
|
|
52
|
-
(tag ? tag + "-" : "") +
|
|
53
|
-
(summary || `${operation.method}-${operation.path}`),
|
|
54
|
-
);
|
|
53
|
+
return slugify(prefix + summary);
|
|
55
54
|
};
|
|
56
55
|
|
|
57
56
|
export type SchemaImports = Record<
|
|
@@ -104,7 +103,9 @@ export const getAllTags = (schema: OpenAPIDocument): TagObject[] => {
|
|
|
104
103
|
];
|
|
105
104
|
};
|
|
106
105
|
|
|
107
|
-
const getAllOperations = (
|
|
106
|
+
export const getAllOperations = (
|
|
107
|
+
paths?: PathsObject,
|
|
108
|
+
): GraphQLOperationObject[] => {
|
|
108
109
|
const operations = Object.entries(paths ?? {}).flatMap(([path, value]) =>
|
|
109
110
|
HttpMethods.flatMap((method) => {
|
|
110
111
|
if (!value?.[method]) return [];
|
|
@@ -132,7 +133,7 @@ const getAllOperations = (paths?: PathsObject) => {
|
|
|
132
133
|
path,
|
|
133
134
|
parameters,
|
|
134
135
|
tags: operation.tags ?? [],
|
|
135
|
-
};
|
|
136
|
+
} satisfies GraphQLOperationObject;
|
|
136
137
|
}),
|
|
137
138
|
);
|
|
138
139
|
|
|
@@ -141,7 +142,7 @@ const getAllOperations = (paths?: PathsObject) => {
|
|
|
141
142
|
|
|
142
143
|
const SchemaTag = builder.objectRef<TagObject>("SchemaTag").implement({
|
|
143
144
|
fields: (t) => ({
|
|
144
|
-
name: t.exposeString("name"
|
|
145
|
+
name: t.exposeString("name"),
|
|
145
146
|
description: t.exposeString("description", { nullable: true }),
|
|
146
147
|
operations: t.field({
|
|
147
148
|
type: [OperationItem],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
2
2
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
3
3
|
import { useState, useTransition } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { useSelectedServer } from "../../authentication/state.js";
|
|
5
5
|
import { InlineCode } from "../../components/InlineCode.js";
|
|
6
6
|
import { Button } from "../../ui/Button.js";
|
|
7
7
|
import { useCreateQuery } from "./client/useCreateQuery.js";
|
|
@@ -48,20 +48,24 @@ export const Endpoint = () => {
|
|
|
48
48
|
const query = useCreateQuery(ServersQuery, { input, type });
|
|
49
49
|
const result = useSuspenseQuery(query);
|
|
50
50
|
const [, startTransition] = useTransition();
|
|
51
|
-
const { selectedServer, setSelectedServer } =
|
|
51
|
+
const { selectedServer, setSelectedServer } = useSelectedServer(
|
|
52
|
+
result.data.schema.servers,
|
|
53
|
+
);
|
|
52
54
|
|
|
53
55
|
const { servers } = result.data.schema;
|
|
54
56
|
|
|
55
57
|
if (servers.length === 0) return null;
|
|
56
58
|
|
|
59
|
+
const firstServer = servers.at(0)!;
|
|
60
|
+
|
|
57
61
|
if (servers.length === 1) {
|
|
58
62
|
return (
|
|
59
63
|
<div className="flex items-center gap-2">
|
|
60
64
|
<span className="font-medium text-sm">Endpoint:</span>
|
|
61
65
|
<InlineCode className="text-xs px-2 py-1.5" selectOnClick>
|
|
62
|
-
{
|
|
66
|
+
{firstServer.url}
|
|
63
67
|
</InlineCode>
|
|
64
|
-
<CopyButton url={
|
|
68
|
+
<CopyButton url={firstServer.url} />
|
|
65
69
|
</div>
|
|
66
70
|
);
|
|
67
71
|
}
|
|
@@ -73,18 +77,16 @@ export const Endpoint = () => {
|
|
|
73
77
|
<SimpleSelect
|
|
74
78
|
className="font-mono text-xs bg-border/50 dark:bg-border/70 py-1.5 max-w-[450px] truncate"
|
|
75
79
|
onChange={(e) =>
|
|
76
|
-
startTransition(() =>
|
|
77
|
-
setSelectedServer(e.target.value);
|
|
78
|
-
})
|
|
80
|
+
startTransition(() => setSelectedServer(e.target.value))
|
|
79
81
|
}
|
|
80
|
-
value={selectedServer
|
|
82
|
+
value={selectedServer}
|
|
81
83
|
showChevrons={servers.length > 1}
|
|
82
84
|
options={servers.map((server) => ({
|
|
83
85
|
value: server.url,
|
|
84
86
|
label: server.url,
|
|
85
87
|
}))}
|
|
86
88
|
/>
|
|
87
|
-
<CopyButton url={selectedServer
|
|
89
|
+
<CopyButton url={selectedServer} />
|
|
88
90
|
</div>
|
|
89
91
|
);
|
|
90
92
|
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
SelectTrigger,
|
|
10
10
|
SelectValue,
|
|
11
11
|
} from "zudoku/ui/Select.js";
|
|
12
|
-
import {
|
|
12
|
+
import { useSelectedServer } from "../../authentication/state.js";
|
|
13
13
|
import { CategoryHeading } from "../../components/CategoryHeading.js";
|
|
14
14
|
import { Heading } from "../../components/Heading.js";
|
|
15
15
|
import { Markdown, ProseClasses } from "../../components/Markdown.js";
|
|
@@ -96,6 +96,9 @@ const AllOperationsQuery = graphql(/* GraphQL */ `
|
|
|
96
96
|
$untagged: Boolean
|
|
97
97
|
) {
|
|
98
98
|
schema(input: $input, type: $type) {
|
|
99
|
+
servers {
|
|
100
|
+
url
|
|
101
|
+
}
|
|
99
102
|
description
|
|
100
103
|
summary
|
|
101
104
|
title
|
|
@@ -127,13 +130,16 @@ export const OperationList = ({
|
|
|
127
130
|
tag,
|
|
128
131
|
untagged,
|
|
129
132
|
});
|
|
130
|
-
const { selectedServer } = useSelectedServerStore();
|
|
131
133
|
const result = useSuspenseQuery(query);
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
const {
|
|
135
|
+
data: { schema },
|
|
136
|
+
} = result;
|
|
137
|
+
const { selectedServer } = useSelectedServer(schema.servers);
|
|
138
|
+
const title = schema.title;
|
|
139
|
+
const summary = schema.summary;
|
|
140
|
+
const description = schema.description;
|
|
135
141
|
const navigate = useNavigate();
|
|
136
|
-
const operations =
|
|
142
|
+
const operations = schema.operations;
|
|
137
143
|
// Prefetch for Playground
|
|
138
144
|
useApiIdentities();
|
|
139
145
|
|
|
@@ -184,7 +190,7 @@ export const OperationList = ({
|
|
|
184
190
|
)}
|
|
185
191
|
</div>
|
|
186
192
|
</div>
|
|
187
|
-
<Markdown content={
|
|
193
|
+
<Markdown content={schema.description ?? ""} />
|
|
188
194
|
</div>
|
|
189
195
|
<hr />
|
|
190
196
|
<div className="my-4 flex items-center justify-end gap-4">
|
|
@@ -192,12 +198,12 @@ export const OperationList = ({
|
|
|
192
198
|
</div>
|
|
193
199
|
{operations.map((fragment) => (
|
|
194
200
|
<OperationListItem
|
|
195
|
-
serverUrl={selectedServer
|
|
201
|
+
serverUrl={selectedServer}
|
|
196
202
|
key={fragment.slug}
|
|
197
203
|
operationFragment={fragment}
|
|
198
204
|
/>
|
|
199
205
|
))}
|
|
200
|
-
{/* {
|
|
206
|
+
{/* {schema.tags
|
|
201
207
|
.filter((tag) => tag.operations.length > 0)
|
|
202
208
|
.map((tag) => (
|
|
203
209
|
// px, -mx is so that `content-visibility` doesn't cut off overflown heading anchor links '#'
|
|
@@ -213,7 +219,7 @@ export const OperationList = ({
|
|
|
213
219
|
<StaggeredRender>
|
|
214
220
|
{tag.operations.map((fragment) => (
|
|
215
221
|
<OperationListItem
|
|
216
|
-
serverUrl={selectedServer ??
|
|
222
|
+
serverUrl={selectedServer ?? schema.url}
|
|
217
223
|
key={fragment.slug}
|
|
218
224
|
operationFragment={fragment}
|
|
219
225
|
/>
|
|
@@ -2,7 +2,7 @@ import { useSuspenseQuery } from "@tanstack/react-query";
|
|
|
2
2
|
import { HTTPSnippet } from "@zudoku/httpsnippet";
|
|
3
3
|
import { useMemo, useState, useTransition } from "react";
|
|
4
4
|
import { useSearchParams } from "react-router";
|
|
5
|
-
import {
|
|
5
|
+
import { useSelectedServer } from "../../authentication/state.js";
|
|
6
6
|
import { PathRenderer } from "../../components/PathRenderer.js";
|
|
7
7
|
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
8
8
|
import type { SchemaObject } from "../../oas/parser/index.js";
|
|
@@ -131,7 +131,7 @@ export const Sidecar = ({
|
|
|
131
131
|
/>
|
|
132
132
|
);
|
|
133
133
|
|
|
134
|
-
const { selectedServer } =
|
|
134
|
+
const { selectedServer } = useSelectedServer(result.data.schema.servers);
|
|
135
135
|
|
|
136
136
|
const code = useMemo(() => {
|
|
137
137
|
const example =
|
|
@@ -143,7 +143,7 @@ export const Sidecar = ({
|
|
|
143
143
|
const snippet = new HTTPSnippet({
|
|
144
144
|
method: operation.method.toLocaleUpperCase(),
|
|
145
145
|
url:
|
|
146
|
-
|
|
146
|
+
selectedServer +
|
|
147
147
|
operation.path.replaceAll("{", ":").replaceAll("}", ""),
|
|
148
148
|
postData: example
|
|
149
149
|
? {
|
|
@@ -187,7 +187,7 @@ export const Sidecar = ({
|
|
|
187
187
|
</span>
|
|
188
188
|
{isOnScreen && (
|
|
189
189
|
<PlaygroundDialogWrapper
|
|
190
|
-
server={
|
|
190
|
+
server={selectedServer}
|
|
191
191
|
servers={result.data.schema.servers.map((server) => server.url)}
|
|
192
192
|
operation={operation}
|
|
193
193
|
examples={requestBodyContent ?? undefined}
|
|
@@ -17,13 +17,13 @@ const documents = {
|
|
|
17
17
|
types.ServersQueryDocument,
|
|
18
18
|
"\n fragment OperationsFragment on OperationItem {\n slug\n summary\n method\n description\n operationId\n contentTypes\n path\n parameters {\n name\n in\n description\n required\n schema\n style\n examples {\n name\n description\n externalValue\n value\n summary\n }\n }\n requestBody {\n content {\n mediaType\n encoding {\n name\n }\n examples {\n name\n description\n externalValue\n value\n summary\n }\n schema\n }\n description\n required\n }\n responses {\n statusCode\n links\n description\n content {\n examples {\n name\n description\n externalValue\n value\n summary\n }\n mediaType\n encoding {\n name\n }\n schema\n }\n }\n }\n":
|
|
19
19
|
types.OperationsFragmentFragmentDoc,
|
|
20
|
-
"\n query AllOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n description\n summary\n title\n url\n version\n tags(name: $tag) {\n name\n description\n }\n operations(tag: $tag, untagged: $untagged) {\n slug\n ...OperationsFragment\n }\n }\n }\n":
|
|
20
|
+
"\n query AllOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n servers {\n url\n }\n description\n summary\n title\n url\n version\n tags(name: $tag) {\n name\n description\n }\n operations(tag: $tag, untagged: $untagged) {\n slug\n ...OperationsFragment\n }\n }\n }\n":
|
|
21
21
|
types.AllOperationsDocument,
|
|
22
22
|
"\n query getServerQuery($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n servers {\n url\n }\n }\n }\n":
|
|
23
23
|
types.GetServerQueryDocument,
|
|
24
24
|
"\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n tags {\n name\n }\n }\n }\n":
|
|
25
25
|
types.GetCategoriesDocument,
|
|
26
|
-
"\n query GetOperations(
|
|
26
|
+
"\n query GetOperations($input: JSON!, $type: SchemaType!, $tag: String) {\n schema(input: $input, type: $type) {\n operations(tag: $tag) {\n slug\n deprecated\n method\n summary\n operationId\n path\n tags {\n name\n }\n }\n untagged: operations(untagged: true) {\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n":
|
|
27
27
|
types.GetOperationsDocument,
|
|
28
28
|
};
|
|
29
29
|
|
|
@@ -43,7 +43,7 @@ export function graphql(
|
|
|
43
43
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
44
44
|
*/
|
|
45
45
|
export function graphql(
|
|
46
|
-
source: "\n query AllOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n description\n summary\n title\n url\n version\n tags(name: $tag) {\n name\n description\n }\n operations(tag: $tag, untagged: $untagged) {\n slug\n ...OperationsFragment\n }\n }\n }\n",
|
|
46
|
+
source: "\n query AllOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n servers {\n url\n }\n description\n summary\n title\n url\n version\n tags(name: $tag) {\n name\n description\n }\n operations(tag: $tag, untagged: $untagged) {\n slug\n ...OperationsFragment\n }\n }\n }\n",
|
|
47
47
|
): typeof import("./graphql.js").AllOperationsDocument;
|
|
48
48
|
/**
|
|
49
49
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
@@ -61,7 +61,7 @@ export function graphql(
|
|
|
61
61
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
62
62
|
*/
|
|
63
63
|
export function graphql(
|
|
64
|
-
source: "\n query GetOperations(
|
|
64
|
+
source: "\n query GetOperations($input: JSON!, $type: SchemaType!, $tag: String) {\n schema(input: $input, type: $type) {\n operations(tag: $tag) {\n slug\n deprecated\n method\n summary\n operationId\n path\n tags {\n name\n }\n }\n untagged: operations(untagged: true) {\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n",
|
|
65
65
|
): typeof import("./graphql.js").GetOperationsDocument;
|
|
66
66
|
|
|
67
67
|
export function graphql(source: string) {
|
|
@@ -156,7 +156,7 @@ export type SchemaTagsArgs = {
|
|
|
156
156
|
export type SchemaTag = {
|
|
157
157
|
__typename?: "SchemaTag";
|
|
158
158
|
description?: Maybe<Scalars["String"]["output"]>;
|
|
159
|
-
name
|
|
159
|
+
name: Scalars["String"]["output"];
|
|
160
160
|
operations: Array<OperationItem>;
|
|
161
161
|
};
|
|
162
162
|
|
|
@@ -271,9 +271,10 @@ export type AllOperationsQuery = {
|
|
|
271
271
|
title: string;
|
|
272
272
|
url?: string | null;
|
|
273
273
|
version: string;
|
|
274
|
+
servers: Array<{ __typename?: "Server"; url: string }>;
|
|
274
275
|
tags: Array<{
|
|
275
276
|
__typename?: "SchemaTag";
|
|
276
|
-
name
|
|
277
|
+
name: string;
|
|
277
278
|
description?: string | null;
|
|
278
279
|
}>;
|
|
279
280
|
operations: Array<
|
|
@@ -310,7 +311,7 @@ export type GetCategoriesQuery = {
|
|
|
310
311
|
schema: {
|
|
311
312
|
__typename?: "Schema";
|
|
312
313
|
url?: string | null;
|
|
313
|
-
tags: Array<{ __typename?: "SchemaTag"; name
|
|
314
|
+
tags: Array<{ __typename?: "SchemaTag"; name: string }>;
|
|
314
315
|
};
|
|
315
316
|
};
|
|
316
317
|
|
|
@@ -318,7 +319,6 @@ export type GetOperationsQueryVariables = Exact<{
|
|
|
318
319
|
input: Scalars["JSON"]["input"];
|
|
319
320
|
type: SchemaType;
|
|
320
321
|
tag?: InputMaybe<Scalars["String"]["input"]>;
|
|
321
|
-
untagged?: InputMaybe<Scalars["Boolean"]["input"]>;
|
|
322
322
|
}>;
|
|
323
323
|
|
|
324
324
|
export type GetOperationsQuery = {
|
|
@@ -333,6 +333,16 @@ export type GetOperationsQuery = {
|
|
|
333
333
|
summary?: string | null;
|
|
334
334
|
operationId?: string | null;
|
|
335
335
|
path: string;
|
|
336
|
+
tags?: Array<{ __typename?: "TagItem"; name: string }> | null;
|
|
337
|
+
}>;
|
|
338
|
+
untagged: Array<{
|
|
339
|
+
__typename?: "OperationItem";
|
|
340
|
+
slug: string;
|
|
341
|
+
deprecated?: boolean | null;
|
|
342
|
+
method: string;
|
|
343
|
+
summary?: string | null;
|
|
344
|
+
operationId?: string | null;
|
|
345
|
+
path: string;
|
|
336
346
|
}>;
|
|
337
347
|
};
|
|
338
348
|
};
|
|
@@ -436,6 +446,9 @@ export const ServersQueryDocument = new TypedDocumentString(`
|
|
|
436
446
|
export const AllOperationsDocument = new TypedDocumentString(`
|
|
437
447
|
query AllOperations($input: JSON!, $type: SchemaType!, $tag: String, $untagged: Boolean) {
|
|
438
448
|
schema(input: $input, type: $type) {
|
|
449
|
+
servers {
|
|
450
|
+
url
|
|
451
|
+
}
|
|
439
452
|
description
|
|
440
453
|
summary
|
|
441
454
|
title
|
|
@@ -542,9 +555,20 @@ export const GetCategoriesDocument = new TypedDocumentString(`
|
|
|
542
555
|
GetCategoriesQueryVariables
|
|
543
556
|
>;
|
|
544
557
|
export const GetOperationsDocument = new TypedDocumentString(`
|
|
545
|
-
query GetOperations($input: JSON!, $type: SchemaType!, $tag: String
|
|
558
|
+
query GetOperations($input: JSON!, $type: SchemaType!, $tag: String) {
|
|
546
559
|
schema(input: $input, type: $type) {
|
|
547
|
-
operations(tag: $tag
|
|
560
|
+
operations(tag: $tag) {
|
|
561
|
+
slug
|
|
562
|
+
deprecated
|
|
563
|
+
method
|
|
564
|
+
summary
|
|
565
|
+
operationId
|
|
566
|
+
path
|
|
567
|
+
tags {
|
|
568
|
+
name
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
untagged: operations(untagged: true) {
|
|
548
572
|
slug
|
|
549
573
|
deprecated
|
|
550
574
|
method
|