UNPKG

integreat

Version:
82 lines 3.79 kB
import debugLib from 'debug'; import pLimit from 'p-limit'; import { createErrorResponse, createUnknownServiceError, combineResponses, setOrigin, } from '../utils/response.js'; import mutateAndSend from '../utils/mutateAndSend.js'; import { isObject } from '../utils/is.js'; const debug = debugLib('great'); const isErrorResponse = (response) => isObject(response) && response.status !== 'ok' && response.status !== 'notfound' && response.status !== 'noaction'; const hasId = ({ payload: { id } }) => !!id; const getIdFromAction = ({ payload: { id } }) => Array.isArray(id) && id.length === 1 ? id[0] : id; function combineIndividualResponses(action, responses) { const errorResponses = responses.filter(isErrorResponse); if (errorResponses.length > 0) { const combinedResponse = combineResponses(errorResponses); return setOrigin({ ...combinedResponse, error: `One or more of the requests for ids ${getIdFromAction(action)} failed with the following error(s): ${combinedResponse.error}`, }, 'handler:GET'); } else { return { ...action.response, status: 'ok', data: responses.map((response) => Array.isArray(response.data) ? response.data[0] : response.data), }; } } const setIdOnActionPayload = (action, id) => ({ ...action, payload: { ...action.payload, id }, }); const createNoEndpointError = (action, serviceId) => createErrorResponse(`No endpoint matching ${action.type} request to service '${serviceId}'.`, 'handler:GET', 'badrequest'); async function runAsIndividualActions(action, service, dispatch) { const actions = action.payload.id.map((individualId) => setIdOnActionPayload(action, individualId)); const representativeAction = actions.find(hasId); if (!representativeAction) { return combineIndividualResponses(action, actions.map(() => ({ status: 'noaction', data: null }))); } const endpoint = await service.endpointFromAction(representativeAction); if (!endpoint) { return createNoEndpointError(action, service.id); } const responses = await Promise.all(actions.map((individualAction) => hasId(individualAction) ? pLimit(1)(() => mutateAndSend(service, endpoint, individualAction, dispatch)) : { status: 'noaction', data: null })); return combineIndividualResponses(action, responses); } const isMembersAction = (action) => Array.isArray(action.payload.id); async function runOneOrMany(action, service, dispatch) { const endpoint = await service.endpointFromAction(action); if (!endpoint) { if (isMembersAction(action)) { return runAsIndividualActions(action, service, dispatch); } else { return createNoEndpointError(action, service.id); } } else { return mutateAndSend(service, endpoint, action, dispatch); } } export default async function get(action, { getService, dispatch }) { const { type, targetService: serviceId, endpoint: endpointId, } = action.payload; const id = getIdFromAction(action); if (Array.isArray(id) && id.length === 0) { return createErrorResponse('GET action was dispatched with empty array of ids', 'handler:GET', 'noaction'); } const service = getService(type, serviceId); if (!service) { return createUnknownServiceError(type, serviceId, 'GET'); } const endpointDebug = endpointId ? `endpoint '${endpointId}'` : `endpoint matching type '${type}' and id '${id}'`; debug('GET: Fetch from service %s at %s', service.id, endpointDebug); const nextAction = setIdOnActionPayload(action, id); return await runOneOrMany(nextAction, service, dispatch); } //# sourceMappingURL=get.js.map