@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/index.mjs CHANGED
@@ -8,6 +8,7 @@ import { gzipSync, gunzipSync } from 'fflate';
8
8
  import { randomUUID } from 'crypto';
9
9
  import * as Sentry from '@sentry/node';
10
10
  import { Logtail } from '@logtail/node';
11
+ import { Databuddy } from '@databuddy/sdk/node';
11
12
  import { SeverityNumber } from '@opentelemetry/api-logs';
12
13
  import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
13
14
  import { resourceFromAttributes } from '@opentelemetry/resources';
@@ -197,6 +198,7 @@ var CLIENT_LOG_LEVELS = [
197
198
  ];
198
199
  var clientConnectorRequestSchema = z.union([
199
200
  z.literal("betterstack"),
201
+ z.literal("databuddy"),
200
202
  z.literal("posthog"),
201
203
  z.literal("sentry"),
202
204
  z.undefined(),
@@ -237,16 +239,16 @@ function normalizeEndpointPath(path3) {
237
239
  }
238
240
 
239
241
  // src/shared/once.ts
240
- function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()) {
242
+ function createConsoleOnceLogger(method, warnedKeys7 = /* @__PURE__ */ new Set()) {
241
243
  return (key, message, error) => {
242
- if (warnedKeys6.has(key) || typeof console === "undefined") {
244
+ if (warnedKeys7.has(key) || typeof console === "undefined") {
243
245
  return;
244
246
  }
245
247
  const writer = console[method];
246
248
  if (typeof writer !== "function") {
247
249
  return;
248
250
  }
249
- warnedKeys6.add(key);
251
+ warnedKeys7.add(key);
250
252
  if (error === void 0) {
251
253
  writer.call(console, message);
252
254
  return;
@@ -254,11 +256,11 @@ function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()
254
256
  writer.call(console, message, error);
255
257
  };
256
258
  }
257
- function createWarnOnceLogger(warnedKeys6) {
258
- return createConsoleOnceLogger("warn", warnedKeys6);
259
+ function createWarnOnceLogger(warnedKeys7) {
260
+ return createConsoleOnceLogger("warn", warnedKeys7);
259
261
  }
260
- function createErrorOnceLogger(warnedKeys6) {
261
- return createConsoleOnceLogger("error", warnedKeys6);
262
+ function createErrorOnceLogger(warnedKeys7) {
263
+ return createConsoleOnceLogger("error", warnedKeys7);
262
264
  }
263
265
 
264
266
  // src/core/config.ts
@@ -624,6 +626,28 @@ function mergePostHogConnectorConfig(base, override) {
624
626
  }
625
627
  };
626
628
  }
629
+ function mergeDatabuddyConnectorConfig(base, override) {
630
+ const enabled = override?.enabled ?? base?.enabled ?? false;
631
+ const apiKey = override?.apiKey ?? base?.apiKey;
632
+ const websiteId = override?.websiteId ?? base?.websiteId;
633
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
634
+ return {
635
+ enabled,
636
+ mode: override?.mode ?? base?.mode ?? "auto",
637
+ apiKey,
638
+ websiteId,
639
+ namespace: override?.namespace ?? base?.namespace,
640
+ source: override?.source ?? base?.source,
641
+ apiUrl: override?.apiUrl ?? base?.apiUrl,
642
+ debug: override?.debug ?? base?.debug ?? false,
643
+ enableBatching: override?.enableBatching ?? base?.enableBatching ?? true,
644
+ batchSize: override?.batchSize ?? base?.batchSize,
645
+ batchTimeout: override?.batchTimeout ?? base?.batchTimeout,
646
+ maxQueueSize: override?.maxQueueSize ?? base?.maxQueueSize,
647
+ ready,
648
+ status: ready ? "enabled" : "missing"
649
+ };
650
+ }
627
651
  function mergeBetterStackConnectorConfig(base, override) {
628
652
  const sourceToken = override?.sourceToken ?? base?.sourceToken;
629
653
  const ingestingHost = override?.ingestingHost ?? base?.ingestingHost;
@@ -714,6 +738,7 @@ function mergeOTLPConnectorsConfig(base, override) {
714
738
  function mergeConnectorsConfig(base, override) {
715
739
  return {
716
740
  betterstack: mergeBetterStackConnectorConfig(base?.betterstack, override?.betterstack),
741
+ databuddy: mergeDatabuddyConnectorConfig(base?.databuddy, override?.databuddy),
717
742
  posthog: mergePostHogConnectorConfig(base?.posthog, override?.posthog),
718
743
  sentry: mergeSentryConnectorConfig(base?.sentry, override?.sentry),
719
744
  otlp: mergeOTLPConnectorsConfig(base?.otlp, override?.otlp)
@@ -1830,10 +1855,318 @@ function createBetterStackSender(config) {
1830
1855
  }
1831
1856
  };
1832
1857
  }
1833
- var PREVIOUSLY_CAPTURED_ERROR_KEY2 = "__posthog_previously_captured_error";
1834
1858
  var warnedKeys3 = /* @__PURE__ */ new Set();
1859
+ var senderCache = /* @__PURE__ */ new Map();
1835
1860
  var testHooks2 = {};
1836
1861
  var warnOnce4 = createErrorOnceLogger(warnedKeys3);
1862
+ function registerShutdownHooks2(key, shutdown) {
1863
+ const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
1864
+ for (const event of handlers) {
1865
+ process.once(event, () => {
1866
+ void shutdown().catch((error) => {
1867
+ warnOnce4(
1868
+ `${key}:shutdown`,
1869
+ "[Blyp] Failed to flush Databuddy telemetry during shutdown.",
1870
+ error
1871
+ );
1872
+ });
1873
+ });
1874
+ }
1875
+ }
1876
+ function resolveConnectorConfig2(config) {
1877
+ const connector = isBlypConfig(config) ? config.connectors?.databuddy : config;
1878
+ const enabled = connector?.enabled ?? false;
1879
+ const apiKey = connector?.apiKey;
1880
+ const websiteId = connector?.websiteId;
1881
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
1882
+ return {
1883
+ enabled,
1884
+ mode: connector?.mode ?? "auto",
1885
+ apiKey,
1886
+ websiteId,
1887
+ namespace: connector?.namespace,
1888
+ source: connector?.source,
1889
+ apiUrl: connector?.apiUrl,
1890
+ debug: connector?.debug ?? false,
1891
+ enableBatching: connector?.enableBatching ?? true,
1892
+ batchSize: connector?.batchSize,
1893
+ batchTimeout: connector?.batchTimeout,
1894
+ maxQueueSize: connector?.maxQueueSize,
1895
+ ready,
1896
+ status: ready ? "enabled" : "missing"
1897
+ };
1898
+ }
1899
+ function createDefaultClient2(connector) {
1900
+ return new Databuddy({
1901
+ apiKey: connector.apiKey ?? "",
1902
+ ...connector.websiteId ? { websiteId: connector.websiteId } : {},
1903
+ ...connector.namespace ? { namespace: connector.namespace } : {},
1904
+ ...connector.source ? { source: connector.source } : {},
1905
+ ...connector.apiUrl ? { apiUrl: connector.apiUrl } : {},
1906
+ debug: connector.debug,
1907
+ enableBatching: connector.enableBatching,
1908
+ ...connector.batchSize !== void 0 ? { batchSize: connector.batchSize } : {},
1909
+ ...connector.batchTimeout !== void 0 ? { batchTimeout: connector.batchTimeout } : {},
1910
+ ...connector.maxQueueSize !== void 0 ? { maxQueueSize: connector.maxQueueSize } : {}
1911
+ });
1912
+ }
1913
+ function getDatabuddySenderKey(connector) {
1914
+ return JSON.stringify({
1915
+ enabled: connector.enabled,
1916
+ mode: connector.mode,
1917
+ apiKey: connector.apiKey ?? null,
1918
+ websiteId: connector.websiteId ?? null,
1919
+ namespace: connector.namespace ?? null,
1920
+ source: connector.source ?? null,
1921
+ apiUrl: connector.apiUrl ?? null,
1922
+ debug: connector.debug,
1923
+ enableBatching: connector.enableBatching,
1924
+ batchSize: connector.batchSize ?? null,
1925
+ batchTimeout: connector.batchTimeout ?? null,
1926
+ maxQueueSize: connector.maxQueueSize ?? null
1927
+ });
1928
+ }
1929
+ function getSessionId(record) {
1930
+ const direct = getField(record, "sessionId");
1931
+ if (hasNonEmptyString(direct)) {
1932
+ return direct;
1933
+ }
1934
+ return getClientSessionField(record, "sessionId");
1935
+ }
1936
+ function getAnonymousId(record) {
1937
+ const direct = getField(record, "anonymousId");
1938
+ if (hasNonEmptyString(direct)) {
1939
+ return direct;
1940
+ }
1941
+ const payload = getPrimaryPayload(record);
1942
+ if (isPlainObject(payload.metadata) && hasNonEmptyString(payload.metadata.databuddyAnonymousId)) {
1943
+ return payload.metadata.databuddyAnonymousId;
1944
+ }
1945
+ return void 0;
1946
+ }
1947
+ function getDatabuddyEventName(record) {
1948
+ const recordType = getRecordType(record);
1949
+ if (hasNonEmptyString(recordType)) {
1950
+ return recordType;
1951
+ }
1952
+ return "log";
1953
+ }
1954
+ function buildRecordProperties(record, source) {
1955
+ const properties = {
1956
+ blyp_level: record.level,
1957
+ blyp_source: source,
1958
+ blyp_payload: serializeLogRecord(record),
1959
+ message: typeof record.message === "string" ? record.message : String(record.message)
1960
+ };
1961
+ const caller = typeof record.caller === "string" ? record.caller : void 0;
1962
+ const groupId = getField(record, "groupId");
1963
+ const method = getField(record, "method");
1964
+ const path3 = getField(record, "path");
1965
+ const status = getField(record, "status");
1966
+ const duration = getField(record, "duration");
1967
+ const pagePath = getClientPageField(record, "pathname");
1968
+ const pageUrl = getClientPageField(record, "url");
1969
+ const sessionId = getClientSessionField(record, "sessionId");
1970
+ const pageId = getClientSessionField(record, "pageId");
1971
+ const ifTruthy = [
1972
+ ["blyp_type", getRecordType(record)],
1973
+ ["caller", caller],
1974
+ ["group_id", groupId],
1975
+ ["method", method],
1976
+ ["path", path3],
1977
+ ["page_path", pagePath],
1978
+ ["page_url", pageUrl],
1979
+ ["session_id", sessionId],
1980
+ ["page_id", pageId]
1981
+ ];
1982
+ const ifDefined = [
1983
+ ["status_code", status],
1984
+ ["duration_ms", duration]
1985
+ ];
1986
+ for (const [key, value] of ifTruthy) {
1987
+ if (value) {
1988
+ properties[key] = value;
1989
+ }
1990
+ }
1991
+ for (const [key, value] of ifDefined) {
1992
+ if (value !== void 0) {
1993
+ properties[key] = value;
1994
+ }
1995
+ }
1996
+ return properties;
1997
+ }
1998
+ function createTrackEvent(record, source) {
1999
+ return {
2000
+ name: getDatabuddyEventName(record),
2001
+ anonymousId: getAnonymousId(record),
2002
+ sessionId: getSessionId(record),
2003
+ properties: buildRecordProperties(record, source)
2004
+ };
2005
+ }
2006
+ function normalizeExceptionProperties(value) {
2007
+ if (!isPlainObject(value)) {
2008
+ return {};
2009
+ }
2010
+ return normalizeLogValue(value);
2011
+ }
2012
+ function normalizeExceptionInput2(value, fallbackMessage) {
2013
+ if (value instanceof Error) {
2014
+ return {
2015
+ message: value.message || fallbackMessage,
2016
+ properties: {
2017
+ error_type: value.name,
2018
+ ...value.stack ? { stack: value.stack } : {},
2019
+ ...normalizeExceptionProperties(value)
2020
+ }
2021
+ };
2022
+ }
2023
+ if (isPlainObject(value)) {
2024
+ const message = hasNonEmptyString(value.message) ? value.message : hasNonEmptyString(value.error) ? value.error : fallbackMessage;
2025
+ return {
2026
+ message,
2027
+ properties: normalizeExceptionProperties(value)
2028
+ };
2029
+ }
2030
+ if (typeof value === "string") {
2031
+ return {
2032
+ message: value,
2033
+ properties: {
2034
+ message: value
2035
+ }
2036
+ };
2037
+ }
2038
+ return {
2039
+ message: fallbackMessage,
2040
+ properties: {
2041
+ value: normalizeLogValue(value)
2042
+ }
2043
+ };
2044
+ }
2045
+ function createDatabuddySender(config) {
2046
+ const connector = resolveConnectorConfig2(config);
2047
+ const senderKey = getDatabuddySenderKey(connector);
2048
+ const cached = senderCache.get(senderKey);
2049
+ if (cached) {
2050
+ return cached;
2051
+ }
2052
+ const key = `${connector.apiUrl ?? "default"}:${connector.mode}:${connector.apiKey ?? "missing"}`;
2053
+ const client = connector.ready ? testHooks2.createClient?.(connector) ?? createDefaultClient2(connector) : void 0;
2054
+ if (client) {
2055
+ registerShutdownHooks2(key, async () => {
2056
+ await client.flush();
2057
+ });
2058
+ }
2059
+ const emitUnavailableWarning = () => {
2060
+ warnOnce4(
2061
+ `databuddy-unavailable:${key}`,
2062
+ "[Blyp] Databuddy connector is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy delivery."
2063
+ );
2064
+ };
2065
+ const emitExceptionUnavailableWarning = () => {
2066
+ warnOnce4(
2067
+ `databuddy-exception-unavailable:${key}`,
2068
+ "[Blyp] Databuddy error tracking is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy exception capture."
2069
+ );
2070
+ };
2071
+ const sender = {
2072
+ enabled: connector.enabled,
2073
+ ready: connector.ready,
2074
+ mode: connector.mode,
2075
+ status: connector.status,
2076
+ shouldAutoForwardServerLogs() {
2077
+ return connector.ready && connector.mode === "auto";
2078
+ },
2079
+ shouldAutoCaptureExceptions() {
2080
+ return connector.ready && connector.mode === "auto";
2081
+ },
2082
+ send(record, options = {}) {
2083
+ if (!connector.ready || !client) {
2084
+ if (options.warnIfUnavailable) {
2085
+ emitUnavailableWarning();
2086
+ }
2087
+ return;
2088
+ }
2089
+ try {
2090
+ const result = client.track(createTrackEvent(record, options.source ?? "server"));
2091
+ if (result && typeof result.catch === "function") {
2092
+ void result.catch((error) => {
2093
+ warnOnce4(
2094
+ `databuddy-send:${key}`,
2095
+ "[Blyp] Failed to deliver log to Databuddy.",
2096
+ error
2097
+ );
2098
+ });
2099
+ }
2100
+ } catch (error) {
2101
+ warnOnce4(
2102
+ `databuddy-send:${key}`,
2103
+ "[Blyp] Failed to deliver log to Databuddy.",
2104
+ error
2105
+ );
2106
+ }
2107
+ },
2108
+ captureException(error, options = {}) {
2109
+ if (!connector.ready || !client) {
2110
+ if (options.warnIfUnavailable) {
2111
+ emitExceptionUnavailableWarning();
2112
+ }
2113
+ return;
2114
+ }
2115
+ const normalized = normalizeExceptionInput2(
2116
+ error,
2117
+ options.source === "client" ? "Client error" : "Server error"
2118
+ );
2119
+ try {
2120
+ const result = client.track({
2121
+ name: "error",
2122
+ anonymousId: options.anonymousId,
2123
+ sessionId: options.sessionId,
2124
+ properties: {
2125
+ message: normalized.message,
2126
+ blyp_source: options.source ?? "server",
2127
+ blyp_level: "error",
2128
+ ...normalized.properties,
2129
+ ...options.properties ?? {}
2130
+ }
2131
+ });
2132
+ if (result && typeof result.catch === "function") {
2133
+ void result.catch((captureError) => {
2134
+ warnOnce4(
2135
+ `databuddy-capture:${key}`,
2136
+ "[Blyp] Failed to capture exception in Databuddy.",
2137
+ captureError
2138
+ );
2139
+ });
2140
+ }
2141
+ } catch (captureError) {
2142
+ warnOnce4(
2143
+ `databuddy-capture:${key}`,
2144
+ "[Blyp] Failed to capture exception in Databuddy.",
2145
+ captureError
2146
+ );
2147
+ }
2148
+ },
2149
+ async flush() {
2150
+ try {
2151
+ if (client) {
2152
+ await client.flush();
2153
+ }
2154
+ } catch (error) {
2155
+ warnOnce4(
2156
+ `databuddy-flush:${key}`,
2157
+ "[Blyp] Failed to flush Databuddy telemetry.",
2158
+ error
2159
+ );
2160
+ }
2161
+ }
2162
+ };
2163
+ senderCache.set(senderKey, sender);
2164
+ return sender;
2165
+ }
2166
+ var PREVIOUSLY_CAPTURED_ERROR_KEY2 = "__posthog_previously_captured_error";
2167
+ var warnedKeys4 = /* @__PURE__ */ new Set();
2168
+ var testHooks3 = {};
2169
+ var warnOnce5 = createErrorOnceLogger(warnedKeys4);
1837
2170
  function normalizeHost(host) {
1838
2171
  const trimmed = (host || "https://us.i.posthog.com").trim();
1839
2172
  return trimmed.replace(/\/+$/, "");
@@ -1874,7 +2207,7 @@ function buildRecordAttributes(record, source) {
1874
2207
  for (const [k, v] of ifDefined) if (v !== void 0) attributes[k] = v;
1875
2208
  return attributes;
1876
2209
  }
1877
- function normalizeExceptionProperties(value) {
2210
+ function normalizeExceptionProperties2(value) {
1878
2211
  if (!isPlainObject(value)) {
1879
2212
  return {};
1880
2213
  }
@@ -1906,18 +2239,18 @@ function createSyntheticError(message, source) {
1906
2239
  assignExceptionField(error, "details", source.details);
1907
2240
  return error;
1908
2241
  }
1909
- function normalizeExceptionInput2(input, fallbackMessage = "Unknown error") {
2242
+ function normalizeExceptionInput3(input, fallbackMessage = "Unknown error") {
1910
2243
  if (input instanceof Error) {
1911
2244
  return {
1912
2245
  error: input,
1913
- properties: normalizeExceptionProperties(input)
2246
+ properties: normalizeExceptionProperties2(input)
1914
2247
  };
1915
2248
  }
1916
2249
  if (isPlainObject(input)) {
1917
2250
  const message = hasNonEmptyString(input.message) ? input.message : hasNonEmptyString(input.error) ? input.error : fallbackMessage;
1918
2251
  return {
1919
2252
  error: createSyntheticError(message, input),
1920
- properties: normalizeExceptionProperties(input)
2253
+ properties: normalizeExceptionProperties2(input)
1921
2254
  };
1922
2255
  }
1923
2256
  if (typeof input === "string") {
@@ -1993,12 +2326,12 @@ function resolveSeverity(level) {
1993
2326
  return { text: "info", number: SeverityNumber.INFO };
1994
2327
  }
1995
2328
  }
1996
- function registerShutdownHooks2(key, shutdown) {
2329
+ function registerShutdownHooks3(key, shutdown) {
1997
2330
  const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
1998
2331
  for (const event of handlers) {
1999
2332
  process.once(event, () => {
2000
2333
  void shutdown().catch((error) => {
2001
- warnOnce4(
2334
+ warnOnce5(
2002
2335
  `${key}:shutdown`,
2003
2336
  "[Blyp] Failed to flush PostHog telemetry during shutdown.",
2004
2337
  error
@@ -2052,7 +2385,7 @@ function createDefaultExceptionClient(connector) {
2052
2385
  }
2053
2386
  };
2054
2387
  }
2055
- function resolveConnectorConfig2(config) {
2388
+ function resolveConnectorConfig3(config) {
2056
2389
  const connector = isBlypConfig(config) ? config.connectors?.posthog : config;
2057
2390
  const enabled = connector?.enabled ?? false;
2058
2391
  const projectKey = connector?.projectKey;
@@ -2075,11 +2408,11 @@ function resolveConnectorConfig2(config) {
2075
2408
  };
2076
2409
  }
2077
2410
  function createPostHogSender(config) {
2078
- const connector = resolveConnectorConfig2(config);
2411
+ const connector = resolveConnectorConfig3(config);
2079
2412
  const key = `${connector.serviceName}:${connector.host}:${connector.mode}`;
2080
2413
  const ready = connector.enabled === true && hasNonEmptyString(connector.projectKey);
2081
- const transport = ready ? testHooks2.createTransport?.(connector) ?? createDefaultTransport(connector) : void 0;
2082
- const exceptionClient = connector.errorTracking.ready ? testHooks2.createExceptionClient?.(connector) ?? createDefaultExceptionClient(connector) : void 0;
2414
+ const transport = ready ? testHooks3.createTransport?.(connector) ?? createDefaultTransport(connector) : void 0;
2415
+ const exceptionClient = connector.errorTracking.ready ? testHooks3.createExceptionClient?.(connector) ?? createDefaultExceptionClient(connector) : void 0;
2083
2416
  const shutdown = async () => {
2084
2417
  if (transport?.shutdown) {
2085
2418
  await transport.shutdown();
@@ -2091,16 +2424,16 @@ function createPostHogSender(config) {
2091
2424
  }
2092
2425
  };
2093
2426
  if (transport || exceptionClient) {
2094
- registerShutdownHooks2(key, shutdown);
2427
+ registerShutdownHooks3(key, shutdown);
2095
2428
  }
2096
2429
  const emitUnavailableWarning = () => {
2097
- warnOnce4(
2430
+ warnOnce5(
2098
2431
  `posthog-unavailable:${key}`,
2099
2432
  "[Blyp] PostHog connector is not configured. Skipping PostHog delivery."
2100
2433
  );
2101
2434
  };
2102
2435
  const emitExceptionUnavailableWarning = () => {
2103
- warnOnce4(
2436
+ warnOnce5(
2104
2437
  `posthog-exception-unavailable:${key}`,
2105
2438
  "[Blyp] PostHog error tracking is not configured. Skipping PostHog exception capture."
2106
2439
  );
@@ -2138,7 +2471,7 @@ function createPostHogSender(config) {
2138
2471
  const result = transport.emit(normalized);
2139
2472
  if (result && typeof result.catch === "function") {
2140
2473
  void result.catch((error) => {
2141
- warnOnce4(
2474
+ warnOnce5(
2142
2475
  `posthog-emit:${key}`,
2143
2476
  "[Blyp] Failed to deliver log to PostHog.",
2144
2477
  error
@@ -2146,7 +2479,7 @@ function createPostHogSender(config) {
2146
2479
  });
2147
2480
  }
2148
2481
  } catch (error) {
2149
- warnOnce4(
2482
+ warnOnce5(
2150
2483
  `posthog-emit:${key}`,
2151
2484
  "[Blyp] Failed to deliver log to PostHog.",
2152
2485
  error
@@ -2163,7 +2496,7 @@ function createPostHogSender(config) {
2163
2496
  if (isPreviouslyCapturedPostHogError(error)) {
2164
2497
  return;
2165
2498
  }
2166
- const normalized = normalizeExceptionInput2(
2499
+ const normalized = normalizeExceptionInput3(
2167
2500
  error,
2168
2501
  options.source === "client" ? "Client error" : "Server error"
2169
2502
  );
@@ -2182,7 +2515,7 @@ function createPostHogSender(config) {
2182
2515
  markPostHogCapturedError(normalized.error);
2183
2516
  if (result && typeof result.catch === "function") {
2184
2517
  void result.catch((captureError) => {
2185
- warnOnce4(
2518
+ warnOnce5(
2186
2519
  `posthog-capture:${key}`,
2187
2520
  "[Blyp] Failed to capture exception in PostHog.",
2188
2521
  captureError
@@ -2190,7 +2523,7 @@ function createPostHogSender(config) {
2190
2523
  });
2191
2524
  }
2192
2525
  } catch (captureError) {
2193
- warnOnce4(
2526
+ warnOnce5(
2194
2527
  `posthog-capture:${key}`,
2195
2528
  "[Blyp] Failed to capture exception in PostHog.",
2196
2529
  captureError
@@ -2203,7 +2536,7 @@ function createPostHogSender(config) {
2203
2536
  await transport.flush();
2204
2537
  }
2205
2538
  } catch (error) {
2206
- warnOnce4(
2539
+ warnOnce5(
2207
2540
  `posthog-flush:${key}`,
2208
2541
  "[Blyp] Failed to flush PostHog telemetry.",
2209
2542
  error
@@ -2218,13 +2551,13 @@ function buildPostHogExceptionProperties(record, source, properties = {}) {
2218
2551
  ...properties
2219
2552
  };
2220
2553
  }
2221
- var warnedKeys4 = /* @__PURE__ */ new Set();
2222
- var testHooks3 = {};
2223
- var warnOnce5 = createErrorOnceLogger(warnedKeys4);
2554
+ var warnedKeys5 = /* @__PURE__ */ new Set();
2555
+ var testHooks4 = {};
2556
+ var warnOnce6 = createErrorOnceLogger(warnedKeys5);
2224
2557
  function getSentryModule2() {
2225
- return testHooks3.module ?? Sentry;
2558
+ return testHooks4.module ?? Sentry;
2226
2559
  }
2227
- function resolveConnectorConfig3(config) {
2560
+ function resolveConnectorConfig4(config) {
2228
2561
  const connector = isBlypConfig(config) ? config.connectors?.sentry : config;
2229
2562
  const enabled = connector?.enabled ?? false;
2230
2563
  const dsn = connector?.dsn;
@@ -2369,7 +2702,7 @@ function hasConfigMismatch(connector, client) {
2369
2702
  return hasNonEmptyString(connector.dsn) && connector.dsn !== options.dsn || hasNonEmptyString(connector.environment) && connector.environment !== options.environment || hasNonEmptyString(connector.release) && connector.release !== options.release;
2370
2703
  }
2371
2704
  function createSentrySender(config) {
2372
- const connector = resolveConnectorConfig3(config);
2705
+ const connector = resolveConnectorConfig4(config);
2373
2706
  const key = `${connector.mode}:${connector.dsn ?? "missing"}`;
2374
2707
  const module = getSentryModule2();
2375
2708
  let client = connector.enabled ? module.getClient() : void 0;
@@ -2383,7 +2716,7 @@ function createSentrySender(config) {
2383
2716
  });
2384
2717
  client = module.getClient();
2385
2718
  } catch (error) {
2386
- warnOnce5(
2719
+ warnOnce6(
2387
2720
  `sentry-init:${key}`,
2388
2721
  "[Blyp] Failed to initialize Sentry. Skipping Sentry delivery.",
2389
2722
  error
@@ -2391,14 +2724,14 @@ function createSentrySender(config) {
2391
2724
  }
2392
2725
  }
2393
2726
  if (client && hasConfigMismatch(connector, client)) {
2394
- warnOnce5(
2727
+ warnOnce6(
2395
2728
  `sentry-mismatch:${key}`,
2396
2729
  "[Blyp] Sentry is already initialized with different options. Reusing the existing Sentry client."
2397
2730
  );
2398
2731
  }
2399
2732
  const ready = connector.enabled && client !== void 0;
2400
2733
  const emitUnavailableWarning = () => {
2401
- warnOnce5(
2734
+ warnOnce6(
2402
2735
  `sentry-unavailable:${key}`,
2403
2736
  "[Blyp] Sentry connector is not configured. Skipping Sentry delivery."
2404
2737
  );
@@ -2424,7 +2757,7 @@ function createSentrySender(config) {
2424
2757
  try {
2425
2758
  logMethod(record.message, attributes);
2426
2759
  } catch (error) {
2427
- warnOnce5(
2760
+ warnOnce6(
2428
2761
  `sentry-log:${key}`,
2429
2762
  "[Blyp] Failed to deliver log to Sentry.",
2430
2763
  error
@@ -2442,7 +2775,7 @@ function createSentrySender(config) {
2442
2775
  module.captureException(exception);
2443
2776
  });
2444
2777
  } catch (error) {
2445
- warnOnce5(
2778
+ warnOnce6(
2446
2779
  `sentry-exception:${key}`,
2447
2780
  "[Blyp] Failed to capture exception in Sentry.",
2448
2781
  error
@@ -2453,7 +2786,7 @@ function createSentrySender(config) {
2453
2786
  try {
2454
2787
  await module.flush(2e3);
2455
2788
  } catch (error) {
2456
- warnOnce5(
2789
+ warnOnce6(
2457
2790
  `sentry-flush:${key}`,
2458
2791
  "[Blyp] Failed to flush Sentry logs.",
2459
2792
  error
@@ -2462,9 +2795,9 @@ function createSentrySender(config) {
2462
2795
  }
2463
2796
  };
2464
2797
  }
2465
- var warnedKeys5 = /* @__PURE__ */ new Set();
2466
- var testHooks4 = {};
2467
- var warnOnce6 = createErrorOnceLogger(warnedKeys5);
2798
+ var warnedKeys6 = /* @__PURE__ */ new Set();
2799
+ var testHooks5 = {};
2800
+ var warnOnce7 = createErrorOnceLogger(warnedKeys6);
2468
2801
  function normalizeOTLPRecord(record, connector, source = "server") {
2469
2802
  const severity = resolveSeverity2(record.level);
2470
2803
  const body = typeof record.message === "string" ? record.message : String(record.message);
@@ -2529,14 +2862,14 @@ function resolveSeverity2(level) {
2529
2862
  return { text: "info", number: SeverityNumber.INFO };
2530
2863
  }
2531
2864
  }
2532
- function registerShutdownHooks3(key, shutdown) {
2865
+ function registerShutdownHooks4(key, shutdown) {
2533
2866
  const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2534
2867
  for (const event of handlers) {
2535
2868
  process.once(event, async () => {
2536
2869
  try {
2537
2870
  await shutdown();
2538
2871
  } catch (error) {
2539
- warnOnce6(
2872
+ warnOnce7(
2540
2873
  `${key}:shutdown`,
2541
2874
  "[Blyp] Failed to flush OTLP logs during shutdown.",
2542
2875
  error
@@ -2613,7 +2946,7 @@ function createUnavailableSender(name, connector) {
2613
2946
  const senderName = name || connector?.name || "otlp";
2614
2947
  const key = `${senderName}:${connector?.serviceName ?? "blyp-app"}:${connector?.endpoint ?? "missing"}`;
2615
2948
  const emitUnavailableWarning = () => {
2616
- warnOnce6(
2949
+ warnOnce7(
2617
2950
  `otlp-unavailable:${key}`,
2618
2951
  `[Blyp] OTLP target "${senderName}" is not configured or not ready. Skipping OTLP delivery.`
2619
2952
  );
@@ -2644,7 +2977,7 @@ function createSender(connector) {
2644
2977
  ...connector,
2645
2978
  headers: resolveTransportHeaders(connector)
2646
2979
  };
2647
- const transport = testHooks4.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
2980
+ const transport = testHooks5.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
2648
2981
  return {
2649
2982
  name: connector.name,
2650
2983
  enabled: connector.enabled,
@@ -2660,7 +2993,7 @@ function createSender(connector) {
2660
2993
  const result = transport.emit(normalized);
2661
2994
  if (result && typeof result.catch === "function") {
2662
2995
  void result.catch((error) => {
2663
- warnOnce6(
2996
+ warnOnce7(
2664
2997
  `otlp-emit:${key}`,
2665
2998
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2666
2999
  error
@@ -2668,7 +3001,7 @@ function createSender(connector) {
2668
3001
  });
2669
3002
  }
2670
3003
  } catch (error) {
2671
- warnOnce6(
3004
+ warnOnce7(
2672
3005
  `otlp-emit:${key}`,
2673
3006
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2674
3007
  error
@@ -2681,7 +3014,7 @@ function createSender(connector) {
2681
3014
  await transport.flush();
2682
3015
  }
2683
3016
  } catch (error) {
2684
- warnOnce6(
3017
+ warnOnce7(
2685
3018
  `otlp-flush:${key}`,
2686
3019
  `[Blyp] Failed to flush OTLP logs for target "${connector.name}".`,
2687
3020
  error
@@ -2710,7 +3043,7 @@ function createOTLPRegistry(config) {
2710
3043
  await Promise.all(Array.from(senders.values()).map((sender) => sender.flush()));
2711
3044
  }
2712
3045
  };
2713
- registerShutdownHooks3("otlp-registry", () => registry.flush());
3046
+ registerShutdownHooks4("otlp-registry", () => registry.flush());
2714
3047
  return registry;
2715
3048
  }
2716
3049
  var _RuntimeDetector = class _RuntimeDetector {
@@ -3108,6 +3441,9 @@ function getPostHogSender(logger3) {
3108
3441
  function getBetterStackSender(logger3) {
3109
3442
  return getLoggerFactory(logger3).betterstack;
3110
3443
  }
3444
+ function getDatabuddySender(logger3) {
3445
+ return getLoggerFactory(logger3).databuddy;
3446
+ }
3111
3447
  function tryGetPostHogSender(logger3) {
3112
3448
  try {
3113
3449
  return getPostHogSender(logger3);
@@ -3122,6 +3458,13 @@ function tryGetBetterStackSender(logger3) {
3122
3458
  return null;
3123
3459
  }
3124
3460
  }
3461
+ function tryGetDatabuddySender(logger3) {
3462
+ try {
3463
+ return getDatabuddySender(logger3);
3464
+ } catch {
3465
+ return null;
3466
+ }
3467
+ }
3125
3468
  function getSentrySender(logger3) {
3126
3469
  return getLoggerFactory(logger3).sentry;
3127
3470
  }
@@ -3181,6 +3524,18 @@ function maybeSendToBetterStack(betterstack, record) {
3181
3524
  }
3182
3525
  betterstack.send(record, { source: "server", warnIfUnavailable: true });
3183
3526
  }
3527
+ function maybeSendToDatabuddy(databuddy, record) {
3528
+ if (isClientLogRecord(record)) {
3529
+ return;
3530
+ }
3531
+ if (!databuddy.shouldAutoForwardServerLogs()) {
3532
+ if (databuddy.enabled && !databuddy.ready) {
3533
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3534
+ }
3535
+ return;
3536
+ }
3537
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3538
+ }
3184
3539
  function maybeSendToSentry(sentry, record) {
3185
3540
  if (isClientLogRecord(record)) {
3186
3541
  return;
@@ -3201,7 +3556,7 @@ function maybeSendToOTLP(otlp, record) {
3201
3556
  sender.send(record, { source: "server", warnIfUnavailable: true });
3202
3557
  }
3203
3558
  }
3204
- function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry, otlp, bindings = {}, source = "root") {
3559
+ function createLoggerInstance(rootRawLogger, sink, betterstack, databuddy, posthog, sentry, otlp, bindings = {}, source = "root") {
3205
3560
  const rawLogger = Object.keys(bindings).length > 0 ? rootRawLogger.child(bindings) : rootRawLogger;
3206
3561
  const writeRecord = (level, message, args, writeSource = source) => {
3207
3562
  if (writeSource === "root" && shouldDropRootLogWrite()) {
@@ -3227,6 +3582,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3227
3582
  );
3228
3583
  sink.write(record);
3229
3584
  maybeSendToBetterStack(betterstack, record);
3585
+ maybeSendToDatabuddy(databuddy, record);
3230
3586
  maybeSendToPostHog(posthog, record);
3231
3587
  maybeSendToSentry(sentry, record);
3232
3588
  maybeSendToOTLP(otlp, record);
@@ -3250,6 +3606,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3250
3606
  sink.write(record);
3251
3607
  }
3252
3608
  maybeSendToBetterStack(betterstack, record);
3609
+ maybeSendToDatabuddy(databuddy, record);
3253
3610
  maybeSendToPostHog(posthog, record);
3254
3611
  maybeSendToSentry(sentry, record);
3255
3612
  maybeSendToOTLP(otlp, record);
@@ -3283,8 +3640,26 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3283
3640
  }
3284
3641
  writeRecord("table", message, data === void 0 ? [] : [data]);
3285
3642
  },
3286
- flush: () => sink.flush(),
3287
- shutdown: () => sink.shutdown(),
3643
+ flush: async () => {
3644
+ await sink.flush();
3645
+ await Promise.allSettled([
3646
+ betterstack.flush(),
3647
+ databuddy.flush(),
3648
+ posthog.flush(),
3649
+ sentry.flush(),
3650
+ otlp.flush()
3651
+ ]);
3652
+ },
3653
+ shutdown: async () => {
3654
+ await sink.shutdown();
3655
+ await Promise.allSettled([
3656
+ betterstack.flush(),
3657
+ databuddy.flush(),
3658
+ posthog.flush(),
3659
+ sentry.flush(),
3660
+ otlp.flush()
3661
+ ]);
3662
+ },
3288
3663
  createStructuredLog: (groupId, initial) => {
3289
3664
  return createStructuredLogForLogger(logger3, groupId, {
3290
3665
  initialFields: initial
@@ -3296,6 +3671,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3296
3671
  rootRawLogger,
3297
3672
  sink,
3298
3673
  betterstack,
3674
+ databuddy,
3299
3675
  posthog,
3300
3676
  sentry,
3301
3677
  otlp,
@@ -3306,6 +3682,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3306
3682
  [LOGGER_FACTORY]: {
3307
3683
  bindings,
3308
3684
  betterstack,
3685
+ databuddy,
3309
3686
  posthog,
3310
3687
  sentry,
3311
3688
  otlp,
@@ -3315,6 +3692,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3315
3692
  rootRawLogger,
3316
3693
  sink,
3317
3694
  betterstack,
3695
+ databuddy,
3318
3696
  posthog,
3319
3697
  sentry,
3320
3698
  otlp,
@@ -3338,6 +3716,7 @@ function createBaseLogger(config) {
3338
3716
  const rawLogger = createPinoLogger(resolvedConfig);
3339
3717
  const sink = createPrimarySink(resolvedConfig);
3340
3718
  const betterstack = createBetterStackSender(resolvedConfig);
3719
+ const databuddy = createDatabuddySender(resolvedConfig);
3341
3720
  const posthog = createPostHogSender(resolvedConfig);
3342
3721
  const sentry = createSentrySender(resolvedConfig);
3343
3722
  const otlp = createOTLPRegistry(resolvedConfig);
@@ -3345,6 +3724,7 @@ function createBaseLogger(config) {
3345
3724
  rawLogger,
3346
3725
  sink,
3347
3726
  betterstack,
3727
+ databuddy,
3348
3728
  posthog,
3349
3729
  sentry,
3350
3730
  otlp
@@ -3960,11 +4340,28 @@ function createError(input) {
3960
4340
  }
3961
4341
  });
3962
4342
  }
3963
- }
3964
- return error;
3965
- }
3966
- var HTTP_CODES2 = buildHttpCodeRegistry((definition, overrides = {}) => {
3967
- return createError({
4343
+ const databuddy = tryGetDatabuddySender(input.logger ?? logger);
4344
+ if (databuddy?.shouldAutoCaptureExceptions()) {
4345
+ databuddy.captureException(error, {
4346
+ source: "server",
4347
+ warnIfUnavailable: true,
4348
+ properties: {
4349
+ blyp_type: "application_error",
4350
+ status: error.status,
4351
+ status_code: error.statusCode,
4352
+ ...error.code !== void 0 ? { code: error.code } : {},
4353
+ ...error.why !== void 0 ? { why: error.why } : {},
4354
+ ...error.fix !== void 0 ? { fix: error.fix } : {},
4355
+ ...error.link !== void 0 ? { link: error.link } : {},
4356
+ ...error.details !== void 0 ? { details: error.details } : {}
4357
+ }
4358
+ });
4359
+ }
4360
+ }
4361
+ return error;
4362
+ }
4363
+ var HTTP_CODES2 = buildHttpCodeRegistry((definition, overrides = {}) => {
4364
+ return createError({
3968
4365
  status: definition.status,
3969
4366
  message: definition.message,
3970
4367
  code: definition.code,
@@ -4344,8 +4741,132 @@ function createStructuredBetterStackLogger(groupId, initial, config = {}) {
4344
4741
  });
4345
4742
  }
4346
4743
 
4347
- // src/connectors/posthog/index.ts
4744
+ // src/connectors/databuddy/index.ts
4348
4745
  function resolveSender2(config = {}) {
4746
+ return createDatabuddySender(resolveConfig({
4747
+ ...config.connectors ? { connectors: config.connectors } : {}
4748
+ }));
4749
+ }
4750
+ function createDatabuddyLoggerInstance(sender, bindings = {}) {
4751
+ const writeRecord = (level, message, args) => {
4752
+ sender.send(buildRecord(level, message, args, bindings), {
4753
+ source: "server",
4754
+ warnIfUnavailable: true
4755
+ });
4756
+ };
4757
+ const writeStructured = (payload, message) => {
4758
+ sender.send(
4759
+ buildStructuredRecord(
4760
+ resolveStructuredWriteLevel(payload.level),
4761
+ message,
4762
+ payload,
4763
+ bindings
4764
+ ),
4765
+ {
4766
+ source: "server",
4767
+ warnIfUnavailable: true
4768
+ }
4769
+ );
4770
+ };
4771
+ return {
4772
+ debug: (message, ...args) => {
4773
+ writeRecord("debug", message, args);
4774
+ },
4775
+ info: (message, ...args) => {
4776
+ writeRecord("info", message, args);
4777
+ },
4778
+ error: (message, ...args) => {
4779
+ writeRecord("error", message, args);
4780
+ },
4781
+ warn: (message, ...args) => {
4782
+ writeRecord("warn", message, args);
4783
+ },
4784
+ warning: (message, ...args) => {
4785
+ writeRecord("warning", message, args);
4786
+ },
4787
+ success: (message, ...args) => {
4788
+ writeRecord("success", message, args);
4789
+ },
4790
+ critical: (message, ...args) => {
4791
+ writeRecord("critical", message, args);
4792
+ },
4793
+ table: (message, data) => {
4794
+ writeRecord("table", message, data === void 0 ? [] : [data]);
4795
+ },
4796
+ flush: async () => {
4797
+ await sender.flush();
4798
+ },
4799
+ shutdown: async () => {
4800
+ await sender.flush();
4801
+ },
4802
+ createStructuredLog: (groupId, initial) => {
4803
+ return createStructuredLog(groupId, {
4804
+ initialFields: initial,
4805
+ write: writeStructured
4806
+ });
4807
+ },
4808
+ child: (childBindings) => {
4809
+ return createDatabuddyLoggerInstance(sender, {
4810
+ ...bindings,
4811
+ ...childBindings
4812
+ });
4813
+ }
4814
+ };
4815
+ }
4816
+ function createDatabuddyErrorTrackerInstance(sender, bindings = {}) {
4817
+ return {
4818
+ capture: (error, options = {}) => {
4819
+ sender.captureException(error, {
4820
+ source: "server",
4821
+ warnIfUnavailable: true,
4822
+ properties: {
4823
+ ...bindings,
4824
+ ...options.properties ?? {},
4825
+ blyp_source: "server",
4826
+ blyp_manual: true
4827
+ }
4828
+ });
4829
+ },
4830
+ child: (childBindings) => {
4831
+ return createDatabuddyErrorTrackerInstance(sender, {
4832
+ ...bindings,
4833
+ ...childBindings
4834
+ });
4835
+ }
4836
+ };
4837
+ }
4838
+ function createDatabuddyLogger(config = {}) {
4839
+ return createDatabuddyLoggerInstance(resolveSender2(config));
4840
+ }
4841
+ function createStructuredDatabuddyLogger(groupId, initial, config = {}) {
4842
+ const sender = resolveSender2(config);
4843
+ return createStructuredLog(groupId, {
4844
+ initialFields: initial,
4845
+ write: (payload, message) => {
4846
+ sender.send(
4847
+ buildStructuredRecord(
4848
+ resolveStructuredWriteLevel(payload.level),
4849
+ message,
4850
+ payload,
4851
+ {}
4852
+ ),
4853
+ {
4854
+ source: "server",
4855
+ warnIfUnavailable: true
4856
+ }
4857
+ );
4858
+ }
4859
+ });
4860
+ }
4861
+ function createDatabuddyErrorTracker(config = {}) {
4862
+ return createDatabuddyErrorTrackerInstance(resolveSender2(config));
4863
+ }
4864
+ function captureDatabuddyException(error, options = {}, config = {}) {
4865
+ createDatabuddyErrorTracker(config).capture(error, options);
4866
+ }
4867
+
4868
+ // src/connectors/posthog/index.ts
4869
+ function resolveSender3(config = {}) {
4349
4870
  return createPostHogSender(resolveConfig({
4350
4871
  ...config.connectors ? { connectors: config.connectors } : {}
4351
4872
  }));
@@ -4438,10 +4959,10 @@ function createPostHogErrorTrackerInstance(sender, bindings = {}) {
4438
4959
  };
4439
4960
  }
4440
4961
  function createPosthogLogger(config = {}) {
4441
- return createPostHogLoggerInstance(resolveSender2(config));
4962
+ return createPostHogLoggerInstance(resolveSender3(config));
4442
4963
  }
4443
4964
  function createStructuredPosthogLogger(groupId, initial, config = {}) {
4444
- const sender = resolveSender2(config);
4965
+ const sender = resolveSender3(config);
4445
4966
  return createStructuredLog(groupId, {
4446
4967
  initialFields: initial,
4447
4968
  write: (payload, message) => {
@@ -4461,14 +4982,14 @@ function createStructuredPosthogLogger(groupId, initial, config = {}) {
4461
4982
  });
4462
4983
  }
4463
4984
  function createPosthogErrorTracker(config = {}) {
4464
- return createPostHogErrorTrackerInstance(resolveSender2(config));
4985
+ return createPostHogErrorTrackerInstance(resolveSender3(config));
4465
4986
  }
4466
4987
  function capturePosthogException(error, options = {}, config = {}) {
4467
4988
  createPosthogErrorTracker(config).capture(error, options);
4468
4989
  }
4469
4990
 
4470
4991
  // src/connectors/sentry/index.ts
4471
- function resolveSender3(config = {}) {
4992
+ function resolveSender4(config = {}) {
4472
4993
  return createSentrySender(resolveConfig({
4473
4994
  ...config.connectors ? { connectors: config.connectors } : {}
4474
4995
  }));
@@ -4538,10 +5059,10 @@ function createSentryLoggerInstance(sender, bindings = {}) {
4538
5059
  };
4539
5060
  }
4540
5061
  function createSentryLogger(config = {}) {
4541
- return createSentryLoggerInstance(resolveSender3(config));
5062
+ return createSentryLoggerInstance(resolveSender4(config));
4542
5063
  }
4543
5064
  function createStructuredSentryLogger(groupId, initial, config = {}) {
4544
- const sender = resolveSender3(config);
5065
+ const sender = resolveSender4(config);
4545
5066
  return createStructuredLog(groupId, {
4546
5067
  initialFields: initial,
4547
5068
  write: (payload, message) => {
@@ -4836,6 +5357,7 @@ function resolveServerLogger(config = {}, loggerOverride) {
4836
5357
  return {
4837
5358
  logger: logger3,
4838
5359
  betterstack: getBetterStackSender(logger3),
5360
+ databuddy: getDatabuddySender(logger3),
4839
5361
  posthog: getPostHogSender(logger3),
4840
5362
  sentry: getSentrySender(logger3),
4841
5363
  otlp: getOtlpRegistry(logger3),
@@ -4955,6 +5477,22 @@ function emitHttpErrorLog(logger3, level, request, path3, statusCode, responseTi
4955
5477
  }
4956
5478
  });
4957
5479
  }
5480
+ const databuddy = tryGetDatabuddySender(logger3);
5481
+ if (databuddy?.shouldAutoCaptureExceptions()) {
5482
+ databuddy.captureException(captureContext.error ?? error ?? message, {
5483
+ source: "server",
5484
+ warnIfUnavailable: true,
5485
+ properties: {
5486
+ method: request.method,
5487
+ path: path3,
5488
+ status_code: statusCode,
5489
+ ...request.url ? { current_url: request.url } : {},
5490
+ ...getHeaderValue(request.headers, "user-agent") ? { user_agent: getHeaderValue(request.headers, "user-agent") } : {},
5491
+ ...errorLogData.ip ? { ip: errorLogData.ip } : {},
5492
+ payload: errorLogData
5493
+ }
5494
+ });
5495
+ }
4958
5496
  return errorLogData;
4959
5497
  }
4960
5498
  async function parseClientLogPayload(request, body) {
@@ -5046,6 +5584,34 @@ async function handleClientLogIngestion(options) {
5046
5584
  });
5047
5585
  }
5048
5586
  }
5587
+ } else if (payload.connector === "databuddy") {
5588
+ headers["x-blyp-databuddy-status"] = config.databuddy.ready ? "enabled" : "missing";
5589
+ if (config.databuddy.ready) {
5590
+ const forwardedRecord = {
5591
+ timestamp: structuredPayload.receivedAt,
5592
+ level: payload.level,
5593
+ message: `[client] ${payload.message}`,
5594
+ data: structuredPayload
5595
+ };
5596
+ config.databuddy.send(forwardedRecord, {
5597
+ source: "client"
5598
+ });
5599
+ if ((payload.level === "error" || payload.level === "critical") && config.databuddy.shouldAutoCaptureExceptions()) {
5600
+ const clientErrorCandidate = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) && typeof payload.data.message === "string" ? payload.data : payload.message;
5601
+ config.databuddy.captureException(clientErrorCandidate, {
5602
+ source: "client",
5603
+ warnIfUnavailable: true,
5604
+ sessionId: payload.session.sessionId,
5605
+ properties: {
5606
+ page_url: payload.page.url,
5607
+ page_path: payload.page.pathname,
5608
+ client_runtime: payload.device?.runtime,
5609
+ metadata: payload.metadata,
5610
+ payload: structuredPayload
5611
+ }
5612
+ });
5613
+ }
5614
+ }
5049
5615
  } else if (payload.connector === "posthog") {
5050
5616
  headers["x-blyp-posthog-status"] = config.posthog.ready ? "enabled" : "missing";
5051
5617
  if (config.posthog.ready) {
@@ -5712,8 +6278,160 @@ function createNextJsLogger(config = {}) {
5712
6278
  };
5713
6279
  }
5714
6280
 
6281
+ // src/frameworks/react-router/logger.ts
6282
+ var REACT_ROUTER_LOGGER_KEY = /* @__PURE__ */ Symbol.for("blyp.react-router.logger");
6283
+ var REACT_ROUTER_LOGGER_FALLBACK_KEY = "__blypLog";
6284
+ function createContext2(args, response, error) {
6285
+ return {
6286
+ request: args.request,
6287
+ params: args.params,
6288
+ context: args.context,
6289
+ response,
6290
+ error
6291
+ };
6292
+ }
6293
+ function readLoggerValue(context) {
6294
+ if (typeof context.get === "function") {
6295
+ const symbolValue = context.get(REACT_ROUTER_LOGGER_KEY);
6296
+ if (symbolValue) {
6297
+ return symbolValue;
6298
+ }
6299
+ return context.get(REACT_ROUTER_LOGGER_FALLBACK_KEY);
6300
+ }
6301
+ return context[REACT_ROUTER_LOGGER_KEY] ?? context[REACT_ROUTER_LOGGER_FALLBACK_KEY];
6302
+ }
6303
+ function writeLoggerValue(context, logger3) {
6304
+ if (typeof context.set === "function") {
6305
+ context.set(REACT_ROUTER_LOGGER_KEY, logger3);
6306
+ context.set(REACT_ROUTER_LOGGER_FALLBACK_KEY, logger3);
6307
+ return;
6308
+ }
6309
+ context[REACT_ROUTER_LOGGER_KEY] = logger3;
6310
+ context[REACT_ROUTER_LOGGER_FALLBACK_KEY] = logger3;
6311
+ }
6312
+ function resolveThrownStatusCode(error) {
6313
+ const errorLike = toErrorLike(error);
6314
+ return errorLike?.status ?? errorLike?.statusCode ?? 500;
6315
+ }
6316
+ function createReactRouterLogger(config = {}) {
6317
+ const shared = resolveServerLogger(config);
6318
+ const setLogger = (context, logger3) => {
6319
+ writeLoggerValue(context, logger3);
6320
+ };
6321
+ const getLogger = (context) => {
6322
+ const logger3 = readLoggerValue(context);
6323
+ return logger3 && typeof logger3 === "object" ? logger3 : shared.logger;
6324
+ };
6325
+ return {
6326
+ logger: shared.logger,
6327
+ setLogger,
6328
+ getLogger,
6329
+ middleware: async (args, next) => {
6330
+ return runWithRequestContext(async () => {
6331
+ const startTime = performance.now();
6332
+ const path3 = extractPathname(args.request.url);
6333
+ let structuredLogEmitted = false;
6334
+ const scopedLogger = createRequestScopedLogger(shared.logger, {
6335
+ resolveStructuredFields: () => ({
6336
+ method: args.request.method,
6337
+ path: path3,
6338
+ ...resolveAdditionalProps(shared, createContext2(args))
6339
+ }),
6340
+ onStructuredEmit: () => {
6341
+ structuredLogEmitted = true;
6342
+ }
6343
+ });
6344
+ setLogger(args.context, scopedLogger);
6345
+ try {
6346
+ const response = await next();
6347
+ if (structuredLogEmitted) {
6348
+ await flushServerLoggerSafely(shared);
6349
+ return response;
6350
+ }
6351
+ const statusCode = response.status;
6352
+ const loggerContext = createContext2(args, response);
6353
+ const responseTime = Math.round(performance.now() - startTime);
6354
+ const requestLike = createRequestLike(
6355
+ args.request.method,
6356
+ args.request.url,
6357
+ args.request.headers
6358
+ );
6359
+ if (isErrorStatus(statusCode)) {
6360
+ if (!shouldSkipErrorLogging(shared, path3)) {
6361
+ emitHttpErrorLog(
6362
+ shared.logger,
6363
+ shared.level,
6364
+ requestLike,
6365
+ path3,
6366
+ statusCode,
6367
+ responseTime,
6368
+ toErrorLike(void 0, statusCode),
6369
+ resolveAdditionalProps(shared, loggerContext)
6370
+ );
6371
+ }
6372
+ } else if (!shouldSkipAutoLogging(shared, loggerContext, path3)) {
6373
+ emitHttpRequestLog(
6374
+ shared.logger,
6375
+ shared.level,
6376
+ requestLike,
6377
+ path3,
6378
+ statusCode,
6379
+ responseTime,
6380
+ resolveAdditionalProps(shared, loggerContext)
6381
+ );
6382
+ }
6383
+ await flushServerLoggerSafely(shared);
6384
+ return response;
6385
+ } catch (error) {
6386
+ if (!structuredLogEmitted && !shouldSkipErrorLogging(shared, path3)) {
6387
+ const statusCode = resolveThrownStatusCode(error);
6388
+ emitHttpErrorLog(
6389
+ shared.logger,
6390
+ shared.level,
6391
+ createRequestLike(args.request.method, args.request.url, args.request.headers),
6392
+ path3,
6393
+ statusCode,
6394
+ Math.round(performance.now() - startTime),
6395
+ toErrorLike(error, statusCode),
6396
+ resolveAdditionalProps(shared, createContext2(args, void 0, error)),
6397
+ { error }
6398
+ );
6399
+ }
6400
+ await flushServerLoggerSafely(shared);
6401
+ throw error;
6402
+ }
6403
+ });
6404
+ },
6405
+ clientLogHandler: async (request) => {
6406
+ const path3 = extractPathname(request.url);
6407
+ if (path3 !== shared.ingestionPath) {
6408
+ return new Response(
6409
+ JSON.stringify({
6410
+ error: `Mounted route path ${path3} does not match configured client logging path ${shared.ingestionPath}`
6411
+ }),
6412
+ {
6413
+ status: 500,
6414
+ headers: { "content-type": "application/json" }
6415
+ }
6416
+ );
6417
+ }
6418
+ const result = await handleClientLogIngestion({
6419
+ config: shared,
6420
+ ctx: createContext2({ request, context: {} }),
6421
+ request,
6422
+ deliveryPath: path3
6423
+ });
6424
+ await flushServerLoggerSafely(shared);
6425
+ return new Response(null, {
6426
+ status: result.status,
6427
+ headers: result.headers
6428
+ });
6429
+ }
6430
+ };
6431
+ }
6432
+
5715
6433
  // src/frameworks/tanstack-start/logger.ts
5716
- function createContext2(request, context, response, error) {
6434
+ function createContext3(request, context, response, error) {
5717
6435
  return { request, context, response, error };
5718
6436
  }
5719
6437
  function createTanStackStartLogger(config = {}) {
@@ -5732,7 +6450,7 @@ function createTanStackStartLogger(config = {}) {
5732
6450
  resolveStructuredFields: () => ({
5733
6451
  method: request.method,
5734
6452
  path: path3,
5735
- ...resolveAdditionalProps(shared, createContext2(request, nextContext))
6453
+ ...resolveAdditionalProps(shared, createContext3(request, nextContext))
5736
6454
  }),
5737
6455
  onStructuredEmit: () => {
5738
6456
  structuredLogEmitted = true;
@@ -5746,7 +6464,7 @@ function createTanStackStartLogger(config = {}) {
5746
6464
  return response;
5747
6465
  }
5748
6466
  const statusCode = response.status;
5749
- const loggerContext = createContext2(request, nextContext, response);
6467
+ const loggerContext = createContext3(request, nextContext, response);
5750
6468
  const responseTime = Math.round(performance.now() - startTime);
5751
6469
  if (isErrorStatus(statusCode)) {
5752
6470
  if (!shouldSkipErrorLogging(shared, path3)) {
@@ -5784,7 +6502,7 @@ function createTanStackStartLogger(config = {}) {
5784
6502
  500,
5785
6503
  Math.round(performance.now() - startTime),
5786
6504
  toErrorLike(error, 500),
5787
- resolveAdditionalProps(shared, createContext2(request, nextContext, void 0, error)),
6505
+ resolveAdditionalProps(shared, createContext3(request, nextContext, void 0, error)),
5788
6506
  {
5789
6507
  error
5790
6508
  }
@@ -5813,7 +6531,7 @@ function createTanStackStartLogger(config = {}) {
5813
6531
  }
5814
6532
  const result = await handleClientLogIngestion({
5815
6533
  config: shared,
5816
- ctx: createContext2(request, {}),
6534
+ ctx: createContext3(request, {}),
5817
6535
  request,
5818
6536
  deliveryPath: path3
5819
6537
  });
@@ -5828,7 +6546,7 @@ function createTanStackStartLogger(config = {}) {
5828
6546
  }
5829
6547
 
5830
6548
  // src/frameworks/sveltekit/logger.ts
5831
- function createContext3(event, response, error) {
6549
+ function createContext4(event, response, error) {
5832
6550
  return { event, response, error };
5833
6551
  }
5834
6552
  function createSvelteKitLogger(config = {}) {
@@ -5840,7 +6558,7 @@ function createSvelteKitLogger(config = {}) {
5840
6558
  resolveStructuredFields: () => ({
5841
6559
  method: event.request.method,
5842
6560
  path: event.url.pathname,
5843
- ...resolveAdditionalProps(shared, createContext3(event))
6561
+ ...resolveAdditionalProps(shared, createContext4(event))
5844
6562
  }),
5845
6563
  onStructuredEmit: () => {
5846
6564
  structuredLogEmitted = true;
@@ -5860,7 +6578,7 @@ function createSvelteKitLogger(config = {}) {
5860
6578
  return response;
5861
6579
  }
5862
6580
  const statusCode = response.status;
5863
- const loggerContext = createContext3(event, response);
6581
+ const loggerContext = createContext4(event, response);
5864
6582
  const responseTime = Math.round(performance.now() - startTime);
5865
6583
  if (isErrorStatus(statusCode)) {
5866
6584
  if (!shouldSkipErrorLogging(shared, path3)) {
@@ -5898,7 +6616,7 @@ function createSvelteKitLogger(config = {}) {
5898
6616
  500,
5899
6617
  Math.round(performance.now() - startTime),
5900
6618
  toErrorLike(error, 500),
5901
- resolveAdditionalProps(shared, createContext3(event, void 0, error)),
6619
+ resolveAdditionalProps(shared, createContext4(event, void 0, error)),
5902
6620
  {
5903
6621
  error
5904
6622
  }
@@ -5929,7 +6647,7 @@ function createSvelteKitLogger(config = {}) {
5929
6647
  }
5930
6648
  const result = await handleClientLogIngestion({
5931
6649
  config: shared,
5932
- ctx: createContext3(event),
6650
+ ctx: createContext4(event),
5933
6651
  request: event.request,
5934
6652
  deliveryPath: path3
5935
6653
  });
@@ -5942,6 +6660,344 @@ function createSvelteKitLogger(config = {}) {
5942
6660
  };
5943
6661
  }
5944
6662
 
6663
+ // src/frameworks/astro/logger.ts
6664
+ function createContext5(context, response, error) {
6665
+ return { context, response, error };
6666
+ }
6667
+ function createAstroLogger(config = {}) {
6668
+ const shared = resolveServerLogger(config);
6669
+ return {
6670
+ logger: shared.logger,
6671
+ onRequest: async (context, next) => {
6672
+ return runWithRequestContext(async () => {
6673
+ let structuredLogEmitted = false;
6674
+ context.locals.blypLog = createRequestScopedLogger(shared.logger, {
6675
+ resolveStructuredFields: () => ({
6676
+ method: context.request.method,
6677
+ path: context.url.pathname,
6678
+ ...resolveAdditionalProps(shared, createContext5(context))
6679
+ }),
6680
+ onStructuredEmit: () => {
6681
+ structuredLogEmitted = true;
6682
+ }
6683
+ });
6684
+ const startTime = performance.now();
6685
+ const path3 = context.url.pathname;
6686
+ const requestLike = createRequestLike(
6687
+ context.request.method,
6688
+ context.request.url,
6689
+ context.request.headers
6690
+ );
6691
+ try {
6692
+ const response = await next();
6693
+ if (structuredLogEmitted) {
6694
+ await flushServerLoggerSafely(shared);
6695
+ return response;
6696
+ }
6697
+ const statusCode = response.status;
6698
+ const loggerContext = createContext5(context, response);
6699
+ const responseTime = Math.round(performance.now() - startTime);
6700
+ if (isErrorStatus(statusCode)) {
6701
+ if (!shouldSkipErrorLogging(shared, path3)) {
6702
+ emitHttpErrorLog(
6703
+ shared.logger,
6704
+ shared.level,
6705
+ requestLike,
6706
+ path3,
6707
+ statusCode,
6708
+ responseTime,
6709
+ toErrorLike(void 0, statusCode),
6710
+ resolveAdditionalProps(shared, loggerContext)
6711
+ );
6712
+ }
6713
+ } else if (!shouldSkipAutoLogging(shared, loggerContext, path3)) {
6714
+ emitHttpRequestLog(
6715
+ shared.logger,
6716
+ shared.level,
6717
+ requestLike,
6718
+ path3,
6719
+ statusCode,
6720
+ responseTime,
6721
+ resolveAdditionalProps(shared, loggerContext)
6722
+ );
6723
+ }
6724
+ await flushServerLoggerSafely(shared);
6725
+ return response;
6726
+ } catch (error) {
6727
+ if (!structuredLogEmitted && !shouldSkipErrorLogging(shared, path3)) {
6728
+ emitHttpErrorLog(
6729
+ shared.logger,
6730
+ shared.level,
6731
+ requestLike,
6732
+ path3,
6733
+ 500,
6734
+ Math.round(performance.now() - startTime),
6735
+ toErrorLike(error, 500),
6736
+ resolveAdditionalProps(shared, createContext5(context, void 0, error)),
6737
+ { error }
6738
+ );
6739
+ }
6740
+ await flushServerLoggerSafely(shared);
6741
+ throw error;
6742
+ }
6743
+ });
6744
+ },
6745
+ clientLogHandler: async (context) => {
6746
+ const path3 = context.url.pathname;
6747
+ if (path3 !== shared.ingestionPath) {
6748
+ return new Response(
6749
+ JSON.stringify({
6750
+ error: `Mounted route path ${path3} does not match configured client logging path ${shared.ingestionPath}`
6751
+ }),
6752
+ {
6753
+ status: 500,
6754
+ headers: { "content-type": "application/json" }
6755
+ }
6756
+ );
6757
+ }
6758
+ const result = await handleClientLogIngestion({
6759
+ config: shared,
6760
+ ctx: createContext5(context),
6761
+ request: context.request,
6762
+ deliveryPath: path3
6763
+ });
6764
+ await flushServerLoggerSafely(shared);
6765
+ return new Response(null, {
6766
+ status: result.status,
6767
+ headers: result.headers
6768
+ });
6769
+ }
6770
+ };
6771
+ }
6772
+
6773
+ // src/frameworks/shared/h3.ts
6774
+ var BLYP_NITRO_STATE_KEY = /* @__PURE__ */ Symbol.for("blyp.nitro.state");
6775
+ function getNitroState(event) {
6776
+ return event.context[BLYP_NITRO_STATE_KEY];
6777
+ }
6778
+ function setNitroState(event, state) {
6779
+ event.context[BLYP_NITRO_STATE_KEY] = state;
6780
+ return state;
6781
+ }
6782
+ function getNitroMethod(event) {
6783
+ return event.method ?? event.node?.req?.method ?? event.request?.method ?? "GET";
6784
+ }
6785
+ function getNitroHeaders(event) {
6786
+ return event.headers ?? event.node?.req?.headers ?? event.request?.headers;
6787
+ }
6788
+ function getNitroUrl(event) {
6789
+ if (event.request?.url) {
6790
+ return event.request.url;
6791
+ }
6792
+ const path3 = event.url ?? event.path ?? event.node?.req?.url ?? "/";
6793
+ return buildAbsoluteUrl(path3, getNitroHeaders(event));
6794
+ }
6795
+ function getNitroPath(event) {
6796
+ if (typeof event.path === "string" && event.path.length > 0) {
6797
+ return event.path;
6798
+ }
6799
+ if (event.request?.url) {
6800
+ return new URL(event.request.url).pathname;
6801
+ }
6802
+ const requestUrl = event.url ?? event.node?.req?.url ?? "/";
6803
+ if (requestUrl.startsWith("http://") || requestUrl.startsWith("https://")) {
6804
+ return new URL(requestUrl).pathname;
6805
+ }
6806
+ const queryIndex = requestUrl.indexOf("?");
6807
+ return queryIndex >= 0 ? requestUrl.slice(0, queryIndex) : requestUrl;
6808
+ }
6809
+ function createNitroRequestLike(event) {
6810
+ return createRequestLike(getNitroMethod(event), getNitroUrl(event), getNitroHeaders(event));
6811
+ }
6812
+ function getNitroStatus(event, response, fallbackStatus = 200) {
6813
+ if (response instanceof Response) {
6814
+ return response.status;
6815
+ }
6816
+ if (typeof response?.status === "number") {
6817
+ return response.status;
6818
+ }
6819
+ if (typeof response?.statusCode === "number") {
6820
+ return response.statusCode;
6821
+ }
6822
+ if (typeof event.node?.res?.statusCode === "number" && event.node.res.statusCode > 0) {
6823
+ return event.node.res.statusCode;
6824
+ }
6825
+ return fallbackStatus;
6826
+ }
6827
+ async function readNitroBody(event) {
6828
+ if (event.body !== void 0) {
6829
+ return event.body;
6830
+ }
6831
+ if (event.request) {
6832
+ const contentType = event.request.headers.get("content-type") ?? "";
6833
+ if (contentType.includes("application/json")) {
6834
+ const fallbackRequest = event.request.clone();
6835
+ try {
6836
+ return await event.request.json();
6837
+ } catch {
6838
+ return await fallbackRequest.text();
6839
+ }
6840
+ }
6841
+ return await event.request.text();
6842
+ }
6843
+ if (event.node?.req) {
6844
+ return await readNodeRequestBody(event.node.req);
6845
+ }
6846
+ throw new Error("Unable to parse Nitro request body");
6847
+ }
6848
+
6849
+ // src/frameworks/nitro/logger.ts
6850
+ function createContext6(event, response, error) {
6851
+ return { event, response, error };
6852
+ }
6853
+ function buildFactory(shared) {
6854
+ const getLogger = (event) => event.context.blypLog ?? shared.logger;
6855
+ const logSuccess = async (event, response) => {
6856
+ const state = getNitroState(event);
6857
+ if (!state || state.structuredLogEmitted || state.errorLogged) {
6858
+ return;
6859
+ }
6860
+ const requestLike = createNitroRequestLike(event);
6861
+ const statusCode = getNitroStatus(event, response);
6862
+ const responseTime = Math.round(performance.now() - state.startTime);
6863
+ const loggerContext = createContext6(event, response);
6864
+ if (isErrorStatus(statusCode)) {
6865
+ if (!shouldSkipErrorLogging(shared, state.path)) {
6866
+ emitHttpErrorLog(
6867
+ shared.logger,
6868
+ shared.level,
6869
+ requestLike,
6870
+ state.path,
6871
+ statusCode,
6872
+ responseTime,
6873
+ toErrorLike(void 0, statusCode),
6874
+ resolveAdditionalProps(shared, loggerContext)
6875
+ );
6876
+ }
6877
+ } else if (!shouldSkipAutoLogging(shared, loggerContext, state.path)) {
6878
+ emitHttpRequestLog(
6879
+ shared.logger,
6880
+ shared.level,
6881
+ requestLike,
6882
+ state.path,
6883
+ statusCode,
6884
+ responseTime,
6885
+ resolveAdditionalProps(shared, loggerContext)
6886
+ );
6887
+ }
6888
+ };
6889
+ const logError = async (event, error, response) => {
6890
+ const state = getNitroState(event);
6891
+ if (!state || state.structuredLogEmitted || state.errorLogged || shouldSkipErrorLogging(shared, state.path)) {
6892
+ return;
6893
+ }
6894
+ state.errorLogged = true;
6895
+ emitHttpErrorLog(
6896
+ shared.logger,
6897
+ shared.level,
6898
+ createNitroRequestLike(event),
6899
+ state.path,
6900
+ getNitroStatus(event, response, 500),
6901
+ Math.round(performance.now() - state.startTime),
6902
+ toErrorLike(error, 500),
6903
+ resolveAdditionalProps(shared, createContext6(event, response, error)),
6904
+ { error }
6905
+ );
6906
+ };
6907
+ return {
6908
+ logger: shared.logger,
6909
+ getLogger,
6910
+ plugin: async (nitroApp) => {
6911
+ await nitroApp.hooks.hook("request", async (eventArg) => {
6912
+ const event = eventArg;
6913
+ enterRequestContext();
6914
+ const path3 = getNitroPath(event);
6915
+ let state = setNitroState(event, {
6916
+ startTime: performance.now(),
6917
+ path: path3,
6918
+ structuredLogEmitted: false
6919
+ });
6920
+ const scopedLogger = createRequestScopedLogger(shared.logger, {
6921
+ resolveStructuredFields: () => ({
6922
+ method: getNitroMethod(event),
6923
+ path: path3,
6924
+ ...resolveAdditionalProps(shared, createContext6(event))
6925
+ }),
6926
+ onStructuredEmit: () => {
6927
+ const currentState = getNitroState(event);
6928
+ if (currentState) {
6929
+ currentState.structuredLogEmitted = true;
6930
+ }
6931
+ }
6932
+ });
6933
+ event.context.blypLog = scopedLogger;
6934
+ state.scopedLogger = scopedLogger;
6935
+ });
6936
+ await nitroApp.hooks.hook("beforeResponse", async (eventArg, payload) => {
6937
+ await logSuccess(eventArg, payload);
6938
+ });
6939
+ await nitroApp.hooks.hook("afterResponse", async (eventArg) => {
6940
+ await flushServerLoggerSafely(shared);
6941
+ const state = getNitroState(eventArg);
6942
+ if (state) {
6943
+ state.errorLogged = true;
6944
+ }
6945
+ });
6946
+ await nitroApp.hooks.hook("error", async (errorArg, eventArg) => {
6947
+ if (eventArg && typeof eventArg === "object") {
6948
+ await logError(eventArg, errorArg);
6949
+ await flushServerLoggerSafely(shared);
6950
+ }
6951
+ });
6952
+ },
6953
+ clientLogHandler: async (event) => {
6954
+ const path3 = getNitroPath(event);
6955
+ if (path3 !== shared.ingestionPath) {
6956
+ return new Response(
6957
+ JSON.stringify({
6958
+ error: `Mounted route path ${path3} does not match configured client logging path ${shared.ingestionPath}`
6959
+ }),
6960
+ {
6961
+ status: 500,
6962
+ headers: { "content-type": "application/json" }
6963
+ }
6964
+ );
6965
+ }
6966
+ const body = await readNitroBody(event);
6967
+ const result = await handleClientLogIngestion({
6968
+ config: shared,
6969
+ ctx: createContext6(event),
6970
+ request: {
6971
+ ...createNitroRequestLike(event),
6972
+ json: async () => body
6973
+ },
6974
+ body,
6975
+ deliveryPath: path3
6976
+ });
6977
+ await flushServerLoggerSafely(shared);
6978
+ return new Response(null, {
6979
+ status: result.status,
6980
+ headers: result.headers
6981
+ });
6982
+ }
6983
+ };
6984
+ }
6985
+ function createNitroLogger(config = {}) {
6986
+ const shared = resolveServerLogger(config);
6987
+ return buildFactory(shared);
6988
+ }
6989
+
6990
+ // src/frameworks/nuxt/logger.ts
6991
+ function createNuxtLogger(config = {}) {
6992
+ const nitro = buildFactory(resolveServerLogger(config));
6993
+ return {
6994
+ logger: nitro.logger,
6995
+ serverPlugin: nitro.plugin,
6996
+ clientLogHandler: nitro.clientLogHandler,
6997
+ getLogger: (event) => nitro.getLogger(event)
6998
+ };
6999
+ }
7000
+
5945
7001
  // src/frameworks/nestjs/constants.ts
5946
7002
  var BLYP_NEST_LOGGER = /* @__PURE__ */ Symbol("BLYP_NEST_LOGGER");
5947
7003
  var BLYP_NEST_LOGGER_INIT_ERROR = "BlypModule.forRoot() requires createLogger(...) to run before NestFactory.create(AppModule).";
@@ -6389,7 +7445,7 @@ BlypModule = __decorateClass([
6389
7445
  ], BlypModule);
6390
7446
 
6391
7447
  // src/connectors/otlp/index.ts
6392
- function resolveSender4(config = { name: "" }) {
7448
+ function resolveSender5(config = { name: "" }) {
6393
7449
  const registry = createOTLPRegistry(resolveConfig({
6394
7450
  ...config.connectors ? { connectors: config.connectors } : {}
6395
7451
  }));
@@ -6460,10 +7516,10 @@ function createOTLPLoggerInstance(sender, bindings = {}) {
6460
7516
  };
6461
7517
  }
6462
7518
  function createOtlpLogger(config = { name: "" }) {
6463
- return createOTLPLoggerInstance(resolveSender4(config));
7519
+ return createOTLPLoggerInstance(resolveSender5(config));
6464
7520
  }
6465
7521
  function createStructuredOtlpLogger(groupId, initial, config) {
6466
- const sender = resolveSender4(config ?? { name: "" });
7522
+ const sender = resolveSender5(config ?? { name: "" });
6467
7523
  return createStructuredLog(groupId, {
6468
7524
  initialFields: initial,
6469
7525
  write: (payload, message) => {
@@ -6489,6 +7545,6 @@ function createStructuredLog2(groupId, initial) {
6489
7545
  return activeLogger.createStructuredLog(groupId, initial);
6490
7546
  }
6491
7547
 
6492
- export { BlypError, BlypModule, CUSTOM_LEVELS, DEFAULT_CLIENT_LOGGING_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_DELIVERY_CONFIG, DEFAULT_DATABASE_RETRY_CONFIG, DEFAULT_FILE_CONFIG, DEFAULT_ROTATION_CONFIG, HTTP_CODES2 as HTTP_CODES, captureBetterStackException, capturePosthogException, colors, createBaseLogger, createBetterStackErrorTracker, createBetterStackLogger, createDrizzleDatabaseAdapter, createElysiaLogger, createError, createExpressErrorLogger, createExpressLogger, createFastifyLogger, createHonoLogger, createLogDir, createElysiaLogger as createLogger, createNestLogger, createNextJsLogger, createOtlpLogger, createPosthogErrorTracker, createPosthogLogger, createPrismaDatabaseAdapter, createRuntimeAdapter, createSentryLogger, createStandaloneLogger, createStructuredBetterStackLogger, createStructuredLog2 as createStructuredLog, createStructuredOtlpLogger, createStructuredPosthogLogger, createStructuredSentryLogger, createSvelteKitLogger, createTanStackStartLogger, formatLogRecord, getArrowForMethod, getColoredLevel, getConfig, getHttpCode2 as getHttpCode, getMethodColor, getResponseTimeColor, getStatusColor, loadConfig, logger2 as logger, mergeBlypConfig, normalizeOTLPRecord, parseError, readLogFile, resetConfigCache, resolveConfig, resolveStatusCode, runtime, shouldIgnorePath, shouldLogTable };
7548
+ export { BlypError, BlypModule, CUSTOM_LEVELS, DEFAULT_CLIENT_LOGGING_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_DELIVERY_CONFIG, DEFAULT_DATABASE_RETRY_CONFIG, DEFAULT_FILE_CONFIG, DEFAULT_ROTATION_CONFIG, HTTP_CODES2 as HTTP_CODES, captureBetterStackException, captureDatabuddyException, capturePosthogException, colors, createAstroLogger, createBaseLogger, createBetterStackErrorTracker, createBetterStackLogger, createDatabuddyErrorTracker, createDatabuddyLogger, createDrizzleDatabaseAdapter, createElysiaLogger, createError, createExpressErrorLogger, createExpressLogger, createFastifyLogger, createHonoLogger, createLogDir, createElysiaLogger as createLogger, createNestLogger, createNextJsLogger, createNitroLogger, createNuxtLogger, createOtlpLogger, createPosthogErrorTracker, createPosthogLogger, createPrismaDatabaseAdapter, createReactRouterLogger, createRuntimeAdapter, createSentryLogger, createStandaloneLogger, createStructuredBetterStackLogger, createStructuredDatabuddyLogger, createStructuredLog2 as createStructuredLog, createStructuredOtlpLogger, createStructuredPosthogLogger, createStructuredSentryLogger, createSvelteKitLogger, createTanStackStartLogger, formatLogRecord, getArrowForMethod, getColoredLevel, getConfig, getHttpCode2 as getHttpCode, getMethodColor, getResponseTimeColor, getStatusColor, loadConfig, logger2 as logger, mergeBlypConfig, normalizeOTLPRecord, parseError, readLogFile, resetConfigCache, resolveConfig, resolveStatusCode, runtime, shouldIgnorePath, shouldLogTable };
6493
7549
  //# sourceMappingURL=index.mjs.map
6494
7550
  //# sourceMappingURL=index.mjs.map