Skip to content

Commit 0ffbbcf

Browse files
feat: use named types for api request params (#6043)
1 parent 0a846a3 commit 0ffbbcf

File tree

2 files changed

+56
-54
lines changed

2 files changed

+56
-54
lines changed

extension/js/common/api/email-provider/gmail/google.ts

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,22 @@
22

33
'use strict';
44

5-
import { Ajax, ProgressCbs } from '../../shared/api.js';
6-
import { Dict, Str, UrlParams } from '../../../core/common.js';
5+
import { Ajax, AjaxParams, JsonParams, ProgressCbs } from '../../shared/api.js';
6+
import { Dict, Str } from '../../../core/common.js';
77

88
import { GMAIL_GOOGLE_API_HOST, PEOPLE_GOOGLE_API_HOST } from '../../../core/const.js';
99
import { GmailRes } from './gmail-parser.js';
1010
import { GoogleOAuth } from '../../authentication/google/google-oauth.js';
11-
import { Serializable } from '../../../platform/store/abstract-store.js';
1211
import { CatchHelper } from '../../../platform/catch-helper.js';
13-
1412
export class Google {
1513
public static webmailUrl = (acctEmail: string) => {
1614
return `https://mail.google.com/mail/u/${acctEmail}`;
1715
};
1816

19-
public static gmailCall = async <RT>(
20-
acctEmail: string,
21-
path: string,
22-
params?:
23-
| {
24-
method: 'POST' | 'PUT';
25-
data: Dict<Serializable>;
26-
dataType?: 'JSON';
27-
}
28-
| {
29-
method: 'POST';
30-
data: string;
31-
contentType: string;
32-
dataType: 'TEXT';
33-
}
34-
| {
35-
method: 'GET';
36-
data?: UrlParams;
37-
}
38-
| { method: 'DELETE' },
39-
progress?: ProgressCbs
40-
): Promise<RT> => {
17+
public static gmailCall = async <RT>(acctEmail: string, path: string, params?: AjaxParams, progress?: ProgressCbs): Promise<RT> => {
4118
progress = progress || {};
4219
let url;
43-
let dataPart:
44-
| { method: 'POST' | 'PUT'; data: Dict<Serializable>; dataType: 'JSON' }
45-
| { method: 'POST'; data: string; contentType: string; dataType: 'TEXT' }
46-
| { method: 'GET'; data?: UrlParams }
47-
| { method: 'DELETE' };
20+
let dataPart: AjaxParams;
4821
if (params?.method === 'POST' && params.dataType === 'TEXT') {
4922
url = `${GMAIL_GOOGLE_API_HOST}/upload/gmail/v1/users/me/${path}?uploadType=multipart`;
5023
dataPart = { method: 'POST', data: params.data, contentType: params.contentType, dataType: 'TEXT' };
@@ -53,7 +26,12 @@ export class Google {
5326
if (params?.method === 'GET') {
5427
dataPart = { method: 'GET', data: params.data };
5528
} else if (params?.method === 'POST' || params?.method === 'PUT') {
56-
dataPart = { method: params.method, data: params.data, dataType: 'JSON' };
29+
const { method, data } = params as JsonParams;
30+
dataPart = {
31+
method,
32+
data,
33+
dataType: 'JSON',
34+
};
5735
} else if (params?.method === 'DELETE') {
5836
dataPart = { ...params };
5937
} else {

extension/js/common/api/shared/api.ts

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,36 @@ export type AjaxHeaders = {
2525
authorization?: string;
2626
['api-version']?: string;
2727
};
28+
interface GetParams {
29+
method: 'GET' | 'DELETE';
30+
data?: UrlParams;
31+
}
32+
export interface JsonParams {
33+
method: 'POST' | 'PUT';
34+
data?: Dict<Serializable>;
35+
dataType?: 'JSON';
36+
}
37+
38+
interface TextParams {
39+
method: 'POST' | 'PUT';
40+
data: string;
41+
contentType?: string;
42+
dataType: 'TEXT';
43+
}
44+
interface FormParams {
45+
method: 'POST' | 'PUT';
46+
data: FormData;
47+
dataType: 'FORM';
48+
}
49+
50+
export type AjaxParams = GetParams | JsonParams | TextParams | FormParams;
2851
export type Ajax = {
2952
url: string;
3053
headers?: AjaxHeaders;
3154
progress?: ProgressCbs;
3255
timeout?: number; // todo: implement
3356
stack: string;
34-
} & (
35-
| { method: 'GET' | 'DELETE'; data?: UrlParams }
36-
| { method: 'POST' }
37-
| { method: 'POST' | 'PUT'; data: Dict<Serializable>; dataType: 'JSON' }
38-
| { method: 'POST' | 'PUT'; contentType?: string; data: string; dataType: 'TEXT' }
39-
| { method: 'POST' | 'PUT'; data: FormData; dataType: 'FORM' }
40-
| { method: never; data: never; contentType: never }
41-
);
57+
} & AjaxParams;
4258
type RawAjaxErr = {
4359
readyState: number;
4460
responseText?: string;
@@ -157,7 +173,7 @@ export class Api {
157173
headersInit.push(['Content-Type', req.contentType]);
158174
}
159175
} else {
160-
body = req.data; // todo: form data content-type?
176+
body = req.data as FormData; // todo: form data content-type?
161177
}
162178
}
163179
}
@@ -291,13 +307,26 @@ export class Api {
291307
let data: BodyInit | undefined = formattedData;
292308
const headersInit: Dict<string> = req.headers ?? {};
293309

294-
if (req.method === 'PUT' || req.method === 'POST') {
295-
if ('data' in req && typeof req.data !== 'undefined') {
296-
data = req.dataType === 'JSON' ? JSON.stringify(req.data) : req.data;
297-
298-
if (req.dataType === 'TEXT' && typeof req.contentType === 'string') {
299-
headersInit['Content-Type'] = req.contentType;
300-
}
310+
if ((req.method === 'PUT' || req.method === 'POST') && 'data' in req) {
311+
switch (req.dataType) {
312+
case 'JSON':
313+
// req.data is Dict<Serializable>
314+
data = JSON.stringify(req.data);
315+
headersInit['Content-Type'] = 'application/json';
316+
break;
317+
case 'TEXT':
318+
// req.data is string
319+
data = req.data;
320+
if (req.contentType) {
321+
headersInit['Content-Type'] = req.contentType;
322+
}
323+
break;
324+
case 'FORM':
325+
// req.data is FormData
326+
data = req.data;
327+
break;
328+
default:
329+
break;
301330
}
302331
}
303332
const apiReq: JQuery.AjaxSettings<ApiCallContext> = {
@@ -385,12 +414,7 @@ export class Api {
385414
): Promise<FetchResult<T, RT>> {
386415
progress = progress || ({} as ProgressCbs);
387416
let formattedData: FormData | string | undefined;
388-
let dataPart:
389-
| { method: 'GET' }
390-
| { method: 'POST' | 'PUT'; data: Dict<Serializable>; dataType: 'JSON' }
391-
| { method: 'POST' | 'PUT'; data: string; dataType: 'TEXT' }
392-
| { method: 'POST' | 'PUT'; data: FormData; dataType: 'FORM' };
393-
dataPart = { method: 'GET' };
417+
let dataPart: AjaxParams = { method: 'GET' };
394418
if (values) {
395419
if (values.fmt === 'JSON') {
396420
dataPart = { method: values.method ?? 'POST', data: values.data, dataType: 'JSON' };

0 commit comments

Comments
 (0)