Help with circular schemas #673
-
Hi there! I'm looking into using Valibot for objects that have internal circular relations, but I'm running into issues and hoping I could get some guidance. For example: const user = {
firstName: 'joe',
$relations: {
// will be assigned farther down
UserToAuth: undefined
}
}
const auth = {
email: 'joe@example.com',
password: '1234',
$relations: {
// will be assigned farther down
UserToAuth: undefined
}
}
const userToAuthRelation = {
from: user,
to: auth
}
user.$relations.UserToAuth = userToAuthRelation
auth.$relations.UserToAuth = userToAuthRelation I tried implementing Valibot schemas to validate these objects using const UserSchema = v.object({
firstName: v.string(),
$relations: v.object({
UserToCredentials: v.lazy(() => UserToAuthRelationSchema)
})
})
const AuthSchema = v.object({
email: v.pipe(v.string(), v.email()),
password: v.pipe(v.string(), v.minLength(8)),
$relations: v.object({
UserToCredentials: v.lazy(() => UserToAuthRelationSchema)
})
})
type TUserToAuthRelationSchema = {
from: v.InferOutput<typeof UserSchema>
to: v.InferOutput<typeof AuthSchema>
}
const UserToAuthRelationSchema: v.GenericSchema<
TUserToAuthRelationSchema
> = v.pipe(
v.object({
from: v.lazy(() => UserSchema),
to: v.lazy(() => AuthSchema),
}),
v.check((input) => !!input && typeof input === 'object')
) I was able to get the TS types working as expected, but when I call I'm wondering if there's something I am doing wrong or if Valibot is not the right solution for this? I've created a repro example in a few places for convenience:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
I think the main problem is that your data contains a circular reference, which leads to a parse execution that never ends. |
Beta Was this translation helpful? Give feedback.
I think the main problem is that your data contains a circular reference, which leads to a parse execution that never ends.
lazy
is intended for recursive schemas like binary trees that end at some point. I think we could technically solve this problem by memorizing whatlazy
does, but the main question for me is whether this is outside the scope of Valibot. Maybe you should validate the data before it is mapped to be circular.