fumadocs-openapi 10.3.5 → 10.3.7

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 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 };
@@ -31,7 +31,10 @@ function PlaygroundClient({ route, method = "GET", securities, parameters = [],
31
31
  const storageKeys = useStorageKey();
32
32
  const { mediaAdapters, client: { playground: { components: { ResultDisplay = DefaultResultDisplay } = {}, requestTimeout = 10, transformAuthInputs } = {} } } = useApiContext();
33
33
  const { serverRef } = useServerContext();
34
- const [securityId, setSecurityId] = useState(0);
34
+ const [securityId, setSecurityId] = useState(() => {
35
+ const idx = securities.findIndex((s) => s.every((entry) => !entry.deprecated));
36
+ return idx === -1 ? 0 : idx;
37
+ });
35
38
  const { inputs, mapInputs, initAuthValues } = useAuthInputs(securities[securityId], transformAuthInputs);
36
39
  const defaultValues = useMemo(() => {
37
40
  const requestData = examples.find((example) => example.id === exampleId)?.data;
@@ -98,7 +101,7 @@ function PlaygroundClient({ route, method = "GET", securities, parameters = [],
98
101
  e.preventDefault();
99
102
  },
100
103
  children: [
101
- /* @__PURE__ */ jsx(ServerSelect, {}),
104
+ /* @__PURE__ */ jsx(ServerSelect, { className: "border-b" }),
102
105
  /* @__PURE__ */ jsxs("div", {
103
106
  className: "flex flex-row items-center gap-2 text-sm p-3 not-last:pb-0",
104
107
  children: [
@@ -150,7 +153,7 @@ function SecurityTabs({ securities, setSecurityId, securityId, children }) {
150
153
  children: security.map((item) => /* @__PURE__ */ jsxs("div", {
151
154
  className: "max-w-[600px]",
152
155
  children: [/* @__PURE__ */ jsx("p", {
153
- className: "font-mono font-medium",
156
+ className: cn("font-mono font-medium", item.deprecated && "text-fd-muted-foreground line-through"),
154
157
  children: item.id
155
158
  }), /* @__PURE__ */ jsx("p", {
156
159
  className: "text-fd-muted-foreground whitespace-pre-wrap",
@@ -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__ */ jsx(DialogTrigger, {
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__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Server URL" }), /* @__PURE__ */ jsx(DialogDescription, { children: "The base URL of your API endpoint." })] }),
34
- /* @__PURE__ */ jsxs(Select, {
35
- value: server?.url,
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
- server?.variables && serverSchema?.variables && /* @__PURE__ */ jsx(ServerSelectContent, {
49
- defaultValues: server.variables,
50
- schema: serverSchema.variables,
51
- onChange: setServerVariables
52
- }, server.url)
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
- switch (field.style) {
97
- case "spaceDelimited": if (!explode && Array.isArray(value)) {
98
- output[field.name] = { values: [value.join(" ")] };
99
- break;
100
- }
101
- case "pipeDelimited": if (!explode && Array.isArray(value)) {
102
- output[field.name] = { values: [value.join("|")] };
103
- break;
104
- }
105
- case "deepObject": if (!Array.isArray(value) && typeof value === "object") {
106
- for (const [k, v] of Object.entries(value)) output[`${field.name}[${k}]`] = { values: Array.isArray(v) ? v : [String(v)] };
107
- break;
108
- }
109
- default:
110
- if (Array.isArray(value)) {
111
- output[field.name] = { values: explode ? value : [value.join(",")] };
112
- break;
113
- }
114
- if (typeof value === "object" && explode) {
115
- for (const [k, v] of Object.entries(value)) output[k] = { values: [String(v)] };
116
- break;
117
- }
118
- if (typeof value === "object") {
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;
@@ -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 | OpenAPIV3_1.Document | OpenAPIV3.Document>;
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 = OpenAPIV3_1.Document;
14
- type OperationObject = OpenAPIV3_1.OperationObject;
15
- type ParameterObject = OpenAPIV3_1.ParameterObject;
16
- type SecuritySchemeObject = OpenAPIV3_1.SecuritySchemeObject;
17
- type ReferenceObject = OpenAPIV3_1.ReferenceObject;
18
- type PathItemObject = OpenAPIV3_1.PathItemObject;
19
- type TagObject = OpenAPIV3_1.TagObject;
20
- type ServerObject = OpenAPIV3_1.ServerObject;
21
- type CallbackObject = OpenAPIV3_1.CallbackObject;
22
- type ServerVariableObject = OpenAPIV3_1.ServerVariableObject;
23
- type ResponseObject = OpenAPIV3_1.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 };
@@ -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: OpenAPIV3_1.HttpMethods;
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: OpenAPIV3_1.HttpMethods;
31
+ method: HttpMethods;
33
32
  }
34
33
  //#endregion
35
34
  export { ApiPageProps, OperationItem, WebhookItem };
@@ -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 (!obj || typeof obj !== "object") return;
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
 
@@ -3,7 +3,7 @@ import { createMethod, methodKeys } from "../../utils/schema.js";
3
3
  import { isMediaTypeSupported } from "../../requests/media/resolve-adapter.js";
4
4
  import "../../requests/media/adapter.js";
5
5
  import { cn } from "../../utils/cn.js";
6
- import { MethodLabel } from "../components/method-label.js";
6
+ import { Badge, MethodLabel } from "../components/method-label.js";
7
7
  import { APIPlayground } from "../../playground/index.js";
8
8
  import { Schema } from "../schema/index.js";
9
9
  import { UsageTabsProviderLazy } from "./usage-tabs/lazy.js";
@@ -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
@@ -370,38 +370,48 @@ function WebhookCallback({ callback, ctx, headingLevel }) {
370
370
  })
371
371
  });
372
372
  }
373
- function AuthScheme({ scheme: schema, scopes, ctx }) {
374
- if (schema.type === "http" || schema.type === "oauth2") return /* @__PURE__ */ jsxs(AuthProperty, {
373
+ function AuthScheme({ scheme, scopes, ctx }) {
374
+ if (scheme.type === "http" || scheme.type === "oauth2") return /* @__PURE__ */ jsxs(AuthProperty, {
375
375
  name: "Authorization",
376
- type: schema.type === "http" && schema.scheme === "basic" ? `Basic <token>` : "Bearer <token>",
376
+ type: scheme.type === "http" && scheme.scheme === "basic" ? `Basic <token>` : "Bearer <token>",
377
+ deprecated: scheme.deprecated,
377
378
  scopes,
378
- children: [schema.description && ctx.renderMarkdown(schema.description), /* @__PURE__ */ jsxs("p", { children: ["In: ", /* @__PURE__ */ jsx("code", { children: "header" })] })]
379
+ children: [scheme.description && ctx.renderMarkdown(scheme.description), /* @__PURE__ */ jsxs("p", { children: ["In: ", /* @__PURE__ */ jsx("code", { children: "header" })] })]
379
380
  });
380
- if (schema.type === "apiKey") return /* @__PURE__ */ jsxs(AuthProperty, {
381
- name: schema.name,
381
+ if (scheme.type === "apiKey") return /* @__PURE__ */ jsxs(AuthProperty, {
382
+ name: scheme.name,
382
383
  type: "<token>",
384
+ deprecated: scheme.deprecated,
383
385
  scopes,
384
- children: [schema.description && ctx.renderMarkdown(schema.description), /* @__PURE__ */ jsxs("p", { children: ["In: ", /* @__PURE__ */ jsx("code", { children: schema.in })] })]
386
+ children: [scheme.description && ctx.renderMarkdown(scheme.description), /* @__PURE__ */ jsxs("p", { children: ["In: ", /* @__PURE__ */ jsx("code", { children: scheme.in })] })]
385
387
  });
386
- if (schema.type === "openIdConnect") return /* @__PURE__ */ jsx(AuthProperty, {
388
+ if (scheme.type === "openIdConnect") return /* @__PURE__ */ jsx(AuthProperty, {
387
389
  name: "OpenID Connect",
388
390
  type: "<token>",
391
+ deprecated: scheme.deprecated,
389
392
  scopes,
390
- children: schema.description && ctx.renderMarkdown(schema.description)
393
+ children: scheme.description && ctx.renderMarkdown(scheme.description)
391
394
  });
392
395
  }
393
- function AuthProperty({ name, type, scopes = [], className, ...props }) {
396
+ function AuthProperty({ name, type, deprecated = false, scopes = [], className, ...props }) {
394
397
  return /* @__PURE__ */ jsxs("div", {
395
398
  className: cn("text-sm border-t my-4 first:border-t-0", className),
396
399
  children: [/* @__PURE__ */ jsxs("div", {
397
400
  className: "flex flex-wrap items-center gap-3 not-prose",
398
- children: [/* @__PURE__ */ jsx("span", {
399
- className: "font-medium font-mono text-fd-primary",
400
- children: name
401
- }), /* @__PURE__ */ jsx("span", {
402
- className: "text-sm font-mono text-fd-muted-foreground",
403
- children: type
404
- })]
401
+ children: [
402
+ /* @__PURE__ */ jsx("span", {
403
+ className: "font-medium font-mono text-fd-primary",
404
+ children: name
405
+ }),
406
+ /* @__PURE__ */ jsx("span", {
407
+ className: "text-sm font-mono text-fd-muted-foreground",
408
+ children: type
409
+ }),
410
+ deprecated && /* @__PURE__ */ jsx(Badge, {
411
+ color: "red",
412
+ children: "Deprecated"
413
+ })
414
+ ]
405
415
  }), /* @__PURE__ */ jsxs("div", {
406
416
  className: "prose-no-margin pt-2.5 empty:hidden",
407
417
  children: [props.children, scopes.length > 0 && /* @__PURE__ */ jsxs("p", { children: ["Scope: ", /* @__PURE__ */ jsx("code", { children: scopes.join(", ") })] })]
@@ -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 media = operation.requestBody ? getPreferredType(operation.requestBody.content) : null;
13
- const bodyOfType = media ? operation.requestBody?.content[media] : null;
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?.description,
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.title,
56
- description: dereferenced.info.description
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
- type ProcessedDocument = {
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, upgrade } from "@scalar/openapi-parser";
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).specification).catch((e) => {
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
  /**
@@ -1,5 +1,4 @@
1
1
  import { ReferenceObject } from "../types.js";
2
- import { OpenAPIV3_1 } from "openapi-types";
3
2
  import { JSONSchema } from "json-schema-typed/draft-2020-12";
4
3
 
5
4
  //#region src/utils/schema.d.ts
@@ -14,7 +14,9 @@ function getPreferredType(body) {
14
14
  return Object.keys(body)[0];
15
15
  }
16
16
  function getTagDisplayName(tag) {
17
- return "x-displayName" in tag && typeof tag["x-displayName"] === "string" ? tag["x-displayName"] : idToTitle(tag.name);
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