attaform 0.17.2 → 0.18.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.
- package/README.md +77 -36
- package/dist/chunks/devtools.cjs +10 -37
- package/dist/chunks/devtools.cjs.map +1 -1
- package/dist/chunks/devtools.mjs +10 -37
- package/dist/chunks/devtools.mjs.map +1 -1
- package/dist/chunks/indexeddb.cjs +4 -4
- package/dist/chunks/indexeddb.cjs.map +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +2 -2
- package/dist/chunks/local-storage.cjs.map +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/session-storage.cjs +2 -2
- package/dist/chunks/session-storage.cjs.map +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/index.cjs +42 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +159 -196
- package/dist/index.d.mts +159 -196
- package/dist/index.d.ts +159 -196
- package/dist/index.mjs +5 -7
- package/dist/index.mjs.map +1 -1
- package/dist/nuxt.cjs +31 -40
- package/dist/nuxt.cjs.map +1 -1
- package/dist/nuxt.d.cts +8 -1
- package/dist/nuxt.d.mts +8 -1
- package/dist/nuxt.d.ts +8 -1
- package/dist/nuxt.mjs +32 -41
- package/dist/nuxt.mjs.map +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.d.vue.ts +7 -0
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +453 -0
- package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +7 -0
- package/dist/runtime/components/DevtoolsValueTree.d.vue.ts +37 -0
- package/dist/runtime/components/DevtoolsValueTree.vue +192 -0
- package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +37 -0
- package/dist/runtime/plugins/attaform.cjs +17 -6
- package/dist/runtime/plugins/attaform.cjs.map +1 -1
- package/dist/runtime/plugins/attaform.mjs +15 -4
- package/dist/runtime/plugins/attaform.mjs.map +1 -1
- package/dist/shared/{attaform.C0iFnTN0.d.ts → attaform.2b7M2mww.d.mts} +57 -23
- package/dist/shared/attaform.5UhpSVFI.cjs +63 -0
- package/dist/shared/attaform.5UhpSVFI.cjs.map +1 -0
- package/dist/shared/attaform.BDdFdjeX.mjs +57 -0
- package/dist/shared/attaform.BDdFdjeX.mjs.map +1 -0
- package/dist/shared/{attaform.Dee2rU1P.cjs → attaform.BqK_L4gK.cjs} +310 -24
- package/dist/shared/attaform.BqK_L4gK.cjs.map +1 -0
- package/dist/shared/attaform.Bubm_slq.cjs.map +1 -1
- package/dist/shared/attaform.CXpzmj38.mjs.map +1 -1
- package/dist/shared/{attaform.Drt6fivF.mjs → attaform.CtNUB9nf.mjs} +74 -76
- package/dist/shared/attaform.CtNUB9nf.mjs.map +1 -0
- package/dist/shared/{attaform.C5MH4lNh.d.mts → attaform.DF8wo-ry.d.ts} +4 -4
- package/dist/shared/attaform.DK9aj0N8.d.ts +1651 -0
- package/dist/shared/{attaform.BPRHR3Zs.cjs → attaform.DUHru0OF.cjs} +83 -85
- package/dist/shared/attaform.DUHru0OF.cjs.map +1 -0
- package/dist/shared/{attaform.C6lbmMUe.d.ts → attaform.DVLB6CAn.d.mts} +4 -4
- package/dist/shared/{attaform.C_5aB6EQ.d.ts → attaform.Dj9mwbaV.d.cts} +756 -148
- package/dist/shared/{attaform.C_5aB6EQ.d.mts → attaform.Dj9mwbaV.d.mts} +756 -148
- package/dist/shared/{attaform.C_5aB6EQ.d.cts → attaform.Dj9mwbaV.d.ts} +756 -148
- package/dist/shared/{attaform.BV40t5y2.cjs → attaform.Dlk1jMuv.cjs} +245 -108
- package/dist/shared/attaform.Dlk1jMuv.cjs.map +1 -0
- package/dist/shared/attaform.DoSuaKMd.d.cts +1651 -0
- package/dist/shared/{attaform.B3ZaPIzS.mjs → attaform.DsC3rZHG.mjs} +1804 -219
- package/dist/shared/attaform.DsC3rZHG.mjs.map +1 -0
- package/dist/shared/{attaform.Cer8JO_P.cjs → attaform.II89Pcf4.cjs} +1860 -272
- package/dist/shared/attaform.II89Pcf4.cjs.map +1 -0
- package/dist/shared/{attaform.CHorcsIU.d.cts → attaform.M33WKVV4.d.cts} +57 -23
- package/dist/shared/{attaform.CIEQgJnM.mjs → attaform.Xhg0AYNa.mjs} +300 -26
- package/dist/shared/attaform.Xhg0AYNa.mjs.map +1 -0
- package/dist/shared/{attaform.CpERWz3u.mjs → attaform.Xt0A3QUd.mjs} +232 -95
- package/dist/shared/attaform.Xt0A3QUd.mjs.map +1 -0
- package/dist/shared/attaform.iTqxvl-P.d.mts +1651 -0
- package/dist/shared/{attaform.CuE-bS1C.d.mts → attaform.tsNFcEW7.d.ts} +57 -23
- package/dist/shared/{attaform.DtMN-MAm.d.cts → attaform.tts_OM7j.d.cts} +4 -4
- package/dist/vite.cjs +288 -2
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +288 -2
- package/dist/vite.mjs.map +1 -1
- package/dist/zod-v3.cjs +11 -8
- package/dist/zod-v3.cjs.map +1 -1
- package/dist/zod-v3.d.cts +6 -6
- package/dist/zod-v3.d.mts +6 -6
- package/dist/zod-v3.d.ts +6 -6
- package/dist/zod-v3.mjs +3 -3
- package/dist/zod-v4.cjs +11 -8
- package/dist/zod-v4.cjs.map +1 -1
- package/dist/zod-v4.d.cts +5 -5
- package/dist/zod-v4.d.mts +5 -5
- package/dist/zod-v4.d.ts +5 -5
- package/dist/zod-v4.mjs +3 -3
- package/dist/zod.cjs +15 -16
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +127 -40
- package/dist/zod.d.mts +127 -40
- package/dist/zod.d.ts +127 -40
- package/dist/zod.mjs +7 -11
- package/dist/zod.mjs.map +1 -1
- package/package.json +18 -7
- package/dist/shared/attaform.B1jvxsOF.d.mts +0 -156
- package/dist/shared/attaform.B3ZaPIzS.mjs.map +0 -1
- package/dist/shared/attaform.BBM2muQ9.cjs +0 -101
- package/dist/shared/attaform.BBM2muQ9.cjs.map +0 -1
- package/dist/shared/attaform.BPRHR3Zs.cjs.map +0 -1
- package/dist/shared/attaform.BV40t5y2.cjs.map +0 -1
- package/dist/shared/attaform.C6qzEdIM.d.cts +0 -156
- package/dist/shared/attaform.C8LVFVVe.cjs +0 -32
- package/dist/shared/attaform.C8LVFVVe.cjs.map +0 -1
- package/dist/shared/attaform.CIEQgJnM.mjs.map +0 -1
- package/dist/shared/attaform.CTwNcpLE.d.ts +0 -156
- package/dist/shared/attaform.Cer8JO_P.cjs.map +0 -1
- package/dist/shared/attaform.CpERWz3u.mjs.map +0 -1
- package/dist/shared/attaform.Dee2rU1P.cjs.map +0 -1
- package/dist/shared/attaform.Drt6fivF.mjs.map +0 -1
- package/dist/shared/attaform.Vo-Kft0t.mjs +0 -29
- package/dist/shared/attaform.Vo-Kft0t.mjs.map +0 -1
- package/dist/shared/attaform.h1sq3BFu.mjs +0 -92
- package/dist/shared/attaform.h1sq3BFu.mjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,187 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
4
|
-
|
|
1
|
+
import { Plugin, App } from 'vue';
|
|
2
|
+
import { S as SSRDetectOptions, a as SerializedFormData, A as AttaformRegistry } from './shared/attaform.DoSuaKMd.cjs';
|
|
3
|
+
export { b as AggregateError, c as AnyForm, d as AttaformErrorCode, C as CompiledStep, F as FormStatus, I as InjectWizardInput, L as LazyMarker, e as StepSlot, U as UseRegisterReturn, f as UseWizardReturnType, W as WizardCtx, g as WizardCtxForm, h as WizardOnError, i as WizardOnSubmit, j as WizardOptions, k as WizardPersistFn, l as WizardRestoreFn, m as WizardRestoreState, n as WizardStatusesProxy, o as WizardSubmitContext, p as createRegistry, q as defaultCoercionRules, r as defineCoercion, s as getRegistryFromApp, t as injectForm, u as injectWizard, v as kAttaformRegistry, w as lazy, x as useRegister, y as useRegistry, z as useWizard } from './shared/attaform.DoSuaKMd.cjs';
|
|
4
|
+
import { A as AttaformDefaults, F as FormKey, G as GenericForm, U as UseFormConfiguration, a as AbstractSchema, D as DefaultValuesInput, b as UseFormReturnType, R as RegisterValue, c as RegisterModelDynamicCustomDirective, S as Segment, d as ShouldShowErrors, V as ValidationError, e as ApiErrorEnvelope, f as ApiErrorDetails } from './shared/attaform.Dj9mwbaV.cjs';
|
|
5
|
+
export { g as ApiErrorEntry, h as ArrayItem, i as ArrayPath, C as CoercionEntry, j as CoercionRegistry, k as CoercionResult, l as CustomDirectiveRegisterAssignerFn, m as DeepPartial, n as DefaultValuesResponse, o as DefaultValuesShape, E as ErrorsProxyShape, p as FieldMetaPayload, q as FieldState, r as FieldStateMap, s as FieldStateMapEntry, t as FlatPath, u as FormErrorRecord, v as FormErrorsSurface, w as FormMeta, x as FormStorage, y as FormStorageKind, H as HandleSubmit, z as HistoryConfig, I as IsTuple, B as IsUnion, J as JoinSegments, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, O as NestedType, P as OnError, Q as OnInvalidSubmitPolicy, T as OnSubmit, W as PartialFlatPath, X as Path, Y as PathKey, Z as PendingValidationStatus, _ as PersistConfig, $ as PersistConfigOptions, a0 as PersistIncludeMode, a1 as Primitive, a2 as ROOT_PATH, a3 as ROOT_PATH_KEY, a4 as ReactiveValidationStatus, a5 as RegisterDirective, a6 as RegisterFlatPath, a7 as RegisterOptions, a8 as RegisterSelectModifier, a9 as RegisterTextModifier, aa as RegisterTransform, ab as SetValueCallback, ac as SetValuePayload, ad as SettledValidationStatus, ae as ShouldShowErrorsConfig, af as SlimPrimitiveKind, ag as SlimRuntimeOf, ah as SubmitHandler, ai as Unset, aj as ValidateOn, ak as ValidateOnConfig, al as ValidationResponse, am as ValidationResponseWithoutValue, an as ValueOfUnion, ao as WriteMeta, ap as WriteShape, aq as canonicalizePath, ar as isPathPrefix, as as isUnset, at as parseDottedPath, au as unset } from './shared/attaform.Dj9mwbaV.cjs';
|
|
5
6
|
export { A as AnonPersistError, a as AttaformError, I as InvalidPathError, b as InvalidUseFormConfigError, O as OutsideSetupError, R as RegistryNotInstalledError, c as ReservedFormKeyError, S as SensitivePersistFieldError, d as SubmitErrorHandlerError } from './shared/attaform.B7rzpK1U.cjs';
|
|
6
7
|
|
|
7
|
-
/**
|
|
8
|
-
* Schema-driven coercion of user-typed DOM values at the v-register
|
|
9
|
-
* directive layer. When the slim schema declares a numeric or
|
|
10
|
-
* boolean type at a path, the directive coerces incoming string
|
|
11
|
-
* values (`'25'` → `25`, `'true'` → `true`) before the slim-primitive
|
|
12
|
-
* gate sees the write — making the schema authoritative for storage
|
|
13
|
-
* shape and freeing consumers from sprinkling `.number` modifiers
|
|
14
|
-
* across templates.
|
|
15
|
-
*
|
|
16
|
-
* Coercion is consumer-extensible: a `CoercionRegistry` is just an
|
|
17
|
-
* `Array<CoercionEntry>` keyed at config time by `(input, output)`
|
|
18
|
-
* `SlimPrimitiveKind` literals. The library ships
|
|
19
|
-
* `defaultCoercionRules` (string→number, string→boolean) and
|
|
20
|
-
* `defineCoercion` for type-narrowed authoring; consumers spread the
|
|
21
|
-
* defaults to extend or supply their own array to replace.
|
|
22
|
-
*
|
|
23
|
-
* Coercion applies ONLY to user-typed DOM values flowing through
|
|
24
|
-
* the directive's assigner. Programmatic writes (`form.setValue`,
|
|
25
|
-
* `setValueWithInternalPath`) bypass coercion — they're authoritative
|
|
26
|
-
* writes whose strict typing is on the caller. This mirrors the
|
|
27
|
-
* `transforms` pipeline's user-input-only contract.
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Type-narrowing helper for authoring entries. At runtime it's
|
|
32
|
-
* identity; at compile time it preserves the `input` / `output`
|
|
33
|
-
* literal types so `transform`'s parameter is narrowed to the
|
|
34
|
-
* runtime type instead of widening to `SlimRuntimeOf<SlimPrimitiveKind>`.
|
|
35
|
-
*
|
|
36
|
-
* Without this helper, authoring `{ input: 'string', output:
|
|
37
|
-
* 'number', transform: (s) => ... }` against the broader
|
|
38
|
-
* `CoercionEntry` widens `s` to `string | number | boolean | ...`,
|
|
39
|
-
* forcing a cast in every transform body. `defineCoercion` is the
|
|
40
|
-
* opaque-free idiom.
|
|
41
|
-
*/
|
|
42
|
-
declare function defineCoercion<I extends SlimPrimitiveKind, O extends SlimPrimitiveKind>(entry: CoercionEntry<I, O>): CoercionEntry<I, O>;
|
|
43
|
-
/**
|
|
44
|
-
* The library's built-in registry. Two cells: string→number and
|
|
45
|
-
* string→boolean. Re-exported so consumers can spread it when
|
|
46
|
-
* supplying a custom registry that extends defaults.
|
|
47
|
-
*/
|
|
48
|
-
declare const defaultCoercionRules: CoercionRegistry;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Portable SSR detection. The plugin captures this value at install time and
|
|
52
|
-
* exposes it via the registry so every runtime branch reads a single source
|
|
53
|
-
* of truth instead of sniffing `import.meta.*` (bundler-specific) at each
|
|
54
|
-
* call site.
|
|
55
|
-
*
|
|
56
|
-
* Consumers can override the heuristic explicitly via
|
|
57
|
-
* `createAttaform({ ssr: true })`; the default handles the common
|
|
58
|
-
* Node-vs-browser split without relying on any bundler-injected flag.
|
|
59
|
-
*/
|
|
60
|
-
interface SSRDetectOptions {
|
|
61
|
-
/**
|
|
62
|
-
* Force SSR-vs-client mode, bypassing the `typeof window` heuristic.
|
|
63
|
-
* `true` activates the SSR code paths (no devtools, no persistence
|
|
64
|
-
* wiring, payload serialisation enabled); `false` forces client mode.
|
|
65
|
-
* The Nuxt plugin sets this from `import.meta.server` so SSR detection
|
|
66
|
-
* never depends on whether `window` is polyfilled. Tests that need to
|
|
67
|
-
* exercise the SSR code paths under jsdom pass `ssr: true`.
|
|
68
|
-
*/
|
|
69
|
-
ssr?: boolean;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Per-Vue-app container for all form state instances. Each
|
|
74
|
-
* `app.use(createAttaform())` call gets its own registry,
|
|
75
|
-
* so the library runs under bare Vue 3 + SSR (via
|
|
76
|
-
* `@vue/server-renderer`) and Nuxt with the same code path.
|
|
77
|
-
*
|
|
78
|
-
* Each form's state lives in `forms: Map<FormKey, FormStore<GenericForm>>`.
|
|
79
|
-
* The type relaxation at storage time is necessary because different
|
|
80
|
-
* forms in the same app have different `Form` generics; callers recover
|
|
81
|
-
* the specific form type via `useForm`'s overloads.
|
|
82
|
-
*/
|
|
83
|
-
/**
|
|
84
|
-
* Serialised snapshot of one form's state, captured by
|
|
85
|
-
* `renderAttaformState` for SSR and replayed by
|
|
86
|
-
* `hydrateAttaformState` on the client. Round-trips through
|
|
87
|
-
* JSON-safe tuples; field references are intentionally omitted
|
|
88
|
-
* (DOM nodes don't survive serialisation).
|
|
89
|
-
*/
|
|
90
|
-
type SerializedFormData = {
|
|
91
|
-
/** The form's value at snapshot time. */
|
|
92
|
-
readonly form: unknown;
|
|
93
|
-
/**
|
|
94
|
-
* Errors produced by the schema at snapshot time. Replayed into
|
|
95
|
-
* the client form's error state at hydration; cleared on
|
|
96
|
-
* successful re-validation client-side.
|
|
97
|
-
*/
|
|
98
|
-
readonly schemaErrors: ReadonlyArray<readonly [string, unknown]>;
|
|
99
|
-
/**
|
|
100
|
-
* Errors set explicitly via `setFieldErrors` / `addFieldErrors`
|
|
101
|
-
* (typically from a server response parsed via `parseApiErrors`)
|
|
102
|
-
* at snapshot time. Replayed at hydration; persists across
|
|
103
|
-
* client-side re-validation.
|
|
104
|
-
*/
|
|
105
|
-
readonly userErrors: ReadonlyArray<readonly [string, unknown]>;
|
|
106
|
-
/** Per-field metadata (timestamps, raw values, connection flags) captured at snapshot time. */
|
|
107
|
-
readonly fields: ReadonlyArray<readonly [string, unknown]>;
|
|
108
|
-
/**
|
|
109
|
-
* Path keys that were in the form's `blankPaths` set at
|
|
110
|
-
* snapshot time. Round-trips the "displayed empty" UI state across
|
|
111
|
-
* the SSR boundary — without it, the client briefly renders
|
|
112
|
-
* `String(slim-default)` (e.g. `'0'`) for fields the server
|
|
113
|
-
* rendered as blank. Optional in the wire format so older payload
|
|
114
|
-
* shapes deserialise cleanly.
|
|
115
|
-
*/
|
|
116
|
-
readonly blankPaths?: ReadonlyArray<string>;
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* The library's per-Vue-app container. One `AttaformRegistry` is
|
|
120
|
-
* created per `app.use(createAttaform())` call.
|
|
121
|
-
*
|
|
122
|
-
* Most consumers never touch this directly — `useForm` and
|
|
123
|
-
* `injectForm` reach the registry on your behalf. Access it
|
|
124
|
-
* explicitly only when wiring SSR or a custom plugin integration.
|
|
125
|
-
*/
|
|
126
|
-
type AttaformRegistry = {
|
|
127
|
-
/** `true` while running on the server during SSR; `false` on the client. */
|
|
128
|
-
readonly ssr: boolean;
|
|
129
|
-
/** App-level defaults applied to every `useForm` call. */
|
|
130
|
-
readonly defaults: AttaformDefaults;
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* The Vue `InjectionKey` under which the registry is provided on the
|
|
134
|
-
* app. Most consumers never need this — `useForm` and
|
|
135
|
-
* `injectForm` resolve the registry automatically.
|
|
136
|
-
*/
|
|
137
|
-
declare const kAttaformRegistry: InjectionKey<AttaformRegistry>;
|
|
138
|
-
declare module 'vue' {
|
|
139
|
-
interface App {
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
/** Options for `createRegistry`. */
|
|
143
|
-
type CreateRegistryOptions = SSRDetectOptions & {
|
|
144
|
-
/**
|
|
145
|
-
* App-level defaults applied to every `useForm` call. Per-form
|
|
146
|
-
* options always win. Omitted is equivalent to `{}`.
|
|
147
|
-
*/
|
|
148
|
-
defaults?: AttaformDefaults;
|
|
149
|
-
};
|
|
150
|
-
/**
|
|
151
|
-
* Create a fresh `AttaformRegistry`. `createAttaform()` calls
|
|
152
|
-
* this internally — most consumers never need to call it directly.
|
|
153
|
-
* Use it when building a custom plugin that doesn't want the
|
|
154
|
-
* `createAttaform` plugin's auto-install behaviour (e.g. test
|
|
155
|
-
* harnesses, embedded apps).
|
|
156
|
-
*/
|
|
157
|
-
declare function createRegistry(options?: CreateRegistryOptions): AttaformRegistry;
|
|
158
|
-
/**
|
|
159
|
-
* Look up the current app's registry from inside a component's
|
|
160
|
-
* `setup()` (or any synchronous code on the setup call stack).
|
|
161
|
-
*
|
|
162
|
-
* Most consumers don't need this — `useForm` and `injectForm`
|
|
163
|
-
* call it on your behalf. Reach for it directly when building
|
|
164
|
-
* custom integrations that need the raw registry.
|
|
165
|
-
*
|
|
166
|
-
* Throws:
|
|
167
|
-
* - `OutsideSetupError` when called outside a Vue setup context
|
|
168
|
-
* (e.g. from an event handler or async callback). Move the call
|
|
169
|
-
* into setup, or trigger it from a child component.
|
|
170
|
-
* - `RegistryNotInstalledError` when called inside setup but the
|
|
171
|
-
* plugin wasn't installed. Add
|
|
172
|
-
* `app.use(createAttaform())` to your app entry.
|
|
173
|
-
*/
|
|
174
|
-
declare function useRegistry(): AttaformRegistry;
|
|
175
|
-
/**
|
|
176
|
-
* Look up a Vue app's registry by `App` reference. Used by
|
|
177
|
-
* SSR helpers (`renderAttaformState`, `hydrateAttaformState`) that
|
|
178
|
-
* run outside a component setup context.
|
|
179
|
-
*
|
|
180
|
-
* Throws `RegistryNotInstalledError` when the app hasn't been wired
|
|
181
|
-
* with `createAttaform()`.
|
|
182
|
-
*/
|
|
183
|
-
declare function getRegistryFromApp(app: App): AttaformRegistry;
|
|
184
|
-
|
|
185
8
|
/**
|
|
186
9
|
* Options for `createAttaform()`.
|
|
187
10
|
*/
|
|
@@ -326,7 +149,19 @@ declare function escapeForInlineScript(json: string): string;
|
|
|
326
149
|
* Returns the same form API as the typed entry points; see
|
|
327
150
|
* `UseFormReturnType` for the full surface.
|
|
328
151
|
*/
|
|
329
|
-
declare function useAbstractForm<Form extends GenericForm, GetValueFormType extends GenericForm = Form, ReadForm extends GenericForm = Form>(configuration: UseFormConfiguration<Form, GetValueFormType, AbstractSchema<Form, GetValueFormType>,
|
|
152
|
+
declare function useAbstractForm<Form extends GenericForm, GetValueFormType extends GenericForm = Form, ReadForm extends GenericForm = Form, K extends FormKey = FormKey>(configuration: UseFormConfiguration<Form, GetValueFormType, AbstractSchema<Form, GetValueFormType>, DefaultValuesInput<Form>, K>,
|
|
153
|
+
/**
|
|
154
|
+
* Internal escape hatch for callers that already hold a registry
|
|
155
|
+
* reference and need to construct a form outside Vue's setup context
|
|
156
|
+
* (e.g. the wizard's lazy noop builder, which runs inside a
|
|
157
|
+
* `computed` re-eval). Passing this skips the strict `useRegistry()`
|
|
158
|
+
* call; everything else (FormStore allocation, registry presence,
|
|
159
|
+
* consumer ref-counting via `onScopeDispose`) goes through the same
|
|
160
|
+
* path eager calls follow. Not part of the public surface.
|
|
161
|
+
*/
|
|
162
|
+
options?: {
|
|
163
|
+
readonly registry?: AttaformRegistry;
|
|
164
|
+
}): UseFormReturnType<Form, GetValueFormType, ReadForm, K>;
|
|
330
165
|
|
|
331
166
|
/**
|
|
332
167
|
* Symbol slot used by custom directive integrations to install an
|
|
@@ -370,28 +205,156 @@ declare function isRegisterValue<Value = unknown>(val: unknown): val is Register
|
|
|
370
205
|
*
|
|
371
206
|
* The directive picks the right binding strategy automatically based
|
|
372
207
|
* on the element's `tagName` and `type`. Registered globally by
|
|
373
|
-
* `createAttaform()
|
|
374
|
-
*
|
|
375
|
-
*
|
|
208
|
+
* `createAttaform()`. Most consumers never import it directly, but
|
|
209
|
+
* it's exposed for advanced integrations that wire directives
|
|
210
|
+
* manually.
|
|
376
211
|
*/
|
|
377
212
|
declare const vRegister: RegisterModelDynamicCustomDirective;
|
|
378
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Shared building blocks for Attaform's two devtools surfaces — the Vue
|
|
216
|
+
* DevTools (Chrome-extension) inspector wired up in `./devtools.ts`, and
|
|
217
|
+
* the Nuxt DevTools (overlay) panel wired up via `../../nuxt.ts` +
|
|
218
|
+
* `../pages/_attaform_devtools.vue`.
|
|
219
|
+
*
|
|
220
|
+
* Centralizing the redaction policy and the window-bridge contract here
|
|
221
|
+
* keeps both surfaces aligned: a future tightening of the sensitive-name
|
|
222
|
+
* heuristic, or a new field added to the bridge, lands in one file.
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
declare const REDACTED = "[redacted]";
|
|
226
|
+
/**
|
|
227
|
+
* Walk `value` and replace any leaf whose enclosing path matches the
|
|
228
|
+
* sensitive-name heuristic with the string `'[redacted]'`. Returns a
|
|
229
|
+
* new tree (no mutation of the input). Object keys + array indices are
|
|
230
|
+
* preserved; only the leaf payloads change.
|
|
231
|
+
*
|
|
232
|
+
* Applied to BOTH devtools surfaces' Form-value rendering AND every
|
|
233
|
+
* timeline event payload — leaks via either surface are treatable as
|
|
234
|
+
* "any developer with the panel open during user testing can read a
|
|
235
|
+
* customer's password," which is exactly the failure mode the
|
|
236
|
+
* sensitive-name guard exists to prevent on the storage side.
|
|
237
|
+
*
|
|
238
|
+
* Leaves whose path doesn't match a pattern pass through untouched.
|
|
239
|
+
* `acknowledgeSensitive: true` on persistence does NOT bypass this — if
|
|
240
|
+
* the consumer opted into persisting the value, they still shouldn't
|
|
241
|
+
* see it in DevTools timelines that grow unbounded.
|
|
242
|
+
*
|
|
243
|
+
* Implementation note: tracks an `inSensitiveSubtree` flag through the
|
|
244
|
+
* recursion instead of allocating a fresh path array per node + calling
|
|
245
|
+
* `isSensitivePath` per leaf. Once any ancestor segment matches the
|
|
246
|
+
* heuristic, the flag stays set for every descendant — the leaf simply
|
|
247
|
+
* returns `REDACTED` without re-scanning the path. For a 100-leaf form:
|
|
248
|
+
* ~100 path allocations + ~100 full-path regex sweeps → 0 path
|
|
249
|
+
* allocations + ~100 single-segment regex sweeps, with whole-subtree
|
|
250
|
+
* short-circuit when sensitive ancestors are found early.
|
|
251
|
+
*/
|
|
252
|
+
declare function redactSensitiveLeaves(value: unknown, matchSensitive: (segment: Segment) => boolean): unknown;
|
|
253
|
+
/**
|
|
254
|
+
* Property key on `window` that the Nuxt-side dev plugin attaches the
|
|
255
|
+
* bridge object to. The iframe-mounted overlay panel reads
|
|
256
|
+
* `window.parent[DEVTOOLS_WINDOW_KEY]` to reach the host app's registry.
|
|
257
|
+
*
|
|
258
|
+
* Underscored + namespaced to make accidental collision with consumer
|
|
259
|
+
* globals vanishingly unlikely. Stable across versions — bumping it
|
|
260
|
+
* would silently disconnect older library builds from newer overlay
|
|
261
|
+
* panels in the same browser tab during a library upgrade.
|
|
262
|
+
*/
|
|
263
|
+
declare const DEVTOOLS_WINDOW_KEY = "__attaform_devtools__";
|
|
264
|
+
/**
|
|
265
|
+
* Shape of the object the host plugin attaches to `window` in dev mode.
|
|
266
|
+
* The iframe overlay panel reads this to discover the live registry and
|
|
267
|
+
* render its forms.
|
|
268
|
+
*
|
|
269
|
+
* Single-registry assumption: the latest `createAttaform()` install
|
|
270
|
+
* wins. Multi-app pages (rare; typically only seen in micro-frontend
|
|
271
|
+
* setups) will only see one app's forms in the panel. Documented but
|
|
272
|
+
* not actively supported — the alternative (a Set of registries with
|
|
273
|
+
* union-rendering) is a future call if a real consumer hits it.
|
|
274
|
+
*/
|
|
275
|
+
interface AttaformDevtoolsBridge {
|
|
276
|
+
registry: AttaformRegistry;
|
|
277
|
+
/**
|
|
278
|
+
* The library version, surfaced in the panel's footer for support /
|
|
279
|
+
* bug-report context. Read from `package.json` at host-plugin init.
|
|
280
|
+
*/
|
|
281
|
+
version: string;
|
|
282
|
+
}
|
|
283
|
+
declare global {
|
|
284
|
+
interface Window {
|
|
285
|
+
[DEVTOOLS_WINDOW_KEY]?: AttaformDevtoolsBridge;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
379
289
|
/**
|
|
380
290
|
* Library-default heuristic for `shouldShowErrors`. Drives
|
|
381
291
|
* `field.showErrors` and `form.meta.showErrors` whenever the consumer
|
|
382
292
|
* has not configured an override at either the plugin or per-form
|
|
383
293
|
* level.
|
|
384
294
|
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
295
|
+
* Four clauses: the first two are hard gates; clause 3 is an
|
|
296
|
+
* aggressive override after the first submit attempt; clause 4 is
|
|
297
|
+
* the pre-submit timing gate.
|
|
298
|
+
*
|
|
299
|
+
* 1. **Own-path filter.** The field must have at least one error whose
|
|
300
|
+
* path equals the field's own path. Leaves always satisfy this when
|
|
301
|
+
* they have errors. Containers (intermediate or root) only satisfy
|
|
302
|
+
* it for errors that point directly at them, so a UI rendering
|
|
303
|
+
* `field.showErrors` at a container never duplicates errors that a
|
|
304
|
+
* more-specific descendant will already render. Aggregate banners
|
|
305
|
+
* that want "any error anywhere passed the gate" should bind to
|
|
306
|
+
* `form.meta.errorCount > 0` (paired with whatever timing signal
|
|
307
|
+
* fits), not to `form.meta.showErrors`.
|
|
308
|
+
*
|
|
309
|
+
* 2. **Not currently validating.** While the field is mid-revalidation
|
|
310
|
+
* (`field.validating === true`) the verdict in `field.errors` is
|
|
311
|
+
* stale by definition. The error itself stays in the store under
|
|
312
|
+
* the stale-while-revalidate contract so the surface doesn't
|
|
313
|
+
* flicker to empty, but the UX gate hides it: the application is
|
|
314
|
+
* actively re-checking, so the message would mis-narrate the
|
|
315
|
+
* state of the world. Containers roll up `validating` as a
|
|
316
|
+
* disjunction, so any descendant under revalidation hides the
|
|
317
|
+
* container's `showErrors` too. The error returns the moment the
|
|
318
|
+
* new verdict lands and `validating` flips back to false.
|
|
319
|
+
*
|
|
320
|
+
* 3. **Post-submit override.** Once `formMeta.submissionAttempts > 0`
|
|
321
|
+
* the heuristic surfaces every own-path error unconditionally on
|
|
322
|
+
* the field axis (subject only to the two gates above). The
|
|
323
|
+
* counter covers two distinct gestures:
|
|
324
|
+
*
|
|
325
|
+
* - `form.handleSubmit` directly, or `wizard.handleSubmit` at an
|
|
326
|
+
* intermediate step. The user asked this specific form to
|
|
327
|
+
* commit; transient mid-edit hiding is no longer appropriate.
|
|
328
|
+
*
|
|
329
|
+
* - `wizard.handleSubmit` at the final step. The wizard validates
|
|
330
|
+
* every form in parallel and bumps each one's `submissionAttempts`,
|
|
331
|
+
* so a `Finish`-button submission reveals errors across the
|
|
332
|
+
* whole multistep flow at once. That's the review-surface UX:
|
|
333
|
+
* by the time the user tries to commit the wizard, every
|
|
334
|
+
* blocking error lights up regardless of which step it lives on.
|
|
335
|
+
*
|
|
336
|
+
* The arm deliberately covers focused, pristine, and untouched
|
|
337
|
+
* fields, so the next paint after the user tried to progress lights
|
|
338
|
+
* up every problem the validator found.
|
|
339
|
+
*
|
|
340
|
+
* 4. **Pre-submit timing gate.** Before the first submit attempt,
|
|
341
|
+
* show once the user has touched the field (sticky-true after the
|
|
342
|
+
* first blur) AND is not currently focused on it. The not-focused
|
|
343
|
+
* half hides transient errors while the user is actively editing
|
|
344
|
+
* the field; they reappear when the user blurs (or focuses a
|
|
345
|
+
* sibling). This deliberately includes blur-without-typing on a
|
|
346
|
+
* required field (touched flips on blur regardless of `dirty`), so
|
|
347
|
+
* a user who visits an empty required field and moves on sees the
|
|
348
|
+
* error.
|
|
349
|
+
*
|
|
350
|
+
* The framework already gates on `errors.length > 0` before invoking
|
|
351
|
+
* the predicate, so the body only decides *when* to surface existing
|
|
352
|
+
* errors, not whether errors exist.
|
|
390
353
|
*
|
|
391
354
|
* Public re-export so adopters can compose with this without
|
|
392
|
-
* copy-pasting the rule body. A layered predicate that adds a
|
|
393
|
-
*
|
|
394
|
-
*
|
|
355
|
+
* copy-pasting the rule body. A layered predicate that adds a special
|
|
356
|
+
* case but otherwise defers to the library default picks up future
|
|
357
|
+
* heuristic refinements automatically:
|
|
395
358
|
*
|
|
396
359
|
* ```ts
|
|
397
360
|
* import { defaultShouldShowErrors } from 'attaform'
|
|
@@ -566,5 +529,5 @@ declare const PARSE_API_ERRORS_DEFAULTS: {
|
|
|
566
529
|
*/
|
|
567
530
|
declare function parseApiErrors(payload: ApiErrorEnvelope | ApiErrorDetails | null | undefined | unknown, options: ParseApiErrorsOptions): ParseApiErrorsResult;
|
|
568
531
|
|
|
569
|
-
export { AbstractSchema, ApiErrorDetails, ApiErrorEnvelope, AttaformDefaults,
|
|
570
|
-
export type {
|
|
532
|
+
export { AbstractSchema, ApiErrorDetails, ApiErrorEnvelope, AttaformDefaults, AttaformRegistry, DEFAULT_SENSITIVE_NAMES, DEVTOOLS_WINDOW_KEY, DefaultValuesInput, FormKey, GenericForm, PARSE_API_ERRORS_DEFAULTS, REDACTED, RegisterValue, Segment, SerializedFormData, ShouldShowErrors, UseFormConfiguration, UseFormReturnType, ValidationError, assignKey, createAttaform, defaultShouldShowErrors, escapeForInlineScript, hydrateAttaformState, isRegisterValue, parseApiErrors, redactSensitiveLeaves, renderAttaformState, useAbstractForm as useForm, vRegister };
|
|
533
|
+
export type { AttaformDevtoolsBridge, AttaformPluginOptions, ParseApiErrorsOptions, ParseApiErrorsResult, SerializedAttaformState };
|