react-native-qalink 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.
Files changed (42) hide show
  1. package/README.md +342 -0
  2. package/dist/core/classifier.d.ts +9 -0
  3. package/dist/core/classifier.d.ts.map +1 -0
  4. package/dist/core/classifier.js +51 -0
  5. package/dist/core/classifier.js.map +1 -0
  6. package/dist/core/session.d.ts +8 -0
  7. package/dist/core/session.d.ts.map +1 -0
  8. package/dist/core/session.js +60 -0
  9. package/dist/core/session.js.map +1 -0
  10. package/dist/index.d.ts +58 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +171 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/interceptors/axios.d.ts +4 -0
  15. package/dist/interceptors/axios.d.ts.map +1 -0
  16. package/dist/interceptors/axios.js +78 -0
  17. package/dist/interceptors/axios.js.map +1 -0
  18. package/dist/interceptors/console.d.ts +4 -0
  19. package/dist/interceptors/console.d.ts.map +1 -0
  20. package/dist/interceptors/console.js +159 -0
  21. package/dist/interceptors/console.js.map +1 -0
  22. package/dist/interceptors/errors.d.ts +4 -0
  23. package/dist/interceptors/errors.d.ts.map +1 -0
  24. package/dist/interceptors/errors.js +49 -0
  25. package/dist/interceptors/errors.js.map +1 -0
  26. package/dist/interceptors/fetch.d.ts +4 -0
  27. package/dist/interceptors/fetch.d.ts.map +1 -0
  28. package/dist/interceptors/fetch.js +83 -0
  29. package/dist/interceptors/fetch.js.map +1 -0
  30. package/dist/interceptors/runtime.d.ts +4 -0
  31. package/dist/interceptors/runtime.d.ts.map +1 -0
  32. package/dist/interceptors/runtime.js +141 -0
  33. package/dist/interceptors/runtime.js.map +1 -0
  34. package/dist/transport/websocket.d.ts +23 -0
  35. package/dist/transport/websocket.d.ts.map +1 -0
  36. package/dist/transport/websocket.js +104 -0
  37. package/dist/transport/websocket.js.map +1 -0
  38. package/dist/types/index.d.ts +139 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/index.js +3 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/package.json +36 -0
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupRuntimeErrorHandler = setupRuntimeErrorHandler;
4
+ const session_1 = require("../core/session");
5
+ /**
6
+ * Captura los errores del runtime de React Native:
7
+ *
8
+ * 1. ErrorUtils.setGlobalHandler → captura la PANTALLA ROJA (errores fatales)
9
+ * Son los errores que crashean la app completamente. React Native los
10
+ * intercepta antes de mostrar el red screen y nosotros nos enganchamos ahí.
11
+ *
12
+ * 2. LogBox.ignoreLogs / console.error → captura las CAJAS AMARILLAS (warnings)
13
+ * Son los warnings que RN muestra en desarrollo. Se generan a través de
14
+ * console.error internamente, así que el interceptor de consola los captura,
15
+ * pero aquí los marcamos también con el handler de RN para mayor precisión.
16
+ *
17
+ * 3. NativeModules errors → errores del bridge JS<->Native
18
+ * Ocurren cuando un módulo nativo falla o no está disponible.
19
+ */
20
+ function classifyRuntimeError(message, isFatal) {
21
+ if (isFatal)
22
+ return 'red_screen';
23
+ if (message.includes('NativeModule') ||
24
+ message.includes('Native module') ||
25
+ message.includes('TurboModule') ||
26
+ message.includes('requireNativeComponent')) {
27
+ return 'native_module';
28
+ }
29
+ if (message.includes('bridge') ||
30
+ message.includes('JSContext') ||
31
+ message.includes('RCTBridge') ||
32
+ message.includes('JavaScriptCore')) {
33
+ return 'bridge';
34
+ }
35
+ if (message.startsWith('Warning:') || message.includes('deprecated')) {
36
+ return 'yellow_box';
37
+ }
38
+ return 'unknown';
39
+ }
40
+ function setupRuntimeErrorHandler(transport, config, getCurrentScreen) {
41
+ var _a, _b;
42
+ const cleanups = [];
43
+ // ── 1. Handler global de errores fatales (pantalla roja) ──────────────────
44
+ // React Native expone ErrorUtils para capturar errores antes de que
45
+ // la app crashee y muestre el red screen.
46
+ try {
47
+ const originalGlobalHandler = ErrorUtils.getGlobalHandler();
48
+ ErrorUtils.setGlobalHandler((error, isFatal) => {
49
+ var _a, _b, _c;
50
+ const fatal = isFatal !== null && isFatal !== void 0 ? isFatal : false;
51
+ const category = classifyRuntimeError((_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '', fatal);
52
+ const event = {
53
+ id: (0, session_1.generateId)(),
54
+ type: 'runtime_error',
55
+ level: fatal ? 'fatal' : 'error',
56
+ message: (_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : String(error),
57
+ stack: error === null || error === void 0 ? void 0 : error.stack,
58
+ isFatal: fatal,
59
+ category,
60
+ timestamp: Date.now(),
61
+ screen: getCurrentScreen(),
62
+ sessionId: (0, session_1.getSessionId)(),
63
+ };
64
+ transport.send(event);
65
+ (_c = config.onEvent) === null || _c === void 0 ? void 0 : _c.call(config, event);
66
+ // CRÍTICO: siempre llamar al handler original
67
+ // Si no lo hacemos, RN no muestra la pantalla roja y el error se pierde
68
+ originalGlobalHandler(error, isFatal);
69
+ });
70
+ cleanups.push(() => {
71
+ ErrorUtils.setGlobalHandler(originalGlobalHandler);
72
+ });
73
+ }
74
+ catch (e) {
75
+ // ErrorUtils puede no estar disponible en algunos entornos (ej: Jest)
76
+ }
77
+ // ── 2. Promesas rechazadas no manejadas ───────────────────────────────────
78
+ // Cuando un Promise.reject() no tiene .catch(), RN lo captura aquí.
79
+ // Ejemplo típico: llamada a API sin try/catch
80
+ const unhandledRejectionHandler = (event) => {
81
+ var _a, _b, _c;
82
+ const error = event === null || event === void 0 ? void 0 : event.reason;
83
+ const message = (_b = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : String(error)) !== null && _b !== void 0 ? _b : 'Unhandled Promise Rejection';
84
+ const runtimeEvent = {
85
+ id: (0, session_1.generateId)(),
86
+ type: 'runtime_error',
87
+ level: 'error',
88
+ message,
89
+ stack: error === null || error === void 0 ? void 0 : error.stack,
90
+ isFatal: false,
91
+ category: 'unknown',
92
+ timestamp: Date.now(),
93
+ screen: getCurrentScreen(),
94
+ sessionId: (0, session_1.getSessionId)(),
95
+ };
96
+ transport.send(runtimeEvent);
97
+ (_c = config.onEvent) === null || _c === void 0 ? void 0 : _c.call(config, runtimeEvent);
98
+ };
99
+ if (typeof global !== 'undefined') {
100
+ (_b = (_a = global).addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, 'unhandledrejection', unhandledRejectionHandler);
101
+ cleanups.push(() => {
102
+ var _a, _b;
103
+ (_b = (_a = global).removeEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, 'unhandledrejection', unhandledRejectionHandler);
104
+ });
105
+ }
106
+ // ── 3. Warnings de LogBox (cajas amarillas) ───────────────────────────────
107
+ // En RN >= 0.64 los warnings se manejan via LogBox.
108
+ // Nos enganchamos al método interno que registra los warnings.
109
+ try {
110
+ const LogBox = require('react-native/Libraries/LogBox/LogBox');
111
+ if (LogBox && LogBox.__warn) {
112
+ const originalWarn = LogBox.__warn.bind(LogBox);
113
+ LogBox.__warn = (message, stack) => {
114
+ var _a;
115
+ const event = {
116
+ id: (0, session_1.generateId)(),
117
+ type: 'runtime_error',
118
+ level: 'warning',
119
+ message,
120
+ stack,
121
+ isFatal: false,
122
+ category: 'yellow_box',
123
+ timestamp: Date.now(),
124
+ screen: getCurrentScreen(),
125
+ sessionId: (0, session_1.getSessionId)(),
126
+ };
127
+ transport.send(event);
128
+ (_a = config.onEvent) === null || _a === void 0 ? void 0 : _a.call(config, event);
129
+ originalWarn(message, stack);
130
+ };
131
+ cleanups.push(() => {
132
+ LogBox.__warn = originalWarn;
133
+ });
134
+ }
135
+ }
136
+ catch (_c) {
137
+ // LogBox puede no estar disponible en versiones viejas de RN
138
+ }
139
+ return () => cleanups.forEach(fn => fn());
140
+ }
141
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/interceptors/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { QALinkEvent } from '../types';
2
+ type TransportStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
3
+ export declare class WebSocketTransport {
4
+ private ws;
5
+ private queue;
6
+ private status;
7
+ private reconnectTimer;
8
+ private reconnectAttempts;
9
+ private readonly maxReconnectAttempts;
10
+ private readonly reconnectBaseMs;
11
+ private debug;
12
+ private serverUrl;
13
+ constructor(serverUrl: string, debug?: boolean);
14
+ connect(): void;
15
+ disconnect(): void;
16
+ send(event: QALinkEvent): void;
17
+ getStatus(): TransportStatus;
18
+ private flushQueue;
19
+ private scheduleReconnect;
20
+ private log;
21
+ }
22
+ export {};
23
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,KAAK,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;AAE7E,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAM;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,EAAE,MAAM,EAAE,KAAK,UAAQ;IAK5C,OAAO,IAAI,IAAI;IAoCf,UAAU,IAAI,IAAI;IAUlB,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAe9B,SAAS,IAAI,eAAe;IAI5B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,GAAG;CAKZ"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketTransport = void 0;
4
+ class WebSocketTransport {
5
+ constructor(serverUrl, debug = false) {
6
+ this.ws = null;
7
+ this.queue = [];
8
+ this.status = 'disconnected';
9
+ this.reconnectTimer = null;
10
+ this.reconnectAttempts = 0;
11
+ this.maxReconnectAttempts = 10;
12
+ this.reconnectBaseMs = 1000;
13
+ this.serverUrl = serverUrl;
14
+ this.debug = debug;
15
+ }
16
+ connect() {
17
+ if (this.status === 'connecting' || this.status === 'connected')
18
+ return;
19
+ this.status = 'connecting';
20
+ this.log(`Connecting to ${this.serverUrl}...`);
21
+ try {
22
+ this.ws = new WebSocket(this.serverUrl);
23
+ this.ws.onopen = () => {
24
+ this.status = 'connected';
25
+ this.reconnectAttempts = 0;
26
+ this.log('Connected ✅');
27
+ this.flushQueue();
28
+ };
29
+ this.ws.onclose = () => {
30
+ this.status = 'disconnected';
31
+ this.log('Disconnected. Scheduling reconnect...');
32
+ this.scheduleReconnect();
33
+ };
34
+ this.ws.onerror = (error) => {
35
+ this.status = 'error';
36
+ this.log('WebSocket error:', error);
37
+ };
38
+ this.ws.onmessage = (msg) => {
39
+ this.log('Message from server:', msg.data);
40
+ };
41
+ }
42
+ catch (error) {
43
+ this.log('Failed to create WebSocket:', error);
44
+ this.scheduleReconnect();
45
+ }
46
+ }
47
+ disconnect() {
48
+ var _a;
49
+ if (this.reconnectTimer) {
50
+ clearTimeout(this.reconnectTimer);
51
+ this.reconnectTimer = null;
52
+ }
53
+ (_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
54
+ this.ws = null;
55
+ this.status = 'disconnected';
56
+ }
57
+ send(event) {
58
+ var _a;
59
+ if (this.status === 'connected' && ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
60
+ try {
61
+ this.ws.send(JSON.stringify(event));
62
+ this.log(`Sent event: ${event.type}`);
63
+ }
64
+ catch (error) {
65
+ this.log('Send failed, queuing event:', error);
66
+ this.queue.push(event);
67
+ }
68
+ }
69
+ else {
70
+ this.queue.push(event);
71
+ this.log(`Queued event (${this.queue.length} pending): ${event.type}`);
72
+ }
73
+ }
74
+ getStatus() {
75
+ return this.status;
76
+ }
77
+ flushQueue() {
78
+ if (this.queue.length === 0)
79
+ return;
80
+ this.log(`Flushing ${this.queue.length} queued events...`);
81
+ const toSend = [...this.queue];
82
+ this.queue = [];
83
+ toSend.forEach(event => this.send(event));
84
+ }
85
+ scheduleReconnect() {
86
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
87
+ this.log('Max reconnect attempts reached. Giving up.');
88
+ return;
89
+ }
90
+ const delay = this.reconnectBaseMs * Math.pow(2, this.reconnectAttempts);
91
+ this.reconnectAttempts++;
92
+ this.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})...`);
93
+ this.reconnectTimer = setTimeout(() => {
94
+ this.connect();
95
+ }, delay);
96
+ }
97
+ log(...args) {
98
+ if (this.debug) {
99
+ console.log('[QALink Transport]', ...args);
100
+ }
101
+ }
102
+ }
103
+ exports.WebSocketTransport = WebSocketTransport;
104
+ //# sourceMappingURL=websocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/transport/websocket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ export type ErrorSource = 'BACKEND' | 'FRONTEND' | 'NETWORK' | 'AUTH' | 'UNKNOWN';
2
+ export type EventType = 'network_request' | 'network_error' | 'js_error' | 'breadcrumb' | 'session_start' | 'console_log' | 'console_warn' | 'console_error' | 'runtime_error' | 'metro_error';
3
+ export interface NetworkEvent {
4
+ id: string;
5
+ type: 'network_request' | 'network_error';
6
+ method: string;
7
+ url: string;
8
+ statusCode?: number;
9
+ requestHeaders?: Record<string, string>;
10
+ requestBody?: unknown;
11
+ responseHeaders?: Record<string, string>;
12
+ responseBody?: unknown;
13
+ durationMs: number;
14
+ timestamp: number;
15
+ source: ErrorSource;
16
+ sessionId: string;
17
+ }
18
+ export interface JSErrorEvent {
19
+ id: string;
20
+ type: 'js_error';
21
+ message: string;
22
+ stack?: string;
23
+ componentStack?: string;
24
+ timestamp: number;
25
+ source: 'FRONTEND';
26
+ sessionId: string;
27
+ }
28
+ /**
29
+ * Errores que React Native lanza en tiempo de ejecución:
30
+ * - Red screen of death (pantalla roja)
31
+ * - Yellow box warnings
32
+ * - Errores de módulos nativos
33
+ * - Errores de bridge JS<->Native
34
+ */
35
+ export interface RuntimeErrorEvent {
36
+ id: string;
37
+ type: 'runtime_error';
38
+ level: 'fatal' | 'error' | 'warning';
39
+ message: string;
40
+ stack?: string;
41
+ componentStack?: string;
42
+ isFatal: boolean;
43
+ category: 'red_screen' | 'yellow_box' | 'native_module' | 'bridge' | 'unknown';
44
+ timestamp: number;
45
+ screen: string;
46
+ sessionId: string;
47
+ }
48
+ /**
49
+ * Errores que Metro Bundler reporta durante el desarrollo:
50
+ * - Syntax errors en el código
51
+ * - Módulos no encontrados
52
+ * - Errores de transformación
53
+ */
54
+ export interface MetroErrorEvent {
55
+ id: string;
56
+ type: 'metro_error';
57
+ message: string;
58
+ file?: string;
59
+ lineNumber?: number;
60
+ column?: number;
61
+ stack?: string;
62
+ timestamp: number;
63
+ sessionId: string;
64
+ }
65
+ export type ConsoleLevel = 'log' | 'warn' | 'error' | 'info' | 'debug';
66
+ /**
67
+ * Captura todo lo que el desarrollador imprime con console.log/warn/error.
68
+ * Incluye los logs internos de React Native y librerías de terceros.
69
+ */
70
+ export interface ConsoleEvent {
71
+ id: string;
72
+ type: 'console_log' | 'console_warn' | 'console_error';
73
+ level: ConsoleLevel;
74
+ message: string;
75
+ args: string[];
76
+ category: 'user_log' | 'rn_warning' | 'rn_error' | 'third_party' | 'unknown';
77
+ timestamp: number;
78
+ screen: string;
79
+ sessionId: string;
80
+ }
81
+ export interface BreadcrumbEvent {
82
+ id: string;
83
+ type: 'breadcrumb';
84
+ action: string;
85
+ screen?: string;
86
+ data?: Record<string, unknown>;
87
+ timestamp: number;
88
+ sessionId: string;
89
+ }
90
+ export interface SessionStartEvent {
91
+ id: string;
92
+ type: 'session_start';
93
+ sessionId: string;
94
+ timestamp: number;
95
+ deviceInfo: DeviceInfo;
96
+ appVersion: string;
97
+ }
98
+ export type QALinkEvent = NetworkEvent | JSErrorEvent | RuntimeErrorEvent | MetroErrorEvent | ConsoleEvent | BreadcrumbEvent | SessionStartEvent;
99
+ export interface DeviceInfo {
100
+ platform: 'ios' | 'android';
101
+ osVersion: string;
102
+ appVersion: string;
103
+ deviceModel: string;
104
+ buildType: 'debug' | 'release';
105
+ }
106
+ export interface ConsoleConfig {
107
+ /** Capturar console.log (default: true) */
108
+ captureLogs?: boolean;
109
+ /** Capturar console.warn (default: true) */
110
+ captureWarnings?: boolean;
111
+ /** Capturar console.error (default: true) */
112
+ captureErrors?: boolean;
113
+ /**
114
+ * Filtrar mensajes que contengan estos strings.
115
+ * Útil para ignorar logs muy verbosos de librerías.
116
+ * Ej: ['[react-query]', '[redux]']
117
+ */
118
+ ignorePatterns?: string[];
119
+ /**
120
+ * Solo capturar mensajes que contengan estos strings.
121
+ * Si está vacío, captura todo.
122
+ */
123
+ includePatterns?: string[];
124
+ }
125
+ export interface QALinkConfig {
126
+ serverUrl: string;
127
+ appVersion: string;
128
+ enabled?: boolean;
129
+ logNetworkBodies?: boolean;
130
+ sensitiveHeaders?: string[];
131
+ sensitiveUrlPatterns?: string[];
132
+ /** Configuración de captura de consola y Metro */
133
+ console?: ConsoleConfig;
134
+ /** Capturar errores del runtime de React Native (red/yellow box) */
135
+ captureRuntimeErrors?: boolean;
136
+ onEvent?: (event: QALinkEvent) => void;
137
+ debug?: boolean;
138
+ }
139
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAElF,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,eAAe,GACf,UAAU,GACV,YAAY,GACZ,eAAe,GACf,aAAa,GACb,cAAc,GACd,eAAe,GACf,eAAe,GACf,aAAa,CAAC;AAIlB,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,GAAG,eAAe,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IAEjB,QAAQ,EACJ,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,QAAQ,GACR,SAAS,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvE;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,GAAG,cAAc,GAAG,eAAe,CAAC;IACvD,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAEhB,IAAI,EAAE,MAAM,EAAE,CAAC;IAEf,QAAQ,EACJ,UAAU,GACV,YAAY,GACZ,UAAU,GACV,aAAa,GACb,SAAS,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GACnB,YAAY,GACZ,YAAY,GACZ,iBAAiB,GACjB,eAAe,GACf,YAAY,GACZ,eAAe,GACf,iBAAiB,CAAC;AAItB,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,kDAAkD;IAClD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "react-native-qalink",
3
+ "version": "0.1.0",
4
+ "description": "Real-time error capture SDK for React Native — helps QA teams identify if bugs are frontend or backend",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "keywords": [
12
+ "react-native",
13
+ "debugging",
14
+ "qa",
15
+ "error-tracking",
16
+ "network-interceptor"
17
+ ],
18
+ "peerDependencies": {
19
+ "react-native": ">=0.70.0",
20
+ "axios": ">=1.0.0"
21
+ },
22
+ "peerDependenciesMeta": {
23
+ "axios": {
24
+ "optional": true
25
+ }
26
+ },
27
+ "devDependencies": {
28
+ "typescript": "^5.0.0",
29
+ "@types/react-native": "^0.72.0"
30
+ },
31
+ "scripts": {
32
+ "build": "tsc",
33
+ "typecheck": "tsc --noEmit"
34
+ },
35
+ "license": "MIT"
36
+ }