From 6333af11365fdc52ea1de22f4fb7d2b1bef6c8a7 Mon Sep 17 00:00:00 2001 From: arnolicious Date: Thu, 4 Dec 2025 11:40:13 +0100 Subject: [PATCH] fix: support discriminated union json schema (oneOf) --- src/lib/formData.ts | 4 ++-- src/lib/jsonSchema/schemaInfo.ts | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/lib/formData.ts b/src/lib/formData.ts index 7ab25b26..062af0a9 100644 --- a/src/lib/formData.ts +++ b/src/lib/formData.ts @@ -204,8 +204,8 @@ function _parseFormData>( } else { let unionKeys: string[] = []; - // Special fix for union schemas, then the keys must be gathered from the objects in the union - if (schema.anyOf) { + // Special fix for (discriminated) union schemas, then the keys must be gathered from the objects in the union + if (schema.anyOf || schema.oneOf) { const info = schemaInfo(schema, false, []); if (info.union?.some((s) => s.type !== 'object')) { throw new SchemaError('All form types must be an object if schema is a union.'); diff --git a/src/lib/jsonSchema/schemaInfo.ts b/src/lib/jsonSchema/schemaInfo.ts index ac1b60cf..74a4ee0c 100644 --- a/src/lib/jsonSchema/schemaInfo.ts +++ b/src/lib/jsonSchema/schemaInfo.ts @@ -41,7 +41,7 @@ const conversionFormatTypes = [ ]; /** - * Normalizes the different kind of schema variations (anyOf, union, const null, etc) + * Normalizes the different kind of schema variations (anyOf, oneOf, union, const null, etc) * to figure out the field type, optional, nullable, etc. */ export function schemaInfo( @@ -121,6 +121,9 @@ function schemaTypes( if (schema.anyOf) { types = schema.anyOf.flatMap((s) => schemaTypes(s, path)); } + if (schema.oneOf) { + types = schema.oneOf.flatMap((s) => schemaTypes(s, path)); + } if (types.includes('array') && schema.uniqueItems) { const i = types.findIndex((t) => t === 'array'); @@ -158,6 +161,12 @@ function schemaTypes( } function unionInfo(schema: JSONSchema7) { - if (!schema.anyOf || !schema.anyOf.length) return undefined; - return schema.anyOf.filter((s) => typeof s !== 'boolean') as JSONSchema7[]; + if (!schema.oneOf && !schema.anyOf) return undefined; + if (schema.oneOf && schema.oneOf.length) { + return schema.oneOf.filter((s) => typeof s !== 'boolean') as JSONSchema7[]; + } + if (schema.anyOf && schema.anyOf.length) { + return schema.anyOf.filter((s) => typeof s !== 'boolean') as JSONSchema7[]; + } + return undefined; }