From bfc784e391d8c88ae92c414a3b2146f725fa9907 Mon Sep 17 00:00:00 2001
From: Kuzma <57258237+ksvirkou-hubspot@users.noreply.github.com>
Date: Tue, 21 May 2024 14:31:05 +0300
Subject: [PATCH] [Typescript] Enum types (#18531)
* Add enum type generator argument
* Generate tests
* fix default sample test
* Fix all typescript tests
* Update docs
* Added description for enum types
* Set enum type as default
* Set addition param for all tests except
---
.../typescript-consolidated-browser.yaml | 1 +
bin/configs/typescript-consolidated-deno.yaml | 1 +
.../typescript-consolidated-jquery.yaml | 1 +
...t-consolidated-node-object-parameters.yaml | 1 +
docs/generators/typescript.md | 1 +
.../languages/TypeScriptClientCodegen.java | 19 +++++++++++++++++++
.../resources/typescript/model/model.mustache | 14 ++++++++++++++
.../typescript/builds/browser/models/Order.ts | 6 +-----
.../typescript/builds/browser/models/Pet.ts | 6 +-----
.../typescript/builds/deno/models/Order.ts | 6 +-----
.../typescript/builds/deno/models/Pet.ts | 6 +-----
.../typescript/builds/jquery/models/Order.ts | 6 +-----
.../typescript/builds/jquery/models/Pet.ts | 6 +-----
.../builds/object_params/models/Order.ts | 6 +-----
.../builds/object_params/models/Pet.ts | 6 +-----
.../tests/browser/test/PetApi.test.ts | 4 ++--
.../test/models/ObjectSerializer.test.ts | 12 ++++++------
.../tests/deno/test/api/PetApi_test.ts | 2 +-
.../tests/jquery/test/api/PetApi.test.ts | 2 +-
.../object_params/test/api/PetApi.test.ts | 2 +-
20 files changed, 57 insertions(+), 51 deletions(-)
diff --git a/bin/configs/typescript-consolidated-browser.yaml b/bin/configs/typescript-consolidated-browser.yaml
index 8ea49d065b2..056c50b36d0 100644
--- a/bin/configs/typescript-consolidated-browser.yaml
+++ b/bin/configs/typescript-consolidated-browser.yaml
@@ -8,3 +8,4 @@ additionalProperties:
projectName: ts-petstore-client
moduleName: petstore
supportsES6: true
+ enumType: stringUnion
diff --git a/bin/configs/typescript-consolidated-deno.yaml b/bin/configs/typescript-consolidated-deno.yaml
index b3317884609..eabb31a4291 100644
--- a/bin/configs/typescript-consolidated-deno.yaml
+++ b/bin/configs/typescript-consolidated-deno.yaml
@@ -7,3 +7,4 @@ additionalProperties:
npmName: ts-petstore-client
projectName: ts-petstore-client
moduleName: petstore
+ enumType: stringUnion
diff --git a/bin/configs/typescript-consolidated-jquery.yaml b/bin/configs/typescript-consolidated-jquery.yaml
index 7e9669984c2..ceac9a204c9 100644
--- a/bin/configs/typescript-consolidated-jquery.yaml
+++ b/bin/configs/typescript-consolidated-jquery.yaml
@@ -7,3 +7,4 @@ additionalProperties:
npmName: ts-petstore-client
projectName: ts-petstore-client
moduleName: petstore
+ enumType: stringUnion
diff --git a/bin/configs/typescript-consolidated-node-object-parameters.yaml b/bin/configs/typescript-consolidated-node-object-parameters.yaml
index 5e4e13a7ec7..d7f391bf5b0 100644
--- a/bin/configs/typescript-consolidated-node-object-parameters.yaml
+++ b/bin/configs/typescript-consolidated-node-object-parameters.yaml
@@ -8,3 +8,4 @@ additionalProperties:
useObjectParameters: true
projectName: ts-petstore-client
moduleName: petstore
+ enumType: stringUnion
diff --git a/docs/generators/typescript.md b/docs/generators/typescript.md
index ed7612a0cea..d2c8464eca9 100644
--- a/docs/generators/typescript.md
+++ b/docs/generators/typescript.md
@@ -24,6 +24,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|enumNameSuffix|Suffix that will be appended to all enum names.| |Enum|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |PascalCase|
|enumPropertyNamingReplaceSpecialChar|Set to true to replace '-' and '+' symbols with 'minus_' and 'plus_' in enum of type string| |false|
+|enumType|Specify the enum type which should be used in the client code.|
- **stringUnion**
- Union of literal string types
- **enum**
- Typescript's [string enums](https://www.typescriptlang.org/docs/handbook/enums.html#string-enums)
|enum|
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|- **false**
- No changes to the enum's are made, this is the default option.
- **true**
- With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.
|false|
|fileContentDataType|Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)| |Buffer|
|framework|Specify the framework which should be used in the client code.|- **fetch-api**
- fetch-api
- **jquery**
- jquery
|fetch-api|
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java
index 4e78a623b0e..e22cb70cdae 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java
@@ -74,6 +74,9 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
private static final String USE_OBJECT_PARAMS_SWITCH = "useObjectParameters";
private static final String USE_OBJECT_PARAMS_DESC = "Use aggregate parameter objects as function arguments for api operations instead of passing each parameter as a separate function argument.";
+ private static final String ENUM_TYPE_SWITCH = "enumType";
+ private static final String ENUM_TYPE_SWITCH_DESC = "Specify the enum type which should be used in the client code.";
+ private static final String[][] ENUM_TYPES = {{"stringUnion", "Union of literal string types"}, {"enum", "Typescript's [string enums](https://www.typescriptlang.org/docs/handbook/enums.html#string-enums)"}};
private final Map frameworkToHttpLibMap;
@@ -135,6 +138,13 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
cliOptions.add(platformOption);
+ CliOption enumTypeOption = new CliOption(TypeScriptClientCodegen.ENUM_TYPE_SWITCH, TypeScriptClientCodegen.ENUM_TYPE_SWITCH_DESC);
+ for (String[] option : TypeScriptClientCodegen.ENUM_TYPES) {
+ enumTypeOption.addEnum(option[0], option[1]);
+ }
+ enumTypeOption.defaultValue(ENUM_TYPES[1][0]);
+ cliOptions.add(enumTypeOption);
+
// Set property naming to camelCase
supportModelPropertyNaming(CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.camelCase);
@@ -426,6 +436,15 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
"http", httpLibName + ".ts"
));
+ additionalProperties.putIfAbsent(ENUM_TYPE_SWITCH, ENUM_TYPES[1][0]);
+ Object propEnumType = additionalProperties.get(ENUM_TYPE_SWITCH);
+
+ Map enumTypes = new HashMap<>();
+ for (String[] option : ENUM_TYPES) {
+ enumTypes.put(option[0], option[0].equals(propEnumType));
+ }
+ additionalProperties.put("enumTypes", enumTypes);
+
Object propPlatform = additionalProperties.get(PLATFORM_SWITCH);
if (propPlatform == null) {
propPlatform = "browser";
diff --git a/modules/openapi-generator/src/main/resources/typescript/model/model.mustache b/modules/openapi-generator/src/main/resources/typescript/model/model.mustache
index 798297cba06..33d22d33993 100644
--- a/modules/openapi-generator/src/main/resources/typescript/model/model.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript/model/model.mustache
@@ -71,6 +71,8 @@ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
{{#vars}}
{{#isEnum}}
+{{#enumTypes}}
+{{#enum}}
export enum {{classname}}{{enumName}} {
{{#allowableValues}}
{{#enumVars}}
@@ -78,12 +80,19 @@ export enum {{classname}}{{enumName}} {
{{/enumVars}}
{{/allowableValues}}
}
+{{/enum}}
+{{#stringUnion}}
+ export type {{classname}}{{enumName}} ={{#allowableValues}}{{#values}} "{{.}}" {{^-last}}|{{/-last}}{{/values}}{{/allowableValues}};
+{{/stringUnion}}
+{{/enumTypes}}
{{/isEnum}}
{{/vars}}
{{/hasEnums}}
{{/isEnum}}
{{#isEnum}}
+{{#enumTypes}}
+{{#enum}}
export enum {{classname}} {
{{#allowableValues}}
{{#enumVars}}
@@ -91,6 +100,11 @@ export enum {{classname}} {
{{/enumVars}}
{{/allowableValues}}
}
+{{/enum}}
+{{#stringUnion}}
+ export type {{classname}} ={{#allowableValues}}{{#values}} "{{.}}" {{^-last}}|{{/-last}}{{/values}}{{/allowableValues}};
+{{/stringUnion}}
+{{/enumTypes}}
{{/isEnum}}
{{/model}}
{{/models}}
\ No newline at end of file
diff --git a/samples/openapi3/client/petstore/typescript/builds/browser/models/Order.ts b/samples/openapi3/client/petstore/typescript/builds/browser/models/Order.ts
index 4d80550bb2a..4e9543bf72f 100644
--- a/samples/openapi3/client/petstore/typescript/builds/browser/models/Order.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/browser/models/Order.ts
@@ -75,9 +75,5 @@ export class Order {
}
-export enum OrderStatusEnum {
- Placed = 'placed',
- Approved = 'approved',
- Delivered = 'delivered'
-}
+ export type OrderStatusEnum = "placed" | "approved" | "delivered" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/browser/models/Pet.ts b/samples/openapi3/client/petstore/typescript/builds/browser/models/Pet.ts
index ecaefffea4f..b52f8f669ef 100644
--- a/samples/openapi3/client/petstore/typescript/builds/browser/models/Pet.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/browser/models/Pet.ts
@@ -77,9 +77,5 @@ export class Pet {
}
-export enum PetStatusEnum {
- Available = 'available',
- Pending = 'pending',
- Sold = 'sold'
-}
+ export type PetStatusEnum = "available" | "pending" | "sold" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/deno/models/Order.ts b/samples/openapi3/client/petstore/typescript/builds/deno/models/Order.ts
index 63e6b8fe3f1..de026e8068a 100644
--- a/samples/openapi3/client/petstore/typescript/builds/deno/models/Order.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/deno/models/Order.ts
@@ -75,9 +75,5 @@ export class Order {
}
-export enum OrderStatusEnum {
- Placed = 'placed',
- Approved = 'approved',
- Delivered = 'delivered'
-}
+ export type OrderStatusEnum = "placed" | "approved" | "delivered" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/deno/models/Pet.ts b/samples/openapi3/client/petstore/typescript/builds/deno/models/Pet.ts
index 1404661b6de..a028c692369 100644
--- a/samples/openapi3/client/petstore/typescript/builds/deno/models/Pet.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/deno/models/Pet.ts
@@ -77,9 +77,5 @@ export class Pet {
}
-export enum PetStatusEnum {
- Available = 'available',
- Pending = 'pending',
- Sold = 'sold'
-}
+ export type PetStatusEnum = "available" | "pending" | "sold" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/jquery/models/Order.ts b/samples/openapi3/client/petstore/typescript/builds/jquery/models/Order.ts
index 4d80550bb2a..4e9543bf72f 100644
--- a/samples/openapi3/client/petstore/typescript/builds/jquery/models/Order.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/jquery/models/Order.ts
@@ -75,9 +75,5 @@ export class Order {
}
-export enum OrderStatusEnum {
- Placed = 'placed',
- Approved = 'approved',
- Delivered = 'delivered'
-}
+ export type OrderStatusEnum = "placed" | "approved" | "delivered" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/jquery/models/Pet.ts b/samples/openapi3/client/petstore/typescript/builds/jquery/models/Pet.ts
index ecaefffea4f..b52f8f669ef 100644
--- a/samples/openapi3/client/petstore/typescript/builds/jquery/models/Pet.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/jquery/models/Pet.ts
@@ -77,9 +77,5 @@ export class Pet {
}
-export enum PetStatusEnum {
- Available = 'available',
- Pending = 'pending',
- Sold = 'sold'
-}
+ export type PetStatusEnum = "available" | "pending" | "sold" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/object_params/models/Order.ts b/samples/openapi3/client/petstore/typescript/builds/object_params/models/Order.ts
index 4d80550bb2a..4e9543bf72f 100644
--- a/samples/openapi3/client/petstore/typescript/builds/object_params/models/Order.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/object_params/models/Order.ts
@@ -75,9 +75,5 @@ export class Order {
}
-export enum OrderStatusEnum {
- Placed = 'placed',
- Approved = 'approved',
- Delivered = 'delivered'
-}
+ export type OrderStatusEnum = "placed" | "approved" | "delivered" ;
diff --git a/samples/openapi3/client/petstore/typescript/builds/object_params/models/Pet.ts b/samples/openapi3/client/petstore/typescript/builds/object_params/models/Pet.ts
index ecaefffea4f..b52f8f669ef 100644
--- a/samples/openapi3/client/petstore/typescript/builds/object_params/models/Pet.ts
+++ b/samples/openapi3/client/petstore/typescript/builds/object_params/models/Pet.ts
@@ -77,9 +77,5 @@ export class Pet {
}
-export enum PetStatusEnum {
- Available = 'available',
- Pending = 'pending',
- Sold = 'sold'
-}
+ export type PetStatusEnum = "available" | "pending" | "sold" ;
diff --git a/samples/openapi3/client/petstore/typescript/tests/browser/test/PetApi.test.ts b/samples/openapi3/client/petstore/typescript/tests/browser/test/PetApi.test.ts
index 88e0a850894..a4334fe7457 100644
--- a/samples/openapi3/client/petstore/typescript/tests/browser/test/PetApi.test.ts
+++ b/samples/openapi3/client/petstore/typescript/tests/browser/test/PetApi.test.ts
@@ -1,5 +1,5 @@
import { expect } from '@esm-bundle/chai';
-import { ServerConfiguration, createConfiguration, PetApi, Tag, Pet, PetStatusEnum, ApiException, RequiredError } from 'ts-petstore-client'
+import { ServerConfiguration, createConfiguration, PetApi, Tag, Pet, ApiException, RequiredError } from 'ts-petstore-client'
import image from "./pet";
const configuration = createConfiguration({
@@ -20,7 +20,7 @@ function createPet() {
pet.id = Math.floor(Math.random() * 100000)
pet.name = "PetName"
pet.photoUrls = []
- pet.status = PetStatusEnum.Available
+ pet.status = 'available'
pet.tags = [ tag ]
return pet as Required;
}
diff --git a/samples/openapi3/client/petstore/typescript/tests/default/test/models/ObjectSerializer.test.ts b/samples/openapi3/client/petstore/typescript/tests/default/test/models/ObjectSerializer.test.ts
index c0a2be85466..c152f5cdc6f 100644
--- a/samples/openapi3/client/petstore/typescript/tests/default/test/models/ObjectSerializer.test.ts
+++ b/samples/openapi3/client/petstore/typescript/tests/default/test/models/ObjectSerializer.test.ts
@@ -66,8 +66,8 @@ describe("ObjectSerializer", () => {
});
it ("Enum", () => {
- const input = "available"
- expect(ObjectSerializer.serialize(input, "Pet.StatusEnum", "")).to.equal("available")
+ const input = petstore.PetStatusEnum.Available
+ expect(ObjectSerializer.serialize(input, "Pet.StatusEnum", "")).to.equal(petstore.PetStatusEnum.Available)
})
it("Complex Class", () => {
@@ -103,7 +103,7 @@ describe("ObjectSerializer", () => {
"name": category.name
},
"photoUrls": [ "url", "other url"],
- "status": "available",
+ "status": petstore.PetStatusEnum.Available,
"tags": tagResult
})
})
@@ -173,8 +173,8 @@ describe("ObjectSerializer", () => {
});
it ("Enum", () => {
- const input = "available"
- expect(ObjectSerializer.deserialize("available", "Pet.StatusEnum", "")).to.equal(input)
+ const input = petstore.PetStatusEnum.Available
+ expect(ObjectSerializer.deserialize(petstore.PetStatusEnum.Available, "Pet.StatusEnum", "")).to.equal(input)
})
it("Complex Class", () => {
@@ -210,7 +210,7 @@ describe("ObjectSerializer", () => {
"name": category.name
},
"photoUrls": [ "url", "other url"],
- "status": "available",
+ "status": petstore.PetStatusEnum.Available,
"tags": tagResult
}, "Pet", "") as petstore.Pet
diff --git a/samples/openapi3/client/petstore/typescript/tests/deno/test/api/PetApi_test.ts b/samples/openapi3/client/petstore/typescript/tests/deno/test/api/PetApi_test.ts
index 9b8e652ce76..4025e670597 100644
--- a/samples/openapi3/client/petstore/typescript/tests/deno/test/api/PetApi_test.ts
+++ b/samples/openapi3/client/petstore/typescript/tests/deno/test/api/PetApi_test.ts
@@ -17,7 +17,7 @@ const petId = Math.floor(Math.random() * 100000);
pet.id = petId;
pet.name = "PetName";
pet.photoUrls = [];
-pet.status = petstore.PetStatusEnum.Available;
+pet.status = 'available';
pet.tags = [tag];
Deno.test({
diff --git a/samples/openapi3/client/petstore/typescript/tests/jquery/test/api/PetApi.test.ts b/samples/openapi3/client/petstore/typescript/tests/jquery/test/api/PetApi.test.ts
index b061610023c..ef3882f9e57 100644
--- a/samples/openapi3/client/petstore/typescript/tests/jquery/test/api/PetApi.test.ts
+++ b/samples/openapi3/client/petstore/typescript/tests/jquery/test/api/PetApi.test.ts
@@ -16,7 +16,7 @@ const pet = new petstore.Pet()
pet.id = Math.floor(Math.random() * 100000)
pet.name = "PetName"
pet.photoUrls = []
-pet.status = petstore.PetStatusEnum.Available
+pet.status = 'available'
pet.tags = [ tag ]
QUnit.module("PetApi")
diff --git a/samples/openapi3/client/petstore/typescript/tests/object_params/test/api/PetApi.test.ts b/samples/openapi3/client/petstore/typescript/tests/object_params/test/api/PetApi.test.ts
index 2e2c311634d..302304492bb 100644
--- a/samples/openapi3/client/petstore/typescript/tests/object_params/test/api/PetApi.test.ts
+++ b/samples/openapi3/client/petstore/typescript/tests/object_params/test/api/PetApi.test.ts
@@ -15,7 +15,7 @@ const pet = new petstore.Pet()
pet.id = Math.floor(Math.random() * 100000)
pet.name = "PetName"
pet.photoUrls = []
-pet.status = petstore.PetStatusEnum.Available
+pet.status = 'available'
pet.tags = [ tag ]
describe("PetApi", () =>{