@debugkit/sdk 0.1.0 → 0.2.0

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 (52) hide show
  1. package/README.md +55 -3
  2. package/dist/{chunk-3UN5VMQU.js → chunk-3WRI3DI2.js} +5 -5
  3. package/dist/chunk-3WRI3DI2.js.map +1 -0
  4. package/dist/chunk-5C7KJJNO.js +651 -0
  5. package/dist/chunk-5C7KJJNO.js.map +1 -0
  6. package/dist/chunk-EGCXLOFH.cjs +663 -0
  7. package/dist/chunk-EGCXLOFH.cjs.map +1 -0
  8. package/dist/{chunk-BD2FNVCP.js → chunk-HO3JW55K.js} +15 -7
  9. package/dist/chunk-HO3JW55K.js.map +1 -0
  10. package/dist/{chunk-NSWUGBA2.cjs → chunk-NJ6DTUVX.cjs} +20 -12
  11. package/dist/chunk-NJ6DTUVX.cjs.map +1 -0
  12. package/dist/{chunk-KUJ4EW3D.cjs → chunk-YELZOB7J.cjs} +10 -10
  13. package/dist/chunk-YELZOB7J.cjs.map +1 -0
  14. package/dist/client-ekzlpWIR.d.cts +220 -0
  15. package/dist/client-ekzlpWIR.d.ts +220 -0
  16. package/dist/expo-router.cjs +4 -4
  17. package/dist/expo-router.d.cts +1 -1
  18. package/dist/expo-router.d.ts +1 -1
  19. package/dist/expo-router.js +2 -2
  20. package/dist/expo.cjs +13 -13
  21. package/dist/expo.d.cts +1 -1
  22. package/dist/expo.d.ts +1 -1
  23. package/dist/expo.js +5 -5
  24. package/dist/index.cjs +12 -8
  25. package/dist/index.d.cts +2 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +1 -1
  28. package/dist/node.cjs +69 -14
  29. package/dist/node.cjs.map +1 -1
  30. package/dist/node.d.cts +4 -7
  31. package/dist/node.d.ts +4 -7
  32. package/dist/node.js +55 -5
  33. package/dist/node.js.map +1 -1
  34. package/dist/react-native.cjs +10 -10
  35. package/dist/react-native.d.cts +1 -1
  36. package/dist/react-native.d.ts +1 -1
  37. package/dist/react-native.js +3 -3
  38. package/dist/react.cjs +6 -6
  39. package/dist/react.d.cts +1 -1
  40. package/dist/react.d.ts +1 -1
  41. package/dist/react.js +2 -2
  42. package/package.json +2 -2
  43. package/dist/chunk-3UN5VMQU.js.map +0 -1
  44. package/dist/chunk-BD2FNVCP.js.map +0 -1
  45. package/dist/chunk-KUJ4EW3D.cjs.map +0 -1
  46. package/dist/chunk-NSWUGBA2.cjs.map +0 -1
  47. package/dist/chunk-VIJ5USKQ.js +0 -300
  48. package/dist/chunk-VIJ5USKQ.js.map +0 -1
  49. package/dist/chunk-XEFWRCN4.cjs +0 -311
  50. package/dist/chunk-XEFWRCN4.cjs.map +0 -1
  51. package/dist/client-drmb0n15.d.cts +0 -103
  52. package/dist/client-drmb0n15.d.ts +0 -103
@@ -0,0 +1,220 @@
1
+ import { ContextInput, EventInput, Breadcrumb, Severity, parseStack } from '@debugkit/schema/core';
2
+
3
+ type Shallow<T> = {
4
+ [K in keyof T]?: T[K] extends object ? Partial<T[K]> : T[K];
5
+ };
6
+ type ContextPatch = Shallow<ContextInput>;
7
+ /** Merge two context patches one level deep (os, device, app ... are merged field by field). */
8
+ declare function mergeContext(a: ContextPatch, b: ContextPatch): ContextPatch;
9
+ /**
10
+ * Best-effort context for browsers (React, TanStack Start/Router client, Next client ...).
11
+ * Safe to call in any runtime: it never touches globals that might not exist.
12
+ */
13
+ declare function browserContext(): ContextPatch;
14
+
15
+ /**
16
+ * Automatic instrumentation installed by `init()`: network requests, console, navigation,
17
+ * clicks and page lifecycle. Every installer is a no-op on platforms that lack the global it
18
+ * patches, and returns a function that undoes the patch.
19
+ */
20
+ interface RequestInfo {
21
+ method: string;
22
+ url: string;
23
+ status?: number;
24
+ error?: unknown;
25
+ aborted?: boolean;
26
+ timedOut?: boolean;
27
+ durationMs: number;
28
+ /** Stack captured where the request was made, so a failure points at the calling code. */
29
+ stack?: string;
30
+ }
31
+ /** What the instrumentation needs from the client. */
32
+ interface AutoSink {
33
+ request(info: RequestInfo): void;
34
+ crumb(category: "navigation" | "network" | "ui" | "log", message: string, level?: "debug" | "info" | "warning" | "error", data?: Record<string, string | number | boolean | null>): void;
35
+ navigated(to: string): void;
36
+ lifecycle(state: "foreground" | "background"): void;
37
+ ignored(url: string): boolean;
38
+ }
39
+ /**
40
+ * "https://api.x.com/v1/orders/8812?token=abc" → "api.x.com/v1/orders/:id". Query strings and
41
+ * fragments never leave the device (they often carry tokens and personal data), and ids are
42
+ * replaced so requests group by endpoint. Same-origin URLs keep only the path.
43
+ */
44
+ declare function normaliseUrl(raw: string): string;
45
+
46
+ declare const SDK_NAME = "@debugkit/sdk";
47
+ declare const SDK_VERSION = "0.2.0";
48
+ /** Optional persistence so events survive app restarts / offline. e.g. AsyncStorage. */
49
+ interface QueueStorage {
50
+ getItem(key: string): Promise<string | null>;
51
+ setItem(key: string, value: string): Promise<void>;
52
+ }
53
+ interface InitOptions {
54
+ /** URL of the ingest function deployed in your cloud. */
55
+ endpoint: string;
56
+ /** Public, write-only key. Safe to ship in the app. */
57
+ ingestKey: string;
58
+ app: {
59
+ id: string;
60
+ version?: string;
61
+ build?: string;
62
+ environment?: string;
63
+ };
64
+ /**
65
+ * Platform context. Defaults to browserContext() in browsers. The framework entry points
66
+ * (`/expo`, `/react-native`, `/node`) fill this in for you.
67
+ */
68
+ context?: ContextPatch;
69
+ /**
70
+ * What deBug records on its own once initialised. Everything is on by default; pass `false`
71
+ * to turn it all off, or switch parts off: `autoCapture: { console: false }`.
72
+ */
73
+ autoCapture?: boolean | AutoCaptureOptions;
74
+ /** Network capture settings. */
75
+ network?: NetworkOptions;
76
+ /** Fraction of errors and events to keep, 0 to 1. Sessions are never sampled. Default 1. */
77
+ sampleRate?: number;
78
+ /** At most this many errors are sent per minute, and at most a sixth of that for one repeating error. Default 60. */
79
+ maxErrorsPerMinute?: number;
80
+ /** @deprecated Use `autoCapture: { errors: false }`. */
81
+ captureGlobalErrors?: boolean;
82
+ storage?: QueueStorage;
83
+ /** How often queued events are sent. 0 disables the timer (edge runtimes): call flush() yourself. Default 5000. */
84
+ flushIntervalMs?: number;
85
+ maxBatch?: number;
86
+ maxBreadcrumbs?: number;
87
+ /** Drop or edit events before they are sent (PII scrubbing). Return null to drop. */
88
+ beforeSend?: (e: EventInput) => EventInput | null;
89
+ fetch?: typeof fetch;
90
+ debug?: boolean;
91
+ }
92
+ interface AutoCaptureOptions {
93
+ /** Uncaught errors and unhandled promise rejections. */
94
+ errors?: boolean;
95
+ /** fetch and XMLHttpRequest: a breadcrumb for every request, an error for each failed one. */
96
+ network?: boolean;
97
+ /** console.warn and console.error as breadcrumbs. */
98
+ console?: boolean;
99
+ /** Page changes in browsers (History API), so any router is covered. */
100
+ navigation?: boolean;
101
+ /** Clicks on buttons, links and other controls in browsers, by their label. */
102
+ clicks?: boolean;
103
+ /** Foreground/background and online/offline as breadcrumbs; flushes when the app is hidden. */
104
+ lifecycle?: boolean;
105
+ /** Session start, errored and crashed markers, for crash-free rates per release. */
106
+ sessions?: boolean;
107
+ }
108
+ interface NetworkOptions {
109
+ /** URLs never recorded (substring or regex). The ingest endpoint is always skipped. */
110
+ ignoreUrls?: (string | RegExp)[];
111
+ /**
112
+ * Tag requests with a flow by URL, first match wins:
113
+ * `flows: [["/v2/auth/", "auth.login"], [/\/payments\//, "checkout.payment"]]`.
114
+ */
115
+ flows?: [string | RegExp, string][];
116
+ /** Which HTTP statuses count as failures. Default: 500 and above. Network failures and timeouts always count. */
117
+ isFailure?: (status: number, url: string) => boolean;
118
+ /** Requests slower than this get a warning breadcrumb. Default 3000ms. */
119
+ slowMs?: number;
120
+ }
121
+ interface EventMeta {
122
+ flow?: string;
123
+ step?: string;
124
+ tags?: Record<string, string>;
125
+ }
126
+ declare class DebugClient {
127
+ private opts;
128
+ private queue;
129
+ private crumbs;
130
+ private session;
131
+ private user;
132
+ private timer;
133
+ private flushing;
134
+ private backoffUntil;
135
+ private failures;
136
+ private ready;
137
+ private handlersInstalled;
138
+ private auto;
139
+ private restores;
140
+ private sessionState;
141
+ private lastNav;
142
+ private limits;
143
+ /** fetch as it was before instrumentation, so our own uploads are never recorded. */
144
+ private rawFetch;
145
+ init(options: InitOptions): this;
146
+ /** Which automatic captures are on, after defaults. */
147
+ get autoCapture(): Readonly<Required<AutoCaptureOptions>>;
148
+ /**
149
+ * Begin a new session: a fresh id and a "started" marker. Called by `init()`, and by the
150
+ * React Native entry when the app returns after 30 minutes in the background.
151
+ */
152
+ startSession(): void;
153
+ /** Record a navigation breadcrumb ("from → to"). Repeated paths are ignored. */
154
+ navigated(to: string): void;
155
+ get initialized(): boolean;
156
+ /** Merge extra context (e.g. after an async device lookup). Applies to events sent from now on. */
157
+ setContext(patch: ContextPatch): void;
158
+ setUser(id: string | undefined): void;
159
+ breadcrumb(category: Breadcrumb["category"], message: string, data?: Record<string, string | number | boolean | null>, level?: Breadcrumb["level"]): void;
160
+ /** Log an error. `flow` is the part of the app it belongs to, e.g. "auth.login". */
161
+ error(err: unknown, meta?: EventMeta & {
162
+ severity?: Severity;
163
+ handled?: boolean;
164
+ fatal?: boolean;
165
+ }): void;
166
+ /** Log a custom event. Use outcome to let deBug compute failure rates per flow. */
167
+ event(name: string, meta?: EventMeta & {
168
+ outcome?: "success" | "failure" | "abandoned";
169
+ props?: Record<string, string | number | boolean | null>;
170
+ }): void;
171
+ /**
172
+ * Wraps an async step: logs a success or failure outcome for the flow, plus the error.
173
+ * Pass `{ captureError: false }` when the error is already reported elsewhere, e.g. a
174
+ * server function wrapped in withDebug, so it isn't counted twice.
175
+ */
176
+ track<T>(flow: string, step: string, fn: () => Promise<T>, opts?: {
177
+ captureError?: boolean;
178
+ }): Promise<T>;
179
+ flush(): Promise<void>;
180
+ /** Stop the flush timer, undo automatic instrumentation and send what is queued. */
181
+ close(): Promise<void>;
182
+ /** @internal Used by the platform entry points for errors that have no thrown value. */
183
+ captureError(e: {
184
+ name: string;
185
+ message: string;
186
+ stack?: string;
187
+ frames?: ReturnType<typeof parseStack>;
188
+ }, meta: EventMeta & {
189
+ severity?: Severity;
190
+ handled?: boolean;
191
+ fatal?: boolean;
192
+ }, request?: {
193
+ method: string;
194
+ url: string;
195
+ status?: number;
196
+ durationMs?: number;
197
+ }): void;
198
+ /** Per-minute limits: one runaway error can't flood the queue, the network or your database. */
199
+ private allowError;
200
+ private sampled;
201
+ private enqueue;
202
+ /** Queue without sampling (sessions must be complete for crash-free rates to be right). */
203
+ private push;
204
+ private buildContext;
205
+ /** Set when the ingest rejects 0.2 fields: it predates them, so send what it understands. */
206
+ private legacyIngest;
207
+ private send;
208
+ private persist;
209
+ private restore;
210
+ private installGlobalHandlers;
211
+ private instrument;
212
+ private uninstrument;
213
+ /** The bridge the instrumentation (./auto, and the platform entry points) reports through. */
214
+ sink(): AutoSink;
215
+ private isIgnored;
216
+ private recordRequest;
217
+ private log;
218
+ }
219
+
220
+ export { type AutoCaptureOptions as A, type ContextPatch as C, DebugClient as D, type EventMeta as E, type InitOptions as I, type NetworkOptions as N, type QueueStorage as Q, SDK_NAME as S, SDK_VERSION as a, browserContext as b, mergeContext as m, normaliseUrl as n };
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkKUJ4EW3D_cjs = require('./chunk-KUJ4EW3D.cjs');
4
- var chunkXEFWRCN4_cjs = require('./chunk-XEFWRCN4.cjs');
3
+ var chunkYELZOB7J_cjs = require('./chunk-YELZOB7J.cjs');
4
+ var chunkEGCXLOFH_cjs = require('./chunk-EGCXLOFH.cjs');
5
5
  var expoRouter = require('expo-router');
6
6
 
7
- function useDebugExpoRouter(client = chunkXEFWRCN4_cjs.deBug) {
8
- chunkKUJ4EW3D_cjs.useDebugNavigation(expoRouter.usePathname(), client);
7
+ function useDebugExpoRouter(client = chunkEGCXLOFH_cjs.deBug) {
8
+ chunkYELZOB7J_cjs.useDebugNavigation(expoRouter.usePathname(), client);
9
9
  }
10
10
 
11
11
  exports.useDebugExpoRouter = useDebugExpoRouter;
@@ -1,4 +1,4 @@
1
- import { D as DebugClient } from './client-drmb0n15.cjs';
1
+ import { D as DebugClient } from './client-ekzlpWIR.cjs';
2
2
  import '@debugkit/schema/core';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { D as DebugClient } from './client-drmb0n15.js';
1
+ import { D as DebugClient } from './client-ekzlpWIR.js';
2
2
  import '@debugkit/schema/core';
3
3
 
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { useDebugNavigation } from './chunk-3UN5VMQU.js';
2
- import { deBug } from './chunk-VIJ5USKQ.js';
1
+ import { useDebugNavigation } from './chunk-3WRI3DI2.js';
2
+ import { deBug } from './chunk-5C7KJJNO.js';
3
3
  import { usePathname } from 'expo-router';
4
4
 
5
5
  function useDebugExpoRouter(client = deBug) {
package/dist/expo.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkNSWUGBA2_cjs = require('./chunk-NSWUGBA2.cjs');
4
- var chunkKUJ4EW3D_cjs = require('./chunk-KUJ4EW3D.cjs');
5
- var chunkXEFWRCN4_cjs = require('./chunk-XEFWRCN4.cjs');
3
+ var chunkNJ6DTUVX_cjs = require('./chunk-NJ6DTUVX.cjs');
4
+ var chunkYELZOB7J_cjs = require('./chunk-YELZOB7J.cjs');
5
+ var chunkEGCXLOFH_cjs = require('./chunk-EGCXLOFH.cjs');
6
6
  var Application = require('expo-application');
7
7
  var Device = require('expo-device');
8
8
 
@@ -52,12 +52,12 @@ function expoContext() {
52
52
  }
53
53
  };
54
54
  }
55
- function initExpo(options, client = chunkXEFWRCN4_cjs.deBug) {
55
+ function initExpo(options, client = chunkEGCXLOFH_cjs.deBug) {
56
56
  var _a;
57
57
  const ctx = expoContext();
58
- const merged = chunkXEFWRCN4_cjs.mergeContext(ctx, (_a = options.context) != null ? _a : {});
58
+ const merged = chunkEGCXLOFH_cjs.mergeContext(ctx, (_a = options.context) != null ? _a : {});
59
59
  if (!ctx.os) delete merged.os;
60
- return chunkNSWUGBA2_cjs.initReactNative(
60
+ return chunkNJ6DTUVX_cjs.initReactNative(
61
61
  { ...options, app: { ...ctx.app, ...options.app }, context: merged },
62
62
  client
63
63
  );
@@ -65,31 +65,31 @@ function initExpo(options, client = chunkXEFWRCN4_cjs.deBug) {
65
65
 
66
66
  Object.defineProperty(exports, "initReactNative", {
67
67
  enumerable: true,
68
- get: function () { return chunkNSWUGBA2_cjs.initReactNative; }
68
+ get: function () { return chunkNJ6DTUVX_cjs.initReactNative; }
69
69
  });
70
70
  Object.defineProperty(exports, "nativeContext", {
71
71
  enumerable: true,
72
- get: function () { return chunkNSWUGBA2_cjs.nativeContext; }
72
+ get: function () { return chunkNJ6DTUVX_cjs.nativeContext; }
73
73
  });
74
74
  Object.defineProperty(exports, "trackReactNavigation", {
75
75
  enumerable: true,
76
- get: function () { return chunkNSWUGBA2_cjs.trackReactNavigation; }
76
+ get: function () { return chunkNJ6DTUVX_cjs.trackReactNavigation; }
77
77
  });
78
78
  Object.defineProperty(exports, "DebugErrorBoundary", {
79
79
  enumerable: true,
80
- get: function () { return chunkKUJ4EW3D_cjs.DebugErrorBoundary; }
80
+ get: function () { return chunkYELZOB7J_cjs.DebugErrorBoundary; }
81
81
  });
82
82
  Object.defineProperty(exports, "trackTanStackRouter", {
83
83
  enumerable: true,
84
- get: function () { return chunkKUJ4EW3D_cjs.trackTanStackRouter; }
84
+ get: function () { return chunkYELZOB7J_cjs.trackTanStackRouter; }
85
85
  });
86
86
  Object.defineProperty(exports, "useDebugNavigation", {
87
87
  enumerable: true,
88
- get: function () { return chunkKUJ4EW3D_cjs.useDebugNavigation; }
88
+ get: function () { return chunkYELZOB7J_cjs.useDebugNavigation; }
89
89
  });
90
90
  Object.defineProperty(exports, "deBug", {
91
91
  enumerable: true,
92
- get: function () { return chunkXEFWRCN4_cjs.deBug; }
92
+ get: function () { return chunkEGCXLOFH_cjs.deBug; }
93
93
  });
94
94
  exports.expoContext = expoContext;
95
95
  exports.initExpo = initExpo;
package/dist/expo.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { deBug } from './index.cjs';
2
- import { C as ContextPatch, D as DebugClient } from './client-drmb0n15.cjs';
2
+ import { C as ContextPatch, D as DebugClient } from './client-ekzlpWIR.cjs';
3
3
  import { ReactNativeInitOptions } from './react-native.cjs';
4
4
  export { DeviceInfoModule, initReactNative, nativeContext, trackReactNavigation } from './react-native.cjs';
5
5
  export { DebugErrorBoundary, DebugErrorBoundaryProps, trackTanStackRouter, useDebugNavigation } from './react.cjs';
package/dist/expo.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { deBug } from './index.js';
2
- import { C as ContextPatch, D as DebugClient } from './client-drmb0n15.js';
2
+ import { C as ContextPatch, D as DebugClient } from './client-ekzlpWIR.js';
3
3
  import { ReactNativeInitOptions } from './react-native.js';
4
4
  export { DeviceInfoModule, initReactNative, nativeContext, trackReactNavigation } from './react-native.js';
5
5
  export { DebugErrorBoundary, DebugErrorBoundaryProps, trackTanStackRouter, useDebugNavigation } from './react.js';
package/dist/expo.js CHANGED
@@ -1,8 +1,8 @@
1
- import { initReactNative } from './chunk-BD2FNVCP.js';
2
- export { initReactNative, nativeContext, trackReactNavigation } from './chunk-BD2FNVCP.js';
3
- export { DebugErrorBoundary, trackTanStackRouter, useDebugNavigation } from './chunk-3UN5VMQU.js';
4
- import { deBug, mergeContext } from './chunk-VIJ5USKQ.js';
5
- export { deBug } from './chunk-VIJ5USKQ.js';
1
+ import { initReactNative } from './chunk-HO3JW55K.js';
2
+ export { initReactNative, nativeContext, trackReactNavigation } from './chunk-HO3JW55K.js';
3
+ export { DebugErrorBoundary, trackTanStackRouter, useDebugNavigation } from './chunk-3WRI3DI2.js';
4
+ import { deBug, mergeContext } from './chunk-5C7KJJNO.js';
5
+ export { deBug } from './chunk-5C7KJJNO.js';
6
6
  import * as Application from 'expo-application';
7
7
  import * as Device from 'expo-device';
8
8
 
package/dist/index.cjs CHANGED
@@ -1,36 +1,40 @@
1
1
  'use strict';
2
2
 
3
- var chunkXEFWRCN4_cjs = require('./chunk-XEFWRCN4.cjs');
3
+ var chunkEGCXLOFH_cjs = require('./chunk-EGCXLOFH.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "DebugClient", {
8
8
  enumerable: true,
9
- get: function () { return chunkXEFWRCN4_cjs.DebugClient; }
9
+ get: function () { return chunkEGCXLOFH_cjs.DebugClient; }
10
10
  });
11
11
  Object.defineProperty(exports, "SDK_NAME", {
12
12
  enumerable: true,
13
- get: function () { return chunkXEFWRCN4_cjs.SDK_NAME; }
13
+ get: function () { return chunkEGCXLOFH_cjs.SDK_NAME; }
14
14
  });
15
15
  Object.defineProperty(exports, "SDK_VERSION", {
16
16
  enumerable: true,
17
- get: function () { return chunkXEFWRCN4_cjs.SDK_VERSION; }
17
+ get: function () { return chunkEGCXLOFH_cjs.SDK_VERSION; }
18
18
  });
19
19
  Object.defineProperty(exports, "browserContext", {
20
20
  enumerable: true,
21
- get: function () { return chunkXEFWRCN4_cjs.browserContext; }
21
+ get: function () { return chunkEGCXLOFH_cjs.browserContext; }
22
22
  });
23
23
  Object.defineProperty(exports, "deBug", {
24
24
  enumerable: true,
25
- get: function () { return chunkXEFWRCN4_cjs.deBug; }
25
+ get: function () { return chunkEGCXLOFH_cjs.deBug; }
26
26
  });
27
27
  Object.defineProperty(exports, "mergeContext", {
28
28
  enumerable: true,
29
- get: function () { return chunkXEFWRCN4_cjs.mergeContext; }
29
+ get: function () { return chunkEGCXLOFH_cjs.mergeContext; }
30
+ });
31
+ Object.defineProperty(exports, "normaliseUrl", {
32
+ enumerable: true,
33
+ get: function () { return chunkEGCXLOFH_cjs.normaliseUrl; }
30
34
  });
31
35
  Object.defineProperty(exports, "parseStack", {
32
36
  enumerable: true,
33
- get: function () { return chunkXEFWRCN4_cjs.parseStack; }
37
+ get: function () { return chunkEGCXLOFH_cjs.parseStack; }
34
38
  });
35
39
  //# sourceMappingURL=index.cjs.map
36
40
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { D as DebugClient } from './client-drmb0n15.cjs';
2
- export { C as ContextPatch, E as EventMeta, I as InitOptions, Q as QueueStorage, S as SDK_NAME, a as SDK_VERSION, b as browserContext, m as mergeContext } from './client-drmb0n15.cjs';
1
+ import { D as DebugClient } from './client-ekzlpWIR.cjs';
2
+ export { A as AutoCaptureOptions, C as ContextPatch, E as EventMeta, I as InitOptions, N as NetworkOptions, Q as QueueStorage, S as SDK_NAME, a as SDK_VERSION, b as browserContext, m as mergeContext, n as normaliseUrl } from './client-ekzlpWIR.cjs';
3
3
  export { Breadcrumb, EventInput, Severity, StackFrame, parseStack } from '@debugkit/schema/core';
4
4
 
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { D as DebugClient } from './client-drmb0n15.js';
2
- export { C as ContextPatch, E as EventMeta, I as InitOptions, Q as QueueStorage, S as SDK_NAME, a as SDK_VERSION, b as browserContext, m as mergeContext } from './client-drmb0n15.js';
1
+ import { D as DebugClient } from './client-ekzlpWIR.js';
2
+ export { A as AutoCaptureOptions, C as ContextPatch, E as EventMeta, I as InitOptions, N as NetworkOptions, Q as QueueStorage, S as SDK_NAME, a as SDK_VERSION, b as browserContext, m as mergeContext, n as normaliseUrl } from './client-ekzlpWIR.js';
3
3
  export { Breadcrumb, EventInput, Severity, StackFrame, parseStack } from '@debugkit/schema/core';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { DebugClient, SDK_NAME, SDK_VERSION, browserContext, deBug, mergeContext, parseStack } from './chunk-VIJ5USKQ.js';
1
+ export { DebugClient, SDK_NAME, SDK_VERSION, browserContext, deBug, mergeContext, normaliseUrl, parseStack } from './chunk-5C7KJJNO.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/node.cjs CHANGED
@@ -1,10 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunkXEFWRCN4_cjs = require('./chunk-XEFWRCN4.cjs');
3
+ var chunkEGCXLOFH_cjs = require('./chunk-EGCXLOFH.cjs');
4
+ var dc = require('diagnostics_channel');
4
5
  var os = require('os');
5
6
 
6
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
8
 
9
+ var dc__default = /*#__PURE__*/_interopDefault(dc);
8
10
  var os__default = /*#__PURE__*/_interopDefault(os);
9
11
 
10
12
  function nodeContext() {
@@ -12,14 +14,16 @@ function nodeContext() {
12
14
  os: { name: os__default.default.platform(), version: os__default.default.release() },
13
15
  runtime: { name: "node", version: process.versions.node },
14
16
  device: { type: "unknown", memoryMb: Math.round(os__default.default.totalmem() / 1024 / 1024) },
15
- timezone: chunkXEFWRCN4_cjs.timezone()
17
+ timezone: chunkEGCXLOFH_cjs.timezone()
16
18
  };
17
19
  }
18
20
  var installed = false;
19
- function initNode(options, client = chunkXEFWRCN4_cjs.deBug) {
20
- var _a;
21
+ function initNode(options, client = chunkEGCXLOFH_cjs.deBug) {
22
+ var _a, _b;
21
23
  const { captureProcessErrors = true, shutdownTimeoutMs = 2e3, ...rest } = options;
22
- client.init({ ...rest, captureGlobalErrors: false, context: chunkXEFWRCN4_cjs.mergeContext(nodeContext(), (_a = rest.context) != null ? _a : {}) });
24
+ const auto = rest.autoCapture === false ? false : { console: false, ...typeof rest.autoCapture === "object" ? rest.autoCapture : {} };
25
+ client.init({ ...rest, autoCapture: auto === false ? false : { ...auto, errors: false }, context: chunkEGCXLOFH_cjs.mergeContext(nodeContext(), (_a = rest.context) != null ? _a : {}) });
26
+ if (client.autoCapture.network) instrumentNodeHttp(client, (_b = rest.captureServerErrors) != null ? _b : true);
23
27
  if (!captureProcessErrors || installed) return client;
24
28
  installed = true;
25
29
  const flushThenExit = async (err) => {
@@ -28,7 +32,7 @@ function initNode(options, client = chunkXEFWRCN4_cjs.deBug) {
28
32
  process.exit(1);
29
33
  };
30
34
  process.on("uncaughtException", (err) => {
31
- client.error(err, { handled: false, severity: "critical", tags: { source: "uncaughtException" } });
35
+ client.error(err, { handled: false, fatal: true, tags: { source: "uncaughtException" } });
32
36
  void flushThenExit(err);
33
37
  });
34
38
  process.on("unhandledRejection", (reason) => {
@@ -38,7 +42,54 @@ function initNode(options, client = chunkXEFWRCN4_cjs.deBug) {
38
42
  process.on("beforeExit", () => void client.flush());
39
43
  return client;
40
44
  }
41
- function withDebug(flow, fn, client = chunkXEFWRCN4_cjs.deBug) {
45
+ var httpInstrumented = false;
46
+ function instrumentNodeHttp(client, captureServer) {
47
+ var _a;
48
+ if (httpInstrumented || typeof ((_a = dc__default.default) == null ? void 0 : _a.subscribe) !== "function") return;
49
+ httpInstrumented = true;
50
+ const sink = client.sink();
51
+ const urlOf = (r) => {
52
+ var _a2, _b, _c, _d, _e;
53
+ return `${(_a2 = r.protocol) != null ? _a2 : "http:"}//${String((_d = (_c = (_b = r.getHeader) == null ? void 0 : _b.call(r, "host")) != null ? _c : r.host) != null ? _d : "")}${(_e = r.path) != null ? _e : ""}`;
54
+ };
55
+ dc__default.default.subscribe("http.client.request.start", (m) => {
56
+ const r = m.request;
57
+ r.__debugStart = Date.now();
58
+ r.__debugStack = new Error().stack;
59
+ });
60
+ dc__default.default.subscribe("http.client.response.finish", (m) => {
61
+ var _a2, _b;
62
+ const { request: r, response } = m;
63
+ const url = urlOf(r);
64
+ if (sink.ignored(url)) return;
65
+ sink.request({ method: (_a2 = r.method) != null ? _a2 : "GET", url, status: response.statusCode, durationMs: Date.now() - ((_b = r.__debugStart) != null ? _b : Date.now()), stack: r.__debugStack });
66
+ });
67
+ dc__default.default.subscribe("http.client.request.error", (m) => {
68
+ var _a2, _b;
69
+ const { request: r, error } = m;
70
+ const url = urlOf(r);
71
+ if (sink.ignored(url)) return;
72
+ sink.request({ method: (_a2 = r.method) != null ? _a2 : "GET", url, error, durationMs: Date.now() - ((_b = r.__debugStart) != null ? _b : Date.now()), stack: r.__debugStack });
73
+ });
74
+ if (!captureServer) return;
75
+ dc__default.default.subscribe("http.server.request.start", (m) => {
76
+ m.request.__debugStart = Date.now();
77
+ });
78
+ dc__default.default.subscribe("http.server.response.finish", (m) => {
79
+ var _a2, _b, _c, _d;
80
+ const { request: r, response } = m;
81
+ const status = (_a2 = response.statusCode) != null ? _a2 : 0;
82
+ if (status < 500) return;
83
+ const url = chunkEGCXLOFH_cjs.normaliseUrl((_b = r.url) != null ? _b : "/");
84
+ const method = ((_c = r.method) != null ? _c : "GET").toUpperCase();
85
+ client.captureError(
86
+ { name: "HttpServerError", message: `${method} ${url} responded ${status}`, frames: [] },
87
+ { handled: true, tags: { source: "http-server" } },
88
+ { method, url, status, durationMs: Date.now() - ((_d = r.__debugStart) != null ? _d : Date.now()) }
89
+ );
90
+ });
91
+ }
92
+ function withDebug(flow, fn, client = chunkEGCXLOFH_cjs.deBug) {
42
93
  return async (...args) => {
43
94
  try {
44
95
  return await fn(...args);
@@ -52,31 +103,35 @@ function withDebug(flow, fn, client = chunkXEFWRCN4_cjs.deBug) {
52
103
 
53
104
  Object.defineProperty(exports, "DebugClient", {
54
105
  enumerable: true,
55
- get: function () { return chunkXEFWRCN4_cjs.DebugClient; }
106
+ get: function () { return chunkEGCXLOFH_cjs.DebugClient; }
56
107
  });
57
108
  Object.defineProperty(exports, "SDK_NAME", {
58
109
  enumerable: true,
59
- get: function () { return chunkXEFWRCN4_cjs.SDK_NAME; }
110
+ get: function () { return chunkEGCXLOFH_cjs.SDK_NAME; }
60
111
  });
61
112
  Object.defineProperty(exports, "SDK_VERSION", {
62
113
  enumerable: true,
63
- get: function () { return chunkXEFWRCN4_cjs.SDK_VERSION; }
114
+ get: function () { return chunkEGCXLOFH_cjs.SDK_VERSION; }
64
115
  });
65
116
  Object.defineProperty(exports, "browserContext", {
66
117
  enumerable: true,
67
- get: function () { return chunkXEFWRCN4_cjs.browserContext; }
118
+ get: function () { return chunkEGCXLOFH_cjs.browserContext; }
68
119
  });
69
120
  Object.defineProperty(exports, "deBug", {
70
121
  enumerable: true,
71
- get: function () { return chunkXEFWRCN4_cjs.deBug; }
122
+ get: function () { return chunkEGCXLOFH_cjs.deBug; }
72
123
  });
73
124
  Object.defineProperty(exports, "mergeContext", {
74
125
  enumerable: true,
75
- get: function () { return chunkXEFWRCN4_cjs.mergeContext; }
126
+ get: function () { return chunkEGCXLOFH_cjs.mergeContext; }
127
+ });
128
+ Object.defineProperty(exports, "normaliseUrl", {
129
+ enumerable: true,
130
+ get: function () { return chunkEGCXLOFH_cjs.normaliseUrl; }
76
131
  });
77
132
  Object.defineProperty(exports, "parseStack", {
78
133
  enumerable: true,
79
- get: function () { return chunkXEFWRCN4_cjs.parseStack; }
134
+ get: function () { return chunkEGCXLOFH_cjs.parseStack; }
80
135
  });
81
136
  exports.initNode = initNode;
82
137
  exports.nodeContext = nodeContext;
package/dist/node.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/node.ts"],"names":["os","timezone","deBug","mergeContext"],"mappings":";;;;;;;;;AAKO,SAAS,WAAA,GAA4B;AAC1C,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,EAAE,IAAA,EAAMA,mBAAA,CAAG,UAAS,EAAG,OAAA,EAASA,mBAAA,CAAG,OAAA,EAAQ,EAAE;AAAA,IACjD,SAAS,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,OAAA,CAAQ,SAAS,IAAA,EAAK;AAAA,IACxD,MAAA,EAAQ,EAAE,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,IAAA,CAAK,KAAA,CAAMA,mBAAA,CAAG,QAAA,EAAS,GAAI,IAAA,GAAO,IAAI,CAAA,EAAE;AAAA,IAC7E,UAAUC,0BAAA;AAAS,GACrB;AACF;AASA,IAAI,SAAA,GAAY,KAAA;AAGT,SAAS,QAAA,CAAS,OAAA,EAA0B,MAAA,GAAsBC,uBAAA,EAAoB;AAxB7F,EAAA,IAAA,EAAA;AAyBE,EAAA,MAAM,EAAE,oBAAA,GAAuB,IAAA,EAAM,oBAAoB,GAAA,EAAM,GAAG,MAAK,GAAI,OAAA;AAC3E,EAAA,MAAA,CAAO,KAAK,EAAE,GAAG,IAAA,EAAM,mBAAA,EAAqB,OAAO,OAAA,EAASC,8BAAA,CAAa,WAAA,EAAY,EAAA,CAAG,UAAK,OAAA,KAAL,IAAA,GAAA,EAAA,GAAgB,EAAE,GAAG,CAAA;AAC7G,EAAA,IAAI,CAAC,oBAAA,IAAwB,SAAA,EAAW,OAAO,MAAA;AAC/C,EAAA,SAAA,GAAY,IAAA;AAEZ,EAAA,MAAM,aAAA,GAAgB,OAAO,GAAA,KAAiB;AAC5C,IAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,CAAO,OAAM,EAAG,IAAI,OAAA,CAAQ,CAAC,MAAM,UAAA,CAAW,CAAA,EAAG,iBAAiB,CAAC,CAAC,CAAC,CAAA;AACzF,IAAA,OAAA,CAAQ,MAAM,GAAG,CAAA;AACjB,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB,CAAA;AAEA,EAAA,OAAA,CAAQ,EAAA,CAAG,mBAAA,EAAqB,CAAC,GAAA,KAAQ;AACvC,IAAA,MAAA,CAAO,KAAA,CAAM,GAAA,EAAK,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,IAAA,EAAM,EAAE,MAAA,EAAQ,mBAAA,EAAoB,EAAG,CAAA;AACjG,IAAA,KAAK,cAAc,GAAG,CAAA;AAAA,EACxB,CAAC,CAAA;AACD,EAAA,OAAA,CAAQ,EAAA,CAAG,oBAAA,EAAsB,CAAC,MAAA,KAAW;AAC3C,IAAA,MAAA,CAAO,KAAA,CAAM,MAAA,EAAQ,EAAE,OAAA,EAAS,KAAA,EAAO,MAAM,EAAE,MAAA,EAAQ,oBAAA,EAAqB,EAAG,CAAA;AAC/E,IAAA,IAAI,QAAQ,aAAA,CAAc,oBAAoB,MAAM,CAAA,EAAG,KAAK,cAAc,MAAM,CAAA;AAAA,EAClF,CAAC,CAAA;AACD,EAAA,OAAA,CAAQ,GAAG,YAAA,EAAc,MAAM,KAAK,MAAA,CAAO,OAAO,CAAA;AAClD,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,SAAA,CAAkC,IAAA,EAAc,EAAA,EAAgC,MAAA,GAAsBD,uBAAA,EAAO;AAC3H,EAAA,OAAO,UAAU,IAAA,KAAwB;AACvC,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,MAAM,GAAA,EAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AAC1C,MAAA,MAAM,OAAO,KAAA,EAAM;AACnB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF","file":"node.cjs","sourcesContent":["import os from \"node:os\";\nimport { deBug, type DebugClient, type InitOptions } from \"./index\";\nimport { mergeContext, timezone, type ContextPatch } from \"./context\";\n\n/** Context for Node servers (TanStack Start server functions, Next API routes, Express ...). */\nexport function nodeContext(): ContextPatch {\n return {\n os: { name: os.platform(), version: os.release() },\n runtime: { name: \"node\", version: process.versions.node },\n device: { type: \"unknown\", memoryMb: Math.round(os.totalmem() / 1024 / 1024) },\n timezone: timezone(),\n };\n}\n\nexport interface NodeInitOptions extends InitOptions {\n /** Capture uncaught exceptions and unhandled rejections, then exit like Node would. Default true. */\n captureProcessErrors?: boolean;\n /** Max time to wait for a final flush before exiting on a fatal error. Default 2000ms. */\n shutdownTimeoutMs?: number;\n}\n\nlet installed = false;\n\n/** Initialise deBug on a Node server. */\nexport function initNode(options: NodeInitOptions, client: DebugClient = deBug): DebugClient {\n const { captureProcessErrors = true, shutdownTimeoutMs = 2000, ...rest } = options;\n client.init({ ...rest, captureGlobalErrors: false, context: mergeContext(nodeContext(), rest.context ?? {}) });\n if (!captureProcessErrors || installed) return client;\n installed = true;\n\n const flushThenExit = async (err: unknown) => {\n await Promise.race([client.flush(), new Promise((r) => setTimeout(r, shutdownTimeoutMs))]);\n console.error(err);\n process.exit(1);\n };\n // Adding these listeners disables Node's default crash, so we re-create it after flushing.\n process.on(\"uncaughtException\", (err) => {\n client.error(err, { handled: false, severity: \"critical\", tags: { source: \"uncaughtException\" } });\n void flushThenExit(err);\n });\n process.on(\"unhandledRejection\", (reason) => {\n client.error(reason, { handled: false, tags: { source: \"unhandledRejection\" } });\n if (process.listenerCount(\"unhandledRejection\") === 1) void flushThenExit(reason);\n });\n process.on(\"beforeExit\", () => void client.flush());\n return client;\n}\n\n/**\n * Wrap a server handler so any error it throws is reported (and re-thrown).\n * Good for TanStack Start server functions and route handlers:\n * .handler(withDebug(\"checkout.payment\", async ({ data }) => { ... }))\n */\nexport function withDebug<A extends unknown[], R>(flow: string, fn: (...args: A) => Promise<R>, client: DebugClient = deBug) {\n return async (...args: A): Promise<R> => {\n try {\n return await fn(...args);\n } catch (err) {\n client.error(err, { flow, handled: false });\n await client.flush();\n throw err;\n }\n };\n}\n\nexport * from \"./index\";\n"]}
1
+ {"version":3,"sources":["../src/node.ts"],"names":["os","timezone","deBug","mergeContext","dc","_a","normaliseUrl"],"mappings":"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","file":"node.cjs","sourcesContent":["import dc from \"node:diagnostics_channel\";\nimport os from \"node:os\";\nimport { deBug, type DebugClient, type InitOptions } from \"./index\";\nimport { mergeContext, timezone, type ContextPatch } from \"./context\";\nimport { normaliseUrl } from \"./auto\";\n\n/** Context for Node servers (TanStack Start server functions, Next API routes, Express ...). */\nexport function nodeContext(): ContextPatch {\n return {\n os: { name: os.platform(), version: os.release() },\n runtime: { name: \"node\", version: process.versions.node },\n device: { type: \"unknown\", memoryMb: Math.round(os.totalmem() / 1024 / 1024) },\n timezone: timezone(),\n };\n}\n\nexport interface NodeInitOptions extends InitOptions {\n /** Capture uncaught exceptions and unhandled rejections, then exit like Node would. Default true. */\n captureProcessErrors?: boolean;\n /** Max time to wait for a final flush before exiting on a fatal error. Default 2000ms. */\n shutdownTimeoutMs?: number;\n /** Report responses your server sends with a 5xx status. Default true (needs `autoCapture.network`). */\n captureServerErrors?: boolean;\n}\n\nlet installed = false;\n\n/** Initialise deBug on a Node server. */\nexport function initNode(options: NodeInitOptions, client: DebugClient = deBug): DebugClient {\n const { captureProcessErrors = true, shutdownTimeoutMs = 2000, ...rest } = options;\n const auto = rest.autoCapture === false ? false : { console: false, ...(typeof rest.autoCapture === \"object\" ? rest.autoCapture : {}) };\n // Process-level hooks below replace the browser-style global handlers.\n client.init({ ...rest, autoCapture: auto === false ? false : { ...auto, errors: false }, context: mergeContext(nodeContext(), rest.context ?? {}) });\n if (client.autoCapture.network) instrumentNodeHttp(client, rest.captureServerErrors ?? true);\n if (!captureProcessErrors || installed) return client;\n installed = true;\n\n const flushThenExit = async (err: unknown) => {\n await Promise.race([client.flush(), new Promise((r) => setTimeout(r, shutdownTimeoutMs))]);\n console.error(err);\n process.exit(1);\n };\n // Adding these listeners disables Node's default crash, so we re-create it after flushing.\n process.on(\"uncaughtException\", (err) => {\n client.error(err, { handled: false, fatal: true, tags: { source: \"uncaughtException\" } });\n void flushThenExit(err);\n });\n process.on(\"unhandledRejection\", (reason) => {\n client.error(reason, { handled: false, tags: { source: \"unhandledRejection\" } });\n if (process.listenerCount(\"unhandledRejection\") === 1) void flushThenExit(reason);\n });\n process.on(\"beforeExit\", () => void client.flush());\n return client;\n}\n\n/**\n * Wrap a server handler so any error it throws is reported (and re-thrown).\n * Good for TanStack Start server functions and route handlers:\n * .handler(withDebug(\"checkout.payment\", async ({ data }) => { ... }))\n */\ntype ClientReq = { method?: string; protocol?: string; host?: string; path?: string; getHeader?(n: string): unknown; __debugStart?: number; __debugStack?: string };\ntype ServerReq = { method?: string; url?: string; __debugStart?: number };\nlet httpInstrumented = false;\n\n/**\n * Outgoing requests made with node:http/https (axios, got, SDKs) and responses this server\n * sends, through Node's diagnostics channels. `fetch` is covered by the shared instrumentation.\n */\nfunction instrumentNodeHttp(client: DebugClient, captureServer: boolean) {\n if (httpInstrumented || typeof dc?.subscribe !== \"function\") return;\n httpInstrumented = true;\n const sink = client.sink();\n // The Host header keeps a non-default port; request.host doesn't.\n const urlOf = (r: ClientReq) => `${r.protocol ?? \"http:\"}//${String(r.getHeader?.(\"host\") ?? r.host ?? \"\")}${r.path ?? \"\"}`;\n dc.subscribe(\"http.client.request.start\", (m) => {\n const r = (m as { request: ClientReq }).request;\n r.__debugStart = Date.now();\n r.__debugStack = new Error().stack;\n });\n dc.subscribe(\"http.client.response.finish\", (m) => {\n const { request: r, response } = m as { request: ClientReq; response: { statusCode?: number } };\n const url = urlOf(r);\n if (sink.ignored(url)) return;\n sink.request({ method: r.method ?? \"GET\", url, status: response.statusCode, durationMs: Date.now() - (r.__debugStart ?? Date.now()), stack: r.__debugStack });\n });\n dc.subscribe(\"http.client.request.error\", (m) => {\n const { request: r, error } = m as { request: ClientReq; error: unknown };\n const url = urlOf(r);\n if (sink.ignored(url)) return;\n sink.request({ method: r.method ?? \"GET\", url, error, durationMs: Date.now() - (r.__debugStart ?? Date.now()), stack: r.__debugStack });\n });\n if (!captureServer) return;\n dc.subscribe(\"http.server.request.start\", (m) => {\n (m as { request: ServerReq }).request.__debugStart = Date.now();\n });\n dc.subscribe(\"http.server.response.finish\", (m) => {\n const { request: r, response } = m as { request: ServerReq; response: { statusCode?: number } };\n const status = response.statusCode ?? 0;\n if (status < 500) return;\n const url = normaliseUrl(r.url ?? \"/\");\n const method = (r.method ?? \"GET\").toUpperCase();\n client.captureError(\n { name: \"HttpServerError\", message: `${method} ${url} responded ${status}`, frames: [] },\n { handled: true, tags: { source: \"http-server\" } },\n { method, url, status, durationMs: Date.now() - (r.__debugStart ?? Date.now()) },\n );\n });\n}\n\nexport function withDebug<A extends unknown[], R>(flow: string, fn: (...args: A) => Promise<R>, client: DebugClient = deBug) {\n return async (...args: A): Promise<R> => {\n try {\n return await fn(...args);\n } catch (err) {\n client.error(err, { flow, handled: false });\n await client.flush();\n throw err;\n }\n };\n}\n\nexport * from \"./index\";\n"]}
package/dist/node.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { deBug } from './index.cjs';
2
- import { I as InitOptions, D as DebugClient, C as ContextPatch } from './client-drmb0n15.cjs';
3
- export { E as EventMeta, Q as QueueStorage, S as SDK_NAME, a as SDK_VERSION, b as browserContext, m as mergeContext } from './client-drmb0n15.cjs';
2
+ import { I as InitOptions, D as DebugClient, C as ContextPatch } from './client-ekzlpWIR.cjs';
3
+ export { A as AutoCaptureOptions, E as EventMeta, N as NetworkOptions, Q as QueueStorage, S as SDK_NAME, a as SDK_VERSION, b as browserContext, m as mergeContext, n as normaliseUrl } from './client-ekzlpWIR.cjs';
4
4
  export { Breadcrumb, EventInput, Severity, StackFrame, parseStack } from '@debugkit/schema/core';
5
5
 
6
6
  /** Context for Node servers (TanStack Start server functions, Next API routes, Express ...). */
@@ -10,14 +10,11 @@ interface NodeInitOptions extends InitOptions {
10
10
  captureProcessErrors?: boolean;
11
11
  /** Max time to wait for a final flush before exiting on a fatal error. Default 2000ms. */
12
12
  shutdownTimeoutMs?: number;
13
+ /** Report responses your server sends with a 5xx status. Default true (needs `autoCapture.network`). */
14
+ captureServerErrors?: boolean;
13
15
  }
14
16
  /** Initialise deBug on a Node server. */
15
17
  declare function initNode(options: NodeInitOptions, client?: DebugClient): DebugClient;
16
- /**
17
- * Wrap a server handler so any error it throws is reported (and re-thrown).
18
- * Good for TanStack Start server functions and route handlers:
19
- * .handler(withDebug("checkout.payment", async ({ data }) => { ... }))
20
- */
21
18
  declare function withDebug<A extends unknown[], R>(flow: string, fn: (...args: A) => Promise<R>, client?: DebugClient): (...args: A) => Promise<R>;
22
19
 
23
20
  export { ContextPatch, DebugClient, InitOptions, type NodeInitOptions, initNode, nodeContext, withDebug };