posthog-node 4.7.0 → 4.8.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 +4 -0
- package/lib/index.cjs.js +38 -5
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.esm.js +36 -6
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +1 -1
- package/lib/posthog-core/src/utils.d.ts +1 -0
- package/lib/posthog-node/src/feature-flags.d.ts +9 -0
- package/lib/posthog-node/src/posthog-node.d.ts +3 -0
- package/package.json +1 -1
- package/src/feature-flags.ts +32 -3
- package/src/posthog-node.ts +17 -5
- package/test/posthog-node.spec.ts +34 -2
package/CHANGELOG.md
CHANGED
package/lib/index.cjs.js
CHANGED
|
@@ -7,7 +7,7 @@ var node_fs = require('node:fs');
|
|
|
7
7
|
var node_readline = require('node:readline');
|
|
8
8
|
var node_path = require('node:path');
|
|
9
9
|
|
|
10
|
-
var version = "4.
|
|
10
|
+
var version = "4.8.0";
|
|
11
11
|
|
|
12
12
|
var PostHogPersistedProperty;
|
|
13
13
|
(function (PostHogPersistedProperty) {
|
|
@@ -1495,6 +1495,8 @@ class FeatureFlagsPoller {
|
|
|
1495
1495
|
...options
|
|
1496
1496
|
}) {
|
|
1497
1497
|
this.debugMode = false;
|
|
1498
|
+
this.lastRequestWasAuthenticationError = false;
|
|
1499
|
+
this.authenticationErrorCount = 0;
|
|
1498
1500
|
this.pollingInterval = pollingInterval;
|
|
1499
1501
|
this.personalApiKey = personalApiKey;
|
|
1500
1502
|
this.featureFlags = [];
|
|
@@ -1506,7 +1508,6 @@ class FeatureFlagsPoller {
|
|
|
1506
1508
|
this.projectApiKey = projectApiKey;
|
|
1507
1509
|
this.host = host;
|
|
1508
1510
|
this.poller = undefined;
|
|
1509
|
-
// NOTE: as any is required here as the AbortSignal typing is slightly misaligned but works just fine
|
|
1510
1511
|
this.fetch = options.fetch || fetch$1;
|
|
1511
1512
|
this.onError = options.onError;
|
|
1512
1513
|
this.customHeaders = customHeaders;
|
|
@@ -1726,16 +1727,35 @@ class FeatureFlagsPoller {
|
|
|
1726
1727
|
await this._loadFeatureFlags();
|
|
1727
1728
|
}
|
|
1728
1729
|
}
|
|
1730
|
+
/**
|
|
1731
|
+
* If a client is misconfigured with an invalid or improper API key, the polling interval is doubled each time
|
|
1732
|
+
* until a successful request is made, up to a maximum of 60 seconds.
|
|
1733
|
+
*
|
|
1734
|
+
* @returns The polling interval to use for the next request.
|
|
1735
|
+
*/
|
|
1736
|
+
getPollingInterval() {
|
|
1737
|
+
if (!this.lastRequestWasAuthenticationError) {
|
|
1738
|
+
return this.pollingInterval;
|
|
1739
|
+
}
|
|
1740
|
+
return Math.min(SIXTY_SECONDS, this.pollingInterval * 2 ** this.authenticationErrorCount);
|
|
1741
|
+
}
|
|
1729
1742
|
async _loadFeatureFlags() {
|
|
1730
1743
|
if (this.poller) {
|
|
1731
1744
|
clearTimeout(this.poller);
|
|
1732
1745
|
this.poller = undefined;
|
|
1733
1746
|
}
|
|
1734
|
-
this.poller = setTimeout(() => this._loadFeatureFlags(), this.
|
|
1747
|
+
this.poller = setTimeout(() => this._loadFeatureFlags(), this.getPollingInterval());
|
|
1735
1748
|
try {
|
|
1736
1749
|
const res = await this._requestFeatureFlagDefinitions();
|
|
1737
1750
|
if (res && res.status === 401) {
|
|
1738
|
-
|
|
1751
|
+
this.lastRequestWasAuthenticationError = true;
|
|
1752
|
+
this.authenticationErrorCount += 1;
|
|
1753
|
+
throw new ClientError(`Your project key or personal API key is invalid. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
|
|
1754
|
+
}
|
|
1755
|
+
if (res && res.status === 403) {
|
|
1756
|
+
this.lastRequestWasAuthenticationError = true;
|
|
1757
|
+
this.authenticationErrorCount += 1;
|
|
1758
|
+
throw new ClientError(`Your personal API key does not have permission to fetch feature flag definitions for local evaluation. Setting next polling interval to ${this.getPollingInterval()}ms. Are you sure you're using the correct personal and Project API key pair? More information: https://posthog.com/docs/api/overview`);
|
|
1739
1759
|
}
|
|
1740
1760
|
if (res && res.status !== 200) {
|
|
1741
1761
|
// something else went wrong, or the server is down.
|
|
@@ -1751,6 +1771,8 @@ class FeatureFlagsPoller {
|
|
|
1751
1771
|
this.groupTypeMapping = responseJson.group_type_mapping || {};
|
|
1752
1772
|
this.cohorts = responseJson.cohorts || [];
|
|
1753
1773
|
this.loadedSuccessfullyOnce = true;
|
|
1774
|
+
this.lastRequestWasAuthenticationError = false;
|
|
1775
|
+
this.authenticationErrorCount = 0;
|
|
1754
1776
|
} catch (err) {
|
|
1755
1777
|
// if an error that is not an instance of ClientError is thrown
|
|
1756
1778
|
// we silently ignore the error when reloading feature flags
|
|
@@ -2939,7 +2961,11 @@ class ErrorTracking {
|
|
|
2939
2961
|
}
|
|
2940
2962
|
}
|
|
2941
2963
|
|
|
2964
|
+
// Standard local evaluation rate limit is 600 per minute (10 per second),
|
|
2965
|
+
// so the fastest a poller should ever be set is 100ms.
|
|
2966
|
+
const MINIMUM_POLLING_INTERVAL = 100;
|
|
2942
2967
|
const THIRTY_SECONDS = 30 * 1000;
|
|
2968
|
+
const SIXTY_SECONDS = 60 * 1000;
|
|
2943
2969
|
const MAX_CACHE_SIZE = 50 * 1000;
|
|
2944
2970
|
// The actual exported Nodejs API.
|
|
2945
2971
|
class PostHog extends PostHogCoreStateless {
|
|
@@ -2947,9 +2973,13 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2947
2973
|
super(apiKey, options);
|
|
2948
2974
|
this._memoryStorage = new PostHogMemoryStorage();
|
|
2949
2975
|
this.options = options;
|
|
2976
|
+
this.options.featureFlagsPollingInterval = typeof options.featureFlagsPollingInterval === 'number' ? Math.max(options.featureFlagsPollingInterval, MINIMUM_POLLING_INTERVAL) : THIRTY_SECONDS;
|
|
2950
2977
|
if (options.personalApiKey) {
|
|
2978
|
+
if (options.personalApiKey.includes('phc_')) {
|
|
2979
|
+
throw new Error('Your Personal API key is invalid. These keys are prefixed with "phx_" and can be created in PostHog project settings.');
|
|
2980
|
+
}
|
|
2951
2981
|
this.featureFlagsPoller = new FeatureFlagsPoller({
|
|
2952
|
-
pollingInterval:
|
|
2982
|
+
pollingInterval: this.options.featureFlagsPollingInterval,
|
|
2953
2983
|
personalApiKey: options.personalApiKey,
|
|
2954
2984
|
projectApiKey: apiKey,
|
|
2955
2985
|
timeout: options.requestTimeout ?? 10000,
|
|
@@ -3404,8 +3434,11 @@ function setupExpressErrorHandler(_posthog, app) {
|
|
|
3404
3434
|
});
|
|
3405
3435
|
}
|
|
3406
3436
|
|
|
3437
|
+
exports.MINIMUM_POLLING_INTERVAL = MINIMUM_POLLING_INTERVAL;
|
|
3407
3438
|
exports.PostHog = PostHog;
|
|
3408
3439
|
exports.PostHogSentryIntegration = PostHogSentryIntegration;
|
|
3440
|
+
exports.SIXTY_SECONDS = SIXTY_SECONDS;
|
|
3441
|
+
exports.THIRTY_SECONDS = THIRTY_SECONDS;
|
|
3409
3442
|
exports.createEventProcessor = createEventProcessor;
|
|
3410
3443
|
exports.sentryIntegration = sentryIntegration;
|
|
3411
3444
|
exports.setupExpressErrorHandler = setupExpressErrorHandler;
|