Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 10 additions & 32 deletions extension/js/common/api/email-provider/gmail/google.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,22 @@

'use strict';

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

import { GMAIL_GOOGLE_API_HOST, PEOPLE_GOOGLE_API_HOST } from '../../../core/const.js';
import { GmailRes } from './gmail-parser.js';
import { GoogleOAuth } from '../../authentication/google/google-oauth.js';
import { Serializable } from '../../../platform/store/abstract-store.js';
import { CatchHelper } from '../../../platform/catch-helper.js';

export class Google {
public static webmailUrl = (acctEmail: string) => {
return `https://mail.google.com/mail/u/${acctEmail}`;
};

public static gmailCall = async <RT>(
acctEmail: string,
path: string,
params?:
| {
method: 'POST' | 'PUT';
data: Dict<Serializable>;
dataType?: 'JSON';
}
| {
method: 'POST';
data: string;
contentType: string;
dataType: 'TEXT';
}
| {
method: 'GET';
data?: UrlParams;
}
| { method: 'DELETE' },
progress?: ProgressCbs
): Promise<RT> => {
public static gmailCall = async <RT>(acctEmail: string, path: string, params?: AjaxParams, progress?: ProgressCbs): Promise<RT> => {
progress = progress || {};
let url;
let dataPart:
| { method: 'POST' | 'PUT'; data: Dict<Serializable>; dataType: 'JSON' }
| { method: 'POST'; data: string; contentType: string; dataType: 'TEXT' }
| { method: 'GET'; data?: UrlParams }
| { method: 'DELETE' };
let dataPart: AjaxParams;
if (params?.method === 'POST' && params.dataType === 'TEXT') {
url = `${GMAIL_GOOGLE_API_HOST}/upload/gmail/v1/users/me/${path}?uploadType=multipart`;
dataPart = { method: 'POST', data: params.data, contentType: params.contentType, dataType: 'TEXT' };
Expand All @@ -53,7 +26,12 @@ export class Google {
if (params?.method === 'GET') {
dataPart = { method: 'GET', data: params.data };
} else if (params?.method === 'POST' || params?.method === 'PUT') {
dataPart = { method: params.method, data: params.data, dataType: 'JSON' };
const { method, data } = params as JsonParams;
dataPart = {
method,
data,
dataType: 'JSON',
};
} else if (params?.method === 'DELETE') {
dataPart = { ...params };
} else {
Expand Down
68 changes: 46 additions & 22 deletions extension/js/common/api/shared/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,36 @@ export type AjaxHeaders = {
authorization?: string;
['api-version']?: string;
};
interface GetParams {
method: 'GET' | 'DELETE';
data?: UrlParams;
}
export interface JsonParams {
method: 'POST' | 'PUT';
data?: Dict<Serializable>;
dataType?: 'JSON';
}

interface TextParams {
method: 'POST' | 'PUT';
data: string;
contentType?: string;
dataType: 'TEXT';
}
interface FormParams {
method: 'POST' | 'PUT';
data: FormData;
dataType: 'FORM';
}

export type AjaxParams = GetParams | JsonParams | TextParams | FormParams;
export type Ajax = {
url: string;
headers?: AjaxHeaders;
progress?: ProgressCbs;
timeout?: number; // todo: implement
stack: string;
} & (
| { method: 'GET' | 'DELETE'; data?: UrlParams }
| { method: 'POST' }
| { method: 'POST' | 'PUT'; data: Dict<Serializable>; dataType: 'JSON' }
| { method: 'POST' | 'PUT'; contentType?: string; data: string; dataType: 'TEXT' }
| { method: 'POST' | 'PUT'; data: FormData; dataType: 'FORM' }
| { method: never; data: never; contentType: never }
);
} & AjaxParams;
type RawAjaxErr = {
readyState: number;
responseText?: string;
Expand Down Expand Up @@ -157,7 +173,7 @@ export class Api {
headersInit.push(['Content-Type', req.contentType]);
}
} else {
body = req.data; // todo: form data content-type?
body = req.data as FormData; // todo: form data content-type?
}
}
}
Expand Down Expand Up @@ -291,13 +307,26 @@ export class Api {
let data: BodyInit | undefined = formattedData;
const headersInit: Dict<string> = req.headers ?? {};

if (req.method === 'PUT' || req.method === 'POST') {
if ('data' in req && typeof req.data !== 'undefined') {
data = req.dataType === 'JSON' ? JSON.stringify(req.data) : req.data;

if (req.dataType === 'TEXT' && typeof req.contentType === 'string') {
headersInit['Content-Type'] = req.contentType;
}
if ((req.method === 'PUT' || req.method === 'POST') && 'data' in req) {
switch (req.dataType) {
case 'JSON':
// req.data is Dict<Serializable>
data = JSON.stringify(req.data);
headersInit['Content-Type'] = 'application/json';
break;
case 'TEXT':
// req.data is string
data = req.data;
if (req.contentType) {
headersInit['Content-Type'] = req.contentType;
}
break;
case 'FORM':
// req.data is FormData
data = req.data;
break;
default:
break;
}
}
const apiReq: JQuery.AjaxSettings<ApiCallContext> = {
Expand Down Expand Up @@ -385,12 +414,7 @@ export class Api {
): Promise<FetchResult<T, RT>> {
progress = progress || ({} as ProgressCbs);
let formattedData: FormData | string | undefined;
let dataPart:
| { method: 'GET' }
| { method: 'POST' | 'PUT'; data: Dict<Serializable>; dataType: 'JSON' }
| { method: 'POST' | 'PUT'; data: string; dataType: 'TEXT' }
| { method: 'POST' | 'PUT'; data: FormData; dataType: 'FORM' };
dataPart = { method: 'GET' };
let dataPart: AjaxParams = { method: 'GET' };
if (values) {
if (values.fmt === 'JSON') {
dataPart = { method: values.method ?? 'POST', data: values.data, dataType: 'JSON' };
Expand Down
Loading