posthog-node 3.3.0 → 3.5.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,13 @@
1
+ # 3.5.0 - 2024-01-09
2
+
3
+ 1. When local evaluation is enabled, we automatically add flag information to all events sent to PostHog, whenever possible. This makes it easier to use these events in experiments.
4
+ 2. Fixes a bug where in some rare cases we may drop events when send_feature_flags is enabled on capture.
5
+
6
+ # 3.4.0 - 2024-01-09
7
+
8
+ 1. Numeric property handling for feature flags now does the expected: When passed in a number, we do a numeric comparison. When passed in a string, we do a string comparison. Previously, we always did a string comparison.
9
+ 2. Add support for relative date operators for local evaluation.
10
+
1
11
  # 3.3.0 - 2024-01-02
2
12
 
3
13
  1. Adds PostHogSentryIntegration to allow automatic capturing of exceptions reported via the @sentry/node package
package/lib/index.cjs.js CHANGED
@@ -158,7 +158,7 @@ function __spreadArray(to, from, pack) {
158
158
  return to.concat(ar || Array.prototype.slice.call(from));
159
159
  }
160
160
 
161
- var version = "3.3.0";
161
+ var version = "3.5.0";
162
162
 
163
163
  var PostHogPersistedProperty;
164
164
  (function (PostHogPersistedProperty) {
@@ -751,8 +751,8 @@ var PostHogCoreStateless = /** @class */ (function () {
751
751
  function PostHogCoreStateless(apiKey, options) {
752
752
  var _a, _b, _c, _d, _e;
753
753
  this.debugMode = false;
754
- this.pendingPromises = {};
755
754
  this.disableGeoip = true;
755
+ this.pendingPromises = {};
756
756
  // internal
757
757
  this._events = new SimpleEventEmitter();
758
758
  assert(apiKey, "You must pass your PostHog project's api key.");
@@ -810,6 +810,14 @@ var PostHogCoreStateless = /** @class */ (function () {
810
810
  properties: __assign(__assign({}, (payload.properties || {})), this.getCommonEventProperties()),
811
811
  };
812
812
  };
813
+ PostHogCoreStateless.prototype.addPendingPromise = function (promise) {
814
+ var _this = this;
815
+ var promiseUUID = generateUUID();
816
+ this.pendingPromises[promiseUUID] = promise;
817
+ promise.finally(function () {
818
+ delete _this.pendingPromises[promiseUUID];
819
+ });
820
+ };
813
821
  /***
814
822
  *** TRACKING
815
823
  ***/
@@ -860,6 +868,7 @@ var PostHogCoreStateless = /** @class */ (function () {
860
868
  if (extraPayload === void 0) { extraPayload = {}; }
861
869
  return __awaiter(this, void 0, void 0, function () {
862
870
  var url, fetchOptions;
871
+ var _this = this;
863
872
  return __generator(this, function (_a) {
864
873
  url = "".concat(this.host, "/decide/?v=3");
865
874
  fetchOptions = {
@@ -870,7 +879,7 @@ var PostHogCoreStateless = /** @class */ (function () {
870
879
  return [2 /*return*/, this.fetchWithRetry(url, fetchOptions)
871
880
  .then(function (response) { return response.json(); })
872
881
  .catch(function (error) {
873
- console.error('Error fetching feature flags', error);
882
+ _this._events.emit('error', error);
874
883
  return undefined;
875
884
  })];
876
885
  });
@@ -1057,14 +1066,11 @@ var PostHogCoreStateless = /** @class */ (function () {
1057
1066
  batch: messages,
1058
1067
  sent_at: currentISOTime(),
1059
1068
  };
1060
- var promiseUUID = generateUUID();
1061
1069
  var done = function (err) {
1062
1070
  if (err) {
1063
1071
  _this._events.emit('error', err);
1064
1072
  }
1065
1073
  callback === null || callback === void 0 ? void 0 : callback(err, messages);
1066
- // remove promise from pendingPromises
1067
- delete _this.pendingPromises[promiseUUID];
1068
1074
  _this._events.emit('flush', messages);
1069
1075
  };
1070
1076
  // Don't set the user agent if we're not on a browser. The latest spec allows
@@ -1090,12 +1096,11 @@ var PostHogCoreStateless = /** @class */ (function () {
1090
1096
  body: payload,
1091
1097
  };
1092
1098
  var requestPromise = this.fetchWithRetry(url, fetchOptions);
1093
- this.pendingPromises[promiseUUID] = requestPromise;
1094
- requestPromise
1099
+ this.addPendingPromise(requestPromise
1095
1100
  .then(function () { return done(); })
1096
1101
  .catch(function (err) {
1097
1102
  done(err);
1098
- });
1103
+ }));
1099
1104
  };
1100
1105
  PostHogCoreStateless.prototype.fetchWithRetry = function (url, options, retryOptions) {
1101
1106
  var _a;
@@ -1149,7 +1154,7 @@ var PostHogCoreStateless = /** @class */ (function () {
1149
1154
  clearTimeout(this._flushTimer);
1150
1155
  _a.label = 1;
1151
1156
  case 1:
1152
- _a.trys.push([1, 4, , 5]);
1157
+ _a.trys.push([1, 5, , 6]);
1153
1158
  return [4 /*yield*/, this.flushAsync()];
1154
1159
  case 2:
1155
1160
  _a.sent();
@@ -1157,18 +1162,31 @@ var PostHogCoreStateless = /** @class */ (function () {
1157
1162
  return x.catch(function () {
1158
1163
  // ignore errors as we are shutting down and can't deal with them anyways.
1159
1164
  });
1160
- }))];
1165
+ }))
1166
+ // flush again to make sure we send all events, some of which might've been added
1167
+ // while we were waiting for the pending promises to resolve
1168
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1169
+ ];
1161
1170
  case 3:
1162
1171
  _a.sent();
1163
- return [3 /*break*/, 5];
1172
+ // flush again to make sure we send all events, some of which might've been added
1173
+ // while we were waiting for the pending promises to resolve
1174
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1175
+ return [4 /*yield*/, this.flushAsync()];
1164
1176
  case 4:
1177
+ // flush again to make sure we send all events, some of which might've been added
1178
+ // while we were waiting for the pending promises to resolve
1179
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1180
+ _a.sent();
1181
+ return [3 /*break*/, 6];
1182
+ case 5:
1165
1183
  e_2 = _a.sent();
1166
1184
  if (!isPostHogFetchError(e_2)) {
1167
1185
  throw e_2;
1168
1186
  }
1169
1187
  console.error('Error while shutting down PostHog', e_2);
1170
- return [3 /*break*/, 5];
1171
- case 5: return [2 /*return*/];
1188
+ return [3 /*break*/, 6];
1189
+ case 6: return [2 /*return*/];
1172
1190
  }
1173
1191
  });
1174
1192
  });
@@ -1760,6 +1778,8 @@ function () {
1760
1778
  };
1761
1779
 
1762
1780
  FeatureFlagsPoller.prototype.getFeatureFlag = function (key, distinctId, groups, personProperties, groupProperties) {
1781
+ var _a;
1782
+
1763
1783
  if (groups === void 0) {
1764
1784
  groups = {};
1765
1785
  }
@@ -1773,17 +1793,17 @@ function () {
1773
1793
  }
1774
1794
 
1775
1795
  return __awaiter(this, void 0, void 0, function () {
1776
- var response, featureFlag, _i, _a, flag;
1796
+ var response, featureFlag, _i, _b, flag;
1777
1797
 
1778
- return __generator(this, function (_b) {
1779
- switch (_b.label) {
1798
+ return __generator(this, function (_c) {
1799
+ switch (_c.label) {
1780
1800
  case 0:
1781
1801
  return [4
1782
1802
  /*yield*/
1783
1803
  , this.loadFeatureFlags()];
1784
1804
 
1785
1805
  case 1:
1786
- _b.sent();
1806
+ _c.sent();
1787
1807
 
1788
1808
  response = undefined;
1789
1809
  featureFlag = undefined;
@@ -1794,8 +1814,8 @@ function () {
1794
1814
  , response];
1795
1815
  }
1796
1816
 
1797
- for (_i = 0, _a = this.featureFlags; _i < _a.length; _i++) {
1798
- flag = _a[_i];
1817
+ for (_i = 0, _b = this.featureFlags; _i < _b.length; _i++) {
1818
+ flag = _b[_i];
1799
1819
 
1800
1820
  if (key === flag.key) {
1801
1821
  featureFlag = flag;
@@ -1816,7 +1836,7 @@ function () {
1816
1836
  console.debug("InconclusiveMatchError when computing flag locally: ".concat(key, ": ").concat(e));
1817
1837
  }
1818
1838
  } else if (e instanceof Error) {
1819
- console.error("Error computing flag locally: ".concat(key, ": ").concat(e));
1839
+ (_a = this.onError) === null || _a === void 0 ? void 0 : _a.call(this, new Error("Error computing flag locally: ".concat(key, ": ").concat(e)));
1820
1840
  }
1821
1841
  }
1822
1842
  }
@@ -1992,12 +2012,18 @@ function () {
1992
2012
  var groupName = this.groupTypeMapping[String(aggregation_group_type_index)];
1993
2013
 
1994
2014
  if (!groupName) {
1995
- console.warn("[FEATURE FLAGS] Unknown group type index ".concat(aggregation_group_type_index, " for feature flag ").concat(flag.key));
2015
+ if (this.debugMode) {
2016
+ console.warn("[FEATURE FLAGS] Unknown group type index ".concat(aggregation_group_type_index, " for feature flag ").concat(flag.key));
2017
+ }
2018
+
1996
2019
  throw new InconclusiveMatchError('Flag has unknown group type index');
1997
2020
  }
1998
2021
 
1999
2022
  if (!(groupName in groups)) {
2000
- console.warn("[FEATURE FLAGS] Can't compute group feature flag: ".concat(flag.key, " without group names passed in"));
2023
+ if (this.debugMode) {
2024
+ console.warn("[FEATURE FLAGS] Can't compute group feature flag: ".concat(flag.key, " without group names passed in"));
2025
+ }
2026
+
2001
2027
  return false;
2002
2028
  }
2003
2029
 
@@ -2174,15 +2200,15 @@ function () {
2174
2200
  };
2175
2201
 
2176
2202
  FeatureFlagsPoller.prototype._loadFeatureFlags = function () {
2177
- var _a;
2203
+ var _a, _b;
2178
2204
 
2179
2205
  return __awaiter(this, void 0, void 0, function () {
2180
2206
  var res, responseJson, err_1;
2181
2207
 
2182
2208
  var _this = this;
2183
2209
 
2184
- return __generator(this, function (_b) {
2185
- switch (_b.label) {
2210
+ return __generator(this, function (_c) {
2211
+ switch (_c.label) {
2186
2212
  case 0:
2187
2213
  if (this.poller) {
2188
2214
  clearTimeout(this.poller);
@@ -2192,17 +2218,17 @@ function () {
2192
2218
  this.poller = setTimeout(function () {
2193
2219
  return _this._loadFeatureFlags();
2194
2220
  }, this.pollingInterval);
2195
- _b.label = 1;
2221
+ _c.label = 1;
2196
2222
 
2197
2223
  case 1:
2198
- _b.trys.push([1, 4,, 5]);
2224
+ _c.trys.push([1, 4,, 5]);
2199
2225
 
2200
2226
  return [4
2201
2227
  /*yield*/
2202
2228
  , this._requestFeatureFlagDefinitions()];
2203
2229
 
2204
2230
  case 2:
2205
- res = _b.sent();
2231
+ res = _c.sent();
2206
2232
 
2207
2233
  if (res && res.status === 401) {
2208
2234
  throw new ClientError("Your personalApiKey is invalid. Are you sure you're not using your Project API key? More information: https://posthog.com/docs/api/overview");
@@ -2221,10 +2247,10 @@ function () {
2221
2247
  , res.json()];
2222
2248
 
2223
2249
  case 3:
2224
- responseJson = _b.sent();
2250
+ responseJson = _c.sent();
2225
2251
 
2226
2252
  if (!('flags' in responseJson)) {
2227
- console.error("Invalid response when getting feature flags: ".concat(JSON.stringify(responseJson)));
2253
+ (_a = this.onError) === null || _a === void 0 ? void 0 : _a.call(this, new Error("Invalid response when getting feature flags: ".concat(JSON.stringify(responseJson))));
2228
2254
  }
2229
2255
 
2230
2256
  this.featureFlags = responseJson.flags || [];
@@ -2239,11 +2265,11 @@ function () {
2239
2265
  , 5];
2240
2266
 
2241
2267
  case 4:
2242
- err_1 = _b.sent(); // if an error that is not an instance of ClientError is thrown
2268
+ err_1 = _c.sent(); // if an error that is not an instance of ClientError is thrown
2243
2269
  // we silently ignore the error when reloading feature flags
2244
2270
 
2245
2271
  if (err_1 instanceof ClientError) {
2246
- (_a = this.onError) === null || _a === void 0 ? void 0 : _a.call(this, err_1);
2272
+ (_b = this.onError) === null || _b === void 0 ? void 0 : _b.call(this, err_1);
2247
2273
  }
2248
2274
 
2249
2275
  return [3
@@ -2348,12 +2374,36 @@ function matchProperty(property, propertyValues) {
2348
2374
 
2349
2375
  var overrideValue = propertyValues[key];
2350
2376
 
2377
+ function computeExactMatch(value, overrideValue) {
2378
+ if (Array.isArray(value)) {
2379
+ return value.map(function (val) {
2380
+ return String(val).toLowerCase();
2381
+ }).includes(String(overrideValue).toLowerCase());
2382
+ }
2383
+
2384
+ return String(value).toLowerCase() === String(overrideValue).toLowerCase();
2385
+ }
2386
+
2387
+ function compare(lhs, rhs, operator) {
2388
+ if (operator === 'gt') {
2389
+ return lhs > rhs;
2390
+ } else if (operator === 'gte') {
2391
+ return lhs >= rhs;
2392
+ } else if (operator === 'lt') {
2393
+ return lhs < rhs;
2394
+ } else if (operator === 'lte') {
2395
+ return lhs <= rhs;
2396
+ } else {
2397
+ throw new Error("Invalid operator: ".concat(operator));
2398
+ }
2399
+ }
2400
+
2351
2401
  switch (operator) {
2352
2402
  case 'exact':
2353
- return Array.isArray(value) ? value.indexOf(overrideValue) !== -1 : value === overrideValue;
2403
+ return computeExactMatch(value, overrideValue);
2354
2404
 
2355
2405
  case 'is_not':
2356
- return Array.isArray(value) ? value.indexOf(overrideValue) === -1 : value !== overrideValue;
2406
+ return !computeExactMatch(value, overrideValue);
2357
2407
 
2358
2408
  case 'is_set':
2359
2409
  return key in propertyValues;
@@ -2371,24 +2421,53 @@ function matchProperty(property, propertyValues) {
2371
2421
  return isValidRegex(String(value)) && String(overrideValue).match(String(value)) === null;
2372
2422
 
2373
2423
  case 'gt':
2374
- return typeof overrideValue == typeof value && overrideValue > value;
2375
-
2376
2424
  case 'gte':
2377
- return typeof overrideValue == typeof value && overrideValue >= value;
2378
-
2379
2425
  case 'lt':
2380
- return typeof overrideValue == typeof value && overrideValue < value;
2381
-
2382
2426
  case 'lte':
2383
- return typeof overrideValue == typeof value && overrideValue <= value;
2427
+ {
2428
+ // :TRICKY: We adjust comparison based on the override value passed in,
2429
+ // to make sure we handle both numeric and string comparisons appropriately.
2430
+ var parsedValue = typeof value === 'number' ? value : null;
2431
+
2432
+ if (typeof value === 'string') {
2433
+ try {
2434
+ parsedValue = parseFloat(value);
2435
+ } catch (err) {// pass
2436
+ }
2437
+ }
2438
+
2439
+ if (parsedValue != null && overrideValue != null) {
2440
+ // check both null and undefined
2441
+ if (typeof overrideValue === 'string') {
2442
+ return compare(overrideValue, String(value), operator);
2443
+ } else {
2444
+ return compare(overrideValue, parsedValue, operator);
2445
+ }
2446
+ } else {
2447
+ return compare(String(overrideValue), String(value), operator);
2448
+ }
2449
+ }
2384
2450
 
2385
2451
  case 'is_date_after':
2386
2452
  case 'is_date_before':
2453
+ case 'is_relative_date_before':
2454
+ case 'is_relative_date_after':
2387
2455
  {
2388
- var parsedDate = convertToDateTime(value);
2456
+ var parsedDate = null;
2457
+
2458
+ if (['is_relative_date_before', 'is_relative_date_after'].includes(operator)) {
2459
+ parsedDate = relativeDateParseForFeatureFlagMatching(String(value));
2460
+ } else {
2461
+ parsedDate = convertToDateTime(value);
2462
+ }
2463
+
2464
+ if (parsedDate == null) {
2465
+ throw new InconclusiveMatchError("Invalid date: ".concat(value));
2466
+ }
2467
+
2389
2468
  var overrideDate = convertToDateTime(overrideValue);
2390
2469
 
2391
- if (operator === 'is_date_before') {
2470
+ if (['is_date_before', 'is_relative_date_before'].includes(operator)) {
2392
2471
  return overrideDate < parsedDate;
2393
2472
  }
2394
2473
 
@@ -2396,8 +2475,7 @@ function matchProperty(property, propertyValues) {
2396
2475
  }
2397
2476
 
2398
2477
  default:
2399
- console.error("Unknown operator: ".concat(operator));
2400
- return false;
2478
+ throw new InconclusiveMatchError("Unknown operator: ".concat(operator));
2401
2479
  }
2402
2480
  }
2403
2481
 
@@ -2539,6 +2617,45 @@ function convertToDateTime(value) {
2539
2617
  }
2540
2618
  }
2541
2619
 
2620
+ function relativeDateParseForFeatureFlagMatching(value) {
2621
+ var regex = /^(?<number>[0-9]+)(?<interval>[a-z])$/;
2622
+ var match = value.match(regex);
2623
+ var parsedDt = new Date(new Date().toISOString());
2624
+
2625
+ if (match) {
2626
+ if (!match.groups) {
2627
+ return null;
2628
+ }
2629
+
2630
+ var number = parseInt(match.groups['number']);
2631
+
2632
+ if (number >= 10000) {
2633
+ // Guard against overflow, disallow numbers greater than 10_000
2634
+ return null;
2635
+ }
2636
+
2637
+ var interval = match.groups['interval'];
2638
+
2639
+ if (interval == 'h') {
2640
+ parsedDt.setUTCHours(parsedDt.getUTCHours() - number);
2641
+ } else if (interval == 'd') {
2642
+ parsedDt.setUTCDate(parsedDt.getUTCDate() - number);
2643
+ } else if (interval == 'w') {
2644
+ parsedDt.setUTCDate(parsedDt.getUTCDate() - number * 7);
2645
+ } else if (interval == 'm') {
2646
+ parsedDt.setUTCMonth(parsedDt.getUTCMonth() - number);
2647
+ } else if (interval == 'y') {
2648
+ parsedDt.setUTCFullYear(parsedDt.getUTCFullYear() - number);
2649
+ } else {
2650
+ return null;
2651
+ }
2652
+
2653
+ return parsedDt;
2654
+ } else {
2655
+ return null;
2656
+ }
2657
+ }
2658
+
2542
2659
  var THIRTY_SECONDS = 30 * 1000;
2543
2660
  var MAX_CACHE_SIZE = 50 * 1000; // The actual exported Nodejs API.
2544
2661
 
@@ -2640,41 +2757,94 @@ function (_super) {
2640
2757
  timestamp: timestamp,
2641
2758
  disableGeoip: disableGeoip
2642
2759
  });
2643
- };
2760
+ }; // :TRICKY: If we flush, or need to shut down, to not lose events we want this promise to resolve before we flush
2644
2761
 
2645
- if (sendFeatureFlags) {
2646
- _super.prototype.getFeatureFlagsStateless.call(this, distinctId, groups, undefined, undefined, disableGeoip).then(function (flags) {
2647
- var featureVariantProperties = {};
2648
2762
 
2649
- if (flags) {
2650
- for (var _i = 0, _a = Object.entries(flags); _i < _a.length; _i++) {
2651
- var _b = _a[_i],
2652
- feature = _b[0],
2653
- variant = _b[1];
2763
+ var capturePromise = Promise.resolve().then(function () {
2764
+ return __awaiter(_this, void 0, void 0, function () {
2765
+ var groupsWithStringValues, _i, _a, _b, key, value;
2654
2766
 
2655
- if (variant !== false) {
2656
- featureVariantProperties["$feature/".concat(feature)] = variant;
2657
- }
2767
+ var _c, _d;
2768
+
2769
+ return __generator(this, function (_e) {
2770
+ switch (_e.label) {
2771
+ case 0:
2772
+ if (!sendFeatureFlags) return [3
2773
+ /*break*/
2774
+ , 2];
2775
+ return [4
2776
+ /*yield*/
2777
+ , _super.prototype.getFeatureFlagsStateless.call(this, distinctId, groups, undefined, undefined, disableGeoip)];
2778
+
2779
+ case 1:
2780
+ // If we are sending feature flags, we need to make sure we have the latest flags
2781
+ return [2
2782
+ /*return*/
2783
+ , _e.sent()];
2784
+
2785
+ case 2:
2786
+ if (!((((_d = (_c = this.featureFlagsPoller) === null || _c === void 0 ? void 0 : _c.featureFlags) === null || _d === void 0 ? void 0 : _d.length) || 0) > 0)) return [3
2787
+ /*break*/
2788
+ , 4];
2789
+ groupsWithStringValues = {};
2790
+
2791
+ for (_i = 0, _a = Object.entries(groups || {}); _i < _a.length; _i++) {
2792
+ _b = _a[_i], key = _b[0], value = _b[1];
2793
+ groupsWithStringValues[key] = String(value);
2794
+ }
2795
+
2796
+ return [4
2797
+ /*yield*/
2798
+ , this.getAllFlags(distinctId, {
2799
+ groups: groupsWithStringValues,
2800
+ disableGeoip: disableGeoip,
2801
+ onlyEvaluateLocally: true
2802
+ })];
2803
+
2804
+ case 3:
2805
+ return [2
2806
+ /*return*/
2807
+ , _e.sent()];
2808
+
2809
+ case 4:
2810
+ return [2
2811
+ /*return*/
2812
+ , {}];
2658
2813
  }
2814
+ });
2815
+ });
2816
+ }).then(function (flags) {
2817
+ // Derive the relevant flag properties to add
2818
+ var additionalProperties = {};
2819
+
2820
+ if (flags) {
2821
+ for (var _i = 0, _a = Object.entries(flags); _i < _a.length; _i++) {
2822
+ var _b = _a[_i],
2823
+ feature = _b[0],
2824
+ variant = _b[1];
2825
+ additionalProperties["$feature/".concat(feature)] = variant;
2659
2826
  }
2827
+ }
2660
2828
 
2661
- var activeFlags = Object.keys(flags || {}).filter(function (flag) {
2662
- return (flags === null || flags === void 0 ? void 0 : flags[flag]) !== false;
2663
- });
2829
+ var activeFlags = Object.keys(flags || {}).filter(function (flag) {
2830
+ return (flags === null || flags === void 0 ? void 0 : flags[flag]) !== false;
2831
+ });
2664
2832
 
2665
- var flagProperties = __assign({
2666
- $active_feature_flags: activeFlags || undefined
2667
- }, featureVariantProperties);
2833
+ if (activeFlags.length > 0) {
2834
+ additionalProperties['$active_feature_flags'] = activeFlags;
2835
+ }
2668
2836
 
2669
- _capture(__assign(__assign(__assign({}, properties), {
2670
- $groups: groups
2671
- }), flagProperties));
2672
- });
2673
- } else {
2674
- _capture(__assign(__assign({}, properties), {
2837
+ return additionalProperties;
2838
+ }).catch(function () {
2839
+ // Something went wrong getting the flag info - we should capture the event anyways
2840
+ return {};
2841
+ }).then(function (additionalProperties) {
2842
+ // No matter what - capture the event
2843
+ _capture(__assign(__assign(__assign({}, additionalProperties), properties), {
2675
2844
  $groups: groups
2676
2845
  }));
2677
- }
2846
+ });
2847
+ this.addPendingPromise(capturePromise);
2678
2848
  };
2679
2849
 
2680
2850
  PostHog.prototype.identify = function (_a) {
@@ -2701,15 +2871,18 @@ function (_super) {
2701
2871
  var _a;
2702
2872
 
2703
2873
  return __awaiter(this, void 0, void 0, function () {
2704
- var _b, groups, personProperties, groupProperties, disableGeoip, _c, onlyEvaluateLocally, sendFeatureFlagEvents, response, flagWasLocallyEvaluated, featureFlagReportedKey;
2874
+ var _b, groups, disableGeoip, _c, onlyEvaluateLocally, sendFeatureFlagEvents, personProperties, groupProperties, adjustedProperties, response, flagWasLocallyEvaluated, featureFlagReportedKey;
2705
2875
 
2706
2876
  var _d;
2707
2877
 
2708
2878
  return __generator(this, function (_e) {
2709
2879
  switch (_e.label) {
2710
2880
  case 0:
2711
- _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties, disableGeoip = _b.disableGeoip;
2712
- _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, sendFeatureFlagEvents = _c.sendFeatureFlagEvents; // set defaults
2881
+ _b = options || {}, groups = _b.groups, disableGeoip = _b.disableGeoip;
2882
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, sendFeatureFlagEvents = _c.sendFeatureFlagEvents, personProperties = _c.personProperties, groupProperties = _c.groupProperties;
2883
+ adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
2884
+ personProperties = adjustedProperties.allPersonProperties;
2885
+ groupProperties = adjustedProperties.allGroupProperties; // set defaults
2713
2886
 
2714
2887
  if (onlyEvaluateLocally == undefined) {
2715
2888
  onlyEvaluateLocally = false;
@@ -2776,13 +2949,16 @@ function (_super) {
2776
2949
  var _a;
2777
2950
 
2778
2951
  return __awaiter(this, void 0, void 0, function () {
2779
- var _b, groups, personProperties, groupProperties, disableGeoip, _c, onlyEvaluateLocally, response, payloadWasLocallyEvaluated;
2952
+ var _b, groups, disableGeoip, _c, onlyEvaluateLocally, personProperties, groupProperties, adjustedProperties, response, payloadWasLocallyEvaluated;
2780
2953
 
2781
2954
  return __generator(this, function (_d) {
2782
2955
  switch (_d.label) {
2783
2956
  case 0:
2784
- _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties, disableGeoip = _b.disableGeoip;
2785
- _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, _c.sendFeatureFlagEvents;
2957
+ _b = options || {}, groups = _b.groups, disableGeoip = _b.disableGeoip;
2958
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, _c.sendFeatureFlagEvents, personProperties = _c.personProperties, groupProperties = _c.groupProperties;
2959
+ adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
2960
+ personProperties = adjustedProperties.allPersonProperties;
2961
+ groupProperties = adjustedProperties.allGroupProperties;
2786
2962
  response = undefined;
2787
2963
  if (!!matchValue) return [3
2788
2964
  /*break*/
@@ -2902,13 +3078,16 @@ function (_super) {
2902
3078
  var _a;
2903
3079
 
2904
3080
  return __awaiter(this, void 0, void 0, function () {
2905
- var _b, groups, personProperties, groupProperties, disableGeoip, onlyEvaluateLocally, localEvaluationResult, featureFlags, featureFlagPayloads, fallbackToDecide, remoteEvaluationResult;
3081
+ var _b, groups, disableGeoip, _c, onlyEvaluateLocally, personProperties, groupProperties, adjustedProperties, localEvaluationResult, featureFlags, featureFlagPayloads, fallbackToDecide, remoteEvaluationResult;
2906
3082
 
2907
- return __generator(this, function (_c) {
2908
- switch (_c.label) {
3083
+ return __generator(this, function (_d) {
3084
+ switch (_d.label) {
2909
3085
  case 0:
2910
- _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties, disableGeoip = _b.disableGeoip;
2911
- onlyEvaluateLocally = (options || {}).onlyEvaluateLocally; // set defaults
3086
+ _b = options || {}, groups = _b.groups, disableGeoip = _b.disableGeoip;
3087
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, personProperties = _c.personProperties, groupProperties = _c.groupProperties;
3088
+ adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
3089
+ personProperties = adjustedProperties.allPersonProperties;
3090
+ groupProperties = adjustedProperties.allGroupProperties; // set defaults
2912
3091
 
2913
3092
  if (onlyEvaluateLocally == undefined) {
2914
3093
  onlyEvaluateLocally = false;
@@ -2919,7 +3098,7 @@ function (_super) {
2919
3098
  , (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.getAllFlagsAndPayloads(distinctId, groups, personProperties, groupProperties)];
2920
3099
 
2921
3100
  case 1:
2922
- localEvaluationResult = _c.sent();
3101
+ localEvaluationResult = _d.sent();
2923
3102
  featureFlags = {};
2924
3103
  featureFlagPayloads = {};
2925
3104
  fallbackToDecide = true;
@@ -2938,10 +3117,10 @@ function (_super) {
2938
3117
  , _super.prototype.getFeatureFlagsAndPayloadsStateless.call(this, distinctId, groups, personProperties, groupProperties, disableGeoip)];
2939
3118
 
2940
3119
  case 2:
2941
- remoteEvaluationResult = _c.sent();
3120
+ remoteEvaluationResult = _d.sent();
2942
3121
  featureFlags = __assign(__assign({}, featureFlags), remoteEvaluationResult.flags || {});
2943
3122
  featureFlagPayloads = __assign(__assign({}, featureFlagPayloads), remoteEvaluationResult.payloads || {});
2944
- _c.label = 3;
3123
+ _d.label = 3;
2945
3124
 
2946
3125
  case 3:
2947
3126
  return [2
@@ -3006,6 +3185,28 @@ function (_super) {
3006
3185
  });
3007
3186
  };
3008
3187
 
3188
+ PostHog.prototype.addLocalPersonAndGroupProperties = function (distinctId, groups, personProperties, groupProperties) {
3189
+ var allPersonProperties = __assign({
3190
+ $current_distinct_id: distinctId
3191
+ }, personProperties || {});
3192
+
3193
+ var allGroupProperties = {};
3194
+
3195
+ if (groups) {
3196
+ for (var _i = 0, _a = Object.keys(groups); _i < _a.length; _i++) {
3197
+ var groupName = _a[_i];
3198
+ allGroupProperties[groupName] = __assign({
3199
+ $group_key: groups[groupName]
3200
+ }, (groupProperties === null || groupProperties === void 0 ? void 0 : groupProperties[groupName]) || {});
3201
+ }
3202
+ }
3203
+
3204
+ return {
3205
+ allPersonProperties: allPersonProperties,
3206
+ allGroupProperties: allGroupProperties
3207
+ };
3208
+ };
3209
+
3009
3210
  return PostHog;
3010
3211
  }(PostHogCoreStateless);
3011
3212