This example demonstrates how to write and register custom validation plugins that enforce constraints on JMAP requests before they are sent.
Create a .env file in the repo root or export these variables in your shell:
JMAP_BEARER_TOKEN=your-token
JMAP_HOSTNAME=api.fastmail.com
JMAP_LOG_LEVEL=info
Clone the jmap-kit repository, then from the repo root:
yarn tsx examples/validation-plugins/validation-plugins.ts
Core/echo invocation to include a "requestId" argumentCapabilityDefinition (no invocation factories, just the validator)Core/echo call without "requestId", catching and displaying the AggregateErrorCore/echo call with "requestId", showing the full pass/fail contrastA validation plugin has four parts:
const myValidator: ValidationPlugin<"invocation"> = {
name: "my-validator", // Unique identifier
hook: "invocation", // Lifecycle hook
trigger: {
// When to run
dataType: "Core",
method: "echo",
},
validate(context) {
// The validation logic
// Return { valid: true } or { valid: false, errors: [...] }
},
};
Validators can run at different points in the request pipeline:
| Hook | Runs | Context |
|---|---|---|
"invocation" |
Once per method call | Individual invocation |
"pre-build" |
Before request construction | Full JMAP request |
"pre-serialization" |
Before JSON serialisation | Full JMAP request |
"post-serialization" |
After JSON serialisation | Serialised body + headers |
For "invocation" hooks, the trigger filters which method calls the validator applies to:
capabilityUri — match by capability URIdataType — match by data type (e.g., "Core", "Email")method — match by method name (e.g., "echo", "get", "set")Omitted fields match any value (wildcard).
When validation fails, request.send() throws an AggregateError whose .errors array contains the individual validation errors:
try {
await request.send();
} catch (error) {
if (error instanceof AggregateError) {
for (const e of error.errors) {
console.error(e.message);
}
}
}
CapabilityDefinition. A capability can have just validators and no invocation factories.CoreCapability includes validators for maxObjectsInGet, maxObjectsInSet, maxCallsInRequest, and maxSizeRequest.