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/lib/index.d.ts CHANGED
@@ -108,9 +108,9 @@ declare abstract class PostHogCoreStateless {
108
108
  private captureMode;
109
109
  private removeDebugCallback?;
110
110
  private debugMode;
111
- private pendingPromises;
112
111
  private disableGeoip;
113
112
  private _optoutOverride;
113
+ private pendingPromises;
114
114
  protected _events: SimpleEventEmitter;
115
115
  protected _flushTimer?: any;
116
116
  protected _retryOptions: RetriableOptions;
@@ -128,6 +128,7 @@ declare abstract class PostHogCoreStateless {
128
128
  on(event: string, cb: (...args: any[]) => void): () => void;
129
129
  debug(enabled?: boolean): void;
130
130
  private buildPayload;
131
+ protected addPendingPromise(promise: Promise<any>): void;
131
132
  /***
132
133
  *** TRACKING
133
134
  ***/
@@ -377,6 +378,7 @@ declare class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
377
378
  reloadFeatureFlags(): Promise<void>;
378
379
  shutdown(): void;
379
380
  shutdownAsync(): Promise<void>;
381
+ private addLocalPersonAndGroupProperties;
380
382
  }
381
383
 
382
384
  /**
package/lib/index.esm.js CHANGED
@@ -154,7 +154,7 @@ function __spreadArray(to, from, pack) {
154
154
  return to.concat(ar || Array.prototype.slice.call(from));
155
155
  }
156
156
 
157
- var version = "3.3.0";
157
+ var version = "3.5.0";
158
158
 
159
159
  var PostHogPersistedProperty;
160
160
  (function (PostHogPersistedProperty) {
@@ -747,8 +747,8 @@ var PostHogCoreStateless = /** @class */ (function () {
747
747
  function PostHogCoreStateless(apiKey, options) {
748
748
  var _a, _b, _c, _d, _e;
749
749
  this.debugMode = false;
750
- this.pendingPromises = {};
751
750
  this.disableGeoip = true;
751
+ this.pendingPromises = {};
752
752
  // internal
753
753
  this._events = new SimpleEventEmitter();
754
754
  assert(apiKey, "You must pass your PostHog project's api key.");
@@ -806,6 +806,14 @@ var PostHogCoreStateless = /** @class */ (function () {
806
806
  properties: __assign(__assign({}, (payload.properties || {})), this.getCommonEventProperties()),
807
807
  };
808
808
  };
809
+ PostHogCoreStateless.prototype.addPendingPromise = function (promise) {
810
+ var _this = this;
811
+ var promiseUUID = generateUUID();
812
+ this.pendingPromises[promiseUUID] = promise;
813
+ promise.finally(function () {
814
+ delete _this.pendingPromises[promiseUUID];
815
+ });
816
+ };
809
817
  /***
810
818
  *** TRACKING
811
819
  ***/
@@ -856,6 +864,7 @@ var PostHogCoreStateless = /** @class */ (function () {
856
864
  if (extraPayload === void 0) { extraPayload = {}; }
857
865
  return __awaiter(this, void 0, void 0, function () {
858
866
  var url, fetchOptions;
867
+ var _this = this;
859
868
  return __generator(this, function (_a) {
860
869
  url = "".concat(this.host, "/decide/?v=3");
861
870
  fetchOptions = {
@@ -866,7 +875,7 @@ var PostHogCoreStateless = /** @class */ (function () {
866
875
  return [2 /*return*/, this.fetchWithRetry(url, fetchOptions)
867
876
  .then(function (response) { return response.json(); })
868
877
  .catch(function (error) {
869
- console.error('Error fetching feature flags', error);
878
+ _this._events.emit('error', error);
870
879
  return undefined;
871
880
  })];
872
881
  });
@@ -1053,14 +1062,11 @@ var PostHogCoreStateless = /** @class */ (function () {
1053
1062
  batch: messages,
1054
1063
  sent_at: currentISOTime(),
1055
1064
  };
1056
- var promiseUUID = generateUUID();
1057
1065
  var done = function (err) {
1058
1066
  if (err) {
1059
1067
  _this._events.emit('error', err);
1060
1068
  }
1061
1069
  callback === null || callback === void 0 ? void 0 : callback(err, messages);
1062
- // remove promise from pendingPromises
1063
- delete _this.pendingPromises[promiseUUID];
1064
1070
  _this._events.emit('flush', messages);
1065
1071
  };
1066
1072
  // Don't set the user agent if we're not on a browser. The latest spec allows
@@ -1086,12 +1092,11 @@ var PostHogCoreStateless = /** @class */ (function () {
1086
1092
  body: payload,
1087
1093
  };
1088
1094
  var requestPromise = this.fetchWithRetry(url, fetchOptions);
1089
- this.pendingPromises[promiseUUID] = requestPromise;
1090
- requestPromise
1095
+ this.addPendingPromise(requestPromise
1091
1096
  .then(function () { return done(); })
1092
1097
  .catch(function (err) {
1093
1098
  done(err);
1094
- });
1099
+ }));
1095
1100
  };
1096
1101
  PostHogCoreStateless.prototype.fetchWithRetry = function (url, options, retryOptions) {
1097
1102
  var _a;
@@ -1145,7 +1150,7 @@ var PostHogCoreStateless = /** @class */ (function () {
1145
1150
  clearTimeout(this._flushTimer);
1146
1151
  _a.label = 1;
1147
1152
  case 1:
1148
- _a.trys.push([1, 4, , 5]);
1153
+ _a.trys.push([1, 5, , 6]);
1149
1154
  return [4 /*yield*/, this.flushAsync()];
1150
1155
  case 2:
1151
1156
  _a.sent();
@@ -1153,18 +1158,31 @@ var PostHogCoreStateless = /** @class */ (function () {
1153
1158
  return x.catch(function () {
1154
1159
  // ignore errors as we are shutting down and can't deal with them anyways.
1155
1160
  });
1156
- }))];
1161
+ }))
1162
+ // flush again to make sure we send all events, some of which might've been added
1163
+ // while we were waiting for the pending promises to resolve
1164
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1165
+ ];
1157
1166
  case 3:
1158
1167
  _a.sent();
1159
- return [3 /*break*/, 5];
1168
+ // flush again to make sure we send all events, some of which might've been added
1169
+ // while we were waiting for the pending promises to resolve
1170
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1171
+ return [4 /*yield*/, this.flushAsync()];
1160
1172
  case 4:
1173
+ // flush again to make sure we send all events, some of which might've been added
1174
+ // while we were waiting for the pending promises to resolve
1175
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1176
+ _a.sent();
1177
+ return [3 /*break*/, 6];
1178
+ case 5:
1161
1179
  e_2 = _a.sent();
1162
1180
  if (!isPostHogFetchError(e_2)) {
1163
1181
  throw e_2;
1164
1182
  }
1165
1183
  console.error('Error while shutting down PostHog', e_2);
1166
- return [3 /*break*/, 5];
1167
- case 5: return [2 /*return*/];
1184
+ return [3 /*break*/, 6];
1185
+ case 6: return [2 /*return*/];
1168
1186
  }
1169
1187
  });
1170
1188
  });
@@ -1756,6 +1774,8 @@ function () {
1756
1774
  };
1757
1775
 
1758
1776
  FeatureFlagsPoller.prototype.getFeatureFlag = function (key, distinctId, groups, personProperties, groupProperties) {
1777
+ var _a;
1778
+
1759
1779
  if (groups === void 0) {
1760
1780
  groups = {};
1761
1781
  }
@@ -1769,17 +1789,17 @@ function () {
1769
1789
  }
1770
1790
 
1771
1791
  return __awaiter(this, void 0, void 0, function () {
1772
- var response, featureFlag, _i, _a, flag;
1792
+ var response, featureFlag, _i, _b, flag;
1773
1793
 
1774
- return __generator(this, function (_b) {
1775
- switch (_b.label) {
1794
+ return __generator(this, function (_c) {
1795
+ switch (_c.label) {
1776
1796
  case 0:
1777
1797
  return [4
1778
1798
  /*yield*/
1779
1799
  , this.loadFeatureFlags()];
1780
1800
 
1781
1801
  case 1:
1782
- _b.sent();
1802
+ _c.sent();
1783
1803
 
1784
1804
  response = undefined;
1785
1805
  featureFlag = undefined;
@@ -1790,8 +1810,8 @@ function () {
1790
1810
  , response];
1791
1811
  }
1792
1812
 
1793
- for (_i = 0, _a = this.featureFlags; _i < _a.length; _i++) {
1794
- flag = _a[_i];
1813
+ for (_i = 0, _b = this.featureFlags; _i < _b.length; _i++) {
1814
+ flag = _b[_i];
1795
1815
 
1796
1816
  if (key === flag.key) {
1797
1817
  featureFlag = flag;
@@ -1812,7 +1832,7 @@ function () {
1812
1832
  console.debug("InconclusiveMatchError when computing flag locally: ".concat(key, ": ").concat(e));
1813
1833
  }
1814
1834
  } else if (e instanceof Error) {
1815
- console.error("Error computing flag locally: ".concat(key, ": ").concat(e));
1835
+ (_a = this.onError) === null || _a === void 0 ? void 0 : _a.call(this, new Error("Error computing flag locally: ".concat(key, ": ").concat(e)));
1816
1836
  }
1817
1837
  }
1818
1838
  }
@@ -1988,12 +2008,18 @@ function () {
1988
2008
  var groupName = this.groupTypeMapping[String(aggregation_group_type_index)];
1989
2009
 
1990
2010
  if (!groupName) {
1991
- console.warn("[FEATURE FLAGS] Unknown group type index ".concat(aggregation_group_type_index, " for feature flag ").concat(flag.key));
2011
+ if (this.debugMode) {
2012
+ console.warn("[FEATURE FLAGS] Unknown group type index ".concat(aggregation_group_type_index, " for feature flag ").concat(flag.key));
2013
+ }
2014
+
1992
2015
  throw new InconclusiveMatchError('Flag has unknown group type index');
1993
2016
  }
1994
2017
 
1995
2018
  if (!(groupName in groups)) {
1996
- console.warn("[FEATURE FLAGS] Can't compute group feature flag: ".concat(flag.key, " without group names passed in"));
2019
+ if (this.debugMode) {
2020
+ console.warn("[FEATURE FLAGS] Can't compute group feature flag: ".concat(flag.key, " without group names passed in"));
2021
+ }
2022
+
1997
2023
  return false;
1998
2024
  }
1999
2025
 
@@ -2170,15 +2196,15 @@ function () {
2170
2196
  };
2171
2197
 
2172
2198
  FeatureFlagsPoller.prototype._loadFeatureFlags = function () {
2173
- var _a;
2199
+ var _a, _b;
2174
2200
 
2175
2201
  return __awaiter(this, void 0, void 0, function () {
2176
2202
  var res, responseJson, err_1;
2177
2203
 
2178
2204
  var _this = this;
2179
2205
 
2180
- return __generator(this, function (_b) {
2181
- switch (_b.label) {
2206
+ return __generator(this, function (_c) {
2207
+ switch (_c.label) {
2182
2208
  case 0:
2183
2209
  if (this.poller) {
2184
2210
  clearTimeout(this.poller);
@@ -2188,17 +2214,17 @@ function () {
2188
2214
  this.poller = setTimeout(function () {
2189
2215
  return _this._loadFeatureFlags();
2190
2216
  }, this.pollingInterval);
2191
- _b.label = 1;
2217
+ _c.label = 1;
2192
2218
 
2193
2219
  case 1:
2194
- _b.trys.push([1, 4,, 5]);
2220
+ _c.trys.push([1, 4,, 5]);
2195
2221
 
2196
2222
  return [4
2197
2223
  /*yield*/
2198
2224
  , this._requestFeatureFlagDefinitions()];
2199
2225
 
2200
2226
  case 2:
2201
- res = _b.sent();
2227
+ res = _c.sent();
2202
2228
 
2203
2229
  if (res && res.status === 401) {
2204
2230
  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");
@@ -2217,10 +2243,10 @@ function () {
2217
2243
  , res.json()];
2218
2244
 
2219
2245
  case 3:
2220
- responseJson = _b.sent();
2246
+ responseJson = _c.sent();
2221
2247
 
2222
2248
  if (!('flags' in responseJson)) {
2223
- console.error("Invalid response when getting feature flags: ".concat(JSON.stringify(responseJson)));
2249
+ (_a = this.onError) === null || _a === void 0 ? void 0 : _a.call(this, new Error("Invalid response when getting feature flags: ".concat(JSON.stringify(responseJson))));
2224
2250
  }
2225
2251
 
2226
2252
  this.featureFlags = responseJson.flags || [];
@@ -2235,11 +2261,11 @@ function () {
2235
2261
  , 5];
2236
2262
 
2237
2263
  case 4:
2238
- err_1 = _b.sent(); // if an error that is not an instance of ClientError is thrown
2264
+ err_1 = _c.sent(); // if an error that is not an instance of ClientError is thrown
2239
2265
  // we silently ignore the error when reloading feature flags
2240
2266
 
2241
2267
  if (err_1 instanceof ClientError) {
2242
- (_a = this.onError) === null || _a === void 0 ? void 0 : _a.call(this, err_1);
2268
+ (_b = this.onError) === null || _b === void 0 ? void 0 : _b.call(this, err_1);
2243
2269
  }
2244
2270
 
2245
2271
  return [3
@@ -2344,12 +2370,36 @@ function matchProperty(property, propertyValues) {
2344
2370
 
2345
2371
  var overrideValue = propertyValues[key];
2346
2372
 
2373
+ function computeExactMatch(value, overrideValue) {
2374
+ if (Array.isArray(value)) {
2375
+ return value.map(function (val) {
2376
+ return String(val).toLowerCase();
2377
+ }).includes(String(overrideValue).toLowerCase());
2378
+ }
2379
+
2380
+ return String(value).toLowerCase() === String(overrideValue).toLowerCase();
2381
+ }
2382
+
2383
+ function compare(lhs, rhs, operator) {
2384
+ if (operator === 'gt') {
2385
+ return lhs > rhs;
2386
+ } else if (operator === 'gte') {
2387
+ return lhs >= rhs;
2388
+ } else if (operator === 'lt') {
2389
+ return lhs < rhs;
2390
+ } else if (operator === 'lte') {
2391
+ return lhs <= rhs;
2392
+ } else {
2393
+ throw new Error("Invalid operator: ".concat(operator));
2394
+ }
2395
+ }
2396
+
2347
2397
  switch (operator) {
2348
2398
  case 'exact':
2349
- return Array.isArray(value) ? value.indexOf(overrideValue) !== -1 : value === overrideValue;
2399
+ return computeExactMatch(value, overrideValue);
2350
2400
 
2351
2401
  case 'is_not':
2352
- return Array.isArray(value) ? value.indexOf(overrideValue) === -1 : value !== overrideValue;
2402
+ return !computeExactMatch(value, overrideValue);
2353
2403
 
2354
2404
  case 'is_set':
2355
2405
  return key in propertyValues;
@@ -2367,24 +2417,53 @@ function matchProperty(property, propertyValues) {
2367
2417
  return isValidRegex(String(value)) && String(overrideValue).match(String(value)) === null;
2368
2418
 
2369
2419
  case 'gt':
2370
- return typeof overrideValue == typeof value && overrideValue > value;
2371
-
2372
2420
  case 'gte':
2373
- return typeof overrideValue == typeof value && overrideValue >= value;
2374
-
2375
2421
  case 'lt':
2376
- return typeof overrideValue == typeof value && overrideValue < value;
2377
-
2378
2422
  case 'lte':
2379
- return typeof overrideValue == typeof value && overrideValue <= value;
2423
+ {
2424
+ // :TRICKY: We adjust comparison based on the override value passed in,
2425
+ // to make sure we handle both numeric and string comparisons appropriately.
2426
+ var parsedValue = typeof value === 'number' ? value : null;
2427
+
2428
+ if (typeof value === 'string') {
2429
+ try {
2430
+ parsedValue = parseFloat(value);
2431
+ } catch (err) {// pass
2432
+ }
2433
+ }
2434
+
2435
+ if (parsedValue != null && overrideValue != null) {
2436
+ // check both null and undefined
2437
+ if (typeof overrideValue === 'string') {
2438
+ return compare(overrideValue, String(value), operator);
2439
+ } else {
2440
+ return compare(overrideValue, parsedValue, operator);
2441
+ }
2442
+ } else {
2443
+ return compare(String(overrideValue), String(value), operator);
2444
+ }
2445
+ }
2380
2446
 
2381
2447
  case 'is_date_after':
2382
2448
  case 'is_date_before':
2449
+ case 'is_relative_date_before':
2450
+ case 'is_relative_date_after':
2383
2451
  {
2384
- var parsedDate = convertToDateTime(value);
2452
+ var parsedDate = null;
2453
+
2454
+ if (['is_relative_date_before', 'is_relative_date_after'].includes(operator)) {
2455
+ parsedDate = relativeDateParseForFeatureFlagMatching(String(value));
2456
+ } else {
2457
+ parsedDate = convertToDateTime(value);
2458
+ }
2459
+
2460
+ if (parsedDate == null) {
2461
+ throw new InconclusiveMatchError("Invalid date: ".concat(value));
2462
+ }
2463
+
2385
2464
  var overrideDate = convertToDateTime(overrideValue);
2386
2465
 
2387
- if (operator === 'is_date_before') {
2466
+ if (['is_date_before', 'is_relative_date_before'].includes(operator)) {
2388
2467
  return overrideDate < parsedDate;
2389
2468
  }
2390
2469
 
@@ -2392,8 +2471,7 @@ function matchProperty(property, propertyValues) {
2392
2471
  }
2393
2472
 
2394
2473
  default:
2395
- console.error("Unknown operator: ".concat(operator));
2396
- return false;
2474
+ throw new InconclusiveMatchError("Unknown operator: ".concat(operator));
2397
2475
  }
2398
2476
  }
2399
2477
 
@@ -2535,6 +2613,45 @@ function convertToDateTime(value) {
2535
2613
  }
2536
2614
  }
2537
2615
 
2616
+ function relativeDateParseForFeatureFlagMatching(value) {
2617
+ var regex = /^(?<number>[0-9]+)(?<interval>[a-z])$/;
2618
+ var match = value.match(regex);
2619
+ var parsedDt = new Date(new Date().toISOString());
2620
+
2621
+ if (match) {
2622
+ if (!match.groups) {
2623
+ return null;
2624
+ }
2625
+
2626
+ var number = parseInt(match.groups['number']);
2627
+
2628
+ if (number >= 10000) {
2629
+ // Guard against overflow, disallow numbers greater than 10_000
2630
+ return null;
2631
+ }
2632
+
2633
+ var interval = match.groups['interval'];
2634
+
2635
+ if (interval == 'h') {
2636
+ parsedDt.setUTCHours(parsedDt.getUTCHours() - number);
2637
+ } else if (interval == 'd') {
2638
+ parsedDt.setUTCDate(parsedDt.getUTCDate() - number);
2639
+ } else if (interval == 'w') {
2640
+ parsedDt.setUTCDate(parsedDt.getUTCDate() - number * 7);
2641
+ } else if (interval == 'm') {
2642
+ parsedDt.setUTCMonth(parsedDt.getUTCMonth() - number);
2643
+ } else if (interval == 'y') {
2644
+ parsedDt.setUTCFullYear(parsedDt.getUTCFullYear() - number);
2645
+ } else {
2646
+ return null;
2647
+ }
2648
+
2649
+ return parsedDt;
2650
+ } else {
2651
+ return null;
2652
+ }
2653
+ }
2654
+
2538
2655
  var THIRTY_SECONDS = 30 * 1000;
2539
2656
  var MAX_CACHE_SIZE = 50 * 1000; // The actual exported Nodejs API.
2540
2657
 
@@ -2636,41 +2753,94 @@ function (_super) {
2636
2753
  timestamp: timestamp,
2637
2754
  disableGeoip: disableGeoip
2638
2755
  });
2639
- };
2756
+ }; // :TRICKY: If we flush, or need to shut down, to not lose events we want this promise to resolve before we flush
2640
2757
 
2641
- if (sendFeatureFlags) {
2642
- _super.prototype.getFeatureFlagsStateless.call(this, distinctId, groups, undefined, undefined, disableGeoip).then(function (flags) {
2643
- var featureVariantProperties = {};
2644
2758
 
2645
- if (flags) {
2646
- for (var _i = 0, _a = Object.entries(flags); _i < _a.length; _i++) {
2647
- var _b = _a[_i],
2648
- feature = _b[0],
2649
- variant = _b[1];
2759
+ var capturePromise = Promise.resolve().then(function () {
2760
+ return __awaiter(_this, void 0, void 0, function () {
2761
+ var groupsWithStringValues, _i, _a, _b, key, value;
2650
2762
 
2651
- if (variant !== false) {
2652
- featureVariantProperties["$feature/".concat(feature)] = variant;
2653
- }
2763
+ var _c, _d;
2764
+
2765
+ return __generator(this, function (_e) {
2766
+ switch (_e.label) {
2767
+ case 0:
2768
+ if (!sendFeatureFlags) return [3
2769
+ /*break*/
2770
+ , 2];
2771
+ return [4
2772
+ /*yield*/
2773
+ , _super.prototype.getFeatureFlagsStateless.call(this, distinctId, groups, undefined, undefined, disableGeoip)];
2774
+
2775
+ case 1:
2776
+ // If we are sending feature flags, we need to make sure we have the latest flags
2777
+ return [2
2778
+ /*return*/
2779
+ , _e.sent()];
2780
+
2781
+ case 2:
2782
+ 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
2783
+ /*break*/
2784
+ , 4];
2785
+ groupsWithStringValues = {};
2786
+
2787
+ for (_i = 0, _a = Object.entries(groups || {}); _i < _a.length; _i++) {
2788
+ _b = _a[_i], key = _b[0], value = _b[1];
2789
+ groupsWithStringValues[key] = String(value);
2790
+ }
2791
+
2792
+ return [4
2793
+ /*yield*/
2794
+ , this.getAllFlags(distinctId, {
2795
+ groups: groupsWithStringValues,
2796
+ disableGeoip: disableGeoip,
2797
+ onlyEvaluateLocally: true
2798
+ })];
2799
+
2800
+ case 3:
2801
+ return [2
2802
+ /*return*/
2803
+ , _e.sent()];
2804
+
2805
+ case 4:
2806
+ return [2
2807
+ /*return*/
2808
+ , {}];
2654
2809
  }
2810
+ });
2811
+ });
2812
+ }).then(function (flags) {
2813
+ // Derive the relevant flag properties to add
2814
+ var additionalProperties = {};
2815
+
2816
+ if (flags) {
2817
+ for (var _i = 0, _a = Object.entries(flags); _i < _a.length; _i++) {
2818
+ var _b = _a[_i],
2819
+ feature = _b[0],
2820
+ variant = _b[1];
2821
+ additionalProperties["$feature/".concat(feature)] = variant;
2655
2822
  }
2823
+ }
2656
2824
 
2657
- var activeFlags = Object.keys(flags || {}).filter(function (flag) {
2658
- return (flags === null || flags === void 0 ? void 0 : flags[flag]) !== false;
2659
- });
2825
+ var activeFlags = Object.keys(flags || {}).filter(function (flag) {
2826
+ return (flags === null || flags === void 0 ? void 0 : flags[flag]) !== false;
2827
+ });
2660
2828
 
2661
- var flagProperties = __assign({
2662
- $active_feature_flags: activeFlags || undefined
2663
- }, featureVariantProperties);
2829
+ if (activeFlags.length > 0) {
2830
+ additionalProperties['$active_feature_flags'] = activeFlags;
2831
+ }
2664
2832
 
2665
- _capture(__assign(__assign(__assign({}, properties), {
2666
- $groups: groups
2667
- }), flagProperties));
2668
- });
2669
- } else {
2670
- _capture(__assign(__assign({}, properties), {
2833
+ return additionalProperties;
2834
+ }).catch(function () {
2835
+ // Something went wrong getting the flag info - we should capture the event anyways
2836
+ return {};
2837
+ }).then(function (additionalProperties) {
2838
+ // No matter what - capture the event
2839
+ _capture(__assign(__assign(__assign({}, additionalProperties), properties), {
2671
2840
  $groups: groups
2672
2841
  }));
2673
- }
2842
+ });
2843
+ this.addPendingPromise(capturePromise);
2674
2844
  };
2675
2845
 
2676
2846
  PostHog.prototype.identify = function (_a) {
@@ -2697,15 +2867,18 @@ function (_super) {
2697
2867
  var _a;
2698
2868
 
2699
2869
  return __awaiter(this, void 0, void 0, function () {
2700
- var _b, groups, personProperties, groupProperties, disableGeoip, _c, onlyEvaluateLocally, sendFeatureFlagEvents, response, flagWasLocallyEvaluated, featureFlagReportedKey;
2870
+ var _b, groups, disableGeoip, _c, onlyEvaluateLocally, sendFeatureFlagEvents, personProperties, groupProperties, adjustedProperties, response, flagWasLocallyEvaluated, featureFlagReportedKey;
2701
2871
 
2702
2872
  var _d;
2703
2873
 
2704
2874
  return __generator(this, function (_e) {
2705
2875
  switch (_e.label) {
2706
2876
  case 0:
2707
- _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties, disableGeoip = _b.disableGeoip;
2708
- _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, sendFeatureFlagEvents = _c.sendFeatureFlagEvents; // set defaults
2877
+ _b = options || {}, groups = _b.groups, disableGeoip = _b.disableGeoip;
2878
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, sendFeatureFlagEvents = _c.sendFeatureFlagEvents, personProperties = _c.personProperties, groupProperties = _c.groupProperties;
2879
+ adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
2880
+ personProperties = adjustedProperties.allPersonProperties;
2881
+ groupProperties = adjustedProperties.allGroupProperties; // set defaults
2709
2882
 
2710
2883
  if (onlyEvaluateLocally == undefined) {
2711
2884
  onlyEvaluateLocally = false;
@@ -2772,13 +2945,16 @@ function (_super) {
2772
2945
  var _a;
2773
2946
 
2774
2947
  return __awaiter(this, void 0, void 0, function () {
2775
- var _b, groups, personProperties, groupProperties, disableGeoip, _c, onlyEvaluateLocally, response, payloadWasLocallyEvaluated;
2948
+ var _b, groups, disableGeoip, _c, onlyEvaluateLocally, personProperties, groupProperties, adjustedProperties, response, payloadWasLocallyEvaluated;
2776
2949
 
2777
2950
  return __generator(this, function (_d) {
2778
2951
  switch (_d.label) {
2779
2952
  case 0:
2780
- _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties, disableGeoip = _b.disableGeoip;
2781
- _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, _c.sendFeatureFlagEvents;
2953
+ _b = options || {}, groups = _b.groups, disableGeoip = _b.disableGeoip;
2954
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, _c.sendFeatureFlagEvents, personProperties = _c.personProperties, groupProperties = _c.groupProperties;
2955
+ adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
2956
+ personProperties = adjustedProperties.allPersonProperties;
2957
+ groupProperties = adjustedProperties.allGroupProperties;
2782
2958
  response = undefined;
2783
2959
  if (!!matchValue) return [3
2784
2960
  /*break*/
@@ -2898,13 +3074,16 @@ function (_super) {
2898
3074
  var _a;
2899
3075
 
2900
3076
  return __awaiter(this, void 0, void 0, function () {
2901
- var _b, groups, personProperties, groupProperties, disableGeoip, onlyEvaluateLocally, localEvaluationResult, featureFlags, featureFlagPayloads, fallbackToDecide, remoteEvaluationResult;
3077
+ var _b, groups, disableGeoip, _c, onlyEvaluateLocally, personProperties, groupProperties, adjustedProperties, localEvaluationResult, featureFlags, featureFlagPayloads, fallbackToDecide, remoteEvaluationResult;
2902
3078
 
2903
- return __generator(this, function (_c) {
2904
- switch (_c.label) {
3079
+ return __generator(this, function (_d) {
3080
+ switch (_d.label) {
2905
3081
  case 0:
2906
- _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties, disableGeoip = _b.disableGeoip;
2907
- onlyEvaluateLocally = (options || {}).onlyEvaluateLocally; // set defaults
3082
+ _b = options || {}, groups = _b.groups, disableGeoip = _b.disableGeoip;
3083
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, personProperties = _c.personProperties, groupProperties = _c.groupProperties;
3084
+ adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
3085
+ personProperties = adjustedProperties.allPersonProperties;
3086
+ groupProperties = adjustedProperties.allGroupProperties; // set defaults
2908
3087
 
2909
3088
  if (onlyEvaluateLocally == undefined) {
2910
3089
  onlyEvaluateLocally = false;
@@ -2915,7 +3094,7 @@ function (_super) {
2915
3094
  , (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.getAllFlagsAndPayloads(distinctId, groups, personProperties, groupProperties)];
2916
3095
 
2917
3096
  case 1:
2918
- localEvaluationResult = _c.sent();
3097
+ localEvaluationResult = _d.sent();
2919
3098
  featureFlags = {};
2920
3099
  featureFlagPayloads = {};
2921
3100
  fallbackToDecide = true;
@@ -2934,10 +3113,10 @@ function (_super) {
2934
3113
  , _super.prototype.getFeatureFlagsAndPayloadsStateless.call(this, distinctId, groups, personProperties, groupProperties, disableGeoip)];
2935
3114
 
2936
3115
  case 2:
2937
- remoteEvaluationResult = _c.sent();
3116
+ remoteEvaluationResult = _d.sent();
2938
3117
  featureFlags = __assign(__assign({}, featureFlags), remoteEvaluationResult.flags || {});
2939
3118
  featureFlagPayloads = __assign(__assign({}, featureFlagPayloads), remoteEvaluationResult.payloads || {});
2940
- _c.label = 3;
3119
+ _d.label = 3;
2941
3120
 
2942
3121
  case 3:
2943
3122
  return [2
@@ -3002,6 +3181,28 @@ function (_super) {
3002
3181
  });
3003
3182
  };
3004
3183
 
3184
+ PostHog.prototype.addLocalPersonAndGroupProperties = function (distinctId, groups, personProperties, groupProperties) {
3185
+ var allPersonProperties = __assign({
3186
+ $current_distinct_id: distinctId
3187
+ }, personProperties || {});
3188
+
3189
+ var allGroupProperties = {};
3190
+
3191
+ if (groups) {
3192
+ for (var _i = 0, _a = Object.keys(groups); _i < _a.length; _i++) {
3193
+ var groupName = _a[_i];
3194
+ allGroupProperties[groupName] = __assign({
3195
+ $group_key: groups[groupName]
3196
+ }, (groupProperties === null || groupProperties === void 0 ? void 0 : groupProperties[groupName]) || {});
3197
+ }
3198
+ }
3199
+
3200
+ return {
3201
+ allPersonProperties: allPersonProperties,
3202
+ allGroupProperties: allGroupProperties
3203
+ };
3204
+ };
3205
+
3005
3206
  return PostHog;
3006
3207
  }(PostHogCoreStateless);
3007
3208