Skip to content

Commit e8442d4

Browse files
committed
Working with effect-free schema.
1 parent 61f296a commit e8442d4

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

src/lib/client/index.ts

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ import type {
3434
z,
3535
AnyZodObject,
3636
ZodEffects,
37+
ZodArray,
38+
ZodAny,
3739
ZodTypeAny,
38-
SafeParseReturnType,
39-
ZodArray
40+
SafeParseReturnType
4041
} from 'zod';
4142
import { stringify } from 'devalue';
4243
import type { FormFields } from '../index.js';
@@ -47,7 +48,8 @@ import {
4748
traversePathsAsync,
4849
comparePaths,
4950
setPaths,
50-
pathExists
51+
pathExists,
52+
type ZodTypeInfo
5153
} from '../entity.js';
5254
import { fieldProxy } from './proxies.js';
5355
import { clone } from '../utils.js';
@@ -920,9 +922,68 @@ async function validateField<T extends AnyZodObject, M>(
920922
return defaultValidate();
921923
}
922924

925+
// Remove numeric indices, they're not used for validators.
926+
const validationPath = path.filter((p) => isNaN(parseInt(p)));
927+
928+
function extractValidator(
929+
data: ZodTypeInfo,
930+
key: string
931+
): ZodTypeAny | undefined {
932+
if (data.effects) return undefined;
933+
934+
// No effects, check if ZodObject or ZodArray, which are the
935+
// "allowed" objects in the path above the leaf.
936+
const type = data.zodType;
937+
938+
if (type._def.typeName == 'ZodObject') {
939+
const nextType = (type as AnyZodObject)._def.shape()[key];
940+
const unwrapped = unwrapZodType(nextType);
941+
return unwrapped.effects ? undefined : unwrapped.zodType;
942+
} else if (type._def.typeName == 'ZodArray') {
943+
const array = type as ZodArray<ZodAny>;
944+
const unwrapped = unwrapZodType(array.element);
945+
if (unwrapped.effects) return undefined;
946+
return extractValidator(unwrapped, key);
947+
} else {
948+
throw new SuperFormError('Invalid validator');
949+
}
950+
}
951+
923952
if ('safeParseAsync' in validators) {
924953
// Zod validator
925-
const result = await (validators as AnyZodObject).safeParseAsync(
954+
// Check if any effects exist for the path, then parse the entire schema.
955+
const leaf = traversePath(
956+
validators,
957+
validationPath as FieldPath<typeof validators>,
958+
(pathData) => {
959+
return extractValidator(
960+
unwrapZodType(pathData.parent),
961+
pathData.key
962+
);
963+
}
964+
);
965+
966+
if (leaf) {
967+
const validator = extractValidator(
968+
unwrapZodType(leaf.parent),
969+
leaf.key
970+
);
971+
if (validator) {
972+
console.log('🚀 ~ file: index.ts:972 ~ no effects:', validator);
973+
const result = await validator.safeParseAsync(value);
974+
if (!result.success) {
975+
const errors = result.error.format();
976+
return setError(errors._errors);
977+
} else {
978+
return setError(undefined);
979+
}
980+
}
981+
}
982+
983+
console.log('🚀 ~ file: index.ts:983 ~ Effects found, validating all');
984+
985+
// Effects are found, validate entire data, unfortunately
986+
const result = await (validators as ZodTypeAny).safeParseAsync(
926987
get(data)
927988
);
928989

@@ -936,9 +997,6 @@ async function validateField<T extends AnyZodObject, M>(
936997
} else {
937998
// SuperForms validator
938999

939-
// Remove numeric indices, they're not used for validators.
940-
const validationPath = path.filter((p) => isNaN(parseInt(p)));
941-
9421000
const validator = traversePath(
9431001
validators as Validators<UnwrapEffects<T>>,
9441002
validationPath as FieldPath<typeof validators>

src/routes/tests/rex/schema.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export const basicSchema = z.object({
2424
}
2525
)
2626
.array()
27-
.nullable()
2827
.default([{ min: 5, max: 10 }])
2928
});
3029

0 commit comments

Comments
 (0)