$assert
The $assert tool provides type-safe validation using ArkType with detailed error reporting and standardized error codes. It's designed to validate data structures and return comprehensive error information when validation fails.
Features
- Type-safe validation using ArkType validators
- Detailed error reporting with specific error codes
- Schema extraction for debugging and error messages
- Integration with $code status codes
- Result pattern for consistent error handling
API Reference
$assert(value, validator)
Validates a value against an ArkType validator and returns a Result.
Parameters:
val: T- The value to validatevalidator: Type<unknown>- An ArkType validator/schema
Returns: Result<T> - Success with validated data or error with details
ts
import { type } from 'arktype'
import { $assert } from '#appkit/tools'
const userValidator = type({
name: "string",
email: "string.email",
age: "number>=0"
})
const result = $assert(userData, userValidator)
if (result.success) {
console.log('Valid user:', result.data)
} else {
console.error('Validation error:', result.error)
console.error('Expected schema:', result.context.expected)
console.error('Received:', result.context.got)
}Error Handling
The $assert function maps ArkType errors to specific validation error codes:
Error Code Mapping
| ArkType Error | Validation Code | Description |
|---|---|---|
pattern | validationPatternError | String pattern/regex validation failed |
union, unit, intersection | validationTypeError | Type mismatch errors |
min, max | validationRangeError | Numeric range validation failed |
minLength, maxLength, exactLength | validationLengthError | String/array length validation failed |
required | validationRequiredError | Required field is missing |
domain, divisor, proto, before, after, predicate | validationFormatError | Format/domain validation failed |
| Other errors | badRequest | Generic validation error |
Usage Examples
Basic Validation
ts
import { type } from 'arktype'
import { $assert } from '#appkit/tools'
// Simple string validation
const nameValidator = type("string>0")
const nameResult = $assert("John Doe", nameValidator)
// Email validation
const emailValidator = type("string.email")
const emailResult = $assert("user@example.com", emailValidator)
// Number range validation
const ageValidator = type("number>=18&<=120")
const ageResult = $assert(25, ageValidator)Complex Object Validation
ts
const productValidator = type({
id: "string",
name: "string>0",
price: "number>0",
category: "'electronics' | 'books' | 'clothing'",
"description?": "string",
tags: "string[]",
metadata: {
weight: "number>0",
dimensions: {
width: "number>0",
height: "number>0",
depth: "number>0"
}
}
})
const productData = {
id: "prod-123",
name: "Wireless Headphones",
price: 199.99,
category: "electronics",
tags: ["wireless", "bluetooth", "headphones"],
metadata: {
weight: 0.3,
dimensions: {
width: 15,
height: 20,
depth: 8
}
}
}
const result = $assert(productData, productValidator)
if (!result.success) {
// Handle specific error types
switch (result.code) {
case $code.validationRequiredError:
console.error('Missing required fields')
break
case $code.validationTypeError:
console.error('Invalid data types')
break
case $code.validationRangeError:
console.error('Values out of range')
break
default:
console.error('Validation failed:', result.error)
}
}Error Context Usage
ts
const userValidator = type({
username: "string>=3<=20",
email: "string.email",
age: "number>=13"
})
const invalidUser = {
username: "ab", // too short
email: "invalid-email", // invalid format
age: 10 // too young
}
const result = $assert(invalidUser, userValidator)
if (!result.success) {
console.log('Validation failed:', result.error)
console.log('Expected schema:', result.context.expected)
console.log('Received data:', result.context.got)
console.log('Error code:', result.code)
}Utility Functions
getValidationErrorCode(errors)
Maps ArkType errors to specific validation error codes.
Parameters:
errors: InstanceType<typeof arktype.errors>- ArkType validation errors
Returns: Specific $code error code
ts
import { getValidationErrorCode } from '#appkit/tools'
import { type } from 'arktype'
const validator = type("string.email")
const result = validator("invalid-email")
if (result instanceof type.errors) {
const errorCode = getValidationErrorCode(result)
console.log('Error code:', errorCode) // validationPatternError
}getArkValidatorSchema(schema)
Extracts the expected schema structure from an ArkType validator for debugging.
Parameters:
schema: Type- ArkType validator
Returns: Schema structure object
ts
import { getArkValidatorSchema } from '#appkit/tools'
import { type } from 'arktype'
const validator = type({
name: "string",
age: "number"
})
const schema = getArkValidatorSchema(validator)
console.log(schema) // { name: "string", age: "number" }Integration with Forms
The $assert tool works seamlessly with form validation:
ts
import { $assert } from '#appkit/tools'
import { type } from 'arktype'
const loginValidator = type({
email: "string.email",
password: "string>=8"
})
async function handleLogin(formData: unknown) {
const validation = $assert(formData, loginValidator)
if (!validation.success) {
// Return user-friendly error messages based on error code
switch (validation.code) {
case $code.validationPatternError:
return { error: 'Please enter a valid email address' }
case $code.validationLengthError:
return { error: 'Password must be at least 8 characters' }
case $code.validationRequiredError:
return { error: 'All fields are required' }
default:
return { error: 'Please check your input and try again' }
}
}
// Proceed with validated data
const { email, password } = validation.data
// ... login logic
}Best Practices
- Create Reusable Validators: Define common validators as constants
- Handle Specific Error Codes: Use the error code mapping for user-friendly messages
- Use Context Information: Leverage the expected/got context for debugging
- Type Safety: Let TypeScript infer the validated type from the validator
- Error Boundaries: Implement proper error handling for validation failures