@databuddy/sdk 2.3.28 → 2.3.29
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/node/index.d.mts +33 -5
- package/dist/node/index.d.ts +33 -5
- package/dist/node/index.mjs +57 -36
- package/package.json +1 -1
package/dist/node/index.d.mts
CHANGED
|
@@ -13,8 +13,14 @@ interface Logger {
|
|
|
13
13
|
*/
|
|
14
14
|
type Middleware = (event: BatchEventInput) => BatchEventInput | null | Promise<BatchEventInput | null>;
|
|
15
15
|
interface DatabuddyConfig {
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/** API key for authentication (dbdy_xxx) */
|
|
17
|
+
apiKey: string;
|
|
18
|
+
/** Optional default website ID to scope events to */
|
|
19
|
+
websiteId?: string;
|
|
20
|
+
/** Optional default namespace for logical grouping (e.g., 'billing', 'auth', 'api') */
|
|
21
|
+
namespace?: string;
|
|
22
|
+
/** Optional default source identifier for events (e.g., 'backend', 'webhook', 'cli') */
|
|
23
|
+
source?: string;
|
|
18
24
|
/** Custom API endpoint (default: https://basket.databuddy.cc) */
|
|
19
25
|
apiUrl?: string;
|
|
20
26
|
/** Enable debug logging */
|
|
@@ -49,6 +55,12 @@ interface CustomEventInput {
|
|
|
49
55
|
timestamp?: number | null;
|
|
50
56
|
/** Event properties/metadata */
|
|
51
57
|
properties?: Record<string, unknown> | null;
|
|
58
|
+
/** Website ID to scope the event to (overrides default) */
|
|
59
|
+
websiteId?: string | null;
|
|
60
|
+
/** Namespace for logical grouping (overrides default) */
|
|
61
|
+
namespace?: string | null;
|
|
62
|
+
/** Source identifier (overrides default) */
|
|
63
|
+
source?: string | null;
|
|
52
64
|
}
|
|
53
65
|
interface EventResponse {
|
|
54
66
|
/** Whether the event was successfully sent */
|
|
@@ -73,6 +85,12 @@ interface BatchEventInput {
|
|
|
73
85
|
timestamp?: number | null;
|
|
74
86
|
/** Event properties/metadata */
|
|
75
87
|
properties?: Record<string, unknown> | null;
|
|
88
|
+
/** Website ID to scope the event to */
|
|
89
|
+
websiteId?: string | null;
|
|
90
|
+
/** Namespace for logical grouping */
|
|
91
|
+
namespace?: string | null;
|
|
92
|
+
/** Source identifier */
|
|
93
|
+
source?: string | null;
|
|
76
94
|
}
|
|
77
95
|
/**
|
|
78
96
|
* Global properties that will be attached to all events
|
|
@@ -207,7 +225,10 @@ declare function createServerFlagsManagerInMemory(config: FlagsConfig): ServerFl
|
|
|
207
225
|
/** biome-ignore-all lint/performance/noBarrelFile: im a big fan of barrels */
|
|
208
226
|
|
|
209
227
|
declare class Databuddy {
|
|
210
|
-
private readonly
|
|
228
|
+
private readonly apiKey;
|
|
229
|
+
private readonly websiteId?;
|
|
230
|
+
private readonly namespace?;
|
|
231
|
+
private readonly source?;
|
|
211
232
|
private readonly apiUrl;
|
|
212
233
|
private readonly logger;
|
|
213
234
|
private readonly enableBatching;
|
|
@@ -231,13 +252,20 @@ declare class Databuddy {
|
|
|
231
252
|
* name: 'user_signup',
|
|
232
253
|
* properties: { plan: 'pro', source: 'web' }
|
|
233
254
|
* });
|
|
255
|
+
*
|
|
256
|
+
* // With website scope
|
|
257
|
+
* await client.track({
|
|
258
|
+
* name: 'page_view',
|
|
259
|
+
* websiteId: 'website-uuid',
|
|
260
|
+
* properties: { path: '/pricing' }
|
|
261
|
+
* });
|
|
234
262
|
* ```
|
|
235
263
|
*/
|
|
236
264
|
track(event: CustomEventInput): Promise<EventResponse>;
|
|
237
265
|
/**
|
|
238
|
-
* Convert BatchEventInput to
|
|
266
|
+
* Convert BatchEventInput to format expected by /track endpoint
|
|
239
267
|
*/
|
|
240
|
-
private
|
|
268
|
+
private toTrackPayload;
|
|
241
269
|
private send;
|
|
242
270
|
private scheduleFlush;
|
|
243
271
|
/**
|
package/dist/node/index.d.ts
CHANGED
|
@@ -13,8 +13,14 @@ interface Logger {
|
|
|
13
13
|
*/
|
|
14
14
|
type Middleware = (event: BatchEventInput) => BatchEventInput | null | Promise<BatchEventInput | null>;
|
|
15
15
|
interface DatabuddyConfig {
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/** API key for authentication (dbdy_xxx) */
|
|
17
|
+
apiKey: string;
|
|
18
|
+
/** Optional default website ID to scope events to */
|
|
19
|
+
websiteId?: string;
|
|
20
|
+
/** Optional default namespace for logical grouping (e.g., 'billing', 'auth', 'api') */
|
|
21
|
+
namespace?: string;
|
|
22
|
+
/** Optional default source identifier for events (e.g., 'backend', 'webhook', 'cli') */
|
|
23
|
+
source?: string;
|
|
18
24
|
/** Custom API endpoint (default: https://basket.databuddy.cc) */
|
|
19
25
|
apiUrl?: string;
|
|
20
26
|
/** Enable debug logging */
|
|
@@ -49,6 +55,12 @@ interface CustomEventInput {
|
|
|
49
55
|
timestamp?: number | null;
|
|
50
56
|
/** Event properties/metadata */
|
|
51
57
|
properties?: Record<string, unknown> | null;
|
|
58
|
+
/** Website ID to scope the event to (overrides default) */
|
|
59
|
+
websiteId?: string | null;
|
|
60
|
+
/** Namespace for logical grouping (overrides default) */
|
|
61
|
+
namespace?: string | null;
|
|
62
|
+
/** Source identifier (overrides default) */
|
|
63
|
+
source?: string | null;
|
|
52
64
|
}
|
|
53
65
|
interface EventResponse {
|
|
54
66
|
/** Whether the event was successfully sent */
|
|
@@ -73,6 +85,12 @@ interface BatchEventInput {
|
|
|
73
85
|
timestamp?: number | null;
|
|
74
86
|
/** Event properties/metadata */
|
|
75
87
|
properties?: Record<string, unknown> | null;
|
|
88
|
+
/** Website ID to scope the event to */
|
|
89
|
+
websiteId?: string | null;
|
|
90
|
+
/** Namespace for logical grouping */
|
|
91
|
+
namespace?: string | null;
|
|
92
|
+
/** Source identifier */
|
|
93
|
+
source?: string | null;
|
|
76
94
|
}
|
|
77
95
|
/**
|
|
78
96
|
* Global properties that will be attached to all events
|
|
@@ -207,7 +225,10 @@ declare function createServerFlagsManagerInMemory(config: FlagsConfig): ServerFl
|
|
|
207
225
|
/** biome-ignore-all lint/performance/noBarrelFile: im a big fan of barrels */
|
|
208
226
|
|
|
209
227
|
declare class Databuddy {
|
|
210
|
-
private readonly
|
|
228
|
+
private readonly apiKey;
|
|
229
|
+
private readonly websiteId?;
|
|
230
|
+
private readonly namespace?;
|
|
231
|
+
private readonly source?;
|
|
211
232
|
private readonly apiUrl;
|
|
212
233
|
private readonly logger;
|
|
213
234
|
private readonly enableBatching;
|
|
@@ -231,13 +252,20 @@ declare class Databuddy {
|
|
|
231
252
|
* name: 'user_signup',
|
|
232
253
|
* properties: { plan: 'pro', source: 'web' }
|
|
233
254
|
* });
|
|
255
|
+
*
|
|
256
|
+
* // With website scope
|
|
257
|
+
* await client.track({
|
|
258
|
+
* name: 'page_view',
|
|
259
|
+
* websiteId: 'website-uuid',
|
|
260
|
+
* properties: { path: '/pricing' }
|
|
261
|
+
* });
|
|
234
262
|
* ```
|
|
235
263
|
*/
|
|
236
264
|
track(event: CustomEventInput): Promise<EventResponse>;
|
|
237
265
|
/**
|
|
238
|
-
* Convert BatchEventInput to
|
|
266
|
+
* Convert BatchEventInput to format expected by /track endpoint
|
|
239
267
|
*/
|
|
240
|
-
private
|
|
268
|
+
private toTrackPayload;
|
|
241
269
|
private send;
|
|
242
270
|
private scheduleFlush;
|
|
243
271
|
/**
|
package/dist/node/index.mjs
CHANGED
|
@@ -320,7 +320,10 @@ const DEFAULT_BATCH_TIMEOUT = 2e3;
|
|
|
320
320
|
const DEFAULT_MAX_QUEUE_SIZE = 1e3;
|
|
321
321
|
const DEFAULT_MAX_DEDUPLICATION_CACHE_SIZE = 1e4;
|
|
322
322
|
class Databuddy {
|
|
323
|
-
|
|
323
|
+
apiKey;
|
|
324
|
+
websiteId;
|
|
325
|
+
namespace;
|
|
326
|
+
source;
|
|
324
327
|
apiUrl;
|
|
325
328
|
logger;
|
|
326
329
|
enableBatching;
|
|
@@ -334,10 +337,13 @@ class Databuddy {
|
|
|
334
337
|
deduplicationCache = /* @__PURE__ */ new Set();
|
|
335
338
|
maxDeduplicationCacheSize;
|
|
336
339
|
constructor(config) {
|
|
337
|
-
if (!config.
|
|
338
|
-
throw new Error("
|
|
340
|
+
if (!config.apiKey || typeof config.apiKey !== "string") {
|
|
341
|
+
throw new Error("apiKey is required and must be a string");
|
|
339
342
|
}
|
|
340
|
-
this.
|
|
343
|
+
this.apiKey = config.apiKey.trim();
|
|
344
|
+
this.websiteId = config.websiteId?.trim();
|
|
345
|
+
this.namespace = config.namespace?.trim();
|
|
346
|
+
this.source = config.source?.trim();
|
|
341
347
|
this.apiUrl = config.apiUrl?.trim() || DEFAULT_API_URL;
|
|
342
348
|
this.enableBatching = config.enableBatching !== false;
|
|
343
349
|
this.batchSize = Math.min(config.batchSize || DEFAULT_BATCH_SIZE, 100);
|
|
@@ -354,7 +360,10 @@ class Databuddy {
|
|
|
354
360
|
this.logger = createNoopLogger();
|
|
355
361
|
}
|
|
356
362
|
this.logger.info("Initialized", {
|
|
357
|
-
|
|
363
|
+
hasApiKey: true,
|
|
364
|
+
websiteId: this.websiteId,
|
|
365
|
+
namespace: this.namespace,
|
|
366
|
+
source: this.source,
|
|
358
367
|
apiUrl: this.apiUrl,
|
|
359
368
|
enableBatching: this.enableBatching,
|
|
360
369
|
batchSize: this.batchSize,
|
|
@@ -373,6 +382,13 @@ class Databuddy {
|
|
|
373
382
|
* name: 'user_signup',
|
|
374
383
|
* properties: { plan: 'pro', source: 'web' }
|
|
375
384
|
* });
|
|
385
|
+
*
|
|
386
|
+
* // With website scope
|
|
387
|
+
* await client.track({
|
|
388
|
+
* name: 'page_view',
|
|
389
|
+
* websiteId: 'website-uuid',
|
|
390
|
+
* properties: { path: '/pricing' }
|
|
391
|
+
* });
|
|
376
392
|
* ```
|
|
377
393
|
*/
|
|
378
394
|
async track(event) {
|
|
@@ -392,7 +408,10 @@ class Databuddy {
|
|
|
392
408
|
properties: {
|
|
393
409
|
...this.globalProperties,
|
|
394
410
|
...event.properties || {}
|
|
395
|
-
}
|
|
411
|
+
},
|
|
412
|
+
websiteId: event.websiteId ?? this.websiteId,
|
|
413
|
+
namespace: event.namespace ?? this.namespace,
|
|
414
|
+
source: event.source ?? this.source
|
|
396
415
|
};
|
|
397
416
|
const processedEvent = await this.applyMiddleware(batchEvent);
|
|
398
417
|
if (!processedEvent) {
|
|
@@ -420,34 +439,38 @@ class Databuddy {
|
|
|
420
439
|
return { success: true };
|
|
421
440
|
}
|
|
422
441
|
/**
|
|
423
|
-
* Convert BatchEventInput to
|
|
442
|
+
* Convert BatchEventInput to format expected by /track endpoint
|
|
424
443
|
*/
|
|
425
|
-
|
|
444
|
+
toTrackPayload(event) {
|
|
426
445
|
const timestamp = event.timestamp ? Math.floor(event.timestamp) : Date.now();
|
|
427
446
|
return {
|
|
447
|
+
name: event.name,
|
|
448
|
+
namespace: event.namespace ?? void 0,
|
|
428
449
|
timestamp,
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
450
|
+
properties: event.properties ?? void 0,
|
|
451
|
+
anonymousId: event.anonymousId ?? void 0,
|
|
452
|
+
sessionId: event.sessionId ?? void 0,
|
|
453
|
+
websiteId: event.websiteId ?? void 0,
|
|
454
|
+
source: event.source ?? void 0
|
|
434
455
|
};
|
|
435
456
|
}
|
|
436
457
|
async send(event) {
|
|
437
458
|
try {
|
|
438
|
-
const url = `${this.apiUrl}/
|
|
439
|
-
const
|
|
459
|
+
const url = `${this.apiUrl}/track`;
|
|
460
|
+
const payload = this.toTrackPayload(event);
|
|
440
461
|
this.logger.info("\u{1F4E4} SENDING SINGLE EVENT:", {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
462
|
+
name: payload.name,
|
|
463
|
+
websiteId: payload.websiteId,
|
|
464
|
+
source: payload.source,
|
|
465
|
+
properties: JSON.stringify(payload.properties, null, 2)
|
|
444
466
|
});
|
|
445
467
|
const response = await fetch(url, {
|
|
446
468
|
method: "POST",
|
|
447
469
|
headers: {
|
|
448
|
-
"Content-Type": "application/json"
|
|
470
|
+
"Content-Type": "application/json",
|
|
471
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
449
472
|
},
|
|
450
|
-
body: JSON.stringify(
|
|
473
|
+
body: JSON.stringify(payload)
|
|
451
474
|
});
|
|
452
475
|
if (!response.ok) {
|
|
453
476
|
const errorText = await response.text().catch(() => "Unknown error");
|
|
@@ -566,7 +589,10 @@ class Databuddy {
|
|
|
566
589
|
properties: {
|
|
567
590
|
...this.globalProperties,
|
|
568
591
|
...event.properties || {}
|
|
569
|
-
}
|
|
592
|
+
},
|
|
593
|
+
websiteId: event.websiteId ?? this.websiteId,
|
|
594
|
+
namespace: event.namespace ?? this.namespace,
|
|
595
|
+
source: event.source ?? this.source
|
|
570
596
|
}));
|
|
571
597
|
const processedEvents = [];
|
|
572
598
|
for (const event of enrichedEvents) {
|
|
@@ -593,28 +619,23 @@ class Databuddy {
|
|
|
593
619
|
};
|
|
594
620
|
}
|
|
595
621
|
try {
|
|
596
|
-
const url = `${this.apiUrl}/
|
|
597
|
-
const
|
|
598
|
-
(event) => this.
|
|
622
|
+
const url = `${this.apiUrl}/track`;
|
|
623
|
+
const payloads = processedEvents.map(
|
|
624
|
+
(event) => this.toTrackPayload(event)
|
|
599
625
|
);
|
|
600
626
|
this.logger.info("\u{1F4E6} SENDING BATCH EVENTS:", {
|
|
601
|
-
count:
|
|
602
|
-
firstEventName:
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
null,
|
|
606
|
-
2
|
|
607
|
-
),
|
|
608
|
-
firstEventPropertiesCount: Object.keys(
|
|
609
|
-
customEventSpans[0]?.properties || {}
|
|
610
|
-
).length
|
|
627
|
+
count: payloads.length,
|
|
628
|
+
firstEventName: payloads[0]?.name,
|
|
629
|
+
firstWebsiteId: payloads[0]?.websiteId,
|
|
630
|
+
firstSource: payloads[0]?.source
|
|
611
631
|
});
|
|
612
632
|
const response = await fetch(url, {
|
|
613
633
|
method: "POST",
|
|
614
634
|
headers: {
|
|
615
|
-
"Content-Type": "application/json"
|
|
635
|
+
"Content-Type": "application/json",
|
|
636
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
616
637
|
},
|
|
617
|
-
body: JSON.stringify(
|
|
638
|
+
body: JSON.stringify(payloads)
|
|
618
639
|
});
|
|
619
640
|
if (!response.ok) {
|
|
620
641
|
const errorText = await response.text().catch(() => "Unknown error");
|