refactored mutator to listen for returned data from event listeners

This commit is contained in:
dswbx
2025-01-16 10:10:47 +01:00
parent 438e36f185
commit 6c9707d12c
7 changed files with 96 additions and 28 deletions

View File

@@ -192,10 +192,26 @@ export class Entity<
this.data = data;
}
// @todo: add tests
isValidData(data: EntityData, context: TActionContext, explain?: boolean): boolean {
if (typeof data !== "object") {
if (explain) {
throw new Error(`Entity "${this.name}" data must be an object`);
}
}
const fields = this.getFillableFields(context, false);
//const fields = this.fields;
//console.log("data", data);
const field_names = fields.map((f) => f.name);
const given_keys = Object.keys(data);
if (given_keys.some((key) => !field_names.includes(key))) {
if (explain) {
throw new Error(
`Entity "${this.name}" data must only contain known keys, got: "${given_keys}"`
);
}
}
for (const field of fields) {
if (!field.isValid(data[field.name], context)) {
console.log("Entity.isValidData:invalid", context, field.name, data[field.name]);

View File

@@ -132,14 +132,17 @@ export class Mutator<
throw new Error(`Creation of system entity "${entity.name}" is disabled`);
}
// @todo: establish the original order from "data"
const result = await this.emgr.emit(
new Mutator.Events.MutatorInsertBefore({ entity, data: data as any })
);
// if listener returned, take what's returned
const _data = result.returned ? result.params.data : data;
const validatedData = {
...entity.getDefaultObject(),
...(await this.getValidatedData(data, "create"))
...(await this.getValidatedData(_data, "create"))
};
await this.emgr.emit(new Mutator.Events.MutatorInsertBefore({ entity, data: validatedData }));
// check if required fields are present
const required = entity.getRequiredFields();
for (const field of required) {
@@ -169,16 +172,17 @@ export class Mutator<
throw new Error("ID must be provided for update");
}
const validatedData = await this.getValidatedData(data, "update");
await this.emgr.emit(
const result = await this.emgr.emit(
new Mutator.Events.MutatorUpdateBefore({
entity,
entityId: id,
data: validatedData as any
data
})
);
const _data = result.returned ? result.params.data : data;
const validatedData = await this.getValidatedData(_data, "update");
const query = this.conn
.updateTable(entity.name)
.set(validatedData as any)

View File

@@ -1,20 +1,48 @@
import type { PrimaryFieldType } from "core";
import { Event } from "core/events";
import { Event, InvalidEventReturn } from "core/events";
import type { Entity, EntityData } from "../entities";
import type { RepoQuery } from "../server/data-query-impl";
export class MutatorInsertBefore extends Event<{ entity: Entity; data: EntityData }> {
export class MutatorInsertBefore extends Event<{ entity: Entity; data: EntityData }, EntityData> {
static override slug = "mutator-insert-before";
override validate(data: EntityData) {
const { entity } = this.params;
if (!entity.isValidData(data, "create")) {
throw new InvalidEventReturn("EntityData", "invalid");
}
return this.clone({
entity,
data
});
}
}
export class MutatorInsertAfter extends Event<{ entity: Entity; data: EntityData }> {
static override slug = "mutator-insert-after";
}
export class MutatorUpdateBefore extends Event<{
entity: Entity;
entityId: PrimaryFieldType;
data: EntityData;
}> {
export class MutatorUpdateBefore extends Event<
{
entity: Entity;
entityId: PrimaryFieldType;
data: EntityData;
},
EntityData
> {
static override slug = "mutator-update-before";
override validate(data: EntityData) {
const { entity, ...rest } = this.params;
if (!entity.isValidData(data, "update")) {
throw new InvalidEventReturn("EntityData", "invalid");
}
return this.clone({
...rest,
entity,
data
});
}
}
export class MutatorUpdateAfter extends Event<{
entity: Entity;