attaform 0.30.0 → 0.30.1

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 (67) hide show
  1. package/dist/abstract.d.mts +15 -21
  2. package/dist/abstract.mjs +2 -2
  3. package/dist/dev/abstract.mjs +4 -4
  4. package/dist/dev/chunks/devtools.mjs +2 -2
  5. package/dist/dev/directive.mjs +1 -1
  6. package/dist/dev/history.mjs +1 -1
  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.BK6Ge2qR.mjs → attaform-dev.BJK1kqHY.mjs} +14 -14
  10. package/dist/dev/shared/{attaform-dev.D6CLvaQT.mjs → attaform-dev.BMQ3GcgD.mjs} +46 -59
  11. package/dist/dev/shared/{attaform-dev.BisFstxh.mjs → attaform-dev.BUIFcTYf.mjs} +6 -6
  12. package/dist/dev/shared/{attaform-dev.DTrHonpc.mjs → attaform-dev.CT7MDjPy.mjs} +27 -36
  13. package/dist/dev/shared/{attaform-dev.BcYT6tFh.mjs → attaform-dev.CZz4GYZ6.mjs} +21 -9
  14. package/dist/dev/shared/{attaform-dev.DUZckyV8.mjs → attaform-dev.Chm4D6SJ.mjs} +2 -2
  15. package/dist/dev/shared/{attaform-dev.BcNtyOmf.mjs → attaform-dev.DuEE4GU1.mjs} +4 -4
  16. package/dist/dev/shared/{attaform-dev.CQ2rJiAX.mjs → attaform-dev.DxHdkkPG.mjs} +126 -115
  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 +1 -1
  27. package/dist/index.d.mts +67 -70
  28. package/dist/index.mjs +3 -3
  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 +12 -12
  36. package/dist/runtime/components/DevtoolsValueTree.vue +2 -2
  37. package/dist/shared/{attaform.Rc9u4Vfw.d.mts → attaform.2FslhB9R.d.mts} +83 -95
  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.ByWP6kSx.mjs → attaform.B2iebkPA.mjs} +3 -3
  42. package/dist/shared/{attaform.DhnPb6nK.mjs → attaform.BAf3UNn4.mjs} +1 -1
  43. package/dist/shared/{attaform.DNJOWjQw.mjs → attaform.BIWicztt.mjs} +102 -100
  44. package/dist/shared/attaform.BcQwgWaq.d.mts +2153 -0
  45. package/dist/shared/attaform.Br8EBn5B.d.mts +4553 -0
  46. package/dist/shared/{attaform.BXneBxEj.mjs → attaform.CO918TdU.mjs} +13 -13
  47. package/dist/shared/{attaform.CUfrMK7t.mjs → attaform.DRsANMok.mjs} +5 -5
  48. package/dist/shared/{attaform.B3resMQ1.mjs → attaform.D_f1WgYf.mjs} +40 -53
  49. package/dist/shared/{attaform.CJ8DpRGj.mjs → attaform.D_pt1gOj.mjs} +26 -33
  50. package/dist/shared/attaform.L0kUn3vL.d.mts +42 -0
  51. package/dist/shared/{attaform.BK0cgu2K.mjs → attaform.ZYn2ahzJ.mjs} +3 -3
  52. package/dist/transforms.d.mts +153 -26
  53. package/dist/transforms.mjs +1 -1
  54. package/dist/vite.d.mts +29 -52
  55. package/dist/vite.mjs +3 -3
  56. package/dist/webpack.d.mts +20 -12
  57. package/dist/webpack.mjs +1 -1
  58. package/dist/zod-v3.d.mts +90 -96
  59. package/dist/zod-v3.mjs +4 -4
  60. package/dist/zod-v4.d.mts +118 -118
  61. package/dist/zod-v4.mjs +4 -4
  62. package/dist/zod.d.mts +5 -5
  63. package/dist/zod.mjs +3 -3
  64. package/package.json +7 -6
  65. package/dist/shared/attaform.Clz0ArIi.d.mts +0 -44
  66. package/dist/shared/attaform.UGyOK83T.d.mts +0 -2366
  67. package/dist/shared/attaform.bKLzMU0o.d.mts +0 -4761
package/dist/zod-v4.d.mts CHANGED
@@ -1,163 +1,163 @@
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.2FslhB9R.mjs';
2
+ export { P as PathInput, a as PathOutput, u as useForm } from './shared/attaform.2FslhB9R.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.BcQwgWaq.mjs';
4
+ import { F as FormKey, ap as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.Br8EBn5B.mjs';
5
5
  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';
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.Br8EBn5B.mjs';
7
+ export { v as vRegister } from './shared/attaform.L0kUn3vL.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 three fronts:
19
+ * `getDefaultValues`' validate-then-fix loop, delegated to
20
+ * `default-values.ts`, with a DU-aware first-option fallback for
21
+ * invalid_type issues; `getSchemasAtPath`' DU-aware path walk; and
22
+ * `validateAtPath`'s per-branch parse with aggregated errors.
23
+ */
24
+
25
+ /**
26
+ * Wrap a Zod v4 schema in an `AbstractSchema` factory.
27
+ *
28
+ * `useForm` from `attaform/zod` does this for you, so reach for it to
29
+ * use the adapter outside `useForm`: validating data with the same
30
+ * library the form runtime uses, or handing the adapter to a custom
31
+ * integration. The factory it returns takes per-form
32
+ * `SchemaFactoryOptions`, and the adapter closure bakes them into every
33
+ * downstream walk, so `maxRecursionDepth` can be lifted for one form
34
+ * alone.
35
+ *
36
+ * Throws if the schema is not Zod v4, or if its root cannot hold keys.
37
+ * No kind is refused anywhere BELOW the root: a leaf the walkers have no
38
+ * case for is carried opaquely rather than rejected, so a schema a newer
39
+ * Zod can parse is one Attaform can mount. Recursive `z.lazy(...)`
40
+ * works, its descent bounded by `maxRecursionDepth`.
31
41
  */
32
42
  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
43
 
34
44
  /**
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`.
45
+ * The ONE file that reads Zod v4's internal `def` shape. Every other file
46
+ * in the adapter goes through these public-shaped accessors, so a Zod
47
+ * minor bump that reshapes internals touches only this file.
48
+ *
49
+ * Treat `schema.def.*` as unstable whatever Zod's docs say. Each helper
50
+ * returns a narrow, well-typed slice, and no adapter code outside this
51
+ * file pattern-matches on `def`.
43
52
  */
44
53
 
45
54
  /**
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.
55
+ * Stable kind discriminant for a Zod v4 schema, returned by `kindOf`.
56
+ * Reach for it in a custom integration that branches on schema shape.
49
57
  */
50
58
  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
59
  /**
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).
60
+ * The `ZodKind` of a Zod v4 schema; `'unknown'` for a non-Zod input or an
61
+ * unrecognised shape. Useful in an introspection helper that branches on
62
+ * structure, a custom error formatter or a doc generator.
57
63
  */
58
64
  declare function kindOf(schema: unknown): ZodKind;
59
65
  /**
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.
66
+ * Verify a schema is Zod v4, throwing a clear error for a v3 schema
67
+ * imported through `attaform/zod` by mistake. The adapter calls it on
68
+ * every schema; reach for it directly only in a custom adapter that
69
+ * wants the same guard.
66
70
  */
67
71
  declare function assertZodVersion(schema: unknown): void;
68
72
 
69
73
  /**
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.
74
+ * Field-metadata write and read API for the Zod v4 adapter.
76
75
  *
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.
76
+ * Storage lives in the shared `core/field-meta-store`, where every entry
77
+ * (`attaform/zod`, `attaform/zod-v3`, `attaform/zod-v4`) reads and
78
+ * writes the same `WeakMap`s, so a payload registered through any of
79
+ * them surfaces at lookup whichever adapter runs. The native chain
80
+ * `schema.register(fieldMeta, payload)` works too: Zod 4's `.register`
81
+ * calls `registry.add(this, payload)` and returns the schema, which the
82
+ * shared store satisfies structurally.
80
83
  *
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:
84
+ * **Registration order does not matter.** Register on the schema
85
+ * reference assigned into the parent's shape, or on the inner schema
86
+ * before wrapping:
86
87
  *
87
- * // both equivalent — registry hits at lookup time
88
+ * // equivalent; all four hit at lookup time
88
89
  * withMeta(z.string(), { label: 'Email' }).optional()
89
90
  * withMeta(z.string().optional(), { label: 'Email' })
90
91
  * z.string().optional().register(fieldMeta, { label: 'Email' })
91
92
  * z.string().register(fieldMeta, { label: 'Email' }).optional()
92
93
  *
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.
94
+ * The path walker returns the wrapper at a terminal position, so
95
+ * `['email']` against `{ email: z.string().optional() }` resolves to
96
+ * `ZodOptional<ZodString>`, and peels at intermediate descent, so
97
+ * `['address', 'street']` goes through `address`'s wrapper to the inner
98
+ * object. The resolver tries the walker's schema before the peeled
99
+ * inner, so the two-stage lookup covers leaf and container
100
+ * registrations symmetrically.
99
101
  */
100
102
 
101
103
  type ZodFieldMetaRegistry = ReturnType<typeof z.registry<FieldMetaPayload>>;
102
104
  /**
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:
105
+ * The shared registry an Attaform-aware Zod 4 schema registers field
106
+ * metadata against.
107
+ *
108
+ * ```ts
109
+ * import { fieldMeta } from 'attaform/zod'
110
+ *
111
+ * const schema = z.object({
112
+ * email: z.string().register(fieldMeta, { label: 'Email address' }),
113
+ * })
114
+ * ```
115
+ *
116
+ * One module-scoped instance, shared with the v3 adapter and the
117
+ * unified `attaform/zod` entry, so a `.register()` chain written in one
118
+ * place is read by an adapter in another. Extending `FieldMetaPayload`
119
+ * by declaration merging gives the richer payload type at every
120
+ * `register` / `add` / `get` call site.
121
+ *
122
+ * **One schema instance can carry different metadata per path.** Reuse
123
+ * an address schema at both `pickup` and `delivery` and each keeps its
124
+ * own label, through the native chain included:
123
125
  *
124
126
  * z.object({
125
127
  * pickup: addressSchema.register(fieldMeta, { label: 'Pickup address' }),
126
128
  * delivery: addressSchema.register(fieldMeta, { label: 'Delivery address' }),
127
129
  * })
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.
130
+ * // form.fields('pickup').label -> 'Pickup address'
131
+ * // form.fields('delivery').label -> 'Delivery address'
132
+ *
133
+ * The store keeps a parallel list of every registration, and the
134
+ * path-resolver walks the form's schema tree counting per-schema
135
+ * occurrences to pick the right payload per path. Object literals
136
+ * evaluate left to right, so registration order matches tree-walk order
137
+ * and the pairing holds. `withMeta()` never reaches this case at all,
138
+ * since it clones per call.
139
+ *
140
+ * The cast to the registry type is what lets `schema.register(fieldMeta,
141
+ * payload)` type-check at the call site; Zod 4's `.register()` only
142
+ * calls `.add(this, payload)`, so it is sound at runtime. Every `add`
143
+ * also installs the path-walking resolver into the shared store's
144
+ * builder slot, which is what makes the walk's bytes ride this module's
145
+ * import rather than the adapter: a consumer who never registers
146
+ * metadata never ships the walk.
144
147
  */
145
148
  declare const fieldMeta: ZodFieldMetaRegistry;
146
149
  /**
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.
150
+ * Attach `payload` to `schema` in the shared `fieldMeta` registry and
151
+ * return a chainable CLONE of `schema` carrying it. It matches
152
+ * `attaform/zod-v3`'s `withMeta()`, so a schema module written with it
153
+ * reads the same under either adapter.
154
+ *
155
+ * For v4-only code prefer the native `schema.register(fieldMeta,
156
+ * payload)`, which registers on the instance you passed and returns
157
+ * that same instance. Reach for `withMeta` when the module has to
158
+ * compile under both adapters, or when one schema instance is reused at
159
+ * several paths and each needs its own payload: the clone per call is
160
+ * what gives each call site its own registry slot.
161
161
  */
162
162
  declare function withMeta<S extends z.ZodType>(schema: S, payload: FieldMetaPayload): S;
163
163
 
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.CO918TdU.mjs';
2
+ import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.DRsANMok.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';
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.BIWicztt.mjs';
5
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';
6
+ export { a as assignKey, v as vRegister } from './shared/attaform.D_f1WgYf.mjs';
7
7
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
8
8
 
9
9
  const fieldMeta = installingFieldMetaStore;
package/dist/zod.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- 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';
2
- 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, h as FieldMetaPayload, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, F as FormKey, 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';
3
- export { v as vRegister } from './shared/attaform.Clz0ArIi.mjs';
1
+ 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.BcQwgWaq.mjs';
2
+ 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, h as FieldMetaPayload, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, F as FormKey, 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.Br8EBn5B.mjs';
3
+ export { v as vRegister } from './shared/attaform.L0kUn3vL.mjs';
4
4
  export { UseFormConfig, UseFormConfigV3, UseFormConfigV4, UseFormReturn, UseFormReturnV3, UseFormReturnV4, fieldMeta, useForm, withMeta } from './index.mjs';
5
- export { P as PathInput, a as PathOutput } from './shared/attaform.Rc9u4Vfw.mjs';
5
+ export { P as PathInput, a as PathOutput } from './shared/attaform.2FslhB9R.mjs';
6
6
  import 'vue';
7
- import './shared/attaform.DRUT703x.mjs';
7
+ import './shared/attaform.B-Tb62qV.mjs';
8
8
  import 'zod';
package/dist/zod.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  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';
2
- 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';
2
+ 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.BIWicztt.mjs';
3
3
  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';
4
- export { a as assignKey, v as vRegister } from './shared/attaform.B3resMQ1.mjs';
5
- export { f as fieldMeta, u as useForm, w as withMeta } from './shared/attaform.ByWP6kSx.mjs';
4
+ export { a as assignKey, v as vRegister } from './shared/attaform.D_f1WgYf.mjs';
5
+ export { f as fieldMeta, u as useForm, w as withMeta } from './shared/attaform.B2iebkPA.mjs';
6
6
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "attaform",
3
- "version": "0.30.0",
3
+ "version": "0.30.1",
4
4
  "types": "./dist/index.d.mts",
5
5
  "files": [
6
6
  "dist",
@@ -129,7 +129,7 @@
129
129
  "@commitlint/cli": "^21.0.1",
130
130
  "@commitlint/config-conventional": "^21.0.1",
131
131
  "@eslint/js": "^10.0.1",
132
- "@fast-check/vitest": "^0.4.0",
132
+ "@fast-check/vitest": "^0.5.0",
133
133
  "@nuxt/devtools": "^3.4.2",
134
134
  "@nuxt/devtools-kit": "^3.2.0",
135
135
  "@nuxt/kit": "^4.4.2",
@@ -141,7 +141,7 @@
141
141
  "@types/jsdom": "^30.0.0",
142
142
  "@types/node": "^26.5.1",
143
143
  "@vitejs/plugin-vue": "^6.0.6",
144
- "@vitest/coverage-v8": "^4.1.11",
144
+ "@vitest/coverage-v8": "^5.0.1",
145
145
  "@vue/compiler-core": "^3.5.33",
146
146
  "@vue/compiler-sfc": "^3.5.33",
147
147
  "@vue/devtools-api": "^8.1.1",
@@ -171,7 +171,7 @@
171
171
  "typescript-eslint": "^8.59.0",
172
172
  "unbuild": "^3.6.1",
173
173
  "vite": "^8.3.0",
174
- "vitest": "^4.1.11",
174
+ "vitest": "^5.0.1",
175
175
  "vue": "^3.5.33",
176
176
  "vue-eslint-parser": "^10.4.0",
177
177
  "vue-tsc": "^3.2.7",
@@ -212,8 +212,8 @@
212
212
  "build:site": "pnpm --filter attaform-site build",
213
213
  "lint": "eslint --cache --concurrency=auto --max-warnings 0 . && pnpm format:check",
214
214
  "lint:fix": "eslint --cache --concurrency=auto --max-warnings 0 --fix . && pnpm format",
215
- "format": "prettier --write '**/*.{ts,js,vue,css,scss,md,json,yml,yaml}'",
216
- "format:check": "prettier --check '**/*.{ts,js,vue,css,scss,md,json,yml,yaml}'",
215
+ "format": "prettier --write '**/*.{ts,js,mjs,cjs,vue,css,scss,md,json,yml,yaml}'",
216
+ "format:check": "prettier --check '**/*.{ts,js,mjs,cjs,vue,css,scss,md,json,yml,yaml}'",
217
217
  "check": "pnpm check:security-floors && pnpm lint && pnpm typecheck && pnpm check:site && pnpm test && pnpm test:nuxt-ui && pnpm check:size && pnpm check:tarball && pnpm check:eager && pnpm check:bench && pnpm check:coverage",
218
218
  "fix": "pnpm lint:fix",
219
219
  "typecheck": "tsc --noEmit",
@@ -233,6 +233,7 @@
233
233
  "bench:delta": "node scripts/bench-delta.mjs",
234
234
  "check:bundled-types": "node scripts/check-bundled-types.mjs",
235
235
  "check:doc-snippets": "node scripts/check-doc-snippets.mjs",
236
+ "check:comment-only": "node scripts/check-comment-only.mjs",
236
237
  "check:site": "pnpm dev:prepare && pnpm --filter attaform-site typecheck",
237
238
  "fallow": "DO_NOT_TRACK=1 FALLOW_TELEMETRY=0 npx --yes fallow@2.88.3 --score",
238
239
  "version": "node scripts/promote-changelog.mjs && (node scripts/generate-release-notes.mjs || echo '[version] release-notes step failed; continuing') && node scripts/sync-doc-versions.mjs && node scripts/build-bestpractices-json.mjs && git add CHANGELOG.md RELEASES.md docs/scorecard/cii-best-practices-answers.md .bestpractices.json"
@@ -1,44 +0,0 @@
1
- import { App } from 'vue';
2
- import { ao as RegisterModelDynamicCustomDirective } from './attaform.bKLzMU0o.mjs';
3
-
4
- /**
5
- * The `v-register` directive. Bind a form field to a native input,
6
- * select, textarea, checkbox, or radio:
7
- *
8
- * ```vue
9
- * <input v-register="form.register('email')" />
10
- * <select v-register="form.register('country')">
11
- * <option value="us">US</option>
12
- * <option value="uk">UK</option>
13
- * </select>
14
- * ```
15
- *
16
- * The directive picks the right binding strategy automatically based
17
- * on the element's `tagName` and `type`. Delivered by the Vite / Nuxt
18
- * plugin's compile-time binding, or by `installVRegister(app)`
19
- * everywhere else. Most consumers never import it directly, but it's
20
- * exposed for advanced integrations that wire directives manually.
21
- */
22
- declare const vRegister: RegisterModelDynamicCustomDirective;
23
- /**
24
- * Register the `v-register` directive app-wide. The one-line setup for
25
- * apps whose templates are compiled without Attaform's Vite or Nuxt
26
- * plugin — a webpack-family bundler, a no-build / CDN page, or
27
- * runtime-compiled templates:
28
- *
29
- * ```ts
30
- * import { createApp } from 'vue'
31
- * import { installVRegister } from 'attaform/directive'
32
- *
33
- * const app = createApp(App)
34
- * installVRegister(app)
35
- * ```
36
- *
37
- * Vite and Nuxt consumers don't call this: the build plugin binds each
38
- * template's `v-register` to the directive at compile time. Idempotent —
39
- * a second call for the same app is a no-op, and an app-level directive
40
- * a consumer registered under the same name is left in place.
41
- */
42
- declare function installVRegister(app: App): void;
43
-
44
- export { installVRegister as i, vRegister as v };