API
StandardSchemaValidationPipe
Validates values using any schema that implements the Standard Schema v1 spec. Register it globally to validate incoming HTTP parameters (e.g., body) in your controllers.
constructor(schemaList?: StandardSchemaV1[])
Parameters
- schemaList (optional StandardSchemaV1[]): One or more Standard Schema schemas applied globally to every validated value. These run before any parameter-level schemas added via
@ValidateStandardSchemaV1.
StandardSchemaValidationPipe can be registered as a global pipe: adapter.useGlobalPipe(new StandardSchemaValidationPipe()).
This way, controller parameters decorated @ValidateStandardSchemaV1 are automatically validated.
Example: register a StandardSchemaValidationPipe globally
import { InversifyExpressHttpAdapter } from '@inversifyjs/http-express';
import { InversifyValidationErrorFilter } from '@inversifyjs/http-validation';
import { StandardSchemaValidationPipe } from '@inversifyjs/standard-schema-validation';
import { Container } from 'inversify';
const container: Container = new Container();
const adapter: InversifyExpressHttpAdapter = new InversifyExpressHttpAdapter(
container,
{ logger: true },
);
adapter.useGlobalFilters(InversifyValidationErrorFilter);
adapter.useGlobalPipe(new StandardSchemaValidationPipe());
ValidateStandardSchemaV1
Attaches one or more Standard Schema v1 schemas to a specific parameter (e.g., @Body()), so the StandardSchemaValidationPipe can validate and (optionally) transform the value before your controller method runs.
ValidateStandardSchemaV1(...schemaList: StandardSchemaV1[]): ParameterDecorator
Parameters
- schemaList: One or more schemas from any library that implements the Standard Schema v1 spec (e.g., Zod, Valibot, Arktype).
When multiple schemas are provided, they run in order. The output of one becomes the input of the next. Any schemas provided to StandardSchemaValidationPipe run first; parameter-level schemas run afterwards. If a schema transforms the value (e.g., parsing/coercion), the controller receives the transformed value.
On failure, an InversifyStandardSchemaValidationError (a subclass of InversifyValidationError) is thrown with an errors field containing the raw Standard Schema Issue[]. It can be converted to a Bad Request HTTP response by InversifyValidationErrorFilter.
Example: validate request body with Zod
import { Body, Controller, Post } from '@inversifyjs/http-core';
import { ValidateStandardSchemaV1 } from '@inversifyjs/standard-schema-validation';
import zod from 'zod';
interface Message {
content: string;
}
@Controller('/messages')
export class MessageController {
@Post()
public async createMessage(
@Body()
@ValidateStandardSchemaV1(
zod.object({ content: zod.string().max(100) }).strict(),
)
message: Message,
): Promise<Message> {
return message;
}
}
Customizing validation error responses
InversifyValidationErrorFilter returns { message } by default. When frontends need field-level errors, catch InversifyStandardSchemaValidationError and map its errors field into the response body you want:
import {
BadRequestHttpResponse,
CatchError,
type ErrorFilter,
} from '@inversifyjs/http-core';
import { InversifyStandardSchemaValidationError } from '@inversifyjs/standard-schema-validation';
import { InversifyValidationErrorKind } from '@inversifyjs/validation-common';
function mapStandardSchemaIssues(
issues: NonNullable<InversifyStandardSchemaValidationError['errors']>,
): Record<string, string> {
const result: Record<string, string> = {};
for (const issue of issues) {
const path: string =
issue.path
?.map((segment: PropertyKey | { key: PropertyKey }): string =>
typeof segment === 'object' && 'key' in segment
? String(segment.key)
: String(segment),
)
.join('.') ?? '';
if (path !== '' && result[path] === undefined) {
result[path] = issue.message;
}
}
return result;
}
@CatchError(InversifyStandardSchemaValidationError)
export class CustomStandardSchemaValidationErrorFilter implements ErrorFilter<InversifyStandardSchemaValidationError> {
public catch(error: InversifyStandardSchemaValidationError): never {
switch (error.kind) {
case InversifyValidationErrorKind.validationFailed:
throw new BadRequestHttpResponse(
{
errors: mapStandardSchemaIssues(error.errors ?? []),
message: 'Validation failed',
success: false,
},
error.message,
{
cause: error,
},
);
default:
throw new Error(error.message, {
cause: error,
});
}
}
}
Register the filter instead of (or in addition to) the built-in one:
adapter.useGlobalFilters(CustomStandardSchemaValidationErrorFilter);
That yields responses like:
{
"success": false,
"message": "Validation failed",
"errors": {
"firstName": "First name is required",
"lastName": "Last name is required"
}
}