@minimaltech/ra-infra
Version:
Minimal Technology ReactJS Infrastructure
159 lines • 5.99 kB
JavaScript
import isEmpty from 'lodash/isEmpty';
import { App, LocalStorageKeys, RequestBodyTypes, RequestMethods, RequestTypes, } from '../../common';
import { getError } from '../../utilities';
import { BaseNetworkRequestService } from './base-network-request.service';
export class DefaultNetworkRequestService extends BaseNetworkRequestService {
authToken;
noAuthPaths;
headers;
constructor(opts) {
const { name, baseUrl, headers, noAuthPaths } = opts;
super({ name, scope: DefaultNetworkRequestService.name, baseUrl });
this.headers = headers;
this.noAuthPaths = noAuthPaths;
}
//-------------------------------------------------------------
getRequestAuthorizationHeader() {
const authToken = this.authToken ||
JSON.parse(localStorage.getItem(LocalStorageKeys.KEY_AUTH_TOKEN) || '{}');
if (!authToken?.value) {
throw getError({
message: '[dataProvider][getAuthHeader] Invalid auth token to fetch!',
statusCode: 401,
});
}
return `${authToken?.type || 'Bearer'} ${authToken.value}`;
}
//-------------------------------------------------------------
setAuthToken(opts) {
const { type, value } = opts;
this.authToken = { type, value };
}
//-------------------------------------------------------------
getRequestHeader(opts) {
const { resource } = opts;
const defaultHeaders = {
['Timezone']: App.TIMEZONE,
['Timezone-Offset']: `${App.TIMEZONE_OFFSET}`,
...this.headers,
};
if (this.noAuthPaths?.includes(resource)) {
return defaultHeaders;
}
const authHeader = this.getRequestAuthorizationHeader();
return { ...defaultHeaders, ['Authorization']: authHeader };
}
//-------------------------------------------------------------
getRequestProps(params) {
const { bodyType, body, file, resource } = params;
const headers = this.getRequestHeader({ resource });
const rs = { headers, body };
switch (bodyType) {
case RequestBodyTypes.FORM_URL_ENCODED: {
rs.headers = {
...headers,
'Content-Type': 'application/x-www-form-urlencoded',
};
const formData = new FormData();
for (const key in body) {
if (!body[key]) {
continue;
}
formData.append(key, body[key]);
}
rs.body = formData;
break;
}
case RequestBodyTypes.FORM_DATA: {
rs.headers = headers;
const formData = new FormData();
if (file) {
formData.append('file', file, file.name);
}
rs.body = formData;
break;
}
default: {
rs.headers = {
...headers,
'Content-Type': 'application/json',
};
rs.body = body;
break;
}
}
return rs;
}
//-------------------------------------------------------------
convertResponse(opts) {
const { response: { data, headers }, type, } = opts;
switch (type) {
case RequestTypes.GET_LIST:
case RequestTypes.GET_MANY_REFERENCE: {
const _data = !Array.isArray(data) ? [data] : data;
// content-range: <unit> <range-start>-<range-end>/<size>
// TODO: Handle content range not use `getListVariant`
const contentRange = (headers?.get('content-range') || headers?.get['Content-Range']) ??
_data.length;
return {
data: _data,
total: parseInt(contentRange.split('/').pop(), 10),
};
}
default: {
return { data };
}
}
}
//-------------------------------------------------------------
async doRequest(opts) {
const { baseUrl = this.baseUrl, type, method, paths, body, headers, query } = opts;
if (!baseUrl || isEmpty(baseUrl)) {
throw getError({
message: '[doRequest] Invalid baseUrl to send request!',
});
}
const url = this.getRequestUrl({ baseUrl, paths });
const rs = await this.networkService.send({
url,
method,
params: query,
body: method === RequestMethods.GET ? undefined : body,
headers,
configs: {},
});
const jsonRs = await rs.json();
const status = rs.status;
if (status < 200 || status >= 300) {
throw getError(jsonRs?.error);
}
let tempRs = {
response: { data: {}, headers: rs.headers ?? {} },
type,
};
switch (status) {
case 204: {
tempRs = { ...tempRs, response: { ...tempRs.response, data: {} } };
break;
}
default: {
if ([rs.headers?.get('content-type'), rs.headers?.get('Content-Type')].includes('application/octet-stream')) {
const blob = await rs.blob();
tempRs = {
...tempRs,
response: { ...tempRs.response, data: blob },
};
break;
}
tempRs = {
...tempRs,
response: { ...tempRs.response, data: jsonRs },
};
break;
}
}
const _rs = this.convertResponse(tempRs);
return _rs;
}
}
//# sourceMappingURL=default-network-data.service.js.map