Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / shared / lib / drawer / createDrawerApi.ts
blobafa66d6ca7e506bd9e59d7b875af4c1d687cd5f7
1 import { updateServerTime } from '@proton/crypto';
2 import type { ApiWithListener } from '@proton/shared/lib/api/createApi';
3 import noop from '@proton/utils/noop';
5 import type { APP_NAMES } from '../constants';
6 import { DEFAULT_TIMEOUT } from '../constants';
7 import { createTimeoutError, deserializeApiErrorData } from '../fetch/ApiError';
8 import { getIsAuthorizedApp, getIsDrawerPostMessage, postMessageFromIframe } from './helpers';
9 import { DRAWER_EVENTS } from './interfaces';
11 export const createDrawerApi = ({
12     parentApp,
13     appVersion,
14 }: {
15     parentApp: APP_NAMES | undefined;
16     appVersion: string;
17 }): ApiWithListener => {
18     let n = 1;
20     const callback = (arg: any) => {
21         const id = `${n++}`;
22         let timeout: ReturnType<typeof setTimeout> | undefined;
24         let resolve: (arg: any) => void = noop;
25         let reject: (error: any) => void = noop;
26         const promise = new Promise<any>((res, rej) => {
27             resolve = res;
28             reject = rej;
29         });
31         const handler = (event: MessageEvent) => {
32             if (!getIsDrawerPostMessage(event)) {
33                 return;
34             }
36             if (event.data.type === DRAWER_EVENTS.API_RESPONSE && event.data.payload.id === id) {
37                 const { output, serverTime, data, success, isApiError } = event.data.payload;
39                 window.removeEventListener('message', handler);
40                 if (timeout) {
41                     clearTimeout(timeout);
42                 }
44                 updateServerTime(serverTime);
46                 if (success && data) {
47                     if (output === 'raw') {
48                         resolve({ ...data, headers: new Headers(data.headers), json: async () => data.json });
49                     } else {
50                         resolve(data);
51                     }
52                 } else {
53                     if (isApiError) {
54                         reject(deserializeApiErrorData(data));
55                     }
56                     reject(data);
57                 }
58             }
59         };
61         if (parentApp && getIsAuthorizedApp(parentApp)) {
62             const hasAbortController = 'signal' in arg;
64             const newArg: any = { ...arg };
65             if (hasAbortController) {
66                 delete newArg.signal;
67                 (arg.signal as AbortSignal).onabort = () => {
68                     postMessageFromIframe(
69                         {
70                             type: DRAWER_EVENTS.ABORT_REQUEST,
71                             payload: { id },
72                         },
73                         parentApp as APP_NAMES
74                     );
75                 };
76             }
77             postMessageFromIframe(
78                 {
79                     type: DRAWER_EVENTS.API_REQUEST,
80                     payload: { arg: newArg, id, appVersion, hasAbortController },
81                 },
82                 parentApp
83             );
84             window.addEventListener('message', handler);
86             // Reject the promise if the parent app does not respond
87             timeout = setTimeout(() => {
88                 reject(createTimeoutError({}));
89             }, DEFAULT_TIMEOUT);
90         }
92         return promise;
93     };
95     Object.defineProperties(callback, {
96         UID: {
97             set() {},
98         },
99     });
101     return Object.assign(callback as ApiWithListener, {
102         addEventListener: () => {},
103         removeEventListener: () => {},
104     });