Re-arrange OpenAPI Scopes for OAuth2 (#3799)

This commit is contained in:
Nolann B.
2025-11-12 19:40:21 +01:00
committed by GitHub
parent 9cbefa89c7
commit a512c90bda
12 changed files with 37 additions and 12 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@gitbook/react-openapi': patch
---
Re-arrange OpenAPI Scopes for OAuth2
@@ -25,12 +25,6 @@ export function OpenAPIRequiredScopes(props: {
} }
const scopes = selectedSecurity.schemes.flatMap((scheme) => { const scopes = selectedSecurity.schemes.flatMap((scheme) => {
if (scheme.type === 'oauth2') {
return Object.entries(scheme.flows ?? {}).flatMap(([_, flow]) =>
Object.entries(flow.scopes ?? {})
);
}
return scheme.scopes ?? []; return scheme.scopes ?? [];
}); });
@@ -66,16 +60,20 @@ export function OpenAPIRequiredScopes(props: {
); );
} }
function OpenAPISchemaScopes(props: { export function OpenAPISchemaScopes(props: {
scopes: OpenAPISecurityScope[]; scopes: OpenAPISecurityScope[];
context: OpenAPIClientContext; context: OpenAPIClientContext;
isOAuth2?: boolean;
}) { }) {
const { scopes, context } = props; const { scopes, context, isOAuth2 } = props;
return ( return (
<div className="openapi-securities-scopes openapi-markdown"> <div className="openapi-securities-scopes openapi-markdown">
<div className="openapi-required-scopes-description"> <div className="openapi-required-scopes-description">
{t(context.translation, 'required_scopes_description')} {t(
context.translation,
isOAuth2 ? 'available_scopes' : 'required_scopes_description'
)}
</div> </div>
<ul> <ul>
{scopes.map((scope) => ( {scopes.map((scope) => (
@@ -3,7 +3,7 @@ import { Fragment } from 'react';
import { InteractiveSection } from './InteractiveSection'; import { InteractiveSection } from './InteractiveSection';
import { Markdown } from './Markdown'; import { Markdown } from './Markdown';
import { OpenAPICopyButton } from './OpenAPICopyButton'; import { OpenAPICopyButton } from './OpenAPICopyButton';
import { OpenAPIRequiredScopes } from './OpenAPIRequiredScopes'; import { OpenAPIRequiredScopes, OpenAPISchemaScopes } from './OpenAPIRequiredScopes';
import { OpenAPISchemaName } from './OpenAPISchemaName'; import { OpenAPISchemaName } from './OpenAPISchemaName';
import type { OpenAPIClientContext } from './context'; import type { OpenAPIClientContext } from './context';
import { t } from './translate'; import { t } from './translate';
@@ -43,7 +43,11 @@ export function OpenAPISecurities(props: {
body: ( body: (
<div className="openapi-schema"> <div className="openapi-schema">
{schemes.map((security, index) => { {schemes.map((security, index) => {
const description = resolveDescription(security); // OAuth2 description is already rendered in OpenAPISchemaOAuth2Item
const description =
security.type !== 'oauth2'
? resolveDescription(security)
: undefined;
return ( return (
<div <div
key={`${key}-${index}`} key={`${key}-${index}`}
@@ -172,6 +176,10 @@ function OpenAPISchemaOAuth2Item(props: {
return null; return null;
} }
const scopes = !security.scopes?.length && flow.scopes ? Object.entries(flow.scopes) : [];
const description = resolveDescription(security);
return ( return (
<div> <div>
<OpenAPISchemaName <OpenAPISchemaName
@@ -181,7 +189,9 @@ function OpenAPISchemaOAuth2Item(props: {
required={security.required} required={security.required}
/> />
<div className="openapi-securities-oauth-content openapi-markdown"> <div className="openapi-securities-oauth-content openapi-markdown">
{security.description ? <Markdown source={security.description} /> : null} {description ? (
<Markdown source={description} className="openapi-securities-description" />
) : null}
{'authorizationUrl' in flow && flow.authorizationUrl ? ( {'authorizationUrl' in flow && flow.authorizationUrl ? (
<span> <span>
Authorization URL:{' '} Authorization URL:{' '}
@@ -221,6 +231,9 @@ function OpenAPISchemaOAuth2Item(props: {
</OpenAPICopyButton> </OpenAPICopyButton>
</span> </span>
) : null} ) : null}
{scopes.length ? (
<OpenAPISchemaScopes scopes={scopes} context={context} isOAuth2 />
) : null}
</div> </div>
</div> </div>
); );
@@ -38,6 +38,7 @@ export const de = {
available_items: 'Verfügbare Elemente', available_items: 'Verfügbare Elemente',
required_scopes: 'Erforderliche Scopes', required_scopes: 'Erforderliche Scopes',
required_scopes_description: 'Dieser Endpunkt erfordert die folgenden Scopes:', required_scopes_description: 'Dieser Endpunkt erfordert die folgenden Scopes:',
available_scopes: 'Verfügbare Scopes:',
properties: 'Eigenschaften', properties: 'Eigenschaften',
or: 'oder', or: 'oder',
and: 'und', and: 'und',
@@ -38,6 +38,7 @@ export const en = {
available_items: 'Available items', available_items: 'Available items',
required_scopes: 'Required scopes', required_scopes: 'Required scopes',
required_scopes_description: 'This endpoint requires the following scopes:', required_scopes_description: 'This endpoint requires the following scopes:',
available_scopes: 'Available scopes:',
possible_values: 'Possible values', possible_values: 'Possible values',
properties: 'Properties', properties: 'Properties',
or: 'or', or: 'or',
@@ -38,6 +38,7 @@ export const es = {
available_items: 'Elementos disponibles', available_items: 'Elementos disponibles',
required_scopes: 'Scopes requeridos', required_scopes: 'Scopes requeridos',
required_scopes_description: 'Este endpoint requiere los siguientes scopes:', required_scopes_description: 'Este endpoint requiere los siguientes scopes:',
available_scopes: 'Scopes disponibles:',
properties: 'Propiedades', properties: 'Propiedades',
or: 'o', or: 'o',
and: 'y', and: 'y',
@@ -38,6 +38,7 @@ export const fr = {
available_items: 'Éléments disponibles', available_items: 'Éléments disponibles',
required_scopes: 'Scopes requis', required_scopes: 'Scopes requis',
required_scopes_description: 'Cet endpoint nécessite les scopes suivants:', required_scopes_description: 'Cet endpoint nécessite les scopes suivants:',
available_scopes: 'Scopes disponibles:',
properties: 'Propriétés', properties: 'Propriétés',
or: 'ou', or: 'ou',
and: 'et', and: 'et',
@@ -38,6 +38,7 @@ export const ja = {
available_items: '利用可能なアイテム', available_items: '利用可能なアイテム',
required_scopes: '必須スコープ', required_scopes: '必須スコープ',
required_scopes_description: 'このエンドポイントには次のスコープが必要です:', required_scopes_description: 'このエンドポイントには次のスコープが必要です:',
available_scopes: '利用可能なスコープ:',
properties: 'プロパティ', properties: 'プロパティ',
or: 'または', or: 'または',
and: 'かつ', and: 'かつ',
@@ -38,6 +38,7 @@ export const nl = {
available_items: 'Beschikbare items', available_items: 'Beschikbare items',
required_scopes: 'Vereiste scopes', required_scopes: 'Vereiste scopes',
required_scopes_description: 'Dit endpoint vereist de volgende scopes:', required_scopes_description: 'Dit endpoint vereist de volgende scopes:',
available_scopes: 'Beschikbare scopes:',
properties: 'Eigenschappen', properties: 'Eigenschappen',
or: 'of', or: 'of',
and: 'en', and: 'en',
@@ -38,6 +38,7 @@ export const no = {
available_items: 'Tilgjengelige elementer', available_items: 'Tilgjengelige elementer',
required_scopes: 'Påkrevde scopes', required_scopes: 'Påkrevde scopes',
required_scopes_description: 'Dette endepunktet krever følgende scopes:', required_scopes_description: 'Dette endepunktet krever følgende scopes:',
available_scopes: 'Tilgjengelige scopes:',
properties: 'Egenskaper', properties: 'Egenskaper',
or: 'eller', or: 'eller',
and: 'og', and: 'og',
@@ -38,6 +38,7 @@ export const pt_br = {
available_items: 'Itens disponíveis', available_items: 'Itens disponíveis',
required_scopes: 'Scopes obrigatórios', required_scopes: 'Scopes obrigatórios',
required_scopes_description: 'Este endpoint requer os seguintes scopes:', required_scopes_description: 'Este endpoint requer os seguintes scopes:',
available_scopes: 'Scopes disponíveis:',
properties: 'Propriedades', properties: 'Propriedades',
or: 'ou', or: 'ou',
and: 'e', and: 'e',
@@ -38,6 +38,7 @@ export const zh = {
available_items: '可用项', available_items: '可用项',
required_scopes: '必需范围', required_scopes: '必需范围',
required_scopes_description: '此端点需要以下范围:', required_scopes_description: '此端点需要以下范围:',
available_scopes: '可用范围:',
properties: '属性', properties: '属性',
or: '或', or: '或',
and: '和', and: '和',