react-native-qalink 0.1.2 → 0.1.3
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/dist/interceptors/console.js +67 -111
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setupConsoleInterceptor =
|
|
3
|
+
exports.setupConsoleInterceptor = void 0;
|
|
4
4
|
const session_1 = require("../core/session");
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
const originalConsole = {
|
|
7
7
|
log: console.log.bind(console),
|
|
8
8
|
warn: console.warn.bind(console),
|
|
@@ -10,132 +10,88 @@ const originalConsole = {
|
|
|
10
10
|
info: console.info.bind(console),
|
|
11
11
|
debug: console.debug.bind(console),
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
'VirtualizedList',
|
|
20
|
-
'Each child in a list',
|
|
21
|
-
'componentWillMount',
|
|
22
|
-
'componentWillReceiveProps',
|
|
23
|
-
'componentWillUpdate',
|
|
24
|
-
'findDOMNode',
|
|
25
|
-
'ReactDOM.render',
|
|
26
|
-
'key prop',
|
|
27
|
-
'unique "key"',
|
|
28
|
-
'Maximum update depth',
|
|
29
|
-
];
|
|
30
|
-
const RN_ERROR_PATTERNS = [
|
|
31
|
-
'Invariant Violation',
|
|
32
|
-
'Text strings must be rendered',
|
|
33
|
-
'Cannot update a component',
|
|
34
|
-
'Element type is invalid',
|
|
35
|
-
'Objects are not valid as a React child',
|
|
36
|
-
'TypeError',
|
|
37
|
-
'ReferenceError',
|
|
38
|
-
'Cannot read property',
|
|
39
|
-
'Cannot read properties',
|
|
40
|
-
'is not a function',
|
|
41
|
-
'undefined is not an object',
|
|
42
|
-
'null is not an object',
|
|
43
|
-
];
|
|
44
|
-
const METRO_ERROR_PATTERNS = [
|
|
45
|
-
'Unable to resolve module',
|
|
46
|
-
'Module not found',
|
|
47
|
-
'SyntaxError',
|
|
48
|
-
'TransformError',
|
|
49
|
-
'bundling failed',
|
|
50
|
-
'Metro Bundler',
|
|
51
|
-
'Error: Metro',
|
|
52
|
-
];
|
|
53
|
-
const THIRD_PARTY_PATTERNS = [
|
|
54
|
-
'[react-navigation]',
|
|
55
|
-
'[react-query]',
|
|
56
|
-
'[redux]',
|
|
57
|
-
'[mobx]',
|
|
58
|
-
'[zustand]',
|
|
59
|
-
'Reanimated',
|
|
60
|
-
'Gesture Handler',
|
|
61
|
-
'SafeAreaProvider',
|
|
62
|
-
];
|
|
13
|
+
|
|
14
|
+
const RN_WARNING_PATTERNS = ['Warning:', 'VirtualizedList', 'Each child in a list', 'componentWillMount', 'componentWillReceiveProps', 'componentWillUpdate', 'findDOMNode', 'ReactDOM.render', 'key prop', 'unique "key"', 'Maximum update depth'];
|
|
15
|
+
const RN_ERROR_PATTERNS = ['Invariant Violation', 'Text strings must be rendered', 'Cannot update a component', 'Element type is invalid', 'Objects are not valid as a React child', 'TypeError', 'ReferenceError', 'Cannot read property', 'Cannot read properties', 'is not a function', 'undefined is not an object', 'null is not an object'];
|
|
16
|
+
const METRO_ERROR_PATTERNS = ['Unable to resolve module', 'Module not found', 'SyntaxError', 'TransformError', 'bundling failed', 'Metro Bundler', 'Error: Metro'];
|
|
17
|
+
const THIRD_PARTY_PATTERNS = ['[react-navigation]', '[react-query]', '[redux]', '[mobx]', '[zustand]', 'Reanimated', 'Gesture Handler', 'SafeAreaProvider'];
|
|
18
|
+
|
|
63
19
|
function classifyConsoleMessage(message) {
|
|
64
|
-
if (METRO_ERROR_PATTERNS.some(p => message.includes(p)))
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
if (RN_WARNING_PATTERNS.some(p => message.includes(p)))
|
|
69
|
-
return 'rn_warning';
|
|
70
|
-
if (THIRD_PARTY_PATTERNS.some(p => message.includes(p)))
|
|
71
|
-
return 'third_party';
|
|
20
|
+
if (METRO_ERROR_PATTERNS.some(p => message.includes(p))) return 'rn_error';
|
|
21
|
+
if (RN_ERROR_PATTERNS.some(p => message.includes(p))) return 'rn_error';
|
|
22
|
+
if (RN_WARNING_PATTERNS.some(p => message.includes(p))) return 'rn_warning';
|
|
23
|
+
if (THIRD_PARTY_PATTERNS.some(p => message.includes(p))) return 'third_party';
|
|
72
24
|
return 'user_log';
|
|
73
25
|
}
|
|
26
|
+
|
|
74
27
|
function serializeArg(arg) {
|
|
75
|
-
|
|
76
|
-
if (arg ===
|
|
77
|
-
|
|
78
|
-
if (arg ===
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return arg;
|
|
82
|
-
if (typeof arg === 'number' || typeof arg === 'boolean')
|
|
83
|
-
return String(arg);
|
|
84
|
-
if (arg instanceof Error)
|
|
85
|
-
return `${arg.name}: ${arg.message}\n${(_a = arg.stack) !== null && _a !== void 0 ? _a : ''}`;
|
|
86
|
-
try {
|
|
87
|
-
return JSON.stringify(arg, null, 2);
|
|
88
|
-
}
|
|
89
|
-
catch (_b) {
|
|
90
|
-
return String(arg);
|
|
91
|
-
}
|
|
28
|
+
if (arg === null) return 'null';
|
|
29
|
+
if (arg === undefined) return 'undefined';
|
|
30
|
+
if (typeof arg === 'string') return arg;
|
|
31
|
+
if (typeof arg === 'number' || typeof arg === 'boolean') return String(arg);
|
|
32
|
+
if (arg instanceof Error) return `${arg.name}: ${arg.message}\n${arg.stack ?? ''}`;
|
|
33
|
+
try { return JSON.stringify(arg, null, 2); } catch { return String(arg); }
|
|
92
34
|
}
|
|
35
|
+
|
|
93
36
|
function shouldCapture(message, config) {
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
return true;
|
|
97
|
-
// Ignorar si matchea algún patrón de exclusión
|
|
98
|
-
if ((_a = config.ignorePatterns) === null || _a === void 0 ? void 0 : _a.some(p => message.includes(p)))
|
|
99
|
-
return false;
|
|
100
|
-
// Si hay patrones de inclusión, solo capturar si matchea alguno
|
|
37
|
+
if (!config) return true;
|
|
38
|
+
if (config.ignorePatterns?.some(p => message.includes(p))) return false;
|
|
101
39
|
if (config.includePatterns && config.includePatterns.length > 0) {
|
|
102
40
|
return config.includePatterns.some(p => message.includes(p));
|
|
103
41
|
}
|
|
104
42
|
return true;
|
|
105
43
|
}
|
|
44
|
+
|
|
45
|
+
// FLAG para prevenir loops de recursión
|
|
46
|
+
let _isSending = false;
|
|
47
|
+
|
|
106
48
|
function setupConsoleInterceptor(transport, config, getCurrentScreen) {
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
49
|
+
const consoleConfig = config.console ?? {};
|
|
50
|
+
const { captureLogs = true, captureWarnings = true, captureErrors = true } = consoleConfig;
|
|
51
|
+
|
|
110
52
|
function intercept(level, eventType, originalFn) {
|
|
111
53
|
return (...args) => {
|
|
112
|
-
|
|
113
|
-
// Siempre llamar al original primero — Metro sigue mostrando todo
|
|
54
|
+
// SIEMPRE llamar el original primero
|
|
114
55
|
originalFn(...args);
|
|
56
|
+
|
|
57
|
+
// Evitar loop recursivo — si ya estamos enviando, no volver a entrar
|
|
58
|
+
if (_isSending) return;
|
|
59
|
+
|
|
115
60
|
const serializedArgs = args.map(serializeArg);
|
|
116
61
|
const message = serializedArgs.join(' ');
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
62
|
+
|
|
63
|
+
// Ignorar logs internos de QALink
|
|
64
|
+
if (message.startsWith('[QALink]')) return;
|
|
65
|
+
|
|
66
|
+
// Ignorar errores de call stack para evitar loop infinito
|
|
67
|
+
if (message.includes('Maximum call stack') || message.includes('call stack size exceeded')) return;
|
|
68
|
+
|
|
69
|
+
if (!shouldCapture(message, consoleConfig)) return;
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
_isSending = true;
|
|
73
|
+
const category = classifyConsoleMessage(message);
|
|
74
|
+
const event = {
|
|
75
|
+
id: (0, session_1.generateId)(),
|
|
76
|
+
type: eventType,
|
|
77
|
+
level,
|
|
78
|
+
message,
|
|
79
|
+
args: serializedArgs,
|
|
80
|
+
category,
|
|
81
|
+
timestamp: Date.now(),
|
|
82
|
+
screen: getCurrentScreen(),
|
|
83
|
+
sessionId: (0, session_1.getSessionId)(),
|
|
84
|
+
};
|
|
85
|
+
transport.send(event);
|
|
86
|
+
config.onEvent?.(event);
|
|
87
|
+
} catch {
|
|
88
|
+
// Nunca romper la app por un error del interceptor
|
|
89
|
+
} finally {
|
|
90
|
+
_isSending = false;
|
|
91
|
+
}
|
|
136
92
|
};
|
|
137
93
|
}
|
|
138
|
-
|
|
94
|
+
|
|
139
95
|
if (captureLogs) {
|
|
140
96
|
console.log = intercept('log', 'console_log', originalConsole.log);
|
|
141
97
|
console.info = intercept('info', 'console_log', originalConsole.info);
|
|
@@ -147,7 +103,7 @@ function setupConsoleInterceptor(transport, config, getCurrentScreen) {
|
|
|
147
103
|
if (captureErrors) {
|
|
148
104
|
console.error = intercept('error', 'console_error', originalConsole.error);
|
|
149
105
|
}
|
|
150
|
-
|
|
106
|
+
|
|
151
107
|
return () => {
|
|
152
108
|
console.log = originalConsole.log;
|
|
153
109
|
console.warn = originalConsole.warn;
|
|
@@ -156,4 +112,4 @@ function setupConsoleInterceptor(transport, config, getCurrentScreen) {
|
|
|
156
112
|
console.debug = originalConsole.debug;
|
|
157
113
|
};
|
|
158
114
|
}
|
|
159
|
-
|
|
115
|
+
exports.setupConsoleInterceptor = setupConsoleInterceptor;
|
package/package.json
CHANGED