Open WebServiceTeam opened 9 years ago
If you pass a function as the default to a Joi schema, you'll see it in the JSON Schema. What value would you expect to see? The problem here is that the schema does have a default so returning null or no default in the JSON Schema would not be representative of the original. As a solution, you might consider post-processing the result of the conversion to remove (or otherwise manipulate) any instance of /default:\s\[Object\],?/
The problem is you just get the string representation of the function, which can break validation for types. In the case above, the literal value Date.now fails the date-time format validation.
I would expect that if the default in joi was set to a function (and not the output of a function invocation, which should pass through post-evaluation), default would just be omitted from the JSON schema conversion since the string representation of the function is meaningless.
Hmm..but as I wrote above, that would indicate that the value had no default, which is not true.
Yes, but setting the default to a function in Joi is a special Joi-specific instruction to use the function as a generator, and JSON schema has no concept of generators. Maybe it could be interpreted as required?
You could also provide a transformer as the second argument to the convert() function to convert unacceptable values to whatever you'd like.
Sorry, I logged this issue from my shared company Github account instead of my personal. I just think that since your module is providing a translation from Javascript to JSON, it shouldn't try to convert types that aren't valid in JSON, functions inclusive. If I try to JSON.stringify() a function, it comes back undefined.
Here's a start for writing your own transformer:
var util=require('util'),
joi=require('joi'),
convert=require('joi-to-json-schema');
var s=joi.object({
created: joi.date().default(Date.now,'date for now')
});
console.log(convert(s,function(elt){
console.log('elt:'+util.inspect(arguments,{depth:null}));
return elt;
}));
And I do understand your point. I'll mark this as a bug and see what I can do.
If I have a joi schema like this:
joi.object().keys({ foo: joi.string().default('foo'), bar: joi.string().default('bar'), created: joi.date().default(Date.now, 'generated'), updated: joi.date().default(Date.now, 'generated') })
And I don't want the function defaults to come through into the json schema export, but I do want the static defaults, how do I achieve that?
By just calling convert(schema) by default I get this:
{ type: 'object', properties: { foo: { default: 'foo', type: 'string' }, bar: { default: 'bar', type: 'string' }, created: { default: [Object], type: 'string', format: 'date-time' }, updated: { default: [Object], type: 'string', format: 'date-time' }, }, additionalProperties: false }
That [Object] is the Date.now function