@@ -33,6 +33,10 @@ export class SchemaModifier {
3333 this . handleOneOfConst ( schema , schemaName )
3434 this . collapseOrMergeOneOfArray ( schema )
3535 this . collapseOneOfObjectPropContainsTitleSchema ( schema )
36+ // Only mark x-oneof-constraint for top-level schemas, not nested in allOf/anyOf/oneOf
37+ if ( schemaName && ! [ 'allOf' , 'anyOf' , 'oneOf' ] . includes ( schemaName ) ) {
38+ this . markTopLevelOneOfConstraint ( schema ) ;
39+ }
3640 } ,
3741 } ) ;
3842 const visit = new Set ( ) ;
@@ -437,4 +441,30 @@ export class SchemaModifier {
437441
438442 this . logger . info ( `Converted additionalProperties to named property '${ propertyName } ' with type: object` ) ;
439443 }
444+
445+ markTopLevelOneOfConstraint ( schema : OpenAPIV3 . SchemaObject ) : void {
446+ if ( schema . minProperties === 1 && schema . maxProperties === 1 ) {
447+ ( schema as any ) [ 'x-oneof-constraint' ] = true ;
448+ this . logger . info ( `Marked schema with x-oneof-constraint` ) ;
449+ return ;
450+ }
451+
452+ const composedKeys = [ 'allOf' , 'anyOf' , 'oneOf' ] as const ;
453+ for ( const key of composedKeys ) {
454+ const items = schema [ key ] ;
455+ if ( Array . isArray ( items ) ) {
456+ for ( const item of items ) {
457+ if ( item && typeof item === 'object' && ! ( '$ref' in item ) ) {
458+ const itemSchema = item as any ;
459+ if ( itemSchema . minProperties === 1 && itemSchema . maxProperties === 1 ) {
460+ ( schema as any ) [ 'x-oneof-constraint' ] = true ;
461+ this . logger . info ( `Marked schema with x-oneof-constraint (found in nested ${ key } )` ) ;
462+ return ;
463+ }
464+ }
465+ }
466+ }
467+ }
468+ }
469+
440470}
0 commit comments