posthog-node 2.0.0-alpha4 → 2.0.0-alpha7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthog-node",
3
- "version": "2.0.0-alpha4",
3
+ "version": "2.0.0-alpha7",
4
4
  "description": "PostHog Node.js integration",
5
5
  "repository": "PostHog/posthog-node",
6
6
  "scripts": {
@@ -7,12 +7,15 @@ import {
7
7
  PostHogFetchResponse,
8
8
  PostHogPersistedProperty,
9
9
  } from '../../posthog-core/src'
10
+ import { PostHogMemoryStorage } from '../../posthog-core/src/storage-memory'
10
11
  import { EventMessageV1, GroupIdentifyMessage, IdentifyMessageV1, PostHogNodeV1 } from './types'
11
12
 
12
- export type PostHogOptions = PosthogCoreOptions
13
+ export type PostHogOptions = PosthogCoreOptions & {
14
+ persistence?: 'memory'
15
+ }
13
16
 
14
17
  class PostHog extends PostHogCore {
15
- private _memoryStorage: { [key: string]: any | undefined } = {}
18
+ private _memoryStorage = new PostHogMemoryStorage()
16
19
 
17
20
  constructor(apiKey: string, options: PostHogOptions = {}) {
18
21
  options.captureMode = options?.captureMode || 'json'
@@ -22,11 +25,11 @@ class PostHog extends PostHogCore {
22
25
  }
23
26
 
24
27
  getPersistedProperty(key: PostHogPersistedProperty): any | undefined {
25
- return this._memoryStorage[key]
28
+ return this._memoryStorage.getProperty(key)
26
29
  }
27
30
 
28
31
  setPersistedProperty(key: PostHogPersistedProperty, value: any | null): void {
29
- this._memoryStorage[key] = value !== null ? value : undefined
32
+ return this._memoryStorage.setProperty(key, value)
30
33
  }
31
34
 
32
35
  getSessionId(): string | undefined {
@@ -59,10 +62,14 @@ export class PostHogGlobal implements PostHogNodeV1 {
59
62
  }
60
63
 
61
64
  private reInit(distinctId: string): void {
62
- // Remove all state except the queue
63
- const queue = this._sharedClient.getPersistedProperty(PostHogPersistedProperty.Queue)
64
- this._sharedClient.reset()
65
- this._sharedClient.setPersistedProperty(PostHogPersistedProperty.Queue, queue)
65
+ // Certain properties we want to persist
66
+ const propertiesToKeep = [PostHogPersistedProperty.Queue, PostHogPersistedProperty.OptedOut]
67
+
68
+ for (const key in PostHogPersistedProperty) {
69
+ if (!propertiesToKeep.includes(key as any)) {
70
+ this._sharedClient.setPersistedProperty((PostHogPersistedProperty as any)[key], null)
71
+ }
72
+ }
66
73
  this._sharedClient.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId)
67
74
  }
68
75
 
@@ -111,7 +118,7 @@ export class PostHogGlobal implements PostHogNodeV1 {
111
118
  defaultResult?: boolean | undefined,
112
119
  groups?: Record<string, string> | undefined
113
120
  ): Promise<boolean> {
114
- const feat = this.getFeatureFlag(key, distinctId, groups)
121
+ const feat = await this.getFeatureFlag(key, distinctId, groups)
115
122
  return !!feat || defaultResult || false
116
123
  }
117
124
 
@@ -17,7 +17,7 @@ const getLastBatchEvents = (): any[] | undefined => {
17
17
  return JSON.parse((call[1] as any).body as any).batch
18
18
  }
19
19
 
20
- describe('PostHog Core', () => {
20
+ describe('PostHog Node.js', () => {
21
21
  let posthog: PostHog
22
22
 
23
23
  jest.useFakeTimers()
@@ -37,7 +37,7 @@ describe('PostHog Core', () => {
37
37
  } as any)
38
38
  })
39
39
 
40
- describe('legacy methods', () => {
40
+ describe('core methods', () => {
41
41
  it('should capture an event to shared queue', async () => {
42
42
  expect(mockedUndici.fetch).toHaveBeenCalledTimes(0)
43
43
  posthog.capture({ distinctId: '123', event: 'test-event', properties: { foo: 'bar' }, groups: { org: 123 } })
@@ -89,4 +89,49 @@ describe('PostHog Core', () => {
89
89
  ])
90
90
  })
91
91
  })
92
+
93
+ describe('feature flags', () => {
94
+ beforeEach(() => {
95
+ const mockFeatureFlags = {
96
+ 'feature-1': true,
97
+ 'feature-2': true,
98
+ 'feature-variant': 'variant',
99
+ }
100
+
101
+ mockedUndici.fetch.mockImplementation((url) => {
102
+ if ((url as any).includes('/decide/')) {
103
+ return Promise.resolve({
104
+ status: 200,
105
+ text: () => Promise.resolve('ok'),
106
+ json: () =>
107
+ Promise.resolve({
108
+ featureFlags: mockFeatureFlags,
109
+ }),
110
+ }) as any
111
+ }
112
+
113
+ return Promise.resolve({
114
+ status: 200,
115
+ text: () => Promise.resolve('ok'),
116
+ json: () =>
117
+ Promise.resolve({
118
+ status: 'ok',
119
+ }),
120
+ }) as any
121
+ })
122
+ })
123
+
124
+ it('should do getFeatureFlag', async () => {
125
+ expect(mockedUndici.fetch).toHaveBeenCalledTimes(0)
126
+ await expect(posthog.getFeatureFlag('feature-variant', '123', { org: '123' })).resolves.toEqual('variant')
127
+ expect(mockedUndici.fetch).toHaveBeenCalledTimes(1)
128
+ })
129
+
130
+ it('should do isFeatureEnabled', async () => {
131
+ expect(mockedUndici.fetch).toHaveBeenCalledTimes(0)
132
+ await expect(posthog.isFeatureEnabled('feature-1', '123', false, { org: '123' })).resolves.toEqual(true)
133
+ await expect(posthog.isFeatureEnabled('feature-4', '123', false, { org: '123' })).resolves.toEqual(false)
134
+ expect(mockedUndici.fetch).toHaveBeenCalledTimes(2)
135
+ })
136
+ })
92
137
  })