Skip to content

Commit 783bd60

Browse files
committed
Normalize mixed oneOf patterns
Signed-off-by: xil <fridalu66@gmail.com>
1 parent 8f45486 commit 783bd60

3 files changed

Lines changed: 334 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
88
### Changed
99
- Fix simplifySingleMapSchema to generate named wrapper schemas. ([#406](https://github.com/opensearch-project/opensearch-protobufs/pull/406))
1010
- Change vendorExtension protobuf type handling to use protobuf type instead of openApi type ([#409](https://github.com/opensearch-project/opensearch-protobufs/pull/409))
11-
11+
- Normalize mixed oneOf patterns ([#411](https://github.com/opensearch-project/opensearch-protobufs/pull/411))
1212
### Removed
1313

1414
### Fixed

tools/proto-convert/src/SchemaModifier.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export class SchemaModifier {
2222
this.convertNullTypeToNullValue(schema)
2323
this.deduplicateOneOfWithArrayType(schema)
2424
this.collapseSingleItemComposite(schema);
25+
this.normalizeMixedOneOf(schema)
2526
},
2627
onSchema: (schema, schemaName) => {
2728
if (!schema || isReferenceObject(schema)) return;
@@ -33,6 +34,7 @@ export class SchemaModifier {
3334
this.deduplicateOneOfWithArrayType(schema)
3435
this.collapseSingleItemComposite(schema);
3536
this.collapseOneOfObjectPropContainsTitleSchema(schema)
37+
this.normalizeMixedOneOf(schema)
3638
this.convertOneOfToMinMaxProperties(schema)
3739
},
3840
});
@@ -515,6 +517,81 @@ export class SchemaModifier {
515517
logger.info(`Converted additionalProperties to named property '${propertyName}' with type: object`);
516518
}
517519

520+
/**
521+
* Normalizes mixed oneOf patterns where some items have properties and others are direct $refs.
522+
* Converts direct $ref items into property-based format to match the inline property items.
523+
*
524+
*
525+
* Example:
526+
* Input:
527+
* {
528+
* type: object,
529+
* oneOf: [
530+
* { properties: { max: { $ref: '#/components/schemas/MaxAggregation' } }, required: ['max'] },
531+
* { $ref: '#/components/schemas/TermsAggregation' }
532+
* ]
533+
* }
534+
*
535+
* Output:
536+
* {
537+
* type: object,
538+
* oneOf: [
539+
* { properties: { max: { $ref: '#/components/schemas/MaxAggregation' } }, required: ['max'] },
540+
* { properties: { terms_aggregation: { $ref: '#/components/schemas/TermsAggregation' } }, required: ['terms_aggregation'] }
541+
* ]
542+
* }
543+
**/
544+
normalizeMixedOneOf(schema: OpenAPIV3.SchemaObject): void {
545+
// Check if this schema has oneOf with mixed types (properties + $ref)
546+
if (!Array.isArray(schema.oneOf) || schema.oneOf.length === 0) {
547+
return;
548+
}
549+
550+
let hasPropertiesType = false;
551+
let hasRefType = false;
552+
553+
for (const item of schema.oneOf) {
554+
if (!item || typeof item !== 'object') continue;
555+
556+
if ('$ref' in item) {
557+
hasRefType = true;
558+
} else if ('properties' in item) {
559+
hasPropertiesType = true;
560+
}
561+
}
562+
563+
// Only process if we have both types
564+
if (!hasPropertiesType || !hasRefType) {
565+
return;
566+
}
567+
568+
// Normalize $ref items to properties format
569+
for (let i = 0; i < schema.oneOf.length; i++) {
570+
const item = schema.oneOf[i];
571+
if (!item || typeof item !== 'object') continue;
572+
573+
if ('$ref' in item) {
574+
const ref = item.$ref;
575+
// Extract schema name from $ref
576+
const schemaName = ref.split('/').pop();
577+
if (!schemaName) continue;
578+
579+
// Convert to snake_case for property name
580+
const propertyName = toSnakeCase(schemaName);
581+
582+
// Replace $ref item with properties format
583+
schema.oneOf[i] = {
584+
properties: {
585+
[propertyName]: { $ref: ref }
586+
},
587+
required: [propertyName]
588+
};
589+
590+
logger.info(`Normalized oneOf $ref to properties: ${ref} -> ${propertyName}`);
591+
}
592+
}
593+
}
594+
518595
/**
519596
* Converts oneOf pattern with single-property objects into minProperties/maxProperties pattern.
520597
* For AggregationContainer

0 commit comments

Comments
 (0)