posthog-node 2.5.3 → 2.6.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 +7 -0
- package/lib/index.cjs.js +163 -10
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.esm.js +163 -10
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +1 -0
- package/lib/posthog-node/src/feature-flags.d.ts +4 -1
- package/lib/posthog-node/src/posthog-node.d.ts +1 -0
- package/lib/posthog-node/src/types.d.ts +12 -6
- package/package.json +1 -1
- package/src/feature-flags.ts +143 -10
- package/src/posthog-node.ts +5 -0
- package/src/types.ts +14 -6
- package/test/feature-flags.spec.ts +173 -2
package/lib/index.d.ts
CHANGED
|
@@ -103,6 +103,7 @@ declare abstract class PostHogCoreStateless {
|
|
|
103
103
|
private requestTimeout;
|
|
104
104
|
private captureMode;
|
|
105
105
|
private removeDebugCallback?;
|
|
106
|
+
private debugMode;
|
|
106
107
|
private pendingPromises;
|
|
107
108
|
private _optoutOverride;
|
|
108
109
|
protected _events: SimpleEventEmitter;
|
|
@@ -319,6 +320,7 @@ declare class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
|
|
|
319
320
|
getCustomUserAgent(): string;
|
|
320
321
|
enable(): void;
|
|
321
322
|
disable(): void;
|
|
323
|
+
debug(enabled?: boolean): void;
|
|
322
324
|
capture({ distinctId, event, properties, groups, sendFeatureFlags, timestamp }: EventMessageV1): void;
|
|
323
325
|
identify({ distinctId, properties }: IdentifyMessageV1): void;
|
|
324
326
|
alias(data: {
|
package/lib/index.esm.js
CHANGED
|
@@ -155,7 +155,7 @@ function __spreadArray(to, from, pack) {
|
|
|
155
155
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
var version = "2.
|
|
158
|
+
var version = "2.6.0";
|
|
159
159
|
|
|
160
160
|
var PostHogPersistedProperty;
|
|
161
161
|
(function (PostHogPersistedProperty) {
|
|
@@ -717,6 +717,7 @@ var SimpleEventEmitter = /** @class */ (function () {
|
|
|
717
717
|
var PostHogCoreStateless = /** @class */ (function () {
|
|
718
718
|
function PostHogCoreStateless(apiKey, options) {
|
|
719
719
|
var _a, _b, _c, _d;
|
|
720
|
+
this.debugMode = false;
|
|
720
721
|
this.pendingPromises = {};
|
|
721
722
|
// internal
|
|
722
723
|
this._events = new SimpleEventEmitter();
|
|
@@ -761,6 +762,7 @@ var PostHogCoreStateless = /** @class */ (function () {
|
|
|
761
762
|
var _a;
|
|
762
763
|
if (enabled === void 0) { enabled = true; }
|
|
763
764
|
(_a = this.removeDebugCallback) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
765
|
+
this.debugMode = enabled;
|
|
764
766
|
if (enabled) {
|
|
765
767
|
this.removeDebugCallback = this.on('*', function (event, payload) { return console.log('PostHog Debug', event, payload); });
|
|
766
768
|
}
|
|
@@ -1590,11 +1592,13 @@ function () {
|
|
|
1590
1592
|
host = _a.host,
|
|
1591
1593
|
options = __rest(_a, ["pollingInterval", "personalApiKey", "projectApiKey", "timeout", "host"]);
|
|
1592
1594
|
|
|
1595
|
+
this.debugMode = false;
|
|
1593
1596
|
this.pollingInterval = pollingInterval;
|
|
1594
1597
|
this.personalApiKey = personalApiKey;
|
|
1595
1598
|
this.featureFlags = [];
|
|
1596
1599
|
this.featureFlagsByKey = {};
|
|
1597
1600
|
this.groupTypeMapping = {};
|
|
1601
|
+
this.cohorts = {};
|
|
1598
1602
|
this.loadedSuccessfullyOnce = false;
|
|
1599
1603
|
this.timeout = timeout;
|
|
1600
1604
|
this.projectApiKey = projectApiKey;
|
|
@@ -1605,6 +1609,14 @@ function () {
|
|
|
1605
1609
|
void this.loadFeatureFlags();
|
|
1606
1610
|
}
|
|
1607
1611
|
|
|
1612
|
+
FeatureFlagsPoller.prototype.debug = function (enabled) {
|
|
1613
|
+
if (enabled === void 0) {
|
|
1614
|
+
enabled = true;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
this.debugMode = enabled;
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1608
1620
|
FeatureFlagsPoller.prototype.getFeatureFlag = function (key, distinctId, groups, personProperties, groupProperties) {
|
|
1609
1621
|
if (groups === void 0) {
|
|
1610
1622
|
groups = {};
|
|
@@ -1652,9 +1664,15 @@ function () {
|
|
|
1652
1664
|
if (featureFlag !== undefined) {
|
|
1653
1665
|
try {
|
|
1654
1666
|
response = this.computeFlagLocally(featureFlag, distinctId, groups, personProperties, groupProperties);
|
|
1667
|
+
|
|
1668
|
+
if (this.debugMode) {
|
|
1669
|
+
console.debug("Successfully computed flag locally: ".concat(key, " -> ").concat(response));
|
|
1670
|
+
}
|
|
1655
1671
|
} catch (e) {
|
|
1656
1672
|
if (e instanceof InconclusiveMatchError) {
|
|
1657
|
-
|
|
1673
|
+
if (this.debugMode) {
|
|
1674
|
+
console.debug("InconclusiveMatchError when computing flag locally: ".concat(key, ": ").concat(e));
|
|
1675
|
+
}
|
|
1658
1676
|
} else if (e instanceof Error) {
|
|
1659
1677
|
console.error("Error computing flag locally: ".concat(key, ": ").concat(e));
|
|
1660
1678
|
}
|
|
@@ -1918,14 +1936,23 @@ function () {
|
|
|
1918
1936
|
var rolloutPercentage = condition.rollout_percentage;
|
|
1919
1937
|
|
|
1920
1938
|
if ((condition.properties || []).length > 0) {
|
|
1921
|
-
var
|
|
1922
|
-
|
|
1923
|
-
|
|
1939
|
+
for (var _i = 0, _a = condition.properties; _i < _a.length; _i++) {
|
|
1940
|
+
var prop = _a[_i];
|
|
1941
|
+
var propertyType = prop.type;
|
|
1942
|
+
var matches = false;
|
|
1924
1943
|
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1944
|
+
if (propertyType === 'cohort') {
|
|
1945
|
+
matches = matchCohort(prop, properties, this.cohorts);
|
|
1946
|
+
} else {
|
|
1947
|
+
matches = matchProperty(prop, properties);
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
if (!matches) {
|
|
1951
|
+
return false;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
if (rolloutPercentage == undefined) {
|
|
1929
1956
|
return true;
|
|
1930
1957
|
}
|
|
1931
1958
|
}
|
|
@@ -2058,6 +2085,7 @@ function () {
|
|
|
2058
2085
|
return acc[curr.key] = curr, acc;
|
|
2059
2086
|
}, {});
|
|
2060
2087
|
this.groupTypeMapping = responseJson.group_type_mapping || {};
|
|
2088
|
+
this.cohorts = responseJson.cohorts || [];
|
|
2061
2089
|
this.loadedSuccessfullyOnce = true;
|
|
2062
2090
|
return [3
|
|
2063
2091
|
/*break*/
|
|
@@ -2090,7 +2118,7 @@ function () {
|
|
|
2090
2118
|
return __generator(this, function (_a) {
|
|
2091
2119
|
switch (_a.label) {
|
|
2092
2120
|
case 0:
|
|
2093
|
-
url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey);
|
|
2121
|
+
url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey, "&send_cohorts");
|
|
2094
2122
|
options = {
|
|
2095
2123
|
method: 'GET',
|
|
2096
2124
|
headers: {
|
|
@@ -2227,6 +2255,119 @@ function matchProperty(property, propertyValues) {
|
|
|
2227
2255
|
}
|
|
2228
2256
|
}
|
|
2229
2257
|
|
|
2258
|
+
function matchCohort(property, propertyValues, cohortProperties) {
|
|
2259
|
+
var cohortId = String(property.value);
|
|
2260
|
+
|
|
2261
|
+
if (!(cohortId in cohortProperties)) {
|
|
2262
|
+
throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
var propertyGroup = cohortProperties[cohortId];
|
|
2266
|
+
return matchPropertyGroup(propertyGroup, propertyValues, cohortProperties);
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
|
|
2270
|
+
if (!propertyGroup) {
|
|
2271
|
+
return true;
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
var propertyGroupType = propertyGroup.type;
|
|
2275
|
+
var properties = propertyGroup.values;
|
|
2276
|
+
|
|
2277
|
+
if (!properties || properties.length === 0) {
|
|
2278
|
+
// empty groups are no-ops, always match
|
|
2279
|
+
return true;
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
var errorMatchingLocally = false;
|
|
2283
|
+
|
|
2284
|
+
if ('values' in properties[0]) {
|
|
2285
|
+
// a nested property group
|
|
2286
|
+
for (var _i = 0, _a = properties; _i < _a.length; _i++) {
|
|
2287
|
+
var prop = _a[_i];
|
|
2288
|
+
|
|
2289
|
+
try {
|
|
2290
|
+
var matches = matchPropertyGroup(prop, propertyValues, cohortProperties);
|
|
2291
|
+
|
|
2292
|
+
if (propertyGroupType === 'AND') {
|
|
2293
|
+
if (!matches) {
|
|
2294
|
+
return false;
|
|
2295
|
+
}
|
|
2296
|
+
} else {
|
|
2297
|
+
// OR group
|
|
2298
|
+
if (matches) {
|
|
2299
|
+
return true;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
} catch (err) {
|
|
2303
|
+
if (err instanceof InconclusiveMatchError) {
|
|
2304
|
+
console.debug("Failed to compute property ".concat(prop, " locally: ").concat(err));
|
|
2305
|
+
errorMatchingLocally = true;
|
|
2306
|
+
} else {
|
|
2307
|
+
throw err;
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
if (errorMatchingLocally) {
|
|
2313
|
+
throw new InconclusiveMatchError("Can't match cohort without a given cohort property value");
|
|
2314
|
+
} // if we get here, all matched in AND case, or none matched in OR case
|
|
2315
|
+
|
|
2316
|
+
|
|
2317
|
+
return propertyGroupType === 'AND';
|
|
2318
|
+
} else {
|
|
2319
|
+
for (var _b = 0, _c = properties; _b < _c.length; _b++) {
|
|
2320
|
+
var prop = _c[_b];
|
|
2321
|
+
|
|
2322
|
+
try {
|
|
2323
|
+
var matches = void 0;
|
|
2324
|
+
|
|
2325
|
+
if (prop.type === 'cohort') {
|
|
2326
|
+
matches = matchCohort(prop, propertyValues, cohortProperties);
|
|
2327
|
+
} else {
|
|
2328
|
+
matches = matchProperty(prop, propertyValues);
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
var negation = prop.negation || false;
|
|
2332
|
+
|
|
2333
|
+
if (propertyGroupType === 'AND') {
|
|
2334
|
+
// if negated property, do the inverse
|
|
2335
|
+
if (!matches && !negation) {
|
|
2336
|
+
return false;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
if (matches && negation) {
|
|
2340
|
+
return false;
|
|
2341
|
+
}
|
|
2342
|
+
} else {
|
|
2343
|
+
// OR group
|
|
2344
|
+
if (matches && !negation) {
|
|
2345
|
+
return true;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
if (!matches && negation) {
|
|
2349
|
+
return true;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
} catch (err) {
|
|
2353
|
+
if (err instanceof InconclusiveMatchError) {
|
|
2354
|
+
console.debug("Failed to compute property ".concat(prop, " locally: ").concat(err));
|
|
2355
|
+
errorMatchingLocally = true;
|
|
2356
|
+
} else {
|
|
2357
|
+
throw err;
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
if (errorMatchingLocally) {
|
|
2363
|
+
throw new InconclusiveMatchError("can't match cohort without a given cohort property value");
|
|
2364
|
+
} // if we get here, all matched in AND case, or none matched in OR case
|
|
2365
|
+
|
|
2366
|
+
|
|
2367
|
+
return propertyGroupType === 'AND';
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2230
2371
|
function isValidRegex(regex) {
|
|
2231
2372
|
try {
|
|
2232
2373
|
new RegExp(regex);
|
|
@@ -2322,6 +2463,18 @@ function (_super) {
|
|
|
2322
2463
|
return _super.prototype.optOut.call(this);
|
|
2323
2464
|
};
|
|
2324
2465
|
|
|
2466
|
+
PostHog.prototype.debug = function (enabled) {
|
|
2467
|
+
var _a;
|
|
2468
|
+
|
|
2469
|
+
if (enabled === void 0) {
|
|
2470
|
+
enabled = true;
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
_super.prototype.debug.call(this, enabled);
|
|
2474
|
+
|
|
2475
|
+
(_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.debug(enabled);
|
|
2476
|
+
};
|
|
2477
|
+
|
|
2325
2478
|
PostHog.prototype.capture = function (_a) {
|
|
2326
2479
|
var _this = this;
|
|
2327
2480
|
|