@blyp/core 0.1.2 → 0.1.21

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.
Files changed (124) hide show
  1. package/README.md +56 -3
  2. package/dist/astro.js +4602 -0
  3. package/dist/astro.js.map +1 -0
  4. package/dist/astro.mjs +4574 -0
  5. package/dist/astro.mjs.map +1 -0
  6. package/dist/client.js +7 -0
  7. package/dist/client.js.map +1 -1
  8. package/dist/client.mjs +7 -0
  9. package/dist/client.mjs.map +1 -1
  10. package/dist/connectors/betterstack.js +24 -0
  11. package/dist/connectors/betterstack.js.map +1 -1
  12. package/dist/connectors/betterstack.mjs +24 -0
  13. package/dist/connectors/betterstack.mjs.map +1 -1
  14. package/dist/connectors/databuddy/index.d.ts +7 -0
  15. package/dist/connectors/databuddy/sender.d.ts +5 -0
  16. package/dist/connectors/databuddy.js +1456 -0
  17. package/dist/connectors/databuddy.js.map +1 -0
  18. package/dist/connectors/databuddy.mjs +1451 -0
  19. package/dist/connectors/databuddy.mjs.map +1 -0
  20. package/dist/connectors/otlp.js +24 -0
  21. package/dist/connectors/otlp.js.map +1 -1
  22. package/dist/connectors/otlp.mjs +24 -0
  23. package/dist/connectors/otlp.mjs.map +1 -1
  24. package/dist/connectors/posthog.js +24 -0
  25. package/dist/connectors/posthog.js.map +1 -1
  26. package/dist/connectors/posthog.mjs +24 -0
  27. package/dist/connectors/posthog.mjs.map +1 -1
  28. package/dist/connectors/sentry.js +24 -0
  29. package/dist/connectors/sentry.js.map +1 -1
  30. package/dist/connectors/sentry.mjs +24 -0
  31. package/dist/connectors/sentry.mjs.map +1 -1
  32. package/dist/core/config.d.ts +1 -1
  33. package/dist/core/logger.d.ts +3 -0
  34. package/dist/elysia.js +455 -30
  35. package/dist/elysia.js.map +1 -1
  36. package/dist/elysia.mjs +455 -30
  37. package/dist/elysia.mjs.map +1 -1
  38. package/dist/expo.js +7 -0
  39. package/dist/expo.js.map +1 -1
  40. package/dist/expo.mjs +7 -0
  41. package/dist/expo.mjs.map +1 -1
  42. package/dist/express.js +455 -30
  43. package/dist/express.js.map +1 -1
  44. package/dist/express.mjs +455 -30
  45. package/dist/express.mjs.map +1 -1
  46. package/dist/fastify.js +455 -30
  47. package/dist/fastify.js.map +1 -1
  48. package/dist/fastify.mjs +455 -30
  49. package/dist/fastify.mjs.map +1 -1
  50. package/dist/frameworks/astro/index.d.ts +2 -0
  51. package/dist/frameworks/astro/logger.d.ts +3 -0
  52. package/dist/frameworks/nitro/index.d.ts +2 -0
  53. package/dist/frameworks/nitro/logger.d.ts +6 -0
  54. package/dist/frameworks/nuxt/index.d.ts +2 -0
  55. package/dist/frameworks/nuxt/logger.d.ts +3 -0
  56. package/dist/frameworks/react-router/index.d.ts +2 -0
  57. package/dist/frameworks/react-router/logger.d.ts +3 -0
  58. package/dist/frameworks/shared/h3.d.ts +19 -0
  59. package/dist/hono.js +455 -30
  60. package/dist/hono.js.map +1 -1
  61. package/dist/hono.mjs +455 -30
  62. package/dist/hono.mjs.map +1 -1
  63. package/dist/index.d.ts +11 -1
  64. package/dist/index.js +1142 -78
  65. package/dist/index.js.map +1 -1
  66. package/dist/index.mjs +1135 -79
  67. package/dist/index.mjs.map +1 -1
  68. package/dist/nestjs.js +455 -30
  69. package/dist/nestjs.js.map +1 -1
  70. package/dist/nestjs.mjs +455 -30
  71. package/dist/nestjs.mjs.map +1 -1
  72. package/dist/nextjs.js +455 -30
  73. package/dist/nextjs.js.map +1 -1
  74. package/dist/nextjs.mjs +455 -30
  75. package/dist/nextjs.mjs.map +1 -1
  76. package/dist/nitro.js +4726 -0
  77. package/dist/nitro.js.map +1 -0
  78. package/dist/nitro.mjs +4698 -0
  79. package/dist/nitro.mjs.map +1 -0
  80. package/dist/nuxt.js +4733 -0
  81. package/dist/nuxt.js.map +1 -0
  82. package/dist/nuxt.mjs +4705 -0
  83. package/dist/nuxt.mjs.map +1 -0
  84. package/dist/react-router.js +4644 -0
  85. package/dist/react-router.js.map +1 -0
  86. package/dist/react-router.mjs +4616 -0
  87. package/dist/react-router.mjs.map +1 -0
  88. package/dist/standalone.js +423 -53
  89. package/dist/standalone.js.map +1 -1
  90. package/dist/standalone.mjs +423 -53
  91. package/dist/standalone.mjs.map +1 -1
  92. package/dist/sveltekit.js +455 -30
  93. package/dist/sveltekit.js.map +1 -1
  94. package/dist/sveltekit.mjs +455 -30
  95. package/dist/sveltekit.mjs.map +1 -1
  96. package/dist/tanstack-start.js +455 -30
  97. package/dist/tanstack-start.js.map +1 -1
  98. package/dist/tanstack-start.mjs +455 -30
  99. package/dist/tanstack-start.mjs.map +1 -1
  100. package/dist/types/connectors/databuddy.d.ts +52 -0
  101. package/dist/types/core/config.d.ts +32 -0
  102. package/dist/types/core/logger.d.ts +2 -0
  103. package/dist/types/frameworks/astro.d.ts +32 -0
  104. package/dist/types/frameworks/nitro.d.ts +62 -0
  105. package/dist/types/frameworks/nuxt.d.ts +12 -0
  106. package/dist/types/frameworks/react-router.d.ts +33 -0
  107. package/dist/types/frameworks/shared.d.ts +24 -0
  108. package/dist/types/shared/client-log.d.ts +1 -1
  109. package/exports/connectors/databuddy.js +1 -0
  110. package/exports/connectors/databuddy.mjs +1 -0
  111. package/exports/frameworks/astro.js +1 -0
  112. package/exports/frameworks/astro.mjs +1 -0
  113. package/exports/frameworks/nitro.js +1 -0
  114. package/exports/frameworks/nitro.mjs +1 -0
  115. package/exports/frameworks/nuxt.js +1 -0
  116. package/exports/frameworks/nuxt.mjs +1 -0
  117. package/exports/frameworks/react-router.js +1 -0
  118. package/exports/frameworks/react-router.mjs +1 -0
  119. package/package.json +59 -2
  120. package/types/connectors/databuddy.d.ts +1 -0
  121. package/types/frameworks/astro.d.ts +1 -0
  122. package/types/frameworks/nitro.d.ts +1 -0
  123. package/types/frameworks/nuxt.d.ts +1 -0
  124. package/types/frameworks/react-router.d.ts +1 -0
package/dist/nestjs.mjs CHANGED
@@ -13,6 +13,7 @@ import { AsyncLocalStorage } from 'async_hooks';
13
13
  import { randomUUID } from 'crypto';
14
14
  import * as Sentry from '@sentry/node';
15
15
  import { Logtail } from '@logtail/node';
16
+ import { Databuddy } from '@databuddy/sdk/node';
16
17
  import { Catch, Inject, Injectable, Global, Module, RequestMethod, HttpException } from '@nestjs/common';
17
18
  import { APP_INTERCEPTOR, APP_FILTER, BaseExceptionFilter } from '@nestjs/core';
18
19
  import { tap } from 'rxjs';
@@ -383,6 +384,7 @@ var CLIENT_LOG_LEVELS = [
383
384
  ];
384
385
  var clientConnectorRequestSchema = z.union([
385
386
  z.literal("betterstack"),
387
+ z.literal("databuddy"),
386
388
  z.literal("posthog"),
387
389
  z.literal("sentry"),
388
390
  z.undefined(),
@@ -423,16 +425,16 @@ function normalizeEndpointPath(path3) {
423
425
  }
424
426
 
425
427
  // src/shared/once.ts
426
- function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()) {
428
+ function createConsoleOnceLogger(method, warnedKeys7 = /* @__PURE__ */ new Set()) {
427
429
  return (key, message, error) => {
428
- if (warnedKeys6.has(key) || typeof console === "undefined") {
430
+ if (warnedKeys7.has(key) || typeof console === "undefined") {
429
431
  return;
430
432
  }
431
433
  const writer = console[method];
432
434
  if (typeof writer !== "function") {
433
435
  return;
434
436
  }
435
- warnedKeys6.add(key);
437
+ warnedKeys7.add(key);
436
438
  if (error === void 0) {
437
439
  writer.call(console, message);
438
440
  return;
@@ -440,11 +442,11 @@ function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()
440
442
  writer.call(console, message, error);
441
443
  };
442
444
  }
443
- function createWarnOnceLogger(warnedKeys6) {
444
- return createConsoleOnceLogger("warn", warnedKeys6);
445
+ function createWarnOnceLogger(warnedKeys7) {
446
+ return createConsoleOnceLogger("warn", warnedKeys7);
445
447
  }
446
- function createErrorOnceLogger(warnedKeys6) {
447
- return createConsoleOnceLogger("error", warnedKeys6);
448
+ function createErrorOnceLogger(warnedKeys7) {
449
+ return createConsoleOnceLogger("error", warnedKeys7);
448
450
  }
449
451
 
450
452
  // src/core/config.ts
@@ -810,6 +812,28 @@ function mergePostHogConnectorConfig(base, override) {
810
812
  }
811
813
  };
812
814
  }
815
+ function mergeDatabuddyConnectorConfig(base, override) {
816
+ const enabled = override?.enabled ?? base?.enabled ?? false;
817
+ const apiKey = override?.apiKey ?? base?.apiKey;
818
+ const websiteId = override?.websiteId ?? base?.websiteId;
819
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
820
+ return {
821
+ enabled,
822
+ mode: override?.mode ?? base?.mode ?? "auto",
823
+ apiKey,
824
+ websiteId,
825
+ namespace: override?.namespace ?? base?.namespace,
826
+ source: override?.source ?? base?.source,
827
+ apiUrl: override?.apiUrl ?? base?.apiUrl,
828
+ debug: override?.debug ?? base?.debug ?? false,
829
+ enableBatching: override?.enableBatching ?? base?.enableBatching ?? true,
830
+ batchSize: override?.batchSize ?? base?.batchSize,
831
+ batchTimeout: override?.batchTimeout ?? base?.batchTimeout,
832
+ maxQueueSize: override?.maxQueueSize ?? base?.maxQueueSize,
833
+ ready,
834
+ status: ready ? "enabled" : "missing"
835
+ };
836
+ }
813
837
  function mergeBetterStackConnectorConfig(base, override) {
814
838
  const sourceToken = override?.sourceToken ?? base?.sourceToken;
815
839
  const ingestingHost = override?.ingestingHost ?? base?.ingestingHost;
@@ -900,6 +924,7 @@ function mergeOTLPConnectorsConfig(base, override) {
900
924
  function mergeConnectorsConfig(base, override) {
901
925
  return {
902
926
  betterstack: mergeBetterStackConnectorConfig(base?.betterstack, override?.betterstack),
927
+ databuddy: mergeDatabuddyConnectorConfig(base?.databuddy, override?.databuddy),
903
928
  posthog: mergePostHogConnectorConfig(base?.posthog, override?.posthog),
904
929
  sentry: mergeSentryConnectorConfig(base?.sentry, override?.sentry),
905
930
  otlp: mergeOTLPConnectorsConfig(base?.otlp, override?.otlp)
@@ -2538,12 +2563,320 @@ function createBetterStackSender(config) {
2538
2563
  };
2539
2564
  }
2540
2565
  var warnedKeys4 = /* @__PURE__ */ new Set();
2566
+ var senderCache = /* @__PURE__ */ new Map();
2541
2567
  var testHooks3 = {};
2542
2568
  var warnOnce5 = createErrorOnceLogger(warnedKeys4);
2543
- function getSentryModule2() {
2544
- return testHooks3.module ?? Sentry;
2569
+ function registerShutdownHooks3(key, shutdown) {
2570
+ const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2571
+ for (const event of handlers) {
2572
+ process.once(event, () => {
2573
+ void shutdown().catch((error) => {
2574
+ warnOnce5(
2575
+ `${key}:shutdown`,
2576
+ "[Blyp] Failed to flush Databuddy telemetry during shutdown.",
2577
+ error
2578
+ );
2579
+ });
2580
+ });
2581
+ }
2545
2582
  }
2546
2583
  function resolveConnectorConfig3(config) {
2584
+ const connector = isBlypConfig(config) ? config.connectors?.databuddy : config;
2585
+ const enabled = connector?.enabled ?? false;
2586
+ const apiKey = connector?.apiKey;
2587
+ const websiteId = connector?.websiteId;
2588
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
2589
+ return {
2590
+ enabled,
2591
+ mode: connector?.mode ?? "auto",
2592
+ apiKey,
2593
+ websiteId,
2594
+ namespace: connector?.namespace,
2595
+ source: connector?.source,
2596
+ apiUrl: connector?.apiUrl,
2597
+ debug: connector?.debug ?? false,
2598
+ enableBatching: connector?.enableBatching ?? true,
2599
+ batchSize: connector?.batchSize,
2600
+ batchTimeout: connector?.batchTimeout,
2601
+ maxQueueSize: connector?.maxQueueSize,
2602
+ ready,
2603
+ status: ready ? "enabled" : "missing"
2604
+ };
2605
+ }
2606
+ function createDefaultClient2(connector) {
2607
+ return new Databuddy({
2608
+ apiKey: connector.apiKey ?? "",
2609
+ ...connector.websiteId ? { websiteId: connector.websiteId } : {},
2610
+ ...connector.namespace ? { namespace: connector.namespace } : {},
2611
+ ...connector.source ? { source: connector.source } : {},
2612
+ ...connector.apiUrl ? { apiUrl: connector.apiUrl } : {},
2613
+ debug: connector.debug,
2614
+ enableBatching: connector.enableBatching,
2615
+ ...connector.batchSize !== void 0 ? { batchSize: connector.batchSize } : {},
2616
+ ...connector.batchTimeout !== void 0 ? { batchTimeout: connector.batchTimeout } : {},
2617
+ ...connector.maxQueueSize !== void 0 ? { maxQueueSize: connector.maxQueueSize } : {}
2618
+ });
2619
+ }
2620
+ function getDatabuddySenderKey(connector) {
2621
+ return JSON.stringify({
2622
+ enabled: connector.enabled,
2623
+ mode: connector.mode,
2624
+ apiKey: connector.apiKey ?? null,
2625
+ websiteId: connector.websiteId ?? null,
2626
+ namespace: connector.namespace ?? null,
2627
+ source: connector.source ?? null,
2628
+ apiUrl: connector.apiUrl ?? null,
2629
+ debug: connector.debug,
2630
+ enableBatching: connector.enableBatching,
2631
+ batchSize: connector.batchSize ?? null,
2632
+ batchTimeout: connector.batchTimeout ?? null,
2633
+ maxQueueSize: connector.maxQueueSize ?? null
2634
+ });
2635
+ }
2636
+ function getSessionId(record) {
2637
+ const direct = getField(record, "sessionId");
2638
+ if (hasNonEmptyString(direct)) {
2639
+ return direct;
2640
+ }
2641
+ return getClientSessionField(record, "sessionId");
2642
+ }
2643
+ function getAnonymousId(record) {
2644
+ const direct = getField(record, "anonymousId");
2645
+ if (hasNonEmptyString(direct)) {
2646
+ return direct;
2647
+ }
2648
+ const payload = getPrimaryPayload(record);
2649
+ if (isPlainObject(payload.metadata) && hasNonEmptyString(payload.metadata.databuddyAnonymousId)) {
2650
+ return payload.metadata.databuddyAnonymousId;
2651
+ }
2652
+ return void 0;
2653
+ }
2654
+ function getDatabuddyEventName(record) {
2655
+ const recordType = getRecordType(record);
2656
+ if (hasNonEmptyString(recordType)) {
2657
+ return recordType;
2658
+ }
2659
+ return "log";
2660
+ }
2661
+ function buildRecordProperties(record, source) {
2662
+ const properties = {
2663
+ blyp_level: record.level,
2664
+ blyp_source: source,
2665
+ blyp_payload: serializeLogRecord(record),
2666
+ message: typeof record.message === "string" ? record.message : String(record.message)
2667
+ };
2668
+ const caller = typeof record.caller === "string" ? record.caller : void 0;
2669
+ const groupId = getField(record, "groupId");
2670
+ const method = getField(record, "method");
2671
+ const path3 = getField(record, "path");
2672
+ const status = getField(record, "status");
2673
+ const duration = getField(record, "duration");
2674
+ const pagePath = getClientPageField(record, "pathname");
2675
+ const pageUrl = getClientPageField(record, "url");
2676
+ const sessionId = getClientSessionField(record, "sessionId");
2677
+ const pageId = getClientSessionField(record, "pageId");
2678
+ const ifTruthy = [
2679
+ ["blyp_type", getRecordType(record)],
2680
+ ["caller", caller],
2681
+ ["group_id", groupId],
2682
+ ["method", method],
2683
+ ["path", path3],
2684
+ ["page_path", pagePath],
2685
+ ["page_url", pageUrl],
2686
+ ["session_id", sessionId],
2687
+ ["page_id", pageId]
2688
+ ];
2689
+ const ifDefined = [
2690
+ ["status_code", status],
2691
+ ["duration_ms", duration]
2692
+ ];
2693
+ for (const [key, value] of ifTruthy) {
2694
+ if (value) {
2695
+ properties[key] = value;
2696
+ }
2697
+ }
2698
+ for (const [key, value] of ifDefined) {
2699
+ if (value !== void 0) {
2700
+ properties[key] = value;
2701
+ }
2702
+ }
2703
+ return properties;
2704
+ }
2705
+ function createTrackEvent(record, source) {
2706
+ return {
2707
+ name: getDatabuddyEventName(record),
2708
+ anonymousId: getAnonymousId(record),
2709
+ sessionId: getSessionId(record),
2710
+ properties: buildRecordProperties(record, source)
2711
+ };
2712
+ }
2713
+ function normalizeExceptionProperties2(value) {
2714
+ if (!isPlainObject(value)) {
2715
+ return {};
2716
+ }
2717
+ return normalizeLogValue(value);
2718
+ }
2719
+ function normalizeExceptionInput3(value, fallbackMessage) {
2720
+ if (value instanceof Error) {
2721
+ return {
2722
+ message: value.message || fallbackMessage,
2723
+ properties: {
2724
+ error_type: value.name,
2725
+ ...value.stack ? { stack: value.stack } : {},
2726
+ ...normalizeExceptionProperties2(value)
2727
+ }
2728
+ };
2729
+ }
2730
+ if (isPlainObject(value)) {
2731
+ const message = hasNonEmptyString(value.message) ? value.message : hasNonEmptyString(value.error) ? value.error : fallbackMessage;
2732
+ return {
2733
+ message,
2734
+ properties: normalizeExceptionProperties2(value)
2735
+ };
2736
+ }
2737
+ if (typeof value === "string") {
2738
+ return {
2739
+ message: value,
2740
+ properties: {
2741
+ message: value
2742
+ }
2743
+ };
2744
+ }
2745
+ return {
2746
+ message: fallbackMessage,
2747
+ properties: {
2748
+ value: normalizeLogValue(value)
2749
+ }
2750
+ };
2751
+ }
2752
+ function createDatabuddySender(config) {
2753
+ const connector = resolveConnectorConfig3(config);
2754
+ const senderKey = getDatabuddySenderKey(connector);
2755
+ const cached = senderCache.get(senderKey);
2756
+ if (cached) {
2757
+ return cached;
2758
+ }
2759
+ const key = `${connector.apiUrl ?? "default"}:${connector.mode}:${connector.apiKey ?? "missing"}`;
2760
+ const client = connector.ready ? testHooks3.createClient?.(connector) ?? createDefaultClient2(connector) : void 0;
2761
+ if (client) {
2762
+ registerShutdownHooks3(key, async () => {
2763
+ await client.flush();
2764
+ });
2765
+ }
2766
+ const emitUnavailableWarning = () => {
2767
+ warnOnce5(
2768
+ `databuddy-unavailable:${key}`,
2769
+ "[Blyp] Databuddy connector is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy delivery."
2770
+ );
2771
+ };
2772
+ const emitExceptionUnavailableWarning = () => {
2773
+ warnOnce5(
2774
+ `databuddy-exception-unavailable:${key}`,
2775
+ "[Blyp] Databuddy error tracking is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy exception capture."
2776
+ );
2777
+ };
2778
+ const sender = {
2779
+ enabled: connector.enabled,
2780
+ ready: connector.ready,
2781
+ mode: connector.mode,
2782
+ status: connector.status,
2783
+ shouldAutoForwardServerLogs() {
2784
+ return connector.ready && connector.mode === "auto";
2785
+ },
2786
+ shouldAutoCaptureExceptions() {
2787
+ return connector.ready && connector.mode === "auto";
2788
+ },
2789
+ send(record, options = {}) {
2790
+ if (!connector.ready || !client) {
2791
+ if (options.warnIfUnavailable) {
2792
+ emitUnavailableWarning();
2793
+ }
2794
+ return;
2795
+ }
2796
+ try {
2797
+ const result = client.track(createTrackEvent(record, options.source ?? "server"));
2798
+ if (result && typeof result.catch === "function") {
2799
+ void result.catch((error) => {
2800
+ warnOnce5(
2801
+ `databuddy-send:${key}`,
2802
+ "[Blyp] Failed to deliver log to Databuddy.",
2803
+ error
2804
+ );
2805
+ });
2806
+ }
2807
+ } catch (error) {
2808
+ warnOnce5(
2809
+ `databuddy-send:${key}`,
2810
+ "[Blyp] Failed to deliver log to Databuddy.",
2811
+ error
2812
+ );
2813
+ }
2814
+ },
2815
+ captureException(error, options = {}) {
2816
+ if (!connector.ready || !client) {
2817
+ if (options.warnIfUnavailable) {
2818
+ emitExceptionUnavailableWarning();
2819
+ }
2820
+ return;
2821
+ }
2822
+ const normalized = normalizeExceptionInput3(
2823
+ error,
2824
+ options.source === "client" ? "Client error" : "Server error"
2825
+ );
2826
+ try {
2827
+ const result = client.track({
2828
+ name: "error",
2829
+ anonymousId: options.anonymousId,
2830
+ sessionId: options.sessionId,
2831
+ properties: {
2832
+ message: normalized.message,
2833
+ blyp_source: options.source ?? "server",
2834
+ blyp_level: "error",
2835
+ ...normalized.properties,
2836
+ ...options.properties ?? {}
2837
+ }
2838
+ });
2839
+ if (result && typeof result.catch === "function") {
2840
+ void result.catch((captureError) => {
2841
+ warnOnce5(
2842
+ `databuddy-capture:${key}`,
2843
+ "[Blyp] Failed to capture exception in Databuddy.",
2844
+ captureError
2845
+ );
2846
+ });
2847
+ }
2848
+ } catch (captureError) {
2849
+ warnOnce5(
2850
+ `databuddy-capture:${key}`,
2851
+ "[Blyp] Failed to capture exception in Databuddy.",
2852
+ captureError
2853
+ );
2854
+ }
2855
+ },
2856
+ async flush() {
2857
+ try {
2858
+ if (client) {
2859
+ await client.flush();
2860
+ }
2861
+ } catch (error) {
2862
+ warnOnce5(
2863
+ `databuddy-flush:${key}`,
2864
+ "[Blyp] Failed to flush Databuddy telemetry.",
2865
+ error
2866
+ );
2867
+ }
2868
+ }
2869
+ };
2870
+ senderCache.set(senderKey, sender);
2871
+ return sender;
2872
+ }
2873
+ var warnedKeys5 = /* @__PURE__ */ new Set();
2874
+ var testHooks4 = {};
2875
+ var warnOnce6 = createErrorOnceLogger(warnedKeys5);
2876
+ function getSentryModule2() {
2877
+ return testHooks4.module ?? Sentry;
2878
+ }
2879
+ function resolveConnectorConfig4(config) {
2547
2880
  const connector = isBlypConfig(config) ? config.connectors?.sentry : config;
2548
2881
  const enabled = connector?.enabled ?? false;
2549
2882
  const dsn = connector?.dsn;
@@ -2688,7 +3021,7 @@ function hasConfigMismatch(connector, client) {
2688
3021
  return hasNonEmptyString(connector.dsn) && connector.dsn !== options.dsn || hasNonEmptyString(connector.environment) && connector.environment !== options.environment || hasNonEmptyString(connector.release) && connector.release !== options.release;
2689
3022
  }
2690
3023
  function createSentrySender(config) {
2691
- const connector = resolveConnectorConfig3(config);
3024
+ const connector = resolveConnectorConfig4(config);
2692
3025
  const key = `${connector.mode}:${connector.dsn ?? "missing"}`;
2693
3026
  const module = getSentryModule2();
2694
3027
  let client = connector.enabled ? module.getClient() : void 0;
@@ -2702,7 +3035,7 @@ function createSentrySender(config) {
2702
3035
  });
2703
3036
  client = module.getClient();
2704
3037
  } catch (error) {
2705
- warnOnce5(
3038
+ warnOnce6(
2706
3039
  `sentry-init:${key}`,
2707
3040
  "[Blyp] Failed to initialize Sentry. Skipping Sentry delivery.",
2708
3041
  error
@@ -2710,14 +3043,14 @@ function createSentrySender(config) {
2710
3043
  }
2711
3044
  }
2712
3045
  if (client && hasConfigMismatch(connector, client)) {
2713
- warnOnce5(
3046
+ warnOnce6(
2714
3047
  `sentry-mismatch:${key}`,
2715
3048
  "[Blyp] Sentry is already initialized with different options. Reusing the existing Sentry client."
2716
3049
  );
2717
3050
  }
2718
3051
  const ready = connector.enabled && client !== void 0;
2719
3052
  const emitUnavailableWarning = () => {
2720
- warnOnce5(
3053
+ warnOnce6(
2721
3054
  `sentry-unavailable:${key}`,
2722
3055
  "[Blyp] Sentry connector is not configured. Skipping Sentry delivery."
2723
3056
  );
@@ -2743,7 +3076,7 @@ function createSentrySender(config) {
2743
3076
  try {
2744
3077
  logMethod(record.message, attributes);
2745
3078
  } catch (error) {
2746
- warnOnce5(
3079
+ warnOnce6(
2747
3080
  `sentry-log:${key}`,
2748
3081
  "[Blyp] Failed to deliver log to Sentry.",
2749
3082
  error
@@ -2761,7 +3094,7 @@ function createSentrySender(config) {
2761
3094
  module.captureException(exception);
2762
3095
  });
2763
3096
  } catch (error) {
2764
- warnOnce5(
3097
+ warnOnce6(
2765
3098
  `sentry-exception:${key}`,
2766
3099
  "[Blyp] Failed to capture exception in Sentry.",
2767
3100
  error
@@ -2772,7 +3105,7 @@ function createSentrySender(config) {
2772
3105
  try {
2773
3106
  await module.flush(2e3);
2774
3107
  } catch (error) {
2775
- warnOnce5(
3108
+ warnOnce6(
2776
3109
  `sentry-flush:${key}`,
2777
3110
  "[Blyp] Failed to flush Sentry logs.",
2778
3111
  error
@@ -2781,9 +3114,9 @@ function createSentrySender(config) {
2781
3114
  }
2782
3115
  };
2783
3116
  }
2784
- var warnedKeys5 = /* @__PURE__ */ new Set();
2785
- var testHooks4 = {};
2786
- var warnOnce6 = createErrorOnceLogger(warnedKeys5);
3117
+ var warnedKeys6 = /* @__PURE__ */ new Set();
3118
+ var testHooks5 = {};
3119
+ var warnOnce7 = createErrorOnceLogger(warnedKeys6);
2787
3120
  function normalizeOTLPRecord(record, connector, source = "server") {
2788
3121
  const severity = resolveSeverity2(record.level);
2789
3122
  const body = typeof record.message === "string" ? record.message : String(record.message);
@@ -2848,14 +3181,14 @@ function resolveSeverity2(level) {
2848
3181
  return { text: "info", number: SeverityNumber.INFO };
2849
3182
  }
2850
3183
  }
2851
- function registerShutdownHooks3(key, shutdown) {
3184
+ function registerShutdownHooks4(key, shutdown) {
2852
3185
  const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2853
3186
  for (const event of handlers) {
2854
3187
  process.once(event, async () => {
2855
3188
  try {
2856
3189
  await shutdown();
2857
3190
  } catch (error) {
2858
- warnOnce6(
3191
+ warnOnce7(
2859
3192
  `${key}:shutdown`,
2860
3193
  "[Blyp] Failed to flush OTLP logs during shutdown.",
2861
3194
  error
@@ -2932,7 +3265,7 @@ function createUnavailableSender(name, connector) {
2932
3265
  const senderName = name || connector?.name || "otlp";
2933
3266
  const key = `${senderName}:${connector?.serviceName ?? "blyp-app"}:${connector?.endpoint ?? "missing"}`;
2934
3267
  const emitUnavailableWarning = () => {
2935
- warnOnce6(
3268
+ warnOnce7(
2936
3269
  `otlp-unavailable:${key}`,
2937
3270
  `[Blyp] OTLP target "${senderName}" is not configured or not ready. Skipping OTLP delivery.`
2938
3271
  );
@@ -2963,7 +3296,7 @@ function createSender(connector) {
2963
3296
  ...connector,
2964
3297
  headers: resolveTransportHeaders(connector)
2965
3298
  };
2966
- const transport = testHooks4.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
3299
+ const transport = testHooks5.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
2967
3300
  return {
2968
3301
  name: connector.name,
2969
3302
  enabled: connector.enabled,
@@ -2979,7 +3312,7 @@ function createSender(connector) {
2979
3312
  const result = transport.emit(normalized);
2980
3313
  if (result && typeof result.catch === "function") {
2981
3314
  void result.catch((error) => {
2982
- warnOnce6(
3315
+ warnOnce7(
2983
3316
  `otlp-emit:${key}`,
2984
3317
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2985
3318
  error
@@ -2987,7 +3320,7 @@ function createSender(connector) {
2987
3320
  });
2988
3321
  }
2989
3322
  } catch (error) {
2990
- warnOnce6(
3323
+ warnOnce7(
2991
3324
  `otlp-emit:${key}`,
2992
3325
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2993
3326
  error
@@ -3000,7 +3333,7 @@ function createSender(connector) {
3000
3333
  await transport.flush();
3001
3334
  }
3002
3335
  } catch (error) {
3003
- warnOnce6(
3336
+ warnOnce7(
3004
3337
  `otlp-flush:${key}`,
3005
3338
  `[Blyp] Failed to flush OTLP logs for target "${connector.name}".`,
3006
3339
  error
@@ -3029,7 +3362,7 @@ function createOTLPRegistry(config) {
3029
3362
  await Promise.all(Array.from(senders.values()).map((sender) => sender.flush()));
3030
3363
  }
3031
3364
  };
3032
- registerShutdownHooks3("otlp-registry", () => registry.flush());
3365
+ registerShutdownHooks4("otlp-registry", () => registry.flush());
3033
3366
  return registry;
3034
3367
  }
3035
3368
  var _RuntimeDetector = class _RuntimeDetector {
@@ -3420,6 +3753,9 @@ function getPostHogSender(logger3) {
3420
3753
  function getBetterStackSender(logger3) {
3421
3754
  return getLoggerFactory(logger3).betterstack;
3422
3755
  }
3756
+ function getDatabuddySender(logger3) {
3757
+ return getLoggerFactory(logger3).databuddy;
3758
+ }
3423
3759
  function tryGetPostHogSender(logger3) {
3424
3760
  try {
3425
3761
  return getPostHogSender(logger3);
@@ -3434,6 +3770,13 @@ function tryGetBetterStackSender(logger3) {
3434
3770
  return null;
3435
3771
  }
3436
3772
  }
3773
+ function tryGetDatabuddySender(logger3) {
3774
+ try {
3775
+ return getDatabuddySender(logger3);
3776
+ } catch {
3777
+ return null;
3778
+ }
3779
+ }
3437
3780
  function getSentrySender(logger3) {
3438
3781
  return getLoggerFactory(logger3).sentry;
3439
3782
  }
@@ -3493,6 +3836,18 @@ function maybeSendToBetterStack(betterstack, record) {
3493
3836
  }
3494
3837
  betterstack.send(record, { source: "server", warnIfUnavailable: true });
3495
3838
  }
3839
+ function maybeSendToDatabuddy(databuddy, record) {
3840
+ if (isClientLogRecord(record)) {
3841
+ return;
3842
+ }
3843
+ if (!databuddy.shouldAutoForwardServerLogs()) {
3844
+ if (databuddy.enabled && !databuddy.ready) {
3845
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3846
+ }
3847
+ return;
3848
+ }
3849
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3850
+ }
3496
3851
  function maybeSendToSentry(sentry, record) {
3497
3852
  if (isClientLogRecord(record)) {
3498
3853
  return;
@@ -3513,7 +3868,7 @@ function maybeSendToOTLP(otlp, record) {
3513
3868
  sender.send(record, { source: "server", warnIfUnavailable: true });
3514
3869
  }
3515
3870
  }
3516
- function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry, otlp, bindings = {}, source = "root") {
3871
+ function createLoggerInstance(rootRawLogger, sink, betterstack, databuddy, posthog, sentry, otlp, bindings = {}, source = "root") {
3517
3872
  const rawLogger = Object.keys(bindings).length > 0 ? rootRawLogger.child(bindings) : rootRawLogger;
3518
3873
  const writeRecord = (level, message, args, writeSource = source) => {
3519
3874
  if (writeSource === "root" && shouldDropRootLogWrite()) {
@@ -3539,6 +3894,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3539
3894
  );
3540
3895
  sink.write(record);
3541
3896
  maybeSendToBetterStack(betterstack, record);
3897
+ maybeSendToDatabuddy(databuddy, record);
3542
3898
  maybeSendToPostHog(posthog, record);
3543
3899
  maybeSendToSentry(sentry, record);
3544
3900
  maybeSendToOTLP(otlp, record);
@@ -3562,6 +3918,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3562
3918
  sink.write(record);
3563
3919
  }
3564
3920
  maybeSendToBetterStack(betterstack, record);
3921
+ maybeSendToDatabuddy(databuddy, record);
3565
3922
  maybeSendToPostHog(posthog, record);
3566
3923
  maybeSendToSentry(sentry, record);
3567
3924
  maybeSendToOTLP(otlp, record);
@@ -3595,8 +3952,26 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3595
3952
  }
3596
3953
  writeRecord("table", message, data === void 0 ? [] : [data]);
3597
3954
  },
3598
- flush: () => sink.flush(),
3599
- shutdown: () => sink.shutdown(),
3955
+ flush: async () => {
3956
+ await sink.flush();
3957
+ await Promise.allSettled([
3958
+ betterstack.flush(),
3959
+ databuddy.flush(),
3960
+ posthog.flush(),
3961
+ sentry.flush(),
3962
+ otlp.flush()
3963
+ ]);
3964
+ },
3965
+ shutdown: async () => {
3966
+ await sink.shutdown();
3967
+ await Promise.allSettled([
3968
+ betterstack.flush(),
3969
+ databuddy.flush(),
3970
+ posthog.flush(),
3971
+ sentry.flush(),
3972
+ otlp.flush()
3973
+ ]);
3974
+ },
3600
3975
  createStructuredLog: (groupId, initial) => {
3601
3976
  return createStructuredLogForLogger(logger3, groupId, {
3602
3977
  initialFields: initial
@@ -3608,6 +3983,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3608
3983
  rootRawLogger,
3609
3984
  sink,
3610
3985
  betterstack,
3986
+ databuddy,
3611
3987
  posthog,
3612
3988
  sentry,
3613
3989
  otlp,
@@ -3618,6 +3994,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3618
3994
  [LOGGER_FACTORY]: {
3619
3995
  bindings,
3620
3996
  betterstack,
3997
+ databuddy,
3621
3998
  posthog,
3622
3999
  sentry,
3623
4000
  otlp,
@@ -3627,6 +4004,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3627
4004
  rootRawLogger,
3628
4005
  sink,
3629
4006
  betterstack,
4007
+ databuddy,
3630
4008
  posthog,
3631
4009
  sentry,
3632
4010
  otlp,
@@ -3650,6 +4028,7 @@ function createBaseLogger(config) {
3650
4028
  const rawLogger = createPinoLogger(resolvedConfig);
3651
4029
  const sink = createPrimarySink(resolvedConfig);
3652
4030
  const betterstack = createBetterStackSender(resolvedConfig);
4031
+ const databuddy = createDatabuddySender(resolvedConfig);
3653
4032
  const posthog = createPostHogSender(resolvedConfig);
3654
4033
  const sentry = createSentrySender(resolvedConfig);
3655
4034
  const otlp = createOTLPRegistry(resolvedConfig);
@@ -3657,6 +4036,7 @@ function createBaseLogger(config) {
3657
4036
  rawLogger,
3658
4037
  sink,
3659
4038
  betterstack,
4039
+ databuddy,
3660
4040
  posthog,
3661
4041
  sentry,
3662
4042
  otlp
@@ -3739,6 +4119,7 @@ function resolveServerLogger(config = {}, loggerOverride) {
3739
4119
  return {
3740
4120
  logger: logger3,
3741
4121
  betterstack: getBetterStackSender(logger3),
4122
+ databuddy: getDatabuddySender(logger3),
3742
4123
  posthog: getPostHogSender(logger3),
3743
4124
  sentry: getSentrySender(logger3),
3744
4125
  otlp: getOtlpRegistry(logger3),
@@ -3858,6 +4239,22 @@ function emitHttpErrorLog(logger3, level, request, path3, statusCode, responseTi
3858
4239
  }
3859
4240
  });
3860
4241
  }
4242
+ const databuddy = tryGetDatabuddySender(logger3);
4243
+ if (databuddy?.shouldAutoCaptureExceptions()) {
4244
+ databuddy.captureException(captureContext.error ?? error ?? message, {
4245
+ source: "server",
4246
+ warnIfUnavailable: true,
4247
+ properties: {
4248
+ method: request.method,
4249
+ path: path3,
4250
+ status_code: statusCode,
4251
+ ...request.url ? { current_url: request.url } : {},
4252
+ ...getHeaderValue(request.headers, "user-agent") ? { user_agent: getHeaderValue(request.headers, "user-agent") } : {},
4253
+ ...errorLogData.ip ? { ip: errorLogData.ip } : {},
4254
+ payload: errorLogData
4255
+ }
4256
+ });
4257
+ }
3861
4258
  return errorLogData;
3862
4259
  }
3863
4260
  async function parseClientLogPayload(request, body) {
@@ -3949,6 +4346,34 @@ async function handleClientLogIngestion(options) {
3949
4346
  });
3950
4347
  }
3951
4348
  }
4349
+ } else if (payload.connector === "databuddy") {
4350
+ headers["x-blyp-databuddy-status"] = config.databuddy.ready ? "enabled" : "missing";
4351
+ if (config.databuddy.ready) {
4352
+ const forwardedRecord = {
4353
+ timestamp: structuredPayload.receivedAt,
4354
+ level: payload.level,
4355
+ message: `[client] ${payload.message}`,
4356
+ data: structuredPayload
4357
+ };
4358
+ config.databuddy.send(forwardedRecord, {
4359
+ source: "client"
4360
+ });
4361
+ if ((payload.level === "error" || payload.level === "critical") && config.databuddy.shouldAutoCaptureExceptions()) {
4362
+ const clientErrorCandidate = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) && typeof payload.data.message === "string" ? payload.data : payload.message;
4363
+ config.databuddy.captureException(clientErrorCandidate, {
4364
+ source: "client",
4365
+ warnIfUnavailable: true,
4366
+ sessionId: payload.session.sessionId,
4367
+ properties: {
4368
+ page_url: payload.page.url,
4369
+ page_path: payload.page.pathname,
4370
+ client_runtime: payload.device?.runtime,
4371
+ metadata: payload.metadata,
4372
+ payload: structuredPayload
4373
+ }
4374
+ });
4375
+ }
4376
+ }
3952
4377
  } else if (payload.connector === "posthog") {
3953
4378
  headers["x-blyp-posthog-status"] = config.posthog.ready ? "enabled" : "missing";
3954
4379
  if (config.posthog.ready) {