Closed jdgamble555 closed 2 months ago
file
& blob
must be added in the customSchemaConversion
in https://github.com/ciscoheat/sveltekit-superforms/blob/1dcb881a61d8bf8074c639834a733652d3878506/src/lib/adapters/valibot.ts#L32
I don't understand. Does it not support all Valibot functions out of the box? What about mimeType
, maxSize
, etc?
Files aren't supported by JSON Schema natively, so it needs to have an explicit custom schema generator. I'm quite sure this has worked before, but Valibot is a 0.x library, so not much to do. It'll be added in the next version.
Until then, you can configure the adapter with that option:
valibot(schema, { customSchemaConversion: {
custom: () => ({}),
instance: () => ({}),
file: () => ({}),
blob: () => ({})
}});
What do you guys mean "not supported?" It is literally in the example on Valibot:
https://valibot.dev/api/file/#examples
I don't know what customSchemaConversion
does. There are no examples in the docs. You guys show me the code, but I don't understand how to use it?
valibot(schema, { customSchemaConversion: {
custom: () => ({}),
instance: () => ({}),
file: () => ({}),
blob: () => ({})
}});
How would I use this?
Thanks,
J
It's not as simple as using your favorite library and validate some data with it. Have you ever wondered how Superforms can conjure default values for schemas, create browser constraints, map errors to correct paths and transform posted form data into the correct types, for nine different validation libraries?
It can only be done consistently if there is a underlying unified data format for all of them.
That format is called JSON Schema. Using a validation schema to JSON Schema library, like the very well written one for Valibot, it's possible to handle the primitive types quite easily, those that can be directly serialized to JSON, but there are others like Date
and, File
of course, that cannot be directly converted to JSON Schema, because there is no standard for them.
So when we say "not supported", even though Valibot and many others validate files, you cannot directly convert the schema for file validation to JSON Schema. A custom schema conversion is required, that will say "here's how I want files to be handled".
Now, to solve your problem. You have used superValidate before, right?
const form = await superValidate(valibot(schema));
Solution: Add the option object you're wondering about as a second parameter to the valibot
function. It will make files and blobs pass through the converter (but not pass through the validator, of course. I hope you know the difference by now.)
I don't know what customSchemaConversion does. There are no examples in the docs. You guys show me the code, but I don't understand how to use it?
That's how it is with open source software, everyone's time is limited, so when you don't pay with money, you pay with your time. Now I've spent plenty of time explaining this to you, so I hope you can pay it forward somehow.
Hi @ciscoheat,
I appreciate the basic explanation, but that is not my issue.
What I'm not understanding are two things.
1.) Why is this possible with zod
but not valibot
:
https://superforms.rocks/concepts/files
Should I use the image: optional(instance(File))
instead? This seems like a work-around. I'm assuming this means the core converter has not been added for valibot... yet?
2.) This still doesn't explain how to use this:
valibot(schema, { customSchemaConversion: {
custom: () => ({}),
instance: () => ({}),
file: () => ({
// what goes here?
}),
blob: () => ({})
}});
This seems like something that should be in the docs. Where can I find how to use customSchemaConversion
(a link, not asking anyone to write anything for me).
Thanks,
J
1.) Why is this possible with
zod
but notvalibot
:
The Zod to JSON Schema library isn't as strict as the Valibot one. It converts File
(or rather, instanceof
) validators to an any
type, which again isn't used in validation, but in the data conversion, when providing default values, etc.
The Valibot converter requires you to be more explicit, which in combination with 0.x versions can lead to these kind of issues.
Should I use the
image: optional(instance(File))
instead? This seems like a work-around. I'm assuming this means the core converter has not been added for valibot... yet?
No, just add the option object as-is. It's just a matter of being explicit.
2.) This still doesn't explain how to use this:
valibot(schema, { customSchemaConversion: { custom: () => ({}), instance: () => ({}), file: () => ({ // what goes here? }), blob: () => ({}) }});
Nothing goes there, {}
is the same as any
in the JSON Schema definition, which is a bit confusing, but it represents a validator object without any validation. Read more about it here: https://json-schema.org/understanding-json-schema/basics
Again, the any
type is not used in validation, but as metadata for the default values, constraints, etc, so it's safe to use. Validation itself is handled by Valibot, not by the JSON Schema.
This seems like something that should be in the docs. Where can I find how to use
customSchemaConversion
(a link, not asking anyone to write anything for me).
It's tied to the Valibot JSON Schema library, so: https://github.com/gcornut/valibot-json-schema?tab=readme-ov-file#custom-schema-conversion
In the next version, it won't be a problem anymore since I will add the conversions to the default options for the adapter. Until the next missing schema type comes up, of course... ;)
I could link to the respective JSON Schema converter for each adapter, but it's rare to configure them, and some are directly in the library code due to ESM/bundle issues, others only have a simple representation due to not being convertible to JSON Schema (see my blog post about this), so I'm not sure how to make the docs for that succinct and useful.
Thanks,
Thank you for sponsoring, it's very much appreciated!
Should be working without any customSchemaConversion now in 2.17.0
Description When creating a schema with
file
orblob
, I get:using something like:
J