Utility for parsing URL routes with typesafe parameters
Many routing libraries like react-router
allow you to define
route patterns with parameters like /users/:userId
, but they
don't validate or parse the parameters, like if userId
must
be a number.
zod-route-schemas
allows you to validate and parse the parameters
according to a zod schema:
import z from 'zod'
import ZodRoute from 'zod-route-schemas'
const usersRoute = new ZodRoute(
'/users/:userId',
z.object({
// ZodRoute type magic requires this schema to have a userId property!
userId: z
.string()
.regex(/^\d+$/)
.transform((s) => parseInt(s)),
})
)
const params: { userId: number } = usersRoute.parse('/users/23') // type safe!
A pattern should be a valid URL path (this is not strictly enforced at the moment).
Any path segment (part delimited by /
) that starts with :
is a parameter. For example the path
/org/:orgId/dashboards/:dashboardId
has two parameters, orgId
and dashboardId
.
You can mark a path segment optional (whether it's a parameter or not) with a trailing ?
.
For example /settings/account?/password
matches /settings/account/password
or /settings/account
,
and /users/:userId
matches /users
or /users/dude
with userId: 'dude'
.
import ZodRoute from 'zod-route-schemas'
class ZodRoute<
Pattern extends string,
Schema extends SchemaForPattern<Pattern>,
FormatSchema extends InvertSchema<Schema> = InvertSchema<Schema>
>
constructor(pattern: Pattern, schema: Schema, options?: { formatSchema?: FormatSchema, partialFormatSchema?: PartialFormatSchema })
Creates a ZodRoute
. The schema
must accept an object as input with all parameters
from pattern
as string
-valued properties.
schema
is used to parse the parameters in .parse()
/.safeParse()
.
formatSchema
is optional, and is used to transform the output parameter values back
to the raw string values in .format()
.
only accepts an object with string
, number
, boolean
, null
, or undefined
values,
and String()
ifies them.
partialFormatSchema
is optional, and is used to transform the output parameter values back
to the raw string values in .partialFormat()
.
The pattern for this route.
The schema for parsing this route's parameters in .parse()
/.safeParse()
The schema for formatting this route's parameters in .format()
/.partialFormat()
.
safeParse(path: string): z.SafeParseReturnType<z.input<Schema>, z.output<Schema>>
Parses the given path
. If it matches the pattern
,
returns { success: true, data: z.output<Schema> }
.
Otherwise, returns { success: false, error: ZodError }
parse(path: string): z.output<Schema>
Parses the given path
, returning the parsed parameters.
If path
doesn't match the pattern
or schema
, throws a ZodError
.
format(params: z.output<Schema>): BindParams<Pattern, z.output<Schema>
Creates a path from the given params
. If formatSchema
can't parse the params
, throws an error. The return type
can be computed exactly if the params
are passed as const
and have only primitive values.
partialFormat<P extends Partial<z.output<Schema>>>(params: P): BindParams<Pattern, P>
Creates a path or pattern from the given params
. If a
parameter is omitted, the corresponding path segment
(starting with :
) will be preserved in the returned
pattern.
extend<
Subpattern extends string,
Subschema extends SchemaForPattern<Subpattern>,
FormatSubschema extends InvertSchema<Subschema> = InvertSchema<Subschema>
>(
subpattern: Subpattern,
subschema: Subschema,
formatSubschema: FormatSubschema = defaultFormatSchema as any
): ZodRoute<
`${Pattern}/${Subpattern}`,
z.ZodIntersection<Schema, Subschema>,
z.ZodIntersection<FormatSchema, FormatSubschema>
>