UNPKG

@xompass/sdk-cloud-api

Version:

Xompass Client for cloud-api

186 lines (162 loc) 6.12 kB
import { XompassAuth } from './'; import { XompassClient } from '../../XompassClient'; import { LoopBackFilter } from '../../models'; import { XompassHTTPClient } from './XompassHTTP'; import { SDKModels } from '../custom'; export abstract class XompassBaseApi { protected static model: any; /** * This is a core method, every HTTP Call will be done from here, every API Service will * extend this class and use this method to get RESTful communication. */ public static request( method: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH' | 'HEAD' | 'OPTIONS', url: string, routeParams: any = {}, urlParams: any = {}, postBody: any = {}, retry = false, ): Promise<any> { // Transpile route variables to the actual request Values Object.keys(routeParams).forEach((key: string) => { url = url.replace( new RegExp(':' + key + '(/|$)', 'g'), routeParams[key] + '$1', ); }); // Headers to be sent let headers: any = { 'Content-Type': 'application/json' }; // Authenticate request headers = this.authenticate(url, headers); // Body fix for built-in remote methods using "data", "options" or "credentials // that are the actual body, Custom remote method properties are different and need // to be wrapped into a body object let body: any; const postBodyKeys: Array<any> = typeof postBody === 'object' ? Object.keys(postBody) : []; if (postBodyKeys.length === 1) { body = postBody[postBodyKeys.shift()]; } else { body = postBody; } let queryString = Object.keys(urlParams).length ? '?' : ''; // Separate filter object from url params and add to search query if (urlParams.filter) { queryString += `filter=${ encodeURIComponent(JSON.stringify(urlParams.filter)) }`; delete urlParams.filter; } else if (urlParams.where) { // Separate where object from url XompassApiConfigParams and add to search query queryString += `where=${ encodeURIComponent(JSON.stringify(urlParams.where)) }`; delete urlParams.where; } queryString += Object.keys(urlParams).reduce((array: string[], key) => { const value = urlParams[key]; if (value) { array.push(`${ key }=${ typeof value === 'object' ? encodeURIComponent(JSON.stringify(value)) : value + '' }`); } return array; }, []).join('&'); return XompassHTTPClient .exec({ method, url: `${ url }${ queryString }`, body, headers, routeParams, retry }); } /** * This method will try to authenticate using either an access_token or basic http auth */ public static authenticate<T>(url: string, headers: { [key: string]: string | number }): object { if (XompassAuth.getAccessTokenId()) { headers['Authorization'] = XompassClient.getAuthPrefix() + XompassAuth.getAccessTokenId(); } return headers; } /** * Generic create method */ public static create<T>(data: T, retry=false): Promise<T> { const url = this.getBasePath(); return this.request('POST', url, undefined, undefined, { data }, retry) .then((response: T) => this.model.factory(response)); } /** * Generic findById method */ public static findById<T>(id: any, _filter: LoopBackFilter = {}, retry = false): Promise<T> { const _urlParams: any = {}; if (_filter) { _urlParams.filter = _filter; } const url = this.getBasePath() + ':id'; return this.request('GET', url, { id }, _urlParams, undefined, retry) .then((data: T) => this.model.factory(data)); } /** * Generic find method */ public static find<T>(_filter: LoopBackFilter = {}, retry = false): Promise<T[]> { const url = this.getBasePath(); return this.request('GET', url, undefined, { filter: _filter }, undefined, retry) .then((datum: T[]) => datum.map((data: T) => this.model.factory(data))); } /** * Generic exists method */ public static exists<T>(id: any, retry = false): Promise<{ exist: boolean }> { const url = this.getBasePath() + ':id/exists'; return this.request('HEAD', url, { id }, undefined, undefined, retry) .then((response: { exist: boolean }) => response); } /** * Generic findOne method */ public static findOne<T>(_filter: LoopBackFilter = {}, retry = false): Promise<T> { const url = this.getBasePath() + 'findOne'; return this.request('GET', url, undefined, { filter: _filter }, undefined, retry) .then((data: T) => this.model.factory(data)); } /** * Generic deleteById method */ public static deleteById<T>(id: any, retry = false): Promise<T> { const url = this.getBasePath() + ':id'; return this.request('DELETE', url, { id }, undefined, undefined, retry) .then((data: T) => this.model.factory(data)); } /** * Generic count method */ public static count(where: any = {}, retry = false): Promise<{ count: number }> { const url = this.getBasePath() + 'count'; const _urlParams: any = {}; if (where) { _urlParams.where = where; } return this.request('GET', url, undefined, _urlParams, undefined, retry); } /** * Generic updateAttributes method */ public static updateAttributes<T>(id: any, data: T, retry = false): Promise<T> { const url = this.getBasePath() + ':id'; return this.request('PUT', url, { id }, undefined, { data }, retry) .then((response: T) => this.model.factory(response)); } /** * Generic patchAttributes method */ public static patchAttributes<T>(id: any, data: T, retry = false): Promise<T> { const url = this.getBasePath() + ':id'; return this.request('PATCH', url, { id }, undefined, { data }, retry) .then((response: T) => this.model.factory(response)); } /** * Abstract getModelName method */ abstract getModelName(): string; public static getBasePath() { return [XompassClient.getPath(), XompassClient.getApiVersion(), this.model.getModelDefinition().path].join('/') + '/'; } }