Skip to content
VibORM
Esc
navigateopen⌘Jpreview
On this page

L3 - Operation Schemas

Validation schemas generated for where, create, update, and args operations

Location: src/validation/model/, src/validation/relations/

Why This Layer Exists

VibORM validates query inputs at runtime:

orm.user.findMany({
  where: { email: { contains: "@example.com" } },  // Validated!
  include: { posts: true },                         // Validated!
});

Operation schemas define what’s valid for each operation. They’re built dynamically by SchemaRegistry from model definitions.

Schema Categories

Core Schemas (Per Scalar)

Each scalar type generates its own schemas:

Schema Purpose Example
Base Raw input validation string or null
Filter Where clause operators { contains: string }
Create Create operation input Required unless defaulted
Update Update operation input Optional, can be null

Args Schemas (Per Model)

The validation registry composes scalar, relation, and model state into operation schemas:

Schema Purpose
WhereSchema Full where clause with all fields
CreateDataSchema Full data for create operations
UpdateDataSchema Full data for update operations
FindArgs where + select + include + orderBy
CreateArgs data with nested relation creates
UpdateArgs where + data with nested writes

Dynamic Schema Generation

Schemas are generated based on scalar state:

// If scalar is nullable + has default:
// - Filter: allows null comparisons
// - Create: optional (has default)  
// - Update: accepts null or value

The logic considers:

  • Is the scalar nullable?
  • Does it have a default value?
  • Is it an auto-generated scalar (UUID, timestamps)?
  • Is it optional vs required?

Handling Relations

Relations add complexity because queries can be nested:

orm.user.findMany({
  where: {
    posts: { some: { published: true } }  // Nested where
  },
  include: {
    posts: {
      where: { published: true },  // Nested filter
      select: { title: true }      // Nested select
    }
  }
});

Operation schemas handle this with recursive definitions using thunks to avoid infinite loops.

Why Registry Building?

Schemas are expensive to construct and nested relation inputs need full model graph context. VibORM builds them through SchemaRegistry:

const registry = createSchemaRegistry({ user });
registry.proxy.user.core.where; // Built through registry access, then cached

This keeps schema definitions focused on structure while operation validation stays centralized.

Connection to Other Layers

  • L1 (Validation): Operation schemas use v.* primitives and SchemaRegistry
  • L2 (Scalars): Scalar base schemas and state feed registry scalar schemas
  • L4 (Relations): Relation state feeds nested operation schemas
  • L6 (Query Engine): Query engine validates against these schemas

Was this page helpful?