VibORM

Schema Validation

Validate schema correctness before runtime

Schema Validation

VibORM includes a comprehensive validation system that checks your schema for errors before runtime.

Quick Start

import { validateSchemaOrThrow } from "viborm";

// Validate all models
validateSchemaOrThrow([user, post, comment]);

Validation Functions

validateSchema(models)

Returns a validation result with all errors:

import { validateSchema } from "viborm";

const result = validateSchema([user, post]);

if (!result.valid) {
  for (const error of result.errors) {
    console.log(`[${error.code}] ${error.model}: ${error.message}`);
  }
}

validateSchemaOrThrow(models)

Throws on the first error (useful for startup):

import { validateSchemaOrThrow } from "viborm";

// Throws if invalid
validateSchemaOrThrow([user, post]);

SchemaValidator Class

For custom validation:

import { SchemaValidator } from "viborm";

const validator = new SchemaValidator([user, post], {
  database: "postgres",  // Optional: enable DB-specific rules
});

const result = validator.validate();

Rule Categories

CodeCategoryDescription
M0xxModelBasic model structure
F0xxFieldField-level constraints
I0xxIndexIndex definitions
R0xxRelationRelation configuration
JT0xxJunctionMany-to-many tables
SR0xxSelf-refSelf-referential relations
CM0xxCross-modelCross-model dependencies
FK0xxForeign KeyFK field validation
RA0xxReferential ActiononDelete/onUpdate rules
DB0xxDatabaseDatabase-specific constraints

Model Rules (M0xx)

CodeRuleDescription
M001modelHasFieldsModel must have at least one field
M002modelUniqueNameModel names must be unique
M003modelNameValidModel name cannot be empty
M004modelNameNotReservedModel name cannot be SQL reserved word

Field Rules (F0xx)

CodeRuleDescription
F001noduplicateFieldsNo duplicate field names
F002modelHasIdModel must have exactly one ID (field or compound)
F003defaultTypeMatchDefault value must match field type
F004arrayFieldsSupportedArray fields only on supported DBs

Index Rules (I0xx)

CodeRuleDescription
I001indexFieldsExistIndex fields must exist in model
I002indexNameUniqueIndex names must be unique per model
I003compoundFieldsExistCompound ID/unique fields must exist

Relation Rules (R0xx)

CodeRuleDescription
R001relationTargetExistsRelation target model must exist
R002relationHasInverseBidirectional relations should have inverse
R003relationNameUniqueRelation names must be unique per model

Foreign Key Rules (FK0xx)

CodeRuleDescription
FK001fkFieldExistsFK field must exist in model
FK002fkReferenceExistsReferenced field must exist in target
FK003fkTypeMatchFK and reference types must match
FK004fkRequiredForOwningOwning side must have FK
FK005fkReferencesUniqueFK must reference unique field
FK006fkFieldNotRelationFK field cannot be a relation
FK007fkCardinalityMatchFK count must match relation cardinality

Referential Action Rules (RA0xx)

CodeRuleDescription
RA001onDeleteValidonDelete action must be valid
RA002onUpdateValidonUpdate action must be valid
RA003cascadeOnRequiredWarningWarning: CASCADE on required relation
RA004setNullRequiresNullableSET NULL requires nullable FK

Junction Table Rules (JT0xx)

CodeRuleDescription
JT001junctionTableUniqueJunction table names must be unique
JT002junctionFieldsValidJunction FK columns must be valid
JT003junctionFieldsDistinctA and B columns must be different
JT004selfRefJunctionOrderSelf-ref junction must have consistent order
JT005throughOnlyManyToMany.through() only on many-to-many

Self-Reference Rules (SR0xx)

CodeRuleDescription
SR001selfRefValidInverseSelf-ref must have valid inverse
SR002selfRefDistinctNamesSelf-ref relations must have distinct names

Cross-Model Rules (CM0xx)

CodeRuleDescription
CM001noOrphanFkFieldsFK fields should have relation
CM002relationPairFkSingleSideOnly one side should have FK
CM003polymorphicRelationWarningWarning for polymorphic pattern
CM004noCircularRequiredChainNo circular required relations

Database Rules (DB0xx)

CodeRuleDescription
DB001mysqlNoArrayFieldsMySQL doesn't support array fields
DB002sqliteNoEnumSQLite enum is stored as TEXT

Error Structure

interface ValidationError {
  code: string;        // e.g., "F002"
  severity: "error" | "warning";
  model: string;       // Model name
  field?: string;      // Field name (if applicable)
  message: string;     // Human-readable message
}

interface ValidationResult {
  valid: boolean;
  errors: ValidationError[];
}

Example Errors

const result = validateSchema([user, post]);

// Example errors:
// [F002] User: Model must have exactly one ID field
// [FK003] Post.authorId: FK type 'int' doesn't match reference type 'string'
// [RA004] Comment.postId: SET NULL requires nullable FK field

Best Practices

  1. Validate on startup — Catch errors early
  2. Use validateSchemaOrThrow — Fail fast in development
  3. Check warnings — Warnings may indicate issues
  4. Database-specific validation — Pass database option for DB rules

On this page