posthog-node 4.8.1 → 4.10.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Next
2
2
 
3
+ # 4.10.0 – 2025-03-06
4
+
5
+ 1. Attach requestId to $feature_flag_called if present in /decide response
6
+
7
+ # 4.9.0 – 2025-03-04
8
+
9
+ 1. Allow feature flags to be evaluated individually when local evaluation is not being used
10
+
3
11
  # 4.8.1 – 2025-02-26
4
12
 
5
13
  1. Supports gracefully handling quotaLimited responses from the PostHog API for feature flag evaluation
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.8.1";
10
+ var version = "4.10.0";
11
11
 
12
12
  var PostHogPersistedProperty;
13
13
  (function (PostHogPersistedProperty) {
@@ -1155,10 +1155,14 @@ class PostHogCoreStateless {
1155
1155
  }
1156
1156
  async getFeatureFlagStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
1157
1157
  await this._initPromise;
1158
- const featureFlags = await this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
1158
+ const decideResponse = await this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [key]);
1159
+ const featureFlags = decideResponse.flags;
1159
1160
  if (!featureFlags) {
1160
1161
  // If we haven't loaded flags yet, or errored out, we respond with undefined
1161
- return undefined;
1162
+ return {
1163
+ response: undefined,
1164
+ requestId: undefined,
1165
+ };
1162
1166
  }
1163
1167
  let response = featureFlags[key];
1164
1168
  // `/decide` v3 returns all flags
@@ -1167,11 +1171,14 @@ class PostHogCoreStateless {
1167
1171
  response = false;
1168
1172
  }
1169
1173
  // If we have flags we either return the value (true or string) or false
1170
- return response;
1174
+ return {
1175
+ response,
1176
+ requestId: decideResponse.requestId,
1177
+ };
1171
1178
  }
1172
1179
  async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
1173
1180
  await this._initPromise;
1174
- const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
1181
+ const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [key]);
1175
1182
  if (!payloads) {
1176
1183
  return undefined;
1177
1184
  }
@@ -1182,9 +1189,9 @@ class PostHogCoreStateless {
1182
1189
  }
1183
1190
  return response;
1184
1191
  }
1185
- async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
1192
+ async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
1186
1193
  await this._initPromise;
1187
- const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).payloads;
1194
+ const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate)).payloads;
1188
1195
  return payloads;
1189
1196
  }
1190
1197
  _parsePayload(response) {
@@ -1195,16 +1202,19 @@ class PostHogCoreStateless {
1195
1202
  return response;
1196
1203
  }
1197
1204
  }
1198
- async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
1205
+ async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
1199
1206
  await this._initPromise;
1200
- return (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).flags;
1207
+ return await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeysToEvaluate);
1201
1208
  }
1202
- async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
1209
+ async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
1203
1210
  await this._initPromise;
1204
1211
  const extraPayload = {};
1205
1212
  if (disableGeoip ?? this.disableGeoip) {
1206
1213
  extraPayload['geoip_disable'] = true;
1207
1214
  }
1215
+ if (flagKeysToEvaluate) {
1216
+ extraPayload['flag_keys_to_evaluate'] = flagKeysToEvaluate;
1217
+ }
1208
1218
  const decideResponse = await this.getDecide(distinctId, groups, personProperties, groupProperties, extraPayload);
1209
1219
  // Add check for quota limitation on feature flags
1210
1220
  if (decideResponse?.quotaLimited?.includes(QuotaLimitedFeature.FeatureFlags)) {
@@ -1212,6 +1222,7 @@ class PostHogCoreStateless {
1212
1222
  return {
1213
1223
  flags: undefined,
1214
1224
  payloads: undefined,
1225
+ requestId: decideResponse?.requestId,
1215
1226
  };
1216
1227
  }
1217
1228
  const flags = decideResponse?.featureFlags;
@@ -1223,6 +1234,7 @@ class PostHogCoreStateless {
1223
1234
  return {
1224
1235
  flags,
1225
1236
  payloads: parsedPayloads,
1237
+ requestId: decideResponse?.requestId,
1226
1238
  };
1227
1239
  }
1228
1240
  /***
@@ -3063,8 +3075,8 @@ class PostHog extends PostHogCoreStateless {
3063
3075
  uuid
3064
3076
  });
3065
3077
  };
3066
- const _getFlags = (distinctId, groups, disableGeoip) => {
3067
- return super.getFeatureFlagsStateless(distinctId, groups, undefined, undefined, disableGeoip);
3078
+ const _getFlags = async (distinctId, groups, disableGeoip) => {
3079
+ return (await super.getFeatureFlagsStateless(distinctId, groups, undefined, undefined, disableGeoip)).flags;
3068
3080
  };
3069
3081
  // :TRICKY: If we flush, or need to shut down, to not lose events we want this promise to resolve before we flush
3070
3082
  const capturePromise = Promise.resolve().then(async () => {
@@ -3162,8 +3174,11 @@ class PostHog extends PostHogCoreStateless {
3162
3174
  }
3163
3175
  let response = await this.featureFlagsPoller?.getFeatureFlag(key, distinctId, groups, personProperties, groupProperties);
3164
3176
  const flagWasLocallyEvaluated = response !== undefined;
3177
+ let requestId = undefined;
3165
3178
  if (!flagWasLocallyEvaluated && !onlyEvaluateLocally) {
3166
- response = await super.getFeatureFlagStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
3179
+ const remoteResponse = await super.getFeatureFlagStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
3180
+ response = remoteResponse.response;
3181
+ requestId = remoteResponse.requestId;
3167
3182
  }
3168
3183
  const featureFlagReportedKey = `${key}_${response}`;
3169
3184
  if (sendFeatureFlagEvents && (!(distinctId in this.distinctIdHasSentFlagCalls) || !this.distinctIdHasSentFlagCalls[distinctId].includes(featureFlagReportedKey))) {
@@ -3182,7 +3197,8 @@ class PostHog extends PostHogCoreStateless {
3182
3197
  $feature_flag: key,
3183
3198
  $feature_flag_response: response,
3184
3199
  locally_evaluated: flagWasLocallyEvaluated,
3185
- [`$feature/${key}`]: response
3200
+ [`$feature/${key}`]: response,
3201
+ $feature_flag_request_id: requestId
3186
3202
  },
3187
3203
  groups,
3188
3204
  disableGeoip