@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 CHANGED
@@ -49,9 +49,17 @@ export declare enum AssignmentStatus {
49
49
  }
50
50
  export interface SegmentationRule {
51
51
  key: string;
52
- operator: '==' | '!=' | 'semver' | 'regex' | 'boolean';
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
- * Validate a users segmentation data against a single rule
33
+ * Map of segmentation rule validators
34
34
  */
35
- export declare const validateSegmentationRule: (rule: SegmentationRule, data: SegmentationData) => boolean;
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.validateSegmentationRule = exports.validateSegmentationRules = exports.validateTotalBucketRatio = exports.determineBucket = exports.determineAssignment = exports.rollDie = exports.generateUserAssignmentData = void 0;
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
- if (!(0, exports.validateSegmentationRule)(rule, segmentationData))
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
- * Validate a users segmentation data against a single rule
92
+ * Map of segmentation rule validators
92
93
  */
93
- const validateSegmentationRule = (rule, data) => {
94
- const { key, value, operator } = rule;
95
- if (operator === '==') {
96
- return data[key] === value;
97
- }
98
- else if (operator === '!=') {
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.1",
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": "^18.11.18",
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: '==' | '!=' | 'semver' | 'regex' | 'boolean'
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
- if (!validateSegmentationRule(rule, segmentationData)) return false
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
- * Validate a users segmentation data against a single rule
111
+ * Map of segmentation rule validators
109
112
  */
110
- export const validateSegmentationRule = (
111
- rule: SegmentationRule,
112
- data: SegmentationData,
113
- ): boolean => {
114
- const { key, value, operator } = rule
115
- if (operator === '==') {
116
- return data[key] === value
117
- } else if (operator === '!=') {
118
- return data[key] !== value
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
  /**