Skip to content
Warlock.js v4

API reference

Thin reference. Every exported identifier, grouped by category, with signature and one minimal example. For “how to use this well” guidance, see the Essentials and Guides sections.

Canonical import:

import {
v,
validate,
type Infer,
configureSeal,
registerPlugin,
type SealPlugin,
} from "@warlock.js/seal";

The factory object. Every primitive and structural validator comes off v.

const schema = v.object({ email: v.string().email() });

Source: @warlock.js/seal/src/factory/validators.ts.

validate<T extends BaseValidator>(
schema: T,
data: any,
options?: ValidateOptions,
): Promise<ValidationResult>;

Runs the schema against data and returns { isValid, data, errors }. Never throws on bad input.

const result = await validate(userSchema, request.body);
if (result.isValid) handle(result.data);

Source: @warlock.js/seal/src/factory/validate.ts.

type ValidateOptions = {
context?: Record<string, any>; // passed through to SchemaContext.rootContext
translateRule?: TranslateRuleCallback;
translateAttribute?: TranslateAttributeCallback;
firstErrorOnly?: boolean;
};
v.string() // type: string
v.string().email()
v.string().url()
v.string().uuid(4)
v.string().min(3).max(50)
v.email() // shortcut for v.string().email()
v.number().min(0).max(100)
v.int().positive() // rejects 1.5 and negatives
v.float().between(0, 1) // rejects 1 and 0
v.numeric().min(0) // accepts "42" and 42
v.boolean()
v.boolean().accepted() // for "on" / "yes" / "1" form values
v.scalar() // type: string | number | boolean
v.date().past()
v.date().defaultNow()
v.literal("admin", "user") // type: "admin" | "user"
v.enum(["draft", "published"]) // array form
v.enum(StatusEnum) // TS enum object
v.instanceof(File)
v.instanceof(MyClass)
v.computed<string>(({ first, last }) => `${first} ${last}`)
v.managed<Date>(() => new Date())
v.managed<string>(({ user }) => user.id)
v.any() // type: any
v.object({
email: v.string().email(),
age: v.int().optional(),
})
v.array(v.string()).minLength(1).maxLength(10)
v.record(v.int()) // type: Record<string, number>
v.tuple([v.string(), v.int()]) // type: [string, number]
v.union([v.string(), v.int()]) // type: string | number
v.discriminatedUnion("type", [
v.object({ type: v.literal("a"), x: v.string() }),
v.object({ type: v.literal("b"), y: v.int() }),
])
v.lazy(() => categorySchema) // for recursive / forward refs
type User = Infer<typeof userSchema>;

Alias for Infer.Input<T>.

What the caller is allowed to send (pre-validation). .optional(), .default(), .catch() all mark a key optional here.

What result.data contains (post-validation). .default() and .catch() guarantee a value, so those keys are required here.

type In = Infer.Input<typeof schema>;
type Out = Infer.Output<typeof schema>;
configureSeal({
firstErrorOnly: false,
translateRule: ({ rule, attributes }) => t(`validation.${rule.name}`, attributes),
});
const config = getSealConfig(); // SealConfig
resetSealConfig(); // clear translation hooks + reset firstErrorOnly to true
type SealConfig = {
translateRule?: (ruleTranslation: RuleTranslation) => string;
translateAttribute?: (attributeTranslation: AttributeTranslation) => string;
firstErrorOnly?: boolean; // default: true
};

Source: @warlock.js/seal/src/config.ts.

await registerPlugin(slugPlugin);

Async. Idempotent — duplicate names warn and skip.

await unregisterPlugin("slug");

Runs the plugin’s uninstall?.() and removes from the registry.

if (hasPlugin("slug")) { /* ... */ }
const plugins = getInstalledPlugins(); // SealPlugin[]
type SealPlugin = {
name: string;
version?: string;
description?: string;
install: (context: PluginContext) => void | Promise<void>;
uninstall?: () => void | Promise<void>;
};

Source: @warlock.js/seal/src/plugins/plugin-system.ts.

Validator classes (for plugin authoring + type narrowing)

Section titled “Validator classes (for plugin authoring + type narrowing)”

These are the underlying classes the factory wraps. You rarely touch them in app code — they’re exported for plugin authoring (module augmentation, prototype patching) and for typing slots that accept a specific validator shape.

  • BaseValidator — root class with validate, toJsonSchema, chain methods.
  • StringValidator, NumberValidator, IntValidator, FloatValidator, NumericValidator, BooleanValidator, ScalarValidator, DateValidator.
  • LiteralValidator<T>, InstanceOfValidator<T>, AnyValidator.
  • ObjectValidator<TSchema>, ArrayValidator, RecordValidator, TupleValidator.
  • UnionValidator, DiscriminatedUnionValidator<K, Branches>.
  • LazyValidator<T>.
  • ComputedValidator<TResult>, ManagedValidator<TResult>.

Each lives in its own file under @warlock.js/seal/src/validators/.

const result = await schema["~standard"].validate(input);
// → { value } on success, { issues } on failure
const json = schema["~standard"].jsonSchema.input({ target: "openai-strict" });

The Standard Schema V1 accessor. See Bridge Standard Schema guide.

The Standard Schema V1 interface seal implements. Re-exported from @warlock.js/seal/src/standard-schema/types.ts.

Seal’s extension of the Standard Schema spec adding JSON Schema accessors.

schema.toJsonSchema("draft-2020-12");
schema.toJsonSchema("draft-07");
schema.toJsonSchema("openapi-3.0");
schema.toJsonSchema("openai-strict");

Default target is "draft-2020-12".

type JsonSchemaTarget =
| "draft-2020-12"
| "draft-07"
| "openapi-3.0"
| "openai-strict";

Source: @warlock.js/seal/src/standard-schema/json-schema.ts.

The package exports its type surface from @warlock.js/seal/src/types/:

  • Schema — a Record<string, BaseValidator> (the input to v.object).
  • SchemaContext — runtime context passed through validation (siblings, path, configurations).
  • ValidationResult{ isValid, data, errors }.
  • RuleTranslation, AttributeTranslation — params passed to the translation hooks.
  • Mutator, TransformerCallback, SimpleTransformerCallback — data-pipeline shapes.
  • SchemaRule, ContextualSchemaRule, SchemaRuleOptions — for custom rule authoring.

Source: @warlock.js/seal/src/types/index.ts.