Introduce the common-resolver
common-resolver is a lightweight, universal library designed to solve recurring validation and error-handling problems in a simple and consistent way across different environments. It provides adapter interfaces for validation libraries such as zod (v3, v4), yup, and superstruct so you can swap and reuse validation logic with minimal changes. Its modular design makes it quick to integrate and easy to extend, while keeping configuration minimal.
Installation#
You can install common-resolver using any of the methods shown below.
Features#
common-resolver provides the following features. Along with resolvers for each schema validation library, it exposes type-safe helper functions that validate schemas. The getResolver function automatically detects the type of the provided schema and selects the appropriate resolver, so switching validation libraries requires minimal code changes.
Additionally, type definitions such as ValidateSchema and Resolver offer complete TypeScript safety, enabling IDE autocompletion and compile-time error checks. These features let developers focus on business logic instead of the intricacies of schema validation.
Below is a simple example using a Zod schema. The schema defines a string type with a minimum length of 1. Passing an empty string ("") to the validate method will fail the length check and produce an error object that includes a message ("zSchema is required") under the special "root" property. This example is for a single value, so errors are recorded on the "root" property instead of on a specific field. For complex object structures, errors are mapped to each field path accordingly.
Using common-resolver in the global state manager caro-kann#
The code below demonstrates a middleware in the caro-kann global state manager that performs validation. The validate function accepts the initial state and a schema validator, and automatically validates whenever state changes. By using getResolver, the middleware can handle different schema types through the same interface. If the state is invalid, the middleware logs the error and blocks the state update, ensuring the application state always conforms to the schema.
Regardless of which validation library you use, passing a schema as the second argument to validate allows caro-kann to detect and pick the appropriate resolver via common-resolver. getResolver inspects the provided schema (Zod, Yup, Superstruct, etc.) and returns the matching resolver, so caro-kann users can replace schema objects without changing other code. This flexibility is especially useful when project requirements change or when experimenting with different validation libraries.
Using common-resolver in the form manager sicilian#
The Validate class inside sicilian receives a state store, an error setter, and a Resolver object from common-resolver. Its doValidate method runs validation in response to user input events and sets field-specific error messages when validation fails. This structure provides immediate per-field feedback while maintaining overall form consistency.
sicilian re-exposes common-resolver functionality through its own API, simplifying the developer experience and reducing direct dependencies on the common-resolver package.
The example below shows a complex signup form validated by a Zod schema. The schema includes rules for email, nickname, password, password confirmation, and terms agreement. It uses zod's refine method for cross-field checks such as ensuring password and passwordCheck match. The zodResolver passes this schema to the sicilian form controller so all rules are enforced declaratively and user input is validated automatically.