From a5235f25b47af797af9f71acf80c03156657d7e7 Mon Sep 17 00:00:00 2001 From: Vincent Devos <46601673+karismann@users.noreply.github.com> Date: Tue, 30 Apr 2019 18:46:05 +0200 Subject: [PATCH] [TypeScript] Generate oneOf schemas as type unions (#2647) * [TypeScript] Generate oneOf schemas as type unions * [TypeScript] Generate oneOf schemas as type unions * [TypeScript] Generate oneOf schemas as type unions update aurelia sample --- .../TypeScriptFetchClientCodegen.java | 4 +- .../typescript-angular/model.mustache | 2 +- .../typescript-angular/modelOneOf.mustache | 14 +++ .../typescript-aurelia/modelOneOf.mustache | 6 ++ .../typescript-aurelia/models.mustache | 3 + .../resources/typescript-axios/api.mustache | 2 +- .../resources/typescript-axios/model.mustache | 2 +- .../typescript-axios/modelOneOf.mustache | 6 ++ .../typescript-inversify/model.mustache | 2 +- .../typescript-inversify/modelOneOf.mustache | 14 +++ .../typescript-jquery/model.mustache | 2 +- .../typescript-jquery/modelOneOf.mustache | 6 ++ .../typescript-rxjs/modelOneOf.mustache | 14 +++ .../resources/typescript-rxjs/models.mustache | 7 +- .../src/test/resources/3_0/oneOf.yaml | 100 +++++++----------- .../typescript-aurelia/default/models.ts | 6 ++ 16 files changed, 113 insertions(+), 77 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/typescript-angular/modelOneOf.mustache create mode 100644 modules/openapi-generator/src/main/resources/typescript-aurelia/modelOneOf.mustache create mode 100644 modules/openapi-generator/src/main/resources/typescript-axios/modelOneOf.mustache create mode 100644 modules/openapi-generator/src/main/resources/typescript-inversify/modelOneOf.mustache create mode 100644 modules/openapi-generator/src/main/resources/typescript-jquery/modelOneOf.mustache create mode 100644 modules/openapi-generator/src/main/resources/typescript-rxjs/modelOneOf.mustache diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java index 45aa36c02d6..5dc9706feea 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java @@ -166,9 +166,9 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege } } } - if (cm.oneOf.size() > 0) { + if (!cm.oneOf.isEmpty()) { // For oneOfs only import $refs within the oneOf - TreeSet oneOfRefs = new TreeSet(); + TreeSet oneOfRefs = new TreeSet<>(); for (String im : cm.imports) { if (cm.oneOf.contains(im)) { oneOfRefs.add(im); diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/model.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/model.mustache index 0b93ad2998f..0afee532731 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/model.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/model.mustache @@ -11,6 +11,6 @@ import { {{classname}} } from './{{filename}}'; * {{{description}}} */ {{/description}} -{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{>modelGeneric}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/modelOneOf.mustache new file mode 100644 index 00000000000..0763eaacf1e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-angular/modelOneOf.mustache @@ -0,0 +1,14 @@ +{{#hasImports}} +import { + {{#imports}} + {{{.}}}, + {{/imports}} +} from './'; + +{{/hasImports}} +/** + * @type {{classname}}{{#description}} + * {{{description}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; diff --git a/modules/openapi-generator/src/main/resources/typescript-aurelia/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-aurelia/modelOneOf.mustache new file mode 100644 index 00000000000..ac93c4ab199 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-aurelia/modelOneOf.mustache @@ -0,0 +1,6 @@ +/** + * @type {{classname}}{{#description}} + * {{{description}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; diff --git a/modules/openapi-generator/src/main/resources/typescript-aurelia/models.mustache b/modules/openapi-generator/src/main/resources/typescript-aurelia/models.mustache index f40db1f3945..75bf9ee4627 100644 --- a/modules/openapi-generator/src/main/resources/typescript-aurelia/models.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-aurelia/models.mustache @@ -1,6 +1,8 @@ {{>licenseInfo}} {{#models}} {{#model}} +{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}} +{{^oneOf}} {{#description}} /** * {{{description}}} @@ -35,5 +37,6 @@ export type {{{enumName}}} = {{#allowableValues}}{{#values}}'{{{.}}}'{{^-last}} {{/isEnum}} {{/vars}} {{/hasEnums}} +{{/oneOf}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/typescript-axios/api.mustache b/modules/openapi-generator/src/main/resources/typescript-axios/api.mustache index 2d6ac670cc0..13b63161d72 100644 --- a/modules/openapi-generator/src/main/resources/typescript-axios/api.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-axios/api.mustache @@ -9,7 +9,7 @@ import globalAxios, { AxiosPromise, AxiosInstance } from 'axios'; import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base'; {{#models}} -{{#model}}{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>modelGeneric}}{{/isEnum}}{{/model}} +{{#model}}{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^isEnum}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/isEnum}}{{/model}} {{/models}} {{#apiInfo}}{{#apis}} {{>apiInner}} diff --git a/modules/openapi-generator/src/main/resources/typescript-axios/model.mustache b/modules/openapi-generator/src/main/resources/typescript-axios/model.mustache index 8806847340b..711a1e0f16b 100644 --- a/modules/openapi-generator/src/main/resources/typescript-axios/model.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-axios/model.mustache @@ -4,6 +4,6 @@ {{#withSeparateModelsAndApi}}{{#imports}} import { {{class}} } from './{{filename}}';{{/imports}}{{/withSeparateModelsAndApi}} {{#models}}{{#model}} -{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>modelGeneric}}{{/isEnum}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^isEnum}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/isEnum}} {{/model}}{{/models}} diff --git a/modules/openapi-generator/src/main/resources/typescript-axios/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-axios/modelOneOf.mustache new file mode 100644 index 00000000000..ac93c4ab199 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-axios/modelOneOf.mustache @@ -0,0 +1,6 @@ +/** + * @type {{classname}}{{#description}} + * {{{description}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; diff --git a/modules/openapi-generator/src/main/resources/typescript-inversify/model.mustache b/modules/openapi-generator/src/main/resources/typescript-inversify/model.mustache index 0b93ad2998f..0afee532731 100644 --- a/modules/openapi-generator/src/main/resources/typescript-inversify/model.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-inversify/model.mustache @@ -11,6 +11,6 @@ import { {{classname}} } from './{{filename}}'; * {{{description}}} */ {{/description}} -{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{>modelGeneric}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/typescript-inversify/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-inversify/modelOneOf.mustache new file mode 100644 index 00000000000..0763eaacf1e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-inversify/modelOneOf.mustache @@ -0,0 +1,14 @@ +{{#hasImports}} +import { + {{#imports}} + {{{.}}}, + {{/imports}} +} from './'; + +{{/hasImports}} +/** + * @type {{classname}}{{#description}} + * {{{description}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; diff --git a/modules/openapi-generator/src/main/resources/typescript-jquery/model.mustache b/modules/openapi-generator/src/main/resources/typescript-jquery/model.mustache index 39fa04722e6..aa7f905acd2 100644 --- a/modules/openapi-generator/src/main/resources/typescript-jquery/model.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-jquery/model.mustache @@ -8,6 +8,6 @@ import * as models from './models'; * {{{description}}} */ {{/description}} -{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>modelGeneric}}{{/isEnum}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^isEnum}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/isEnum}} {{/model}} {{/models}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-jquery/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-jquery/modelOneOf.mustache new file mode 100644 index 00000000000..783cb0f7bd9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-jquery/modelOneOf.mustache @@ -0,0 +1,6 @@ +/** + * @type {{classname}}{{#description}} + * {{{description}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}models.{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-rxjs/modelOneOf.mustache b/modules/openapi-generator/src/main/resources/typescript-rxjs/modelOneOf.mustache new file mode 100644 index 00000000000..11e4f25fba4 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-rxjs/modelOneOf.mustache @@ -0,0 +1,14 @@ +{{#hasImports}} +import { + {{#imports}} + {{{.}}}, + {{/imports}} +} from './'; + +{{/hasImports}} +/** + * @type {{classname}}{{#description}} + * {{{description}}}{{/description}} + * @export + */ +export type {{classname}} = {{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}; \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/typescript-rxjs/models.mustache b/modules/openapi-generator/src/main/resources/typescript-rxjs/models.mustache index ff9993dc14c..ae5738af984 100644 --- a/modules/openapi-generator/src/main/resources/typescript-rxjs/models.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-rxjs/models.mustache @@ -2,11 +2,6 @@ {{>licenseInfo}} {{#models}} {{#model}} -{{#isEnum}} -{{>modelEnum}} -{{/isEnum}} -{{^isEnum}} -{{>modelGeneric}} -{{/isEnum}} +{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{#oneOf}}{{#-first}}{{>modelOneOf}}{{/-first}}{{/oneOf}}{{^isEnum}}{{^oneOf}}{{>modelGeneric}}{{/oneOf}}{{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf.yaml index 4da439e5f3b..d98fcf6667a 100644 --- a/modules/openapi-generator/src/test/resources/3_0/oneOf.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf.yaml @@ -1,64 +1,36 @@ -{ - "openapi":"3.0.1", - "info":{ - "title":"fruity", - "version":"0.0.1" - }, - "paths":{ - "/":{ - "get":{ - "responses":{ - "200":{ - "description":"desc", - "content":{ - "application/json":{ - "schema":{ - "$ref":"#/components/schemas/fruit" - } - } - } - } - } - } - } - }, - "components":{ - "schemas":{ - "fruit":{ - "title":"fruit", - "type":"object", - "properties":{ - "color":{ - "type":"string" - } - }, - "oneOf":[ - { - "$ref":"#/components/schemas/apple" - }, - { - "$ref":"#/components/schemas/banana" - } - ] - }, - "apple":{ - "title":"apple", - "type":"object", - "properties":{ - "kind":{ - "type":"string" - } - } - }, - "banana":{ - "title":"banana", - "type":"object", - "properties":{ - "count":{ - "type":"number" - } - } - } - } - } -} +openapi: 3.0.1 +info: + title: fruity + version: 0.0.1 +paths: + /: + get: + responses: + '200': + description: desc + content: + application/json: + schema: + $ref: '#/components/schemas/fruit' +components: + schemas: + fruit: + title: fruit + properties: + color: + type: string + oneOf: + - $ref: '#/components/schemas/apple' + - $ref: '#/components/schemas/banana' + apple: + title: apple + type: object + properties: + kind: + type: string + banana: + title: banana + type: object + properties: + count: + type: number diff --git a/samples/client/petstore/typescript-aurelia/default/models.ts b/samples/client/petstore/typescript-aurelia/default/models.ts index acc07bf2739..ce9de9e13de 100644 --- a/samples/client/petstore/typescript-aurelia/default/models.ts +++ b/samples/client/petstore/typescript-aurelia/default/models.ts @@ -10,6 +10,7 @@ * Do not edit the class manually. */ + /** * Describes the result of uploading an image resource */ @@ -19,6 +20,7 @@ export interface ApiResponse { message?: string; } + /** * A category for a pet */ @@ -27,6 +29,7 @@ export interface Category { name?: string; } + /** * An order for a pets from the pet store */ @@ -47,6 +50,7 @@ export interface Order { */ export type OrderStatusEnum = 'placed' | 'approved' | 'delivered'; + /** * A pet for sale in the pet store */ @@ -67,6 +71,7 @@ export interface Pet { */ export type PetStatusEnum = 'available' | 'pending' | 'sold'; + /** * A tag for a pet */ @@ -75,6 +80,7 @@ export interface Tag { name?: string; } + /** * A User who is purchasing from the pet store */