@speria-jp/json-schema-validator-gen
v0.3.2
Published
A lightweight JSON Schema validator generator that creates minimal TypeScript code and type definitions
Maintainers
Readme
json-schema-validator-gen
A lightweight JSON Schema validator generator that creates minimal TypeScript code and type definitions.
Features
- 🚀 Zero runtime dependencies - Generated validators are standalone
- 🔍 Type-safe - Full TypeScript support with generated type definitions
- ⚡ Fast validation - No runtime schema parsing, direct code execution
- 🌐 Universal - Works in Node.js and browsers
- 📋 Detailed errors - Rich error information with path, expected/received values
Installation
npm install -D @speria-jp/json-schema-validator-gen
# or
yarn add -D @speria-jp/json-schema-validator-gen
# or
pnpm add -D @speria-jp/json-schema-validator-gen
# or
bun add -D @speria-jp/json-schema-validator-genUsage
CLI
Basic usage:
# Generate from root schema (type name derived from file name)
npx @speria-jp/json-schema-validator-gen -s user-schema.json -o validator.ts
# Generate with custom type name
npx @speria-jp/json-schema-validator-gen -s schema.json -o validator.ts \
-t 'path=#,name=User'
# Generate from specific definition
npx @speria-jp/json-schema-validator-gen -s schema.json -o validator.ts \
-t '#/$defs/User'
# Generate multiple types with custom names
npx @speria-jp/json-schema-validator-gen -s schema.json -o types.ts \
-t 'path=#/$defs/User,name=AppUser' \
-t 'path=#/$defs/Post,name=BlogPost'If installed locally, you can also use your package manager directly:
# npm
npx json-schema-validator-gen -s schema.json -o validator.ts
# yarn
yarn json-schema-validator-gen -s schema.json -o validator.ts
# pnpm
pnpm json-schema-validator-gen -s schema.json -o validator.ts
# bun
bun json-schema-validator-gen -s schema.json -o validator.tsOptions:
-s, --schema- Path to JSON Schema file (required)-o, --output- Output path for generated code (required)-t, --target- JSON Schema target path (e.g.,#/$defs/User). Can be specified multiple times to generate multiple types. Supports custom type names withpath=...,name=...format. Defaults to#(root schema)-h, --help- Show help message
Programmatic API
import { generate } from '@speria-jp/json-schema-validator-gen';
// Generate from root schema (default, type name derived from file name)
const result = await generate({
schemaPath: './user-schema.json',
outputPath: './validator.ts'
});
// Generate from root with custom type name
const result = await generate({
schemaPath: './schema.json',
outputPath: './validator.ts',
targets: ['path=#,name=User']
});
// Generate from specific targets
const results = await generate({
schemaPath: './schema.json',
outputPath: './types.ts',
targets: ['#/$defs/User', '#/$defs/Post']
});
// Generate with custom type names
const results = await generate({
schemaPath: './schema.json',
outputPath: './types.ts',
targets: [
'path=#/$defs/User,name=AppUser',
'path=#/$defs/Post,name=BlogPost'
]
});Example
Given a JSON Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "User",
"required": ["id", "name", "email"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email",
"pattern": "^[\\w.-]+@[\\w.-]+\\.[a-z]{2,}$"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"role": {
"type": "string",
"enum": ["admin", "user", "guest"]
}
},
"additionalProperties": false
}The generator creates:
export type User = {
id: number;
name: string;
email: string;
age?: number;
tags?: string[];
role?: "admin" | "user" | "guest";
};
// Returns ValidationResult with detailed error information
export function validateUser(value: unknown, options?: ValidationOptions): ValidationResult<User> {
// ... validation logic
}
// Throws an error if validation fails, returns the validated value otherwise
export function unsafeValidateUser(value: unknown): User {
// ... validation logic
}Usage:
import { validateUser, unsafeValidateUser, type User } from './validator';
// Using validateUser - returns ValidationResult
const result = validateUser(data);
if (result.success) {
console.log('Valid user:', result.data);
} else {
console.log('Validation errors:', result.issues);
// Each issue contains: code, path, message, expected, received
}
// Using unsafeValidateUser - throws on invalid input
try {
const user = unsafeValidateUser(data);
console.log('Valid user:', user);
} catch (error) {
console.log('Validation failed:', error.message);
}
// Abort early option - stop on first error
const result = validateUser(data, { abortEarly: true });Multiple Types Example
You can generate multiple types from a single JSON Schema file using the --target option:
# Generate User and Post types from $defs (type names derived from path)
npx json-schema-validator-gen -s schema.json -o types.ts \
-t '#/$defs/User' -t '#/$defs/Post'Given a JSON Schema with $defs:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$defs": {
"Address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zipCode": { "type": "string" }
},
"required": ["street", "city"]
},
"User": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "$ref": "#/$defs/Address" }
},
"required": ["id", "name", "email"]
},
"Post": {
"type": "object",
"properties": {
"id": { "type": "string" },
"title": { "type": "string" },
"authorId": { "type": "string" }
},
"required": ["id", "title", "authorId"]
}
}
}The generator automatically collects dependencies and creates all necessary types in a single file. Note that Address is also generated because it's referenced by User, but it's not exported since it wasn't specified in --target:
// Address type (generated as dependency, not exported)
type Address = {
street: string;
city: string;
zipCode?: string;
};
// User type uses type reference instead of inline expansion
export type User = {
id: string;
name: string;
email: string;
address?: Address;
};
export type Post = {
id: string;
title: string;
authorId: string;
};
// Dependency validator (not exported)
function validateAddress(value: unknown): ValidationResult<Address> { /* ... */ }
// Exported validators for User and Post
export function validateUser(value: unknown): ValidationResult<User> { /* ... */ }
export function unsafeValidateUser(value: unknown): User { /* ... */ }
export function validatePost(value: unknown): ValidationResult<Post> { /* ... */ }
export function unsafeValidatePost(value: unknown): Post { /* ... */ }Validation Result
Generated validators return a ValidationResult<T> discriminated union:
type ValidationResult<T> =
| { success: true; data: T }
| { success: false; issues: ValidationIssue[] };
interface ValidationIssue {
code: ValidationIssueCode;
path: (string | number)[]; // e.g., ["address", "zipCode"] or ["items", 0]
message: string;
expected: string;
received: string;
}Error Codes
| Code | Description | Example |
|------|-------------|---------|
| invalid_type | Value has wrong type | Expected string, received number |
| missing_key | Required property is missing | Missing email property |
| too_small | Value below minimum | Number < minimum, string length < minLength |
| too_big | Value above maximum | Number > maximum, string length > maxLength |
| invalid_string | String doesn't match pattern | Email pattern mismatch |
| invalid_value | Value not in allowed set | Enum value not in list |
| not_integer | Number is not an integer | 25.5 instead of 25 |
| not_unique | Array has duplicate items | ["a", "a"] with uniqueItems: true |
| unrecognized_key | Unknown property | Extra property with additionalProperties: false |
Supported JSON Schema Features
- Basic types: string, number, integer, boolean, null, array, object
- Type constraints:
- Numbers: minimum, maximum
- Strings: minLength, maxLength, pattern, format
- Arrays: items validation
- Integers: proper integer validation
- Object validation: required properties, additionalProperties
- Array validation: items schema validation
- Enums and const values: Full enum support
- Union types: Full support for oneOf and anyOf with validation
- References: $ref support for local definitions (#/definitions/ and #/$defs/)
- Optional properties: Proper handling of required vs optional fields
Security Considerations
For general security considerations when working with JSON Schema validation, please refer to the Ajv Security Guidelines. While this tool generates code at build time rather than runtime, many of the same principles apply regarding input validation and schema design.
Development
# Install dependencies
bun install
# Run development CLI
bun run dev
# Build the project
bun run build
# Run tests
bun test
# Type checking
bun run typecheck
# Linting
bun run lint
bun run lint:fixLicense
MIT
