forked from loafle/openapi-generator-original
[typescript] Prevent generating invalid enum code due to empty variable names (#20699)
* [typescript] Prevent generating invalid enum code due to empty variable names After sanitizing all characters (e.g. multibyte characters), the enum variable name may become an empty string. Since an empty string would cause a syntax error, this patch pads the pseudo variable name (`STRING`) to avoid that issue. For example, given the following OpenAPI definition: ```yaml openapi: "3.0.0" info: title: Sample project version: '1.0' description: 'Sample API Check "API Key" ' license: name: Apache 2.0 url: 'https://www.apache.org/licenses/LICENSE-2.0' paths: {} components: schemas: Greeting: type: string enum: - 'こんにちは' - '你好' - '안녕하세요' ``` The current logic generates the following code for Greeting: ```typescript export enum Greeting { = 'こんにちは', 2 = '你好', 3 = '안녕하세요' } ``` This code is invalid. With this patch, the generated code becomes: ```typescript export enum Greeting { STRING = 'こんにちは', STRING2 = '你好', STRING3 = '안녕하세요' } ``` Signed-off-by: moznion <moznion@mail.moznion.net> * Remove unnecessary imports Signed-off-by: moznion <moznion@mail.moznion.net> * Use new sanitizer for TypeScript symbol which takes wider variety characters for enum var name Signed-off-by: moznion <moznion@mail.moznion.net> --------- Signed-off-by: moznion <moznion@mail.moznion.net>
This commit is contained in:
parent
a06a2b4c7b
commit
9537a7fb46
@ -311,9 +311,25 @@ public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen imp
|
||||
|
||||
if (enumName.matches("\\d.*")) { // starts with number
|
||||
return "_" + enumName;
|
||||
} else {
|
||||
return enumName;
|
||||
}
|
||||
|
||||
if (enumName.isEmpty()) {
|
||||
// After sanitizing *all* characters (e.g. multibyte characters), the var name becomes an empty string.
|
||||
// An empty string would cause a syntax error, so this code attempts to re-sanitize the name using another sanitizer that allows a wider variety of characters.
|
||||
// For backward compatibility, this additional sanitization is only applied if the original sanitized name is empty.
|
||||
final String sanitized = sanitizeNameForTypeScriptSymbol(name);
|
||||
if (sanitized.isEmpty()) {
|
||||
// After re-sanitizing, this pads a pseudo var name ("STRING") if still the name is empty.
|
||||
return "STRING";
|
||||
}
|
||||
return "_" + sanitized;
|
||||
}
|
||||
|
||||
return enumName;
|
||||
}
|
||||
|
||||
private String sanitizeNameForTypeScriptSymbol(String name) {
|
||||
return sanitizeName(name, "[^\\p{L}\\p{Nd}\\$_]");
|
||||
}
|
||||
|
||||
private String getNameWithEnumPropertyNaming(String name) {
|
||||
|
@ -5,6 +5,7 @@ import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.PathItem;
|
||||
import io.swagger.v3.oas.models.media.*;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.config.CodegenConfigurator;
|
||||
import org.openapitools.codegen.languages.TypeScriptClientCodegen;
|
||||
import org.openapitools.codegen.model.ModelMap;
|
||||
import org.openapitools.codegen.model.ModelsMap;
|
||||
@ -12,6 +13,9 @@ import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -179,4 +183,31 @@ public class TypeScriptClientCodegenTest {
|
||||
|
||||
Assert.assertEquals(codegen.getLicenseName(), licenseName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForAllSanitizedEnum() throws Exception {
|
||||
final File output = Files.createTempDirectory("typescriptnodeclient_").toFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
final CodegenConfigurator configurator = new CodegenConfigurator()
|
||||
.setGeneratorName("typescript")
|
||||
.setInputSpec("src/test/resources/bugs/typescript_enum_var_name_all_sanitized.yaml")
|
||||
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
|
||||
|
||||
final ClientOptInput clientOptInput = configurator.toClientOptInput();
|
||||
final DefaultGenerator generator = new DefaultGenerator();
|
||||
final List<File> files = generator.opts(clientOptInput).generate();
|
||||
files.forEach(File::deleteOnExit);
|
||||
|
||||
TestUtils.assertFileContains(
|
||||
Paths.get(output + "/models/Greeting.ts"),
|
||||
"export enum Greeting {\n" +
|
||||
" _こんにちは = 'こんにちは',\n" +
|
||||
" _你好 = '你好',\n" +
|
||||
" _안녕하세요 = '안녕하세요',\n" +
|
||||
" STRING = '!@#%',\n" +
|
||||
" STRING2 = '^&*\uD83C\uDF63'",
|
||||
"}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
title: Sample project
|
||||
version: '1.0'
|
||||
description: 'Sample API Check "API Key" '
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'https://www.apache.org/licenses/LICENSE-2.0'
|
||||
paths: {}
|
||||
components:
|
||||
schemas:
|
||||
Greeting:
|
||||
type: string
|
||||
enum:
|
||||
- 'こんにちは'
|
||||
- '你好'
|
||||
- '안녕하세요'
|
||||
- '!@#%'
|
||||
- '^&*🍣'
|
Loading…
x
Reference in New Issue
Block a user