fastify / fastify/fast-json-stringify
oneOf schemas not matching when an object has a custom toJSON() method
- Dominant language
- JavaScript
- Stars
- 3.7k
- Forks
- 226
- Avg merge
- 1d 59m
- Merged PRs (30d)
- 3
Description
### Prerequisites
- [X] I have written a descriptive issue title
- [X] I have searched existing issues to ensure the bug has not already been reported
### Fastify version
4.15.0
### Plugin version
_No response_
### Node.js version
18.12.1
### Operating system
Linux
### Operating system version (i.e. 20.04, 11.3, 10)
Ubuntu 22.10
### Description
`toJSON()` is not called on objects before attempting to match a schema in `oneOf`, resulting in an error "does not match schema definition". When oneOf is not used, the same schema matches, works, and serializes.
### Steps to Reproduce
```js
const fastJson = require('fast-json-stringify');
// schema using oneOf
const stringifyOneOf = fastJson({
description: 'transfer failed.',
oneOf: [
{
type: 'object',
description: 'Invalid withdrawal address provided.',
properties: {
error: { type: 'string', const: 'INVALID_ADDRESS' },
},
required: ['error'],
additionalProperties: false,
},
{
type: 'object',
description: 'Cannot afford this transfer + fee.',
properties: {
error: { type: 'string', const: 'INSUFFICIENT_ACCOUNT_BALANCE' },
balance: {
type: 'object',
description: 'Available balance for this currency.',
properties: {
value: { type: 'string' },
currency: { type: 'string' },
},
additionalProperties: false,
required: ['value', 'currency'],
},
},
required: ['error', 'balance'],
additionalProperties: false,
},
],
});
// schema with no oneOf
const stringify = fastJson({
type: 'object',
description: 'Cannot afford this transfer + fee.',
properties: {
error: { type: 'string', const: 'INSUFFICIENT_ACCOUNT_BALANCE' },
balance: {
type: 'object',
description: 'Available balance for this currency.',
properties: {
value: { type: 'string' },
currency: { type: 'string' },
},
additionalProperties: false,
required: ['value', 'currency'],
},
},
required: ['error', 'balance'],
additionalProperties: false,
});
// custom class with toJSON() method
class Balance {
constructor(value, currency) {
this._value = value;
this._currency = currency;
}
toJSON() {
return {
value: this._value,
currency: this._currency,
};
}
}
const balance = new Balance(100, 'USD');
// will throw 'The value of '#' does not match schema definition.'
console.log(stringifyOneOf({
error: 'INSUFFICIENT_ACCOUNT_BALANCE',
balance,
}));
// stringifies as expected
console.log(stringify({
error: 'INSUFFICIENT_ACCOUNT_BALANCE',
balance,
}));
```
### Expected Behavior
the schema inside `oneOf` should match as it is the same schema that works when used outside of `oneOf` - `toJSON()` not called on objects before matching?
Contributor guide
Assessment
This issue has not been assessed yet.