attaform 0.16.3 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/devtools.cjs +19 -12
  3. package/dist/chunks/devtools.cjs.map +1 -1
  4. package/dist/chunks/devtools.mjs +19 -12
  5. package/dist/chunks/devtools.mjs.map +1 -1
  6. package/dist/chunks/indexeddb.cjs +1 -1
  7. package/dist/chunks/indexeddb.mjs +1 -1
  8. package/dist/chunks/local-storage.cjs +1 -1
  9. package/dist/chunks/local-storage.mjs +1 -1
  10. package/dist/chunks/session-storage.cjs +1 -1
  11. package/dist/chunks/session-storage.mjs +1 -1
  12. package/dist/index.cjs +27 -7
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +80 -8
  15. package/dist/index.d.mts +80 -8
  16. package/dist/index.d.ts +80 -8
  17. package/dist/index.mjs +28 -9
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/nuxt.d.cts +1 -1
  20. package/dist/nuxt.d.mts +1 -1
  21. package/dist/nuxt.d.ts +1 -1
  22. package/dist/runtime/plugins/attaform.cjs +3 -3
  23. package/dist/runtime/plugins/attaform.cjs.map +1 -1
  24. package/dist/runtime/plugins/attaform.mjs +3 -3
  25. package/dist/runtime/plugins/attaform.mjs.map +1 -1
  26. package/dist/shared/{attaform.KrNw10aW.cjs → attaform.0Wg7UEeX.cjs} +60 -20
  27. package/dist/shared/attaform.0Wg7UEeX.cjs.map +1 -0
  28. package/dist/shared/attaform.AOgGyRoI.d.cts +65 -0
  29. package/dist/shared/{attaform.lFNwBcA3.d.ts → attaform.B0zue7zt.d.ts} +1 -1
  30. package/dist/shared/{attaform.c_NzdRyc.cjs → attaform.BBM2muQ9.cjs} +7 -3
  31. package/dist/shared/attaform.BBM2muQ9.cjs.map +1 -0
  32. package/dist/shared/{attaform.C9Ph2SMx.cjs → attaform.BFumZXY2.cjs} +1514 -391
  33. package/dist/shared/attaform.BFumZXY2.cjs.map +1 -0
  34. package/dist/shared/attaform.BQ-iGGWd.d.mts +65 -0
  35. package/dist/shared/{attaform.DILbdvfo.mjs → attaform.BT55rDNN.mjs} +1514 -393
  36. package/dist/shared/attaform.BT55rDNN.mjs.map +1 -0
  37. package/dist/shared/{attaform._EqYNPYF.d.mts → attaform.BYbsV2Wv.d.cts} +738 -138
  38. package/dist/shared/{attaform._EqYNPYF.d.ts → attaform.BYbsV2Wv.d.mts} +738 -138
  39. package/dist/shared/{attaform._EqYNPYF.d.cts → attaform.BYbsV2Wv.d.ts} +738 -138
  40. package/dist/shared/{attaform.DGuGGNg9.cjs → attaform.C6_zOf8x.cjs} +232 -113
  41. package/dist/shared/attaform.C6_zOf8x.cjs.map +1 -0
  42. package/dist/shared/{attaform.CJttVxRj.cjs → attaform.C8LVFVVe.cjs} +2 -2
  43. package/dist/shared/{attaform.CJttVxRj.cjs.map → attaform.C8LVFVVe.cjs.map} +1 -1
  44. package/dist/shared/{attaform.BfMxsfmE.mjs → attaform.CIEQgJnM.mjs} +143 -78
  45. package/dist/shared/attaform.CIEQgJnM.mjs.map +1 -0
  46. package/dist/shared/attaform.CX9v2M8k.d.ts +65 -0
  47. package/dist/shared/{attaform.XYOMTvuO.mjs → attaform.Cj0pCNVn.mjs} +232 -113
  48. package/dist/shared/attaform.Cj0pCNVn.mjs.map +1 -0
  49. package/dist/shared/{attaform.DLnKT7wk.d.cts → attaform.ClfCi1i2.d.mts} +1 -1
  50. package/dist/shared/{attaform.CFA6y0KF.mjs → attaform.D6Q5ZP8L.mjs} +60 -20
  51. package/dist/shared/attaform.D6Q5ZP8L.mjs.map +1 -0
  52. package/dist/shared/{attaform.Bls_kFR6.d.mts → attaform.D7lomopc.d.cts} +1 -1
  53. package/dist/shared/{attaform.rIRYSUI1.cjs → attaform.Dee2rU1P.cjs} +145 -77
  54. package/dist/shared/attaform.Dee2rU1P.cjs.map +1 -0
  55. package/dist/shared/{attaform.CINUMjPq.mjs → attaform.Vo-Kft0t.mjs} +2 -2
  56. package/dist/shared/{attaform.CINUMjPq.mjs.map → attaform.Vo-Kft0t.mjs.map} +1 -1
  57. package/dist/shared/{attaform.jrxE_xZw.mjs → attaform.h1sq3BFu.mjs} +6 -4
  58. package/dist/shared/attaform.h1sq3BFu.mjs.map +1 -0
  59. package/dist/zod-v3.cjs +3 -3
  60. package/dist/zod-v3.d.cts +5 -5
  61. package/dist/zod-v3.d.mts +5 -5
  62. package/dist/zod-v3.d.ts +5 -5
  63. package/dist/zod-v3.mjs +3 -3
  64. package/dist/zod-v4.cjs +3 -3
  65. package/dist/zod-v4.d.cts +16 -42
  66. package/dist/zod-v4.d.mts +16 -42
  67. package/dist/zod-v4.d.ts +16 -42
  68. package/dist/zod-v4.mjs +3 -3
  69. package/dist/zod.cjs +4 -4
  70. package/dist/zod.cjs.map +1 -1
  71. package/dist/zod.d.cts +6 -5
  72. package/dist/zod.d.mts +6 -5
  73. package/dist/zod.d.ts +6 -5
  74. package/dist/zod.mjs +5 -5
  75. package/dist/zod.mjs.map +1 -1
  76. package/package.json +3 -8
  77. package/dist/shared/attaform.BfMxsfmE.mjs.map +0 -1
  78. package/dist/shared/attaform.C9Ph2SMx.cjs.map +0 -1
  79. package/dist/shared/attaform.CFA6y0KF.mjs.map +0 -1
  80. package/dist/shared/attaform.DGuGGNg9.cjs.map +0 -1
  81. package/dist/shared/attaform.DILbdvfo.mjs.map +0 -1
  82. package/dist/shared/attaform.KrNw10aW.cjs.map +0 -1
  83. package/dist/shared/attaform.XYOMTvuO.mjs.map +0 -1
  84. package/dist/shared/attaform.c_NzdRyc.cjs.map +0 -1
  85. package/dist/shared/attaform.jrxE_xZw.mjs.map +0 -1
  86. package/dist/shared/attaform.rIRYSUI1.cjs.map +0 -1
@@ -71,7 +71,7 @@ function formatAnonPersistMessage(opts) {
71
71
  }
72
72
 
73
73
  function detectSSR(options = {}) {
74
- if (options.override !== void 0) return options.override;
74
+ if (options.ssr !== void 0) return options.ssr;
75
75
  return typeof window === "undefined" && typeof document === "undefined";
76
76
  }
77
77
 
@@ -381,91 +381,138 @@ function createPersistOptInRegistry() {
381
381
  };
382
382
  }
383
383
 
384
- const SENSITIVE_NAME_PATTERNS = [
385
- // Passwords and PIN-like
386
- /password/i,
387
- /passwd/i,
388
- /passwords/i,
389
- /\bpwd\b/i,
390
- /\bpin\b/i,
384
+ const DEFAULT_SENSITIVE_NAMES = Object.freeze([
385
+ // Passwords + PIN-like
386
+ "password",
387
+ "passwd",
388
+ "pwd",
389
+ "pin",
391
390
  // Card / payment
392
- /\bcvv\b/i,
393
- /\bcvc\b/i,
394
- /card[_\s-]?(?:number|num)/i,
395
- /\bcard\b/i,
396
- /\biban\b/i,
397
- /routing[_\s-]?number/i,
398
- /account[_\s-]?number/i,
391
+ "cvv",
392
+ "cvc",
393
+ "card_number",
394
+ "card_num",
395
+ "card",
396
+ "iban",
397
+ "routing_number",
398
+ "account_number",
399
399
  // Government / identity
400
- /\bssn\b/i,
401
- /social[_\s-]?security/i,
402
- /\bdob\b/i,
403
- /date[_\s-]?of[_\s-]?birth/i,
404
- /passport/i,
405
- /driver[_\s-]?license/i,
406
- // Tax IDs (US + international common variants)
407
- /\btin\b/i,
408
- /\bein\b/i,
409
- /\bitin\b/i,
410
- /tax[_\s-]?id/i,
411
- // Tokens, secrets, API/auth credentials
412
- /\btoken\b/i,
413
- /\btokens\b/i,
414
- /secret/i,
415
- /secrets/i,
416
- /api[_\s-]?key/i,
417
- /api[_\s-]?secret/i,
418
- /api[_\s-]?token/i,
419
- /private[_\s-]?key/i,
420
- /\bbearer\b/i,
421
- /\boauth\b/i,
422
- /auth[_\s-]?token/i,
423
- /access[_\s-]?token/i,
424
- /refresh[_\s-]?token/i,
425
- /session[_\s-]?(?:id|key|token)/i,
400
+ "ssn",
401
+ "social_security",
402
+ "dob",
403
+ "date_of_birth",
404
+ "passport",
405
+ "driver_license",
406
+ // Tax IDs
407
+ "tin",
408
+ "ein",
409
+ "itin",
410
+ "tax_id",
411
+ // Tokens / secrets / API auth
412
+ "token",
413
+ "tokens",
414
+ "secret",
415
+ "secrets",
416
+ "api_key",
417
+ "api_secret",
418
+ "api_token",
419
+ "private_key",
420
+ "bearer",
421
+ "oauth",
422
+ "auth_token",
423
+ "access_token",
424
+ "refresh_token",
425
+ "session_id",
426
+ "session_key",
427
+ "session_token",
426
428
  // MFA / OTP
427
- /\botp\b/i,
428
- /one[_\s-]?time[_\s-]?(?:password|code)/i,
429
- /mfa[_\s-]?(?:secret|seed|code|token)/i,
430
- /two[_\s-]?factor[_\s-]?(?:code|token)/i,
431
- /\b2fa[_\s-]?(?:code|token)?\b/i,
432
- /recovery[_\s-]?code/i,
433
- /backup[_\s-]?code/i
434
- ];
435
- function segmentMatchesSensitive(segment) {
436
- if (typeof segment !== "string") return false;
437
- for (const pattern of SENSITIVE_NAME_PATTERNS) {
438
- if (pattern.test(segment)) return true;
429
+ "otp",
430
+ "one_time_password",
431
+ "one_time_code",
432
+ "mfa_secret",
433
+ "mfa_seed",
434
+ "mfa_code",
435
+ "mfa_token",
436
+ "two_factor_code",
437
+ "two_factor_token",
438
+ "2fa",
439
+ "2fa_code",
440
+ "2fa_token",
441
+ "recovery_code",
442
+ "backup_code"
443
+ ]);
444
+ const WORD_BOUNDARY_THRESHOLD = 5;
445
+ function escapeRegex(s) {
446
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
447
+ }
448
+ function nameToRegex(name) {
449
+ const parts = name.split(/[_\s-]/).filter((p) => p.length > 0);
450
+ if (parts.length === 0) {
451
+ return /(?!)/;
439
452
  }
440
- return false;
441
- }
442
- function isSensitivePath(path) {
443
- if (typeof path !== "string") {
444
- for (const segment of path) {
445
- if (segmentMatchesSensitive(segment)) return true;
453
+ const escaped = parts.map(escapeRegex).join("[_\\s-]?");
454
+ const compactLength = parts.reduce((sum, p) => sum + p.length, 0);
455
+ const useBoundary = compactLength <= WORD_BOUNDARY_THRESHOLD;
456
+ const source = useBoundary ? `\\b${escaped}\\b` : escaped;
457
+ return new RegExp(source, "i");
458
+ }
459
+ function namesToPatterns(names) {
460
+ const patterns = [];
461
+ for (const name of names) {
462
+ if (typeof name !== "string" || name.length === 0) continue;
463
+ patterns.push(nameToRegex(name));
464
+ }
465
+ return patterns;
466
+ }
467
+ const DEFAULT_PATTERNS = namesToPatterns(DEFAULT_SENSITIVE_NAMES);
468
+ function createSegmentMatchesSensitive(names = DEFAULT_SENSITIVE_NAMES) {
469
+ const patterns = names === DEFAULT_SENSITIVE_NAMES ? DEFAULT_PATTERNS : namesToPatterns(names);
470
+ return (segment) => {
471
+ if (typeof segment !== "string") return false;
472
+ for (const p of patterns) {
473
+ if (p.test(segment)) return true;
446
474
  }
447
475
  return false;
448
- }
449
- if (path.startsWith("[")) {
450
- try {
451
- const parsed = JSON.parse(path);
452
- if (Array.isArray(parsed)) {
453
- for (const segment of parsed) {
454
- if (segmentMatchesSensitive(segment)) return true;
476
+ };
477
+ }
478
+ function createIsSensitivePath(names = DEFAULT_SENSITIVE_NAMES) {
479
+ const segmentMatches = createSegmentMatchesSensitive(names);
480
+ return (path) => {
481
+ if (typeof path !== "string") {
482
+ for (const segment of path) {
483
+ if (segmentMatches(segment)) return true;
484
+ }
485
+ return false;
486
+ }
487
+ if (path.startsWith("[")) {
488
+ try {
489
+ const parsed = JSON.parse(path);
490
+ if (Array.isArray(parsed)) {
491
+ for (const segment of parsed) {
492
+ if (segmentMatches(segment)) return true;
493
+ }
494
+ return false;
455
495
  }
456
- return false;
496
+ } catch {
457
497
  }
458
- } catch {
459
498
  }
460
- }
461
- for (const segment of path.split(".")) {
462
- if (segmentMatchesSensitive(segment)) return true;
463
- }
464
- return false;
499
+ for (const segment of path.split(".")) {
500
+ if (segmentMatches(segment)) return true;
501
+ }
502
+ return false;
503
+ };
465
504
  }
466
- function enforceSensitiveCheck(path, acknowledged) {
505
+ const defaultSegmentMatches = createSegmentMatchesSensitive();
506
+ const defaultIsSensitivePath = createIsSensitivePath();
507
+ function segmentMatchesSensitive(segment) {
508
+ return defaultSegmentMatches(segment);
509
+ }
510
+ function isSensitivePath(path) {
511
+ return defaultIsSensitivePath(path);
512
+ }
513
+ function enforceSensitiveCheck(path, acknowledged, isSensitive = defaultIsSensitivePath) {
467
514
  if (acknowledged) return;
468
- if (!isSensitivePath(path)) return;
515
+ if (!isSensitive(path)) return;
469
516
  throw new SensitivePersistFieldError(path);
470
517
  }
471
518
 
@@ -607,10 +654,25 @@ function syncPersistOptIn(el, value, oldValue) {
607
654
  }
608
655
  if (wantsOptIn) {
609
656
  const v = value;
610
- enforceSensitiveCheck(v.path, v.acknowledgeSensitive);
657
+ enforceSensitiveCheck(v.path, v.acknowledgeSensitive, v.isSensitivePath);
611
658
  v.persistOptIns.add(elementId, v.path);
612
659
  }
613
660
  }
661
+ function syncMultiTabOptOut(value, oldValue) {
662
+ const wasOptedOut = isRegisterValue(oldValue) && oldValue.unmarkNoSync !== void 0;
663
+ const wantsOptOut = isRegisterValue(value) && value.markNoSync !== void 0;
664
+ if (!wasOptedOut && !wantsOptOut) return;
665
+ if (wasOptedOut) {
666
+ const old = oldValue;
667
+ const samePath = wantsOptOut && value.path === old.path;
668
+ if (!samePath) old.unmarkNoSync?.();
669
+ }
670
+ if (wantsOptOut) {
671
+ const v = value;
672
+ const samePathOld = wasOptedOut && oldValue.path === v.path;
673
+ if (!samePathOld) v.markNoSync?.();
674
+ }
675
+ }
614
676
  function syncElementRegistration(el, value, oldValue) {
615
677
  const wasRegistered = isRegisterValue(oldValue);
616
678
  const isRegistered = isRegisterValue(value);
@@ -1059,6 +1121,7 @@ const warnedUnsupportedElements = __DEV__ ? /* @__PURE__ */ new WeakSet() : null
1059
1121
  const vRegisterDynamic = {
1060
1122
  created(el, binding, vnode) {
1061
1123
  syncPersistOptIn(el, binding.value, void 0);
1124
+ syncMultiTabOptOut(binding.value, void 0);
1062
1125
  callModelHook(el, binding, vnode, null, "created");
1063
1126
  if (__DEV__ && warnedUnsupportedElements !== null && !SUPPORTED_TAGS.has(el.tagName) && !warnedUnsupportedElements.has(el)) {
1064
1127
  void nextTick(() => {
@@ -1080,6 +1143,7 @@ const vRegisterDynamic = {
1080
1143
  },
1081
1144
  beforeUpdate(el, binding, vnode, prevVNode) {
1082
1145
  syncPersistOptIn(el, binding.value, binding.oldValue);
1146
+ syncMultiTabOptOut(binding.value, binding.oldValue);
1083
1147
  syncElementRegistration(el, binding.value, binding.oldValue);
1084
1148
  callModelHook(el, binding, vnode, prevVNode, "beforeUpdate");
1085
1149
  },
@@ -1090,6 +1154,7 @@ const vRegisterDynamic = {
1090
1154
  removeTrackedListeners(el);
1091
1155
  if (isRegisterValue(value)) {
1092
1156
  value.persistOptIns.removeAllFor(getOrAssignElementId(el));
1157
+ value.unmarkNoSync?.();
1093
1158
  }
1094
1159
  if (!isRegisterValue(value)) return;
1095
1160
  value.deregisterElement(el);
@@ -1165,5 +1230,5 @@ function createAttaform(options = {}) {
1165
1230
  return plugin;
1166
1231
  }
1167
1232
 
1168
- export { AnonPersistError as A, InvalidPathError as I, OutsideSetupError as O, RegistryNotInstalledError as R, SensitivePersistFieldError as S, __DEV__ as _, AttaformError as a, InvalidUseFormConfigError as b, createAttaform as c, ReservedFormKeyError as d, SubmitErrorHandlerError as e, assignKey as f, getRegistryFromApp as g, createRegistry as h, isSensitivePath as i, isRegisterValue as j, kAttaformRegistry as k, useRegistry as l, captureUserCallSite as m, enforceSensitiveCheck as n, createPersistOptInRegistry as o, ensureAttaformInstalled as p, kFormContext as q, kFormInstanceId as r, segmentMatchesSensitive as s, useRegister as u, vRegister as v };
1169
- //# sourceMappingURL=attaform.BfMxsfmE.mjs.map
1233
+ export { AnonPersistError as A, DEFAULT_SENSITIVE_NAMES as D, InvalidPathError as I, OutsideSetupError as O, RegistryNotInstalledError as R, SensitivePersistFieldError as S, __DEV__ as _, AttaformError as a, InvalidUseFormConfigError as b, createAttaform as c, ReservedFormKeyError as d, SubmitErrorHandlerError as e, assignKey as f, getRegistryFromApp as g, createRegistry as h, isRegisterValue as i, useRegistry as j, kAttaformRegistry as k, captureUserCallSite as l, enforceSensitiveCheck as m, isSensitivePath as n, createPersistOptInRegistry as o, ensureAttaformInstalled as p, kFormContext as q, kFormInstanceId as r, segmentMatchesSensitive as s, createIsSensitivePath as t, useRegister as u, vRegister as v, createSegmentMatchesSensitive as w };
1234
+ //# sourceMappingURL=attaform.CIEQgJnM.mjs.map