Skip to content

Commit 74593ee

Browse files
authored
Merge pull request #526 from hypery2k/improved_angular_support
Refactor and consolidate Angular Code Generator
2 parents cdae21b + fbcf394 commit 74593ee

6 files changed

Lines changed: 138 additions & 35 deletions

File tree

src/main/java/io/swagger/codegen/v3/generators/typescript/TypeScriptAngularClientCodegen.java

Lines changed: 118 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
4040
public static final String WITH_INTERFACES = "withInterfaces";
4141
public static final String NG_VERSION = "ngVersion";
4242
public static final String NG_PACKAGR = "useNgPackagr";
43+
public static final String PROVIDED_IN_ROOT ="providedInRoot";
4344

4445
protected String npmName = null;
4546
protected String npmVersion = "1.0.0";
@@ -55,6 +56,7 @@ public TypeScriptAngularClientCodegen() {
5556
this.cliOptions.add(new CliOption(SNAPSHOT, "When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
5657
this.cliOptions.add(new CliOption(WITH_INTERFACES, "Setting this property to true will generate interfaces next to the default class implementations.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
5758
this.cliOptions.add(new CliOption(NG_VERSION, "The version of Angular. Default is '4.3'"));
59+
this.cliOptions.add(new CliOption(PROVIDED_IN_ROOT, "Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
5860
}
5961

6062
@Override
@@ -106,26 +108,116 @@ public void processOpts() {
106108
supportingFiles.add(new SupportingFile("npmignore", "", ".npmignore"));
107109
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
108110

109-
// determine NG version
110-
SemVer ngVersion;
111-
if (additionalProperties.containsKey(NG_VERSION)) {
112-
ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString());
111+
SemVer ngVersion = determineNgVersion();
112+
113+
additionalProperties.put(NG_VERSION, ngVersion);
114+
115+
// for Angular 2 AOT support we will use good-old ngc,
116+
// Angular Package format wasn't invented at this time and building was much more easier
117+
if (!ngVersion.atLeast("4.0.0")) {
118+
LOGGER.warn("Please update your legacy Angular " + ngVersion + " project to benefit from 'Angular Package Format' support.");
119+
additionalProperties.put(NG_PACKAGR, false);
113120
} else {
114-
ngVersion = new SemVer("6.0.0");
115-
LOGGER.info("generating code for Angular {} ...", ngVersion);
116-
LOGGER.info(" (you can select the angular version by setting the additionalProperty ngVersion)");
121+
additionalProperties.put(NG_PACKAGR, true);
122+
}
123+
124+
// Set the typescript version compatible to the Angular version
125+
if (ngVersion.atLeast("8.0.0")) {
126+
additionalProperties.put("tsVersion", ">=3.4.0 <3.6.0");
127+
} else if (ngVersion.atLeast("7.0.0")) {
128+
additionalProperties.put("tsVersion", ">=3.1.1 <3.2.0");
129+
} else if (ngVersion.atLeast("6.0.0")) {
130+
additionalProperties.put("tsVersion", ">=2.7.2 and <2.10.0");
131+
} else if (ngVersion.atLeast("5.0.0")) {
132+
additionalProperties.put("tsVersion", ">=2.1.5 <2.7.0");
133+
} else {
134+
// Angular v2-v4 requires typescript ">=2.1.5 <2.8"
135+
additionalProperties.put("tsVersion", ">=2.1.5 <2.8.0");
136+
}
137+
138+
// Set the rxJS version compatible to the Angular version
139+
if (ngVersion.atLeast("8.0.0")) {
140+
additionalProperties.put("rxjsVersion", "6.5.0");
141+
additionalProperties.put("useRxJS6", true);
142+
} else if (ngVersion.atLeast("7.0.0")) {
143+
additionalProperties.put("rxjsVersion", "6.3.0");
144+
additionalProperties.put("useRxJS6", true);
145+
} else if (ngVersion.atLeast("6.0.0")) {
146+
additionalProperties.put("rxjsVersion", "6.1.0");
147+
additionalProperties.put("useRxJS6", true);
148+
} else {
149+
// Angular prior to v6
150+
additionalProperties.put("rxjsVersion", "5.4.0");
117151
}
118-
additionalProperties.put(NG_VERSION, ngVersion);
119-
additionalProperties.put(NG_PACKAGR, ngVersion.atLeast("4.0.0"));
120-
additionalProperties.put("useRxJS6", ngVersion.atLeast("6.0.0"));
121-
additionalProperties.put("injectionToken", ngVersion.atLeast("4.0.0") ? "InjectionToken" : "OpaqueToken");
122-
additionalProperties.put("injectionTokenTyped", ngVersion.atLeast("4.0.0"));
123-
additionalProperties.put("useHttpClient", ngVersion.atLeast("4.3.0"));
124-
additionalProperties.put("useHttpClientPackage", ngVersion.atLeast("4.3.0") && !ngVersion.atLeast("8.0.0"));
125152
if (!ngVersion.atLeast("4.3.0")) {
126153
supportingFiles.add(new SupportingFile("rxjs-operators.mustache", getIndexDirectory(), "rxjs-operators.ts"));
127154
}
128155

156+
// for Angular 2 AOT support we will use good-old ngc,
157+
// Angular Package format wasn't invented at this time and building was much more easier
158+
if (!ngVersion.atLeast("4.0.0")) {
159+
LOGGER.warn("Please update your legacy Angular " + ngVersion + " project to benefit from 'Angular Package Format' support.");
160+
additionalProperties.put("useNgPackagr", false);
161+
} else {
162+
additionalProperties.put("useNgPackagr", true);
163+
supportingFiles.add(new SupportingFile("ng-package.mustache", getIndexDirectory(), "ng-package.json"));
164+
}
165+
166+
// Libraries generated with v1.x of ng-packagr will ship with AoT metadata in v3, which is intended for Angular v4.
167+
// Libraries generated with v2.x of ng-packagr will ship with AoT metadata in v4, which is intended for Angular v5 (and Angular v6).
168+
additionalProperties.put("useOldNgPackagr", !ngVersion.atLeast("5.0.0"));
169+
170+
// Specific ng-packagr configuration
171+
if (ngVersion.atLeast("8.0.0")) {
172+
additionalProperties.put("ngPackagrVersion", "5.4.0");
173+
additionalProperties.put("tsickleVersion", "0.35.0");
174+
} else if (ngVersion.atLeast("7.0.0")) {
175+
// compatible versions with typescript version
176+
additionalProperties.put("ngPackagrVersion", "5.1.0");
177+
additionalProperties.put("tsickleVersion", "0.34.0");
178+
} else if (ngVersion.atLeast("6.0.0")) {
179+
// compatible versions with typescript version
180+
additionalProperties.put("ngPackagrVersion", "3.0.6");
181+
additionalProperties.put("tsickleVersion", "0.32.1");
182+
} else if (ngVersion.atLeast("5.0.0")) {
183+
// compatible versions with typescript version
184+
additionalProperties.put("ngPackagrVersion", "2.4.5");
185+
additionalProperties.put("tsickleVersion", "0.27.5");
186+
} else {
187+
// Angular versions prior to v5
188+
additionalProperties.put("ngPackagrVersion", "1.6.0");
189+
}
190+
191+
// set zone.js version
192+
if (ngVersion.atLeast("8.0.0")) {
193+
additionalProperties.put("zonejsVersion", "0.9.1");
194+
} else if (ngVersion.atLeast("5.0.0")) {
195+
// compatible versions to Angular 5+
196+
additionalProperties.put("zonejsVersion", "0.8.26");
197+
} else {
198+
// Angular versions prior to v5
199+
additionalProperties.put("zonejsVersion", "0.7.6");
200+
}
201+
202+
// set http client usage
203+
if (ngVersion.atLeast("8.0.0")) {
204+
additionalProperties.put("useHttpClient", true);
205+
additionalProperties.put("useHttpClientPackage", false);
206+
} else if (ngVersion.atLeast("4.3.0")) {
207+
additionalProperties.put("useHttpClient", true);
208+
additionalProperties.put("useHttpClientPackage", true);
209+
} else {
210+
additionalProperties.put("useHttpClient", false);
211+
additionalProperties.put("useHttpClientPackage", false);
212+
}
213+
214+
if (additionalProperties.containsKey(PROVIDED_IN_ROOT) && !ngVersion.atLeast("6.0.0")) {
215+
additionalProperties.put(PROVIDED_IN_ROOT,false);
216+
}
217+
218+
additionalProperties.put("injectionToken", ngVersion.atLeast("4.0.0") ? "InjectionToken" : "OpaqueToken");
219+
additionalProperties.put("injectionTokenTyped", ngVersion.atLeast("4.0.0"));
220+
129221
if (additionalProperties.containsKey(NPM_NAME)) {
130222
addNpmPackageGeneration();
131223
}
@@ -139,6 +231,18 @@ public void processOpts() {
139231

140232
}
141233

234+
private SemVer determineNgVersion() {
235+
SemVer ngVersion;
236+
if (additionalProperties.containsKey(NG_VERSION)) {
237+
ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString());
238+
} else {
239+
ngVersion = new SemVer("8.0.0");
240+
LOGGER.info("generating code for Angular {} ...", ngVersion);
241+
LOGGER.info(" (you can select the angular version by setting the additionalProperty ngVersion)");
242+
}
243+
return ngVersion;
244+
}
245+
142246
private void addNpmPackageGeneration() {
143247
if (additionalProperties.containsKey(NPM_NAME)) {
144248
this.setNpmName(additionalProperties.get(NPM_NAME).toString());

src/main/resources/handlebars/typescript-angular/api.service.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ export class {{classname}} {
305305
{{/isListContainer}}
306306
{{^isListContainer}}
307307
if ({{paramName}} !== undefined) {
308-
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', <any>{{paramName}}){{#useHttpClient}} || formParams{{/useHttpClient}};
308+
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', {{^isModel}}<any>{{paramName}}{{/isModel}}{{#isModel}}useForm ? new Blob([JSON.stringify({{paramName}})], {type: 'application/json'}) : <any>{{paramName}}{{/isModel}}){{#useHttpClient}} as any || formParams{{/useHttpClient}};
309309
}
310310
{{/isListContainer}}
311311
{{/formParams}}

src/main/resources/handlebars/typescript-angular/package.mustache

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
"module": "dist/index.js",
1818
"typings": "dist/index.d.ts",
1919
"scripts": {
20-
"build": "ngc",
21-
"postinstall": "npm run build"
20+
"build": "ngc && npm pack"
2221
},
2322
{{/useNgPackagr}}
2423
"peerDependencies": {
@@ -28,9 +27,7 @@
2827
"@angular/compiler": "^{{ngVersion}}",
2928
"core-js": "^2.4.0",
3029
"reflect-metadata": "^0.1.3",
31-
"rxjs": "{{#useRxJS6}}~6.3.3{{/useRxJS6}}{{^useRxJS6}}^5.4.0{{/useRxJS6}}",
32-
33-
"zone.js": "^0.7.6"
30+
"rxjs": "^{{rxjsVersion}}"
3431
},
3532
"devDependencies": {
3633
"@angular/compiler-cli": "^{{ngVersion}}",
@@ -39,11 +36,12 @@
3936
"@angular/common": "^{{ngVersion}}",
4037
"@angular/compiler": "^{{ngVersion}}",
4138
"@angular/platform-browser": "^{{ngVersion}}",{{#useNgPackagr}}
42-
"ng-packagr": {{#useOldNgPackagr}}"^1.6.0"{{/useOldNgPackagr}}{{^useOldNgPackagr}}{{#useRxJS6}}"5.5.1"{{/useRxJS6}}{{^useRxJS6}}"^2.4.1"{{/useRxJS6}}{{/useOldNgPackagr}},{{/useNgPackagr}}
39+
"ng-packagr": "^{{ngPackagrVersion}}",{{/useNgPackagr}}
4340
"reflect-metadata": "^0.1.3",
44-
"rxjs": "{{#useRxJS6}}~6.3.3{{/useRxJS6}}{{^useRxJS6}}^5.4.0{{/useRxJS6}}",
45-
"zone.js": "^0.7.6",
46-
"typescript": "{{#useNgPackagr}}~3.4.5{{/useNgPackagr}}{{^useNgPackagr}}^2.1.5{{/useNgPackagr}}"
41+
"rxjs": "^{{rxjsVersion}}",{{#useNgPackagr}}{{^useOldNgPackagr}}
42+
"tsickle": "^{{tsickleVersion}}",{{/useOldNgPackagr}}{{/useNgPackagr}}
43+
"typescript": "{{{tsVersion}}}",
44+
"zone.js": "^{{zonejsVersion}}"
4745
}{{#npmRepository}},{{/npmRepository}}
4846
{{#npmRepository}}
4947
"publishConfig": {

src/main/resources/mustache/typescript-angular/api.service.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ export class {{classname}} {
305305
{{/isListContainer}}
306306
{{^isListContainer}}
307307
if ({{paramName}} !== undefined) {
308-
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', <any>{{paramName}}){{#useHttpClient}} || formParams{{/useHttpClient}};
308+
{{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', {{^isModel}}<any>{{paramName}}{{/isModel}}{{#isModel}}useForm ? new Blob([JSON.stringify({{paramName}})], {type: 'application/json'}) : <any>{{paramName}}{{/isModel}}){{#useHttpClient}} as any || formParams{{/useHttpClient}};
309309
}
310310
{{/isListContainer}}
311311
{{/formParams}}

src/main/resources/mustache/typescript-angular/package.mustache

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,31 @@
1717
"module": "dist/index.js",
1818
"typings": "dist/index.d.ts",
1919
"scripts": {
20-
"build": "ngc",
21-
"postinstall": "npm run build"
20+
"build": "ngc && npm pack"
2221
},
2322
{{/useNgPackagr}}
2423
"peerDependencies": {
25-
"@angular/core": "^{{ngVersion}}",{{^useHttpClientPackage}}
24+
"@angular/core": "^{{ngVersion}}",{{#useHttpClientPackage}}
2625
"@angular/http": "^{{ngVersion}}",{{/useHttpClientPackage}}
2726
"@angular/common": "^{{ngVersion}}",
2827
"@angular/compiler": "^{{ngVersion}}",
2928
"core-js": "^2.4.0",
3029
"reflect-metadata": "^0.1.3",
31-
"rxjs": "{{#useRxJS6}}~6.3.3{{/useRxJS6}}{{^useRxJS6}}^5.4.0{{/useRxJS6}}",
32-
"zone.js": "^0.7.6"
30+
"rxjs": "^{{rxjsVersion}}"
3331
},
3432
"devDependencies": {
3533
"@angular/compiler-cli": "^{{ngVersion}}",
36-
"@angular/core": "^{{ngVersion}}",{{^useHttpClientPackage}}
34+
"@angular/core": "^{{ngVersion}}",{{#useHttpClientPackage}}
3735
"@angular/http": "^{{ngVersion}}",{{/useHttpClientPackage}}
3836
"@angular/common": "^{{ngVersion}}",
3937
"@angular/compiler": "^{{ngVersion}}",
4038
"@angular/platform-browser": "^{{ngVersion}}",{{#useNgPackagr}}
41-
"ng-packagr": {{#useOldNgPackagr}}"^1.6.0"{{/useOldNgPackagr}}{{^useOldNgPackagr}}{{#useRxJS6}}"5.3.0"{{/useRxJS6}}{{^useRxJS6}}"^2.4.1"{{/useRxJS6}}{{/useOldNgPackagr}},{{/useNgPackagr}}
39+
"ng-packagr": "^{{ngPackagrVersion}}",{{/useNgPackagr}}
4240
"reflect-metadata": "^0.1.3",
43-
"rxjs": "{{#useRxJS6}}~6.3.3{{/useRxJS6}}{{^useRxJS6}}^5.4.0{{/useRxJS6}}",
44-
"zone.js": "^0.7.6",
45-
"typescript": "{{#useNgPackagr}}~3.4.5{{/useNgPackagr}}{{^useNgPackagr}}^>=2.1.5 <2.8{{/useNgPackagr}}"
41+
"rxjs": "^{{rxjsVersion}}",{{#useNgPackagr}}{{^useOldNgPackagr}}
42+
"tsickle": "^{{tsickleVersion}}",{{/useOldNgPackagr}}{{/useNgPackagr}}
43+
"typescript": "{{{tsVersion}}}",
44+
"zone.js": "^{{zonejsVersion}}"
4645
}{{#npmRepository}},{{/npmRepository}}
4746
{{#npmRepository}}
4847
"publishConfig": {

src/test/java/io/swagger/codegen/v3/generators/options/TypeScriptAngularClientOptionsProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
1515
private static final String NMP_VERSION = "1.1.2";
1616
private static final String NPM_REPOSITORY = "https://registry.npmjs.org";
1717
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
18+
private static final String PROVIDED_IN_ROOT = "true";
1819
public static final String NG_VERSION = "2";
1920

2021

@@ -36,6 +37,7 @@ public Map<String, String> createOptions() {
3637
.put(TypeScriptAngularClientCodegen.WITH_INTERFACES, Boolean.FALSE.toString())
3738
.put(TypeScriptAngularClientCodegen.NPM_REPOSITORY, NPM_REPOSITORY)
3839
.put(TypeScriptAngularClientCodegen.NG_VERSION, NG_VERSION)
40+
.put(TypeScriptAngularClientCodegen.PROVIDED_IN_ROOT, PROVIDED_IN_ROOT)
3941
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
4042
.build();
4143
}

0 commit comments

Comments
 (0)