@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.js CHANGED
@@ -15,6 +15,7 @@ var async_hooks = require('async_hooks');
15
15
  var crypto = require('crypto');
16
16
  var Sentry = require('@sentry/node');
17
17
  var node = require('@logtail/node');
18
+ var node$1 = require('@databuddy/sdk/node');
18
19
  var common = require('@nestjs/common');
19
20
  var core = require('@nestjs/core');
20
21
  var rxjs = require('rxjs');
@@ -410,6 +411,7 @@ var CLIENT_LOG_LEVELS = [
410
411
  ];
411
412
  var clientConnectorRequestSchema = zod.z.union([
412
413
  zod.z.literal("betterstack"),
414
+ zod.z.literal("databuddy"),
413
415
  zod.z.literal("posthog"),
414
416
  zod.z.literal("sentry"),
415
417
  zod.z.undefined(),
@@ -450,16 +452,16 @@ function normalizeEndpointPath(path3) {
450
452
  }
451
453
 
452
454
  // src/shared/once.ts
453
- function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()) {
455
+ function createConsoleOnceLogger(method, warnedKeys7 = /* @__PURE__ */ new Set()) {
454
456
  return (key, message, error) => {
455
- if (warnedKeys6.has(key) || typeof console === "undefined") {
457
+ if (warnedKeys7.has(key) || typeof console === "undefined") {
456
458
  return;
457
459
  }
458
460
  const writer = console[method];
459
461
  if (typeof writer !== "function") {
460
462
  return;
461
463
  }
462
- warnedKeys6.add(key);
464
+ warnedKeys7.add(key);
463
465
  if (error === void 0) {
464
466
  writer.call(console, message);
465
467
  return;
@@ -467,11 +469,11 @@ function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()
467
469
  writer.call(console, message, error);
468
470
  };
469
471
  }
470
- function createWarnOnceLogger(warnedKeys6) {
471
- return createConsoleOnceLogger("warn", warnedKeys6);
472
+ function createWarnOnceLogger(warnedKeys7) {
473
+ return createConsoleOnceLogger("warn", warnedKeys7);
472
474
  }
473
- function createErrorOnceLogger(warnedKeys6) {
474
- return createConsoleOnceLogger("error", warnedKeys6);
475
+ function createErrorOnceLogger(warnedKeys7) {
476
+ return createConsoleOnceLogger("error", warnedKeys7);
475
477
  }
476
478
 
477
479
  // src/core/config.ts
@@ -837,6 +839,28 @@ function mergePostHogConnectorConfig(base, override) {
837
839
  }
838
840
  };
839
841
  }
842
+ function mergeDatabuddyConnectorConfig(base, override) {
843
+ const enabled = override?.enabled ?? base?.enabled ?? false;
844
+ const apiKey = override?.apiKey ?? base?.apiKey;
845
+ const websiteId = override?.websiteId ?? base?.websiteId;
846
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
847
+ return {
848
+ enabled,
849
+ mode: override?.mode ?? base?.mode ?? "auto",
850
+ apiKey,
851
+ websiteId,
852
+ namespace: override?.namespace ?? base?.namespace,
853
+ source: override?.source ?? base?.source,
854
+ apiUrl: override?.apiUrl ?? base?.apiUrl,
855
+ debug: override?.debug ?? base?.debug ?? false,
856
+ enableBatching: override?.enableBatching ?? base?.enableBatching ?? true,
857
+ batchSize: override?.batchSize ?? base?.batchSize,
858
+ batchTimeout: override?.batchTimeout ?? base?.batchTimeout,
859
+ maxQueueSize: override?.maxQueueSize ?? base?.maxQueueSize,
860
+ ready,
861
+ status: ready ? "enabled" : "missing"
862
+ };
863
+ }
840
864
  function mergeBetterStackConnectorConfig(base, override) {
841
865
  const sourceToken = override?.sourceToken ?? base?.sourceToken;
842
866
  const ingestingHost = override?.ingestingHost ?? base?.ingestingHost;
@@ -927,6 +951,7 @@ function mergeOTLPConnectorsConfig(base, override) {
927
951
  function mergeConnectorsConfig(base, override) {
928
952
  return {
929
953
  betterstack: mergeBetterStackConnectorConfig(base?.betterstack, override?.betterstack),
954
+ databuddy: mergeDatabuddyConnectorConfig(base?.databuddy, override?.databuddy),
930
955
  posthog: mergePostHogConnectorConfig(base?.posthog, override?.posthog),
931
956
  sentry: mergeSentryConnectorConfig(base?.sentry, override?.sentry),
932
957
  otlp: mergeOTLPConnectorsConfig(base?.otlp, override?.otlp)
@@ -2565,12 +2590,320 @@ function createBetterStackSender(config) {
2565
2590
  };
2566
2591
  }
2567
2592
  var warnedKeys4 = /* @__PURE__ */ new Set();
2593
+ var senderCache = /* @__PURE__ */ new Map();
2568
2594
  var testHooks3 = {};
2569
2595
  var warnOnce5 = createErrorOnceLogger(warnedKeys4);
2570
- function getSentryModule2() {
2571
- return testHooks3.module ?? Sentry__namespace;
2596
+ function registerShutdownHooks3(key, shutdown) {
2597
+ const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2598
+ for (const event of handlers) {
2599
+ process.once(event, () => {
2600
+ void shutdown().catch((error) => {
2601
+ warnOnce5(
2602
+ `${key}:shutdown`,
2603
+ "[Blyp] Failed to flush Databuddy telemetry during shutdown.",
2604
+ error
2605
+ );
2606
+ });
2607
+ });
2608
+ }
2572
2609
  }
2573
2610
  function resolveConnectorConfig3(config) {
2611
+ const connector = isBlypConfig(config) ? config.connectors?.databuddy : config;
2612
+ const enabled = connector?.enabled ?? false;
2613
+ const apiKey = connector?.apiKey;
2614
+ const websiteId = connector?.websiteId;
2615
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
2616
+ return {
2617
+ enabled,
2618
+ mode: connector?.mode ?? "auto",
2619
+ apiKey,
2620
+ websiteId,
2621
+ namespace: connector?.namespace,
2622
+ source: connector?.source,
2623
+ apiUrl: connector?.apiUrl,
2624
+ debug: connector?.debug ?? false,
2625
+ enableBatching: connector?.enableBatching ?? true,
2626
+ batchSize: connector?.batchSize,
2627
+ batchTimeout: connector?.batchTimeout,
2628
+ maxQueueSize: connector?.maxQueueSize,
2629
+ ready,
2630
+ status: ready ? "enabled" : "missing"
2631
+ };
2632
+ }
2633
+ function createDefaultClient2(connector) {
2634
+ return new node$1.Databuddy({
2635
+ apiKey: connector.apiKey ?? "",
2636
+ ...connector.websiteId ? { websiteId: connector.websiteId } : {},
2637
+ ...connector.namespace ? { namespace: connector.namespace } : {},
2638
+ ...connector.source ? { source: connector.source } : {},
2639
+ ...connector.apiUrl ? { apiUrl: connector.apiUrl } : {},
2640
+ debug: connector.debug,
2641
+ enableBatching: connector.enableBatching,
2642
+ ...connector.batchSize !== void 0 ? { batchSize: connector.batchSize } : {},
2643
+ ...connector.batchTimeout !== void 0 ? { batchTimeout: connector.batchTimeout } : {},
2644
+ ...connector.maxQueueSize !== void 0 ? { maxQueueSize: connector.maxQueueSize } : {}
2645
+ });
2646
+ }
2647
+ function getDatabuddySenderKey(connector) {
2648
+ return JSON.stringify({
2649
+ enabled: connector.enabled,
2650
+ mode: connector.mode,
2651
+ apiKey: connector.apiKey ?? null,
2652
+ websiteId: connector.websiteId ?? null,
2653
+ namespace: connector.namespace ?? null,
2654
+ source: connector.source ?? null,
2655
+ apiUrl: connector.apiUrl ?? null,
2656
+ debug: connector.debug,
2657
+ enableBatching: connector.enableBatching,
2658
+ batchSize: connector.batchSize ?? null,
2659
+ batchTimeout: connector.batchTimeout ?? null,
2660
+ maxQueueSize: connector.maxQueueSize ?? null
2661
+ });
2662
+ }
2663
+ function getSessionId(record) {
2664
+ const direct = getField(record, "sessionId");
2665
+ if (hasNonEmptyString(direct)) {
2666
+ return direct;
2667
+ }
2668
+ return getClientSessionField(record, "sessionId");
2669
+ }
2670
+ function getAnonymousId(record) {
2671
+ const direct = getField(record, "anonymousId");
2672
+ if (hasNonEmptyString(direct)) {
2673
+ return direct;
2674
+ }
2675
+ const payload = getPrimaryPayload(record);
2676
+ if (isPlainObject(payload.metadata) && hasNonEmptyString(payload.metadata.databuddyAnonymousId)) {
2677
+ return payload.metadata.databuddyAnonymousId;
2678
+ }
2679
+ return void 0;
2680
+ }
2681
+ function getDatabuddyEventName(record) {
2682
+ const recordType = getRecordType(record);
2683
+ if (hasNonEmptyString(recordType)) {
2684
+ return recordType;
2685
+ }
2686
+ return "log";
2687
+ }
2688
+ function buildRecordProperties(record, source) {
2689
+ const properties = {
2690
+ blyp_level: record.level,
2691
+ blyp_source: source,
2692
+ blyp_payload: serializeLogRecord(record),
2693
+ message: typeof record.message === "string" ? record.message : String(record.message)
2694
+ };
2695
+ const caller = typeof record.caller === "string" ? record.caller : void 0;
2696
+ const groupId = getField(record, "groupId");
2697
+ const method = getField(record, "method");
2698
+ const path3 = getField(record, "path");
2699
+ const status = getField(record, "status");
2700
+ const duration = getField(record, "duration");
2701
+ const pagePath = getClientPageField(record, "pathname");
2702
+ const pageUrl = getClientPageField(record, "url");
2703
+ const sessionId = getClientSessionField(record, "sessionId");
2704
+ const pageId = getClientSessionField(record, "pageId");
2705
+ const ifTruthy = [
2706
+ ["blyp_type", getRecordType(record)],
2707
+ ["caller", caller],
2708
+ ["group_id", groupId],
2709
+ ["method", method],
2710
+ ["path", path3],
2711
+ ["page_path", pagePath],
2712
+ ["page_url", pageUrl],
2713
+ ["session_id", sessionId],
2714
+ ["page_id", pageId]
2715
+ ];
2716
+ const ifDefined = [
2717
+ ["status_code", status],
2718
+ ["duration_ms", duration]
2719
+ ];
2720
+ for (const [key, value] of ifTruthy) {
2721
+ if (value) {
2722
+ properties[key] = value;
2723
+ }
2724
+ }
2725
+ for (const [key, value] of ifDefined) {
2726
+ if (value !== void 0) {
2727
+ properties[key] = value;
2728
+ }
2729
+ }
2730
+ return properties;
2731
+ }
2732
+ function createTrackEvent(record, source) {
2733
+ return {
2734
+ name: getDatabuddyEventName(record),
2735
+ anonymousId: getAnonymousId(record),
2736
+ sessionId: getSessionId(record),
2737
+ properties: buildRecordProperties(record, source)
2738
+ };
2739
+ }
2740
+ function normalizeExceptionProperties2(value) {
2741
+ if (!isPlainObject(value)) {
2742
+ return {};
2743
+ }
2744
+ return normalizeLogValue(value);
2745
+ }
2746
+ function normalizeExceptionInput3(value, fallbackMessage) {
2747
+ if (value instanceof Error) {
2748
+ return {
2749
+ message: value.message || fallbackMessage,
2750
+ properties: {
2751
+ error_type: value.name,
2752
+ ...value.stack ? { stack: value.stack } : {},
2753
+ ...normalizeExceptionProperties2(value)
2754
+ }
2755
+ };
2756
+ }
2757
+ if (isPlainObject(value)) {
2758
+ const message = hasNonEmptyString(value.message) ? value.message : hasNonEmptyString(value.error) ? value.error : fallbackMessage;
2759
+ return {
2760
+ message,
2761
+ properties: normalizeExceptionProperties2(value)
2762
+ };
2763
+ }
2764
+ if (typeof value === "string") {
2765
+ return {
2766
+ message: value,
2767
+ properties: {
2768
+ message: value
2769
+ }
2770
+ };
2771
+ }
2772
+ return {
2773
+ message: fallbackMessage,
2774
+ properties: {
2775
+ value: normalizeLogValue(value)
2776
+ }
2777
+ };
2778
+ }
2779
+ function createDatabuddySender(config) {
2780
+ const connector = resolveConnectorConfig3(config);
2781
+ const senderKey = getDatabuddySenderKey(connector);
2782
+ const cached = senderCache.get(senderKey);
2783
+ if (cached) {
2784
+ return cached;
2785
+ }
2786
+ const key = `${connector.apiUrl ?? "default"}:${connector.mode}:${connector.apiKey ?? "missing"}`;
2787
+ const client = connector.ready ? testHooks3.createClient?.(connector) ?? createDefaultClient2(connector) : void 0;
2788
+ if (client) {
2789
+ registerShutdownHooks3(key, async () => {
2790
+ await client.flush();
2791
+ });
2792
+ }
2793
+ const emitUnavailableWarning = () => {
2794
+ warnOnce5(
2795
+ `databuddy-unavailable:${key}`,
2796
+ "[Blyp] Databuddy connector is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy delivery."
2797
+ );
2798
+ };
2799
+ const emitExceptionUnavailableWarning = () => {
2800
+ warnOnce5(
2801
+ `databuddy-exception-unavailable:${key}`,
2802
+ "[Blyp] Databuddy error tracking is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy exception capture."
2803
+ );
2804
+ };
2805
+ const sender = {
2806
+ enabled: connector.enabled,
2807
+ ready: connector.ready,
2808
+ mode: connector.mode,
2809
+ status: connector.status,
2810
+ shouldAutoForwardServerLogs() {
2811
+ return connector.ready && connector.mode === "auto";
2812
+ },
2813
+ shouldAutoCaptureExceptions() {
2814
+ return connector.ready && connector.mode === "auto";
2815
+ },
2816
+ send(record, options = {}) {
2817
+ if (!connector.ready || !client) {
2818
+ if (options.warnIfUnavailable) {
2819
+ emitUnavailableWarning();
2820
+ }
2821
+ return;
2822
+ }
2823
+ try {
2824
+ const result = client.track(createTrackEvent(record, options.source ?? "server"));
2825
+ if (result && typeof result.catch === "function") {
2826
+ void result.catch((error) => {
2827
+ warnOnce5(
2828
+ `databuddy-send:${key}`,
2829
+ "[Blyp] Failed to deliver log to Databuddy.",
2830
+ error
2831
+ );
2832
+ });
2833
+ }
2834
+ } catch (error) {
2835
+ warnOnce5(
2836
+ `databuddy-send:${key}`,
2837
+ "[Blyp] Failed to deliver log to Databuddy.",
2838
+ error
2839
+ );
2840
+ }
2841
+ },
2842
+ captureException(error, options = {}) {
2843
+ if (!connector.ready || !client) {
2844
+ if (options.warnIfUnavailable) {
2845
+ emitExceptionUnavailableWarning();
2846
+ }
2847
+ return;
2848
+ }
2849
+ const normalized = normalizeExceptionInput3(
2850
+ error,
2851
+ options.source === "client" ? "Client error" : "Server error"
2852
+ );
2853
+ try {
2854
+ const result = client.track({
2855
+ name: "error",
2856
+ anonymousId: options.anonymousId,
2857
+ sessionId: options.sessionId,
2858
+ properties: {
2859
+ message: normalized.message,
2860
+ blyp_source: options.source ?? "server",
2861
+ blyp_level: "error",
2862
+ ...normalized.properties,
2863
+ ...options.properties ?? {}
2864
+ }
2865
+ });
2866
+ if (result && typeof result.catch === "function") {
2867
+ void result.catch((captureError) => {
2868
+ warnOnce5(
2869
+ `databuddy-capture:${key}`,
2870
+ "[Blyp] Failed to capture exception in Databuddy.",
2871
+ captureError
2872
+ );
2873
+ });
2874
+ }
2875
+ } catch (captureError) {
2876
+ warnOnce5(
2877
+ `databuddy-capture:${key}`,
2878
+ "[Blyp] Failed to capture exception in Databuddy.",
2879
+ captureError
2880
+ );
2881
+ }
2882
+ },
2883
+ async flush() {
2884
+ try {
2885
+ if (client) {
2886
+ await client.flush();
2887
+ }
2888
+ } catch (error) {
2889
+ warnOnce5(
2890
+ `databuddy-flush:${key}`,
2891
+ "[Blyp] Failed to flush Databuddy telemetry.",
2892
+ error
2893
+ );
2894
+ }
2895
+ }
2896
+ };
2897
+ senderCache.set(senderKey, sender);
2898
+ return sender;
2899
+ }
2900
+ var warnedKeys5 = /* @__PURE__ */ new Set();
2901
+ var testHooks4 = {};
2902
+ var warnOnce6 = createErrorOnceLogger(warnedKeys5);
2903
+ function getSentryModule2() {
2904
+ return testHooks4.module ?? Sentry__namespace;
2905
+ }
2906
+ function resolveConnectorConfig4(config) {
2574
2907
  const connector = isBlypConfig(config) ? config.connectors?.sentry : config;
2575
2908
  const enabled = connector?.enabled ?? false;
2576
2909
  const dsn = connector?.dsn;
@@ -2715,7 +3048,7 @@ function hasConfigMismatch(connector, client) {
2715
3048
  return hasNonEmptyString(connector.dsn) && connector.dsn !== options.dsn || hasNonEmptyString(connector.environment) && connector.environment !== options.environment || hasNonEmptyString(connector.release) && connector.release !== options.release;
2716
3049
  }
2717
3050
  function createSentrySender(config) {
2718
- const connector = resolveConnectorConfig3(config);
3051
+ const connector = resolveConnectorConfig4(config);
2719
3052
  const key = `${connector.mode}:${connector.dsn ?? "missing"}`;
2720
3053
  const module = getSentryModule2();
2721
3054
  let client = connector.enabled ? module.getClient() : void 0;
@@ -2729,7 +3062,7 @@ function createSentrySender(config) {
2729
3062
  });
2730
3063
  client = module.getClient();
2731
3064
  } catch (error) {
2732
- warnOnce5(
3065
+ warnOnce6(
2733
3066
  `sentry-init:${key}`,
2734
3067
  "[Blyp] Failed to initialize Sentry. Skipping Sentry delivery.",
2735
3068
  error
@@ -2737,14 +3070,14 @@ function createSentrySender(config) {
2737
3070
  }
2738
3071
  }
2739
3072
  if (client && hasConfigMismatch(connector, client)) {
2740
- warnOnce5(
3073
+ warnOnce6(
2741
3074
  `sentry-mismatch:${key}`,
2742
3075
  "[Blyp] Sentry is already initialized with different options. Reusing the existing Sentry client."
2743
3076
  );
2744
3077
  }
2745
3078
  const ready = connector.enabled && client !== void 0;
2746
3079
  const emitUnavailableWarning = () => {
2747
- warnOnce5(
3080
+ warnOnce6(
2748
3081
  `sentry-unavailable:${key}`,
2749
3082
  "[Blyp] Sentry connector is not configured. Skipping Sentry delivery."
2750
3083
  );
@@ -2770,7 +3103,7 @@ function createSentrySender(config) {
2770
3103
  try {
2771
3104
  logMethod(record.message, attributes);
2772
3105
  } catch (error) {
2773
- warnOnce5(
3106
+ warnOnce6(
2774
3107
  `sentry-log:${key}`,
2775
3108
  "[Blyp] Failed to deliver log to Sentry.",
2776
3109
  error
@@ -2788,7 +3121,7 @@ function createSentrySender(config) {
2788
3121
  module.captureException(exception);
2789
3122
  });
2790
3123
  } catch (error) {
2791
- warnOnce5(
3124
+ warnOnce6(
2792
3125
  `sentry-exception:${key}`,
2793
3126
  "[Blyp] Failed to capture exception in Sentry.",
2794
3127
  error
@@ -2799,7 +3132,7 @@ function createSentrySender(config) {
2799
3132
  try {
2800
3133
  await module.flush(2e3);
2801
3134
  } catch (error) {
2802
- warnOnce5(
3135
+ warnOnce6(
2803
3136
  `sentry-flush:${key}`,
2804
3137
  "[Blyp] Failed to flush Sentry logs.",
2805
3138
  error
@@ -2808,9 +3141,9 @@ function createSentrySender(config) {
2808
3141
  }
2809
3142
  };
2810
3143
  }
2811
- var warnedKeys5 = /* @__PURE__ */ new Set();
2812
- var testHooks4 = {};
2813
- var warnOnce6 = createErrorOnceLogger(warnedKeys5);
3144
+ var warnedKeys6 = /* @__PURE__ */ new Set();
3145
+ var testHooks5 = {};
3146
+ var warnOnce7 = createErrorOnceLogger(warnedKeys6);
2814
3147
  function normalizeOTLPRecord(record, connector, source = "server") {
2815
3148
  const severity = resolveSeverity2(record.level);
2816
3149
  const body = typeof record.message === "string" ? record.message : String(record.message);
@@ -2875,14 +3208,14 @@ function resolveSeverity2(level) {
2875
3208
  return { text: "info", number: apiLogs.SeverityNumber.INFO };
2876
3209
  }
2877
3210
  }
2878
- function registerShutdownHooks3(key, shutdown) {
3211
+ function registerShutdownHooks4(key, shutdown) {
2879
3212
  const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2880
3213
  for (const event of handlers) {
2881
3214
  process.once(event, async () => {
2882
3215
  try {
2883
3216
  await shutdown();
2884
3217
  } catch (error) {
2885
- warnOnce6(
3218
+ warnOnce7(
2886
3219
  `${key}:shutdown`,
2887
3220
  "[Blyp] Failed to flush OTLP logs during shutdown.",
2888
3221
  error
@@ -2959,7 +3292,7 @@ function createUnavailableSender(name, connector) {
2959
3292
  const senderName = name || connector?.name || "otlp";
2960
3293
  const key = `${senderName}:${connector?.serviceName ?? "blyp-app"}:${connector?.endpoint ?? "missing"}`;
2961
3294
  const emitUnavailableWarning = () => {
2962
- warnOnce6(
3295
+ warnOnce7(
2963
3296
  `otlp-unavailable:${key}`,
2964
3297
  `[Blyp] OTLP target "${senderName}" is not configured or not ready. Skipping OTLP delivery.`
2965
3298
  );
@@ -2990,7 +3323,7 @@ function createSender(connector) {
2990
3323
  ...connector,
2991
3324
  headers: resolveTransportHeaders(connector)
2992
3325
  };
2993
- const transport = testHooks4.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
3326
+ const transport = testHooks5.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
2994
3327
  return {
2995
3328
  name: connector.name,
2996
3329
  enabled: connector.enabled,
@@ -3006,7 +3339,7 @@ function createSender(connector) {
3006
3339
  const result = transport.emit(normalized);
3007
3340
  if (result && typeof result.catch === "function") {
3008
3341
  void result.catch((error) => {
3009
- warnOnce6(
3342
+ warnOnce7(
3010
3343
  `otlp-emit:${key}`,
3011
3344
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
3012
3345
  error
@@ -3014,7 +3347,7 @@ function createSender(connector) {
3014
3347
  });
3015
3348
  }
3016
3349
  } catch (error) {
3017
- warnOnce6(
3350
+ warnOnce7(
3018
3351
  `otlp-emit:${key}`,
3019
3352
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
3020
3353
  error
@@ -3027,7 +3360,7 @@ function createSender(connector) {
3027
3360
  await transport.flush();
3028
3361
  }
3029
3362
  } catch (error) {
3030
- warnOnce6(
3363
+ warnOnce7(
3031
3364
  `otlp-flush:${key}`,
3032
3365
  `[Blyp] Failed to flush OTLP logs for target "${connector.name}".`,
3033
3366
  error
@@ -3056,7 +3389,7 @@ function createOTLPRegistry(config) {
3056
3389
  await Promise.all(Array.from(senders.values()).map((sender) => sender.flush()));
3057
3390
  }
3058
3391
  };
3059
- registerShutdownHooks3("otlp-registry", () => registry.flush());
3392
+ registerShutdownHooks4("otlp-registry", () => registry.flush());
3060
3393
  return registry;
3061
3394
  }
3062
3395
  var _RuntimeDetector = class _RuntimeDetector {
@@ -3447,6 +3780,9 @@ function getPostHogSender(logger3) {
3447
3780
  function getBetterStackSender(logger3) {
3448
3781
  return getLoggerFactory(logger3).betterstack;
3449
3782
  }
3783
+ function getDatabuddySender(logger3) {
3784
+ return getLoggerFactory(logger3).databuddy;
3785
+ }
3450
3786
  function tryGetPostHogSender(logger3) {
3451
3787
  try {
3452
3788
  return getPostHogSender(logger3);
@@ -3461,6 +3797,13 @@ function tryGetBetterStackSender(logger3) {
3461
3797
  return null;
3462
3798
  }
3463
3799
  }
3800
+ function tryGetDatabuddySender(logger3) {
3801
+ try {
3802
+ return getDatabuddySender(logger3);
3803
+ } catch {
3804
+ return null;
3805
+ }
3806
+ }
3464
3807
  function getSentrySender(logger3) {
3465
3808
  return getLoggerFactory(logger3).sentry;
3466
3809
  }
@@ -3520,6 +3863,18 @@ function maybeSendToBetterStack(betterstack, record) {
3520
3863
  }
3521
3864
  betterstack.send(record, { source: "server", warnIfUnavailable: true });
3522
3865
  }
3866
+ function maybeSendToDatabuddy(databuddy, record) {
3867
+ if (isClientLogRecord(record)) {
3868
+ return;
3869
+ }
3870
+ if (!databuddy.shouldAutoForwardServerLogs()) {
3871
+ if (databuddy.enabled && !databuddy.ready) {
3872
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3873
+ }
3874
+ return;
3875
+ }
3876
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3877
+ }
3523
3878
  function maybeSendToSentry(sentry, record) {
3524
3879
  if (isClientLogRecord(record)) {
3525
3880
  return;
@@ -3540,7 +3895,7 @@ function maybeSendToOTLP(otlp, record) {
3540
3895
  sender.send(record, { source: "server", warnIfUnavailable: true });
3541
3896
  }
3542
3897
  }
3543
- function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry, otlp, bindings = {}, source = "root") {
3898
+ function createLoggerInstance(rootRawLogger, sink, betterstack, databuddy, posthog, sentry, otlp, bindings = {}, source = "root") {
3544
3899
  const rawLogger = Object.keys(bindings).length > 0 ? rootRawLogger.child(bindings) : rootRawLogger;
3545
3900
  const writeRecord = (level, message, args, writeSource = source) => {
3546
3901
  if (writeSource === "root" && shouldDropRootLogWrite()) {
@@ -3566,6 +3921,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3566
3921
  );
3567
3922
  sink.write(record);
3568
3923
  maybeSendToBetterStack(betterstack, record);
3924
+ maybeSendToDatabuddy(databuddy, record);
3569
3925
  maybeSendToPostHog(posthog, record);
3570
3926
  maybeSendToSentry(sentry, record);
3571
3927
  maybeSendToOTLP(otlp, record);
@@ -3589,6 +3945,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3589
3945
  sink.write(record);
3590
3946
  }
3591
3947
  maybeSendToBetterStack(betterstack, record);
3948
+ maybeSendToDatabuddy(databuddy, record);
3592
3949
  maybeSendToPostHog(posthog, record);
3593
3950
  maybeSendToSentry(sentry, record);
3594
3951
  maybeSendToOTLP(otlp, record);
@@ -3622,8 +3979,26 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3622
3979
  }
3623
3980
  writeRecord("table", message, data === void 0 ? [] : [data]);
3624
3981
  },
3625
- flush: () => sink.flush(),
3626
- shutdown: () => sink.shutdown(),
3982
+ flush: async () => {
3983
+ await sink.flush();
3984
+ await Promise.allSettled([
3985
+ betterstack.flush(),
3986
+ databuddy.flush(),
3987
+ posthog.flush(),
3988
+ sentry.flush(),
3989
+ otlp.flush()
3990
+ ]);
3991
+ },
3992
+ shutdown: async () => {
3993
+ await sink.shutdown();
3994
+ await Promise.allSettled([
3995
+ betterstack.flush(),
3996
+ databuddy.flush(),
3997
+ posthog.flush(),
3998
+ sentry.flush(),
3999
+ otlp.flush()
4000
+ ]);
4001
+ },
3627
4002
  createStructuredLog: (groupId, initial) => {
3628
4003
  return createStructuredLogForLogger(logger3, groupId, {
3629
4004
  initialFields: initial
@@ -3635,6 +4010,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3635
4010
  rootRawLogger,
3636
4011
  sink,
3637
4012
  betterstack,
4013
+ databuddy,
3638
4014
  posthog,
3639
4015
  sentry,
3640
4016
  otlp,
@@ -3645,6 +4021,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3645
4021
  [LOGGER_FACTORY]: {
3646
4022
  bindings,
3647
4023
  betterstack,
4024
+ databuddy,
3648
4025
  posthog,
3649
4026
  sentry,
3650
4027
  otlp,
@@ -3654,6 +4031,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3654
4031
  rootRawLogger,
3655
4032
  sink,
3656
4033
  betterstack,
4034
+ databuddy,
3657
4035
  posthog,
3658
4036
  sentry,
3659
4037
  otlp,
@@ -3677,6 +4055,7 @@ function createBaseLogger(config) {
3677
4055
  const rawLogger = createPinoLogger(resolvedConfig);
3678
4056
  const sink = createPrimarySink(resolvedConfig);
3679
4057
  const betterstack = createBetterStackSender(resolvedConfig);
4058
+ const databuddy = createDatabuddySender(resolvedConfig);
3680
4059
  const posthog = createPostHogSender(resolvedConfig);
3681
4060
  const sentry = createSentrySender(resolvedConfig);
3682
4061
  const otlp = createOTLPRegistry(resolvedConfig);
@@ -3684,6 +4063,7 @@ function createBaseLogger(config) {
3684
4063
  rawLogger,
3685
4064
  sink,
3686
4065
  betterstack,
4066
+ databuddy,
3687
4067
  posthog,
3688
4068
  sentry,
3689
4069
  otlp
@@ -3766,6 +4146,7 @@ function resolveServerLogger(config = {}, loggerOverride) {
3766
4146
  return {
3767
4147
  logger: logger3,
3768
4148
  betterstack: getBetterStackSender(logger3),
4149
+ databuddy: getDatabuddySender(logger3),
3769
4150
  posthog: getPostHogSender(logger3),
3770
4151
  sentry: getSentrySender(logger3),
3771
4152
  otlp: getOtlpRegistry(logger3),
@@ -3885,6 +4266,22 @@ function emitHttpErrorLog(logger3, level, request, path3, statusCode, responseTi
3885
4266
  }
3886
4267
  });
3887
4268
  }
4269
+ const databuddy = tryGetDatabuddySender(logger3);
4270
+ if (databuddy?.shouldAutoCaptureExceptions()) {
4271
+ databuddy.captureException(captureContext.error ?? error ?? message, {
4272
+ source: "server",
4273
+ warnIfUnavailable: true,
4274
+ properties: {
4275
+ method: request.method,
4276
+ path: path3,
4277
+ status_code: statusCode,
4278
+ ...request.url ? { current_url: request.url } : {},
4279
+ ...getHeaderValue(request.headers, "user-agent") ? { user_agent: getHeaderValue(request.headers, "user-agent") } : {},
4280
+ ...errorLogData.ip ? { ip: errorLogData.ip } : {},
4281
+ payload: errorLogData
4282
+ }
4283
+ });
4284
+ }
3888
4285
  return errorLogData;
3889
4286
  }
3890
4287
  async function parseClientLogPayload(request, body) {
@@ -3976,6 +4373,34 @@ async function handleClientLogIngestion(options) {
3976
4373
  });
3977
4374
  }
3978
4375
  }
4376
+ } else if (payload.connector === "databuddy") {
4377
+ headers["x-blyp-databuddy-status"] = config.databuddy.ready ? "enabled" : "missing";
4378
+ if (config.databuddy.ready) {
4379
+ const forwardedRecord = {
4380
+ timestamp: structuredPayload.receivedAt,
4381
+ level: payload.level,
4382
+ message: `[client] ${payload.message}`,
4383
+ data: structuredPayload
4384
+ };
4385
+ config.databuddy.send(forwardedRecord, {
4386
+ source: "client"
4387
+ });
4388
+ if ((payload.level === "error" || payload.level === "critical") && config.databuddy.shouldAutoCaptureExceptions()) {
4389
+ const clientErrorCandidate = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) && typeof payload.data.message === "string" ? payload.data : payload.message;
4390
+ config.databuddy.captureException(clientErrorCandidate, {
4391
+ source: "client",
4392
+ warnIfUnavailable: true,
4393
+ sessionId: payload.session.sessionId,
4394
+ properties: {
4395
+ page_url: payload.page.url,
4396
+ page_path: payload.page.pathname,
4397
+ client_runtime: payload.device?.runtime,
4398
+ metadata: payload.metadata,
4399
+ payload: structuredPayload
4400
+ }
4401
+ });
4402
+ }
4403
+ }
3979
4404
  } else if (payload.connector === "posthog") {
3980
4405
  headers["x-blyp-posthog-status"] = config.posthog.ready ? "enabled" : "missing";
3981
4406
  if (config.posthog.ready) {