@@ -33,10 +33,12 @@ import type {
3333 BundleResult ,
3434 Oas3Definition ,
3535 Oas3_1Definition ,
36+ Oas3_2Definition ,
3637 Oas3Parameter ,
3738 Oas3PathItem ,
3839 Oas3Server ,
3940 Oas3Tag ,
41+ Oas3_2Tag ,
4042 SpecVersion ,
4143} from '@redocly/openapi-core' ;
4244import type { CommandArgs } from '../wrapper.js' ;
@@ -46,14 +48,17 @@ const Tags = 'tags';
4648const xTagGroups = 'x-tagGroups' ;
4749let potentialConflictsTotal = 0 ;
4850
51+ type AnyOas3Definition = Oas3Definition | Oas3_1Definition | Oas3_2Definition ;
52+
4953type JoinDocumentContext = {
5054 api : string ;
5155 apiFilename : string ;
5256 apiTitle ?: string ;
53- tags ?: Oas3Tag [ ] ;
57+ tags ?: ( Oas3Tag | Oas3_2Tag ) [ ] ;
5458 potentialConflicts : any ;
5559 tagsPrefix : string ;
5660 componentsPrefix : string | undefined ;
61+ oasVersion : Extract < SpecVersion , 'oas3_0' | 'oas3_1' | 'oas3_2' > | null ;
5762} ;
5863
5964export type JoinArgv = {
@@ -154,9 +159,9 @@ export async function handleJoin({
154159 try {
155160 const version = detectSpec ( document . parsed ) ;
156161 collectSpecData ?.( document . parsed ) ;
157- if ( version !== 'oas3_0' && version !== 'oas3_1' ) {
162+ if ( version !== 'oas3_0' && version !== 'oas3_1' && version !== 'oas3_2' ) {
158163 return exitWithError (
159- `Only OpenAPI 3.0 and OpenAPI 3.1 are supported: ${ blue ( document . source . absoluteRef ) } .`
164+ `Only OpenAPI 3.0, 3.1, and 3.2 are supported: ${ blue ( document . source . absoluteRef ) } .`
160165 ) ;
161166 }
162167
@@ -171,7 +176,7 @@ export async function handleJoin({
171176 }
172177 }
173178
174- const [ first , ...others ] = ( documents ?? [ ] ) as Document < Oas3Definition | Oas3_1Definition > [ ] ;
179+ const [ first , ...others ] = ( documents ?? [ ] ) as Document < AnyOas3Definition > [ ] ;
175180 const serversAreTheSame = others . every ( ( { parsed : { paths, servers } } ) => {
176181 // include only documents with paths
177182 if ( ! paths || isEmptyObject ( paths || { } ) ) {
@@ -197,9 +202,9 @@ export async function handleJoin({
197202 }
198203
199204 for ( const document of documents ) {
200- const openapi = isPlainObject < Oas3Definition | Oas3_1Definition > ( document . parsed )
205+ const openapi = isPlainObject < AnyOas3Definition > ( document . parsed )
201206 ? document . parsed
202- : ( { } as Oas3Definition | Oas3_1Definition ) ;
207+ : ( { } as AnyOas3Definition ) ;
203208 const { tags, info } = openapi ;
204209 const api = path . relative ( process . cwd ( ) , document . source . absoluteRef ) ;
205210 const apiFilename = getApiFilename ( api ) ;
@@ -220,14 +225,15 @@ export async function handleJoin({
220225 potentialConflicts,
221226 tagsPrefix,
222227 componentsPrefix,
228+ oasVersion,
223229 } ;
224230 if ( tags ) {
225231 populateTags ( context ) ;
226232 }
227233 collectExternalDocs ( openapi , context ) ;
228234 collectPaths ( openapi , context , serversAreTheSame ) ;
229235 collectComponents ( openapi , context ) ;
230- collectWebhooks ( oasVersion ! , openapi , context ) ;
236+ collectWebhooks ( openapi , context ) ;
231237 if ( componentsPrefix ) {
232238 replace$Refs ( openapi , componentsPrefix ) ;
233239 }
@@ -252,6 +258,7 @@ export async function handleJoin({
252258 potentialConflicts,
253259 tagsPrefix,
254260 componentsPrefix,
261+ oasVersion,
255262 } : JoinDocumentContext ) {
256263 if ( ! joinedDef . hasOwnProperty ( Tags ) ) {
257264 joinedDef [ Tags ] = [ ] ;
@@ -268,7 +275,9 @@ export async function handleJoin({
268275 tag . description = addComponentsPrefix ( tag . description , componentsPrefix ! ) ;
269276 }
270277
271- const tagDuplicate = joinedDef . tags . find ( ( t : Oas3Tag ) => t . name === entrypointTagName ) ;
278+ const tagDuplicate = joinedDef . tags . find (
279+ ( t : Oas3Tag | Oas3_2Tag ) => t . name === entrypointTagName
280+ ) ;
272281
273282 if ( tagDuplicate && withoutXTagGroups ) {
274283 // If tag already exist and `without-x-tag-groups` option,
@@ -281,7 +290,11 @@ export async function handleJoin({
281290 ) ;
282291 } else if ( ! tagDuplicate ) {
283292 // Instead add tag to joinedDef if there no duplicate;
284- tag [ 'x-displayName' ] = tag [ 'x-displayName' ] || tag . name ;
293+ if ( oasVersion === 'oas3_0' || oasVersion === 'oas3_1' ) {
294+ ( tag as Oas3Tag ) [ 'x-displayName' ] = ( tag as Oas3Tag ) [ 'x-displayName' ] || tag . name ;
295+ } else if ( oasVersion === 'oas3_2' ) {
296+ ( tag as Oas3_2Tag ) . summary = ( tag as Oas3_2Tag ) . summary || tag . name ;
297+ }
285298 tag . name = entrypointTagName ;
286299 joinedDef . tags . push ( tag ) ;
287300
@@ -290,7 +303,7 @@ export async function handleJoin({
290303 }
291304 }
292305
293- if ( ! withoutXTagGroups ) {
306+ if ( ! withoutXTagGroups && oasVersion !== 'oas3_2' ) {
294307 const groupName = apiTitle || apiFilename ;
295308 createXTagGroups ( groupName ) ;
296309 if ( ! tagDuplicate ) {
@@ -337,10 +350,7 @@ export async function handleJoin({
337350 }
338351 }
339352
340- function collectExternalDocs (
341- openapi : Oas3Definition | Oas3_1Definition ,
342- { api } : JoinDocumentContext
343- ) {
353+ function collectExternalDocs ( openapi : AnyOas3Definition , { api } : JoinDocumentContext ) {
344354 const { externalDocs } = openapi ;
345355 if ( externalDocs ) {
346356 if ( joinedDef . hasOwnProperty ( 'externalDocs' ) ) {
@@ -352,14 +362,15 @@ export async function handleJoin({
352362 }
353363
354364 function collectPaths (
355- openapi : Oas3Definition | Oas3_1Definition ,
365+ openapi : AnyOas3Definition ,
356366 {
357367 apiFilename,
358368 apiTitle,
359369 api,
360370 potentialConflicts,
361371 tagsPrefix,
362372 componentsPrefix,
373+ oasVersion,
363374 } : JoinDocumentContext ,
364375 serversAreTheSame : boolean
365376 ) {
@@ -521,6 +532,7 @@ export async function handleJoin({
521532 potentialConflicts,
522533 tagsPrefix,
523534 componentsPrefix,
535+ oasVersion,
524536 } ) ;
525537 } else {
526538 joinedDef . paths [ path ] [ operation ] [ 'tags' ] = [ addPrefix ( 'other' , tagsPrefix || apiFilename ) ] ;
@@ -532,6 +544,7 @@ export async function handleJoin({
532544 potentialConflicts,
533545 tagsPrefix : tagsPrefix || apiFilename ,
534546 componentsPrefix,
547+ oasVersion,
535548 } ) ;
536549 }
537550 if ( ! security && openapi . hasOwnProperty ( 'security' ) ) {
@@ -557,7 +570,7 @@ export async function handleJoin({
557570 }
558571
559572 function collectComponents (
560- openapi : Oas3Definition | Oas3_1Definition ,
573+ openapi : AnyOas3Definition ,
561574 { api, potentialConflicts, componentsPrefix } : JoinDocumentContext
562575 ) {
563576 const { components } = openapi ;
@@ -583,19 +596,19 @@ export async function handleJoin({
583596 }
584597
585598 function collectWebhooks (
586- oasVersion : SpecVersion ,
587- openapi : Oas3Definition | Oas3_1Definition ,
599+ openapi : AnyOas3Definition ,
588600 {
589601 apiFilename,
590602 apiTitle,
591603 api,
592604 potentialConflicts,
593605 tagsPrefix,
594606 componentsPrefix,
607+ oasVersion,
595608 } : JoinDocumentContext
596609 ) {
597610 const webhooks = oasVersion === 'oas3_1' ? 'webhooks' : 'x-webhooks' ;
598- const openapiWebhooks = ( openapi as Exact < Oas3Definition | Oas3_1Definition > ) [ webhooks ] ;
611+ const openapiWebhooks = ( openapi as Exact < AnyOas3Definition > ) [ webhooks ] ;
599612 if ( openapiWebhooks ) {
600613 if ( ! joinedDef . hasOwnProperty ( webhooks ) ) {
601614 joinedDef [ webhooks ] = { } ;
@@ -626,6 +639,7 @@ export async function handleJoin({
626639 potentialConflicts,
627640 tagsPrefix,
628641 componentsPrefix,
642+ oasVersion,
629643 } ) ;
630644 }
631645 }
0 commit comments