Skip to content

Commit 5d2cec6

Browse files
customTypeAliases parameter
1 parent 5696f67 commit 5d2cec6

File tree

5 files changed

+88
-0
lines changed

5 files changed

+88
-0
lines changed

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/Settings.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.net.URL;
1616
import java.net.URLClassLoader;
1717
import java.util.ArrayList;
18+
import java.util.Arrays;
1819
import java.util.Collections;
1920
import java.util.LinkedHashMap;
2021
import java.util.LinkedHashSet;
@@ -23,6 +24,7 @@
2324
import java.util.Objects;
2425
import java.util.Set;
2526
import java.util.function.Predicate;
27+
import java.util.regex.Matcher;
2628
import java.util.regex.Pattern;
2729

2830

@@ -60,6 +62,7 @@ public class Settings {
6062
public List<String> referencedFiles = new ArrayList<>();
6163
public List<String> importDeclarations = new ArrayList<>();
6264
public Map<String, String> customTypeMappings = new LinkedHashMap<>();
65+
public Map<String, String> customTypeAliases = new LinkedHashMap<>();
6366
public DateMapping mapDate; // default is DateMapping.asDate
6467
public EnumMapping mapEnum; // default is EnumMapping.asUnion
6568
public boolean nonConstEnums = false;
@@ -205,6 +208,30 @@ public static Map<String, String> convertToMap(List<String> mappings) {
205208
return result;
206209
}
207210

211+
public static Pair<String, List<String>> parseGenericTypeName(String type) {
212+
final Matcher matcher = Pattern.compile("([^<]+)<([^>]+)>").matcher(type);
213+
final String name;
214+
final List<String> typeParameters;
215+
if (matcher.matches()) { // is generic?
216+
name = matcher.group(1);
217+
typeParameters = Arrays.asList(matcher.group(2).split(","));
218+
} else {
219+
name = type;
220+
typeParameters = null;
221+
}
222+
if (!ModelCompiler.isValidIdentifierName(name)) {
223+
throw new RuntimeException(String.format("Invalid identifier: '%s'", name));
224+
}
225+
if (typeParameters != null) {
226+
for (String typeParameter : typeParameters) {
227+
if (!ModelCompiler.isValidIdentifierName(typeParameter)) {
228+
throw new RuntimeException(String.format("Invalid generic type parameter: '%s'", typeParameter));
229+
}
230+
}
231+
}
232+
return Pair.of(name, typeParameters);
233+
}
234+
208235
public void validate() {
209236
if (outputKind == null) {
210237
throw new RuntimeException("Required 'outputKind' parameter is not configured. " + seeLink());
@@ -233,6 +260,9 @@ public void validate() {
233260
if (jackson2Configuration != null && jsonLibrary != JsonLibrary.jackson2) {
234261
throw new RuntimeException("'jackson2Configuration' parameter is only applicable to 'jackson2' library.");
235262
}
263+
for (Map.Entry<String, String> entry : customTypeAliases.entrySet()) {
264+
parseGenericTypeName(entry.getValue());
265+
}
236266
for (EmitterExtension extension : extensions) {
237267
final String extensionName = extension.getClass().getSimpleName();
238268
final DeprecationText deprecation = extension.getClass().getAnnotation(DeprecationText.class);

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/compiler/ModelCompiler.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public TsModel javaToTypeScript(Model model) {
111111
final List<Extension.TransformerDefinition> extensionTransformers = getExtensionTransformers();
112112
model = applyExtensionModelTransformers(symbolTable, model, extensionTransformers);
113113
TsModel tsModel = processModel(symbolTable, model);
114+
tsModel = addCustomTypeAliases(symbolTable, tsModel);
114115
tsModel = removeInheritedProperties(symbolTable, tsModel);
115116
tsModel = addImplementedProperties(symbolTable, tsModel);
116117

@@ -420,6 +421,20 @@ private TsType typeFromJava(SymbolTable symbolTable, Type javaType, Object typeC
420421
}
421422
}
422423

424+
private TsModel addCustomTypeAliases(SymbolTable symbolTable, TsModel tsModel) {
425+
final List<TsAliasModel> aliases = new ArrayList<>(tsModel.getTypeAliases());
426+
for (Map.Entry<String, String> entry : settings.customTypeAliases.entrySet()) {
427+
final Pair<String, List<String>> pair = Settings.parseGenericTypeName(entry.getKey());
428+
final Symbol name = symbolTable.getSyntheticSymbol(pair.getValue1());
429+
final List<TsType.GenericVariableType> typeParameters = pair.getValue2().stream()
430+
.map(TsType.GenericVariableType::new)
431+
.collect(Collectors.toList());
432+
final TsType definition = new TsType.VerbatimType(entry.getValue());
433+
aliases.add(new TsAliasModel(null, name, typeParameters, definition, null));
434+
}
435+
return tsModel.withTypeAliases(aliases);
436+
}
437+
423438
private TsModel removeInheritedProperties(SymbolTable symbolTable, TsModel tsModel) {
424439
final List<TsBeanModel> beans = new ArrayList<>();
425440
for (TsBeanModel bean : tsModel.getBeans()) {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
package cz.habarta.typescript.generator;
3+
4+
import java.util.Collections;
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
8+
9+
public class CustomTypeAliasesTest {
10+
11+
@Test
12+
public void test() {
13+
final Settings settings = TestUtils.settings();
14+
settings.outputKind = TypeScriptOutputKind.module;
15+
settings.customTypeAliases = Collections.singletonMap("Id<T>", "string");
16+
settings.customTypeMappings = Collections.singletonMap(IdRepresentation.class.getName(), "Id");
17+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(MyEntityRepresentation.class));
18+
Assert.assertTrue(output.contains("id: Id<MyEntityRepresentation>"));
19+
Assert.assertTrue(output.contains("export type Id<T> = string"));
20+
}
21+
22+
private static class MyEntityRepresentation {
23+
public IdRepresentation<MyEntityRepresentation> id;
24+
}
25+
26+
private static class IdRepresentation<T> {
27+
public String id;
28+
}
29+
30+
}

typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public class GenerateTask extends DefaultTask {
6868
public List<String> referencedFiles;
6969
public List<String> importDeclarations;
7070
public List<String> customTypeMappings;
71+
public List<String> customTypeAliases;
7172
public DateMapping mapDate;
7273
public EnumMapping mapEnum;
7374
public boolean nonConstEnums;
@@ -165,6 +166,7 @@ public void generate() throws Exception {
165166
settings.referencedFiles = referencedFiles;
166167
settings.importDeclarations = importDeclarations;
167168
settings.customTypeMappings = Settings.convertToMap(customTypeMappings);
169+
settings.customTypeAliases = Settings.convertToMap(customTypeAliases);
168170
settings.mapDate = mapDate;
169171
settings.mapEnum = mapEnum;
170172
settings.nonConstEnums = nonConstEnums;

typescript-generator-maven-plugin/src/main/java/cz/habarta/typescript/generator/maven/GenerateMojo.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,16 @@ public class GenerateMojo extends AbstractMojo {
325325
@Parameter
326326
private List<String> customTypeMappings;
327327

328+
/**
329+
* List of custom type aliases.
330+
* Each item it this list specifies type alias name (possibly with generic parameters) and its definition.
331+
* Item format is: <code>name:definition</code>.
332+
* For example for <code>Unwrap&lt;T>:T</code> following type alias will be generated <code>type Unwrap&lt;T> = T</code>.
333+
* Other examples: <code>SimpleName:VeryLongGeneratedName</code>, <code>StringID&lt;T>:string</code>.
334+
*/
335+
@Parameter
336+
private List<String> customTypeAliases;
337+
328338
/**
329339
* Specifies how {@link java.util.Date} will be mapped.
330340
* Supported values are:
@@ -743,6 +753,7 @@ public void execute() {
743753
settings.referencedFiles = referencedFiles;
744754
settings.importDeclarations = importDeclarations;
745755
settings.customTypeMappings = Settings.convertToMap(customTypeMappings);
756+
settings.customTypeAliases = Settings.convertToMap(customTypeAliases);
746757
settings.mapDate = mapDate;
747758
settings.mapEnum = mapEnum;
748759
settings.nonConstEnums = nonConstEnums;

0 commit comments

Comments
 (0)