// @ts-check const { isZodErrorLike } = require('zod-validation-error') /** * @typedef {import('zod').ZodType} ZodType */ /** * @template T * @typedef {import('zod').output} output */ /** * A helper function to safely get a nested value from an object * using a path array (e.g., ["query", "resource_type"]) * @param {any} data * @param {Array} path */ function getPathValue(data, path) { let current = data for (const key of path) { if (current === null || typeof current !== 'object') { return undefined } current = current[key] } return current } /** * @param {any} issue * @param {any} value */ const isRequiredError = (issue, value) => value === undefined && (issue.code === 'invalid_type' || issue.code === 'invalid_union') /** * Validates data against a Zod schema and throws a user-friendly error. * * @template {ZodType} T * @param {T} schema - The Zod schema * @param {unknown} data - The data to validate * @returns {output} The validated (and transformed) data */ function validateSchema(schema, data) { try { return schema.parse(data) } catch (err) { if (isZodErrorLike(err)) { const errorMessages = err.issues.map(issue => { const value = getPathValue(data, issue.path) if (issue.path.length === 0) { return issue.message } const fieldName = String(issue.path[issue.path.length - 1]) if (isRequiredError(issue, value)) { return `"${fieldName}" is required` } return `"${fieldName}" - ` + issue.message }) throw new Error(errorMessages.join('; ')) } throw err } } module.exports = { validateSchema }