posthog-node 3.0.0 → 3.1.1

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,15 @@
1
+ # 3.1.1 - 2023-04-26
2
+
3
+ 1. Replace crypto library with pure-js rusha library which makes posthog-node work with Cloudflare Workers in Next.js edge runtime.
4
+
5
+ # 3.1.0 - 2023-04-19
6
+
7
+ 1. Some small fixes to incorrect types
8
+ 2. Fixed fetch compatibility by aligning error handling
9
+ 3. Added two errors: PostHogFetchHttpError (non-2xx status) and PostHogFetchNetworkError (fetch network error)
10
+ 4. Added .on('error', (err) => void)
11
+ 5. shutdownAsync now ignores fetch errors. They should be handled with .on('error', ...) from now on.
12
+
1
13
  # 3.0.0 - 2023-04-14
2
14
 
3
15
  Breaking change:
@@ -12,7 +24,7 @@ To restore previous behaviour, you can set the default to False like so:
12
24
  ```javascript
13
25
  const posthog = new PostHog(PH_API_KEY, {
14
26
  host: PH_HOST,
15
- disableGeoip: false
27
+ disableGeoip: false,
16
28
  })
17
29
  ```
18
30
 
@@ -23,10 +35,12 @@ const posthog = new PostHog(PH_API_KEY, {
23
35
  # 2.5.4 - 2023-02-27
24
36
 
25
37
  1. Fix error log for local evaluation of feature flags (InconclusiveMatchError(s)) to only show during debug mode.
38
+
26
39
  # 2.5.3 - 2023-02-21
27
40
 
28
41
  1. Allow passing in a distinctId to `groupIdentify()`.
29
42
  2. Fix a bug with active feature flags on capture events, where non-active flags would be added to the list as well.
43
+
30
44
  # 2.5.2 - 2023-02-17
31
45
 
32
46
  1. Fix issue where properties passed to `.identify` were not set correctly
package/lib/index.cjs.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var crypto = require('crypto');
5
+ var rusha = require('rusha');
6
6
  var axios = require('axios');
7
7
 
8
8
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -163,7 +163,7 @@ function __spreadArray(to, from, pack) {
163
163
  return to.concat(ar || Array.prototype.slice.call(from));
164
164
  }
165
165
 
166
- var version = "3.0.0";
166
+ var version = "3.1.1";
167
167
 
168
168
  var PostHogPersistedProperty;
169
169
  (function (PostHogPersistedProperty) {
@@ -201,29 +201,31 @@ function retriable(fn, props) {
201
201
  i = 0;
202
202
  _d.label = 1;
203
203
  case 1:
204
- if (!(i < retryCount + 1)) return [3 /*break*/, 8];
205
- _d.label = 2;
204
+ if (!(i < retryCount + 1)) return [3 /*break*/, 7];
205
+ if (!(i > 0)) return [3 /*break*/, 3];
206
+ // don't wait when it's the last try
207
+ return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, retryDelay); })];
206
208
  case 2:
207
- _d.trys.push([2, 4, , 5]);
208
- return [4 /*yield*/, fn()];
209
+ // don't wait when it's the last try
210
+ _d.sent();
211
+ _d.label = 3;
209
212
  case 3:
213
+ _d.trys.push([3, 5, , 6]);
214
+ return [4 /*yield*/, fn()];
215
+ case 4:
210
216
  res = _d.sent();
211
217
  return [2 /*return*/, res];
212
- case 4:
218
+ case 5:
213
219
  e_1 = _d.sent();
214
220
  lastError = e_1;
215
221
  if (!retryCheck(e_1)) {
216
222
  throw e_1;
217
223
  }
218
- return [3 /*break*/, 5];
219
- case 5: return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, retryDelay); })];
224
+ return [3 /*break*/, 6];
220
225
  case 6:
221
- _d.sent();
222
- _d.label = 7;
223
- case 7:
224
226
  i++;
225
227
  return [3 /*break*/, 1];
226
- case 8: throw lastError;
228
+ case 7: throw lastError;
227
229
  }
228
230
  });
229
231
  });
@@ -722,6 +724,29 @@ var SimpleEventEmitter = /** @class */ (function () {
722
724
  return SimpleEventEmitter;
723
725
  }());
724
726
 
727
+ var PostHogFetchHttpError = /** @class */ (function (_super) {
728
+ __extends(PostHogFetchHttpError, _super);
729
+ function PostHogFetchHttpError(response) {
730
+ var _this = _super.call(this, 'HTTP error while fetching PostHog: ' + response.status) || this;
731
+ _this.response = response;
732
+ _this.name = 'PostHogFetchHttpError';
733
+ return _this;
734
+ }
735
+ return PostHogFetchHttpError;
736
+ }(Error));
737
+ var PostHogFetchNetworkError = /** @class */ (function (_super) {
738
+ __extends(PostHogFetchNetworkError, _super);
739
+ function PostHogFetchNetworkError(error) {
740
+ var _this = _super.call(this, 'Network error while fetching PostHog', error instanceof Error ? { cause: error } : {}) || this;
741
+ _this.error = error;
742
+ _this.name = 'PostHogFetchNetworkError';
743
+ return _this;
744
+ }
745
+ return PostHogFetchNetworkError;
746
+ }(Error));
747
+ function isPostHogFetchError(err) {
748
+ return typeof err === 'object' && (err.name === 'PostHogFetchHttpError' || err.name === 'PostHogFetchNetworkError');
749
+ }
725
750
  var PostHogCoreStateless = /** @class */ (function () {
726
751
  function PostHogCoreStateless(apiKey, options) {
727
752
  var _a, _b, _c, _d, _e;
@@ -741,6 +766,7 @@ var PostHogCoreStateless = /** @class */ (function () {
741
766
  this._retryOptions = {
742
767
  retryCount: (_b = options === null || options === void 0 ? void 0 : options.fetchRetryCount) !== null && _b !== void 0 ? _b : 3,
743
768
  retryDelay: (_c = options === null || options === void 0 ? void 0 : options.fetchRetryDelay) !== null && _c !== void 0 ? _c : 3000,
769
+ retryCheck: isPostHogFetchError,
744
770
  };
745
771
  this.requestTimeout = (_d = options === null || options === void 0 ? void 0 : options.requestTimeout) !== null && _d !== void 0 ? _d : 10000; // 10 seconds
746
772
  this.disableGeoip = (_e = options === null || options === void 0 ? void 0 : options.disableGeoip) !== null && _e !== void 0 ? _e : true;
@@ -1033,6 +1059,9 @@ var PostHogCoreStateless = /** @class */ (function () {
1033
1059
  };
1034
1060
  var promiseUUID = generateUUID();
1035
1061
  var done = function (err) {
1062
+ if (err) {
1063
+ _this._events.emit('error', err);
1064
+ }
1036
1065
  callback === null || callback === void 0 ? void 0 : callback(err, messages);
1037
1066
  // remove promise from pendingPromises
1038
1067
  delete _this.pendingPromises[promiseUUID];
@@ -1065,10 +1094,6 @@ var PostHogCoreStateless = /** @class */ (function () {
1065
1094
  requestPromise
1066
1095
  .then(function () { return done(); })
1067
1096
  .catch(function (err) {
1068
- if (err.response) {
1069
- var error = new Error(err.response.statusText);
1070
- return done(error);
1071
- }
1072
1097
  done(err);
1073
1098
  });
1074
1099
  };
@@ -1078,30 +1103,72 @@ var PostHogCoreStateless = /** @class */ (function () {
1078
1103
  return __awaiter(this, void 0, void 0, function () {
1079
1104
  var _this = this;
1080
1105
  return __generator(this, function (_c) {
1081
- (_a = (_b = AbortSignal).timeout) !== null && _a !== void 0 ? _a : (_b.timeout = function timeout(ms) {
1082
- var ctrl = new AbortController();
1083
- setTimeout(function () { return ctrl.abort(); }, ms);
1084
- return ctrl.signal;
1085
- });
1086
- return [2 /*return*/, retriable(function () {
1087
- return _this.fetch(url, __assign({ signal: AbortSignal.timeout(_this.requestTimeout) }, options));
1088
- }, retryOptions || this._retryOptions)];
1106
+ switch (_c.label) {
1107
+ case 0:
1108
+ (_a = (_b = AbortSignal).timeout) !== null && _a !== void 0 ? _a : (_b.timeout = function timeout(ms) {
1109
+ var ctrl = new AbortController();
1110
+ setTimeout(function () { return ctrl.abort(); }, ms);
1111
+ return ctrl.signal;
1112
+ });
1113
+ return [4 /*yield*/, retriable(function () { return __awaiter(_this, void 0, void 0, function () {
1114
+ var res, e_1;
1115
+ return __generator(this, function (_a) {
1116
+ switch (_a.label) {
1117
+ case 0:
1118
+ res = null;
1119
+ _a.label = 1;
1120
+ case 1:
1121
+ _a.trys.push([1, 3, , 4]);
1122
+ return [4 /*yield*/, this.fetch(url, __assign({ signal: AbortSignal.timeout(this.requestTimeout) }, options))];
1123
+ case 2:
1124
+ res = _a.sent();
1125
+ return [3 /*break*/, 4];
1126
+ case 3:
1127
+ e_1 = _a.sent();
1128
+ // fetch will only throw on network errors or on timeouts
1129
+ throw new PostHogFetchNetworkError(e_1);
1130
+ case 4:
1131
+ if (res.status < 200 || res.status >= 400) {
1132
+ throw new PostHogFetchHttpError(res);
1133
+ }
1134
+ return [2 /*return*/, res];
1135
+ }
1136
+ });
1137
+ }); }, __assign(__assign({}, this._retryOptions), retryOptions))];
1138
+ case 1: return [2 /*return*/, _c.sent()];
1139
+ }
1089
1140
  });
1090
1141
  });
1091
1142
  };
1092
1143
  PostHogCoreStateless.prototype.shutdownAsync = function () {
1093
1144
  return __awaiter(this, void 0, void 0, function () {
1145
+ var e_2;
1094
1146
  return __generator(this, function (_a) {
1095
1147
  switch (_a.label) {
1096
1148
  case 0:
1097
1149
  clearTimeout(this._flushTimer);
1098
- return [4 /*yield*/, this.flushAsync()];
1150
+ _a.label = 1;
1099
1151
  case 1:
1100
- _a.sent();
1101
- return [4 /*yield*/, Promise.allSettled(Object.values(this.pendingPromises))];
1152
+ _a.trys.push([1, 4, , 5]);
1153
+ return [4 /*yield*/, this.flushAsync()];
1102
1154
  case 2:
1103
1155
  _a.sent();
1104
- return [2 /*return*/];
1156
+ return [4 /*yield*/, Promise.all(Object.values(this.pendingPromises).map(function (x) {
1157
+ return x.catch(function () {
1158
+ // ignore errors as we are shutting down and can't deal with them anyways.
1159
+ });
1160
+ }))];
1161
+ case 3:
1162
+ _a.sent();
1163
+ return [3 /*break*/, 5];
1164
+ case 4:
1165
+ e_2 = _a.sent();
1166
+ if (!isPostHogFetchError(e_2)) {
1167
+ throw e_2;
1168
+ }
1169
+ console.error('Error while shutting down PostHog', e_2);
1170
+ return [3 /*break*/, 5];
1171
+ case 5: return [2 /*return*/];
1105
1172
  }
1106
1173
  });
1107
1174
  });
@@ -1122,12 +1189,6 @@ var PostHogCoreStateless = /** @class */ (function () {
1122
1189
  _this.flagCallReported = {};
1123
1190
  _this.sendFeatureFlagEvent = (_b = options === null || options === void 0 ? void 0 : options.sendFeatureFlagEvent) !== null && _b !== void 0 ? _b : true;
1124
1191
  _this._sessionExpirationTimeSeconds = (_c = options === null || options === void 0 ? void 0 : options.sessionExpirationTimeSeconds) !== null && _c !== void 0 ? _c : 1800; // 30 minutes
1125
- // NOTE: It is important we don't initiate anything in the constructor as some async IO may still be underway on the parent
1126
- if ((options === null || options === void 0 ? void 0 : options.preloadFeatureFlags) !== false) {
1127
- safeSetTimeout(function () {
1128
- _this.reloadFeatureFlags();
1129
- }, 1);
1130
- }
1131
1192
  return _this;
1132
1193
  }
1133
1194
  PostHogCore.prototype.setupBootstrap = function (options) {
@@ -1242,9 +1303,7 @@ var PostHogCoreStateless = /** @class */ (function () {
1242
1303
  // We keep the AnonymousId to be used by decide calls and identify to link the previousId
1243
1304
  this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, previousDistinctId);
1244
1305
  this.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
1245
- if (this.getFeatureFlags()) {
1246
- this.reloadFeatureFlags();
1247
- }
1306
+ this.reloadFeatureFlags();
1248
1307
  }
1249
1308
  _super.prototype.identifyStateless.call(this, distinctId, allProperties, options);
1250
1309
  return this;
@@ -1284,7 +1343,7 @@ var PostHogCoreStateless = /** @class */ (function () {
1284
1343
  this.register({
1285
1344
  $groups: __assign(__assign({}, existingGroups), groups),
1286
1345
  });
1287
- if (Object.keys(groups).find(function (type) { return existingGroups[type] !== groups[type]; }) && this.getFeatureFlags()) {
1346
+ if (Object.keys(groups).find(function (type) { return existingGroups[type] !== groups[type]; })) {
1288
1347
  this.reloadFeatureFlags();
1289
1348
  }
1290
1349
  return this;
@@ -1545,7 +1604,11 @@ var fetch = function (url, options) {
1545
1604
  headers: options.headers,
1546
1605
  method: options.method.toLowerCase(),
1547
1606
  data: options.body,
1548
- signal: options.signal
1607
+ signal: options.signal,
1608
+ // fetch only throws on network errors, not on HTTP errors
1609
+ validateStatus: function () {
1610
+ return true;
1611
+ }
1549
1612
  })];
1550
1613
 
1551
1614
  case 1:
@@ -1555,10 +1618,22 @@ var fetch = function (url, options) {
1555
1618
  , {
1556
1619
  status: res.status,
1557
1620
  text: function () {
1558
- return res.data;
1621
+ return __awaiter(void 0, void 0, void 0, function () {
1622
+ return __generator(this, function (_a) {
1623
+ return [2
1624
+ /*return*/
1625
+ , res.data];
1626
+ });
1627
+ });
1559
1628
  },
1560
1629
  json: function () {
1561
- return res.data;
1630
+ return __awaiter(void 0, void 0, void 0, function () {
1631
+ return __generator(this, function (_a) {
1632
+ return [2
1633
+ /*return*/
1634
+ , res.data];
1635
+ });
1636
+ });
1562
1637
  }
1563
1638
  }];
1564
1639
  }
@@ -2178,7 +2253,7 @@ function () {
2178
2253
 
2179
2254
  case 3:
2180
2255
  err_2 = _a.sent();
2181
- throw new Error("Request failed with error: ".concat(err_2));
2256
+ throw err_2;
2182
2257
 
2183
2258
  case 4:
2184
2259
  clearTimeout(abortTimeout);
@@ -2209,9 +2284,10 @@ function () {
2209
2284
  function _hash(key, distinctId, salt) {
2210
2285
  if (salt === void 0) {
2211
2286
  salt = '';
2212
- }
2287
+ } // rusha is a fast sha1 implementation in pure javascript
2288
+
2213
2289
 
2214
- var sha1Hash = crypto.createHash('sha1');
2290
+ var sha1Hash = rusha.createHash();
2215
2291
  sha1Hash.update("".concat(key, ".").concat(distinctId).concat(salt));
2216
2292
  return parseInt(sha1Hash.digest('hex').slice(0, 15), 16) / LONG_SCALE;
2217
2293
  }