UNPKG

@argab/request-service

Version:

Provides a fully customizable Library for handling API using Request repositories and Stubs.

246 lines (200 loc) 6.18 kB
import {RequestFactory} from "./RequestFactory" import {RequestMiddleware} from "./RequestMiddleware" import {RequestMiddlewareDecorator} from "./Decorators" import {RequestManager} from "./RequestManager" import {RequestRetry} from "./RequestRetry" import {proxy, isPrototype, applyCall} from "./helpers" class AbstractRequest { _requests = [] _factory _manager _middleware _retry _getRepo _getStub _useStubs _config = { handler: null, client: null, repo: null, repoPath: null, repoMethod: null, loader: null, useLoader: false, stubData: null, headers: {'Content-Type': 'application/json;charset=UTF-8'}, uri: '', params: {}, method: 'get', statusCode: 0, retry: null, retryOnCatch: null, retryChain: null, retryMaxCount: 0, retryTimeout: 0, retryCount: 0, dataError: null, result: null, log: true } _extend = { middleware: null, request: null } repo() { } stub() { } getLog() { } log() { } extends() { } } class RequestService extends AbstractRequest { constructor({config, getRepo, getStub, useStubs, extend, factory, manager, middleware, request, requestRetry}) { super() this._getRepo = getRepo instanceof Function ? getRepo : () => null this._getStub = getStub instanceof Function ? getStub : () => null this._useStubs = Boolean(useStubs) this._factory = isPrototype(RequestFactory, factory) ? factory : RequestFactory this._manager = isPrototype(RequestManager, manager) ? manager : RequestManager this._middleware = isPrototype(RequestMiddleware, middleware) ? middleware : RequestMiddlewareDecorator this._retry = isPrototype(RequestRetry, requestRetry) ? requestRetry : RequestRetry this._factory = new this._factory({request, service: this}) config instanceof Object && Object.assign(this._config, config) extend instanceof Object && Object.assign(this._extend, extend) const _extend = this.extends().middleware _extend instanceof Object && Object.keys(_extend).forEach(key => this._middleware.prototype[key] = _extend[key]) return this.proxy } repo(path) { if (this._useStubs) { const stub = this.stub(path) if (stub) return stub } return this._getRepo(path) } stub(path) { return this._getStub(path) } getLog() { return this._requests } log(request) { this._requests.push(request) } extends() { return {...this._extend} } get proxy() { return proxy(this, null, (state, method, args) => { if (false === ['repo', 'stub'].includes(method) && state[method] instanceof Function) { return state[method](args[0]) } return applyCall(new state._middleware(state), method, args) }) } } class Request { data = {} chain = [] _fetch _resolve #methods = ['then', 'catch', 'finally', 'success', 'error', 'retry', 'retryOnCatch', 'retryChain', 'retryMaxCount', 'retryTimeout'] #resolveMethods = ['then', 'catch', 'finally', 'success', 'error'] get methods() { return this.#methods.slice() } set methods(name) { return this.#methods.push(name) } get resolveMethods() { return this.#resolveMethods.slice() } constructor(data) { this.data = data } /* * Method is Abstract. * */ then(callback) { } /* * Method is Abstract. * */ catch(callback) { } /* * Method is Abstract. * */ finally(callback) { } /* * Method is Abstract. * */ success(callback) { } /* * Method is Abstract. * */ error(callback) { } /* * This method doesn't restarts the request, it brings the Function that * takes the request data as an argument and initiates the request restarting method. * The Function executes at the end of a Promise.prototype.finally() * @param: {Boolean}|{Function}(data):<Boolean|Promise> Boolean or a Function returning both Boolean or a Promise * returning Boolean that whenever is TRUE then restarts the request * @return: void * */ retry(resolve) { this.data.retry = resolve } /* * The request retry error handler. * The Function executes at the end of a Promise.prototype.finally() * @param: {Boolean}|{Function}(data):<Boolean|Promise> Boolean or a Function returning both Boolean or a Promise * returning Boolean that whenever is TRUE then restarts the request * @return: void * */ retryOnCatch(resolve) { this.data.retryOnCatch = resolve } /* * Overrides the current request`s methods call chain on retry. * The Function executes within a retry method. * @example: ....retryChain(({set}) => set.json() * .post('http://some.url', {params}) * .success(...).error(...).catch(...)) * @param: {Function}({set, chain, data}):<void|Array> * - @property "set" creates a new set * of the current request`s methods call. * - @property "chain" provides an Array * [{method, args}, {method, args}, ....] * containing the current request`s methods call chain. * - @property "data" - current request`s data. * @return: void * */ retryChain(callback) { this.data.retryChain = callback } /* * Sets a max number of retry attempts * @param: {Number} * @return: void * */ retryMaxCount(count) { this.data.retryMaxCount = Number.isNaN(+count) ? 0 : +count } /* * Sets the timeout between retry attempts * @param: {Number} * @return: void * */ retryTimeout(miliseconds) { this.data.retryTimeout = Number.isNaN(+miliseconds) ? 0 : +miliseconds } } export {RequestService, Request, AbstractRequest}