mirror of
https://github.com/StepanovPlaton/jelly_belly_wiki.git
synced 2026-04-03 20:30:41 +04:00
09-07
This commit is contained in:
93
src/shared/utils/http.ts
Normal file
93
src/shared/utils/http.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export type RequestCacheOptions = {
|
||||
cache?: RequestCache;
|
||||
next?: NextFetchRequestConfig;
|
||||
};
|
||||
|
||||
type GetRequestOptions = RequestCacheOptions & {
|
||||
headers?: HeadersInit;
|
||||
};
|
||||
|
||||
type RequestOptions = GetRequestOptions & {
|
||||
body?: BodyInit | object;
|
||||
stringify?: boolean;
|
||||
};
|
||||
|
||||
export abstract class HTTPService {
|
||||
private static deepUndefinedToNull(o?: object): object | undefined {
|
||||
if (Array.isArray(o)) return o;
|
||||
if (o)
|
||||
return Object.fromEntries(
|
||||
Object.entries(o).map(([k, v]) => {
|
||||
if (v === undefined) return [k, null];
|
||||
if (typeof v === "object") return [k, this.deepUndefinedToNull(v)];
|
||||
return [k, v];
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public static async request<Z extends z.ZodTypeAny>(
|
||||
method: "GET" | "POST" | "PUT" | "DELETE",
|
||||
url: string,
|
||||
schema: Z,
|
||||
options?: RequestOptions
|
||||
) {
|
||||
return await fetch(process.env.NEXT_PUBLIC_API_URL + url, {
|
||||
method: method,
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
...((options?.stringify ?? true) != true
|
||||
? {}
|
||||
: { "Content-Type": "application/json" }),
|
||||
...options?.headers,
|
||||
},
|
||||
body:
|
||||
(options?.stringify ?? true) != true
|
||||
? (options?.body as BodyInit)
|
||||
: JSON.stringify(
|
||||
this.deepUndefinedToNull(options?.body as object | undefined)
|
||||
),
|
||||
cache: options?.cache ?? options?.next ? undefined : "no-cache",
|
||||
next: options?.next ?? {},
|
||||
})
|
||||
.then((r) => {
|
||||
if (r && r.ok) return r;
|
||||
else throw Error("Response ok = false");
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.then((d) => {
|
||||
const parsed = schema.safeParse(d);
|
||||
if (parsed.success) return parsed.data as z.infer<Z>;
|
||||
else throw new Error(parsed.error.message);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public static async get<Z extends z.ZodTypeAny>(
|
||||
url: string,
|
||||
schema: Z,
|
||||
options?: GetRequestOptions
|
||||
) {
|
||||
return await this.request<Z>("GET", url, schema, options);
|
||||
}
|
||||
|
||||
public static async post<Z extends z.ZodTypeAny>(
|
||||
url: string,
|
||||
schema: Z,
|
||||
options?: RequestOptions
|
||||
) {
|
||||
return await this.request<Z>("POST", url, schema, options);
|
||||
}
|
||||
|
||||
public static async put<Z extends z.ZodType>(
|
||||
url: string,
|
||||
schema: Z,
|
||||
options?: RequestOptions
|
||||
) {
|
||||
return await this.request<Z>("PUT", url, schema, options);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user