@leanbase-giangnd/js 0.0.4 → 0.0.7

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/src/types.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { FeatureFlagValue, JsonType, PostHogCoreOptions } from '@posthog/core'
2
2
  import { KnownUnsafeEditableEvent } from '@posthog/core'
3
- import type { recordOptions } from './extensions/replay/types/rrweb'
4
3
  import { Leanbase } from './leanbase'
5
4
 
6
5
  export const COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'
@@ -101,6 +100,11 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
101
100
  * @default 'https://i.leanbase.co'
102
101
  */
103
102
  host?: string
103
+ /**
104
+ * Backwards-compatible alias expected by replay code
105
+ */
106
+ api_host: string
107
+ ui_host?: string | null
104
108
 
105
109
  /**
106
110
  * The token for your Leanbase project.
@@ -123,22 +127,6 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
123
127
  */
124
128
  autocapture: boolean | AutocaptureConfig
125
129
 
126
- /**
127
- * Enables or disables session recording. When true, session recording is disabled on the client.
128
- * @default false
129
- */
130
- disable_session_recording?: boolean
131
-
132
- /**
133
- * Session recording configuration
134
- */
135
- session_recording?: SessionRecordingOptions
136
-
137
- /**
138
- * Enable console.log recording for session replay (can be controlled remotely). Undefined defers to server.
139
- */
140
- enable_recording_console_log?: boolean
141
-
142
130
  /**
143
131
  * Determines whether Leanbase should capture pageview events automatically.
144
132
  * Can be:
@@ -150,11 +138,6 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
150
138
  */
151
139
  capture_pageview: boolean | 'history_change'
152
140
 
153
- /**
154
- * Enables performance capture. When true, network performance timing can be forwarded to replay when enabled.
155
- */
156
- capture_performance?: boolean | { network_timing?: boolean }
157
-
158
141
  /**
159
142
  * Determines the session idle timeout in seconds.
160
143
  * Any new event that's happened after this timeout will create a new session.
@@ -210,6 +193,26 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
210
193
  */
211
194
  persistence_name: string
212
195
 
196
+ /**
197
+ * Session recording options (browser parity)
198
+ */
199
+ session_recording: SessionRecordingOptions
200
+
201
+ /**
202
+ * Backwards-compatible flag to disable session recording
203
+ */
204
+ disable_session_recording?: boolean
205
+
206
+ /**
207
+ * Controls performance capture options used by replay/network tracing
208
+ */
209
+ capture_performance?: boolean | { network_timing?: boolean; web_vitals?: boolean }
210
+
211
+ /**
212
+ * Enable recording of console logs for session replay
213
+ */
214
+ enable_recording_console_log?: boolean
215
+
213
216
  /**
214
217
  * Prevent autocapture from capturing any attribute names on elements.
215
218
  *
@@ -352,81 +355,15 @@ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
352
355
  * @param instance - The Leanbase instance that has been loaded.
353
356
  */
354
357
  loaded: (instance: Leanbase) => void
355
- }
356
358
 
357
- export type SessionRecordingCanvasOptions = {
358
- recordCanvas?: boolean | null
359
- canvasFps?: number | null
360
- canvasQuality?: string | null
361
- }
362
-
363
- export interface SessionRecordingOptions {
364
- blockClass?: string | RegExp
365
- blockSelector?: string | null
366
- ignoreClass?: string | RegExp
367
- maskTextClass?: string | RegExp
368
- maskTextSelector?: string | null
369
- maskTextFn?: ((text: string, element?: HTMLElement) => string) | null
370
- maskAllInputs?: boolean
371
- maskInputOptions?: recordOptions['maskInputOptions']
372
- maskInputFn?: ((text: string, element?: HTMLElement) => string) | null
373
- slimDOMOptions?: recordOptions['slimDOMOptions']
374
- collectFonts?: boolean
375
- inlineStylesheet?: boolean
376
- recordCrossOriginIframes?: boolean
377
- recordHeaders?: boolean
378
- recordBody?: boolean
379
- captureCanvas?: SessionRecordingCanvasOptions
380
- maskCapturedNetworkRequestFn?: ((data: CapturedNetworkRequest) => CapturedNetworkRequest | null | undefined) | null
381
- maskNetworkRequestFn?: ((data: NetworkRequest) => NetworkRequest | null | undefined) | null
382
- full_snapshot_interval_millis?: number
383
- compress_events?: boolean
384
- session_idle_threshold_ms?: number
385
- __mutationThrottlerRefillRate?: number
386
- __mutationThrottlerBucketSize?: number
387
359
  /**
388
- * Force-enable session recording locally even if remote config disables it.
389
- * Useful for dev/testing when the backend has sessionRecording set to false.
360
+ * Hook to allow preparing external dependency stylesheet before injection
390
361
  */
391
- forceClientRecording?: boolean
392
- }
393
-
394
- export type SessionRecordingPersistedConfig = Omit<
395
- SessionRecordingRemoteConfig,
396
- | 'recordCanvas'
397
- | 'canvasFps'
398
- | 'canvasQuality'
399
- | 'networkPayloadCapture'
400
- | 'sampleRate'
401
- | 'minimumDurationMilliseconds'
402
- > & {
403
- enabled: boolean
404
- networkPayloadCapture: SessionRecordingRemoteConfig['networkPayloadCapture'] & {
405
- capturePerformance: RemoteConfig['capturePerformance']
406
- }
407
- canvasRecording: {
408
- enabled: SessionRecordingRemoteConfig['recordCanvas']
409
- fps: SessionRecordingRemoteConfig['canvasFps']
410
- quality: SessionRecordingRemoteConfig['canvasQuality']
411
- }
412
- sampleRate: number | null
413
- minimumDurationMilliseconds: number | null | undefined
362
+ prepare_external_dependency_stylesheet?: (stylesheet: HTMLStyleElement) => HTMLStyleElement | null | undefined
414
363
  }
415
364
 
416
- export type SessionRecordingRemoteConfig = SessionRecordingCanvasOptions & {
417
- endpoint?: string
418
- consoleLogRecordingEnabled?: boolean
419
- sampleRate?: string | null
420
- minimumDurationMilliseconds?: number
421
- linkedFlag?: string | { flag: string; variant: string } | null
422
- networkPayloadCapture?: Pick<NetworkRecordOptions, 'recordBody' | 'recordHeaders' | 'payloadHostDenyList'>
423
- masking?: Pick<SessionRecordingOptions, 'maskAllInputs' | 'maskTextSelector' | 'blockSelector'>
424
- urlTriggers?: SessionRecordingUrlTrigger[]
425
- scriptConfig?: { script?: string | undefined }
426
- urlBlocklist?: SessionRecordingUrlTrigger[]
427
- eventTriggers?: string[]
428
- triggerMatchType?: 'any' | 'all'
429
- }
365
+ // Backwards-compatible alias expected by replay code
366
+ export type PostHogConfig = LeanbaseConfig
430
367
 
431
368
  export interface RageclickConfig {
432
369
  /**
@@ -562,11 +499,6 @@ export interface RemoteConfig {
562
499
  */
563
500
  autocaptureExceptions?: boolean | { endpoint?: string }
564
501
 
565
- /**
566
- * Session recording configuration options
567
- */
568
- sessionRecording?: SessionRecordingRemoteConfig | false
569
-
570
502
  /**
571
503
  * @deprecated, moved to toolbarParams
572
504
  */
@@ -577,6 +509,11 @@ export interface RemoteConfig {
577
509
  */
578
510
  isAuthenticated: boolean
579
511
 
512
+ /**
513
+ * Session recording remote config (when available)
514
+ */
515
+ sessionRecording?: SessionRecordingRemoteConfig
516
+
580
517
  /**
581
518
  * List of site apps with their IDs and URLs
582
519
  */
@@ -667,16 +604,34 @@ export interface RequestWithOptions {
667
604
  }
668
605
  }
669
606
 
607
+ export type DeadClicksAutoCaptureConfig = {
608
+ scroll_threshold_ms?: number
609
+ selection_change_threshold_ms?: number
610
+ mutation_threshold_ms?: number
611
+ __onCapture?: ((click: any, properties: Properties) => void) | undefined
612
+ } & Pick<AutocaptureConfig, 'element_attribute_ignorelist'>
613
+
614
+ export type ExternalIntegrationKind = 'intercom' | 'crispChat'
615
+
616
+ export type SiteAppLoader = {
617
+ id: string
618
+ init: (config: { posthog: any; callback: (success: boolean) => void }) => {
619
+ processEvent?: (globals: any) => void
620
+ }
621
+ }
622
+
623
+ // Network / replay types (copied from browser package) -------------------------------------------------
670
624
  export type InitiatorType =
671
625
  | 'audio'
672
626
  | 'beacon'
673
627
  | 'body'
674
628
  | 'css'
675
- | 'early-hints'
629
+ | 'early-hint'
676
630
  | 'embed'
677
631
  | 'fetch'
678
632
  | 'frame'
679
633
  | 'iframe'
634
+ | 'icon'
680
635
  | 'image'
681
636
  | 'img'
682
637
  | 'input'
@@ -689,24 +644,8 @@ export type InitiatorType =
689
644
  | 'video'
690
645
  | 'xmlhttprequest'
691
646
 
692
- export type NetworkRecordOptions = {
693
- initiatorTypes?: InitiatorType[]
694
- maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined
695
- recordHeaders?: boolean | { request: boolean; response: boolean }
696
- recordBody?: boolean | string[] | { request: boolean | string[]; response: boolean | string[] }
697
- recordInitialRequests?: boolean
698
- recordPerformance?: boolean
699
- performanceEntryTypeToObserve: string[]
700
- payloadSizeLimitBytes: number
701
- payloadHostDenyList?: string[]
702
- }
703
-
704
- export type NetworkRequest = {
705
- url: string
706
- }
707
-
708
- export type Headers = Record<string, any>
709
-
647
+ // we mirror PerformanceEntry since we read into this type from a PerformanceObserver,
648
+ // but we don't want to inherit its readonly-iness
710
649
  type Writable<T> = { -readonly [P in keyof T]: T[P] }
711
650
 
712
651
  export type CapturedNetworkRequest = Writable<Omit<PerformanceEntry, 'toJSON'>> & {
@@ -721,14 +660,35 @@ export type CapturedNetworkRequest = Writable<Omit<PerformanceEntry, 'toJSON'>>
721
660
  requestBody?: string | null
722
661
  responseHeaders?: Headers
723
662
  responseBody?: string | null
663
+ // was this captured before fetch/xhr could have been wrapped
724
664
  isInitial?: boolean
725
665
  }
726
666
 
727
- export interface SessionRecordingUrlTrigger {
667
+ export type Headers = Record<string, string>
668
+
669
+ export type NetworkRecordOptions = {
670
+ initiatorTypes?: InitiatorType[]
671
+ maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined
672
+ recordHeaders?: boolean | { request: boolean; response: boolean }
673
+ recordBody?: boolean | string[] | { request: boolean | string[]; response: boolean | string[] }
674
+ recordInitialRequests?: boolean
675
+ recordPerformance?: boolean
676
+ performanceEntryTypeToObserve: string[]
677
+ payloadSizeLimitBytes: number
678
+ payloadHostDenyList?: string[]
679
+ }
680
+
681
+ /** @deprecated - use CapturedNetworkRequest instead */
682
+ export type NetworkRequest = {
728
683
  url: string
729
- matching: 'regex'
730
684
  }
731
685
 
686
+ export type SessionIdChangedCallback = (
687
+ sessionId: string,
688
+ windowId: string | null | undefined,
689
+ changeReason?: { noSessionId: boolean; activityTimeout: boolean; sessionPastMaximumLength: boolean }
690
+ ) => void
691
+
732
692
  export type SessionStartReason =
733
693
  | 'sampling_overridden'
734
694
  | 'recording_initialized'
@@ -739,11 +699,47 @@ export type SessionStartReason =
739
699
  | 'url_trigger_matched'
740
700
  | 'event_trigger_matched'
741
701
 
742
- export type SessionIdChangedCallback = (
743
- sessionId: string,
744
- windowId: string | null | undefined,
745
- changeReason?: { noSessionId: boolean; activityTimeout: boolean; sessionPastMaximumLength: boolean }
746
- ) => void
702
+ export type SessionRecordingCanvasOptions = {
703
+ recordCanvas?: boolean | null
704
+ canvasFps?: number | null
705
+ canvasQuality?: string | null
706
+ }
707
+
708
+ export type SessionRecordingOptions = {
709
+ __mutationThrottlerBucketSize?: number
710
+ __mutationThrottlerRefillRate?: number
711
+ blockClass?: string | RegExp
712
+ blockSelector?: string | null
713
+ captureCanvas?: SessionRecordingCanvasOptions
714
+ collectFonts?: boolean
715
+ compress_events?: boolean
716
+ full_snapshot_interval_millis?: number
717
+ ignoreClass?: string | RegExp
718
+ inlineStylesheet?: boolean
719
+ maskAllInputs?: boolean
720
+ maskCapturedNetworkRequestFn?: ((data: CapturedNetworkRequest) => CapturedNetworkRequest | null | undefined) | null
721
+ maskInputFn?: ((text: string, element?: HTMLElement) => string) | null
722
+ maskInputOptions?: any
723
+ maskNetworkRequestFn?: ((data: NetworkRequest) => NetworkRequest | null | undefined) | null
724
+ maskTextClass?: string | RegExp
725
+ maskTextFn?: ((text: string, element?: HTMLElement) => string) | null
726
+ maskTextSelector?: string | null
727
+ recordBody?: boolean
728
+ recordCrossOriginIframes?: boolean
729
+ recordHeaders?: boolean
730
+ session_idle_threshold_ms?: number
731
+ slimDOMOptions?: any
732
+ }
733
+
734
+ export type SessionRecordingPersistedConfig = any
735
+ export type SessionRecordingRemoteConfig = any
736
+
737
+ export type FlagVariant = { flag: string; variant: string }
738
+
739
+ export interface SessionRecordingUrlTrigger {
740
+ url: string
741
+ matching: 'regex'
742
+ }
747
743
 
748
744
  export type LeanbasegCaptureOptions = {
749
745
  /** If provided overrides the auto-generated event ID */
@@ -0,0 +1,239 @@
1
+ import type { PostHog } from '../posthog-core'
2
+ import { SessionIdManager } from '../sessionid'
3
+ import {
4
+ DeadClicksAutoCaptureConfig,
5
+ ExternalIntegrationKind,
6
+ Properties,
7
+ RemoteConfig,
8
+ SiteAppLoader,
9
+ SessionStartReason,
10
+ } from '../types'
11
+ // only importing types here, so won't affect the bundle
12
+ // eslint-disable-next-line posthog-js/no-external-replay-imports
13
+ import type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'
14
+ import { eventWithTime } from '../extensions/replay/types/rrweb-types'
15
+ import { ErrorTracking } from '@posthog/core'
16
+
17
+ /*
18
+ * Global helpers to protect access to browser globals in a way that is safer for different targets
19
+ * like DOM, SSR, Web workers etc.
20
+ *
21
+ * NOTE: Typically we want the "window" but globalThis works for both the typical browser context as
22
+ * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.
23
+ * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced
24
+ * to handle the case where the global is not available.
25
+ */
26
+
27
+ // eslint-disable-next-line no-restricted-globals
28
+ const win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined
29
+
30
+ export type AssignableWindow = Window &
31
+ typeof globalThis & {
32
+ /*
33
+ * Main PostHog instance
34
+ */
35
+ posthog: any
36
+
37
+ /*
38
+ * This is our contract between (potentially) lazily loaded extensions and the SDK
39
+ */
40
+ __PosthogExtensions__?: PostHogExtensions
41
+
42
+ /**
43
+ * When loading remote config, we assign it to this global configuration
44
+ * for ease of sharing it with the rest of the SDK
45
+ */
46
+ _POSTHOG_REMOTE_CONFIG?: Record<
47
+ string,
48
+ {
49
+ config: RemoteConfig
50
+ siteApps: SiteAppLoader[]
51
+ }
52
+ >
53
+
54
+ /**
55
+ * If this is set on the window, our logger will log to the console
56
+ * for ease of debugging. Used for testing purposes only.
57
+ *
58
+ * @see {Config.DEBUG} from config.ts
59
+ */
60
+ POSTHOG_DEBUG: any
61
+
62
+ // Exposed by the browser
63
+ doNotTrack: any
64
+
65
+ // See entrypoints/customizations.full.ts
66
+ posthogCustomizations: any
67
+
68
+ /**
69
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
70
+ * Can be removed once we drop support for 1.161.1
71
+ *
72
+ * See entrypoints/exception-autocapture.ts
73
+ *
74
+ * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead
75
+ */
76
+ posthogErrorWrappingFunctions: any
77
+
78
+ /**
79
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
80
+ * Can be removed once we drop support for 1.161.1
81
+ *
82
+ * See entrypoints/posthog-recorder.ts
83
+ *
84
+ * @deprecated use `__PosthogExtensions__.rrweb` instead
85
+ */
86
+ rrweb: any
87
+
88
+ /**
89
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
90
+ * Can be removed once we drop support for 1.161.1
91
+ *
92
+ * See entrypoints/posthog-recorder.ts
93
+ *
94
+ * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead
95
+ */
96
+ rrwebConsoleRecord: any
97
+
98
+ /**
99
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
100
+ * Can be removed once we drop support for 1.161.1
101
+ *
102
+ * See entrypoints/posthog-recorder.ts
103
+ *
104
+ * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead
105
+ */
106
+ getRecordNetworkPlugin: any
107
+
108
+ /**
109
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
110
+ * Can be removed once we drop support for 1.161.1
111
+ *
112
+ * See entrypoints/web-vitals.ts
113
+ *
114
+ * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead
115
+ */
116
+ postHogWebVitalsCallbacks: any
117
+
118
+ /**
119
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
120
+ * Can be removed once we drop support for 1.161.1
121
+ *
122
+ * See entrypoints/tracing-headers.ts
123
+ *
124
+ * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead
125
+ */
126
+ postHogTracingHeadersPatchFns: any
127
+
128
+ /**
129
+ * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility
130
+ * Can be removed once we drop support for 1.161.1
131
+ *
132
+ * See entrypoints/surveys.ts
133
+ *
134
+ * @deprecated use `__PosthogExtensions__.generateSurveys` instead
135
+ */
136
+ extendPostHogWithSurveys: any
137
+
138
+ /*
139
+ * These are used to handle our toolbar state.
140
+ * @see {Toolbar} from extensions/toolbar.ts
141
+ */
142
+ ph_load_toolbar: any
143
+ ph_load_editor: any
144
+ ph_toolbar_state: any
145
+ } & Record<`__$$ph_site_app_${string}`, any>
146
+
147
+ /**
148
+ * This is our contract between (potentially) lazily loaded extensions and the SDK
149
+ * changes to this interface can be breaking changes for users of the SDK
150
+ */
151
+
152
+ export type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'
153
+
154
+ export type PostHogExtensionKind =
155
+ | 'toolbar'
156
+ | 'exception-autocapture'
157
+ | 'web-vitals'
158
+ | 'recorder'
159
+ | 'lazy-recorder'
160
+ | 'tracing-headers'
161
+ | 'surveys'
162
+ | 'dead-clicks-autocapture'
163
+ | 'remote-config'
164
+ | ExternalExtensionKind
165
+
166
+ export interface LazyLoadedSessionRecordingInterface {
167
+ start: (startReason?: SessionStartReason) => void
168
+ stop: () => void
169
+ sessionId: string
170
+ status: SessionRecordingStatus
171
+ onRRwebEmit: (rawEvent: eventWithTime) => void
172
+ log: (message: string, level: 'log' | 'warn' | 'error') => void
173
+ sdkDebugProperties: Properties
174
+ overrideLinkedFlag: () => void
175
+ overrideSampling: () => void
176
+ overrideTrigger: (triggerType: TriggerType) => void
177
+ isStarted: boolean
178
+ tryAddCustomEvent(tag: string, payload: any): boolean
179
+ }
180
+
181
+ export interface LazyLoadedDeadClicksAutocaptureInterface {
182
+ start: (observerTarget: Node) => void
183
+ stop: () => void
184
+ }
185
+
186
+ interface PostHogExtensions {
187
+ loadExternalDependency?: (
188
+ posthog: PostHog,
189
+ kind: PostHogExtensionKind,
190
+ callback: (error?: string | Event, event?: Event) => void
191
+ ) => void
192
+
193
+ loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void
194
+
195
+ errorWrappingFunctions?: {
196
+ wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void
197
+ wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void
198
+ wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void
199
+ }
200
+ rrweb?: { record: any; version: string }
201
+ rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }
202
+ generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined
203
+ postHogWebVitalsCallbacks?: {
204
+ onLCP: (metric: any) => void
205
+ onCLS: (metric: any) => void
206
+ onFCP: (metric: any) => void
207
+ onINP: (metric: any) => void
208
+ }
209
+ tracingHeadersPatchFns?: {
210
+ _patchFetch: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void
211
+ _patchXHR: (hostnames: string[], distinctId: string, sessionManager?: SessionIdManager) => () => void
212
+ }
213
+ initDeadClicksAutocapture?: (
214
+ ph: PostHog,
215
+ config: DeadClicksAutoCaptureConfig
216
+ ) => LazyLoadedDeadClicksAutocaptureInterface
217
+ integrations?: {
218
+ [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }
219
+ }
220
+ initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface
221
+ }
222
+
223
+ const global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win
224
+
225
+ export const ArrayProto = Array.prototype
226
+ export const nativeForEach = ArrayProto.forEach
227
+ export const nativeIndexOf = ArrayProto.indexOf
228
+
229
+ export const navigator = global?.navigator
230
+ export const document = global?.document
231
+ export const location = global?.location
232
+ export const fetch = global?.fetch
233
+ export const XMLHttpRequest =
234
+ global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined
235
+ export const AbortController = global?.AbortController
236
+ export const userAgent = navigator?.userAgent
237
+ export const assignableWindow: AssignableWindow = win ?? ({} as any)
238
+
239
+ export { win as window }
@@ -1,26 +1,64 @@
1
- import { logger as baseLogger } from '../leanbase-logger'
1
+ import Config from '../config'
2
+ import { isUndefined } from '@posthog/core'
3
+ import { assignableWindow, window } from './globals'
4
+ import { logger as leanbaseLogger } from '../leanbase-logger'
5
+ import type { Logger } from '@posthog/core'
2
6
 
3
- export type PosthogJsLogger = {
4
- info: (...args: any[]) => void
5
- warn: (...args: any[]) => void
6
- error: (...args: any[]) => void
7
- critical: (...args: any[]) => void
7
+ type PosthogJsLogger = Omit<Logger, 'createLogger'> & {
8
+ _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void
8
9
  uninitializedWarning: (methodName: string) => void
9
10
  createLogger: (prefix: string) => PosthogJsLogger
10
11
  }
11
12
 
12
13
  const _createLogger = (prefix: string): PosthogJsLogger => {
13
- return {
14
- info: (...args: any[]) => baseLogger.info(prefix, ...args),
15
- warn: (...args: any[]) => baseLogger.warn(prefix, ...args),
16
- error: (...args: any[]) => baseLogger.error(prefix, ...args),
17
- critical: (...args: any[]) => baseLogger.critical(prefix, ...args),
14
+ const logger: PosthogJsLogger = {
15
+ _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {
16
+ if (
17
+ window &&
18
+ (Config.DEBUG || assignableWindow.POSTHOG_DEBUG) &&
19
+ !isUndefined(window.console) &&
20
+ window.console
21
+ ) {
22
+ const consoleLog =
23
+ '__rrweb_original__' in window.console[level]
24
+ ? (window.console[level] as any)['__rrweb_original__']
25
+ : window.console[level]
26
+
27
+ // eslint-disable-next-line no-console
28
+ consoleLog(prefix, ...args)
29
+ }
30
+ },
31
+
32
+ info: (...args: any[]) => {
33
+ logger._log('log', ...args)
34
+ },
35
+
36
+ warn: (...args: any[]) => {
37
+ logger._log('warn', ...args)
38
+ },
39
+
40
+ error: (...args: any[]) => {
41
+ logger._log('error', ...args)
42
+ },
43
+
44
+ critical: (...args: any[]) => {
45
+ // Critical errors are always logged to the console
46
+ // eslint-disable-next-line no-console
47
+ console.error(prefix, ...args)
48
+ },
49
+
18
50
  uninitializedWarning: (methodName: string) => {
19
- baseLogger.error(prefix, `You must initialize Leanbase before calling ${methodName}`)
51
+ logger.error(`You must initialize Leanbase before calling ${methodName}`)
20
52
  },
53
+
21
54
  createLogger: (additionalPrefix: string) => _createLogger(`${prefix} ${additionalPrefix}`),
22
55
  }
56
+ return logger
23
57
  }
24
58
 
25
59
  export const logger = _createLogger('[Leanbase]')
26
- export const createLogger = _createLogger
60
+
61
+ export const createLogger = logger.createLogger
62
+
63
+ // Provide fallback leanbase logger methods for code that expects a simple logger
64
+ export const fallbackLogger = leanbaseLogger