mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-02 08:06:00 +00:00
ca55503e66
* refactored core and core/utils imports * refactored core and core/utils imports * refactored media imports * refactored auth imports * refactored data imports * updated package json exports, fixed mm config * fix tests
147 lines
5.2 KiB
TypeScript
147 lines
5.2 KiB
TypeScript
import type { DB, EntityData, RepoQueryIn } from "bknd";
|
|
|
|
import type { Insertable, Selectable, Updateable } from "kysely";
|
|
import { type BaseModuleApiOptions, ModuleApi, type PrimaryFieldType } from "modules";
|
|
import type { FetchPromise, ResponseObject } from "modules/ModuleApi";
|
|
import type { RepositoryResultJSON } from "data/entities/query/RepositoryResult";
|
|
|
|
export type DataApiOptions = BaseModuleApiOptions & {
|
|
queryLengthLimit: number;
|
|
defaultQuery: Partial<RepoQueryIn>;
|
|
};
|
|
|
|
export class DataApi extends ModuleApi<DataApiOptions> {
|
|
protected override getDefaultOptions(): Partial<DataApiOptions> {
|
|
return {
|
|
basepath: "/api/data",
|
|
queryLengthLimit: 1000,
|
|
defaultQuery: {
|
|
limit: 10,
|
|
},
|
|
};
|
|
}
|
|
|
|
private requireObjectSet(obj: any, message?: string) {
|
|
if (!obj || typeof obj !== "object" || Object.keys(obj).length === 0) {
|
|
throw new Error(message ?? "object is required");
|
|
}
|
|
}
|
|
|
|
readOne<E extends keyof DB | string>(
|
|
entity: E,
|
|
id: PrimaryFieldType,
|
|
query: Omit<RepoQueryIn, "where" | "limit" | "offset"> = {},
|
|
) {
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.get<RepositoryResultJSON<Data>>(["entity", entity as any, id], query);
|
|
}
|
|
|
|
readOneBy<E extends keyof DB | string>(
|
|
entity: E,
|
|
query: Omit<RepoQueryIn, "limit" | "offset" | "sort"> = {},
|
|
) {
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
type T = RepositoryResultJSON<Data>;
|
|
return this.readMany(entity, {
|
|
...query,
|
|
limit: 1,
|
|
offset: 0,
|
|
}).refine((data) => data[0]) as unknown as FetchPromise<ResponseObject<T>>;
|
|
}
|
|
|
|
readMany<E extends keyof DB | string>(entity: E, query: RepoQueryIn = {}) {
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
type T = RepositoryResultJSON<Data[]>;
|
|
|
|
const input = query ?? this.options.defaultQuery;
|
|
const req = this.get<T>(["entity", entity as any], input);
|
|
|
|
if (req.request.url.length <= this.options.queryLengthLimit) {
|
|
return req;
|
|
}
|
|
|
|
return this.post<T>(["entity", entity as any, "query"], input);
|
|
}
|
|
|
|
readManyByReference<E extends keyof DB | string, R extends keyof DB | string>(
|
|
entity: E,
|
|
id: PrimaryFieldType,
|
|
reference: R,
|
|
query: RepoQueryIn = {},
|
|
) {
|
|
type Data = R extends keyof DB ? Selectable<DB[R]> : EntityData;
|
|
return this.get<RepositoryResultJSON<Data[]>>(
|
|
["entity", entity as any, id, reference],
|
|
query ?? this.options.defaultQuery,
|
|
);
|
|
}
|
|
|
|
createOne<E extends keyof DB | string, Input = E extends keyof DB ? DB[E] : EntityData>(
|
|
entity: E,
|
|
input: Insertable<Input>,
|
|
) {
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.post<RepositoryResultJSON<Data>>(["entity", entity as any], input);
|
|
}
|
|
|
|
createMany<E extends keyof DB | string, Input = E extends keyof DB ? DB[E] : EntityData>(
|
|
entity: E,
|
|
input: Insertable<Input>[],
|
|
) {
|
|
if (!input || !Array.isArray(input) || input.length === 0) {
|
|
throw new Error("input is required");
|
|
}
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.post<RepositoryResultJSON<Data[]>>(["entity", entity as any], input);
|
|
}
|
|
|
|
updateOne<E extends keyof DB | string, Input = E extends keyof DB ? DB[E] : EntityData>(
|
|
entity: E,
|
|
id: PrimaryFieldType,
|
|
input: Updateable<Input>,
|
|
) {
|
|
if (!id) throw new Error("ID is required");
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.patch<RepositoryResultJSON<Data>>(["entity", entity as any, id], input);
|
|
}
|
|
|
|
updateMany<E extends keyof DB | string, Input = E extends keyof DB ? DB[E] : EntityData>(
|
|
entity: E,
|
|
where: RepoQueryIn["where"],
|
|
update: Updateable<Input>,
|
|
) {
|
|
this.requireObjectSet(where);
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.patch<RepositoryResultJSON<Data[]>>(["entity", entity as any], {
|
|
update,
|
|
where,
|
|
});
|
|
}
|
|
|
|
deleteOne<E extends keyof DB | string>(entity: E, id: PrimaryFieldType) {
|
|
if (!id) throw new Error("ID is required");
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.delete<RepositoryResultJSON<Data>>(["entity", entity as any, id]);
|
|
}
|
|
|
|
deleteMany<E extends keyof DB | string>(entity: E, where: RepoQueryIn["where"]) {
|
|
this.requireObjectSet(where);
|
|
type Data = E extends keyof DB ? Selectable<DB[E]> : EntityData;
|
|
return this.delete<RepositoryResultJSON<Data>>(["entity", entity as any], where);
|
|
}
|
|
|
|
count<E extends keyof DB | string>(entity: E, where: RepoQueryIn["where"] = {}) {
|
|
return this.post<RepositoryResultJSON<{ entity: E; count: number }>>(
|
|
["entity", entity as any, "fn", "count"],
|
|
where,
|
|
);
|
|
}
|
|
|
|
exists<E extends keyof DB | string>(entity: E, where: RepoQueryIn["where"] = {}) {
|
|
return this.post<RepositoryResultJSON<{ entity: E; exists: boolean }>>(
|
|
["entity", entity as any, "fn", "exists"],
|
|
where,
|
|
);
|
|
}
|
|
}
|