contensis-core-api
Version:
A dependency library used by contensis-delivery-api and contensis-management-api
100 lines (83 loc) • 3.27 kB
text/typescript
import { IParamsProvider, ResponseContext, ResponseHandlerFunction, IHttpClient, ClientCredentialsGrant } from '../models';
import { isBrowser } from '../utils';
export class HttpClient implements IHttpClient {
constructor(
private paramsProvider: IParamsProvider,
private fetchFn: (input: RequestInfo, init?: RequestInit) => Promise<Response>) {
}
request<T>(url: string, request: RequestInit = {}): Promise<T> {
let params = this.paramsProvider.getParams();
const isRelativeRequestUrl = !params.rootUrl || params.rootUrl === '/';
if (!isBrowser() && isRelativeRequestUrl) {
throw new Error('You cannot specify a relative root url if not in a browser context.');
}
request.method = request.method || (!!request.body ? 'POST' : 'GET');
if (!isRelativeRequestUrl) {
request.mode = 'cors';
}
request.headers = request.headers || {};
let headers = request.headers as any;
if (!headers.accessToken && !!params.accessToken) {
headers.accessToken = params.accessToken;
}
if (params.clientType === 'none' && !headers.accessToken) {
throw new Error(`If the property clientType is set to "${params.clientType}" then the property accessToken must be provided.`);
}
if (params.clientType === 'client_credentials' && !(params.clientDetails as ClientCredentialsGrant)) {
throw new Error(`If the property client type is set to "${params.clientType}" then the property clientDetails must be set to a ClientCredentialsGrant value.`);
}
if (!!params.defaultHeaders) {
const keys = Object.keys(params.defaultHeaders);
keys.forEach(key => {
if (!headers[key] && !!params.defaultHeaders[key]) {
headers[key] = params.defaultHeaders[key];
}
});
}
const requestUrl = isRelativeRequestUrl ? `${url}` : `${params.rootUrl}${url}`;
return this.fetchFn(requestUrl, request)
.then((response) => {
let responseHandlerFunction: ResponseHandlerFunction = null;
if (!!params.responseHandler) {
if (!!params.responseHandler['*']) {
responseHandlerFunction = params.responseHandler['*'];
}
if (!!params.responseHandler[response.status]) {
responseHandlerFunction = params.responseHandler[response.status];
}
}
let responseContext: ResponseContext = {
status: response.status,
statusText: response.statusText,
url: response.url,
data: null
};
return response
.text()
.then(text => {
return !!text && text.length && text.length > 0 ? JSON.parse(text) : {};
})
.then(
result => {
responseContext.data = result;
if (response.ok) {
if (!!responseHandlerFunction) {
responseHandlerFunction(response, responseContext);
}
return result;
}
return !!responseHandlerFunction ?
responseHandlerFunction(response, responseContext)
: Promise.reject(responseContext);
},
reason => {
responseContext.data = reason;
return !!responseHandlerFunction ?
responseHandlerFunction(response, responseContext)
: Promise.reject(responseContext);
}
);
})
.then(result => result as any);
}
}