@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
169 lines (167 loc) • 5.69 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { ajax } from 'rxjs/ajax';
import { catchError } from 'rxjs/operators';
import { reversePluckProps } from './object';
import { of } from 'rxjs';
import { sessionTimeout } from '../state/actions/user';
import { UNDEFINED } from './constants';
const HEADERS = {};
export const CONTENT_TYPE_JSON = { 'Content-Type': 'application/json' };
export const OMIT_GLOBAL_HEADERS = Symbol('OmitGlobalHeaders');
export function setGlobalHeaders(props) {
Object.assign(HEADERS, props);
}
export function removeGlobalHeaders(...headersToDelete) {
headersToDelete.forEach((header) => {
delete HEADERS[header];
});
}
export function getGlobalHeaders() {
return { ...HEADERS };
}
/**
* Merges the supplied `headers` object with the current global headers and returns the resulting object.
**/
function mergeHeaders(headers = {}) {
if (!headers || headers === OMIT_GLOBAL_HEADERS) {
return UNDEFINED;
} else if (Object.values(headers).includes(OMIT_GLOBAL_HEADERS)) {
return headers;
}
return Object.assign({}, HEADERS, headers);
}
export function get(url, headers) {
return ajax.get(url, mergeHeaders(headers));
}
export function getText(url, headers) {
return ajax({
url,
headers: mergeHeaders(headers),
responseType: 'text'
});
}
export function getBinary(url, headers, responseType = 'arraybuffer') {
return ajax({
url,
responseType,
headers: mergeHeaders(headers)
});
}
export function post(url, body, headers) {
return ajax.post(url, body, mergeHeaders(headers));
}
export function postJSON(url, body, headers) {
return ajax.post(url, body, mergeHeaders({ ...CONTENT_TYPE_JSON, ...headers }));
}
export function patch(url, body, headers) {
return ajax.patch(url, body, mergeHeaders(headers));
}
export function patchJSON(url, body, headers) {
return ajax.patch(url, body, mergeHeaders({ ...CONTENT_TYPE_JSON, ...headers }));
}
export function put(url, body, headers) {
return ajax.put(url, body, mergeHeaders(headers));
}
export function del(url, headers) {
return ajax.delete(url, mergeHeaders(headers));
}
function ajaxWithCrafterHeaders(urlOrRequest) {
if (typeof urlOrRequest === 'string') {
return ajax(urlOrRequest);
} else {
return ajax({ ...urlOrRequest, headers: mergeHeaders(urlOrRequest.headers) });
}
}
export { ajaxWithCrafterHeaders as ajax };
export const catchAjaxError = (fetchFailedCreator, ...moreActionCreators) =>
catchError((error) => {
if (error.name === 'AjaxError') {
const ajaxError = reversePluckProps(error, 'xhr', 'request');
ajaxError.response = ajaxError.response?.response ?? {
code: ajaxError.status,
message: 'An unknown error has occurred.'
};
const actions = [fetchFailedCreator(ajaxError), ...moreActionCreators.map((ac) => ac(ajaxError))];
if (ajaxError.status === 401) {
actions.push(sessionTimeout());
}
return of(...actions);
} else {
console.error('[ajax/catchAjaxError] An epic threw and hence it will be disabled. Check logic.', error);
throw error;
}
});
export const errorSelectorApi1 = (error) => {
let response = {
code: 1000,
message: 'Internal system failure',
remedialAction: 'Contact support'
};
if (error.name === 'AjaxError') {
switch (error.status) {
case 400:
// eslint-disable-next-line no-throw-literal
response = {
code: 1001,
message: 'Invalid parameter(s)',
remedialAction: "Check API and make sure you're sending the correct parameters"
};
break;
case 401:
// eslint-disable-next-line no-throw-literal
response = {
code: 2000,
message: 'Unauthenticated',
remedialAction: 'Please login first'
};
break;
case 403:
// eslint-disable-next-line no-throw-literal
response = {
code: 2001,
message: 'Unauthorized',
remedialAction: "You don't have permission to perform this task, please contact your administrator"
};
break;
case 404: {
// eslint-disable-next-line no-throw-literal
response = {
code: 404,
message: 'Resource not found'
};
break;
}
}
}
error.response = { response };
throw error;
};