svelte-jsoneditor
svelte-jsoneditor copied to clipboard
Using Ajv extentions with createAjvValidator.
I would like to use the default Ajv validator with custom errormessages (using this Ajv extention. There seems no way to use extentions with the default createAjvValidator method, however. Would it be possible to add this functionality or, if that is too much work/not a priority, make a snippet explaining how this can be done? I tried making my own Ajv validator but there is no documentation for this and I couldn't get it to work.
You can find the code of createAjvValidator
here: /src/lib/plugins/validator/createAjvValidator.ts. You can just copy that code and change it to your needs. It could be interesting to think though if we can make the provided createAjvValidator
a bit more flexible, so you can for example pass you're own ajv
instance or can hook up an extension like the one you're using. I'm open to proposals.
What JSONEditor
expects when you configure a validator
is something of type Validator
: a function that has the JSON document as input, and a list with errors as output.
https://github.com/josdejong/svelte-jsoneditor/blob/8f678228eb2c7e17e968ce38e573fa2a0e17b8d0/src/lib/types.ts#L175
It would be great if addFormats(ajv)
(https://ajv.js.org/packages/ajv-formats.html#usage) is added to createAjvValidator
, because current "default" behavior does not support format JSONSchema keyword at all (no formats are supported out of the box, they are in a separate plugin). So when passing a schema with any "format" option, an unhandled error is raised.
Yes that makes sense. Ideally, you have access to the created ajv
instance to invoke methods like addFormats
Maybe we can introduce a forth, optional argument allowing to pass a callback onCreateAjv
. This callback can be used to invoke addFormats
and other methods, or you can even return a different ajv instance if you want.
export function createAjvValidator(
schema: JSONValue,
schemaDefinitions?: JSONValue,
ajvOptions?: Options,
onCreateAjv?: (ajv: Ajv) => Ajv | undefined
): Validator {
// ...
}
Having four arguments of which three are optional is a bit ugly, so I think we should wrap this into an object so we have named parameters and no required order, like:
export function createAjvValidator({
schema: JSONValue,
schemaDefinitions?: JSONValue,
ajvOptions?: Options,
onCreateAjv?: (ajv: Ajv) => Ajv | undefined
}): Validator {
// ...
}
What do you think?
That sound good. However if ajv instance is not passed, addFormats() should be anyway called on created instance, otherwise most schemas are not recognized by default validator. Even with simple "date" format.
Yes indeed, so you can use this calllback onCreateAjv
in two ways:
- do some additional configuration on the provided ajv instance:
function onCreateAjv(ajv: Ajv) { ajv.addFormats(...) }
- create your own ajv instance and ignore the provided ajv instance:
function onCreateAjv(ajv: Ajv) { const myAjv = new Ajv(...) myAjv.addFormats(...) return myAjv }
This looks like a very clean solutions, because one of the problems I encountered as well, is that you would need to import Ajv seperately from svelte-jsoneditor or install it again via npm to customise it. This way, you would only have to install the plugin and add it inside the function.
The new onCreateAjv
callback is implemented now in v0.10.0
.