@pyreon/validation 0.3.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/analysis/index.js.html +1 -1
- package/lib/arktype.js.map +1 -1
- package/lib/index.js +60 -60
- package/lib/index.js.map +1 -1
- package/lib/types/arktype.d.ts +44 -85
- package/lib/types/arktype.d.ts.map +1 -1
- package/lib/types/index.d.ts +91 -93
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/valibot.d.ts +46 -84
- package/lib/types/valibot.d.ts.map +1 -1
- package/lib/types/zod.d.ts +63 -78
- package/lib/types/zod.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/arktype.ts +1 -3
- package/src/index.ts +7 -8
- package/src/tests/{validation.test.ts → validation.test.tsx} +17 -12
- package/lib/types/arktype2.d.ts +0 -51
- package/lib/types/arktype2.d.ts.map +0 -1
- package/lib/types/valibot2.d.ts +0 -51
- package/lib/types/valibot2.d.ts.map +0 -1
- package/lib/types/zod2.d.ts +0 -71
- package/lib/types/zod2.d.ts.map +0 -1
package/lib/types/index.d.ts
CHANGED
|
@@ -1,71 +1,79 @@
|
|
|
1
1
|
import { SchemaValidateFn, SchemaValidateFn as SchemaValidateFn$1, ValidateFn, ValidateFn as ValidateFn$1, ValidationError, ValidationError as ValidationError$1 } from "@pyreon/form";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
4
|
-
/**
|
|
5
|
-
* Minimal Zod-compatible interfaces so we don't require zod as a hard dep.
|
|
6
|
-
* These match Zod v3's public API surface.
|
|
7
|
-
*/
|
|
8
|
-
interface ZodIssue {
|
|
9
|
-
path: PropertyKey[];
|
|
10
|
-
message: string;
|
|
11
|
-
}
|
|
3
|
+
//#region src/arktype.d.ts
|
|
12
4
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
5
|
+
* Internal callable interface matching ArkType's Type.
|
|
6
|
+
* Not exposed publicly — consumers pass their ArkType schema directly.
|
|
15
7
|
*/
|
|
16
|
-
|
|
17
|
-
safeParse(data: unknown): {
|
|
18
|
-
success: boolean;
|
|
19
|
-
data?: T;
|
|
20
|
-
error?: {
|
|
21
|
-
issues: ZodIssue[];
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
safeParseAsync(data: unknown): Promise<{
|
|
25
|
-
success: boolean;
|
|
26
|
-
data?: T;
|
|
27
|
-
error?: {
|
|
28
|
-
issues: ZodIssue[];
|
|
29
|
-
};
|
|
30
|
-
}>;
|
|
31
|
-
}
|
|
8
|
+
type ArkTypeCallable = (data: unknown) => unknown;
|
|
32
9
|
/**
|
|
33
|
-
* Create a form-level schema validator from
|
|
34
|
-
*
|
|
10
|
+
* Create a form-level schema validator from an ArkType schema.
|
|
11
|
+
*
|
|
12
|
+
* Accepts any callable ArkType `Type` instance. The schema is duck-typed —
|
|
13
|
+
* no ArkType import required.
|
|
35
14
|
*
|
|
36
15
|
* @example
|
|
37
|
-
* import {
|
|
38
|
-
* import {
|
|
16
|
+
* import { type } from 'arktype'
|
|
17
|
+
* import { arktypeSchema } from '@pyreon/validation/arktype'
|
|
39
18
|
*
|
|
40
|
-
* const schema =
|
|
41
|
-
* email:
|
|
42
|
-
* password:
|
|
19
|
+
* const schema = type({
|
|
20
|
+
* email: 'string.email',
|
|
21
|
+
* password: 'string >= 8',
|
|
43
22
|
* })
|
|
44
23
|
*
|
|
45
24
|
* const form = useForm({
|
|
46
25
|
* initialValues: { email: '', password: '' },
|
|
47
|
-
* schema:
|
|
26
|
+
* schema: arktypeSchema(schema),
|
|
48
27
|
* onSubmit: (values) => { ... },
|
|
49
28
|
* })
|
|
50
29
|
*/
|
|
51
|
-
declare function
|
|
30
|
+
declare function arktypeSchema<TValues extends Record<string, unknown>>(schema: ArkTypeCallable): SchemaValidateFn$1<TValues>;
|
|
52
31
|
/**
|
|
53
|
-
* Create a single-field validator from
|
|
54
|
-
* Supports both sync and async Zod refinements.
|
|
32
|
+
* Create a single-field validator from an ArkType schema.
|
|
55
33
|
*
|
|
56
34
|
* @example
|
|
57
|
-
* import {
|
|
58
|
-
* import {
|
|
35
|
+
* import { type } from 'arktype'
|
|
36
|
+
* import { arktypeField } from '@pyreon/validation/arktype'
|
|
59
37
|
*
|
|
60
38
|
* const form = useForm({
|
|
61
39
|
* initialValues: { email: '' },
|
|
62
40
|
* validators: {
|
|
63
|
-
* email:
|
|
41
|
+
* email: arktypeField(type('string.email')),
|
|
64
42
|
* },
|
|
65
43
|
* onSubmit: (values) => { ... },
|
|
66
44
|
* })
|
|
67
45
|
*/
|
|
68
|
-
declare function
|
|
46
|
+
declare function arktypeField<T>(schema: ArkTypeCallable): ValidateFn$1<T>;
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/types.d.ts
|
|
49
|
+
/**
|
|
50
|
+
* Generic issue produced by any schema library.
|
|
51
|
+
* Adapters normalize library-specific errors into this shape.
|
|
52
|
+
*/
|
|
53
|
+
interface ValidationIssue {
|
|
54
|
+
/** Dot-separated field path (e.g. "address.city"). */
|
|
55
|
+
path: string;
|
|
56
|
+
/** Human-readable error message. */
|
|
57
|
+
message: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A generic schema adapter transforms library-specific parse results
|
|
61
|
+
* into a flat record of field → error message.
|
|
62
|
+
*/
|
|
63
|
+
type SchemaAdapter<TSchema> = <TValues extends Record<string, unknown>>(schema: TSchema) => SchemaValidateFn<TValues>;
|
|
64
|
+
/**
|
|
65
|
+
* A generic field adapter transforms a library-specific schema
|
|
66
|
+
* into a single-field validator function.
|
|
67
|
+
*/
|
|
68
|
+
type FieldAdapter<TSchema> = <T>(schema: TSchema) => ValidateFn<T>;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/utils.d.ts
|
|
71
|
+
/**
|
|
72
|
+
* Convert an array of validation issues into a flat field → error record.
|
|
73
|
+
* For nested paths like ["address", "city"], produces "address.city".
|
|
74
|
+
* When multiple issues exist for the same path, the first message wins.
|
|
75
|
+
*/
|
|
76
|
+
declare function issuesToRecord<TValues extends Record<string, unknown>>(issues: ValidationIssue[]): Partial<Record<keyof TValues, ValidationError$1>>;
|
|
69
77
|
//#endregion
|
|
70
78
|
//#region src/valibot.d.ts
|
|
71
79
|
/**
|
|
@@ -114,82 +122,72 @@ declare function valibotSchema<TValues extends Record<string, unknown>>(schema:
|
|
|
114
122
|
*/
|
|
115
123
|
declare function valibotField<T>(schema: unknown, safeParseFn: GenericSafeParseFn): ValidateFn$1<T>;
|
|
116
124
|
//#endregion
|
|
117
|
-
//#region src/
|
|
125
|
+
//#region src/zod.d.ts
|
|
118
126
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
127
|
+
* Minimal Zod-compatible interfaces so we don't require zod as a hard dep.
|
|
128
|
+
* These match Zod v3's public API surface.
|
|
121
129
|
*/
|
|
122
|
-
interface
|
|
123
|
-
|
|
130
|
+
interface ZodIssue {
|
|
131
|
+
path: PropertyKey[];
|
|
132
|
+
message: string;
|
|
124
133
|
}
|
|
125
134
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
|
|
129
|
-
|
|
135
|
+
* Duck-typed Zod schema interface — works with both Zod v3 and v4.
|
|
136
|
+
* Inlines the result shape to avoid version-specific type mismatches.
|
|
137
|
+
*/
|
|
138
|
+
interface ZodSchema<T = unknown> {
|
|
139
|
+
safeParse(data: unknown): {
|
|
140
|
+
success: boolean;
|
|
141
|
+
data?: T;
|
|
142
|
+
error?: {
|
|
143
|
+
issues: ZodIssue[];
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
safeParseAsync(data: unknown): Promise<{
|
|
147
|
+
success: boolean;
|
|
148
|
+
data?: T;
|
|
149
|
+
error?: {
|
|
150
|
+
issues: ZodIssue[];
|
|
151
|
+
};
|
|
152
|
+
}>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create a form-level schema validator from a Zod schema.
|
|
156
|
+
* Supports both sync and async Zod schemas (uses `safeParseAsync`).
|
|
130
157
|
*
|
|
131
158
|
* @example
|
|
132
|
-
* import {
|
|
133
|
-
* import {
|
|
159
|
+
* import { z } from 'zod'
|
|
160
|
+
* import { zodSchema } from '@pyreon/validation/zod'
|
|
134
161
|
*
|
|
135
|
-
* const schema =
|
|
136
|
-
* email:
|
|
137
|
-
* password:
|
|
162
|
+
* const schema = z.object({
|
|
163
|
+
* email: z.string().email(),
|
|
164
|
+
* password: z.string().min(8),
|
|
138
165
|
* })
|
|
139
166
|
*
|
|
140
167
|
* const form = useForm({
|
|
141
168
|
* initialValues: { email: '', password: '' },
|
|
142
|
-
* schema:
|
|
169
|
+
* schema: zodSchema(schema),
|
|
143
170
|
* onSubmit: (values) => { ... },
|
|
144
171
|
* })
|
|
145
172
|
*/
|
|
146
|
-
declare function
|
|
173
|
+
declare function zodSchema<TValues extends Record<string, unknown>>(schema: ZodSchema<TValues>): SchemaValidateFn$1<TValues>;
|
|
147
174
|
/**
|
|
148
|
-
* Create a single-field validator from
|
|
175
|
+
* Create a single-field validator from a Zod schema.
|
|
176
|
+
* Supports both sync and async Zod refinements.
|
|
149
177
|
*
|
|
150
178
|
* @example
|
|
151
|
-
* import {
|
|
152
|
-
* import {
|
|
179
|
+
* import { z } from 'zod'
|
|
180
|
+
* import { zodField } from '@pyreon/validation/zod'
|
|
153
181
|
*
|
|
154
182
|
* const form = useForm({
|
|
155
183
|
* initialValues: { email: '' },
|
|
156
184
|
* validators: {
|
|
157
|
-
* email:
|
|
185
|
+
* email: zodField(z.string().email('Invalid email')),
|
|
158
186
|
* },
|
|
159
187
|
* onSubmit: (values) => { ... },
|
|
160
188
|
* })
|
|
161
189
|
*/
|
|
162
|
-
declare function
|
|
163
|
-
//#endregion
|
|
164
|
-
//#region src/types.d.ts
|
|
165
|
-
/**
|
|
166
|
-
* Generic issue produced by any schema library.
|
|
167
|
-
* Adapters normalize library-specific errors into this shape.
|
|
168
|
-
*/
|
|
169
|
-
interface ValidationIssue {
|
|
170
|
-
/** Dot-separated field path (e.g. "address.city"). */
|
|
171
|
-
path: string;
|
|
172
|
-
/** Human-readable error message. */
|
|
173
|
-
message: string;
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* A generic schema adapter transforms library-specific parse results
|
|
177
|
-
* into a flat record of field → error message.
|
|
178
|
-
*/
|
|
179
|
-
type SchemaAdapter<TSchema> = <TValues extends Record<string, unknown>>(schema: TSchema) => SchemaValidateFn<TValues>;
|
|
180
|
-
/**
|
|
181
|
-
* A generic field adapter transforms a library-specific schema
|
|
182
|
-
* into a single-field validator function.
|
|
183
|
-
*/
|
|
184
|
-
type FieldAdapter<TSchema> = <T>(schema: TSchema) => ValidateFn<T>;
|
|
185
|
-
//#endregion
|
|
186
|
-
//#region src/utils.d.ts
|
|
187
|
-
/**
|
|
188
|
-
* Convert an array of validation issues into a flat field → error record.
|
|
189
|
-
* For nested paths like ["address", "city"], produces "address.city".
|
|
190
|
-
* When multiple issues exist for the same path, the first message wins.
|
|
191
|
-
*/
|
|
192
|
-
declare function issuesToRecord<TValues extends Record<string, unknown>>(issues: ValidationIssue[]): Partial<Record<keyof TValues, ValidationError$1>>;
|
|
190
|
+
declare function zodField<T>(schema: ZodSchema<T>): ValidateFn$1<T>;
|
|
193
191
|
//#endregion
|
|
194
192
|
export { type FieldAdapter, type SchemaAdapter, type SchemaValidateFn, type ValidateFn, type ValidationError, type ValidationIssue, arktypeField, arktypeSchema, issuesToRecord, valibotField, valibotSchema, zodField, zodSchema };
|
|
195
193
|
//# sourceMappingURL=index2.d.ts.map
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index2.d.ts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/arktype.ts","../../../src/types.ts","../../../src/utils.ts","../../../src/valibot.ts","../../../src/zod.ts"],"mappings":";;;;;AAIqB;;KAoBhB,eAAA,IAAmB,IAAA;;;AAkCxB;;;;;;;;;;;;;;;;;AAgCA;;iBAhCgB,aAAA,iBAA8B,MAAA,kBAAA,CAC5C,MAAA,EAAQ,eAAA,GACP,kBAAA,CAAiB,OAAA;;;;;;;;;;;;;;;;iBA8BJ,YAAA,GAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,YAAA,CAAW,CAAA;;;AAtFhD;;;;AAAA,UCSJ,eAAA;ED6CD;EC3Cd,IAAA;ED2C2B;ECzC3B,OAAA;AAAA;;;;;KAOU,aAAA,6BAA0C,MAAA,mBACpD,MAAA,EAAQ,OAAA,KACL,gBAAA,CAAiB,OAAA;;;;;KAMV,YAAA,gBAA4B,MAAA,EAAQ,OAAA,KAAY,UAAA,CAAW,CAAA;;;;AD5BlD;;;;iBEIL,cAAA,iBAA+B,MAAA,kBAAA,CAC7C,MAAA,EAAQ,eAAA,KACP,OAAA,CAAQ,MAAA,OAAa,OAAA,EAAS,iBAAA;;;;;AFNZ;;;;KG6BhB,kBAAA,GAAqB,QAAA;AHyB1B;;;;;;;;;;;;;;;;;AAgCA;;;;AAhCA,iBGUgB,aAAA,iBAA8B,MAAA,kBAAA,CAC5C,MAAA,WACA,WAAA,EAAa,kBAAA,GACZ,kBAAA,CAAiB,OAAA;;;;;;;;;;;;;;AF1DpB;;iBE2FgB,YAAA,GAAA,CACd,MAAA,WACA,WAAA,EAAa,kBAAA,GACZ,YAAA,CAAW,CAAA;;;;;AHvGO;;UIQX,QAAA;EACR,IAAA,EAAM,WAAA;EACN,OAAA;AAAA;;;;;UAOQ,SAAA;EACR,SAAA,CAAU,IAAA;IACR,OAAA;IACA,IAAA,GAAO,CAAA;IACP,KAAA;MAAU,MAAA,EAAQ,QAAA;IAAA;EAAA;EAEpB,cAAA,CACE,IAAA,YACC,OAAA;IAAU,OAAA;IAAkB,IAAA,GAAO,CAAA;IAAG,KAAA;MAAU,MAAA,EAAQ,QAAA;IAAA;EAAA;AAAA;;;;;;;;;;;;;;;AHhB7D;;;;;iBG6CgB,SAAA,iBAA0B,MAAA,kBAAA,CACxC,MAAA,EAAQ,SAAA,CAAU,OAAA,IACjB,kBAAA,CAAiB,OAAA;;;;;;;;;;;;;;;;;iBA+BJ,QAAA,GAAA,CAAY,MAAA,EAAQ,SAAA,CAAU,CAAA,IAAK,YAAA,CAAW,CAAA"}
|
package/lib/types/valibot.d.ts
CHANGED
|
@@ -1,89 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Convert an array of validation issues into a flat field → error record.
|
|
4
|
-
* For nested paths like ["address", "city"], produces "address.city".
|
|
5
|
-
* When multiple issues exist for the same path, the first message wins.
|
|
6
|
-
*/
|
|
7
|
-
function issuesToRecord(issues) {
|
|
8
|
-
const errors = {};
|
|
9
|
-
for (const issue of issues) {
|
|
10
|
-
const key = issue.path;
|
|
11
|
-
if (errors[key] === void 0) errors[key] = issue.message;
|
|
12
|
-
}
|
|
13
|
-
return errors;
|
|
14
|
-
}
|
|
1
|
+
import { SchemaValidateFn, ValidateFn } from "@pyreon/form";
|
|
15
2
|
|
|
16
|
-
//#
|
|
17
|
-
//#region src/valibot.ts
|
|
18
|
-
function valibotIssuesToGeneric(issues) {
|
|
19
|
-
return issues.map(issue => ({
|
|
20
|
-
path: issue.path?.map(p => String(p.key)).join(".") ?? "",
|
|
21
|
-
message: issue.message
|
|
22
|
-
}));
|
|
23
|
-
}
|
|
3
|
+
//#region src/valibot.d.ts
|
|
24
4
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* import * as v from 'valibot'
|
|
32
|
-
* import { valibotSchema } from '@pyreon/validation/valibot'
|
|
33
|
-
*
|
|
34
|
-
* const schema = v.object({
|
|
35
|
-
* email: v.pipe(v.string(), v.email()),
|
|
36
|
-
* password: v.pipe(v.string(), v.minLength(8)),
|
|
37
|
-
* })
|
|
38
|
-
*
|
|
39
|
-
* const form = useForm({
|
|
40
|
-
* initialValues: { email: '', password: '' },
|
|
41
|
-
* schema: valibotSchema(schema, v.safeParseAsync),
|
|
42
|
-
* onSubmit: (values) => { ... },
|
|
43
|
-
* })
|
|
44
|
-
*/
|
|
45
|
-
function valibotSchema(schema, safeParseFn) {
|
|
46
|
-
const parse = safeParseFn;
|
|
47
|
-
return async values => {
|
|
48
|
-
try {
|
|
49
|
-
const result = await parse(schema, values);
|
|
50
|
-
if (result.success) return {};
|
|
51
|
-
return issuesToRecord(valibotIssuesToGeneric(result.issues ?? []));
|
|
52
|
-
} catch (err) {
|
|
53
|
-
return {
|
|
54
|
-
"": err instanceof Error ? err.message : String(err)
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
5
|
+
* Any function that takes (schema, input, ...rest) and returns a parse result.
|
|
6
|
+
* Valibot's safeParse/safeParseAsync have generic constraints on the schema
|
|
7
|
+
* parameter that can't be expressed without importing Valibot types. We accept
|
|
8
|
+
* any callable and cast internally.
|
|
9
|
+
*/
|
|
10
|
+
type GenericSafeParseFn = Function;
|
|
59
11
|
/**
|
|
60
|
-
* Create a
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* })
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
12
|
+
* Create a form-level schema validator from a Valibot schema.
|
|
13
|
+
*
|
|
14
|
+
* Valibot uses standalone functions rather than methods, so you must pass
|
|
15
|
+
* the `safeParseAsync` (or `safeParse`) function from valibot.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* import * as v from 'valibot'
|
|
19
|
+
* import { valibotSchema } from '@pyreon/validation/valibot'
|
|
20
|
+
*
|
|
21
|
+
* const schema = v.object({
|
|
22
|
+
* email: v.pipe(v.string(), v.email()),
|
|
23
|
+
* password: v.pipe(v.string(), v.minLength(8)),
|
|
24
|
+
* })
|
|
25
|
+
*
|
|
26
|
+
* const form = useForm({
|
|
27
|
+
* initialValues: { email: '', password: '' },
|
|
28
|
+
* schema: valibotSchema(schema, v.safeParseAsync),
|
|
29
|
+
* onSubmit: (values) => { ... },
|
|
30
|
+
* })
|
|
31
|
+
*/
|
|
32
|
+
declare function valibotSchema<TValues extends Record<string, unknown>>(schema: unknown, safeParseFn: GenericSafeParseFn): SchemaValidateFn<TValues>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a single-field validator from a Valibot schema.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import * as v from 'valibot'
|
|
38
|
+
* import { valibotField } from '@pyreon/validation/valibot'
|
|
39
|
+
*
|
|
40
|
+
* const form = useForm({
|
|
41
|
+
* initialValues: { email: '' },
|
|
42
|
+
* validators: {
|
|
43
|
+
* email: valibotField(v.pipe(v.string(), v.email('Invalid email')), v.safeParseAsync),
|
|
44
|
+
* },
|
|
45
|
+
* onSubmit: (values) => { ... },
|
|
46
|
+
* })
|
|
47
|
+
*/
|
|
48
|
+
declare function valibotField<T>(schema: unknown, safeParseFn: GenericSafeParseFn): ValidateFn<T>;
|
|
87
49
|
//#endregion
|
|
88
50
|
export { valibotField, valibotSchema };
|
|
89
|
-
//# sourceMappingURL=
|
|
51
|
+
//# sourceMappingURL=valibot2.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"
|
|
1
|
+
{"version":3,"file":"valibot2.d.ts","names":[],"sources":["../../../src/valibot.ts"],"mappings":";;;;;AAIqB;;;;KA6BhB,kBAAA,GAAqB,QAAA;AAmC1B;;;;;;;;;;;;;;;;;;AAoCA;;;AApCA,iBAAgB,aAAA,iBAA8B,MAAA,kBAAA,CAC5C,MAAA,WACA,WAAA,EAAa,kBAAA,GACZ,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;;;;iBAiCJ,YAAA,GAAA,CACd,MAAA,WACA,WAAA,EAAa,kBAAA,GACZ,UAAA,CAAW,CAAA"}
|
package/lib/types/zod.d.ts
CHANGED
|
@@ -1,86 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Convert an array of validation issues into a flat field → error record.
|
|
4
|
-
* For nested paths like ["address", "city"], produces "address.city".
|
|
5
|
-
* When multiple issues exist for the same path, the first message wins.
|
|
6
|
-
*/
|
|
7
|
-
function issuesToRecord(issues) {
|
|
8
|
-
const errors = {};
|
|
9
|
-
for (const issue of issues) {
|
|
10
|
-
const key = issue.path;
|
|
11
|
-
if (errors[key] === void 0) errors[key] = issue.message;
|
|
12
|
-
}
|
|
13
|
-
return errors;
|
|
14
|
-
}
|
|
1
|
+
import { SchemaValidateFn, ValidateFn } from "@pyreon/form";
|
|
15
2
|
|
|
16
|
-
//#
|
|
17
|
-
//#region src/zod.ts
|
|
18
|
-
function zodIssuesToGeneric(issues) {
|
|
19
|
-
return issues.map(issue => ({
|
|
20
|
-
path: issue.path.map(String).join("."),
|
|
21
|
-
message: issue.message
|
|
22
|
-
}));
|
|
23
|
-
}
|
|
3
|
+
//#region src/zod.d.ts
|
|
24
4
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*
|
|
32
|
-
* const schema = z.object({
|
|
33
|
-
* email: z.string().email(),
|
|
34
|
-
* password: z.string().min(8),
|
|
35
|
-
* })
|
|
36
|
-
*
|
|
37
|
-
* const form = useForm({
|
|
38
|
-
* initialValues: { email: '', password: '' },
|
|
39
|
-
* schema: zodSchema(schema),
|
|
40
|
-
* onSubmit: (values) => { ... },
|
|
41
|
-
* })
|
|
42
|
-
*/
|
|
43
|
-
function zodSchema(schema) {
|
|
44
|
-
return async values => {
|
|
45
|
-
try {
|
|
46
|
-
const result = await schema.safeParseAsync(values);
|
|
47
|
-
if (result.success) return {};
|
|
48
|
-
return issuesToRecord(zodIssuesToGeneric(result.error.issues));
|
|
49
|
-
} catch (err) {
|
|
50
|
-
return {
|
|
51
|
-
"": err instanceof Error ? err.message : String(err)
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
};
|
|
5
|
+
* Minimal Zod-compatible interfaces so we don't require zod as a hard dep.
|
|
6
|
+
* These match Zod v3's public API surface.
|
|
7
|
+
*/
|
|
8
|
+
interface ZodIssue {
|
|
9
|
+
path: PropertyKey[];
|
|
10
|
+
message: string;
|
|
55
11
|
}
|
|
56
12
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* email: zodField(z.string().email('Invalid email')),
|
|
68
|
-
* },
|
|
69
|
-
* onSubmit: (values) => { ... },
|
|
70
|
-
* })
|
|
71
|
-
*/
|
|
72
|
-
function zodField(schema) {
|
|
73
|
-
return async value => {
|
|
74
|
-
try {
|
|
75
|
-
const result = await schema.safeParseAsync(value);
|
|
76
|
-
if (result.success) return void 0;
|
|
77
|
-
return result.error.issues[0]?.message;
|
|
78
|
-
} catch (err) {
|
|
79
|
-
return err instanceof Error ? err.message : String(err);
|
|
80
|
-
}
|
|
13
|
+
* Duck-typed Zod schema interface — works with both Zod v3 and v4.
|
|
14
|
+
* Inlines the result shape to avoid version-specific type mismatches.
|
|
15
|
+
*/
|
|
16
|
+
interface ZodSchema<T = unknown> {
|
|
17
|
+
safeParse(data: unknown): {
|
|
18
|
+
success: boolean;
|
|
19
|
+
data?: T;
|
|
20
|
+
error?: {
|
|
21
|
+
issues: ZodIssue[];
|
|
22
|
+
};
|
|
81
23
|
};
|
|
24
|
+
safeParseAsync(data: unknown): Promise<{
|
|
25
|
+
success: boolean;
|
|
26
|
+
data?: T;
|
|
27
|
+
error?: {
|
|
28
|
+
issues: ZodIssue[];
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
82
31
|
}
|
|
83
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Create a form-level schema validator from a Zod schema.
|
|
34
|
+
* Supports both sync and async Zod schemas (uses `safeParseAsync`).
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import { z } from 'zod'
|
|
38
|
+
* import { zodSchema } from '@pyreon/validation/zod'
|
|
39
|
+
*
|
|
40
|
+
* const schema = z.object({
|
|
41
|
+
* email: z.string().email(),
|
|
42
|
+
* password: z.string().min(8),
|
|
43
|
+
* })
|
|
44
|
+
*
|
|
45
|
+
* const form = useForm({
|
|
46
|
+
* initialValues: { email: '', password: '' },
|
|
47
|
+
* schema: zodSchema(schema),
|
|
48
|
+
* onSubmit: (values) => { ... },
|
|
49
|
+
* })
|
|
50
|
+
*/
|
|
51
|
+
declare function zodSchema<TValues extends Record<string, unknown>>(schema: ZodSchema<TValues>): SchemaValidateFn<TValues>;
|
|
52
|
+
/**
|
|
53
|
+
* Create a single-field validator from a Zod schema.
|
|
54
|
+
* Supports both sync and async Zod refinements.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* import { z } from 'zod'
|
|
58
|
+
* import { zodField } from '@pyreon/validation/zod'
|
|
59
|
+
*
|
|
60
|
+
* const form = useForm({
|
|
61
|
+
* initialValues: { email: '' },
|
|
62
|
+
* validators: {
|
|
63
|
+
* email: zodField(z.string().email('Invalid email')),
|
|
64
|
+
* },
|
|
65
|
+
* onSubmit: (values) => { ... },
|
|
66
|
+
* })
|
|
67
|
+
*/
|
|
68
|
+
declare function zodField<T>(schema: ZodSchema<T>): ValidateFn<T>;
|
|
84
69
|
//#endregion
|
|
85
70
|
export { zodField, zodSchema };
|
|
86
|
-
//# sourceMappingURL=
|
|
71
|
+
//# sourceMappingURL=zod2.d.ts.map
|
package/lib/types/zod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"
|
|
1
|
+
{"version":3,"file":"zod2.d.ts","names":[],"sources":["../../../src/zod.ts"],"mappings":";;;;;AAIqB;;UAQX,QAAA;EACR,IAAA,EAAM,WAAA;EACN,OAAA;AAAA;;;;AAAO;UAOC,SAAA;EACR,SAAA,CAAU,IAAA;IACR,OAAA;IACA,IAAA,GAAO,CAAA;IACP,KAAA;MAAU,MAAA,EAAQ,QAAA;IAAA;EAAA;EAEpB,cAAA,CACE,IAAA,YACC,OAAA;IAAU,OAAA;IAAkB,IAAA,GAAO,CAAA;IAAG,KAAA;MAAU,MAAA,EAAQ,QAAA;IAAA;EAAA;AAAA;;;;;;;;;;;;;;AA6B7D;;;;;;iBAAgB,SAAA,iBAA0B,MAAA,kBAAA,CACxC,MAAA,EAAQ,SAAA,CAAU,OAAA,IACjB,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;AA+BpB;;;;iBAAgB,QAAA,GAAA,CAAY,MAAA,EAAQ,SAAA,CAAU,CAAA,IAAK,UAAA,CAAW,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/validation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Schema validation adapters for Pyreon forms (Zod, Valibot, ArkType)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"typecheck": "tsc --noEmit"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@pyreon/form": "^0.
|
|
58
|
+
"@pyreon/form": "^0.7.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependenciesMeta": {
|
|
61
61
|
"zod": {
|
package/src/arktype.ts
CHANGED
|
@@ -22,9 +22,7 @@ interface ArkErrors extends Array<ArkError> {
|
|
|
22
22
|
* Internal callable interface matching ArkType's Type.
|
|
23
23
|
* Not exposed publicly — consumers pass their ArkType schema directly.
|
|
24
24
|
*/
|
|
25
|
-
|
|
26
|
-
(data: unknown): unknown
|
|
27
|
-
}
|
|
25
|
+
type ArkTypeCallable = (data: unknown) => unknown
|
|
28
26
|
|
|
29
27
|
function isArkErrors(result: unknown): result is ArkErrors {
|
|
30
28
|
return Array.isArray(result) && 'summary' in (result as object)
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { valibotSchema, valibotField } from './valibot'
|
|
3
|
-
export { arktypeSchema, arktypeField } from './arktype'
|
|
4
|
-
export { issuesToRecord } from './utils'
|
|
5
|
-
|
|
1
|
+
export { arktypeField, arktypeSchema } from './arktype'
|
|
6
2
|
export type {
|
|
7
|
-
|
|
3
|
+
FieldAdapter,
|
|
4
|
+
SchemaAdapter,
|
|
8
5
|
SchemaValidateFn,
|
|
9
6
|
ValidateFn,
|
|
10
7
|
ValidationError,
|
|
11
|
-
|
|
12
|
-
FieldAdapter,
|
|
8
|
+
ValidationIssue,
|
|
13
9
|
} from './types'
|
|
10
|
+
export { issuesToRecord } from './utils'
|
|
11
|
+
export { valibotField, valibotSchema } from './valibot'
|
|
12
|
+
export { zodField, zodSchema } from './zod'
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
import * as v from 'valibot'
|
|
3
|
-
import { type } from 'arktype'
|
|
4
|
-
import { h } from '@pyreon/core'
|
|
5
|
-
import { mount } from '@pyreon/runtime-dom'
|
|
6
1
|
import { useForm } from '@pyreon/form'
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
2
|
+
import { mount } from '@pyreon/runtime-dom'
|
|
3
|
+
import { type } from 'arktype'
|
|
4
|
+
import * as v from 'valibot'
|
|
5
|
+
import { z } from 'zod'
|
|
6
|
+
import { arktypeField, arktypeSchema } from '../arktype'
|
|
10
7
|
import { issuesToRecord } from '../utils'
|
|
8
|
+
import { valibotField, valibotSchema } from '../valibot'
|
|
9
|
+
import { zodField, zodSchema } from '../zod'
|
|
11
10
|
|
|
12
11
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
13
12
|
|
|
13
|
+
function Capture<T>({ fn }: { fn: () => T }) {
|
|
14
|
+
fn()
|
|
15
|
+
return null
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
function mountWith<T>(fn: () => T): { result: T; unmount: () => void } {
|
|
15
19
|
let result: T | undefined
|
|
16
20
|
const el = document.createElement('div')
|
|
17
21
|
document.body.appendChild(el)
|
|
18
22
|
const unmount = mount(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
<Capture
|
|
24
|
+
fn={() => {
|
|
25
|
+
result = fn()
|
|
26
|
+
}}
|
|
27
|
+
/>,
|
|
23
28
|
el,
|
|
24
29
|
)
|
|
25
30
|
return {
|