@samatawy/checks
v0.1.3
Published
Fluent TypeScript validation checks for objects, arrays, files, and images.
Downloads
388
Maintainers
Readme
@samatawy/checks
TypeScript validation utilities for fluent object, array, field, string, number, date, file, and image checks.
The package builds to both ESM and CommonJS, ships declaration files, and supports both synchronous and asynchronous validation flows.
Documentation
Where It Fits
This package is a good fit when validation is part of application logic instead of a one-off form helper.
Typical uses:
- data ingestion pipelines that need to validate imported records before persistence
- data quality audits that need both nested findings and flattened issue lists
- API boundary validation for request payloads, events, or jobs
- admin or back-office tooling that needs warnings and hints, not just hard failures
- file and image intake flows that need MIME, size, or dimension checks
Installation
npm install @samatawy/checksOptional peer dependencies
The core object, array, string, number, and date validators work with just the main package.
If you use FileCheck, ImageCheck, field.file(), or field.image(), also install the binary inspection peer dependencies:
npm install @samatawy/checks file-type probe-image-sizeWhy these are optional:
file-typeis used to detect MIME types from file buffersprobe-image-sizeis used for image metadata in Node runtimes- browser image dimension checks can also use browser-native APIs
Quick Start
import { ObjectCheck } from '@samatawy/checks';
const check = await ObjectCheck.for({
name: 'Sam',
age: 34,
address: {
city: 'Cairo'
}
})
.notEmpty()
.check(person => [
person.required('name').string().minLength(2),
person.optional('age').number().atLeast(18),
person.required('address').object().check(address => [
address.required('city').string()
])
]);
const result = check.result({ language: 'en' });
if (!result.valid) {
console.error(result.results);
}check, isTrue, checkEach, isTrueEach, file, and image may all become async depending on the validators you use, so await at the outer rule boundary is the safe default.
Getting Results
The package now uses result(options?) as the main output API.
For object and array checks:
result({ language })returns the merged nested result treeresult({ flattened: true, language })returns flattenedhints,warnings, anderrorsresult({ nested: true, language })returns an input-shaped projection underinputresult({ raw: true, nested: true, flattened: true, language })returns all projections at once
For value-level checks such as FieldCheck, StringCheck, or NumberCheck, result({ language }) returns the finalized single result.
Example:
const output = check.result({
raw: true,
nested: true,
flattened: true,
language: 'en'
});
console.log(output.raw);
console.log(output.input);
console.log(output.errors);Use result() with no options when you want the current internal result state while building advanced flows. For application-facing output, prefer explicit result options.
Public API
Everything is exported from the package root in src/index.ts.
Check classes
ObjectCheckFieldCheckArrayCheckArrayItemCheckStringCheckEmailCheckUrlCheckNumberCheckDateCheckFileCheckImageCheckValueCheck
Result and option types
CheckCheckOptionsStringCheckOptionsTolerantCheckOptionsIResultSingleResultResultSetResultCodeResultCodeDefinitionIResultCatalog
Catalog exports
ResultCatalogResultCatalog.global
Validation Model
The fluent API accumulates validation output while you compose rules.
required(name)asserts that a field existsoptional(name)starts a field check without requiring presenceconditional(name, condition)requires a field only when another condition is metnoExtraFields()rejects undeclared object keys in final object resultscheck(...)applies nested object or array rulescheckEach(...)applies nested rules to each array itemnoDuplicates()rejects duplicate array values or duplicate keys when you provide a selector keyisTrue(...)andisTrueEach(...)add custom predicatesfile()andimage()create asynchronously initialized binary validatorsemail()andurl()branch into specialized string validators
String-related inheritance:
StringCheck,EmailCheck, andUrlCheckshare common string comparison methods through the internalStringBaseCheckStringBaseCheckitself is not part of the public API
Coded Results
Stable result codes and translated output are supported, but they are optional. If you just need direct inline messages, you can ignore that layer entirely.
The dedicated guide is here:
File And Image Validation
import { ObjectCheck } from '@samatawy/checks';
const check = await ObjectCheck.for(input).check(person => [
person.optional('avatar').file().then(file =>
file.notEmpty()
.mimeType('image/*')
.minSize(5 * 1024)
.maxSize(5 * 1024 * 1024)
),
person.optional('avatar').image().then(image =>
image.isImage()
.minWidth(200)
.minHeight(200)
.maxWidth(2000)
.maxHeight(2000)
)
]);
const result = check.result({ flattened: true, language: 'en' });Development
npm install
npm run lint
npm test
npm run buildUseful scripts:
npm run buildbuilds ESM, CJS, and declaration files intodist/npm run devwatches the package entrypointnpm run lintruns TypeScript type checkingnpm testruns the Vitest suite oncenpm run test:watchruns Vitest in watch mode
When validating integration in this workspace, use the package build output from dist/ and then rebuild the local consumer package if it depends on file:../checks.
License
MIT
