integreat
Version:
Node.js integration layer
75 lines • 3.05 kB
JavaScript
import { createMetaForSubAction } from '../utils/action.js';
import { createErrorResponse, setOrigin } from '../utils/response.js';
import { isObject, isTypedData } from '../utils/is.js';
const ORIGIN = 'handler:GET_ALL';
const extractLastId = (data, field = 'id') => Array.isArray(data) && isObject(data[data.length - 1])
?
data[data.length - 1] && data[data.length - 1][field]
: undefined;
const createAction = (page, { pageAfterField, ...payload }, paging, data, meta) => paging
? { type: 'GET', payload: paging, meta }
: {
type: 'GET',
payload: {
...payload,
page: Math.floor(page),
pageOffset: (page - 1) * payload.pageSize,
pageAfter: extractLastId(data, typeof pageAfterField === 'string' ? pageAfterField : undefined),
},
meta,
};
function getCurrentPage(payload) {
if (typeof payload.page === 'number') {
return payload.page;
}
else if (typeof payload.pageOffset === 'number') {
return payload.pageOffset / payload.pageSize + 1;
}
else {
return 1;
}
}
const getFirstId = (data) => Array.isArray(data) && isTypedData(data[0]) ? data[0].id : null;
function hasProps(obj) {
if (!obj)
return false;
const values = Object.values(obj);
return values.length > 0 && values.some((val) => val !== undefined);
}
const createNextPaging = (payload, paging) => hasProps(paging) ? { ...payload, ...paging } : undefined;
export default async function getAll(action, { dispatch }) {
const { pageSize, noLoopCheck = false } = action.payload;
if (typeof pageSize !== 'number') {
return createErrorResponse('GET_ALL requires a pageSize', ORIGIN, 'badrequest');
}
const data = [];
let page = getCurrentPage(action.payload);
let paging = undefined;
let lastSize = -1;
let prevFirstId = null;
do {
const response = await dispatch(createAction(page++, action.payload, paging, data, createMetaForSubAction(action.meta)));
if (response?.status !== 'ok') {
return setOrigin(response, ORIGIN);
}
const usePageId = !!paging || response?.paging?.next !== undefined;
paging = createNextPaging(action.payload, response?.paging?.next);
const responseData = response?.data;
if (Array.isArray(responseData)) {
if (!noLoopCheck) {
const firstId = getFirstId(responseData);
if (typeof firstId === 'string' && firstId === prevFirstId) {
return createErrorResponse('GET_ALL detected a possible infinite loop', ORIGIN);
}
prevFirstId = firstId;
}
data.push(...responseData);
lastSize = Array.isArray(responseData) ? responseData.length : 1;
}
if (!Array.isArray(responseData) || (usePageId && !paging)) {
lastSize = 0;
}
} while (lastSize === pageSize);
return { status: 'ok', data };
}
//# sourceMappingURL=getAll.js.map