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 +10 -0
- package/lib/index.cjs.js +286 -85
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.esm.js +286 -85
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +2 -1
- package/lib/posthog-node/src/feature-flags.d.ts +2 -1
- package/lib/posthog-node/src/posthog-node.d.ts +1 -0
- package/package.json +1 -1
- package/src/feature-flags.ts +116 -19
- package/src/posthog-node.ts +99 -19
- package/test/extensions/sentry-integration.spec.ts +2 -0
- package/test/feature-flags.spec.ts +273 -5
- package/test/posthog-node.spec.ts +407 -10
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.
|
|
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
|
-
|
|
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.
|
|
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,
|
|
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
|
-
|
|
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*/,
|
|
1171
|
-
case
|
|
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,
|
|
1796
|
+
var response, featureFlag, _i, _b, flag;
|
|
1777
1797
|
|
|
1778
|
-
return __generator(this, function (
|
|
1779
|
-
switch (
|
|
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
|
-
|
|
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,
|
|
1798
|
-
flag =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
2185
|
-
switch (
|
|
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
|
-
|
|
2221
|
+
_c.label = 1;
|
|
2196
2222
|
|
|
2197
2223
|
case 1:
|
|
2198
|
-
|
|
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 =
|
|
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 =
|
|
2250
|
+
responseJson = _c.sent();
|
|
2225
2251
|
|
|
2226
2252
|
if (!('flags' in responseJson)) {
|
|
2227
|
-
|
|
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 =
|
|
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
|
-
(
|
|
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
|
|
2403
|
+
return computeExactMatch(value, overrideValue);
|
|
2354
2404
|
|
|
2355
2405
|
case 'is_not':
|
|
2356
|
-
return
|
|
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
|
-
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
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
|
-
|
|
2656
|
-
|
|
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
|
-
|
|
2662
|
-
|
|
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
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2833
|
+
if (activeFlags.length > 0) {
|
|
2834
|
+
additionalProperties['$active_feature_flags'] = activeFlags;
|
|
2835
|
+
}
|
|
2668
2836
|
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
}
|
|
2673
|
-
}
|
|
2674
|
-
|
|
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,
|
|
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,
|
|
2712
|
-
_c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, sendFeatureFlagEvents = _c.sendFeatureFlagEvents
|
|
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,
|
|
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,
|
|
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,
|
|
3081
|
+
var _b, groups, disableGeoip, _c, onlyEvaluateLocally, personProperties, groupProperties, adjustedProperties, localEvaluationResult, featureFlags, featureFlagPayloads, fallbackToDecide, remoteEvaluationResult;
|
|
2906
3082
|
|
|
2907
|
-
return __generator(this, function (
|
|
2908
|
-
switch (
|
|
3083
|
+
return __generator(this, function (_d) {
|
|
3084
|
+
switch (_d.label) {
|
|
2909
3085
|
case 0:
|
|
2910
|
-
_b = options || {}, groups = _b.groups,
|
|
2911
|
-
|
|
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 =
|
|
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 =
|
|
3120
|
+
remoteEvaluationResult = _d.sent();
|
|
2942
3121
|
featureFlags = __assign(__assign({}, featureFlags), remoteEvaluationResult.flags || {});
|
|
2943
3122
|
featureFlagPayloads = __assign(__assign({}, featureFlagPayloads), remoteEvaluationResult.payloads || {});
|
|
2944
|
-
|
|
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
|
|