@molecule/api-middleware-validation
v1.0.1
Published
Zod-based request validation middleware for molecule.dev
Downloads
623
Readme
@molecule/api-middleware-validation
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Request validation middleware for molecule API packages. Uses Zod schemas to validate request body, params, and query.
Quick Start
import { validate, validateBody, paginationSchema } from '@molecule/api-middleware-validation'
import { z } from 'zod'
const createPostSchema = z.object({
title: z.string().min(1).max(200),
content: z.string().min(1),
tags: z.array(z.string()).optional(),
})
router.post('/posts', validateBody(createPostSchema), createPost)
router.get('/posts', validate({ query: paginationSchema }), listPosts)Type
utility
Installation
npm install @molecule/api-middleware-validation @molecule/api-bond @molecule/api-i18n zodAPI
Interfaces
PaginatedResponse
Shape of a paginated list response.
interface PaginatedResponse<T> {
/** The page of results. */
data: T[]
/** Pagination metadata. */
pagination: {
/** Current page number. */
page: number
/** Items per page. */
perPage: number
/** Total number of items across all pages. */
total: number
/** Total number of pages. */
totalPages: number
/** Whether more pages exist after the current one. */
hasMore: boolean
}
}ValidationError
A single validation error describing which field failed and why.
interface ValidationError {
/** Dot-delimited path to the invalid field (e.g. `"address.city"`). */
field: string
/** Human-readable error message. */
message: string
/** Zod issue code (e.g. `"invalid_type"`, `"too_small"`). */
code: string
}ValidationResult
The result of validating a request against a schema.
interface ValidationResult {
/** Whether validation passed without errors. */
success: boolean
/** Array of validation errors (empty when `success` is `true`). */
errors: ValidationError[]
}Types
PaginationQuery
Inferred type for pagination query parameters.
type PaginationQuery = z.infer<typeof paginationSchema>SearchQuery
Inferred type for search query parameters (pagination + search term).
type SearchQuery = z.infer<typeof searchQuerySchema>ValidationSchema
Schema definition for validating different parts of a request. Each key maps to a Zod schema that validates the corresponding request property.
type ValidationSchema = {
/** Schema for validating the request body. */
body?: ZodType
/** Schema for validating URL params. */
params?: ZodType
/** Schema for validating query string parameters. */
query?: ZodType
}Functions
error(message, errors)
Creates a standard error response object.
function error(
message: string,
errors?: { field: string; message: string }[],
): { error: string; errors?: Array<{ field: string; message: string }> }message— Top-level error message.errors— Optional array of field-level errors.
Returns: An error response object.
paginated(data, total, page, perPage)
Wraps a list of items with pagination metadata.
function paginated(data: T[], total: number, page: number, perPage: number): PaginatedResponse<T>data— The items for the current page.total— Total item count across all pages.page— Current page number (1-based).perPage— Number of items per page.
Returns: A PaginatedResponse object.
success(data)
Wraps a value in a standard { data } envelope.
function success(data: T): { data: T }data— The payload to wrap.
Returns: An object with a single data key.
validate(schema)
Creates an Express middleware that validates the request body, params, and/or query against the provided Zod schemas.
On success the parsed (and possibly coerced/defaulted) values replace the
original request properties and next() is called.
On failure a 400 JSON response is returned with structured error details.
function validate(
schema: ValidationSchema,
): RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>schema— Object mapping request parts (body,params,query) to Zod schemas.
Returns: Express middleware function.
validateBody(schema)
Convenience wrapper that validates only the request body.
function validateBody(
schema: T,
): RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>schema— Zod schema forreq.body.
Returns: Express middleware function.
validateParams(schema)
Convenience wrapper that validates only URL params.
function validateParams(
schema: T,
): RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>schema— Zod schema forreq.params.
Returns: Express middleware function.
validateQuery(schema)
Convenience wrapper that validates only query string parameters.
function validateQuery(
schema: T,
): RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>schema— Zod schema forreq.query.
Returns: Express middleware function.
Constants
idParamSchema
Schema for a single UUID id URL parameter.
const idParamSchema: z.ZodObject<{ id: z.ZodUUID }, z.core.$strip>paginationSchema
Schema for standard pagination query parameters.
Coerces string values to numbers (as query params arrive as strings).
const paginationSchema: z.ZodObject<
{
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>
perPage: z.ZodDefault<z.ZodCoercedNumber<unknown>>
sort: z.ZodOptional<z.ZodString>
order: z.ZodDefault<z.ZodEnum<{ asc: 'asc'; desc: 'desc' }>>
},
z.core.$strip
>searchQuerySchema
Schema that extends pagination with an optional search query q.
const searchQuerySchema: z.ZodObject<
{
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>
perPage: z.ZodDefault<z.ZodCoercedNumber<unknown>>
sort: z.ZodOptional<z.ZodString>
order: z.ZodDefault<z.ZodEnum<{ asc: 'asc'; desc: 'desc' }>>
q: z.ZodOptional<z.ZodString>
},
z.core.$strip
>Injection Notes
Requirements
Peer dependencies:
@molecule/api-bond^1.0.1@molecule/api-i18n^1.0.1
Runtime Dependencies
@molecule/api-bond@molecule/api-i18nzod
Express/Connect middleware (Express 4 and 5 — including the Express 5
getter-only req.query, which is handled internally). For other
frameworks, call the schemas directly and shape your own 400 response.
On success the parsed values REPLACE req.body / req.params /
req.query, so Zod coercions and defaults are what handlers see. On
failure the response is 400 { error, errors: [{ field, message, code }] }.
MASS-ASSIGNMENT SAFETY — Zod object schemas STRIP unknown keys by default, so
after validateBody(schema) the replaced req.body holds ONLY the schema's
declared fields. THAT is what makes persisting it wholesale safe:
create('posts', req.body) / updateById('posts', id, req.body) /
updateById('posts', id, { ...req.body }) cannot smuggle privileged columns
(role, is_admin, user_id, owner_id, status, balance, …) — the
client's extra keys were dropped. The corollary is LOAD-BEARING: writing raw
req.body / { ...req.body } to the DataStore on a route that is NOT behind
validateBody/validate({ body }) (or an in-handler schema.parse()) IS a
mass-assignment hole. A const body = req.body as z.infer<typeof schema> CAST
does NOTHING at runtime (types are erased) — it neither validates nor strips;
only the middleware (or a real .parse()) sanitizes. Rule: validate the body
before you persist it, every mutation route.
Sibling: @molecule/api-utilities-validation is the PROGRAMMATIC helper
set (getValidProps, safeParse) for use inside handlers/services — both
packages export a validate, so alias if you import both.
