Skip to content

A lightweight code generator that creates zero-dependency, runtime validation functions and TypeScript types from a JSON schema.

Notifications You must be signed in to change notification settings

TyNorth/AssertScript

Repository files navigation

AssertScript

Build Status NPM Version License: MIT

A lightweight, zero-dependency, runtime validation library powered by code generation. Define your data shapes in a simple JSON file and AssertScript generates highly-optimized validation and sanitization functions, plus TypeScript definitions automatically.


Overview

AssertScript solves the problem of wanting type-safety in JavaScript without the overhead of a full TypeScript compilation step. It provides runtime guarantees that your data structures are correct, which is essential for validating API responses, form data, and function arguments.

The core workflow is simple:

  1. Define: You declare all your data shapes and rules in a single types.json file.
  2. Generate: Run the AssertScript Node.js script to automatically generate validators.js and validators.d.ts files.
  3. Assert or Validate: Import the generated functions into your application to perform fast, precise, and descriptive runtime validation.

Features

  • Zero Production Dependencies: The generated validation code is pure, vanilla JavaScript.
  • Dual-Mode Operation: Functions can fail-fast by throwing errors (assertion) or return a detailed result object (verbose validation).
  • Data Sanitization: Automatically cleans and transforms data (e.g., trims whitespace, converts strings to numbers) based on schema rules.
  • Rich Validation Rules: Go beyond simple typeof checks with powerful content-based rules.
  • TypeScript Declaration Generation: Get full autocompletion and type-checking in your editor (like VS Code) for free, even in a .js project.
  • Watch Mode: Automatically regenerates validators and types whenever your schema changes.
  • Robust CLI: A professional command-line interface for easy use.

Setup

  1. Install dependencies: This project uses a few development dependencies for code generation and testing.

    npm install
  2. Define Your Types: Edit the types.json file to define your data structures according to the guide below.

  3. Generate Validators: Run one of the following commands:

    # Generate validators once
    npm run generate
    
    # Generate validators and the .d.ts file for type-safety
    npm run generate:dts
    
    # Start watch mode for automatic regeneration on save
    npm run watch

Usage

Each validator can be used in two modes, chosen at runtime.

Assertion Mode (Default)

Ideal for backend services or critical paths where you want to fail fast. It throws a descriptive error on the first validation failure.

import { validateUser } from './validators.js'

const badUserData = { id: 1, username: 'a' } // Username is too short

try {
  validateUser(badUserData)
  // This line will not be reached
} catch (error) {
  console.error(error.message)
  // Output: "Validation failed for User.username: must be at least 3 characters long."
}

Verbose Mode

Pass { verbose: true } as the second argument. This mode never throws. It's perfect for UI form validation where you want to collect all errors at once.

The function returns an object: { isValid: boolean, errors: Array, value: object }.

import { validateUser } from './validators.js'

const formInput = { id: 1, username: 'a', email: 'bad-email' }
const result = validateUser(formInput, { verbose: true })

if (!result.isValid) {
  console.log('Please fix the following errors:')
  for (const err of result.errors) {
    // err is an object: { property: 'username', rule: 'minLength', message: '...' }
    console.log(`- ${err.property}: ${err.message}`)
  }
} else {
  // The 'value' property contains the cleaned and sanitized data
  const sanitizedUser = result.value
  // ... do something with the safe data
}

Schema Definition Guide (types.json)

This is the API for defining your data shapes.

Basic Types & Optional Properties

By default, all properties are required. Add a ? to a property name to make it optional.

"MyType": {
  "id": { "type": "number" },
  "name": { "type": "string" },
  "isActive": { "type": "boolean" },
  "notes?": { "type": "string" }
}

Nested Types (Composition)

Reference another type by using its name as the type.

"Product": {
  "productId": { "type": "string" },
  "seller": { "type": "Seller" }
}

Content Validation Rules

Rule Type Description
minLength string The minimum number of characters.
maxLength string The maximum number of characters.
pattern string A regular expression string the value must match.
min number The minimum numeric value.
max number The maximum numeric value.
enum string An array of specific string values that are allowed.
isInteger number Value must be a whole number.
startsWith string Value must start with the given substring.

Advanced Array Validation

You can specify rules for the array itself (minLength) and for the items within it.

"Product": {
  "tags": {
    "type": "array",
    "minLength": 1,
    "items": {
      "type": "string",
      "minLength": 2
    }
  }
}

Sanitization & Transformation

Use the transform array to clean and process data before it's validated.

Transform Description
trim Removes leading/trailing whitespace.
toLowerCase Converts the string to lowercase.
toUpperCase Converts the string to uppercase.
toInt Parses the value into an integer.

Example:

"User": {
  "username": {
    "type": "string",
    "minLength": 3,
    "transform": ["trim", "toLowerCase"]
  },
  "id_from_url": {
    "type": "string",
    "transform": ["toInt"]
  }
}

License

This project is licensed under the MIT License.

About

A lightweight code generator that creates zero-dependency, runtime validation functions and TypeScript types from a JSON schema.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published