posthog-node 2.5.4 → 2.6.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/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 2.6.0 - 2023-03-14
2
+
3
+ 1. Add support for all cohorts local evaluation in feature flags.
4
+
1
5
  # 2.5.4 - 2023-02-27
2
6
 
3
7
  1. Fix error log for local evaluation of feature flags (InconclusiveMatchError(s)) to only show during debug mode.
package/lib/index.cjs.js CHANGED
@@ -163,7 +163,7 @@ function __spreadArray(to, from, pack) {
163
163
  return to.concat(ar || Array.prototype.slice.call(from));
164
164
  }
165
165
 
166
- var version = "2.5.4";
166
+ var version = "2.6.0";
167
167
 
168
168
  var PostHogPersistedProperty;
169
169
  (function (PostHogPersistedProperty) {
@@ -1606,6 +1606,7 @@ function () {
1606
1606
  this.featureFlags = [];
1607
1607
  this.featureFlagsByKey = {};
1608
1608
  this.groupTypeMapping = {};
1609
+ this.cohorts = {};
1609
1610
  this.loadedSuccessfullyOnce = false;
1610
1611
  this.timeout = timeout;
1611
1612
  this.projectApiKey = projectApiKey;
@@ -1943,14 +1944,23 @@ function () {
1943
1944
  var rolloutPercentage = condition.rollout_percentage;
1944
1945
 
1945
1946
  if ((condition.properties || []).length > 0) {
1946
- var matchAll = condition.properties.every(function (property) {
1947
- return matchProperty(property, properties);
1948
- });
1947
+ for (var _i = 0, _a = condition.properties; _i < _a.length; _i++) {
1948
+ var prop = _a[_i];
1949
+ var propertyType = prop.type;
1950
+ var matches = false;
1949
1951
 
1950
- if (!matchAll) {
1951
- return false;
1952
- } else if (rolloutPercentage == undefined) {
1953
- // == to include `null` as a match, not just `undefined`
1952
+ if (propertyType === 'cohort') {
1953
+ matches = matchCohort(prop, properties, this.cohorts);
1954
+ } else {
1955
+ matches = matchProperty(prop, properties);
1956
+ }
1957
+
1958
+ if (!matches) {
1959
+ return false;
1960
+ }
1961
+ }
1962
+
1963
+ if (rolloutPercentage == undefined) {
1954
1964
  return true;
1955
1965
  }
1956
1966
  }
@@ -2083,6 +2093,7 @@ function () {
2083
2093
  return acc[curr.key] = curr, acc;
2084
2094
  }, {});
2085
2095
  this.groupTypeMapping = responseJson.group_type_mapping || {};
2096
+ this.cohorts = responseJson.cohorts || [];
2086
2097
  this.loadedSuccessfullyOnce = true;
2087
2098
  return [3
2088
2099
  /*break*/
@@ -2115,7 +2126,7 @@ function () {
2115
2126
  return __generator(this, function (_a) {
2116
2127
  switch (_a.label) {
2117
2128
  case 0:
2118
- url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey);
2129
+ url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey, "&send_cohorts");
2119
2130
  options = {
2120
2131
  method: 'GET',
2121
2132
  headers: {
@@ -2252,6 +2263,119 @@ function matchProperty(property, propertyValues) {
2252
2263
  }
2253
2264
  }
2254
2265
 
2266
+ function matchCohort(property, propertyValues, cohortProperties) {
2267
+ var cohortId = String(property.value);
2268
+
2269
+ if (!(cohortId in cohortProperties)) {
2270
+ throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
2271
+ }
2272
+
2273
+ var propertyGroup = cohortProperties[cohortId];
2274
+ return matchPropertyGroup(propertyGroup, propertyValues, cohortProperties);
2275
+ }
2276
+
2277
+ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
2278
+ if (!propertyGroup) {
2279
+ return true;
2280
+ }
2281
+
2282
+ var propertyGroupType = propertyGroup.type;
2283
+ var properties = propertyGroup.values;
2284
+
2285
+ if (!properties || properties.length === 0) {
2286
+ // empty groups are no-ops, always match
2287
+ return true;
2288
+ }
2289
+
2290
+ var errorMatchingLocally = false;
2291
+
2292
+ if ('values' in properties[0]) {
2293
+ // a nested property group
2294
+ for (var _i = 0, _a = properties; _i < _a.length; _i++) {
2295
+ var prop = _a[_i];
2296
+
2297
+ try {
2298
+ var matches = matchPropertyGroup(prop, propertyValues, cohortProperties);
2299
+
2300
+ if (propertyGroupType === 'AND') {
2301
+ if (!matches) {
2302
+ return false;
2303
+ }
2304
+ } else {
2305
+ // OR group
2306
+ if (matches) {
2307
+ return true;
2308
+ }
2309
+ }
2310
+ } catch (err) {
2311
+ if (err instanceof InconclusiveMatchError) {
2312
+ console.debug("Failed to compute property ".concat(prop, " locally: ").concat(err));
2313
+ errorMatchingLocally = true;
2314
+ } else {
2315
+ throw err;
2316
+ }
2317
+ }
2318
+ }
2319
+
2320
+ if (errorMatchingLocally) {
2321
+ throw new InconclusiveMatchError("Can't match cohort without a given cohort property value");
2322
+ } // if we get here, all matched in AND case, or none matched in OR case
2323
+
2324
+
2325
+ return propertyGroupType === 'AND';
2326
+ } else {
2327
+ for (var _b = 0, _c = properties; _b < _c.length; _b++) {
2328
+ var prop = _c[_b];
2329
+
2330
+ try {
2331
+ var matches = void 0;
2332
+
2333
+ if (prop.type === 'cohort') {
2334
+ matches = matchCohort(prop, propertyValues, cohortProperties);
2335
+ } else {
2336
+ matches = matchProperty(prop, propertyValues);
2337
+ }
2338
+
2339
+ var negation = prop.negation || false;
2340
+
2341
+ if (propertyGroupType === 'AND') {
2342
+ // if negated property, do the inverse
2343
+ if (!matches && !negation) {
2344
+ return false;
2345
+ }
2346
+
2347
+ if (matches && negation) {
2348
+ return false;
2349
+ }
2350
+ } else {
2351
+ // OR group
2352
+ if (matches && !negation) {
2353
+ return true;
2354
+ }
2355
+
2356
+ if (!matches && negation) {
2357
+ return true;
2358
+ }
2359
+ }
2360
+ } catch (err) {
2361
+ if (err instanceof InconclusiveMatchError) {
2362
+ console.debug("Failed to compute property ".concat(prop, " locally: ").concat(err));
2363
+ errorMatchingLocally = true;
2364
+ } else {
2365
+ throw err;
2366
+ }
2367
+ }
2368
+ }
2369
+
2370
+ if (errorMatchingLocally) {
2371
+ throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
2372
+ } // if we get here, all matched in AND case, or none matched in OR case
2373
+
2374
+
2375
+ return propertyGroupType === 'AND';
2376
+ }
2377
+ }
2378
+
2255
2379
  function isValidRegex(regex) {
2256
2380
  try {
2257
2381
  new RegExp(regex);