rxrest
Version:
RxRest a reactive REST utility
384 lines • 12 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const RxRestConfiguration_1 = require("./RxRestConfiguration");
const index_1 = require("./index");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const utils_1 = require("./utils");
// const fromPromise = function(promise: Promise<any>) {
// return Observable.create((observer: Observer<any>) => {
// promise
// .then((v) => {
// observer.next(v)
// observer.complete()
// })
// .catch(observer.error)
// })
// }
class RxRest {
/**
* constructor
*
* @param {String} [route] the resource route
*/
constructor(config = new RxRestConfiguration_1.RxRestConfiguration(), route, metadata) {
this.$fromServer = false;
this.$asIterable = true;
this.$queryParams = new URLSearchParams();
this.$headers = new Headers();
this.$pristine = true;
this.$route = route === undefined ? [] : [...route];
this.config = config;
this.$metadata = metadata;
if (config.uuid) {
this.$uuid = utils_1.uuid();
}
}
addRoute(route) {
this.$route.push.apply(this.$route, route.split('/'));
}
/**
* one
*
* @param {String} route
* @param {any} id
* @returns {RxRestItem}
*/
one(route, id, ...suffix) {
this.addRoute(route);
let o = {};
if (id) {
o[this.config.identifier] = id;
}
return new index_1.RxRestItem(this.$route, o, this.config, null, suffix);
}
/**
* all
*
* @param {String} route
* @param {boolean} [asIterable=true] - forces the next request to return an Observable<Array>
* instead of emitting multiple events
* @returns {RxRestCollection}
*/
all(route, asIterable = true) {
this.addRoute(route);
return new index_1.RxRestCollection(this.$route, undefined, this.config, null, asIterable);
}
/**
* asIterable - sets the flag $asIterable
* instead of emitting multiple events
*
* @returns {self}
*/
asIterable(value = true) {
this.$asIterable = value;
return this;
}
/**
* fromObject
*
* @param {String} route
* @param {Object|Object[]} element
* @returns {RxRestItem|RxRestCollection}
*/
fromObject(route, element, suffix) {
this.addRoute(route);
if (Array.isArray(element)) {
return new index_1.RxRestCollection(this.$route, element, this.config);
}
return new index_1.RxRestItem(this.$route, element, this.config, null, suffix);
}
/**
* @access private
* @param {BodyParam} body
* @return {BodyParam|RxRestItem}
*/
withBody(body) {
return body ? body : this;
}
/**
* post
*
* @param {Body|Blob|FormData|URLSearchParams|Object|RxRestItem} [body]
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
post(body, queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('POST', this.withBody(body));
}
/**
* remove
*
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
remove(queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('DELETE');
}
/**
* get
*
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
get(queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('GET');
}
/**
* put
*
* @param {Body|Blob|FormData|URLSearchParams|Object|RxRestItem} [body]
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
put(body, queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('PUT', this.withBody(body));
}
/**
* patch
*
* @param {Body|Blob|FormData|URLSearchParams|Object|RxRestItem} [body]
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
patch(body, queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('PATCH', this.withBody(body));
}
/**
* head
*
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
head(queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('HEAD');
}
/**
* trace
*
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
trace(queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('TRACE');
}
/**
* options
*
* @param {Object|URLSearchParams} [queryParams]
* @param {Object|Headers} [headers]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
options(queryParams, headers) {
this.queryParams = queryParams;
this.headers = headers;
return this.request('OPTIONS');
}
/**
* URL
*
* @returns {string}
*/
get URL() {
return `${this.config.baseURL}${this.$route.join('/')}`;
}
/**
* set local query params
* @param {Object|URLSearchParams} params
*/
set queryParams(params) {
if (!params) {
return;
}
if (params instanceof URLSearchParams) {
this.$queryParams = params;
return;
}
this.$queryParams = utils_1.objectToMap(new URLSearchParams(), params);
}
/**
* Sets local query params useful to add params to a custom request
* @param {Object|URLSearchParams}
* @return this
*/
setQueryParams(params) {
this.queryParams = params;
return this;
}
/**
* Sets local headers useful to add headers to a custom request
* @param {Object|URLSearchParams}
* @return this
*/
setHeaders(params) {
this.headers = params;
return this;
}
/**
* Get local query params
* @return URLSearchParams
*/
get queryParams() {
return this.$queryParams;
}
/**
* Get request query params
* Combine local and global query params
* Local query params are overriding global params
* @return {String}
*/
get requestQueryParams() {
let params = new URLSearchParams();
for (let param of this.config.queryParams) {
params.append(param[0], param[1]);
}
for (let param of this.queryParams) {
params.append(param[0], param[1]);
}
let str = params.toString();
if (str.length) {
return '?' + str;
}
return '';
}
/**
* Set local headers
* @param {Object|Headers} params
*/
set headers(params) {
if (!params) {
return;
}
if (params instanceof Headers) {
this.$headers = params;
return;
}
this.$headers = utils_1.objectToMap(new Headers(), params);
}
/**
* Get local headers
* @return Headers
*/
get headers() {
return this.$headers;
}
/**
* get request Headers
* Combine local and global headers
* Local headers are overriding global headers
*
* @returns {Headers}
*/
get requestHeaders() {
let headers = new Headers();
for (let header of this.headers) {
headers.append(header[0], header[1]);
}
for (let header of this.config.headers) {
headers.append(header[0], header[1]);
}
return headers;
}
/**
* expandInterceptors
*
* @param {RequestInterceptor[]|ResponseInterceptor[]|ErrorInterceptor[]} interceptors
* @returns {Observable<any>} fn
*/
expandInterceptors(interceptors) {
return function (origin) {
return interceptors.reduce((obs, interceptor) => obs.pipe(operators_1.concatMap(value => {
let result = interceptor(value);
if (result === undefined) {
return rxjs_1.of(value);
}
if (result instanceof Promise) {
return rxjs_1.from(result);
}
if (result instanceof rxjs_1.Observable) {
return result;
}
return rxjs_1.of(result);
})), rxjs_1.of(origin));
};
}
/**
* request
*
* @param {string} method
* @param {RxRestItem|FormData|URLSearchParams|Body|Blob|undefined|Object} [body]
* @returns {Observable<RxRestItem|RxRestCollection>}
*/
request(method, body) {
let requestOptions = {
method: method,
headers: this.requestHeaders,
body: this.config.requestBodyHandler(body)
};
let request = new Request(this.URL + this.requestQueryParams, requestOptions);
let stream = rxjs_1.of(request)
.pipe(operators_1.mergeMap(this.expandInterceptors(this.config.requestInterceptors)), operators_1.mergeMap(request => this.config.fetch(request, null, this.config.abortCallback)), operators_1.mergeMap(this.expandInterceptors(this.config.responseInterceptors)), operators_1.mergeMap(body => rxjs_1.from(this.config.responseBodyHandler(body))), operators_1.mergeMap(({ body, metadata }) => {
if (!Array.isArray(body)) {
let item;
if (this instanceof index_1.RxRestItem) {
item = this;
item.element = body;
item.$metadata = metadata;
}
else {
item = new index_1.RxRestItem(this.$route, body, this.config, metadata);
}
item.$fromServer = true;
item.$pristine = true;
return rxjs_1.Observable.create((observer) => {
observer.next(item);
observer.complete();
});
}
let collection = new index_1.RxRestCollection(this.$route, body.map((e) => {
let item = new index_1.RxRestItem(this.$route, e, this.config, metadata);
item.$fromServer = true;
item.$pristine = true;
return item;
}), this.config, metadata);
collection.$pristine = true;
return rxjs_1.Observable.create((observer) => {
if (this.$asIterable) {
observer.next(collection);
}
else {
for (let item of collection) {
observer.next(item);
}
}
observer.complete();
});
}), operators_1.catchError(body => {
return rxjs_1.of(body).pipe(operators_1.mergeMap(this.expandInterceptors(this.config.errorInterceptors)), operators_1.mergeMap((body) => rxjs_1.throwError(body)));
}));
return stream;
}
}
exports.RxRest = RxRest;
//# sourceMappingURL=RxRest.js.map