@raytio/core 8.1.3 → 9.0.3

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 (78) hide show
  1. package/README.md +104 -11
  2. package/dist/accessApplication/createAA.js +0 -1
  3. package/dist/crypto/decryptKeys.js +0 -2
  4. package/dist/crypto/helpers.d.ts +1 -1
  5. package/dist/general/index.d.ts +1 -0
  6. package/dist/general/index.js +1 -0
  7. package/dist/general/types.d.ts +6 -0
  8. package/dist/general/types.js +13 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +1 -0
  11. package/dist/rules/calculateScore.d.ts +11 -0
  12. package/dist/rules/calculateScore.js +52 -0
  13. package/dist/rules/convertInstanceToRuleInput.d.ts +3 -0
  14. package/dist/rules/convertInstanceToRuleInput.js +139 -0
  15. package/dist/rules/evaluateScoreCondition.d.ts +2 -0
  16. package/dist/rules/evaluateScoreCondition.js +45 -0
  17. package/dist/rules/helpers/addInfiniteThresholdBoundaries.d.ts +8 -0
  18. package/dist/rules/helpers/addInfiniteThresholdBoundaries.js +11 -0
  19. package/dist/rules/helpers/checkTypeofValue.d.ts +3 -0
  20. package/dist/rules/helpers/checkTypeofValue.js +43 -0
  21. package/dist/rules/helpers/getValuesFromPath.d.ts +3 -0
  22. package/dist/rules/helpers/getValuesFromPath.js +50 -0
  23. package/dist/rules/helpers/index.d.ts +5 -0
  24. package/dist/rules/helpers/index.js +17 -0
  25. package/dist/rules/helpers/symbols.d.ts +2 -0
  26. package/dist/rules/helpers/symbols.js +5 -0
  27. package/dist/rules/helpers/thresholds.d.ts +5 -0
  28. package/dist/rules/helpers/thresholds.js +47 -0
  29. package/dist/rules/index.d.ts +6 -0
  30. package/dist/rules/index.js +20 -0
  31. package/dist/rules/operators/bool.d.ts +2 -0
  32. package/dist/rules/operators/bool.js +17 -0
  33. package/dist/rules/operators/date.d.ts +2 -0
  34. package/dist/rules/operators/date.js +91 -0
  35. package/dist/rules/operators/hfield.d.ts +2 -0
  36. package/dist/rules/operators/hfield.js +33 -0
  37. package/dist/rules/operators/hschema.d.ts +2 -0
  38. package/dist/rules/operators/hschema.js +21 -0
  39. package/dist/rules/operators/index.d.ts +3 -0
  40. package/dist/rules/operators/index.js +11 -0
  41. package/dist/rules/operators/number.d.ts +2 -0
  42. package/dist/rules/operators/number.js +41 -0
  43. package/dist/rules/operators/string.d.ts +2 -0
  44. package/dist/rules/operators/string.js +58 -0
  45. package/dist/rules/types/config.d.ts +86 -0
  46. package/dist/rules/types/config.js +2 -0
  47. package/dist/rules/types/dataValueTypes.d.ts +19 -0
  48. package/dist/rules/types/dataValueTypes.js +4 -0
  49. package/dist/rules/types/index.d.ts +3 -0
  50. package/dist/rules/types/index.js +15 -0
  51. package/dist/rules/types/internal.d.ts +20 -0
  52. package/dist/rules/types/internal.js +2 -0
  53. package/dist/{verifications/checkVerifications.d.ts → util/canonicalJsonify.d.ts} +0 -0
  54. package/dist/util/canonicalJsonify.js +50 -0
  55. package/dist/util/handleResponse.js +0 -1
  56. package/dist/util/index.d.ts +1 -0
  57. package/dist/util/index.js +1 -0
  58. package/dist/verifications/getPOVerification.d.ts +5 -2
  59. package/dist/verifications/getPOVerification.js +4 -5
  60. package/dist/verifications/getVerifiedBy.js +1 -1
  61. package/dist/verifications/index.d.ts +1 -1
  62. package/dist/verifications/index.js +1 -2
  63. package/dist/verifications/safeHarbour.d.ts +1 -1
  64. package/dist/verifications/safeHarbour.js +2 -2
  65. package/dist/verifications/verifyCheck/getOwnRealVerifications.d.ts +13 -0
  66. package/dist/verifications/verifyCheck/getOwnRealVerifications.js +63 -0
  67. package/dist/verifications/verifyCheck/getSomeoneElsesRealVerifications.d.ts +19 -0
  68. package/dist/verifications/{getRealVerifications.js → verifyCheck/getSomeoneElsesRealVerifications.js} +21 -19
  69. package/dist/verifications/verifyCheck/index.d.ts +3 -0
  70. package/dist/verifications/verifyCheck/index.js +17 -0
  71. package/dist/verifications/verifyCheck/operations/checkOwnVerification.d.ts +15 -0
  72. package/dist/verifications/verifyCheck/operations/checkOwnVerification.js +39 -0
  73. package/dist/verifications/verifyCheck/operations/checkSomeoneElsesVerifications.d.ts +1 -0
  74. package/dist/verifications/{checkVerifications.js → verifyCheck/operations/checkSomeoneElsesVerifications.js} +4 -4
  75. package/dist/verifications/verifyCheck/operations/index.d.ts +2 -0
  76. package/dist/verifications/verifyCheck/operations/index.js +14 -0
  77. package/package.json +8 -8
  78. package/dist/verifications/getRealVerifications.d.ts +0 -22
package/README.md CHANGED
@@ -10,7 +10,7 @@ Nodejs does not support [fetch](https://developer.mozilla.org/en-US/docs/Web/API
10
10
 
11
11
  If you use the high-level [`@raytio/decrypt-helper`](https://npm.im/@raytio/decrypt-helper) module, you don't need to worry about this.
12
12
 
13
- If you wish to use `@raytio/core` directly, an example of configuring polyfills for nodejs is availble [here](https://gitlab.com/raytio/tools/decrypt-helper/-/blob/master/src/configureEnv.ts)
13
+ If you wish to use `@raytio/core` directly, an example of configuring polyfills for nodejs is availble [here](https://gitlab.com/raytio/tools/decrypt-helper/-/blob/main/src/configureEnv.ts)
14
14
 
15
15
  # API
16
16
 
@@ -24,14 +24,18 @@ If you wish to use `@raytio/core` directly, an example of configuring polyfills
24
24
  ### Functions
25
25
 
26
26
  - [calcSafeHarbourScore](#calcsafeharbourscore)
27
+ - [calculateScore](#calculatescore)
28
+ - [checkJsonSignature](#checkjsonsignature)
27
29
  - [cleanInstance](#cleaninstance)
30
+ - [convertInstanceToRuleInput](#convertinstancetoruleinput)
28
31
  - [createAA](#createaa)
29
32
  - [decryptSharedData](#decryptshareddata)
30
33
  - [findSchemaLabel](#findschemalabel)
31
34
  - [fromCognitoAttributes](#fromcognitoattributes)
32
35
  - [getAADecryptor](#getaadecryptor)
36
+ - [getOwnRealVerifications](#getownrealverifications)
33
37
  - [getPOVerification](#getpoverification)
34
- - [getRealVerifications](#getrealverifications)
38
+ - [getSomeoneElsesRealVerifications](#getsomeoneelsesrealverifications)
35
39
  - [hashPassword](#hashpassword)
36
40
  - [isConditionMet](#isconditionmet)
37
41
  - [isEncrypted](#isencrypted)
@@ -70,7 +74,7 @@ the response from [calcSafeHarbourScore](#calcsafeharbourscore)
70
74
 
71
75
  The Safe Harbour Score indidicates whether a person's identity has been verified
72
76
  to the extent requried for Safe Harbour Compliance. This requires multiple verifications
73
- from different sources. For infomation, refer to the
77
+ from different sources. For information, refer to the
74
78
  [Raytio Documentation](https://dev-docs.rayt.io/docs/features/pep-checks).
75
79
 
76
80
  #### Parameters
@@ -78,8 +82,8 @@ from different sources. For infomation, refer to the
78
82
  | Name | Type |
79
83
  | :------ | :------ |
80
84
  | `data` | `Object` |
81
- | `data.person` | `ProfileObject`<`any`\> |
82
- | `data.profileObjects` | `ProfileObject`<`any`\>[] |
85
+ | `data.person` | `ProfileObject`<`Json`\> |
86
+ | `data.profileObjects` | `ProfileObject`<`Json`\>[] |
83
87
  | `data.realVers` | `RealVer`[] |
84
88
  | `data.getSchema` | (`schemaName`: `string`) => `Promise`<`Schema`\> |
85
89
 
@@ -89,6 +93,47 @@ from different sources. For infomation, refer to the
89
93
 
90
94
  ___
91
95
 
96
+ ### calculateScore
97
+
98
+ ▸ **calculateScore**(`ruleConfig`, `ruleInput`): `ScoreResult`
99
+
100
+ the main function to calculate a score and category.
101
+ Might throw an error.
102
+
103
+ #### Parameters
104
+
105
+ | Name | Type |
106
+ | :------ | :------ |
107
+ | `ruleConfig` | `ScoreConfig` |
108
+ | `ruleInput` | `RuleData` |
109
+
110
+ #### Returns
111
+
112
+ `ScoreResult`
113
+
114
+ ___
115
+
116
+ ### checkJsonSignature
117
+
118
+ ▸ `Const` **checkJsonSignature**(`data`, `signature`): `Promise`<`boolean`\>
119
+
120
+ checks that a json object was signed by the provided signature. Unless you're
121
+ dealing with bundled verifications, you should use `getOwnRealVerifications`
122
+ or `getSomeoneElsesRealVerifications` instead.
123
+
124
+ #### Parameters
125
+
126
+ | Name | Type |
127
+ | :------ | :------ |
128
+ | `data` | `unknown` |
129
+ | `signature` | `string` |
130
+
131
+ #### Returns
132
+
133
+ `Promise`<`boolean`\>
134
+
135
+ ___
136
+
92
137
  ### cleanInstance
93
138
 
94
139
  ▸ **cleanInstance**(`instance`): `Instance`
@@ -111,6 +156,24 @@ We relace `hashed_n_id`s with a string `HASHED::{NId}::{AId}`
111
156
 
112
157
  ___
113
158
 
159
+ ### convertInstanceToRuleInput
160
+
161
+ ▸ `Const` **convertInstanceToRuleInput**(`instance`, `realVers`, `getSchema`): `Promise`<`RuleData`\>
162
+
163
+ #### Parameters
164
+
165
+ | Name | Type |
166
+ | :------ | :------ |
167
+ | `instance` | `Instance` |
168
+ | `realVers` | `RealVer`[] |
169
+ | `getSchema` | (`schemaName`: `string`) => `Promise`<`Schema`\> |
170
+
171
+ #### Returns
172
+
173
+ `Promise`<`RuleData`\>
174
+
175
+ ___
176
+
114
177
  ### createAA
115
178
 
116
179
  ▸ **createAA**(`__namedParameters`): `Promise`<`AA`\>
@@ -227,6 +290,32 @@ an `ApplicationEncryptor` and the public key of the Access Application
227
290
 
228
291
  ___
229
292
 
293
+ ### getOwnRealVerifications
294
+
295
+ ▸ `Const` **getOwnRealVerifications**(`__namedParameters`): `Promise`<`RealVer`[]\>
296
+
297
+ Given a list of verifications and decrypted profile objects, this function
298
+ locally verifies the credibility of the signatures in the verifications.
299
+
300
+ This function does NOT call the API, except to fetch the public key.
301
+
302
+ #### Parameters
303
+
304
+ | Name | Type |
305
+ | :------ | :------ |
306
+ | `__namedParameters` | `Object` |
307
+ | `__namedParameters.profileObjects` | `ProfileObject`<`Json`\>[] |
308
+ | `__namedParameters.userId` | `UId` |
309
+ | `__namedParameters.verifications` | `Verification`<``false``\>[] |
310
+
311
+ #### Returns
312
+
313
+ `Promise`<`RealVer`[]\>
314
+
315
+ a list of authentic RealVer
316
+
317
+ ___
318
+
230
319
  ### getPOVerification
231
320
 
232
321
  ▸ **getPOVerification**(`__namedParameters`): `Object`
@@ -238,7 +327,7 @@ Determines the verification status of a profile object, and its individual field
238
327
  | Name | Type |
239
328
  | :------ | :------ |
240
329
  | `__namedParameters` | `Object` |
241
- | `__namedParameters.PO` | `ProfileObject`<`any`\> \| `ProfileObjectForUpload`<`any`\> |
330
+ | `__namedParameters.PO` | `ProfileObject`<`Json`\> \| `ProfileObjectForUpload`<`Json`\> |
242
331
  | `__namedParameters.realVers` | `RealVer`[] |
243
332
  | `__namedParameters.schema` | `Schema` |
244
333
 
@@ -248,20 +337,24 @@ Determines the verification status of a profile object, and its individual field
248
337
 
249
338
  | Name | Type |
250
339
  | :------ | :------ |
251
- | `details` | `VerificationProvider`[] |
340
+ | `details` | `Object` |
341
+ | `details.sourceNId?` | `NId` |
342
+ | `details.verifiers` | `VerificationProvider`[] |
252
343
  | `fieldVerifications` | `Record`<`string`, `FieldVerification`\> |
253
344
  | `status` | `POVerification` |
254
345
 
255
346
  ___
256
347
 
257
- ### getRealVerifications
348
+ ### getSomeoneElsesRealVerifications
258
349
 
259
- ▸ `Const` **getRealVerifications**(`__namedParameters`): `Promise`<`RealVer`[]\>
350
+ ▸ `Const` **getSomeoneElsesRealVerifications**(`__namedParameters`): `Promise`<`RealVer`[]\>
260
351
 
261
352
  Given a list of verifications and decrypted profile objects, this function calls
262
353
  the Raytio API to verify the credibility of these verifications, returning only valid
263
354
  verifications.
264
355
 
356
+ ❗ prefer `getOwnRealVerifications` if the data to be verified belongs to the current user.
357
+
265
358
  #### Parameters
266
359
 
267
360
  | Name | Type |
@@ -360,7 +453,7 @@ ___
360
453
 
361
454
  ### someEncrypted
362
455
 
363
- ▸ `Const` **someEncrypted**<`T`, `K`\>(`x`): `number`
456
+ ▸ `Const` **someEncrypted**<`T`, `K`\>(...`args`): `number`
364
457
 
365
458
  Given a profile object's properties, returns the number
366
459
  of properties that are encryted.
@@ -376,7 +469,7 @@ of properties that are encryted.
376
469
 
377
470
  | Name | Type |
378
471
  | :------ | :------ |
379
- | `x` | `T` |
472
+ | `...args` | [obj: T] |
380
473
 
381
474
  #### Returns
382
475
 
@@ -46,7 +46,6 @@ async function createApplicationEncryptor(userDoc, maxcryptor) {
46
46
  */
47
47
  async function createAA({ apiUrl, apiToken, userDoc, maxcryptor, application, }) {
48
48
  if (!application.org_id) {
49
- // eslint-disable-next-line fp/no-throw
50
49
  throw new Error("Cannot create an AA without an org_id");
51
50
  }
52
51
  const newApp = await createApplication({
@@ -13,7 +13,6 @@ const decryptKeys = async ({ applicationDecryptor, keys, data, onCorruptedData,
13
13
  const error = new Error(`Can't decrypt shared data because there are no keys for ${key}`);
14
14
  if (onCorruptedData)
15
15
  return [key, onCorruptedData(key, value, error)];
16
- // eslint-disable-next-line fp/no-throw
17
16
  throw error;
18
17
  }
19
18
  try {
@@ -26,7 +25,6 @@ const decryptKeys = async ({ applicationDecryptor, keys, data, onCorruptedData,
26
25
  const error = _ex instanceof Error ? _ex : new Error(`${_ex}`);
27
26
  if (onCorruptedData)
28
27
  return [key, onCorruptedData(key, value, error)];
29
- // eslint-disable-next-line fp/no-throw
30
28
  throw error;
31
29
  }
32
30
  }));
@@ -15,4 +15,4 @@ export declare const isEncryptedFile: (value: unknown) => value is Encrypted<str
15
15
  * Given a profile object's properties, returns the number
16
16
  * of properties that are encryted.
17
17
  */
18
- export declare const someEncrypted: <T extends object, K extends keyof T>(x: T) => number;
18
+ export declare const someEncrypted: <T extends object, K extends keyof T>(obj: T) => number;
@@ -1,2 +1,3 @@
1
1
  export * from "./conditional";
2
2
  export * from "./password";
3
+ export * from "./types";
@@ -12,3 +12,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  __exportStar(require("./conditional"), exports);
14
14
  __exportStar(require("./password"), exports);
15
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,6 @@
1
+ /**
2
+ * to prevent a key from the JS object prototype (e.g. `__proto__`) from
3
+ * returning an unexpected value (see #1162)
4
+ * @ignore
5
+ */
6
+ export declare function assertSafeProperty(key: string): asserts key is string;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertSafeProperty = void 0;
4
+ /**
5
+ * to prevent a key from the JS object prototype (e.g. `__proto__`) from
6
+ * returning an unexpected value (see #1162)
7
+ * @ignore
8
+ */
9
+ function assertSafeProperty(key) {
10
+ if (key in {})
11
+ throw new Error("Unacceptable object property");
12
+ }
13
+ exports.assertSafeProperty = assertSafeProperty;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./accessApplication";
2
2
  export * from "./crypto";
3
3
  export * from "./general";
4
+ export * from "./rules";
4
5
  export * from "./schema";
5
6
  export * from "./verifications";
package/dist/index.js CHANGED
@@ -13,5 +13,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  __exportStar(require("./accessApplication"), exports);
14
14
  __exportStar(require("./crypto"), exports);
15
15
  __exportStar(require("./general"), exports);
16
+ __exportStar(require("./rules"), exports);
16
17
  __exportStar(require("./schema"), exports);
17
18
  __exportStar(require("./verifications"), exports);
@@ -0,0 +1,11 @@
1
+ import { RuleData, ScoreConfig } from "./types";
2
+ /** @ignore */
3
+ export declare type ScoreResult = {
4
+ score: number;
5
+ category: string;
6
+ };
7
+ /**
8
+ * the main function to calculate a score and category.
9
+ * Might throw an error.
10
+ */
11
+ export declare function calculateScore(ruleConfig: ScoreConfig, ruleInput: RuleData): ScoreResult;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateScore = void 0;
4
+ const evaluateScoreCondition_1 = require("./evaluateScoreCondition");
5
+ const helpers_1 = require("./helpers");
6
+ function evaluateASTNode(node, data) {
7
+ if (node.type === "LanguageOperator") {
8
+ if (!node.children.length) {
9
+ // we allow a single child because why not.
10
+ throw new Error("LanguageOperator has no children");
11
+ }
12
+ if (node.operator === "AND") {
13
+ return node.children.every(n => evaluateASTNode(n, data));
14
+ }
15
+ if (node.operator === "OR") {
16
+ return node.children.some(n => evaluateASTNode(n, data));
17
+ }
18
+ throw new Error(`LanguageOperator node has invalid operator '${node.operator}'`);
19
+ }
20
+ if (node.type === "ScoreCondition") {
21
+ return (0, evaluateScoreCondition_1.evaluateScoreCondition)(node, data);
22
+ }
23
+ throw new Error("ASTNode has invalid type");
24
+ }
25
+ function evaluateRule(rule, data) {
26
+ if (rule.tree.length !== 1) {
27
+ throw new Error("A rule may only have 1 root node");
28
+ }
29
+ const rulePassed = rule.tree.every(n => evaluateASTNode(n, data));
30
+ return rulePassed ? rule.trueWeight : rule.falseWeight;
31
+ }
32
+ /**
33
+ * the main function to calculate a score and category.
34
+ * Might throw an error.
35
+ */
36
+ function calculateScore(ruleConfig, ruleInput) {
37
+ const result = ruleConfig.rules.map(rule => evaluateRule(rule, ruleInput));
38
+ const [addOrMultiply, initialValue] = (0, helpers_1.getCombinator)(ruleConfig.combinator);
39
+ const finalScore = result.reduce(addOrMultiply, initialValue);
40
+ const matchingCategories = (0, helpers_1.addInfiniteThresholdBoundaries)(ruleConfig.scoreThresholds).filter(threshold => finalScore >= threshold.from && finalScore <= threshold.to);
41
+ if (matchingCategories.length === 0) {
42
+ throw new Error(`No categories match the final score (${finalScore})`);
43
+ }
44
+ if (matchingCategories.length !== 1) {
45
+ throw new Error(`Multiple categories match the final score (${finalScore})`);
46
+ }
47
+ return {
48
+ score: finalScore,
49
+ category: matchingCategories[0].name,
50
+ };
51
+ }
52
+ exports.calculateScore = calculateScore;
@@ -0,0 +1,3 @@
1
+ import { Instance, RealVer, Schema } from "@raytio/types";
2
+ import { RuleData } from "./types";
3
+ export declare const convertInstanceToRuleInput: (instance: Instance, realVers: RealVer[], getSchema: (schemaName: string) => Promise<Schema>) => Promise<RuleData>;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertInstanceToRuleInput = void 0;
4
+ const ramda_1 = require("ramda");
5
+ const verifications_1 = require("../verifications");
6
+ const schema_1 = require("../schema");
7
+ const helpers_1 = require("./helpers");
8
+ // has to be hardcodede since we're in @raytio/core
9
+ const VERIFICATION_SCHEMA = "ss_Verification";
10
+ /**
11
+ * this is only called for field values, so we can easily work out the type
12
+ * There are no complications like POVerification or DateUnits
13
+ */
14
+ function getTypeofFieldValue(value) {
15
+ if (Array.isArray(value))
16
+ return "Array";
17
+ if (typeof value === "boolean")
18
+ return "Bool";
19
+ if (typeof value === "number")
20
+ return "Number";
21
+ if (typeof value === "string")
22
+ return "String";
23
+ return undefined;
24
+ }
25
+ const isDateField = (schema) => ([fieldName]) => {
26
+ var _a;
27
+ return (_a = schema.properties[fieldName].tags) === null || _a === void 0 ? void 0 : _a.some(tag => tag.startsWith("group:date_picker"));
28
+ };
29
+ const convertInstanceToRuleInput = async (instance, realVers, getSchema) => {
30
+ const out = {};
31
+ // eslint-disable-next-line fp/no-loops
32
+ for (const PO of instance.profile_objects) {
33
+ const schemaName = (0, schema_1.findSchemaLabel)(PO.labels);
34
+ // eslint-disable-next-line no-continue
35
+ if (schemaName === VERIFICATION_SCHEMA)
36
+ continue;
37
+ const schema = await getSchema(schemaName);
38
+ const verified = (0, verifications_1.getPOVerification)({ PO, schema, realVers });
39
+ // remove anything we can't make rules for (e.g. object), and
40
+ // also remove any fields that aren't defined in the schema.
41
+ const validFields = Object.entries(PO.properties).filter(([fieldName, value]) => getTypeofFieldValue(value) && schema.properties[fieldName]);
42
+ const nonDateProperties = validFields
43
+ .filter(d => !isDateField(schema)(d))
44
+ .map(([fieldName, value]) => {
45
+ var _a;
46
+ const verifiedBy = (0, ramda_1.uniq)((_a = realVers
47
+ .filter(x => x.belongsToNId === PO.n_id &&
48
+ x.fieldName === fieldName &&
49
+ x.provider.verifierNId)) === null || _a === void 0 ? void 0 : _a.map(x => x.provider.verifierNId));
50
+ const field = {
51
+ hField: {
52
+ __typeof__: helpers_1.HFieldSymbol,
53
+ cameFromSchema: schemaName,
54
+ verification: verified.fieldVerifications[fieldName],
55
+ verifiedBy,
56
+ },
57
+ type: getTypeofFieldValue(value),
58
+ value,
59
+ };
60
+ return [fieldName, field];
61
+ });
62
+ const dateFieldByCategorys = (0, ramda_1.groupBy)(([fieldName]) => schema.properties[fieldName].tags.find(tag => tag.startsWith("group:date_picker")), validFields.filter(isDateField(schema)));
63
+ // the three date fields become one pseudo field for the score system
64
+ const pseudoDateFields = Object.entries(dateFieldByCategorys).map(([groupTag, members]) => {
65
+ var _a;
66
+ const groupName = groupTag.split(":")[2] || "NO_NAME";
67
+ const memberFieldNames = members.map(x => x[0]);
68
+ const worstVer = (0, ramda_1.sort)((a, b) => b - a, // find the highest enum value (that's the worst)
69
+ memberFieldNames.map(f => verified.fieldVerifications[f]))[0];
70
+ const fieldVers = (0, ramda_1.uniq)((_a = realVers
71
+ .filter(x => x.belongsToNId === PO.n_id &&
72
+ memberFieldNames.includes(x.fieldName) &&
73
+ x.provider.verifierNId)) === null || _a === void 0 ? void 0 : _a.map(v => v.provider.verifierNId).filter((val) => !!val));
74
+ const values = Object.fromEntries(members);
75
+ const dayFieldName = memberFieldNames.find(f => { var _a; return (_a = schema.properties[f].tags) === null || _a === void 0 ? void 0 : _a.includes("date_component:day"); });
76
+ const monthFieldName = memberFieldNames.find(f => { var _a; return (_a = schema.properties[f].tags) === null || _a === void 0 ? void 0 : _a.includes("date_component:month"); });
77
+ const yearFieldName = memberFieldNames.find(f => { var _a; return (_a = schema.properties[f].tags) === null || _a === void 0 ? void 0 : _a.includes("date_component:year"); });
78
+ if (!dayFieldName || !monthFieldName || !yearFieldName) {
79
+ throw new Error("Failed to infer date component field");
80
+ }
81
+ const isoString = [
82
+ values[yearFieldName],
83
+ `${values[monthFieldName]}`.padStart(2, "0"),
84
+ `${values[dayFieldName]}`.padStart(2, "0"),
85
+ ].join("-");
86
+ const pseudoField = {
87
+ hField: {
88
+ __typeof__: helpers_1.HFieldSymbol,
89
+ cameFromSchema: schemaName,
90
+ verification: worstVer,
91
+ verifiedBy: fieldVers,
92
+ },
93
+ type: "Date",
94
+ value: new Date(isoString),
95
+ };
96
+ return [`__group_${groupName}`, pseudoField];
97
+ });
98
+ const deepProperties = Object.entries(PO.properties)
99
+ .filter(([fieldName, fieldValue]) => {
100
+ const field = schema.properties[fieldName];
101
+ return (field &&
102
+ field.type === "object" &&
103
+ field.properties &&
104
+ fieldValue &&
105
+ typeof fieldValue === "object");
106
+ })
107
+ .flatMap(([fieldName, fieldValue]) => {
108
+ const subFields = Object.keys(schema.properties[fieldName].properties);
109
+ return subFields.map(subFieldName => {
110
+ const value = fieldValue[subFieldName];
111
+ const hsubfield = {
112
+ hField: null,
113
+ type: getTypeofFieldValue(value),
114
+ value,
115
+ };
116
+ return [`${fieldName}|${subFieldName}`, hsubfield];
117
+ });
118
+ });
119
+ // eslint-disable-next-line fp/no-mutation
120
+ out[schemaName] || (out[schemaName] = []);
121
+ // eslint-disable-next-line fp/no-mutating-methods
122
+ out[schemaName].push({
123
+ hSchema: {
124
+ __typeof__: helpers_1.HSchemaSymbol,
125
+ verification: verified.status,
126
+ verifiedBy: verified.details.verifiers
127
+ .map(x => x.verifierNId)
128
+ .filter((val) => !!val),
129
+ },
130
+ properties: Object.fromEntries([
131
+ ...nonDateProperties,
132
+ ...pseudoDateFields,
133
+ ...deepProperties,
134
+ ]),
135
+ });
136
+ }
137
+ return out;
138
+ };
139
+ exports.convertInstanceToRuleInput = convertInstanceToRuleInput;
@@ -0,0 +1,2 @@
1
+ import { ASTScoreConditionNode, RuleData } from "./types";
2
+ export declare function evaluateScoreCondition(node: ASTScoreConditionNode, data: RuleData): boolean;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.evaluateScoreCondition = void 0;
4
+ /* eslint-disable fp/no-loops */
5
+ const ramda_1 = require("ramda");
6
+ const general_1 = require("../general");
7
+ const operators_1 = require("./operators");
8
+ const helpers_1 = require("./helpers");
9
+ function evaluateScoreCondition(node, data) {
10
+ (0, general_1.assertSafeProperty)(node.operator);
11
+ const op = operators_1.operators[node.operator];
12
+ if (!op) {
13
+ throw new Error(`Operator '${node.operator}' is not known`);
14
+ }
15
+ if (node.values.length !== op.operands.length) {
16
+ throw new Error(`Operator argument length mismatch for '${node.operator}'`);
17
+ }
18
+ const rawValues = node.values
19
+ .map(x => x.value.type === "constant"
20
+ ? [x.value.value]
21
+ : (0, helpers_1.getValuesFromPath)(x.value.path, data))
22
+ .map(valuesForArg => valuesForArg.filter(v => typeof v !== "undefined"));
23
+ for (const [i, argType] of op.operands.entries()) {
24
+ if (argType !== node.values[i].type) {
25
+ throw new TypeError(`Operator argument ${i} expected ${argType} but got ${node.values[i].type} for '${node.operator}'`);
26
+ }
27
+ const values = rawValues[i];
28
+ if (!values.length) {
29
+ // TODO: if one of the values required for your rule doesn't exist, then what?
30
+ // for now, the rule will return value
31
+ return false;
32
+ }
33
+ // also check if the claimed type of the value matches the actual type of the value
34
+ for (const value of values) {
35
+ if (!(0, helpers_1.checkTypeofValue)(argType, value)) {
36
+ throw new Error(`Operator argument ${i} falsely claimed to be ${argType} for '${node.operator}'`);
37
+ }
38
+ }
39
+ }
40
+ const options = (0, ramda_1.transpose)(rawValues);
41
+ // everything adds up so far, so we can call the function for each
42
+ // data value. Return true if ANY of the values return true.
43
+ return options.some(args => op.implementation(...args));
44
+ }
45
+ exports.evaluateScoreCondition = evaluateScoreCondition;
@@ -0,0 +1,8 @@
1
+ import { ScoreThreshold } from "../types";
2
+ /**
3
+ * @ignore the first and last threshold boundaries are -Infinity and +Infinity.
4
+ * We override whatever is specified to ensure these boundaries are infinite.
5
+ *
6
+ * This is also needed because json converts non-finite numbers to `null`
7
+ */
8
+ export declare const addInfiniteThresholdBoundaries: (list: readonly ScoreThreshold[]) => ScoreThreshold[];
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addInfiniteThresholdBoundaries = void 0;
4
+ const ramda_1 = require("ramda");
5
+ /**
6
+ * @ignore the first and last threshold boundaries are -Infinity and +Infinity.
7
+ * We override whatever is specified to ensure these boundaries are infinite.
8
+ *
9
+ * This is also needed because json converts non-finite numbers to `null`
10
+ */
11
+ exports.addInfiniteThresholdBoundaries = (0, ramda_1.pipe)((0, ramda_1.adjust)(0, v => (Object.assign(Object.assign({}, v), { from: -Infinity }))), (0, ramda_1.adjust)(-1, v => (Object.assign(Object.assign({}, v), { to: Infinity }))));
@@ -0,0 +1,3 @@
1
+ import { GetTSType, ValueType } from "../types";
2
+ /** asserts that the provided `value` meets the constaints of `type` */
3
+ export declare function checkTypeofValue<T extends ValueType>(type: T, value: unknown): value is GetTSType<T>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkTypeofValue = void 0;
4
+ const types_1 = require("@raytio/types");
5
+ const symbols_1 = require("./symbols");
6
+ const types_2 = require("../types");
7
+ const VALID_DATE_UNITS = types_2.DATE_UNITS;
8
+ // we need this function beacuse TS's typeguards aren't great
9
+ const isObjectWithTypeofProp = (x) => typeof x === "object" && !!x && "__typeof__" in x;
10
+ /** asserts that the provided `value` meets the constaints of `type` */
11
+ function checkTypeofValue(type, value) {
12
+ switch (type) {
13
+ case "Array":
14
+ return Array.isArray(value);
15
+ case "Bool":
16
+ return typeof value === "boolean";
17
+ case "Date":
18
+ return value instanceof Date;
19
+ case "DateUnit":
20
+ return typeof value === "string" && VALID_DATE_UNITS.includes(value);
21
+ case "FieldVerification":
22
+ return typeof value === "number" && value in types_1.FieldVerification;
23
+ case "HField":
24
+ // this is fakeable (you could make a constant object with these props),
25
+ // but that's not a concern in this context.
26
+ return isObjectWithTypeofProp(value) && value.__typeof__ === symbols_1.HFieldSymbol;
27
+ case "HSchema":
28
+ // this is fakeable (you could make a constant object with these props),
29
+ // but that's not a concern in this context.
30
+ return (isObjectWithTypeofProp(value) && value.__typeof__ === symbols_1.HSchemaSymbol);
31
+ case "Number":
32
+ return typeof value === "number";
33
+ case "POVerification":
34
+ return typeof value === "number" && value in types_1.POVerification;
35
+ case "RegEx":
36
+ return value instanceof RegExp;
37
+ case "String":
38
+ return typeof value === "string";
39
+ default:
40
+ return false;
41
+ }
42
+ }
43
+ exports.checkTypeofValue = checkTypeofValue;
@@ -0,0 +1,3 @@
1
+ import { RuleData, ValuePath } from "../types";
2
+ /** this returns an array because there might be multiple of the same schema shared */
3
+ export declare function getValuesFromPath(path: ValuePath, data: RuleData): unknown[];