Detailed English documentation is in this file. Turkish documentation is available in README.tr.md.
validare is a TypeScript and JavaScript validation library designed around named JSON schemas, direct schema objects, Express middleware, and browser-side form validation.
At a high level, the system does four things:
- Loads validation schemas and message files.
- Resolves a schema either by name or from an inline object.
- Executes a type-specific validation pipeline.
- Returns a structured status object with an error key, reason, original value, and optional message.
The repository supports two runtime styles:
- Node.js and Express validation through
validationConfig,validator,Schema,validateFields, andvalidateSwitch. - Browser validation through the bundled
dist/validare-web.js, remote JSON schema loading, and DOM auto-validation for inputs withdata-validate.
The public entrypoint re-exports the following symbols:
| Export | Purpose |
|---|---|
schema |
Type-only export describing supported schema shapes. |
Schema |
Wrapper class around a schema object. Provides validate, create_id, and random. |
validationConfig |
Initializes runtime schema and message loading for Node.js usage. |
validator |
Core validation function. Accepts a schema object or schema name and returns a Status. |
ID |
Alias for create_id. Generates IDs from string schema settings. |
validateFields |
Express middleware builder for validating multiple request or response fields. |
validateSwitch |
Express middleware builder that selects a validation set based on another field value. |
validateFile |
Express middleware export intended for file validation. Current implementation is a placeholder. |
validate_element |
Browser helper that validates a DOM input or CSS selector target. |
validate_inner_keys |
Utility to check whether nested object keys exist and are non-null. |
loadValidareMessages |
Loads message JSON files from a folder in Node.js. |
get_schema |
Resolves and returns a named schema after the standard lookup flow. |
Schemas can be stored in JSON files and loaded into global.validare.
Example schema file:
{
"username": {
"type": "string",
"regex": {
"pattern": "^[a-zA-Z0-9]+$",
"flag": "g"
},
"min_length": 3,
"max_length": 30
}
}You can then validate by name:
import { validationConfig, validator } from 'validare';
await validationConfig({
files: ['requiments.json'],
messages: 'messages'
});
const result = await validator('username', 'alice01');You can also validate directly against a schema object without registering it globally.
import { validator } from 'validare';
const result = await validator(
{
type: 'url',
protocols: ['https'],
hostnames: ['example.com']
},
'https://example.com/docs'
);Every validation returns a Status instance with this runtime shape:
{
status: boolean;
error: string;
reason: any;
value: any;
message: string;
}Meaning of the fields:
status:truefor success,falsefor failure.error: machine-friendly error key such astype,min_length, orinvalid.reason: schema value associated with the failing rule when available.value: original input value.message: localized or custom message resolved from loaded message JSON.
Understanding the execution order matters because some options override others.
validator accepts either:
- A schema object.
- A string name that is resolved from loaded schemas.
If a named schema cannot be found, the library falls back to:
{ type: 'string', required: true }validator accepts an optional third argument:
{ dont_validate: string[] }Each listed key is deleted from the schema before validation starts.
Example:
await validator('username', 'ALICE', {
dont_validate: ['casetype']
});The library checks these flags before any type-specific validators run:
dont_validate_empty: if the value is'', validation succeeds immediately.allow_undefined: if the value isundefined, validation succeeds immediately.allow_null: if the value isnull, validation succeeds immediately.
If required: true is present, the library rejects:
undefinedwith errorundefinednullwith errornull
Important detail: allow_undefined and allow_null run before required. If both are present, the allow-rule wins.
For regular schema types, the library looks up a validator function array from src/validator/validators.ts and runs those functions in order.
The first failing function stops the pipeline and creates the final Status.
If type is multi-type, the library tries each schema in types until one succeeds.
If none succeeds, it returns not-matched-with-any-type.
validationConfig is the standard setup entrypoint for server-side usage.
import { validationConfig } from 'validare';
await validationConfig({
files: ['requiments.json'],
messages: 'messages'
});Options:
| Option | Type | Meaning |
|---|---|---|
files |
`string | string[]` |
messages |
string |
Folder path containing message JSON files. |
What it does:
- Initializes
global.validare = {}. - Loads schema files into the
validarenamespace. - Loads all message JSON files in the provided folder and merges them into
global.validare.messages.
Practical guidance:
- Treat
validationConfigas asynchronous andawaitit before the first validation call. - Call it once during application bootstrap.
Browser usage is built around the generated UMD bundle in dist/validare-web.js and meta tags that tell the client which JSON files to fetch.
Example page:
<meta
name="validare-schemas"
dist="/test"
schemas='"a.json","b.json","c.json"'
>
<meta
name="messages"
dist="/messages"
schemas='"messages.json"'
>
<input data-validate data-message-box="message" name="username" type="text">
<p id="message"></p>
<script src="/dist/validare-web.js"></script>What happens in the browser build:
- The library fetches all schema JSON files listed in the
validare-schemasmeta tag. - It fetches all message files listed in the
messagesmeta tag. - It merges all loaded objects into in-memory browser stores.
- On
DOMContentLoaded, it finds every element withdata-validate. - It validates each matching input immediately and again on
change,focusout, andkeyup.
validate_element uses these element attributes:
| Attribute | Meaning |
|---|---|
data-validate |
Enables auto-validation. If non-empty, its value is used as the schema name. If empty, the name attribute is used instead. |
name |
Fallback schema name when data-validate is empty. |
data-message-box |
Element id where the message text should be written. |
After validation, the target element receives:
data-validation-status:'true'or'false'data-validation-full-result: full serializedStatusJSON
All schemas may also include shared global flags.
| Option | Type | Meaning |
|---|---|---|
required |
boolean |
Rejects undefined and null. |
dont_validate_empty |
boolean |
Immediately accepts '' before any other validation runs. |
allow_undefined |
boolean |
Immediately accepts undefined. |
allow_null |
boolean |
Immediately accepts null. |
name |
string |
Explicit schema name used for message lookup. |
These two options do different things.
dont_validate_emptymeans an empty string is accepted and validation stops successfully.ignore_emptymeans certain validators return the erroremptywhen the value is an empty string.
Despite the name, ignore_empty does not skip validation. In the current implementation it creates an error condition.
Supported options:
| Option | Type | Notes |
|---|---|---|
regex |
{ pattern: string, flag: string } |
Tested with new RegExp(pattern, flag). |
ignore_empty |
boolean |
Returns empty for ''. |
chars |
string |
Not used by string validation. Used by ID generation helpers. |
casetype |
`'uppercase' | 'lowercase' |
ignored |
string[] |
Rejects exact matches in this list with ignored. |
min_length |
number |
Uses value.length. |
max_length |
number |
Uses value.length. |
length |
number |
Uses exact value.length. |
Pipeline order:
validate_onlytypeignore_emptyvalidate_stringvalidate_lengthvalidate_casevalidate_igonered
Possible error keys from this type:
typeemptyregexlengthmin_lengthmax_lengthlowercaseuppercasecombinedignored
Example:
{
"username": {
"type": "string",
"regex": {
"pattern": "^[a-zA-Z0-9_]+$",
"flag": "g"
},
"min_length": 3,
"max_length": 20,
"casetype": "unset",
"ignored": ["admin", "root"]
}
}Supported options:
| Option | Type | Notes |
|---|---|---|
min_length |
`number | string` |
max_length |
`number | string` |
length |
`number | string` |
base |
number |
Used only for string-number parsing. |
Pipeline order:
| Type | Pipeline |
|---|---|
number |
validate_onlytype -> validate_numbers |
bigint |
validate_onlytype -> validate_numbers |
string-number |
validate_numbers |
Date expressions are supported in the number validator using strings such as:
{
"type": "number",
"max_length": "date 1:minute:add"
}That expression resolves to Date.now() + 1 minute before comparison.
Important detail:
- For these schema types,
min_length,max_length, andlengthmean numeric comparison values, not string length.
Supported options:
| Option | Type | Notes |
|---|---|---|
min_length |
number |
Checks value.length. |
max_length |
number |
Checks value.length. |
length |
number |
Checks value.length. |
Pipeline order:
validate_onlytypevalidate_length
Important detail:
typeof []is'object', but arrays use their ownarraytype pipeline. Usetype: 'array'when you need array-specific behavior.validate_lengthrelies onvalue.length, so plain objects without alengthproperty are not a good fit for length-based object validation.
Pipeline order:
validate_onlytype
Possible error keys:
type
Pipeline order:
validate_onlytype
This is a niche schema type for cases where the value must literally be undefined.
Supported options:
| Option | Type | Notes |
|---|---|---|
services |
string[] |
Restricts the captured domain/service portion. |
ignore_empty |
boolean |
Returns empty for ''. |
min_length |
number |
Uses string length. |
max_length |
number |
Uses string length. |
length |
number |
Uses exact string length. |
Pipeline order:
ignore_emptyvalidate_emailvalidate_length
Possible error keys:
emptyinvalidserviceslengthmin_lengthmax_length
Pipeline order:
ignore_emptyvalidate_ipvalidate_length
Current implementation validates IPv4 addresses with a regex.
Pipeline order:
ignore_emptyvalidate_phonevalidate_length
Current implementation accepts a narrow digit-oriented phone format based on a regex, not a full international phone parser.
Supported options:
| Option | Type | Meaning |
|---|---|---|
hostnames |
string[] |
Allowed hostnames. |
ignored_hostnames |
string[] |
Rejected hostnames. |
protocols |
string[] |
Allowed protocols without the trailing :. |
ports |
number[] |
Allowed explicit ports. |
origins |
string[] |
Allowed full origins such as https://example.com. |
ignore_empty |
boolean |
Returns empty for ''. |
min_length |
number |
Uses string length. |
max_length |
number |
Uses string length. |
length |
number |
Uses exact string length. |
Pipeline order:
ignore_emptyvalidate_urlvalidate_length
Possible error keys:
emptyinvalidprotocolsportsoriginshostnameslengthmin_lengthmax_length
Supported options:
| Option | Type |
|---|---|
values |
any[] |
Pipeline order:
validate_values
Example:
{
"status": {
"type": "values",
"values": ["draft", "published", "archived"]
}
}Supported options:
| Option | Type | Meaning |
|---|---|---|
possible_types |
schema[] |
Every element must match at least one listed schema. |
max_element |
number |
Upper element count bound. |
min_element |
number |
Lower element count bound. |
max_element_eq |
number |
Implemented like max_element in current code. |
min_element_eq |
number |
Implemented like min_element in current code. |
Pipeline order:
validate_array
Possible error keys:
typemax_elementmin_elementpossible_types
Example:
{
"tags": {
"type": "array",
"min_element": 1,
"max_element": 5,
"possible_types": [
{
"type": "string",
"min_length": 2,
"max_length": 20
}
]
}
}Supported options:
| Option | Type |
|---|---|
min_size |
number |
max_size |
number |
Pipeline order:
validate_base64
Important detail:
min_sizeandmax_sizeare compared to the encoded string length, not the decoded byte length.
Supported options:
| Option | Type |
|---|---|
ignore_empty |
boolean |
min_length |
number |
max_length |
number |
length |
number |
Pipeline order:
ignore_emptyvalidate_doi
The implementation uses a DOI-oriented regular expression.
Supported options:
| Option | Type | Meaning |
|---|---|---|
casetype |
`'uppercase' | 'lowercase' |
allowed_chars |
string |
Extra non-letter characters allowed one-by-one. |
ignore_empty |
boolean |
Returns empty for ''. |
min_length |
number |
Uses string length. |
max_length |
number |
Uses string length. |
length |
number |
Uses exact string length. |
Pipeline order:
validate_unicode_nameignore_emptyvalidate_lengthvalidate_case
Important detail:
- The first step checks every character with Unicode letter matching. Non-letter characters are only accepted when present in
allowed_chars.
Supported options:
| Option | Type |
|---|---|
min_length |
number |
max_length |
number |
length |
number |
Pipeline order:
validate_lengthvalidate_latex
KaTeX is used with throwOnError: true, so invalid LaTeX returns invalid.
Supported options:
| Option | Type | Meaning |
|---|---|---|
extension |
`string | string[]` |
mime |
`string | string[]` |
max_size |
`{ size: number, size_type: 'bit' | 'kib' |
min_size |
same shape as max_size |
Minimum file size. |
Pipeline order:
validate_filevalidate_mime_extensionwhen extension or mime constraints existvalidate_sizewhen size constraints exist
Direct validation example:
import { readFileSync } from 'fs';
import { validator } from 'validare';
const buffer = readFileSync('avatar.png');
const result = await validator(
{
type: 'file',
extension: ['png', 'jpg'],
max_size: { size: 2, size_type: 'mb' }
},
buffer
);Important detail:
- The underlying validator expects a
Buffer.
Supported options:
| Option | Type |
|---|---|
types |
schema[] |
Example:
{
"website": {
"type": "multi-type",
"types": [
{
"type": "url"
},
{
"type": "values",
"values": [":delete-value"]
}
]
}
}Messages are loaded from JSON files and merged into a single message object.
Example:
{
"$default": {
"length": "This value must be #{value} characters long"
},
"username": {
"$default": "This value is invalid",
"min_length": "Username must be at least #{value} characters"
}
}Resolution order inside Status:
- Schema-specific error message:
messages[name][error] - Schema-specific default:
messages[name]['$default'] - Global default for the error key:
messages['$default'][error]
The #{value} placeholder is replaced with the failing rule value stored in reason.
This helper builds middleware that validates multiple values and collects every failure.
String shorthand:
['body.username', 'body.email', 'body.password?']Behavior of the shorthand:
- Dot notation is resolved from
reqby default. - If the first segment is
reqorres, the lookup starts there explicitly. - The final segment becomes the schema name.
- A trailing
?meansallow_undefined: truefor this middleware field.
Object form:
[
{ dataname: 'body.login', schema: 'username' },
{ dataname: 'body.email', schema: 'email', allow_undefined: true }
]Callback signature:
(invalidValues, req, res) => anyEach invalid value record contains:
{
data: any;
dataname: string;
error: string;
reason: any;
message: string;
}Example:
import express from 'express';
import { validateFields } from 'validare';
const app = express();
app.post(
'/users',
validateFields(
['body.username', 'body.email', 'body.password?'],
(invalidValues, req, res) => {
return res.status(400).json({ errors: invalidValues });
}
),
(req, res) => {
res.json({ ok: true });
}
);This helper chooses a field set based on another field's runtime value.
Example:
validateSwitch(
'body.type',
{
business: ['body.taxNumber', 'body.companyName'],
personal: ['body.firstName', 'body.lastName'],
$default: ['body.firstName']
},
(invalidValues, req, res) => {
return res.status(400).json({ errors: invalidValues });
}
)This function is exported, but the current source implementation immediately calls next() and does not execute any file validation logic.
Recommendation:
- For now, validate uploaded file buffers manually with
validator({ type: 'file', ... }, buffer).
The Schema class wraps a schema object and exposes convenience methods.
Example:
import { Schema } from 'validare';
const usernameSchema = new Schema({
type: 'string',
min_length: 3,
max_length: 20
});
const result = await usernameSchema.validate('alice');Calls the core validator with the wrapped schema.
Builds an ID string using string schema settings.
Relevant schema fields for ID generation:
lengthchars
Available chars presets from src/create-id/presets.ts:
allstandartA-Za-z0-90-f0-Fbinary
You can combine preset names with literal extra characters in the same string.
Example:
import { ID } from 'validare';
const token = await ID({
type: 'string',
length: 16,
chars: 'A-Z0-9'
});This helper only makes sense for:
numberbigintstring-number
It passes max_length, min_length, and length into the internal randomizer.
Practical caution:
- The implementation is a simple numeric random helper, not a generic example-value generator for all schema types.
- If
lengthis set, the randomizer uses that value as the numeric upper bound, not as a digit count.
Resolves a named schema through the same lookup logic used by validator.
Checks whether a dotted path exists and stays non-null throughout traversal.
Example:
const ok = await validate_inner_keys('profile.address.city', payload);Internal utility used by Express middleware.
Lookup rules:
req.body.emailstarts fromreq.res.locals.userstarts fromres.body.emailalso starts fromreqbecausereqis the implicit default root.
| Path | Role |
|---|---|
src/index.ts |
Main library entrypoint and export surface. |
src/validator |
Core validation engine and validator registry. |
src/validator/validators |
One folder per validator implementation. |
src/class |
Schema and Status classes. |
src/express-middlewares |
Express integration helpers. |
src/functions |
Schema loading, message loading, DOM integration, and general helpers. |
src/types |
TypeScript schema and middleware type definitions. |
dist/validare-web.js |
Browser bundle produced by webpack. |
build |
Compiled JavaScript output used as webpack input. |
messages |
Example message JSON files. |
test |
Example browser-loaded schema fragments. |
Current scripts from package.json:
| Script | Command | Meaning |
|---|---|---|
npm run tsc |
tsc ./test.ts --outDir ./build -w |
TypeScript watch compile around the current test harness. |
npm run nodemon |
nodemon ./build/test.js |
Runs the built test script. |
Webpack currently bundles build/index.js into dist/validare-web.js as a UMD library named validare.
This section documents current behavior exactly as implemented.
validateFilemiddleware is unfinished. It exports successfully but does not validate anything yet.ignore_emptymeans fail on empty string with errorempty; it does not ignore empties.- For numeric schema types,
min_length,max_length, andlengthare numeric comparison values, not digit lengths. base64size checks use encoded string length, not decoded byte length.- File validation expects a
Bufferwhen usingvalidatordirectly. - The file-size helper currently returns
max_sizewhen the value is belowmin_size; that is the present implementation behavior. array.max_element_eqandarray.min_element_eqare currently implemented with the same comparison style asmax_elementandmin_element, so the_eqsuffix does not introduce different equality semantics.objectlength checks rely onvalue.length, which is only meaningful for object-like values that expose that property.- Browser schema loading depends on exact meta-tag names:
validare-schemasandmessages. - If no message is found for an error,
Status.messagecan remain empty.
import express from 'express';
import { validationConfig, validateFields } from 'validare';
await validationConfig({
files: ['requiments.json'],
messages: 'messages'
});
const app = express();
app.use(express.json());
app.post(
'/register',
validateFields(
['body.username', 'body.email'],
(invalidValues, req, res) => {
return res.status(400).json({ errors: invalidValues });
}
),
(req, res) => {
res.json({ ok: true });
}
);import { validator } from 'validare';
const result = await validator(
{
type: 'multi-type',
types: [
{ type: 'url', protocols: ['https'] },
{ type: 'values', values: [':delete-value'] }
]
},
'https://example.com'
);
console.log(result.status);<input data-validate data-message-box="message" name="username" type="text">
<p id="message"></p>
<script src="/dist/validare-web.js"></script>When the page loads, the input is validated automatically and revalidated as the user types or leaves the field.
validare is best understood as a schema-driven validation engine with three integration styles:
- direct validation in application code
- Express middleware composition
- browser-side input validation with remote schema files
Its architecture is compact and readable: schema lookup, short-circuit flags, type-specific validator chains, and optional message translation. When using it in production, the most important thing is to follow the current implementation semantics exactly, especially around empty values, number comparison naming, and the incomplete file middleware.