Closed alexnix closed 3 years ago
What exactly is your use case? Is it mapping user input to a mongo objectID? The way myzod does this is via the map method.
const objectIdSchema = z.string().map(value => new ObjectId(value))
Maybe zod might consider doing something like this? Otherwise you can try myzod which is similar to zod.
Yeah, kind of that use case... I found a workaround to use:
z.union([z.any(), userSchema])
with userSchema being the schema of the collection the field would point to. Mongoose will do verify that the input is indeed a correct ObjectID so I am covered from the validation point of view.
I guess the only thing I could ask for now would be for a way to make it infer the type of the field to string | z.infer<typeof userSchema>
(string cause when the object is sent from the the API as JSON, ObjectID becomes a string, and
Hi @alexnix. Sounds like ObjectId
is a class? In that case you should use z.instanceof
:
const User = z.object({
id: z.instanceof(ObjectId)
})
This simply checks that the value passed into the id
property is an intance of the ObjectID class. Docs are at https://github.com/colinhacks/zod#instanceof
Hi @alexnix. Sounds like
ObjectId
is a class? In that case you should usez.instanceof
:const User = z.object({ id: z.instanceof(ObjectId) })
This simply checks that the value passed into the
id
property is an intance of the ObjectID class. Docs are at https://github.com/colinhacks/zod#instanceof
This works as long as you do the check on the server. I had the same problem with my next.js app when I tried to access the schema in my components.
It was an easy fix tho.
const User = z.object({ id: z.instanceof(Object).transform((id) => id.toString()), })
Hi @alexnix. Sounds like
ObjectId
is a class? In that case you should usez.instanceof
:const User = z.object({ id: z.instanceof(ObjectId) })
This simply checks that the value passed into the
id
property is an intance of the ObjectID class. Docs are at https://github.com/colinhacks/zod#instanceof
This doesn't work if It is coming from a HTTP request. are there ways to do that?
This doesn't work if It is coming from a HTTP request. are there ways to do that?
You should be able to use preprocess
Will this work?
import type { ObjectId } from 'bson';
const _id = z.custom<ObjectId>();
Hi, when i try to guess your implementation, i think you probably want to achieve this 😎.
import z from 'zod'
import mongoose from 'mongoose'
const paramsSchema = z.object({
id: z.string().refine((val) => {
return mongoose.Types.ObjectId.isValid(val)
}),
})
//-------
paramsSchema.parse(req.params.id) //pass the validation
While the solution of catnug works, I have found that the solution of bbar works better. So here's it refactored:
import mongoose from 'mongoose'
const schema = z
.object({
_id: z.custom<mongoose.Types.ObjectId>(),
})
The above solutions using instanceof
does not really work if data is coming from an HTTP request.
In my case (data is coming from an HTTP request,) I used
const mongoIdSchema = z.string().regex(/^[0-9a-f]{24}$/);
from joi-objectid
I don't know if it was the best way, but for https requests, the simplest way I found was like this:
// create a schema with zod:
export const getSignSchema = z.object({
id: z.string(),
})
// using schema:
const { id } = getSignSchema.parse(request.params)
const sign = await Sign.findById(new ObjectId(id))
or simple ready solution using https://github.com/validatorjs/validator.js
import isMongoId from 'validator/es/lib/isMongoId'
const schema = z.object({
id: z.string().refine(isMongoId),
})
Update: but be careful sometimes it breaks the scheme better to use regexp solution or rewrite to transform
Why I can't use ObjectId for _id in zod shared types. It is using Turbo Repo to use in backend and frontend.
Hi, when i try to guess your implementation, i think you probably want to achieve this 😎.
import z from 'zod' import mongoose from 'mongoose' const paramsSchema = z.object({ id: z.string().refine((val) => { return mongoose.Types.ObjectId.isValid(val) }), }) //------- paramsSchema.parse(req.params.id) //pass the validation
This one working perfact..
Update: but be careful sometimes it breaks the scheme ...
What you mean?
I am trying to integrate zod with Mongoose but I have an issue.
One of the fields is ObjectID... how should I define this in the schema? I tried z.string() but I does not work (even if I add the ObjectID as a string on my object before saving it, I guess Mongoose internally converts it back to ObjectID before calling the pre-validate hook so in the end I am getting an ObjectID again).
Any workaround? Maybe something like https://github.com/jquense/yup/issues/467