Skip to content

Commit 24d5c2c

Browse files
authored
fix: support discriminated union json schema (oneOf) (#666)
1 parent f3f6b23 commit 24d5c2c

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

src/lib/formData.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ function _parseFormData<T extends Record<string, unknown>>(
204204
} else {
205205
let unionKeys: string[] = [];
206206

207-
// Special fix for union schemas, then the keys must be gathered from the objects in the union
208-
if (schema.anyOf) {
207+
// Special fix for (discriminated) union schemas, then the keys must be gathered from the objects in the union
208+
if (schema.anyOf || schema.oneOf) {
209209
const info = schemaInfo(schema, false, []);
210210
if (info.union?.some((s) => s.type !== 'object')) {
211211
throw new SchemaError('All form types must be an object if schema is a union.');

src/lib/jsonSchema/schemaInfo.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const conversionFormatTypes = [
4141
];
4242

4343
/**
44-
* Normalizes the different kind of schema variations (anyOf, union, const null, etc)
44+
* Normalizes the different kind of schema variations (anyOf, oneOf, union, const null, etc)
4545
* to figure out the field type, optional, nullable, etc.
4646
*/
4747
export function schemaInfo(
@@ -121,6 +121,9 @@ function schemaTypes(
121121
if (schema.anyOf) {
122122
types = schema.anyOf.flatMap((s) => schemaTypes(s, path));
123123
}
124+
if (schema.oneOf) {
125+
types = schema.oneOf.flatMap((s) => schemaTypes(s, path));
126+
}
124127

125128
if (types.includes('array') && schema.uniqueItems) {
126129
const i = types.findIndex((t) => t === 'array');
@@ -158,6 +161,12 @@ function schemaTypes(
158161
}
159162

160163
function unionInfo(schema: JSONSchema7) {
161-
if (!schema.anyOf || !schema.anyOf.length) return undefined;
162-
return schema.anyOf.filter((s) => typeof s !== 'boolean') as JSONSchema7[];
164+
if (!schema.oneOf && !schema.anyOf) return undefined;
165+
if (schema.oneOf && schema.oneOf.length) {
166+
return schema.oneOf.filter((s) => typeof s !== 'boolean') as JSONSchema7[];
167+
}
168+
if (schema.anyOf && schema.anyOf.length) {
169+
return schema.anyOf.filter((s) => typeof s !== 'boolean') as JSONSchema7[];
170+
}
171+
return undefined;
163172
}

0 commit comments

Comments
 (0)