fumadocs-openapi 10.3.5 → 10.3.6
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/css/generated/shared.css +4 -0
- package/dist/_openapi/types.d.ts +880 -0
- package/dist/index.d.ts +2 -2
- package/dist/playground/client.js +1 -1
- package/dist/playground/components/oauth-dialog.js +19 -7
- package/dist/playground/components/server-select.js +34 -25
- package/dist/requests/media/encode.js +26 -29
- package/dist/server/create.d.ts +2 -2
- package/dist/types.d.ts +18 -13
- package/dist/ui/api-page.d.ts +3 -4
- package/dist/ui/contexts/api.js +4 -3
- package/dist/ui/operation/index.js +3 -3
- package/dist/ui/operation/request-tabs.js +5 -4
- package/dist/utils/pages/preset-auto.js +2 -2
- package/dist/utils/process-document.d.ts +2 -3
- package/dist/utils/process-document.js +3 -2
- package/dist/utils/schema.d.ts +0 -1
- package/dist/utils/schema.js +3 -1
- package/package.json +13 -17
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MediaAdapter } from "./requests/media/adapter.js";
|
|
2
2
|
import { OperationOutput, OutputEntry, OutputGroup, PagesBuilder, PagesBuilderConfig, TagOutput, WebhookOutput, fromSchema, fromServer } from "./utils/pages/builder.js";
|
|
3
3
|
import { SchemaToPagesOptions, createAutoPreset } from "./utils/pages/preset-auto.js";
|
|
4
|
-
import { Awaitable, CallbackObject, DistributiveOmit, Document, MethodInformation, OperationObject, ParameterObject, PathItemObject, ReferenceObject, RenderContext, ResponseObject, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject } from "./types.js";
|
|
4
|
+
import { Awaitable, CallbackObject, DistributiveOmit, Document, ExampleObject, HttpMethods, MediaTypeObject, MethodInformation, OAuth2SecurityScheme, OperationObject, ParameterObject, PathItemObject, ReferenceObject, RenderContext, RequestBodyObject, ResponseObject, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject } from "./types.js";
|
|
5
5
|
import { Config, OutputFile, generateFiles, generateFilesOnly } from "./generate-file.js";
|
|
6
|
-
export { Awaitable, CallbackObject, Config, DistributiveOmit, Document, type MediaAdapter, MethodInformation, OperationObject, OperationOutput, OutputEntry, OutputFile, OutputGroup, PagesBuilder, PagesBuilderConfig, ParameterObject, PathItemObject, ReferenceObject, RenderContext, ResponseObject, SchemaToPagesOptions, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject, TagOutput, WebhookOutput, createAutoPreset, fromSchema, fromServer, generateFiles, generateFilesOnly };
|
|
6
|
+
export { Awaitable, CallbackObject, Config, DistributiveOmit, Document, ExampleObject, HttpMethods, type MediaAdapter, MediaTypeObject, MethodInformation, OAuth2SecurityScheme, OperationObject, OperationOutput, OutputEntry, OutputFile, OutputGroup, PagesBuilder, PagesBuilderConfig, ParameterObject, PathItemObject, ReferenceObject, RenderContext, RequestBodyObject, ResponseObject, SchemaToPagesOptions, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject, TagOutput, WebhookOutput, createAutoPreset, fromSchema, fromServer, generateFiles, generateFilesOnly };
|
|
@@ -98,7 +98,7 @@ function PlaygroundClient({ route, method = "GET", securities, parameters = [],
|
|
|
98
98
|
e.preventDefault();
|
|
99
99
|
},
|
|
100
100
|
children: [
|
|
101
|
-
/* @__PURE__ */ jsx(ServerSelect, {}),
|
|
101
|
+
/* @__PURE__ */ jsx(ServerSelect, { className: "border-b" }),
|
|
102
102
|
/* @__PURE__ */ jsxs("div", {
|
|
103
103
|
className: "flex flex-row items-center gap-2 text-sm p-3 not-last:pb-0",
|
|
104
104
|
children: [
|
|
@@ -12,25 +12,35 @@ import { useForm } from "react-hook-form";
|
|
|
12
12
|
const FlowTypes = {
|
|
13
13
|
password: {
|
|
14
14
|
name: "Resource Owner Password Flow",
|
|
15
|
-
description: "Authenticate using username and password."
|
|
15
|
+
description: "Authenticate using username and password.",
|
|
16
|
+
supported: true
|
|
16
17
|
},
|
|
17
18
|
clientCredentials: {
|
|
18
19
|
name: "Client Credentials",
|
|
19
|
-
description: "Intended for the server-to-server authentication."
|
|
20
|
+
description: "Intended for the server-to-server authentication.",
|
|
21
|
+
supported: true
|
|
20
22
|
},
|
|
21
23
|
authorizationCode: {
|
|
22
24
|
name: "Authorization code",
|
|
23
|
-
description: "Authenticate with 3rd party services"
|
|
25
|
+
description: "Authenticate with 3rd party services",
|
|
26
|
+
supported: true
|
|
24
27
|
},
|
|
25
28
|
implicit: {
|
|
26
29
|
name: "Implicit",
|
|
27
|
-
description: "Retrieve the access token directly."
|
|
30
|
+
description: "Retrieve the access token directly.",
|
|
31
|
+
supported: true
|
|
32
|
+
},
|
|
33
|
+
deviceAuthorization: {
|
|
34
|
+
name: "Device Authorization",
|
|
35
|
+
description: "Authenticate with device.",
|
|
36
|
+
supported: false
|
|
28
37
|
}
|
|
29
38
|
};
|
|
30
39
|
function OauthDialog({ scheme, scopes, setToken, children, open, setOpen }) {
|
|
31
40
|
const [type, setType] = useState(() => {
|
|
32
41
|
return Object.keys(scheme.flows)[0];
|
|
33
42
|
});
|
|
43
|
+
const { supported } = FlowTypes[type];
|
|
34
44
|
const form = useForm({ defaultValues: {
|
|
35
45
|
clientId: "",
|
|
36
46
|
clientSecret: "",
|
|
@@ -252,15 +262,17 @@ function OauthDialog({ scheme, scopes, setToken, children, open, setOpen }) {
|
|
|
252
262
|
...form.register("password", { required: true })
|
|
253
263
|
})]
|
|
254
264
|
})] }),
|
|
255
|
-
error ? /* @__PURE__ */ jsx("p", {
|
|
265
|
+
supported ? /* @__PURE__ */ jsxs(Fragment$1, { children: [error ? /* @__PURE__ */ jsx("p", {
|
|
256
266
|
className: "text-red-400 font-medium text-sm",
|
|
257
267
|
children: String(error)
|
|
258
|
-
}) : null,
|
|
259
|
-
/* @__PURE__ */ jsx("button", {
|
|
268
|
+
}) : null, /* @__PURE__ */ jsx("button", {
|
|
260
269
|
type: "submit",
|
|
261
270
|
disabled: isLoading,
|
|
262
271
|
className: cn(buttonVariants({ color: "primary" })),
|
|
263
272
|
children: authCodeCallback.isLoading ? "Fetching token..." : "Submit"
|
|
273
|
+
})] }) : /* @__PURE__ */ jsx("p", {
|
|
274
|
+
className: "text-fd-muted-foreground bg-fd-muted p-2 rounded-lg border",
|
|
275
|
+
children: "Unsupported"
|
|
264
276
|
})
|
|
265
277
|
]
|
|
266
278
|
})] })]
|
|
@@ -8,6 +8,7 @@ import { Input, labelVariants } from "../../ui/components/input.js";
|
|
|
8
8
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "../../ui/components/dialog.js";
|
|
9
9
|
import { useEffect, useRef, useState } from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { EditIcon } from "lucide-react";
|
|
11
12
|
import { StfProvider, useFieldValue, useListener, useStf } from "@fumari/stf";
|
|
12
13
|
|
|
13
14
|
//#region src/playground/components/server-select.tsx
|
|
@@ -24,34 +25,42 @@ function ServerSelect(props) {
|
|
|
24
25
|
return /* @__PURE__ */ jsxs(Dialog, {
|
|
25
26
|
open,
|
|
26
27
|
onOpenChange: setOpen,
|
|
27
|
-
children: [/* @__PURE__ */
|
|
28
|
-
className: "text-xs p-3 py-2 bg-fd-muted text-fd-muted-foreground transition-colors truncate hover:bg-fd-accent hover:text-fd-accent-foreground focus-visible:outline-none",
|
|
29
|
-
children: isMounted ? withBase(server ? resolveServerUrl(server.url, server.variables) : "/", window.location.origin) : "loading..."
|
|
30
|
-
}), /* @__PURE__ */ jsxs(DialogContent, {
|
|
28
|
+
children: [/* @__PURE__ */ jsxs(DialogTrigger, {
|
|
31
29
|
...props,
|
|
30
|
+
className: cn("flex items-center gap-2 text-sm text-start px-3 py-2 bg-fd-muted text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground", props.className),
|
|
32
31
|
children: [
|
|
33
|
-
/* @__PURE__ */
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
onValueChange: setServer,
|
|
37
|
-
children: [/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }), /* @__PURE__ */ jsx(SelectContent, { children: servers.map((item) => /* @__PURE__ */ jsxs(SelectItem, {
|
|
38
|
-
value: item.url,
|
|
39
|
-
children: [/* @__PURE__ */ jsx("code", {
|
|
40
|
-
className: "text-[0.8125rem]",
|
|
41
|
-
children: item.url
|
|
42
|
-
}), /* @__PURE__ */ jsx("p", {
|
|
43
|
-
className: "text-fd-muted-foreground",
|
|
44
|
-
children: item.description
|
|
45
|
-
})]
|
|
46
|
-
}, item.url)) })]
|
|
32
|
+
/* @__PURE__ */ jsx("span", {
|
|
33
|
+
className: "px-2 py-0.5 -ms-2 font-medium rounded-lg border bg-fd-secondary text-fd-secondary-foreground shadow-sm",
|
|
34
|
+
children: server?.name ?? "Server URL"
|
|
47
35
|
}),
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
36
|
+
/* @__PURE__ */ jsx("code", {
|
|
37
|
+
className: "truncate min-w-0 flex-1",
|
|
38
|
+
children: isMounted ? withBase(server ? resolveServerUrl(server.url, server.variables) : "/", window.location.origin) : "loading..."
|
|
39
|
+
}),
|
|
40
|
+
/* @__PURE__ */ jsx(EditIcon, { className: "size-4" })
|
|
53
41
|
]
|
|
54
|
-
})
|
|
42
|
+
}), /* @__PURE__ */ jsxs(DialogContent, { children: [
|
|
43
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Server URL" }), /* @__PURE__ */ jsx(DialogDescription, { children: "The base URL of your API endpoint." })] }),
|
|
44
|
+
/* @__PURE__ */ jsxs(Select, {
|
|
45
|
+
value: server?.url,
|
|
46
|
+
onValueChange: setServer,
|
|
47
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }), /* @__PURE__ */ jsx(SelectContent, { children: servers.map((item) => /* @__PURE__ */ jsxs(SelectItem, {
|
|
48
|
+
value: item.url,
|
|
49
|
+
children: [/* @__PURE__ */ jsx("code", {
|
|
50
|
+
className: "text-[0.8125rem]",
|
|
51
|
+
children: item.url
|
|
52
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
53
|
+
className: "text-fd-muted-foreground",
|
|
54
|
+
children: item.description
|
|
55
|
+
})]
|
|
56
|
+
}, item.url)) })]
|
|
57
|
+
}),
|
|
58
|
+
server?.variables && serverSchema?.variables && /* @__PURE__ */ jsx(ServerSelectContent, {
|
|
59
|
+
defaultValues: server.variables,
|
|
60
|
+
schema: serverSchema.variables,
|
|
61
|
+
onChange: setServerVariables
|
|
62
|
+
}, server.url)
|
|
63
|
+
] })]
|
|
55
64
|
});
|
|
56
65
|
}
|
|
57
66
|
function ServerSelectContent({ defaultValues, onChange, schema }) {
|
|
@@ -102,7 +111,7 @@ function Field({ fieldName, variable }) {
|
|
|
102
111
|
id: fieldName,
|
|
103
112
|
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
104
113
|
}), /* @__PURE__ */ jsx(SelectContent, { children: variable.enum.map((value) => /* @__PURE__ */ jsx(SelectItem, {
|
|
105
|
-
value,
|
|
114
|
+
value: String(value),
|
|
106
115
|
children: value
|
|
107
116
|
}, value)) })]
|
|
108
117
|
});
|
|
@@ -5,7 +5,7 @@ import "./adapter.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* serialize parameters, see https://swagger.io/docs/specification/v3_0/serialization.
|
|
7
7
|
*/
|
|
8
|
-
function encodeRequestData(from, adapters, parameters) {
|
|
8
|
+
function encodeRequestData(from, adapters, parameters = []) {
|
|
9
9
|
const result = {
|
|
10
10
|
method: from.method,
|
|
11
11
|
body: from.body,
|
|
@@ -92,35 +92,32 @@ function serializePathParameter(field, value, output) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
function serializeQueryParameter(field, value, output) {
|
|
95
|
-
const { explode = true } = field;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
output[field.name] = { values: [Object.entries(value).flat().join(",")] };
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
output[field.name] = { values: [String(value)] };
|
|
95
|
+
const { style, explode = true } = field;
|
|
96
|
+
if (style === "spaceDelimited" && !explode && Array.isArray(value)) {
|
|
97
|
+
output[field.name] = { values: [value.join(" ")] };
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (style === "pipeDelimited" && !explode && Array.isArray(value)) {
|
|
101
|
+
output[field.name] = { values: [value.join("|")] };
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (style === "deepObject" && !Array.isArray(value) && typeof value === "object") {
|
|
105
|
+
for (const [k, v] of Object.entries(value)) output[`${field.name}[${k}]`] = { values: Array.isArray(v) ? v : [String(v)] };
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (Array.isArray(value)) {
|
|
109
|
+
output[field.name] = { values: explode ? value : [value.join(",")] };
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (typeof value === "object" && explode) {
|
|
113
|
+
for (const [k, v] of Object.entries(value)) output[k] = { values: [String(v)] };
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (typeof value === "object") {
|
|
117
|
+
output[field.name] = { values: [Object.entries(value).flat().join(",")] };
|
|
118
|
+
return;
|
|
123
119
|
}
|
|
120
|
+
output[field.name] = { values: [String(value)] };
|
|
124
121
|
}
|
|
125
122
|
function serializeCookieParameter(field, value, output) {
|
|
126
123
|
const { explode = true } = field;
|
package/dist/server/create.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createProxy } from "./proxy.js";
|
|
2
2
|
import { CodeUsageGenerator } from "../ui/operation/usage-tabs/index.js";
|
|
3
|
+
import { Document } from "../types.js";
|
|
3
4
|
import { ProcessedDocument } from "../utils/process-document.js";
|
|
4
|
-
import { OpenAPIV3, OpenAPIV3_1 } from "openapi-types";
|
|
5
5
|
|
|
6
6
|
//#region src/server/create.d.ts
|
|
7
7
|
/**
|
|
8
8
|
* schema id -> file path, URL, or downloaded schema object
|
|
9
9
|
*/
|
|
10
|
-
type SchemaMap = Record<string, string |
|
|
10
|
+
type SchemaMap = Record<string, string | Document>;
|
|
11
11
|
type ProcessedSchemaMap = Record<string, ProcessedDocument>;
|
|
12
12
|
interface OpenAPIOptions {
|
|
13
13
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OpenAPIV3, OpenAPIV3_2 } from "./_openapi/types.js";
|
|
1
2
|
import { NoReference } from "./utils/schema.js";
|
|
2
3
|
import { MediaAdapter } from "./requests/media/adapter.js";
|
|
3
4
|
import { CodeUsageGenerator } from "./ui/operation/usage-tabs/index.js";
|
|
@@ -7,20 +8,24 @@ import { CreateAPIPageOptions } from "./ui/base.js";
|
|
|
7
8
|
import { ProcessedDocument } from "./utils/process-document.js";
|
|
8
9
|
import Slugger from "github-slugger";
|
|
9
10
|
import { HTMLAttributes, ReactNode } from "react";
|
|
10
|
-
import { OpenAPIV3_1 } from "openapi-types";
|
|
11
11
|
|
|
12
12
|
//#region src/types.d.ts
|
|
13
|
-
type Document =
|
|
14
|
-
type OperationObject =
|
|
15
|
-
type ParameterObject =
|
|
16
|
-
type SecuritySchemeObject =
|
|
17
|
-
type ReferenceObject =
|
|
18
|
-
type PathItemObject =
|
|
19
|
-
type TagObject =
|
|
20
|
-
type ServerObject =
|
|
21
|
-
type CallbackObject =
|
|
22
|
-
type ServerVariableObject =
|
|
23
|
-
type ResponseObject =
|
|
13
|
+
type Document = OpenAPIV3_2.Document;
|
|
14
|
+
type OperationObject = OpenAPIV3_2.OperationObject;
|
|
15
|
+
type ParameterObject = OpenAPIV3_2.ParameterObject;
|
|
16
|
+
type SecuritySchemeObject = OpenAPIV3_2.SecuritySchemeObject;
|
|
17
|
+
type ReferenceObject = OpenAPIV3_2.ReferenceObject;
|
|
18
|
+
type PathItemObject = OpenAPIV3_2.PathItemObject;
|
|
19
|
+
type TagObject = OpenAPIV3_2.TagObject;
|
|
20
|
+
type ServerObject = OpenAPIV3_2.ServerObject;
|
|
21
|
+
type CallbackObject = OpenAPIV3_2.CallbackObject;
|
|
22
|
+
type ServerVariableObject = OpenAPIV3.ServerVariableObject;
|
|
23
|
+
type ResponseObject = OpenAPIV3_2.ResponseObject;
|
|
24
|
+
type OAuth2SecurityScheme = OpenAPIV3_2.OAuth2SecurityScheme;
|
|
25
|
+
type HttpMethods = OpenAPIV3_2.HttpMethods;
|
|
26
|
+
type ExampleObject = OpenAPIV3_2.ExampleObject;
|
|
27
|
+
type MediaTypeObject = OpenAPIV3_2.MediaTypeObject;
|
|
28
|
+
type RequestBodyObject = OpenAPIV3_2.RequestBodyObject;
|
|
24
29
|
type MethodInformation = NoReference<OperationObject> & {
|
|
25
30
|
method: string;
|
|
26
31
|
'x-codeSamples'?: Omit<CodeUsageGenerator, 'id'>[];
|
|
@@ -41,4 +46,4 @@ interface RenderContext extends Pick<OpenAPIOptions, 'proxyUrl'>, Omit<CreateAPI
|
|
|
41
46
|
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
42
47
|
type Awaitable<T> = T | Promise<T>;
|
|
43
48
|
//#endregion
|
|
44
|
-
export { Awaitable, CallbackObject, DistributiveOmit, Document, MethodInformation, OperationObject, ParameterObject, PathItemObject, ReferenceObject, RenderContext, ResponseObject, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject };
|
|
49
|
+
export { Awaitable, CallbackObject, DistributiveOmit, Document, ExampleObject, HttpMethods, MediaTypeObject, MethodInformation, OAuth2SecurityScheme, OperationObject, ParameterObject, PathItemObject, ReferenceObject, RenderContext, RequestBodyObject, ResponseObject, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject };
|
package/dist/ui/api-page.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import "../types.js";
|
|
1
|
+
import { HttpMethods } from "../types.js";
|
|
2
2
|
import { ProcessedDocument } from "../utils/process-document.js";
|
|
3
3
|
import "react/jsx-runtime";
|
|
4
|
-
import { OpenAPIV3_1 } from "openapi-types";
|
|
5
4
|
|
|
6
5
|
//#region src/ui/api-page.d.ts
|
|
7
6
|
interface ApiPageProps {
|
|
@@ -19,7 +18,7 @@ interface WebhookItem {
|
|
|
19
18
|
* webhook name in `webhooks`
|
|
20
19
|
*/
|
|
21
20
|
name: string;
|
|
22
|
-
method:
|
|
21
|
+
method: HttpMethods;
|
|
23
22
|
}
|
|
24
23
|
interface OperationItem {
|
|
25
24
|
/**
|
|
@@ -29,7 +28,7 @@ interface OperationItem {
|
|
|
29
28
|
/**
|
|
30
29
|
* the HTTP method of operation
|
|
31
30
|
*/
|
|
32
|
-
method:
|
|
31
|
+
method: HttpMethods;
|
|
33
32
|
}
|
|
34
33
|
//#endregion
|
|
35
34
|
export { ApiPageProps, OperationItem, WebhookItem };
|
package/dist/ui/contexts/api.js
CHANGED
|
@@ -54,6 +54,7 @@ function ServerSelectProvider({ defaultBaseUrl, children }) {
|
|
|
54
54
|
const [server, setServer] = useState(() => {
|
|
55
55
|
const defaultItem = defaultBaseUrl ? servers.find((item) => item.url === defaultBaseUrl) : servers[0];
|
|
56
56
|
return defaultItem ? {
|
|
57
|
+
name: defaultItem.name,
|
|
57
58
|
url: defaultItem.url,
|
|
58
59
|
variables: getDefaultValues(defaultItem)
|
|
59
60
|
} : null;
|
|
@@ -64,8 +65,7 @@ function ServerSelectProvider({ defaultBaseUrl, children }) {
|
|
|
64
65
|
if (!cached) return;
|
|
65
66
|
try {
|
|
66
67
|
const obj = JSON.parse(cached);
|
|
67
|
-
if (
|
|
68
|
-
setServer(obj);
|
|
68
|
+
if (typeof obj === "object" && obj !== null && "url" in obj && typeof obj.url === "string" && "variables" in obj && typeof obj.variables === "object" && obj.variables !== null) setServer(obj);
|
|
69
69
|
} catch {}
|
|
70
70
|
}, [storageKeys]);
|
|
71
71
|
return /* @__PURE__ */ jsx(ServerSelectContext, {
|
|
@@ -86,6 +86,7 @@ function ServerSelectProvider({ defaultBaseUrl, children }) {
|
|
|
86
86
|
const obj = servers.find((item) => item.url === value);
|
|
87
87
|
if (!obj) return;
|
|
88
88
|
const result = {
|
|
89
|
+
name: obj.name,
|
|
89
90
|
url: value,
|
|
90
91
|
variables: getDefaultValues(obj)
|
|
91
92
|
};
|
|
@@ -103,7 +104,7 @@ function ServerSelectProvider({ defaultBaseUrl, children }) {
|
|
|
103
104
|
function getDefaultValues(server) {
|
|
104
105
|
const out = {};
|
|
105
106
|
if (!server.variables) return out;
|
|
106
|
-
for (const [k, v] of Object.entries(server.variables)) out[k] = v.default;
|
|
107
|
+
for (const [k, v] of Object.entries(server.variables)) if (v.default !== void 0) out[k] = String(v.default);
|
|
107
108
|
return out;
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -36,7 +36,7 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
|
|
|
36
36
|
headNode = ctx.renderHeading(headingLevel, title);
|
|
37
37
|
headingLevel++;
|
|
38
38
|
}
|
|
39
|
-
const contentTypes = body ? Object.entries(body.content) : null;
|
|
39
|
+
const contentTypes = body?.content ? Object.entries(body.content) : null;
|
|
40
40
|
if (body && contentTypes && contentTypes.length > 0) {
|
|
41
41
|
const items = contentTypes.map(([key]) => ({
|
|
42
42
|
label: /* @__PURE__ */ jsx("code", {
|
|
@@ -100,11 +100,11 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
|
|
|
100
100
|
name: param.name,
|
|
101
101
|
required: param.required
|
|
102
102
|
},
|
|
103
|
-
root: {
|
|
103
|
+
root: typeof param.schema === "object" ? {
|
|
104
104
|
...param.schema,
|
|
105
105
|
description: param.description ?? param.schema?.description,
|
|
106
106
|
deprecated: (param.deprecated ?? false) || (param.schema?.deprecated ?? false)
|
|
107
|
-
},
|
|
107
|
+
} : param.schema,
|
|
108
108
|
readOnly: method.method === "GET",
|
|
109
109
|
writeOnly: method.method !== "GET",
|
|
110
110
|
ctx
|
|
@@ -9,8 +9,9 @@ import { sample } from "openapi-sampler";
|
|
|
9
9
|
|
|
10
10
|
//#region src/ui/operation/request-tabs.tsx
|
|
11
11
|
function getExampleRequests(path, operation, ctx) {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
12
|
+
const requestBody = operation.requestBody;
|
|
13
|
+
const media = requestBody?.content ? getPreferredType(requestBody.content) : null;
|
|
14
|
+
const bodyOfType = media ? requestBody.content[media] : null;
|
|
14
15
|
if (bodyOfType?.examples) {
|
|
15
16
|
const result = [];
|
|
16
17
|
for (const [key, value] of Object.entries(bodyOfType.examples)) {
|
|
@@ -29,7 +30,7 @@ function getExampleRequests(path, operation, ctx) {
|
|
|
29
30
|
return [{
|
|
30
31
|
id: "_default",
|
|
31
32
|
name: "Default",
|
|
32
|
-
description: bodyOfType?.schema
|
|
33
|
+
description: typeof bodyOfType?.schema === "object" ? bodyOfType.schema.description : void 0,
|
|
33
34
|
data,
|
|
34
35
|
encoded: encodeRequestData(data, ctx.mediaAdapters, operation.parameters ?? [])
|
|
35
36
|
}];
|
|
@@ -66,7 +67,7 @@ function getRequestData(path, method, sampleKey, _ctx) {
|
|
|
66
67
|
default: result.path[param.name] = value;
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
|
-
if (method.requestBody) {
|
|
70
|
+
if (method.requestBody?.content) {
|
|
70
71
|
const body = method.requestBody.content;
|
|
71
72
|
const type = getPreferredType(body);
|
|
72
73
|
if (!type) throw new Error(`Cannot find body schema for ${path} ${method.method}: missing media type`);
|
|
@@ -52,8 +52,8 @@ function createAutoPreset(options) {
|
|
|
52
52
|
schemaId: builder.id,
|
|
53
53
|
path: "",
|
|
54
54
|
info: {
|
|
55
|
-
title: dereferenced.info
|
|
56
|
-
description: dereferenced.info
|
|
55
|
+
title: dereferenced.info?.title ?? "Unknown",
|
|
56
|
+
description: dereferenced.info?.description
|
|
57
57
|
},
|
|
58
58
|
...items
|
|
59
59
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { NoReference } from "./schema.js";
|
|
2
2
|
import { Document } from "../types.js";
|
|
3
|
-
import { OpenAPIV3, OpenAPIV3_1 } from "openapi-types";
|
|
4
3
|
|
|
5
4
|
//#region src/utils/process-document.d.ts
|
|
6
|
-
|
|
5
|
+
interface ProcessedDocument {
|
|
7
6
|
/**
|
|
8
7
|
* dereferenced document
|
|
9
8
|
*/
|
|
@@ -14,6 +13,6 @@ type ProcessedDocument = {
|
|
|
14
13
|
*/
|
|
15
14
|
getRawRef: (obj: object) => string | undefined;
|
|
16
15
|
bundled: Document;
|
|
17
|
-
}
|
|
16
|
+
}
|
|
18
17
|
//#endregion
|
|
19
18
|
export { ProcessedDocument };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { dereference
|
|
1
|
+
import { dereference } from "@scalar/openapi-parser";
|
|
2
2
|
import { bundle } from "@scalar/json-magic/bundle";
|
|
3
|
+
import { upgrade } from "@scalar/openapi-upgrader";
|
|
3
4
|
import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
4
5
|
|
|
5
6
|
//#region src/utils/process-document.ts
|
|
@@ -14,7 +15,7 @@ async function processDocument(input) {
|
|
|
14
15
|
hooks: { onResolveError(node) {
|
|
15
16
|
throw new Error(`Failed to resolve ${node.$ref}`);
|
|
16
17
|
} }
|
|
17
|
-
}).then((v) => upgrade(v
|
|
18
|
+
}).then((v) => upgrade(v, "3.2")).catch((e) => {
|
|
18
19
|
throw new Error(`[OpenAPI] Failed to resolve input: ${input}`, { cause: e });
|
|
19
20
|
});
|
|
20
21
|
/**
|
package/dist/utils/schema.d.ts
CHANGED
package/dist/utils/schema.js
CHANGED
|
@@ -14,7 +14,9 @@ function getPreferredType(body) {
|
|
|
14
14
|
return Object.keys(body)[0];
|
|
15
15
|
}
|
|
16
16
|
function getTagDisplayName(tag) {
|
|
17
|
-
|
|
17
|
+
if ("x-displayName" in tag && typeof tag["x-displayName"] === "string") return tag["x-displayName"];
|
|
18
|
+
if (tag.summary) return tag.summary;
|
|
19
|
+
return idToTitle(tag.name);
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Summarize method endpoint information
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-openapi",
|
|
3
|
-
"version": "10.3.
|
|
3
|
+
"version": "10.3.6",
|
|
4
4
|
"description": "Generate MDX docs for your OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -61,37 +61,37 @@
|
|
|
61
61
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
62
62
|
"@radix-ui/react-select": "^2.2.6",
|
|
63
63
|
"@radix-ui/react-slot": "^1.2.4",
|
|
64
|
-
"@scalar/json-magic": "^0.
|
|
65
|
-
"@scalar/openapi-parser": "0.24.
|
|
66
|
-
"
|
|
64
|
+
"@scalar/json-magic": "^0.11.1",
|
|
65
|
+
"@scalar/openapi-parser": "0.24.10",
|
|
66
|
+
"@scalar/openapi-upgrader": "^0.1.8",
|
|
67
|
+
"ajv": "^8.18.0",
|
|
67
68
|
"class-variance-authority": "^0.7.1",
|
|
68
69
|
"github-slugger": "^2.0.0",
|
|
69
70
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
70
71
|
"js-yaml": "^4.1.1",
|
|
71
|
-
"lucide-react": "^0.
|
|
72
|
+
"lucide-react": "^0.570.0",
|
|
72
73
|
"next-themes": "^0.4.6",
|
|
73
|
-
"openapi-sampler": "^1.
|
|
74
|
+
"openapi-sampler": "^1.7.0",
|
|
74
75
|
"react-hook-form": "^7.71.1",
|
|
75
76
|
"remark": "^15.0.1",
|
|
76
77
|
"remark-rehype": "^11.1.2",
|
|
77
|
-
"tailwind-merge": "^3.4.
|
|
78
|
+
"tailwind-merge": "^3.4.1",
|
|
78
79
|
"xml-js": "^1.6.11",
|
|
79
80
|
"@fumari/stf": "^0.0.3"
|
|
80
81
|
},
|
|
81
82
|
"devDependencies": {
|
|
82
|
-
"@scalar/api-client-react": "^1.3.
|
|
83
|
+
"@scalar/api-client-react": "^1.3.96",
|
|
83
84
|
"@types/js-yaml": "^4.0.9",
|
|
84
|
-
"@types/node": "25.2.
|
|
85
|
+
"@types/node": "25.2.3",
|
|
85
86
|
"@types/openapi-sampler": "^1.0.3",
|
|
86
|
-
"@types/react": "^19.2.
|
|
87
|
+
"@types/react": "^19.2.14",
|
|
87
88
|
"json-schema-typed": "^8.0.2",
|
|
88
|
-
"openapi-types": "^12.1.3",
|
|
89
89
|
"tailwindcss": "^4.1.18",
|
|
90
90
|
"tsdown": "^0.20.3",
|
|
91
91
|
"@fumadocs/tailwind": "0.0.2",
|
|
92
92
|
"eslint-config-custom": "0.0.0",
|
|
93
|
-
"fumadocs-core": "16.6.
|
|
94
|
-
"fumadocs-ui": "16.6.
|
|
93
|
+
"fumadocs-core": "16.6.3",
|
|
94
|
+
"fumadocs-ui": "16.6.3",
|
|
95
95
|
"tsconfig": "0.0.0"
|
|
96
96
|
},
|
|
97
97
|
"peerDependencies": {
|
|
@@ -100,7 +100,6 @@
|
|
|
100
100
|
"fumadocs-core": "^16.5.0",
|
|
101
101
|
"fumadocs-ui": "^16.5.0",
|
|
102
102
|
"json-schema-typed": "*",
|
|
103
|
-
"openapi-types": "*",
|
|
104
103
|
"react": "^19.2.0",
|
|
105
104
|
"react-dom": "^19.2.0"
|
|
106
105
|
},
|
|
@@ -108,9 +107,6 @@
|
|
|
108
107
|
"json-schema-typed": {
|
|
109
108
|
"optional": true
|
|
110
109
|
},
|
|
111
|
-
"openapi-types": {
|
|
112
|
-
"optional": true
|
|
113
|
-
},
|
|
114
110
|
"@types/react": {
|
|
115
111
|
"optional": true
|
|
116
112
|
},
|