diff --git a/src/openApi/v3/interfaces/JsonCustomVocabulary.d.ts b/src/openApi/v3/interfaces/JsonCustomVocabulary.d.ts new file mode 100644 index 000000000..9ecab4625 --- /dev/null +++ b/src/openApi/v3/interfaces/JsonCustomVocabulary.d.ts @@ -0,0 +1,5 @@ +// https://json-schema.org/draft/2020-12/json-schema-core.html#name-non-json-instances + +export interface JsonCustomVocabulary { + const?: string | number; +} \ No newline at end of file diff --git a/src/openApi/v3/interfaces/OpenApiSchema.d.ts b/src/openApi/v3/interfaces/OpenApiSchema.d.ts index a51456f3b..91f732e05 100644 --- a/src/openApi/v3/interfaces/OpenApiSchema.d.ts +++ b/src/openApi/v3/interfaces/OpenApiSchema.d.ts @@ -1,5 +1,6 @@ import type { Dictionary } from '../../../utils/types'; import type { WithEnumExtension } from './Extensions/WithEnumExtension'; +import type { JsonCustomVocabulary } from './JsonCustomVocabulary'; import type { OpenApiDiscriminator } from './OpenApiDiscriminator'; import type { OpenApiExternalDocs } from './OpenApiExternalDocs'; import type { OpenApiReference } from './OpenApiReference'; @@ -8,7 +9,7 @@ import type { OpenApiXml } from './OpenApiXml'; /** * https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schemaObject */ -export interface OpenApiSchema extends OpenApiReference, WithEnumExtension { +export interface OpenApiSchema extends OpenApiReference, WithEnumExtension, JsonCustomVocabulary { title?: string; multipleOf?: number; maximum?: number; diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index 9e9c60a98..4f7a024ea 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -1,3 +1,4 @@ +import { Enum } from '../../../client/interfaces/Enum'; import type { Model } from '../../../client/interfaces/Model'; import { getPattern } from '../../../utils/getPattern'; import type { OpenApi } from '../interfaces/OpenApi'; @@ -8,6 +9,7 @@ import { getModelComposition } from './getModelComposition'; import { getModelDefault } from './getModelDefault'; import { getModelProperties } from './getModelProperties'; import { getType } from './getType'; +import { getOneOfEnum } from './getOneOfEnum'; export const getModel = ( openApi: OpenApi, @@ -122,7 +124,22 @@ export const getModel = ( } } - if (definition.oneOf?.length) { + if ( + definition.oneOf?.length && + (definition.type === 'integer' || definition.type === 'string') && + (typeof definition.oneOf?.at(0)?.const === 'number' || typeof definition.oneOf?.at(0)?.const === 'string') + ) { + const enumerator: Enum[] = getOneOfEnum(definition.oneOf); + if (enumerator.length) { + model.export = 'enum'; + model.type = 'string'; + model.base = 'string'; + model.enum.push(...enumerator); + model.default = getModelDefault(definition, model); + + return model; + } + } else if (definition.oneOf?.length) { const composition = getModelComposition(openApi, definition, definition.oneOf, 'one-of', getModel); model.export = composition.type; model.imports.push(...composition.imports); diff --git a/src/openApi/v3/parser/getModelComposition.ts b/src/openApi/v3/parser/getModelComposition.ts index 2c27d1815..a6f625a9a 100644 --- a/src/openApi/v3/parser/getModelComposition.ts +++ b/src/openApi/v3/parser/getModelComposition.ts @@ -30,9 +30,10 @@ export const getModelComposition = ( .filter(model => { const hasProperties = model.properties.length; const hasEnums = model.enums.length; + const hasLink = typeof model.link !== 'undefined' && model.link !== null; const isObject = model.type === 'any'; const isDictionary = model.export === 'dictionary'; - const isEmpty = isObject && !hasProperties && !hasEnums; + const isEmpty = isObject && !hasProperties && !hasEnums && !hasLink; return !isEmpty || isDictionary; }) .forEach(model => { diff --git a/src/openApi/v3/parser/getOneOfEnum.ts b/src/openApi/v3/parser/getOneOfEnum.ts new file mode 100644 index 000000000..e3d9c650f --- /dev/null +++ b/src/openApi/v3/parser/getOneOfEnum.ts @@ -0,0 +1,22 @@ +import type { Enum } from '../../../client/interfaces/Enum'; +import { OpenApiSchema } from '../interfaces/OpenApiSchema'; + +export const getOneOfEnum = (oneOf: OpenApiSchema[]): Enum[] => + oneOf.reduce((enums, item) => { + if (typeof item.const === 'number') { + enums.push({ + value: String(item.const), + name: `${item.title}` || `'_${item.const}'`, + type: 'number', + description: item.description || item.title || null, + }); + } else { + enums.push({ + value: `'${item.const}'`, + name: `'${item.title}'` || `'${item.const}'`, + type: 'string', + description: item.description || item.title || null, + }); + } + return enums; + }, [] as Enum[]);