zudoku 0.3.0-dev.116 → 0.3.0-dev.119
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/demo.js +3 -1
- package/dist/app/demo.js.map +1 -1
- package/dist/app/main.js +1 -1
- package/dist/app/main.js.map +1 -1
- package/dist/app/standalone.js +3 -1
- package/dist/app/standalone.js.map +1 -1
- package/dist/cli/dev/handler.js +1 -1
- package/dist/lib/components/Markdown.js +3 -2
- package/dist/lib/components/Markdown.js.map +1 -1
- package/dist/lib/components/navigation/SidebarCategory.js +6 -2
- package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
- package/dist/lib/components/navigation/SidebarItem.js +3 -2
- package/dist/lib/components/navigation/SidebarItem.js.map +1 -1
- package/dist/lib/oas/graphql/index.js +17 -2
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js +1 -1
- package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
- package/dist/lib/plugins/openapi/OperationListItem.js +6 -4
- package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
- package/dist/lib/plugins/openapi/ParameterList.js +3 -1
- package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.d.ts +3 -1
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js +5 -9
- package/dist/lib/plugins/openapi/ResponsesSidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.d.ts +3 -1
- package/dist/lib/plugins/openapi/Sidecar.js +6 -4
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/schema/SchemaComponents.d.ts +13 -0
- package/dist/lib/plugins/openapi/schema/SchemaComponents.js +28 -0
- package/dist/lib/plugins/openapi/schema/SchemaComponents.js.map +1 -0
- package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +6 -0
- package/dist/lib/plugins/openapi/schema/SchemaView.js +44 -0
- package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -0
- package/dist/lib/plugins/openapi/schema/utils.d.ts +3 -0
- package/dist/lib/plugins/openapi/schema/utils.js +6 -0
- package/dist/lib/plugins/openapi/schema/utils.js.map +1 -0
- package/dist/lib/themeToggle.d.ts +1 -0
- package/dist/lib/themeToggle.js +7 -0
- package/dist/lib/themeToggle.js.map +1 -0
- package/dist/lib/util/MdxComponents.js +4 -4
- package/dist/lib/util/MdxComponents.js.map +1 -1
- package/dist/vite/config.d.ts +4 -5
- package/dist/vite/config.js +7 -4
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/config.test.js +2 -2
- package/dist/vite/config.test.js.map +1 -1
- package/dist/vite/dev-server.d.ts +0 -1
- package/dist/vite/dev-server.js +2 -21
- package/dist/vite/dev-server.js.map +1 -1
- package/dist/vite/html.js +2 -11
- package/dist/vite/html.js.map +1 -1
- package/dist/vite/plugin-api-keys.d.ts +3 -3
- package/dist/vite/plugin-api-keys.js +2 -1
- package/dist/vite/plugin-api-keys.js.map +1 -1
- package/dist/vite/plugin-api.d.ts +3 -3
- package/dist/vite/plugin-api.js +2 -1
- package/dist/vite/plugin-api.js.map +1 -1
- package/dist/vite/plugin-auth.d.ts +3 -3
- package/dist/vite/plugin-auth.js +2 -1
- package/dist/vite/plugin-auth.js.map +1 -1
- package/dist/vite/plugin-component.d.ts +3 -3
- package/dist/vite/plugin-component.js +17 -14
- package/dist/vite/plugin-component.js.map +1 -1
- package/dist/vite/plugin-config-reload.d.ts +4 -0
- package/dist/vite/plugin-config-reload.js +24 -0
- package/dist/vite/plugin-config-reload.js.map +1 -0
- package/dist/vite/plugin-config.d.ts +2 -2
- package/dist/vite/plugin-config.js.map +1 -1
- package/dist/vite/plugin-custom-css.d.ts +3 -3
- package/dist/vite/plugin-custom-css.js +2 -1
- package/dist/vite/plugin-custom-css.js.map +1 -1
- package/dist/vite/plugin-docs.d.ts +3 -3
- package/dist/vite/plugin-docs.js +3 -2
- package/dist/vite/plugin-docs.js.map +1 -1
- package/dist/vite/plugin-html-transform.d.ts +2 -0
- package/dist/vite/plugin-html-transform.js +15 -0
- package/dist/vite/plugin-html-transform.js.map +1 -0
- package/dist/vite/plugin-mdx.d.ts +3 -3
- package/dist/vite/plugin-mdx.js +2 -1
- package/dist/vite/plugin-mdx.js.map +1 -1
- package/dist/vite/plugin-metadata.d.ts +1 -1
- package/dist/vite/plugin-redirect.d.ts +3 -3
- package/dist/vite/plugin-redirect.js +2 -1
- package/dist/vite/plugin-redirect.js.map +1 -1
- package/dist/vite/plugin-sidebar.d.ts +3 -3
- package/dist/vite/plugin-sidebar.js +2 -1
- package/dist/vite/plugin-sidebar.js.map +1 -1
- package/dist/vite/plugin.d.ts +3 -2
- package/dist/vite/plugin.js +16 -11
- package/dist/vite/plugin.js.map +1 -1
- package/lib/{CategoryHeading-BWq12Bfa.js → CategoryHeading-z15xh7Jb.js} +2 -2
- package/lib/{CategoryHeading-BWq12Bfa.js.map → CategoryHeading-z15xh7Jb.js.map} +1 -1
- package/lib/{Combination-D-9IH0zy.js → Combination-DTfV-c98.js} +2 -2
- package/lib/{Combination-D-9IH0zy.js.map → Combination-DTfV-c98.js.map} +1 -1
- package/lib/{Input-HmAaR6kw.js → Input-DB9VROFR.js} +3 -3
- package/lib/{Input-HmAaR6kw.js.map → Input-DB9VROFR.js.map} +1 -1
- package/lib/Markdown-CEccPMI_.js +20508 -0
- package/lib/Markdown-CEccPMI_.js.map +1 -0
- package/lib/{MdxPage-oN3huD58.js → MdxPage-CnqOoqvp.js} +12 -15
- package/lib/MdxPage-CnqOoqvp.js.map +1 -0
- package/lib/OperationList-MFaKgMyg.js +414 -0
- package/lib/OperationList-MFaKgMyg.js.map +1 -0
- package/lib/{Route-DAF15JAU.js → Route-CL9hUSJ2.js} +2 -2
- package/lib/{Route-DAF15JAU.js.map → Route-CL9hUSJ2.js.map} +1 -1
- package/lib/{SlotletProvider-BG2PU1Mf.js → SlotletProvider-ByLSCZQa.js} +3 -3
- package/lib/{SlotletProvider-BG2PU1Mf.js.map → SlotletProvider-ByLSCZQa.js.map} +1 -1
- package/lib/{Spinner-BCz1kNGw.js → Spinner-BT_AYFrA.js} +3 -3
- package/lib/{Spinner-BCz1kNGw.js.map → Spinner-BT_AYFrA.js.map} +1 -1
- package/lib/assets/{worker-CR7aeKop.js → worker-TEvS6miZ.js} +709 -702
- package/lib/assets/{worker-CR7aeKop.js.map → worker-TEvS6miZ.js.map} +1 -1
- package/lib/{index-CtKkHGcd.js → index-Bf5yypxf.js} +671 -640
- package/lib/{index-CtKkHGcd.js.map → index-Bf5yypxf.js.map} +1 -1
- package/lib/{index-D-9Z7HSn.js → index-Dz4LyXZI.js} +3 -3
- package/lib/{index-D-9Z7HSn.js.map → index-Dz4LyXZI.js.map} +1 -1
- package/lib/zudoku.components.js +494 -481
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.openapi-worker.js +733 -726
- package/lib/zudoku.openapi-worker.js.map +1 -1
- package/lib/zudoku.plugin-api-keys.js +4 -4
- package/lib/zudoku.plugin-custom-page.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +3 -3
- package/package.json +2 -1
- package/src/app/demo.tsx +4 -1
- package/src/app/main.tsx +1 -1
- package/src/app/standalone.tsx +4 -1
- package/src/lib/components/Markdown.tsx +3 -2
- package/src/lib/components/navigation/SidebarCategory.tsx +13 -2
- package/src/lib/components/navigation/SidebarItem.tsx +3 -2
- package/src/lib/oas/graphql/index.ts +24 -5
- package/src/lib/plugins/markdown/MdxPage.tsx +0 -1
- package/src/lib/plugins/openapi/OperationListItem.tsx +18 -8
- package/src/lib/plugins/openapi/ParameterList.tsx +10 -8
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +51 -39
- package/src/lib/plugins/openapi/Sidecar.tsx +13 -4
- package/src/lib/plugins/openapi/schema/SchemaComponents.tsx +126 -0
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +112 -0
- package/src/lib/plugins/openapi/schema/utils.ts +10 -0
- package/src/lib/themeToggle.ts +7 -0
- package/src/lib/util/MdxComponents.tsx +12 -12
- package/dist/lib/plugins/openapi/SchemaListView.d.ts +0 -7
- package/dist/lib/plugins/openapi/SchemaListView.js +0 -27
- package/dist/lib/plugins/openapi/SchemaListView.js.map +0 -1
- package/dist/lib/plugins/openapi/SchemaListViewItem.d.ts +0 -8
- package/dist/lib/plugins/openapi/SchemaListViewItem.js +0 -25
- package/dist/lib/plugins/openapi/SchemaListViewItem.js.map +0 -1
- package/dist/lib/plugins/openapi/SchemaListViewItemGroup.d.ts +0 -8
- package/dist/lib/plugins/openapi/SchemaListViewItemGroup.js +0 -17
- package/dist/lib/plugins/openapi/SchemaListViewItemGroup.js.map +0 -1
- package/lib/Markdown-B_Gax7at.js +0 -14108
- package/lib/Markdown-B_Gax7at.js.map +0 -1
- package/lib/MdxPage-oN3huD58.js.map +0 -1
- package/lib/OperationList-Ctj0ihBN.js +0 -448
- package/lib/OperationList-Ctj0ihBN.js.map +0 -1
- package/src/lib/plugins/openapi/SchemaListView.tsx +0 -75
- package/src/lib/plugins/openapi/SchemaListViewItem.tsx +0 -125
- package/src/lib/plugins/openapi/SchemaListViewItemGroup.tsx +0 -63
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-B6kdoens.js";
|
|
2
|
-
import { S as p, R as f } from "./SlotletProvider-
|
|
3
|
-
import { u as g, a as u, I as j, S as k, b as v, c as w, d as b, e as K, f as y } from "./Input-
|
|
2
|
+
import { S as p, R as f } from "./SlotletProvider-ByLSCZQa.js";
|
|
3
|
+
import { u as g, a as u, I as j, S as k, b as v, c as w, d as b, e as K, f as y } from "./Input-DB9VROFR.js";
|
|
4
4
|
import { b as N, L as x, O as E } from "./index-7kcHaXD6.js";
|
|
5
5
|
import { u as h, t as A, j as S } from "./ZudokuContext-BIZ8zHbZ.js";
|
|
6
|
-
import { B as l, p as I } from "./Combination-
|
|
6
|
+
import { B as l, p as I } from "./Combination-DTfV-c98.js";
|
|
7
7
|
import { D as P } from "./DeveloperHint-BQSFXH01.js";
|
|
8
8
|
import { useState as C } from "react";
|
|
9
|
-
import { c as d, a as D } from "./Markdown-
|
|
9
|
+
import { c as d, a as D } from "./Markdown-CEccPMI_.js";
|
|
10
10
|
/**
|
|
11
11
|
* @license lucide-react v0.378.0 - ISC
|
|
12
12
|
*
|
|
@@ -6,7 +6,7 @@ const u = (t, e) => Object.entries(t).flatMap(([a, r]) => {
|
|
|
6
6
|
return {
|
|
7
7
|
path: s.at(-1) === "index" ? s.slice(0, -1).join("/") : o,
|
|
8
8
|
lazy: async () => {
|
|
9
|
-
const { MdxPage: i } = await import("./MdxPage-
|
|
9
|
+
const { MdxPage: i } = await import("./MdxPage-CnqOoqvp.js"), { default: p, ...c } = await r();
|
|
10
10
|
return {
|
|
11
11
|
element: /* @__PURE__ */ m.jsx(
|
|
12
12
|
i,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./jsx-runtime-B6kdoens.js";
|
|
2
|
-
import { o as l } from "./index-
|
|
2
|
+
import { o as l } from "./index-Bf5yypxf.js";
|
|
3
3
|
import "./urql-DrBfkb92.js";
|
|
4
4
|
import "./ZudokuContext-BIZ8zHbZ.js";
|
|
5
5
|
import "zudoku/openapi-worker";
|
|
6
|
-
import "./Combination-
|
|
7
|
-
import "./Markdown-
|
|
6
|
+
import "./Combination-DTfV-c98.js";
|
|
7
|
+
import "./Markdown-CEccPMI_.js";
|
|
8
8
|
import "./joinPath-B7kNnUX4.js";
|
|
9
9
|
import "./router-BiRCp01d.js";
|
|
10
10
|
import "./index-7kcHaXD6.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.119",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -128,6 +128,7 @@
|
|
|
128
128
|
"react-is": "18.3.1",
|
|
129
129
|
"react-markdown": "9.0.1",
|
|
130
130
|
"react-router-dom": "6.25.1",
|
|
131
|
+
"rehype-raw": "7.0.0",
|
|
131
132
|
"rehype-slug": "6.0.0",
|
|
132
133
|
"remark-comment": "1.0.0",
|
|
133
134
|
"remark-directive": "3.0.0",
|
package/src/app/demo.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { createBrowserRouter } from "react-router-dom";
|
|
|
4
4
|
import { Bootstrap } from "zudoku/components";
|
|
5
5
|
import type { ZudokuConfig } from "../config/validators/validate.js";
|
|
6
6
|
import { openApiPlugin } from "../lib/plugins/openapi/index.js";
|
|
7
|
+
import { themeToggle } from "../lib/themeToggle.js";
|
|
7
8
|
import "../lib/util/logInit.js";
|
|
8
9
|
import "./main.css";
|
|
9
10
|
import { getRoutesByConfig } from "./main.js";
|
|
@@ -16,6 +17,8 @@ if (!apiUrl) {
|
|
|
16
17
|
);
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
themeToggle();
|
|
21
|
+
|
|
19
22
|
logger.info(`API URL: ${apiUrl}`);
|
|
20
23
|
|
|
21
24
|
const root =
|
|
@@ -51,6 +54,6 @@ const config = {
|
|
|
51
54
|
|
|
52
55
|
const routes = getRoutesByConfig(config);
|
|
53
56
|
const router = createBrowserRouter(routes, {
|
|
54
|
-
basename:
|
|
57
|
+
basename: window.location.pathname,
|
|
55
58
|
});
|
|
56
59
|
createRoot(root).render(<Bootstrap router={router} />);
|
package/src/app/main.tsx
CHANGED
|
@@ -9,9 +9,9 @@ import "virtual:zudoku-theme.css";
|
|
|
9
9
|
import { DevPortal, Layout, RouterError } from "zudoku/components";
|
|
10
10
|
import { isNavigationPlugin } from "zudoku/internal";
|
|
11
11
|
import { customPagePlugin } from "zudoku/plugins/custom-page";
|
|
12
|
+
import { inkeepSearchPlugin } from "zudoku/plugins/search-inkeep";
|
|
12
13
|
import type { ZudokuConfig } from "../config/config.js";
|
|
13
14
|
import type { ZudokuContextOptions } from "../lib/core/DevPortalContext.js";
|
|
14
|
-
import { inkeepSearchPlugin } from "../lib/plugins/search-inkeep/index.js";
|
|
15
15
|
|
|
16
16
|
export const convertZudokuConfigToOptions = (
|
|
17
17
|
config: ZudokuConfig,
|
package/src/app/standalone.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { createBrowserRouter } from "react-router-dom";
|
|
|
3
3
|
import { Bootstrap } from "zudoku/components";
|
|
4
4
|
import type { ZudokuConfig } from "../config/validators/validate.js";
|
|
5
5
|
import { openApiPlugin } from "../lib/plugins/openapi/index.js";
|
|
6
|
+
import { themeToggle } from "../lib/themeToggle.js";
|
|
6
7
|
import "../lib/util/logInit.js";
|
|
7
8
|
import "./main.css";
|
|
8
9
|
import { getRoutesByConfig } from "./main.js";
|
|
@@ -12,6 +13,8 @@ if (!root) {
|
|
|
12
13
|
throw new Error("No div found with attribute data-api-url");
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
themeToggle();
|
|
17
|
+
|
|
15
18
|
const apiUrl = root.getAttribute("data-api-url");
|
|
16
19
|
const pageTitle = document.getElementsByTagName("title")[0].innerText;
|
|
17
20
|
const logoUrl = root.getAttribute("data-logo-url");
|
|
@@ -50,6 +53,6 @@ const config = {
|
|
|
50
53
|
|
|
51
54
|
const routes = getRoutesByConfig(config);
|
|
52
55
|
const router = createBrowserRouter(routes, {
|
|
53
|
-
basename:
|
|
56
|
+
basename: window.location.pathname,
|
|
54
57
|
});
|
|
55
58
|
createRoot(root).render(<Bootstrap router={router} />);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ReactMarkdown from "react-markdown";
|
|
2
|
+
import rehypeRaw from "rehype-raw";
|
|
2
3
|
import remarkGfm from "remark-gfm";
|
|
3
4
|
import { visit } from "unist-util-visit";
|
|
4
5
|
import { MdxComponents } from "../util/MdxComponents.js";
|
|
@@ -8,13 +9,13 @@ import { MdxComponents } from "../util/MdxComponents.js";
|
|
|
8
9
|
const rehypeCodeBlockPlugin = () => (tree: any) => {
|
|
9
10
|
visit(tree, "element", (node, _index, parent) => {
|
|
10
11
|
if (node.tagName === "code") {
|
|
11
|
-
node.properties.inline = parent?.tagName !== "pre";
|
|
12
|
+
node.properties.inline = String(parent?.tagName !== "pre");
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
const remarkPlugins = [remarkGfm];
|
|
17
|
-
const rehypePlugins = [rehypeCodeBlockPlugin];
|
|
18
|
+
const rehypePlugins = [rehypeCodeBlockPlugin, rehypeRaw];
|
|
18
19
|
|
|
19
20
|
// other styles are defined in main.css .prose
|
|
20
21
|
export const ProseClasses = "prose dark:prose-invert prose-neutral";
|
|
@@ -18,6 +18,7 @@ export const SidebarCategory = ({
|
|
|
18
18
|
}) => {
|
|
19
19
|
const topNavItem = useTopNavigationItem();
|
|
20
20
|
const isCategoryOpen = useIsCategoryOpen(category);
|
|
21
|
+
const [hasInteracted, setHasInteracted] = useState(false);
|
|
21
22
|
|
|
22
23
|
const isCollapsible = category.collapsible ?? true;
|
|
23
24
|
const isCollapsed = category.collapsed ?? true;
|
|
@@ -40,11 +41,15 @@ export const SidebarCategory = ({
|
|
|
40
41
|
onClick={(e) => {
|
|
41
42
|
e.preventDefault();
|
|
42
43
|
setOpen((prev) => !prev);
|
|
44
|
+
setHasInteracted(true);
|
|
43
45
|
}}
|
|
44
46
|
>
|
|
45
47
|
<ChevronRightIcon
|
|
46
48
|
size={16}
|
|
47
|
-
className=
|
|
49
|
+
className={cn(
|
|
50
|
+
hasInteracted && "transition",
|
|
51
|
+
"shrink-0 group-data-[state=open]:rotate-90",
|
|
52
|
+
)}
|
|
48
53
|
/>
|
|
49
54
|
</button>
|
|
50
55
|
);
|
|
@@ -88,7 +93,13 @@ export const SidebarCategory = ({
|
|
|
88
93
|
</div>
|
|
89
94
|
)}
|
|
90
95
|
</Collapsible.Trigger>
|
|
91
|
-
<Collapsible.Content
|
|
96
|
+
<Collapsible.Content
|
|
97
|
+
className={cn(
|
|
98
|
+
// CollapsibleContent class is used to animate and it should only be applied when the user has triggered the toggle
|
|
99
|
+
hasInteracted && "CollapsibleContent",
|
|
100
|
+
"ms-[calc(var(--padding-nav-item)*1.125)]",
|
|
101
|
+
)}
|
|
102
|
+
>
|
|
92
103
|
<ul className="mt-1 border-l ps-2">
|
|
93
104
|
{category.items.map((item) => (
|
|
94
105
|
<SidebarItem
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
import { ExternalLinkIcon } from "lucide-react";
|
|
3
|
-
import { NavLink } from "react-router-dom";
|
|
3
|
+
import { NavLink, useSearchParams } from "react-router-dom";
|
|
4
4
|
|
|
5
5
|
import type { SidebarItem as SidebarItemType } from "../../../config/validators/SidebarSchema.js";
|
|
6
6
|
import { cn } from "../../util/cn.js";
|
|
@@ -42,6 +42,7 @@ export const SidebarItem = ({
|
|
|
42
42
|
}) => {
|
|
43
43
|
const topNavItem = useTopNavigationItem();
|
|
44
44
|
const { activeAnchor } = useViewportAnchor();
|
|
45
|
+
const [searchParams] = useSearchParams();
|
|
45
46
|
|
|
46
47
|
switch (item.type) {
|
|
47
48
|
case "category":
|
|
@@ -69,7 +70,7 @@ export const SidebarItem = ({
|
|
|
69
70
|
case "link":
|
|
70
71
|
return item.href.startsWith("#") ? (
|
|
71
72
|
<AnchorLink
|
|
72
|
-
to={item.href}
|
|
73
|
+
to={{ hash: item.href, search: searchParams.toString() }}
|
|
73
74
|
{...{ [DATA_ANCHOR_ATTR]: item.href.slice(1) }}
|
|
74
75
|
className={cn(
|
|
75
76
|
"flex gap-2.5 justify-between",
|
|
@@ -68,6 +68,25 @@ const builder = new SchemaBuilder<{
|
|
|
68
68
|
const JSONScalar = builder.addScalarType("JSON", GraphQLJSON);
|
|
69
69
|
const JSONObjectScalar = builder.addScalarType("JSONObject", GraphQLJSONObject);
|
|
70
70
|
|
|
71
|
+
const getAllTags = (schema: OpenAPIDocument): TagObject[] => {
|
|
72
|
+
const tags = schema.tags ?? [];
|
|
73
|
+
|
|
74
|
+
// Extract tags from operations
|
|
75
|
+
const operationTags = Object.values(schema.paths ?? {})
|
|
76
|
+
.flatMap((path) => Object.values(path ?? {}))
|
|
77
|
+
.flatMap((operation) =>
|
|
78
|
+
typeof operation === "object" && "tags" in operation
|
|
79
|
+
? operation.tags ?? []
|
|
80
|
+
: [],
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Remove duplicates and tags that appear in the schema
|
|
84
|
+
const uniqueOperationTags = [...new Set(operationTags)].filter(
|
|
85
|
+
(tag) => !tags.some((rootTag) => rootTag.name === tag),
|
|
86
|
+
);
|
|
87
|
+
return [...tags, ...uniqueOperationTags.map((tag) => ({ name: tag }))];
|
|
88
|
+
};
|
|
89
|
+
|
|
71
90
|
const getAllOperations = (paths?: PathsObject, tag?: string) => {
|
|
72
91
|
return Object.entries(paths ?? {}).flatMap(([path, value]) =>
|
|
73
92
|
HttpMethods.flatMap((method) => {
|
|
@@ -117,7 +136,7 @@ const SchemaTag = builder.objectRef<TagObject>("SchemaTag").implement({
|
|
|
117
136
|
operations: t.field({
|
|
118
137
|
type: [OperationItem],
|
|
119
138
|
resolve: (parent, _args, ctx) => {
|
|
120
|
-
const rootTags = ctx.schema.
|
|
139
|
+
const rootTags = getAllTags(ctx.schema).map((tag) => tag.name);
|
|
121
140
|
|
|
122
141
|
return getAllOperations(ctx.schema.paths, parent.name).filter((item) =>
|
|
123
142
|
parent.name
|
|
@@ -363,10 +382,10 @@ const Schema = builder.objectRef<OpenAPIDocument>("Schema").implement({
|
|
|
363
382
|
name: t.arg.string(),
|
|
364
383
|
},
|
|
365
384
|
type: [SchemaTag],
|
|
366
|
-
resolve: (root, args) =>
|
|
367
|
-
[...(root
|
|
368
|
-
|
|
369
|
-
|
|
385
|
+
resolve: (root, args) => {
|
|
386
|
+
const tags = [...getAllTags(root), { name: "" }];
|
|
387
|
+
return args.name ? tags.filter((tag) => tag.name === args.name) : tags;
|
|
388
|
+
},
|
|
370
389
|
}),
|
|
371
390
|
operations: t.field({
|
|
372
391
|
type: [OperationItem],
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
1
2
|
import { Heading } from "../../components/Heading.js";
|
|
2
3
|
import { Markdown } from "../../components/Markdown.js";
|
|
3
4
|
import { Card } from "../../ui/Card.js";
|
|
@@ -6,9 +7,9 @@ import { groupBy } from "../../util/groupBy.js";
|
|
|
6
7
|
import { renderIf } from "../../util/renderIf.js";
|
|
7
8
|
import { OperationsFragment } from "./OperationList.js";
|
|
8
9
|
import { ParameterList } from "./ParameterList.js";
|
|
9
|
-
import { SchemaListView } from "./SchemaListView.js";
|
|
10
10
|
import { Sidecar } from "./Sidecar.js";
|
|
11
11
|
import { FragmentType, useFragment } from "./graphql/index.js";
|
|
12
|
+
import { SchemaView } from "./schema/SchemaView.js";
|
|
12
13
|
import { SchemaProseClasses } from "./util/prose.js";
|
|
13
14
|
|
|
14
15
|
export const PARAM_GROUPS = ["path", "query", "header", "cookie"] as const;
|
|
@@ -26,6 +27,8 @@ export const OperationListItem = ({
|
|
|
26
27
|
);
|
|
27
28
|
|
|
28
29
|
const first = operation.responses.at(0);
|
|
30
|
+
const [selectedResponse, setSelectedResponse] = useState(first?.statusCode);
|
|
31
|
+
|
|
29
32
|
return (
|
|
30
33
|
<div
|
|
31
34
|
key={operation.operationId}
|
|
@@ -62,7 +65,7 @@ export const OperationListItem = ({
|
|
|
62
65
|
<Heading level={3} className="capitalize">
|
|
63
66
|
Request Body
|
|
64
67
|
</Heading>
|
|
65
|
-
<
|
|
68
|
+
<SchemaView schema={schema} />
|
|
66
69
|
</div>
|
|
67
70
|
))}
|
|
68
71
|
{operation.responses.length > 0 && (
|
|
@@ -70,12 +73,15 @@ export const OperationListItem = ({
|
|
|
70
73
|
<Heading level={3} className="capitalize mt-8 pt-8 border-t">
|
|
71
74
|
Responses
|
|
72
75
|
</Heading>
|
|
73
|
-
<Tabs
|
|
76
|
+
<Tabs
|
|
77
|
+
onValueChange={(value) => setSelectedResponse(value)}
|
|
78
|
+
value={selectedResponse}
|
|
79
|
+
>
|
|
74
80
|
{operation.responses.length > 1 && (
|
|
75
81
|
<TabsList>
|
|
76
82
|
{operation.responses.map((response) => (
|
|
77
83
|
<TabsTrigger
|
|
78
|
-
value={response.statusCode
|
|
84
|
+
value={response.statusCode}
|
|
79
85
|
key={response.statusCode}
|
|
80
86
|
title={response.description}
|
|
81
87
|
>
|
|
@@ -87,16 +93,16 @@ export const OperationListItem = ({
|
|
|
87
93
|
<ul className="list-none m-0 px-0 overflow-hidden">
|
|
88
94
|
{operation.responses.map((response) => (
|
|
89
95
|
<TabsContent
|
|
90
|
-
value={response.statusCode
|
|
96
|
+
value={response.statusCode}
|
|
91
97
|
key={response.statusCode}
|
|
92
98
|
>
|
|
93
99
|
{renderIf(
|
|
94
100
|
response.content?.find((content) => content.schema),
|
|
95
101
|
(content) => {
|
|
96
|
-
return <
|
|
102
|
+
return <SchemaView schema={content.schema} />;
|
|
97
103
|
},
|
|
98
104
|
) ?? (
|
|
99
|
-
<Card className="font-mono text-sm p-4">
|
|
105
|
+
<Card className="font-mono text-sm p-4 italic bg-border/20">
|
|
100
106
|
No response body
|
|
101
107
|
</Card>
|
|
102
108
|
)}
|
|
@@ -108,7 +114,11 @@ export const OperationListItem = ({
|
|
|
108
114
|
)}
|
|
109
115
|
</div>
|
|
110
116
|
|
|
111
|
-
<Sidecar
|
|
117
|
+
<Sidecar
|
|
118
|
+
selectedResponse={selectedResponse}
|
|
119
|
+
onSelectResponse={setSelectedResponse}
|
|
120
|
+
operation={operation}
|
|
121
|
+
/>
|
|
112
122
|
</div>
|
|
113
123
|
);
|
|
114
124
|
};
|
|
@@ -21,14 +21,16 @@ export const ParameterList = ({
|
|
|
21
21
|
</Heading>
|
|
22
22
|
<Card>
|
|
23
23
|
<ul className="list-none m-0 px-0 divide-y ">
|
|
24
|
-
{parameters
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
{parameters
|
|
25
|
+
.sort((a, b) => (a.required === b.required ? 0 : a.required ? -1 : 1))
|
|
26
|
+
.map((parameter) => (
|
|
27
|
+
<ParameterListItem
|
|
28
|
+
key={`${parameter.name}-${parameter.in}`}
|
|
29
|
+
parameter={parameter}
|
|
30
|
+
id={id}
|
|
31
|
+
group={group}
|
|
32
|
+
/>
|
|
33
|
+
))}
|
|
32
34
|
</ul>
|
|
33
35
|
</Card>
|
|
34
36
|
</>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Tabs from "@radix-ui/react-tabs";
|
|
2
2
|
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
3
3
|
import { type SchemaObject } from "../../oas/graphql/index.js";
|
|
4
4
|
import { cn } from "../../util/cn.js";
|
|
@@ -9,52 +9,64 @@ import { generateSchemaExample } from "./util/generateSchemaExample.js";
|
|
|
9
9
|
type Responses = OperationListItemResult["responses"];
|
|
10
10
|
export const ResponsesSidecarBox = ({
|
|
11
11
|
responses,
|
|
12
|
+
selectedResponse,
|
|
13
|
+
onSelectResponse,
|
|
12
14
|
}: {
|
|
13
15
|
responses: Responses;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
selectedResponse?: string;
|
|
17
|
+
onSelectResponse: (response: string) => void;
|
|
18
|
+
}) => (
|
|
19
|
+
<SidecarBox.Root>
|
|
20
|
+
<Tabs.Root
|
|
21
|
+
defaultValue={responses[0]?.statusCode}
|
|
22
|
+
value={selectedResponse}
|
|
23
|
+
onValueChange={(value) => onSelectResponse(value)}
|
|
24
|
+
>
|
|
25
|
+
<SidecarBox.Head className="text-xs flex flex-col gap-2 pb-0">
|
|
23
26
|
<span className="font-mono">Example Responses</span>
|
|
24
|
-
<
|
|
25
|
-
{responses.map((response
|
|
26
|
-
<
|
|
27
|
+
<Tabs.List className="flex gap-2">
|
|
28
|
+
{responses.map((response) => (
|
|
29
|
+
<Tabs.Trigger
|
|
27
30
|
key={response.statusCode}
|
|
28
|
-
|
|
31
|
+
value={response.statusCode}
|
|
29
32
|
className={cn(
|
|
30
33
|
"text-xs font-mono px-1.5 py-1 pb-px translate-y-px border-b-2 border-transparent rounded-t cursor-pointer",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
: "hover:border-accent-foreground/25",
|
|
34
|
+
"data-[state=active]:text-primary data-[state=active]:dark:text-inherit data-[state=active]:border-primary",
|
|
35
|
+
"hover:border-accent-foreground/25",
|
|
34
36
|
)}
|
|
35
37
|
>
|
|
36
38
|
{response.statusCode}
|
|
37
|
-
</
|
|
39
|
+
</Tabs.Trigger>
|
|
38
40
|
))}
|
|
39
|
-
</
|
|
41
|
+
</Tabs.List>
|
|
40
42
|
</SidecarBox.Head>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
43
|
+
{responses.map((response) => {
|
|
44
|
+
const schema = response.content?.[0]?.schema as
|
|
45
|
+
| SchemaObject
|
|
46
|
+
| undefined;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Tabs.Content key={response.statusCode} value={response.statusCode}>
|
|
50
|
+
<SidecarBox.Body>
|
|
51
|
+
{schema ? (
|
|
52
|
+
<SyntaxHighlight
|
|
53
|
+
language="json"
|
|
54
|
+
noBackground
|
|
55
|
+
className="text-xs"
|
|
56
|
+
code={JSON.stringify(generateSchemaExample(schema), null, 2)}
|
|
57
|
+
/>
|
|
58
|
+
) : (
|
|
59
|
+
<span className="text-muted-foreground font-mono italic text-xs">
|
|
60
|
+
Empty Response
|
|
61
|
+
</span>
|
|
62
|
+
)}
|
|
63
|
+
</SidecarBox.Body>
|
|
64
|
+
<SidecarBox.Footer className="flex justify-end text-xs">
|
|
65
|
+
{response.description}
|
|
66
|
+
</SidecarBox.Footer>
|
|
67
|
+
</Tabs.Content>
|
|
68
|
+
);
|
|
69
|
+
})}
|
|
70
|
+
</Tabs.Root>
|
|
71
|
+
</SidecarBox.Root>
|
|
72
|
+
);
|
|
@@ -84,8 +84,12 @@ const methodToColor = {
|
|
|
84
84
|
|
|
85
85
|
export const Sidecar = ({
|
|
86
86
|
operation,
|
|
87
|
+
selectedResponse,
|
|
88
|
+
onSelectResponse,
|
|
87
89
|
}: {
|
|
88
90
|
operation: OperationListItemResult;
|
|
91
|
+
selectedResponse?: string;
|
|
92
|
+
onSelectResponse: (response: string) => void;
|
|
89
93
|
}) => {
|
|
90
94
|
const oasConfig = useOasConfig();
|
|
91
95
|
const [result] = useQuery({
|
|
@@ -105,8 +109,9 @@ export const Sidecar = ({
|
|
|
105
109
|
|
|
106
110
|
const requestBodyContent = operation.requestBody?.content;
|
|
107
111
|
|
|
108
|
-
const path = operation.path.split("/").map((part) => (
|
|
109
|
-
|
|
112
|
+
const path = operation.path.split("/").map((part, i, arr) => (
|
|
113
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
114
|
+
<Fragment key={part + i}>
|
|
110
115
|
{part.startsWith("{") && part.endsWith("}") ? (
|
|
111
116
|
<ColorizedParam
|
|
112
117
|
name={part.slice(1, -1)}
|
|
@@ -119,7 +124,7 @@ export const Sidecar = ({
|
|
|
119
124
|
) : (
|
|
120
125
|
part
|
|
121
126
|
)}
|
|
122
|
-
/
|
|
127
|
+
{i < arr.length - 1 ? "/" : null}
|
|
123
128
|
<wbr />
|
|
124
129
|
</Fragment>
|
|
125
130
|
));
|
|
@@ -200,7 +205,11 @@ export const Sidecar = ({
|
|
|
200
205
|
<RequestBodySidecarBox content={requestBodyContent} />
|
|
201
206
|
)}
|
|
202
207
|
{operation.responses.length > 0 && (
|
|
203
|
-
<ResponsesSidecarBox
|
|
208
|
+
<ResponsesSidecarBox
|
|
209
|
+
selectedResponse={selectedResponse}
|
|
210
|
+
onSelectResponse={onSelectResponse}
|
|
211
|
+
responses={operation.responses}
|
|
212
|
+
/>
|
|
204
213
|
)}
|
|
205
214
|
</aside>
|
|
206
215
|
);
|