posthog-node 4.8.0 → 4.9.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 +8 -0
- package/lib/index.cjs.js +34 -8
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +4 -3
- package/lib/index.esm.js +34 -8
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +4 -4
- package/lib/posthog-core/src/types.d.ts +1 -0
- package/lib/posthog-node/test/test-utils.d.ts +2 -1
- package/package.json +1 -1
- package/src/feature-flags.ts +13 -0
- package/test/feature-flags.spec.ts +39 -1
- package/test/posthog-node.spec.ts +4 -0
- package/test/test-utils.ts +3 -1
package/lib/index.d.ts
CHANGED
|
@@ -108,6 +108,7 @@ type PostHogDecideResponse = {
|
|
|
108
108
|
[key: string]: JsonType;
|
|
109
109
|
};
|
|
110
110
|
errorsWhileComputingFlags: boolean;
|
|
111
|
+
quotaLimited?: string[];
|
|
111
112
|
sessionRecording?: boolean | {
|
|
112
113
|
[key: string]: JsonType;
|
|
113
114
|
};
|
|
@@ -196,10 +197,10 @@ declare abstract class PostHogCoreStateless {
|
|
|
196
197
|
protected getDecide(distinctId: string, groups?: Record<string, string | number>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, extraPayload?: Record<string, any>): Promise<PostHogDecideResponse | undefined>;
|
|
197
198
|
protected getFeatureFlagStateless(key: string, distinctId: string, groups?: Record<string, string>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean): Promise<boolean | string | undefined>;
|
|
198
199
|
protected getFeatureFlagPayloadStateless(key: string, distinctId: string, groups?: Record<string, string>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean): Promise<JsonType | undefined>;
|
|
199
|
-
protected getFeatureFlagPayloadsStateless(distinctId: string, groups?: Record<string, string>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean): Promise<PostHogDecideResponse['featureFlagPayloads'] | undefined>;
|
|
200
|
+
protected getFeatureFlagPayloadsStateless(distinctId: string, groups?: Record<string, string>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean, flagKeysToEvaluate?: string[]): Promise<PostHogDecideResponse['featureFlagPayloads'] | undefined>;
|
|
200
201
|
protected _parsePayload(response: any): any;
|
|
201
|
-
protected getFeatureFlagsStateless(distinctId: string, groups?: Record<string, string | number>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean): Promise<PostHogDecideResponse['featureFlags'] | undefined>;
|
|
202
|
-
protected getFeatureFlagsAndPayloadsStateless(distinctId: string, groups?: Record<string, string | number>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean): Promise<{
|
|
202
|
+
protected getFeatureFlagsStateless(distinctId: string, groups?: Record<string, string | number>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean, flagKeysToEvaluate?: string[]): Promise<PostHogDecideResponse['featureFlags'] | undefined>;
|
|
203
|
+
protected getFeatureFlagsAndPayloadsStateless(distinctId: string, groups?: Record<string, string | number>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, disableGeoip?: boolean, flagKeysToEvaluate?: string[]): Promise<{
|
|
203
204
|
flags: PostHogDecideResponse['featureFlags'] | undefined;
|
|
204
205
|
payloads: PostHogDecideResponse['featureFlagPayloads'] | undefined;
|
|
205
206
|
}>;
|
package/lib/index.esm.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createReadStream } from 'node:fs';
|
|
|
3
3
|
import { createInterface } from 'node:readline';
|
|
4
4
|
import { posix, dirname, sep } from 'node:path';
|
|
5
5
|
|
|
6
|
-
var version = "4.
|
|
6
|
+
var version = "4.9.0";
|
|
7
7
|
|
|
8
8
|
var PostHogPersistedProperty;
|
|
9
9
|
(function (PostHogPersistedProperty) {
|
|
@@ -954,6 +954,11 @@ class PostHogFetchNetworkError extends Error {
|
|
|
954
954
|
function isPostHogFetchError(err) {
|
|
955
955
|
return typeof err === 'object' && (err instanceof PostHogFetchHttpError || err instanceof PostHogFetchNetworkError);
|
|
956
956
|
}
|
|
957
|
+
var QuotaLimitedFeature;
|
|
958
|
+
(function (QuotaLimitedFeature) {
|
|
959
|
+
QuotaLimitedFeature["FeatureFlags"] = "feature_flags";
|
|
960
|
+
QuotaLimitedFeature["Recordings"] = "recordings";
|
|
961
|
+
})(QuotaLimitedFeature || (QuotaLimitedFeature = {}));
|
|
957
962
|
class PostHogCoreStateless {
|
|
958
963
|
constructor(apiKey, options) {
|
|
959
964
|
this.flushPromise = null;
|
|
@@ -1146,7 +1151,7 @@ class PostHogCoreStateless {
|
|
|
1146
1151
|
}
|
|
1147
1152
|
async getFeatureFlagStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1148
1153
|
await this._initPromise;
|
|
1149
|
-
const featureFlags = await this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
1154
|
+
const featureFlags = await this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [key]);
|
|
1150
1155
|
if (!featureFlags) {
|
|
1151
1156
|
// If we haven't loaded flags yet, or errored out, we respond with undefined
|
|
1152
1157
|
return undefined;
|
|
@@ -1162,7 +1167,7 @@ class PostHogCoreStateless {
|
|
|
1162
1167
|
}
|
|
1163
1168
|
async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1164
1169
|
await this._initPromise;
|
|
1165
|
-
const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
1170
|
+
const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [key]);
|
|
1166
1171
|
if (!payloads) {
|
|
1167
1172
|
return undefined;
|
|
1168
1173
|
}
|
|
@@ -1173,9 +1178,9 @@ class PostHogCoreStateless {
|
|
|
1173
1178
|
}
|
|
1174
1179
|
return response;
|
|
1175
1180
|
}
|
|
1176
|
-
async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1181
|
+
async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1177
1182
|
await this._initPromise;
|
|
1178
|
-
const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).payloads;
|
|
1183
|
+
const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate)).payloads;
|
|
1179
1184
|
return payloads;
|
|
1180
1185
|
}
|
|
1181
1186
|
_parsePayload(response) {
|
|
@@ -1186,17 +1191,28 @@ class PostHogCoreStateless {
|
|
|
1186
1191
|
return response;
|
|
1187
1192
|
}
|
|
1188
1193
|
}
|
|
1189
|
-
async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1194
|
+
async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1190
1195
|
await this._initPromise;
|
|
1191
|
-
return (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).flags;
|
|
1196
|
+
return (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate)).flags;
|
|
1192
1197
|
}
|
|
1193
|
-
async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1198
|
+
async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
|
|
1194
1199
|
await this._initPromise;
|
|
1195
1200
|
const extraPayload = {};
|
|
1196
1201
|
if (disableGeoip ?? this.disableGeoip) {
|
|
1197
1202
|
extraPayload['geoip_disable'] = true;
|
|
1198
1203
|
}
|
|
1204
|
+
if (flagKeysToEvaluate) {
|
|
1205
|
+
extraPayload['flag_keys_to_evaluate'] = flagKeysToEvaluate;
|
|
1206
|
+
}
|
|
1199
1207
|
const decideResponse = await this.getDecide(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
1208
|
+
// Add check for quota limitation on feature flags
|
|
1209
|
+
if (decideResponse?.quotaLimited?.includes(QuotaLimitedFeature.FeatureFlags)) {
|
|
1210
|
+
console.warn('[FEATURE FLAGS] Feature flags quota limit exceeded - feature flags unavailable. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts');
|
|
1211
|
+
return {
|
|
1212
|
+
flags: undefined,
|
|
1213
|
+
payloads: undefined,
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1200
1216
|
const flags = decideResponse?.featureFlags;
|
|
1201
1217
|
const payloads = decideResponse?.featureFlagPayloads;
|
|
1202
1218
|
let parsedPayloads = payloads;
|
|
@@ -1753,6 +1769,16 @@ class FeatureFlagsPoller {
|
|
|
1753
1769
|
this.authenticationErrorCount += 1;
|
|
1754
1770
|
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`);
|
|
1755
1771
|
}
|
|
1772
|
+
if (res && res.status === 402) {
|
|
1773
|
+
// Quota limited - clear all flags
|
|
1774
|
+
console.warn('[FEATURE FLAGS] Feature flags quota limit exceeded - unsetting all local flags. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts');
|
|
1775
|
+
this.featureFlags = [];
|
|
1776
|
+
this.featureFlagsByKey = {};
|
|
1777
|
+
this.groupTypeMapping = {};
|
|
1778
|
+
this.cohorts = {};
|
|
1779
|
+
this.loadedSuccessfullyOnce = false;
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1756
1782
|
if (res && res.status !== 200) {
|
|
1757
1783
|
// something else went wrong, or the server is down.
|
|
1758
1784
|
// In this case, don't override existing flags
|