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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Next
2
2
 
3
+ # 4.2.0 - 2024-08-26
4
+
5
+ 1. Added `historicalMigration` option for use in tools that are migrating large data to PostHog
6
+
7
+ # 4.1.1 - 2024-08-20
8
+
9
+ 1. Local evaluation returns correct results on `undefined/null` values
10
+
3
11
  # 4.1.0 - 2024-08-14
4
12
 
5
13
  1. chore: change host to new address.
package/lib/index.cjs.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var rusha = require('rusha');
6
6
 
7
- var version = "4.1.0";
7
+ var version = "4.2.0";
8
8
 
9
9
  var PostHogPersistedProperty;
10
10
  (function (PostHogPersistedProperty) {
@@ -952,6 +952,7 @@ class PostHogCoreStateless {
952
952
  constructor(apiKey, options) {
953
953
  this.flushPromise = null;
954
954
  this.disableGeoip = true;
955
+ this.historicalMigration = false;
955
956
  this.disabled = false;
956
957
  this.defaultOptIn = true;
957
958
  this.pendingPromises = {};
@@ -977,6 +978,7 @@ class PostHogCoreStateless {
977
978
  this.featureFlagsRequestTimeoutMs = options?.featureFlagsRequestTimeoutMs ?? 3000; // 3 seconds
978
979
  this.disableGeoip = options?.disableGeoip ?? true;
979
980
  this.disabled = options?.disabled ?? false;
981
+ this.historicalMigration = options?.historicalMigration ?? false;
980
982
  // Init promise allows the derived class to block calls until it is ready
981
983
  this._initPromise = Promise.resolve();
982
984
  this._isInitialized = true;
@@ -1291,6 +1293,9 @@ class PostHogCoreStateless {
1291
1293
  batch: messages,
1292
1294
  sent_at: currentISOTime(),
1293
1295
  };
1296
+ if (this.historicalMigration) {
1297
+ data.historical_migration = true;
1298
+ }
1294
1299
  const payload = JSON.stringify(data);
1295
1300
  const url = this.captureMode === 'form'
1296
1301
  ? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
@@ -1434,6 +1439,7 @@ if (!_fetch) {
1434
1439
  var fetch$1 = _fetch;
1435
1440
 
1436
1441
  const LONG_SCALE = 0xfffffffffffffff;
1442
+ const NULL_VALUES_ALLOWED_OPERATORS = ['is_not'];
1437
1443
 
1438
1444
  class ClientError extends Error {
1439
1445
  constructor(message) {
@@ -1680,6 +1686,12 @@ class FeatureFlagsPoller {
1680
1686
  isConditionMatch(flag, distinctId, condition, properties) {
1681
1687
  const rolloutPercentage = condition.rollout_percentage;
1682
1688
 
1689
+ const warnFunction = msg => {
1690
+ if (this.debugMode) {
1691
+ console.warn(msg);
1692
+ }
1693
+ };
1694
+
1683
1695
  if ((condition.properties || []).length > 0) {
1684
1696
  for (const prop of condition.properties) {
1685
1697
  const propertyType = prop.type;
@@ -1688,7 +1700,7 @@ class FeatureFlagsPoller {
1688
1700
  if (propertyType === 'cohort') {
1689
1701
  matches = matchCohort(prop, properties, this.cohorts, this.debugMode);
1690
1702
  } else {
1691
- matches = matchProperty(prop, properties);
1703
+ matches = matchProperty(prop, properties, warnFunction);
1692
1704
  }
1693
1705
 
1694
1706
  if (!matches) {
@@ -1830,7 +1842,7 @@ function _hash(key, distinctId, salt = '') {
1830
1842
  return parseInt(sha1Hash.digest('hex').slice(0, 15), 16) / LONG_SCALE;
1831
1843
  }
1832
1844
 
1833
- function matchProperty(property, propertyValues) {
1845
+ function matchProperty(property, propertyValues, warnFunction) {
1834
1846
  const key = property.key;
1835
1847
  const value = property.value;
1836
1848
  const operator = property.operator || 'exact';
@@ -1843,6 +1855,16 @@ function matchProperty(property, propertyValues) {
1843
1855
 
1844
1856
  const overrideValue = propertyValues[key];
1845
1857
 
1858
+ if (overrideValue == null && !NULL_VALUES_ALLOWED_OPERATORS.includes(operator)) {
1859
+ // if the value is null, just fail the feature flag comparison
1860
+ // this isn't an InconclusiveMatchError because the property value was provided.
1861
+ if (warnFunction) {
1862
+ warnFunction(`Property ${key} cannot have a value of null/undefined with the ${operator} operator`);
1863
+ }
1864
+
1865
+ return false;
1866
+ }
1867
+
1846
1868
  function computeExactMatch(value, overrideValue) {
1847
1869
  if (Array.isArray(value)) {
1848
1870
  return value.map(val => String(val).toLowerCase()).includes(String(overrideValue).toLowerCase());