diff --git a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap index f43b92da..5cbc5e04 100644 --- a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap @@ -300,7 +300,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "pattern": undefined, "pointer": "#/components/schemas/Dog/properties/packSize", "rawSchema": { - "default": undefined, "type": "number", }, "readOnly": false, @@ -309,7 +308,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "#/components/schemas/Dog/properties/packSize", ], "schema": { - "default": undefined, "type": "number", }, "title": "", @@ -576,7 +574,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "pattern": undefined, "pointer": "#/components/schemas/Dog/properties/type", "rawSchema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Dog", @@ -593,7 +590,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "#/components/schemas/Dog/properties/type", ], "schema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Dog", @@ -1164,7 +1160,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "pattern": undefined, "pointer": "#/components/schemas/Cat/properties/type", "rawSchema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Cat", @@ -1181,7 +1176,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "#/components/schemas/Cat/properties/type", ], "schema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Cat", @@ -1452,7 +1446,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "pattern": undefined, "pointer": "#/components/schemas/Cat/properties/packSize", "rawSchema": { - "default": undefined, "type": "number", "x-refsStack": [ "#/components/schemas/Cat", @@ -1466,7 +1459,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "#/components/schemas/Cat/properties/packSize", ], "schema": { - "default": undefined, "type": "number", "x-refsStack": [ "#/components/schemas/Cat", @@ -2309,7 +2301,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "pattern": undefined, "pointer": "#/components/schemas/Dog/properties/packSize", "rawSchema": { - "default": undefined, "type": "number", }, "readOnly": false, @@ -2318,7 +2309,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "#/components/schemas/Dog/properties/packSize", ], "schema": { - "default": undefined, "type": "number", }, "title": "", @@ -2585,7 +2575,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "pattern": undefined, "pointer": "#/components/schemas/Dog/properties/type", "rawSchema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Dog", @@ -2602,7 +2591,6 @@ exports[`Components SchemaView discriminator should correctly render SchemaView "#/components/schemas/Dog/properties/type", ], "schema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Dog", @@ -2945,7 +2933,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat "pattern": undefined, "pointer": "#/components/schemas/Dog/properties/packSize", "rawSchema": { - "default": undefined, "type": "number", }, "readOnly": false, @@ -2954,7 +2941,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat "#/components/schemas/Dog/properties/packSize", ], "schema": { - "default": undefined, "type": "number", }, "title": "", @@ -3008,7 +2994,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat "pattern": undefined, "pointer": "#/components/schemas/Dog/properties/type", "rawSchema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Dog", @@ -3025,7 +3010,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat "#/components/schemas/Dog/properties/type", ], "schema": { - "default": undefined, "type": "string", "x-refsStack": [ "#/components/schemas/Dog", diff --git a/src/services/__tests__/fixtures/oneOf.json b/src/services/__tests__/fixtures/oneOf.json new file mode 100644 index 00000000..f02d9b3d --- /dev/null +++ b/src/services/__tests__/fixtures/oneOf.json @@ -0,0 +1,40 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Test", + "version": "1.0.0" + }, + "components": { + "schemas": { + "Response": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/Data" + } + } + }, + "Data": { + "type": "object", + "oneOf": [ + { "$ref": "#/components/schemas/WithTitle" }, + { "$ref": "#/components/schemas/NoTitle" }, + { + "title": "InlineWithTitle", + "type": "object", + "properties": { + "inline": { "type": "string" } + } + } + ] + }, + "WithTitle": { + "title": "ExplicitTitle", + "type": "object" + }, + "NoTitle": { + "type": "object" + } + } + } +} diff --git a/src/services/__tests__/models/Schema.test.ts b/src/services/__tests__/models/Schema.test.ts index 514599d9..13dc672a 100644 --- a/src/services/__tests__/models/Schema.test.ts +++ b/src/services/__tests__/models/Schema.test.ts @@ -56,6 +56,20 @@ describe('Models', () => { expect(schema.displayType).toBe('(Array of strings or numbers) or string'); }); + test('oneOf titles: explicit, inferred from $ref, and inline with title', () => { + const spec = require('../fixtures/oneOf.json'); + parser = new OpenAPIParser(spec, undefined, opts); + const schema = new SchemaModel(parser, spec.components.schemas.Response, '', opts); + + const dataField = schema.fields?.find(f => f.name === 'data'); + expect(dataField).toBeDefined(); + expect(dataField!.schema.oneOf).toHaveLength(3); + + expect(dataField!.schema.oneOf![0].title).toBe('ExplicitTitle'); + expect(dataField!.schema.oneOf![1].title).toBe('NoTitle'); + expect(dataField!.schema.oneOf![2].title).toBe('InlineWithTitle'); + }); + test('schemaDefinition should resolve double ref', () => { const spec = require('../fixtures/3.1/schemaDefinition.json'); parser = new OpenAPIParser(spec, undefined, opts); diff --git a/src/services/__tests__/models/__snapshots__/Schema.test.ts.snap b/src/services/__tests__/models/__snapshots__/Schema.test.ts.snap index 4996ba0e..defc840c 100644 --- a/src/services/__tests__/models/__snapshots__/Schema.test.ts.snap +++ b/src/services/__tests__/models/__snapshots__/Schema.test.ts.snap @@ -3,7 +3,6 @@ exports[`Models Schema schemaDefinition should resolve field with conditional operators 1`] = ` { "allOf": undefined, - "default": undefined, "description": undefined, "items": { "allOf": undefined, @@ -31,7 +30,6 @@ exports[`Models Schema schemaDefinition should resolve field with conditional op exports[`Models Schema schemaDefinition should resolve field with conditional operators 2`] = ` { "allOf": undefined, - "default": undefined, "description": undefined, "items": { "allOf": undefined, diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts index a07e0719..19638a56 100644 --- a/src/services/models/Schema.ts +++ b/src/services/models/Schema.ts @@ -447,6 +447,8 @@ function buildFields( const required = schema.required === undefined ? false : schema.required.indexOf(fieldName) > -1; + const defaultValue = field.default === undefined && defaults ? defaults[fieldName] : field.default; + return new FieldModel( parser, { @@ -454,7 +456,9 @@ function buildFields( required, schema: { ...field, - default: field.default === undefined && defaults ? defaults[fieldName] : field.default, + // Only include default if it has an actual value; adding `default: undefined` + // triggers allOf wrapping in OpenAPI 3.1's mergeRefs, breaking oneOf handling + ...(defaultValue !== undefined ? { default: defaultValue } : {}), }, }, $ref + '/properties/' + fieldName,