OpenAPI: Support OpenAPI 3.2 security scheme deprecation

This commit is contained in:
Fuma Nama
2026-02-19 17:43:39 +08:00
parent 108b16d460
commit 3f8c9b0ed9
5 changed files with 49 additions and 18 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-openapi': patch
---
Support OpenAPI 3.2 security scheme deprecation
+1
View File
@@ -445,6 +445,7 @@ components:
type: http
scheme: bearer
description: JWT Bearer token authentication
deprecated: true
basicAuth:
type: http
scheme: basic
+5 -4
View File
@@ -261,13 +261,14 @@ export declare namespace OpenAPIV3_2 {
mediaTypes?: Record<string, MediaTypeObject | ReferenceObject>;
}
>;
export type SecuritySchemeObject =
export type SecuritySchemeObject = (
| HttpSecurityScheme
| ApiKeySecurityScheme
| OAuth2SecurityScheme
| (OpenIdSecurityScheme & {
deprecated?: boolean;
});
| OpenIdSecurityScheme
) & {
deprecated?: boolean;
};
export type HttpSecurityScheme = OpenAPIV3_1.HttpSecurityScheme;
export type ApiKeySecurityScheme = OpenAPIV3_1.ApiKeySecurityScheme;
export type OAuthFlows = OpenAPIV3_1.OAuthFlows & {
+12 -2
View File
@@ -151,7 +151,10 @@ export default function PlaygroundClient({
},
} = useApiContext();
const { serverRef } = useServerContext();
const [securityId, setSecurityId] = useState(0);
const [securityId, setSecurityId] = useState(() => {
const idx = securities.findIndex((s) => s.every((entry) => !entry.deprecated));
return idx === -1 ? 0 : idx;
});
const { inputs, mapInputs, initAuthValues } = useAuthInputs(
securities[securityId],
transformAuthInputs,
@@ -312,7 +315,14 @@ function SecurityTabs({
<SelectItem key={i} value={i.toString()}>
{security.map((item) => (
<div key={item.id} className="max-w-[600px]">
<p className="font-mono font-medium">{item.id}</p>
<p
className={cn(
'font-mono font-medium',
item.deprecated && 'text-fd-muted-foreground line-through',
)}
>
{item.id}
</p>
<p className="text-fd-muted-foreground whitespace-pre-wrap">{item.description}</p>
</div>
))}
+26 -12
View File
@@ -9,7 +9,7 @@ import { createMethod, methodKeys, type NoReference, type ResolvedSchema } from
import { idToTitle } from '@/utils/id-to-title';
import { Schema } from '../schema';
import { UsageTabs } from '@/ui/operation/usage-tabs';
import { MethodLabel } from '@/ui/components/method-label';
import { Badge, MethodLabel } from '@/ui/components/method-label';
import { CopyResponseTypeScript, SelectTab, SelectTabs, SelectTabTrigger } from './client';
import {
AccordionContent,
@@ -452,7 +452,7 @@ function WebhookCallback({
}
function AuthScheme({
scheme: schema,
scheme,
scopes,
ctx,
}: {
@@ -460,16 +460,17 @@ function AuthScheme({
scopes: string[];
ctx: RenderContext;
}) {
if (schema.type === 'http' || schema.type === 'oauth2') {
if (scheme.type === 'http' || scheme.type === 'oauth2') {
return (
<AuthProperty
name="Authorization"
type={
schema.type === 'http' && schema.scheme === 'basic' ? `Basic <token>` : 'Bearer <token>'
scheme.type === 'http' && scheme.scheme === 'basic' ? `Basic <token>` : 'Bearer <token>'
}
deprecated={scheme.deprecated}
scopes={scopes}
>
{schema.description && ctx.renderMarkdown(schema.description)}
{scheme.description && ctx.renderMarkdown(scheme.description)}
<p>
In: <code>header</code>
</p>
@@ -477,21 +478,31 @@ function AuthScheme({
);
}
if (schema.type === 'apiKey') {
if (scheme.type === 'apiKey') {
return (
<AuthProperty name={schema.name!} type="<token>" scopes={scopes}>
{schema.description && ctx.renderMarkdown(schema.description)}
<AuthProperty
name={scheme.name!}
type="<token>"
deprecated={scheme.deprecated}
scopes={scopes}
>
{scheme.description && ctx.renderMarkdown(scheme.description)}
<p>
In: <code>{schema.in}</code>
In: <code>{scheme.in}</code>
</p>
</AuthProperty>
);
}
if (schema.type === 'openIdConnect') {
if (scheme.type === 'openIdConnect') {
return (
<AuthProperty name="OpenID Connect" type="<token>" scopes={scopes}>
{schema.description && ctx.renderMarkdown(schema.description)}
<AuthProperty
name="OpenID Connect"
type="<token>"
deprecated={scheme.deprecated}
scopes={scopes}
>
{scheme.description && ctx.renderMarkdown(scheme.description)}
</AuthProperty>
);
}
@@ -500,12 +511,14 @@ function AuthScheme({
function AuthProperty({
name,
type,
deprecated = false,
scopes = [],
className,
...props
}: ComponentProps<'div'> & {
name: string;
type: string;
deprecated?: boolean;
scopes?: string[];
}) {
return (
@@ -513,6 +526,7 @@ function AuthProperty({
<div className="flex flex-wrap items-center gap-3 not-prose">
<span className="font-medium font-mono text-fd-primary">{name}</span>
<span className="text-sm font-mono text-fd-muted-foreground">{type}</span>
{deprecated && <Badge color="red">Deprecated</Badge>}
</div>
<div className="prose-no-margin pt-2.5 empty:hidden">
{props.children}