VibORM

Schema Validation

Comprehensive validation system that checks your schema for errors before runtime

Automatic Validation

CLI Validation

Schema validation runs automatically when using CLI commands like viborm push or viborm migrate. You don't need to call validation manually unless you want to validate at application startup.

Manual Validation

validateSchema(schema)

Returns a validation result with all errors and warnings:

import { validateSchema } from "viborm";
import * as schema from "./schema";

const result = validateSchema(schema);

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

// Also check warnings
for (const warning of result.warnings) {
  console.log(`[${warning.code}] Warning: ${warning.message}`);
}

validateSchemaOrThrow(schema)

Throws on the first error (useful for startup):

import { validateSchemaOrThrow } from "viborm";
import * as schema from "./schema";

// Throws if invalid
validateSchemaOrThrow(schema);

SchemaValidator Class

For custom validation with specific rules:

import { SchemaValidator, fkRules, relationRules } from "viborm";
import * as schema from "./schema";

const validator = new SchemaValidator()
  .registerAll(schema);

// Validate with all rules
const result = validator.validate();

// Or validate with specific rules only
const fkResult = validator.validate([...fkRules, ...relationRules]);

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";
  message: string;     // Human-readable message
  model?: string;      // Model name (if applicable)
  field?: string;      // Field name (if applicable)
  relation?: string;   // Relation name (if applicable)
}

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

Example Errors

import { validateSchema } from "viborm";
import * as schema from "./schema";

const result = validateSchema(schema);

// Example errors:
// [F002] Model 'user' 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. Let CLI validate — CLI commands validate automatically
  2. Validate on startup — Call validateSchemaOrThrow in production for early error detection
  3. Check warnings — Warnings may indicate potential issues
  4. Use specific rules — For performance, validate with only the rules you need

On this page