UNPKG

@ima/plugin-http-client

Version:

Generic http client for the IMA application framework.

152 lines (151 loc) 4.75 kB
import { GenericError } from '@ima/core'; import { HttpClient } from '../HttpClient'; /** * AbstractResource will help with creating paths to the API as well as working with entities. */ export class AbstractResource { #httpClient; #baseApiUrl; static get $dependencies() { return [ HttpClient, '$Settings.plugin.httpClient.rest' ]; } /** * PathType is set of constant for use in getter path * @class */ static get PathType() { return { GET: 'get', CREATE: 'create', UPDATE: 'update', REPLACE: 'replace', DELETE: 'delete' }; } /** * This getter should return paths to API for concrete PathType */ get path() { throw new GenericError(`AbstractResource: getter "path" must be overriden.`); } /** * Optionally getter for EntityProcessor */ get entityClass() { return null; } constructor(httpClient, settings){ this.#httpClient = httpClient; if (!settings?.baseApiUrl) { throw new GenericError(`$Settings.plugin.httpClient.rest.baseApiUrl is not set.`); } this.#baseApiUrl = settings.baseApiUrl; } getBaseApiUrl() { return this.#baseApiUrl; } update(data, options, pathType = this.constructor.PathType.UPDATE) { return this.#restClientRequest('patch', pathType, data, options); } create(data, options, pathType = this.constructor.PathType.CREATE) { return this.#restClientRequest('post', pathType, data, options); } delete(data, options, pathType = this.constructor.PathType.DELETE) { return this.#restClientRequest('delete', pathType, data, options); } get(data, options, pathType = this.constructor.PathType.GET) { return this.#restClientRequest('get', pathType, data, options); } replace(data, options, pathType = this.constructor.PathType.REPLACE) { return this.#restClientRequest('put', pathType, data, options); } /** * Method invalidate cache for given params * @param method * @param data * @param pathType */ invalidateCache(method, data, pathType) { const url = this.getUrl(pathType, data); this.#httpClient.invalidateCache(method, url, this.prepareData(data)); } /** * Return pathTemplate by pathType * * @param pathType * @private */ #getPathTemplate(pathType) { const pathTemplate = this.path[pathType]; if (!pathTemplate) { throw new GenericError(`AbstractResource: getter "path" does not contain '${pathType}' pathType in ${this.constructor.name}`); } return pathTemplate; } /** * Create URL to API by baseApiUrl settings and processed path * * @param pathType * @param data */ getUrl(pathType, data) { const pathTemplate = this.#getPathTemplate(pathType); const path = this.processPathTemplate(pathTemplate, data); return this.getBaseApiUrl() + path; } /** * Prepare data for request * @param data */ prepareData(data) { return { ...data }; } /** * Prepare options for request * @param options */ prepareOptions(options) { return { ...options }; } /** * Process path - replace variables by values from data. * * @param pathTemplate * @param data * @private */ processPathTemplate(pathTemplate, data) { let path = pathTemplate; const regexFindVariables = new RegExp('{(.*?)}', 'g'); const keys = []; let matches; while(matches = regexFindVariables.exec(pathTemplate)){ keys.push(matches[1]); } keys.forEach((key)=>{ if (key === undefined || !(key in data)) { throw new GenericError(`AbstractResource: No attribute of key {${key}} found in data in ${this.constructor.name}.`); } path = path.replace(`{${key}}`, data[key]); delete data[key]; }); return path; } async #restClientRequest(method, pathType, data, options) { const url = this.getUrl(pathType, data); const { response } = await this.#httpClient.request({ method, url, data: this.prepareData(data), options: this.prepareOptions(options) }, this.getResourceInfo(pathType)); return response; } /** * Returns additionalParams for processors * @param pathType */ getResourceInfo(pathType) { return { resource: this, pathType }; } } //# sourceMappingURL=AbstractResource.js.map