attaform 0.23.0 → 0.24.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/README.md +1 -1
- 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 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -132
- package/dist/index.d.mts +6 -132
- package/dist/index.d.ts +6 -132
- package/dist/index.mjs +4 -150
- package/dist/index.mjs.map +1 -1
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +2 -2
- package/dist/runtime/plugins/attaform.cjs +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.CzVta5o2.mjs → attaform.BJ_W7q3U.mjs} +8 -6
- package/dist/shared/attaform.BJ_W7q3U.mjs.map +1 -0
- package/dist/shared/{attaform.D52oJiYC.d.cts → attaform.BNmkKz0q.d.mts} +38 -6
- package/dist/shared/{attaform.CaYj3ZfY.cjs → attaform.BV_HyaMO.cjs} +6 -4
- package/dist/shared/attaform.BV_HyaMO.cjs.map +1 -0
- package/dist/shared/{attaform.Cmb_LCie.cjs → attaform.BnUXV01g.cjs} +4 -4
- package/dist/shared/attaform.BnUXV01g.cjs.map +1 -0
- package/dist/shared/{attaform.alpG7rT7.mjs → attaform.C-dAB90u.mjs} +4 -4
- package/dist/shared/attaform.C-dAB90u.mjs.map +1 -0
- package/dist/shared/{attaform.DsQkXE3o.cjs → attaform.C42wL7EJ.cjs} +195 -179
- package/dist/shared/attaform.C42wL7EJ.cjs.map +1 -0
- package/dist/shared/{attaform.BGMRvckW.d.ts → attaform.C6eE50re.d.ts} +18 -11
- package/dist/shared/{attaform.Dx9-QQE2.mjs → attaform.CAWKNCzc.mjs} +2 -2
- package/dist/shared/{attaform.Dx9-QQE2.mjs.map → attaform.CAWKNCzc.mjs.map} +1 -1
- package/dist/shared/{attaform.CtJOd7ox.mjs → attaform.CuBdtfbe.mjs} +196 -179
- package/dist/shared/attaform.CuBdtfbe.mjs.map +1 -0
- package/dist/shared/{attaform.WEwfXcHq.d.ts → attaform.CwFZGv5-.d.ts} +38 -6
- package/dist/shared/{attaform.DuPneYR0.d.cts → attaform.DdUYEhkV.d.cts} +18 -11
- package/dist/shared/attaform.DdjDqTah.d.cts +56 -0
- package/dist/shared/attaform.DdjDqTah.d.mts +56 -0
- package/dist/shared/attaform.DdjDqTah.d.ts +56 -0
- package/dist/shared/{attaform.BhI9Icek.mjs → attaform.Df-s8j1X.mjs} +2 -4
- package/dist/shared/attaform.Df-s8j1X.mjs.map +1 -0
- package/dist/shared/{attaform.DrY8srOp.d.mts → attaform.DiWNbKWa.d.mts} +18 -11
- package/dist/shared/{attaform.Db4E4IW6.cjs → attaform.DwkU0oY9.cjs} +1 -5
- package/dist/shared/attaform.DwkU0oY9.cjs.map +1 -0
- package/dist/shared/{attaform.BJnNK75Y.d.cts → attaform.GJbSmwLB.d.cts} +181 -156
- package/dist/shared/{attaform.BJnNK75Y.d.mts → attaform.GJbSmwLB.d.mts} +181 -156
- package/dist/shared/{attaform.BJnNK75Y.d.ts → attaform.GJbSmwLB.d.ts} +181 -156
- package/dist/shared/{attaform.DCkSNnPr.d.mts → attaform.K-3glmiT.d.cts} +38 -6
- package/dist/shared/{attaform.DbyTD8N2.cjs → attaform.Z1qTwOYE.cjs} +8 -6
- package/dist/shared/attaform.Z1qTwOYE.cjs.map +1 -0
- package/dist/shared/{attaform.BibT5AS_.cjs → attaform.nycEksJn.cjs} +2 -2
- package/dist/shared/{attaform.BibT5AS_.cjs.map → attaform.nycEksJn.cjs.map} +1 -1
- package/dist/shared/{attaform.Dd1Kmmaj.mjs → attaform.o95Kjd3U.mjs} +6 -4
- package/dist/shared/attaform.o95Kjd3U.mjs.map +1 -0
- package/dist/zod-v3.cjs +2 -2
- package/dist/zod-v3.d.cts +12 -11
- package/dist/zod-v3.d.mts +12 -11
- package/dist/zod-v3.d.ts +12 -11
- package/dist/zod-v3.mjs +2 -2
- package/dist/zod-v4.cjs +2 -2
- package/dist/zod-v4.d.cts +6 -5
- package/dist/zod-v4.d.mts +6 -5
- package/dist/zod-v4.d.ts +6 -5
- package/dist/zod-v4.mjs +2 -2
- package/dist/zod.cjs +5 -5
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +21 -52
- package/dist/zod.d.mts +21 -52
- package/dist/zod.d.ts +21 -52
- package/dist/zod.mjs +5 -5
- package/dist/zod.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/shared/attaform.BhI9Icek.mjs.map +0 -1
- package/dist/shared/attaform.CaYj3ZfY.cjs.map +0 -1
- package/dist/shared/attaform.Cmb_LCie.cjs.map +0 -1
- package/dist/shared/attaform.CtJOd7ox.mjs.map +0 -1
- package/dist/shared/attaform.CzVta5o2.mjs.map +0 -1
- package/dist/shared/attaform.Db4E4IW6.cjs.map +0 -1
- package/dist/shared/attaform.DbyTD8N2.cjs.map +0 -1
- package/dist/shared/attaform.Dd1Kmmaj.mjs.map +0 -1
- package/dist/shared/attaform.DsQkXE3o.cjs.map +0 -1
- package/dist/shared/attaform.alpG7rT7.mjs.map +0 -1
- package/dist/shared/attaform.nf83TIR5.d.cts +0 -35
- package/dist/shared/attaform.nf83TIR5.d.mts +0 -35
- package/dist/shared/attaform.nf83TIR5.d.ts +0 -35
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
|
|
2
|
-
import { o as pathsEqual, j as isPathPrefix, _ as __DEV__,
|
|
2
|
+
import { o as pathsEqual, j as isPathPrefix, _ as __DEV__, f as canonicalizePath, s as segmentsForPathKey, q as keyForSegments, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, r as INTERACTIVE_TAG_NAMES, R as ROOT_PATH, w as coerceToPathKey, a as InvalidUseFormConfigError, x as ensureAttaformInstalled, u as useRegistry, y as kFormContext, z as kFormInstanceId, d as ReservedFormKeyError, B as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, m as kAttaformWizardActiveStepResolver, C as kAttaformAncestorWizard } from './attaform.Df-s8j1X.mjs';
|
|
3
3
|
|
|
4
4
|
function safeAssign(target, key, value) {
|
|
5
5
|
if (key === "__proto__") {
|
|
@@ -540,6 +540,58 @@ function structuralSnapshot(value) {
|
|
|
540
540
|
return out;
|
|
541
541
|
}
|
|
542
542
|
|
|
543
|
+
const AttaformErrorCode = {
|
|
544
|
+
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
545
|
+
NoValueSupplied: "atta:no-value-supplied",
|
|
546
|
+
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
547
|
+
AdapterThrew: "atta:adapter-threw",
|
|
548
|
+
/**
|
|
549
|
+
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
550
|
+
* threw (sync or async). The adapter caught the throw and surfaced
|
|
551
|
+
* it as a `ValidationError` at the field path so the form's normal
|
|
552
|
+
* error pipeline handles it instead of leaking as an unhandled
|
|
553
|
+
* rejection or routing through `submitError`.
|
|
554
|
+
*/
|
|
555
|
+
ValidatorThrew: "atta:validator-threw",
|
|
556
|
+
/**
|
|
557
|
+
* A function-form `defaultValues` factory threw or its promise
|
|
558
|
+
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
559
|
+
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
560
|
+
* the standard error pipeline carries the signal. Critical for the
|
|
561
|
+
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
562
|
+
* payload, but `schemaErrors` does, so the client sees the failure
|
|
563
|
+
* after rehydration without an extra channel.
|
|
564
|
+
*/
|
|
565
|
+
HydrationFailed: "atta:hydration-failed",
|
|
566
|
+
/** The supplied path didn't resolve to any node in the schema. */
|
|
567
|
+
PathNotFound: "atta:path-not-found",
|
|
568
|
+
/**
|
|
569
|
+
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
570
|
+
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
571
|
+
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
572
|
+
* aggregate error pipeline can carry the failure alongside ordinary
|
|
573
|
+
* validation errors. The raw factory error remains on
|
|
574
|
+
* `form.hydrateError` for retry UX.
|
|
575
|
+
*/
|
|
576
|
+
ActivationFailed: "atta:activation-failed",
|
|
577
|
+
/**
|
|
578
|
+
* Default code stamped on a manual error set through `form.setErrors`
|
|
579
|
+
* when the caller omits an explicit `code`. The `setErrors` input is
|
|
580
|
+
* lenient (`code` optional), so this is the fallback that keeps every
|
|
581
|
+
* produced `ValidationError` carrying a stable, branchable identifier.
|
|
582
|
+
* Override it per error by passing your own `code` (`api:…`, `auth:…`).
|
|
583
|
+
*/
|
|
584
|
+
UserError: "atta:user-error"
|
|
585
|
+
};
|
|
586
|
+
function makeBlankRequiredError(segments, formKey) {
|
|
587
|
+
return {
|
|
588
|
+
message: "No value supplied",
|
|
589
|
+
path: [...segments],
|
|
590
|
+
formKey,
|
|
591
|
+
code: AttaformErrorCode.NoValueSupplied
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
|
|
543
595
|
function isGateOpen(field, formMeta) {
|
|
544
596
|
return formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
|
|
545
597
|
}
|
|
@@ -595,50 +647,6 @@ function resolveGetDisplayState(config) {
|
|
|
595
647
|
return config ?? defaultDisplayState;
|
|
596
648
|
}
|
|
597
649
|
|
|
598
|
-
const AttaformErrorCode = {
|
|
599
|
-
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
600
|
-
NoValueSupplied: "atta:no-value-supplied",
|
|
601
|
-
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
602
|
-
AdapterThrew: "atta:adapter-threw",
|
|
603
|
-
/**
|
|
604
|
-
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
605
|
-
* threw (sync or async). The adapter caught the throw and surfaced
|
|
606
|
-
* it as a `ValidationError` at the field path so the form's normal
|
|
607
|
-
* error pipeline handles it instead of leaking as an unhandled
|
|
608
|
-
* rejection or routing through `submitError`.
|
|
609
|
-
*/
|
|
610
|
-
ValidatorThrew: "atta:validator-threw",
|
|
611
|
-
/**
|
|
612
|
-
* A function-form `defaultValues` factory threw or its promise
|
|
613
|
-
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
614
|
-
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
615
|
-
* the standard error pipeline carries the signal. Critical for the
|
|
616
|
-
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
617
|
-
* payload, but `schemaErrors` does, so the client sees the failure
|
|
618
|
-
* after rehydration without an extra channel.
|
|
619
|
-
*/
|
|
620
|
-
HydrationFailed: "atta:hydration-failed",
|
|
621
|
-
/** The supplied path didn't resolve to any node in the schema. */
|
|
622
|
-
PathNotFound: "atta:path-not-found",
|
|
623
|
-
/**
|
|
624
|
-
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
625
|
-
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
626
|
-
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
627
|
-
* aggregate error pipeline can carry the failure alongside ordinary
|
|
628
|
-
* validation errors. The raw factory error remains on
|
|
629
|
-
* `form.hydrateError` for retry UX.
|
|
630
|
-
*/
|
|
631
|
-
ActivationFailed: "atta:activation-failed"
|
|
632
|
-
};
|
|
633
|
-
function makeBlankRequiredError(segments, formKey) {
|
|
634
|
-
return {
|
|
635
|
-
message: "No value supplied",
|
|
636
|
-
path: [...segments],
|
|
637
|
-
formKey,
|
|
638
|
-
code: AttaformErrorCode.NoValueSupplied
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
|
|
642
650
|
const DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS = 0;
|
|
643
651
|
const DEFAULT_HISTORY_MAX_SNAPSHOTS = 128;
|
|
644
652
|
const RESERVED_KEY_PREFIX = "__atta:";
|
|
@@ -1031,7 +1039,7 @@ function aggregateErrorsAt(state, prefix) {
|
|
|
1031
1039
|
const segs = segmentsForPathKey(pathKey);
|
|
1032
1040
|
if (segs === null) continue;
|
|
1033
1041
|
if (!isPathPrefix(prefix, segs)) continue;
|
|
1034
|
-
if (
|
|
1042
|
+
if (segs.length > 0 && !hasAtPath(formValue, segs)) continue;
|
|
1035
1043
|
const ordinal = state.ensurePathOrdinal(pathKey);
|
|
1036
1044
|
const existing = buckets.get(ordinal);
|
|
1037
1045
|
if (existing === void 0) buckets.set(ordinal, [...list]);
|
|
@@ -1150,7 +1158,12 @@ function buildSurfaceProxy(opts) {
|
|
|
1150
1158
|
const proxy = new Proxy(target, {
|
|
1151
1159
|
apply(_, __, args) {
|
|
1152
1160
|
const arg = args[0];
|
|
1153
|
-
if (arg === void 0)
|
|
1161
|
+
if (arg === void 0) {
|
|
1162
|
+
if (segments.length === 0 && opts.resolveRootCall !== void 0) {
|
|
1163
|
+
return opts.resolveRootCall();
|
|
1164
|
+
}
|
|
1165
|
+
return opts.resolveCallTarget(segments);
|
|
1166
|
+
}
|
|
1154
1167
|
const { segments: argSegs } = canonicalizePath(arg);
|
|
1155
1168
|
return opts.resolveCallTarget(argSegs);
|
|
1156
1169
|
},
|
|
@@ -1361,8 +1374,7 @@ function buildErrorsProxy(state) {
|
|
|
1361
1374
|
return merged;
|
|
1362
1375
|
}
|
|
1363
1376
|
const { key } = canonicalizePath(path);
|
|
1364
|
-
const
|
|
1365
|
-
const active = isFormLevel || hasAtPath(state.form.value, path);
|
|
1377
|
+
const active = hasAtPath(state.form.value, path);
|
|
1366
1378
|
collectAtKey(key, active, merged);
|
|
1367
1379
|
return merged;
|
|
1368
1380
|
},
|
|
@@ -1370,37 +1382,42 @@ function buildErrorsProxy(state) {
|
|
|
1370
1382
|
// undefined) IS the terminal.
|
|
1371
1383
|
materializeContainer: (segments) => materializeErrors(state, segments),
|
|
1372
1384
|
// Any path ending in `''` is a meaningful terminal at the proxy
|
|
1373
|
-
// layer
|
|
1374
|
-
// the container-self sentinel that surfaces
|
|
1375
|
-
// and container-targeted marks
|
|
1376
|
-
// '']`
|
|
1377
|
-
// stores. When a schema legitimately owns a `''`
|
|
1378
|
-
// literal leaf and any container-self errors share the
|
|
1379
|
-
// (errors concatenate) — vanishingly rare, accepted as the
|
|
1380
|
-
// ergonomic cost of one unified sentinel convention at
|
|
1381
|
-
// depth.
|
|
1385
|
+
// layer. A bare `['']` is the literal root `''` field; at depth
|
|
1386
|
+
// >= 1 a trailing `''` is the container-self sentinel that surfaces
|
|
1387
|
+
// cross-field refines and container-targeted marks (`resolveLeaf`
|
|
1388
|
+
// translates `[..., '']` to the parent container path before
|
|
1389
|
+
// querying the stores). When a schema legitimately owns a `''`
|
|
1390
|
+
// field, the literal leaf and any container-self errors share the
|
|
1391
|
+
// slot (errors concatenate) — vanishingly rare, accepted as the
|
|
1392
|
+
// ergonomic cost of one unified sentinel convention at depth >= 1.
|
|
1382
1393
|
isTerminalAt: (segs) => segs.length >= 1 && segs[segs.length - 1] === "",
|
|
1383
1394
|
// Call-form aggregates: `form.errors(path)` returns a single
|
|
1384
|
-
// `ValidationError[]` for any depth (leaf or container)
|
|
1395
|
+
// `ValidationError[]` for any depth (leaf or container) via the
|
|
1385
1396
|
// shared `aggregateErrorsAt` helper that `form.meta.errors` and
|
|
1386
|
-
// `form.fields(path).errors` use, so the
|
|
1387
|
-
//
|
|
1388
|
-
//
|
|
1389
|
-
//
|
|
1390
|
-
//
|
|
1391
|
-
//
|
|
1392
|
-
|
|
1397
|
+
// `form.fields(path).errors` also use, so the surfaces never drift.
|
|
1398
|
+
//
|
|
1399
|
+
// The root is the one carve-out. An EXPLICIT root path
|
|
1400
|
+
// (`errors([])`) returns ONLY the global `[]` bucket (root
|
|
1401
|
+
// `.refine()`, hydration failures, `setErrors`) via
|
|
1402
|
+
// `getErrorsForPath`, giving consumers a dedicated channel for
|
|
1403
|
+
// global messages undiluted by field errors. The no-arg `errors()`
|
|
1404
|
+
// instead resolves the FULL aggregate through `resolveRootCall`
|
|
1405
|
+
// below (identical to `meta.errors`).
|
|
1406
|
+
resolveCallTarget: (path) => path.length === 0 ? state.getErrorsForPath([]) : aggregateErrorsAt(state, path),
|
|
1407
|
+
// No-arg `errors()` = the whole-form aggregate, matching
|
|
1408
|
+
// `meta.errors`. Distinct from `errors([])` (global bucket only);
|
|
1409
|
+
// see `resolveCallTarget`.
|
|
1410
|
+
resolveRootCall: () => aggregateErrorsAt(state, []),
|
|
1393
1411
|
// Enumeration unions the live form-data keys at this path with the
|
|
1394
1412
|
// first-child segments drawn from every error store. Without the
|
|
1395
1413
|
// union, `Object.keys(form.errors)` / `{...form.errors}` /
|
|
1396
|
-
// `v-for="(errs, k) in form.errors"` silently
|
|
1397
|
-
//
|
|
1398
|
-
//
|
|
1399
|
-
//
|
|
1400
|
-
//
|
|
1401
|
-
//
|
|
1402
|
-
//
|
|
1403
|
-
// about (`['ghost']`, `['address', 'ghost']`).
|
|
1414
|
+
// `v-for="(errs, k) in form.errors"` would silently drop
|
|
1415
|
+
// **server-only** errors at a key the schema doesn't know about
|
|
1416
|
+
// (`['ghost']`, `['address', 'ghost']`) that the dot / call /
|
|
1417
|
+
// JSON.stringify surfaces already expose. Global errors at the root
|
|
1418
|
+
// `[]` are NOT a child key and never enumerate here (read them via
|
|
1419
|
+
// `errors([])` / `meta.errors`); a literal `''` field enumerates
|
|
1420
|
+
// under the key `''` like any other field.
|
|
1404
1421
|
//
|
|
1405
1422
|
// The union closes that gap so `ownKeys` agrees with the rest of
|
|
1406
1423
|
// the surface. Active-path filter mirrors `resolveLeaf`:
|
|
@@ -1422,10 +1439,6 @@ function errorAwareContainerKeys(state, segments) {
|
|
|
1422
1439
|
const walk = (store, applyActivePathFilter) => {
|
|
1423
1440
|
for (const [pathKey, errors] of store) {
|
|
1424
1441
|
if (errors.length === 0) continue;
|
|
1425
|
-
if (pathKey === FORM_ERRORS_PATH_KEY) {
|
|
1426
|
-
if (segments.length === 0) keys.add("");
|
|
1427
|
-
continue;
|
|
1428
|
-
}
|
|
1429
1442
|
const decoded = segmentsForPathKey(pathKey);
|
|
1430
1443
|
if (decoded === null) continue;
|
|
1431
1444
|
if (decoded.length <= segments.length) continue;
|
|
@@ -1448,31 +1461,25 @@ function materializeErrors(state, containerSegments) {
|
|
|
1448
1461
|
if (errors.length === 0) continue;
|
|
1449
1462
|
const fullPath = segmentsForPathKey(pathKey);
|
|
1450
1463
|
if (fullPath === null) continue;
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
if (fullPath.length < containerSegments.length) continue;
|
|
1454
|
-
for (let i = 0; i < containerSegments.length; i++) {
|
|
1455
|
-
if (fullPath[i] !== containerSegments[i]) continue entries;
|
|
1456
|
-
}
|
|
1457
|
-
} else if (containerSegments.length !== 0) {
|
|
1464
|
+
if (fullPath.length === 0) {
|
|
1465
|
+
if (containerSegments.length === 0) placeAt(tree, [ROOT_PATH_KEY], errors);
|
|
1458
1466
|
continue;
|
|
1459
1467
|
}
|
|
1460
|
-
if (
|
|
1461
|
-
|
|
1468
|
+
if (fullPath.length < containerSegments.length) continue;
|
|
1469
|
+
for (let i = 0; i < containerSegments.length; i++) {
|
|
1470
|
+
if (fullPath[i] !== containerSegments[i]) continue entries;
|
|
1471
|
+
}
|
|
1472
|
+
if (applyActivePathFilter && !hasAtPath(state.form.value, fullPath)) continue;
|
|
1473
|
+
const relativePath = fullPath.slice(containerSegments.length);
|
|
1462
1474
|
let placePath;
|
|
1463
|
-
if (
|
|
1475
|
+
if (relativePath.length === 0) {
|
|
1464
1476
|
placePath = [""];
|
|
1477
|
+
} else if (state.schema.isLeafAtPath(fullPath)) {
|
|
1478
|
+
placePath = relativePath;
|
|
1479
|
+
} else if (state.schema.getSlimPrimitiveTypesAtPath(fullPath).size > 0) {
|
|
1480
|
+
placePath = [...relativePath, ""];
|
|
1465
1481
|
} else {
|
|
1466
|
-
|
|
1467
|
-
if (relativePath.length === 0) {
|
|
1468
|
-
placePath = [""];
|
|
1469
|
-
} else if (state.schema.isLeafAtPath(fullPath)) {
|
|
1470
|
-
placePath = relativePath;
|
|
1471
|
-
} else if (state.schema.getSlimPrimitiveTypesAtPath(fullPath).size > 0) {
|
|
1472
|
-
placePath = [...relativePath, ""];
|
|
1473
|
-
} else {
|
|
1474
|
-
placePath = relativePath;
|
|
1475
|
-
}
|
|
1482
|
+
placePath = relativePath;
|
|
1476
1483
|
}
|
|
1477
1484
|
placeAt(tree, placePath, errors);
|
|
1478
1485
|
}
|
|
@@ -2906,62 +2913,56 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2906
2913
|
return true;
|
|
2907
2914
|
}
|
|
2908
2915
|
const errorsProxy = buildErrorsProxy(state);
|
|
2909
|
-
function
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
console.warn(
|
|
2918
|
-
`[attaform] ${op}: dropped ${dropped} error(s) with non-matching formKey (this form's key is "${String(state.formKey)}"). Errors are scoped to the form that produced them \u2014 pass them to the matching form instance.`
|
|
2919
|
-
);
|
|
2916
|
+
function normalizeErrorInput(item, scope) {
|
|
2917
|
+
if (item instanceof Error) {
|
|
2918
|
+
return {
|
|
2919
|
+
message: item.message.length > 0 ? item.message : "Unknown error",
|
|
2920
|
+
path: scope !== void 0 ? [...scope] : [],
|
|
2921
|
+
formKey: state.formKey,
|
|
2922
|
+
code: AttaformErrorCode.UserError
|
|
2923
|
+
};
|
|
2920
2924
|
}
|
|
2921
|
-
|
|
2925
|
+
const entry = {
|
|
2926
|
+
message: typeof item.message === "string" && item.message.length > 0 ? item.message : "Unknown error",
|
|
2927
|
+
path: scope !== void 0 ? [...scope] : Array.isArray(item.path) ? [...item.path] : [],
|
|
2928
|
+
formKey: state.formKey,
|
|
2929
|
+
code: typeof item.code === "string" && item.code.length > 0 ? item.code : AttaformErrorCode.UserError
|
|
2930
|
+
};
|
|
2931
|
+
if (item.data !== void 0) entry.data = item.data;
|
|
2932
|
+
return entry;
|
|
2922
2933
|
}
|
|
2923
|
-
function
|
|
2924
|
-
const
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2934
|
+
function normalizeErrorInputs(input, scope) {
|
|
2935
|
+
const items = Array.isArray(input) ? input : [input];
|
|
2936
|
+
return items.map((item) => normalizeErrorInput(item, scope));
|
|
2937
|
+
}
|
|
2938
|
+
function flattenUserErrors() {
|
|
2939
|
+
const all = [];
|
|
2940
|
+
for (const errs of state.userErrors.values()) all.push(...errs);
|
|
2941
|
+
return all;
|
|
2942
|
+
}
|
|
2943
|
+
function setErrors(arg1, arg2) {
|
|
2944
|
+
const isScoped = arguments.length >= 2 && (typeof arg1 === "string" || Array.isArray(arg1));
|
|
2945
|
+
if (isScoped) {
|
|
2946
|
+
const { segments, key } = canonicalizePath(arg1);
|
|
2947
|
+
const input2 = arg2;
|
|
2948
|
+
const resolved2 = typeof input2 === "function" ? input2((state.userErrors.get(key) ?? []).slice()) : input2;
|
|
2949
|
+
state.setUserErrorsForPath(segments, normalizeErrorInputs(resolved2, segments));
|
|
2950
|
+
return;
|
|
2928
2951
|
}
|
|
2952
|
+
const input = arg1;
|
|
2953
|
+
const resolved = typeof input === "function" ? input(flattenUserErrors()) : input;
|
|
2954
|
+
state.setAllUserErrors(normalizeErrorInputs(resolved, void 0));
|
|
2929
2955
|
}
|
|
2930
|
-
function
|
|
2931
|
-
state.addUserErrors(filterToOwnFormKey(errors, "addFieldErrors"));
|
|
2932
|
-
}
|
|
2933
|
-
function clearFieldErrors(path) {
|
|
2956
|
+
function clearErrors(path) {
|
|
2934
2957
|
if (path === void 0) {
|
|
2935
|
-
const preserved = state.userErrors.get(FORM_ERRORS_PATH_KEY);
|
|
2936
2958
|
state.clearSchemaErrors();
|
|
2937
2959
|
state.clearUserErrors();
|
|
2938
|
-
if (preserved !== void 0 && preserved.length > 0) {
|
|
2939
|
-
state.userErrors.set(FORM_ERRORS_PATH_KEY, preserved);
|
|
2940
|
-
}
|
|
2941
2960
|
return;
|
|
2942
2961
|
}
|
|
2943
2962
|
const segments = canonicalizePath(path).segments;
|
|
2944
2963
|
state.clearSchemaErrors(segments);
|
|
2945
2964
|
state.clearUserErrors(segments);
|
|
2946
2965
|
}
|
|
2947
|
-
function setFormErrors(errors) {
|
|
2948
|
-
if (errors.length === 0) {
|
|
2949
|
-
state.userErrors.delete(FORM_ERRORS_PATH_KEY);
|
|
2950
|
-
return;
|
|
2951
|
-
}
|
|
2952
|
-
state.userErrors.set(
|
|
2953
|
-
FORM_ERRORS_PATH_KEY,
|
|
2954
|
-
errors.map((e) => ({
|
|
2955
|
-
path: [...FORM_ERRORS_PATH],
|
|
2956
|
-
message: e.message,
|
|
2957
|
-
formKey: state.formKey,
|
|
2958
|
-
code: e.code ?? "atta:form-error"
|
|
2959
|
-
}))
|
|
2960
|
-
);
|
|
2961
|
-
}
|
|
2962
|
-
function clearFormErrors() {
|
|
2963
|
-
state.userErrors.delete(FORM_ERRORS_PATH_KEY);
|
|
2964
|
-
}
|
|
2965
2966
|
const submitting = computed(() => state.submitting.value);
|
|
2966
2967
|
const submissionAttempts = computed(() => state.submissionAttempts.value);
|
|
2967
2968
|
const submitted = computed(() => state.submitted.value);
|
|
@@ -3228,14 +3229,14 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3228
3229
|
}
|
|
3229
3230
|
const EMPTY_FIELD_RECORD = Object.freeze({});
|
|
3230
3231
|
function record(path) {
|
|
3231
|
-
const
|
|
3232
|
+
const segments = path === void 0 ? [] : canonicalizePath(path).segments;
|
|
3232
3233
|
const value = state.getValueAtPath(segments);
|
|
3233
3234
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
3234
3235
|
return EMPTY_FIELD_RECORD;
|
|
3235
3236
|
}
|
|
3236
3237
|
const out = {};
|
|
3237
3238
|
for (const key of Object.keys(value)) {
|
|
3238
|
-
safeAssign(out, key, callTerminal(`${path}.${key}`));
|
|
3239
|
+
safeAssign(out, key, callTerminal(segments.length === 0 ? key : `${path}.${key}`));
|
|
3239
3240
|
}
|
|
3240
3241
|
return Object.freeze(out);
|
|
3241
3242
|
}
|
|
@@ -3292,11 +3293,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3292
3293
|
return errorsProxy;
|
|
3293
3294
|
},
|
|
3294
3295
|
toRef: gated(pathToRef),
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
clearFieldErrors: gated(clearFieldErrors),
|
|
3298
|
-
setFormErrors: gated(setFormErrors),
|
|
3299
|
-
clearFormErrors: gated(clearFormErrors),
|
|
3296
|
+
setErrors: gated(setErrors),
|
|
3297
|
+
clearErrors: gated(clearErrors),
|
|
3300
3298
|
get meta() {
|
|
3301
3299
|
void state.activate();
|
|
3302
3300
|
return formMeta;
|
|
@@ -4814,25 +4812,14 @@ function createFormStore(options) {
|
|
|
4814
4812
|
function getValueAtPath(path) {
|
|
4815
4813
|
return getAtPath(form.value, path);
|
|
4816
4814
|
}
|
|
4817
|
-
function rerouteFormLevelEntry(err) {
|
|
4818
|
-
if (err.path.length === 0) {
|
|
4819
|
-
return { ...err, path: [...FORM_ERRORS_PATH] };
|
|
4820
|
-
}
|
|
4821
|
-
return err;
|
|
4822
|
-
}
|
|
4823
|
-
function pathKeyForEntry(err) {
|
|
4824
|
-
if (err.path.length === 0) return FORM_ERRORS_PATH_KEY;
|
|
4825
|
-
return canonicalizePath(err.path).key;
|
|
4826
|
-
}
|
|
4827
4815
|
function appendErrorsTo(map, entries) {
|
|
4828
4816
|
for (const raw of entries) {
|
|
4829
|
-
const
|
|
4830
|
-
const key = pathKeyForEntry(err);
|
|
4817
|
+
const { key } = canonicalizePath(raw.path);
|
|
4831
4818
|
const current = map.get(key);
|
|
4832
4819
|
if (current === void 0) {
|
|
4833
|
-
map.set(key, [
|
|
4820
|
+
map.set(key, [raw]);
|
|
4834
4821
|
} else {
|
|
4835
|
-
map.set(key, [...current,
|
|
4822
|
+
map.set(key, [...current, raw]);
|
|
4836
4823
|
}
|
|
4837
4824
|
}
|
|
4838
4825
|
}
|
|
@@ -4857,14 +4844,13 @@ function createFormStore(options) {
|
|
|
4857
4844
|
schemaErrors.set(key, [...entries]);
|
|
4858
4845
|
}
|
|
4859
4846
|
function applySchemaErrorsForSubtree(path, entries) {
|
|
4860
|
-
const parentKey =
|
|
4847
|
+
const parentKey = canonicalizePath(path).key;
|
|
4861
4848
|
const grouped = /* @__PURE__ */ new Map();
|
|
4862
4849
|
for (const raw of entries) {
|
|
4863
|
-
const
|
|
4864
|
-
const key = pathKeyForEntry(err);
|
|
4850
|
+
const { key } = canonicalizePath(raw.path);
|
|
4865
4851
|
const list = grouped.get(key);
|
|
4866
|
-
if (list === void 0) grouped.set(key, [
|
|
4867
|
-
else list.push(
|
|
4852
|
+
if (list === void 0) grouped.set(key, [raw]);
|
|
4853
|
+
else list.push(raw);
|
|
4868
4854
|
}
|
|
4869
4855
|
if (!grouped.has(parentKey)) schemaErrors.delete(parentKey);
|
|
4870
4856
|
for (const existingKey of [...schemaErrors.keys()]) {
|
|
@@ -4886,8 +4872,13 @@ function createFormStore(options) {
|
|
|
4886
4872
|
function setAllUserErrors(entries) {
|
|
4887
4873
|
replaceErrorsIn(userErrors, entries);
|
|
4888
4874
|
}
|
|
4889
|
-
function
|
|
4890
|
-
|
|
4875
|
+
function setUserErrorsForPath(path, entries) {
|
|
4876
|
+
const { key } = canonicalizePath(path);
|
|
4877
|
+
if (entries.length === 0) {
|
|
4878
|
+
userErrors.delete(key);
|
|
4879
|
+
return;
|
|
4880
|
+
}
|
|
4881
|
+
userErrors.set(key, [...entries]);
|
|
4891
4882
|
}
|
|
4892
4883
|
function clearUserErrors(path) {
|
|
4893
4884
|
clearErrorsIn(userErrors, path);
|
|
@@ -5081,25 +5072,25 @@ function createFormStore(options) {
|
|
|
5081
5072
|
}
|
|
5082
5073
|
}
|
|
5083
5074
|
function clearHydrationFailedEntry() {
|
|
5084
|
-
const existing = schemaErrors.get(
|
|
5075
|
+
const existing = schemaErrors.get(ROOT_PATH_KEY);
|
|
5085
5076
|
if (existing === void 0) return;
|
|
5086
5077
|
const filtered = existing.filter((e) => e.code !== AttaformErrorCode.HydrationFailed);
|
|
5087
5078
|
if (filtered.length === 0) {
|
|
5088
|
-
schemaErrors.delete(
|
|
5079
|
+
schemaErrors.delete(ROOT_PATH_KEY);
|
|
5089
5080
|
} else {
|
|
5090
|
-
schemaErrors.set(
|
|
5081
|
+
schemaErrors.set(ROOT_PATH_KEY, filtered);
|
|
5091
5082
|
}
|
|
5092
5083
|
}
|
|
5093
5084
|
function appendHydrationFailedEntry(error) {
|
|
5094
5085
|
const message = error instanceof Error ? error.message : typeof error === "string" ? error : "Hydration failed";
|
|
5095
5086
|
const entry = {
|
|
5096
5087
|
message,
|
|
5097
|
-
path: [...
|
|
5088
|
+
path: [...ROOT_PATH],
|
|
5098
5089
|
formKey,
|
|
5099
5090
|
code: AttaformErrorCode.HydrationFailed
|
|
5100
5091
|
};
|
|
5101
|
-
const existing = schemaErrors.get(
|
|
5102
|
-
schemaErrors.set(
|
|
5092
|
+
const existing = schemaErrors.get(ROOT_PATH_KEY) ?? [];
|
|
5093
|
+
schemaErrors.set(ROOT_PATH_KEY, [...existing, entry]);
|
|
5103
5094
|
return entry;
|
|
5104
5095
|
}
|
|
5105
5096
|
function reset(nextDefaultValues) {
|
|
@@ -5332,7 +5323,7 @@ function createFormStore(options) {
|
|
|
5332
5323
|
clearSchemaErrors,
|
|
5333
5324
|
applySchemaErrorsForSubtree,
|
|
5334
5325
|
setAllUserErrors,
|
|
5335
|
-
|
|
5326
|
+
setUserErrorsForPath,
|
|
5336
5327
|
clearUserErrors,
|
|
5337
5328
|
getErrorsForPath,
|
|
5338
5329
|
ensurePathOrdinal,
|
|
@@ -5409,12 +5400,38 @@ function captureErrorEntries(map) {
|
|
|
5409
5400
|
for (const [k, v] of map) out.push([k, [...v]]);
|
|
5410
5401
|
return out;
|
|
5411
5402
|
}
|
|
5403
|
+
function dataEqual(a, b) {
|
|
5404
|
+
if (a === b) return true;
|
|
5405
|
+
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
5406
|
+
if (typeof a !== typeof b) return false;
|
|
5407
|
+
if (Array.isArray(a)) {
|
|
5408
|
+
if (!Array.isArray(b) || a.length !== b.length) return false;
|
|
5409
|
+
for (let i = 0; i < a.length; i++) {
|
|
5410
|
+
if (!dataEqual(a[i], b[i])) return false;
|
|
5411
|
+
}
|
|
5412
|
+
return true;
|
|
5413
|
+
}
|
|
5414
|
+
if (Array.isArray(b)) return false;
|
|
5415
|
+
if (typeof a === "object") {
|
|
5416
|
+
const ao = a;
|
|
5417
|
+
const bo = b;
|
|
5418
|
+
const keys = Object.keys(ao);
|
|
5419
|
+
if (keys.length !== Object.keys(bo).length) return false;
|
|
5420
|
+
for (const k of keys) {
|
|
5421
|
+
if (!Object.prototype.hasOwnProperty.call(bo, k)) return false;
|
|
5422
|
+
if (!dataEqual(ao[k], bo[k])) return false;
|
|
5423
|
+
}
|
|
5424
|
+
return true;
|
|
5425
|
+
}
|
|
5426
|
+
return false;
|
|
5427
|
+
}
|
|
5412
5428
|
function errorFieldsEqual(av, bvi) {
|
|
5413
5429
|
if (av === bvi) return true;
|
|
5414
5430
|
if (av.message !== bvi.message) return false;
|
|
5415
5431
|
if (av.code !== bvi.code) return false;
|
|
5416
5432
|
if (av.formKey !== bvi.formKey) return false;
|
|
5417
|
-
|
|
5433
|
+
if (av.path !== bvi.path && !pathsEqual(av.path, bvi.path)) return false;
|
|
5434
|
+
return dataEqual(av.data, bvi.data);
|
|
5418
5435
|
}
|
|
5419
5436
|
function errorsEqual(a, b) {
|
|
5420
5437
|
if (a.length !== b.length) return false;
|
|
@@ -7010,5 +7027,5 @@ function warnIfAmbientWizardProviderHadDuplicates() {
|
|
|
7010
7027
|
}
|
|
7011
7028
|
}
|
|
7012
7029
|
|
|
7013
|
-
export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, defaultCoercionRules as e, defaultDisplayState as f, defineCoercion as g, useAbstractForm as h, injectForm as i, isPlainRecord as j, safeAssign as k, lazy as l, makeDefaultDisplayState as m,
|
|
7014
|
-
//# sourceMappingURL=attaform.
|
|
7030
|
+
export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, defaultCoercionRules as e, defaultDisplayState as f, defineCoercion as g, useAbstractForm as h, injectForm as i, isPlainRecord as j, safeAssign as k, lazy as l, makeDefaultDisplayState as m, slimKindOf as n, humanize as o, getAtPath as p, setAtPath as q, safeOwnRead as s, unset as u };
|
|
7031
|
+
//# sourceMappingURL=attaform.CuBdtfbe.mjs.map
|