posthog-node 5.5.0 → 5.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Next
2
2
 
3
+ # 5.6.0 – 2025-07-15
4
+
5
+ 1. Added support for filtering feature flags with flagKeys parameter in sendFeatureFlags options
6
+
7
+ # 5.5.1 – 2025-07-15
8
+
9
+ 1. wrap `InconclusiveMatchError`s in `logMsgIfDebug` for local flag evaluations on `sendFeatureFlags`
10
+
3
11
  # 5.5.0 – 2025-07-10
4
12
 
5
13
  1. feat: make the `sendFeatureFlags` parameter more declarative and ergonomic. Implementation notes below:
@@ -937,7 +937,7 @@ function setupExpressErrorHandler(_posthog, app) {
937
937
  });
938
938
  }
939
939
 
940
- var version = "5.5.0";
940
+ var version = "5.6.0";
941
941
 
942
942
  var PostHogPersistedProperty;
943
943
  (function (PostHogPersistedProperty) {
@@ -2176,12 +2176,7 @@ class FeatureFlagsPoller {
2176
2176
  if (!this.loadedSuccessfullyOnce) {
2177
2177
  return response;
2178
2178
  }
2179
- for (const flag of this.featureFlags) {
2180
- if (key === flag.key) {
2181
- featureFlag = flag;
2182
- break;
2183
- }
2184
- }
2179
+ featureFlag = this.featureFlagsByKey[key];
2185
2180
  if (featureFlag !== undefined) {
2186
2181
  try {
2187
2182
  response = await this.computeFlagLocally(featureFlag, distinctId, groups, personProperties, groupProperties);
@@ -2217,12 +2212,13 @@ class FeatureFlagsPoller {
2217
2212
  return response;
2218
2213
  }
2219
2214
  }
2220
- async getAllFlagsAndPayloads(distinctId, groups = {}, personProperties = {}, groupProperties = {}) {
2215
+ async getAllFlagsAndPayloads(distinctId, groups = {}, personProperties = {}, groupProperties = {}, flagKeysToExplicitlyEvaluate) {
2221
2216
  await this.loadFeatureFlags();
2222
2217
  const response = {};
2223
2218
  const payloads = {};
2224
2219
  let fallbackToFlags = this.featureFlags.length == 0;
2225
- await Promise.all(this.featureFlags.map(async flag => {
2220
+ const flagsToEvaluate = flagKeysToExplicitlyEvaluate ? flagKeysToExplicitlyEvaluate.map(key => this.featureFlagsByKey[key]).filter(Boolean) : this.featureFlags;
2221
+ await Promise.all(flagsToEvaluate.map(async flag => {
2226
2222
  try {
2227
2223
  const matchValue = await this.computeFlagLocally(flag, distinctId, groups, personProperties, groupProperties);
2228
2224
  response[flag.key] = matchValue;
@@ -2232,7 +2228,7 @@ class FeatureFlagsPoller {
2232
2228
  }
2233
2229
  } catch (e) {
2234
2230
  if (e instanceof InconclusiveMatchError) {
2235
- this.onError?.(new Error(`Unable to compute flag locally: ${flag.key} - ${e.message}`));
2231
+ this.logMsgIfDebug(() => console.debug(`InconclusiveMatchError when computing flag locally: ${flag.key}: ${e}`));
2236
2232
  } else if (e instanceof Error) {
2237
2233
  this.onError?.(new Error(`Error computing flag locally: ${flag.key}: ${e}`));
2238
2234
  }
@@ -2329,6 +2325,9 @@ class FeatureFlagsPoller {
2329
2325
  let matches = false;
2330
2326
  if (propertyType === 'cohort') {
2331
2327
  matches = matchCohort(prop, properties, this.cohorts, this.debugMode);
2328
+ } else if (propertyType === 'flag') {
2329
+ this.logMsgIfDebug(() => console.warn(`[FEATURE FLAGS] Flag dependency filters are not supported in local evaluation. ` + `Skipping condition for flag '${flag.key}' with dependency on flag '${prop.key || 'unknown'}'`));
2330
+ continue;
2332
2331
  } else {
2333
2332
  matches = matchProperty(prop, properties, warnFunction);
2334
2333
  }
@@ -2666,6 +2665,11 @@ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties, deb
2666
2665
  let matches;
2667
2666
  if (prop.type === 'cohort') {
2668
2667
  matches = matchCohort(prop, propertyValues, cohortProperties, debugMode);
2668
+ } else if (prop.type === 'flag') {
2669
+ if (debugMode) {
2670
+ console.warn(`[FEATURE FLAGS] Flag dependency filters are not supported in local evaluation. ` + `Skipping condition with dependency on flag '${prop.key || 'unknown'}'`);
2671
+ }
2672
+ continue;
2669
2673
  } else {
2670
2674
  matches = matchProperty(prop, propertyValues);
2671
2675
  }
@@ -3167,7 +3171,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
3167
3171
  async getAllFlagsAndPayloads(distinctId, options) {
3168
3172
  const {
3169
3173
  groups,
3170
- disableGeoip
3174
+ disableGeoip,
3175
+ flagKeys
3171
3176
  } = options || {};
3172
3177
  let {
3173
3178
  onlyEvaluateLocally,
@@ -3181,7 +3186,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
3181
3186
  if (onlyEvaluateLocally == undefined) {
3182
3187
  onlyEvaluateLocally = false;
3183
3188
  }
3184
- const localEvaluationResult = await this.featureFlagsPoller?.getAllFlagsAndPayloads(distinctId, groups, personProperties, groupProperties);
3189
+ const localEvaluationResult = await this.featureFlagsPoller?.getAllFlagsAndPayloads(distinctId, groups, personProperties, groupProperties, flagKeys);
3185
3190
  let featureFlags = {};
3186
3191
  let featureFlagPayloads = {};
3187
3192
  let fallbackToFlags = true;
@@ -3191,7 +3196,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
3191
3196
  fallbackToFlags = localEvaluationResult.fallbackToFlags;
3192
3197
  }
3193
3198
  if (fallbackToFlags && !onlyEvaluateLocally) {
3194
- const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
3199
+ const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, flagKeys);
3195
3200
  featureFlags = {
3196
3201
  ...featureFlags,
3197
3202
  ...(remoteEvaluationResult.flags || {})
@@ -3291,6 +3296,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
3291
3296
  // Use properties directly from options if they exist
3292
3297
  const finalPersonProperties = sendFeatureFlagsOptions?.personProperties || {};
3293
3298
  const finalGroupProperties = sendFeatureFlagsOptions?.groupProperties || {};
3299
+ const flagKeys = sendFeatureFlagsOptions?.flagKeys;
3294
3300
  // Check if we should only evaluate locally
3295
3301
  const onlyEvaluateLocally = sendFeatureFlagsOptions?.onlyEvaluateLocally ?? false;
3296
3302
  // If onlyEvaluateLocally is true, only use local evaluation
@@ -3305,7 +3311,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
3305
3311
  personProperties: finalPersonProperties,
3306
3312
  groupProperties: finalGroupProperties,
3307
3313
  disableGeoip,
3308
- onlyEvaluateLocally: true
3314
+ onlyEvaluateLocally: true,
3315
+ flagKeys
3309
3316
  });
3310
3317
  } else {
3311
3318
  // If onlyEvaluateLocally is true but we don't have local flags, return empty
@@ -3323,7 +3330,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
3323
3330
  personProperties: finalPersonProperties,
3324
3331
  groupProperties: finalGroupProperties,
3325
3332
  disableGeoip,
3326
- onlyEvaluateLocally: true
3333
+ onlyEvaluateLocally: true,
3334
+ flagKeys
3327
3335
  });
3328
3336
  }
3329
3337
  // Fall back to remote evaluation if local evaluation is not available