wjarjoui
wjarjoui13mo ago

Skip schema validation for object arguments

I would like to use v.object() without passing a specific schema to validate
6 Replies
ian
ian13mo ago
Here are a few options: 1. use v.any() and then check with typeof & "object" 2. Use v.optional for every known field (doesn't work if you don't know all the fields)
v.object({
fieldA: v.optional(v.string()),
...
})
v.object({
fieldA: v.optional(v.string()),
...
})
Then you could pass in empty objects and have it pass. I wouldn't really recommend this, as you probably want all-or-nothing 3. use v.optional around the whole object, to avoid validating the object when not present
v.optional(v.object({
fieldA: v.string(),
}))
v.optional(v.object({
fieldA: v.string(),
}))
This doesn't work if you don't know the fields I'd like us to add a v.object that doesn't require every field to be specified, but we don't yet. To get around this in my apps I've done something like:
const { fieldA, fieldB, ...rest } = data;
ctx.db.insert("mytable", { fieldA, fieldB, rest });
const { fieldA, fieldB, ...rest } = data;
ctx.db.insert("mytable", { fieldA, fieldB, rest });
with a schema like:
mytable: defineTable({
fieldA: v.string(),
fieldB: v.number(),
rest: v.any()
});
mytable: defineTable({
fieldA: v.string(),
fieldB: v.number(),
rest: v.any()
});
that way you can store what you know to be there, and keep the rest around if you ever need it. You can cast it doc.rest as object in typescript, since you only put objects in there
wjarjoui
wjarjouiOP13mo ago
Sure, just want to be clear that right now I'm passing in data to a function validator, there is no database table being used in the use case. this is not a blocker, so if we track it as a feature request I am OK waiting for supporting the schema argument itself being optional
ian
ian13mo ago
ah gotcha. so something like
const myQuery = query({
args: {
fieldA: v.string(),
fieldB: v.number(),
rest: v.any()
},
handler: ...
});
const myQuery = query({
args: {
fieldA: v.string(),
fieldB: v.number(),
rest: v.any()
},
handler: ...
});
all of these options work for both arguments and schema. out of curiosity, why do you want to skip validation on them? too annoying to turn the typescript type into a validator? If I built a tool to convert TypeScript into a validator, would that be helpful? and just in case your question is for something already supported:
const myQuery = query({
args: {
someUnknownObject: v.optional(v.any()),
},
handler: ...
});
const myQuery = query({
args: {
someUnknownObject: v.optional(v.any()),
},
handler: ...
});
this already works and lets you pass anything or nothing as the parameter
wjarjoui
wjarjouiOP13mo ago
the specific use case is this. I need to make a downstream JSON request, and I'm abstracting it so that when we change the underlying request library I can do it one place. So I have a postJSON that accepts a body parameter. I would like that parameter to be an object, I don't want the caller to have to JSON.stringify, but obviously since it's a generic function the body schema is not static. The simplest workaround is to simply use v.string() instead of v.object(), so that's what I'm doing for now.
ian
ian13mo ago
I would use v.any() as the type, and do a check for typeof args.body === 'object' && !Array.isArray(args.body) v.any() allows any object or string or number or... JSON.stringify won't guarantee it's an object - it'll serialize & deserialize an array too, so I think v.any is just as safe as passing it as a json string
wjarjoui
wjarjouiOP13mo ago
good point about array & object ok will do that, thanks for your time on this! unrelated - see my message in #general regarding timeouts

Did you find this page helpful?