@leanbase.com/js 0.1.1 → 0.1.2

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 ADDED
@@ -0,0 +1,634 @@
1
+ import { FeatureFlagValue, JsonType, PostHogCoreOptions } from '@posthog/core'
2
+ import { KnownUnsafeEditableEvent } from '@posthog/core'
3
+ import { Leanbase } from './leanbase'
4
+
5
+ export const COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'
6
+
7
+ export type Property = any
8
+ export type Properties = Record<string, Property>
9
+
10
+ export type AutocaptureCompatibleElement = 'a' | 'button' | 'form' | 'input' | 'select' | 'textarea' | 'label'
11
+
12
+ export type DomAutocaptureEvents = 'click' | 'change' | 'submit'
13
+
14
+ export interface BootstrapConfig {
15
+ distinctId?: string
16
+ isIdentifiedId?: boolean
17
+ featureFlags?: Record<string, FeatureFlagValue>
18
+ featureFlagPayloads?: Record<string, JsonType>
19
+
20
+ /**
21
+ * Optionally provide a sessionID, this is so that you can provide an existing sessionID here to continue a user's session across a domain or device. It MUST be:
22
+ * - unique to this user
23
+ * - a valid UUID v7
24
+ * - the timestamp part must be <= the timestamp of the first event in the session
25
+ * - the timestamp of the last event in the session must be < the timestamp part + 24 hours
26
+ * **/
27
+ sessionID?: string
28
+ }
29
+
30
+ /**
31
+ * If an array is passed for an allowlist, autocapture events will only be sent for elements matching
32
+ * at least one of the elements in the array. Multiple allowlists can be used
33
+ */
34
+ export interface AutocaptureConfig {
35
+ /**
36
+ * List of URLs to allow autocapture on, can be strings to match
37
+ * or regexes e.g. ['https://example.com', 'test.com/.*']
38
+ * this is useful when you want to autocapture on specific pages only
39
+ *
40
+ * if you set both url_allowlist and url_ignorelist,
41
+ * we check the allowlist first and then the ignorelist.
42
+ * the ignorelist can override the allowlist
43
+ */
44
+ url_allowlist?: (string | RegExp)[]
45
+
46
+ /**
47
+ * List of URLs to not allow autocapture on, can be strings to match
48
+ * or regexes e.g. ['https://example.com', 'test.com/.*']
49
+ * this is useful when you want to autocapture on most pages but not some specific ones
50
+ *
51
+ * if you set both url_allowlist and url_ignorelist,
52
+ * we check the allowlist first and then the ignorelist.
53
+ * the ignorelist can override the allowlist
54
+ */
55
+ url_ignorelist?: (string | RegExp)[]
56
+
57
+ /**
58
+ * List of DOM events to allow autocapture on e.g. ['click', 'change', 'submit']
59
+ */
60
+ dom_event_allowlist?: DomAutocaptureEvents[]
61
+
62
+ /**
63
+ * List of DOM elements to allow autocapture on
64
+ * e.g. ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']
65
+ *
66
+ * We consider the tree of elements from the root to the target element of the click event
67
+ * so for the tree `div > div > button > svg`
68
+ * if the allowlist has `button` then we allow the capture when the `button` or the `svg` is the click target
69
+ * but not if either of the `div`s are detected as the click target
70
+ */
71
+ element_allowlist?: AutocaptureCompatibleElement[]
72
+
73
+ /**
74
+ * List of CSS selectors to allow autocapture on
75
+ * e.g. ['[ph-capture]']
76
+ * we consider the tree of elements from the root to the target element of the click event
77
+ * so for the tree div > div > button > svg
78
+ * and allow list config `['[id]']`
79
+ * we will capture the click if the click-target or its parents has any id
80
+ *
81
+ * Everything is allowed when there's no allowlist
82
+ */
83
+ css_selector_allowlist?: string[]
84
+
85
+ /**
86
+ * Exclude certain element attributes from autocapture
87
+ * E.g. ['aria-label'] or [data-attr-pii]
88
+ */
89
+ element_attribute_ignorelist?: string[]
90
+
91
+ /**
92
+ * When set to true, autocapture will capture the text of any element that is cut or copied.
93
+ */
94
+ capture_copied_text?: boolean
95
+ }
96
+
97
+ export interface LeanbaseConfig extends Partial<PostHogCoreOptions> {
98
+ /**
99
+ * API host for Leanbase
100
+ * @default 'https://i.leanbase.co'
101
+ */
102
+ host?: string
103
+
104
+ /**
105
+ * The token for your Leanbase project.
106
+ * It should NOT be provided manually in the config, but rather passed as the first parameter to `leanbase.init()`.
107
+ */
108
+ token: string
109
+
110
+ /**
111
+ * Enables debug mode, which provides more verbose logging for development purposes.
112
+ * @default false
113
+ */
114
+ debug?: boolean
115
+
116
+ /**
117
+ * Determines whether Leanbase should autocapture events.
118
+ * This setting does not affect capturing pageview events (see `capture_pageview`).
119
+ *
120
+ * by default autocapture is ignored on elements that match a `ph-no-capture` css class on the element or a parent
121
+ * @default true
122
+ */
123
+ autocapture: boolean | AutocaptureConfig
124
+
125
+ /**
126
+ * Determines whether Leanbase should capture pageview events automatically.
127
+ * Can be:
128
+ * - `true`: Capture regular pageviews (default)
129
+ * - `false`: Don't capture any pageviews
130
+ * - `'history_change'`: Only capture pageviews on history API changes (pushState, replaceState, popstate)
131
+ *
132
+ * @default true
133
+ */
134
+ capture_pageview: boolean | 'history_change'
135
+
136
+ /**
137
+ * Determines the session idle timeout in seconds.
138
+ * Any new event that's happened after this timeout will create a new session.
139
+ *
140
+ * @default 30 * 60 -- 30 minutes
141
+ */
142
+ session_idle_timeout_seconds: number
143
+
144
+ /**
145
+ * An object containing the `distinctID`, `isIdentifiedID`, and `featureFlags` keys,
146
+ * where `distinctID` is a string, and `featureFlags` is an object of key-value pairs.
147
+ *
148
+ * Since there is a delay between initializing PostHog and fetching feature flags,
149
+ * feature flags are not always available immediately.
150
+ * This makes them unusable if you want to do something like redirecting a user
151
+ * to a different page based on a feature flag.
152
+ *
153
+ * You can, therefore, fetch the feature flags in your server and pre-fill them here,
154
+ * allowing PostHog to know the feature flag values immediately.
155
+ *
156
+ * After the SDK fetches feature flags from PostHog, it will use those flag values instead of bootstrapped ones.
157
+ *
158
+ * @default {}
159
+ */
160
+ bootstrap: BootstrapConfig
161
+
162
+ /**
163
+ * Determines whether Leanbase should capture pageleave events.
164
+ * If set to `true`, it will capture pageleave events for all pages.
165
+ * If set to `'if_capture_pageview'`, it will only capture pageleave events if `capture_pageview` is also set to `true` or `'history_change'`.
166
+ *
167
+ * @default 'if_capture_pageview'
168
+ */
169
+ capture_pageleave: boolean | 'if_capture_pageview'
170
+
171
+ /**
172
+ * Determines whether Leanbase should capture rage clicks.
173
+ *
174
+ * by default rageclicks are ignored on elements that match a `ph-no-capture` or `ph-no-rageclick` css class on the element or a parent
175
+ * @default true
176
+ */
177
+ rageclick: boolean | RageclickConfig
178
+
179
+ /**
180
+ * Determines where to store the Leanbase persistence information.
181
+ */
182
+ persistence: 'localStorage' | 'cookie' | 'memory' | 'localStorage+cookie' | 'sessionStorage'
183
+
184
+ /**
185
+ * The name for the super properties persistent store
186
+ *
187
+ * @default ''
188
+ */
189
+ persistence_name: string
190
+
191
+ /**
192
+ * Prevent autocapture from capturing any attribute names on elements.
193
+ *
194
+ * @default false
195
+ */
196
+ mask_all_element_attributes: boolean
197
+
198
+ /**
199
+ * Prevent autocapture from capturing `textContent` on elements.
200
+ *
201
+ * @default false
202
+ */
203
+ mask_all_text: boolean
204
+
205
+ /**
206
+ * Used to extend the list of campaign parameters that are saved by default.
207
+ *
208
+ * @see {CAMPAIGN_PARAMS} from './utils/event-utils' - Default campaign parameters like utm_source, utm_medium, etc.
209
+ * @default []
210
+ */
211
+ custom_campaign_params: string[]
212
+
213
+ /**
214
+ * Mask personal data properties from the current URL.
215
+ * This will mask personal data properties such as advertising IDs (gclid, fbclid, etc.), and you can also add
216
+ * custom properties to mask with `custom_personal_data_properties`.
217
+ * @default false
218
+ * @see {PERSONAL_DATA_CAMPAIGN_PARAMS} - Default campaign parameters that are masked by default.
219
+ * @see {LeanbaseConfig.custom_personal_data_properties} - Custom list of personal data properties to mask.
220
+ */
221
+ mask_personal_data_properties: boolean
222
+
223
+ /**
224
+ * Custom list of personal data properties to mask.
225
+ *
226
+ * E.g. if you added `email` to this list, then any `email` property in the URL will be masked.
227
+ * https://www.example.com/login?email=john.doe%40example.com => https://www.example.com/login?email=<MASKED>
228
+ *
229
+ * @default []
230
+ * @see {LeanbaseConfig.mask_personal_data_properties} - Must be enabled for this to take effect.
231
+ */
232
+ custom_personal_data_properties: string[]
233
+
234
+ /**
235
+ * Determines the number of days to store cookies for.
236
+ *
237
+ * @default 365
238
+ */
239
+ cookie_expiration: number
240
+
241
+ /**
242
+ * Determines whether Leanbase should use secure cookies.
243
+ * If this is `true`, Leanbase cookies will be marked as secure,
244
+ * meaning they will only be transmitted over HTTPS.
245
+ *
246
+ * @default window.location.protocol === 'https:'
247
+ */
248
+ secure_cookie: boolean
249
+
250
+ /**
251
+ * Determines if cookie should be set on the top level domain (example.com).
252
+ * If leanbase-js is loaded on a subdomain (test.example.com), and `cross_subdomain_cookie` is set to false,
253
+ * it'll set the cookie on the subdomain only (test.example.com).
254
+ *
255
+ * NOTE: It will be set to `false` if we detect that the domain is a subdomain of a platform that is excluded from cross-subdomain cookie setting.
256
+ * The current list of excluded platforms is `herokuapp.com`, `vercel.app`, and `netlify.app`.
257
+ *
258
+ * @see `isCrossDomainCookie`
259
+ * @default true
260
+ */
261
+ cross_subdomain_cookie: boolean
262
+
263
+ /**
264
+ * Determines whether Leanbase should disable persistence.
265
+ * If set to `true`, the library will not save any data to the browser. It will also delete any data previously saved to the browser.
266
+ *
267
+ * @default false
268
+ */
269
+ disable_persistence: boolean
270
+
271
+ /**
272
+ * Enables cookieless mode. In this mode, Leanbase will not set any cookies, or use session or local storage. User
273
+ * identity is handled by generating a privacy-preserving hash on Leanbase's servers.
274
+ * - 'always' - enable cookieless mode immediately on startup, use this if you do not intend to show a cookie banner
275
+ * - 'on_reject' - enable cookieless mode only if the user rejects cookies, use this if you want to show a cookie banner. If the user accepts cookies, cookieless mode will not be used, and PostHog will use cookies and local storage as usual.
276
+ *
277
+ * Note that you MUST enable cookieless mode in your Leanbase project's settings, otherwise all your cookieless events will be ignored. We plan to remove this requirement in the future.
278
+ * */
279
+ cookieless_mode?: 'always' | 'on_reject'
280
+
281
+ /**
282
+ * Determines whether PostHog should save referrer information.
283
+ *
284
+ * @default true
285
+ */
286
+ save_referrer: boolean
287
+
288
+ /**
289
+ * Determines whether PostHog should save marketing parameters.
290
+ * These are `utm_*` paramaters and friends.
291
+ *
292
+ * @see {CAMPAIGN_PARAMS} from './utils/event-utils' - Default campaign parameters like utm_source, utm_medium, etc.
293
+ * @default true
294
+ */
295
+ save_campaign_params: boolean
296
+
297
+ /**
298
+ * Determines whether to disable scroll properties.
299
+ * These allow you to keep track of how far down someone scrolled in your website.
300
+ *
301
+ * @default false
302
+ */
303
+ disable_scroll_properties?: boolean
304
+
305
+ /**
306
+ * Let the pageview scroll stats use a custom css selector for the root element, e.g. `main`
307
+ * It will use `window.document.documentElement` if not specified.
308
+ */
309
+ scroll_root_selector?: string | string[]
310
+
311
+ /**
312
+ * Determines if users should be opted out of user agent filtering such as googlebot or other bots.
313
+ * If this is set to `true`, PostHog will set `$browser_type` to either `bot` or `browser` for all events,
314
+ * but will process all events as if they were from a browser.
315
+ *
316
+ * @default false
317
+ */
318
+ opt_out_useragent_filter: boolean
319
+
320
+ /**
321
+ * Determines the maximum length of the properties string that can be sent with capture calls.
322
+ *
323
+ * @default 65535
324
+ */
325
+ properties_string_max_length: number
326
+
327
+ /**
328
+ * A function to be called once the Leanbase scripts have loaded successfully.
329
+ *
330
+ * @param instance - The Leanbase instance that has been loaded.
331
+ */
332
+ loaded: (instance: Leanbase) => void
333
+ }
334
+
335
+ export interface RageclickConfig {
336
+ /**
337
+ * List of CSS selectors to ignore rageclicks on
338
+ * e.g. ['.my-calendar-button']
339
+ * we consider the tree of elements from the root to the target element of the click event
340
+ * so for the tree div > div > button > svg
341
+ * and ignore list config `['[id]']`
342
+ * we will ignore the rageclick if the click-target or its parents has any id
343
+ *
344
+ * Nothing is ignored when there's an empty ignorelist, e.g. []
345
+ * If no ignorelist is set, we default to ignoring .ph-no-rageclick
346
+ * If an element has .ph-no-capture, it will always be ignored by rageclick and autocapture
347
+ */
348
+ css_selector_ignorelist?: string[]
349
+ }
350
+
351
+ export type PropertyMatchType = 'regex' | 'not_regex' | 'exact' | 'is_not' | 'icontains' | 'not_icontains'
352
+
353
+ export interface ErrorTrackingSuppressionRule {
354
+ type: 'AND' | 'OR'
355
+ values: ErrorTrackingSuppressionRuleValue[]
356
+ }
357
+
358
+ export interface ErrorTrackingSuppressionRuleValue {
359
+ key: '$exception_types' | '$exception_values'
360
+ operator: PropertyMatchType
361
+ value: string | string[]
362
+ type: string
363
+ }
364
+
365
+ export enum Compression {
366
+ GZipJS = 'gzip-js',
367
+ Base64 = 'base64',
368
+ }
369
+
370
+ export type SupportedWebVitalsMetrics = 'LCP' | 'CLS' | 'FCP' | 'INP'
371
+
372
+ export interface PerformanceCaptureConfig {
373
+ /**
374
+ * Works with session replay to use the browser's native performance observer to capture performance metrics
375
+ */
376
+ network_timing?: boolean
377
+
378
+ /**
379
+ * Use chrome's web vitals library to wrap fetch and capture web vitals
380
+ */
381
+ web_vitals?: boolean
382
+
383
+ /**
384
+ * We observe very large values reported by the Chrome web vitals library
385
+ * These outliers are likely not real, useful values, and we exclude them
386
+ * You can set this to 0 in order to include all values, NB this is not recommended
387
+ *
388
+ * @default 15 * 60 * 1000 (15 minutes)
389
+ */
390
+ __web_vitals_max_value?: number
391
+
392
+ /**
393
+ * By default all 4 metrics are captured
394
+ * You can set this config to restrict which metrics are captured
395
+ * e.g. ['CLS', 'FCP'] to only capture those two metrics
396
+ * NB setting this does not override whether the capture is enabled
397
+ *
398
+ * @default ['LCP', 'CLS', 'FCP', 'INP']
399
+ */
400
+ web_vitals_allowed_metrics?: SupportedWebVitalsMetrics[]
401
+
402
+ /**
403
+ * We delay flushing web vitals metrics to reduce the number of events we send
404
+ * This is the maximum time we will wait before sending the metrics
405
+ *
406
+ * @default 5000
407
+ */
408
+ web_vitals_delayed_flush_ms?: number
409
+ }
410
+
411
+ /**
412
+ * Remote configuration for the Leanbase instance
413
+ *
414
+ * All of these settings can be configured directly in your Leanbase instance
415
+ * Any configuration set in the client overrides the information from the server
416
+ */
417
+ export interface RemoteConfig {
418
+ /**
419
+ * Supported compression algorithms
420
+ */
421
+ supportedCompression: Compression[]
422
+
423
+ /**
424
+ * If set, disables autocapture
425
+ */
426
+ autocapture_opt_out?: boolean
427
+
428
+ /**
429
+ * originally capturePerformance was replay only and so boolean true
430
+ * is equivalent to { network_timing: true }
431
+ * now capture performance can be separately enabled within replay
432
+ * and as a standalone web vitals tracker
433
+ * people can have them enabled separately
434
+ * they work standalone but enhance each other
435
+ * TODO: deprecate this so we make a new config that doesn't need this explanation
436
+ */
437
+ capturePerformance?: boolean | PerformanceCaptureConfig
438
+
439
+ /**
440
+ * Whether we should use a custom endpoint for analytics
441
+ *
442
+ * @default { endpoint: "/e" }
443
+ */
444
+ analytics?: {
445
+ endpoint?: string
446
+ }
447
+
448
+ /**
449
+ * Whether the `$elements_chain` property should be sent as a string or as an array
450
+ *
451
+ * @default false
452
+ */
453
+ elementsChainAsString?: boolean
454
+
455
+ /**
456
+ * Error tracking configuration options
457
+ */
458
+ errorTracking?: {
459
+ autocaptureExceptions?: boolean
460
+ captureExtensionExceptions?: boolean
461
+ suppressionRules?: ErrorTrackingSuppressionRule[]
462
+ }
463
+
464
+ /**
465
+ * This is currently in development and may have breaking changes without a major version bump
466
+ */
467
+ autocaptureExceptions?: boolean | { endpoint?: string }
468
+
469
+ /**
470
+ * @deprecated, moved to toolbarParams
471
+ */
472
+ toolbarVersion: 'toolbar'
473
+
474
+ /**
475
+ * Whether the user is authenticated
476
+ */
477
+ isAuthenticated: boolean
478
+
479
+ /**
480
+ * List of site apps with their IDs and URLs
481
+ */
482
+ siteApps: { id: string; url: string }[]
483
+
484
+ /**
485
+ * Whether heatmaps are enabled
486
+ */
487
+ heatmaps?: boolean
488
+
489
+ /**
490
+ * Whether to only capture identified users by default
491
+ */
492
+ defaultIdentifiedOnly?: boolean
493
+
494
+ /**
495
+ * Whether to capture dead clicks
496
+ */
497
+ captureDeadClicks?: boolean
498
+
499
+ /**
500
+ * Indicates if the team has any flags enabled (if not we don't need to load them)
501
+ */
502
+ hasFeatureFlags?: boolean
503
+ }
504
+
505
+ /**
506
+ * These are known events Leanbase events that can be processed by the `beforeCapture` function
507
+ * That means Leanbase functionality does not rely on receiving 100% of these for calculations
508
+ * So, it is safe to sample them to reduce the volume of events sent to Leanbase
509
+ */
510
+ export type KnownEventName =
511
+ | '$heatmaps_data'
512
+ | '$opt_in'
513
+ | '$exception'
514
+ | '$$heatmap'
515
+ | '$web_vitals'
516
+ | '$dead_click'
517
+ | '$autocapture'
518
+ | typeof COPY_AUTOCAPTURE_EVENT
519
+ | '$rageclick'
520
+
521
+ export type EventName = KnownUnsafeEditableEvent | KnownEventName | (string & {})
522
+
523
+ export interface PersistentStore {
524
+ _is_supported: () => boolean
525
+ _error: (error: any) => void
526
+ _parse: (name: string) => any
527
+ _get: (name: string) => any
528
+ _set: (
529
+ name: string,
530
+ value: any,
531
+ expire_days?: number | null,
532
+ cross_subdomain?: boolean,
533
+ secure?: boolean,
534
+ debug?: boolean
535
+ ) => void
536
+ _remove: (name: string, cross_subdomain?: boolean) => void
537
+ }
538
+
539
+ export interface RequestResponse {
540
+ statusCode: number
541
+ text?: string
542
+ json?: any
543
+ }
544
+
545
+ export type RequestCallback = (response: RequestResponse) => void
546
+
547
+ // See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options
548
+ type NextOptions = { revalidate: false | 0 | number; tags: string[] }
549
+
550
+ export interface RequestWithOptions {
551
+ url: string
552
+ data?: Record<string, any> | Record<string, any>[]
553
+ headers?: Record<string, any>
554
+ transport?: 'XHR' | 'fetch' | 'sendBeacon'
555
+ method?: 'POST' | 'GET'
556
+ urlQueryArgs?: { compression: Compression }
557
+ callback?: RequestCallback
558
+ timeout?: number
559
+ noRetries?: boolean
560
+ disableTransport?: ('XHR' | 'fetch' | 'sendBeacon')[]
561
+ disableXHRCredentials?: boolean
562
+ compression?: Compression | 'best-available'
563
+ fetchOptions?: {
564
+ cache?: RequestInit['cache']
565
+ next?: NextOptions
566
+ }
567
+ }
568
+
569
+ export type SessionIdChangedCallback = (
570
+ sessionId: string,
571
+ windowId: string | null | undefined,
572
+ changeReason?: { noSessionId: boolean; activityTimeout: boolean; sessionPastMaximumLength: boolean }
573
+ ) => void
574
+
575
+ export type LeanbasegCaptureOptions = {
576
+ /** If provided overrides the auto-generated event ID */
577
+ uuid?: string
578
+ disableGeoip?: boolean
579
+ /**
580
+ * Used when `$identify` is called
581
+ * Will set person properties overriding previous values
582
+ */
583
+ $set?: Properties
584
+
585
+ /**
586
+ * Used when `$identify` is called
587
+ * Will set person properties but only once, it will NOT override previous values
588
+ */
589
+ $set_once?: Properties
590
+
591
+ /**
592
+ * Used to override the desired endpoint for the captured event
593
+ */
594
+ _url?: string
595
+
596
+ /**
597
+ * key of queue, e.g. 'sessionRecording' vs 'event'
598
+ */
599
+ _batchKey?: string
600
+
601
+ /**
602
+ * If set, overrides and disables config.properties_string_max_length
603
+ */
604
+ _noTruncate?: boolean
605
+
606
+ /**
607
+ * If set, skips the batched queue
608
+ */
609
+ send_instantly?: boolean
610
+
611
+ /**
612
+ * If set, skips the client side rate limiting
613
+ */
614
+ skip_client_rate_limiting?: boolean
615
+
616
+ /**
617
+ * If set, overrides the desired transport method
618
+ */
619
+ transport?: RequestWithOptions['transport']
620
+
621
+ /**
622
+ * If set, overrides the current timestamp
623
+ */
624
+ timestamp?: Date
625
+ }
626
+
627
+ export interface CaptureResult {
628
+ uuid: string
629
+ event: EventName
630
+ properties: Properties
631
+ $set?: Properties
632
+ $set_once?: Properties
633
+ timestamp?: Date
634
+ }