@protontech/autofill 0.0.33690782 → 0.0.35059265

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 (51) hide show
  1. package/features/feature.d.ts +2 -1
  2. package/features/feature.js +15 -10
  3. package/features/feature.spec.js +6 -2
  4. package/features/registry.d.ts +3 -0
  5. package/features/registry.js +9 -0
  6. package/features/sorted.gen.d.ts +14 -0
  7. package/features/sorted.gen.js +22 -0
  8. package/features/v1/abstract.field.js +2 -2
  9. package/features/v1/abstract.form.d.ts +0 -612
  10. package/features/v1/abstract.form.js +1 -2
  11. package/features/v1/index.d.ts +13 -4425
  12. package/features/v1/index.js +12 -14
  13. package/index.d.ts +2 -0
  14. package/index.js +1 -0
  15. package/models/perceptron/index.d.ts +2 -2
  16. package/models/perceptron/index.js +34 -19
  17. package/models/perceptron/params/email-model.json +4 -4
  18. package/models/perceptron/params/login-model.json +94 -94
  19. package/models/perceptron/params/new-password-model.json +18 -18
  20. package/models/perceptron/params/otp-model.json +13 -13
  21. package/models/perceptron/params/password-change-model.json +77 -77
  22. package/models/perceptron/params/password-model.json +20 -20
  23. package/models/perceptron/params/recovery-model.json +70 -70
  24. package/models/perceptron/params/register-model.json +97 -97
  25. package/models/perceptron/params/username-hidden-model.json +8 -8
  26. package/models/perceptron/params/username-model.json +4 -4
  27. package/models/random_forest/index.d.ts +2 -2
  28. package/models/random_forest/index.js +34 -19
  29. package/package.json +6 -3
  30. package/rules/v1/index.d.ts +2 -1
  31. package/rules/v1/index.js +12 -15
  32. package/rulesets.d.ts +9 -2
  33. package/rulesets.js +5 -1
  34. package/scripts/gen-sorted-features.d.ts +1 -0
  35. package/scripts/gen-sorted-features.js +32 -0
  36. package/types/index.d.ts +4 -6
  37. package/types/index.js +3 -3
  38. package/models/prod_20240829/index.d.ts +0 -2
  39. package/models/prod_20240829/index.js +0 -27
  40. package/models/prod_20240829/params/email-model.json +0 -45
  41. package/models/prod_20240829/params/login-model.json +0 -421
  42. package/models/prod_20240829/params/new-password-model.json +0 -125
  43. package/models/prod_20240829/params/otp-model.json +0 -153
  44. package/models/prod_20240829/params/password-change-model.json +0 -421
  45. package/models/prod_20240829/params/password-model.json +0 -125
  46. package/models/prod_20240829/params/recovery-model.json +0 -421
  47. package/models/prod_20240829/params/register-model.json +0 -421
  48. package/models/prod_20240829/params/username-hidden-model.json +0 -41
  49. package/models/prod_20240829/params/username-model.json +0 -45
  50. package/models/v1/index.d.ts +0 -2
  51. package/models/v1/index.js +0 -35
@@ -12,6 +12,7 @@ type FlatFeatures<F extends AbstractFeatures> = {
12
12
  [K in keyof F]: FlatFeature<F[K]>;
13
13
  };
14
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>>;
15
+ export declare const getComputerForFeatures: (sorted: readonly AbstractFeature[], outputNames: readonly string[]) => FeatureComputer;
16
16
  export declare const topologicalSort: (features: AbstractFeatures) => AbstractFeature<unknown>[];
17
+ export declare const computeFeatures: <F extends AbstractFeatures>(featureComputer: FeatureComputer<F>, fnode: Fnode) => import("@protontech/autofill/types").ComputedFeatures<F>;
17
18
  export {};
@@ -7,21 +7,25 @@ export const feature = (name, parents, compute) => ({
7
7
  });
8
8
  export const featureCount = (feat) => feature(`${feat.name}Count`, { [feat.name]: feat }, (parents) => parents[feat.name].length);
9
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]));
10
+ export const featuresInnerProduct = (feat1, feat2) => feature(`${feat1.name},${feat2.name}`, {
11
+ [feat1.name]: feat1,
12
+ [feat2.name]: feat2,
13
+ }, (parents) => Math.sqrt(Number(parents[feat1.name]) * Number(parents[feat2.name])));
14
+ export const featuresProduct = (feat1, feat2) => feature(`${feat1.name},${feat2.name}`, {
15
+ [feat1.name]: feat1,
16
+ [feat2.name]: feat2,
17
+ }, (parents) => Number(parents[feat1.name]) * Number(parents[feat2.name]));
12
18
  export const flattenFeatures = (features) => features;
13
- export const getComputerForFeatures = (features) => {
14
- const sorted = topologicalSort(features);
19
+ export const getComputerForFeatures = (sorted, outputNames) => {
20
+ const outputSet = new Set(outputNames);
15
21
  return {
16
22
  compute: (fnode) => {
17
23
  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]]));
24
+ for (const feature of sorted)
25
+ computed_parents[feature.name] = feature.compute(computed_parents, fnode);
26
+ return Object.fromEntries(outputNames.map((n) => [n, computed_parents[n]]));
23
27
  },
24
- features: Array.from(Object.values(features)).filter((feat) => !feat.name.startsWith("__")),
28
+ features: sorted.filter((f) => outputSet.has(f.name) && !f.name.startsWith("__")),
25
29
  };
26
30
  };
27
31
  export const topologicalSort = (features) => {
@@ -70,3 +74,4 @@ export const topologicalSort = (features) => {
70
74
  }
71
75
  return sorted;
72
76
  };
77
+ export const computeFeatures = (featureComputer, fnode) => featureComputer.compute(fnode);
@@ -44,12 +44,16 @@ describe("Feature engineering", () => {
44
44
  const A = feature("A", {}, () => 2);
45
45
  const B = feature("B", { A }, () => 4);
46
46
  const C = featuresProduct(A, B);
47
- expect(getComputerForFeatures({ A, B, C }).compute({})).toStrictEqual({ A: 2, B: 4, "A,B": 8 });
47
+ const features = { A, B, C };
48
+ const outputNames = Object.values(features).map((f) => f.name);
49
+ expect(getComputerForFeatures(topologicalSort(features), outputNames).compute({})).toStrictEqual({ A: 2, B: 4, "A,B": 8 });
48
50
  });
49
51
  test("feature name re-mapping", () => {
50
52
  const A = feature("A", {}, () => 2);
51
53
  const B = feature("_B", { A }, () => 4);
52
54
  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 });
55
+ const features = { A, B, C };
56
+ const outputNames = Object.values(features).map((f) => f.name);
57
+ expect(getComputerForFeatures(topologicalSort(features), outputNames).compute({})).toStrictEqual({ A: 2, _B: 4, C: 6 });
54
58
  });
55
59
  });
@@ -0,0 +1,3 @@
1
+ import type { FeatureComputer } from "@protontech/autofill/types";
2
+ export declare const setFormFeaturesComputer: (c: FeatureComputer) => void;
3
+ export declare const getFormFeaturesComputer: () => FeatureComputer;
@@ -0,0 +1,9 @@
1
+ let formFeaturesComputer;
2
+ export const setFormFeaturesComputer = (c) => {
3
+ formFeaturesComputer = c;
4
+ };
5
+ export const getFormFeaturesComputer = () => {
6
+ if (!formFeaturesComputer)
7
+ throw new Error("formFeaturesComputer accessed before registration; features/v1 must be initialised first");
8
+ return formFeaturesComputer;
9
+ };
@@ -0,0 +1,14 @@
1
+ export declare const sortedFieldFeatures: import("..").AbstractFeature<unknown>[];
2
+ export declare const fieldFeatureNames: ("text" | "label" | "autocomplete" | "visible" | "attrs" | "isCC" | "isFormLogin" | "parentFormFnode" | "isFormNoop" | "isFormPasswordChange" | "isFormRecovery" | "isFormRegister" | "isIdentity" | "searchField" | "nextField" | "parentFormFeatures" | "prevField" | "prevInput")[];
3
+ export declare const sortedFormFeatures: import("..").AbstractFeature<unknown>[];
4
+ export declare const formFeatureNames: ("__formInputMFACandidates" | "__formMFA" | "formTextMFA" | "formAttrsMFA" | "__formOTPOutlier" | "__formTextAuthenticator" | "inputsMFA" | "__headingsOTPOutlier" | "__inputIterator" | "__linkOTPOutlier" | "visibleFieldsCountScaled" | "visibleInputsCountScaled" | "fieldsetsCountScaled" | "textsCountScaled" | "textareasCountScaled" | "selectsCountScaled" | "disabledCountScaled" | "radiosCountScaled" | "readOnlyCountScaled" | "formComplexityScaled" | "visibleIdentifiersCountScaled" | "hiddenIdentifiersCountScaled" | "usernamesCountScaled" | "emailsCountScaled" | "hiddenCountScaled" | "hiddenPasswordsCountScaled" | "submitsCountScaled" | "identitiesCountScaled" | "ccsCountScaled" | "hasTels" | "hasOAuth" | "hasCaptchas" | "hasFiles" | "hasDate" | "hasNumber" | "oneVisibleField" | "twoVisibleFields" | "threeOrMoreVisibleFields" | "noPasswords" | "onePassword" | "twoPasswords" | "threeOrMorePasswords" | "noIdentifiers" | "oneIdentifier" | "twoIdentifiers" | "threeOrMoreIdentifiers" | "autofocusedIsIdentifier" | "autofocusedIsPassword" | "visibleRatio" | "inputRatio" | "hiddenRatio" | "identifierRatio" | "emailRatio" | "usernameRatio" | "passwordRatio" | "disabledRatio" | "requiredRatio" | "checkboxRatio" | "hiddenIdentifierRatio" | "hiddenPasswordRatio" | "pageLogin" | "formTextLogin" | "formAttrsLogin" | "headingsLogin" | "layoutLogin" | "rememberMeCheckbox" | "troubleLink" | "submitLogin" | "pageRegister" | "formTextRegister" | "formAttrsRegister" | "headingsRegister" | "layoutRegister" | "pwNewRegister" | "pwConfirmRegister" | "submitRegister" | "TOSRef" | "pagePwReset" | "formTextPwReset" | "formAttrsPwReset" | "headingsPwReset" | "layoutPwReset" | "pageRecovery" | "formTextRecovery" | "formAttrsRecovery" | "headingsRecovery" | "layoutRecovery" | "identifierRecovery" | "submitRecovery" | "newsletterForm" | "searchForm" | "multistepForm" | "multiAuthForm" | "multistepForm,multiAuthForm" | "visibleRatio,visibleFieldsCountScaled" | "visibleRatio,visibleIdentifiersCountScaled" | "visibleRatio,visiblePasswordsCountScaled" | "visibleRatio,hiddenIdentifiersCountScaled" | "visibleRatio,hiddenPasswordsCountScaled" | "visibleRatio,multiAuthForm" | "visibleRatio,multistepForm" | "identifierRatio,visibleFieldsCountScaled" | "identifierRatio,visibleIdentifiersCountScaled" | "identifierRatio,visiblePasswordsCountScaled" | "identifierRatio,hiddenIdentifiersCountScaled" | "identifierRatio,hiddenPasswordsCountScaled" | "identifierRatio,multiAuthForm" | "identifierRatio,multistepForm" | "passwordRatio,visibleFieldsCountScaled" | "passwordRatio,visibleIdentifiersCountScaled" | "passwordRatio,visiblePasswordsCountScaled" | "passwordRatio,hiddenIdentifiersCountScaled" | "passwordRatio,hiddenPasswordsCountScaled" | "passwordRatio,multiAuthForm" | "passwordRatio,multistepForm" | "requiredRatio,visibleFieldsCountScaled" | "requiredRatio,visibleIdentifiersCountScaled" | "requiredRatio,visiblePasswordsCountScaled" | "requiredRatio,hiddenIdentifiersCountScaled" | "requiredRatio,hiddenPasswordsCountScaled" | "requiredRatio,multiAuthForm" | "requiredRatio,multistepForm")[];
5
+ export declare const sortedEmailFeatures: import("..").AbstractFeature<unknown>[];
6
+ export declare const emailFeatureNames: ("fieldCC" | "fieldIdentity" | "isSearchField" | "attrEmail" | "autocompleteEmail" | "autocompleteOff" | "typeEmail" | "exactAttrEmail" | "textEmail" | "labelEmail" | "placeholderEmail" | "mfaOutlier")[];
7
+ export declare const sortedOtpFeatures: import("..").AbstractFeature<unknown>[];
8
+ export declare const otpFeatureNames: ("formComplexity" | "fieldCC" | "fieldIdentity" | "formMFA" | "formAuthenticator" | "outlierForm" | "outlierLink" | "outlierHeadings" | "numericMode" | "patternOTP" | "nameMatch" | "idMatch" | "autocompleteOTC" | "singleInput" | "siblingOfInterest" | "attrOTP" | "attrMFA" | "textMFA" | "textAuthenticator" | "labelOTP" | "labelMFA" | "labelAuthenticator" | "outlierMaxLength" | "outlierInputCount" | "outlierEmailMatchScaled" | "outlierField" | "outlierSearch" | "outlierAutocomplete")[];
9
+ export declare const sortedPasswordFeatures: import("..").AbstractFeature<unknown>[];
10
+ export declare const passwordFeatureNames: ("fieldCC" | "fieldIdentity" | "autocompleteOff" | "fieldLogin" | "fieldRegister" | "fieldExotic" | "passwordOutlier" | "autocompleteNew" | "autocompleteCurrent" | "autocompleteOTP" | "attrCurrent" | "textCurrent" | "labelCurrent" | "attrCreate" | "textCreate" | "labelCreate" | "attrConfirm" | "textConfirm" | "labelConfirm" | "attrReset" | "prevPwField" | "prevPwNew" | "prevPwCurrent" | "nextPwField" | "nextPwNew" | "nextPwConfirm" | "nextPwCurrent" | "fieldLogin,autocompleteNew" | "fieldLogin,maybeNew" | "fieldRegister,autocompleteCurrent" | "fieldRegister,maybeCurrent" | "prevPwCurrent,nextPwNew")[];
11
+ export declare const sortedUsernameFeatures: import("..").AbstractFeature<unknown>[];
12
+ export declare const usernameFeatureNames: ("fieldCC" | "fieldIdentity" | "isSearchField" | "autocompleteUsername" | "attrUsername" | "autocompleteEmail" | "autocompleteOff" | "textUsername" | "labelUsername" | "outlierAttrs" | "outlierText" | "outlierLabel" | "outlierEmail" | "firstLoginFormField")[];
13
+ export declare const sortedUsernameHiddenFeatures: import("..").AbstractFeature<unknown>[];
14
+ export declare const usernameHiddenFeatureNames: ("fieldCC" | "fieldIdentity" | "autocompleteUsername" | "attrEmail" | "attrUsername" | "autocompleteEmail" | "fieldExotic" | "visibleReadonly" | "attrMatch" | "valueEmail" | "valueTel" | "valueUsername")[];
@@ -0,0 +1,22 @@
1
+ import { topologicalSort } from "@protontech/autofill/features/feature";
2
+ import { fieldFeatures } from "./v1/abstract.field";
3
+ import { formFeatures } from "./v1/abstract.form";
4
+ import { emailFeatures } from "./v1/field.email";
5
+ import { otpFeatures } from "./v1/field.otp";
6
+ import { passwordFeatures } from "./v1/field.password";
7
+ import { usernameFeatures } from "./v1/field.username";
8
+ import { usernameHiddenFeatures } from "./v1/field.username-hidden";
9
+ export const sortedFieldFeatures = topologicalSort(fieldFeatures);
10
+ export const fieldFeatureNames = Object.values(fieldFeatures).map((f) => f.name);
11
+ export const sortedFormFeatures = topologicalSort(formFeatures);
12
+ export const formFeatureNames = Object.values(formFeatures).map((f) => f.name);
13
+ export const sortedEmailFeatures = topologicalSort(emailFeatures);
14
+ export const emailFeatureNames = Object.values(emailFeatures).map((f) => f.name);
15
+ export const sortedOtpFeatures = topologicalSort(otpFeatures);
16
+ export const otpFeatureNames = Object.values(otpFeatures).map((f) => f.name);
17
+ export const sortedPasswordFeatures = topologicalSort(passwordFeatures);
18
+ export const passwordFeatureNames = Object.values(passwordFeatures).map((f) => f.name);
19
+ export const sortedUsernameFeatures = topologicalSort(usernameFeatures);
20
+ export const usernameFeatureNames = Object.values(usernameFeatures).map((f) => f.name);
21
+ export const sortedUsernameHiddenFeatures = topologicalSort(usernameHiddenFeatures);
22
+ export const usernameHiddenFeatureNames = Object.values(usernameHiddenFeatures).map((f) => f.name);
@@ -1,6 +1,6 @@
1
1
  import { kEmailSelector } from "@protontech/autofill/constants/selectors";
2
2
  import { feature, flattenFeatures } from "@protontech/autofill/features/feature";
3
- import { formFeaturesComputer } from "@protontech/autofill/features/v1/abstract.form";
3
+ import { getFormFeaturesComputer } from "@protontech/autofill/features/registry";
4
4
  import { any } from "@protontech/autofill/utils/combinators";
5
5
  import { matchCCFieldCandidate } from "@protontech/autofill/utils/credit-card";
6
6
  import { getFieldHaystacks } from "@protontech/autofill/utils/extract";
@@ -25,7 +25,7 @@ const parentFormFnode = feature("parentFormFnode", {}, (_, fnode) => getParentFo
25
25
  const parentFormFeatures = feature("parentFormFeatures", { parentFormFnode }, (p) => {
26
26
  const parent = p.parentFormFnode;
27
27
  if (parent && !parent.hasNoteFor("form"))
28
- parent.setNoteFor("form", formFeaturesComputer.compute(parent));
28
+ parent.setNoteFor("form", getFormFeaturesComputer().compute(parent));
29
29
  return parent === null || parent === void 0 ? void 0 : parent.noteFor("form");
30
30
  });
31
31
  const parentFormInputIterator = feature("parentFormInputIterator", { parentFormFeatures }, (p) => { var _a, _b; return (_b = (_a = p.parentFormFeatures) === null || _a === void 0 ? void 0 : _a.__inputIterator) !== null && _b !== void 0 ? _b : null; });