The Docs.

Prim+RPC is in prerelease mode and may be unstable until official release.
All Plugins

Validators

Plugin Details
  • Plugin Type:
    Validation Tool
  • Transport:
    Inapplicable

Prim+RPC does not include validation of arguments and return values by default but this can easily be added in one of several ways, using the validation tool of your choice.

See the Security guide to learn various ways of setting up validation. In this guide, we’ll see how to set up several popular validation libraries with our functions directly. However we could just as easily move this validation into a Pre-Call or Post-Call hook.

For all of these examples we will be adding validation to this example function (implementation can generally be ignored, we will only be focusing on the validation of inputs):

import { transport } from "./email-example"
 
interface Options {
	to: string
	name?: string
	reply: string
	subject?: string
}
 
export function sendMessage(message: string, opts: Options) {
	try {
		const text = `Message from ${opts.name} <${opts.reply}>\n\n${message}`
		const { to, subject } = opts
		await transport.sendMail({ text, to, subject })
	} catch (error) {
		throw new Error("Internal email error")
	}
}

Zod

Zod is a very popular form of validation. We could set up validation like so:

import { transport } from "./email-example"
import { z } from "zod"
 
const optsSchema = z.object({
	to: z.string().email(),
	name: z.string().optional(),
	reply: z.string().email(),
	subject: z.string().optional(),
})
type Options = z.infer<typeof optsSchema>
 
export function sendMessage(message: string, opts: Options) {
	;[message, opts] = z.tuple([z.string(), optsSchema]).parse([message, opts])
	try {
		const text = `Message from ${opts.name} <${opts.reply}>\n\n${message}`
		const { to, subject } = opts
		await transport.sendMail({ text, to, subject })
	} catch (error) {
		throw new Error("Internal email error")
	}
}

ArkType

ArkType is a recent library gaining traction for its resemblance to TypeScript types. We could set up validation like so:

import { transport } from "./email-example"
import { type } from "arktype"
 
const optsSchema = type({
	to: "email",
	name: "string|undefined",
	reply: "email",
	subject: "string|undefined",
})
type Options = typeof optsSchema.infer
 
export function sendMessage(message: string, opts: Options) {
	;[message, opts] = type(["string", optsSchema]).assert([message, opts])
	try {
		const text = `Message from ${opts.name} <${opts.reply}>\n\n${message}`
		const { to, subject } = opts
		await transport.sendMail({ text, to, subject })
	} catch (error) {
		throw new Error("Internal email error")
	}
}

Valibot

Valibot is an alternative to Zod that has a tree-shakeable design.

import { transport } from "./email-example"
import { object, string, optional, email, parse, type Output } from "valibot"
 
const optsSchema = object({
	to: string([email()]),
	name: optional(string()),
	reply: string([email()]),
	subject: optional(string()),
})
type Options = Output<typeof optsSchema>
 
export function sendMessage(message: string, opts: Options) {
	;[message, opts] = parse(tuple([string(), optsSchema]), [message, opts])
	try {
		const text = `Message from ${opts.name} <${opts.reply}>\n\n${message}`
		const { to, subject } = opts
		await transport.sendMail({ text, to, subject })
	} catch (error) {
		throw new Error("Internal email error")
	}
}

Others

The examples on this page are not exhaustive. You may use any validation library that you’d like.

Report an Issue