posthog-node 5.1.1 → 5.3.1

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/lib/index.d.ts CHANGED
@@ -230,6 +230,12 @@ type SurveyAppearance = {
230
230
  widgetColor?: string;
231
231
  };
232
232
  declare enum SurveyPosition {
233
+ TopLeft = "top_left",
234
+ TopCenter = "top_center",
235
+ TopRight = "top_right",
236
+ MiddleLeft = "middle_left",
237
+ MiddleCenter = "middle_center",
238
+ MiddleRight = "middle_right",
233
239
  Left = "left",
234
240
  Right = "right",
235
241
  Center = "center"
@@ -620,6 +626,7 @@ type PostHogOptions = PostHogCoreOptions & {
620
626
  featureFlagsPollingInterval?: number;
621
627
  maxCacheSize?: number;
622
628
  fetch?: (url: string, options: PostHogFetchOptions) => Promise<PostHogFetchResponse>;
629
+ enableLocalEvaluation?: boolean;
623
630
  };
624
631
  type PostHogFeatureFlag = {
625
632
  id: number;
@@ -818,7 +825,7 @@ declare class ErrorTracking {
818
825
  private _exceptionAutocaptureEnabled;
819
826
  static stackParser: StackParser;
820
827
  static frameModifiers: StackFrameModifierFn[];
821
- static captureException(client: PostHogBackendClient, error: unknown, hint: EventHint, distinctId?: string, additionalProperties?: Record<string | number, any>): Promise<void>;
828
+ static buildEventMessage(error: unknown, hint: EventHint, distinctId?: string, additionalProperties?: Record<string | number, any>): Promise<EventMessage>;
822
829
  constructor(client: PostHogBackendClient, options: PostHogOptions);
823
830
  private startAutocaptureIfEnabled;
824
831
  private onException;
@@ -904,8 +911,10 @@ declare abstract class PostHogBackendClient extends PostHogCoreStateless impleme
904
911
  */
905
912
  reloadFeatureFlags(): Promise<void>;
906
913
  _shutdown(shutdownTimeoutMs?: number): Promise<void>;
914
+ private _requestRemoteConfigPayload;
907
915
  private addLocalPersonAndGroupProperties;
908
916
  captureException(error: unknown, distinctId?: string, additionalProperties?: Record<string | number, any>): void;
917
+ captureExceptionImmediate(error: unknown, distinctId?: string, additionalProperties?: Record<string | number, any>): Promise<void>;
909
918
  }
910
919
 
911
920
  /**
@@ -881,7 +881,7 @@ function applyChunkIds(frames, parser) {
881
881
 
882
882
  const SHUTDOWN_TIMEOUT = 2000;
883
883
  class ErrorTracking {
884
- static async captureException(client, error, hint, distinctId, additionalProperties) {
884
+ static async buildEventMessage(error, hint, distinctId, additionalProperties) {
885
885
  const properties = {
886
886
  ...additionalProperties
887
887
  };
@@ -891,14 +891,14 @@ class ErrorTracking {
891
891
  properties.$process_person_profile = false;
892
892
  }
893
893
  const exceptionProperties = await propertiesFromUnknownInput(this.stackParser, this.frameModifiers, error, hint);
894
- client.capture({
894
+ return {
895
895
  event: '$exception',
896
896
  distinctId: distinctId || uuidv7(),
897
897
  properties: {
898
898
  ...exceptionProperties,
899
899
  ...properties
900
900
  }
901
- });
901
+ };
902
902
  }
903
903
  constructor(client, options) {
904
904
  this.client = client;
@@ -912,7 +912,9 @@ class ErrorTracking {
912
912
  }
913
913
  }
914
914
  onException(exception, hint) {
915
- ErrorTracking.captureException(this.client, exception, hint);
915
+ void ErrorTracking.buildEventMessage(exception, hint).then(msg => {
916
+ this.client.capture(msg);
917
+ });
916
918
  }
917
919
  async onFatalError() {
918
920
  await this.client.shutdown(SHUTDOWN_TIMEOUT);
@@ -932,9 +934,9 @@ function setupExpressErrorHandler(_posthog, app) {
932
934
  };
933
935
  // Given stateless nature of Node SDK we capture exceptions using personless processing
934
936
  // when no user can be determined e.g. in the case of exception autocapture
935
- ErrorTracking.captureException(_posthog, error, hint, uuidv7(), {
937
+ ErrorTracking.buildEventMessage(error, hint, uuidv7(), {
936
938
  $process_person_profile: false
937
- });
939
+ }).then(msg => _posthog.capture(msg));
938
940
  next(error);
939
941
  });
940
942
  }
@@ -1340,7 +1342,7 @@ function snipLine(line, colno) {
1340
1342
  return newLine;
1341
1343
  }
1342
1344
 
1343
- var version = "5.1.1";
1345
+ var version = "5.3.1";
1344
1346
 
1345
1347
  var PostHogPersistedProperty;
1346
1348
  (function (PostHogPersistedProperty) {
@@ -1378,6 +1380,12 @@ var Compression;
1378
1380
  })(Compression || (Compression = {}));
1379
1381
  var SurveyPosition;
1380
1382
  (function (SurveyPosition) {
1383
+ SurveyPosition["TopLeft"] = "top_left";
1384
+ SurveyPosition["TopCenter"] = "top_center";
1385
+ SurveyPosition["TopRight"] = "top_right";
1386
+ SurveyPosition["MiddleLeft"] = "middle_left";
1387
+ SurveyPosition["MiddleCenter"] = "middle_center";
1388
+ SurveyPosition["MiddleRight"] = "middle_right";
1381
1389
  SurveyPosition["Left"] = "left";
1382
1390
  SurveyPosition["Right"] = "right";
1383
1391
  SurveyPosition["Center"] = "center";
@@ -2898,23 +2906,6 @@ class FeatureFlagsPoller {
2898
2906
  stopPoller() {
2899
2907
  clearTimeout(this.poller);
2900
2908
  }
2901
- _requestRemoteConfigPayload(flagKey) {
2902
- const url = `${this.host}/api/projects/@current/feature_flags/${flagKey}/remote_config/`;
2903
- const options = this.getPersonalApiKeyRequestOptions();
2904
- let abortTimeout = null;
2905
- if (this.timeout && typeof this.timeout === 'number') {
2906
- const controller = new AbortController();
2907
- abortTimeout = safeSetTimeout(() => {
2908
- controller.abort();
2909
- }, this.timeout);
2910
- options.signal = controller.signal;
2911
- }
2912
- try {
2913
- return this.fetch(url, options);
2914
- } finally {
2915
- clearTimeout(abortTimeout);
2916
- }
2917
- }
2918
2909
  }
2919
2910
  // # This function takes a distinct_id and a feature flag key and returns a float between 0 and 1.
2920
2911
  // # Given the same distinct_id and key, it'll always return the same float. These floats are
@@ -3199,21 +3190,25 @@ class PostHogBackendClient extends PostHogCoreStateless {
3199
3190
  if (options.personalApiKey.includes('phc_')) {
3200
3191
  throw new Error('Your Personal API key is invalid. These keys are prefixed with "phx_" and can be created in PostHog project settings.');
3201
3192
  }
3202
- this.featureFlagsPoller = new FeatureFlagsPoller({
3203
- pollingInterval: this.options.featureFlagsPollingInterval,
3204
- personalApiKey: options.personalApiKey,
3205
- projectApiKey: apiKey,
3206
- timeout: options.requestTimeout ?? 10000,
3207
- host: this.host,
3208
- fetch: options.fetch,
3209
- onError: err => {
3210
- this._events.emit('error', err);
3211
- },
3212
- onLoad: count => {
3213
- this._events.emit('localEvaluationFlagsLoaded', count);
3214
- },
3215
- customHeaders: this.getCustomHeaders()
3216
- });
3193
+ // Only start the poller if local evaluation is enabled (defaults to true for backward compatibility)
3194
+ const shouldEnableLocalEvaluation = options.enableLocalEvaluation !== false;
3195
+ if (shouldEnableLocalEvaluation) {
3196
+ this.featureFlagsPoller = new FeatureFlagsPoller({
3197
+ pollingInterval: this.options.featureFlagsPollingInterval,
3198
+ personalApiKey: options.personalApiKey,
3199
+ projectApiKey: apiKey,
3200
+ timeout: options.requestTimeout ?? 10000,
3201
+ host: this.host,
3202
+ fetch: options.fetch,
3203
+ onError: err => {
3204
+ this._events.emit('error', err);
3205
+ },
3206
+ onLoad: count => {
3207
+ this._events.emit('localEvaluationFlagsLoaded', count);
3208
+ },
3209
+ customHeaders: this.getCustomHeaders()
3210
+ });
3211
+ }
3217
3212
  }
3218
3213
  this.errorTracking = new ErrorTracking(this, options);
3219
3214
  this.distinctIdHasSentFlagCalls = {};
@@ -3569,7 +3564,10 @@ class PostHogBackendClient extends PostHogCoreStateless {
3569
3564
  return response;
3570
3565
  }
3571
3566
  async getRemoteConfigPayload(flagKey) {
3572
- const response = await this.featureFlagsPoller?._requestRemoteConfigPayload(flagKey);
3567
+ if (!this.options.personalApiKey) {
3568
+ throw new Error('Personal API key is required for remote config payload decryption');
3569
+ }
3570
+ const response = await this._requestRemoteConfigPayload(flagKey);
3573
3571
  if (!response) {
3574
3572
  return undefined;
3575
3573
  }
@@ -3663,6 +3661,38 @@ class PostHogBackendClient extends PostHogCoreStateless {
3663
3661
  this.featureFlagsPoller?.stopPoller();
3664
3662
  return super._shutdown(shutdownTimeoutMs);
3665
3663
  }
3664
+ async _requestRemoteConfigPayload(flagKey) {
3665
+ if (!this.options.personalApiKey) {
3666
+ return undefined;
3667
+ }
3668
+ const url = `${this.host}/api/projects/@current/feature_flags/${flagKey}/remote_config/`;
3669
+ const options = {
3670
+ method: 'GET',
3671
+ headers: {
3672
+ ...this.getCustomHeaders(),
3673
+ 'Content-Type': 'application/json',
3674
+ Authorization: `Bearer ${this.options.personalApiKey}`
3675
+ }
3676
+ };
3677
+ let abortTimeout = null;
3678
+ if (this.options.requestTimeout && typeof this.options.requestTimeout === 'number') {
3679
+ const controller = new AbortController();
3680
+ abortTimeout = safeSetTimeout(() => {
3681
+ controller.abort();
3682
+ }, this.options.requestTimeout);
3683
+ options.signal = controller.signal;
3684
+ }
3685
+ try {
3686
+ return await this.fetch(url, options);
3687
+ } catch (error) {
3688
+ this._events.emit('error', error);
3689
+ return undefined;
3690
+ } finally {
3691
+ if (abortTimeout) {
3692
+ clearTimeout(abortTimeout);
3693
+ }
3694
+ }
3695
+ }
3666
3696
  addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties) {
3667
3697
  const allPersonProperties = {
3668
3698
  distinct_id: distinctId,
@@ -3684,9 +3714,18 @@ class PostHogBackendClient extends PostHogCoreStateless {
3684
3714
  }
3685
3715
  captureException(error, distinctId, additionalProperties) {
3686
3716
  const syntheticException = new Error('PostHog syntheticException');
3687
- ErrorTracking.captureException(this, error, {
3717
+ ErrorTracking.buildEventMessage(error, {
3718
+ syntheticException
3719
+ }, distinctId, additionalProperties).then(msg => {
3720
+ this.capture(msg);
3721
+ });
3722
+ }
3723
+ async captureExceptionImmediate(error, distinctId, additionalProperties) {
3724
+ const syntheticException = new Error('PostHog syntheticException');
3725
+ const evtMsg = await ErrorTracking.buildEventMessage(error, {
3688
3726
  syntheticException
3689
3727
  }, distinctId, additionalProperties);
3728
+ return await this.captureImmediate(evtMsg);
3690
3729
  }
3691
3730
  }
3692
3731