From dba4883b58d5dd2cbb5485e0e6af4ef6c7b70f01 Mon Sep 17 00:00:00 2001 From: Abby Schweitzer Date: Wed, 6 Dec 2023 16:02:58 -0900 Subject: [PATCH 1/3] Add support for const enums --- .../v3/interfaces/JsonCustomVocabulary.d.ts | 5 +++++ src/openApi/v3/interfaces/OpenApiSchema.d.ts | 3 ++- src/openApi/v3/parser/getModel.ts | 19 +++++++++++++++- src/openApi/v3/parser/getOneOfEnum.ts | 22 +++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/openApi/v3/interfaces/JsonCustomVocabulary.d.ts create mode 100644 src/openApi/v3/parser/getOneOfEnum.ts 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/getOneOfEnum.ts b/src/openApi/v3/parser/getOneOfEnum.ts new file mode 100644 index 000000000..997ff2a87 --- /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[]); \ No newline at end of file From c26164a9a418b65a35adadf902b847a7ffc77cf0 Mon Sep 17 00:00:00 2001 From: Abby Schweitzer Date: Wed, 6 Dec 2023 16:12:13 -0900 Subject: [PATCH 2/3] atempt to fix dashed titles causing ts failures --- src/openApi/v3/parser/getOneOfEnum.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openApi/v3/parser/getOneOfEnum.ts b/src/openApi/v3/parser/getOneOfEnum.ts index 997ff2a87..e3d9c650f 100644 --- a/src/openApi/v3/parser/getOneOfEnum.ts +++ b/src/openApi/v3/parser/getOneOfEnum.ts @@ -13,10 +13,10 @@ export const getOneOfEnum = (oneOf: OpenApiSchema[]): Enum[] => } else { enums.push({ value: `'${item.const}'`, - name: `${item.title}` || `'${item.const}'`, + name: `'${item.title}'` || `'${item.const}'`, type: 'string', description: item.description || item.title || null, }); } return enums; - }, [] as Enum[]); \ No newline at end of file + }, [] as Enum[]); From 0e077bdc7e46229b9d7d896e8d182f45b00ff38e Mon Sep 17 00:00:00 2001 From: Abby Schweitzer Date: Wed, 6 Dec 2023 17:09:35 -0900 Subject: [PATCH 3/3] attempt to fix erroniouns any's --- src/openApi/v3/parser/getModelComposition.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 => {