标准 JSON 架构: 错误和缺失的转换
作者: AbdelrahmanHafez创建于 2026年4月8日更新于 2026年4月11日
标签bug
问题:其他目标…
什么问题你在试图解决呢?
~standard.jsonSchema 输出中的两个错误和几个缺失的转换:
错误:
1. alternatives.match('all') 生成 anyOf 而不是 allOf
const schema = Joi.alternatives().try(Joi.string(), Joi.number()).match('all');
const json = schema['~standard'].jsonSchema.input();
// 实际: { anyOf: [...] }
// 预期: { allOf: [...] }alternatives.js 中的代码只检查 match('one') -> oneOf,然后对其他所有内容使用 anyOf:
const matchMode = schema._flags.match ?? 'any';
if (matchMode === 'one') {
res.oneOf = matches;
}
else {
res.anyOf = matches; // 'all' 也会在这里出现
}2. 使用 Joi.ref() 而不是字面值的规则生成无效的 JSON Schema
当一个规则接收 Joi.ref() 而不是一个字面值时,Ref 对象会直接被赋值为 JSON Schema 关键字值:
const schema = Joi.number().min(Joi.ref('other'));
const json = schema['~standard'].jsonSchema.input();
// 生成: { type: 'number', minimum: { ref: ... } }
// 这不是有效的 JSON Schema数字、字符串和数组规则不检查 arg 是否为 Ref 之前就将其赋值。日期规则部分地处理了这个问题,通过检查 date instanceof Date,但其他类型则完全不进行保护。
由于 refs 根据运行时值(而不是 schema 定义)进行解析,因此没有标准的 JSON Schema 等效值。2020-12 版草案中没有 $data 关键字或跨字段引用机制。修复方法是,如果 arg 是一个 Ref,则跳过发布约束,类似于日期规则已经跳过 arg 不是 Date 实例的情况。
内容来源: hapijs/joi