UNPKG

integreat

Version:
103 lines 4.7 kB
import compareEndpoints from './utils/compareEndpoints.js'; import isEndpointMatch from './utils/isEndpointMatch.js'; import { populateActionAfterMutation } from '../utils/mutationHelpers.js'; import { ensureArray } from '../utils/array.js'; import { isNotNullOrUndefined, isObject } from '../utils/is.js'; import { combineResponses, setOrigin } from '../utils/response.js'; import prepareValidator from '../utils/validation.js'; const prepareMatch = ({ scope, ...match }) => scope === 'all' || !scope ? match : { scope, ...match }; const prepareEndpoint = ({ match, ...endpoint }) => ({ match: prepareMatch(match || {}), ...endpoint, }); function runMutationAndPopulateAction(mutator) { return () => async (action, state) => { const mutatedAction = (await mutator(action, state)); return populateActionAfterMutation(action, mutatedAction); }; } const setModifyFlag = (def) => isObject(def) ? { ...def, $modify: true } : def; const transformerFromAdapter = (serviceId, options = {}) => function createAdapterTransformer(adapter) { const adapterId = adapter.id; const preparedOptions = typeof adapterId === 'string' ? adapter.prepareOptions(options[adapterId] || {}, serviceId) : {}; return () => async (action, state) => state.rev ? await adapter.serialize(action, preparedOptions) : await adapter.normalize(action, preparedOptions); }; function prepareActionMutation(serviceMutation, endpointMutation, serviceAdapterTransformer, endpointAdapterTransformer, mapTransform, mapOptions) { const serviceMutator = mapTransform(ensureArray(serviceMutation) .map(setModifyFlag) .filter(isNotNullOrUndefined), mapOptions); const endpointMutator = mapTransform(ensureArray(endpointMutation) .map(setModifyFlag) .filter(isNotNullOrUndefined), mapOptions); const pipeline = [ ...serviceAdapterTransformer.map((transformer) => ({ $transform: transformer, })), { $transform: runMutationAndPopulateAction(serviceMutator) }, ...endpointAdapterTransformer.map((transformer) => ({ $transform: transformer, })), { $transform: runMutationAndPopulateAction(endpointMutator) }, ]; return mapTransform(pipeline, mapOptions); } export default class Endpoint { id; match; options; allowRawRequest; allowRawResponse; castWithoutDefaults; outgoingAuth; incomingAuth; #origin; #validator; #mutateAction; #checkIfMatch; constructor(endpointDef, serviceId, options, mapTransform, mapOptions, serviceMutation, serviceAdapters = [], endpointAdapters = [], outgoingAuth, incomingAuth) { this.id = endpointDef.id; this.#origin = endpointDef.id ? `service:${serviceId}:endpoint:${endpointDef.id}` : `service:${serviceId}:endpoint`; this.allowRawRequest = endpointDef.allowRawRequest; this.allowRawResponse = endpointDef.allowRawResponse; this.castWithoutDefaults = endpointDef.castWithoutDefaults ?? false; this.match = endpointDef.match; this.#checkIfMatch = isEndpointMatch(endpointDef, mapTransform, mapOptions); this.options = options; this.#validator = prepareValidator(endpointDef.validate, mapTransform, mapOptions); this.#mutateAction = prepareActionMutation(serviceMutation, endpointDef.mutation || endpointDef.mutate, serviceAdapters.map(transformerFromAdapter(serviceId, options.adapters)), endpointAdapters.map(transformerFromAdapter(serviceId, options.adapters)), mapTransform, mapOptions); this.outgoingAuth = outgoingAuth; this.incomingAuth = incomingAuth; } async validateAction(action) { const [errors] = await this.#validator(action); const response = combineResponses(errors); return response ? setOrigin(response, `validate:${this.#origin}`) : null; } async mutate(action, isRev) { if (!action) { throw new Error('Endpoint mutation was run without action'); } return (await this.#mutateAction(action, { rev: isRev })); } async isMatch(action, isIncoming) { return await this.#checkIfMatch(action, isIncoming); } static sortAndPrepare(endpointDefs) { return endpointDefs.map(prepareEndpoint).sort(compareEndpoints); } static async findMatchingEndpoint(endpoints, action, isIncoming = false) { for (const endpoint of endpoints) { if (await endpoint.isMatch(action, isIncoming)) { return endpoint; } } return undefined; } } //# sourceMappingURL=Endpoint.js.map