Skip to content

Commit

Permalink
Default values for nested discriminated unions didn't work.
Browse files Browse the repository at this point in the history
Fixes #519
  • Loading branch information
ciscoheat committed Dec 4, 2024
1 parent 6a2f286 commit cf79677
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Headlines: Added, Changed, Deprecated, Removed, Fixed, Security
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.21.1] - 2024-12-04

### Fixed

- Default values for nested discriminated unions didn't work.

## [2.21.0] - 2024-12-01

### Fixed
Expand Down
9 changes: 2 additions & 7 deletions src/lib/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,9 @@ export function replaceInvalidDefaults<T extends Record<string, unknown>>(
}

const fieldType = pathTypes.value ?? defaultType;
if (!fieldType) {
throw new SchemaError(
'No default value specified for field (can be undefined, but must be explicit)',
currentPath
);
if (fieldType) {
Data_setValue(currentPath, Types_correctValue(dataValue, defValue, fieldType));
}

Data_setValue(currentPath, Types_correctValue(dataValue, defValue, fieldType));
}
}

Expand Down
51 changes: 45 additions & 6 deletions src/tests/zodUnion.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { ValidationAdapter } from '$lib/adapters/adapters.js';
import type { Infer, ValidationAdapter } from '$lib/adapters/adapters.js';
import { zod } from '$lib/adapters/zod.js';
import { superValidate } from '$lib/superValidate.js';
import { stringify } from 'devalue';
import { describe, expect, test } from 'vitest';
import { assert, describe, expect, test } from 'vitest';
import { z } from 'zod';

async function validate(
data: unknown,
schema: ValidationAdapter<Record<string, unknown>>,
async function validate<T extends Record<string, unknown>>(
data: T,
schema: ValidationAdapter<T>,
strict = false
) {
const formInput = new FormData();
Expand Down Expand Up @@ -35,10 +35,49 @@ describe('Default discriminated union values 1', () => {
});

test('Union with schema 2', async () => {
const form = await validate({ type: 'extra' }, zod(schema), true);
const form = await validate({ type: 'extra' } as Infer<typeof schema>, zod(schema), true);
expect(form.valid).toBe(false);
expect(form.data).toEqual({ type: 'extra', options: [] });
});

test('Nested discriminated union with default value', async () => {
const nested = z.object({
addresses: z.object({
additional: z
.discriminatedUnion('type', [
z.object({
type: z.literal('poBox'),
name: z.string().min(1, 'min len').max(10, 'max len')
}),
z.object({
type: z.literal('none')
})
])
.default({
type: 'none'
})
})
});

const form1 = await superValidate(zod(nested));
expect(form1.data.addresses.additional).toEqual({ type: 'none' });

const form2 = await validate(
{
addresses: {
additional: {
type: 'poBox',
name: '#123'
}
}
},
zod(nested)
);

expect(form2.valid).toBe(true);
assert(form2.data.addresses.additional?.type === 'poBox');
expect(form2.data.addresses.additional.name).toBe('#123');
});
});

describe('Default discriminated union values 2', () => {
Expand Down

0 comments on commit cf79677

Please sign in to comment.