@lcgroup.core/api
Version:
Angular HttpClient simplifier
254 lines (246 loc) • 10.8 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Optional, Inject, NgModule } from '@angular/core';
import { map, catchError } from 'rxjs/operators';
import * as i1 from '@angular/common/http';
import { HttpParams, HttpErrorResponse, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { throwError } from 'rxjs';
const API_ENDPOINT = new InjectionToken('API_ENDPOINT');
const API_SERIALIZER = new InjectionToken('API_SERIALIZER');
class ApiQueryStringBuilder {
constructor(encoder) {
this.encoder = encoder;
}
build(key, value) {
return value instanceof Object
? this.buildStringFromObject(key, value)
: this.buildStringFromPrimitive(key, value);
}
buildStringFromObject(key, object) {
const keys = Object.keys(object);
const result = [];
for (const childK in keys) {
if (childK) {
const childKey = keys[childK];
const buildedKey = this.buildKey(object, key, childKey);
const objectChildKey = this.build(buildedKey, object[childKey]);
if (objectChildKey !== '') {
result.push(objectChildKey);
}
}
}
return result.join('&');
}
buildKey(value, key, childKey) {
if ((value instanceof Array && value[childKey] instanceof Object) ||
(value instanceof Array && !(value[childKey] instanceof Object))) {
return key;
}
if (value instanceof Object) {
return `${key}[${this.encoder.encodeKey(childKey)}]`;
}
return childKey;
}
buildStringFromPrimitive(key, value) {
return value === undefined ? key.toString() : `${key}=${this.encoder.encodeValue(value)}`;
}
}
const getWebApiHttpParams = (options) => {
return new Proxy(new HttpParams(options), {
get(target, property) {
const t = target;
if (property === 'toString') {
t.init();
const queryStringBuilder = new ApiQueryStringBuilder(t.encoder);
return () => t
.keys()
.map((key) => {
const eKey = t.encoder.encodeKey(key);
const mapValue = t.map.get(key);
return queryStringBuilder.build(eKey, mapValue);
})
.join('&');
}
return t[property];
},
});
};
var ResponseTypeEnum;
(function (ResponseTypeEnum) {
ResponseTypeEnum["json"] = "json";
ResponseTypeEnum["text"] = "text";
ResponseTypeEnum["arraybuffer"] = "arraybuffer";
ResponseTypeEnum["blob"] = "blob";
})(ResponseTypeEnum || (ResponseTypeEnum = {}));
class Api {
constructor(http, apiEndpoint = null, serializer) {
this.http = http;
this.apiEndpoint = apiEndpoint;
this.serializer = serializer;
}
get(url, options) {
const opts = this.buildOptions(options);
return this.http
.get(this.buildUrl(url), opts)
.pipe(map(result => this.tryDeserialize(result, opts === null || opts === void 0 ? void 0 : opts.deserializeTo)));
}
post(url, body, options) {
const opts = this.buildOptions(options);
return this.http
.post(this.buildUrl(url), this.trySerialize(body), opts)
.pipe(map(result => this.tryDeserialize(result, opts === null || opts === void 0 ? void 0 : opts.deserializeTo)));
}
put(url, body, options) {
const opts = this.buildOptions(options);
return this.http
.put(this.buildUrl(url), this.trySerialize(body), opts)
.pipe(map(result => this.tryDeserialize(result, opts === null || opts === void 0 ? void 0 : opts.deserializeTo)));
}
delete(url, options) {
const opts = this.buildOptions(options);
return this.http
.delete(this.buildUrl(url), opts)
.pipe(map(result => this.tryDeserialize(result, opts === null || opts === void 0 ? void 0 : opts.deserializeTo)));
}
buildUrl(url) {
if ((url && url.startsWith('http')) || !this.apiEndpoint) {
return url;
}
return this.apiEndpoint.concat(url);
}
buildOptions(options) {
const opts = Object.assign({ responseType: ResponseTypeEnum.json }, options);
opts.params = this.getHttpParams(opts === null || opts === void 0 ? void 0 : opts.params);
return opts;
}
getHttpParams(params = null) {
if (params === null || params === undefined) {
return undefined;
}
const serializedParams = this.trySerialize(params);
return getWebApiHttpParams(typeof serializedParams === 'object'
? { fromObject: this.trySerialize(params) }
: { fromString: serializedParams.toString() });
}
trySerialize(data) {
if (this.serializer) {
return this.serializer.serialize(data);
}
return data;
}
tryDeserialize(data, deserializeTo) {
if (!deserializeTo || !this.serializer) {
return data;
}
if (deserializeTo instanceof Array && data instanceof Array) {
const type = deserializeTo.length > 0 ? deserializeTo[0] : undefined;
return data.map(d => this.serializer.deserialize(d, type));
}
if (typeof deserializeTo === 'function') {
return this.serializer.deserialize(data, deserializeTo);
}
return data;
}
}
Api.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: Api, deps: [{ token: i1.HttpClient }, { token: API_ENDPOINT, optional: true }, { token: API_SERIALIZER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
Api.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: Api });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: Api, decorators: [{
type: Injectable
}], ctorParameters: function () {
return [{ type: i1.HttpClient }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [API_ENDPOINT]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [API_SERIALIZER]
}] }];
} });
class BlobErrorHttpInterceptor {
intercept(req, next) {
return next.handle(req).pipe(catchError(err => {
if (err instanceof HttpErrorResponse &&
err.error instanceof Blob &&
err.error.type === 'application/json') {
// https://github.com/angular/angular/issues/19888
// When request of type Blob, the error is also in Blob instead of object of the json data
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
try {
const errmsg = JSON.parse(e.target.result);
reject(new HttpErrorResponse({
error: errmsg,
headers: err.headers,
status: err.status,
statusText: err.statusText,
url: err.url,
}));
}
catch (e) {
console.warn(e);
reject(err);
}
};
reader.onerror = e => {
console.warn(e);
reject(err);
};
reader.readAsText(err.error);
});
}
return throwError(err);
}));
}
}
BlobErrorHttpInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: BlobErrorHttpInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
BlobErrorHttpInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: BlobErrorHttpInterceptor });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: BlobErrorHttpInterceptor, decorators: [{
type: Injectable
}] });
function nullSerializerFactory() {
return {
serialize: data => data,
deserialize: data => data,
};
}
class ApiModule {
static forRoot(options = {}) {
return {
ngModule: ApiModule,
providers: [
Api,
options.endpointProvider || {
provide: API_ENDPOINT,
useValue: options.endpoint || '',
},
options.serializeProvider || {
provide: API_SERIALIZER,
useFactory: nullSerializerFactory,
},
{
provide: HTTP_INTERCEPTORS,
useClass: BlobErrorHttpInterceptor,
multi: true,
},
],
};
}
}
ApiModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: ApiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ApiModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: ApiModule, imports: [HttpClientModule] });
ApiModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: ApiModule, providers: [Api], imports: [[HttpClientModule]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: ApiModule, decorators: [{
type: NgModule,
args: [{
imports: [HttpClientModule],
providers: [Api],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { API_ENDPOINT, API_SERIALIZER, Api, ApiModule, ApiQueryStringBuilder, ResponseTypeEnum, getWebApiHttpParams, nullSerializerFactory };
//# sourceMappingURL=lcgroup.core-api.mjs.map