Skip to content

Commit 892c5d5

Browse files
committed
Missing boolean fields were valid in strict mode.
1 parent 6dc5050 commit 892c5d5

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- A successful `PageData` result from `invalidateAll` was overwritten by the `ActionData` result.
2020
- Using `goto` in events didn't work when the target page redirected.
2121
- `FormPath` and `FormPathLeaves` didn't handle fields with type `unknown` and `any`.
22+
- Missing boolean fields were valid in strict mode.
2223

2324
## [2.5.0] - 2024-02-21
2425

src/lib/formData.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,14 @@ function _parseFormData<T extends Record<string, unknown>>(
149149
options?: SuperValidateOptions<T>
150150
) {
151151
const output: Record<string, unknown> = {};
152-
const schemaKeys = new Set(
153-
[
154-
...Object.keys(schema.properties ?? {}),
155-
...(schema.additionalProperties ? formData.keys() : [])
156-
].filter((key) => !key.startsWith('__superform_'))
157-
);
152+
const schemaKeys = options?.strict
153+
? new Set([...formData.keys()].filter((key) => !key.startsWith('__superform_')))
154+
: new Set(
155+
[
156+
...Object.keys(schema.properties ?? {}),
157+
...(schema.additionalProperties ? formData.keys() : [])
158+
].filter((key) => !key.startsWith('__superform_'))
159+
);
158160

159161
function parseSingleEntry(key: string, entry: FormDataEntryValue, info: SchemaInfo) {
160162
if (options?.preprocessed && options.preprocessed.includes(key as keyof T)) {
@@ -246,7 +248,7 @@ function parseFormDataEntry(
246248
info: SchemaInfo
247249
): unknown {
248250
if (!value) {
249-
//console.log(`No FormData for "${key}" (${type}).`, info); //debug
251+
//console.log(`No FormData for "${key}" (${type}).`, info, strict); //debug
250252

251253
// Special case for booleans with default value true
252254
if (type == 'boolean' && info.isOptional && info.schema.default === true) {

src/tests/legacy/strict.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,38 @@ describe('Strict mode', () => {
2929
expect(form.valid).toEqual(true);
3030
});
3131

32+
describe('Should not allow missing boolean fields', () => {
33+
test('With FormData', async () => {
34+
const formData = new FormData();
35+
36+
const schema = z.object({
37+
enabled: z.boolean()
38+
});
39+
40+
const form = await superValidate(formData, zod(schema), {
41+
strict: true
42+
});
43+
44+
expect(form.valid).toBe(false);
45+
expect(form.errors).toEqual({ enabled: ['Required'] });
46+
});
47+
48+
test('With an object', async () => {
49+
const data = {};
50+
51+
const schema = z.object({
52+
enabled: z.boolean()
53+
});
54+
55+
const form = await superValidate(data, zod(schema), {
56+
strict: true
57+
});
58+
59+
expect(form.valid).toBe(false);
60+
expect(form.errors).toEqual({ enabled: ['Required'] });
61+
});
62+
});
63+
3264
const strictTests = [
3365
{
3466
name: 'Should be invalid if foo is not present in object',

0 commit comments

Comments
 (0)