Skip to main content
Glama
validator.ts1.87 kB
// src/validator.ts import Ajv from 'ajv'; export type ValidationMode = 'exact' | 'contains' | 'regex' | 'json-schema'; export interface Expectation { mode?: ValidationMode; // string for exact/contains/regex, object for json-schema value: string | Record<string, unknown>; } const ajv = new Ajv(); /** * Validate the raw output string against the given expectation. * Returns { success: true } or { success: false, errors: [...] }. */ export function validateOutput( output: string, expected: Expectation ): { success: true } | { success: false; errors: string[] } { const mode = expected.mode ?? 'exact'; const errors: string[] = []; switch (mode) { case 'exact': { if (output !== expected.value) { errors.push(`Exact mismatch. Expected: ${expected.value}, Got: ${output}`); } break; } case 'contains': { if (!output.includes(expected.value as string)) { errors.push(`Missing substring. Expected to contain: ${expected.value}`); } break; } case 'regex': { const re = new RegExp(expected.value as string); if (!re.test(output)) { errors.push(`Regex ${expected.value} did not match output. ${output}`); } break; } case 'json-schema': { let data: unknown; try { data = JSON.parse(output); } catch (err: any) { errors.push(`Invalid JSON: ${err.message}`); break; } { const validate = ajv.compile(expected.value as object); const valid = validate(data); if (!valid) { errors.push(`Schema errors: ${ajv.errorsText(validate.errors)}`); } } break; } default: { errors.push(`Unknown validation mode: ${mode}`); break; } } return errors.length === 0 ? { success: true } : { success: false, errors }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TheLunarCompany/lunar'

If you have feedback or need assistance with the MCP directory API, please join our Discord server