@debugbundle/sdk-react-native 0.1.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.
- package/DebugBundleReactNative.podspec +15 -0
- package/README.md +124 -0
- package/android/build.gradle +37 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/com/debugbundle/reactnative/DebugBundleReactNativeModule.java +281 -0
- package/android/src/main/java/com/debugbundle/reactnative/DebugBundleReactNativePackage.java +20 -0
- package/app.plugin.js +52 -0
- package/dist/NativeDebugBundleReactNative.d.ts +13 -0
- package/dist/NativeDebugBundleReactNative.d.ts.map +1 -0
- package/dist/NativeDebugBundleReactNative.js +2 -0
- package/dist/app-state.d.ts +9 -0
- package/dist/app-state.d.ts.map +1 -0
- package/dist/app-state.js +10 -0
- package/dist/client.d.ts +36 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +328 -0
- package/dist/console.d.ts +3 -0
- package/dist/console.d.ts.map +1 -0
- package/dist/console.js +35 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +42 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/native.d.ts +7 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +59 -0
- package/dist/navigation.d.ts +13 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +26 -0
- package/dist/network.d.ts +14 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +179 -0
- package/dist/probes.d.ts +4 -0
- package/dist/probes.d.ts.map +1 -0
- package/dist/probes.js +8 -0
- package/dist/react.d.ts +21 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +36 -0
- package/dist/redaction.d.ts +12 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +132 -0
- package/dist/testing.d.ts +9 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +36 -0
- package/dist/types.d.ts +152 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/ios/DebugBundleReactNative.swift +125 -0
- package/ios/DebugBundleReactNativeBridge.m +28 -0
- package/package.json +99 -0
- package/src/NativeDebugBundleReactNative.ts +14 -0
- package/src/app-state.ts +17 -0
- package/src/client.ts +385 -0
- package/src/console.ts +38 -0
- package/src/errors.ts +64 -0
- package/src/index.ts +82 -0
- package/src/native.ts +79 -0
- package/src/navigation.tsx +37 -0
- package/src/network.ts +240 -0
- package/src/probes.ts +11 -0
- package/src/react-native-shim.d.ts +14 -0
- package/src/react.tsx +60 -0
- package/src/redaction.ts +165 -0
- package/src/testing.ts +45 -0
- package/src/types.ts +173 -0
package/dist/network.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { DebugBundle } from "./index.js";
|
|
2
|
+
import { sanitizeHeaders } from "./redaction.js";
|
|
3
|
+
const TRACE_HEADER = "X-DebugBundle-Trace-Id";
|
|
4
|
+
let fetchRestore = null;
|
|
5
|
+
let xhrRestore = null;
|
|
6
|
+
export function instrumentDebugBundleNetwork(options = {}) {
|
|
7
|
+
const client = options.client ?? DebugBundle;
|
|
8
|
+
const fetchTarget = globalThis;
|
|
9
|
+
if (fetchTarget.fetch && !fetchRestore) {
|
|
10
|
+
const originalFetch = fetchTarget.fetch.bind(globalThis);
|
|
11
|
+
fetchTarget.fetch = createInstrumentedFetch(originalFetch, client, options);
|
|
12
|
+
fetchRestore = () => {
|
|
13
|
+
fetchTarget.fetch = originalFetch;
|
|
14
|
+
fetchRestore = null;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (fetchTarget.XMLHttpRequest && !xhrRestore) {
|
|
18
|
+
xhrRestore = instrumentXMLHttpRequest(fetchTarget.XMLHttpRequest, client, options);
|
|
19
|
+
}
|
|
20
|
+
return () => {
|
|
21
|
+
fetchRestore?.();
|
|
22
|
+
xhrRestore?.();
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function createInstrumentedFetch(originalFetch, client, options) {
|
|
26
|
+
return (async (input, init) => {
|
|
27
|
+
const startedAt = Date.now();
|
|
28
|
+
const url = requestUrl(input);
|
|
29
|
+
const method = requestMethod(input, init);
|
|
30
|
+
const traceId = shouldInjectTrace(url, options.tracePropagationTargets ?? []) ? existingTraceHeader(input, init) ?? generateTraceId() : null;
|
|
31
|
+
const nextInit = traceId ? withTraceHeader(init, traceId) : init;
|
|
32
|
+
try {
|
|
33
|
+
const response = await originalFetch(input, nextInit);
|
|
34
|
+
maybeCaptureNetwork(client, options, url, method, traceId, response.status, Date.now() - startedAt, headersToRecord(nextInit?.headers));
|
|
35
|
+
return response;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
maybeCaptureNetwork(client, options, url, method, traceId, 0, Date.now() - startedAt, headersToRecord(nextInit?.headers));
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function shouldInjectTrace(url, targets) {
|
|
44
|
+
if (isRelativeUrl(url)) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return targets.some((target) => matchesTarget(url, target));
|
|
48
|
+
}
|
|
49
|
+
function instrumentXMLHttpRequest(OriginalXHR, client, options) {
|
|
50
|
+
const proto = OriginalXHR.prototype;
|
|
51
|
+
if (proto.__debugBundleWrapped) {
|
|
52
|
+
return () => undefined;
|
|
53
|
+
}
|
|
54
|
+
const originalOpen = proto.open;
|
|
55
|
+
const originalSend = proto.send;
|
|
56
|
+
const originalSetRequestHeader = proto.setRequestHeader;
|
|
57
|
+
proto.open = function open(method, url) {
|
|
58
|
+
this.__debugBundleMethod = method;
|
|
59
|
+
this.__debugBundleUrl = String(url);
|
|
60
|
+
return originalOpen.apply(this, arguments);
|
|
61
|
+
};
|
|
62
|
+
proto.send = function send() {
|
|
63
|
+
const url = this.__debugBundleUrl ?? "";
|
|
64
|
+
const traceId = shouldInjectTrace(url, options.tracePropagationTargets ?? []) ? generateTraceId() : null;
|
|
65
|
+
this.__debugBundleTraceId = traceId;
|
|
66
|
+
this.__debugBundleStartedAt = Date.now();
|
|
67
|
+
if (traceId) {
|
|
68
|
+
originalSetRequestHeader.call(this, TRACE_HEADER, traceId);
|
|
69
|
+
}
|
|
70
|
+
this.addEventListener("loadend", () => {
|
|
71
|
+
maybeCaptureNetwork(client, options, url, this.__debugBundleMethod ?? "GET", this.__debugBundleTraceId ?? null, this.status, Date.now() - (this.__debugBundleStartedAt ?? Date.now()), traceId ? { [TRACE_HEADER]: traceId } : {});
|
|
72
|
+
});
|
|
73
|
+
return originalSend.apply(this, arguments);
|
|
74
|
+
};
|
|
75
|
+
proto.__debugBundleWrapped = true;
|
|
76
|
+
return () => {
|
|
77
|
+
proto.open = originalOpen;
|
|
78
|
+
proto.send = originalSend;
|
|
79
|
+
proto.__debugBundleWrapped = false;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function maybeCaptureNetwork(client, options, url, method, traceId, statusCode, durationMillis, headers) {
|
|
83
|
+
if (options.captureNetwork === false || !matchesNetworkFilter(url, statusCode, durationMillis, options.networkFilter)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const sanitizeOptions = options.redactFields ? { redactFields: options.redactFields } : {};
|
|
87
|
+
client.captureRequest({
|
|
88
|
+
method,
|
|
89
|
+
url,
|
|
90
|
+
headers: sanitizeHeaders(headers, options.headerAllowlist, sanitizeOptions),
|
|
91
|
+
...(traceId ? { traceId } : {})
|
|
92
|
+
}, { statusCode, durationMillis }, traceId ? { trace_id: traceId } : undefined);
|
|
93
|
+
}
|
|
94
|
+
function matchesNetworkFilter(url, statusCode, durationMillis, filter = {}) {
|
|
95
|
+
if (filter.urlDenylist?.some((entry) => url.includes(entry))) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (filter.urlAllowlist && filter.urlAllowlist.length > 0 && !filter.urlAllowlist.some((entry) => url.includes(entry))) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (filter.statusCodes && filter.statusCodes.length > 0 && !filter.statusCodes.includes(statusCode)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
if (filter.minResponseTime !== undefined && durationMillis < filter.minResponseTime) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return statusCode === 0 || statusCode >= 400 || filter.statusCodes !== undefined || filter.minResponseTime !== undefined;
|
|
108
|
+
}
|
|
109
|
+
function requestUrl(input) {
|
|
110
|
+
if (typeof input === "string") {
|
|
111
|
+
return input;
|
|
112
|
+
}
|
|
113
|
+
if (input instanceof URL) {
|
|
114
|
+
return input.toString();
|
|
115
|
+
}
|
|
116
|
+
return "url" in input ? input.url : String(input);
|
|
117
|
+
}
|
|
118
|
+
function requestMethod(input, init) {
|
|
119
|
+
if (init?.method) {
|
|
120
|
+
return init.method.toUpperCase();
|
|
121
|
+
}
|
|
122
|
+
if (typeof input === "object" && "method" in input && typeof input.method === "string") {
|
|
123
|
+
return input.method.toUpperCase();
|
|
124
|
+
}
|
|
125
|
+
return "GET";
|
|
126
|
+
}
|
|
127
|
+
function withTraceHeader(init, traceId) {
|
|
128
|
+
const headers = new Headers(init?.headers);
|
|
129
|
+
if (!headers.has(TRACE_HEADER)) {
|
|
130
|
+
headers.set(TRACE_HEADER, traceId);
|
|
131
|
+
}
|
|
132
|
+
return { ...init, headers };
|
|
133
|
+
}
|
|
134
|
+
function existingTraceHeader(input, init) {
|
|
135
|
+
const fromInit = init?.headers ? new Headers(init.headers).get(TRACE_HEADER) : null;
|
|
136
|
+
if (fromInit) {
|
|
137
|
+
return fromInit;
|
|
138
|
+
}
|
|
139
|
+
if (typeof input === "object" && "headers" in input) {
|
|
140
|
+
return new Headers(input.headers).get(TRACE_HEADER);
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
function headersToRecord(headers) {
|
|
145
|
+
const output = {};
|
|
146
|
+
if (!headers) {
|
|
147
|
+
return output;
|
|
148
|
+
}
|
|
149
|
+
new Headers(headers).forEach((value, key) => {
|
|
150
|
+
output[key] = value;
|
|
151
|
+
});
|
|
152
|
+
return output;
|
|
153
|
+
}
|
|
154
|
+
function isRelativeUrl(url) {
|
|
155
|
+
return url.startsWith("/") && !url.startsWith("//");
|
|
156
|
+
}
|
|
157
|
+
function matchesTarget(url, target) {
|
|
158
|
+
if (!target || target.includes("*")) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const parsedUrl = new URL(url);
|
|
163
|
+
const parsedTarget = new URL(target);
|
|
164
|
+
return parsedUrl.origin === parsedTarget.origin && parsedUrl.pathname.startsWith(parsedTarget.pathname.replace(/\/$/, ""));
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function generateTraceId() {
|
|
171
|
+
if (globalThis.crypto?.randomUUID) {
|
|
172
|
+
return globalThis.crypto.randomUUID();
|
|
173
|
+
}
|
|
174
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (marker) => {
|
|
175
|
+
const random = Math.trunc(Math.random() * 16);
|
|
176
|
+
const value = marker === "x" ? random : (random & 0x3) | 0x8;
|
|
177
|
+
return value.toString(16);
|
|
178
|
+
});
|
|
179
|
+
}
|
package/dist/probes.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DebugBundleClient, DebugBundleProbeOptions } from "./types.js";
|
|
2
|
+
export declare function probe(label: string, data: unknown | (() => unknown), options?: DebugBundleProbeOptions): void;
|
|
3
|
+
export declare function activateDebugBundleProbeTrigger(token: string, client?: DebugBundleClient): boolean;
|
|
4
|
+
//# sourceMappingURL=probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../src/probes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE7E,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAE7G;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,iBAA+B,GAAG,OAAO,CAG/G"}
|
package/dist/probes.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DebugBundle } from "./index.js";
|
|
2
|
+
export function probe(label, data, options) {
|
|
3
|
+
DebugBundle.probe(label, data, options);
|
|
4
|
+
}
|
|
5
|
+
export function activateDebugBundleProbeTrigger(token, client = DebugBundle) {
|
|
6
|
+
void client.activateProbeTriggerToken(token);
|
|
7
|
+
return Boolean(token);
|
|
8
|
+
}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { DebugBundleClient } from "./types.js";
|
|
3
|
+
export interface DebugBundleErrorBoundaryProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
client?: DebugBundleClient;
|
|
6
|
+
fallback?: React.ReactNode | ((error: Error) => React.ReactNode);
|
|
7
|
+
context?: Record<string, unknown>;
|
|
8
|
+
rethrow?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface DebugBundleErrorBoundaryState {
|
|
11
|
+
error: Error | null;
|
|
12
|
+
}
|
|
13
|
+
export declare class DebugBundleErrorBoundary extends React.Component<DebugBundleErrorBoundaryProps, DebugBundleErrorBoundaryState> {
|
|
14
|
+
state: DebugBundleErrorBoundaryState;
|
|
15
|
+
static getDerivedStateFromError(error: Error): DebugBundleErrorBoundaryState;
|
|
16
|
+
componentDidCatch(error: Error, info: React.ErrorInfo): void;
|
|
17
|
+
render(): React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare function useDebugBundleAction(actionName: string, client?: DebugBundleClient): (data?: Record<string, unknown>) => void;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,6BAA6B;IACrC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,qBAAa,wBAAyB,SAAQ,KAAK,CAAC,SAAS,CAC3D,6BAA6B,EAC7B,6BAA6B,CAC9B;IACC,KAAK,EAAE,6BAA6B,CAAmB;IAEvD,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,6BAA6B;IAI5E,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI;IAY5D,MAAM,IAAI,KAAK,CAAC,SAAS;CAS1B;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,iBAA+B,GACtC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAO1C"}
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { DebugBundle } from "./index.js";
|
|
3
|
+
export class DebugBundleErrorBoundary extends React.Component {
|
|
4
|
+
state = { error: null };
|
|
5
|
+
static getDerivedStateFromError(error) {
|
|
6
|
+
return { error };
|
|
7
|
+
}
|
|
8
|
+
componentDidCatch(error, info) {
|
|
9
|
+
const client = this.props.client ?? DebugBundle;
|
|
10
|
+
client.captureException(error, {
|
|
11
|
+
...this.props.context,
|
|
12
|
+
component_stack: info.componentStack,
|
|
13
|
+
source: "react-error-boundary"
|
|
14
|
+
});
|
|
15
|
+
if (this.props.rethrow) {
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
render() {
|
|
20
|
+
if (!this.state.error) {
|
|
21
|
+
return this.props.children;
|
|
22
|
+
}
|
|
23
|
+
if (typeof this.props.fallback === "function") {
|
|
24
|
+
return this.props.fallback(this.state.error);
|
|
25
|
+
}
|
|
26
|
+
return this.props.fallback ?? null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function useDebugBundleAction(actionName, client = DebugBundle) {
|
|
30
|
+
return (data) => {
|
|
31
|
+
client.recordBreadcrumb("action", {
|
|
32
|
+
action_name: actionName,
|
|
33
|
+
...(data ?? {})
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const DEFAULT_HEADER_ALLOWLIST: string[];
|
|
2
|
+
export interface SanitizeOptions {
|
|
3
|
+
redactFields?: string[];
|
|
4
|
+
maxDepth?: number;
|
|
5
|
+
maxStringLength?: number;
|
|
6
|
+
maxArrayLength?: number;
|
|
7
|
+
maxObjectKeys?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function defaultRedactFields(): string[];
|
|
10
|
+
export declare function sanitizeValue(value: unknown, options?: SanitizeOptions): unknown;
|
|
11
|
+
export declare function sanitizeHeaders(headers: Record<string, string> | undefined, allowlist?: string[], options?: SanitizeOptions): Record<string, string>;
|
|
12
|
+
//# sourceMappingURL=redaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,wBAAwB,UAQpC,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAGpF;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,SAAS,GAAE,MAAM,EAA6B,EAC9C,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAaxB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const DEFAULT_REDACT_FIELDS = [
|
|
2
|
+
"password",
|
|
3
|
+
"secret",
|
|
4
|
+
"token",
|
|
5
|
+
"api_key",
|
|
6
|
+
"apikey",
|
|
7
|
+
"access_token",
|
|
8
|
+
"refresh_token",
|
|
9
|
+
"private_key",
|
|
10
|
+
"passwd",
|
|
11
|
+
"card_number",
|
|
12
|
+
"cvv",
|
|
13
|
+
"cvc",
|
|
14
|
+
"pin",
|
|
15
|
+
"expiry",
|
|
16
|
+
"phone",
|
|
17
|
+
"bearer",
|
|
18
|
+
"session_id",
|
|
19
|
+
"otp",
|
|
20
|
+
"verification_code",
|
|
21
|
+
"authorization",
|
|
22
|
+
"cookie",
|
|
23
|
+
"ssn"
|
|
24
|
+
];
|
|
25
|
+
export const DEFAULT_HEADER_ALLOWLIST = [
|
|
26
|
+
"user-agent",
|
|
27
|
+
"content-type",
|
|
28
|
+
"accept",
|
|
29
|
+
"x-request-id",
|
|
30
|
+
"x-correlation-id",
|
|
31
|
+
"x-debugbundle-trace-id",
|
|
32
|
+
"traceparent"
|
|
33
|
+
];
|
|
34
|
+
export function defaultRedactFields() {
|
|
35
|
+
return [...DEFAULT_REDACT_FIELDS];
|
|
36
|
+
}
|
|
37
|
+
export function sanitizeValue(value, options = {}) {
|
|
38
|
+
const visited = new WeakSet();
|
|
39
|
+
return sanitize(value, normalizeOptions(options), 0, visited, undefined);
|
|
40
|
+
}
|
|
41
|
+
export function sanitizeHeaders(headers, allowlist = DEFAULT_HEADER_ALLOWLIST, options = {}) {
|
|
42
|
+
if (!headers) {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
const allowed = new Set(allowlist.map((header) => header.toLowerCase()));
|
|
46
|
+
const sanitized = {};
|
|
47
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
48
|
+
const normalizedKey = key.toLowerCase();
|
|
49
|
+
if (allowed.has(normalizedKey)) {
|
|
50
|
+
sanitized[normalizedKey] = String(sanitizeValue(value, options));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return sanitized;
|
|
54
|
+
}
|
|
55
|
+
function normalizeOptions(options) {
|
|
56
|
+
return {
|
|
57
|
+
redactFields: options.redactFields ?? DEFAULT_REDACT_FIELDS,
|
|
58
|
+
maxDepth: options.maxDepth ?? 8,
|
|
59
|
+
maxStringLength: options.maxStringLength ?? 2048,
|
|
60
|
+
maxArrayLength: options.maxArrayLength ?? 50,
|
|
61
|
+
maxObjectKeys: options.maxObjectKeys ?? 50
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function sanitize(value, options, depth, visited, key) {
|
|
65
|
+
if (key && isSensitiveKey(key, options.redactFields)) {
|
|
66
|
+
return "[Redacted]";
|
|
67
|
+
}
|
|
68
|
+
if (value === null || value === undefined) {
|
|
69
|
+
return value ?? null;
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === "string") {
|
|
72
|
+
return truncate(value, options.maxStringLength);
|
|
73
|
+
}
|
|
74
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
if (typeof value === "bigint") {
|
|
78
|
+
return value.toString();
|
|
79
|
+
}
|
|
80
|
+
if (typeof value === "function" || typeof value === "symbol") {
|
|
81
|
+
return `[${typeof value}]`;
|
|
82
|
+
}
|
|
83
|
+
if (value instanceof Error) {
|
|
84
|
+
return sanitizeError(value, options, depth, visited);
|
|
85
|
+
}
|
|
86
|
+
if (depth >= options.maxDepth) {
|
|
87
|
+
return "[Truncated: depth]";
|
|
88
|
+
}
|
|
89
|
+
if (typeof value === "object") {
|
|
90
|
+
if (visited.has(value)) {
|
|
91
|
+
return "[Circular]";
|
|
92
|
+
}
|
|
93
|
+
visited.add(value);
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
return value
|
|
96
|
+
.slice(0, options.maxArrayLength)
|
|
97
|
+
.map((entry) => sanitize(entry, options, depth + 1, visited, undefined));
|
|
98
|
+
}
|
|
99
|
+
const output = {};
|
|
100
|
+
for (const [entryKey, entryValue] of Object.entries(value).slice(0, options.maxObjectKeys)) {
|
|
101
|
+
output[entryKey] = sanitize(entryValue, options, depth + 1, visited, entryKey);
|
|
102
|
+
}
|
|
103
|
+
return output;
|
|
104
|
+
}
|
|
105
|
+
return String(value);
|
|
106
|
+
}
|
|
107
|
+
function sanitizeError(error, options, depth, visited) {
|
|
108
|
+
return {
|
|
109
|
+
name: truncate(error.name || "Error", options.maxStringLength),
|
|
110
|
+
message: truncate(error.message || "", options.maxStringLength),
|
|
111
|
+
stack: typeof error.stack === "string" ? truncate(error.stack, options.maxStringLength * 4) : null,
|
|
112
|
+
cause: "cause" in error ? sanitize(error.cause, options, depth + 1, visited, "cause") : null
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function truncate(value, maxLength) {
|
|
116
|
+
if (value.length <= maxLength) {
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
return `${value.slice(0, maxLength)}...[Truncated]`;
|
|
120
|
+
}
|
|
121
|
+
function isSensitiveKey(key, sensitiveFields) {
|
|
122
|
+
const segments = splitKey(key);
|
|
123
|
+
const sensitive = new Set(sensitiveFields.flatMap(splitKey));
|
|
124
|
+
return segments.some((segment) => sensitive.has(segment));
|
|
125
|
+
}
|
|
126
|
+
function splitKey(key) {
|
|
127
|
+
return key
|
|
128
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
129
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
130
|
+
.map((segment) => segment.toLowerCase())
|
|
131
|
+
.filter(Boolean);
|
|
132
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DebugBundleEventEnvelope, NativeDebugBundleModule, NativeDebugBundleState, ResolvedDebugBundleConfig } from "./types.js";
|
|
2
|
+
export interface RecordingNativeModule extends NativeDebugBundleModule {
|
|
3
|
+
events: DebugBundleEventEnvelope[];
|
|
4
|
+
config: ResolvedDebugBundleConfig | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function createRecordingNativeModule(initialState?: NativeDebugBundleState): RecordingNativeModule;
|
|
7
|
+
export declare function installRecordingNativeModule(module?: RecordingNativeModule): RecordingNativeModule;
|
|
8
|
+
export declare function resetDebugBundleNativeModule(): void;
|
|
9
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEvI,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACnC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAgB,2BAA2B,CAAC,YAAY,GAAE,sBAAiE,GAAG,qBAAqB,CA0BlJ;AAED,wBAAgB,4BAA4B,CAAC,MAAM,GAAE,qBAAqD,GAAG,qBAAqB,CAGjI;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAGnD"}
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { resetNativeModuleCacheForTesting, setNativeModuleForTesting } from "./native.js";
|
|
2
|
+
export function createRecordingNativeModule(initialState = { status: "healthy", lastEventAt: null }) {
|
|
3
|
+
const state = { ...initialState };
|
|
4
|
+
return {
|
|
5
|
+
events: [],
|
|
6
|
+
config: null,
|
|
7
|
+
initialize(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
return state;
|
|
10
|
+
},
|
|
11
|
+
enqueueEvent(event) {
|
|
12
|
+
this.events.push(event);
|
|
13
|
+
state.lastEventAt = Date.now();
|
|
14
|
+
},
|
|
15
|
+
flush() {
|
|
16
|
+
state.status = "healthy";
|
|
17
|
+
},
|
|
18
|
+
getStatus() {
|
|
19
|
+
return state;
|
|
20
|
+
},
|
|
21
|
+
setContext() {
|
|
22
|
+
return undefined;
|
|
23
|
+
},
|
|
24
|
+
activateProbeTriggerToken() {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function installRecordingNativeModule(module = createRecordingNativeModule()) {
|
|
30
|
+
setNativeModuleForTesting(module);
|
|
31
|
+
return module;
|
|
32
|
+
}
|
|
33
|
+
export function resetDebugBundleNativeModule() {
|
|
34
|
+
setNativeModuleForTesting(undefined);
|
|
35
|
+
resetNativeModuleCacheForTesting();
|
|
36
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
export type DebugBundleStatus = "healthy" | "degraded" | "disconnected";
|
|
2
|
+
export type DebugBundleLogLevel = "debug" | "info" | "warning" | "error" | "critical";
|
|
3
|
+
export interface DebugBundleConfig {
|
|
4
|
+
projectToken?: string;
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
environment?: string;
|
|
7
|
+
service?: string;
|
|
8
|
+
endpoint?: string;
|
|
9
|
+
releaseChannel?: string;
|
|
10
|
+
appVersion?: string;
|
|
11
|
+
buildNumber?: string;
|
|
12
|
+
batchSize?: number;
|
|
13
|
+
flushInterval?: number;
|
|
14
|
+
sampleRate?: number;
|
|
15
|
+
sessionSampleRate?: number;
|
|
16
|
+
maxEventsPerSession?: number;
|
|
17
|
+
maxBreadcrumbs?: number;
|
|
18
|
+
captureErrors?: boolean;
|
|
19
|
+
captureUnhandledRejections?: boolean;
|
|
20
|
+
captureScreens?: boolean;
|
|
21
|
+
captureActions?: boolean;
|
|
22
|
+
captureNetwork?: boolean;
|
|
23
|
+
captureConsole?: boolean;
|
|
24
|
+
captureLogs?: boolean;
|
|
25
|
+
logLevel?: DebugBundleLogLevel;
|
|
26
|
+
tracePropagationTargets?: string[];
|
|
27
|
+
networkFilter?: DebugBundleNetworkFilter;
|
|
28
|
+
offlineQueueMaxEvents?: number;
|
|
29
|
+
offlineQueueMaxBytes?: number;
|
|
30
|
+
offlineQueueTtl?: number;
|
|
31
|
+
requestTimeout?: number;
|
|
32
|
+
maxProbeLabels?: number;
|
|
33
|
+
maxProbeEntriesPerLabel?: number;
|
|
34
|
+
probeFlushOnError?: boolean;
|
|
35
|
+
redactFields?: string[];
|
|
36
|
+
headerAllowlist?: string[];
|
|
37
|
+
sdkVersion?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ResolvedDebugBundleConfig {
|
|
40
|
+
projectToken: string;
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
environment: string;
|
|
43
|
+
service: string;
|
|
44
|
+
endpoint: string;
|
|
45
|
+
releaseChannel: string;
|
|
46
|
+
appVersion: string | null;
|
|
47
|
+
buildNumber: string | null;
|
|
48
|
+
batchSize: number;
|
|
49
|
+
flushInterval: number;
|
|
50
|
+
sampleRate: number;
|
|
51
|
+
sessionSampleRate: number;
|
|
52
|
+
maxEventsPerSession: number;
|
|
53
|
+
maxBreadcrumbs: number;
|
|
54
|
+
captureErrors: boolean;
|
|
55
|
+
captureUnhandledRejections: boolean;
|
|
56
|
+
captureScreens: boolean;
|
|
57
|
+
captureActions: boolean;
|
|
58
|
+
captureNetwork: boolean;
|
|
59
|
+
captureConsole: boolean;
|
|
60
|
+
captureLogs: boolean;
|
|
61
|
+
logLevel: DebugBundleLogLevel;
|
|
62
|
+
tracePropagationTargets: string[];
|
|
63
|
+
networkFilter: DebugBundleNetworkFilter;
|
|
64
|
+
offlineQueueMaxEvents: number;
|
|
65
|
+
offlineQueueMaxBytes: number;
|
|
66
|
+
offlineQueueTtl: number;
|
|
67
|
+
requestTimeout: number;
|
|
68
|
+
maxProbeLabels: number;
|
|
69
|
+
maxProbeEntriesPerLabel: number;
|
|
70
|
+
probeFlushOnError: boolean;
|
|
71
|
+
redactFields: string[];
|
|
72
|
+
headerAllowlist: string[];
|
|
73
|
+
sdkVersion: string;
|
|
74
|
+
}
|
|
75
|
+
export interface DebugBundleNetworkFilter {
|
|
76
|
+
urlAllowlist?: string[];
|
|
77
|
+
urlDenylist?: string[];
|
|
78
|
+
statusCodes?: number[];
|
|
79
|
+
minResponseTime?: number;
|
|
80
|
+
}
|
|
81
|
+
export interface DebugBundleRequestInfo {
|
|
82
|
+
method: string;
|
|
83
|
+
url: string;
|
|
84
|
+
headers?: Record<string, string>;
|
|
85
|
+
routeTemplate?: string;
|
|
86
|
+
traceId?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface DebugBundleResponseInfo {
|
|
89
|
+
statusCode: number;
|
|
90
|
+
durationMillis?: number;
|
|
91
|
+
headers?: Record<string, string>;
|
|
92
|
+
}
|
|
93
|
+
export interface DebugBundleCaptureContext {
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
}
|
|
96
|
+
export interface DebugBundleProbeOptions {
|
|
97
|
+
heavy?: boolean;
|
|
98
|
+
}
|
|
99
|
+
export interface DebugBundleEventEnvelope {
|
|
100
|
+
schema_version: "1";
|
|
101
|
+
event_id: string;
|
|
102
|
+
event_type: "frontend_exception" | "frontend_breadcrumb" | "log_event" | "request_event" | "error_suppressed" | "probe_event";
|
|
103
|
+
sdk_name: "@debugbundle/sdk-react-native";
|
|
104
|
+
sdk_version: string;
|
|
105
|
+
service: {
|
|
106
|
+
name: string;
|
|
107
|
+
environment: string;
|
|
108
|
+
runtime: "react-native";
|
|
109
|
+
framework: "react-native";
|
|
110
|
+
};
|
|
111
|
+
occurred_at: string;
|
|
112
|
+
correlation: {
|
|
113
|
+
trace_id: string | null;
|
|
114
|
+
request_id?: string | null;
|
|
115
|
+
session_id?: string | null;
|
|
116
|
+
user_id_hash?: string | null;
|
|
117
|
+
} | null;
|
|
118
|
+
payload: Record<string, unknown>;
|
|
119
|
+
device: Record<string, unknown> | null;
|
|
120
|
+
}
|
|
121
|
+
export interface DebugBundleClient {
|
|
122
|
+
readonly status: DebugBundleStatus;
|
|
123
|
+
readonly lastEventAt: number | null;
|
|
124
|
+
init(config: DebugBundleConfig): void;
|
|
125
|
+
captureException(error: unknown, context?: DebugBundleCaptureContext): void;
|
|
126
|
+
captureError(error: unknown, context?: DebugBundleCaptureContext): void;
|
|
127
|
+
captureLog(message: string, level?: DebugBundleLogLevel, context?: DebugBundleCaptureContext): void;
|
|
128
|
+
captureRequest(request: DebugBundleRequestInfo, response: DebugBundleResponseInfo, context?: DebugBundleCaptureContext): void;
|
|
129
|
+
captureMessage(message: string, level?: DebugBundleLogLevel, context?: DebugBundleCaptureContext): void;
|
|
130
|
+
setContext(key: string, value: unknown): void;
|
|
131
|
+
probe(label: string, data: unknown | (() => unknown), options?: DebugBundleProbeOptions): void;
|
|
132
|
+
flush(): Promise<void>;
|
|
133
|
+
activateProbeTriggerToken(token: string): Promise<boolean>;
|
|
134
|
+
recordBreadcrumb(type: string, data?: Record<string, unknown>): void;
|
|
135
|
+
recordScreen(screenName: string, previousScreen?: string | null, source?: string): void;
|
|
136
|
+
}
|
|
137
|
+
export interface NativeDebugBundleModule {
|
|
138
|
+
initialize(config: ResolvedDebugBundleConfig): Promise<NativeDebugBundleState> | NativeDebugBundleState;
|
|
139
|
+
enqueueEvent(event: DebugBundleEventEnvelope): Promise<void> | void;
|
|
140
|
+
flush(): Promise<void> | void;
|
|
141
|
+
getStatus(): Promise<NativeDebugBundleState> | NativeDebugBundleState;
|
|
142
|
+
setContext?(key: string, value: unknown): Promise<void> | void;
|
|
143
|
+
activateProbeTriggerToken?(token: string): Promise<boolean> | boolean;
|
|
144
|
+
}
|
|
145
|
+
export interface NativeDebugBundleState {
|
|
146
|
+
status: DebugBundleStatus;
|
|
147
|
+
lastEventAt?: number | null;
|
|
148
|
+
device?: Record<string, unknown> | null;
|
|
149
|
+
nativeModuleAvailable?: boolean;
|
|
150
|
+
degradedReason?: string | null;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|