mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2024-11-24 17:30:59 -05:00
Made fetch
-related utils for testing purposes
This commit is contained in:
parent
750c0028b0
commit
7fec30e288
1 changed files with 87 additions and 0 deletions
87
tests/utils/fetch-utils.ts
Normal file
87
tests/utils/fetch-utils.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
import { readFile } from "node:fs/promises";
|
||||
import { existsSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { Fetch, HttpMethod, HttpRequest, HttpResponse, createFetch } from "@/utils/net";
|
||||
|
||||
type FetchInterceptorResponse = string | string[] | HttpResponse | unknown;
|
||||
|
||||
type FetchInterceptorHandler = (args: string[], request: HttpRequest, url: string) => FetchInterceptorResponse | Promise<FetchInterceptorResponse>;
|
||||
|
||||
type FetchInterceptor = {
|
||||
baseUrl?: string;
|
||||
|
||||
requiredHeaders?: string[];
|
||||
} & {
|
||||
[Method in HttpMethod]?: {
|
||||
[url: string]: FetchInterceptorHandler;
|
||||
};
|
||||
};
|
||||
|
||||
const FAKE_FETCH: Fetch = (url, request) => Promise.reject(
|
||||
new Error(`Unsupported request: '${normalizeHttpMethod(request?.method)} ${url}'`)
|
||||
);
|
||||
|
||||
function normalizeHttpMethod(method: string): HttpMethod {
|
||||
return (method?.toUpperCase() as HttpMethod) || "GET";
|
||||
}
|
||||
|
||||
async function normalizeResponse(response: FetchInterceptorResponse): Promise<HttpResponse> {
|
||||
if (typeof response === "string") {
|
||||
return HttpResponse.text(response);
|
||||
}
|
||||
|
||||
if (Array.isArray(response) && response.length && response.every(x => typeof x === "string")) {
|
||||
const path = resolve(...response);
|
||||
if (existsSync(path)) {
|
||||
const content = await readFile(path, "utf8");
|
||||
return HttpResponse.text(content);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof response["url"] === "string" && typeof response["blob"] === "function") {
|
||||
return response as HttpResponse;
|
||||
}
|
||||
|
||||
return HttpResponse.json(response);
|
||||
}
|
||||
|
||||
export function createFakeFetch(interceptor: FetchInterceptor): Fetch {
|
||||
const baseUrl = interceptor.baseUrl?.endsWith("/") ? interceptor.baseUrl.slice(0, -1) : (interceptor.baseUrl || "");
|
||||
const requiredHeaders = interceptor.requiredHeaders || [];
|
||||
const methods = interceptor;
|
||||
|
||||
return createFetch({ handler: FAKE_FETCH }).use(async (url, request, next) => {
|
||||
url = String(url);
|
||||
const urlPath = url.startsWith(baseUrl) ? url.substring(baseUrl.length) : url;
|
||||
|
||||
const handlerEntry = Object.entries(methods[normalizeHttpMethod(request?.method)] || {})
|
||||
.map(([urlMatcher, handler]) => [urlPath.match(urlMatcher), handler] as const)
|
||||
.find(([match]) => match !== null);
|
||||
|
||||
if (!handlerEntry || !requiredHeaders.every(header => request?.headers?.[header])) {
|
||||
return await next(url, request);
|
||||
}
|
||||
|
||||
const args = handlerEntry[0].slice(1);
|
||||
const response = await handlerEntry[1](args, request, url);
|
||||
return await normalizeResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
export function createCombinedFetch(...fetchComponents: Fetch[]): Fetch {
|
||||
const handlers = [...fetchComponents].reverse();
|
||||
|
||||
return async (url, request) => {
|
||||
for (let i = handlers.length - 1; i >= 0; i--) {
|
||||
try {
|
||||
return await handlers[i](url, request);
|
||||
} catch (error: unknown) {
|
||||
if (i === 0) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HttpResponse.error();
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue