attaform 0.17.0 → 0.17.2
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/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/shared/{attaform.ClfCi1i2.d.mts → attaform.B1jvxsOF.d.mts} +1 -1
- package/dist/shared/{attaform.BT55rDNN.mjs → attaform.B3ZaPIzS.mjs} +15 -2
- package/dist/shared/attaform.B3ZaPIzS.mjs.map +1 -0
- package/dist/shared/{attaform.0Wg7UEeX.cjs → attaform.BPRHR3Zs.cjs} +20 -8
- package/dist/shared/attaform.BPRHR3Zs.cjs.map +1 -0
- package/dist/shared/{attaform.C6_zOf8x.cjs → attaform.BV40t5y2.cjs} +16 -6
- package/dist/shared/attaform.BV40t5y2.cjs.map +1 -0
- package/dist/shared/attaform.C0iFnTN0.d.ts +165 -0
- package/dist/shared/attaform.C5MH4lNh.d.mts +53 -0
- package/dist/shared/attaform.C6lbmMUe.d.ts +53 -0
- package/dist/shared/{attaform.D7lomopc.d.cts → attaform.C6qzEdIM.d.cts} +1 -1
- package/dist/shared/attaform.CHorcsIU.d.cts +165 -0
- package/dist/shared/{attaform.B0zue7zt.d.ts → attaform.CTwNcpLE.d.ts} +1 -1
- package/dist/shared/{attaform.BYbsV2Wv.d.mts → attaform.C_5aB6EQ.d.cts} +95 -15
- package/dist/shared/{attaform.BYbsV2Wv.d.ts → attaform.C_5aB6EQ.d.mts} +95 -15
- package/dist/shared/{attaform.BYbsV2Wv.d.cts → attaform.C_5aB6EQ.d.ts} +95 -15
- package/dist/shared/{attaform.BFumZXY2.cjs → attaform.Cer8JO_P.cjs} +15 -2
- package/dist/shared/attaform.Cer8JO_P.cjs.map +1 -0
- package/dist/shared/{attaform.Cj0pCNVn.mjs → attaform.CpERWz3u.mjs} +16 -6
- package/dist/shared/attaform.CpERWz3u.mjs.map +1 -0
- package/dist/shared/attaform.CuE-bS1C.d.mts +165 -0
- package/dist/shared/{attaform.D6Q5ZP8L.mjs → attaform.Drt6fivF.mjs} +20 -8
- package/dist/shared/attaform.Drt6fivF.mjs.map +1 -0
- package/dist/shared/attaform.DtMN-MAm.d.cts +53 -0
- package/dist/zod-v3.cjs +2 -2
- package/dist/zod-v3.d.cts +35 -61
- package/dist/zod-v3.d.mts +35 -61
- package/dist/zod-v3.d.ts +35 -61
- package/dist/zod-v3.mjs +2 -2
- package/dist/zod-v4.cjs +2 -2
- package/dist/zod-v4.d.cts +4 -4
- package/dist/zod-v4.d.mts +4 -4
- package/dist/zod-v4.d.ts +4 -4
- package/dist/zod-v4.mjs +2 -2
- package/dist/zod.cjs +9 -5
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +37 -11
- package/dist/zod.d.mts +37 -11
- package/dist/zod.d.ts +37 -11
- package/dist/zod.mjs +9 -5
- package/dist/zod.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/shared/attaform.0Wg7UEeX.cjs.map +0 -1
- package/dist/shared/attaform.AOgGyRoI.d.cts +0 -65
- package/dist/shared/attaform.BFumZXY2.cjs.map +0 -1
- package/dist/shared/attaform.BQ-iGGWd.d.mts +0 -65
- package/dist/shared/attaform.BT55rDNN.mjs.map +0 -1
- package/dist/shared/attaform.C6_zOf8x.cjs.map +0 -1
- package/dist/shared/attaform.CX9v2M8k.d.ts +0 -65
- package/dist/shared/attaform.Cj0pCNVn.mjs.map +0 -1
- package/dist/shared/attaform.D6Q5ZP8L.mjs.map +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { G as GenericForm, s as FlatPath, B as NestedType, U as UseFormConfiguration, b as AbstractSchema, D as DeepPartial, c as DefaultValuesShape, ag as ValidateOnConfig, d as UseFormReturnType } from './attaform.C_5aB6EQ.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The shape `form.values.<key>` returns at runtime.
|
|
6
|
+
*
|
|
7
|
+
* Per leaf:
|
|
8
|
+
*
|
|
9
|
+
* 1. `z.preprocess(fn, inner)` — compiles to `ZodPipe<ZodTransform, inner>`.
|
|
10
|
+
* The preprocess fn fires at the write boundary (synthesized into
|
|
11
|
+
* `setValue`), so storage holds whatever `inner` stores. Recurse
|
|
12
|
+
* `StorageShape` on `inner` so a defaulted leaf inside `inner` still
|
|
13
|
+
* reads `T` (not `T | undefined`).
|
|
14
|
+
*
|
|
15
|
+
* 2. `inner.transform(fn)` — compiles to `ZodPipe<inner, ZodTransform>`.
|
|
16
|
+
* Transforms fire at submit / validate, NOT at the write boundary,
|
|
17
|
+
* so storage holds whatever `inner` stores. Recurse `StorageShape`
|
|
18
|
+
* on `inner` for the same reason.
|
|
19
|
+
*
|
|
20
|
+
* A bare top-level `ZodTransform` (no `in` schema) reads
|
|
21
|
+
* `_zod.input` directly — there's no inner to recurse into.
|
|
22
|
+
*
|
|
23
|
+
* 3. Codec / generic pipe — neither side is a transform. Read
|
|
24
|
+
* `_zod.output`. Codecs aren't write-boundary-synthesized, so the
|
|
25
|
+
* post-parse view is the only honest storage type.
|
|
26
|
+
*
|
|
27
|
+
* 4. Everything else (defaults, catch, readonly, optional, primitives,
|
|
28
|
+
* nested objects) — read `_zod.output`. Defaults and catches fire
|
|
29
|
+
* at parse time, so the post-init view is what storage holds.
|
|
30
|
+
* Nested objects delegate to Zod's own recursion on `_zod.output`,
|
|
31
|
+
* which peels nested defaults inside structural containers.
|
|
32
|
+
*
|
|
33
|
+
* Recursion: the alias calls itself on the non-transform side of a
|
|
34
|
+
* pipe so the inner shape gets the same per-key storage treatment as
|
|
35
|
+
* the top level. Without it, an inner `.default(...)` inside a
|
|
36
|
+
* transformed object would peel back to `T | undefined` (the broad
|
|
37
|
+
* input contract). Recursion only fires for pipe leaves — most leaves
|
|
38
|
+
* skip it.
|
|
39
|
+
*
|
|
40
|
+
* Implementation note: direct `_zod` property access mirrors Zod's
|
|
41
|
+
* own `$InferObjectOutput` / `$InferObjectInput`, which read
|
|
42
|
+
* `T[k]['_zod']['output']` / `T[k]['_zod']['input']` directly rather
|
|
43
|
+
* than wrapping in the top-level `output<T>` / `input<T>` conditional.
|
|
44
|
+
* Wrapping per key spawns a fresh conditional instantiation for every
|
|
45
|
+
* key; Volar's web-worker checker collapses that per-key walk to
|
|
46
|
+
* `any` once the schema is non-trivial. Property access has no
|
|
47
|
+
* conditional and resolves cleanly under the same budget.
|
|
48
|
+
*
|
|
49
|
+
* Shape access also goes through `_zod.def.shape` rather than
|
|
50
|
+
* `infer Shape from z.ZodObject<Shape>` — the latter collapses to the
|
|
51
|
+
* `$ZodShape` upper bound in the same worker because of
|
|
52
|
+
* `z.ZodObject`'s `out Shape` covariance markers.
|
|
53
|
+
*/
|
|
54
|
+
type StorageShape<S> = S extends {
|
|
55
|
+
_zod: {
|
|
56
|
+
def: {
|
|
57
|
+
type: 'object';
|
|
58
|
+
shape: infer Shape;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
} ? {
|
|
62
|
+
[K in keyof Shape]-?: StorageLeaf<Shape[K]>;
|
|
63
|
+
} : StorageLeaf<S>;
|
|
64
|
+
type StorageLeaf<L> = L extends {
|
|
65
|
+
_zod: {
|
|
66
|
+
def: {
|
|
67
|
+
type: 'pipe';
|
|
68
|
+
in: infer A;
|
|
69
|
+
out: infer B;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
} ? A extends {
|
|
73
|
+
_zod: {
|
|
74
|
+
def: {
|
|
75
|
+
type: 'transform';
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
} ? StorageShape<B> : B extends {
|
|
79
|
+
_zod: {
|
|
80
|
+
def: {
|
|
81
|
+
type: 'transform';
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
} ? StorageShape<A> : L extends {
|
|
85
|
+
_zod: {
|
|
86
|
+
output: infer Out;
|
|
87
|
+
};
|
|
88
|
+
} ? Out : never : L extends {
|
|
89
|
+
_zod: {
|
|
90
|
+
def: {
|
|
91
|
+
type: 'transform';
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
} ? L extends {
|
|
95
|
+
_zod: {
|
|
96
|
+
input: infer In;
|
|
97
|
+
};
|
|
98
|
+
} ? In : never : L extends {
|
|
99
|
+
_zod: {
|
|
100
|
+
output: infer Out;
|
|
101
|
+
};
|
|
102
|
+
} ? Out : never;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Zod v4 adapter entry point. Re-exports the adapter + the useForm
|
|
106
|
+
* wrapper that threads zod-v4-specific schema types through
|
|
107
|
+
* useAbstractForm.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Type of the value accepted at `Path` for `setValue` / `defaultValues`
|
|
112
|
+
* — the schema's `z.input<Schema>` shape at that path. Matches what
|
|
113
|
+
* `form.values.X` returns at runtime (the honest input view storage
|
|
114
|
+
* holds before transforms run).
|
|
115
|
+
*
|
|
116
|
+
* ```ts
|
|
117
|
+
* const schema = z.object({
|
|
118
|
+
* flag: z.string().transform((v) => v.length > 10),
|
|
119
|
+
* })
|
|
120
|
+
* type FlagWriteIn = PathInput<typeof schema, 'flag'> // string
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
type PathInput<Schema extends z.ZodType, Path extends string> = z.input<Schema> extends GenericForm ? Path extends FlatPath<z.input<Schema>> ? NestedType<z.input<Schema>, Path> : never : never;
|
|
124
|
+
/**
|
|
125
|
+
* Type produced at `Path` after the full parse pipeline — the schema's
|
|
126
|
+
* `z.output<Schema>` shape at that path. Matches the `data` payload of
|
|
127
|
+
* `form.process()` and the value handed to `handleSubmit`'s callback.
|
|
128
|
+
*
|
|
129
|
+
* ```ts
|
|
130
|
+
* const schema = z.object({
|
|
131
|
+
* flag: z.string().transform((v) => v.length > 10),
|
|
132
|
+
* })
|
|
133
|
+
* type FlagParsedOut = PathOutput<typeof schema, 'flag'> // boolean
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
type PathOutput<Schema extends z.ZodType, Path extends string> = z.output<Schema> extends GenericForm ? Path extends FlatPath<z.output<Schema>> ? NestedType<z.output<Schema>, Path> : never : never;
|
|
137
|
+
/**
|
|
138
|
+
* Create a form bound to a Zod v4 schema.
|
|
139
|
+
*
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { useForm } from 'attaform/zod'
|
|
142
|
+
* import { z } from 'zod'
|
|
143
|
+
*
|
|
144
|
+
* const form = useForm({
|
|
145
|
+
* schema: z.object({
|
|
146
|
+
* email: z.email(),
|
|
147
|
+
* password: z.string().min(8),
|
|
148
|
+
* }),
|
|
149
|
+
* defaultValues: { email: '' },
|
|
150
|
+
* })
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* Returns a form API exposing `register`, `values`, `errors`,
|
|
154
|
+
* `fields`, `setValue`, `handleSubmit`, `meta`, field-array
|
|
155
|
+
* helpers, and more. See `UseFormReturnType` for the full
|
|
156
|
+
* surface.
|
|
157
|
+
*
|
|
158
|
+
* For Zod v3, import from `attaform/zod-v3` instead.
|
|
159
|
+
*/
|
|
160
|
+
declare function useForm<Schema extends z.ZodObject>(configuration: Omit<UseFormConfiguration<z.input<Schema> extends GenericForm ? z.input<Schema> : never, z.output<Schema> extends GenericForm ? z.output<Schema> : never, AbstractSchema<z.input<Schema> extends GenericForm ? z.input<Schema> : never, z.output<Schema> extends GenericForm ? z.output<Schema> : never>, DeepPartial<DefaultValuesShape<z.input<Schema> extends GenericForm ? z.input<Schema> : never>>>, 'schema' | 'validateOn' | 'debounceMs'> & {
|
|
161
|
+
schema: Schema;
|
|
162
|
+
} & ValidateOnConfig): UseFormReturnType<z.input<Schema> extends GenericForm ? z.input<Schema> : never, z.output<Schema> extends GenericForm ? z.output<Schema> : never, StorageShape<Schema> extends GenericForm ? StorageShape<Schema> : never>;
|
|
163
|
+
|
|
164
|
+
export { useForm as u };
|
|
165
|
+
export type { PathInput as P, StorageShape as S, PathOutput as a };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ag as ValidateOnConfig, F as FormKey, E as OnInvalidSubmitPolicy, X as PersistConfig, y as HistoryConfig, C as CoercionRegistry } from './attaform.C_5aB6EQ.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* v3 mirror of the Zod v4 `StorageShape`. Per top-level key, default
|
|
6
|
+
* to `z.output<Shape[K]>` (the post-init view — defaults have fired,
|
|
7
|
+
* Zod's own recursion peels nested defaults inside structural
|
|
8
|
+
* containers); fall back to `z.input<Shape[K]>` for transform / pipe
|
|
9
|
+
* carriers (`ZodEffects`, `ZodPipeline`) where storage holds the
|
|
10
|
+
* pre-transform input — transforms only run at submission /
|
|
11
|
+
* validation, not at the write boundary.
|
|
12
|
+
*
|
|
13
|
+
* v3 quirk: `ZodEffects` covers BOTH `.transform()` and
|
|
14
|
+
* `z.preprocess()` at the TS level — v3 doesn't carry a separate
|
|
15
|
+
* preprocess class the way v4 does. Deferring to `z.input` for
|
|
16
|
+
* `ZodEffects` means a top-level `z.preprocess(fn, T)` leaf reads as
|
|
17
|
+
* the preprocess input (commonly `unknown`); reach for the
|
|
18
|
+
* `AbstractSchema` escape hatch if a stronger type is needed.
|
|
19
|
+
* Transforms preserve their pre-transform input shape, which matches
|
|
20
|
+
* storage.
|
|
21
|
+
*/
|
|
22
|
+
type StorageShape<S extends z.ZodTypeAny> = S extends z.ZodObject<infer Shape> ? {
|
|
23
|
+
[K in keyof Shape]-?: Shape[K] extends z.ZodEffects<z.ZodTypeAny> | z.ZodPipeline<z.ZodTypeAny, z.ZodTypeAny> ? z.input<Shape[K]> : z.output<Shape[K]>;
|
|
24
|
+
} : z.input<S>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Configuration object for the Zod v3 `useForm` overload. Same
|
|
28
|
+
* shape as the schema-agnostic `UseFormConfiguration`, but with
|
|
29
|
+
* `schema` constrained to a `z.ZodObject` (or wrapped form).
|
|
30
|
+
*/
|
|
31
|
+
type UseFormConfigurationWithZod<Schema extends z.ZodType<unknown>, DefaultValues> = ValidateOnConfig & {
|
|
32
|
+
/** A Zod v3 `ZodObject` schema (or one wrapped in `.optional()` / `.nullable()` / `.default()` / `.refine()`). */
|
|
33
|
+
schema: Schema extends z.ZodType<unknown> ? UnwrapZodObject<Schema> extends z.ZodObject<z.ZodRawShape> ? Schema : never : never;
|
|
34
|
+
key?: FormKey;
|
|
35
|
+
defaultValues?: DefaultValues;
|
|
36
|
+
strict?: boolean;
|
|
37
|
+
onInvalidSubmit?: OnInvalidSubmitPolicy;
|
|
38
|
+
persist?: PersistConfig;
|
|
39
|
+
history?: HistoryConfig;
|
|
40
|
+
rememberVariants?: boolean;
|
|
41
|
+
coerce?: boolean | CoercionRegistry;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Peel `.optional()` / `.nullable()` / `.default()` / `.refine()` /
|
|
45
|
+
* `.transform()` wrappers off a Zod v3 schema to reach the inner
|
|
46
|
+
* `ZodObject`. Returns `never` if no `ZodObject` is found.
|
|
47
|
+
*
|
|
48
|
+
* Used internally by the v3 `useForm` overload to verify the
|
|
49
|
+
* supplied schema bottoms out at a `ZodObject`.
|
|
50
|
+
*/
|
|
51
|
+
type UnwrapZodObject<T> = T extends z.ZodEffects<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodOptional<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodNullable<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodDefault<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodObject<infer Shape> ? z.ZodObject<Shape> : never;
|
|
52
|
+
|
|
53
|
+
export type { StorageShape as S, UnwrapZodObject as U, UseFormConfigurationWithZod as a };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ag as ValidateOnConfig, F as FormKey, E as OnInvalidSubmitPolicy, X as PersistConfig, y as HistoryConfig, C as CoercionRegistry } from './attaform.C_5aB6EQ.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* v3 mirror of the Zod v4 `StorageShape`. Per top-level key, default
|
|
6
|
+
* to `z.output<Shape[K]>` (the post-init view — defaults have fired,
|
|
7
|
+
* Zod's own recursion peels nested defaults inside structural
|
|
8
|
+
* containers); fall back to `z.input<Shape[K]>` for transform / pipe
|
|
9
|
+
* carriers (`ZodEffects`, `ZodPipeline`) where storage holds the
|
|
10
|
+
* pre-transform input — transforms only run at submission /
|
|
11
|
+
* validation, not at the write boundary.
|
|
12
|
+
*
|
|
13
|
+
* v3 quirk: `ZodEffects` covers BOTH `.transform()` and
|
|
14
|
+
* `z.preprocess()` at the TS level — v3 doesn't carry a separate
|
|
15
|
+
* preprocess class the way v4 does. Deferring to `z.input` for
|
|
16
|
+
* `ZodEffects` means a top-level `z.preprocess(fn, T)` leaf reads as
|
|
17
|
+
* the preprocess input (commonly `unknown`); reach for the
|
|
18
|
+
* `AbstractSchema` escape hatch if a stronger type is needed.
|
|
19
|
+
* Transforms preserve their pre-transform input shape, which matches
|
|
20
|
+
* storage.
|
|
21
|
+
*/
|
|
22
|
+
type StorageShape<S extends z.ZodTypeAny> = S extends z.ZodObject<infer Shape> ? {
|
|
23
|
+
[K in keyof Shape]-?: Shape[K] extends z.ZodEffects<z.ZodTypeAny> | z.ZodPipeline<z.ZodTypeAny, z.ZodTypeAny> ? z.input<Shape[K]> : z.output<Shape[K]>;
|
|
24
|
+
} : z.input<S>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Configuration object for the Zod v3 `useForm` overload. Same
|
|
28
|
+
* shape as the schema-agnostic `UseFormConfiguration`, but with
|
|
29
|
+
* `schema` constrained to a `z.ZodObject` (or wrapped form).
|
|
30
|
+
*/
|
|
31
|
+
type UseFormConfigurationWithZod<Schema extends z.ZodType<unknown>, DefaultValues> = ValidateOnConfig & {
|
|
32
|
+
/** A Zod v3 `ZodObject` schema (or one wrapped in `.optional()` / `.nullable()` / `.default()` / `.refine()`). */
|
|
33
|
+
schema: Schema extends z.ZodType<unknown> ? UnwrapZodObject<Schema> extends z.ZodObject<z.ZodRawShape> ? Schema : never : never;
|
|
34
|
+
key?: FormKey;
|
|
35
|
+
defaultValues?: DefaultValues;
|
|
36
|
+
strict?: boolean;
|
|
37
|
+
onInvalidSubmit?: OnInvalidSubmitPolicy;
|
|
38
|
+
persist?: PersistConfig;
|
|
39
|
+
history?: HistoryConfig;
|
|
40
|
+
rememberVariants?: boolean;
|
|
41
|
+
coerce?: boolean | CoercionRegistry;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Peel `.optional()` / `.nullable()` / `.default()` / `.refine()` /
|
|
45
|
+
* `.transform()` wrappers off a Zod v3 schema to reach the inner
|
|
46
|
+
* `ZodObject`. Returns `never` if no `ZodObject` is found.
|
|
47
|
+
*
|
|
48
|
+
* Used internally by the v3 `useForm` overload to verify the
|
|
49
|
+
* supplied schema bottoms out at a `ZodObject`.
|
|
50
|
+
*/
|
|
51
|
+
type UnwrapZodObject<T> = T extends z.ZodEffects<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodOptional<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodNullable<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodDefault<infer Inner> ? UnwrapZodObject<Inner> : T extends z.ZodObject<infer Shape> ? z.ZodObject<Shape> : never;
|
|
52
|
+
|
|
53
|
+
export type { StorageShape as S, UnwrapZodObject as U, UseFormConfigurationWithZod as a };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GenericForm, F as FormKey, d as UseFormReturnType, R as RegisterValue } from './attaform.
|
|
1
|
+
import { G as GenericForm, F as FormKey, d as UseFormReturnType, R as RegisterValue } from './attaform.C_5aB6EQ.cjs';
|
|
2
2
|
import { Ref } from 'vue';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { G as GenericForm, s as FlatPath, B as NestedType, U as UseFormConfiguration, b as AbstractSchema, D as DeepPartial, c as DefaultValuesShape, ag as ValidateOnConfig, d as UseFormReturnType } from './attaform.C_5aB6EQ.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The shape `form.values.<key>` returns at runtime.
|
|
6
|
+
*
|
|
7
|
+
* Per leaf:
|
|
8
|
+
*
|
|
9
|
+
* 1. `z.preprocess(fn, inner)` — compiles to `ZodPipe<ZodTransform, inner>`.
|
|
10
|
+
* The preprocess fn fires at the write boundary (synthesized into
|
|
11
|
+
* `setValue`), so storage holds whatever `inner` stores. Recurse
|
|
12
|
+
* `StorageShape` on `inner` so a defaulted leaf inside `inner` still
|
|
13
|
+
* reads `T` (not `T | undefined`).
|
|
14
|
+
*
|
|
15
|
+
* 2. `inner.transform(fn)` — compiles to `ZodPipe<inner, ZodTransform>`.
|
|
16
|
+
* Transforms fire at submit / validate, NOT at the write boundary,
|
|
17
|
+
* so storage holds whatever `inner` stores. Recurse `StorageShape`
|
|
18
|
+
* on `inner` for the same reason.
|
|
19
|
+
*
|
|
20
|
+
* A bare top-level `ZodTransform` (no `in` schema) reads
|
|
21
|
+
* `_zod.input` directly — there's no inner to recurse into.
|
|
22
|
+
*
|
|
23
|
+
* 3. Codec / generic pipe — neither side is a transform. Read
|
|
24
|
+
* `_zod.output`. Codecs aren't write-boundary-synthesized, so the
|
|
25
|
+
* post-parse view is the only honest storage type.
|
|
26
|
+
*
|
|
27
|
+
* 4. Everything else (defaults, catch, readonly, optional, primitives,
|
|
28
|
+
* nested objects) — read `_zod.output`. Defaults and catches fire
|
|
29
|
+
* at parse time, so the post-init view is what storage holds.
|
|
30
|
+
* Nested objects delegate to Zod's own recursion on `_zod.output`,
|
|
31
|
+
* which peels nested defaults inside structural containers.
|
|
32
|
+
*
|
|
33
|
+
* Recursion: the alias calls itself on the non-transform side of a
|
|
34
|
+
* pipe so the inner shape gets the same per-key storage treatment as
|
|
35
|
+
* the top level. Without it, an inner `.default(...)` inside a
|
|
36
|
+
* transformed object would peel back to `T | undefined` (the broad
|
|
37
|
+
* input contract). Recursion only fires for pipe leaves — most leaves
|
|
38
|
+
* skip it.
|
|
39
|
+
*
|
|
40
|
+
* Implementation note: direct `_zod` property access mirrors Zod's
|
|
41
|
+
* own `$InferObjectOutput` / `$InferObjectInput`, which read
|
|
42
|
+
* `T[k]['_zod']['output']` / `T[k]['_zod']['input']` directly rather
|
|
43
|
+
* than wrapping in the top-level `output<T>` / `input<T>` conditional.
|
|
44
|
+
* Wrapping per key spawns a fresh conditional instantiation for every
|
|
45
|
+
* key; Volar's web-worker checker collapses that per-key walk to
|
|
46
|
+
* `any` once the schema is non-trivial. Property access has no
|
|
47
|
+
* conditional and resolves cleanly under the same budget.
|
|
48
|
+
*
|
|
49
|
+
* Shape access also goes through `_zod.def.shape` rather than
|
|
50
|
+
* `infer Shape from z.ZodObject<Shape>` — the latter collapses to the
|
|
51
|
+
* `$ZodShape` upper bound in the same worker because of
|
|
52
|
+
* `z.ZodObject`'s `out Shape` covariance markers.
|
|
53
|
+
*/
|
|
54
|
+
type StorageShape<S> = S extends {
|
|
55
|
+
_zod: {
|
|
56
|
+
def: {
|
|
57
|
+
type: 'object';
|
|
58
|
+
shape: infer Shape;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
} ? {
|
|
62
|
+
[K in keyof Shape]-?: StorageLeaf<Shape[K]>;
|
|
63
|
+
} : StorageLeaf<S>;
|
|
64
|
+
type StorageLeaf<L> = L extends {
|
|
65
|
+
_zod: {
|
|
66
|
+
def: {
|
|
67
|
+
type: 'pipe';
|
|
68
|
+
in: infer A;
|
|
69
|
+
out: infer B;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
} ? A extends {
|
|
73
|
+
_zod: {
|
|
74
|
+
def: {
|
|
75
|
+
type: 'transform';
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
} ? StorageShape<B> : B extends {
|
|
79
|
+
_zod: {
|
|
80
|
+
def: {
|
|
81
|
+
type: 'transform';
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
} ? StorageShape<A> : L extends {
|
|
85
|
+
_zod: {
|
|
86
|
+
output: infer Out;
|
|
87
|
+
};
|
|
88
|
+
} ? Out : never : L extends {
|
|
89
|
+
_zod: {
|
|
90
|
+
def: {
|
|
91
|
+
type: 'transform';
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
} ? L extends {
|
|
95
|
+
_zod: {
|
|
96
|
+
input: infer In;
|
|
97
|
+
};
|
|
98
|
+
} ? In : never : L extends {
|
|
99
|
+
_zod: {
|
|
100
|
+
output: infer Out;
|
|
101
|
+
};
|
|
102
|
+
} ? Out : never;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Zod v4 adapter entry point. Re-exports the adapter + the useForm
|
|
106
|
+
* wrapper that threads zod-v4-specific schema types through
|
|
107
|
+
* useAbstractForm.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Type of the value accepted at `Path` for `setValue` / `defaultValues`
|
|
112
|
+
* — the schema's `z.input<Schema>` shape at that path. Matches what
|
|
113
|
+
* `form.values.X` returns at runtime (the honest input view storage
|
|
114
|
+
* holds before transforms run).
|
|
115
|
+
*
|
|
116
|
+
* ```ts
|
|
117
|
+
* const schema = z.object({
|
|
118
|
+
* flag: z.string().transform((v) => v.length > 10),
|
|
119
|
+
* })
|
|
120
|
+
* type FlagWriteIn = PathInput<typeof schema, 'flag'> // string
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
type PathInput<Schema extends z.ZodType, Path extends string> = z.input<Schema> extends GenericForm ? Path extends FlatPath<z.input<Schema>> ? NestedType<z.input<Schema>, Path> : never : never;
|
|
124
|
+
/**
|
|
125
|
+
* Type produced at `Path` after the full parse pipeline — the schema's
|
|
126
|
+
* `z.output<Schema>` shape at that path. Matches the `data` payload of
|
|
127
|
+
* `form.process()` and the value handed to `handleSubmit`'s callback.
|
|
128
|
+
*
|
|
129
|
+
* ```ts
|
|
130
|
+
* const schema = z.object({
|
|
131
|
+
* flag: z.string().transform((v) => v.length > 10),
|
|
132
|
+
* })
|
|
133
|
+
* type FlagParsedOut = PathOutput<typeof schema, 'flag'> // boolean
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
type PathOutput<Schema extends z.ZodType, Path extends string> = z.output<Schema> extends GenericForm ? Path extends FlatPath<z.output<Schema>> ? NestedType<z.output<Schema>, Path> : never : never;
|
|
137
|
+
/**
|
|
138
|
+
* Create a form bound to a Zod v4 schema.
|
|
139
|
+
*
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { useForm } from 'attaform/zod'
|
|
142
|
+
* import { z } from 'zod'
|
|
143
|
+
*
|
|
144
|
+
* const form = useForm({
|
|
145
|
+
* schema: z.object({
|
|
146
|
+
* email: z.email(),
|
|
147
|
+
* password: z.string().min(8),
|
|
148
|
+
* }),
|
|
149
|
+
* defaultValues: { email: '' },
|
|
150
|
+
* })
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* Returns a form API exposing `register`, `values`, `errors`,
|
|
154
|
+
* `fields`, `setValue`, `handleSubmit`, `meta`, field-array
|
|
155
|
+
* helpers, and more. See `UseFormReturnType` for the full
|
|
156
|
+
* surface.
|
|
157
|
+
*
|
|
158
|
+
* For Zod v3, import from `attaform/zod-v3` instead.
|
|
159
|
+
*/
|
|
160
|
+
declare function useForm<Schema extends z.ZodObject>(configuration: Omit<UseFormConfiguration<z.input<Schema> extends GenericForm ? z.input<Schema> : never, z.output<Schema> extends GenericForm ? z.output<Schema> : never, AbstractSchema<z.input<Schema> extends GenericForm ? z.input<Schema> : never, z.output<Schema> extends GenericForm ? z.output<Schema> : never>, DeepPartial<DefaultValuesShape<z.input<Schema> extends GenericForm ? z.input<Schema> : never>>>, 'schema' | 'validateOn' | 'debounceMs'> & {
|
|
161
|
+
schema: Schema;
|
|
162
|
+
} & ValidateOnConfig): UseFormReturnType<z.input<Schema> extends GenericForm ? z.input<Schema> : never, z.output<Schema> extends GenericForm ? z.output<Schema> : never, StorageShape<Schema> extends GenericForm ? StorageShape<Schema> : never>;
|
|
163
|
+
|
|
164
|
+
export { useForm as u };
|
|
165
|
+
export type { PathInput as P, StorageShape as S, PathOutput as a };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GenericForm, F as FormKey, d as UseFormReturnType, R as RegisterValue } from './attaform.
|
|
1
|
+
import { G as GenericForm, F as FormKey, d as UseFormReturnType, R as RegisterValue } from './attaform.C_5aB6EQ.js';
|
|
2
2
|
import { Ref } from 'vue';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -670,6 +670,34 @@ type AbstractSchema<Form, GetValueFormType> = {
|
|
|
670
670
|
* callers treat that as "don't fill" and fall back to existing data.
|
|
671
671
|
*/
|
|
672
672
|
getDefaultAtPath(path: Path): unknown;
|
|
673
|
+
/**
|
|
674
|
+
* Return the schema's "appropriate nullish value" at the given path
|
|
675
|
+
* — the underlying type's empty/falsy concrete, with `.default(x)`
|
|
676
|
+
* wrappers explicitly NOT honoured. Powers `form.clear(path)`:
|
|
677
|
+
* `clear` differs from `reset` precisely in that it ignores
|
|
678
|
+
* declared defaults and produces `false` / `0` / `''` / `[]` / a
|
|
679
|
+
* recursively-empty object instead.
|
|
680
|
+
*
|
|
681
|
+
* Semantics (mirrors `getDefaultAtPath`'s sub-path resolution,
|
|
682
|
+
* differs at leaves):
|
|
683
|
+
* - **Primitive leaf:** the primitive's falsy concrete
|
|
684
|
+
* (`''` / `0` / `false` / `0n` / `new Date(0)`, etc.).
|
|
685
|
+
* - **Array / Set / Record:** empty.
|
|
686
|
+
* - **Optional<T>:** `undefined` (the wrapper's "absent" marker).
|
|
687
|
+
* - **Nullable<T>:** `null` (the wrapper's "explicit empty").
|
|
688
|
+
* - **Default<T> / Prefault<T> / Catch<T>:** inner-schema empty
|
|
689
|
+
* — the declared default value is INTENTIONALLY skipped.
|
|
690
|
+
* - **Readonly<T> / preprocess(fn, T):** inner-schema empty.
|
|
691
|
+
* - **Object:** recursive — every property gets its own empty.
|
|
692
|
+
* - **Discriminated union:** first variant's recursive empty
|
|
693
|
+
* (parallels `getDefaultAtPath`'s first-success precedent).
|
|
694
|
+
* - **Path doesn't exist in schema:** `undefined`.
|
|
695
|
+
*
|
|
696
|
+
* Adapters may return `undefined` when the path can't be resolved;
|
|
697
|
+
* callers treat that as "don't write" and leave existing storage
|
|
698
|
+
* unchanged.
|
|
699
|
+
*/
|
|
700
|
+
getEmptyValueAtPath(path: Path): unknown;
|
|
673
701
|
/**
|
|
674
702
|
* Give the schema a chance to normalize the consumer's write value
|
|
675
703
|
* before it lands in storage / hits the slim-primitive gate. Each
|
|
@@ -3016,23 +3044,30 @@ type FormMeta<F = unknown> = FieldState<F> & {
|
|
|
3016
3044
|
* form.meta.submitting // form-level reactive flag
|
|
3017
3045
|
* ```
|
|
3018
3046
|
*
|
|
3019
|
-
*
|
|
3047
|
+
* Three generic slots split the write view, parse view, and read view:
|
|
3020
3048
|
*
|
|
3021
|
-
* - `Form` — the **input /
|
|
3022
|
-
* by `setValue`, `defaultValues`,
|
|
3023
|
-
*
|
|
3024
|
-
*
|
|
3025
|
-
* write boundary, but `.transform()`s are deferred to parse-time.
|
|
3049
|
+
* - `Form` — the **input / write shape** (`z.input<Schema>`). Used
|
|
3050
|
+
* by `setValue`, `defaultValues`, and `register`'s write side.
|
|
3051
|
+
* Loose: preprocess paths accept `unknown` at the write boundary,
|
|
3052
|
+
* defaulted fields accept their inner type optionally.
|
|
3026
3053
|
*
|
|
3027
3054
|
* - `GetValueFormType` — the **output / parsed shape**
|
|
3028
3055
|
* (`z.output<Schema>`). Used by `handleSubmit`'s `onSubmit`
|
|
3029
3056
|
* callback and by `form.process()`'s success payload. This is the
|
|
3030
3057
|
* shape after refinements have fired and transforms have run.
|
|
3031
3058
|
*
|
|
3032
|
-
*
|
|
3033
|
-
*
|
|
3059
|
+
* - `ReadForm` — the **read / storage shape**. Used by `values`,
|
|
3060
|
+
* `fields`, `register`'s read side, `toRef`. Per-key precise: at
|
|
3061
|
+
* the write-boundary wrappers (`default` / `prefault` / `catch` /
|
|
3062
|
+
* `readonly` / `preprocess`) the value is `z.output<Inner>`
|
|
3063
|
+
* (default has fired, preprocess has normalized); at transforms /
|
|
3064
|
+
* pipes the value stays `z.input<Inner>` (transforms are deferred
|
|
3065
|
+
* until parse). For schema-agnostic call sites defaults to `Form`.
|
|
3066
|
+
*
|
|
3067
|
+
* For schemas without write-boundary wrappers or transforms the three
|
|
3068
|
+
* shapes coincide.
|
|
3034
3069
|
*/
|
|
3035
|
-
type UseFormReturnType<Form extends GenericForm, GetValueFormType extends GenericForm = Form> = {
|
|
3070
|
+
type UseFormReturnType<Form extends GenericForm, GetValueFormType extends GenericForm = Form, ReadForm extends GenericForm = Form> = {
|
|
3036
3071
|
/**
|
|
3037
3072
|
* Wraps your submit logic with validation and error routing.
|
|
3038
3073
|
*
|
|
@@ -3079,7 +3114,7 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
3079
3114
|
* value reads as `string`, not `boolean`. Use `handleSubmit` or
|
|
3080
3115
|
* `form.process()` when you need the post-transform output shape.
|
|
3081
3116
|
*/
|
|
3082
|
-
values: ValuesSurface<WriteShape<
|
|
3117
|
+
values: ValuesSurface<WriteShape<ReadForm>>;
|
|
3083
3118
|
/**
|
|
3084
3119
|
* Reactive per-field state proxy. Pinia-style nested object — read
|
|
3085
3120
|
* leaf properties (`value`, `dirty`, `touched`, `errors`, `blurred`,
|
|
@@ -3108,7 +3143,7 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
3108
3143
|
* Document edge case; rename the offending schema field if the
|
|
3109
3144
|
* collision matters.
|
|
3110
3145
|
*/
|
|
3111
|
-
fields: FieldStateMap<WriteShape<
|
|
3146
|
+
fields: FieldStateMap<WriteShape<ReadForm>>;
|
|
3112
3147
|
/**
|
|
3113
3148
|
* Write to the form programmatically. Two forms:
|
|
3114
3149
|
*
|
|
@@ -3259,8 +3294,8 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
3259
3294
|
* for storage activity to actually happen.
|
|
3260
3295
|
*/
|
|
3261
3296
|
register: {
|
|
3262
|
-
<Path extends RegisterFlatPath<Form, keyof Form>>(path: Path, options?: RegisterOptions): RegisterValue<NestedReadType<WriteShape<
|
|
3263
|
-
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [RegisterFlatPath<Form, keyof Form>] ? unknown : never), options?: RegisterOptions): RegisterValue<NestedReadType<WriteShape<
|
|
3297
|
+
<Path extends RegisterFlatPath<Form, keyof Form>>(path: Path, options?: RegisterOptions): RegisterValue<NestedReadType<WriteShape<ReadForm>, Path>>;
|
|
3298
|
+
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [RegisterFlatPath<Form, keyof Form>] ? unknown : never), options?: RegisterOptions): RegisterValue<NestedReadType<WriteShape<ReadForm>, JoinSegments<S>>>;
|
|
3264
3299
|
};
|
|
3265
3300
|
/**
|
|
3266
3301
|
* The form's identifier — either the explicit `key` passed to
|
|
@@ -3315,8 +3350,8 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
3315
3350
|
* scripts; `toRef` is for ref-shaped interop only.
|
|
3316
3351
|
*/
|
|
3317
3352
|
toRef: {
|
|
3318
|
-
<Path extends FlatPath<Form>>(path: Path): Readonly<Ref<NestedReadType<WriteShape<
|
|
3319
|
-
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): Readonly<Ref<NestedReadType<WriteShape<
|
|
3353
|
+
<Path extends FlatPath<Form>>(path: Path): Readonly<Ref<NestedReadType<WriteShape<ReadForm>, Path>>>;
|
|
3354
|
+
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): Readonly<Ref<NestedReadType<WriteShape<ReadForm>, JoinSegments<S>>>>;
|
|
3320
3355
|
};
|
|
3321
3356
|
/**
|
|
3322
3357
|
* Replace every field error for this form with the provided list.
|
|
@@ -3430,6 +3465,51 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
3430
3465
|
* from the persisted draft too.
|
|
3431
3466
|
*/
|
|
3432
3467
|
resetField: (path: FlatPath<Form>) => void;
|
|
3468
|
+
/**
|
|
3469
|
+
* Wipe a field (or the whole form) to the "appropriate nullish
|
|
3470
|
+
* value" for its declared type — the underlying type's empty/falsy
|
|
3471
|
+
* concrete, with any `.default(x)` wrapper INTENTIONALLY skipped.
|
|
3472
|
+
* Orthogonal to `reset` / `resetField` by design.
|
|
3473
|
+
*
|
|
3474
|
+
* ```ts
|
|
3475
|
+
* const schema = z.object({
|
|
3476
|
+
* notify: z.boolean().default(true),
|
|
3477
|
+
* count: z.number().default(5),
|
|
3478
|
+
* })
|
|
3479
|
+
* const form = useForm({ schema })
|
|
3480
|
+
*
|
|
3481
|
+
* form.reset() // notify → true, count → 5 (defaults)
|
|
3482
|
+
* form.clear() // notify → false, count → 0 (falsy-for-type)
|
|
3483
|
+
* form.clear('notify') // → false (NOT the declared default true)
|
|
3484
|
+
* ```
|
|
3485
|
+
*
|
|
3486
|
+
* Per-wrapper semantics:
|
|
3487
|
+
*
|
|
3488
|
+
* - `.default(x)` / `.prefault(x)` / `.catch(x)` → inner-schema
|
|
3489
|
+
* empty (default is INTENTIONALLY skipped).
|
|
3490
|
+
* - `.optional()` → `undefined` (the wrapper's "absent" marker).
|
|
3491
|
+
* - `.nullable()` → `null` (the wrapper's "explicit empty").
|
|
3492
|
+
* - Object → recursive (every property gets its own empty).
|
|
3493
|
+
* - Array / Set / Record → empty.
|
|
3494
|
+
*
|
|
3495
|
+
* Returns `true` when the write was accepted, `false` when the
|
|
3496
|
+
* adapter couldn't resolve an empty value at the path (e.g. the
|
|
3497
|
+
* path doesn't exist in the schema). The form state is unchanged
|
|
3498
|
+
* on a `false` return.
|
|
3499
|
+
*
|
|
3500
|
+
* Sugar over `setValue(path, schema.getEmptyValueAtPath(path))` —
|
|
3501
|
+
* no separate bookkeeping. Variant memory, history, persistence,
|
|
3502
|
+
* and listeners all see this as a regular write at the path.
|
|
3503
|
+
*
|
|
3504
|
+
* `clear()` (no arg) targets the whole form. `clear('')` targets
|
|
3505
|
+
* the empty-string path slot SPECIFICALLY — the two are NOT
|
|
3506
|
+
* interchangeable, matching `touch()` / `touch('')` from #184.
|
|
3507
|
+
*/
|
|
3508
|
+
clear: {
|
|
3509
|
+
(): boolean;
|
|
3510
|
+
<Path extends FlatPath<Form> | ''>(path: Path): boolean;
|
|
3511
|
+
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form> | ''] ? unknown : never)): boolean;
|
|
3512
|
+
};
|
|
3433
3513
|
/**
|
|
3434
3514
|
* Write the current value at `path` to storage immediately. Useful
|
|
3435
3515
|
* for explicit "Save draft" buttons, `beforeunload` handlers, or
|