diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index ad55d0fc7..b48d70344 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -13,7 +13,8 @@ export const getModel = ( openApi: OpenApi, definition: OpenApiSchema, isDefinition: boolean = false, - name: string = '' + name: string = '', + parentDefinition: OpenApiSchema | null = null ): Model => { const model: Model = { name, @@ -82,7 +83,7 @@ export const getModel = ( model.imports.push(...arrayItems.imports); model.default = getModelDefault(definition, model); return model; - } else if (definition.items.anyOf) { + } else if (definition.items.anyOf && parentDefinition) { return getModel(openApi, definition.items); } else { const arrayItems = getModel(openApi, definition.items); diff --git a/src/openApi/v3/parser/getModelComposition.ts b/src/openApi/v3/parser/getModelComposition.ts index 2c27d1815..41dc4d321 100644 --- a/src/openApi/v3/parser/getModelComposition.ts +++ b/src/openApi/v3/parser/getModelComposition.ts @@ -26,15 +26,7 @@ export const getModelComposition = ( const properties: Model[] = []; definitions - .map(definition => getModel(openApi, definition)) - .filter(model => { - const hasProperties = model.properties.length; - const hasEnums = model.enums.length; - const isObject = model.type === 'any'; - const isDictionary = model.export === 'dictionary'; - const isEmpty = isObject && !hasProperties && !hasEnums; - return !isEmpty || isDictionary; - }) + .map(def => getModel(openApi, def, undefined, undefined, definition)) .forEach(model => { composition.imports.push(...model.imports); composition.enums.push(...model.enums); diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index ec4f8de9e..d86e8a7ac 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -3690,6 +3690,9 @@ export { OpenAPI } from './core/OpenAPI'; export type { OpenAPIConfig } from './core/OpenAPI'; export type { _default } from './models/_default'; +export type { AnyOfAnyAndNull } from './models/AnyOfAnyAndNull'; +export type { AnyOfArrays } from './models/AnyOfArrays'; +export type { ArrayWithAnyOfProperties } from './models/ArrayWithAnyOfProperties'; export type { ArrayWithArray } from './models/ArrayWithArray'; export type { ArrayWithBooleans } from './models/ArrayWithBooleans'; export type { ArrayWithNumbers } from './models/ArrayWithNumbers'; @@ -3708,6 +3711,7 @@ export type { CompositionWithAllOfAndNullable } from './models/CompositionWithAl export type { CompositionWithAnyOf } from './models/CompositionWithAnyOf'; export type { CompositionWithAnyOfAndNullable } from './models/CompositionWithAnyOfAndNullable'; export type { CompositionWithAnyOfAnonymous } from './models/CompositionWithAnyOfAnonymous'; +export type { CompositionWithNestedAnyAndTypeNull } from './models/CompositionWithNestedAnyAndTypeNull'; export type { CompositionWithNestedAnyOfAndNull } from './models/CompositionWithNestedAnyOfAndNull'; export type { CompositionWithOneOf } from './models/CompositionWithOneOf'; export type { CompositionWithOneOfAndComplexArrayDictionary } from './models/CompositionWithOneOfAndComplexArrayDictionary'; @@ -3764,6 +3768,9 @@ export type { SimpleString } from './models/SimpleString'; export type { SimpleStringWithPattern } from './models/SimpleStringWithPattern'; export { $_default } from './schemas/$_default'; +export { $AnyOfAnyAndNull } from './schemas/$AnyOfAnyAndNull'; +export { $AnyOfArrays } from './schemas/$AnyOfArrays'; +export { $ArrayWithAnyOfProperties } from './schemas/$ArrayWithAnyOfProperties'; export { $ArrayWithArray } from './schemas/$ArrayWithArray'; export { $ArrayWithBooleans } from './schemas/$ArrayWithBooleans'; export { $ArrayWithNumbers } from './schemas/$ArrayWithNumbers'; @@ -3782,6 +3789,7 @@ export { $CompositionWithAllOfAndNullable } from './schemas/$CompositionWithAllO export { $CompositionWithAnyOf } from './schemas/$CompositionWithAnyOf'; export { $CompositionWithAnyOfAndNullable } from './schemas/$CompositionWithAnyOfAndNullable'; export { $CompositionWithAnyOfAnonymous } from './schemas/$CompositionWithAnyOfAnonymous'; +export { $CompositionWithNestedAnyAndTypeNull } from './schemas/$CompositionWithNestedAnyAndTypeNull'; export { $CompositionWithNestedAnyOfAndNull } from './schemas/$CompositionWithNestedAnyOfAndNull'; export { $CompositionWithOneOf } from './schemas/$CompositionWithOneOf'; export { $CompositionWithOneOfAndComplexArrayDictionary } from './schemas/$CompositionWithOneOfAndComplexArrayDictionary'; @@ -3873,6 +3881,53 @@ export type _default = { " `; +exports[`v3 should generate: test/generated/v3/models/AnyOfAnyAndNull.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type AnyOfAnyAndNull = { + data?: (any | null); +}; + +" +`; + +exports[`v3 should generate: test/generated/v3/models/AnyOfArrays.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +/** + * This is a simple array with any of properties + */ +export type AnyOfArrays = { + results?: Array<({ + foo?: string; + } | { + bar?: string; + })>; +}; + +" +`; + +exports[`v3 should generate: test/generated/v3/models/ArrayWithAnyOfProperties.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +/** + * This is a simple array with any of properties + */ +export type ArrayWithAnyOfProperties = Array<({ + foo?: string; +} | { + bar?: string; +})>; +" +`; + exports[`v3 should generate: test/generated/v3/models/ArrayWithArray.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ @@ -4135,6 +4190,23 @@ export type CompositionWithAnyOfAnonymous = { " `; +exports[`v3 should generate: test/generated/v3/models/CompositionWithNestedAnyAndTypeNull.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ModelWithArray } from './ModelWithArray'; +import type { ModelWithDictionary } from './ModelWithDictionary'; +/** + * This is a model with nested 'any of' property with a type null + */ +export type CompositionWithNestedAnyAndTypeNull = { + propA?: ((ModelWithDictionary | null) | (ModelWithArray | null)); +}; + +" +`; + exports[`v3 should generate: test/generated/v3/models/CompositionWithNestedAnyOfAndNull.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ @@ -5054,6 +5126,86 @@ export const $_default = { " `; +exports[`v3 should generate: test/generated/v3/schemas/$AnyOfAnyAndNull.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnyOfAnyAndNull = { + properties: { + data: { + type: 'any-of', + contains: [{ + properties: { + }, + }, { + type: 'null', + }], + }, + }, +} as const; +" +`; + +exports[`v3 should generate: test/generated/v3/schemas/$AnyOfArrays.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $AnyOfArrays = { + description: \`This is a simple array with any of properties\`, + properties: { + results: { + type: 'array', + contains: { + type: 'any-of', + contains: [{ + properties: { + foo: { + type: 'string', + }, + }, + }, { + properties: { + bar: { + type: 'string', + }, + }, + }], + }, + }, + }, +} as const; +" +`; + +exports[`v3 should generate: test/generated/v3/schemas/$ArrayWithAnyOfProperties.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $ArrayWithAnyOfProperties = { + type: 'array', + contains: { + type: 'any-of', + contains: [{ + properties: { + foo: { + type: 'string', + }, + }, + }, { + properties: { + bar: { + type: 'string', + }, + }, + }], + }, +} as const; +" +`; + exports[`v3 should generate: test/generated/v3/schemas/$ArrayWithArray.ts 1`] = ` "/* generated using openapi-typescript-codegen -- do no edit */ /* istanbul ignore file */ @@ -5386,6 +5538,37 @@ export const $CompositionWithAnyOfAnonymous = { " `; +exports[`v3 should generate: test/generated/v3/schemas/$CompositionWithNestedAnyAndTypeNull.ts 1`] = ` +"/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export const $CompositionWithNestedAnyAndTypeNull = { + description: \`This is a model with nested 'any of' property with a type null\`, + properties: { + propA: { + type: 'any-of', + contains: [{ + type: 'any-of', + contains: [{ + type: 'ModelWithDictionary', + }, { + type: 'null', + }], + }, { + type: 'any-of', + contains: [{ + type: 'ModelWithArray', + }, { + type: 'null', + }], + }], + }, + }, +} as const; +" +`; + exports[`v3 should generate: test/generated/v3/schemas/$CompositionWithNestedAnyOfAndNull.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 e11af1eb2..c901a6526 100644 --- a/test/spec/v3.json +++ b/test/spec/v3.json @@ -1683,6 +1683,72 @@ } } }, + "ArrayWithAnyOfProperties": { + "description": "This is a simple array with any of properties", + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + } + } + ] + } + }, + "AnyOfAnyAndNull": { + "type": "object", + "properties": { + "data": { + "anyOf": [ + {}, + { + "type": "null" + } + ] + } + } + }, + "AnyOfArrays": { + "description": "This is a simple array with any of properties", + "type": "object", + "properties": { + "results": { + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + }, + { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + } + } + ] + }, + "type": "array" + } + } + }, "DictionaryWithString": { "description": "This is a string dictionary", "type": "object", @@ -2095,7 +2161,44 @@ } } }, - "Enum1":{ + "CompositionWithNestedAnyAndTypeNull": { + "description": "This is a model with nested 'any of' property with a type null", + "type": "object", + "properties": { + "propA": { + "type": "object", + "anyOf": [ + { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelWithDictionary" + }, + { + "type": "null" + } + ] + }, + "type": "array" + }, + { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/ModelWithArray" + }, + { + "type": "null" + } + ] + }, + "type": "array" + } + ] + } + } + }, + "Enum1": { "enum": [ "Bird", "Dog"