fumadocs-openapi 5.11.0 → 5.11.2
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/index.d.ts +4 -9
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.js +23 -23
- package/dist/ui/client-client-Dxsry8Mu.js +538 -0
- package/dist/ui/{fetcher-B7R5rjLv.js → fetcher-C0NHTJev.js} +1 -1
- package/dist/ui/{index-client-B6op0H4J.js → index-client-wsc_5cAY.js} +18 -119
- package/dist/ui/index.d.ts +31 -19
- package/dist/ui/index.js +6 -8
- package/package.json +3 -3
- package/dist/ui/client-client-NS2E5Jdn.js +0 -312
package/dist/index.d.ts
CHANGED
|
@@ -73,7 +73,6 @@ interface ResponseProps {
|
|
|
73
73
|
interface APIInfoProps {
|
|
74
74
|
method: string;
|
|
75
75
|
route: string;
|
|
76
|
-
baseUrls: string[];
|
|
77
76
|
head: ReactNode;
|
|
78
77
|
children: ReactNode;
|
|
79
78
|
}
|
|
@@ -100,6 +99,7 @@ interface ResponseTypeProps {
|
|
|
100
99
|
}
|
|
101
100
|
interface RootProps {
|
|
102
101
|
baseUrl?: string;
|
|
102
|
+
servers: ServerObject[];
|
|
103
103
|
children: ReactNode;
|
|
104
104
|
}
|
|
105
105
|
interface Renderer {
|
|
@@ -178,12 +178,7 @@ type SecuritySchemeObject = OpenAPIV3_1.SecuritySchemeObject;
|
|
|
178
178
|
type ReferenceObject = OpenAPIV3_1.ReferenceObject;
|
|
179
179
|
type PathItemObject = OpenAPIV3_1.PathItemObject;
|
|
180
180
|
type TagObject = OpenAPIV3_1.TagObject;
|
|
181
|
-
|
|
182
|
-
path: string;
|
|
183
|
-
summary?: string;
|
|
184
|
-
description?: string;
|
|
185
|
-
methods: MethodInformation[];
|
|
186
|
-
}
|
|
181
|
+
type ServerObject = NoReference<OpenAPIV3_1.ServerObject>;
|
|
187
182
|
type MethodInformation = NoReference<OperationObject> & {
|
|
188
183
|
method: string;
|
|
189
184
|
};
|
|
@@ -203,7 +198,7 @@ interface RenderContext {
|
|
|
203
198
|
*/
|
|
204
199
|
document: NoReference<Document>;
|
|
205
200
|
baseUrl: string;
|
|
206
|
-
|
|
201
|
+
servers: ServerObject[];
|
|
207
202
|
slugger: Slugger;
|
|
208
203
|
dereferenceMap: DereferenceMap;
|
|
209
204
|
/**
|
|
@@ -322,4 +317,4 @@ interface Config extends GenerateOptions {
|
|
|
322
317
|
}
|
|
323
318
|
declare function generateFiles(options: Config): Promise<void>;
|
|
324
319
|
|
|
325
|
-
export { type Config, type DereferenceMap, type Document, type GenerateOptions, type GeneratePageOutput, type GenerateTagOutput, type MethodInformation, type OperationObject, type ParameterObject, type PathItemObject, type ReferenceObject, type RenderContext, type
|
|
320
|
+
export { type Config, type DereferenceMap, type Document, type GenerateOptions, type GeneratePageOutput, type GenerateTagOutput, type MethodInformation, type OperationObject, type ParameterObject, type PathItemObject, type ReferenceObject, type RenderContext, type SecurityRequirementObject, type SecuritySchemeObject, type ServerObject, type TagObject, generateAll, generateFiles, generatePages, generateTags };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -75,7 +75,6 @@ interface ResponseProps {
|
|
|
75
75
|
interface APIInfoProps {
|
|
76
76
|
method: string;
|
|
77
77
|
route: string;
|
|
78
|
-
baseUrls: string[];
|
|
79
78
|
head: ReactNode;
|
|
80
79
|
children: ReactNode;
|
|
81
80
|
}
|
|
@@ -102,6 +101,7 @@ interface ResponseTypeProps {
|
|
|
102
101
|
}
|
|
103
102
|
interface RootProps {
|
|
104
103
|
baseUrl?: string;
|
|
104
|
+
servers: ServerObject[];
|
|
105
105
|
children: ReactNode;
|
|
106
106
|
}
|
|
107
107
|
interface Renderer {
|
|
@@ -174,6 +174,7 @@ interface CodeSample {
|
|
|
174
174
|
|
|
175
175
|
type Document = OpenAPIV3_1.Document;
|
|
176
176
|
type ReferenceObject = OpenAPIV3_1.ReferenceObject;
|
|
177
|
+
type ServerObject = NoReference<OpenAPIV3_1.ServerObject>;
|
|
177
178
|
type Awaitable<T> = T | Promise<T>;
|
|
178
179
|
/**
|
|
179
180
|
* Dereferenced value and its original `$ref` value
|
|
@@ -190,7 +191,7 @@ interface RenderContext {
|
|
|
190
191
|
*/
|
|
191
192
|
document: NoReference<Document>;
|
|
192
193
|
baseUrl: string;
|
|
193
|
-
|
|
194
|
+
servers: ServerObject[];
|
|
194
195
|
slugger: Slugger;
|
|
195
196
|
dereferenceMap: DereferenceMap;
|
|
196
197
|
/**
|
package/dist/server/index.js
CHANGED
|
@@ -24,26 +24,6 @@ function getPreferredType(body) {
|
|
|
24
24
|
if ('application/json' in body) return 'application/json';
|
|
25
25
|
return Object.keys(body)[0];
|
|
26
26
|
}
|
|
27
|
-
/**
|
|
28
|
-
* Convert input to string (with quotes)
|
|
29
|
-
*/ function inputToString(value, mediaType = 'application/json', multiLine = 'none') {
|
|
30
|
-
const getStr = (v)=>{
|
|
31
|
-
if (multiLine === 'none') return JSON.stringify(v);
|
|
32
|
-
const delimit = multiLine === 'backtick' ? `\`` : `'`;
|
|
33
|
-
return `${delimit}${v.replaceAll(delimit, `\\${delimit}`)}${delimit}`;
|
|
34
|
-
};
|
|
35
|
-
if (typeof value === 'string') return getStr(value);
|
|
36
|
-
if (mediaType === 'application/json' || mediaType === 'multipart/form-data') {
|
|
37
|
-
return getStr(JSON.stringify(value, null, 2));
|
|
38
|
-
}
|
|
39
|
-
if (mediaType === 'application/xml') {
|
|
40
|
-
return getStr(js2xml(value, {
|
|
41
|
-
compact: true,
|
|
42
|
-
spaces: 2
|
|
43
|
-
}));
|
|
44
|
-
}
|
|
45
|
-
throw new Error(`Unsupported media type: ${mediaType}`);
|
|
46
|
-
}
|
|
47
27
|
function isNullable(schema, includeOneOf = true) {
|
|
48
28
|
if (Array.isArray(schema.type) && schema.type.includes('null')) return true;
|
|
49
29
|
if (includeOneOf && (schema.anyOf || schema.oneOf)) {
|
|
@@ -159,6 +139,27 @@ function generateBody(method, schema) {
|
|
|
159
139
|
});
|
|
160
140
|
}
|
|
161
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Convert input value to hardcoded string (with quotes)
|
|
144
|
+
*/ function inputToString(value, mediaType = 'application/json', multiLine = 'none') {
|
|
145
|
+
const getStr = (v)=>{
|
|
146
|
+
if (multiLine === 'none') return JSON.stringify(v);
|
|
147
|
+
const delimit = multiLine === 'backtick' ? `\`` : `'`;
|
|
148
|
+
return `${delimit}${v.replaceAll(delimit, `\\${delimit}`)}${delimit}`;
|
|
149
|
+
};
|
|
150
|
+
if (typeof value === 'string') return getStr(value);
|
|
151
|
+
if (mediaType === 'application/json' || mediaType === 'multipart/form-data') {
|
|
152
|
+
return getStr(JSON.stringify(value, null, 2));
|
|
153
|
+
}
|
|
154
|
+
if (mediaType === 'application/xml') {
|
|
155
|
+
return getStr(js2xml(value, {
|
|
156
|
+
compact: true,
|
|
157
|
+
spaces: 2
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
throw new Error(`Unsupported media type: ${mediaType}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
162
163
|
function getSampleRequest$3(endpoint) {
|
|
163
164
|
const s = [];
|
|
164
165
|
s.push(`curl -X ${endpoint.method} "${endpoint.url}"`);
|
|
@@ -791,7 +792,6 @@ const methodKeys = [
|
|
|
791
792
|
];
|
|
792
793
|
|
|
793
794
|
function Operation({ type = 'operation', path, method, ctx, hasHead, headingLevel = 2 }) {
|
|
794
|
-
const { baseUrls } = ctx;
|
|
795
795
|
const body = method.requestBody;
|
|
796
796
|
const security = method.security ?? ctx.document.security;
|
|
797
797
|
let headNode = null;
|
|
@@ -906,7 +906,6 @@ function Operation({ type = 'operation', path, method, ctx, hasHead, headingLeve
|
|
|
906
906
|
head: headNode,
|
|
907
907
|
method: method.method,
|
|
908
908
|
route: path,
|
|
909
|
-
baseUrls: type === 'operation' ? baseUrls : [],
|
|
910
909
|
children: [
|
|
911
910
|
type === 'operation' ? /*#__PURE__*/ jsx(Playground, {
|
|
912
911
|
path: path,
|
|
@@ -1259,6 +1258,7 @@ async function APIPage(props) {
|
|
|
1259
1258
|
const { document } = processed;
|
|
1260
1259
|
return /*#__PURE__*/ jsxs(ctx.renderer.Root, {
|
|
1261
1260
|
baseUrl: ctx.baseUrl,
|
|
1261
|
+
servers: ctx.servers,
|
|
1262
1262
|
children: [
|
|
1263
1263
|
operations?.map((item)=>{
|
|
1264
1264
|
const pathItem = document.paths?.[item.path];
|
|
@@ -1306,7 +1306,7 @@ async function getContext({ document, dereferenceMap }, options = {}) {
|
|
|
1306
1306
|
generateTypeScriptSchema: options.generateTypeScriptSchema,
|
|
1307
1307
|
generateCodeSamples: options.generateCodeSamples,
|
|
1308
1308
|
baseUrl: document.servers?.[0].url ?? 'https://example.com',
|
|
1309
|
-
|
|
1309
|
+
servers: document.servers ?? [],
|
|
1310
1310
|
slugger: new Slugger()
|
|
1311
1311
|
};
|
|
1312
1312
|
}
|
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { forwardRef, createElement, useContext, createContext, useState, useRef, useEffect, useMemo } from 'react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
import { cn, useCopyButton, buttonVariants } from 'fumadocs-ui/components/api';
|
|
6
|
+
import dynamic from 'next/dynamic';
|
|
7
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
8
|
+
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from 'fumadocs-ui/components/ui/collapsible';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @license lucide-react v0.469.0 - ISC
|
|
12
|
+
*
|
|
13
|
+
* This source code is licensed under the ISC license.
|
|
14
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
15
|
+
*/ const toKebabCase = (string)=>string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
16
|
+
const mergeClasses = (...classes)=>classes.filter((className, index, array)=>{
|
|
17
|
+
return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
|
|
18
|
+
}).join(" ").trim();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @license lucide-react v0.469.0 - ISC
|
|
22
|
+
*
|
|
23
|
+
* This source code is licensed under the ISC license.
|
|
24
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
25
|
+
*/ var defaultAttributes = {
|
|
26
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
27
|
+
width: 24,
|
|
28
|
+
height: 24,
|
|
29
|
+
viewBox: "0 0 24 24",
|
|
30
|
+
fill: "none",
|
|
31
|
+
stroke: "currentColor",
|
|
32
|
+
strokeWidth: 2,
|
|
33
|
+
strokeLinecap: "round",
|
|
34
|
+
strokeLinejoin: "round"
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const Icon = /*#__PURE__*/ forwardRef(({ color = "currentColor", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = "", children, iconNode, ...rest }, ref)=>{
|
|
38
|
+
return /*#__PURE__*/ createElement("svg", {
|
|
39
|
+
ref,
|
|
40
|
+
...defaultAttributes,
|
|
41
|
+
width: size,
|
|
42
|
+
height: size,
|
|
43
|
+
stroke: color,
|
|
44
|
+
strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
|
|
45
|
+
className: mergeClasses("lucide", className),
|
|
46
|
+
...rest
|
|
47
|
+
}, [
|
|
48
|
+
...iconNode.map(([tag, attrs])=>/*#__PURE__*/ createElement(tag, attrs)),
|
|
49
|
+
...Array.isArray(children) ? children : [
|
|
50
|
+
children
|
|
51
|
+
]
|
|
52
|
+
]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const createLucideIcon = (iconName, iconNode)=>{
|
|
56
|
+
const Component = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ createElement(Icon, {
|
|
57
|
+
ref,
|
|
58
|
+
iconNode,
|
|
59
|
+
className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),
|
|
60
|
+
...props
|
|
61
|
+
}));
|
|
62
|
+
Component.displayName = `${iconName}`;
|
|
63
|
+
return Component;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const Check = createLucideIcon("Check", [
|
|
67
|
+
[
|
|
68
|
+
"path",
|
|
69
|
+
{
|
|
70
|
+
d: "M20 6 9 17l-5-5",
|
|
71
|
+
key: "1gmf2c"
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
const ChevronDown = createLucideIcon("ChevronDown", [
|
|
77
|
+
[
|
|
78
|
+
"path",
|
|
79
|
+
{
|
|
80
|
+
d: "m6 9 6 6 6-6",
|
|
81
|
+
key: "qrunsl"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
const ChevronUp = createLucideIcon("ChevronUp", [
|
|
87
|
+
[
|
|
88
|
+
"path",
|
|
89
|
+
{
|
|
90
|
+
d: "m18 15-6-6-6 6",
|
|
91
|
+
key: "153udz"
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
const CircleCheck = createLucideIcon("CircleCheck", [
|
|
97
|
+
[
|
|
98
|
+
"circle",
|
|
99
|
+
{
|
|
100
|
+
cx: "12",
|
|
101
|
+
cy: "12",
|
|
102
|
+
r: "10",
|
|
103
|
+
key: "1mglay"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
[
|
|
107
|
+
"path",
|
|
108
|
+
{
|
|
109
|
+
d: "m9 12 2 2 4-4",
|
|
110
|
+
key: "dzmm74"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
const CircleX = createLucideIcon("CircleX", [
|
|
116
|
+
[
|
|
117
|
+
"circle",
|
|
118
|
+
{
|
|
119
|
+
cx: "12",
|
|
120
|
+
cy: "12",
|
|
121
|
+
r: "10",
|
|
122
|
+
key: "1mglay"
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"path",
|
|
127
|
+
{
|
|
128
|
+
d: "m15 9-6 6",
|
|
129
|
+
key: "1uzhvr"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
"path",
|
|
134
|
+
{
|
|
135
|
+
d: "m9 9 6 6",
|
|
136
|
+
key: "z0biqf"
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
const Copy = createLucideIcon("Copy", [
|
|
142
|
+
[
|
|
143
|
+
"rect",
|
|
144
|
+
{
|
|
145
|
+
width: "14",
|
|
146
|
+
height: "14",
|
|
147
|
+
x: "8",
|
|
148
|
+
y: "8",
|
|
149
|
+
rx: "2",
|
|
150
|
+
ry: "2",
|
|
151
|
+
key: "17jyea"
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
[
|
|
155
|
+
"path",
|
|
156
|
+
{
|
|
157
|
+
d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
|
|
158
|
+
key: "zix9uf"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
]);
|
|
162
|
+
|
|
163
|
+
const Plus = createLucideIcon("Plus", [
|
|
164
|
+
[
|
|
165
|
+
"path",
|
|
166
|
+
{
|
|
167
|
+
d: "M5 12h14",
|
|
168
|
+
key: "1ays0h"
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
[
|
|
172
|
+
"path",
|
|
173
|
+
{
|
|
174
|
+
d: "M12 5v14",
|
|
175
|
+
key: "s699le"
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
const Trash2 = createLucideIcon("Trash2", [
|
|
181
|
+
[
|
|
182
|
+
"path",
|
|
183
|
+
{
|
|
184
|
+
d: "M3 6h18",
|
|
185
|
+
key: "d0wm0j"
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
"path",
|
|
190
|
+
{
|
|
191
|
+
d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",
|
|
192
|
+
key: "4alrt4"
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
"path",
|
|
197
|
+
{
|
|
198
|
+
d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",
|
|
199
|
+
key: "v07s0e"
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
[
|
|
203
|
+
"line",
|
|
204
|
+
{
|
|
205
|
+
x1: "10",
|
|
206
|
+
x2: "10",
|
|
207
|
+
y1: "11",
|
|
208
|
+
y2: "17",
|
|
209
|
+
key: "1uufr5"
|
|
210
|
+
}
|
|
211
|
+
],
|
|
212
|
+
[
|
|
213
|
+
"line",
|
|
214
|
+
{
|
|
215
|
+
x1: "14",
|
|
216
|
+
x2: "14",
|
|
217
|
+
y1: "11",
|
|
218
|
+
y2: "17",
|
|
219
|
+
key: "xtxkd"
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
]);
|
|
223
|
+
|
|
224
|
+
const ApiContext = /*#__PURE__*/ createContext(undefined);
|
|
225
|
+
const ServerSelectContext = /*#__PURE__*/ createContext(undefined);
|
|
226
|
+
function useApiContext() {
|
|
227
|
+
const ctx = useContext(ApiContext);
|
|
228
|
+
if (!ctx) throw new Error('Component must be used under <ApiProvider />');
|
|
229
|
+
return ctx;
|
|
230
|
+
}
|
|
231
|
+
function useServerSelectContext() {
|
|
232
|
+
const ctx = useContext(ServerSelectContext);
|
|
233
|
+
if (!ctx) throw new Error('Component must be used under <ApiProvider />');
|
|
234
|
+
return ctx;
|
|
235
|
+
}
|
|
236
|
+
function ApiProvider({ defaultBaseUrl, children, ...props }) {
|
|
237
|
+
const [server, setServer] = useState(()=>{
|
|
238
|
+
const defaultItem = defaultBaseUrl ? props.servers.find((item)=>item.url === defaultBaseUrl) : undefined;
|
|
239
|
+
return defaultItem ? {
|
|
240
|
+
url: defaultItem.url,
|
|
241
|
+
variables: getDefaultValues(defaultItem)
|
|
242
|
+
} : null;
|
|
243
|
+
});
|
|
244
|
+
const serverRef = useRef(server);
|
|
245
|
+
serverRef.current = server;
|
|
246
|
+
useEffect(()=>{
|
|
247
|
+
const cached = localStorage.getItem('apiBaseUrl');
|
|
248
|
+
if (!cached) return;
|
|
249
|
+
try {
|
|
250
|
+
const obj = JSON.parse(cached);
|
|
251
|
+
if (!obj || typeof obj !== 'object') return;
|
|
252
|
+
setServer(obj);
|
|
253
|
+
} catch {
|
|
254
|
+
// ignore
|
|
255
|
+
}
|
|
256
|
+
}, []);
|
|
257
|
+
return /*#__PURE__*/ jsx(ApiContext.Provider, {
|
|
258
|
+
value: useMemo(()=>({
|
|
259
|
+
...props,
|
|
260
|
+
serverRef
|
|
261
|
+
}), [
|
|
262
|
+
props
|
|
263
|
+
]),
|
|
264
|
+
children: /*#__PURE__*/ jsx(ServerSelectContext.Provider, {
|
|
265
|
+
value: useMemo(()=>({
|
|
266
|
+
server,
|
|
267
|
+
setServerVariables (variables) {
|
|
268
|
+
setServer((prev)=>{
|
|
269
|
+
if (!prev) return null;
|
|
270
|
+
const updated = {
|
|
271
|
+
...prev,
|
|
272
|
+
variables
|
|
273
|
+
};
|
|
274
|
+
localStorage.setItem('apiBaseUrl', JSON.stringify(updated));
|
|
275
|
+
return updated;
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
setServer (value) {
|
|
279
|
+
const obj = props.servers.find((item)=>item.url === value);
|
|
280
|
+
if (!obj) return;
|
|
281
|
+
const result = {
|
|
282
|
+
url: value,
|
|
283
|
+
variables: getDefaultValues(obj)
|
|
284
|
+
};
|
|
285
|
+
localStorage.setItem('apiBaseUrl', JSON.stringify(result));
|
|
286
|
+
setServer(result);
|
|
287
|
+
}
|
|
288
|
+
}), [
|
|
289
|
+
server,
|
|
290
|
+
props.servers
|
|
291
|
+
]),
|
|
292
|
+
children: children
|
|
293
|
+
})
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
function getDefaultValues(server) {
|
|
297
|
+
return Object.fromEntries(Object.entries(server.variables ?? {}).map(([k, v])=>[
|
|
298
|
+
k,
|
|
299
|
+
v.default
|
|
300
|
+
]));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const Input = /*#__PURE__*/ React.forwardRef(({ className, type, ...props }, ref)=>{
|
|
304
|
+
return /*#__PURE__*/ jsx("input", {
|
|
305
|
+
type: type,
|
|
306
|
+
className: cn('flex h-9 w-full rounded-md border bg-transparent px-2 py-1.5 text-sm text-fd-foreground transition-colors placeholder:text-fd-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50', className),
|
|
307
|
+
ref: ref,
|
|
308
|
+
...props
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
Input.displayName = 'Input';
|
|
312
|
+
|
|
313
|
+
const Select = SelectPrimitive.Root;
|
|
314
|
+
const SelectValue = SelectPrimitive.Value;
|
|
315
|
+
const SelectTrigger = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>/*#__PURE__*/ jsxs(SelectPrimitive.Trigger, {
|
|
316
|
+
ref: ref,
|
|
317
|
+
className: cn('flex h-10 items-center justify-between rounded-md border px-3 py-2 text-sm text-fd-foreground hover:bg-fd-accent focus:outline-none focus:ring-2 focus:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50', className),
|
|
318
|
+
...props,
|
|
319
|
+
children: [
|
|
320
|
+
children,
|
|
321
|
+
/*#__PURE__*/ jsx(SelectPrimitive.Icon, {
|
|
322
|
+
asChild: true,
|
|
323
|
+
children: /*#__PURE__*/ jsx(ChevronDown, {
|
|
324
|
+
className: "size-4 text-fd-muted-foreground"
|
|
325
|
+
})
|
|
326
|
+
})
|
|
327
|
+
]
|
|
328
|
+
}));
|
|
329
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
330
|
+
const SelectScrollUpButton = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.ScrollUpButton, {
|
|
331
|
+
ref: ref,
|
|
332
|
+
className: cn('flex items-center justify-center py-1', className),
|
|
333
|
+
...props,
|
|
334
|
+
children: /*#__PURE__*/ jsx(ChevronUp, {
|
|
335
|
+
className: "size-4"
|
|
336
|
+
})
|
|
337
|
+
}));
|
|
338
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
339
|
+
const SelectScrollDownButton = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.ScrollDownButton, {
|
|
340
|
+
ref: ref,
|
|
341
|
+
className: cn('flex items-center justify-center py-1', className),
|
|
342
|
+
...props,
|
|
343
|
+
children: /*#__PURE__*/ jsx(ChevronDown, {
|
|
344
|
+
className: "size-4"
|
|
345
|
+
})
|
|
346
|
+
}));
|
|
347
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
348
|
+
const SelectContent = /*#__PURE__*/ forwardRef(({ className, children, position = 'popper', ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Portal, {
|
|
349
|
+
children: /*#__PURE__*/ jsxs(SelectPrimitive.Content, {
|
|
350
|
+
ref: ref,
|
|
351
|
+
className: cn('z-50 overflow-hidden rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-md data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in', className),
|
|
352
|
+
position: position,
|
|
353
|
+
...props,
|
|
354
|
+
children: [
|
|
355
|
+
/*#__PURE__*/ jsx(SelectScrollUpButton, {}),
|
|
356
|
+
/*#__PURE__*/ jsx(SelectPrimitive.Viewport, {
|
|
357
|
+
className: cn('p-1', position === 'popper' && 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'),
|
|
358
|
+
children: children
|
|
359
|
+
}),
|
|
360
|
+
/*#__PURE__*/ jsx(SelectScrollDownButton, {})
|
|
361
|
+
]
|
|
362
|
+
})
|
|
363
|
+
}));
|
|
364
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
365
|
+
const SelectLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Label, {
|
|
366
|
+
ref: ref,
|
|
367
|
+
className: cn('py-1.5 pe-2 ps-6 text-sm font-semibold', className),
|
|
368
|
+
...props
|
|
369
|
+
}));
|
|
370
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
371
|
+
const SelectItem = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>/*#__PURE__*/ jsxs(SelectPrimitive.Item, {
|
|
372
|
+
ref: ref,
|
|
373
|
+
className: cn('flex select-none flex-row items-center rounded-md py-1.5 pe-2 ps-6 text-sm outline-none focus:bg-fd-accent focus:text-fd-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', className),
|
|
374
|
+
...props,
|
|
375
|
+
children: [
|
|
376
|
+
/*#__PURE__*/ jsx(SelectPrimitive.ItemIndicator, {
|
|
377
|
+
className: "absolute start-2",
|
|
378
|
+
children: /*#__PURE__*/ jsx(Check, {
|
|
379
|
+
className: "size-4"
|
|
380
|
+
})
|
|
381
|
+
}),
|
|
382
|
+
/*#__PURE__*/ jsx(SelectPrimitive.ItemText, {
|
|
383
|
+
children: children
|
|
384
|
+
})
|
|
385
|
+
]
|
|
386
|
+
}));
|
|
387
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
388
|
+
const SelectSeparator = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Separator, {
|
|
389
|
+
ref: ref,
|
|
390
|
+
className: cn('my-1 h-px bg-fd-muted', className),
|
|
391
|
+
...props
|
|
392
|
+
}));
|
|
393
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
394
|
+
|
|
395
|
+
function getUrl(url, variables) {
|
|
396
|
+
let out = url;
|
|
397
|
+
for (const [key, value] of Object.entries(variables)){
|
|
398
|
+
out = out.replaceAll(`{${key}}`, value);
|
|
399
|
+
}
|
|
400
|
+
return out;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const SchemaContext = /*#__PURE__*/ createContext(undefined);
|
|
404
|
+
function useSchemaContext() {
|
|
405
|
+
const ctx = useContext(SchemaContext);
|
|
406
|
+
if (!ctx) throw new Error('Missing provider');
|
|
407
|
+
return ctx;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const APIPlayground = dynamic(()=>import('./index-client-wsc_5cAY.js').then(function (n) { return n.i; }).then((mod)=>mod.APIPlayground));
|
|
411
|
+
function Root({ children, baseUrl, className, shikiOptions, servers, ...props }) {
|
|
412
|
+
return /*#__PURE__*/ jsx("div", {
|
|
413
|
+
className: cn('flex flex-col gap-24 text-sm text-fd-muted-foreground', className),
|
|
414
|
+
...props,
|
|
415
|
+
children: /*#__PURE__*/ jsx(ApiProvider, {
|
|
416
|
+
servers: servers,
|
|
417
|
+
shikiOptions: shikiOptions,
|
|
418
|
+
defaultBaseUrl: baseUrl,
|
|
419
|
+
children: children
|
|
420
|
+
})
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
function CopyRouteButton({ className, route, ...props }) {
|
|
424
|
+
const { serverRef } = useApiContext();
|
|
425
|
+
const [checked, onCopy] = useCopyButton(()=>{
|
|
426
|
+
void navigator.clipboard.writeText(`${serverRef.current ? getUrl(serverRef.current.url, serverRef.current.variables) : ''}${route}`);
|
|
427
|
+
});
|
|
428
|
+
return /*#__PURE__*/ jsx("button", {
|
|
429
|
+
type: "button",
|
|
430
|
+
className: cn(buttonVariants({
|
|
431
|
+
color: 'ghost',
|
|
432
|
+
className
|
|
433
|
+
})),
|
|
434
|
+
onClick: onCopy,
|
|
435
|
+
"aria-label": "Copy route path",
|
|
436
|
+
...props,
|
|
437
|
+
children: checked ? /*#__PURE__*/ jsx(Check, {
|
|
438
|
+
className: "size-full"
|
|
439
|
+
}) : /*#__PURE__*/ jsx(Copy, {
|
|
440
|
+
className: "size-full"
|
|
441
|
+
})
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
function ServerSelect() {
|
|
445
|
+
const { servers } = useApiContext();
|
|
446
|
+
const { server, setServer, setServerVariables } = useServerSelectContext();
|
|
447
|
+
if (servers.length <= 1) return null;
|
|
448
|
+
const schema = server ? servers.find((item)=>item.url === server.url) : undefined;
|
|
449
|
+
return /*#__PURE__*/ jsxs(Collapsible, {
|
|
450
|
+
className: "-m-2 mt-2",
|
|
451
|
+
children: [
|
|
452
|
+
/*#__PURE__*/ jsxs(CollapsibleTrigger, {
|
|
453
|
+
className: "flex w-full flex-row items-center justify-between p-2 text-xs font-medium",
|
|
454
|
+
children: [
|
|
455
|
+
"Configure Server",
|
|
456
|
+
/*#__PURE__*/ jsx(ChevronDown, {
|
|
457
|
+
className: "size-4 text-fd-muted-foreground"
|
|
458
|
+
})
|
|
459
|
+
]
|
|
460
|
+
}),
|
|
461
|
+
/*#__PURE__*/ jsx(CollapsibleContent, {
|
|
462
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
463
|
+
className: "flex flex-col gap-4 p-2",
|
|
464
|
+
children: [
|
|
465
|
+
/*#__PURE__*/ jsxs(Select, {
|
|
466
|
+
value: server?.url,
|
|
467
|
+
onValueChange: setServer,
|
|
468
|
+
children: [
|
|
469
|
+
/*#__PURE__*/ jsx(SelectTrigger, {
|
|
470
|
+
className: "h-auto",
|
|
471
|
+
children: /*#__PURE__*/ jsx(SelectValue, {})
|
|
472
|
+
}),
|
|
473
|
+
/*#__PURE__*/ jsx(SelectContent, {
|
|
474
|
+
children: servers.map((item)=>/*#__PURE__*/ jsxs(SelectItem, {
|
|
475
|
+
value: item.url,
|
|
476
|
+
children: [
|
|
477
|
+
item.url,
|
|
478
|
+
/*#__PURE__*/ jsx("p", {
|
|
479
|
+
className: "text-start text-xs text-fd-muted-foreground",
|
|
480
|
+
children: item.description
|
|
481
|
+
})
|
|
482
|
+
]
|
|
483
|
+
}, item.url))
|
|
484
|
+
})
|
|
485
|
+
]
|
|
486
|
+
}),
|
|
487
|
+
Object.entries(schema?.variables ?? {}).map(([key, variable])=>{
|
|
488
|
+
if (!server) return;
|
|
489
|
+
const id = `fd_server_select_${key}`;
|
|
490
|
+
return /*#__PURE__*/ jsxs("fieldset", {
|
|
491
|
+
className: "flex flex-col gap-1",
|
|
492
|
+
children: [
|
|
493
|
+
/*#__PURE__*/ jsx("label", {
|
|
494
|
+
className: "font-mono text-xs text-fd-foreground",
|
|
495
|
+
htmlFor: id,
|
|
496
|
+
children: key
|
|
497
|
+
}),
|
|
498
|
+
/*#__PURE__*/ jsx("p", {
|
|
499
|
+
className: "text-xs text-fd-muted-foreground empty:hidden",
|
|
500
|
+
children: variable.description
|
|
501
|
+
}),
|
|
502
|
+
variable.enum ? /*#__PURE__*/ jsxs(Select, {
|
|
503
|
+
value: server.variables[key],
|
|
504
|
+
onValueChange: (v)=>setServerVariables({
|
|
505
|
+
...server?.variables,
|
|
506
|
+
[key]: v
|
|
507
|
+
}),
|
|
508
|
+
children: [
|
|
509
|
+
/*#__PURE__*/ jsx(SelectTrigger, {
|
|
510
|
+
id: id,
|
|
511
|
+
children: /*#__PURE__*/ jsx(SelectValue, {})
|
|
512
|
+
}),
|
|
513
|
+
/*#__PURE__*/ jsx(SelectContent, {
|
|
514
|
+
children: variable.enum.map((value)=>/*#__PURE__*/ jsx(SelectItem, {
|
|
515
|
+
value: value,
|
|
516
|
+
children: value
|
|
517
|
+
}, value))
|
|
518
|
+
})
|
|
519
|
+
]
|
|
520
|
+
}) : /*#__PURE__*/ jsx(Input, {
|
|
521
|
+
id: id,
|
|
522
|
+
value: server.variables[key],
|
|
523
|
+
onChange: (e)=>setServerVariables({
|
|
524
|
+
...server?.variables,
|
|
525
|
+
[key]: e.target.value
|
|
526
|
+
})
|
|
527
|
+
})
|
|
528
|
+
]
|
|
529
|
+
}, key);
|
|
530
|
+
})
|
|
531
|
+
]
|
|
532
|
+
})
|
|
533
|
+
})
|
|
534
|
+
]
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
export { APIPlayground as A, CircleCheck as C, Input as I, Plus as P, Root as R, Select as S, Trash2 as T, SelectTrigger as a, SelectValue as b, SelectContent as c, SelectItem as d, CircleX as e, useApiContext as f, SchemaContext as g, getUrl as h, CopyRouteButton as i, ServerSelect as j, useSchemaContext as u };
|