Skip to main content

Omission & Customization

Prisma Guard provides rich granularity to select, omit, and customize fields in your generated Zod schemas globally, at the model level, or down to individual fields.


Omission Levels

1. Global Omission

Define fields to exclude from all generated public schemas in your config file using zodOmit:

// prisma-guard.config.js
export default defineConfig({
zodOmit: ["password", "secret", "resetToken"],
});

Overriding Global Omission (@zod.include)

If you want to bypass the global zodOmit rule for a specific field in a single model, annotate that field with /// @zod.include:

model SpecialUser {
id String @id
/// @zod.include
password String // password will be included in the public schema despite global omission
}

2. Model Omission

To prevent the compiler from generating any Zod schemas or TypeScript types for a specific database model, add /// @zod.omit at the top of the model:

/// @zod.omit
model InternalLog {
id Int @id @default(autoincrement())
payload String
createdAt DateTime @default(now())
}

3. Model-Level Omit (@zod.omit(...))

To omit specific fields from only a single model's public schemas (while keeping them in intermediate scalar schemas), define the fields at the model header:

/// @zod.omit(password, salt)
model User {
id String @id
email String
password String
salt String
}

4. Field Omission

Exclude a single field from the generated public schema by adding /// @zod.omit directly above it:

model User {
id String @id
email String
/// @zod.omit
resetToken String?
}

Selection & Named Picks (@zod.pick)

Sometimes you want to keep only a specific set of fields in the validation schema.

1. Model-Level Pick

Use /// @zod.pick(...) at the model header. All other fields in the model will automatically be omitted from the public validation schemas:

/// @zod.pick(email, username)
model User {
id String @id
email String
username String
password String // Omitted from public schema
createdAt DateTime @default(now())
}

2. Named Picks (.as(<Alias>))

If you want to generate a secondary custom Zod schema and TypeScript types while keeping the main model validation schemas intact, use .as(AliasName):

/// @zod.omit(name)
/// @zod.pick(id, name, secret, createdAt).as(VerifySecret)
model Account {
id String @id
name String
/// @zod.omit
secret String
createdAt DateTime
}

[!IMPORTANT] Omission Bypassing: Fields explicitly listed in a named pick will bypass all local model-level omissions (@zod.omit(...)), local field-level omissions (/// @zod.omit), and global configuration omissions (omitIds, omitDates, and zodOmit). This ensures that your custom sub-schema contains exactly the fields you specified.

Generated Outputs: Because the main model Account has all of its fields omitted, no schemas or types are generated for it. However, the named pick will compile:

  • VerifySecretCreateSchema
  • VerifySecretUpdateSchema
  • TypeScript types VerifySecretCreate, VerifySecretUpdate, and scalar/required variants.

Handling Arrays

Prisma Guard automatically translates list fields into z.array() structures. For complex validations (such as verifying minimum/maximum array lengths), you can configure array decorators.

Option A: Inline Array Override

model Post {
/// @zod.z.array(z.string()).min(1).max(5)
tags String[]
}

Option B: Named Decorator

// prisma-guard.config.js
export default defineConfig({
decorators: {
tags: v.array(v.string()).min(1).max(5),
},
});
model Post {
/// @zod.use(tags)
tags String[]
}

Generated Zod Schema:

// generated/zod/post.ts
import { z } from "zod";

export const PostCreateSchema = z.object({
tags: z.array(z.string()).min(1).max(5),
});

Absolute Overrides vs. Decorators

It is important to choose the right decorator syntax based on whether you want to extend or replace default type translations:

  • Decorators (e.g. /// @zod.min(5)): Append validation methods to the default inferred Prisma type translation (e.g. z.string().trim().min(5)).
  • Absolute Overrides (e.g. /// @zod.z. or /// @zod.override): Replace the inferred schema definition completely.
model Example {
// ✅ Decorator: Appends .email() onto z.string().trim()
/// @zod.email()
email String

// ✅ Absolute Override: Replaces standard string mapping with a uuid validator
/// @zod.z.uuid()
token String
}

When to use Absolute Overrides

You must use an absolute override (/// @zod.z.) to configure:

  1. Coercion: Forcing type parsing (e.g. z.coerce.number()).
  2. Base Type Changes: Turning a String field into a z.enum() or z.any().
  3. Complex Structures: Implementing z.union(), z.record(), or z.lazy().

Custom Top-Level Imports (@zod.import)

If your inline validation checks rely on external validation logic, libraries, or schemas, inject imports at the top of the generated file using the @zod.import directive at the model level:

/// @zod.import { externalSchema } from "../../shared/schemas"
/// @zod.add customField: externalSchema
model User {
id String @id
}