Skip to content

Commit 6322db8

Browse files
committed
Added support for ZodPipeline.
1 parent 7d2b0d8 commit 6322db8

File tree

5 files changed

+39
-11
lines changed

5 files changed

+39
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3333
- Added `superValidateSync`, useful on the client for SPA:s.
3434
- Added `defaultValues`, which takes a schema and returns the default values for it.
3535
- `options.resetForm` now works without `use:enhance`!
36+
- Support for `ZodPipeline`.
3637

3738
## [0.8.7] - 2023-05-22
3839

src/index.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,3 +909,29 @@ test('setMessage and setError with refined schema', async () => {
909909
id: ['Id error']
910910
});
911911
});
912+
913+
test.only('Schema with pipe()', async () => {
914+
const schema = z.object({
915+
len: z
916+
.string()
917+
.transform((val) => val.length)
918+
.pipe(z.number().min(5)),
919+
date: z.union([z.number(), z.string(), z.date()]).pipe(z.coerce.date()),
920+
num: z.number().or(z.string()).pipe(z.coerce.number())
921+
});
922+
923+
const form = await superValidate(schema);
924+
assert(form.valid === false);
925+
expect(form.data.len).toEqual(0);
926+
expect(form.data.num).toEqual(0);
927+
928+
const formData4 = new FormData();
929+
formData4.set('len', 'four');
930+
formData4.set('date', '2023-05-28');
931+
formData4.set('num', '123');
932+
const form4 = await superValidate(formData4, schema);
933+
assert(form4.valid === false);
934+
expect(form4.data.len).toBeNaN();
935+
expect(form4.data.date.getDate()).toEqual(28);
936+
expect(form4.data.num).toEqual(123);
937+
});

src/lib/schemaEntity.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import {
2424
ZodBigInt,
2525
ZodObject,
2626
ZodSymbol,
27-
ZodRecord
27+
ZodRecord,
28+
ZodPipeline
2829
} from 'zod';
2930

3031
import type { SuperValidateOptions } from './superValidate.js';
@@ -75,6 +76,8 @@ export function hasEffects(zodType: ZodTypeAny): boolean {
7576
}
7677

7778
export function unwrapZodType(zodType: ZodTypeAny): ZodTypeInfo {
79+
const originalType = zodType;
80+
7881
let _wrapped = true;
7982
let isNullable = false;
8083
let isOptional = false;
@@ -98,13 +101,16 @@ export function unwrapZodType(zodType: ZodTypeAny): ZodTypeInfo {
98101
} else if (zodType._def.typeName == 'ZodEffects') {
99102
if (!effects) effects = zodType as ZodEffects<ZodTypeAny>;
100103
zodType = zodType._def.schema;
104+
} else if (zodType._def.typeName == 'ZodPipeline') {
105+
zodType = (zodType as ZodPipeline<ZodTypeAny, ZodTypeAny>)._def.out;
101106
} else {
102107
_wrapped = false;
103108
}
104109
}
105110

106111
return {
107112
zodType,
113+
originalType,
108114
isNullable,
109115
isOptional,
110116
hasDefault,

src/lib/superValidate.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,9 @@ function formDataToValidation<T extends AnyZodObject>(
121121
) {
122122
if (entry && typeof entry !== 'string') {
123123
// File object, not supported
124-
/*
125-
throw new SuperFormError(
126-
`Field "${key}" contains a file, which is not supported by Superforms. Remove it from the schema and use FormData directly instead.`
127-
);
128-
return (entry.valueOf() as File).name;
129-
return entry as File;
130-
*/
131124
return undefined;
132125
} else {
133-
return parseEntry(key, entry, typeInfo);
126+
return parseFormDataEntry(key, entry, typeInfo);
134127
}
135128
}
136129

@@ -146,7 +139,7 @@ function formDataToValidation<T extends AnyZodObject>(
146139
}
147140
}
148141

149-
function parseEntry(
142+
function parseFormDataEntry(
150143
field: string,
151144
value: string | null,
152145
typeInfo: ZodTypeInfo
@@ -171,7 +164,7 @@ function formDataToValidation<T extends AnyZodObject>(
171164
return new Date(value ?? '');
172165
} else if (zodType instanceof ZodArray) {
173166
const arrayType = unwrapZodType(zodType._def.type);
174-
return parseEntry(field, value, arrayType);
167+
return parseFormDataEntry(field, value, arrayType);
175168
} else if (zodType instanceof ZodBigInt) {
176169
try {
177170
return BigInt(value ?? '.');
@@ -521,6 +514,7 @@ export function superValidateSync<
521514
output = emptyResultToValidation(result, entityInfo, addErrors);
522515
} else {
523516
const result = originalSchema.safeParse(data);
517+
524518
output = resultToValidation(
525519
result,
526520
entityInfo,

src/lib/traversal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { MaybePromise } from '$app/forms';
99

1010
export type ZodTypeInfo = {
1111
zodType: ZodTypeAny;
12+
originalType: ZodTypeAny;
1213
isNullable: boolean;
1314
isOptional: boolean;
1415
hasDefault: boolean;

0 commit comments

Comments
 (0)