diff --git a/app/src/core/events/Event.ts b/app/src/core/events/Event.ts index 9defb4c4..009556b6 100644 --- a/app/src/core/events/Event.ts +++ b/app/src/core/events/Event.ts @@ -14,6 +14,10 @@ export abstract class Event { params: Params; returned: boolean = false; + /** + * Shallow validation of the event return + * It'll be deeply validated on the place where it is called + */ validate(value: Returning): Event | void { throw new EventReturnedWithoutValidation(this as any, value); } diff --git a/app/src/core/index.ts b/app/src/core/index.ts index 5c63a4b7..c1bce4db 100644 --- a/app/src/core/index.ts +++ b/app/src/core/index.ts @@ -27,6 +27,7 @@ export { export { Registry, type Constructor } from "./registry/Registry"; export * from "./console"; +export * from "./events"; // compatibility export type Middleware = MiddlewareHandler; diff --git a/app/src/data/entities/Entity.ts b/app/src/data/entities/Entity.ts index a59672fa..aade33f4 100644 --- a/app/src/data/entities/Entity.ts +++ b/app/src/data/entities/Entity.ts @@ -232,7 +232,7 @@ export class Entity< } for (const field of fields) { - if (!field.isValid(data[field.name], context)) { + if (!field.isValid(data?.[field.name], context)) { $console.warn( "invalid data given for", this.name, diff --git a/app/src/data/events/index.ts b/app/src/data/events/index.ts index b9d75599..85497506 100644 --- a/app/src/data/events/index.ts +++ b/app/src/data/events/index.ts @@ -1,4 +1,4 @@ -import type { PrimaryFieldType } from "core"; +import { $console, type PrimaryFieldType } from "core"; import { Event, InvalidEventReturn } from "core/events"; import type { Entity, EntityData } from "../entities"; import type { RepoQuery } from "../server/data-query-impl"; @@ -9,6 +9,10 @@ export class MutatorInsertBefore extends Event<{ entity: Entity; data: EntityDat override validate(data: EntityData) { const { entity } = this.params; if (!entity.isValidData(data, "create")) { + $console.warn("MutatorInsertBefore.validate: invalid", { + entity: entity.name, + data, + }); throw new InvalidEventReturn("EntityData", "invalid"); } @@ -36,13 +40,18 @@ export class MutatorUpdateBefore extends Event< static override slug = "mutator-update-before"; override validate(data: EntityData) { - const { entity, ...rest } = this.params; + const { entity, entityId } = this.params; if (!entity.isValidData(data, "update")) { + $console.warn("MutatorUpdateBefore.validate: invalid", { + entity: entity.name, + entityId, + data, + }); throw new InvalidEventReturn("EntityData", "invalid"); } return this.clone({ - ...rest, + entityId, entity, data, }); diff --git a/app/src/data/fields/Field.ts b/app/src/data/fields/Field.ts index 2b51edfb..cb1e47d3 100644 --- a/app/src/data/fields/Field.ts +++ b/app/src/data/fields/Field.ts @@ -185,12 +185,14 @@ export abstract class Field< }; } + // @todo: add field level validation isValid(value: any, context: TActionContext): boolean { - if (value) { + if (typeof value !== "undefined") { return this.isFillable(context); - } else { + } else if (context === "create") { return !this.isRequired(); } + return true; } /**