validators.ts•3.33 kB
/**
* Input Validation Utilities
*
* Provides Zod schemas and validation functions for tool inputs.
* All validation follows the data model defined in data-model.md.
*/
import { z } from "zod";
/**
* Schema for search-posts tool input
*/
export const SearchPostsInputSchema = z.object({
query: z.string().min(1, "query must contain at least 1 character"),
tags: z.array(z.string()).optional(),
numericFilters: z.array(z.string()).optional(),
page: z.number().int().nonnegative("page must be non-negative").default(0),
hitsPerPage: z
.number()
.int()
.min(1, "hitsPerPage must be at least 1")
.max(1000, "hitsPerPage must not exceed 1000")
.default(20),
});
/**
* Schema for get-front-page tool input
*/
export const GetFrontPageInputSchema = z.object({
page: z.number().int().nonnegative("page must be non-negative").default(0),
hitsPerPage: z
.number()
.int()
.min(1, "hitsPerPage must be at least 1")
.max(1000, "hitsPerPage must not exceed 1000")
.default(30),
});
/**
* Schema for get-latest-posts tool input
*/
export const GetLatestPostsInputSchema = z.object({
tags: z.array(z.string()).optional(),
page: z.number().int().nonnegative("page must be non-negative").default(0),
hitsPerPage: z
.number()
.int()
.min(1, "hitsPerPage must be at least 1")
.max(1000, "hitsPerPage must not exceed 1000")
.default(20),
});
/**
* Schema for get-item tool input
*/
export const GetItemInputSchema = z.object({
itemId: z.string().min(1, "itemId must not be empty"),
});
/**
* Schema for get-user tool input
*/
export const GetUserInputSchema = z.object({
username: z
.string()
.min(1, "username must not be empty")
.regex(/^[a-zA-Z0-9_]+$/, "username must be alphanumeric with underscores only"),
});
/**
* Type inference for validated inputs
*/
export type SearchPostsInput = z.infer<typeof SearchPostsInputSchema>;
export type GetFrontPageInput = z.infer<typeof GetFrontPageInputSchema>;
export type GetLatestPostsInput = z.infer<typeof GetLatestPostsInputSchema>;
export type GetItemInput = z.infer<typeof GetItemInputSchema>;
export type GetUserInput = z.infer<typeof GetUserInputSchema>;
/**
* Validate input against a Zod schema
*
* @param schema - Zod schema to validate against
* @param input - Input data to validate
* @returns Validated and type-safe output
* @throws ZodError if validation fails
*
* @example
* ```typescript
* const validated = validateInput(SearchPostsInputSchema, { query: "AI" });
* // validated.query is type-safe and guaranteed to be valid
* ```
*/
export function validateInput<T>(schema: z.ZodSchema<T>, input: unknown): T {
return schema.parse(input);
}
/**
* Safely validate input and return result or error
*
* @param schema - Zod schema to validate against
* @param input - Input data to validate
* @returns Object with success flag and either data or error
*
* @example
* ```typescript
* const result = safeValidateInput(SearchPostsInputSchema, { query: "" });
* if (!result.success) {
* console.error(result.error.errors);
* } else {
* console.log(result.data.query);
* }
* ```
*/
export function safeValidateInput<T>(
schema: z.ZodSchema<T>,
input: unknown
): { success: true; data: T } | { success: false; error: z.ZodError } {
const result = schema.safeParse(input);
return result;
}