UNPKG

@orpc/contract

Version:

<div align="center"> <image align="center" src="https://orpc.unnoq.com/logo.webp" width=280 alt="oRPC logo" /> </div>

82 lines (78 loc) 2.83 kB
import { ORPCError } from '@orpc/client'; import { get } from '@orpc/shared'; import { i as isContractProcedure, V as ValidationError, v as validateORPCError } from '../shared/contract.D_dZrO__.mjs'; class RequestValidationPluginError extends Error { } class RequestValidationPlugin { constructor(contract) { this.contract = contract; } init(options) { options.interceptors ??= []; options.interceptors.push(async ({ next, path, input }) => { const procedure = get(this.contract, path); if (!isContractProcedure(procedure)) { throw new RequestValidationPluginError(`No valid procedure found at path "${path.join(".")}", this may happen when the contract router is not properly configured.`); } const inputSchema = procedure["~orpc"].inputSchema; if (inputSchema) { const result = await inputSchema["~standard"].validate(input); if (result.issues) { throw new ORPCError("BAD_REQUEST", { message: "Input validation failed", data: { issues: result.issues }, cause: new ValidationError({ message: "Input validation failed", issues: result.issues, data: input }) }); } } return await next(); }); } } class ResponseValidationPlugin { constructor(contract) { this.contract = contract; } /** * run before (validate after) retry plugin, because validation failed can't be retried * run before (validate after) durable iterator plugin, because we expect durable iterator to validation (if user use it) */ order = 12e5; init(options) { options.interceptors ??= []; options.interceptors.push(async ({ next, path }) => { const procedure = get(this.contract, path); if (!isContractProcedure(procedure)) { throw new Error(`[ResponseValidationPlugin] no valid procedure found at path "${path.join(".")}", this may happen when the contract router is not properly configured.`); } try { const output = await next(); const outputSchema = procedure["~orpc"].outputSchema; if (!outputSchema) { return output; } const result = await outputSchema["~standard"].validate(output); if (result.issues) { throw new ValidationError({ message: "Server response output does not match expected schema", issues: result.issues, data: output }); } return result.value; } catch (e) { if (e instanceof ORPCError) { throw await validateORPCError(procedure["~orpc"].errorMap, e); } throw e; } }); } } export { RequestValidationPlugin, RequestValidationPluginError, ResponseValidationPlugin };