1 import { createAction } from '@reduxjs/toolkit';
3 import { type ActionCallback, withCallback } from '@proton/pass/store/actions/enhancers/callback';
4 import { pipe } from '@proton/pass/utils/fp/pipe';
6 import { withRequest, withRequestFailure, withRequestSuccess } from './enhancers';
7 import type { RequestConfig } from './types';
9 type RequestPrepareAction<P extends any[], R> = (...params: P) => R;
10 type Payload<T = any> = { payload: T };
12 export type RequestFlow<I, S, F> = ReturnType<ReturnType<typeof requestActionsFactory<I, S, F>>>;
13 export type RequestIntent<T extends RequestFlow<any, any, any>> = T extends RequestFlow<infer U, any, any> ? U : never;
14 export type RequestSuccess<T extends RequestFlow<any, any, any>> = T extends RequestFlow<any, infer U, any> ? U : never;
16 type CreateRequestActionsOptions<
20 IntentData extends boolean,
21 SuccessData extends boolean,
22 FailureData extends boolean,
23 IntentPrepared extends Payload,
24 SuccessPrepared extends Payload,
25 FailurePrepared extends Payload,
27 requestId: (dto: IntentDTO) => string;
29 config?: RequestConfig<'start', IntentData>;
30 prepare?: RequestPrepareAction<[intent: IntentDTO], IntentPrepared>;
34 config?: RequestConfig<'success', SuccessData>;
35 prepare?: RequestPrepareAction<[success: SuccessDTO], SuccessPrepared>;
39 config?: RequestConfig<'failure', FailureData>;
40 prepare?: RequestPrepareAction<[error: unknown, failure: FailureDTO], FailurePrepared>;
44 /** Creates action creators for each stage of a request sequence:
45 * intent, success, and error. These action creators facilitate the
46 * dispatching of actions to represent the initiation of a request,
47 * successful completion of a request, and handling of errors that
48 * occur during the request process.*/
49 export const requestActionsFactory =
50 <IntentDTO, SuccessDTO, FailureDTO = void>(namespace: string) =>
52 IntentPrepared extends Payload = Payload<IntentDTO>,
53 SuccessPrepared extends Payload = Payload<SuccessDTO>,
54 FailurePrepared extends Payload = Payload<FailureDTO>,
55 IntentData extends boolean = false,
56 SuccessData extends boolean = false,
57 FailureData extends boolean = false,
59 options: CreateRequestActionsOptions<
71 type IntentPA = RequestPrepareAction<[intent: IntentDTO], IntentPrepared>;
72 type SuccessPA = RequestPrepareAction<[success: SuccessDTO], SuccessPrepared>;
73 type FailurePA = RequestPrepareAction<[error: unknown, failure: FailureDTO], FailurePrepared>;
75 const toPayload = (payload: unknown) => ({ payload });
76 const toPayloadWithError = (error: unknown, payload: unknown) => ({ payload, error });
78 const intentPA = (options.intent?.prepare ?? toPayload) as IntentPA;
79 const successPA = (options.success?.prepare ?? toPayload) as SuccessPA;
80 const failurePA = (options.failure?.prepare ?? toPayloadWithError) as FailurePA;
83 intent: createAction(`${namespace}::intent`, (payload: IntentDTO, callback?: ActionCallback) =>
87 id: options.requestId(payload),
88 ...(options.intent?.config ?? { data: false as IntentData }),
90 withCallback(callback)
93 success: createAction(`${namespace}::success`, withRequestSuccess(successPA, options.success?.config)),
94 failure: createAction(`${namespace}::failure`, withRequestFailure(failurePA, options.failure?.config)),