@debugbundle/sdk-react-native 3.0.1 → 3.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/CHANGELOG.md +16 -0
- package/DebugBundleReactNative.podspec +2 -2
- package/MIGRATION-3.1.md +116 -0
- package/README.md +37 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/debugbundle/reactnative/DebugBundleReactNativeModule.java +34 -3
- package/app.plugin.js +1 -1
- package/dist/NativeDebugBundleReactNative.d.ts +1 -0
- package/dist/NativeDebugBundleReactNative.d.ts.map +1 -1
- package/dist/before-send.d.ts.map +1 -1
- package/dist/before-send.js +9 -131
- package/dist/canonical-schema.d.ts +15 -0
- package/dist/canonical-schema.d.ts.map +1 -0
- package/dist/canonical-schema.js +139 -0
- package/dist/client-values.d.ts +17 -0
- package/dist/client-values.d.ts.map +1 -0
- package/dist/client-values.js +185 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +102 -205
- package/dist/diagnostic-budget.d.ts +16 -0
- package/dist/diagnostic-budget.d.ts.map +1 -0
- package/dist/diagnostic-budget.js +120 -0
- package/dist/event-schema-data.d.ts +2 -0
- package/dist/event-schema-data.d.ts.map +1 -0
- package/dist/event-schema-data.js +49 -0
- package/dist/evidence-capabilities.d.ts +5 -0
- package/dist/evidence-capabilities.d.ts.map +1 -0
- package/dist/evidence-capabilities.js +21 -0
- package/dist/evidence-controller.d.ts +24 -0
- package/dist/evidence-controller.d.ts.map +1 -0
- package/dist/evidence-controller.js +113 -0
- package/dist/evidence-types.d.ts +33 -0
- package/dist/evidence-types.d.ts.map +1 -0
- package/dist/evidence-types.js +1 -0
- package/dist/evidence-wire.d.ts +7 -0
- package/dist/evidence-wire.d.ts.map +1 -0
- package/dist/evidence-wire.js +132 -0
- package/dist/exception-evidence.d.ts +25 -0
- package/dist/exception-evidence.d.ts.map +1 -0
- package/dist/exception-evidence.js +175 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/owned-json.d.ts +11 -0
- package/dist/owned-json.d.ts.map +1 -0
- package/dist/owned-json.js +85 -0
- package/dist/privacy-keys.d.ts +2 -0
- package/dist/privacy-keys.d.ts.map +1 -1
- package/dist/privacy-keys.js +10 -2
- package/dist/privacy-telemetry.js +7 -7
- package/dist/privacy-text.d.ts +2 -2
- package/dist/privacy-text.d.ts.map +1 -1
- package/dist/privacy-text.js +35 -33
- package/dist/redaction.d.ts.map +1 -1
- package/dist/redaction.js +9 -7
- package/dist/safe-error-fields.d.ts +4 -0
- package/dist/safe-error-fields.d.ts.map +1 -0
- package/dist/safe-error-fields.js +54 -0
- package/dist/types.d.ts +21 -6
- package/dist/types.d.ts.map +1 -1
- package/ios/DebugBundleReactNative.swift +58 -4
- package/ios/DebugBundleReactNativeBridge.mm +4 -0
- package/package.json +3 -2
- package/src/NativeDebugBundleReactNative.ts +1 -0
- package/src/before-send.ts +10 -174
- package/src/canonical-schema.ts +108 -0
- package/src/client-values.ts +196 -0
- package/src/client.ts +92 -213
- package/src/diagnostic-budget.ts +90 -0
- package/src/event-schema-data.ts +49 -0
- package/src/evidence-capabilities.ts +19 -0
- package/src/evidence-controller.ts +89 -0
- package/src/evidence-types.ts +14 -0
- package/src/evidence-wire.ts +100 -0
- package/src/exception-evidence.ts +112 -0
- package/src/index.ts +6 -0
- package/src/owned-json.ts +60 -0
- package/src/privacy-keys.ts +12 -2
- package/src/privacy-telemetry.ts +9 -9
- package/src/privacy-text.ts +32 -31
- package/src/redaction.ts +8 -7
- package/src/safe-error-fields.ts +46 -0
- package/src/types.ts +23 -5
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { eventSchemaData } from "./event-schema-data.js";
|
|
2
|
+
import { EventValidationUnavailable, jsonObject } from "./owned-json.js";
|
|
3
|
+
const KEYWORDS = new Set(["$schema", "$id", "$comment", "$ref", "type", "anyOf", "const", "enum", "properties",
|
|
4
|
+
"required", "additionalProperties", "items", "minimum", "maximum", "exclusiveMinimum", "minLength", "maxLength",
|
|
5
|
+
"minItems", "maxItems", "format", "pattern"]);
|
|
6
|
+
const TYPES = new Set(["null", "boolean", "number", "integer", "string", "array", "object"]);
|
|
7
|
+
const choices = (value) => value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
8
|
+
export function canonicalTimestamp(text) {
|
|
9
|
+
if (!/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?Z$/.test(text))
|
|
10
|
+
return false;
|
|
11
|
+
const year = Number(text.slice(0, 4)), month = Number(text.slice(5, 7)), day = Number(text.slice(8, 10));
|
|
12
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
13
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
14
|
+
return month >= 1 && month <= 12 && day >= 1 && day <= days[month - 1] &&
|
|
15
|
+
Number(text.slice(11, 13)) < 24 && Number(text.slice(14, 16)) < 60 && Number(text.slice(17, 19)) < 60;
|
|
16
|
+
}
|
|
17
|
+
/** Small closed Draft-7 interpreter for the generated accepting contract. */
|
|
18
|
+
export class CanonicalSchema {
|
|
19
|
+
refs = new Map();
|
|
20
|
+
patterns = new Map();
|
|
21
|
+
root;
|
|
22
|
+
constructor(schema) { this.root = schema; this.compile(this.root); }
|
|
23
|
+
resolve(ref) {
|
|
24
|
+
const cached = this.refs.get(ref);
|
|
25
|
+
if (cached !== undefined)
|
|
26
|
+
return cached;
|
|
27
|
+
if (!ref.startsWith("#/"))
|
|
28
|
+
throw new EventValidationUnavailable();
|
|
29
|
+
let value = this.root;
|
|
30
|
+
for (const part of ref.slice(2).split("/")) {
|
|
31
|
+
const key = part.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
32
|
+
value = Array.isArray(value) ? value[Number(key)] : jsonObject(value)?.[key];
|
|
33
|
+
if (value === undefined)
|
|
34
|
+
throw new EventValidationUnavailable();
|
|
35
|
+
}
|
|
36
|
+
this.refs.set(ref, value);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
compile(schema) {
|
|
40
|
+
if (typeof schema === "boolean")
|
|
41
|
+
return;
|
|
42
|
+
const node = jsonObject(schema);
|
|
43
|
+
if (!node || Object.keys(node).some(key => !KEYWORDS.has(key)) ||
|
|
44
|
+
choices(node.type).some(value => typeof value !== "string" || !TYPES.has(value)) ||
|
|
45
|
+
node.format !== undefined && !["uuid", "date-time"].includes(String(node.format)))
|
|
46
|
+
throw new EventValidationUnavailable();
|
|
47
|
+
if (typeof node.pattern === "string")
|
|
48
|
+
this.patterns.set(node.pattern, new RegExp(node.pattern));
|
|
49
|
+
if (typeof node.$ref === "string" && !this.refs.has(node.$ref))
|
|
50
|
+
this.compile(this.resolve(node.$ref));
|
|
51
|
+
for (const child of Object.values(jsonObject(node.properties) ?? {}))
|
|
52
|
+
this.compile(child);
|
|
53
|
+
for (const child of choices(node.anyOf))
|
|
54
|
+
this.compile(child);
|
|
55
|
+
for (const key of ["items", "additionalProperties"])
|
|
56
|
+
if (node[key] !== undefined)
|
|
57
|
+
this.compile(node[key]);
|
|
58
|
+
}
|
|
59
|
+
accepts(value) {
|
|
60
|
+
let steps = 100_000;
|
|
61
|
+
const check = (schema, value, depth) => {
|
|
62
|
+
if (--steps < 0 || depth > 64)
|
|
63
|
+
throw new EventValidationUnavailable();
|
|
64
|
+
if (typeof schema === "boolean")
|
|
65
|
+
return schema;
|
|
66
|
+
const node = jsonObject(schema);
|
|
67
|
+
if (!node)
|
|
68
|
+
throw new EventValidationUnavailable();
|
|
69
|
+
if (typeof node.$ref === "string")
|
|
70
|
+
return check(this.resolve(node.$ref), value, depth + 1);
|
|
71
|
+
if (Array.isArray(node.anyOf) && !node.anyOf.some(child => check(child, value, depth + 1)))
|
|
72
|
+
return false;
|
|
73
|
+
if (node.type !== undefined && !choices(node.type).some(type => this.matches(value, type)))
|
|
74
|
+
return false;
|
|
75
|
+
if (node.const !== undefined && node.const !== value)
|
|
76
|
+
return false;
|
|
77
|
+
if (Array.isArray(node.enum) && !node.enum.includes(value))
|
|
78
|
+
return false;
|
|
79
|
+
const object = jsonObject(value);
|
|
80
|
+
if (object) {
|
|
81
|
+
if (choices(node.required).some(key => typeof key !== "string" || !Object.hasOwn(object, key)))
|
|
82
|
+
return false;
|
|
83
|
+
const fields = jsonObject(node.properties) ?? {};
|
|
84
|
+
for (const [key, child] of Object.entries(object)) {
|
|
85
|
+
if (!check((Object.hasOwn(fields, key) ? fields[key] : undefined) ?? node.additionalProperties ?? true, child, depth + 1))
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(value)) {
|
|
90
|
+
if (typeof node.minItems === "number" && value.length < node.minItems ||
|
|
91
|
+
typeof node.maxItems === "number" && value.length > node.maxItems)
|
|
92
|
+
return false;
|
|
93
|
+
if (node.items !== undefined && !value.every(child => check(node.items, child, depth + 1)))
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (typeof value === "string") {
|
|
97
|
+
if (typeof node.minLength === "number" && value.length < node.minLength ||
|
|
98
|
+
typeof node.maxLength === "number" && value.length > node.maxLength)
|
|
99
|
+
return false;
|
|
100
|
+
if (typeof node.pattern === "string" && !this.patterns.get(node.pattern).test(value))
|
|
101
|
+
return false;
|
|
102
|
+
if (node.format === "uuid" && !/^[\da-f]{8}-(?:[\da-f]{4}-){3}[\da-f]{12}$/i.test(value))
|
|
103
|
+
return false;
|
|
104
|
+
if (node.format === "date-time" && !canonicalTimestamp(value))
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
if (typeof value === "number") {
|
|
108
|
+
if (typeof node.minimum === "number" && value < node.minimum || typeof node.maximum === "number" && value > node.maximum ||
|
|
109
|
+
typeof node.exclusiveMinimum === "number" && value <= node.exclusiveMinimum)
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return true;
|
|
113
|
+
};
|
|
114
|
+
return check(this.root, value, 0);
|
|
115
|
+
}
|
|
116
|
+
matches(value, type) {
|
|
117
|
+
if (type === "integer")
|
|
118
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value);
|
|
119
|
+
if (type === "number")
|
|
120
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
121
|
+
if (type === "null")
|
|
122
|
+
return value === null;
|
|
123
|
+
if (type === "array")
|
|
124
|
+
return Array.isArray(value);
|
|
125
|
+
if (type === "object")
|
|
126
|
+
return jsonObject(value) !== null;
|
|
127
|
+
return typeof value === type;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
let schema = null;
|
|
131
|
+
try {
|
|
132
|
+
schema = new CanonicalSchema(eventSchemaData);
|
|
133
|
+
}
|
|
134
|
+
catch { /* Unknown generated keywords fail closed. */ }
|
|
135
|
+
export function canonicalShape(value) {
|
|
136
|
+
if (!schema)
|
|
137
|
+
throw new EventValidationUnavailable();
|
|
138
|
+
return schema.accepts(value);
|
|
139
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NativeDebugBundleState, DebugBundleEventEnvelope, ResolvedDebugBundleConfig } from "./types.js";
|
|
2
|
+
export declare function correlationFromContext(context: Record<string, unknown>, traceId?: string | null): DebugBundleEventEnvelope["correlation"];
|
|
3
|
+
/** Both inputs are validated, owned canonical device JSON. Key order is immaterial. */
|
|
4
|
+
export declare function sameMobileDevice(left: unknown, right: unknown): boolean;
|
|
5
|
+
export declare function normalizeNativeState(state: NativeDebugBundleState): NativeDebugBundleState;
|
|
6
|
+
export declare function stringValue(value: unknown): string | null;
|
|
7
|
+
export declare function asRecord(value: unknown): Record<string, unknown>;
|
|
8
|
+
export declare function objectWrap(value: unknown): Record<string, unknown>;
|
|
9
|
+
export declare function parseRequestUrl(url: string): {
|
|
10
|
+
path: string;
|
|
11
|
+
query: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
export declare function sanitizeScreenName(screenName: string): string;
|
|
14
|
+
export declare function generateId(): string;
|
|
15
|
+
export declare function canonicalDevice(nativeDevice: Record<string, unknown> | null | undefined, config: ResolvedDebugBundleConfig): Record<string, unknown>;
|
|
16
|
+
export declare function toLegacyNativeEvent(event: DebugBundleEventEnvelope): DebugBundleEventEnvelope;
|
|
17
|
+
//# sourceMappingURL=client-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-values.d.ts","sourceRoot":"","sources":["../src/client-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE9G,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAE,MAAM,GAAG,IAAW,GAAG,wBAAwB,CAAC,aAAa,CAAC,CAU/I;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAMvE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,sBAAsB,GAAG,sBAAsB,CAM1F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEzD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKhE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIlE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAoC7F;AAUD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,UAAU,IAAI,MAAM,CAUnC;AAED,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACxD,MAAM,EAAE,yBAAyB,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyCzB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,wBAAwB,CAa7F"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
export function correlationFromContext(context, traceId = null) {
|
|
2
|
+
const nested = Object.getOwnPropertyDescriptor(context, "correlation");
|
|
3
|
+
const source = nested && "value" in nested && nested.value && typeof nested.value === "object" ? nested.value : {};
|
|
4
|
+
const result = {};
|
|
5
|
+
for (const key of ["request_id", "trace_id", "session_id", "user_id_hash"]) {
|
|
6
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key) ?? Object.getOwnPropertyDescriptor(context, key);
|
|
7
|
+
if (descriptor && "value" in descriptor && (descriptor.value === null || typeof descriptor.value === "string"))
|
|
8
|
+
result[key] = descriptor.value;
|
|
9
|
+
}
|
|
10
|
+
if (traceId !== null)
|
|
11
|
+
result.trace_id = traceId;
|
|
12
|
+
return Object.keys(result).length ? result : undefined;
|
|
13
|
+
}
|
|
14
|
+
/** Both inputs are validated, owned canonical device JSON. Key order is immaterial. */
|
|
15
|
+
export function sameMobileDevice(left, right) {
|
|
16
|
+
if (left === right)
|
|
17
|
+
return true;
|
|
18
|
+
if (!left || !right || typeof left !== "object" || typeof right !== "object" || Array.isArray(left) || Array.isArray(right))
|
|
19
|
+
return false;
|
|
20
|
+
const a = left, b = right;
|
|
21
|
+
const keys = Object.keys(a);
|
|
22
|
+
return keys.length === Object.keys(b).length && keys.every(key => Object.hasOwn(b, key) && sameMobileDevice(a[key], b[key]));
|
|
23
|
+
}
|
|
24
|
+
export function normalizeNativeState(state) {
|
|
25
|
+
return {
|
|
26
|
+
...state,
|
|
27
|
+
status: state.status || "healthy",
|
|
28
|
+
nativeModuleAvailable: state.nativeModuleAvailable ?? true
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function stringValue(value) {
|
|
32
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
33
|
+
}
|
|
34
|
+
export function asRecord(value) {
|
|
35
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
export function objectWrap(value) {
|
|
41
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
42
|
+
? value
|
|
43
|
+
: { value };
|
|
44
|
+
}
|
|
45
|
+
export function parseRequestUrl(url) {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = new URL(url);
|
|
48
|
+
const query = {};
|
|
49
|
+
for (const [key, value] of parsed.searchParams) {
|
|
50
|
+
const existing = query[key];
|
|
51
|
+
if (existing === undefined) {
|
|
52
|
+
query[key] = value;
|
|
53
|
+
}
|
|
54
|
+
else if (Array.isArray(existing)) {
|
|
55
|
+
existing.push(value);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
query[key] = [existing, value];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { path: parsed.pathname || "/", query };
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
const [path = "/", rawQuery = ""] = url.split("?", 2);
|
|
65
|
+
const query = {};
|
|
66
|
+
for (const segment of rawQuery.split("&")) {
|
|
67
|
+
if (!segment) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const [rawKey = "", rawValue = ""] = segment.split("=", 2);
|
|
71
|
+
const key = decodeQuerySegment(rawKey);
|
|
72
|
+
const value = decodeQuerySegment(rawValue);
|
|
73
|
+
const existing = query[key];
|
|
74
|
+
if (existing === undefined) {
|
|
75
|
+
query[key] = value;
|
|
76
|
+
}
|
|
77
|
+
else if (Array.isArray(existing)) {
|
|
78
|
+
existing.push(value);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
query[key] = [existing, value];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { path: path || "/", query };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function decodeQuerySegment(value) {
|
|
88
|
+
try {
|
|
89
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function sanitizeScreenName(screenName) {
|
|
96
|
+
return screenName.replace(/[^a-zA-Z0-9_.:/-]/g, "_").slice(0, 120);
|
|
97
|
+
}
|
|
98
|
+
export function generateId() {
|
|
99
|
+
const cryptoLike = globalThis.crypto;
|
|
100
|
+
if (cryptoLike?.randomUUID) {
|
|
101
|
+
return cryptoLike.randomUUID();
|
|
102
|
+
}
|
|
103
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (marker) => {
|
|
104
|
+
const random = Math.trunc(Math.random() * 16);
|
|
105
|
+
const value = marker === "x" ? random : (random & 0x3) | 0x8;
|
|
106
|
+
return value.toString(16);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
export function canonicalDevice(nativeDevice, config) {
|
|
110
|
+
const source = nativeDevice ?? {};
|
|
111
|
+
const sourceOs = asRecord(source.os);
|
|
112
|
+
const sourceScreen = asRecord(source.screen);
|
|
113
|
+
const sourceViewport = asRecord(source.viewport);
|
|
114
|
+
const width = nonNegativeInteger(sourceScreen.width ?? source.screen_width);
|
|
115
|
+
const height = nonNegativeInteger(sourceScreen.height ?? source.screen_height);
|
|
116
|
+
return {
|
|
117
|
+
user_agent: stringValue(source.user_agent),
|
|
118
|
+
os: {
|
|
119
|
+
name: stringValue(sourceOs.name ?? source.os_name),
|
|
120
|
+
version: stringValue(sourceOs.version ?? source.os_version)
|
|
121
|
+
},
|
|
122
|
+
device_type: canonicalDeviceType(source.device_type),
|
|
123
|
+
screen: { width, height },
|
|
124
|
+
viewport: {
|
|
125
|
+
width: nonNegativeInteger(sourceViewport.width ?? width),
|
|
126
|
+
height: nonNegativeInteger(sourceViewport.height ?? height)
|
|
127
|
+
},
|
|
128
|
+
device_pixel_ratio: positiveNumber(source.device_pixel_ratio),
|
|
129
|
+
touch_capable: typeof source.touch_capable === "boolean" ? source.touch_capable : null,
|
|
130
|
+
language: stringValue(source.language ?? source.locale),
|
|
131
|
+
connection_type: stringValue(source.connection_type),
|
|
132
|
+
color_scheme_preference: canonicalColorScheme(source.color_scheme_preference),
|
|
133
|
+
app_version: stringValue(source.app_version) ?? config.appVersion,
|
|
134
|
+
build_number: stringValue(source.build_number) ?? config.buildNumber,
|
|
135
|
+
release_channel: stringValue(source.release_channel) ?? config.releaseChannel,
|
|
136
|
+
api_level: nullableNonNegativeInteger(source.api_level),
|
|
137
|
+
manufacturer: stringValue(source.manufacturer),
|
|
138
|
+
model: stringValue(source.model),
|
|
139
|
+
timezone: stringValue(source.timezone),
|
|
140
|
+
battery_level: nonNegativeNumber(source.battery_level),
|
|
141
|
+
battery_charging: typeof source.battery_charging === "boolean"
|
|
142
|
+
? source.battery_charging
|
|
143
|
+
: typeof source.charging === "boolean" ? source.charging : null,
|
|
144
|
+
free_disk_bytes: nullableNonNegativeInteger(source.free_disk_bytes),
|
|
145
|
+
free_memory_bytes: nullableNonNegativeInteger(source.free_memory_bytes),
|
|
146
|
+
jailbroken: typeof source.jailbroken === "boolean"
|
|
147
|
+
? source.jailbroken
|
|
148
|
+
: typeof source.rooted === "boolean" ? source.rooted : null
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export function toLegacyNativeEvent(event) {
|
|
152
|
+
const context = event.context ?? {};
|
|
153
|
+
const payload = { ...event.payload, context };
|
|
154
|
+
if (event.event_type === "frontend_exception") {
|
|
155
|
+
payload.error = {
|
|
156
|
+
name: event.payload.name,
|
|
157
|
+
message: event.payload.message,
|
|
158
|
+
stack: event.payload.stack
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
else if (event.event_type === "request_event") {
|
|
162
|
+
payload.url = event.payload.path;
|
|
163
|
+
}
|
|
164
|
+
return { ...event, payload };
|
|
165
|
+
}
|
|
166
|
+
function canonicalDeviceType(value) {
|
|
167
|
+
return value === "desktop" || value === "mobile" || value === "tablet" ? value : "unknown";
|
|
168
|
+
}
|
|
169
|
+
function canonicalColorScheme(value) {
|
|
170
|
+
return value === "light" || value === "dark" || value === "no-preference" ? value : null;
|
|
171
|
+
}
|
|
172
|
+
function nonNegativeInteger(value) {
|
|
173
|
+
return nullableNonNegativeInteger(value) ?? 0;
|
|
174
|
+
}
|
|
175
|
+
function nullableNonNegativeInteger(value) {
|
|
176
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
177
|
+
? Math.trunc(value)
|
|
178
|
+
: null;
|
|
179
|
+
}
|
|
180
|
+
function positiveNumber(value) {
|
|
181
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
|
|
182
|
+
}
|
|
183
|
+
function nonNegativeNumber(value) {
|
|
184
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
185
|
+
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EvidenceCapabilities, OperationScope, RecoveryObservation } from "./evidence-types.js";
|
|
1
2
|
import type { DebugBundleCaptureContext, DebugBundleClient, DebugBundleConfig, DebugBundleLogLevel, DebugBundleProbeOptions, DebugBundleRequestInfo, DebugBundleResponseInfo, DebugBundleStatus, ResolvedDebugBundleConfig } from "./types.js";
|
|
2
3
|
export declare class DebugBundleReactNativeClient implements DebugBundleClient {
|
|
3
4
|
private config;
|
|
@@ -9,9 +10,15 @@ export declare class DebugBundleReactNativeClient implements DebugBundleClient {
|
|
|
9
10
|
private jsProbeActivationExpiresAt;
|
|
10
11
|
private pendingNativeCalls;
|
|
11
12
|
private pendingNativeBytes;
|
|
13
|
+
private evidence;
|
|
12
14
|
constructor(config?: DebugBundleConfig);
|
|
13
15
|
get status(): DebugBundleStatus;
|
|
14
16
|
get lastEventAt(): number | null;
|
|
17
|
+
get evidenceCapabilities(): EvidenceCapabilities;
|
|
18
|
+
private hasCanonicalBridge;
|
|
19
|
+
beginOperation(): OperationScope;
|
|
20
|
+
withOperationContext<T>(operation: (scope: OperationScope) => T): T;
|
|
21
|
+
captureRecovery(observation: RecoveryObservation): void;
|
|
15
22
|
init(config: DebugBundleConfig): void;
|
|
16
23
|
captureException(error: unknown, context?: DebugBundleCaptureContext): void;
|
|
17
24
|
captureError(error: unknown, context?: DebugBundleCaptureContext): void;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|