@outlit/core 1.4.3 → 1.4.5

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/dist/index.d.mts CHANGED
@@ -18,29 +18,36 @@ interface BrowserTrackOptions {
18
18
  eventName: string;
19
19
  properties?: Record<string, string | number | boolean | null>;
20
20
  }
21
- interface BrowserIdentifyOptions {
21
+ interface BrowserIdentifyOptions extends CustomerAttribution {
22
22
  email?: string;
23
+ /** Your system-owned user/contact ID. */
23
24
  userId?: string;
25
+ /** User/contact traits. */
24
26
  traits?: IdentifyTraits;
27
+ /** Customer/account-level traits. */
28
+ customerTraits?: CustomerTraits;
25
29
  }
26
30
  /**
27
- * Server identity - requires at least one of fingerprint, email, or userId.
28
- * This is validated at runtime to avoid complex union types that
29
- * cause TypeScript memory issues during type checking.
31
+ * Base server-side user identity.
32
+ * Track calls may use customerId/customerDomain without these fields.
33
+ * Identify calls still require email or userId at runtime.
30
34
  *
31
35
  * - fingerprint: Device identifier for anonymous tracking (can be linked later)
32
36
  * - email: User's email address (definitive identity, resolves immediately)
33
- * - userId: App's internal user ID
37
+ * - userId: Your system-owned user/contact ID
34
38
  */
35
39
  interface ServerIdentity {
36
40
  fingerprint?: string;
37
41
  email?: string;
42
+ /** Your system-owned user/contact ID. */
38
43
  userId?: string;
39
44
  }
40
- /**
41
- * Customer-level traits that can be nested under `customer` in identify.
42
- * These are applied to the customer/account, not the individual user.
43
- */
45
+ interface CustomerAttribution {
46
+ /** Your system-owned customer/account/workspace ID. */
47
+ customerId?: string;
48
+ /** Public customer/account domain used for billing and attribution. */
49
+ customerDomain?: string;
50
+ }
44
51
  interface CustomerTraits {
45
52
  /** Customer's billing plan */
46
53
  plan?: string;
@@ -48,33 +55,36 @@ interface CustomerTraits {
48
55
  [key: string]: string | number | boolean | null | undefined;
49
56
  }
50
57
  /**
51
- * Traits for identify calls, supporting both user-level
52
- * and nested customer-level properties.
58
+ * Traits for identify calls.
59
+ * These are user/contact traits, not customer/account traits.
53
60
  */
54
61
  interface IdentifyTraits {
55
- /** Nested customer/account-level traits */
56
- customer?: CustomerTraits;
57
62
  /** User-level traits */
58
- [key: string]: string | number | boolean | null | CustomerTraits | undefined;
63
+ [key: string]: string | number | boolean | null | undefined;
59
64
  }
60
- interface ServerTrackOptions extends ServerIdentity {
65
+ interface ServerTrackOptions extends ServerIdentity, CustomerAttribution {
61
66
  eventName: string;
62
67
  properties?: Record<string, string | number | boolean | null>;
63
68
  timestamp?: number;
64
69
  }
65
- interface ServerIdentifyOptions extends ServerIdentity {
70
+ interface ServerIdentifyOptions extends ServerIdentity, CustomerAttribution {
66
71
  traits?: IdentifyTraits;
72
+ customerTraits?: CustomerTraits;
67
73
  }
68
74
  /**
69
75
  * Customer identity for SDK billing methods.
70
- * Domain is required as the primary identifier; additional identifiers are optional.
76
+ * Public billing calls should use `customerId` and/or `customerDomain`.
71
77
  */
72
- interface CustomerIdentifier {
73
- /** Required: The customer's domain (e.g., "acme.com") */
74
- domain: string;
75
- /** Optional: Your internal customer ID */
76
- customerId?: string;
77
- /** Optional: Stripe customer ID (e.g., "cus_xxx") */
78
+ interface CustomerIdentifier extends CustomerAttribution {
79
+ /**
80
+ * @deprecated Use `customerDomain` instead.
81
+ * Legacy alias kept for backward compatibility.
82
+ */
83
+ domain?: string;
84
+ /**
85
+ * @deprecated Stripe customer identifier.
86
+ * Billing attribution should use `customerId` and/or `customerDomain` publicly.
87
+ */
78
88
  stripeCustomerId?: string;
79
89
  }
80
90
  interface BaseEvent {
@@ -99,11 +109,19 @@ interface IdentifyEvent extends BaseEvent {
99
109
  email?: string;
100
110
  userId?: string;
101
111
  fingerprint?: string;
112
+ customerId?: string;
113
+ customerDomain?: string;
114
+ customerTraits?: CustomerTraits;
102
115
  traits?: IdentifyTraits;
103
116
  }
104
117
  interface CustomEvent extends BaseEvent {
105
118
  type: "custom";
106
119
  eventName: string;
120
+ email?: string;
121
+ userId?: string;
122
+ fingerprint?: string;
123
+ customerId?: string;
124
+ customerDomain?: string;
107
125
  properties?: Record<string, string | number | boolean | null>;
108
126
  }
109
127
  interface CalendarEvent extends BaseEvent {
@@ -140,8 +158,10 @@ interface BillingEvent extends BaseEvent {
140
158
  status: BillingStatus;
141
159
  /** Optional customer identifiers */
142
160
  customerId?: string;
143
- stripeCustomerId?: string;
161
+ customerDomain?: string;
162
+ /** @deprecated Legacy alias for `customerDomain`. */
144
163
  domain?: string;
164
+ stripeCustomerId?: string;
145
165
  /** Optional properties for context */
146
166
  properties?: Record<string, string | number | boolean | null>;
147
167
  }
@@ -149,10 +169,37 @@ type TrackerEvent = PageviewEvent | FormEvent | IdentifyEvent | CustomEvent | Ca
149
169
  /**
150
170
  * User identity for payload-level resolution.
151
171
  * Used by browser SDK when user is logged in (via setUser).
172
+ * Customer attribution is carried separately in `customerIdentity`.
152
173
  */
153
174
  interface PayloadUserIdentity {
154
175
  email?: string;
176
+ /** Your system-owned user/contact ID. */
155
177
  userId?: string;
178
+ /** User/contact traits. */
179
+ traits?: IdentifyTraits;
180
+ /**
181
+ * @deprecated Use payload-level `customerIdentity.customerId` instead.
182
+ * Kept for one compatibility window while callers migrate.
183
+ */
184
+ customerId?: string;
185
+ /**
186
+ * @deprecated Use payload-level `customerIdentity.customerDomain` instead.
187
+ * Kept for one compatibility window while callers migrate.
188
+ */
189
+ customerDomain?: string;
190
+ /**
191
+ * @deprecated Use payload-level `customerIdentity.customerTraits` instead.
192
+ * Kept for one compatibility window while callers migrate.
193
+ */
194
+ customerTraits?: CustomerTraits;
195
+ }
196
+ /**
197
+ * Customer identity for payload-level attribution.
198
+ * Used by browser SDK to attach account/workspace context to a batch.
199
+ */
200
+ interface PayloadCustomerIdentity extends CustomerAttribution {
201
+ /** Customer/account traits. */
202
+ customerTraits?: CustomerTraits;
156
203
  }
157
204
  interface IngestPayload {
158
205
  visitorId?: string;
@@ -180,6 +227,12 @@ interface IngestPayload {
180
227
  * allowing immediate identity resolution for SPA/React apps.
181
228
  */
182
229
  userIdentity?: PayloadUserIdentity;
230
+ /**
231
+ * Customer/account identity for this batch of events.
232
+ * Used to attribute browser batches to a customer/workspace even when
233
+ * the customer fields are not present on every event.
234
+ */
235
+ customerIdentity?: PayloadCustomerIdentity;
183
236
  }
184
237
  interface IngestResponse {
185
238
  success: boolean;
@@ -193,88 +246,6 @@ declare const DEFAULT_API_HOST = "https://app.outlit.ai";
193
246
 
194
247
  declare const DEFAULT_DENIED_FORM_FIELDS: string[];
195
248
 
196
- /**
197
- * Extract UTM parameters from a URL.
198
- */
199
- declare function extractUtmParams(url: string): UtmParams | undefined;
200
- /**
201
- * Extract path from a URL.
202
- */
203
- declare function extractPathFromUrl(url: string): string;
204
- /**
205
- * Check if a field name should be denied (case-insensitive).
206
- */
207
- declare function isFieldDenied(fieldName: string, denylist: string[]): boolean;
208
- /**
209
- * Sanitize form fields by removing sensitive data.
210
- * Returns a new object with denied fields removed.
211
- */
212
- declare function sanitizeFormFields(fields: Record<string, string> | undefined, customDenylist?: string[]): Record<string, string> | undefined;
213
- /**
214
- * Validate that at least one identity field is provided.
215
- * Used by the server SDK to enforce identity requirements.
216
- *
217
- * Valid identities:
218
- * - fingerprint: Device identifier (for anonymous tracking, can be linked later)
219
- * - email: User's email (definitive identity)
220
- * - userId: App's internal user ID
221
- */
222
- declare function validateServerIdentity(fingerprint?: string, email?: string, userId?: string): void;
223
- /**
224
- * Validate that a string looks like a valid email address.
225
- */
226
- declare function isValidEmail(value: string): boolean;
227
- /**
228
- * Find an email value from form fields.
229
- *
230
- * Priority:
231
- * 1. Fields with input type="email" (if inputTypes map provided)
232
- * 2. Field names matching email patterns
233
- * 3. Any field with a value that looks like an email
234
- *
235
- * @param fields - Form field key-value pairs
236
- * @param inputTypes - Optional map of field names to input types
237
- * @returns The email value if found, undefined otherwise
238
- */
239
- declare function findEmailField(fields: Record<string, string>, inputTypes?: Map<string, string>): string | undefined;
240
- /**
241
- * Extract name fields from form data.
242
- *
243
- * Looks for:
244
- * - Full name fields (name, full_name, etc.)
245
- * - First name fields (first_name, fname, etc.)
246
- * - Last name fields (last_name, lname, etc.)
247
- *
248
- * If only first/last names are found, combines them into a full name.
249
- *
250
- * @param fields - Form field key-value pairs
251
- * @returns Object with name, firstName, and/or lastName if found
252
- */
253
- declare function findNameFields(fields: Record<string, string>): {
254
- name?: string;
255
- firstName?: string;
256
- lastName?: string;
257
- };
258
- /**
259
- * Identity extracted from a form submission.
260
- */
261
- interface ExtractedIdentity {
262
- email: string;
263
- name?: string;
264
- firstName?: string;
265
- lastName?: string;
266
- }
267
- /**
268
- * Extract identity information (email + name) from form fields.
269
- *
270
- * Returns undefined if no valid email is found (email is required for identification).
271
- *
272
- * @param fields - Form field key-value pairs
273
- * @param inputTypes - Optional map of field names to input types
274
- * @returns Extracted identity with email and optional name fields, or undefined
275
- */
276
- declare function extractIdentityFromForm(fields: Record<string, string>, inputTypes?: Map<string, string>): ExtractedIdentity | undefined;
277
-
278
249
  interface BaseEventParams {
279
250
  url: string;
280
251
  referrer?: string;
@@ -301,6 +272,9 @@ declare function buildIdentifyEvent(params: BaseEventParams & {
301
272
  userId?: string;
302
273
  fingerprint?: string;
303
274
  traits?: IdentifyTraits;
275
+ customerId?: string;
276
+ customerDomain?: string;
277
+ customerTraits?: CustomerTraits;
304
278
  }): IdentifyEvent;
305
279
  /**
306
280
  * Build a custom event.
@@ -308,6 +282,11 @@ declare function buildIdentifyEvent(params: BaseEventParams & {
308
282
  declare function buildCustomEvent(params: BaseEventParams & {
309
283
  eventName: string;
310
284
  properties?: Record<string, string | number | boolean | null>;
285
+ email?: string;
286
+ userId?: string;
287
+ fingerprint?: string;
288
+ customerId?: string;
289
+ customerDomain?: string;
311
290
  }): CustomEvent;
312
291
  /**
313
292
  * Build a calendar booking event.
@@ -347,6 +326,7 @@ declare function buildStageEvent(params: BaseEventParams & {
347
326
  declare function buildBillingEvent(params: BaseEventParams & {
348
327
  status: BillingStatus;
349
328
  customerId?: string;
329
+ customerDomain?: string;
350
330
  stripeCustomerId?: string;
351
331
  domain?: string;
352
332
  properties?: Record<string, string | number | boolean | null>;
@@ -360,8 +340,9 @@ declare function buildBillingEvent(params: BaseEventParams & {
360
340
  * @param userIdentity - Optional user identity for immediate resolution (from setUser in SPA)
361
341
  * @param sessionId - Optional session ID for grouping events (browser SDK only)
362
342
  * @param fingerprint - Optional device identifier for server-side anonymous tracking
343
+ * @param customerIdentity - Optional customer identity for batch attribution
363
344
  */
364
- declare function buildIngestPayload(visitorId: string, source: SourceType, events: TrackerEvent[], userIdentity?: PayloadUserIdentity, sessionId?: string, fingerprint?: string): IngestPayload;
345
+ declare function buildIngestPayload(visitorId: string, source: SourceType, events: TrackerEvent[], userIdentity?: PayloadUserIdentity, sessionId?: string, fingerprint?: string, customerIdentity?: PayloadCustomerIdentity): IngestPayload;
365
346
  /**
366
347
  * Maximum number of events in a single batch.
367
348
  */
@@ -371,4 +352,92 @@ declare const MAX_BATCH_SIZE = 100;
371
352
  */
372
353
  declare function batchEvents(events: TrackerEvent[]): TrackerEvent[][];
373
354
 
374
- export { type BillingEvent, type BillingStatus, type BrowserIdentifyOptions, type BrowserTrackOptions, type CalendarEvent, type CalendarProvider, type CustomEvent, type CustomerIdentifier, type CustomerTraits, DEFAULT_API_HOST, DEFAULT_DENIED_FORM_FIELDS, type EngagementEvent, type EventType, type ExplicitJourneyStage, type ExtractedIdentity, type FormEvent, type IdentifyEvent, type IdentifyTraits, type IngestPayload, type IngestResponse, MAX_BATCH_SIZE, type PageviewEvent, type PayloadUserIdentity, type ServerIdentifyOptions, type ServerIdentity, type ServerTrackOptions, type SourceType, type StageEvent, type TrackerConfig, type TrackerEvent, type UtmParams, batchEvents, buildBillingEvent, buildCalendarEvent, buildCustomEvent, buildEngagementEvent, buildFormEvent, buildIdentifyEvent, buildIngestPayload, buildPageviewEvent, buildStageEvent, extractIdentityFromForm, extractPathFromUrl, extractUtmParams, findEmailField, findNameFields, isFieldDenied, isValidEmail, sanitizeFormFields, validateServerIdentity };
355
+ /**
356
+ * Extract UTM parameters from a URL.
357
+ */
358
+ declare function extractUtmParams(url: string): UtmParams | undefined;
359
+ /**
360
+ * Extract path from a URL.
361
+ */
362
+ declare function extractPathFromUrl(url: string): string;
363
+ /**
364
+ * Check if a field name should be denied (case-insensitive).
365
+ */
366
+ declare function isFieldDenied(fieldName: string, denylist: string[]): boolean;
367
+ /**
368
+ * Sanitize form fields by removing sensitive data.
369
+ * Returns a new object with denied fields removed.
370
+ */
371
+ declare function sanitizeFormFields(fields: Record<string, string> | undefined, customDenylist?: string[]): Record<string, string> | undefined;
372
+ /**
373
+ * Validate that at least one identity field is provided.
374
+ * Used by the server SDK to enforce identity requirements.
375
+ *
376
+ * Valid identities:
377
+ * - fingerprint: Device identifier (for anonymous tracking, can be linked later)
378
+ * - email: User's email (definitive identity)
379
+ * - userId: Your system-owned user/contact ID
380
+ * - customerId: Your system-owned customer/account/workspace ID
381
+ * - customerDomain: Public customer/account domain used for billing and attribution
382
+ */
383
+ declare function validateServerIdentity(fingerprint?: string, email?: string, userId?: string, customerId?: string, customerDomain?: string): void;
384
+ /**
385
+ * Validate that at least one customer identifier is provided for billing calls.
386
+ */
387
+ declare function validateCustomerIdentity(customerId?: string, customerDomain?: string, domain?: string, stripeCustomerId?: string): void;
388
+ /**
389
+ * Validate that a string looks like a valid email address.
390
+ */
391
+ declare function isValidEmail(value: string): boolean;
392
+ /**
393
+ * Find an email value from form fields.
394
+ *
395
+ * Priority:
396
+ * 1. Fields with input type="email" (if inputTypes map provided)
397
+ * 2. Field names matching email patterns
398
+ * 3. Any field with a value that looks like an email
399
+ *
400
+ * @param fields - Form field key-value pairs
401
+ * @param inputTypes - Optional map of field names to input types
402
+ * @returns The email value if found, undefined otherwise
403
+ */
404
+ declare function findEmailField(fields: Record<string, string>, inputTypes?: Map<string, string>): string | undefined;
405
+ /**
406
+ * Extract name fields from form data.
407
+ *
408
+ * Looks for:
409
+ * - Full name fields (name, full_name, etc.)
410
+ * - First name fields (first_name, fname, etc.)
411
+ * - Last name fields (last_name, lname, etc.)
412
+ *
413
+ * If only first/last names are found, combines them into a full name.
414
+ *
415
+ * @param fields - Form field key-value pairs
416
+ * @returns Object with name, firstName, and/or lastName if found
417
+ */
418
+ declare function findNameFields(fields: Record<string, string>): {
419
+ name?: string;
420
+ firstName?: string;
421
+ lastName?: string;
422
+ };
423
+ /**
424
+ * Identity extracted from a form submission.
425
+ */
426
+ interface ExtractedIdentity {
427
+ email: string;
428
+ name?: string;
429
+ firstName?: string;
430
+ lastName?: string;
431
+ }
432
+ /**
433
+ * Extract identity information (email + name) from form fields.
434
+ *
435
+ * Returns undefined if no valid email is found (email is required for identification).
436
+ *
437
+ * @param fields - Form field key-value pairs
438
+ * @param inputTypes - Optional map of field names to input types
439
+ * @returns Extracted identity with email and optional name fields, or undefined
440
+ */
441
+ declare function extractIdentityFromForm(fields: Record<string, string>, inputTypes?: Map<string, string>): ExtractedIdentity | undefined;
442
+
443
+ export { type BillingEvent, type BillingStatus, type BrowserIdentifyOptions, type BrowserTrackOptions, type CalendarEvent, type CalendarProvider, type CustomEvent, type CustomerAttribution, type CustomerIdentifier, type CustomerTraits, DEFAULT_API_HOST, DEFAULT_DENIED_FORM_FIELDS, type EngagementEvent, type EventType, type ExplicitJourneyStage, type ExtractedIdentity, type FormEvent, type IdentifyEvent, type IdentifyTraits, type IngestPayload, type IngestResponse, MAX_BATCH_SIZE, type PageviewEvent, type PayloadCustomerIdentity, type PayloadUserIdentity, type ServerIdentifyOptions, type ServerIdentity, type ServerTrackOptions, type SourceType, type StageEvent, type TrackerConfig, type TrackerEvent, type UtmParams, batchEvents, buildBillingEvent, buildCalendarEvent, buildCustomEvent, buildEngagementEvent, buildFormEvent, buildIdentifyEvent, buildIngestPayload, buildPageviewEvent, buildStageEvent, extractIdentityFromForm, extractPathFromUrl, extractUtmParams, findEmailField, findNameFields, isFieldDenied, isValidEmail, sanitizeFormFields, validateCustomerIdentity, validateServerIdentity };