update & fix typing, updated examples

This commit is contained in:
dswbx
2024-12-23 19:28:31 +01:00
parent 70e42a02d7
commit c1e92e503b
21 changed files with 126 additions and 139 deletions

View File

@@ -11,7 +11,7 @@ import { Module } from "modules/Module";
import { DataController } from "./api/DataController";
import { type AppDataConfig, dataConfigSchema } from "./data-schema";
export class AppData<DB> extends Module<typeof dataConfigSchema> {
export class AppData extends Module<typeof dataConfigSchema> {
override async build() {
const entities = transformObject(this.config.entities ?? {}, (entityConfig, name) => {
return constructEntity(name, entityConfig);
@@ -59,7 +59,7 @@ export class AppData<DB> extends Module<typeof dataConfigSchema> {
return dataConfigSchema;
}
get em(): EntityManager<DB> {
get em(): EntityManager {
this.throwIfNotBuilt();
return this.ctx.em;
}

View File

@@ -1,3 +1,4 @@
import type { DB } from "core";
import type { EntityData, RepoQuery, RepositoryResponse } from "data";
import { type BaseModuleApiOptions, ModuleApi, type PrimaryFieldType } from "modules";
@@ -5,7 +6,7 @@ export type DataApiOptions = BaseModuleApiOptions & {
defaultQuery?: Partial<RepoQuery>;
};
export class DataApi<DB> extends ModuleApi<DataApiOptions> {
export class DataApi extends ModuleApi<DataApiOptions> {
protected override getDefaultOptions(): Partial<DataApiOptions> {
return {
basepath: "/api/data",

View File

@@ -1,3 +1,4 @@
import type { DB as DefaultDB } from "core";
import { EventManager } from "core/events";
import { sql } from "kysely";
import { Connection } from "../connection/Connection";
@@ -14,15 +15,18 @@ import { SchemaManager } from "../schema/SchemaManager";
import { Entity } from "./Entity";
import { type EntityData, Mutator, Repository } from "./index";
type EntitySchema<E extends Entity | string, DB = any> = E extends Entity<infer Name>
? Name extends keyof DB
type EntitySchema<
TBD extends object = DefaultDB,
E extends Entity | keyof TBD | string = string
> = E extends Entity<infer Name>
? Name extends keyof TBD
? Name
: never
: E extends keyof DB
: E extends keyof TBD
? E
: never;
export class EntityManager<DB> {
export class EntityManager<TBD extends object = DefaultDB> {
connection: Connection;
private _entities: Entity[] = [];
@@ -58,7 +62,7 @@ export class EntityManager<DB> {
* Forks the EntityManager without the EventManager.
* This is useful when used inside an event handler.
*/
fork(): EntityManager<DB> {
fork(): EntityManager {
return new EntityManager(this._entities, this.connection, this._relations, this._indices);
}
@@ -95,16 +99,17 @@ export class EntityManager<DB> {
this.entities.push(entity);
}
entity(e: Entity | string): Entity {
entity(e: Entity | keyof TBD | string): Entity {
let entity: Entity | undefined;
if (typeof e === "string") {
entity = this.entities.find((entity) => entity.name === e);
} else {
} else if (e instanceof Entity) {
entity = e;
}
if (!entity) {
throw new EntityNotDefinedException(typeof e === "string" ? e : e.name);
// @ts-ignore
throw new EntityNotDefinedException(e instanceof Entity ? e.name : e);
}
return entity;
@@ -176,15 +181,17 @@ export class EntityManager<DB> {
return this.relations.relationReferencesOf(this.entity(entity_name));
}
repository<E extends Entity | string>(entity: E): Repository<DB, EntitySchema<E, DB>> {
repository<E extends Entity | keyof TBD | string>(
entity: E
): Repository<TBD, EntitySchema<TBD, E>> {
return this.repo(entity);
}
repo<E extends Entity | string>(entity: E): Repository<DB, EntitySchema<E, DB>> {
repo<E extends Entity | keyof TBD | string>(entity: E): Repository<TBD, EntitySchema<TBD, E>> {
return new Repository(this, this.entity(entity), this.emgr);
}
mutator<E extends Entity | string>(entity: E): Mutator<DB, EntitySchema<E, DB>> {
mutator<E extends Entity | keyof TBD | string>(entity: E): Mutator<TBD, EntitySchema<TBD, E>> {
return new Mutator(this, this.entity(entity), this.emgr);
}

View File

@@ -1,4 +1,4 @@
import type { PrimaryFieldType } from "core";
import type { DB as DefaultDB, PrimaryFieldType } from "core";
import { type EmitsEvents, EventManager } from "core/events";
import type { DeleteQueryBuilder, InsertQueryBuilder, UpdateQueryBuilder } from "kysely";
import { type TActionContext, WhereBuilder } from "..";
@@ -26,13 +26,13 @@ export type MutatorResponse<T = EntityData[]> = {
};
export class Mutator<
DB = any,
TB extends keyof DB = any,
Output = DB[TB],
TBD extends object = DefaultDB,
TB extends keyof TBD = any,
Output = TBD[TB],
Input = Omit<Output, "id">
> implements EmitsEvents
{
em: EntityManager<DB>;
em: EntityManager<TBD>;
entity: Entity;
static readonly Events = MutatorEvents;
emgr: EventManager<typeof MutatorEvents>;
@@ -43,7 +43,7 @@ export class Mutator<
this.__unstable_disable_system_entity_creation = value;
}
constructor(em: EntityManager<DB>, entity: Entity, emgr?: EventManager<any>) {
constructor(em: EntityManager<TBD>, entity: Entity, emgr?: EventManager<any>) {
this.em = em;
this.entity = entity;
this.emgr = emgr ?? new EventManager(MutatorEvents);
@@ -163,7 +163,7 @@ export class Mutator<
return res as any;
}
async updateOne(id: PrimaryFieldType, data: Input): Promise<MutatorResponse<Output>> {
async updateOne(id: PrimaryFieldType, data: Partial<Input>): Promise<MutatorResponse<Output>> {
const entity = this.entity;
if (!Number.isInteger(id)) {
throw new Error("ID must be provided for update");
@@ -270,7 +270,10 @@ export class Mutator<
return (await this.many(qb)) as any;
}
async updateWhere(data: Partial<Input>, where?: RepoQuery["where"]): Promise<MutatorResponse<Output[]>> {
async updateWhere(
data: Partial<Input>,
where?: RepoQuery["where"]
): Promise<MutatorResponse<Output[]>> {
const entity = this.entity;
const validatedData = await this.getValidatedData(data, "update");

View File

@@ -1,4 +1,4 @@
import type { PrimaryFieldType } from "core";
import type { DB as DefaultDB, PrimaryFieldType } from "core";
import { type EmitsEvents, EventManager } from "core/events";
import { type SelectQueryBuilder, sql } from "kysely";
import { cloneDeep } from "lodash-es";
@@ -43,13 +43,15 @@ export type RepositoryExistsResponse = RepositoryRawResponse & {
exists: boolean;
};
export class Repository<DB = any, TB extends keyof DB = any> implements EmitsEvents {
em: EntityManager<DB>;
export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = any>
implements EmitsEvents
{
em: EntityManager<TBD>;
entity: Entity;
static readonly Events = RepositoryEvents;
emgr: EventManager<typeof Repository.Events>;
constructor(em: EntityManager<DB>, entity: Entity, emgr?: EventManager<any>) {
constructor(em: EntityManager<TBD>, entity: Entity, emgr?: EventManager<any>) {
this.em = em;
this.entity = entity;
this.emgr = emgr ?? new EventManager(MutatorEvents);
@@ -272,7 +274,7 @@ export class Repository<DB = any, TB extends keyof DB = any> implements EmitsEve
async findId(
id: PrimaryFieldType,
_options?: Partial<Omit<RepoQuery, "where" | "limit" | "offset">>
): Promise<RepositoryResponse<DB[TB] | undefined>> {
): Promise<RepositoryResponse<TBD[TB] | undefined>> {
const { qb, options } = this.buildQuery(
{
..._options,
@@ -288,7 +290,7 @@ export class Repository<DB = any, TB extends keyof DB = any> implements EmitsEve
async findOne(
where: RepoQuery["where"],
_options?: Partial<Omit<RepoQuery, "where" | "limit" | "offset">>
): Promise<RepositoryResponse<DB[TB] | undefined>> {
): Promise<RepositoryResponse<TBD[TB] | undefined>> {
const { qb, options } = this.buildQuery({
..._options,
where,
@@ -298,7 +300,7 @@ export class Repository<DB = any, TB extends keyof DB = any> implements EmitsEve
return this.single(qb, options) as any;
}
async findMany(_options?: Partial<RepoQuery>): Promise<RepositoryResponse<DB[TB][]>> {
async findMany(_options?: Partial<RepoQuery>): Promise<RepositoryResponse<TBD[TB][]>> {
const { qb, options } = this.buildQuery(_options);
//console.log("findMany:options", options);