@naturalcycles/abba 1.15.1 → 1.15.2
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/dist/types.d.ts +9 -1
- package/dist/types.js +10 -1
- package/dist/util.d.ts +3 -3
- package/dist/util.js +10 -22
- package/package.json +2 -2
- package/src/types.ts +15 -1
- package/src/util.ts +14 -19
package/dist/types.d.ts
CHANGED
|
@@ -49,9 +49,17 @@ export declare enum AssignmentStatus {
|
|
|
49
49
|
}
|
|
50
50
|
export interface SegmentationRule {
|
|
51
51
|
key: string;
|
|
52
|
-
operator:
|
|
52
|
+
operator: SegmentationRuleOperator;
|
|
53
53
|
value: string | boolean | number;
|
|
54
54
|
}
|
|
55
|
+
export declare enum SegmentationRuleOperator {
|
|
56
|
+
Equals = "==",
|
|
57
|
+
NotEquals = "!=",
|
|
58
|
+
Semver = "semver",
|
|
59
|
+
Regex = "regex",
|
|
60
|
+
Boolean = "boolean"
|
|
61
|
+
}
|
|
62
|
+
export type SegmentationRuleFn = (segmentationProp: string | boolean | number, ruleValue: SegmentationRule['value']) => boolean;
|
|
55
63
|
export interface AssignmentStatistics {
|
|
56
64
|
sampled: number;
|
|
57
65
|
buckets: {
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AssignmentStatus = void 0;
|
|
3
|
+
exports.SegmentationRuleOperator = exports.AssignmentStatus = void 0;
|
|
4
4
|
var AssignmentStatus;
|
|
5
5
|
(function (AssignmentStatus) {
|
|
6
6
|
/**
|
|
@@ -16,3 +16,12 @@ var AssignmentStatus;
|
|
|
16
16
|
*/
|
|
17
17
|
AssignmentStatus[AssignmentStatus["Inactive"] = 3] = "Inactive";
|
|
18
18
|
})(AssignmentStatus = exports.AssignmentStatus || (exports.AssignmentStatus = {}));
|
|
19
|
+
var SegmentationRuleOperator;
|
|
20
|
+
(function (SegmentationRuleOperator) {
|
|
21
|
+
SegmentationRuleOperator["Equals"] = "==";
|
|
22
|
+
SegmentationRuleOperator["NotEquals"] = "!=";
|
|
23
|
+
SegmentationRuleOperator["Semver"] = "semver";
|
|
24
|
+
SegmentationRuleOperator["Regex"] = "regex";
|
|
25
|
+
/* eslint-disable id-blacklist */
|
|
26
|
+
SegmentationRuleOperator["Boolean"] = "boolean";
|
|
27
|
+
})(SegmentationRuleOperator = exports.SegmentationRuleOperator || (exports.SegmentationRuleOperator = {}));
|
package/dist/util.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Saved } from '@naturalcycles/js-lib';
|
|
2
|
-
import { Bucket, ExclusionSet, Experiment, ExperimentWithBuckets, SegmentationData, SegmentationRule, UserAssignment } from './types';
|
|
2
|
+
import { Bucket, ExclusionSet, Experiment, ExperimentWithBuckets, SegmentationData, SegmentationRule, SegmentationRuleFn, SegmentationRuleOperator, UserAssignment } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Generate a new assignment for a given user.
|
|
5
5
|
* Doesn't save it.
|
|
@@ -30,9 +30,9 @@ export declare const validateTotalBucketRatio: (buckets: Bucket[]) => void;
|
|
|
30
30
|
*/
|
|
31
31
|
export declare const validateSegmentationRules: (rules: SegmentationRule[], segmentationData: SegmentationData) => boolean;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Map of segmentation rule validators
|
|
34
34
|
*/
|
|
35
|
-
export declare const
|
|
35
|
+
export declare const segmentationRuleMap: Record<SegmentationRuleOperator, SegmentationRuleFn>;
|
|
36
36
|
/**
|
|
37
37
|
* Returns true if an experiment is able to generate new assignments based on status and start/end dates
|
|
38
38
|
*/
|
package/dist/util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getUserExclusionSet = exports.canGenerateNewAssignments = exports.
|
|
3
|
+
exports.getUserExclusionSet = exports.canGenerateNewAssignments = exports.segmentationRuleMap = exports.validateSegmentationRules = exports.validateTotalBucketRatio = exports.determineBucket = exports.determineAssignment = exports.rollDie = exports.generateUserAssignmentData = void 0;
|
|
4
4
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
5
|
const semver_1 = require("semver");
|
|
6
6
|
const types_1 = require("./types");
|
|
@@ -81,35 +81,23 @@ exports.validateTotalBucketRatio = validateTotalBucketRatio;
|
|
|
81
81
|
*/
|
|
82
82
|
const validateSegmentationRules = (rules, segmentationData) => {
|
|
83
83
|
for (const rule of rules) {
|
|
84
|
-
|
|
84
|
+
const { key, value, operator } = rule;
|
|
85
|
+
if (!exports.segmentationRuleMap[operator](segmentationData[key], value))
|
|
85
86
|
return false;
|
|
86
87
|
}
|
|
87
88
|
return true;
|
|
88
89
|
};
|
|
89
90
|
exports.validateSegmentationRules = validateSegmentationRules;
|
|
90
91
|
/**
|
|
91
|
-
*
|
|
92
|
+
* Map of segmentation rule validators
|
|
92
93
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return data[key] !== value;
|
|
100
|
-
}
|
|
101
|
-
else if (operator === 'semver') {
|
|
102
|
-
return (0, semver_1.satisfies)(data[key]?.toString() || '', value.toString());
|
|
103
|
-
}
|
|
104
|
-
else if (operator === 'regex') {
|
|
105
|
-
return new RegExp(value.toString()).test(data[key]?.toString() || '');
|
|
106
|
-
}
|
|
107
|
-
else if (operator === 'boolean') {
|
|
108
|
-
return Boolean(value) === data[key];
|
|
109
|
-
}
|
|
110
|
-
return false;
|
|
94
|
+
exports.segmentationRuleMap = {
|
|
95
|
+
[types_1.SegmentationRuleOperator.Equals]: (key, ruleValue) => key === ruleValue,
|
|
96
|
+
[types_1.SegmentationRuleOperator.NotEquals]: (key, ruleValue) => key !== ruleValue,
|
|
97
|
+
[types_1.SegmentationRuleOperator.Semver]: (key, ruleValue) => (0, semver_1.satisfies)(key?.toString() || '', ruleValue.toString()),
|
|
98
|
+
[types_1.SegmentationRuleOperator.Regex]: (key, ruleValue) => new RegExp(`${ruleValue}`).test(`${key || ''}`),
|
|
99
|
+
[types_1.SegmentationRuleOperator.Boolean]: (key, ruleValue) => new RegExp(`${ruleValue}`).test(`${key || ''}`),
|
|
111
100
|
};
|
|
112
|
-
exports.validateSegmentationRule = validateSegmentationRule;
|
|
113
101
|
/**
|
|
114
102
|
* Returns true if an experiment is able to generate new assignments based on status and start/end dates
|
|
115
103
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/abba",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.2",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky install",
|
|
6
6
|
"build": "build",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@naturalcycles/dev-lib": "^13.15.0",
|
|
17
|
-
"@types/node": "^
|
|
17
|
+
"@types/node": "^20.2.4",
|
|
18
18
|
"@types/semver": "^7.3.9",
|
|
19
19
|
"jest": "^29.3.1"
|
|
20
20
|
},
|
package/src/types.ts
CHANGED
|
@@ -60,10 +60,24 @@ export enum AssignmentStatus {
|
|
|
60
60
|
|
|
61
61
|
export interface SegmentationRule {
|
|
62
62
|
key: string
|
|
63
|
-
operator:
|
|
63
|
+
operator: SegmentationRuleOperator
|
|
64
64
|
value: string | boolean | number
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
export enum SegmentationRuleOperator {
|
|
68
|
+
Equals = '==',
|
|
69
|
+
NotEquals = '!=',
|
|
70
|
+
Semver = 'semver',
|
|
71
|
+
Regex = 'regex',
|
|
72
|
+
/* eslint-disable id-blacklist */
|
|
73
|
+
Boolean = 'boolean',
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type SegmentationRuleFn = (
|
|
77
|
+
segmentationProp: string | boolean | number,
|
|
78
|
+
ruleValue: SegmentationRule['value'],
|
|
79
|
+
) => boolean
|
|
80
|
+
|
|
67
81
|
export interface AssignmentStatistics {
|
|
68
82
|
sampled: number
|
|
69
83
|
buckets: {
|
package/src/util.ts
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
ExperimentWithBuckets,
|
|
9
9
|
SegmentationData,
|
|
10
10
|
SegmentationRule,
|
|
11
|
+
SegmentationRuleFn,
|
|
12
|
+
SegmentationRuleOperator,
|
|
11
13
|
UserAssignment,
|
|
12
14
|
} from './types'
|
|
13
15
|
|
|
@@ -99,31 +101,24 @@ export const validateSegmentationRules = (
|
|
|
99
101
|
segmentationData: SegmentationData,
|
|
100
102
|
): boolean => {
|
|
101
103
|
for (const rule of rules) {
|
|
102
|
-
|
|
104
|
+
const { key, value, operator } = rule
|
|
105
|
+
if (!segmentationRuleMap[operator](segmentationData[key], value)) return false
|
|
103
106
|
}
|
|
104
107
|
return true
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
/**
|
|
108
|
-
*
|
|
111
|
+
* Map of segmentation rule validators
|
|
109
112
|
*/
|
|
110
|
-
export const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
} else if (operator === 'semver') {
|
|
120
|
-
return satisfies(data[key]?.toString() || '', value.toString())
|
|
121
|
-
} else if (operator === 'regex') {
|
|
122
|
-
return new RegExp(value.toString()).test(data[key]?.toString() || '')
|
|
123
|
-
} else if (operator === 'boolean') {
|
|
124
|
-
return Boolean(value) === data[key]
|
|
125
|
-
}
|
|
126
|
-
return false
|
|
113
|
+
export const segmentationRuleMap: Record<SegmentationRuleOperator, SegmentationRuleFn> = {
|
|
114
|
+
[SegmentationRuleOperator.Equals]: (key, ruleValue) => key === ruleValue,
|
|
115
|
+
[SegmentationRuleOperator.NotEquals]: (key, ruleValue) => key !== ruleValue,
|
|
116
|
+
[SegmentationRuleOperator.Semver]: (key, ruleValue) =>
|
|
117
|
+
satisfies(key?.toString() || '', ruleValue.toString()),
|
|
118
|
+
[SegmentationRuleOperator.Regex]: (key, ruleValue) =>
|
|
119
|
+
new RegExp(`${ruleValue}`).test(`${key || ''}`),
|
|
120
|
+
[SegmentationRuleOperator.Boolean]: (key, ruleValue) =>
|
|
121
|
+
new RegExp(`${ruleValue}`).test(`${key || ''}`),
|
|
127
122
|
}
|
|
128
123
|
|
|
129
124
|
/**
|