karso/front/src/common/service/http-wrapper.ts

484 lines
15 KiB
TypeScript

/** @file
* @author Edouard DUPIN
* @copyright 2018, Edouard DUPIN, all right reserved
* @license PROPRIETARY (see license file)
*/
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http';
import { environment } from 'environments/environment';
import { SessionService } from './session';
import { isArrayOfs, isBoolean, isNullOrUndefined, isNumber, isString } from 'common/utils';
export enum HTTPRequestModel {
POST = 'POST',
GET = 'GET',
PUT = 'PUT',
DELETE = 'DELETE',
PATCH = 'PATCH',
}
export enum HTTPMimeType {
ALL = '*/*',
JSON = 'application/json',
OCTET_STREAM = 'application/octet-stream',
IMAGE = 'image/*',
IMAGE_JPEG = 'image/jpeg',
IMAGE_PNG = 'image/png',
}
export type UrlPath = string | boolean | number | (string | boolean | number)[];
export type ProgressCallback = (count: number, total: number) => void;
export interface HTTPRequest {
server?: string;
endPoint: UrlPath;
requestType: HTTPRequestModel;
accept: HTTPMimeType;
contentType: HTTPMimeType;
params?: object;
body?: any;
authorization?: string; // c'est un hook de merde ...
disableTocken?: boolean;
// progress interface to notify progression of the streaming.
progress?: ProgressCallback;
}
export interface ModelResponseHttp {
status: number;
data: any;
}
/**
* This service permit to add some data like tocken and authorisation.. ir automatically get the token if needed and retake it if expired...
*/
@Injectable()
export class HttpWrapperService {
private displayReturn: boolean = false;
constructor(private http: HttpClient, private session: SessionService) { }
addTokenIfNeeded(headerOption: any): any {
const token = this.session.getToken();
if (!isNullOrUndefined(token)) {
if (headerOption.Authorization === undefined) {
headerOption.Authorization = `Yota ${token}`;
}
}
return headerOption;
}
request(properties: HTTPRequest): Promise<Response> {
//uriRest:string, headerOption:any, params:any): Promise<{status:number, data:any}> {
//console.log(`-------------------------------------------------------\nHTTP-wrapper GET '${ properties.endPoint }'\n\t\tparams=${ JSON.stringify(properties, null, 2)}`);
let connectionAddresses = this.createRESTCall2({
server: properties.server,
api: properties.endPoint,
inputOptions: properties.params,
});
let headers: any = {
Accept: properties.accept,
//'Content-Type': properties.contentType,
};
if (properties.authorization !== undefined && properties.authorization !== null) {
headers['Authorization'] = properties.authorization;
}
if (properties.requestType !== HTTPRequestModel.GET) {
headers['Content-Type'] = properties.contentType;
}
//console.log(`disble tocken : ${JSON.stringify(properties)} properties.disableTocken=${properties.disableTocken}`);
if (
properties.disableTocken === undefined ||
properties.disableTocken === null ||
properties.disableTocken === false
) {
headers = this.addTokenIfNeeded(headers);
}
//console.log(`header: ${JSON.stringify(headers)}`);
let body = properties.body;
if (properties.contentType === HTTPMimeType.JSON) {
body = JSON.stringify(properties.body);
}
console.log(`Call ${connectionAddresses}`)
const result = fetch(connectionAddresses, {
method: properties.requestType,
headers,
body,
});
return result;
}
requestJson(properties: HTTPRequest): Promise<ModelResponseHttp> {
return new Promise((resolve, reject) => {
this.request(properties)
.then((response: Response) => {
if (response.status >= 200 && response.status <= 299) {
const contentType = response.headers.get('Content-Type');
if (contentType === HTTPMimeType.JSON) {
response
.json()
.then((value: any) => {
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
resolve({ status: response.status, data: value });
})
.catch((reason: any) => {
reject({ status: 999, data: reason });
});
} else {
console.error(`content Type is not Json: ${contentType}`);
reject({ status: 999, data: `content Type is not Json: ${contentType}` });
}
} else {
console.error(`wring correct status: ${response.status}`);
reject({ status: 900, data: response });
}
})
.catch((error: any) => {
reject({ status: error.status, data: error.error });
});
});
}
requestImage(properties: HTTPRequest): Promise<ModelResponseHttp> {
return new Promise((resolve, reject) => {
this.request(properties)
.then((response: Response) => {
if (response.status >= 200 && response.status <= 299) {
const contentType = response.headers.get('Content-Type');
//console.log(`REICEIVE ==> ${response.status}`);
resolve({ status: 900, data: response });
/*
resolve({ status:response.status, data:value });
}).catch((reason:any)=> {
reject({ status:999, data:reason });
});
} else {
console.error(`content Type is not Json: ${contentType}`)
reject({ status:999, data:`content Type is not Json: ${contentType}` });
}
*/
} else {
console.error(`wring correct status: ${response.status}`);
resolve({ status: 900, data: response });
}
})
.catch((error: any) => {
reject({ status: error.status, data: error.error });
});
});
}
createRESTCall2({
api,
server,
inputOptions,
addURLToken,
}: {
server?: string;
api: UrlPath;
inputOptions?: object;
addURLToken?: boolean;
}) {
if (isNullOrUndefined(server)) {
server = environment.defaultServer;
}
const basePage = environment.server[server];
let addressServerRest = basePage;
if (!basePage.endsWith('/')) {
addressServerRest = `${basePage}/`;
}
let options = inputOptions;
if (isNullOrUndefined(options)) {
options = {};
}
let out = addressServerRest;
if (isArrayOfs(api, isString, isNumber, isBoolean)) {
for (let iii = 0; iii < api.length; iii++) {
let elem = api[iii];
if (out.endsWith('/')) {
out += elem;
} else {
out += `/${elem}`;
}
}
} else {
out += api;
}
let first = true;
let keys = Object.keys(options);
for (let iii = 0; iii < keys.length; iii++) {
if (first === false) {
out = `${out}&`;
} else {
out = `${out}?`;
first = false;
}
out = out + keys[iii];
if (options[keys[iii]] != null) {
out = out + '=' + options[keys[iii]];
}
}
//console.log(`try to get session : ${this.session.getToken()}`);
if (!isNullOrUndefined(this.session.getToken())) {
if (addURLToken !== undefined && addURLToken === true) {
if (first === false) {
out = `${out}&`;
} else {
out = `${out}?`;
}
out = out + `Authorization=Yota ${this.session.getToken()}`;
}
}
return out;
}
// Deprecated ...
createRESTCall(api: string, inputOptions?: any) {
let basePage = environment.server[environment.defaultServer];
let addressServerRest = `${basePage}/`;
let options = inputOptions;
if (options === undefined) {
options = [];
}
let out = addressServerRest + api;
let first = true;
for (let iii = 0; iii < options.length; iii++) {
if (first === false) {
out = `${out}&`;
} else {
out = `${out}?`;
first = false;
}
out = out + options[iii];
}
return out;
}
// Deprecated ... old model stream
post(uriRest: string, headerOption: any, data: any, progress: ProgressCallback = null) {
//console.log(`-------------------------------------------------------\nHTTP-wrapper POST '${ uriRest }'\n\t\theaderOption=${ JSON.stringify(headerOption, null, 2)}\n\t\tdata=${ JSON.stringify(data, null, 2)}`);
this.addTokenIfNeeded(headerOption);
let connectionAdresse = this.createRESTCall(uriRest, {});
return new Promise((resolve, reject) => {
if (this.displayReturn === true) {
console.log(`call POST ${connectionAdresse} data=${JSON.stringify(data, null, 2)}`);
}
let request = this.http.post(connectionAdresse, data, {
headers: new HttpHeaders(headerOption),
reportProgress: true,
observe: 'events',
});
let self = this;
request.subscribe(
(res: any) => {
if (self.displayReturn === true) {
console.log(`!! data ${JSON.stringify(res, null, 2)}`);
}
if (res.type === HttpEventType.Sent) {
/* res.type === 0 */
//console.log('post : Sent');
} else if (res.type === HttpEventType.UploadProgress) {
/* res.type === 1 */
// console.log("post : " + res.loaded + " / " + res.total);
progress(res.loaded, res.total);
} else if (res.type === HttpEventType.ResponseHeader) {
/* res.type === 2 */
//console.log('post : get header');
} else if (res.type === HttpEventType.DownloadProgress) {
/* res.type === 3 */
//console.log(`post : get DownloadProgress ${ res.loaded}`);
} else if (res.type === HttpEventType.Response) {
/* res.type === 4 */
//console.log('post : get response');
if (res.httpCode) {
resolve({ status: res.httpCode, data: res });
} else {
resolve({ status: 200, data: res });
}
} else if (res.type === HttpEventType.User) {
/* res.type === 5 */
//console.log('post : get User');
} else {
console.log(`post : get unknown ... ${res.type}`);
}
},
error => {
if (self.displayReturn === true) {
console.log(`an error occured status: ${error.status}`);
console.log(`answer: ${JSON.stringify(error, null, 2)}`);
}
reject({ status: error.status, data: error.error });
}
);
});
}
// Deprecated ... old model stream
uploadMultipart(base: string, multipart: FormData, progress: ProgressCallback): any {
//console.log(`Upload multipart to ${ base}`);
let url = base;
let self = this;
return new Promise((resolve, reject) => {
let headers = {
// 'Content-Type': 'multipart/form-data',
}; // new Headers();
self.post(url, headers, multipart, progress).then(
(response: any) => {
//console.log(`URL: ${ url }\nRespond(${ response.status }): ${ JSON.stringify(response.data, null, 2)}`);
if (response.status >= 200 && response.status <= 299) {
resolve(response.data.body);
return;
}
reject('An error occured');
},
(response: any) => {
if (typeof response.data === 'undefined') {
reject('return ERROR undefined');
} else {
reject('return ERROR ...'); // + JSON.stringify(response, null, 2));
}
}
);
});
}
// Complex wrapper to simplify interaction:
getSpecific(urlPath: UrlPath): any {
return new Promise((resolve, reject) => {
this.requestJson({
endPoint: urlPath,
requestType: HTTPRequestModel.GET,
accept: HTTPMimeType.JSON,
contentType: HTTPMimeType.JSON,
}).then(
(response: ModelResponseHttp) => {
//console.log("URL: " + url + "\nRespond(" + response.status + "): " + JSON.stringify(response.data, null, 2));
if (response.status === 200) {
resolve(response.data);
return;
}
reject('An error occured');
},
(response: ModelResponseHttp) => {
if (isNullOrUndefined(response.data)) {
reject('return ERROR undefined');
} else {
reject(`return ERROR ${JSON.stringify(response.data, null, 2)}`);
}
}
);
});
}
// Complex wrapper to simplify interaction:s
putSpecific(urlPath: UrlPath, data: object): Promise<ModelResponseHttp> {
return new Promise((resolve, reject) => {
this.request({
endPoint: urlPath,
requestType: HTTPRequestModel.PUT,
accept: HTTPMimeType.JSON,
contentType: HTTPMimeType.JSON,
body: data,
})
.then((response: Response) => {
if (response.status >= 200 && response.status <= 201) {
const contentType = response.headers.get('Content-Type');
if (contentType === HTTPMimeType.JSON) {
response
.json()
.then((value: any) => {
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
resolve({ status: response.status, data: value });
})
.catch((reason: any) => {
reject({ status: 999, data: reason });
});
} else {
console.error(`content Type is not Json: ${contentType}`);
reject({ status: 998, data: `content Type is not Json: ${contentType}` });
}
} else {
console.error(`wrong correct status: ${response.status}`);
reject({ status: 900, data: response });
}
})
.catch((error: any) => {
reject({ status: error.status, data: error.error });
});
});
}
postSpecific(urlPath: UrlPath, data: object): Promise<ModelResponseHttp> {
return new Promise((resolve, reject) => {
this.request({
endPoint: urlPath,
requestType: HTTPRequestModel.POST,
accept: HTTPMimeType.JSON,
contentType: HTTPMimeType.JSON,
body: data,
})
.then((response: Response) => {
if (response.status >= 200 && response.status <= 201) {
const contentType = response.headers.get('Content-Type');
if (contentType === HTTPMimeType.JSON) {
response
.json()
.then((value: any) => {
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
resolve({ status: response.status, data: value });
})
.catch((reason: any) => {
reject({ status: 999, data: reason });
});
} else {
console.error(`content Type is not Json: ${contentType}`);
reject({ status: 998, data: `content Type is not Json: ${contentType}` });
}
} else {
console.error(`wrong correct status: ${response.status}`);
reject({ status: 900, data: response });
}
})
.catch((error: any) => {
reject({ status: error.status, data: error.error });
});
});
}
deleteSpecific(urlPath: UrlPath): Promise<ModelResponseHttp> {
return new Promise((resolve, reject) => {
this.request({
endPoint: urlPath,
requestType: HTTPRequestModel.DELETE,
accept: HTTPMimeType.JSON,
contentType: HTTPMimeType.JSON,
})
.then((response: Response) => {
if (response.status >= 200 && response.status <= 201) {
const contentType = response.headers.get('Content-Type');
if (contentType === HTTPMimeType.JSON) {
response
.json()
.then((value: any) => {
//console.log(`REICEIVE ==> ${response.status}=${ JSON.stringify(value, null, 2)}`);
resolve({ status: response.status, data: value });
})
.catch((reason: any) => {
reject({ status: 999, data: reason });
});
} else {
console.error(`content Type is not Json: ${contentType}`);
reject({ status: 998, data: `content Type is not Json: ${contentType}` });
}
} else {
console.error(`wrong correct status: ${response.status}`);
reject({ status: 900, data: response });
}
})
.catch((error: any) => {
reject({ status: error.status, data: error.error });
});
});
}
}