npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cqrs-toolkit/schema

v0.1.0

Published

JSON Schema validation, registration, $id/$ref linking, and int64 hydration for event-sourced systems

Readme

@cqrs-toolkit/schema

JSON Schema validation, $id/$ref linking, and runtime value hydration for event-sourced systems.

Wraps AJV with automatic sub-schema discovery, composable $ref replacement, and a visitor-based hydration layer that converts validated string values into domain types (e.g., int64 strings to BigInt).

Install

npm install @cqrs-toolkit/schema ajv @meticoeus/ddd-es

ajv and @meticoeus/ddd-es are peer dependencies.

Entry Points

| Import | Purpose | | ---------------------------- | ----------------------------------------------------- | | @cqrs-toolkit/schema | Core API: validation, registry, visitors | | @cqrs-toolkit/schema/mocks | Test helpers: bootstrapTestAjv, prettyErrorResult |

Quick Start

Bootstrap

Initialize the global validatorProvider during application startup:

import { Ajv } from 'ajv'
import { validatorProvider, int64Visitor } from '@cqrs-toolkit/schema'

const ajv = new Ajv({ allErrors: true })
ajv.addFormat('int64', /^[0-9]+$/)

validatorProvider.setAjv(ajv, [int64Visitor])

Validate and Hydrate

parse() validates data against a JSON Schema, applies visitor hydrations, and returns a typed Result:

import type { JSONSchema7 } from 'json-schema'
import { validatorProvider } from '@cqrs-toolkit/schema'

const schema: JSONSchema7 = {
  type: 'object',
  required: ['name', 'position'],
  properties: {
    name: { type: 'string' },
    position: { type: 'string', format: 'int64' },
  },
}

const result = validatorProvider.parse<{ name: string; position: bigint }>(schema, {
  name: 'Alice',
  position: '42',
})

if (result.ok) {
  result.value.position // bigint(42) — automatically hydrated
} else {
  result.error.details // FieldError[]
}

One-Shot Validation

For schemas constructed at runtime that shouldn't be cached:

const result = validatorProvider.parseOnce<{ value: string }>(dynamicSchema, data)

Schema Registry

SchemaRegistry walks JSON Schema trees and:

  1. Discovers sub-schemas with $id attributes
  2. Registers them with AJV so they can be referenced
  3. Replaces inline definitions with $ref pointers for composition
  4. Computes hydration plans mapping visitor names to paths requiring conversion
import { SchemaRegistry, int64Visitor } from '@cqrs-toolkit/schema'
import { Ajv } from 'ajv'

const ajv = new Ajv()
const registry = new SchemaRegistry(ajv, [int64Visitor])

// Sub-schemas with $id are auto-discovered and shared across schemas
const addressSchema: JSONSchema7 = {
  $id: 'urn:schema:Address',
  type: 'object',
  properties: {
    street: { type: 'string' },
    zip: { type: 'string' },
  },
}

const personSchema: JSONSchema7 = {
  type: 'object',
  properties: {
    name: { type: 'string' },
    address: addressSchema, // replaced with { $ref: 'urn:schema:Address' }
  },
}

registry.register(personSchema)
// addressSchema is now registered in AJV and reusable

Custom Visitors

Visitors are plugins that match schema nodes and convert validated string values into domain types.

import type { SchemaVisitor } from '@cqrs-toolkit/schema'
import type { JSONSchema7 } from 'json-schema'

const dateVisitor: SchemaVisitor = {
  name: 'date',
  match(schema: JSONSchema7): boolean {
    return schema.type === 'string' && schema.format === 'date-time'
  },
  hydrate(value: string): Date | undefined {
    const d = new Date(value)
    return isNaN(d.getTime()) ? undefined : d
  },
}

// Register during bootstrap
validatorProvider.setAjv(ajv, [int64Visitor, dateVisitor])

The built-in int64Visitor converts { type: "string", format: "int64" } fields to BigInt.

Error Handling

Validation errors are returned as Result<T, SchemaException> — never thrown. SchemaException contains structured FieldError objects:

interface FieldError {
  readonly path: string // JSON pointer path (e.g., "/name")
  readonly code: string // error code (e.g., "required")
  readonly message: string // human-readable message
  readonly params: Record<string, unknown>
}

Test Helpers

The @cqrs-toolkit/schema/mocks entry point provides utilities for test setup:

import { bootstrapTestAjv, prettyErrorResult } from '@cqrs-toolkit/schema/mocks'

// Initialize validatorProvider with a test AJV instance + int64Visitor
bootstrapTestAjv()

// Format validation errors for readable test output
const result = validatorProvider.parse(schema, invalidData)
if (!result.ok) {
  console.log(prettyErrorResult(result))
}

API Reference

Full API documentation is generated from source and available at docs/api.

License

MIT