posthog-node 2.5.3 → 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/lib/index.d.ts CHANGED
@@ -103,6 +103,7 @@ declare abstract class PostHogCoreStateless {
103
103
  private requestTimeout;
104
104
  private captureMode;
105
105
  private removeDebugCallback?;
106
+ private debugMode;
106
107
  private pendingPromises;
107
108
  private _optoutOverride;
108
109
  protected _events: SimpleEventEmitter;
@@ -319,6 +320,7 @@ declare class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
319
320
  getCustomUserAgent(): string;
320
321
  enable(): void;
321
322
  disable(): void;
323
+ debug(enabled?: boolean): void;
322
324
  capture({ distinctId, event, properties, groups, sendFeatureFlags, timestamp }: EventMessageV1): void;
323
325
  identify({ distinctId, properties }: IdentifyMessageV1): void;
324
326
  alias(data: {
package/lib/index.esm.js CHANGED
@@ -155,7 +155,7 @@ function __spreadArray(to, from, pack) {
155
155
  return to.concat(ar || Array.prototype.slice.call(from));
156
156
  }
157
157
 
158
- var version = "2.5.3";
158
+ var version = "2.6.0";
159
159
 
160
160
  var PostHogPersistedProperty;
161
161
  (function (PostHogPersistedProperty) {
@@ -717,6 +717,7 @@ var SimpleEventEmitter = /** @class */ (function () {
717
717
  var PostHogCoreStateless = /** @class */ (function () {
718
718
  function PostHogCoreStateless(apiKey, options) {
719
719
  var _a, _b, _c, _d;
720
+ this.debugMode = false;
720
721
  this.pendingPromises = {};
721
722
  // internal
722
723
  this._events = new SimpleEventEmitter();
@@ -761,6 +762,7 @@ var PostHogCoreStateless = /** @class */ (function () {
761
762
  var _a;
762
763
  if (enabled === void 0) { enabled = true; }
763
764
  (_a = this.removeDebugCallback) === null || _a === void 0 ? void 0 : _a.call(this);
765
+ this.debugMode = enabled;
764
766
  if (enabled) {
765
767
  this.removeDebugCallback = this.on('*', function (event, payload) { return console.log('PostHog Debug', event, payload); });
766
768
  }
@@ -1590,11 +1592,13 @@ function () {
1590
1592
  host = _a.host,
1591
1593
  options = __rest(_a, ["pollingInterval", "personalApiKey", "projectApiKey", "timeout", "host"]);
1592
1594
 
1595
+ this.debugMode = false;
1593
1596
  this.pollingInterval = pollingInterval;
1594
1597
  this.personalApiKey = personalApiKey;
1595
1598
  this.featureFlags = [];
1596
1599
  this.featureFlagsByKey = {};
1597
1600
  this.groupTypeMapping = {};
1601
+ this.cohorts = {};
1598
1602
  this.loadedSuccessfullyOnce = false;
1599
1603
  this.timeout = timeout;
1600
1604
  this.projectApiKey = projectApiKey;
@@ -1605,6 +1609,14 @@ function () {
1605
1609
  void this.loadFeatureFlags();
1606
1610
  }
1607
1611
 
1612
+ FeatureFlagsPoller.prototype.debug = function (enabled) {
1613
+ if (enabled === void 0) {
1614
+ enabled = true;
1615
+ }
1616
+
1617
+ this.debugMode = enabled;
1618
+ };
1619
+
1608
1620
  FeatureFlagsPoller.prototype.getFeatureFlag = function (key, distinctId, groups, personProperties, groupProperties) {
1609
1621
  if (groups === void 0) {
1610
1622
  groups = {};
@@ -1652,9 +1664,15 @@ function () {
1652
1664
  if (featureFlag !== undefined) {
1653
1665
  try {
1654
1666
  response = this.computeFlagLocally(featureFlag, distinctId, groups, personProperties, groupProperties);
1667
+
1668
+ if (this.debugMode) {
1669
+ console.debug("Successfully computed flag locally: ".concat(key, " -> ").concat(response));
1670
+ }
1655
1671
  } catch (e) {
1656
1672
  if (e instanceof InconclusiveMatchError) {
1657
- console.error("InconclusiveMatchError when computing flag locally: ".concat(key, ": ").concat(e));
1673
+ if (this.debugMode) {
1674
+ console.debug("InconclusiveMatchError when computing flag locally: ".concat(key, ": ").concat(e));
1675
+ }
1658
1676
  } else if (e instanceof Error) {
1659
1677
  console.error("Error computing flag locally: ".concat(key, ": ").concat(e));
1660
1678
  }
@@ -1918,14 +1936,23 @@ function () {
1918
1936
  var rolloutPercentage = condition.rollout_percentage;
1919
1937
 
1920
1938
  if ((condition.properties || []).length > 0) {
1921
- var matchAll = condition.properties.every(function (property) {
1922
- return matchProperty(property, properties);
1923
- });
1939
+ for (var _i = 0, _a = condition.properties; _i < _a.length; _i++) {
1940
+ var prop = _a[_i];
1941
+ var propertyType = prop.type;
1942
+ var matches = false;
1924
1943
 
1925
- if (!matchAll) {
1926
- return false;
1927
- } else if (rolloutPercentage == undefined) {
1928
- // == to include `null` as a match, not just `undefined`
1944
+ if (propertyType === 'cohort') {
1945
+ matches = matchCohort(prop, properties, this.cohorts);
1946
+ } else {
1947
+ matches = matchProperty(prop, properties);
1948
+ }
1949
+
1950
+ if (!matches) {
1951
+ return false;
1952
+ }
1953
+ }
1954
+
1955
+ if (rolloutPercentage == undefined) {
1929
1956
  return true;
1930
1957
  }
1931
1958
  }
@@ -2058,6 +2085,7 @@ function () {
2058
2085
  return acc[curr.key] = curr, acc;
2059
2086
  }, {});
2060
2087
  this.groupTypeMapping = responseJson.group_type_mapping || {};
2088
+ this.cohorts = responseJson.cohorts || [];
2061
2089
  this.loadedSuccessfullyOnce = true;
2062
2090
  return [3
2063
2091
  /*break*/
@@ -2090,7 +2118,7 @@ function () {
2090
2118
  return __generator(this, function (_a) {
2091
2119
  switch (_a.label) {
2092
2120
  case 0:
2093
- url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey);
2121
+ url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey, "&send_cohorts");
2094
2122
  options = {
2095
2123
  method: 'GET',
2096
2124
  headers: {
@@ -2227,6 +2255,119 @@ function matchProperty(property, propertyValues) {
2227
2255
  }
2228
2256
  }
2229
2257
 
2258
+ function matchCohort(property, propertyValues, cohortProperties) {
2259
+ var cohortId = String(property.value);
2260
+
2261
+ if (!(cohortId in cohortProperties)) {
2262
+ throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
2263
+ }
2264
+
2265
+ var propertyGroup = cohortProperties[cohortId];
2266
+ return matchPropertyGroup(propertyGroup, propertyValues, cohortProperties);
2267
+ }
2268
+
2269
+ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
2270
+ if (!propertyGroup) {
2271
+ return true;
2272
+ }
2273
+
2274
+ var propertyGroupType = propertyGroup.type;
2275
+ var properties = propertyGroup.values;
2276
+
2277
+ if (!properties || properties.length === 0) {
2278
+ // empty groups are no-ops, always match
2279
+ return true;
2280
+ }
2281
+
2282
+ var errorMatchingLocally = false;
2283
+
2284
+ if ('values' in properties[0]) {
2285
+ // a nested property group
2286
+ for (var _i = 0, _a = properties; _i < _a.length; _i++) {
2287
+ var prop = _a[_i];
2288
+
2289
+ try {
2290
+ var matches = matchPropertyGroup(prop, propertyValues, cohortProperties);
2291
+
2292
+ if (propertyGroupType === 'AND') {
2293
+ if (!matches) {
2294
+ return false;
2295
+ }
2296
+ } else {
2297
+ // OR group
2298
+ if (matches) {
2299
+ return true;
2300
+ }
2301
+ }
2302
+ } catch (err) {
2303
+ if (err instanceof InconclusiveMatchError) {
2304
+ console.debug("Failed to compute property ".concat(prop, " locally: ").concat(err));
2305
+ errorMatchingLocally = true;
2306
+ } else {
2307
+ throw err;
2308
+ }
2309
+ }
2310
+ }
2311
+
2312
+ if (errorMatchingLocally) {
2313
+ throw new InconclusiveMatchError("Can't match cohort without a given cohort property value");
2314
+ } // if we get here, all matched in AND case, or none matched in OR case
2315
+
2316
+
2317
+ return propertyGroupType === 'AND';
2318
+ } else {
2319
+ for (var _b = 0, _c = properties; _b < _c.length; _b++) {
2320
+ var prop = _c[_b];
2321
+
2322
+ try {
2323
+ var matches = void 0;
2324
+
2325
+ if (prop.type === 'cohort') {
2326
+ matches = matchCohort(prop, propertyValues, cohortProperties);
2327
+ } else {
2328
+ matches = matchProperty(prop, propertyValues);
2329
+ }
2330
+
2331
+ var negation = prop.negation || false;
2332
+
2333
+ if (propertyGroupType === 'AND') {
2334
+ // if negated property, do the inverse
2335
+ if (!matches && !negation) {
2336
+ return false;
2337
+ }
2338
+
2339
+ if (matches && negation) {
2340
+ return false;
2341
+ }
2342
+ } else {
2343
+ // OR group
2344
+ if (matches && !negation) {
2345
+ return true;
2346
+ }
2347
+
2348
+ if (!matches && negation) {
2349
+ return true;
2350
+ }
2351
+ }
2352
+ } catch (err) {
2353
+ if (err instanceof InconclusiveMatchError) {
2354
+ console.debug("Failed to compute property ".concat(prop, " locally: ").concat(err));
2355
+ errorMatchingLocally = true;
2356
+ } else {
2357
+ throw err;
2358
+ }
2359
+ }
2360
+ }
2361
+
2362
+ if (errorMatchingLocally) {
2363
+ throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
2364
+ } // if we get here, all matched in AND case, or none matched in OR case
2365
+
2366
+
2367
+ return propertyGroupType === 'AND';
2368
+ }
2369
+ }
2370
+
2230
2371
  function isValidRegex(regex) {
2231
2372
  try {
2232
2373
  new RegExp(regex);
@@ -2322,6 +2463,18 @@ function (_super) {
2322
2463
  return _super.prototype.optOut.call(this);
2323
2464
  };
2324
2465
 
2466
+ PostHog.prototype.debug = function (enabled) {
2467
+ var _a;
2468
+
2469
+ if (enabled === void 0) {
2470
+ enabled = true;
2471
+ }
2472
+
2473
+ _super.prototype.debug.call(this, enabled);
2474
+
2475
+ (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.debug(enabled);
2476
+ };
2477
+
2325
2478
  PostHog.prototype.capture = function (_a) {
2326
2479
  var _this = this;
2327
2480