From d5d95e42808b0eb5c992d746cd7df4b85f6e007e Mon Sep 17 00:00:00 2001 From: Lubos Date: Tue, 20 Feb 2024 11:10:30 +0000 Subject: [PATCH] fix(parser): handle composition with any-of and properties --- src/index.ts | 3 +- src/openApi/v3/parser/getModelComposition.ts | 41 +++++++----- test/__snapshots__/index.spec.ts.snap | 70 ++++++++++++++++++++ test/spec/v3.json | 46 +++++++++++++ 4 files changed, 142 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index 31c1bf9c2..fadabba73 100644 --- a/src/index.ts +++ b/src/index.ts @@ -42,11 +42,12 @@ export type Options = { * @param clientName Custom client class name * @param useOptions Use options or arguments functions * @param useUnionTypes Use union types instead of enums + * @param autoformat Process generated files with autoformatter * @param exportCore Generate core client classes * @param exportServices Generate services * @param exportModels Generate models * @param exportSchemas Generate schemas - * @param ignoreOperationId Ignore operationId + * @param useOperationId should the operationId be used when generating operation names * @param indent Indentation options (4, 2 or tab) * @param postfixServices Service name postfix * @param postfixModels Model name postfix diff --git a/src/openApi/v3/parser/getModelComposition.ts b/src/openApi/v3/parser/getModelComposition.ts index c6d4fca72..fcace09c0 100644 --- a/src/openApi/v3/parser/getModelComposition.ts +++ b/src/openApi/v3/parser/getModelComposition.ts @@ -92,23 +92,30 @@ export const getModelComposition = ({ } if (properties.length) { - composition.properties.push({ - name: 'properties', - export: 'interface', - type: 'any', - base: 'any', - template: null, - link: null, - description: '', - isDefinition: false, - isReadOnly: false, - isNullable: false, - isRequired: false, - imports: [], - enum: [], - enums: [], - properties, - }); + const foundComposition = findModelComposition(definition); + if (foundComposition?.type === 'one-of') { + composition.properties.forEach(property => { + property.properties.push(...properties); + }); + } else { + composition.properties.push({ + name: 'properties', + export: 'interface', + type: 'any', + base: 'any', + template: null, + link: null, + description: '', + isDefinition: false, + isReadOnly: false, + isNullable: false, + isRequired: false, + imports: [], + enum: [], + enums: [], + properties, + }); + } } return composition; diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index faff498eb..ef8d9fc54 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -3775,6 +3775,7 @@ export type { CompositionWithNestedAnyOfAndNull } from './models/CompositionWith export type { CompositionWithOneOf } from './models/CompositionWithOneOf'; export type { CompositionWithOneOfAndComplexArrayDictionary } from './models/CompositionWithOneOfAndComplexArrayDictionary'; export type { CompositionWithOneOfAndNullable } from './models/CompositionWithOneOfAndNullable'; +export type { CompositionWithOneOfAndProperties } from './models/CompositionWithOneOfAndProperties'; export type { CompositionWithOneOfAndSimpleArrayDictionary } from './models/CompositionWithOneOfAndSimpleArrayDictionary'; export type { CompositionWithOneOfAndSimpleDictionary } from './models/CompositionWithOneOfAndSimpleDictionary'; export type { CompositionWithOneOfAnonymous } from './models/CompositionWithOneOfAnonymous'; @@ -3856,6 +3857,7 @@ export { $CompositionWithNestedAnyOfAndNull } from './schemas/$CompositionWithNe export { $CompositionWithOneOf } from './schemas/$CompositionWithOneOf'; export { $CompositionWithOneOfAndComplexArrayDictionary } from './schemas/$CompositionWithOneOfAndComplexArrayDictionary'; export { $CompositionWithOneOfAndNullable } from './schemas/$CompositionWithOneOfAndNullable'; +export { $CompositionWithOneOfAndProperties } from './schemas/$CompositionWithOneOfAndProperties'; export { $CompositionWithOneOfAndSimpleArrayDictionary } from './schemas/$CompositionWithOneOfAndSimpleArrayDictionary'; export { $CompositionWithOneOfAndSimpleDictionary } from './schemas/$CompositionWithOneOfAndSimpleDictionary'; export { $CompositionWithOneOfAnonymous } from './schemas/$CompositionWithOneOfAnonymous'; @@ -4344,6 +4346,26 @@ export type CompositionWithOneOfAndNullable = { " `; +exports[`v3 should generate: test/generated/v3/models/CompositionWithOneOfAndProperties.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { NonAsciiStringæøåÆØÅöôêÊ字符串 } from './NonAsciiStringæøåÆØÅöôêÊ字符串'; +import type { SimpleParameter } from './SimpleParameter'; +export type CompositionWithOneOfAndProperties = ({ + foo: SimpleParameter; + baz: number | null; + qux: number; +} | { + bar: NonAsciiStringæøåÆØÅöôêÊ字符串; + baz: number | null; + qux: number; +}); + +" +`; + exports[`v3 should generate: test/generated/v3/models/CompositionWithOneOfAndSimpleArrayDictionary.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ @@ -5802,6 +5824,54 @@ export const $CompositionWithOneOfAndNullable = { " `; +exports[`v3 should generate: test/generated/v3/schemas/$CompositionWithOneOfAndProperties.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $CompositionWithOneOfAndProperties = { + type: 'one-of', + contains: [{ + properties: { + foo: { + type: 'SimpleParameter', + isRequired: true, + }, + baz: { + type: 'number', + isRequired: true, + isNullable: true, + format: 'uint16', + }, + qux: { + type: 'number', + isRequired: true, + format: 'uint8', + }, + }, + }, { + properties: { + bar: { + type: 'NonAsciiStringæøåÆØÅöôêÊ字符串', + isRequired: true, + }, + baz: { + type: 'number', + isRequired: true, + isNullable: true, + format: 'uint16', + }, + qux: { + type: 'number', + isRequired: true, + format: 'uint8', + }, + }, + }], +} as const; +" +`; + exports[`v3 should generate: test/generated/v3/schemas/$CompositionWithOneOfAndSimpleArrayDictionary.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ diff --git a/test/spec/v3.json b/test/spec/v3.json index 5149647c3..bd728203e 100644 --- a/test/spec/v3.json +++ b/test/spec/v3.json @@ -2813,6 +2813,52 @@ } }, "type": "object" + }, + "CompositionWithOneOfAndProperties": { + "type": "object", + "oneOf": [ + { + "type": "object", + "required": [ + "foo" + ], + "properties": { + "foo": { + "$ref": "#/components/parameters/SimpleParameter" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "bar" + ], + "properties": { + "bar": { + "$ref": "#/components/schemas/NonAsciiStringæøåÆØÅöôêÊ字符串" + } + }, + "additionalProperties": false + } + ], + "required": [ + "baz", + "qux" + ], + "properties": { + "baz": { + "type": "integer", + "format": "uint16", + "minimum": 0.0, + "nullable": true + }, + "qux": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } } } }