@@ -24,11 +24,19 @@ export function OpenAPIRequiredScopes(props: {
2424 return null ;
2525 }
2626
27- const scopes = selectedSecurity . schemes . flatMap ( ( scheme ) => {
28- return scheme . scopes ?? [ ] ;
29- } ) ;
27+ const scopeAlternatives =
28+ selectedSecurity . scopeAlternatives . length > 0
29+ ? selectedSecurity . scopeAlternatives
30+ : [
31+ selectedSecurity . schemes . flatMap ( ( scheme ) => {
32+ return scheme . scopes ?? [ ] ;
33+ } ) ,
34+ ] ;
35+ const resolvedAlternatives = scopeAlternatives
36+ . map ( ( scopes ) => dedupeScopes ( scopes ) )
37+ . filter ( ( scopes ) => scopes . length > 0 ) ;
3038
31- if ( ! scopes . length ) {
39+ if ( ! resolvedAlternatives . length ) {
3240 return null ;
3341 }
3442
@@ -51,7 +59,12 @@ export function OpenAPIRequiredScopes(props: {
5159 {
5260 key : 'scopes' ,
5361 label : '' ,
54- body : < OpenAPISchemaScopes scopes = { scopes } context = { context } /> ,
62+ body : (
63+ < OpenAPIScopeAlternatives
64+ alternatives = { resolvedAlternatives }
65+ context = { context }
66+ />
67+ ) ,
5568 } ,
5669 ] ,
5770 } ,
@@ -60,19 +73,54 @@ export function OpenAPIRequiredScopes(props: {
6073 ) ;
6174}
6275
63- export function OpenAPISchemaScopes ( props : {
64- scopes : OpenAPISecurityScope [ ] ;
76+ function OpenAPIScopeAlternatives ( props : {
77+ alternatives : OpenAPISecurityScope [ ] [ ] ;
6578 context : OpenAPIClientContext ;
6679} ) {
67- const { scopes, context } = props ;
80+ const { alternatives, context } = props ;
81+
82+ if ( alternatives . length === 1 ) {
83+ return < OpenAPISchemaScopes scopes = { alternatives [ 0 ] } context = { context } /> ;
84+ }
6885
6986 return (
70- < div className = "openapi-securities- scopes openapi-markdown " >
87+ < div className = "openapi-scopes-alternatives " >
7188 < div className = "openapi-required-scopes-description" >
7289 { t ( context . translation , 'required_scopes_description' ) }
7390 </ div >
91+ < div className = "openapi-schema-alternatives" >
92+ { alternatives . map ( ( scopes , index ) => (
93+ < div key = { index } className = "openapi-schema-alternative" >
94+ < OpenAPISchemaScopes scopes = { scopes } context = { context } hideDescription />
95+ { index < alternatives . length - 1 ? (
96+ < span className = "openapi-schema-alternative-separator" >
97+ { t ( context . translation , 'or' ) }
98+ </ span >
99+ ) : null }
100+ </ div >
101+ ) ) }
102+ </ div >
103+ </ div >
104+ ) ;
105+ }
106+
107+ export function OpenAPISchemaScopes ( props : {
108+ scopes : OpenAPISecurityScope [ ] | undefined ;
109+ context : OpenAPIClientContext ;
110+ isOAuth2 ?: boolean ;
111+ hideDescription ?: boolean ;
112+ } ) {
113+ const { scopes, context, hideDescription } = props ;
114+
115+ return (
116+ < div className = "openapi-securities-scopes openapi-markdown" >
117+ { ! hideDescription ? (
118+ < div className = "openapi-required-scopes-description" >
119+ { t ( context . translation , 'required_scopes_description' ) }
120+ </ div >
121+ ) : null }
74122 < ul >
75- { scopes . map ( ( scope ) => (
123+ { scopes ? .map ( ( scope ) => (
76124 < OpenAPIScopeItem key = { scope [ 0 ] } scope = { scope } context = { context } />
77125 ) ) }
78126 </ ul >
@@ -112,3 +160,18 @@ function OpenAPIScopeItemKey(props: {
112160 </ OpenAPICopyButton >
113161 ) ;
114162}
163+
164+ function dedupeScopes ( scopes : OpenAPISecurityScope [ ] ) {
165+ const seen = new Set < string > ( ) ;
166+ const deduped : OpenAPISecurityScope [ ] = [ ] ;
167+
168+ for ( const scope of scopes ) {
169+ if ( seen . has ( scope [ 0 ] ) ) {
170+ continue ;
171+ }
172+ seen . add ( scope [ 0 ] ) ;
173+ deduped . push ( scope ) ;
174+ }
175+
176+ return deduped ;
177+ }
0 commit comments