Valibot 转 OpenAPI 3.0 报 gt_value 不支持
to-json-schema 1.8.0 对严格数值边界拒绝转换,忽略错误会丢失限制。只对已确认的动作做精确覆盖,使用OpenAPI3.0的布尔排他标记。
把正数且小于10的Valibot字段转换为OpenAPI3.0,生成过程抛出:
The "gt_value" action is not supported for OpenAPI 3.0.
若改成 errorMode: 'ignore' 后只得到 { type: 'number' },错误虽然消失,0和10也失去了原来应有的限制。文档生成成功不能以牺牲输入约束为代价。
3.0用布尔标记表达排他边界
OpenAPI3.0可以用minimum配合exclusiveMinimum: true表达严格大于,用maximum配合exclusiveMaximum: true表达严格小于。3.1采用的JSON Schema语义不同,不能直接把数值形式的exclusiveMinimum照搬进3.0文档。
在Valibot1.5.0、to-json-schema1.8.0中,转换器遇到gtValue或ltValue且目标是openapi-3.0,会先记录不支持错误。overrideAction在错误最终处理之前运行,能为经过核对的动作提供局部结果。
只覆盖当前两个已知动作
下面的规则只包含这两个边界,没有另外的minValue或maxValue参与合并:
import * as v from 'valibot';
import { toJsonSchema } from '@valibot/to-json-schema';
const lower = v.gtValue(0);
const upper = v.ltValue(10);
const schema = v.pipe(v.number(), lower, upper);
const jsonSchema = toJsonSchema(schema, {
target: 'openapi-3.0',
overrideAction: ({ valibotAction, jsonSchema }) => {
if (valibotAction === lower) {
return { ...jsonSchema, minimum: 0, exclusiveMinimum: true };
}
if (valibotAction === upper) {
return { ...jsonSchema, maximum: 10, exclusiveMaximum: true };
}
},
});
通过动作实例身份限制范围,避免把整个项目里所有gtValue都套进这两个常量。其余转换错误仍按原规则处理,已有生成字段通过展开保留。
这个覆盖不是通用数值范围合并器。若又增加minValue(5),真正的下界应是5且不排他;若minValue(0)与gtValue(0)并存,0仍应被排除。顺序不同也必须得到同一组允许值,不能依靠最后一次赋值碰巧正确。
override入口本身标记为beta,项目升级转换器时应重新核对接口及生成结果。当前正式1.8.0仍有该限制,不把临时覆盖写成自动修复已发布。
检查边界值和最终消费方
将生成结果交给实际使用的OpenAPI3.0校验或工具链,核对0、10被拒绝,中间合法数值被接受。还要覆盖负数、错误类型、字段必填和原来存在的其他条件。不要只在接受3.1格式的工具里验证3.0文档。
改用OpenAPI3.1是另一项协议迁移,需要下游文档、SDK和网关共同支持;不能为了绕过这条转换错误就只改一个版本字符串。局部覆盖撤回或依赖升级后,仍应保留这些边界样例,确认运行期和公开接口说明没有分歧。


