Skip to content

Commit 61f296a

Browse files
committed
Validating entire structure for Zod schemas.
1 parent 451e101 commit 61f296a

File tree

3 files changed

+9
-67
lines changed

3 files changed

+9
-67
lines changed

src/lib/client/index.ts

Lines changed: 8 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ import type {
3535
AnyZodObject,
3636
ZodEffects,
3737
ZodTypeAny,
38-
SafeParseReturnType
38+
SafeParseReturnType,
39+
ZodArray
3940
} from 'zod';
4041
import { stringify } from 'devalue';
4142
import type { FormFields } from '../index.js';
@@ -919,80 +920,23 @@ async function validateField<T extends AnyZodObject, M>(
919920
return defaultValidate();
920921
}
921922

922-
function extractValidator(data: any, key: string) {
923-
const zodData = unwrapZodType(data);
924-
if (zodData.effects)
925-
return { effects: true, validator: zodData.effects } as const;
926-
data = zodData.zodType;
927-
928-
// ZodObject
929-
930-
// ZodArray
931-
const arrayShape = data?.element?.shape;
932-
if (arrayShape)
933-
return { effects: false, validator: arrayShape[key] } as const;
934-
935-
throw new SuperFormError(
936-
'Invalid Zod validator for ' + key + ': ' + data
937-
);
938-
}
939-
940923
if ('safeParseAsync' in validators) {
941924
// Zod validator
942-
let resultPromise: Promise<SafeParseReturnType<any, any>> | undefined =
943-
undefined;
944-
945-
let effectPath = [];
946-
947-
const extracted = traversePath(
948-
validators as AnyZodObject,
949-
path as FieldPath<AnyZodObject>,
950-
(pathdata) => {
951-
if (!isNaN(parseInt(pathdata.key))) {
952-
return value;
953-
}
954-
const extracted = extractValidator(pathdata.parent, pathdata.key);
955-
if (extracted.effects) {
956-
// ZodEffects found, validate tree from this point
957-
const validator = extracted.validator;
958-
const partialData = traversePath(
959-
get(data),
960-
pathdata.path as FieldPath<z.infer<T>>
961-
);
962-
resultPromise = validator.safeParseAsync(partialData?.parent);
963-
effectPath = pathdata.path.slice(0, -1);
964-
return undefined;
965-
} else {
966-
// No effects, keep going down the tree.
967-
return extracted.validator;
968-
}
969-
}
925+
const result = await (validators as AnyZodObject).safeParseAsync(
926+
get(data)
970927
);
971928

972-
if (!resultPromise) {
973-
if (!extracted) {
974-
throw new SuperFormError('No Zod validator found: ' + path);
975-
}
976-
resultPromise = extracted.value.safeParseAsync(value);
977-
}
978-
979-
const result = await (resultPromise as NonNullable<
980-
typeof resultPromise
981-
>);
982-
983-
console.log('Validated', path, result, get(data));
984-
985929
if (!result.success) {
986-
const msgs = mapErrors<T>(result.error.format());
987-
const current = traversePath(msgs, path as FieldPath<typeof msgs>);
988-
//if (!current) throw new SuperFormError('Error not found: ' + path);
989-
return setError(current?.value);
930+
const errors = result.error.format();
931+
const current = traversePath(errors, path as FieldPath<typeof errors>);
932+
return setError(current?.value?._errors);
990933
} else {
991934
return setError(undefined);
992935
}
993936
} else {
994937
// SuperForms validator
995938

939+
// Remove numeric indices, they're not used for validators.
996940
const validationPath = path.filter((p) => isNaN(parseInt(p)));
997941

998942
const validator = traversePath(

src/routes/tests/rex/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
data.form,
1212
{
1313
dataType: 'json',
14-
validators: refined,
14+
validators: basicSchema,
1515
validationMethod: ($page.url.searchParams.get('method') ??
1616
undefined) as any
1717
}

src/routes/tests/rex/schema.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export const basicSchema = z.object({
1111
min: z.number().int().min(5),
1212
max: z.number().int().min(5)
1313
})
14-
/*
1514
.refine(
1615
(data) => {
1716
if (data.min && data.max) {
@@ -24,7 +23,6 @@ export const basicSchema = z.object({
2423
message: 'Max must be greater or equal to min'
2524
}
2625
)
27-
*/
2826
.array()
2927
.nullable()
3028
.default([{ min: 5, max: 10 }])

0 commit comments

Comments
 (0)