@xompass/sdk-cloud-api
Version:
Xompass Client for cloud-api
186 lines (162 loc) • 6.12 kB
text/typescript
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('/') + '/';
}
}