Skip to content

Commit 819f3ee

Browse files
committed
WIP: Untested validators function in onSubmit
1 parent e2c4a64 commit 819f3ee

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

src/lib/client/superForm.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ export type FormResult<T extends Record<string, unknown> | null> = ActionResult<
5858

5959
export type TaintOption = boolean | 'untaint' | 'untaint-all' | 'untaint-form';
6060

61+
type ValidatorsOption<T extends Record<string, unknown>> =
62+
| ValidationAdapter<Partial<T>, Record<string, unknown>>
63+
| false
64+
| 'clear';
65+
6166
// Need to distribute T with "T extends T",
6267
// since SuperForm<A|B> is not the same as SuperForm<A> | SuperForm<B>
6368
// https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
@@ -82,7 +87,16 @@ export type FormOptions<
8287
submitOnlyTainted: boolean;
8388
onSubmit: (
8489
input: Parameters<SubmitFunction>[0] & {
90+
/**
91+
* If dataType: 'json' is set, send this data instead of $form when posting,
92+
* and client-side validation for $form passes.
93+
* @param data An object that can be serialized with devalue.
94+
*/
8595
jsonData: (data: Record<string, unknown>) => void;
96+
/**
97+
* Override client validation temporarily for this form submission.
98+
*/
99+
validators: (validators: Exclude<ValidatorsOption<T>, 'clear'>) => void;
86100
}
87101
) => MaybePromise<unknown | void>;
88102
onResult: (event: {
@@ -118,11 +132,7 @@ export type FormOptions<
118132
dataType: 'form' | 'json';
119133
jsonChunkSize: number;
120134
// TODO: Use NoInfer<T> on ClientValidationAdapter when available, so T can be used instead of Partial<T>
121-
validators:
122-
| ClientValidationAdapter<Partial<T>, Record<string, unknown>>
123-
| ValidationAdapter<Partial<T>, Record<string, unknown>>
124-
| false
125-
| 'clear';
135+
validators: ClientValidationAdapter<Partial<T>, Record<string, unknown>> | ValidatorsOption<T>;
126136
validationMethod: 'auto' | 'oninput' | 'onblur' | 'onsubmit' | 'submit-only';
127137
customValidity: boolean;
128138
clearOnSubmit: 'errors' | 'message' | 'errors-and-message' | 'none';
@@ -597,9 +607,9 @@ export function superForm<
597607
}
598608
};
599609

600-
async function Form_validate<Schema extends Partial<T>>(
610+
async function Form_validate(
601611
opts: {
602-
adapter?: ValidationAdapter<Schema>;
612+
adapter?: FormOptions<T, M>['validators'];
603613
recheckValidData?: boolean;
604614
formData?: Record<string, unknown>;
605615
} = {}
@@ -1506,6 +1516,7 @@ export function superForm<
15061516

15071517
return enhance(FormElement, async (submitParams) => {
15081518
let jsonData: Record<string, unknown> | undefined = undefined;
1519+
let validationAdapter = options.validators;
15091520

15101521
const submit = {
15111522
...submitParams,
@@ -1514,6 +1525,9 @@ export function superForm<
15141525
throw new SuperFormError("options.dataType must be set to 'json' to use jsonData.");
15151526
}
15161527
jsonData = data;
1528+
},
1529+
validators(adapter: Exclude<ValidatorsOption<T>, 'clear'>) {
1530+
validationAdapter = adapter;
15171531
}
15181532
};
15191533

@@ -1555,8 +1569,13 @@ export function superForm<
15551569

15561570
let validation: SuperFormValidated<T, M, In> | undefined = undefined;
15571571

1572+
const validateForm = async () => {
1573+
// Validate with onSubmit.jsonData() or (default) Form.data
1574+
return await Form_validate({ adapter: validationAdapter });
1575+
};
1576+
15581577
if (!noValidate) {
1559-
validation = await Form_validate({ formData: jsonData });
1578+
validation = await validateForm();
15601579

15611580
if (!validation.valid) {
15621581
cancel(false);
@@ -1607,7 +1626,7 @@ export function superForm<
16071626

16081627
if (options.SPA) {
16091628
cancel(false);
1610-
if (!validation) validation = await Form_validate({ formData: jsonData });
1629+
if (!validation) validation = await validateForm();
16111630

16121631
const validationResult = { ...validation, posted: true };
16131632

@@ -1623,9 +1642,9 @@ export function superForm<
16231642

16241643
setTimeout(() => validationResponse({ result }), 0);
16251644
} else if (options.dataType === 'json') {
1626-
if (!validation) validation = await Form_validate({ formData: jsonData });
1645+
if (!validation) validation = await validateForm();
16271646

1628-
const postData = clone(validation.data);
1647+
const postData = clone(jsonData ?? validation.data);
16291648

16301649
// Move files to form data, since they cannot be serialized.
16311650
// Will be reassembled in superValidate.

src/routes/(v2)/v2/submit-json/+page.svelte

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<script lang="ts">
2+
import { zod } from '$lib/adapters/zod.js';
23
import { superForm } from '$lib/client/index.js';
4+
import { schema } from './schema.js';
35
46
export let data;
57
68
const { form, errors, message, enhance } = superForm(data.form, {
79
taintedMessage: false,
810
dataType: 'json',
11+
validators: zod(schema),
912
onSubmit({ jsonData }) {
1013
jsonData({ ...$form, email: 'no-email' });
1114
}

0 commit comments

Comments
 (0)