add fetcher logic to makeRequest

This commit is contained in:
Jorrin
2024-01-09 23:35:56 +01:00
parent f669b2d168
commit 441d1cb617
2 changed files with 35 additions and 7 deletions

View File

@@ -2,12 +2,16 @@ import type { PlasmoMessaging } from '@plasmohq/messaging';
import type { BaseRequest } from '~types/request'; import type { BaseRequest } from '~types/request';
import type { BaseResponse } from '~types/response'; import type { BaseResponse } from '~types/response';
import { makeFullUrl } from '~utils/fetcher';
import { validateDomainWhiteList } from '~utils/storage'; import { validateDomainWhiteList } from '~utils/storage';
interface Request extends BaseRequest { export interface Request extends BaseRequest {
url: string; baseUrl?: string;
method: string;
headers?: Record<string, string>; headers?: Record<string, string>;
method?: string;
query?: Record<string, string>;
readHeaders?: Record<string, string>;
url: string;
body?: string | FormData | URLSearchParams; body?: string | FormData | URLSearchParams;
} }
@@ -15,27 +19,27 @@ type Response = BaseResponse<{
status: number; status: number;
requestHeaders: Record<string, string>; requestHeaders: Record<string, string>;
responseHeaders: Record<string, string>; responseHeaders: Record<string, string>;
data: string | Record<string, unknown>; body: string | Record<string, unknown>;
}>; }>;
const handler: PlasmoMessaging.MessageHandler<Request, Response> = async (req, res) => { const handler: PlasmoMessaging.MessageHandler<Request, Response> = async (req, res) => {
try { try {
await validateDomainWhiteList(req.body.requestDomain); await validateDomainWhiteList(req.body.requestDomain);
const response = await fetch(req.body.url, { const response = await fetch(makeFullUrl(req.body.url, req.body), {
method: req.body.method, method: req.body.method,
headers: req.body.headers, headers: req.body.headers,
body: req.body.body, body: req.body.body,
}); });
const contentType = response.headers.get('content-type'); const contentType = response.headers.get('content-type');
const data = contentType?.includes('application/json') ? await response.json() : await response.text(); const body = contentType?.includes('application/json') ? await response.json() : await response.text();
res.send({ res.send({
success: true, success: true,
status: response.status, status: response.status,
requestHeaders: req.body.headers, requestHeaders: req.body.headers,
responseHeaders: Object.fromEntries(response.headers.entries()), responseHeaders: Object.fromEntries(response.headers.entries()),
data, body,
}); });
} catch (err) { } catch (err) {
res.send({ res.send({

24
src/utils/fetcher.ts Normal file
View File

@@ -0,0 +1,24 @@
import { type Request as MakeRequest } from '~background/messages/makeRequest';
export function makeFullUrl(url: string, ops?: MakeRequest): string {
// glue baseUrl and rest of url together
let leftSide = ops?.baseUrl ?? '';
let rightSide = url;
// left side should always end with slash, if its set
if (leftSide.length > 0 && !leftSide.endsWith('/')) leftSide += '/';
// right side should never start with slash
if (rightSide.startsWith('/')) rightSide = rightSide.slice(1);
const fullUrl = leftSide + rightSide;
if (!fullUrl.startsWith('http://') && !fullUrl.startsWith('https://'))
throw new Error(`Invald URL -- URL doesn't start with a http scheme: '${fullUrl}'`);
const parsedUrl = new URL(fullUrl);
Object.entries(ops?.query ?? {}).forEach(([k, v]) => {
parsedUrl.searchParams.set(k, v);
});
return parsedUrl.toString();
}