skills/custom-format-validators/SKILL.md
Registers and manages custom format validators in z-schema. Use when the user needs to add custom format validation, create sync or async format validators, register formats globally or per instance, validate emails or dates or phone numbers or custom business rules with format, configure formatAssertions for vocabulary-aware behavior, use customFormats option, list registered formats, handle async format timeouts, or understand how format validation differs across JSON Schema drafts.
npx skillsauth add zaggino/z-schema custom-format-validatorsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
JSON Schema format constrains string (or other) values beyond basic type checking. z-schema includes built-in validators and supports registering custom ones — both sync and async.
z-schema ships with validators for all standard JSON Schema formats:
| Format | Validates |
| ----------------------- | ------------------------------------------- |
| date | RFC 3339 full-date (2024-01-15) |
| date-time | RFC 3339 date-time (2024-01-15T09:30:00Z) |
| time | RFC 3339 time (09:30:00Z) |
| email | RFC 5321 email address |
| idn-email | Internationalized email |
| hostname | RFC 1123 hostname |
| idn-hostname | Internationalized hostname |
| ipv4 | IPv4 address |
| ipv6 | IPv6 address |
| uri | RFC 3986 URI |
| uri-reference | URI or relative reference |
| uri-template | RFC 6570 URI template |
| iri | Internationalized URI |
| iri-reference | Internationalized URI reference |
| json-pointer | RFC 6901 JSON Pointer |
| relative-json-pointer | Relative JSON Pointer |
| regex | ECMA-262 regex |
| duration | ISO 8601 duration |
| uuid | RFC 4122 UUID |
A format validator is a function (input: unknown) => boolean. Return true if valid, false if invalid. Return true for non-applicable types (e.g., when input is not a string) — z-schema calls format validators for any value type.
import ZSchema from 'z-schema';
ZSchema.registerFormat('postal-code', (value) => {
if (typeof value !== 'string') return true; // skip non-strings
return /^\d{5}(-\d{4})?$/.test(value);
});
const validator = ZSchema.create();
validator.registerFormat('postal-code', (value) => {
if (typeof value !== 'string') return true;
return /^\d{5}(-\d{4})?$/.test(value);
});
Instance formats override global formats with the same name.
const validator = ZSchema.create({
customFormats: {
'postal-code': (value) => typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value),
'always-valid': () => true,
'disable-email': null, // disable the built-in email validator
},
});
Pass null to disable a built-in or globally registered format.
Return Promise<boolean>. The validator must be created with { async: true }.
const validator = ZSchema.create({ async: true });
validator.registerFormat('user-exists', async (value) => {
if (typeof value !== 'number') return true;
const user = await db.findUser(value);
return user != null;
});
// Validate (returns Promise)
try {
await validator.validate(data, schema);
} catch (err) {
console.log(err.details);
}
Async format validators time out after asyncTimeout milliseconds (default: 2000). Increase for slow operations:
const validator = ZSchema.create({
async: true,
asyncTimeout: 10000, // 10 seconds
});
Timed-out validators produce an ASYNC_TIMEOUT error.
The JSON Schema spec changed how format works in newer drafts:
| Draft | Default behavior | With formatAssertions: true |
| -------------- | ---------------------------------- | ----------------------------------------- |
| draft-04/06/07 | Always asserts (fails on mismatch) | Always asserts |
| draft-2019-09 | Always asserts (z-schema default) | Annotation-only unless vocabulary enabled |
| draft-2020-12 | Always asserts (z-schema default) | Annotation-only unless vocabulary enabled |
z-schema defaults to formatAssertions: null (legacy — always assert). To respect the spec's vocabulary-aware behavior for modern drafts:
const validator = ZSchema.create({ formatAssertions: true });
To disable all format assertions (annotation-only):
const validator = ZSchema.create({ formatAssertions: false });
By default, z-schema reports UNKNOWN_FORMAT for unrecognized format names in draft-04/06/07. Modern drafts (2019-09, 2020-12) always silently ignore unknown formats.
To suppress unknown format errors in older drafts:
const validator = ZSchema.create({ ignoreUnknownFormats: true });
// Global
ZSchema.unregisterFormat('postal-code');
// Instance
validator.unregisterFormat('postal-code');
// List globally registered custom formats
const customFormats = ZSchema.getRegisteredFormats();
// List all supported formats (built-in + custom) on an instance
const allFormats = validator.getSupportedFormats();
// Check if a specific format is supported
const supported = validator.isFormatSupported('postal-code');
ZSchema.registerFormat('phone', (value) => {
if (typeof value !== 'string') return true;
return /^\+?[1-9]\d{1,14}$/.test(value); // E.164 format
});
ZSchema.registerFormat('iso-date', (value) => {
if (typeof value !== 'string') return true;
const d = new Date(value);
return !isNaN(d.getTime()) && value === d.toISOString().split('T')[0];
});
const validator = ZSchema.create({ async: true });
validator.registerFormat('valid-country', async (value) => {
if (typeof value !== 'string') return true;
const countries = await fetchValidCountries();
return countries.includes(value.toUpperCase());
});
Format validators can mutate objects (use with caution):
ZSchema.registerFormat('fill-defaults', (obj) => {
if (typeof obj === 'object' && obj !== null) {
(obj as Record<string, unknown>).createdAt ??= new Date().toISOString();
}
return true;
});
{
"type": "object",
"properties": {
"phone": { "type": "string", "format": "phone" },
"country": { "type": "string", "format": "valid-country" },
"zipCode": { "type": "string", "format": "postal-code" }
}
}
development
Inspects, filters, and maps z-schema validation errors for application use. Use when the user needs to handle validation errors, walk nested inner errors from anyOf/oneOf/not combinators, map error codes to user-friendly messages, filter errors with includeErrors or excludeErrors, build form-field error mappers, use reportPathAsArray, interpret SchemaErrorDetail fields like code/path/keyword/inner, or debug why validation failed.
development
Guides contributors through the z-schema codebase, PR workflow, and common development tasks. Use when the user wants to contribute to z-schema, add a new feature or keyword, add an error code, add a format validator, modify options, write tests, run the test suite, fix a failing test, understand the validation pipeline, navigate the source code architecture, or submit a pull request. Also use when someone mentions contributing, PRs, the z-schema source code, or the JSON Schema Test Suite integration.
development
Authors JSON Schema definitions for use with z-schema validation. Use when the user needs to write a JSON Schema, define a schema for an API payload, create schemas for form validation, structure schemas with $ref and $defs, choose between oneOf/anyOf/if-then-else, design object schemas with required and additionalProperties, validate arrays with items or prefixItems, add format constraints, organize schemas for reuse, or write draft-2020-12 schemas.
development
Validates JSON data against JSON Schema using the z-schema library. Use when the user needs to validate JSON, check data against a schema, handle validation errors, use custom format validators, work with JSON Schema drafts 04 through 2020-12, set up z-schema in a project, compile schemas with cross-references, resolve remote $ref, configure validation options, or inspect error details. Covers sync/async modes, safe error handling, schema pre-compilation, remote references, TypeScript types, and browser/UMD usage.