posthog-node 2.5.2 → 2.5.4

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.
@@ -11,6 +11,7 @@ export declare abstract class PostHogCoreStateless {
11
11
  private requestTimeout;
12
12
  private captureMode;
13
13
  private removeDebugCallback?;
14
+ private debugMode;
14
15
  private pendingPromises;
15
16
  private _optoutOverride;
16
17
  protected _events: SimpleEventEmitter;
@@ -27,7 +27,9 @@ declare class FeatureFlagsPoller {
27
27
  host: FeatureFlagsPollerOptions['host'];
28
28
  poller?: NodeJS.Timeout;
29
29
  fetch: (url: string, options: PostHogFetchOptions) => Promise<PostHogFetchResponse>;
30
+ debugMode: boolean;
30
31
  constructor({ pollingInterval, personalApiKey, projectApiKey, timeout, host, ...options }: FeatureFlagsPollerOptions);
32
+ debug(enabled?: boolean): void;
31
33
  getFeatureFlag(key: string, distinctId: string, groups?: Record<string, string>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>): Promise<string | boolean | undefined>;
32
34
  computeFeatureFlagPayloadLocally(key: string, matchValue: string | boolean): Promise<JsonType | undefined>;
33
35
  getAllFlagsAndPayloads(distinctId: string, groups?: Record<string, string>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>): Promise<{
@@ -23,6 +23,7 @@ export declare class PostHog extends PostHogCoreStateless implements PostHogNode
23
23
  getCustomUserAgent(): string;
24
24
  enable(): void;
25
25
  disable(): void;
26
+ debug(enabled?: boolean): void;
26
27
  capture({ distinctId, event, properties, groups, sendFeatureFlags, timestamp }: EventMessageV1): void;
27
28
  identify({ distinctId, properties }: IdentifyMessageV1): void;
28
29
  alias(data: {
@@ -62,7 +63,7 @@ export declare class PostHog extends PostHogCoreStateless implements PostHogNode
62
63
  groupProperties?: Record<string, Record<string, string>>;
63
64
  onlyEvaluateLocally?: boolean;
64
65
  }): Promise<PosthogFlagsAndPayloadsResponse>;
65
- groupIdentify({ groupType, groupKey, properties }: GroupIdentifyMessage): void;
66
+ groupIdentify({ groupType, groupKey, properties, distinctId }: GroupIdentifyMessage): void;
66
67
  reloadFeatureFlags(): Promise<void>;
67
68
  shutdown(): void;
68
69
  shutdownAsync(): Promise<void>;
@@ -13,6 +13,7 @@ export interface GroupIdentifyMessage {
13
13
  groupType: string;
14
14
  groupKey: string;
15
15
  properties?: Record<string | number, any>;
16
+ distinctId?: string;
16
17
  }
17
18
  export declare type FeatureFlagCondition = {
18
19
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthog-node",
3
- "version": "2.5.2",
3
+ "version": "2.5.4",
4
4
  "description": "PostHog Node.js integration",
5
5
  "repository": "PostHog/posthog-node",
6
6
  "scripts": {
@@ -51,6 +51,7 @@ class FeatureFlagsPoller {
51
51
  host: FeatureFlagsPollerOptions['host']
52
52
  poller?: NodeJS.Timeout
53
53
  fetch: (url: string, options: PostHogFetchOptions) => Promise<PostHogFetchResponse>
54
+ debugMode: boolean = false
54
55
 
55
56
  constructor({
56
57
  pollingInterval,
@@ -76,6 +77,10 @@ class FeatureFlagsPoller {
76
77
  void this.loadFeatureFlags()
77
78
  }
78
79
 
80
+ debug(enabled: boolean = true): void {
81
+ this.debugMode = enabled
82
+ }
83
+
79
84
  async getFeatureFlag(
80
85
  key: string,
81
86
  distinctId: string,
@@ -102,9 +107,14 @@ class FeatureFlagsPoller {
102
107
  if (featureFlag !== undefined) {
103
108
  try {
104
109
  response = this.computeFlagLocally(featureFlag, distinctId, groups, personProperties, groupProperties)
110
+ if (this.debugMode) {
111
+ console.debug(`Successfully computed flag locally: ${key} -> ${response}`)
112
+ }
105
113
  } catch (e) {
106
114
  if (e instanceof InconclusiveMatchError) {
107
- console.error(`InconclusiveMatchError when computing flag locally: ${key}: ${e}`)
115
+ if (this.debugMode) {
116
+ console.debug(`InconclusiveMatchError when computing flag locally: ${key}: ${e}`)
117
+ }
108
118
  } else if (e instanceof Error) {
109
119
  console.error(`Error computing flag locally: ${key}: ${e}`)
110
120
  }
@@ -92,6 +92,11 @@ export class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
92
92
  return super.optOut()
93
93
  }
94
94
 
95
+ debug(enabled: boolean = true): void {
96
+ super.debug(enabled)
97
+ this.featureFlagsPoller?.debug(enabled)
98
+ }
99
+
95
100
  capture({ distinctId, event, properties, groups, sendFeatureFlags, timestamp }: EventMessageV1): void {
96
101
  const _capture = (props: EventMessageV1['properties']): void => {
97
102
  super.captureStateless(distinctId, event, props, { timestamp })
@@ -102,11 +107,14 @@ export class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
102
107
  const featureVariantProperties: Record<string, string | boolean> = {}
103
108
  if (flags) {
104
109
  for (const [feature, variant] of Object.entries(flags)) {
105
- featureVariantProperties[`$feature/${feature}`] = variant
110
+ if (variant !== false) {
111
+ featureVariantProperties[`$feature/${feature}`] = variant
112
+ }
106
113
  }
107
114
  }
115
+ const activeFlags = Object.keys(flags || {}).filter((flag) => flags?.[flag] !== false)
108
116
  const flagProperties = {
109
- $active_feature_flags: flags ? Object.keys(flags) : undefined,
117
+ $active_feature_flags: activeFlags || undefined,
110
118
  ...featureVariantProperties,
111
119
  }
112
120
  _capture({ ...properties, $groups: groups, ...flagProperties })
@@ -332,8 +340,8 @@ export class PostHog extends PostHogCoreStateless implements PostHogNodeV1 {
332
340
  return { featureFlags, featureFlagPayloads }
333
341
  }
334
342
 
335
- groupIdentify({ groupType, groupKey, properties }: GroupIdentifyMessage): void {
336
- super.groupIdentifyStateless(groupType, groupKey, properties)
343
+ groupIdentify({ groupType, groupKey, properties, distinctId }: GroupIdentifyMessage): void {
344
+ super.groupIdentifyStateless(groupType, groupKey, properties, undefined, distinctId)
337
345
  }
338
346
 
339
347
  async reloadFeatureFlags(): Promise<void> {
package/src/types.ts CHANGED
@@ -16,6 +16,7 @@ export interface GroupIdentifyMessage {
16
16
  groupType: string
17
17
  groupKey: string // Unique identifier for the group
18
18
  properties?: Record<string | number, any>
19
+ distinctId?: string // optional distinctId to associate message with a person
19
20
  }
20
21
 
21
22
  export type FeatureFlagCondition = {
@@ -234,7 +234,6 @@ describe('PostHog Node.js', () => {
234
234
  posthog.groupIdentify({ groupType: 'posthog', groupKey: 'team-1', properties: { analytics: true } })
235
235
  jest.runOnlyPendingTimers()
236
236
  const batchEvents = getLastBatchEvents()
237
- console.log(batchEvents)
238
237
  expect(batchEvents).toMatchObject([
239
238
  {
240
239
  distinct_id: '$posthog_team-1',
@@ -248,6 +247,29 @@ describe('PostHog Node.js', () => {
248
247
  },
249
248
  ])
250
249
  })
250
+
251
+ it('should allow passing optional distinctID to identify group', () => {
252
+ posthog.groupIdentify({
253
+ groupType: 'posthog',
254
+ groupKey: 'team-1',
255
+ properties: { analytics: true },
256
+ distinctId: '123',
257
+ })
258
+ jest.runOnlyPendingTimers()
259
+ const batchEvents = getLastBatchEvents()
260
+ expect(batchEvents).toMatchObject([
261
+ {
262
+ distinct_id: '123',
263
+ event: '$groupidentify',
264
+ properties: {
265
+ $group_type: 'posthog',
266
+ $group_key: 'team-1',
267
+ $group_set: { analytics: true },
268
+ $lib: 'posthog-node',
269
+ },
270
+ },
271
+ ])
272
+ })
251
273
  })
252
274
 
253
275
  describe('feature flags', () => {
@@ -256,6 +278,7 @@ describe('PostHog Node.js', () => {
256
278
  'feature-1': true,
257
279
  'feature-2': true,
258
280
  'feature-variant': 'variant',
281
+ 'disabled-flag': false,
259
282
  }
260
283
 
261
284
  const mockFeatureFlagPayloads = {