fix(omptype): restored required-first wire ordering and defaulted optional keys

- Restored required-before-optional property ordering in JSON Schema emission; downstream wire consumers (pi-ai toolWireSchema) rely on that stable ordering.
- Mapped Type.Optional with a default to a plain defaulted key in the TypeBox shim, since omptype (like ArkType) rejects optional keys that specify defaults.
This commit is contained in:
can1357
2026-08-04 18:25:07 +02:00
parent 003bb5548c
commit fc7cd30bd1
2 changed files with 9 additions and 2 deletions
+4 -1
View File
@@ -273,7 +273,10 @@ function emitObject(
const properties: Record<string, unknown> = {};
const required: string[] = [];
const filled = (prop: PropIR): boolean => !prop.opt && (ctx.options?.io === "output" || !prop.hasDefault);
for (const prop of props) {
// ArkType emits required properties first (each group in declaration
// order); downstream wire consumers rely on that stable ordering.
const ordered = [...props.filter(filled), ...props.filter(prop => !filled(prop))];
for (const prop of ordered) {
if (typeof prop.key === "symbol") throw new TypeError("Cannot convert a symbol to a string");
const key = String(prop.key);
const propertySchema = emit(prop.val, ctx);
+5 -1
View File
@@ -401,7 +401,11 @@ function tObject<const P extends Record<string, AnySchema>>(properties: P, opts?
for (const key in properties) {
const schema = properties[key];
const inner = asRuntime<unknown>(schema)[OPTIONAL_INNER];
def[inner ? `${key}?` : key] = inner ?? schema;
// A defaulted `Type.Optional(...)` maps to a plain defaulted key:
// omptype (like ArkType) rejects `key?` with a default, and a default
// already makes the key omittable on input.
const optionalKey = inner !== undefined && !asRuntime<unknown>(inner).hasDefault;
def[optionalKey ? `${key}?` : key] = inner ?? schema;
props[key] = schema;
}
if (opts?.additionalProperties === false) def["+"] = "reject";