@akanass/rx-http-request
Version:
The world-famous HTTP client Request now RxJS compliant, wrote in Typescript | ES6 for client and server side.
235 lines • 7.63 kB
JavaScript
// import libraries
import * as request from 'request';
import { Buffer } from 'buffer';
import { merge, Observable, of, throwError } from 'rxjs';
import { filter, flatMap, map, tap } from 'rxjs/operators';
import { RxCookieJar } from './rx-cookie-jar';
/**
* Class definition
*/
export class RxHttpRequest {
/**
* Returns singleton instance
*
* @return {RxHttpRequest}
*/
static instance() {
if (!(RxHttpRequest._instance instanceof RxHttpRequest)) {
RxHttpRequest._instance = new RxHttpRequest(request);
}
return RxHttpRequest._instance;
}
/**
* Class constructor
*/
constructor(req) {
// check request parameter
this._checkRequestParam(req);
// set request object
this._request = req;
}
/**
* Returns private attribute _request
*
* @return {RequestAPI<Request, CoreOptions, RequiredUriUrl>}
*/
get request() {
return this._request;
}
/**
* This method returns a wrapper around the normal rx-http-request API that defaults to whatever options
* you pass to it.
* It does not modify the global rx-http-request API; instead, it returns a wrapper that has your default settings
* applied to it.
* You can _call .defaults() on the wrapper that is returned from rx-http-request.defaults to add/override defaults
* that were previously defaulted.
*
* @param options
*
* @return {RxHttpRequest}
*/
defaults(options) {
return new RxHttpRequest(this._request.defaults(options));
}
/**
* Function to do a GET HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
get(uri, options) {
return this._call('get', uri, Object.assign({}, options || {}));
}
/**
* Function to do a GET HTTP request and to return a buffer
*
* @param uri
* @param options
*
* @return {Observable<RxHttpRequestResponse<Buffer>>}
*/
getBuffer(uri, options) {
return new Observable((observer) => {
try {
this._request.get(uri, Object.assign({}, options || {}))
.on('response', (response) => {
let res;
response.on('data', (data) => res = res ? Buffer.concat([].concat(res, data)) : data);
response.on('end', () => {
observer.next(Object.assign({}, {
response: response,
body: res
}));
observer.complete();
});
})
.on('error', /* istanbul ignore next */ /* istanbul ignore next */ error => observer.error(error));
}
catch (error) {
observer.error(error);
}
});
}
/**
* Function to do a POST HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
post(uri, options) {
return this._call('post', uri, Object.assign({}, options || {}));
}
/**
* Function to do a PUT HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
put(uri, options) {
return this._call('put', uri, Object.assign({}, options || {}));
}
/**
* Function to do a PATCH HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
patch(uri, options) {
return this._call('patch', uri, Object.assign({}, options || {}));
}
/**
* Function to do a DELETE HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
delete(uri, options) {
return this._call('del', uri, Object.assign({}, options || {}));
}
/**
* Function to do a HEAD HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
head(uri, options) {
return this._call('head', uri, Object.assign({}, options || {}));
}
/**
* Function to do a OPTIONS HTTP request
*
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*/
options(uri, options) {
return this._call('options', uri, Object.assign({}, options || {}));
}
/**
* Function that creates a new rx cookie jar
*
* @return {Observable<RxCookieJar>}
*/
jar() {
return of(new RxCookieJar(this._request.jar()));
}
/**
* Function that creates a new cookie
*
* @param str {string}
*
* @return {Observable<Cookie>}
*/
cookie(str) {
return of(this._request.cookie(str));
}
/**
* Function to do a HTTP request for given method
*
* @param method {string}
* @param uri {string}
* @param options {CoreOptions}
*
* @return {Observable<RxHttpRequestResponse<R>>}
*
* @private
*/
_call(method, uri, options) {
return new Observable((observer) => {
of([].concat(uri, Object.assign({}, options || {}), ((error, response, body) => {
of(of(error))
.pipe(flatMap(obsError => merge(obsError
.pipe(filter(_ => !!_), tap(err => observer.error(err))), obsError
.pipe(filter(_ => !_), flatMap(() => !!response ?
of(response) :
throwError(new Error('No response found'))), flatMap(_ => of({
response: _,
body: body
})), tap(_ => observer.next(_)), tap(() => observer.complete())))))
.subscribe(() => undefined, err => observer.error(err));
})))
.pipe(map(_ => this._request[method].apply(this._request, _)))
.subscribe(() => undefined, err => observer.error(err));
});
}
/**
* Function to check existing function in request API passed in parameter for a new instance
*
* @param req {RequestAPI<Request, CoreOptions, RequiredUriUrl>}
*
* @private
*/
_checkRequestParam(req) {
// check existing function in API
if (!req ||
Object.prototype.toString.call(req.get) !== '[object Function]' ||
Object.prototype.toString.call(req.head) !== '[object Function]' ||
Object.prototype.toString.call(req.post) !== '[object Function]' ||
Object.prototype.toString.call(req.put) !== '[object Function]' ||
Object.prototype.toString.call(req.patch) !== '[object Function]' ||
Object.prototype.toString.call(req.del) !== '[object Function]' ||
Object.prototype.toString.call(req.defaults) !== '[object Function]' ||
Object.prototype.toString.call(req.jar) !== '[object Function]' ||
Object.prototype.toString.call(req.cookie) !== '[object Function]') {
throw new TypeError('Parameter must be a valid `request` module API');
}
}
}
/**
* Export {RxHttpRequest} instance
*/
export const RxHR = RxHttpRequest.instance();
//# sourceMappingURL=rx-http-request.js.map