attaform 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/fingerprint2.cjs +1 -1
- package/dist/chunks/fingerprint2.mjs +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +3 -3
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/runtime/plugins/attaform.cjs +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.CO0e7YVY.d.cts → attaform.55hFR_cl.d.ts} +3 -0
- package/dist/shared/{attaform.BJt4ZCkM.d.mts → attaform.B71rfNL5.d.mts} +1 -1
- package/dist/shared/{attaform.DmKLa4tL.d.cts → attaform.BFfY7HRI.d.cts} +1 -1
- package/dist/shared/{attaform.3heDHayA.cjs → attaform.BPl-ECRT.cjs} +25 -1
- package/dist/shared/attaform.BPl-ECRT.cjs.map +1 -0
- package/dist/shared/{attaform.B5YcWrKi.cjs → attaform.BQflyVOL.cjs} +3 -3
- package/dist/shared/{attaform.B5YcWrKi.cjs.map → attaform.BQflyVOL.cjs.map} +1 -1
- package/dist/shared/{attaform.B3cgZE3c.d.ts → attaform.Be5otUVw.d.ts} +1 -1
- package/dist/shared/{attaform.DK3xUBkj.mjs → attaform.BoYqnIPI.mjs} +109 -45
- package/dist/shared/attaform.BoYqnIPI.mjs.map +1 -0
- package/dist/shared/{attaform.B5GFS3Su.d.cts → attaform.CEY_WLRJ.d.mts} +12 -1
- package/dist/shared/{attaform.DMNnfQq_.mjs → attaform.CSXDW2tO.mjs} +4 -4
- package/dist/shared/{attaform.DMNnfQq_.mjs.map → attaform.CSXDW2tO.mjs.map} +1 -1
- package/dist/shared/{attaform.CwXXbZIQ.mjs → attaform.CXVmZtFq.mjs} +3 -3
- package/dist/shared/{attaform.CwXXbZIQ.mjs.map → attaform.CXVmZtFq.mjs.map} +1 -1
- package/dist/shared/{attaform.sks1MFVO.cjs → attaform.Cs0UZ7q6.cjs} +4 -4
- package/dist/shared/{attaform.sks1MFVO.cjs.map → attaform.Cs0UZ7q6.cjs.map} +1 -1
- package/dist/shared/{attaform.xBDo0Ko0.cjs → attaform.D51IwDtP.cjs} +2 -2
- package/dist/shared/{attaform.xBDo0Ko0.cjs.map → attaform.D51IwDtP.cjs.map} +1 -1
- package/dist/shared/{attaform.i_LA3X9o.d.cts → attaform.DBNjHgNj.d.cts} +70 -15
- package/dist/shared/{attaform.i_LA3X9o.d.mts → attaform.DBNjHgNj.d.mts} +70 -15
- package/dist/shared/{attaform.i_LA3X9o.d.ts → attaform.DBNjHgNj.d.ts} +70 -15
- package/dist/shared/{attaform.CqwcTExO.mjs → attaform.DGhIix5D.mjs} +24 -2
- package/dist/shared/attaform.DGhIix5D.mjs.map +1 -0
- package/dist/shared/{attaform.CO0e7YVY.d.mts → attaform.DJRz_bzM.d.cts} +3 -0
- package/dist/shared/{attaform.CN4ZEGo6.mjs → attaform.DSOIz08n.mjs} +4 -4
- package/dist/shared/{attaform.CN4ZEGo6.mjs.map → attaform.DSOIz08n.mjs.map} +1 -1
- package/dist/shared/{attaform.BkUzunyB.cjs → attaform.Du9RZp8m.cjs} +109 -45
- package/dist/shared/attaform.Du9RZp8m.cjs.map +1 -0
- package/dist/shared/{attaform.CO0e7YVY.d.ts → attaform.JPsaqjLl.d.mts} +3 -0
- package/dist/shared/{attaform.8vmdOURQ.d.mts → attaform.MgaYKlPP.d.cts} +12 -1
- package/dist/shared/{attaform.OLtKd9gM.mjs → attaform.NqYEzRcM.mjs} +2 -2
- package/dist/shared/{attaform.OLtKd9gM.mjs.map → attaform.NqYEzRcM.mjs.map} +1 -1
- package/dist/shared/{attaform.DS_zBcdr.d.ts → attaform.ceYeVkjn.d.ts} +12 -1
- package/dist/shared/{attaform.Xe8dATED.cjs → attaform.tZ0YKisf.cjs} +4 -4
- package/dist/shared/{attaform.Xe8dATED.cjs.map → attaform.tZ0YKisf.cjs.map} +1 -1
- package/dist/zod-v3.cjs +2 -2
- package/dist/zod-v3.d.cts +3 -3
- package/dist/zod-v3.d.mts +3 -3
- package/dist/zod-v3.d.ts +3 -3
- package/dist/zod-v3.mjs +2 -2
- package/dist/zod-v4.cjs +2 -2
- package/dist/zod-v4.d.cts +6 -6
- package/dist/zod-v4.d.mts +6 -6
- package/dist/zod-v4.d.ts +6 -6
- package/dist/zod-v4.mjs +2 -2
- package/dist/zod.cjs +5 -5
- package/dist/zod.d.cts +5 -5
- package/dist/zod.d.mts +5 -5
- package/dist/zod.d.ts +5 -5
- package/dist/zod.mjs +5 -5
- package/package.json +1 -1
- package/dist/shared/attaform.3heDHayA.cjs.map +0 -1
- package/dist/shared/attaform.BkUzunyB.cjs.map +0 -1
- package/dist/shared/attaform.CqwcTExO.mjs.map +0 -1
- package/dist/shared/attaform.DK3xUBkj.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const paths = require('./attaform.
|
|
3
|
+
const paths = require('./attaform.BPl-ECRT.cjs');
|
|
4
4
|
|
|
5
5
|
function renderAttaformState(app) {
|
|
6
6
|
const registry = paths.getRegistryFromApp(app);
|
|
@@ -36,4 +36,4 @@ const DEVTOOLS_WINDOW_KEY = "__attaform_devtools__";
|
|
|
36
36
|
exports.DEVTOOLS_WINDOW_KEY = DEVTOOLS_WINDOW_KEY;
|
|
37
37
|
exports.hydrateAttaformState = hydrateAttaformState;
|
|
38
38
|
exports.renderAttaformState = renderAttaformState;
|
|
39
|
-
//# sourceMappingURL=attaform.
|
|
39
|
+
//# sourceMappingURL=attaform.D51IwDtP.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attaform.
|
|
1
|
+
{"version":3,"file":"attaform.D51IwDtP.cjs","sources":["../../src/runtime/core/serialize.ts","../../src/runtime/core/devtools-shared.ts"],"sourcesContent":["import type { App } from 'vue'\nimport type { FormKey } from '../types/types-api'\nimport { pathKeyToDotted, type PathKey } from './paths'\nimport { getRegistryFromApp, type SerializedFormData } from './registry'\n\n/**\n * Serialised snapshot of every form in a Vue app, produced by\n * `renderAttaformState` and consumed by `hydrateAttaformState`.\n *\n * JSON-safe — pass to `JSON.stringify`, `devalue`, or any other\n * serialiser before embedding in your SSR payload.\n */\nexport type SerializedAttaformState = {\n /** Tuples of `[formKey, snapshot]` for every form in the app. */\n readonly forms: ReadonlyArray<readonly [FormKey, SerializedFormData]>\n}\n\n/**\n * Snapshot every form on a Vue app for SSR. Call from your server\n * entry after rendering the app:\n *\n * ```ts\n * import { renderToString } from '@vue/server-renderer'\n * import { renderAttaformState, escapeForInlineScript } from 'attaform'\n *\n * const html = await renderToString(app)\n * const state = renderAttaformState(app)\n * const payload = escapeForInlineScript(JSON.stringify(state))\n *\n * return `\n * ${html}\n * <script>window.__ATTAFORM_STATE__ = ${payload}</script>\n * `\n * ```\n *\n * Pair with `hydrateAttaformState` on the client to restore the\n * forms in their server-rendered state. Nuxt users don't need this —\n * `attaform/nuxt` wires SSR automatically.\n */\nexport function renderAttaformState(app: App): SerializedAttaformState {\n const registry = getRegistryFromApp(app)\n const forms: Array<readonly [FormKey, SerializedFormData]> = []\n for (const [key, state] of registry.forms) {\n // Skip the blank field when the set is empty so the\n // wire payload stays minimal for forms that don't use it. The\n // optional shape on the consuming side handles the absence\n // cleanly (defaults to \"no blank paths\"). PathKey → dotted at\n // the boundary so the wire shape matches the rest of the\n // public path notation.\n const transientList: string[] = []\n for (const pk of state.blankPaths) {\n const d = pathKeyToDotted(pk as PathKey)\n if (d !== null) transientList.push(d)\n }\n forms.push([\n key,\n {\n form: state.form.value,\n schemaErrors: Array.from(state.schemaErrors.entries()),\n userErrors: Array.from(state.userErrors.entries()),\n fields: Array.from(state.fields.entries()),\n ...(transientList.length > 0 ? { blankPaths: transientList } : {}),\n },\n ])\n }\n return { forms }\n}\n\n/**\n * Restore forms from a server-rendered snapshot on the client. Call\n * from your client entry before mounting:\n *\n * ```ts\n * import { createApp } from 'vue'\n * import { createAttaform, hydrateAttaformState } from 'attaform'\n *\n * const app = createApp(App).use(createAttaform())\n * hydrateAttaformState(app, window.__ATTAFORM_STATE__)\n * app.mount('#app')\n * ```\n *\n * The next `useForm({ key })` call for each serialised form picks up\n * the snapshot transparently — no further action is required.\n */\nexport function hydrateAttaformState(app: App, payload: SerializedAttaformState): void {\n const registry = getRegistryFromApp(app)\n for (const [key, data] of payload.forms) {\n registry.pendingHydration.set(key, data)\n }\n}\n","/**\n * Shared building blocks for Attaform's two devtools surfaces — the Vue\n * DevTools (Chrome-extension) inspector wired up in `./devtools.ts`, and\n * the Nuxt DevTools (overlay) panel wired up via `../../nuxt.ts` +\n * `../pages/_attaform_devtools.vue`.\n *\n * Houses the window-bridge contract both surfaces consume so a new\n * bridge field lands in one file. Both surfaces render RAW form values\n * by design — DevTools is a dev-only surface, and redaction across every\n * place a value surfaces is impractical security theater rather than a\n * real safeguard.\n */\nimport type { AttaformRegistry } from './registry'\n\n/**\n * Property key on `window` that the Nuxt-side dev plugin attaches the\n * bridge object to. The iframe-mounted overlay panel reads\n * `window.parent[DEVTOOLS_WINDOW_KEY]` to reach the host app's registry.\n *\n * Underscored + namespaced to make accidental collision with consumer\n * globals vanishingly unlikely. Stable across versions — bumping it\n * would silently disconnect older library builds from newer overlay\n * panels in the same browser tab during a library upgrade.\n */\nexport const DEVTOOLS_WINDOW_KEY = '__attaform_devtools__'\n\n/**\n * Shape of the object the host plugin attaches to `window` in dev mode.\n * The iframe overlay panel reads this to discover the live registry and\n * render its forms.\n *\n * Single-registry assumption: the latest `createAttaform()` install\n * wins. Multi-app pages (rare; typically only seen in micro-frontend\n * setups) will only see one app's forms in the panel. Documented but\n * not actively supported — the alternative (a Set of registries with\n * union-rendering) is a future call if a real consumer hits it.\n */\nexport interface AttaformDevtoolsBridge {\n registry: AttaformRegistry\n /**\n * The library version, surfaced in the panel's footer for support /\n * bug-report context. Read from `package.json` at host-plugin init.\n */\n version: string\n}\n\ndeclare global {\n interface Window {\n [DEVTOOLS_WINDOW_KEY]?: AttaformDevtoolsBridge\n }\n}\n"],"names":["getRegistryFromApp","pathKeyToDotted"],"mappings":";;;;AAuCO,SAAS,oBAAoB,GAAA,EAAmC;AACrE,EAAA,MAAM,QAAA,GAAWA,yBAAmB,GAAG,CAAA;AACvC,EAAA,MAAM,QAAuD,EAAC;AAC9D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,SAAS,KAAA,EAAO;AAOzC,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,EAAA,IAAM,MAAM,UAAA,EAAY;AACjC,MAAA,MAAM,CAAA,GAAIC,sBAAgB,EAAa,CAAA;AACvC,MAAA,IAAI,CAAA,KAAM,IAAA,EAAM,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,GAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,MAAM,IAAA,CAAK,KAAA;AAAA,QACjB,cAAc,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,SAAS,CAAA;AAAA,QACrD,YAAY,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA;AAAA,QACjD,QAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAAA,QACzC,GAAI,cAAc,MAAA,GAAS,CAAA,GAAI,EAAE,UAAA,EAAY,aAAA,KAAkB;AAAC;AAClE,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;AAkBO,SAAS,oBAAA,CAAqB,KAAU,OAAA,EAAwC;AACrF,EAAA,MAAM,QAAA,GAAWD,yBAAmB,GAAG,CAAA;AACvC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,CAAA,IAAK,QAAQ,KAAA,EAAO;AACvC,IAAA,QAAA,CAAS,gBAAA,CAAiB,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,EACzC;AACF;;ACjEO,MAAM,mBAAA,GAAsB;;;;;;"}
|
|
@@ -137,8 +137,8 @@ declare function canonicalizePath(input: string | Path): {
|
|
|
137
137
|
* `Path` to address the form value as a whole, and the home for
|
|
138
138
|
* form-level (global) errors: root `.refine()` messages, hydration
|
|
139
139
|
* failures, and `setErrors` entries with no path all live at `[]`. Aggregate
|
|
140
|
-
* reads (`errors()`, `meta.errors`) surface them alongside
|
|
141
|
-
* errors; `
|
|
140
|
+
* reads (`errors()`, `errors([])`, `meta.errors`) surface them alongside
|
|
141
|
+
* field errors; `meta.ownErrors` returns the root bucket alone.
|
|
142
142
|
*
|
|
143
143
|
* The empty SEGMENT tuple `[]` is structurally unconstructible as a
|
|
144
144
|
* field path, so it can never collide with a schema key, unlike the
|
|
@@ -2074,14 +2074,15 @@ type OnError = (error: ValidationError[]) => void | Promise<void>;
|
|
|
2074
2074
|
type DisplayState = 'idle' | 'pending' | 'error' | 'success';
|
|
2075
2075
|
/**
|
|
2076
2076
|
* Keys on `FieldState` layered on FROM the display-state predicate
|
|
2077
|
-
* (plus `firstError`, computed alongside them).
|
|
2078
|
-
* predicate's arguments so a predicate cannot read
|
|
2079
|
-
* form a cycle — enforced at the type level AND at
|
|
2080
|
-
* objects passed in literally lack these keys, so an
|
|
2081
|
-
* or a vanilla-JS caller still can't reach them.
|
|
2082
|
-
* `FormMetaBase` (field-state-api.ts) omit the same
|
|
2077
|
+
* (plus `firstError` / `firstOwnError`, computed alongside them).
|
|
2078
|
+
* `Omit`'d from the predicate's arguments so a predicate cannot read
|
|
2079
|
+
* its own output and form a cycle — enforced at the type level AND at
|
|
2080
|
+
* runtime: the base objects passed in literally lack these keys, so an
|
|
2081
|
+
* `as` cast in TS or a vanilla-JS caller still can't reach them.
|
|
2082
|
+
* `FieldStateBase` / `FormMetaBase` (field-state-api.ts) omit the same
|
|
2083
|
+
* set in lockstep.
|
|
2083
2084
|
*/
|
|
2084
|
-
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError';
|
|
2085
|
+
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError' | 'firstOwnError';
|
|
2085
2086
|
/**
|
|
2086
2087
|
* One step of the display state machine: the verdict the field should
|
|
2087
2088
|
* render right now (`display`, projected to `displayState` and the
|
|
@@ -3114,7 +3115,40 @@ type FieldState<Value = unknown> = {
|
|
|
3114
3115
|
*/
|
|
3115
3116
|
readonly elements: readonly HTMLElement[];
|
|
3116
3117
|
readonly updatedAt: string | null;
|
|
3118
|
+
/**
|
|
3119
|
+
* Every `ValidationError` in this path's SUBTREE: the node's own
|
|
3120
|
+
* bucket plus every descendant's, sorted by schema-declaration order.
|
|
3121
|
+
* On a leaf (no descendants) this equals `ownErrors`. On a container
|
|
3122
|
+
* it rolls up the whole fieldset, so a parent's `errors` is non-empty
|
|
3123
|
+
* whenever any child is invalid.
|
|
3124
|
+
*
|
|
3125
|
+
* For the errors pinned at THIS path alone (a container's own
|
|
3126
|
+
* cross-field `.refine()`, or `setErrors` at this path), read
|
|
3127
|
+
* `ownErrors`.
|
|
3128
|
+
*/
|
|
3117
3129
|
readonly errors: readonly ValidationError[];
|
|
3130
|
+
/**
|
|
3131
|
+
* Every `ValidationError` at THIS exact path's own bucket, excluding
|
|
3132
|
+
* descendants: schema errors, blank-required errors, and `setErrors`
|
|
3133
|
+
* pinned here, in `schema`, `blank`, `user` order. The exact-path
|
|
3134
|
+
* counterpart to the subtree-scoped `errors`.
|
|
3135
|
+
*
|
|
3136
|
+
* On a leaf this is the same array as `errors` (a leaf has no
|
|
3137
|
+
* descendants). On a container it holds only the container's OWN
|
|
3138
|
+
* errors, a cross-field `.refine()` on the fieldset or a path-less
|
|
3139
|
+
* `setErrors` at this node, without dragging in any child error:
|
|
3140
|
+
*
|
|
3141
|
+
* ```vue
|
|
3142
|
+
* <p v-if="form.fields.address.firstOwnError">
|
|
3143
|
+
* {{ form.fields.address.firstOwnError.message }}
|
|
3144
|
+
* </p>
|
|
3145
|
+
* ```
|
|
3146
|
+
*
|
|
3147
|
+
* On `form.meta` this is the root `[]` bucket: form-level errors from
|
|
3148
|
+
* a root `.refine()` or a path-less `setErrors`. `form.meta.ownErrors`
|
|
3149
|
+
* (with `firstOwnError`) is the banner accessor for those.
|
|
3150
|
+
*/
|
|
3151
|
+
readonly ownErrors: readonly ValidationError[];
|
|
3118
3152
|
/**
|
|
3119
3153
|
* `true` while a per-field validation run is in flight at this path.
|
|
3120
3154
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
@@ -3235,9 +3269,28 @@ type FieldState<Value = unknown> = {
|
|
|
3235
3269
|
* decides when to render it.
|
|
3236
3270
|
*
|
|
3237
3271
|
* On container paths, the first error in the aggregated subtree
|
|
3238
|
-
* (descendants sorted by `pathOrdinal`).
|
|
3272
|
+
* (descendants sorted by `pathOrdinal`). For the container's OWN
|
|
3273
|
+
* first error only, read `firstOwnError`.
|
|
3239
3274
|
*/
|
|
3240
3275
|
readonly firstError: ValidationError | undefined;
|
|
3276
|
+
/**
|
|
3277
|
+
* The first `ValidationError` in `ownErrors` (this exact path's own
|
|
3278
|
+
* bucket), or `undefined` when that bucket is empty. Equivalent to
|
|
3279
|
+
* `ownErrors[0]`, the exact-path counterpart to `firstError`.
|
|
3280
|
+
*
|
|
3281
|
+
* On a leaf this equals `firstError`. On a container it is the
|
|
3282
|
+
* container's own cross-field error (a fieldset `.refine()`), never a
|
|
3283
|
+
* child's. `form.meta.firstOwnError` is the form-level banner: the
|
|
3284
|
+
* first root `[]` error from a root `.refine()` or a path-less
|
|
3285
|
+
* `setErrors`:
|
|
3286
|
+
*
|
|
3287
|
+
* ```vue
|
|
3288
|
+
* <p v-if="form.meta.firstOwnError" role="alert">
|
|
3289
|
+
* {{ form.meta.firstOwnError.message }}
|
|
3290
|
+
* </p>
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
readonly firstOwnError: ValidationError | undefined;
|
|
3241
3294
|
readonly path: ReadonlyArray<string | number>;
|
|
3242
3295
|
/**
|
|
3243
3296
|
* Stable, SSR-safe DOM id for this field, unique across every mount
|
|
@@ -3601,11 +3654,13 @@ type FormErrorsSurface<Form> = ErrorsProxyShape<Form> & {
|
|
|
3601
3654
|
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): readonly ValidationError[];
|
|
3602
3655
|
(segments: ReadonlyArray<string | number>): readonly ValidationError[];
|
|
3603
3656
|
/**
|
|
3604
|
-
* No-arg call returns the whole-form error aggregate
|
|
3605
|
-
* `form.meta.errors`: every field error plus
|
|
3606
|
-
*
|
|
3607
|
-
*
|
|
3608
|
-
*
|
|
3657
|
+
* No-arg call returns the whole-form error aggregate, the same as
|
|
3658
|
+
* `form.meta.errors` and `form.errors([])`: every field error plus
|
|
3659
|
+
* the root bucket. `form.errors(path)` is uniform at every depth,
|
|
3660
|
+
* including `[]`, so the root is no exception. For the root bucket
|
|
3661
|
+
* alone (a root `.refine()`, a path-less `setErrors`), read
|
|
3662
|
+
* `form.meta.ownErrors`. Always a readonly array; empty when the form
|
|
3663
|
+
* has no errors.
|
|
3609
3664
|
*/
|
|
3610
3665
|
(): readonly ValidationError[];
|
|
3611
3666
|
};
|
|
@@ -137,8 +137,8 @@ declare function canonicalizePath(input: string | Path): {
|
|
|
137
137
|
* `Path` to address the form value as a whole, and the home for
|
|
138
138
|
* form-level (global) errors: root `.refine()` messages, hydration
|
|
139
139
|
* failures, and `setErrors` entries with no path all live at `[]`. Aggregate
|
|
140
|
-
* reads (`errors()`, `meta.errors`) surface them alongside
|
|
141
|
-
* errors; `
|
|
140
|
+
* reads (`errors()`, `errors([])`, `meta.errors`) surface them alongside
|
|
141
|
+
* field errors; `meta.ownErrors` returns the root bucket alone.
|
|
142
142
|
*
|
|
143
143
|
* The empty SEGMENT tuple `[]` is structurally unconstructible as a
|
|
144
144
|
* field path, so it can never collide with a schema key, unlike the
|
|
@@ -2074,14 +2074,15 @@ type OnError = (error: ValidationError[]) => void | Promise<void>;
|
|
|
2074
2074
|
type DisplayState = 'idle' | 'pending' | 'error' | 'success';
|
|
2075
2075
|
/**
|
|
2076
2076
|
* Keys on `FieldState` layered on FROM the display-state predicate
|
|
2077
|
-
* (plus `firstError`, computed alongside them).
|
|
2078
|
-
* predicate's arguments so a predicate cannot read
|
|
2079
|
-
* form a cycle — enforced at the type level AND at
|
|
2080
|
-
* objects passed in literally lack these keys, so an
|
|
2081
|
-
* or a vanilla-JS caller still can't reach them.
|
|
2082
|
-
* `FormMetaBase` (field-state-api.ts) omit the same
|
|
2077
|
+
* (plus `firstError` / `firstOwnError`, computed alongside them).
|
|
2078
|
+
* `Omit`'d from the predicate's arguments so a predicate cannot read
|
|
2079
|
+
* its own output and form a cycle — enforced at the type level AND at
|
|
2080
|
+
* runtime: the base objects passed in literally lack these keys, so an
|
|
2081
|
+
* `as` cast in TS or a vanilla-JS caller still can't reach them.
|
|
2082
|
+
* `FieldStateBase` / `FormMetaBase` (field-state-api.ts) omit the same
|
|
2083
|
+
* set in lockstep.
|
|
2083
2084
|
*/
|
|
2084
|
-
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError';
|
|
2085
|
+
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError' | 'firstOwnError';
|
|
2085
2086
|
/**
|
|
2086
2087
|
* One step of the display state machine: the verdict the field should
|
|
2087
2088
|
* render right now (`display`, projected to `displayState` and the
|
|
@@ -3114,7 +3115,40 @@ type FieldState<Value = unknown> = {
|
|
|
3114
3115
|
*/
|
|
3115
3116
|
readonly elements: readonly HTMLElement[];
|
|
3116
3117
|
readonly updatedAt: string | null;
|
|
3118
|
+
/**
|
|
3119
|
+
* Every `ValidationError` in this path's SUBTREE: the node's own
|
|
3120
|
+
* bucket plus every descendant's, sorted by schema-declaration order.
|
|
3121
|
+
* On a leaf (no descendants) this equals `ownErrors`. On a container
|
|
3122
|
+
* it rolls up the whole fieldset, so a parent's `errors` is non-empty
|
|
3123
|
+
* whenever any child is invalid.
|
|
3124
|
+
*
|
|
3125
|
+
* For the errors pinned at THIS path alone (a container's own
|
|
3126
|
+
* cross-field `.refine()`, or `setErrors` at this path), read
|
|
3127
|
+
* `ownErrors`.
|
|
3128
|
+
*/
|
|
3117
3129
|
readonly errors: readonly ValidationError[];
|
|
3130
|
+
/**
|
|
3131
|
+
* Every `ValidationError` at THIS exact path's own bucket, excluding
|
|
3132
|
+
* descendants: schema errors, blank-required errors, and `setErrors`
|
|
3133
|
+
* pinned here, in `schema`, `blank`, `user` order. The exact-path
|
|
3134
|
+
* counterpart to the subtree-scoped `errors`.
|
|
3135
|
+
*
|
|
3136
|
+
* On a leaf this is the same array as `errors` (a leaf has no
|
|
3137
|
+
* descendants). On a container it holds only the container's OWN
|
|
3138
|
+
* errors, a cross-field `.refine()` on the fieldset or a path-less
|
|
3139
|
+
* `setErrors` at this node, without dragging in any child error:
|
|
3140
|
+
*
|
|
3141
|
+
* ```vue
|
|
3142
|
+
* <p v-if="form.fields.address.firstOwnError">
|
|
3143
|
+
* {{ form.fields.address.firstOwnError.message }}
|
|
3144
|
+
* </p>
|
|
3145
|
+
* ```
|
|
3146
|
+
*
|
|
3147
|
+
* On `form.meta` this is the root `[]` bucket: form-level errors from
|
|
3148
|
+
* a root `.refine()` or a path-less `setErrors`. `form.meta.ownErrors`
|
|
3149
|
+
* (with `firstOwnError`) is the banner accessor for those.
|
|
3150
|
+
*/
|
|
3151
|
+
readonly ownErrors: readonly ValidationError[];
|
|
3118
3152
|
/**
|
|
3119
3153
|
* `true` while a per-field validation run is in flight at this path.
|
|
3120
3154
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
@@ -3235,9 +3269,28 @@ type FieldState<Value = unknown> = {
|
|
|
3235
3269
|
* decides when to render it.
|
|
3236
3270
|
*
|
|
3237
3271
|
* On container paths, the first error in the aggregated subtree
|
|
3238
|
-
* (descendants sorted by `pathOrdinal`).
|
|
3272
|
+
* (descendants sorted by `pathOrdinal`). For the container's OWN
|
|
3273
|
+
* first error only, read `firstOwnError`.
|
|
3239
3274
|
*/
|
|
3240
3275
|
readonly firstError: ValidationError | undefined;
|
|
3276
|
+
/**
|
|
3277
|
+
* The first `ValidationError` in `ownErrors` (this exact path's own
|
|
3278
|
+
* bucket), or `undefined` when that bucket is empty. Equivalent to
|
|
3279
|
+
* `ownErrors[0]`, the exact-path counterpart to `firstError`.
|
|
3280
|
+
*
|
|
3281
|
+
* On a leaf this equals `firstError`. On a container it is the
|
|
3282
|
+
* container's own cross-field error (a fieldset `.refine()`), never a
|
|
3283
|
+
* child's. `form.meta.firstOwnError` is the form-level banner: the
|
|
3284
|
+
* first root `[]` error from a root `.refine()` or a path-less
|
|
3285
|
+
* `setErrors`:
|
|
3286
|
+
*
|
|
3287
|
+
* ```vue
|
|
3288
|
+
* <p v-if="form.meta.firstOwnError" role="alert">
|
|
3289
|
+
* {{ form.meta.firstOwnError.message }}
|
|
3290
|
+
* </p>
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
readonly firstOwnError: ValidationError | undefined;
|
|
3241
3294
|
readonly path: ReadonlyArray<string | number>;
|
|
3242
3295
|
/**
|
|
3243
3296
|
* Stable, SSR-safe DOM id for this field, unique across every mount
|
|
@@ -3601,11 +3654,13 @@ type FormErrorsSurface<Form> = ErrorsProxyShape<Form> & {
|
|
|
3601
3654
|
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): readonly ValidationError[];
|
|
3602
3655
|
(segments: ReadonlyArray<string | number>): readonly ValidationError[];
|
|
3603
3656
|
/**
|
|
3604
|
-
* No-arg call returns the whole-form error aggregate
|
|
3605
|
-
* `form.meta.errors`: every field error plus
|
|
3606
|
-
*
|
|
3607
|
-
*
|
|
3608
|
-
*
|
|
3657
|
+
* No-arg call returns the whole-form error aggregate, the same as
|
|
3658
|
+
* `form.meta.errors` and `form.errors([])`: every field error plus
|
|
3659
|
+
* the root bucket. `form.errors(path)` is uniform at every depth,
|
|
3660
|
+
* including `[]`, so the root is no exception. For the root bucket
|
|
3661
|
+
* alone (a root `.refine()`, a path-less `setErrors`), read
|
|
3662
|
+
* `form.meta.ownErrors`. Always a readonly array; empty when the form
|
|
3663
|
+
* has no errors.
|
|
3609
3664
|
*/
|
|
3610
3665
|
(): readonly ValidationError[];
|
|
3611
3666
|
};
|
|
@@ -137,8 +137,8 @@ declare function canonicalizePath(input: string | Path): {
|
|
|
137
137
|
* `Path` to address the form value as a whole, and the home for
|
|
138
138
|
* form-level (global) errors: root `.refine()` messages, hydration
|
|
139
139
|
* failures, and `setErrors` entries with no path all live at `[]`. Aggregate
|
|
140
|
-
* reads (`errors()`, `meta.errors`) surface them alongside
|
|
141
|
-
* errors; `
|
|
140
|
+
* reads (`errors()`, `errors([])`, `meta.errors`) surface them alongside
|
|
141
|
+
* field errors; `meta.ownErrors` returns the root bucket alone.
|
|
142
142
|
*
|
|
143
143
|
* The empty SEGMENT tuple `[]` is structurally unconstructible as a
|
|
144
144
|
* field path, so it can never collide with a schema key, unlike the
|
|
@@ -2074,14 +2074,15 @@ type OnError = (error: ValidationError[]) => void | Promise<void>;
|
|
|
2074
2074
|
type DisplayState = 'idle' | 'pending' | 'error' | 'success';
|
|
2075
2075
|
/**
|
|
2076
2076
|
* Keys on `FieldState` layered on FROM the display-state predicate
|
|
2077
|
-
* (plus `firstError`, computed alongside them).
|
|
2078
|
-
* predicate's arguments so a predicate cannot read
|
|
2079
|
-
* form a cycle — enforced at the type level AND at
|
|
2080
|
-
* objects passed in literally lack these keys, so an
|
|
2081
|
-
* or a vanilla-JS caller still can't reach them.
|
|
2082
|
-
* `FormMetaBase` (field-state-api.ts) omit the same
|
|
2077
|
+
* (plus `firstError` / `firstOwnError`, computed alongside them).
|
|
2078
|
+
* `Omit`'d from the predicate's arguments so a predicate cannot read
|
|
2079
|
+
* its own output and form a cycle — enforced at the type level AND at
|
|
2080
|
+
* runtime: the base objects passed in literally lack these keys, so an
|
|
2081
|
+
* `as` cast in TS or a vanilla-JS caller still can't reach them.
|
|
2082
|
+
* `FieldStateBase` / `FormMetaBase` (field-state-api.ts) omit the same
|
|
2083
|
+
* set in lockstep.
|
|
2083
2084
|
*/
|
|
2084
|
-
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError';
|
|
2085
|
+
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError' | 'firstOwnError';
|
|
2085
2086
|
/**
|
|
2086
2087
|
* One step of the display state machine: the verdict the field should
|
|
2087
2088
|
* render right now (`display`, projected to `displayState` and the
|
|
@@ -3114,7 +3115,40 @@ type FieldState<Value = unknown> = {
|
|
|
3114
3115
|
*/
|
|
3115
3116
|
readonly elements: readonly HTMLElement[];
|
|
3116
3117
|
readonly updatedAt: string | null;
|
|
3118
|
+
/**
|
|
3119
|
+
* Every `ValidationError` in this path's SUBTREE: the node's own
|
|
3120
|
+
* bucket plus every descendant's, sorted by schema-declaration order.
|
|
3121
|
+
* On a leaf (no descendants) this equals `ownErrors`. On a container
|
|
3122
|
+
* it rolls up the whole fieldset, so a parent's `errors` is non-empty
|
|
3123
|
+
* whenever any child is invalid.
|
|
3124
|
+
*
|
|
3125
|
+
* For the errors pinned at THIS path alone (a container's own
|
|
3126
|
+
* cross-field `.refine()`, or `setErrors` at this path), read
|
|
3127
|
+
* `ownErrors`.
|
|
3128
|
+
*/
|
|
3117
3129
|
readonly errors: readonly ValidationError[];
|
|
3130
|
+
/**
|
|
3131
|
+
* Every `ValidationError` at THIS exact path's own bucket, excluding
|
|
3132
|
+
* descendants: schema errors, blank-required errors, and `setErrors`
|
|
3133
|
+
* pinned here, in `schema`, `blank`, `user` order. The exact-path
|
|
3134
|
+
* counterpart to the subtree-scoped `errors`.
|
|
3135
|
+
*
|
|
3136
|
+
* On a leaf this is the same array as `errors` (a leaf has no
|
|
3137
|
+
* descendants). On a container it holds only the container's OWN
|
|
3138
|
+
* errors, a cross-field `.refine()` on the fieldset or a path-less
|
|
3139
|
+
* `setErrors` at this node, without dragging in any child error:
|
|
3140
|
+
*
|
|
3141
|
+
* ```vue
|
|
3142
|
+
* <p v-if="form.fields.address.firstOwnError">
|
|
3143
|
+
* {{ form.fields.address.firstOwnError.message }}
|
|
3144
|
+
* </p>
|
|
3145
|
+
* ```
|
|
3146
|
+
*
|
|
3147
|
+
* On `form.meta` this is the root `[]` bucket: form-level errors from
|
|
3148
|
+
* a root `.refine()` or a path-less `setErrors`. `form.meta.ownErrors`
|
|
3149
|
+
* (with `firstOwnError`) is the banner accessor for those.
|
|
3150
|
+
*/
|
|
3151
|
+
readonly ownErrors: readonly ValidationError[];
|
|
3118
3152
|
/**
|
|
3119
3153
|
* `true` while a per-field validation run is in flight at this path.
|
|
3120
3154
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
@@ -3235,9 +3269,28 @@ type FieldState<Value = unknown> = {
|
|
|
3235
3269
|
* decides when to render it.
|
|
3236
3270
|
*
|
|
3237
3271
|
* On container paths, the first error in the aggregated subtree
|
|
3238
|
-
* (descendants sorted by `pathOrdinal`).
|
|
3272
|
+
* (descendants sorted by `pathOrdinal`). For the container's OWN
|
|
3273
|
+
* first error only, read `firstOwnError`.
|
|
3239
3274
|
*/
|
|
3240
3275
|
readonly firstError: ValidationError | undefined;
|
|
3276
|
+
/**
|
|
3277
|
+
* The first `ValidationError` in `ownErrors` (this exact path's own
|
|
3278
|
+
* bucket), or `undefined` when that bucket is empty. Equivalent to
|
|
3279
|
+
* `ownErrors[0]`, the exact-path counterpart to `firstError`.
|
|
3280
|
+
*
|
|
3281
|
+
* On a leaf this equals `firstError`. On a container it is the
|
|
3282
|
+
* container's own cross-field error (a fieldset `.refine()`), never a
|
|
3283
|
+
* child's. `form.meta.firstOwnError` is the form-level banner: the
|
|
3284
|
+
* first root `[]` error from a root `.refine()` or a path-less
|
|
3285
|
+
* `setErrors`:
|
|
3286
|
+
*
|
|
3287
|
+
* ```vue
|
|
3288
|
+
* <p v-if="form.meta.firstOwnError" role="alert">
|
|
3289
|
+
* {{ form.meta.firstOwnError.message }}
|
|
3290
|
+
* </p>
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
readonly firstOwnError: ValidationError | undefined;
|
|
3241
3294
|
readonly path: ReadonlyArray<string | number>;
|
|
3242
3295
|
/**
|
|
3243
3296
|
* Stable, SSR-safe DOM id for this field, unique across every mount
|
|
@@ -3601,11 +3654,13 @@ type FormErrorsSurface<Form> = ErrorsProxyShape<Form> & {
|
|
|
3601
3654
|
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): readonly ValidationError[];
|
|
3602
3655
|
(segments: ReadonlyArray<string | number>): readonly ValidationError[];
|
|
3603
3656
|
/**
|
|
3604
|
-
* No-arg call returns the whole-form error aggregate
|
|
3605
|
-
* `form.meta.errors`: every field error plus
|
|
3606
|
-
*
|
|
3607
|
-
*
|
|
3608
|
-
*
|
|
3657
|
+
* No-arg call returns the whole-form error aggregate, the same as
|
|
3658
|
+
* `form.meta.errors` and `form.errors([])`: every field error plus
|
|
3659
|
+
* the root bucket. `form.errors(path)` is uniform at every depth,
|
|
3660
|
+
* including `[]`, so the root is no exception. For the root bucket
|
|
3661
|
+
* alone (a root `.refine()`, a path-less `setErrors`), read
|
|
3662
|
+
* `form.meta.ownErrors`. Always a readonly array; empty when the form
|
|
3663
|
+
* has no errors.
|
|
3609
3664
|
*/
|
|
3610
3665
|
(): readonly ValidationError[];
|
|
3611
3666
|
};
|
|
@@ -25,6 +25,28 @@ function toError(value) {
|
|
|
25
25
|
const message = typeof value === "string" && value.length > 0 ? value : `Submit callback threw a non-Error value (${typeof value})`;
|
|
26
26
|
return new Error(message, { cause: value });
|
|
27
27
|
}
|
|
28
|
+
function normalizeErrorInput(item, scope, formKey, defaultCode) {
|
|
29
|
+
if (item instanceof Error) {
|
|
30
|
+
return {
|
|
31
|
+
message: item.message.length > 0 ? item.message : "Unknown error",
|
|
32
|
+
path: scope !== void 0 ? [...scope] : [],
|
|
33
|
+
formKey,
|
|
34
|
+
code: defaultCode
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const entry = {
|
|
38
|
+
message: typeof item.message === "string" && item.message.length > 0 ? item.message : "Unknown error",
|
|
39
|
+
path: scope !== void 0 ? [...scope] : Array.isArray(item.path) ? [...item.path] : [],
|
|
40
|
+
formKey,
|
|
41
|
+
code: typeof item.code === "string" && item.code.length > 0 ? item.code : defaultCode
|
|
42
|
+
};
|
|
43
|
+
if (item.data !== void 0) entry.data = item.data;
|
|
44
|
+
return entry;
|
|
45
|
+
}
|
|
46
|
+
function normalizeErrorInputs(input, scope, formKey, defaultCode) {
|
|
47
|
+
const items = Array.isArray(input) ? input : [input];
|
|
48
|
+
return items.map((item) => normalizeErrorInput(item, scope, formKey, defaultCode));
|
|
49
|
+
}
|
|
28
50
|
class RegistryNotInstalledError extends AttaformError {
|
|
29
51
|
constructor() {
|
|
30
52
|
super(
|
|
@@ -1592,5 +1614,5 @@ function pathsEqual(a, b) {
|
|
|
1592
1614
|
return true;
|
|
1593
1615
|
}
|
|
1594
1616
|
|
|
1595
|
-
export { AttaformError as A, InvalidPathError as I, OutsideSetupError as O, ROOT_PATH as R, SubmitErrorHandlerError as S, __DEV__ as _, InvalidUseFormConfigError as a, ROOT_PATH_KEY as b, RegistryNotInstalledError as c, ReservedFormKeyError as d, assignKey as e, canonicalizePath as f, createAttaform as g, createRegistry as h, getRegistryFromApp as i, isPathPrefix as j, kAttaformRegistry as k, kAttaformWizardActiveStepResolver as l, pathKeyToDotted as m, pathsEqual as n, keyForSegments as o, parseDottedPath as p,
|
|
1596
|
-
//# sourceMappingURL=attaform.
|
|
1617
|
+
export { AttaformError as A, kFormInstanceId as B, kAttaformAncestorWizard as C, InvalidPathError as I, OutsideSetupError as O, ROOT_PATH as R, SubmitErrorHandlerError as S, __DEV__ as _, InvalidUseFormConfigError as a, ROOT_PATH_KEY as b, RegistryNotInstalledError as c, ReservedFormKeyError as d, assignKey as e, canonicalizePath as f, createAttaform as g, createRegistry as h, getRegistryFromApp as i, isPathPrefix as j, kAttaformRegistry as k, kAttaformWizardActiveStepResolver as l, pathKeyToDotted as m, pathsEqual as n, keyForSegments as o, parseDottedPath as p, normalizeErrorInput as q, INTERACTIVE_TAG_NAMES as r, segmentsForPathKey as s, toError as t, useRegistry as u, vRegister as v, normalizeErrorInputs as w, coerceToPathKey as x, ensureAttaformInstalled as y, kFormContext as z };
|
|
1618
|
+
//# sourceMappingURL=attaform.DGhIix5D.mjs.map
|