@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/elysia.js CHANGED
@@ -16,6 +16,7 @@ var async_hooks = require('async_hooks');
16
16
  var crypto = require('crypto');
17
17
  var Sentry = require('@sentry/node');
18
18
  var node = require('@logtail/node');
19
+ var node$1 = require('@databuddy/sdk/node');
19
20
 
20
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
22
 
@@ -360,6 +361,7 @@ var CLIENT_LOG_LEVELS = [
360
361
  ];
361
362
  var clientConnectorRequestSchema = zod.z.union([
362
363
  zod.z.literal("betterstack"),
364
+ zod.z.literal("databuddy"),
363
365
  zod.z.literal("posthog"),
364
366
  zod.z.literal("sentry"),
365
367
  zod.z.undefined(),
@@ -400,16 +402,16 @@ function normalizeEndpointPath(path3) {
400
402
  }
401
403
 
402
404
  // src/shared/once.ts
403
- function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()) {
405
+ function createConsoleOnceLogger(method, warnedKeys7 = /* @__PURE__ */ new Set()) {
404
406
  return (key, message, error) => {
405
- if (warnedKeys6.has(key) || typeof console === "undefined") {
407
+ if (warnedKeys7.has(key) || typeof console === "undefined") {
406
408
  return;
407
409
  }
408
410
  const writer = console[method];
409
411
  if (typeof writer !== "function") {
410
412
  return;
411
413
  }
412
- warnedKeys6.add(key);
414
+ warnedKeys7.add(key);
413
415
  if (error === void 0) {
414
416
  writer.call(console, message);
415
417
  return;
@@ -417,11 +419,11 @@ function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()
417
419
  writer.call(console, message, error);
418
420
  };
419
421
  }
420
- function createWarnOnceLogger(warnedKeys6) {
421
- return createConsoleOnceLogger("warn", warnedKeys6);
422
+ function createWarnOnceLogger(warnedKeys7) {
423
+ return createConsoleOnceLogger("warn", warnedKeys7);
422
424
  }
423
- function createErrorOnceLogger(warnedKeys6) {
424
- return createConsoleOnceLogger("error", warnedKeys6);
425
+ function createErrorOnceLogger(warnedKeys7) {
426
+ return createConsoleOnceLogger("error", warnedKeys7);
425
427
  }
426
428
 
427
429
  // src/core/config.ts
@@ -787,6 +789,28 @@ function mergePostHogConnectorConfig(base, override) {
787
789
  }
788
790
  };
789
791
  }
792
+ function mergeDatabuddyConnectorConfig(base, override) {
793
+ const enabled = override?.enabled ?? base?.enabled ?? false;
794
+ const apiKey = override?.apiKey ?? base?.apiKey;
795
+ const websiteId = override?.websiteId ?? base?.websiteId;
796
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
797
+ return {
798
+ enabled,
799
+ mode: override?.mode ?? base?.mode ?? "auto",
800
+ apiKey,
801
+ websiteId,
802
+ namespace: override?.namespace ?? base?.namespace,
803
+ source: override?.source ?? base?.source,
804
+ apiUrl: override?.apiUrl ?? base?.apiUrl,
805
+ debug: override?.debug ?? base?.debug ?? false,
806
+ enableBatching: override?.enableBatching ?? base?.enableBatching ?? true,
807
+ batchSize: override?.batchSize ?? base?.batchSize,
808
+ batchTimeout: override?.batchTimeout ?? base?.batchTimeout,
809
+ maxQueueSize: override?.maxQueueSize ?? base?.maxQueueSize,
810
+ ready,
811
+ status: ready ? "enabled" : "missing"
812
+ };
813
+ }
790
814
  function mergeBetterStackConnectorConfig(base, override) {
791
815
  const sourceToken = override?.sourceToken ?? base?.sourceToken;
792
816
  const ingestingHost = override?.ingestingHost ?? base?.ingestingHost;
@@ -877,6 +901,7 @@ function mergeOTLPConnectorsConfig(base, override) {
877
901
  function mergeConnectorsConfig(base, override) {
878
902
  return {
879
903
  betterstack: mergeBetterStackConnectorConfig(base?.betterstack, override?.betterstack),
904
+ databuddy: mergeDatabuddyConnectorConfig(base?.databuddy, override?.databuddy),
880
905
  posthog: mergePostHogConnectorConfig(base?.posthog, override?.posthog),
881
906
  sentry: mergeSentryConnectorConfig(base?.sentry, override?.sentry),
882
907
  otlp: mergeOTLPConnectorsConfig(base?.otlp, override?.otlp)
@@ -2534,12 +2559,320 @@ function createBetterStackSender(config) {
2534
2559
  };
2535
2560
  }
2536
2561
  var warnedKeys4 = /* @__PURE__ */ new Set();
2562
+ var senderCache = /* @__PURE__ */ new Map();
2537
2563
  var testHooks3 = {};
2538
2564
  var warnOnce5 = createErrorOnceLogger(warnedKeys4);
2539
- function getSentryModule2() {
2540
- return testHooks3.module ?? Sentry__namespace;
2565
+ function registerShutdownHooks3(key, shutdown) {
2566
+ const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2567
+ for (const event of handlers) {
2568
+ process.once(event, () => {
2569
+ void shutdown().catch((error) => {
2570
+ warnOnce5(
2571
+ `${key}:shutdown`,
2572
+ "[Blyp] Failed to flush Databuddy telemetry during shutdown.",
2573
+ error
2574
+ );
2575
+ });
2576
+ });
2577
+ }
2541
2578
  }
2542
2579
  function resolveConnectorConfig3(config) {
2580
+ const connector = isBlypConfig(config) ? config.connectors?.databuddy : config;
2581
+ const enabled = connector?.enabled ?? false;
2582
+ const apiKey = connector?.apiKey;
2583
+ const websiteId = connector?.websiteId;
2584
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
2585
+ return {
2586
+ enabled,
2587
+ mode: connector?.mode ?? "auto",
2588
+ apiKey,
2589
+ websiteId,
2590
+ namespace: connector?.namespace,
2591
+ source: connector?.source,
2592
+ apiUrl: connector?.apiUrl,
2593
+ debug: connector?.debug ?? false,
2594
+ enableBatching: connector?.enableBatching ?? true,
2595
+ batchSize: connector?.batchSize,
2596
+ batchTimeout: connector?.batchTimeout,
2597
+ maxQueueSize: connector?.maxQueueSize,
2598
+ ready,
2599
+ status: ready ? "enabled" : "missing"
2600
+ };
2601
+ }
2602
+ function createDefaultClient2(connector) {
2603
+ return new node$1.Databuddy({
2604
+ apiKey: connector.apiKey ?? "",
2605
+ ...connector.websiteId ? { websiteId: connector.websiteId } : {},
2606
+ ...connector.namespace ? { namespace: connector.namespace } : {},
2607
+ ...connector.source ? { source: connector.source } : {},
2608
+ ...connector.apiUrl ? { apiUrl: connector.apiUrl } : {},
2609
+ debug: connector.debug,
2610
+ enableBatching: connector.enableBatching,
2611
+ ...connector.batchSize !== void 0 ? { batchSize: connector.batchSize } : {},
2612
+ ...connector.batchTimeout !== void 0 ? { batchTimeout: connector.batchTimeout } : {},
2613
+ ...connector.maxQueueSize !== void 0 ? { maxQueueSize: connector.maxQueueSize } : {}
2614
+ });
2615
+ }
2616
+ function getDatabuddySenderKey(connector) {
2617
+ return JSON.stringify({
2618
+ enabled: connector.enabled,
2619
+ mode: connector.mode,
2620
+ apiKey: connector.apiKey ?? null,
2621
+ websiteId: connector.websiteId ?? null,
2622
+ namespace: connector.namespace ?? null,
2623
+ source: connector.source ?? null,
2624
+ apiUrl: connector.apiUrl ?? null,
2625
+ debug: connector.debug,
2626
+ enableBatching: connector.enableBatching,
2627
+ batchSize: connector.batchSize ?? null,
2628
+ batchTimeout: connector.batchTimeout ?? null,
2629
+ maxQueueSize: connector.maxQueueSize ?? null
2630
+ });
2631
+ }
2632
+ function getSessionId(record) {
2633
+ const direct = getField(record, "sessionId");
2634
+ if (hasNonEmptyString(direct)) {
2635
+ return direct;
2636
+ }
2637
+ return getClientSessionField(record, "sessionId");
2638
+ }
2639
+ function getAnonymousId(record) {
2640
+ const direct = getField(record, "anonymousId");
2641
+ if (hasNonEmptyString(direct)) {
2642
+ return direct;
2643
+ }
2644
+ const payload = getPrimaryPayload(record);
2645
+ if (isPlainObject(payload.metadata) && hasNonEmptyString(payload.metadata.databuddyAnonymousId)) {
2646
+ return payload.metadata.databuddyAnonymousId;
2647
+ }
2648
+ return void 0;
2649
+ }
2650
+ function getDatabuddyEventName(record) {
2651
+ const recordType = getRecordType(record);
2652
+ if (hasNonEmptyString(recordType)) {
2653
+ return recordType;
2654
+ }
2655
+ return "log";
2656
+ }
2657
+ function buildRecordProperties(record, source) {
2658
+ const properties = {
2659
+ blyp_level: record.level,
2660
+ blyp_source: source,
2661
+ blyp_payload: serializeLogRecord(record),
2662
+ message: typeof record.message === "string" ? record.message : String(record.message)
2663
+ };
2664
+ const caller = typeof record.caller === "string" ? record.caller : void 0;
2665
+ const groupId = getField(record, "groupId");
2666
+ const method = getField(record, "method");
2667
+ const path3 = getField(record, "path");
2668
+ const status = getField(record, "status");
2669
+ const duration = getField(record, "duration");
2670
+ const pagePath = getClientPageField(record, "pathname");
2671
+ const pageUrl = getClientPageField(record, "url");
2672
+ const sessionId = getClientSessionField(record, "sessionId");
2673
+ const pageId = getClientSessionField(record, "pageId");
2674
+ const ifTruthy = [
2675
+ ["blyp_type", getRecordType(record)],
2676
+ ["caller", caller],
2677
+ ["group_id", groupId],
2678
+ ["method", method],
2679
+ ["path", path3],
2680
+ ["page_path", pagePath],
2681
+ ["page_url", pageUrl],
2682
+ ["session_id", sessionId],
2683
+ ["page_id", pageId]
2684
+ ];
2685
+ const ifDefined = [
2686
+ ["status_code", status],
2687
+ ["duration_ms", duration]
2688
+ ];
2689
+ for (const [key, value] of ifTruthy) {
2690
+ if (value) {
2691
+ properties[key] = value;
2692
+ }
2693
+ }
2694
+ for (const [key, value] of ifDefined) {
2695
+ if (value !== void 0) {
2696
+ properties[key] = value;
2697
+ }
2698
+ }
2699
+ return properties;
2700
+ }
2701
+ function createTrackEvent(record, source) {
2702
+ return {
2703
+ name: getDatabuddyEventName(record),
2704
+ anonymousId: getAnonymousId(record),
2705
+ sessionId: getSessionId(record),
2706
+ properties: buildRecordProperties(record, source)
2707
+ };
2708
+ }
2709
+ function normalizeExceptionProperties2(value) {
2710
+ if (!isPlainObject(value)) {
2711
+ return {};
2712
+ }
2713
+ return normalizeLogValue(value);
2714
+ }
2715
+ function normalizeExceptionInput3(value, fallbackMessage) {
2716
+ if (value instanceof Error) {
2717
+ return {
2718
+ message: value.message || fallbackMessage,
2719
+ properties: {
2720
+ error_type: value.name,
2721
+ ...value.stack ? { stack: value.stack } : {},
2722
+ ...normalizeExceptionProperties2(value)
2723
+ }
2724
+ };
2725
+ }
2726
+ if (isPlainObject(value)) {
2727
+ const message = hasNonEmptyString(value.message) ? value.message : hasNonEmptyString(value.error) ? value.error : fallbackMessage;
2728
+ return {
2729
+ message,
2730
+ properties: normalizeExceptionProperties2(value)
2731
+ };
2732
+ }
2733
+ if (typeof value === "string") {
2734
+ return {
2735
+ message: value,
2736
+ properties: {
2737
+ message: value
2738
+ }
2739
+ };
2740
+ }
2741
+ return {
2742
+ message: fallbackMessage,
2743
+ properties: {
2744
+ value: normalizeLogValue(value)
2745
+ }
2746
+ };
2747
+ }
2748
+ function createDatabuddySender(config) {
2749
+ const connector = resolveConnectorConfig3(config);
2750
+ const senderKey = getDatabuddySenderKey(connector);
2751
+ const cached = senderCache.get(senderKey);
2752
+ if (cached) {
2753
+ return cached;
2754
+ }
2755
+ const key = `${connector.apiUrl ?? "default"}:${connector.mode}:${connector.apiKey ?? "missing"}`;
2756
+ const client = connector.ready ? testHooks3.createClient?.(connector) ?? createDefaultClient2(connector) : void 0;
2757
+ if (client) {
2758
+ registerShutdownHooks3(key, async () => {
2759
+ await client.flush();
2760
+ });
2761
+ }
2762
+ const emitUnavailableWarning = () => {
2763
+ warnOnce5(
2764
+ `databuddy-unavailable:${key}`,
2765
+ "[Blyp] Databuddy connector is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy delivery."
2766
+ );
2767
+ };
2768
+ const emitExceptionUnavailableWarning = () => {
2769
+ warnOnce5(
2770
+ `databuddy-exception-unavailable:${key}`,
2771
+ "[Blyp] Databuddy error tracking is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy exception capture."
2772
+ );
2773
+ };
2774
+ const sender = {
2775
+ enabled: connector.enabled,
2776
+ ready: connector.ready,
2777
+ mode: connector.mode,
2778
+ status: connector.status,
2779
+ shouldAutoForwardServerLogs() {
2780
+ return connector.ready && connector.mode === "auto";
2781
+ },
2782
+ shouldAutoCaptureExceptions() {
2783
+ return connector.ready && connector.mode === "auto";
2784
+ },
2785
+ send(record, options = {}) {
2786
+ if (!connector.ready || !client) {
2787
+ if (options.warnIfUnavailable) {
2788
+ emitUnavailableWarning();
2789
+ }
2790
+ return;
2791
+ }
2792
+ try {
2793
+ const result = client.track(createTrackEvent(record, options.source ?? "server"));
2794
+ if (result && typeof result.catch === "function") {
2795
+ void result.catch((error) => {
2796
+ warnOnce5(
2797
+ `databuddy-send:${key}`,
2798
+ "[Blyp] Failed to deliver log to Databuddy.",
2799
+ error
2800
+ );
2801
+ });
2802
+ }
2803
+ } catch (error) {
2804
+ warnOnce5(
2805
+ `databuddy-send:${key}`,
2806
+ "[Blyp] Failed to deliver log to Databuddy.",
2807
+ error
2808
+ );
2809
+ }
2810
+ },
2811
+ captureException(error, options = {}) {
2812
+ if (!connector.ready || !client) {
2813
+ if (options.warnIfUnavailable) {
2814
+ emitExceptionUnavailableWarning();
2815
+ }
2816
+ return;
2817
+ }
2818
+ const normalized = normalizeExceptionInput3(
2819
+ error,
2820
+ options.source === "client" ? "Client error" : "Server error"
2821
+ );
2822
+ try {
2823
+ const result = client.track({
2824
+ name: "error",
2825
+ anonymousId: options.anonymousId,
2826
+ sessionId: options.sessionId,
2827
+ properties: {
2828
+ message: normalized.message,
2829
+ blyp_source: options.source ?? "server",
2830
+ blyp_level: "error",
2831
+ ...normalized.properties,
2832
+ ...options.properties ?? {}
2833
+ }
2834
+ });
2835
+ if (result && typeof result.catch === "function") {
2836
+ void result.catch((captureError) => {
2837
+ warnOnce5(
2838
+ `databuddy-capture:${key}`,
2839
+ "[Blyp] Failed to capture exception in Databuddy.",
2840
+ captureError
2841
+ );
2842
+ });
2843
+ }
2844
+ } catch (captureError) {
2845
+ warnOnce5(
2846
+ `databuddy-capture:${key}`,
2847
+ "[Blyp] Failed to capture exception in Databuddy.",
2848
+ captureError
2849
+ );
2850
+ }
2851
+ },
2852
+ async flush() {
2853
+ try {
2854
+ if (client) {
2855
+ await client.flush();
2856
+ }
2857
+ } catch (error) {
2858
+ warnOnce5(
2859
+ `databuddy-flush:${key}`,
2860
+ "[Blyp] Failed to flush Databuddy telemetry.",
2861
+ error
2862
+ );
2863
+ }
2864
+ }
2865
+ };
2866
+ senderCache.set(senderKey, sender);
2867
+ return sender;
2868
+ }
2869
+ var warnedKeys5 = /* @__PURE__ */ new Set();
2870
+ var testHooks4 = {};
2871
+ var warnOnce6 = createErrorOnceLogger(warnedKeys5);
2872
+ function getSentryModule2() {
2873
+ return testHooks4.module ?? Sentry__namespace;
2874
+ }
2875
+ function resolveConnectorConfig4(config) {
2543
2876
  const connector = isBlypConfig(config) ? config.connectors?.sentry : config;
2544
2877
  const enabled = connector?.enabled ?? false;
2545
2878
  const dsn = connector?.dsn;
@@ -2684,7 +3017,7 @@ function hasConfigMismatch(connector, client) {
2684
3017
  return hasNonEmptyString(connector.dsn) && connector.dsn !== options.dsn || hasNonEmptyString(connector.environment) && connector.environment !== options.environment || hasNonEmptyString(connector.release) && connector.release !== options.release;
2685
3018
  }
2686
3019
  function createSentrySender(config) {
2687
- const connector = resolveConnectorConfig3(config);
3020
+ const connector = resolveConnectorConfig4(config);
2688
3021
  const key = `${connector.mode}:${connector.dsn ?? "missing"}`;
2689
3022
  const module = getSentryModule2();
2690
3023
  let client = connector.enabled ? module.getClient() : void 0;
@@ -2698,7 +3031,7 @@ function createSentrySender(config) {
2698
3031
  });
2699
3032
  client = module.getClient();
2700
3033
  } catch (error) {
2701
- warnOnce5(
3034
+ warnOnce6(
2702
3035
  `sentry-init:${key}`,
2703
3036
  "[Blyp] Failed to initialize Sentry. Skipping Sentry delivery.",
2704
3037
  error
@@ -2706,14 +3039,14 @@ function createSentrySender(config) {
2706
3039
  }
2707
3040
  }
2708
3041
  if (client && hasConfigMismatch(connector, client)) {
2709
- warnOnce5(
3042
+ warnOnce6(
2710
3043
  `sentry-mismatch:${key}`,
2711
3044
  "[Blyp] Sentry is already initialized with different options. Reusing the existing Sentry client."
2712
3045
  );
2713
3046
  }
2714
3047
  const ready = connector.enabled && client !== void 0;
2715
3048
  const emitUnavailableWarning = () => {
2716
- warnOnce5(
3049
+ warnOnce6(
2717
3050
  `sentry-unavailable:${key}`,
2718
3051
  "[Blyp] Sentry connector is not configured. Skipping Sentry delivery."
2719
3052
  );
@@ -2739,7 +3072,7 @@ function createSentrySender(config) {
2739
3072
  try {
2740
3073
  logMethod(record.message, attributes);
2741
3074
  } catch (error) {
2742
- warnOnce5(
3075
+ warnOnce6(
2743
3076
  `sentry-log:${key}`,
2744
3077
  "[Blyp] Failed to deliver log to Sentry.",
2745
3078
  error
@@ -2757,7 +3090,7 @@ function createSentrySender(config) {
2757
3090
  module.captureException(exception);
2758
3091
  });
2759
3092
  } catch (error) {
2760
- warnOnce5(
3093
+ warnOnce6(
2761
3094
  `sentry-exception:${key}`,
2762
3095
  "[Blyp] Failed to capture exception in Sentry.",
2763
3096
  error
@@ -2768,7 +3101,7 @@ function createSentrySender(config) {
2768
3101
  try {
2769
3102
  await module.flush(2e3);
2770
3103
  } catch (error) {
2771
- warnOnce5(
3104
+ warnOnce6(
2772
3105
  `sentry-flush:${key}`,
2773
3106
  "[Blyp] Failed to flush Sentry logs.",
2774
3107
  error
@@ -2777,9 +3110,9 @@ function createSentrySender(config) {
2777
3110
  }
2778
3111
  };
2779
3112
  }
2780
- var warnedKeys5 = /* @__PURE__ */ new Set();
2781
- var testHooks4 = {};
2782
- var warnOnce6 = createErrorOnceLogger(warnedKeys5);
3113
+ var warnedKeys6 = /* @__PURE__ */ new Set();
3114
+ var testHooks5 = {};
3115
+ var warnOnce7 = createErrorOnceLogger(warnedKeys6);
2783
3116
  function normalizeOTLPRecord(record, connector, source = "server") {
2784
3117
  const severity = resolveSeverity2(record.level);
2785
3118
  const body = typeof record.message === "string" ? record.message : String(record.message);
@@ -2844,14 +3177,14 @@ function resolveSeverity2(level) {
2844
3177
  return { text: "info", number: apiLogs.SeverityNumber.INFO };
2845
3178
  }
2846
3179
  }
2847
- function registerShutdownHooks3(key, shutdown) {
3180
+ function registerShutdownHooks4(key, shutdown) {
2848
3181
  const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2849
3182
  for (const event of handlers) {
2850
3183
  process.once(event, async () => {
2851
3184
  try {
2852
3185
  await shutdown();
2853
3186
  } catch (error) {
2854
- warnOnce6(
3187
+ warnOnce7(
2855
3188
  `${key}:shutdown`,
2856
3189
  "[Blyp] Failed to flush OTLP logs during shutdown.",
2857
3190
  error
@@ -2928,7 +3261,7 @@ function createUnavailableSender(name, connector) {
2928
3261
  const senderName = name || connector?.name || "otlp";
2929
3262
  const key = `${senderName}:${connector?.serviceName ?? "blyp-app"}:${connector?.endpoint ?? "missing"}`;
2930
3263
  const emitUnavailableWarning = () => {
2931
- warnOnce6(
3264
+ warnOnce7(
2932
3265
  `otlp-unavailable:${key}`,
2933
3266
  `[Blyp] OTLP target "${senderName}" is not configured or not ready. Skipping OTLP delivery.`
2934
3267
  );
@@ -2959,7 +3292,7 @@ function createSender(connector) {
2959
3292
  ...connector,
2960
3293
  headers: resolveTransportHeaders(connector)
2961
3294
  };
2962
- const transport = testHooks4.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
3295
+ const transport = testHooks5.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
2963
3296
  return {
2964
3297
  name: connector.name,
2965
3298
  enabled: connector.enabled,
@@ -2975,7 +3308,7 @@ function createSender(connector) {
2975
3308
  const result = transport.emit(normalized);
2976
3309
  if (result && typeof result.catch === "function") {
2977
3310
  void result.catch((error) => {
2978
- warnOnce6(
3311
+ warnOnce7(
2979
3312
  `otlp-emit:${key}`,
2980
3313
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2981
3314
  error
@@ -2983,7 +3316,7 @@ function createSender(connector) {
2983
3316
  });
2984
3317
  }
2985
3318
  } catch (error) {
2986
- warnOnce6(
3319
+ warnOnce7(
2987
3320
  `otlp-emit:${key}`,
2988
3321
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2989
3322
  error
@@ -2996,7 +3329,7 @@ function createSender(connector) {
2996
3329
  await transport.flush();
2997
3330
  }
2998
3331
  } catch (error) {
2999
- warnOnce6(
3332
+ warnOnce7(
3000
3333
  `otlp-flush:${key}`,
3001
3334
  `[Blyp] Failed to flush OTLP logs for target "${connector.name}".`,
3002
3335
  error
@@ -3025,7 +3358,7 @@ function createOTLPRegistry(config) {
3025
3358
  await Promise.all(Array.from(senders.values()).map((sender) => sender.flush()));
3026
3359
  }
3027
3360
  };
3028
- registerShutdownHooks3("otlp-registry", () => registry.flush());
3361
+ registerShutdownHooks4("otlp-registry", () => registry.flush());
3029
3362
  return registry;
3030
3363
  }
3031
3364
  var _RuntimeDetector = class _RuntimeDetector {
@@ -3416,6 +3749,9 @@ function getPostHogSender(logger2) {
3416
3749
  function getBetterStackSender(logger2) {
3417
3750
  return getLoggerFactory(logger2).betterstack;
3418
3751
  }
3752
+ function getDatabuddySender(logger2) {
3753
+ return getLoggerFactory(logger2).databuddy;
3754
+ }
3419
3755
  function tryGetPostHogSender(logger2) {
3420
3756
  try {
3421
3757
  return getPostHogSender(logger2);
@@ -3430,6 +3766,13 @@ function tryGetBetterStackSender(logger2) {
3430
3766
  return null;
3431
3767
  }
3432
3768
  }
3769
+ function tryGetDatabuddySender(logger2) {
3770
+ try {
3771
+ return getDatabuddySender(logger2);
3772
+ } catch {
3773
+ return null;
3774
+ }
3775
+ }
3433
3776
  function getSentrySender(logger2) {
3434
3777
  return getLoggerFactory(logger2).sentry;
3435
3778
  }
@@ -3489,6 +3832,18 @@ function maybeSendToBetterStack(betterstack, record) {
3489
3832
  }
3490
3833
  betterstack.send(record, { source: "server", warnIfUnavailable: true });
3491
3834
  }
3835
+ function maybeSendToDatabuddy(databuddy, record) {
3836
+ if (isClientLogRecord(record)) {
3837
+ return;
3838
+ }
3839
+ if (!databuddy.shouldAutoForwardServerLogs()) {
3840
+ if (databuddy.enabled && !databuddy.ready) {
3841
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3842
+ }
3843
+ return;
3844
+ }
3845
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3846
+ }
3492
3847
  function maybeSendToSentry(sentry, record) {
3493
3848
  if (isClientLogRecord(record)) {
3494
3849
  return;
@@ -3509,7 +3864,7 @@ function maybeSendToOTLP(otlp, record) {
3509
3864
  sender.send(record, { source: "server", warnIfUnavailable: true });
3510
3865
  }
3511
3866
  }
3512
- function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry, otlp, bindings = {}, source = "root") {
3867
+ function createLoggerInstance(rootRawLogger, sink, betterstack, databuddy, posthog, sentry, otlp, bindings = {}, source = "root") {
3513
3868
  const rawLogger = Object.keys(bindings).length > 0 ? rootRawLogger.child(bindings) : rootRawLogger;
3514
3869
  const writeRecord = (level, message, args, writeSource = source) => {
3515
3870
  if (writeSource === "root" && shouldDropRootLogWrite()) {
@@ -3535,6 +3890,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3535
3890
  );
3536
3891
  sink.write(record);
3537
3892
  maybeSendToBetterStack(betterstack, record);
3893
+ maybeSendToDatabuddy(databuddy, record);
3538
3894
  maybeSendToPostHog(posthog, record);
3539
3895
  maybeSendToSentry(sentry, record);
3540
3896
  maybeSendToOTLP(otlp, record);
@@ -3558,6 +3914,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3558
3914
  sink.write(record);
3559
3915
  }
3560
3916
  maybeSendToBetterStack(betterstack, record);
3917
+ maybeSendToDatabuddy(databuddy, record);
3561
3918
  maybeSendToPostHog(posthog, record);
3562
3919
  maybeSendToSentry(sentry, record);
3563
3920
  maybeSendToOTLP(otlp, record);
@@ -3591,8 +3948,26 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3591
3948
  }
3592
3949
  writeRecord("table", message, data === void 0 ? [] : [data]);
3593
3950
  },
3594
- flush: () => sink.flush(),
3595
- shutdown: () => sink.shutdown(),
3951
+ flush: async () => {
3952
+ await sink.flush();
3953
+ await Promise.allSettled([
3954
+ betterstack.flush(),
3955
+ databuddy.flush(),
3956
+ posthog.flush(),
3957
+ sentry.flush(),
3958
+ otlp.flush()
3959
+ ]);
3960
+ },
3961
+ shutdown: async () => {
3962
+ await sink.shutdown();
3963
+ await Promise.allSettled([
3964
+ betterstack.flush(),
3965
+ databuddy.flush(),
3966
+ posthog.flush(),
3967
+ sentry.flush(),
3968
+ otlp.flush()
3969
+ ]);
3970
+ },
3596
3971
  createStructuredLog: (groupId, initial) => {
3597
3972
  return createStructuredLogForLogger(logger2, groupId, {
3598
3973
  initialFields: initial
@@ -3604,6 +3979,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3604
3979
  rootRawLogger,
3605
3980
  sink,
3606
3981
  betterstack,
3982
+ databuddy,
3607
3983
  posthog,
3608
3984
  sentry,
3609
3985
  otlp,
@@ -3614,6 +3990,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3614
3990
  [LOGGER_FACTORY]: {
3615
3991
  bindings,
3616
3992
  betterstack,
3993
+ databuddy,
3617
3994
  posthog,
3618
3995
  sentry,
3619
3996
  otlp,
@@ -3623,6 +4000,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3623
4000
  rootRawLogger,
3624
4001
  sink,
3625
4002
  betterstack,
4003
+ databuddy,
3626
4004
  posthog,
3627
4005
  sentry,
3628
4006
  otlp,
@@ -3646,6 +4024,7 @@ function createBaseLogger(config) {
3646
4024
  const rawLogger = createPinoLogger(resolvedConfig);
3647
4025
  const sink = createPrimarySink(resolvedConfig);
3648
4026
  const betterstack = createBetterStackSender(resolvedConfig);
4027
+ const databuddy = createDatabuddySender(resolvedConfig);
3649
4028
  const posthog = createPostHogSender(resolvedConfig);
3650
4029
  const sentry = createSentrySender(resolvedConfig);
3651
4030
  const otlp = createOTLPRegistry(resolvedConfig);
@@ -3653,6 +4032,7 @@ function createBaseLogger(config) {
3653
4032
  rawLogger,
3654
4033
  sink,
3655
4034
  betterstack,
4035
+ databuddy,
3656
4036
  posthog,
3657
4037
  sentry,
3658
4038
  otlp
@@ -3735,6 +4115,7 @@ function resolveServerLogger(config = {}, loggerOverride) {
3735
4115
  return {
3736
4116
  logger: logger2,
3737
4117
  betterstack: getBetterStackSender(logger2),
4118
+ databuddy: getDatabuddySender(logger2),
3738
4119
  posthog: getPostHogSender(logger2),
3739
4120
  sentry: getSentrySender(logger2),
3740
4121
  otlp: getOtlpRegistry(logger2),
@@ -3854,6 +4235,22 @@ function emitHttpErrorLog(logger2, level, request, path3, statusCode, responseTi
3854
4235
  }
3855
4236
  });
3856
4237
  }
4238
+ const databuddy = tryGetDatabuddySender(logger2);
4239
+ if (databuddy?.shouldAutoCaptureExceptions()) {
4240
+ databuddy.captureException(captureContext.error ?? error ?? message, {
4241
+ source: "server",
4242
+ warnIfUnavailable: true,
4243
+ properties: {
4244
+ method: request.method,
4245
+ path: path3,
4246
+ status_code: statusCode,
4247
+ ...request.url ? { current_url: request.url } : {},
4248
+ ...getHeaderValue(request.headers, "user-agent") ? { user_agent: getHeaderValue(request.headers, "user-agent") } : {},
4249
+ ...errorLogData.ip ? { ip: errorLogData.ip } : {},
4250
+ payload: errorLogData
4251
+ }
4252
+ });
4253
+ }
3857
4254
  return errorLogData;
3858
4255
  }
3859
4256
  async function parseClientLogPayload(request, body) {
@@ -3945,6 +4342,34 @@ async function handleClientLogIngestion(options) {
3945
4342
  });
3946
4343
  }
3947
4344
  }
4345
+ } else if (payload.connector === "databuddy") {
4346
+ headers["x-blyp-databuddy-status"] = config.databuddy.ready ? "enabled" : "missing";
4347
+ if (config.databuddy.ready) {
4348
+ const forwardedRecord = {
4349
+ timestamp: structuredPayload.receivedAt,
4350
+ level: payload.level,
4351
+ message: `[client] ${payload.message}`,
4352
+ data: structuredPayload
4353
+ };
4354
+ config.databuddy.send(forwardedRecord, {
4355
+ source: "client"
4356
+ });
4357
+ if ((payload.level === "error" || payload.level === "critical") && config.databuddy.shouldAutoCaptureExceptions()) {
4358
+ const clientErrorCandidate = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) && typeof payload.data.message === "string" ? payload.data : payload.message;
4359
+ config.databuddy.captureException(clientErrorCandidate, {
4360
+ source: "client",
4361
+ warnIfUnavailable: true,
4362
+ sessionId: payload.session.sessionId,
4363
+ properties: {
4364
+ page_url: payload.page.url,
4365
+ page_path: payload.page.pathname,
4366
+ client_runtime: payload.device?.runtime,
4367
+ metadata: payload.metadata,
4368
+ payload: structuredPayload
4369
+ }
4370
+ });
4371
+ }
4372
+ }
3948
4373
  } else if (payload.connector === "posthog") {
3949
4374
  headers["x-blyp-posthog-status"] = config.posthog.ready ? "enabled" : "missing";
3950
4375
  if (config.posthog.ready) {