@raytio/core 8.1.3 → 9.0.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.
- package/README.md +82 -11
- package/dist/accessApplication/createAA.js +0 -1
- package/dist/crypto/decryptKeys.js +0 -2
- package/dist/crypto/helpers.d.ts +1 -1
- package/dist/general/index.d.ts +1 -0
- package/dist/general/index.js +1 -0
- package/dist/general/types.d.ts +6 -0
- package/dist/general/types.js +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/rules/calculateScore.d.ts +11 -0
- package/dist/rules/calculateScore.js +52 -0
- package/dist/rules/convertInstanceToRuleInput.d.ts +3 -0
- package/dist/rules/convertInstanceToRuleInput.js +140 -0
- package/dist/rules/evaluateScoreCondition.d.ts +2 -0
- package/dist/rules/evaluateScoreCondition.js +45 -0
- package/dist/rules/helpers/addInfiniteThresholdBoundaries.d.ts +8 -0
- package/dist/rules/helpers/addInfiniteThresholdBoundaries.js +11 -0
- package/dist/rules/helpers/checkTypeofValue.d.ts +3 -0
- package/dist/rules/helpers/checkTypeofValue.js +43 -0
- package/dist/rules/helpers/getValuesFromPath.d.ts +3 -0
- package/dist/rules/helpers/getValuesFromPath.js +50 -0
- package/dist/rules/helpers/index.d.ts +5 -0
- package/dist/rules/helpers/index.js +17 -0
- package/dist/rules/helpers/symbols.d.ts +2 -0
- package/dist/rules/helpers/symbols.js +5 -0
- package/dist/rules/helpers/thresholds.d.ts +5 -0
- package/dist/rules/helpers/thresholds.js +47 -0
- package/dist/rules/index.d.ts +6 -0
- package/dist/rules/index.js +20 -0
- package/dist/rules/operators/bool.d.ts +2 -0
- package/dist/rules/operators/bool.js +17 -0
- package/dist/rules/operators/date.d.ts +2 -0
- package/dist/rules/operators/date.js +91 -0
- package/dist/rules/operators/hfield.d.ts +2 -0
- package/dist/rules/operators/hfield.js +33 -0
- package/dist/rules/operators/hschema.d.ts +2 -0
- package/dist/rules/operators/hschema.js +21 -0
- package/dist/rules/operators/index.d.ts +3 -0
- package/dist/rules/operators/index.js +11 -0
- package/dist/rules/operators/number.d.ts +2 -0
- package/dist/rules/operators/number.js +41 -0
- package/dist/rules/operators/string.d.ts +2 -0
- package/dist/rules/operators/string.js +58 -0
- package/dist/rules/types/config.d.ts +86 -0
- package/dist/rules/types/config.js +2 -0
- package/dist/rules/types/dataValueTypes.d.ts +19 -0
- package/dist/rules/types/dataValueTypes.js +4 -0
- package/dist/rules/types/index.d.ts +3 -0
- package/dist/rules/types/index.js +15 -0
- package/dist/rules/types/internal.d.ts +20 -0
- package/dist/rules/types/internal.js +2 -0
- package/dist/{verifications/checkVerifications.d.ts → util/canonicalJsonify.d.ts} +0 -0
- package/dist/util/canonicalJsonify.js +48 -0
- package/dist/util/handleResponse.js +0 -1
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.js +1 -0
- package/dist/verifications/getPOVerification.d.ts +5 -2
- package/dist/verifications/getPOVerification.js +3 -4
- package/dist/verifications/index.d.ts +1 -1
- package/dist/verifications/index.js +1 -1
- package/dist/verifications/safeHarbour.d.ts +1 -1
- package/dist/verifications/safeHarbour.js +2 -2
- package/dist/verifications/verifyCheck/getOwnRealVerifications.d.ts +13 -0
- package/dist/verifications/verifyCheck/getOwnRealVerifications.js +63 -0
- package/dist/verifications/{getRealVerifications.d.ts → verifyCheck/getSomeoneElsesRealVerifications.d.ts} +6 -2
- package/dist/verifications/{getRealVerifications.js → verifyCheck/getSomeoneElsesRealVerifications.js} +22 -15
- package/dist/verifications/verifyCheck/index.d.ts +2 -0
- package/dist/verifications/verifyCheck/index.js +14 -0
- package/dist/verifications/verifyCheck/operations/checkOwnVerification.d.ts +9 -0
- package/dist/verifications/verifyCheck/operations/checkOwnVerification.js +31 -0
- package/dist/verifications/verifyCheck/operations/checkSomeoneElsesVerifications.d.ts +1 -0
- package/dist/verifications/{checkVerifications.js → verifyCheck/operations/checkSomeoneElsesVerifications.js} +4 -4
- package/dist/verifications/verifyCheck/operations/index.d.ts +2 -0
- package/dist/verifications/verifyCheck/operations/index.js +14 -0
- package/package.json +7 -7
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/
|
|
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,17 @@ 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)
|
|
27
28
|
- [cleanInstance](#cleaninstance)
|
|
29
|
+
- [convertInstanceToRuleInput](#convertinstancetoruleinput)
|
|
28
30
|
- [createAA](#createaa)
|
|
29
31
|
- [decryptSharedData](#decryptshareddata)
|
|
30
32
|
- [findSchemaLabel](#findschemalabel)
|
|
31
33
|
- [fromCognitoAttributes](#fromcognitoattributes)
|
|
32
34
|
- [getAADecryptor](#getaadecryptor)
|
|
35
|
+
- [getOwnRealVerifications](#getownrealverifications)
|
|
33
36
|
- [getPOVerification](#getpoverification)
|
|
34
|
-
- [
|
|
37
|
+
- [getSomeoneElsesRealVerifications](#getsomeoneelsesrealverifications)
|
|
35
38
|
- [hashPassword](#hashpassword)
|
|
36
39
|
- [isConditionMet](#isconditionmet)
|
|
37
40
|
- [isEncrypted](#isencrypted)
|
|
@@ -70,7 +73,7 @@ the response from [calcSafeHarbourScore](#calcsafeharbourscore)
|
|
|
70
73
|
|
|
71
74
|
The Safe Harbour Score indidicates whether a person's identity has been verified
|
|
72
75
|
to the extent requried for Safe Harbour Compliance. This requires multiple verifications
|
|
73
|
-
from different sources. For
|
|
76
|
+
from different sources. For information, refer to the
|
|
74
77
|
[Raytio Documentation](https://dev-docs.rayt.io/docs/features/pep-checks).
|
|
75
78
|
|
|
76
79
|
#### Parameters
|
|
@@ -78,8 +81,8 @@ from different sources. For infomation, refer to the
|
|
|
78
81
|
| Name | Type |
|
|
79
82
|
| :------ | :------ |
|
|
80
83
|
| `data` | `Object` |
|
|
81
|
-
| `data.person` | `ProfileObject`<`
|
|
82
|
-
| `data.profileObjects` | `ProfileObject`<`
|
|
84
|
+
| `data.person` | `ProfileObject`<`Json`\> |
|
|
85
|
+
| `data.profileObjects` | `ProfileObject`<`Json`\>[] |
|
|
83
86
|
| `data.realVers` | `RealVer`[] |
|
|
84
87
|
| `data.getSchema` | (`schemaName`: `string`) => `Promise`<`Schema`\> |
|
|
85
88
|
|
|
@@ -89,6 +92,26 @@ from different sources. For infomation, refer to the
|
|
|
89
92
|
|
|
90
93
|
___
|
|
91
94
|
|
|
95
|
+
### calculateScore
|
|
96
|
+
|
|
97
|
+
▸ **calculateScore**(`ruleConfig`, `ruleInput`): `ScoreResult`
|
|
98
|
+
|
|
99
|
+
the main function to calculate a score and category.
|
|
100
|
+
Might throw an error.
|
|
101
|
+
|
|
102
|
+
#### Parameters
|
|
103
|
+
|
|
104
|
+
| Name | Type |
|
|
105
|
+
| :------ | :------ |
|
|
106
|
+
| `ruleConfig` | `ScoreConfig` |
|
|
107
|
+
| `ruleInput` | `RuleData` |
|
|
108
|
+
|
|
109
|
+
#### Returns
|
|
110
|
+
|
|
111
|
+
`ScoreResult`
|
|
112
|
+
|
|
113
|
+
___
|
|
114
|
+
|
|
92
115
|
### cleanInstance
|
|
93
116
|
|
|
94
117
|
▸ **cleanInstance**(`instance`): `Instance`
|
|
@@ -111,6 +134,24 @@ We relace `hashed_n_id`s with a string `HASHED::{NId}::{AId}`
|
|
|
111
134
|
|
|
112
135
|
___
|
|
113
136
|
|
|
137
|
+
### convertInstanceToRuleInput
|
|
138
|
+
|
|
139
|
+
▸ `Const` **convertInstanceToRuleInput**(`instance`, `realVers`, `getSchema`): `Promise`<`RuleData`\>
|
|
140
|
+
|
|
141
|
+
#### Parameters
|
|
142
|
+
|
|
143
|
+
| Name | Type |
|
|
144
|
+
| :------ | :------ |
|
|
145
|
+
| `instance` | `Instance` |
|
|
146
|
+
| `realVers` | `RealVer`[] |
|
|
147
|
+
| `getSchema` | (`schemaName`: `string`) => `Promise`<`Schema`\> |
|
|
148
|
+
|
|
149
|
+
#### Returns
|
|
150
|
+
|
|
151
|
+
`Promise`<`RuleData`\>
|
|
152
|
+
|
|
153
|
+
___
|
|
154
|
+
|
|
114
155
|
### createAA
|
|
115
156
|
|
|
116
157
|
▸ **createAA**(`__namedParameters`): `Promise`<`AA`\>
|
|
@@ -227,6 +268,32 @@ an `ApplicationEncryptor` and the public key of the Access Application
|
|
|
227
268
|
|
|
228
269
|
___
|
|
229
270
|
|
|
271
|
+
### getOwnRealVerifications
|
|
272
|
+
|
|
273
|
+
▸ `Const` **getOwnRealVerifications**(`__namedParameters`): `Promise`<`RealVer`[]\>
|
|
274
|
+
|
|
275
|
+
Given a list of verifications and decrypted profile objects, this function
|
|
276
|
+
locally verifies the credibility of the signatures in the verifications.
|
|
277
|
+
|
|
278
|
+
This function does NOT call the API, except to fetch the public key.
|
|
279
|
+
|
|
280
|
+
#### Parameters
|
|
281
|
+
|
|
282
|
+
| Name | Type |
|
|
283
|
+
| :------ | :------ |
|
|
284
|
+
| `__namedParameters` | `Object` |
|
|
285
|
+
| `__namedParameters.profileObjects` | `ProfileObject`<`Json`\>[] |
|
|
286
|
+
| `__namedParameters.userId` | `UId` |
|
|
287
|
+
| `__namedParameters.verifications` | `Verification`<``false``\>[] |
|
|
288
|
+
|
|
289
|
+
#### Returns
|
|
290
|
+
|
|
291
|
+
`Promise`<`RealVer`[]\>
|
|
292
|
+
|
|
293
|
+
a list of authentic RealVer
|
|
294
|
+
|
|
295
|
+
___
|
|
296
|
+
|
|
230
297
|
### getPOVerification
|
|
231
298
|
|
|
232
299
|
▸ **getPOVerification**(`__namedParameters`): `Object`
|
|
@@ -238,7 +305,7 @@ Determines the verification status of a profile object, and its individual field
|
|
|
238
305
|
| Name | Type |
|
|
239
306
|
| :------ | :------ |
|
|
240
307
|
| `__namedParameters` | `Object` |
|
|
241
|
-
| `__namedParameters.PO` | `ProfileObject`<`
|
|
308
|
+
| `__namedParameters.PO` | `ProfileObject`<`Json`\> \| `ProfileObjectForUpload`<`Json`\> |
|
|
242
309
|
| `__namedParameters.realVers` | `RealVer`[] |
|
|
243
310
|
| `__namedParameters.schema` | `Schema` |
|
|
244
311
|
|
|
@@ -248,20 +315,24 @@ Determines the verification status of a profile object, and its individual field
|
|
|
248
315
|
|
|
249
316
|
| Name | Type |
|
|
250
317
|
| :------ | :------ |
|
|
251
|
-
| `details` | `
|
|
318
|
+
| `details` | `Object` |
|
|
319
|
+
| `details.sourceNId?` | `NId` |
|
|
320
|
+
| `details.verifiers` | `VerificationProvider`[] |
|
|
252
321
|
| `fieldVerifications` | `Record`<`string`, `FieldVerification`\> |
|
|
253
322
|
| `status` | `POVerification` |
|
|
254
323
|
|
|
255
324
|
___
|
|
256
325
|
|
|
257
|
-
###
|
|
326
|
+
### getSomeoneElsesRealVerifications
|
|
258
327
|
|
|
259
|
-
▸ `Const` **
|
|
328
|
+
▸ `Const` **getSomeoneElsesRealVerifications**(`__namedParameters`): `Promise`<`RealVer`[]\>
|
|
260
329
|
|
|
261
330
|
Given a list of verifications and decrypted profile objects, this function calls
|
|
262
331
|
the Raytio API to verify the credibility of these verifications, returning only valid
|
|
263
332
|
verifications.
|
|
264
333
|
|
|
334
|
+
❗ prefer `getOwnRealVerifications` if the data to be verified belongs to the current user.
|
|
335
|
+
|
|
265
336
|
#### Parameters
|
|
266
337
|
|
|
267
338
|
| Name | Type |
|
|
@@ -360,7 +431,7 @@ ___
|
|
|
360
431
|
|
|
361
432
|
### someEncrypted
|
|
362
433
|
|
|
363
|
-
▸ `Const` **someEncrypted**<`T`, `K`\>(`
|
|
434
|
+
▸ `Const` **someEncrypted**<`T`, `K`\>(...`args`): `number`
|
|
364
435
|
|
|
365
436
|
Given a profile object's properties, returns the number
|
|
366
437
|
of properties that are encryted.
|
|
@@ -376,7 +447,7 @@ of properties that are encryted.
|
|
|
376
447
|
|
|
377
448
|
| Name | Type |
|
|
378
449
|
| :------ | :------ |
|
|
379
|
-
| `
|
|
450
|
+
| `...args` | [obj: T] |
|
|
380
451
|
|
|
381
452
|
#### Returns
|
|
382
453
|
|
|
@@ -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
|
}));
|
package/dist/crypto/helpers.d.ts
CHANGED
|
@@ -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>(
|
|
18
|
+
export declare const someEncrypted: <T extends object, K extends keyof T>(obj: T) => number;
|
package/dist/general/index.d.ts
CHANGED
package/dist/general/index.js
CHANGED
|
@@ -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,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
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,140 @@
|
|
|
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
|
+
// TODO: better system
|
|
76
|
+
const dayFieldName = memberFieldNames.find(f => f.includes("day"));
|
|
77
|
+
const monthFieldName = memberFieldNames.find(f => f.includes("month"));
|
|
78
|
+
const yearFieldName = memberFieldNames.find(f => f.includes("year"));
|
|
79
|
+
if (!dayFieldName || !monthFieldName || !yearFieldName) {
|
|
80
|
+
throw new Error("Failed to infer date component field");
|
|
81
|
+
}
|
|
82
|
+
const isoString = [
|
|
83
|
+
values[yearFieldName],
|
|
84
|
+
`${values[monthFieldName]}`.padStart(2, "0"),
|
|
85
|
+
`${values[dayFieldName]}`.padStart(2, "0"),
|
|
86
|
+
].join("-");
|
|
87
|
+
const pseudoField = {
|
|
88
|
+
hField: {
|
|
89
|
+
__typeof__: helpers_1.HFieldSymbol,
|
|
90
|
+
cameFromSchema: schemaName,
|
|
91
|
+
verification: worstVer,
|
|
92
|
+
verifiedBy: fieldVers,
|
|
93
|
+
},
|
|
94
|
+
type: "Date",
|
|
95
|
+
value: new Date(isoString),
|
|
96
|
+
};
|
|
97
|
+
return [`__group_${groupName}`, pseudoField];
|
|
98
|
+
});
|
|
99
|
+
const deepProperties = Object.entries(PO.properties)
|
|
100
|
+
.filter(([fieldName, fieldValue]) => {
|
|
101
|
+
const field = schema.properties[fieldName];
|
|
102
|
+
return (field &&
|
|
103
|
+
field.type === "object" &&
|
|
104
|
+
field.properties &&
|
|
105
|
+
fieldValue &&
|
|
106
|
+
typeof fieldValue === "object");
|
|
107
|
+
})
|
|
108
|
+
.flatMap(([fieldName, fieldValue]) => {
|
|
109
|
+
const subFields = Object.keys(schema.properties[fieldName].properties);
|
|
110
|
+
return subFields.map(subFieldName => {
|
|
111
|
+
const value = fieldValue[subFieldName];
|
|
112
|
+
const hsubfield = {
|
|
113
|
+
hField: null,
|
|
114
|
+
type: getTypeofFieldValue(value),
|
|
115
|
+
value,
|
|
116
|
+
};
|
|
117
|
+
return [`${fieldName}|${subFieldName}`, hsubfield];
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
// eslint-disable-next-line fp/no-mutation
|
|
121
|
+
out[schemaName] || (out[schemaName] = []);
|
|
122
|
+
// eslint-disable-next-line fp/no-mutating-methods
|
|
123
|
+
out[schemaName].push({
|
|
124
|
+
hSchema: {
|
|
125
|
+
__typeof__: helpers_1.HSchemaSymbol,
|
|
126
|
+
verification: verified.status,
|
|
127
|
+
verifiedBy: verified.details.verifiers
|
|
128
|
+
.map(x => x.verifierNId)
|
|
129
|
+
.filter((val) => !!val),
|
|
130
|
+
},
|
|
131
|
+
properties: Object.fromEntries([
|
|
132
|
+
...nonDateProperties,
|
|
133
|
+
...pseudoDateFields,
|
|
134
|
+
...deepProperties,
|
|
135
|
+
]),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
};
|
|
140
|
+
exports.convertInstanceToRuleInput = convertInstanceToRuleInput;
|
|
@@ -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,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,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getValuesFromPath = void 0;
|
|
4
|
+
const general_1 = require("../../general");
|
|
5
|
+
/** this returns an array because there might be multiple of the same schema shared */
|
|
6
|
+
function getValuesFromPath(path, data) {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
const type = path[0];
|
|
9
|
+
switch (type) {
|
|
10
|
+
case "field": {
|
|
11
|
+
const [, schemaName, fieldName, attr] = path;
|
|
12
|
+
(0, general_1.assertSafeProperty)(schemaName);
|
|
13
|
+
(0, general_1.assertSafeProperty)(fieldName);
|
|
14
|
+
(0, general_1.assertSafeProperty)(attr);
|
|
15
|
+
if (attr === "meta") {
|
|
16
|
+
return (((_a = data[schemaName]) === null || _a === void 0 ? void 0 : _a.map(x => { var _a; return (_a = x.properties[fieldName]) === null || _a === void 0 ? void 0 : _a.hField; })) || []);
|
|
17
|
+
}
|
|
18
|
+
const values = ((_b = data[schemaName]) === null || _b === void 0 ? void 0 : _b.map(x => { var _a; return (_a = x.properties[fieldName]) === null || _a === void 0 ? void 0 : _a.value; })) || [];
|
|
19
|
+
if (attr === "value")
|
|
20
|
+
return values;
|
|
21
|
+
if (attr === "valueLength") {
|
|
22
|
+
return values.map(v => {
|
|
23
|
+
if (typeof v === "string" || Array.isArray(v))
|
|
24
|
+
return v.length;
|
|
25
|
+
throw new Error("valueLength may only be used on arrays and strings");
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (attr === null || attr === void 0 ? void 0 : attr.startsWith("subField|")) {
|
|
29
|
+
const subFieldName = attr.slice(9);
|
|
30
|
+
(0, general_1.assertSafeProperty)(subFieldName);
|
|
31
|
+
const key = `${fieldName}|${subFieldName}`;
|
|
32
|
+
const subValueList = ((_c = data[schemaName]) === null || _c === void 0 ? void 0 : _c.map(x => { var _a; return (_a = x.properties[key]) === null || _a === void 0 ? void 0 : _a.value; })) || [];
|
|
33
|
+
return subValueList;
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`Invalid ValuePath[3] for field (${attr})`);
|
|
36
|
+
}
|
|
37
|
+
case "schema": {
|
|
38
|
+
const [, schemaName, attr] = path;
|
|
39
|
+
(0, general_1.assertSafeProperty)(schemaName);
|
|
40
|
+
(0, general_1.assertSafeProperty)(attr);
|
|
41
|
+
if (attr === "meta") {
|
|
42
|
+
return ((_d = data[schemaName]) === null || _d === void 0 ? void 0 : _d.map(x => x.hSchema)) || [];
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Invalid ValuePath[2] for schema (${attr})`);
|
|
45
|
+
}
|
|
46
|
+
default:
|
|
47
|
+
throw new Error(`Invalid ValuePath[0] (${type})`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.getValuesFromPath = getValuesFromPath;
|