@protontech/autofill 0.0.22991789 → 0.0.33690782

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 (190) hide show
  1. package/constants/features.d.ts +1 -0
  2. package/constants/features.js +1 -0
  3. package/constants/heuristics.d.ts +5 -4
  4. package/constants/heuristics.js +5 -10
  5. package/constants/selectors.d.ts +13 -7
  6. package/constants/selectors.js +29 -17
  7. package/debug.d.ts +24 -1
  8. package/debug.js +15 -13
  9. package/dictionary/generate.js +30 -21
  10. package/dictionary/generated/dictionary.d.ts +18 -4
  11. package/dictionary/generated/dictionary.js +31 -17
  12. package/dictionary/source/dictionary.d.ts +4 -3
  13. package/dictionary/source/dictionary.js +155 -89
  14. package/dictionary/source/patterns.js +2 -2
  15. package/features/feature.d.ts +17 -0
  16. package/features/feature.js +72 -0
  17. package/features/feature.spec.d.ts +1 -0
  18. package/features/feature.spec.js +55 -0
  19. package/features/v1/abstract.field.d.ts +20401 -0
  20. package/features/v1/abstract.field.js +95 -0
  21. package/features/v1/abstract.form.d.ts +1226 -0
  22. package/features/v1/abstract.form.js +336 -0
  23. package/features/v1/field.email.d.ts +62 -0
  24. package/features/v1/field.email.js +27 -0
  25. package/features/v1/field.otp.d.ts +142 -0
  26. package/features/v1/field.otp.js +105 -0
  27. package/features/v1/field.password.d.ts +162 -0
  28. package/features/v1/field.password.js +81 -0
  29. package/features/v1/field.username-hidden.d.ts +62 -0
  30. package/features/v1/field.username-hidden.js +25 -0
  31. package/features/v1/field.username.d.ts +72 -0
  32. package/features/v1/field.username.js +31 -0
  33. package/features/v1/index.d.ts +4427 -0
  34. package/features/v1/index.js +22 -0
  35. package/features/v1/index.spec.d.ts +1 -0
  36. package/features/v1/index.spec.js +30 -0
  37. package/index.d.ts +5 -2
  38. package/index.js +10 -3
  39. package/models/perceptron/index.d.ts +2 -0
  40. package/models/perceptron/index.js +27 -0
  41. package/models/perceptron/params/email-model.json +53 -0
  42. package/models/perceptron/params/login-model.json +465 -0
  43. package/models/perceptron/params/new-password-model.json +133 -0
  44. package/models/perceptron/params/otp-model.json +117 -0
  45. package/models/perceptron/params/password-change-model.json +465 -0
  46. package/models/perceptron/params/password-model.json +133 -0
  47. package/models/perceptron/params/recovery-model.json +465 -0
  48. package/models/perceptron/params/register-model.json +465 -0
  49. package/models/perceptron/params/username-hidden-model.json +53 -0
  50. package/models/perceptron/params/username-model.json +61 -0
  51. package/models/prod_20240829/index.d.ts +2 -0
  52. package/models/prod_20240829/index.js +27 -0
  53. package/models/prod_20240829/params/email-model.json +45 -0
  54. package/models/prod_20240829/params/login-model.json +421 -0
  55. package/models/prod_20240829/params/new-password-model.json +125 -0
  56. package/models/prod_20240829/params/otp-model.json +153 -0
  57. package/models/prod_20240829/params/password-change-model.json +421 -0
  58. package/models/prod_20240829/params/password-model.json +125 -0
  59. package/models/prod_20240829/params/recovery-model.json +421 -0
  60. package/models/prod_20240829/params/register-model.json +421 -0
  61. package/models/prod_20240829/params/username-hidden-model.json +41 -0
  62. package/models/prod_20240829/params/username-model.json +45 -0
  63. package/models/random_forest/index.d.ts +2 -0
  64. package/models/random_forest/index.js +27 -0
  65. package/models/random_forest/params/email-model.json +1456 -0
  66. package/models/random_forest/params/login-model.json +4194 -0
  67. package/models/random_forest/params/new-password-model.json +1448 -0
  68. package/models/random_forest/params/otp-model.json +2004 -0
  69. package/models/random_forest/params/password-change-model.json +1422 -0
  70. package/models/random_forest/params/password-model.json +1292 -0
  71. package/models/random_forest/params/recovery-model.json +2754 -0
  72. package/models/random_forest/params/register-model.json +3678 -0
  73. package/models/random_forest/params/username-hidden-model.json +1108 -0
  74. package/models/random_forest/params/username-model.json +1052 -0
  75. package/models/v1/index.d.ts +2 -0
  76. package/models/v1/index.js +35 -0
  77. package/package.json +14 -15
  78. package/rules/v1/index.d.ts +3 -0
  79. package/rules/v1/index.js +69 -0
  80. package/rulesets.d.ts +2 -2
  81. package/rulesets.js +11 -10
  82. package/types/index.d.ts +72 -17
  83. package/types/index.js +35 -2
  84. package/utils/attributes.js +1 -1
  85. package/utils/clustering.js +18 -5
  86. package/utils/credit-card.d.ts +32 -0
  87. package/utils/credit-card.js +259 -0
  88. package/utils/credit-card.samples.spec.d.ts +1 -0
  89. package/utils/credit-card.samples.spec.js +452 -0
  90. package/utils/credit-card.spec.d.ts +1 -0
  91. package/utils/credit-card.spec.js +296 -0
  92. package/utils/dom.d.ts +3 -2
  93. package/utils/dom.js +12 -7
  94. package/utils/exclusion.d.ts +1 -0
  95. package/utils/exclusion.js +22 -10
  96. package/utils/extract.d.ts +1 -0
  97. package/utils/extract.js +26 -7
  98. package/utils/fathom.d.ts +10 -23
  99. package/utils/fathom.js +7 -12
  100. package/utils/field.d.ts +12 -4
  101. package/utils/field.js +25 -14
  102. package/utils/flags.d.ts +9 -3
  103. package/utils/flags.js +27 -9
  104. package/utils/form.d.ts +16 -5
  105. package/utils/form.js +35 -14
  106. package/utils/identity.d.ts +12 -21
  107. package/utils/identity.js +66 -41
  108. package/utils/identity.samples.spec.d.ts +1 -0
  109. package/utils/identity.samples.spec.js +28 -0
  110. package/utils/iframe.d.ts +2 -0
  111. package/utils/iframe.js +22 -0
  112. package/utils/overrides.d.ts +19 -0
  113. package/utils/overrides.js +40 -0
  114. package/utils/prepass.js +6 -4
  115. package/utils/re.d.ts +19 -4
  116. package/utils/re.js +22 -7
  117. package/utils/re.spec.d.ts +1 -0
  118. package/utils/re.spec.js +62 -0
  119. package/utils/shadow-dom.d.ts +8 -0
  120. package/utils/shadow-dom.js +53 -0
  121. package/utils/shadow-dom.spec.d.ts +1 -0
  122. package/utils/shadow-dom.spec.js +215 -0
  123. package/utils/visible.d.ts +3 -2
  124. package/utils/visible.js +42 -22
  125. package/cli.d.ts +0 -2
  126. package/cli.js +0 -128
  127. package/features/abstract.field.d.ts +0 -123
  128. package/features/abstract.field.js +0 -63
  129. package/features/abstract.form.d.ts +0 -98
  130. package/features/abstract.form.js +0 -281
  131. package/features/field.email.d.ts +0 -18
  132. package/features/field.email.js +0 -43
  133. package/features/field.otp.d.ts +0 -36
  134. package/features/field.otp.js +0 -116
  135. package/features/field.password.d.ts +0 -35
  136. package/features/field.password.js +0 -104
  137. package/features/field.username-hidden.d.ts +0 -15
  138. package/features/field.username-hidden.js +0 -40
  139. package/features/field.username.d.ts +0 -16
  140. package/features/field.username.js +0 -41
  141. package/features/form.combined.d.ts +0 -1
  142. package/features/form.combined.js +0 -6
  143. package/trainees/field.email.d.ts +0 -2
  144. package/trainees/field.email.js +0 -16
  145. package/trainees/field.identity.d.ts +0 -2
  146. package/trainees/field.identity.js +0 -9
  147. package/trainees/field.otp.d.ts +0 -2
  148. package/trainees/field.otp.js +0 -16
  149. package/trainees/field.password.current.d.ts +0 -2
  150. package/trainees/field.password.current.js +0 -16
  151. package/trainees/field.password.new.d.ts +0 -2
  152. package/trainees/field.password.new.js +0 -16
  153. package/trainees/field.username-hidden.d.ts +0 -2
  154. package/trainees/field.username-hidden.js +0 -22
  155. package/trainees/field.username.d.ts +0 -2
  156. package/trainees/field.username.js +0 -16
  157. package/trainees/form.login.d.ts +0 -2
  158. package/trainees/form.login.js +0 -16
  159. package/trainees/form.noop.d.ts +0 -1
  160. package/trainees/form.noop.js +0 -7
  161. package/trainees/form.password-change.d.ts +0 -2
  162. package/trainees/form.password-change.js +0 -16
  163. package/trainees/form.recovery.d.ts +0 -2
  164. package/trainees/form.recovery.js +0 -16
  165. package/trainees/form.register.d.ts +0 -2
  166. package/trainees/form.register.js +0 -16
  167. package/trainees/index.d.ts +0 -9
  168. package/trainees/index.js +0 -72
  169. package/trainees/results/result.email.d.ts +0 -2
  170. package/trainees/results/result.email.js +0 -17
  171. package/trainees/results/result.login.d.ts +0 -2
  172. package/trainees/results/result.login.js +0 -110
  173. package/trainees/results/result.new-password.d.ts +0 -2
  174. package/trainees/results/result.new-password.js +0 -36
  175. package/trainees/results/result.otp.d.ts +0 -2
  176. package/trainees/results/result.otp.js +0 -43
  177. package/trainees/results/result.password-change.d.ts +0 -2
  178. package/trainees/results/result.password-change.js +0 -110
  179. package/trainees/results/result.password.d.ts +0 -2
  180. package/trainees/results/result.password.js +0 -36
  181. package/trainees/results/result.recovery.d.ts +0 -2
  182. package/trainees/results/result.recovery.js +0 -110
  183. package/trainees/results/result.register.d.ts +0 -2
  184. package/trainees/results/result.register.js +0 -110
  185. package/trainees/results/result.username-hidden.d.ts +0 -2
  186. package/trainees/results/result.username-hidden.js +0 -15
  187. package/trainees/results/result.username.d.ts +0 -2
  188. package/trainees/results/result.username.js +0 -16
  189. package/utils/memoize.d.ts +0 -5
  190. package/utils/memoize.js +0 -12
@@ -4,10 +4,10 @@ const dictionary = {
4
4
  en: ["login", "signin", "signon", "authenticate", "connect", "new session"],
5
5
  fr: ["connexion", "se connecter", "s'identifier", "authentifier", "entrer", "nouvelle session"],
6
6
  es: ["introduce", "introducir", "entrar", "iniciar sesión", "acceder", "nueva sesión"],
7
- de: ["anmelden", "anmeldung", "anmeldedaten"],
7
+ de: ["anmelden", "anmeldung", "anmeldedaten", "authentifizierungs"],
8
8
  pt: ["iniciar sessão", "conectar", "entrar", "nova sessão"],
9
9
  cz: ["přihlásit"],
10
- it: ['accedi']
10
+ nl: ["inloggen"],
11
11
  },
12
12
  },
13
13
  REGISTER: {
@@ -15,14 +15,14 @@ const dictionary = {
15
15
  en: ["register", "sign up", "create account", "join", "new account", "get started"],
16
16
  fr: ["inscrire", "créer un compte", "rejoindre", "commencer", "nouveau compte", "s'inscrire"],
17
17
  es: ["registrarse", "crear cuenta", "unirse", "empezar", "nueva cuenta"],
18
- de: ["registrieren", "neues konto", "konto erstellen"],
18
+ de: ["registrieren", "registrierung", "neues konto", "konto erstellen"],
19
19
  pt: ["registrar", "criar conta", "juntar", "começar", "nova conta"],
20
- it: ['crea account', 'creare account', 'registrati']
20
+ it: ["crea account", "creare account", "registrati"],
21
21
  },
22
22
  },
23
23
  RECOVERY: {
24
24
  i18n: {
25
- en: ["help", "recover", "restore", "reset", "trouble", "problem"],
25
+ en: ["help", "recover", "restore", "restoring", "reset", "trouble", "problem"],
26
26
  fr: ["aide", "récupérer", "restaurer", "réinitialiser"],
27
27
  es: ["ayuda", "recuperar", "restaurar", "restablecer"],
28
28
  de: ["hilfe", "wiederherstellen", "zurücksetzen"],
@@ -55,6 +55,7 @@ const dictionary = {
55
55
  de: ["passwort", "geheimnis", "zugangscode"],
56
56
  pt: ["senha", "chave secreta", "de segurança"],
57
57
  cz: ["heslo"],
58
+ nl: ["wachtwoord"],
58
59
  },
59
60
  attr: {
60
61
  values: ["pwd", "pw", "mdp", "pass", "fmt"],
@@ -62,7 +63,7 @@ const dictionary = {
62
63
  },
63
64
  PASSWORD_OUTLIER: {
64
65
  i18n: {
65
- en: ["national id", "social security", "userid"],
66
+ en: ["national id", "social security", "userid", "secAnswer", "answer"],
66
67
  },
67
68
  },
68
69
  USERNAME: {
@@ -71,9 +72,10 @@ const dictionary = {
71
72
  fr: ["pseudo", "utilisateur", "identifiant"],
72
73
  es: ["usuario", "identificador", "usuari"],
73
74
  de: ["nutzername", "anmelde", "benutzer"],
75
+ nl: ["gebruikersnaam"],
74
76
  },
75
77
  attr: {
76
- values: ["appleid", "identifyemail", "acct", "userid", "accountid", "loginid", "loginname", "customerid"],
78
+ values: ["appleid", "acct", "userid", "accountid", "loginid", "loginname", "customerid"],
77
79
  },
78
80
  },
79
81
  USERNAME_OUTLIER: {
@@ -106,10 +108,7 @@ const dictionary = {
106
108
  },
107
109
  },
108
110
  CAPTCHA: {
109
- i18n: {},
110
- attr: {
111
- values: ["captcha", "recaptcha", "hcaptcha", "solve-media", "funcaptcha", "keycaptcha"],
112
- },
111
+ attr: { values: ["captcha", "recaptcha", "hcaptcha", "solve-media", "funcaptcha", "keycaptcha"] },
113
112
  },
114
113
  SUBMIT_ACTION: {
115
114
  i18n: {
@@ -127,11 +126,9 @@ const dictionary = {
127
126
  es: ["nuevo", "crear"],
128
127
  de: ["neu", "erstellen"],
129
128
  pt: ["novo", "criar"],
130
- it: ['creare']
131
- },
132
- attr: {
133
- endsWith: ["1", "fst"],
129
+ it: ["creare"],
134
130
  },
131
+ endsWith: ["1", "fst"],
135
132
  },
136
133
  RESET_ACTION: {
137
134
  i18n: {
@@ -150,9 +147,7 @@ const dictionary = {
150
147
  de: ["bestätigen", "wiederholen", "verifizieren", "erneut eingeben"],
151
148
  pt: ["digitar novamente"],
152
149
  },
153
- attr: {
154
- endsWith: ["2", "bis", "snd"],
155
- },
150
+ endsWith: ["2", "bis", "snd"],
156
151
  },
157
152
  STEP_ACTION: {
158
153
  i18n: {
@@ -174,7 +169,7 @@ const dictionary = {
174
169
  },
175
170
  SEARCH_ACTION: {
176
171
  i18n: {
177
- en: ["search", "query"],
172
+ en: ["search", "query", "find"],
178
173
  fr: ["recherche"],
179
174
  es: ["buscar"],
180
175
  de: ["suche"],
@@ -194,17 +189,13 @@ const dictionary = {
194
189
  },
195
190
  },
196
191
  HIDDEN: {
197
- i18n: {},
198
192
  attr: {
199
193
  values: ["offscreen", "move-offscreen", "sr-only", "display-none", "screen-reader-only", "a11y-hide"],
200
194
  exact: ["hidden", "is-hidden"],
201
195
  },
202
196
  },
203
197
  OAUTH: {
204
- i18n: {},
205
- attr: {
206
- values: ["apple", "facebook", "google", "twitch"],
207
- },
198
+ attr: { values: ["apple", "facebook", "google", "twitch"] },
208
199
  },
209
200
  TOS: {
210
201
  i18n: {
@@ -215,47 +206,27 @@ const dictionary = {
215
206
  pt: ["termos de uso", "consentimento", "acordo", "política de privacidade"],
216
207
  },
217
208
  },
218
- MFA_ACTION: {
209
+ TWO_FA: {
219
210
  i18n: {
220
- en: ["Enter code", "verify", "enter auth code", "confirm"],
221
- fr: [],
222
- es: [],
223
- de: [],
224
- pt: [],
225
- },
226
- },
227
- MFA: {
228
- i18n: {
229
- en: [
230
- "2FA",
231
- "2step",
232
- "multi factor",
233
- "two factor",
234
- "two step",
235
- "auth code",
236
- "authenticator",
237
- "authentication app",
238
- "authentication code",
239
- "security code",
240
- "verification",
241
- "generator app",
242
- ],
243
- fr: ["2 étapes", "multi-facteur", "double facteur", "double étape", "authentificateur"],
244
- es: ["2 pasos", "doble paso", "doble factor", "verificacion", "generadora"],
245
- de: ["2-Schritte", "Multi-Faktor", "Zwei-Faktor", "Zwei-Schritte", "Authentifikator", "Authentifizierungs"],
246
- pt: ["2 etapas", "autenticador", "dois passos", "dois fatores", "multifator", "verificação", "autenticador"],
211
+ en: ["2FA", "2step", "multi factor", "two factor", "two step", "auth code", "security code", "verification"],
212
+ fr: ["2 étapes", "multi-facteur", "double facteur", "double étape"],
213
+ es: ["2 pasos", "doble paso", "doble factor", "verificacion"],
214
+ de: ["2-Schritte", "Multi-Faktor", "Zwei-Faktor", "Zwei-Schritte"],
215
+ pt: ["2 etapas", "dois passos", "dois fatores", "multifator", "verificação"],
247
216
  },
248
217
  attr: {
249
- values: ["twofactor", "twostep", "challenge", "two-factor", "loginCode", "2fa", "twofa", "tfacode", "phone_verification", "approvals_code"],
218
+ values: ["twofactor", "twostep", "challenge", "two-factor", "loginCode", "2fa", "twofa", "tfacode", "phone_verification", "approvals_code", "authentication code", "emailCode"],
250
219
  exact: ["tfa", "mfa"],
251
220
  },
252
221
  },
253
- OTP: {
254
- i18n: {},
222
+ AUTHENTICATOR: {
255
223
  attr: {
256
- values: ["onetime", "1time", "totp", "otp", "totpPin", "otc"],
224
+ values: ["authenticator", "authentication app", "generator app", "authentificateur", "Authentifikator", "Authentifizierungs-App", "Authentisierungs-App", "autenticador", "generadora", "application d'authentification"],
257
225
  },
258
226
  },
227
+ OTP: {
228
+ attr: { values: ["onetime", "1time", "totp", "otp", "totpPin", "otc"] },
229
+ },
259
230
  OTP_OUTLIER: {
260
231
  i18n: {
261
232
  en: ["resend", "new code", "send"],
@@ -265,7 +236,7 @@ const dictionary = {
265
236
  pt: ["reenviar", "novo código", "enviar"],
266
237
  },
267
238
  attr: {
268
- values: ["sms", "email", "phone-pin", "tel-pin", "email-pin", "phone_verification_pin"],
239
+ values: ["sms", "email"],
269
240
  },
270
241
  },
271
242
  NEWSLETTER: {
@@ -278,98 +249,193 @@ const dictionary = {
278
249
  },
279
250
  },
280
251
  IDENTITY_FULLNAME: {
281
- i18n: {},
282
252
  attr: {
283
253
  values: ["full-name", "your-name", "address-name", "address-contact", "contact-person"],
284
254
  exact: ["name"],
285
255
  },
286
256
  },
287
257
  IDENTITY_FIRSTNAME: {
288
- i18n: {},
289
258
  attr: { values: ["first-name", "given-name", "first-n"], exact: ["f-name"] },
290
259
  },
291
260
  IDENTITY_MIDDLENAME: {
292
- i18n: {},
293
261
  attr: { values: ["middle-name", "additional-name", "middle-n"], exact: ["m-name"] },
294
262
  },
295
263
  IDENTITY_LASTNAME: {
296
- i18n: {},
297
264
  attr: { values: ["last-name", "surname", "family-name", "family-n", "last-n"], exact: ["l-name", "s-name"] },
298
265
  },
299
266
  IDENTITY_TELEPHONE: {
300
- i18n: {},
301
267
  attr: {
302
- values: ["phone", "mobile", "telephone", "tel-local", "tel-national", "national-number", "contact-number"],
303
- exact: ["tel"],
268
+ values: ["phone", "mobile", "telephone", "national-number", "contact-number"],
269
+ exact: ["tel", "tel-national", "tel-local"],
304
270
  },
305
271
  },
306
- IDENTITY_TELEPHONE_PREFIX: {
307
- i18n: {},
308
- attr: { values: ["prefix", "code", "country"] },
272
+ IDENTITY_TELEPHONE_OUTLIER: {
273
+ attr: { values: ["prefix", "code", "country", "extension", "security"] },
309
274
  },
310
275
  IDENTITY_ADDRESS: {
311
- i18n: {},
312
276
  attr: {
313
- values: [
314
- "address-line-one",
315
- "address-line1",
316
- "address-lines",
317
- "address1",
318
- "bill-addr",
319
- "billing-addr",
320
- "mailing-addr",
321
- "preferred-address",
322
- "street-address",
323
- ],
277
+ values: ["address-line-one", "address-line1", "address-lines", "address1", "bill-addr", "billing-addr", "mailing-addr", "preferred-address", "street-address"],
324
278
  exact: ["address", "addr", "street", "line1", "mail-addr"],
325
279
  },
326
280
  },
327
281
  IDENTITY_ADDRESS_LINES: {
328
- i18n: {},
329
- attr: {
330
- endsWith: ["line2", "line-two", "line3", "line-three"],
331
- },
282
+ endsWith: ["line2", "line-two", "line3", "line-three"],
332
283
  },
333
284
  IDENTITY_STATE: {
334
- i18n: {},
335
285
  attr: {
336
286
  values: ["address-level-1", "address-state", "address-province", "state-province"],
337
287
  exact: ["state", "province", "region", "county"],
338
288
  },
339
289
  },
340
290
  IDENTITY_CITY: {
341
- i18n: {},
342
291
  attr: {
343
292
  values: ["address-level-2", "address-city", "address-town", "personal-city"],
344
293
  exact: ["city", "town", "locality"],
345
294
  },
346
295
  },
347
296
  IDENTITY_ZIPCODE: {
348
- i18n: {},
349
297
  attr: {
350
298
  values: ["zip-code", "postal-code", "post-code", "address-zip", "address-postal", "address-postal-code", "address-zip-code"],
351
299
  exact: ["zip"],
352
300
  },
353
301
  },
354
302
  IDENTITY_ORGANIZATION: {
355
- i18n: {},
356
303
  attr: {
357
304
  values: ["company-name", "organization", "organization-name"],
358
305
  exact: ["organization"],
359
306
  },
360
307
  },
361
308
  IDENTITY_COUNTRY: {
362
- i18n: {},
363
309
  attr: {
364
310
  values: ["country-name", "address-country", "address-country-name"],
365
311
  exact: ["country"],
366
312
  },
367
313
  },
368
314
  IDENTITY_COUNTRY_CODE: {
369
- i18n: {},
370
315
  attr: {
371
316
  values: ["country-code"],
372
317
  },
373
318
  },
319
+ CC_PREFIX: {
320
+ attr: {
321
+ values: ["creditcard", "cartecredit", "credcard", "card", "payment-card", "payments-card", "vads", "stripe", "new-card", "creditDebit"],
322
+ },
323
+ },
324
+ CC_NUMBER: {
325
+ attr: {
326
+ values: ["card-no", "card-num", "card-no", "cc-no", "cb-num", "num-carte", "numero-carte", "numero de carte", "cardnr"],
327
+ exact: ["cc-number", "card number"],
328
+ },
329
+ },
330
+ CC_OUTLIER: {
331
+ attr: {
332
+ values: ["logincard", "certificate", "voucher", "coupon", "promo"],
333
+ },
334
+ },
335
+ CC_CVC: {
336
+ attr: {
337
+ values: ["cvv", "cvc", "csc", "ccv", "card-code", "card-verification", "payments-code", "payment-code"],
338
+ exact: ["cc-csc", "cc-cvv", "cc-code", "cvn"],
339
+ },
340
+ },
341
+ CC_CODE: {
342
+ attr: {
343
+ values: ["security code", "pincode", "cardpin"],
344
+ },
345
+ },
346
+ CC_NAME: {
347
+ attr: {
348
+ values: ["accountholdername", "holdername", "cardname", "cardholder", "cardholdername", "nameoncard"],
349
+ exact: ["cc-name"],
350
+ },
351
+ },
352
+ CC_EXP: {
353
+ attr: {
354
+ values: ["card-expiration", "expiration-date", "expiration-month-year", "expiry-date", "expiry", "expiration", "card-exp"],
355
+ exact: ["cc-exp", "cc-expiration", "expiry date"],
356
+ },
357
+ },
358
+ CC_EXP_MONTH: {
359
+ attr: {
360
+ values: [
361
+ "expiry-mo",
362
+ "expiry-m",
363
+ "expiry-mm",
364
+ "expire-mo",
365
+ "expire-m",
366
+ "expire-mm",
367
+ "expiration-mo",
368
+ "expiration-m",
369
+ "expiration-mm",
370
+ "card-mo",
371
+ "card-m",
372
+ "card-mm",
373
+ "exp-mo",
374
+ "exp-m",
375
+ "exp-mm",
376
+ "expiry-date-field-mo",
377
+ "expiry-date-mo",
378
+ "expiration-date-mo",
379
+ "expiration-date-mm",
380
+ "m-expiration",
381
+ "mois-exp",
382
+ "cb-date-mo",
383
+ ],
384
+ exact: ["cc-exp-month", "cc-month", "cc-mm"],
385
+ },
386
+ endsWith: ["mm", "month", "mo"],
387
+ },
388
+ CC_EXP_YEAR: {
389
+ attr: {
390
+ values: [
391
+ "expiry-year",
392
+ "expiry-y",
393
+ "expiry-yy",
394
+ "expiry-yyyy",
395
+ "expire-year",
396
+ "expire-y",
397
+ "expire-yy",
398
+ "expire-yyyy",
399
+ "expiration-year",
400
+ "expiration-y",
401
+ "expiration-yy",
402
+ "expiration-yyyy",
403
+ "card-year",
404
+ "card-y",
405
+ "card-yy",
406
+ "card-yyyy",
407
+ "exp-year",
408
+ "exp-y",
409
+ "exp-yy",
410
+ "exp-yyyy",
411
+ "expiry-date-field-year",
412
+ "expiry-date-year",
413
+ "expiration-date-year",
414
+ "expiration-date-yy",
415
+ "expiration-date-yyyy",
416
+ "y-expiration",
417
+ "annee-exp",
418
+ "ann-exp",
419
+ "cb-date-ann",
420
+ ],
421
+ exact: ["cc-exp-year", "cc-year", "cc-yr", "cc-yy"],
422
+ },
423
+ endsWith: ["yy", "year"],
424
+ },
425
+ IFRAME_FIELD: {
426
+ attr: {
427
+ values: ["field", "input", "control", "form", "pci", "cvv", "cvc", "security", "pbf", "stripeFrame", "expiry"],
428
+ },
429
+ },
430
+ PAYMENT: {
431
+ attr: {
432
+ values: ["payment", "checkout", "cart", "card"],
433
+ },
434
+ },
435
+ DOCUMENT: {
436
+ attr: {
437
+ values: ["contract", "idcard", "insurance", "licence", "license", "membership", "nationalid", "passeport", "passport", "permit", "social security", "subscription"],
438
+ },
439
+ },
374
440
  };
375
441
  export default dictionary;
@@ -1,3 +1,3 @@
1
- export const EMAIL_VALUE_RE = /^[\w\-\.]+@([\w-]+\.)+[\w-]{2,5}$/;
1
+ export const EMAIL_VALUE_RE = /^[\w\-.]+@([\w-]+\.)+[\w-]{2,5}$/;
2
2
  export const TEL_VALUE_RE = /^[\d()+-]{6,25}$/;
3
- export const USERNAME_VALUE_RE = /^[\w\-\.]{7,30}$/;
3
+ export const USERNAME_VALUE_RE = /^[\w\-.]{7,30}$/;
@@ -0,0 +1,17 @@
1
+ import type { AbstractFeature, AbstractFeatures, Feature, FeatureComputer, InferFeatureName, InferFeatureReturnType, InferParentComputeType } from "@protontech/autofill/types";
2
+ import type { Fnode } from "@protontech/fathom";
3
+ export declare const feature: <N extends string, R, P extends AbstractFeatures>(name: N, parents: P, compute: (parents: InferParentComputeType<P>, fnode: Fnode) => R) => Feature<N, R, P>;
4
+ export declare const featureCount: <N extends string, R extends unknown[], P extends AbstractFeatures>(feat: Feature<N, R, P>) => Feature<`${N}Count`, number, {
5
+ [x: string]: Feature<N, R, P>;
6
+ }>;
7
+ export declare const featureScaled: <N extends string, P extends AbstractFeatures>(feat: Feature<N, number, P>, min: number, max: number) => Feature<`${N}Scaled`, number, Record<N, Feature<N, number, P>>>;
8
+ export declare const featuresInnerProduct: <F1 extends AbstractFeature, F2 extends AbstractFeature, P extends Record<InferFeatureName<F1>, F1> & Record<InferFeatureName<F2>, F2>>(feat1: F1, feat2: F2) => Feature<`${InferFeatureName<F1>},${InferFeatureName<F2>}`, number, P>;
9
+ export declare const featuresProduct: <F1 extends AbstractFeature, F2 extends AbstractFeature, P extends Record<InferFeatureName<F1>, F1> & Record<InferFeatureName<F2>, F2>>(feat1: F1, feat2: F2) => Feature<`${InferFeatureName<F1>},${InferFeatureName<F2>}`, number, P>;
10
+ type FlatFeature<F extends AbstractFeature> = Feature<InferFeatureName<F>, InferFeatureReturnType<F>, AbstractFeatures>;
11
+ type FlatFeatures<F extends AbstractFeatures> = {
12
+ [K in keyof F]: FlatFeature<F[K]>;
13
+ };
14
+ export declare const flattenFeatures: <F extends AbstractFeatures>(features: F) => FlatFeatures<F>;
15
+ export declare const getComputerForFeatures: <F extends AbstractFeatures>(features: F) => FeatureComputer<FlatFeatures<F>>;
16
+ export declare const topologicalSort: (features: AbstractFeatures) => AbstractFeature<unknown>[];
17
+ export {};
@@ -0,0 +1,72 @@
1
+ import { utils } from "@protontech/fathom";
2
+ const { linearScale } = utils;
3
+ export const feature = (name, parents, compute) => ({
4
+ name,
5
+ parents,
6
+ compute,
7
+ });
8
+ export const featureCount = (feat) => feature(`${feat.name}Count`, { [feat.name]: feat }, (parents) => parents[feat.name].length);
9
+ export const featureScaled = (feat, min, max) => feature(`${feat.name}Scaled`, { [feat.name]: feat }, (parents) => linearScale(parents[feat.name], min, max));
10
+ export const featuresInnerProduct = (feat1, feat2) => feature(`${feat1.name},${feat2.name}`, { [feat1.name]: feat1, [feat2.name]: feat2 }, (parents) => Math.sqrt(Number(parents[feat1.name]) * Number(parents[feat2.name])));
11
+ export const featuresProduct = (feat1, feat2) => feature(`${feat1.name},${feat2.name}`, { [feat1.name]: feat1, [feat2.name]: feat2 }, (parents) => Number(parents[feat1.name]) * Number(parents[feat2.name]));
12
+ export const flattenFeatures = (features) => features;
13
+ export const getComputerForFeatures = (features) => {
14
+ const sorted = topologicalSort(features);
15
+ return {
16
+ compute: (fnode) => {
17
+ const computed_parents = {};
18
+ sorted.forEach((feature) => {
19
+ const feature_val = feature.compute(computed_parents, fnode);
20
+ computed_parents[feature.name] = feature_val;
21
+ });
22
+ return Object.fromEntries(Object.values(features).map(({ name }) => [name, computed_parents[name]]));
23
+ },
24
+ features: Array.from(Object.values(features)).filter((feat) => !feat.name.startsWith("__")),
25
+ };
26
+ };
27
+ export const topologicalSort = (features) => {
28
+ var _a;
29
+ const parentToChildren = new Map();
30
+ const childToParents = new Map();
31
+ const to_remove = new Array();
32
+ const to_visit = Array.from(Object.values(features));
33
+ const seen = new Set(to_visit);
34
+ while (to_visit.length > 0) {
35
+ const node = to_visit.pop();
36
+ if (Object.keys(node.parents).length === 0) {
37
+ to_remove.push(node);
38
+ }
39
+ else {
40
+ Object.values(node.parents).forEach((parent) => {
41
+ var _a, _b, _c, _d;
42
+ if (!seen.has(parent))
43
+ to_visit.push(parent);
44
+ (_b = (_a = childToParents.get(node)) === null || _a === void 0 ? void 0 : _a.add(parent)) !== null && _b !== void 0 ? _b : childToParents.set(node, new Set([parent]));
45
+ (_d = (_c = parentToChildren.get(parent)) === null || _c === void 0 ? void 0 : _c.add(node)) !== null && _d !== void 0 ? _d : parentToChildren.set(parent, new Set([node]));
46
+ });
47
+ }
48
+ seen.add(node);
49
+ }
50
+ const sorted = new Array();
51
+ while (to_remove.length > 0) {
52
+ const node = to_remove.pop();
53
+ (_a = parentToChildren.get(node)) === null || _a === void 0 ? void 0 : _a.forEach((child) => {
54
+ const parents = childToParents.get(child);
55
+ parents === null || parents === void 0 ? void 0 : parents.delete(node);
56
+ if ((parents === null || parents === void 0 ? void 0 : parents.size) === 0) {
57
+ to_remove.unshift(child);
58
+ childToParents.delete(child);
59
+ }
60
+ });
61
+ sorted.push(node);
62
+ }
63
+ if (childToParents.size > 0) {
64
+ throw new Error(`loop detected with elements:\n ${Array.from(childToParents.entries().map(([child, parents]) => `${child.name} -> {${Array.from(parents)
65
+ .map((parent) => parent.name)
66
+ .sort()
67
+ .join(", ")}}`))
68
+ .sort()
69
+ .join("\n ")}`);
70
+ }
71
+ return sorted;
72
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,55 @@
1
+ import { feature, featuresProduct, getComputerForFeatures, topologicalSort } from "./feature";
2
+ function doNothing() {
3
+ }
4
+ describe("topological sort", () => {
5
+ test("it works", () => {
6
+ const A = feature("A", {}, doNothing);
7
+ const B = feature("B", { A }, doNothing);
8
+ const C = feature("C", { A }, doNothing);
9
+ const D = feature("D", { B, C }, doNothing);
10
+ const E = feature("E", { B }, doNothing);
11
+ const F = feature("F", {}, doNothing);
12
+ const G = feature("G", { E, F }, doNothing);
13
+ const H = feature("H", {}, doNothing);
14
+ const features = { D, G, H };
15
+ const sorted = topologicalSort(features);
16
+ const nodeNames = sorted.map((feat) => feat.name);
17
+ expect(nodeNames.slice(0, 3).sort()).toEqual(["A", "F", "H"]);
18
+ expect(nodeNames.slice(3, 5).sort()).toEqual(["B", "C"]);
19
+ expect(nodeNames[5]).toEqual("E");
20
+ expect(nodeNames.slice(6, 8).sort()).toEqual(["D", "G"]);
21
+ });
22
+ test("it fails if there is a loop", () => {
23
+ const A = feature("A", {}, doNothing);
24
+ const B = feature("B", { A }, doNothing);
25
+ const C = feature("C", { A }, doNothing);
26
+ const D = feature("D", { B, C }, doNothing);
27
+ const E = feature("E", { B }, doNothing);
28
+ const F = feature("F", {}, doNothing);
29
+ const G = feature("G", { E, F }, doNothing);
30
+ const H = feature("H", {}, doNothing);
31
+ A.parents = { D };
32
+ const features = { A, B, C, D, E, F, G, H };
33
+ expect(() => topologicalSort(features)).toThrow(`loop detected with elements:
34
+ A -> {D}
35
+ B -> {A}
36
+ C -> {A}
37
+ D -> {B, C}
38
+ E -> {B}
39
+ G -> {E}`);
40
+ });
41
+ });
42
+ describe("Feature engineering", () => {
43
+ test("featureProduct", () => {
44
+ const A = feature("A", {}, () => 2);
45
+ const B = feature("B", { A }, () => 4);
46
+ const C = featuresProduct(A, B);
47
+ expect(getComputerForFeatures({ A, B, C }).compute({})).toStrictEqual({ A: 2, B: 4, "A,B": 8 });
48
+ });
49
+ test("feature name re-mapping", () => {
50
+ const A = feature("A", {}, () => 2);
51
+ const B = feature("_B", { A }, () => 4);
52
+ const C = feature("C", { A, B }, (p) => p.A + p._B);
53
+ expect(getComputerForFeatures({ A, B, C }).compute({})).toStrictEqual({ A: 2, _B: 4, C: 6 });
54
+ });
55
+ });