expf-sigma-node.js 1.2.3 → 2.0.1

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 (2) hide show
  1. package/package.json +1 -1
  2. package/public/sigma.js +102 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expf-sigma-node.js",
3
- "version": "1.2.3",
3
+ "version": "2.0.1",
4
4
  "description": "expf-sigma-node.js lets you manage features flags and remote config across web, server side applications. Deliver true Continuous Integration. Get builds out faster. Control who has access to new features.",
5
5
  "main": "public/sigma.js",
6
6
  "keywords": [
package/public/sigma.js CHANGED
@@ -59,7 +59,11 @@ var SigmaUserData = class {
59
59
  time: null,
60
60
  date: null,
61
61
  deviceCategory: null,
62
- featureFlags: []
62
+ featureFlags: [],
63
+ domain: null,
64
+ url: null,
65
+ query: null,
66
+ pathname: null
63
67
  };
64
68
  }
65
69
  init({
@@ -71,7 +75,11 @@ var SigmaUserData = class {
71
75
  deviceCategory,
72
76
  os,
73
77
  browser,
74
- geo
78
+ geo,
79
+ domain,
80
+ url,
81
+ query,
82
+ pathname
75
83
  }) {
76
84
  this.user.userId = userId;
77
85
  this.user.ip = ip;
@@ -84,6 +92,10 @@ var SigmaUserData = class {
84
92
  this.user.os = os;
85
93
  this.user.browser = browser;
86
94
  this.user.geo = geo;
95
+ this.user.domain = domain;
96
+ this.user.url = url;
97
+ this.user.query = query;
98
+ this.user.pathname = pathname;
87
99
  }
88
100
  setUserId(userId) {
89
101
  this.user.userId = userId;
@@ -946,9 +958,13 @@ var Sigma = class {
946
958
  appVersion: this.userData.appVersion || null,
947
959
  custom: this.userData.custom || null,
948
960
  deviceCategory: this.userData.deviceCategory || null,
949
- browser: this.userData.browser || null,
950
- os: this.userData.os || null,
951
- geo: this.userData.geo || null
961
+ browser: this.userData.browser || { version: null, name: null },
962
+ os: this.userData.os || { version: null, name: null },
963
+ geo: this.userData.geo || null,
964
+ domain: this.userData.domain || null,
965
+ url: this.userData.url || null,
966
+ query: this.userData.query || null,
967
+ pathname: this.userData.pathname || null
952
968
  });
953
969
  this.geoCache = new SigmaGeoCache(this.token, options.geoCacheTTL);
954
970
  this.cache.set(sigmaUserId, this.userData.userId);
@@ -1160,8 +1176,10 @@ var Sigma = class {
1160
1176
  }
1161
1177
  conditionOperation(userValue, conditionValues, operation) {
1162
1178
  !operation ? operation = "=" : operation;
1163
- if (!userValue || typeof userValue === "undefined")
1179
+ if (userValue === null || typeof userValue === "undefined" || !conditionValues)
1164
1180
  return false;
1181
+ userValue = String(userValue);
1182
+ conditionValues = String(conditionValues);
1165
1183
  switch (operation.trim()) {
1166
1184
  case "equal":
1167
1185
  return userValue.toLowerCase().trim() == conditionValues.toLowerCase().trim();
@@ -1181,14 +1199,14 @@ var Sigma = class {
1181
1199
  return !conditionValues.includes(userValue);
1182
1200
  case "contains any of":
1183
1201
  for (let i = 0; i < conditionValues.length; i++) {
1184
- if (String(userValue).includes(conditionValues[i])) {
1202
+ if (userValue.includes(conditionValues[i])) {
1185
1203
  return true;
1186
1204
  }
1187
1205
  }
1188
1206
  return false;
1189
1207
  case "contains none of":
1190
1208
  for (let i = 0; i < conditionValues.length; i++) {
1191
- if (String(userValue).includes(conditionValues[i])) {
1209
+ if (userValue.includes(conditionValues[i])) {
1192
1210
  return false;
1193
1211
  }
1194
1212
  }
@@ -1205,7 +1223,7 @@ var Sigma = class {
1205
1223
  return false;
1206
1224
  }
1207
1225
  }
1208
- getUserParamValue(paramKey, privateFlag = null) {
1226
+ getUserParamValue(paramKey, privateFlag = null, isConditionSignForHash = false) {
1209
1227
  if (!paramKey)
1210
1228
  return false;
1211
1229
  const user = this.sigmaUserData.user;
@@ -1235,8 +1253,11 @@ var Sigma = class {
1235
1253
  }
1236
1254
  }
1237
1255
  }
1238
- if (privateFlag && defaultValue)
1256
+ if (defaultValue != null)
1257
+ defaultValue = String(defaultValue);
1258
+ if (privateFlag && defaultValue && isConditionSignForHash) {
1239
1259
  return MD5.hex(defaultValue);
1260
+ }
1240
1261
  return defaultValue;
1241
1262
  }
1242
1263
  calcUserInGroup(salt, exposureRate, controlBucketPerc, forcedExp = false, layer = null, layerBounds = []) {
@@ -1260,6 +1281,41 @@ var Sigma = class {
1260
1281
  }
1261
1282
  return false;
1262
1283
  }
1284
+ checkTargetConditions(experiment) {
1285
+ if (experiment.targets && experiment.targets.conditions && experiment.targets.conditions.length > 0) {
1286
+ const targets = experiment.targets;
1287
+ let results = [];
1288
+ for (let index in targets.conditions) {
1289
+ const userValue = this.getUserParamValue(
1290
+ targets.conditions[index].name,
1291
+ experiment.is_private,
1292
+ this.checkConditionSignForHash(targets.conditions[index].condition_sign)
1293
+ );
1294
+ results.push(
1295
+ this.conditionOperation(
1296
+ userValue,
1297
+ targets.conditions[index].value,
1298
+ targets.conditions[index].condition_sign
1299
+ )
1300
+ );
1301
+ }
1302
+ return this.checkConditionsStatement(targets.conditional_statement, results);
1303
+ }
1304
+ return false;
1305
+ }
1306
+ checkConditionSignForHash(condition) {
1307
+ return ["equal", "not equal", "any of", "none of"].includes(condition);
1308
+ }
1309
+ experimentDefinition(experiment, forcedUserInGroup) {
1310
+ if (forcedUserInGroup) {
1311
+ return experiment;
1312
+ } else if (experiment.targets && experiment.targets.conditions.length > 0 && this.checkTargetConditions(experiment)) {
1313
+ return experiment;
1314
+ } else if (!experiment.targets || experiment.targets && experiment.targets.conditions.length === 0) {
1315
+ return experiment;
1316
+ }
1317
+ return null;
1318
+ }
1263
1319
  async getExperiment(experimentName) {
1264
1320
  if (!experimentName) {
1265
1321
  return null;
@@ -1282,13 +1338,13 @@ var Sigma = class {
1282
1338
  }
1283
1339
  if (sigmaDataLs.experiments[i]["name"] === experimentName && !experiment) {
1284
1340
  forcedUser = checkForcedList(sigmaDataLs.experiments[i].forced_user_list, this.sigmaUserData.user.userId);
1285
- experiment = sigmaDataLs.experiments[i];
1341
+ userInGroupExperiment = this.findUserInForcedGroup(sigmaDataLs.experiments[i]);
1342
+ experiment = this.experimentDefinition(sigmaDataLs.experiments[i], userInGroupExperiment);
1286
1343
  break;
1287
1344
  }
1288
1345
  }
1289
1346
  const localStorageGroupName = `sigma_group_${experimentName}`;
1290
1347
  if (experiment) {
1291
- userInGroupExperiment = this.findUserInForcedGroup(experiment);
1292
1348
  if (!userInGroupExperiment) {
1293
1349
  userInGroupExperiment = this.calcUserInGroup(
1294
1350
  experiment.salt,
@@ -1362,26 +1418,28 @@ var Sigma = class {
1362
1418
  return false;
1363
1419
  let result = "";
1364
1420
  for (let i in sigmaDataLs.experiments) {
1365
- const experiment = sigmaDataLs.experiments[i];
1366
1421
  let layer = null;
1367
1422
  let bounds = [];
1368
- let group = this.findUserInForcedGroup(experiment);
1369
- if (checkBoolValue(experiment["layer_id"]) && !group) {
1370
- layer = experiment["layer_id"];
1371
- bounds = experiment["layer_bounds"];
1372
- }
1373
- if (!group) {
1374
- group = this.calcUserInGroup(
1375
- experiment.salt,
1376
- experiment.allocation,
1377
- experiment.groups,
1378
- checkForcedList(experiment.forced_user_list, this.sigmaUserData.user.userId),
1379
- layer,
1380
- bounds
1381
- );
1423
+ let userInGroupExperiment = this.findUserInForcedGroup(sigmaDataLs.experiments[i]);
1424
+ let experiment = this.experimentDefinition(sigmaDataLs.experiments[i], userInGroupExperiment);
1425
+ if (experiment) {
1426
+ if (checkBoolValue(experiment["layer_id"]) && !userInGroupExperiment) {
1427
+ layer = experiment["layer_id"];
1428
+ bounds = experiment["layer_bounds"];
1429
+ }
1430
+ if (!userInGroupExperiment) {
1431
+ userInGroupExperiment = this.calcUserInGroup(
1432
+ experiment.salt,
1433
+ experiment.allocation,
1434
+ experiment.groups,
1435
+ checkForcedList(experiment.forced_user_list, this.sigmaUserData.user.userId),
1436
+ layer,
1437
+ bounds
1438
+ );
1439
+ }
1382
1440
  }
1383
- if (group) {
1384
- const groupIndex = experiment.groups.findIndex((i2) => i2.name == group);
1441
+ if (userInGroupExperiment) {
1442
+ const groupIndex = experiment.groups.findIndex((i2) => i2.name == userInGroupExperiment);
1385
1443
  result = result.concat(experiment.name).concat(".").concat(groupIndex).concat("|");
1386
1444
  }
1387
1445
  }
@@ -1432,7 +1490,8 @@ var Sigma = class {
1432
1490
  for (let i in conditions) {
1433
1491
  let userValue = this.getUserParamValue(
1434
1492
  conditions[i].name,
1435
- exp ? exp.is_private : flag.is_private
1493
+ exp ? exp.is_private : flag.is_private,
1494
+ this.checkConditionSignForHash(conditions[i].condition_sign)
1436
1495
  );
1437
1496
  results.push(
1438
1497
  this.conditionOperation(
@@ -1442,15 +1501,7 @@ var Sigma = class {
1442
1501
  )
1443
1502
  );
1444
1503
  }
1445
- let isSuccessRule = false;
1446
- if (flagRules[rule].conditional_statement == "OR") {
1447
- const findingItem = results.find((item) => item === true);
1448
- findingItem === true ? isSuccessRule = true : isSuccessRule;
1449
- }
1450
- if (flagRules[rule].conditional_statement == "AND") {
1451
- const findingItem = results.find((item) => item === false);
1452
- findingItem === false ? isSuccessRule : isSuccessRule = true;
1453
- }
1504
+ let isSuccessRule = this.checkConditionsStatement(flagRules[rule].conditional_statement, results);
1454
1505
  let ruleValue = doTypeConversion(flag.type, flagRules[rule].value);
1455
1506
  if (isSuccessRule) {
1456
1507
  if (saveToUser) {
@@ -1483,6 +1534,18 @@ var Sigma = class {
1483
1534
  const data = await this.cache.get(sigmaUserId);
1484
1535
  return data;
1485
1536
  }
1537
+ checkConditionsStatement(ruleStatement, items) {
1538
+ let isSuccessRule = false;
1539
+ if (ruleStatement == "OR") {
1540
+ const findingItem = items.find((item) => item === true);
1541
+ findingItem === true ? isSuccessRule = true : isSuccessRule;
1542
+ }
1543
+ if (ruleStatement == "AND") {
1544
+ const findingItem = items.find((item) => item === false);
1545
+ findingItem === false ? isSuccessRule : isSuccessRule = true;
1546
+ }
1547
+ return isSuccessRule;
1548
+ }
1486
1549
  };
1487
1550
  var sigma_default = Sigma;
1488
1551
  // Annotate the CommonJS export names for ESM import in node: