Skip to content

Commit 3190cbc

Browse files
Merge pull request #13 from Darth-Jurassic/master
Angular 6 support
2 parents 130302c + 6351064 commit 3190cbc

11 files changed

Lines changed: 239 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88

99
Generate REST endpoint client from [Swagger](http://swagger.io/) or [WADL](http://www.w3.org/Submission/wadl/) for you project. Useful for typed languages such TypeScript and Dart. Currently support generation for platforms:
10+
- [x] Angular6 TypeScript (via @angular/common/http)
1011
- [x] Angular5 TypeScript (via @angular/common/http)
1112
- [x] Angular2 TypeScript (via @angular/http)
1213
- [ ] Angular2 Dart

bin/rest-client-generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ program
1010
.usage('[options] <wadl>')
1111
.arguments('<wadl>')
1212
.option('--output-file <value>', 'output file', 'services.ts')
13-
.option('--platform <value>', 'platform, yet only: \'angular2-ts\', \'angular5-ts\'', /^(angular2-ts|angular5-ts)$/i, 'angular5-ts')
13+
.option('--platform <value>', 'platform, yet only: \'angular2-ts\', \'angular5-ts\', \'angular6-ts\'', /^(angular2-ts|angular5-ts|angular6-ts)$/i, 'angular6-ts')
1414
.option('--root-url <value>', 'root URL of all REST calls')
1515
.option('--default-service-name <value>', 'if first resource in WADL has method the service name')
1616
.option('--service-suffix <value>', 'service name suffix', 'Service')

lib/rest-client-generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = function (options) {
77
var opts = {
88
input: '',
99
outputFile: 'services.ts',
10-
platform: 'angular5-ts', //[angular5-ts | angular2-ts | angular2-dart | dojo2-ts]
10+
platform: 'angular6-ts', //[angular6-ts | angular5-ts | angular2-ts | angular2-dart | dojo2-ts]
1111
rootUrl: '',
1212
defaultServiceName: '',
1313
capitalize: true,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
var fs = require('fs');
4+
var ejs = require('ejs');
5+
var formatter = require('typescript-formatter/lib/formatter');
6+
7+
var template = ejs.compile(fs.readFileSync(__dirname + '/main.ejs', 'utf8'), {
8+
filename: __dirname + '/main.ejs'
9+
});
10+
11+
module.exports = function (meta, options) {
12+
var src = template({
13+
varPfx: options.internalVariablePrefix,
14+
moduleName: options.moduleName,
15+
types: meta.types,
16+
rootUrl: meta.rootUrl,
17+
services: meta.services
18+
}).replace(/&amp;lt;/g, '<')
19+
.replace(/&amp;gt;/g, '>')
20+
.replace(/^\s*[\r\n]/gm, '');
21+
22+
fs.writeFileSync(options.outputFile, formatter.format('', src), 'utf8');
23+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Generated REST client by rest-client-generator
3+
* <%- new Date() %>
4+
*/
5+
/* tslint:disable */
6+
import {
7+
Injectable,
8+
InjectionToken,
9+
Inject,
10+
NgModule
11+
} from '@angular/core';
12+
import {
13+
HttpClientModule,
14+
HttpClient,
15+
HttpHeaders,
16+
HttpParams,
17+
HttpResponse
18+
} from '@angular/common/http';
19+
20+
import { Observable } from 'rxjs';
21+
22+
/**
23+
* Configuration stuff.
24+
*/
25+
export const SERVICE_ROOT_URL = new InjectionToken<string>('service-root-url');
26+
export const SERVICE_JSON_DATE_PATTERN = new InjectionToken<string>('service-json-date-pattern');
27+
28+
/**
29+
* Some internal stuff.
30+
*/
31+
class <%- varPfx %>BaseService {
32+
private <%- varPfx %>dateRegExp: RegExp;
33+
constructor(jsonDatePattern: string) {
34+
this.<%- varPfx %>dateRegExp = new RegExp(jsonDatePattern);
35+
}
36+
private <%- varPfx %>dateReviver = (key: string, value: any): any => {
37+
if (typeof value === 'string' && this.<%- varPfx %>dateRegExp.test(value)) {
38+
value = new Date(value);
39+
}
40+
return value;
41+
}
42+
protected <%- varPfx %>toObject = (response: HttpResponse<string>): any => {
43+
return response.body ? JSON.parse(response.body, this.<%- varPfx %>dateReviver) : null;
44+
}
45+
protected <%- varPfx %>toFile = (response: HttpResponse<Blob>): File => {
46+
let fileName = 'download.bin';
47+
const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(response.headers.get('content-disposition'));
48+
if (matches != null && matches[1]) {
49+
fileName = matches[1].replace(/['"]/g, '');
50+
}
51+
return new File([response.body], fileName, {
52+
type: response.body.type,
53+
lastModified: new Date(response.headers.get('last-modified')).getTime()
54+
});
55+
}
56+
protected <%- varPfx %>toString(value: any): string {
57+
if (value !== null && value !== undefined && typeof value !== 'string') {
58+
value = value.toString();
59+
}
60+
return value;
61+
}
62+
}
63+
64+
/**
65+
* Request/response types and enumerations.
66+
*/
67+
<% types.forEach(function(type) { %>
68+
<%- include('type-' + type.type, {type: type}) %>
69+
<% }); %>
70+
71+
/**
72+
* Services stuff.
73+
*/
74+
75+
<% services.forEach(function(service) { %>
76+
<%- include('service', {service: service, rootUrl: rootUrl, varPfx: varPfx}) %>
77+
<% }); %>
78+
79+
/**
80+
* The module with all services.
81+
*/
82+
@NgModule({
83+
imports: [
84+
HttpClientModule
85+
],
86+
providers: [
87+
{ provide: SERVICE_ROOT_URL, useValue: '<%- rootUrl %>' },
88+
{ provide: SERVICE_JSON_DATE_PATTERN, useValue: '\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?' },
89+
// accept: YYYY-MM-DDThh:mm:ss, YYYY-MM-DDThh:mm:ssTZD, YYYY-MM-DDThh:mm:ss.sTZD
90+
<%- services.map(function (service) { return service.name; }).join(',\n'); %>
91+
]
92+
})
93+
export class <%- moduleName %> {
94+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<%
2+
function capitalize(string) {
3+
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
4+
}
5+
6+
var responseType = 'void';
7+
if (method.responseMediaType) {
8+
switch (method.responseMediaType) {
9+
case 'text/plain':
10+
responseType = 'string';
11+
break;
12+
case 'application/json':
13+
responseType = method.responseType || 'any';
14+
break;
15+
case 'application/octet-stream':
16+
responseType = 'File';
17+
break;
18+
default:
19+
responseType = 'ArrayBuffer';
20+
}
21+
}
22+
23+
var requestType = null;
24+
if (method.requestMediaType) {
25+
if (method.requestMediaType === 'application/json') {
26+
requestType = method.requestType;
27+
}
28+
}
29+
30+
var params = (method.pathParams || []).concat(method.queryParams || []).concat(method.formParams || []);
31+
32+
var argsVars = params.map(function(pathParam) {
33+
return pathParam.name + ': ' + pathParam.type;
34+
});
35+
36+
if (requestType) {
37+
argsVars.push(varPfx + 'request : ' + requestType);
38+
}
39+
%>
40+
41+
public <%- method.name %>(<%- argsVars.join(', ') %>): Observable<<%- responseType %>>{
42+
const <%- varPfx %>headers = new HttpHeaders({
43+
'Accept': '<%- method.responseMediaType || '*/*' %>'<% if (method.requestMediaType) { %>,
44+
'Content-Type': '<%- method.requestMediaType %>'
45+
<% } %>
46+
});
47+
<% if (method.queryParams) { %>
48+
const <%- varPfx %>params = new HttpParams({
49+
fromObject: {
50+
<% method.queryParams.forEach(function (param, index) { %>
51+
'<%- param.name %>': this.<%- varPfx %>toString(<%- param.name %>)<%- index !== method.queryParams.length - 1 ? ',' : '' %>
52+
<% }); %>
53+
}
54+
});
55+
<% } %>
56+
<% if (method.formParams && method.requestMediaType !== 'multipart/form-data') { %>
57+
const <%- varPfx %>body = new HttpParams({
58+
fromObject: {
59+
<% method.formParams.forEach(function (param, index) { %>
60+
'<%- param.name %>': this.<%- varPfx %>toString(<%- param.name %>)<%- index !== method.formParams.length - 1 ? ',' : '' %>
61+
<% }); %>
62+
}
63+
});
64+
<% } %>
65+
<% if (method.formParams && method.requestMediaType === 'multipart/form-data') { %>
66+
const <%- varPfx %>body = new FormData();
67+
<% method.formParams.forEach(function (param, index) { %>
68+
<% if (param.type === 'string' || param.type === 'Blob') { %>
69+
<%- varPfx %>body.set('<%- param.name %>', <%- param.name %>);
70+
<% } else { %>
71+
<%- varPfx %>body.set('<%- param.name %>', this.<%- varPfx %>toString(<%- param.name %>));
72+
<% } %>
73+
<% }); %>
74+
<% } %>
75+
return this.<%- varPfx %>http.<%- method.method.toLowerCase() %>(`${this.<%- varPfx %>rootUrl}<%- method.path.replace(/{/g,'${') %>`,
76+
<% if (method.method === 'PATCH' || method.method === 'POST' || method.method === 'PUT') { %>
77+
<% if (method.formParams) { %>
78+
<%- varPfx %>body,
79+
<% } else if (requestType) { %>
80+
<%- varPfx %>request,
81+
<% } else { %>
82+
null,
83+
<% } %>
84+
<% } %> {
85+
<% if (responseType === 'ArrayBuffer') { %>
86+
responseType: 'arraybuffer',
87+
<% } else if (responseType === 'File') { %>
88+
responseType: 'blob',
89+
<% } else { %>
90+
responseType: 'json',
91+
<% } %>
92+
<% if (method.queryParams) { %>
93+
params: <%- varPfx %>params,
94+
<% } %>
95+
headers: <%- varPfx %>headers
96+
});
97+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@Injectable()
2+
export class <%- service.name %> extends <%- varPfx %>BaseService {
3+
constructor(private <%- varPfx %>http: HttpClient, @Inject(SERVICE_ROOT_URL) private <%- varPfx %>rootUrl: string, @Inject(SERVICE_JSON_DATE_PATTERN) jsonDatePattern: string) {
4+
super(jsonDatePattern);
5+
}
6+
<% service.methods.forEach(function(method) { %>
7+
<%- include('service-method', {method: method}) %>
8+
<% }); %>
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface <%- type.name %> <% if (type.parent) { %> extends <%- type.parent %> <% } %> {
2+
<% type.fields.forEach(function(field) { %>
3+
<%- field.name %><%- field.optional ? '?' : '' %>: <%- field.type %><%- field.array ? '[]' : '' %>;
4+
<% }); %>
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export enum <%- type.name %> {
2+
<% type.values.forEach(function(value, index) { %>
3+
<%- value %>= <any>'<%- value %>'<%- index !== type.values.length - 1 ? ',' : '' %>
4+
<% }); %>
5+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"typescript",
99
"angular2",
1010
"angular5",
11+
"angular6",
1112
"wadl",
1213
"swagger",
1314
"generator"

0 commit comments

Comments
 (0)