Skip to content

Commit b78e4d6

Browse files
committed
feat: Add validation support (Zod & others)
1 parent 4023b6b commit b78e4d6

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

packages/nuqs/src/parsers.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ export type ParserBuilder<T> = Required<Parser<T>> &
4040
*/
4141
withOptions<This, Shallow>(this: This, options: Options<Shallow>): This
4242

43+
/**
44+
* Pass in a validation function to perform runtime checks on the parsed
45+
* value. If the validation fails, the value will be set to `null` (or
46+
* the default value if specified).
47+
*
48+
* Validation must be synchronous, and must throw an error on invalid
49+
* inputs.
50+
*
51+
* Example with Zod:
52+
* ```ts
53+
* const [posInt, setPosInt] = useQueryState(
54+
* 'value',
55+
* parseAsInteger.withValidation(z.number().positive().parse)
56+
* )
57+
* ```
58+
*
59+
* @param this
60+
* @param validate
61+
*/
62+
withValidation<This>(this: This, validate: (input: unknown) => T): This
63+
4364
/**
4465
* Specifying a default value makes the hook state non-nullable when the
4566
* query is missing from the URL.
@@ -119,6 +140,18 @@ export function createParser<T>(
119140
eq: (a, b) => a === b,
120141
...parser,
121142
parseServerSide: parseServerSideNullable,
143+
withValidation(validate) {
144+
return {
145+
...this,
146+
parse: (value: string) => {
147+
const parsed = parser.parse(value)
148+
if (parsed === null) {
149+
return null
150+
}
151+
return validate(parsed)
152+
}
153+
}
154+
},
122155
withDefault(defaultValue) {
123156
return {
124157
...this,
@@ -128,7 +161,7 @@ export function createParser<T>(
128161
}
129162
}
130163
},
131-
withOptions(options: Options) {
164+
withOptions(options) {
132165
return {
133166
...this,
134167
...options

0 commit comments

Comments
 (0)