mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 20:37:21 +00:00
updated admin to use swr hooks instead of react-query
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { PrimaryFieldType } from "core";
|
||||
import { type PrimaryFieldType, isDebug } from "core";
|
||||
import { encodeSearch } from "core/utils";
|
||||
|
||||
export type { PrimaryFieldType };
|
||||
@@ -10,6 +10,7 @@ export type BaseModuleApiOptions = {
|
||||
token_transport?: "header" | "cookie" | "none";
|
||||
};
|
||||
|
||||
/** @deprecated */
|
||||
export type ApiResponse<Data = any> = {
|
||||
success: boolean;
|
||||
status: number;
|
||||
@@ -47,7 +48,7 @@ export abstract class ModuleApi<Options extends BaseModuleApiOptions = BaseModul
|
||||
_input: TInput,
|
||||
_query?: Record<string, any> | URLSearchParams,
|
||||
_init?: RequestInit
|
||||
): FetchPromise<ApiResponse<Data>> {
|
||||
): FetchPromise<ResponseObject<Data>> {
|
||||
const method = _init?.method ?? "GET";
|
||||
const input = Array.isArray(_input) ? _input.join("/") : _input;
|
||||
let url = this.getUrl(input);
|
||||
@@ -138,6 +139,58 @@ export abstract class ModuleApi<Options extends BaseModuleApiOptions = BaseModul
|
||||
}
|
||||
}
|
||||
|
||||
export type ResponseObject<Body = any, Data = Body extends { data: infer R } ? R : Body> = Data & {
|
||||
raw: Response;
|
||||
res: Response;
|
||||
data: Data;
|
||||
body: Body;
|
||||
ok: boolean;
|
||||
status: number;
|
||||
toJSON(): Data;
|
||||
};
|
||||
|
||||
export function createResponseProxy<Body = any, Data = any>(
|
||||
raw: Response,
|
||||
body: Body,
|
||||
data?: Data
|
||||
): ResponseObject<Body, Data> {
|
||||
const actualData = data ?? (body as unknown as Data);
|
||||
const _props = ["raw", "body", "ok", "status", "res", "data", "toJSON"];
|
||||
|
||||
return new Proxy(actualData as any, {
|
||||
get(target, prop, receiver) {
|
||||
if (prop === "raw" || prop === "res") return raw;
|
||||
if (prop === "body") return body;
|
||||
if (prop === "data") return data;
|
||||
if (prop === "ok") return raw.ok;
|
||||
if (prop === "status") return raw.status;
|
||||
if (prop === "toJSON") {
|
||||
return () => target;
|
||||
}
|
||||
return Reflect.get(target, prop, receiver);
|
||||
},
|
||||
has(target, prop) {
|
||||
if (_props.includes(prop as string)) {
|
||||
return true;
|
||||
}
|
||||
return Reflect.has(target, prop);
|
||||
},
|
||||
ownKeys(target) {
|
||||
return Array.from(new Set([...Reflect.ownKeys(target), ..._props]));
|
||||
},
|
||||
getOwnPropertyDescriptor(target, prop) {
|
||||
if (_props.includes(prop as string)) {
|
||||
return {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: Reflect.get({ raw, body, ok: raw.ok, status: raw.status }, prop)
|
||||
};
|
||||
}
|
||||
return Reflect.getOwnPropertyDescriptor(target, prop);
|
||||
}
|
||||
}) as ResponseObject<Body, Data>;
|
||||
}
|
||||
|
||||
export class FetchPromise<T = ApiResponse<any>> implements Promise<T> {
|
||||
// @ts-ignore
|
||||
[Symbol.toStringTag]: "FetchPromise";
|
||||
@@ -149,7 +202,10 @@ export class FetchPromise<T = ApiResponse<any>> implements Promise<T> {
|
||||
}
|
||||
) {}
|
||||
|
||||
async execute(): Promise<T> {
|
||||
async execute(): Promise<ResponseObject<T>> {
|
||||
// delay in dev environment
|
||||
isDebug() && (await new Promise((resolve) => setTimeout(resolve, 200)));
|
||||
|
||||
const fetcher = this.options?.fetcher ?? fetch;
|
||||
const res = await fetcher(this.request);
|
||||
let resBody: any;
|
||||
@@ -165,13 +221,7 @@ export class FetchPromise<T = ApiResponse<any>> implements Promise<T> {
|
||||
resBody = await res.text();
|
||||
}
|
||||
|
||||
return {
|
||||
success: res.ok,
|
||||
status: res.status,
|
||||
body: resBody,
|
||||
data: resData,
|
||||
res
|
||||
} as T;
|
||||
return createResponseProxy<T>(res, resBody, resData);
|
||||
}
|
||||
|
||||
// biome-ignore lint/suspicious/noThenProperty: it's a promise :)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ConfigUpdateResponse } from "modules/server/SystemController";
|
||||
import { ModuleApi } from "./ModuleApi";
|
||||
import type { ModuleConfigs, ModuleKey, ModuleSchemas } from "./ModuleManager";
|
||||
|
||||
@@ -15,37 +16,37 @@ export class SystemApi extends ModuleApi<any> {
|
||||
};
|
||||
}
|
||||
|
||||
async readSchema(options?: { config?: boolean; secrets?: boolean }) {
|
||||
return await this.get<ApiSchemaResponse>("schema", {
|
||||
readSchema(options?: { config?: boolean; secrets?: boolean }) {
|
||||
return this.get<ApiSchemaResponse>("schema", {
|
||||
config: options?.config ? 1 : 0,
|
||||
secrets: options?.secrets ? 1 : 0
|
||||
});
|
||||
}
|
||||
|
||||
async setConfig<Module extends ModuleKey>(
|
||||
setConfig<Module extends ModuleKey>(
|
||||
module: Module,
|
||||
value: ModuleConfigs[Module],
|
||||
force?: boolean
|
||||
) {
|
||||
return await this.post<any>(
|
||||
return this.post<ConfigUpdateResponse>(
|
||||
["config", "set", module].join("/") + `?force=${force ? 1 : 0}`,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
async addConfig<Module extends ModuleKey>(module: Module, path: string, value: any) {
|
||||
return await this.post<any>(["config", "add", module, path], value);
|
||||
addConfig<Module extends ModuleKey>(module: Module, path: string, value: any) {
|
||||
return this.post<ConfigUpdateResponse>(["config", "add", module, path], value);
|
||||
}
|
||||
|
||||
async patchConfig<Module extends ModuleKey>(module: Module, path: string, value: any) {
|
||||
return await this.patch<any>(["config", "patch", module, path], value);
|
||||
patchConfig<Module extends ModuleKey>(module: Module, path: string, value: any) {
|
||||
return this.patch<ConfigUpdateResponse>(["config", "patch", module, path], value);
|
||||
}
|
||||
|
||||
async overwriteConfig<Module extends ModuleKey>(module: Module, path: string, value: any) {
|
||||
return await this.put<any>(["config", "overwrite", module, path], value);
|
||||
overwriteConfig<Module extends ModuleKey>(module: Module, path: string, value: any) {
|
||||
return this.put<ConfigUpdateResponse>(["config", "overwrite", module, path], value);
|
||||
}
|
||||
|
||||
async removeConfig<Module extends ModuleKey>(module: Module, path: string) {
|
||||
return await this.delete<any>(["config", "remove", module, path]);
|
||||
removeConfig<Module extends ModuleKey>(module: Module, path: string) {
|
||||
return this.delete<ConfigUpdateResponse>(["config", "remove", module, path]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
/// <reference types="@cloudflare/workers-types" />
|
||||
|
||||
import type { App } from "App";
|
||||
import type { ClassController } from "core";
|
||||
import { tbValidator as tb } from "core";
|
||||
import { StringEnum, Type, TypeInvalidError } from "core/utils";
|
||||
import { type Context, Hono } from "hono";
|
||||
import { MODULE_NAMES, type ModuleKey, getDefaultConfig } from "modules/ModuleManager";
|
||||
import {
|
||||
MODULE_NAMES,
|
||||
type ModuleConfigs,
|
||||
type ModuleKey,
|
||||
getDefaultConfig
|
||||
} from "modules/ModuleManager";
|
||||
import * as SystemPermissions from "modules/permissions";
|
||||
import { generateOpenAPI } from "modules/server/openapi";
|
||||
import type { App } from "../../App";
|
||||
|
||||
const booleanLike = Type.Transform(Type.String())
|
||||
.Decode((v) => v === "1")
|
||||
.Encode((v) => (v ? "1" : "0"));
|
||||
|
||||
export type ConfigUpdate<Key extends ModuleKey = ModuleKey> = {
|
||||
success: true;
|
||||
module: Key;
|
||||
config: ModuleConfigs[Key];
|
||||
};
|
||||
export type ConfigUpdateResponse<Key extends ModuleKey = ModuleKey> =
|
||||
| ConfigUpdate<Key>
|
||||
| { success: false; type: "type-invalid" | "error" | "unknown"; error?: any; errors?: any };
|
||||
|
||||
export class SystemController implements ClassController {
|
||||
constructor(private readonly app: App) {}
|
||||
|
||||
@@ -60,7 +74,7 @@ export class SystemController implements ClassController {
|
||||
}
|
||||
);
|
||||
|
||||
async function handleConfigUpdateResponse(c: Context<any>, cb: () => Promise<object>) {
|
||||
async function handleConfigUpdateResponse(c: Context<any>, cb: () => Promise<ConfigUpdate>) {
|
||||
try {
|
||||
return c.json(await cb(), { status: 202 });
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user