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
@@ -73,7 +73,7 @@ function formatAnonPersistMessage(opts) {
73
73
  }
74
74
 
75
75
  function detectSSR(options = {}) {
76
- if (options.override !== void 0) return options.override;
76
+ if (options.ssr !== void 0) return options.ssr;
77
77
  return typeof window === "undefined" && typeof document === "undefined";
78
78
  }
79
79
 
@@ -383,91 +383,138 @@ function createPersistOptInRegistry() {
383
383
  };
384
384
  }
385
385
 
386
- const SENSITIVE_NAME_PATTERNS = [
387
- // Passwords and PIN-like
388
- /password/i,
389
- /passwd/i,
390
- /passwords/i,
391
- /\bpwd\b/i,
392
- /\bpin\b/i,
386
+ const DEFAULT_SENSITIVE_NAMES = Object.freeze([
387
+ // Passwords + PIN-like
388
+ "password",
389
+ "passwd",
390
+ "pwd",
391
+ "pin",
393
392
  // Card / payment
394
- /\bcvv\b/i,
395
- /\bcvc\b/i,
396
- /card[_\s-]?(?:number|num)/i,
397
- /\bcard\b/i,
398
- /\biban\b/i,
399
- /routing[_\s-]?number/i,
400
- /account[_\s-]?number/i,
393
+ "cvv",
394
+ "cvc",
395
+ "card_number",
396
+ "card_num",
397
+ "card",
398
+ "iban",
399
+ "routing_number",
400
+ "account_number",
401
401
  // Government / identity
402
- /\bssn\b/i,
403
- /social[_\s-]?security/i,
404
- /\bdob\b/i,
405
- /date[_\s-]?of[_\s-]?birth/i,
406
- /passport/i,
407
- /driver[_\s-]?license/i,
408
- // Tax IDs (US + international common variants)
409
- /\btin\b/i,
410
- /\bein\b/i,
411
- /\bitin\b/i,
412
- /tax[_\s-]?id/i,
413
- // Tokens, secrets, API/auth credentials
414
- /\btoken\b/i,
415
- /\btokens\b/i,
416
- /secret/i,
417
- /secrets/i,
418
- /api[_\s-]?key/i,
419
- /api[_\s-]?secret/i,
420
- /api[_\s-]?token/i,
421
- /private[_\s-]?key/i,
422
- /\bbearer\b/i,
423
- /\boauth\b/i,
424
- /auth[_\s-]?token/i,
425
- /access[_\s-]?token/i,
426
- /refresh[_\s-]?token/i,
427
- /session[_\s-]?(?:id|key|token)/i,
402
+ "ssn",
403
+ "social_security",
404
+ "dob",
405
+ "date_of_birth",
406
+ "passport",
407
+ "driver_license",
408
+ // Tax IDs
409
+ "tin",
410
+ "ein",
411
+ "itin",
412
+ "tax_id",
413
+ // Tokens / secrets / API auth
414
+ "token",
415
+ "tokens",
416
+ "secret",
417
+ "secrets",
418
+ "api_key",
419
+ "api_secret",
420
+ "api_token",
421
+ "private_key",
422
+ "bearer",
423
+ "oauth",
424
+ "auth_token",
425
+ "access_token",
426
+ "refresh_token",
427
+ "session_id",
428
+ "session_key",
429
+ "session_token",
428
430
  // MFA / OTP
429
- /\botp\b/i,
430
- /one[_\s-]?time[_\s-]?(?:password|code)/i,
431
- /mfa[_\s-]?(?:secret|seed|code|token)/i,
432
- /two[_\s-]?factor[_\s-]?(?:code|token)/i,
433
- /\b2fa[_\s-]?(?:code|token)?\b/i,
434
- /recovery[_\s-]?code/i,
435
- /backup[_\s-]?code/i
436
- ];
437
- function segmentMatchesSensitive(segment) {
438
- if (typeof segment !== "string") return false;
439
- for (const pattern of SENSITIVE_NAME_PATTERNS) {
440
- if (pattern.test(segment)) return true;
431
+ "otp",
432
+ "one_time_password",
433
+ "one_time_code",
434
+ "mfa_secret",
435
+ "mfa_seed",
436
+ "mfa_code",
437
+ "mfa_token",
438
+ "two_factor_code",
439
+ "two_factor_token",
440
+ "2fa",
441
+ "2fa_code",
442
+ "2fa_token",
443
+ "recovery_code",
444
+ "backup_code"
445
+ ]);
446
+ const WORD_BOUNDARY_THRESHOLD = 5;
447
+ function escapeRegex(s) {
448
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
449
+ }
450
+ function nameToRegex(name) {
451
+ const parts = name.split(/[_\s-]/).filter((p) => p.length > 0);
452
+ if (parts.length === 0) {
453
+ return /(?!)/;
441
454
  }
442
- return false;
443
- }
444
- function isSensitivePath(path) {
445
- if (typeof path !== "string") {
446
- for (const segment of path) {
447
- if (segmentMatchesSensitive(segment)) return true;
455
+ const escaped = parts.map(escapeRegex).join("[_\\s-]?");
456
+ const compactLength = parts.reduce((sum, p) => sum + p.length, 0);
457
+ const useBoundary = compactLength <= WORD_BOUNDARY_THRESHOLD;
458
+ const source = useBoundary ? `\\b${escaped}\\b` : escaped;
459
+ return new RegExp(source, "i");
460
+ }
461
+ function namesToPatterns(names) {
462
+ const patterns = [];
463
+ for (const name of names) {
464
+ if (typeof name !== "string" || name.length === 0) continue;
465
+ patterns.push(nameToRegex(name));
466
+ }
467
+ return patterns;
468
+ }
469
+ const DEFAULT_PATTERNS = namesToPatterns(DEFAULT_SENSITIVE_NAMES);
470
+ function createSegmentMatchesSensitive(names = DEFAULT_SENSITIVE_NAMES) {
471
+ const patterns = names === DEFAULT_SENSITIVE_NAMES ? DEFAULT_PATTERNS : namesToPatterns(names);
472
+ return (segment) => {
473
+ if (typeof segment !== "string") return false;
474
+ for (const p of patterns) {
475
+ if (p.test(segment)) return true;
448
476
  }
449
477
  return false;
450
- }
451
- if (path.startsWith("[")) {
452
- try {
453
- const parsed = JSON.parse(path);
454
- if (Array.isArray(parsed)) {
455
- for (const segment of parsed) {
456
- if (segmentMatchesSensitive(segment)) return true;
478
+ };
479
+ }
480
+ function createIsSensitivePath(names = DEFAULT_SENSITIVE_NAMES) {
481
+ const segmentMatches = createSegmentMatchesSensitive(names);
482
+ return (path) => {
483
+ if (typeof path !== "string") {
484
+ for (const segment of path) {
485
+ if (segmentMatches(segment)) return true;
486
+ }
487
+ return false;
488
+ }
489
+ if (path.startsWith("[")) {
490
+ try {
491
+ const parsed = JSON.parse(path);
492
+ if (Array.isArray(parsed)) {
493
+ for (const segment of parsed) {
494
+ if (segmentMatches(segment)) return true;
495
+ }
496
+ return false;
457
497
  }
458
- return false;
498
+ } catch {
459
499
  }
460
- } catch {
461
500
  }
462
- }
463
- for (const segment of path.split(".")) {
464
- if (segmentMatchesSensitive(segment)) return true;
465
- }
466
- return false;
501
+ for (const segment of path.split(".")) {
502
+ if (segmentMatches(segment)) return true;
503
+ }
504
+ return false;
505
+ };
467
506
  }
468
- function enforceSensitiveCheck(path, acknowledged) {
507
+ const defaultSegmentMatches = createSegmentMatchesSensitive();
508
+ const defaultIsSensitivePath = createIsSensitivePath();
509
+ function segmentMatchesSensitive(segment) {
510
+ return defaultSegmentMatches(segment);
511
+ }
512
+ function isSensitivePath(path) {
513
+ return defaultIsSensitivePath(path);
514
+ }
515
+ function enforceSensitiveCheck(path, acknowledged, isSensitive = defaultIsSensitivePath) {
469
516
  if (acknowledged) return;
470
- if (!isSensitivePath(path)) return;
517
+ if (!isSensitive(path)) return;
471
518
  throw new SensitivePersistFieldError(path);
472
519
  }
473
520
 
@@ -609,10 +656,25 @@ function syncPersistOptIn(el, value, oldValue) {
609
656
  }
610
657
  if (wantsOptIn) {
611
658
  const v = value;
612
- enforceSensitiveCheck(v.path, v.acknowledgeSensitive);
659
+ enforceSensitiveCheck(v.path, v.acknowledgeSensitive, v.isSensitivePath);
613
660
  v.persistOptIns.add(elementId, v.path);
614
661
  }
615
662
  }
663
+ function syncMultiTabOptOut(value, oldValue) {
664
+ const wasOptedOut = isRegisterValue(oldValue) && oldValue.unmarkNoSync !== void 0;
665
+ const wantsOptOut = isRegisterValue(value) && value.markNoSync !== void 0;
666
+ if (!wasOptedOut && !wantsOptOut) return;
667
+ if (wasOptedOut) {
668
+ const old = oldValue;
669
+ const samePath = wantsOptOut && value.path === old.path;
670
+ if (!samePath) old.unmarkNoSync?.();
671
+ }
672
+ if (wantsOptOut) {
673
+ const v = value;
674
+ const samePathOld = wasOptedOut && oldValue.path === v.path;
675
+ if (!samePathOld) v.markNoSync?.();
676
+ }
677
+ }
616
678
  function syncElementRegistration(el, value, oldValue) {
617
679
  const wasRegistered = isRegisterValue(oldValue);
618
680
  const isRegistered = isRegisterValue(value);
@@ -1061,6 +1123,7 @@ const warnedUnsupportedElements = __DEV__ ? /* @__PURE__ */ new WeakSet() : null
1061
1123
  const vRegisterDynamic = {
1062
1124
  created(el, binding, vnode) {
1063
1125
  syncPersistOptIn(el, binding.value, void 0);
1126
+ syncMultiTabOptOut(binding.value, void 0);
1064
1127
  callModelHook(el, binding, vnode, null, "created");
1065
1128
  if (__DEV__ && warnedUnsupportedElements !== null && !SUPPORTED_TAGS.has(el.tagName) && !warnedUnsupportedElements.has(el)) {
1066
1129
  void vue.nextTick(() => {
@@ -1082,6 +1145,7 @@ const vRegisterDynamic = {
1082
1145
  },
1083
1146
  beforeUpdate(el, binding, vnode, prevVNode) {
1084
1147
  syncPersistOptIn(el, binding.value, binding.oldValue);
1148
+ syncMultiTabOptOut(binding.value, binding.oldValue);
1085
1149
  syncElementRegistration(el, binding.value, binding.oldValue);
1086
1150
  callModelHook(el, binding, vnode, prevVNode, "beforeUpdate");
1087
1151
  },
@@ -1092,6 +1156,7 @@ const vRegisterDynamic = {
1092
1156
  removeTrackedListeners(el);
1093
1157
  if (isRegisterValue(value)) {
1094
1158
  value.persistOptIns.removeAllFor(getOrAssignElementId(el));
1159
+ value.unmarkNoSync?.();
1095
1160
  }
1096
1161
  if (!isRegisterValue(value)) return;
1097
1162
  value.deregisterElement(el);
@@ -1169,6 +1234,7 @@ function createAttaform(options = {}) {
1169
1234
 
1170
1235
  exports.AnonPersistError = AnonPersistError;
1171
1236
  exports.AttaformError = AttaformError;
1237
+ exports.DEFAULT_SENSITIVE_NAMES = DEFAULT_SENSITIVE_NAMES;
1172
1238
  exports.InvalidPathError = InvalidPathError;
1173
1239
  exports.InvalidUseFormConfigError = InvalidUseFormConfigError;
1174
1240
  exports.OutsideSetupError = OutsideSetupError;
@@ -1180,8 +1246,10 @@ exports.__DEV__ = __DEV__;
1180
1246
  exports.assignKey = assignKey;
1181
1247
  exports.captureUserCallSite = captureUserCallSite;
1182
1248
  exports.createAttaform = createAttaform;
1249
+ exports.createIsSensitivePath = createIsSensitivePath;
1183
1250
  exports.createPersistOptInRegistry = createPersistOptInRegistry;
1184
1251
  exports.createRegistry = createRegistry;
1252
+ exports.createSegmentMatchesSensitive = createSegmentMatchesSensitive;
1185
1253
  exports.enforceSensitiveCheck = enforceSensitiveCheck;
1186
1254
  exports.ensureAttaformInstalled = ensureAttaformInstalled;
1187
1255
  exports.getRegistryFromApp = getRegistryFromApp;
@@ -1194,4 +1262,4 @@ exports.segmentMatchesSensitive = segmentMatchesSensitive;
1194
1262
  exports.useRegister = useRegister;
1195
1263
  exports.useRegistry = useRegistry;
1196
1264
  exports.vRegister = vRegister;
1197
- //# sourceMappingURL=attaform.rIRYSUI1.cjs.map
1265
+ //# sourceMappingURL=attaform.Dee2rU1P.cjs.map