Skip to content

Commit eef7987

Browse files
committed
added example of #190
1 parent 5aea9f0 commit eef7987

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

example/zod/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,70 @@ You can use zod [extend API](https://github.com/colinhacks/zod#extend).
88
const AttributeInputSchemaWithCUID = AttributeInputSchema().extend({
99
key: z.string().cuid(),
1010
});
11+
```
12+
13+
## Apply input validator via ts decorator
14+
15+
Validate the input object via typescript decorators when implementing resolvers. See: #190
16+
17+
### Usage
18+
19+
```ts
20+
class Mutation {
21+
@validateInput(SignupInputSchema)
22+
async signup(
23+
_root: Record<string, never>,
24+
{ input: { email, password } }: MutationSignupArgs,
25+
context: Context
26+
): Promise<SignupPayload> {
27+
// The input here is automatically valid to adhere to SignupInputSchema
28+
}
29+
}
30+
```
31+
32+
### Implementation:
33+
34+
```ts
35+
type ZodResolver<T extends ZodType<any, any, any>> = ResolverFn<
36+
any,
37+
any,
38+
any,
39+
{ input: TypeOf<T> }
40+
>
41+
42+
/**
43+
* Method decorator that validates the argument of the target function against the given schema.
44+
*
45+
* @export
46+
* @template T The type of the zod schema.
47+
* @param {T} arg The zod schema used for the validation.
48+
* @return {MethodDecorator} A {@link MethodDecorator}.
49+
*/
50+
export function validateInput<T extends AnyZodObject>(
51+
arg: T | (() => T)
52+
): MethodDecorator<ZodResolver<T>> {
53+
return function (_target, _propertyKey, descriptor) {
54+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
55+
const originalMethod = descriptor.value!
56+
// @ts-expect-error: should be fine
57+
descriptor.value = function (root, { input }, context, info) {
58+
const schema = typeof arg === 'function' ? arg() : arg
59+
const result = schema.safeParse(input)
60+
61+
if (result.success) {
62+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
63+
return originalMethod.call(
64+
this,
65+
root,
66+
{ input: result.data },
67+
context,
68+
info
69+
)
70+
} else {
71+
return { problems: result.error.issues }
72+
}
73+
}
74+
return descriptor
75+
}
76+
}
1177
```

0 commit comments

Comments
 (0)