attaform 0.30.0 → 0.31.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.
Files changed (71) hide show
  1. package/dist/abstract.d.mts +15 -21
  2. package/dist/abstract.mjs +3 -3
  3. package/dist/dev/abstract.mjs +4 -4
  4. package/dist/dev/chunks/devtools.mjs +4 -4
  5. package/dist/dev/directive.mjs +1 -1
  6. package/dist/dev/history.mjs +2 -2
  7. package/dist/dev/index.mjs +5 -5
  8. package/dist/dev/runtime/plugins/attaform.mjs +1 -1
  9. package/dist/dev/shared/{attaform-dev.DUZckyV8.mjs → attaform-dev.B1q-x9R9.mjs} +4 -4
  10. package/dist/dev/shared/{attaform-dev.BcYT6tFh.mjs → attaform-dev.CZz4GYZ6.mjs} +21 -9
  11. package/dist/dev/shared/{attaform-dev.BisFstxh.mjs → attaform-dev.Caibt7sb.mjs} +16 -15
  12. package/dist/dev/shared/{attaform-dev.DTrHonpc.mjs → attaform-dev.CtyqGia7.mjs} +176 -260
  13. package/dist/dev/shared/{attaform-dev.BK6Ge2qR.mjs → attaform-dev.DJ3nsWw6.mjs} +86 -122
  14. package/dist/dev/shared/{attaform-dev.BcNtyOmf.mjs → attaform-dev.DlaT4xGd.mjs} +4 -4
  15. package/dist/dev/shared/{attaform-dev.D6CLvaQT.mjs → attaform-dev.k5X47GMD.mjs} +520 -395
  16. package/dist/dev/shared/{attaform-dev.CQ2rJiAX.mjs → attaform-dev.y9x9Vp9F.mjs} +324 -234
  17. package/dist/dev/shared/{attaform-dev.BQc5QV3Y.mjs → attaform-dev.zlvDr0WB.mjs} +2 -2
  18. package/dist/dev/zod-v3.mjs +6 -6
  19. package/dist/dev/zod-v4.mjs +6 -6
  20. package/dist/dev/zod.mjs +5 -5
  21. package/dist/directive.d.mts +4 -4
  22. package/dist/directive.mjs +1 -1
  23. package/dist/esbuild.d.mts +11 -0
  24. package/dist/esbuild.mjs +1 -1
  25. package/dist/history.d.mts +3 -32
  26. package/dist/history.mjs +2 -2
  27. package/dist/index.d.mts +67 -70
  28. package/dist/index.mjs +4 -4
  29. package/dist/nuxt.d.mts +4 -3
  30. package/dist/nuxt.mjs +3 -6
  31. package/dist/rollup.d.mts +11 -0
  32. package/dist/rollup.mjs +1 -1
  33. package/dist/rspack.d.mts +19 -11
  34. package/dist/rspack.mjs +1 -1
  35. package/dist/runtime/components/AttaformDevtoolsPanel.vue +15 -15
  36. package/dist/runtime/components/DevtoolsValueTree.vue +2 -2
  37. package/dist/runtime/plugins/attaform.mjs +1 -1
  38. package/dist/shared/{attaform.BRDDQeHV.mjs → attaform.8mfKZCwH.mjs} +2 -2
  39. package/dist/shared/{attaform.DRUT703x.d.mts → attaform.B-Tb62qV.d.mts} +12 -12
  40. package/dist/shared/{attaform.v0fQtWyA.mjs → attaform.B1rH9ht6.mjs} +1 -1
  41. package/dist/shared/{attaform.DhnPb6nK.mjs → attaform.BAf3UNn4.mjs} +1 -1
  42. package/dist/shared/{attaform.BXneBxEj.mjs → attaform.BWUn8Kjy.mjs} +85 -121
  43. package/dist/shared/{attaform.WiGdIqgx.mjs → attaform.C4shmwyJ.mjs} +2 -2
  44. package/dist/shared/{attaform.Rc9u4Vfw.d.mts → attaform.CRVe8s82.d.mts} +83 -95
  45. package/dist/shared/attaform.D9RqPgGu.d.mts +42 -0
  46. package/dist/shared/attaform.DAo0QBmS.d.mts +2173 -0
  47. package/dist/shared/{attaform.BK0cgu2K.mjs → attaform.DBCbxlyk.mjs} +62 -4
  48. package/dist/shared/{attaform.CUfrMK7t.mjs → attaform.DL2nl_QR.mjs} +15 -14
  49. package/dist/shared/{attaform.DNJOWjQw.mjs → attaform.DNPJPOO7.mjs} +299 -218
  50. package/dist/shared/attaform.DZnrDrNb.d.mts +4657 -0
  51. package/dist/shared/{attaform.B3resMQ1.mjs → attaform.DxKQsqFZ.mjs} +496 -371
  52. package/dist/shared/{attaform.ByWP6kSx.mjs → attaform.L011tHgJ.mjs} +3 -3
  53. package/dist/shared/{attaform.CJ8DpRGj.mjs → attaform.LUPC-2Qg.mjs} +175 -257
  54. package/dist/transforms.d.mts +153 -26
  55. package/dist/transforms.mjs +1 -1
  56. package/dist/vite.d.mts +29 -52
  57. package/dist/vite.mjs +3 -3
  58. package/dist/webpack.d.mts +20 -12
  59. package/dist/webpack.mjs +1 -1
  60. package/dist/zod-v3.d.mts +90 -96
  61. package/dist/zod-v3.mjs +5 -5
  62. package/dist/zod-v4.d.mts +120 -118
  63. package/dist/zod-v4.mjs +5 -5
  64. package/dist/zod.d.mts +5 -5
  65. package/dist/zod.mjs +4 -4
  66. package/package.json +7 -6
  67. package/skills/attaform/SKILL.md +1 -1
  68. package/skills/attaform/references/custom-components.md +4 -0
  69. package/dist/shared/attaform.Clz0ArIi.d.mts +0 -44
  70. package/dist/shared/attaform.UGyOK83T.d.mts +0 -2366
  71. package/dist/shared/attaform.bKLzMU0o.d.mts +0 -4761
package/dist/zod-v3.d.mts CHANGED
@@ -1,22 +1,21 @@
1
1
  import { z } from 'zod';
2
- import { G as GenericForm, F as FormKey, U as UseFormConfiguration, aq as AcceptableDefaults, a as UseFormReturnType, ac as ValidateOnConfig, ap as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.bKLzMU0o.mjs';
2
+ import { G as GenericForm, F as FormKey, U as UseFormConfiguration, ap as AcceptableDefaults, a as UseFormReturnType, ab as ValidateOnConfig, ao as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.DZnrDrNb.mjs';
3
3
  import { AbstractSchema } from './abstract.mjs';
4
- export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaDefaultsResult, a0 as SchemaParseErrorWithData, a1 as SchemaParseErrorWithoutData, a2 as SchemaParseResult, a3 as SchemaParseSuccess, a4 as Segment, a5 as SetValueCallback, a6 as SetValuePayload, a7 as SettledValidationStatus, a8 as SlimPrimitiveKind, a9 as SubmitHandler, aa as Unset, ab as ValidateOn, ad as ValidationError, ae as ValidationResponse, af as ValidationResponseWithoutValue, ag as ValueOfUnion, ah as WriteMeta, ai as WriteShape, aj as canonicalizePath, ak as isPathPrefix, al as isUnset, am as parseDottedPath, an as unset } from './shared/attaform.bKLzMU0o.mjs';
5
- import { S as SupportedRootSchema, U as UnwrapZodRoot, a as StorageShape } from './shared/attaform.DRUT703x.mjs';
6
- export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.UGyOK83T.mjs';
7
- export { v as vRegister } from './shared/attaform.Clz0ArIi.mjs';
4
+ export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, aa as ValidateOn, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.DZnrDrNb.mjs';
5
+ import { S as SupportedRootSchema, U as UnwrapZodRoot, a as StorageShape } from './shared/attaform.B-Tb62qV.mjs';
6
+ export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.DAo0QBmS.mjs';
7
+ export { v as vRegister } from './shared/attaform.D9RqPgGu.mjs';
8
8
  import 'vue';
9
9
 
10
10
  /**
11
- * `FormOf` / `OutOf` / `ReadOf` factor the three identical-shape
12
- * conditionals out of the zod-typed `useForm` signature. The bundled
13
- * `.d.ts` then carries one alias per shape rather than re-inlining
14
- * `z.input<UnwrapZodObject<Schema>> extends GenericForm ? … : never`
15
- * four times — the pattern that produces TS2589 ("Type instantiation
16
- * is excessively deep") on consumer call sites with complex schemas
17
- * (discriminated unions, refines, deep `.register()` chains). Mirrors
18
- * the v4 adapter's own `FormOf`/`OutOf`/`ReadOf` aliases verbatim so
19
- * v3 and v4 carry the same per-call depth cost.
11
+ * Factor the three identical-shape conditionals out of the zod-typed
12
+ * `useForm` signature, so the bundled `.d.ts` carries one alias per
13
+ * shape instead of re-inlining `z.input<UnwrapZodRoot<Schema>> extends
14
+ * GenericForm ? ... : never` four times. That inlining is what produces
15
+ * TS2589 ("Type instantiation is excessively deep") at a consumer call
16
+ * site holding a discriminated union, a refine, or a deep `.register()`
17
+ * chain. The v4 adapter declares the same three aliases, so both lines
18
+ * carry the same per-call depth cost.
20
19
  */
21
20
  type FormOf<Schema extends SupportedRootSchema> = z.input<UnwrapZodRoot<Schema>> extends GenericForm ? z.input<UnwrapZodRoot<Schema>> : never;
22
21
  type OutOf<Schema extends SupportedRootSchema> = z.output<UnwrapZodRoot<Schema>> extends GenericForm ? z.output<UnwrapZodRoot<Schema>> : never;
@@ -27,39 +26,39 @@ type ReadOf<Schema extends SupportedRootSchema> = StorageShape<UnwrapZodRoot<Sch
27
26
  * ```ts
28
27
  * import { useForm } from 'attaform/zod-v3'
29
28
  *
30
- * const form = useForm({ schema: myAdapter, defaultValues: { … } })
29
+ * const form = useForm({ schema: myAdapter, defaultValues: { name: '' } })
31
30
  * ```
32
31
  *
33
- * For Zod schemas, prefer the overload that accepts a `ZodObject`
34
- * directly — it wraps the adapter automatically. For Zod v4, import
35
- * from `attaform/zod` instead.
32
+ * For a Zod schema, prefer the overload that takes the schema directly:
33
+ * it attaches the adapter for you. For Zod v4, import from
34
+ * `attaform/zod`.
36
35
  */
37
36
  declare function useForm<Form extends GenericForm, GetValueFormType extends GenericForm = Form, K extends FormKey = FormKey>(configuration: Omit<UseFormConfiguration<Form, GetValueFormType, AbstractSchema<Form, GetValueFormType>, never, K>, 'defaultValues'> & {
38
37
  defaultValues?: AcceptableDefaults<Form, Form>;
39
38
  }): UseFormReturnType<Form, GetValueFormType, Form, K>;
40
39
  /**
41
- * Create a form bound to a Zod v3 `ZodObject` schema.
40
+ * Create a form bound to a Zod v3 schema.
42
41
  *
43
42
  * ```ts
44
43
  * import { useForm } from 'attaform/zod-v3'
45
44
  * import { z } from 'zod'
46
45
  *
46
+ * const schema = z.object({
47
+ * email: z.string().email(),
48
+ * password: z.string().min(8),
49
+ * })
50
+ *
47
51
  * const form = useForm({
48
- * schema: z.object({
49
- * email: z.string().email(),
50
- * password: z.string().min(8),
51
- * }),
52
+ * schema,
52
53
  * defaultValues: { email: '' },
53
54
  * validateOn: 'blur',
54
55
  * })
55
56
  * ```
56
57
  *
57
- * Returns a form API exposing `register`, `values`, `errors`,
58
- * `fields`, `setValue`, `handleSubmit`, `meta`, field-array
59
- * helpers, and more. See `UseFormReturnType` for the full
60
- * surface.
61
- *
62
- * For Zod v4, import from `attaform/zod` instead.
58
+ * The returned form carries `register`, `values`, `errors`, `fields`,
59
+ * `setValue`, `handleSubmit`, `meta` and the field-array helpers; see
60
+ * `UseFormReturnType` for the whole surface. For Zod v4, import from
61
+ * `attaform/zod`.
63
62
  */
64
63
  declare function useForm<Schema extends SupportedRootSchema, K extends FormKey = FormKey>(configuration: Omit<UseFormConfiguration<FormOf<Schema>, OutOf<Schema>, AbstractSchema<FormOf<Schema>, OutOf<Schema>>, never, K>, 'schema' | 'validateOn' | 'debounceMs' | 'defaultValues'> & {
65
64
  schema: Schema;
@@ -78,9 +77,9 @@ interface ZodTypeWithInnerType extends z.ZodTypeAny {
78
77
  };
79
78
  }
80
79
  /**
81
- * The "honest read shape" of a Zod v3 schema — fields under records,
82
- * arrays, and dynamic boundaries are tagged optional/undefined to
83
- * reflect the runtime reality that those slots may be missing.
80
+ * The honest read shape of a Zod v3 schema: a field under a record, an
81
+ * array or a dynamic boundary is tagged optional or undefined, matching
82
+ * the runtime reality that the slot may be missing.
84
83
  *
85
84
  * Used internally by the v3 adapter as the read-side type for
86
85
  * `getValue` / `getFieldState`. Not commonly needed in consumer code.
@@ -95,15 +94,12 @@ type TypeWithNullableDynamicKeys<Schema extends z.ZodSchema, CrossedBoundary ext
95
94
  z.infer<Schema> | (CrossedBoundary extends true ? undefined : never);
96
95
 
97
96
  /**
98
- * Wrap a Zod v3 form-root schema (`ZodObject` or `ZodRecord`) in an
97
+ * Wrap a Zod v3 form-root schema, a `ZodObject` or `ZodRecord`, in an
99
98
  * `AbstractSchema` factory.
100
99
  *
101
- * Most consumers never call this directly — `useForm` from
102
- * `attaform/zod-v3` does the wrapping automatically. Reach
103
- * for it only when integrating with a custom code path that needs
104
- * the adapter outside of `useForm`.
105
- *
106
- * Throws if the underlying schema isn't a supported form root.
100
+ * `useForm` from `attaform/zod-v3` does this for you, so reach for it
101
+ * only to use the adapter outside `useForm`. Throws if the schema is not
102
+ * a supported form root.
107
103
  */
108
104
  declare function zodAdapter<FormSchema extends z.ZodSchema, Form extends z.input<FormSchema>, GetValueFormType extends TypeWithNullableDynamicKeys<FormSchema>>(zodSchema: FormSchema): (formKey: FormKey, options: SchemaFactoryOptions) => AbstractSchema<Form, GetValueFormType>;
109
105
 
@@ -163,44 +159,29 @@ type ZodTypeMap = {
163
159
  declare function isZodSchemaType<K extends keyof ZodTypeMap>(schema: unknown, expectedType: K): schema is ZodTypeMap[K];
164
160
 
165
161
  /**
166
- * Field-metadata write/read API for the Zod v3 adapter.
167
- *
168
- * Storage lives in the shared `field-meta-store` core — every entry
169
- * (`attaform/zod`, `attaform/zod-v3`, `attaform/zod-v4`) writes to and
170
- * reads from the same `WeakMap`s, so a payload registered via any
171
- * entry surfaces at lookup regardless of which adapter actually runs.
172
- *
173
- * Zod 3 has no `z.registry()` mechanism, so `fieldMeta` is the
174
- * shared registry-shaped object exposing `add` / `get` / `has` /
175
- * `remove`. The public `withMeta(schema, payload)` write API matches
176
- * `attaform/zod`'s so schema authoring reads identically across the
177
- * two adapters.
178
- *
179
- * **Registration patterns:** both styles work — register on whatever
180
- * schema reference you assign into the parent's shape, OR on the
181
- * inner schema before wrapping. The adapter's resolver tries the
182
- * walker-returned schema first, then falls back to the peeled
183
- * inner so either ordering hits:
184
- *
185
- * // both equivalent — registry hits at lookup time
162
+ * Field-metadata write and read API for the Zod v3 adapter.
163
+ *
164
+ * Storage lives in the shared `core/field-meta-store`, where every entry
165
+ * (`attaform/zod`, `attaform/zod-v3`, `attaform/zod-v4`) reads and
166
+ * writes the same `WeakMap`s, so a payload registered through any of
167
+ * them surfaces at lookup whichever adapter runs.
168
+ *
169
+ * **Registration order does not matter.** Register on the schema
170
+ * reference assigned into the parent's shape, or on the inner schema
171
+ * before wrapping:
172
+ *
173
+ * // equivalent; both hit at lookup time
186
174
  * withMeta(z.string(), { label: 'Email' }).optional()
187
175
  * withMeta(z.string().optional(), { label: 'Email' })
188
176
  *
189
- * The path walker returns the wrapper at terminal positions and
190
- * peels at intermediate descent. The two-stage lookup covers both
191
- * leaf and container registrations symmetrically.
177
+ * The path walker returns the wrapper at a terminal position and peels
178
+ * at intermediate descent, and the resolver tries the walker's schema
179
+ * before the peeled inner, so the two-stage lookup covers leaf and
180
+ * container registrations symmetrically.
192
181
  */
193
182
 
194
- /**
195
- * The shared registry every Attaform-aware Zod 3 schema can register
196
- * field metadata against. Backed by the cross-adapter store — a
197
- * payload registered here is visible to the v4 adapter and the
198
- * unified `attaform/zod` entry, and vice versa. Every `add` also
199
- * installs the path-walking resolver into the shared store's builder
200
- * slot, so the walk's bytes ride this module's import instead of the
201
- * adapter — a consumer that never registers metadata never ships the
202
- * walk.
203
- */
183
+ /** The `add` / `get` / `has` / `remove` shape of `fieldMeta`, matching
184
+ * Zod 4's `$ZodRegistry` closely enough to read the same either way. */
204
185
  type FieldMetaRegistryV3 = {
205
186
  /**
206
187
  * Register `payload` against `schema`. Returns the registry to
@@ -220,32 +201,45 @@ type FieldMetaRegistryV3 = {
220
201
  */
221
202
  remove(schema: z.ZodTypeAny): FieldMetaRegistryV3;
222
203
  };
204
+ /**
205
+ * The shared registry an Attaform-aware Zod 3 schema registers field
206
+ * metadata against.
207
+ *
208
+ * ```ts
209
+ * import { fieldMeta } from 'attaform/zod-v3'
210
+ *
211
+ * const email = z.string().email()
212
+ * fieldMeta.add(email, { label: 'Email address' })
213
+ * ```
214
+ *
215
+ * It is backed by the cross-adapter store, so a payload registered here
216
+ * is visible to the v4 adapter and to the unified `attaform/zod` entry,
217
+ * and the reverse. Every `add` also installs the path-walking resolver
218
+ * into the shared store's builder slot, which is what makes the walk's
219
+ * bytes ride this module's import rather than the adapter: a consumer
220
+ * who never registers metadata never ships the walk.
221
+ */
223
222
  declare const fieldMeta: FieldMetaRegistryV3;
224
223
  /**
225
- * Attach `payload` to `schema` in the shared `fieldMeta` registry
226
- * and return a clone of `schema` (chainable, with the new metadata).
227
- * Cross-version with `attaform/zod`'s `withMeta()`.
228
- *
229
- * **Why clone, not mutate.** The shared store keys metadata on the
230
- * schema reference. Calling `withMeta` twice on the same instance
231
- * would overwrite (last-write-wins) — so a sub-schema reused at
232
- * multiple form paths (e.g. an address schema shared between pickup
233
- * and delivery) couldn't carry distinct metadata per path.
234
- *
235
- * `withMeta` sidesteps the footgun by reconstructing `schema` via
236
- * its constructor + `_def` — Zod 3 schemas don't expose `.clone()`,
237
- * but `new schema.constructor(schema._def)` is the equivalent. Each
238
- * call gets a fresh identity and a fresh registry slot. Existing
239
- * metadata on the original is merged through, so chaining
240
- * `withMeta` accumulates payload fields rather than replacing.
241
- *
242
- * Inner field schemas (e.g. an object's `.shape.city`) are shared
243
- * across clones — the def is held by reference — so leaf metadata
244
- * registers once and surfaces at every path.
245
- *
246
- * `schema.register()` does NOT exist on Zod 3 — `withMeta` is the
247
- * only fluent write API. Register on the inner schema before
248
- * wrapping; see the "Registration rule" note in this file's header.
224
+ * Attach `payload` to `schema` in the shared `fieldMeta` registry and
225
+ * return a chainable CLONE of `schema` carrying the new metadata. Zod 3
226
+ * has no `schema.register()`, so this is its only fluent write API, and
227
+ * it matches `attaform/zod`'s `withMeta()`.
228
+ *
229
+ * It clones rather than mutates because the store keys metadata on the
230
+ * schema reference: calling `withMeta` twice on one instance would
231
+ * overwrite last-write-wins, and a sub-schema reused at several paths,
232
+ * an address shared between pickup and delivery say, could then carry
233
+ * only one payload. Zod 3 exposes no `.clone()`, so the reconstruction
234
+ * goes through `new schema.constructor(schema._def)`. Each call gets a
235
+ * fresh identity and a fresh registry slot, and existing metadata merges
236
+ * through, so chaining accumulates payload fields rather than replacing
237
+ * them.
238
+ *
239
+ * An inner field schema, an object's `.shape.city` for instance, is
240
+ * shared across clones, the def being held by reference, so leaf
241
+ * metadata registers once and surfaces at every path. See this file's
242
+ * header for the two equivalent registration orderings.
249
243
  */
250
244
  declare function withMeta<S extends z.ZodTypeAny>(schema: S, payload: FieldMetaPayload): S;
251
245
 
package/dist/zod-v3.mjs CHANGED
@@ -1,9 +1,9 @@
1
- export { i as isZodSchemaType, u as useForm, z as zodAdapter } from './shared/attaform.CJ8DpRGj.mjs';
2
- import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.CUfrMK7t.mjs';
1
+ export { i as isZodSchemaType, u as useForm, z as zodAdapter } from './shared/attaform.LUPC-2Qg.mjs';
2
+ import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.DL2nl_QR.mjs';
3
3
  export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.CdZIEf7_.mjs';
4
- export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNJOWjQw.mjs';
5
- export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.WiGdIqgx.mjs';
6
- export { a as assignKey, v as vRegister } from './shared/attaform.B3resMQ1.mjs';
4
+ export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNPJPOO7.mjs';
5
+ export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.C4shmwyJ.mjs';
6
+ export { a as assignKey, v as vRegister } from './shared/attaform.DxKQsqFZ.mjs';
7
7
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
8
8
 
9
9
  const fieldMeta = installingFieldMetaStore;
package/dist/zod-v4.d.mts CHANGED
@@ -1,163 +1,165 @@
1
- import { S as SupportedRootSchema } from './shared/attaform.Rc9u4Vfw.mjs';
2
- export { P as PathInput, a as PathOutput, u as useForm } from './shared/attaform.Rc9u4Vfw.mjs';
3
- export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.UGyOK83T.mjs';
4
- import { F as FormKey, ap as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.bKLzMU0o.mjs';
1
+ import { S as SupportedRootSchema } from './shared/attaform.CRVe8s82.mjs';
2
+ export { P as PathInput, a as PathOutput, u as useForm } from './shared/attaform.CRVe8s82.mjs';
3
+ import { F as FormKey, ao as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.DZnrDrNb.mjs';
5
4
  import { AbstractSchema } from './abstract.mjs';
6
- export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, G as GenericForm, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaDefaultsResult, a0 as SchemaParseErrorWithData, a1 as SchemaParseErrorWithoutData, a2 as SchemaParseResult, a3 as SchemaParseSuccess, a4 as Segment, a5 as SetValueCallback, a6 as SetValuePayload, a7 as SettledValidationStatus, a8 as SlimPrimitiveKind, a9 as SubmitHandler, aa as Unset, U as UseFormConfiguration, a as UseFormReturnType, ab as ValidateOn, ac as ValidateOnConfig, ad as ValidationError, ae as ValidationResponse, af as ValidationResponseWithoutValue, ag as ValueOfUnion, ah as WriteMeta, ai as WriteShape, aj as canonicalizePath, ak as isPathPrefix, al as isUnset, am as parseDottedPath, an as unset } from './shared/attaform.bKLzMU0o.mjs';
7
- export { v as vRegister } from './shared/attaform.Clz0ArIi.mjs';
5
+ export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, G as GenericForm, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, U as UseFormConfiguration, a as UseFormReturnType, aa as ValidateOn, ab as ValidateOnConfig, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.DZnrDrNb.mjs';
6
+ export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.DAo0QBmS.mjs';
7
+ export { v as vRegister } from './shared/attaform.D9RqPgGu.mjs';
8
8
  import { z } from 'zod';
9
9
  import 'vue';
10
10
 
11
11
  /**
12
- * Wrap a Zod v4 `ZodObject` schema in an `AbstractSchema` factory.
13
- *
14
- * Most consumers never call this directly — `useForm` from
15
- * `attaform/zod` does the wrapping automatically. Reach for
16
- * it when you need an adapter outside of `useForm` (e.g. validating
17
- * data with the same library used elsewhere in the form runtime, or
18
- * exposing the adapter to a custom integration).
19
- *
20
- * The returned factory accepts per-form `SchemaFactoryOptions` (notably
21
- * `maxRecursionDepth`); the adapter closure bakes them into every
22
- * downstream walk so a per-form override can lift the cap for that
23
- * form alone.
24
- *
25
- * Throws if the schema isn't Zod v4, or if its root is not a shape
26
- * that can hold keys. No kind is refused anywhere BELOW the root: a
27
- * leaf the walkers have no case for is carried opaquely rather than
28
- * rejected, so a schema a newer Zod can parse is one Attaform can
29
- * mount. Recursive `z.lazy(...)` is supported — the runtime walks
30
- * bound their descent via `maxRecursionDepth`.
12
+ * The Zod v4 adapter: `AbstractSchema` implemented against Zod v4's
13
+ * public surface. Internal `def.*` access is quarantined to
14
+ * `introspect.ts` and the modules beside it (default-values,
15
+ * path-walker, discriminator, errors), leaving this file as the wiring
16
+ * between them and the `AbstractSchema` contract.
17
+ *
18
+ * It holds parity with the v3 adapter on four fronts:
19
+ * `getDefaultValues`' derivation, delegated to `default-values.ts`
20
+ * (the default walk, then the DU-aware structural repair walk when
21
+ * constraints are supplied, parsing nothing); `validateSync`'s one
22
+ * synchronous parse of the real schema for the construction verdict;
23
+ * `getSchemasAtPath`' DU-aware path walk; and `validateAtPath`'s
24
+ * per-branch parse with aggregated errors.
25
+ */
26
+
27
+ /**
28
+ * Wrap a Zod v4 schema in an `AbstractSchema` factory.
29
+ *
30
+ * `useForm` from `attaform/zod` does this for you, so reach for it to
31
+ * use the adapter outside `useForm`: validating data with the same
32
+ * library the form runtime uses, or handing the adapter to a custom
33
+ * integration. The factory it returns takes per-form
34
+ * `SchemaFactoryOptions`, and the adapter closure bakes them into every
35
+ * downstream walk, so `maxRecursionDepth` can be lifted for one form
36
+ * alone.
37
+ *
38
+ * Throws if the schema is not Zod v4, or if its root cannot hold keys.
39
+ * No kind is refused anywhere BELOW the root: a leaf the walkers have no
40
+ * case for is carried opaquely rather than rejected, so a schema a newer
41
+ * Zod can parse is one Attaform can mount. Recursive `z.lazy(...)`
42
+ * works, its descent bounded by `maxRecursionDepth`.
31
43
  */
32
44
  declare function zodV4Adapter<FormSchema extends SupportedRootSchema, Form extends z.input<FormSchema>, GetValueFormType extends z.output<FormSchema> = z.output<FormSchema>>(rootSchema: FormSchema): (formKey: FormKey, options: SchemaFactoryOptions) => AbstractSchema<Form, GetValueFormType>;
33
45
 
34
46
  /**
35
- * The single file that reads Zod v4's internal `def` shape. Every other
36
- * file in the zod-v4 adapter uses these public-shaped accessors — future
37
- * Zod minor bumps that reshape internals touch only this file.
38
- *
39
- * Design principle: treat `schema.def.*` as an unstable surface, even when
40
- * Zod's docs say otherwise. Each helper returns a narrow, well-typed slice;
41
- * no adapter code outside this file does shape-based pattern matching on
42
- * `def`.
47
+ * The ONE file that reads Zod v4's internal `def` shape. Every other file
48
+ * in the adapter goes through these public-shaped accessors, so a Zod
49
+ * minor bump that reshapes internals touches only this file.
50
+ *
51
+ * Treat `schema.def.*` as unstable whatever Zod's docs say. Each helper
52
+ * returns a narrow, well-typed slice, and no adapter code outside this
53
+ * file pattern-matches on `def`.
43
54
  */
44
55
 
45
56
  /**
46
- * Stable kind discriminant for a Zod v4 schema. Returned by
47
- * `kindOf(schema)`. Use when building a custom integration that
48
- * needs to branch on schema shape — most consumers don't need this.
57
+ * Stable kind discriminant for a Zod v4 schema, returned by `kindOf`.
58
+ * Reach for it in a custom integration that branches on schema shape.
49
59
  */
50
60
  type ZodKind = 'object' | 'array' | 'set' | 'record' | 'tuple' | 'union' | 'discriminated-union' | 'string' | 'number' | 'boolean' | 'bigint' | 'date' | 'enum' | 'literal' | 'null' | 'undefined' | 'any' | 'unknown' | 'optional' | 'nullable' | 'default' | 'pipe' | 'readonly' | 'nan' | 'void' | 'never' | 'lazy' | 'intersection' | 'catch' | 'promise' | 'custom' | 'template-literal' | 'transform' | 'file' | 'nonoptional' | 'success' | 'map' | 'symbol' | 'function';
51
61
  /**
52
- * Inspect a Zod v4 schema and return its `ZodKind`. Returns
53
- * `'unknown'` for non-Zod inputs and unrecognised shapes.
54
- *
55
- * Useful when writing introspection helpers that branch on schema
56
- * structure (e.g. custom error formatters or doc generators).
62
+ * The `ZodKind` of a Zod v4 schema; `'unknown'` for a non-Zod input or an
63
+ * unrecognised shape. Useful in an introspection helper that branches on
64
+ * structure, a custom error formatter or a doc generator.
57
65
  */
58
66
  declare function kindOf(schema: unknown): ZodKind;
59
67
  /**
60
- * Verify a schema is Zod v4. Throws a clear error if it's a v3
61
- * schema mistakenly imported through `attaform/zod`.
62
- *
63
- * Most consumers never call this directly — the v4 adapter calls it
64
- * internally on every schema. Reach for it only when wiring a custom
65
- * adapter that needs the same guard.
68
+ * Verify a schema is Zod v4, throwing a clear error for a v3 schema
69
+ * imported through `attaform/zod` by mistake. The adapter calls it on
70
+ * every schema; reach for it directly only in a custom adapter that
71
+ * wants the same guard.
66
72
  */
67
73
  declare function assertZodVersion(schema: unknown): void;
68
74
 
69
75
  /**
70
- * Field-metadata write/read API for the Zod v4 adapter.
71
- *
72
- * Storage lives in the shared `field-meta-store` core — every entry
73
- * (`attaform/zod`, `attaform/zod-v3`, `attaform/zod-v4`) writes to and
74
- * reads from the same `WeakMap`s, so a payload registered via any
75
- * entry surfaces at lookup regardless of which adapter actually runs.
76
+ * Field-metadata write and read API for the Zod v4 adapter.
76
77
  *
77
- * The native chain `schema.register(fieldMeta, payload)` still works
78
- * — Zod 4's `.register` calls `registry.add(this, payload)` and
79
- * returns the schema; the shared store satisfies that structurally.
78
+ * Storage lives in the shared `core/field-meta-store`, where every entry
79
+ * (`attaform/zod`, `attaform/zod-v3`, `attaform/zod-v4`) reads and
80
+ * writes the same `WeakMap`s, so a payload registered through any of
81
+ * them surfaces at lookup whichever adapter runs. The native chain
82
+ * `schema.register(fieldMeta, payload)` works too: Zod 4's `.register`
83
+ * calls `registry.add(this, payload)` and returns the schema, which the
84
+ * shared store satisfies structurally.
80
85
  *
81
- * **Registration patterns:** both styles work — register on whatever
82
- * schema reference you assign into the parent's shape, OR on the
83
- * inner schema before wrapping. The adapter's resolver tries the
84
- * walker-returned schema first, then falls back to the peeled
85
- * inner so either ordering hits:
86
+ * **Registration order does not matter.** Register on the schema
87
+ * reference assigned into the parent's shape, or on the inner schema
88
+ * before wrapping:
86
89
  *
87
- * // both equivalent — registry hits at lookup time
90
+ * // equivalent; all four hit at lookup time
88
91
  * withMeta(z.string(), { label: 'Email' }).optional()
89
92
  * withMeta(z.string().optional(), { label: 'Email' })
90
93
  * z.string().optional().register(fieldMeta, { label: 'Email' })
91
94
  * z.string().register(fieldMeta, { label: 'Email' }).optional()
92
95
  *
93
- * The path walker returns the wrapper at terminal positions
94
- * (`['email']` against `{ email: z.string().optional() }` resolves
95
- * to `ZodOptional<ZodString>`) and peels at intermediate descent
96
- * (`['address', 'street']` peels through `address`'s wrapper to
97
- * reach the inner object). The two-stage lookup covers both leaf
98
- * and container registrations symmetrically.
96
+ * The path walker returns the wrapper at a terminal position, so
97
+ * `['email']` against `{ email: z.string().optional() }` resolves to
98
+ * `ZodOptional<ZodString>`, and peels at intermediate descent, so
99
+ * `['address', 'street']` goes through `address`'s wrapper to the inner
100
+ * object. The resolver tries the walker's schema before the peeled
101
+ * inner, so the two-stage lookup covers leaf and container
102
+ * registrations symmetrically.
99
103
  */
100
104
 
101
105
  type ZodFieldMetaRegistry = ReturnType<typeof z.registry<FieldMetaPayload>>;
102
106
  /**
103
- * The shared registry every Attaform-aware Zod 4 schema can register
104
- * field metadata against. Backed by the cross-adapter
105
- * `fieldMetaStore` — one module-scoped instance, shared with the v3
106
- * adapter and the unified `attaform/zod` entry, so a `.register()`
107
- * chain in one place is read by adapters in another.
108
- *
109
- * Consumers extending `FieldMetaPayload` via declaration merging
110
- * automatically get the richer payload type at every `register` /
111
- * `add` / `get` call site.
112
- *
113
- * **Shared-instance disambiguation.** A single schema instance reused
114
- * at multiple form paths (e.g. one address schema bound to both
115
- * `pickup` and `delivery`) can carry distinct metadata per path —
116
- * even via the canonical `schema.register(fieldMeta, payload)` chain.
117
- * The shared store keeps a parallel list of every registration; the
118
- * path-resolver walks the form's schema tree counting per-schema
119
- * occurrences to pick the right payload for each path. Object
120
- * literals evaluate left-to-right, so registration order matches
121
- * tree-walk order, and shared schemas pair their two registrations
122
- * to the two paths correctly:
107
+ * The shared registry an Attaform-aware Zod 4 schema registers field
108
+ * metadata against.
109
+ *
110
+ * ```ts
111
+ * import { fieldMeta } from 'attaform/zod'
112
+ *
113
+ * const schema = z.object({
114
+ * email: z.string().register(fieldMeta, { label: 'Email address' }),
115
+ * })
116
+ * ```
117
+ *
118
+ * One module-scoped instance, shared with the v3 adapter and the
119
+ * unified `attaform/zod` entry, so a `.register()` chain written in one
120
+ * place is read by an adapter in another. Extending `FieldMetaPayload`
121
+ * by declaration merging gives the richer payload type at every
122
+ * `register` / `add` / `get` call site.
123
+ *
124
+ * **One schema instance can carry different metadata per path.** Reuse
125
+ * an address schema at both `pickup` and `delivery` and each keeps its
126
+ * own label, through the native chain included:
123
127
  *
124
128
  * z.object({
125
129
  * pickup: addressSchema.register(fieldMeta, { label: 'Pickup address' }),
126
130
  * delivery: addressSchema.register(fieldMeta, { label: 'Delivery address' }),
127
131
  * })
128
- * // form.fields('pickup').label → 'Pickup address'
129
- * // form.fields('delivery').label → 'Delivery address'
130
- *
131
- * Schemas reused via `withMeta()` get a fresh clone per call (see
132
- * `withMeta` below), so they never share a registry slot in the
133
- * first place.
134
- *
135
- * Cast to `z.$ZodRegistry<FieldMetaPayload>` so that
136
- * `schema.register(fieldMeta, payload)` chains type-check at the call
137
- * site — Zod 4's `.register()` only calls `.add(this, payload)`
138
- * structurally, so the cast is sound at runtime.
139
- *
140
- * Backed by `installingFieldMetaStore`: every `add` also installs the
141
- * path-walking resolver into the shared store's builder slot, so the
142
- * walk's bytes ride this module's import instead of the adapter. A
143
- * consumer that never registers metadata never ships the walk.
132
+ * // form.fields('pickup').label -> 'Pickup address'
133
+ * // form.fields('delivery').label -> 'Delivery address'
134
+ *
135
+ * The store keeps a parallel list of every registration, and the
136
+ * path-resolver walks the form's schema tree counting per-schema
137
+ * occurrences to pick the right payload per path. Object literals
138
+ * evaluate left to right, so registration order matches tree-walk order
139
+ * and the pairing holds. `withMeta()` never reaches this case at all,
140
+ * since it clones per call.
141
+ *
142
+ * The cast to the registry type is what lets `schema.register(fieldMeta,
143
+ * payload)` type-check at the call site; Zod 4's `.register()` only
144
+ * calls `.add(this, payload)`, so it is sound at runtime. Every `add`
145
+ * also installs the path-walking resolver into the shared store's
146
+ * builder slot, which is what makes the walk's bytes ride this module's
147
+ * import rather than the adapter: a consumer who never registers
148
+ * metadata never ships the walk.
144
149
  */
145
150
  declare const fieldMeta: ZodFieldMetaRegistry;
146
151
  /**
147
- * Attach `payload` to `schema` in the shared `fieldMeta` registry
148
- * and return `schema` (chainable). Cross-version with `attaform/zod-v3`'s
149
- * `withMeta()`; user code that uses this helper reads the same on
150
- * either adapter.
151
- *
152
- * Equivalent to `schema.register(fieldMeta, payload)` on Zod 4.
153
- * Prefer the native chain for v4-only code; reach for `withMeta`
154
- * when authoring schema modules that may need to compile under both
155
- * adapters.
156
- *
157
- * Registers on the schema reference passed in. See the
158
- * "Registration rule" note in this file's header — register on the
159
- * inner schema before wrapping with `.optional()` / `.nullable()` /
160
- * `.default()` / etc.
152
+ * Attach `payload` to `schema` in the shared `fieldMeta` registry and
153
+ * return a chainable CLONE of `schema` carrying it. It matches
154
+ * `attaform/zod-v3`'s `withMeta()`, so a schema module written with it
155
+ * reads the same under either adapter.
156
+ *
157
+ * For v4-only code prefer the native `schema.register(fieldMeta,
158
+ * payload)`, which registers on the instance you passed and returns
159
+ * that same instance. Reach for `withMeta` when the module has to
160
+ * compile under both adapters, or when one schema instance is reused at
161
+ * several paths and each needs its own payload: the clone per call is
162
+ * what gives each call site its own registry slot.
161
163
  */
162
164
  declare function withMeta<S extends z.ZodType>(schema: S, payload: FieldMetaPayload): S;
163
165
 
package/dist/zod-v4.mjs CHANGED
@@ -1,9 +1,9 @@
1
- export { a as assertZodVersion, k as kindOf, u as useForm, z as zodAdapter } from './shared/attaform.BXneBxEj.mjs';
2
- import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.CUfrMK7t.mjs';
1
+ export { a as assertZodVersion, k as kindOf, u as useForm, z as zodAdapter } from './shared/attaform.BWUn8Kjy.mjs';
2
+ import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.DL2nl_QR.mjs';
3
3
  export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.CdZIEf7_.mjs';
4
- export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNJOWjQw.mjs';
5
- export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.WiGdIqgx.mjs';
6
- export { a as assignKey, v as vRegister } from './shared/attaform.B3resMQ1.mjs';
4
+ export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNPJPOO7.mjs';
5
+ export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.C4shmwyJ.mjs';
6
+ export { a as assignKey, v as vRegister } from './shared/attaform.DxKQsqFZ.mjs';
7
7
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
8
8
 
9
9
  const fieldMeta = installingFieldMetaStore;