Skip to main content

Validators

Sometimes you need more than per-field validation in an action and Validators associated with an action enables that.

export interface Validator<
TEnt extends Ent<TViewer>,
TBuilder extends Builder<TEnt, TViewer, TExistingEnt>,
TViewer extends Viewer = Viewer,
TInput extends Data = Data,
TExistingEnt extends TMaybleNullableEnt<TEnt> = MaybeNull<TEnt>,
> {
validate(builder: TBuilder, input: TInput): Promise<void> | void;
}

Each Validator takes the Builder and the Input.

For example, to validate that the start time is before the end time in the example schema

src/ent/event/actions/event_validators.ts
export class EventTimeValidator
implements Validator<Event, EventBuilder, Viewer, EventInput> {
validate(builder: EventBuilder): void {
const startTime = builder.getNewStartTimeValue();
const endTime = builder.getNewEndTimeValue();

if (!startTime) {
throw new Error("startTime required");
}

if (!endTime) {
// nothing to do here
return;
}

if (startTime.getTime() > endTime.getTime()) {
throw new Error("start time cannot be after end time");
}
}
}

and then update the actions as follows:

/src/ent/event/actions/create_event_action.ts
export default class CreateEventAction extends CreateEventActionBase {
getValidators() {
return [
new EventTimeValidator(),
];
}
}
/src/ent/event/actions/edit_event_action.ts
export default class EditEventAction extends EditEventActionBase {
getValidators() {
return [
new EventTimeValidator(),
];
}
}

so now when creating or editing an event, we'll ensure that the startTime (either new or existing) is before the endTime.

  const user = await getUser();

// throws error
await CreateEventAction.create(viewer, {
name: "fun event",
creatorID: user.id,
startTime: new Date('December 25, 2021'),
endTime: new Date('December 25, 2020'),
location: "location",
}).saveX();

// success
const event = await CreateEventAction.create(viewer, {
name: "fun event",
creatorID: user.id,
startTime: new Date('December 25, 2021'),
location: "location",
}).saveX();

// throws!
const event2 = await EditEventAction.create(viewer, event, {
endTime: new Date('December 25, 2020'),
}).saveX();