Skip to content

Examples

const customerEntity = defineEntity({
name: "Customer",
fields: {
email: field.text({ trim: true, lowercase: true, required: true }),
},
});
export const Customers = {
slug: "customers",
fields: customerEntity.payload.all(),
};
await payload.create({
collection: "customers",
data: { email: " USER@EXAMPLE.COM " },
});

Payload lifecycle stores user@example.com; the same canonical transform is available at customerEntity.fields.email.schema.

const gallery = field.array({
minRows: 1,
fields: {
asset: field.upload({ relationTo: "media", required: true }),
alt: field.text({ trim: true, minLength: 3 }),
},
});

The consumer schema accepts { asset, alt } rows and rejects Payload’s internal row id. Payload compilation preserves row IDs during writes.

const target = field.relationship({
relationTo: ["pages", "posts"] as const,
hasMany: true,
});
target.schema.parse([
{ relationTo: "pages", value: "home" },
{ relationTo: "posts", value: 42 },
]);

Do not pass populated documents to this schema. Create a separate output schema for read projections.

console.log(productEntity.inspect());

Inspection reports field kind, Payload type, required/nullability, schema availability, relation metadata, currency, and nested blocking paths without exposing consumer values or functions.

The entity composition example is type-checked in CI: payload-schema.ts.