diff --git a/src/codecTools/toJsonSchema.ts b/src/codecTools/toJsonSchema.ts index 4a6d77a..c031420 100644 --- a/src/codecTools/toJsonSchema.ts +++ b/src/codecTools/toJsonSchema.ts @@ -25,6 +25,7 @@ type MappableType = /** * Convert an io-ts codec to a JSON Schema (v7) + * * @param _type - an io-ts codec * @param strict - whether to enable strict mode * @param alwaysIncludeRequired - whether to always include required fields (OpenAI requires this) @@ -63,13 +64,28 @@ export const toJsonSchema = ( ), }; } - if (type._tag === 'IntersectionType') { + if (type._tag === 'IntersectionType' && !alwaysIncludeRequired) { return { allOf: type.types.map((t: any) => toJsonSchema(t, strict, alwaysIncludeRequired), ), }; } + if (type._tag === 'IntersectionType' && alwaysIncludeRequired) { + const results = type.types.map((t: any) => + toJsonSchema(t, strict, alwaysIncludeRequired), + ); + if (!results.every((r) => r.type === 'object')) { + throw new Error('InterfaceType must have all children as type=object'); + } + return { + type: 'object', + required: results.map((r) => r.required).flat(), + properties: results.reduce((acc, r) => ({ ...acc, ...r.properties }), {}), + ...(strict ? { additionalProperties: false } : {}), + }; + } + if (type._tag === 'InterfaceType') { return { type: 'object',