posthog-node 4.1.0 → 4.2.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
@@ -40,6 +40,8 @@ declare type PostHogCoreOptions = {
40
40
  /** Whether to post events to PostHog in JSON or compressed format. Defaults to 'form' */
41
41
  captureMode?: 'json' | 'form';
42
42
  disableGeoip?: boolean;
43
+ /** Special flag to indicate ingested data is for a historical migration. */
44
+ historicalMigration?: boolean;
43
45
  };
44
46
  declare enum PostHogPersistedProperty {
45
47
  AnonymousId = "anonymous_id",
@@ -137,6 +139,7 @@ declare abstract class PostHogCoreStateless {
137
139
  private captureMode;
138
140
  private removeDebugCallback?;
139
141
  private disableGeoip;
142
+ private historicalMigration;
140
143
  disabled: boolean;
141
144
  private defaultOptIn;
142
145
  private pendingPromises;
package/lib/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createHash } from 'rusha';
2
2
 
3
- var version = "4.1.0";
3
+ var version = "4.2.0";
4
4
 
5
5
  var PostHogPersistedProperty;
6
6
  (function (PostHogPersistedProperty) {
@@ -948,6 +948,7 @@ class PostHogCoreStateless {
948
948
  constructor(apiKey, options) {
949
949
  this.flushPromise = null;
950
950
  this.disableGeoip = true;
951
+ this.historicalMigration = false;
951
952
  this.disabled = false;
952
953
  this.defaultOptIn = true;
953
954
  this.pendingPromises = {};
@@ -973,6 +974,7 @@ class PostHogCoreStateless {
973
974
  this.featureFlagsRequestTimeoutMs = options?.featureFlagsRequestTimeoutMs ?? 3000; // 3 seconds
974
975
  this.disableGeoip = options?.disableGeoip ?? true;
975
976
  this.disabled = options?.disabled ?? false;
977
+ this.historicalMigration = options?.historicalMigration ?? false;
976
978
  // Init promise allows the derived class to block calls until it is ready
977
979
  this._initPromise = Promise.resolve();
978
980
  this._isInitialized = true;
@@ -1287,6 +1289,9 @@ class PostHogCoreStateless {
1287
1289
  batch: messages,
1288
1290
  sent_at: currentISOTime(),
1289
1291
  };
1292
+ if (this.historicalMigration) {
1293
+ data.historical_migration = true;
1294
+ }
1290
1295
  const payload = JSON.stringify(data);
1291
1296
  const url = this.captureMode === 'form'
1292
1297
  ? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
@@ -1430,6 +1435,7 @@ if (!_fetch) {
1430
1435
  var fetch$1 = _fetch;
1431
1436
 
1432
1437
  const LONG_SCALE = 0xfffffffffffffff;
1438
+ const NULL_VALUES_ALLOWED_OPERATORS = ['is_not'];
1433
1439
 
1434
1440
  class ClientError extends Error {
1435
1441
  constructor(message) {
@@ -1676,6 +1682,12 @@ class FeatureFlagsPoller {
1676
1682
  isConditionMatch(flag, distinctId, condition, properties) {
1677
1683
  const rolloutPercentage = condition.rollout_percentage;
1678
1684
 
1685
+ const warnFunction = msg => {
1686
+ if (this.debugMode) {
1687
+ console.warn(msg);
1688
+ }
1689
+ };
1690
+
1679
1691
  if ((condition.properties || []).length > 0) {
1680
1692
  for (const prop of condition.properties) {
1681
1693
  const propertyType = prop.type;
@@ -1684,7 +1696,7 @@ class FeatureFlagsPoller {
1684
1696
  if (propertyType === 'cohort') {
1685
1697
  matches = matchCohort(prop, properties, this.cohorts, this.debugMode);
1686
1698
  } else {
1687
- matches = matchProperty(prop, properties);
1699
+ matches = matchProperty(prop, properties, warnFunction);
1688
1700
  }
1689
1701
 
1690
1702
  if (!matches) {
@@ -1826,7 +1838,7 @@ function _hash(key, distinctId, salt = '') {
1826
1838
  return parseInt(sha1Hash.digest('hex').slice(0, 15), 16) / LONG_SCALE;
1827
1839
  }
1828
1840
 
1829
- function matchProperty(property, propertyValues) {
1841
+ function matchProperty(property, propertyValues, warnFunction) {
1830
1842
  const key = property.key;
1831
1843
  const value = property.value;
1832
1844
  const operator = property.operator || 'exact';
@@ -1839,6 +1851,16 @@ function matchProperty(property, propertyValues) {
1839
1851
 
1840
1852
  const overrideValue = propertyValues[key];
1841
1853
 
1854
+ if (overrideValue == null && !NULL_VALUES_ALLOWED_OPERATORS.includes(operator)) {
1855
+ // if the value is null, just fail the feature flag comparison
1856
+ // this isn't an InconclusiveMatchError because the property value was provided.
1857
+ if (warnFunction) {
1858
+ warnFunction(`Property ${key} cannot have a value of null/undefined with the ${operator} operator`);
1859
+ }
1860
+
1861
+ return false;
1862
+ }
1863
+
1842
1864
  function computeExactMatch(value, overrideValue) {
1843
1865
  if (Array.isArray(value)) {
1844
1866
  return value.map(val => String(val).toLowerCase()).includes(String(overrideValue).toLowerCase());