zudoku 0.27.0 → 0.28.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/lib/components/navigation/SidebarCategory.js +3 -3
- package/dist/lib/components/navigation/SidebarCategory.js.map +1 -1
- package/dist/lib/oas/graphql/index.d.ts +1 -0
- package/dist/lib/oas/graphql/index.js +41 -23
- package/dist/lib/oas/graphql/index.js.map +1 -1
- package/dist/lib/plugins/openapi/Endpoint.js +2 -2
- package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
- package/dist/lib/plugins/openapi/{Route.d.ts → OpenApiRoute.d.ts} +2 -1
- package/dist/lib/plugins/openapi/{Route.js → OpenApiRoute.js} +3 -4
- package/dist/lib/plugins/openapi/OpenApiRoute.js.map +1 -0
- package/dist/lib/plugins/openapi/OperationList.d.ts +4 -1
- package/dist/lib/plugins/openapi/OperationList.js +20 -14
- package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.d.ts +1 -1
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js +2 -0
- package/dist/lib/plugins/openapi/RequestBodySidecarBox.js.map +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js +1 -1
- package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
- package/dist/lib/plugins/openapi/SidecarExamples.js +17 -14
- package/dist/lib/plugins/openapi/SidecarExamples.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/gql.d.ts +6 -2
- package/dist/lib/plugins/openapi/graphql/gql.js +3 -2
- package/dist/lib/plugins/openapi/graphql/gql.js.map +1 -1
- package/dist/lib/plugins/openapi/graphql/graphql.d.ts +47 -26
- package/dist/lib/plugins/openapi/graphql/graphql.js +20 -16
- package/dist/lib/plugins/openapi/graphql/graphql.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +97 -54
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/interfaces.d.ts +1 -0
- package/dist/lib/util/joinUrl.js +1 -1
- package/dist/lib/util/joinUrl.js.map +1 -1
- package/dist/lib/util/joinUrl.test.d.ts +1 -0
- package/dist/lib/util/joinUrl.test.js +43 -0
- package/dist/lib/util/joinUrl.test.js.map +1 -0
- package/dist/vite/plugin-api.js +7 -1
- package/dist/vite/plugin-api.js.map +1 -1
- package/lib/{AuthenticationPlugin-CO_YCd2x.js → AuthenticationPlugin-Du8cLBSr.js} +2 -2
- package/lib/{AuthenticationPlugin-CO_YCd2x.js.map → AuthenticationPlugin-Du8cLBSr.js.map} +1 -1
- package/lib/{Markdown-B8o9Qz4q.js → Markdown-Cyrx_JrO.js} +8 -9
- package/lib/{Markdown-B8o9Qz4q.js.map → Markdown-Cyrx_JrO.js.map} +1 -1
- package/lib/{MdxPage-BxRt3Ly7.js → MdxPage-DewragjB.js} +5 -5
- package/lib/{MdxPage-BxRt3Ly7.js.map → MdxPage-DewragjB.js.map} +1 -1
- package/lib/OpenApiRoute-UrC_t0e5.js +36 -0
- package/lib/OpenApiRoute-UrC_t0e5.js.map +1 -0
- package/lib/{OperationList-DH-zIgtq.js → OperationList-D_ejrepA.js} +1373 -1372
- package/lib/OperationList-D_ejrepA.js.map +1 -0
- package/lib/{Select-B7UXR0SB.js → Select-CnCZ4WhS.js} +3 -3
- package/lib/{Select-B7UXR0SB.js.map → Select-CnCZ4WhS.js.map} +1 -1
- package/lib/{SlotletProvider-CtIp8rP3.js → SlotletProvider-mQiPDQIH.js} +2 -2
- package/lib/{SlotletProvider-CtIp8rP3.js.map → SlotletProvider-mQiPDQIH.js.map} +1 -1
- package/lib/{SyntaxHighlight-C1w1QPdY.js → SyntaxHighlight-B0L4SC_N.js} +11 -5
- package/lib/SyntaxHighlight-B0L4SC_N.js.map +1 -0
- package/lib/{ZudokuContext-8jts0fF3.js → ZudokuContext-BTUJPpQl.js} +21 -21
- package/lib/{ZudokuContext-8jts0fF3.js.map → ZudokuContext-BTUJPpQl.js.map} +1 -1
- package/lib/{createServer-BV0tHzLK.js → createServer-BydbkTsd.js} +821 -808
- package/lib/{createServer-BV0tHzLK.js.map → createServer-BydbkTsd.js.map} +1 -1
- package/lib/{hook-BG02esyv.js → hook-FT3SJLe_.js} +2 -2
- package/lib/{hook-BG02esyv.js.map → hook-FT3SJLe_.js.map} +1 -1
- package/lib/{index-LNp6rxyU.js → index-CjJS0l4l.js} +2 -2
- package/lib/{index-LNp6rxyU.js.map → index-CjJS0l4l.js.map} +1 -1
- package/lib/{index-DmqsUPcm.js → index-DGugJOLc.js} +836 -777
- package/lib/index-DGugJOLc.js.map +1 -0
- package/lib/{joinUrl-BTy9bvoK.js → joinUrl-nLx9pD-Z.js} +2 -2
- package/lib/joinUrl-nLx9pD-Z.js.map +1 -0
- package/lib/{useScrollToAnchor-Bl6mz9_x.js → useScrollToAnchor-eRM9tVvD.js} +10 -9
- package/lib/useScrollToAnchor-eRM9tVvD.js.map +1 -0
- package/lib/zudoku.auth-clerk.js +1 -1
- package/lib/zudoku.auth-openid.js +3 -3
- package/lib/zudoku.components.js +153 -154
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.plugin-api-catalog.js +3 -3
- package/lib/zudoku.plugin-api-keys.js +4 -4
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +6 -5
- package/lib/zudoku.plugin-openapi.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/components/navigation/SidebarCategory.tsx +3 -2
- package/src/lib/oas/graphql/index.ts +63 -35
- package/src/lib/plugins/openapi/Endpoint.tsx +2 -2
- package/src/lib/plugins/openapi/{Route.tsx → OpenApiRoute.tsx} +3 -3
- package/src/lib/plugins/openapi/OperationList.tsx +34 -12
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +2 -0
- package/src/lib/plugins/openapi/Sidecar.tsx +1 -1
- package/src/lib/plugins/openapi/SidecarExamples.tsx +24 -24
- package/src/lib/plugins/openapi/graphql/gql.ts +12 -4
- package/src/lib/plugins/openapi/graphql/graphql.ts +66 -43
- package/src/lib/plugins/openapi/index.tsx +125 -67
- package/src/lib/plugins/openapi/interfaces.ts +1 -0
- package/src/lib/util/joinUrl.test.ts +62 -0
- package/src/lib/util/joinUrl.ts +1 -1
- package/dist/lib/plugins/openapi/Route.js.map +0 -1
- package/lib/OperationList-DH-zIgtq.js.map +0 -1
- package/lib/Route-DJ0ZlVq1.js +0 -35
- package/lib/Route-DJ0ZlVq1.js.map +0 -1
- package/lib/StaggeredRender-DgsamH_G.js +0 -17
- package/lib/StaggeredRender-DgsamH_G.js.map +0 -1
- package/lib/SyntaxHighlight-C1w1QPdY.js.map +0 -1
- package/lib/index-Bn6Lc9tq.js +0 -9
- package/lib/index-Bn6Lc9tq.js.map +0 -1
- package/lib/index-DmqsUPcm.js.map +0 -1
- package/lib/joinUrl-BTy9bvoK.js.map +0 -1
- package/lib/useScrollToAnchor-Bl6mz9_x.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-Bdg6XQ1m.js";
|
|
2
|
-
import { s as j } from "./index-
|
|
3
|
-
import { u as b } from "./ZudokuContext-
|
|
2
|
+
import { s as j } from "./index-CjJS0l4l.js";
|
|
3
|
+
import { u as b } from "./ZudokuContext-BTUJPpQl.js";
|
|
4
4
|
import { b as y } from "./chunk-SYFQ2XB5-BPvC-soB.js";
|
|
5
5
|
import { Head as v, Link as N } from "./zudoku.components.js";
|
|
6
6
|
import { u as w } from "./state-mM7uaXTW.js";
|
|
7
|
-
import { M as C } from "./Markdown-
|
|
7
|
+
import { M as C } from "./Markdown-Cyrx_JrO.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-mQiPDQIH.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-CnCZ4WhS.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-BPvC-soB.js";
|
|
8
|
-
import { a as y, e as q, u as O } from "./ZudokuContext-
|
|
8
|
+
import { a as y, e as q, u as O } from "./ZudokuContext-BTUJPpQl.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-FT3SJLe_.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-Cyrx_JrO.js";
|
|
4
4
|
import { c } from "./cn-qaFjX9_3.js";
|
|
5
5
|
import { u as p } from "./useExposedProps-BLKFBylA.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-DewragjB.js"), { default: p, ...g } = await a();
|
|
78
78
|
return {
|
|
79
79
|
element: /* @__PURE__ */ P.jsx(
|
|
80
80
|
l,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import "./jsx-runtime-Bdg6XQ1m.js";
|
|
2
|
-
import "./
|
|
3
|
-
import { o as a } from "./index-DmqsUPcm.js";
|
|
2
|
+
import "./index-CjJS0l4l.js";
|
|
4
3
|
import "lucide-react";
|
|
5
|
-
import "./
|
|
4
|
+
import "./chunk-SYFQ2XB5-BPvC-soB.js";
|
|
5
|
+
import "./hook-FT3SJLe_.js";
|
|
6
6
|
import "./ui/Button.js";
|
|
7
|
-
import "./
|
|
7
|
+
import "./joinUrl-nLx9pD-Z.js";
|
|
8
|
+
import { o as f } from "./index-DGugJOLc.js";
|
|
8
9
|
export {
|
|
9
|
-
|
|
10
|
+
f as openApiPlugin
|
|
10
11
|
};
|
|
11
12
|
//# sourceMappingURL=zudoku.plugin-openapi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -67,7 +67,7 @@ export const SidebarCategory = ({
|
|
|
67
67
|
isActive: false,
|
|
68
68
|
className: [
|
|
69
69
|
"text-start font-medium",
|
|
70
|
-
isCollapsible
|
|
70
|
+
isCollapsible || typeof category.link !== "undefined"
|
|
71
71
|
? "cursor-pointer"
|
|
72
72
|
: "cursor-default hover:bg-transparent",
|
|
73
73
|
],
|
|
@@ -82,7 +82,7 @@ export const SidebarCategory = ({
|
|
|
82
82
|
{category.link?.type === "doc" ? (
|
|
83
83
|
<NavLink
|
|
84
84
|
to={joinPath(category.link.id)}
|
|
85
|
-
className="flex-1"
|
|
85
|
+
className="flex-1 truncate"
|
|
86
86
|
onClick={() => {
|
|
87
87
|
// if it is the current path and closed then open it because there's no path change to trigger the open
|
|
88
88
|
if (isActive && !open) {
|
|
@@ -112,6 +112,7 @@ export const SidebarCategory = ({
|
|
|
112
112
|
className={cn(
|
|
113
113
|
// CollapsibleContent class is used to animate and it should only be applied when the user has triggered the toggle
|
|
114
114
|
hasInteracted && "CollapsibleContent",
|
|
115
|
+
category.items.length === 0 && "hidden",
|
|
115
116
|
"ms-6 my-1",
|
|
116
117
|
)}
|
|
117
118
|
>
|
|
@@ -67,15 +67,26 @@ const builder = new SchemaBuilder<{
|
|
|
67
67
|
};
|
|
68
68
|
Context: {
|
|
69
69
|
schema: OpenAPIDocument;
|
|
70
|
+
operations: GraphQLOperationObject[];
|
|
71
|
+
tags: TagObject[];
|
|
70
72
|
schemaImports?: SchemaImports;
|
|
73
|
+
currentTag?: string;
|
|
74
|
+
slugify: CountableSlugify;
|
|
71
75
|
};
|
|
72
76
|
}>({});
|
|
73
77
|
|
|
78
|
+
type GraphQLOperationObject = OperationObject & {
|
|
79
|
+
path: string;
|
|
80
|
+
method: string;
|
|
81
|
+
slug?: string;
|
|
82
|
+
parentTag?: string;
|
|
83
|
+
};
|
|
84
|
+
|
|
74
85
|
const JSONScalar = builder.addScalarType("JSON", GraphQLJSON);
|
|
75
86
|
const JSONObjectScalar = builder.addScalarType("JSONObject", GraphQLJSONObject);
|
|
76
87
|
const JSONSchemaScalar = builder.addScalarType("JSONSchema", GraphQLJSONSchema);
|
|
77
88
|
|
|
78
|
-
const getAllTags = (schema: OpenAPIDocument): TagObject[] => {
|
|
89
|
+
export const getAllTags = (schema: OpenAPIDocument): TagObject[] => {
|
|
79
90
|
const tags = schema.tags ?? [];
|
|
80
91
|
|
|
81
92
|
// Extract tags from operations
|
|
@@ -94,10 +105,10 @@ const getAllTags = (schema: OpenAPIDocument): TagObject[] => {
|
|
|
94
105
|
return [...tags, ...uniqueOperationTags.map((tag) => ({ name: tag }))];
|
|
95
106
|
};
|
|
96
107
|
|
|
97
|
-
const getAllOperations = (paths?: PathsObject
|
|
98
|
-
const
|
|
108
|
+
const getAllOperations = (paths?: PathsObject) => {
|
|
109
|
+
const start = performance.now();
|
|
99
110
|
|
|
100
|
-
|
|
111
|
+
const operations = Object.entries(paths ?? {}).flatMap(([path, value]) =>
|
|
101
112
|
HttpMethods.flatMap((method) => {
|
|
102
113
|
if (!value?.[method]) return [];
|
|
103
114
|
|
|
@@ -118,23 +129,17 @@ const getAllOperations = (paths?: PathsObject, tag?: string) => {
|
|
|
118
129
|
...operationParameters,
|
|
119
130
|
];
|
|
120
131
|
|
|
121
|
-
const slugData = {
|
|
122
|
-
summary: operation.summary,
|
|
123
|
-
operationId: operation.operationId,
|
|
124
|
-
path,
|
|
125
|
-
method,
|
|
126
|
-
};
|
|
127
|
-
|
|
128
132
|
return {
|
|
129
133
|
...operation,
|
|
130
134
|
method,
|
|
131
135
|
path,
|
|
132
136
|
parameters,
|
|
133
137
|
tags: operation.tags ?? [],
|
|
134
|
-
slug: createOperationSlug(slugify, slugData, tag),
|
|
135
138
|
};
|
|
136
139
|
}),
|
|
137
140
|
);
|
|
141
|
+
|
|
142
|
+
return operations;
|
|
138
143
|
};
|
|
139
144
|
|
|
140
145
|
const SchemaTag = builder.objectRef<TagObject>("SchemaTag").implement({
|
|
@@ -144,15 +149,19 @@ const SchemaTag = builder.objectRef<TagObject>("SchemaTag").implement({
|
|
|
144
149
|
operations: t.field({
|
|
145
150
|
type: [OperationItem],
|
|
146
151
|
resolve: (parent, _args, ctx) => {
|
|
147
|
-
const rootTags =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
152
|
+
const rootTags = ctx.tags.map((tag) => tag.name);
|
|
153
|
+
return ctx.operations
|
|
154
|
+
.filter((item) =>
|
|
155
|
+
parent.name
|
|
156
|
+
? item.tags?.includes(parent.name)
|
|
157
|
+
: item.tags?.length === 0 ||
|
|
158
|
+
// If none of the tags are present in the root tags, then show them here
|
|
159
|
+
item.tags?.every((tag) => !rootTags.includes(tag)),
|
|
160
|
+
)
|
|
161
|
+
.map((item) => ({
|
|
162
|
+
...item,
|
|
163
|
+
parentTag: parent.name,
|
|
164
|
+
}));
|
|
156
165
|
},
|
|
157
166
|
}),
|
|
158
167
|
}),
|
|
@@ -300,12 +309,24 @@ const ResponseItem = builder
|
|
|
300
309
|
});
|
|
301
310
|
|
|
302
311
|
const OperationItem = builder
|
|
303
|
-
.objectRef<
|
|
304
|
-
OperationObject & { path: string; method: string; slug: string }
|
|
305
|
-
>("OperationItem")
|
|
312
|
+
.objectRef<GraphQLOperationObject>("OperationItem")
|
|
306
313
|
.implement({
|
|
307
314
|
fields: (t) => ({
|
|
308
|
-
slug: t.
|
|
315
|
+
slug: t.field({
|
|
316
|
+
type: "String",
|
|
317
|
+
resolve: (parent, _, ctx) => {
|
|
318
|
+
const slugData = {
|
|
319
|
+
summary: parent.summary,
|
|
320
|
+
operationId: parent.operationId,
|
|
321
|
+
path: parent.path,
|
|
322
|
+
method: parent.method,
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
//TODO: fix parent tag parent.tags
|
|
326
|
+
return createOperationSlug(ctx.slugify, slugData, parent.parentTag);
|
|
327
|
+
},
|
|
328
|
+
}),
|
|
329
|
+
|
|
309
330
|
path: t.exposeString("path"),
|
|
310
331
|
method: t.exposeString("method"),
|
|
311
332
|
operationId: t.exposeString("operationId", { nullable: true }),
|
|
@@ -414,8 +435,8 @@ const Schema = builder.objectRef<OpenAPIDocument>("Schema").implement({
|
|
|
414
435
|
name: t.arg.string(),
|
|
415
436
|
},
|
|
416
437
|
type: [SchemaTag],
|
|
417
|
-
resolve: (root, args) => {
|
|
418
|
-
const tags = [...
|
|
438
|
+
resolve: (root, args, ctx) => {
|
|
439
|
+
const tags = [...ctx.tags, { name: "" }];
|
|
419
440
|
return args.name ? tags.filter((tag) => tag.name === args.name) : tags;
|
|
420
441
|
},
|
|
421
442
|
}),
|
|
@@ -426,15 +447,18 @@ const Schema = builder.objectRef<OpenAPIDocument>("Schema").implement({
|
|
|
426
447
|
method: t.arg.string(),
|
|
427
448
|
operationId: t.arg.string(),
|
|
428
449
|
tag: t.arg.string(),
|
|
450
|
+
untagged: t.arg.boolean(),
|
|
429
451
|
},
|
|
430
|
-
resolve: (parent, args) =>
|
|
431
|
-
|
|
432
|
-
(
|
|
433
|
-
(!args.operationId ||
|
|
434
|
-
(!args.path ||
|
|
435
|
-
(!args.method ||
|
|
436
|
-
(!args.tag ||
|
|
437
|
-
|
|
452
|
+
resolve: (parent, args, ctx) =>
|
|
453
|
+
ctx.operations.filter((op) => {
|
|
454
|
+
return (
|
|
455
|
+
(!args.operationId || op.operationId === args.operationId) &&
|
|
456
|
+
(!args.path || op.path === args.path) &&
|
|
457
|
+
(!args.method || op.method === args.method) &&
|
|
458
|
+
(!args.tag || op.tags?.some((tag) => args.tag?.includes(tag))) &&
|
|
459
|
+
(!args.untagged || (op.tags ?? []).length === 0)
|
|
460
|
+
);
|
|
461
|
+
}),
|
|
438
462
|
}),
|
|
439
463
|
}),
|
|
440
464
|
});
|
|
@@ -467,6 +491,10 @@ builder.queryType({
|
|
|
467
491
|
}
|
|
468
492
|
|
|
469
493
|
ctx.schema = schema;
|
|
494
|
+
ctx.operations = getAllOperations(schema.paths);
|
|
495
|
+
ctx.slugify = slugifyWithCounter();
|
|
496
|
+
ctx.tags = getAllTags(schema);
|
|
497
|
+
|
|
470
498
|
return schema;
|
|
471
499
|
},
|
|
472
500
|
}),
|
|
@@ -77,14 +77,14 @@ export const Endpoint = () => {
|
|
|
77
77
|
setSelectedServer(e.target.value);
|
|
78
78
|
})
|
|
79
79
|
}
|
|
80
|
-
value={selectedServer ??
|
|
80
|
+
value={selectedServer ?? servers.at(0)!.url}
|
|
81
81
|
showChevrons={servers.length > 1}
|
|
82
82
|
options={servers.map((server) => ({
|
|
83
83
|
value: server.url,
|
|
84
84
|
label: server.url,
|
|
85
85
|
}))}
|
|
86
86
|
/>
|
|
87
|
-
<CopyButton url={selectedServer ??
|
|
87
|
+
<CopyButton url={selectedServer ?? servers.at(0)!.url} />
|
|
88
88
|
</div>
|
|
89
89
|
);
|
|
90
90
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Outlet
|
|
1
|
+
import { Outlet } from "react-router";
|
|
2
2
|
import { joinPath } from "../../util/joinPath.js";
|
|
3
3
|
import type { GraphQLClient } from "./client/GraphQLClient.js";
|
|
4
4
|
import { GraphQLProvider } from "./client/GraphQLContext.js";
|
|
@@ -8,16 +8,16 @@ import { type OasPluginConfig } from "./interfaces.js";
|
|
|
8
8
|
export const OpenApiRoute = ({
|
|
9
9
|
basePath,
|
|
10
10
|
versions,
|
|
11
|
+
version,
|
|
11
12
|
config,
|
|
12
13
|
client,
|
|
13
14
|
}: {
|
|
14
15
|
basePath: string;
|
|
16
|
+
version?: string;
|
|
15
17
|
versions: string[];
|
|
16
18
|
config: OasPluginConfig;
|
|
17
19
|
client: GraphQLClient;
|
|
18
20
|
}) => {
|
|
19
|
-
const { version } = useParams<"version">();
|
|
20
|
-
|
|
21
21
|
const input =
|
|
22
22
|
config.type === "file"
|
|
23
23
|
? {
|
|
@@ -17,7 +17,6 @@ import { useApiIdentities } from "../../components/context/ZudokuContext.js";
|
|
|
17
17
|
import { cn } from "../../util/cn.js";
|
|
18
18
|
import { Endpoint } from "./Endpoint.js";
|
|
19
19
|
import { OperationListItem } from "./OperationListItem.js";
|
|
20
|
-
import StaggeredRender from "./StaggeredRender.js";
|
|
21
20
|
import { useCreateQuery } from "./client/useCreateQuery.js";
|
|
22
21
|
import { useOasConfig } from "./context.js";
|
|
23
22
|
import { graphql } from "./graphql/index.js";
|
|
@@ -90,35 +89,51 @@ export const OperationsFragment = graphql(/* GraphQL */ `
|
|
|
90
89
|
export type OperationListItemResult = ResultOf<typeof OperationsFragment>;
|
|
91
90
|
|
|
92
91
|
const AllOperationsQuery = graphql(/* GraphQL */ `
|
|
93
|
-
query AllOperations(
|
|
92
|
+
query AllOperations(
|
|
93
|
+
$input: JSON!
|
|
94
|
+
$type: SchemaType!
|
|
95
|
+
$tag: String
|
|
96
|
+
$untagged: Boolean
|
|
97
|
+
) {
|
|
94
98
|
schema(input: $input, type: $type) {
|
|
95
99
|
description
|
|
96
100
|
summary
|
|
97
101
|
title
|
|
98
102
|
url
|
|
99
103
|
version
|
|
100
|
-
tags {
|
|
104
|
+
tags(name: $tag) {
|
|
101
105
|
name
|
|
102
106
|
description
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
}
|
|
108
|
+
operations(tag: $tag, untagged: $untagged) {
|
|
109
|
+
slug
|
|
110
|
+
...OperationsFragment
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
114
|
`);
|
|
111
115
|
|
|
112
|
-
export const OperationList = (
|
|
116
|
+
export const OperationList = ({
|
|
117
|
+
tag,
|
|
118
|
+
untagged,
|
|
119
|
+
}: {
|
|
120
|
+
tag?: string;
|
|
121
|
+
untagged?: boolean;
|
|
122
|
+
}) => {
|
|
113
123
|
const { input, type, versions, version } = useOasConfig();
|
|
114
|
-
const query = useCreateQuery(AllOperationsQuery, {
|
|
124
|
+
const query = useCreateQuery(AllOperationsQuery, {
|
|
125
|
+
input,
|
|
126
|
+
type,
|
|
127
|
+
tag,
|
|
128
|
+
untagged,
|
|
129
|
+
});
|
|
115
130
|
const { selectedServer } = useSelectedServerStore();
|
|
116
131
|
const result = useSuspenseQuery(query);
|
|
117
132
|
const title = result.data.schema.title;
|
|
118
133
|
const summary = result.data.schema.summary;
|
|
119
134
|
const description = result.data.schema.description;
|
|
120
135
|
const navigate = useNavigate();
|
|
121
|
-
|
|
136
|
+
const operations = result.data.schema.operations;
|
|
122
137
|
// Prefetch for Playground
|
|
123
138
|
useApiIdentities();
|
|
124
139
|
|
|
@@ -175,7 +190,14 @@ export const OperationList = () => {
|
|
|
175
190
|
<div className="my-4 flex items-center justify-end gap-4">
|
|
176
191
|
<Endpoint />
|
|
177
192
|
</div>
|
|
178
|
-
{
|
|
193
|
+
{operations.map((fragment) => (
|
|
194
|
+
<OperationListItem
|
|
195
|
+
serverUrl={selectedServer ?? result.data.schema.url ?? ""}
|
|
196
|
+
key={fragment.slug}
|
|
197
|
+
operationFragment={fragment}
|
|
198
|
+
/>
|
|
199
|
+
))}
|
|
200
|
+
{/* {result.data.schema.tags
|
|
179
201
|
.filter((tag) => tag.operations.length > 0)
|
|
180
202
|
.map((tag) => (
|
|
181
203
|
// px, -mx is so that `content-visibility` doesn't cut off overflown heading anchor links '#'
|
|
@@ -199,7 +221,7 @@ export const OperationList = () => {
|
|
|
199
221
|
</StaggeredRender>
|
|
200
222
|
</div>
|
|
201
223
|
</div>
|
|
202
|
-
))}
|
|
224
|
+
))} */}
|
|
203
225
|
</div>
|
|
204
226
|
);
|
|
205
227
|
};
|
|
@@ -8,6 +8,8 @@ export const RequestBodySidecarBox = ({
|
|
|
8
8
|
content: Content;
|
|
9
9
|
onExampleChange?: (example: unknown) => void;
|
|
10
10
|
}) => {
|
|
11
|
+
if (content.length === 0) return null;
|
|
12
|
+
|
|
11
13
|
return (
|
|
12
14
|
<SidecarBox.Root>
|
|
13
15
|
<SidecarBox.Head className="text-xs flex justify-between items-center">
|
|
@@ -196,7 +196,7 @@ export const Sidecar = ({
|
|
|
196
196
|
</span>
|
|
197
197
|
{isOnScreen && (
|
|
198
198
|
<PlaygroundDialogWrapper
|
|
199
|
-
server={result.data.schema.url}
|
|
199
|
+
server={result.data.schema.url ?? ""}
|
|
200
200
|
servers={result.data.schema.servers.map((server) => server.url)}
|
|
201
201
|
operation={operation}
|
|
202
202
|
examples={requestBodyContent ?? undefined}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
2
|
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
3
|
-
import {
|
|
3
|
+
import { SchemaObject } from "../../oas/parser/index.js";
|
|
4
4
|
import { CollapsibleCode } from "./CollapsibleCode.js";
|
|
5
5
|
import type { OperationListItemResult } from "./OperationList.js";
|
|
6
6
|
import * as SidecarBox from "./SidecarBox.js";
|
|
@@ -57,27 +57,27 @@ export const SidecarExamples = ({
|
|
|
57
57
|
const examples = effectiveContent?.examples ?? [];
|
|
58
58
|
const selectedExample = examples[selectedExampleIndex];
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
effectiveContent.schema as SchemaObject
|
|
69
|
-
|
|
70
|
-
}
|
|
60
|
+
const exampleValue = useMemo(() => {
|
|
61
|
+
if (selectedExample) {
|
|
62
|
+
// If it's a wrapped example with a value field, use that
|
|
63
|
+
return "value" in selectedExample
|
|
64
|
+
? selectedExample.value
|
|
65
|
+
: selectedExample;
|
|
66
|
+
} else if (effectiveContent?.schema) {
|
|
67
|
+
// No example provided, generate one from schema
|
|
68
|
+
return generateSchemaExample(effectiveContent.schema as SchemaObject);
|
|
69
|
+
}
|
|
70
|
+
}, [selectedExample, effectiveContent?.schema]);
|
|
71
71
|
|
|
72
72
|
useEffect(() => {
|
|
73
|
+
if (!exampleValue) return;
|
|
74
|
+
|
|
73
75
|
onExampleChange?.(exampleValue);
|
|
74
76
|
}, [exampleValue, onExampleChange]);
|
|
75
77
|
|
|
76
78
|
const formattedExample = formatForDisplay(exampleValue);
|
|
77
79
|
const language = getLanguage(effectiveContent?.mediaType);
|
|
78
80
|
|
|
79
|
-
const hasContent = examples.length > 0 || content.length > 0;
|
|
80
|
-
|
|
81
81
|
return (
|
|
82
82
|
<>
|
|
83
83
|
<SidecarBox.Body className="p-0">
|
|
@@ -109,13 +109,13 @@ export const SidecarExamples = ({
|
|
|
109
109
|
</div>
|
|
110
110
|
)}
|
|
111
111
|
</SidecarBox.Body>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
<SidecarBox.Footer className="text-xs p-0 divide-y divide-border">
|
|
113
|
+
{description && (
|
|
114
|
+
<div className="text-muted-foreground text-xs px-3 py-2">
|
|
115
|
+
{description}
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
{(examples.length !== 0 || content.length !== 0) && (
|
|
119
119
|
<div className="flex items-center gap-2 justify-between min-w-0 px-3 py-2">
|
|
120
120
|
<div className="flex items-center gap-2 min-w-0">
|
|
121
121
|
{content.length > 1 ? (
|
|
@@ -156,8 +156,8 @@ export const SidecarExamples = ({
|
|
|
156
156
|
</div>
|
|
157
157
|
)}
|
|
158
158
|
</div>
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
)}
|
|
160
|
+
</SidecarBox.Footer>
|
|
161
161
|
</>
|
|
162
162
|
);
|
|
163
163
|
};
|
|
@@ -17,12 +17,14 @@ 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($input: JSON
|
|
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":
|
|
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
|
-
"\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n tags {\n
|
|
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(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n operations(tag: $tag, untagged: $untagged) {\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n":
|
|
27
|
+
types.GetOperationsDocument,
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -41,7 +43,7 @@ export function graphql(
|
|
|
41
43
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
42
44
|
*/
|
|
43
45
|
export function graphql(
|
|
44
|
-
source: "\n query AllOperations($input: JSON
|
|
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",
|
|
45
47
|
): typeof import("./graphql.js").AllOperationsDocument;
|
|
46
48
|
/**
|
|
47
49
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
@@ -53,8 +55,14 @@ export function graphql(
|
|
|
53
55
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
54
56
|
*/
|
|
55
57
|
export function graphql(
|
|
56
|
-
source: "\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n tags {\n
|
|
58
|
+
source: "\n query GetCategories($input: JSON!, $type: SchemaType!) {\n schema(input: $input, type: $type) {\n url\n tags {\n name\n }\n }\n }\n",
|
|
57
59
|
): typeof import("./graphql.js").GetCategoriesDocument;
|
|
60
|
+
/**
|
|
61
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
62
|
+
*/
|
|
63
|
+
export function graphql(
|
|
64
|
+
source: "\n query GetOperations(\n $input: JSON!\n $type: SchemaType!\n $tag: String\n $untagged: Boolean\n ) {\n schema(input: $input, type: $type) {\n operations(tag: $tag, untagged: $untagged) {\n slug\n deprecated\n method\n summary\n operationId\n path\n }\n }\n }\n",
|
|
65
|
+
): typeof import("./graphql.js").GetOperationsDocument;
|
|
58
66
|
|
|
59
67
|
export function graphql(source: string) {
|
|
60
68
|
return (documents as any)[source] ?? {};
|