@fluwa-tool/sdk 1.0.40 → 1.0.42
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Interceptador de XMLHttpRequest
|
|
3
|
-
*
|
|
3
|
+
* Usa fetch interno quando há mock para evitar problemas em React Native
|
|
4
4
|
*/
|
|
5
5
|
import { ILogger } from '../../core/Logger';
|
|
6
6
|
import { IRequestLogger } from './RequestLogger';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Interceptador de XMLHttpRequest
|
|
4
|
-
*
|
|
4
|
+
* Usa fetch interno quando há mock para evitar problemas em React Native
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.XMLHttpRequestInterceptor = void 0;
|
|
@@ -14,7 +14,7 @@ class XMLHttpRequestInterceptor {
|
|
|
14
14
|
this.sessionId = sessionId;
|
|
15
15
|
this.appName = appName;
|
|
16
16
|
this.isInstalled = false;
|
|
17
|
-
this.urlFilter = null;
|
|
17
|
+
this.urlFilter = null;
|
|
18
18
|
this.urlFilter = urlFilter || null;
|
|
19
19
|
}
|
|
20
20
|
install() {
|
|
@@ -22,18 +22,15 @@ class XMLHttpRequestInterceptor {
|
|
|
22
22
|
this.logger.warn('XMLHttpRequest interceptor já foi instalado');
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
// Verificar se XMLHttpRequest está disponível (apenas em navegadores)
|
|
26
25
|
if (typeof XMLHttpRequest === 'undefined') {
|
|
27
26
|
this.logger.debug('XMLHttpRequest não disponível nesse ambiente (requer navegador)');
|
|
28
27
|
return;
|
|
29
28
|
}
|
|
30
29
|
const self = this;
|
|
31
30
|
const originalXHR = XMLHttpRequest.prototype;
|
|
32
|
-
// Armazenar referência ao open original
|
|
33
31
|
this.originalOpen = originalXHR.open;
|
|
34
32
|
this.originalSend = originalXHR.send;
|
|
35
33
|
this.originalSetRequestHeader = originalXHR.setRequestHeader;
|
|
36
|
-
// Interceptar open()
|
|
37
34
|
originalXHR.open = function (method, url, ...args) {
|
|
38
35
|
const xhr = this;
|
|
39
36
|
xhr._fluwaMethod = method.toUpperCase();
|
|
@@ -43,7 +40,6 @@ class XMLHttpRequestInterceptor {
|
|
|
43
40
|
xhr._fluwaStartTime = Date.now();
|
|
44
41
|
return self.originalOpen.apply(this, [method, url, ...args]);
|
|
45
42
|
};
|
|
46
|
-
// Interceptar setRequestHeader()
|
|
47
43
|
originalXHR.setRequestHeader = function (header, value) {
|
|
48
44
|
const xhr = this;
|
|
49
45
|
if (!xhr._fluwaHeaders) {
|
|
@@ -52,7 +48,6 @@ class XMLHttpRequestInterceptor {
|
|
|
52
48
|
xhr._fluwaHeaders[header] = value;
|
|
53
49
|
return self.originalSetRequestHeader.apply(this, [header, value]);
|
|
54
50
|
};
|
|
55
|
-
// Interceptar send()
|
|
56
51
|
this.originalSend = originalXHR.send;
|
|
57
52
|
originalXHR.send = function (body) {
|
|
58
53
|
const xhr = this;
|
|
@@ -60,10 +55,8 @@ class XMLHttpRequestInterceptor {
|
|
|
60
55
|
const url = xhr._fluwaUrl;
|
|
61
56
|
const requestId = xhr._fluwaRequestId;
|
|
62
57
|
const headers = xhr._fluwaHeaders || {};
|
|
63
|
-
// ✅ Verificar URL Filter: ignorar requisições para servidor Fluwa ou URLs excluídas
|
|
64
|
-
// Isso previne loops infinitos onde o servidor Fluwa faz requisições que são interceptadas
|
|
65
58
|
if (self.urlFilter && !self.urlFilter.shouldIntercept(url)) {
|
|
66
|
-
self.logger.debug(`🔧 [XMLHttpRequestInterceptor] Ignorando URL excluída: ${url}
|
|
59
|
+
self.logger.debug(`🔧 [XMLHttpRequestInterceptor] Ignorando URL excluída: ${url}`);
|
|
67
60
|
return self.originalSend.apply(this, [body]);
|
|
68
61
|
}
|
|
69
62
|
const requestMetadata = {
|
|
@@ -77,59 +70,60 @@ class XMLHttpRequestInterceptor {
|
|
|
77
70
|
appName: self.appName,
|
|
78
71
|
source: types_1.RequestSource.REAL,
|
|
79
72
|
};
|
|
80
|
-
// Logar início imediatamente
|
|
81
73
|
self.requestLogger.logStart(requestMetadata).catch(() => { });
|
|
82
|
-
//
|
|
74
|
+
// Verificar mock com retry
|
|
83
75
|
const checkMockWithRetry = async () => {
|
|
84
76
|
let mockResponse = await self.mockResolver.resolve(method, url);
|
|
85
|
-
// Se não encontrou, aguardar e tentar novamente
|
|
86
77
|
if (!mockResponse) {
|
|
87
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
78
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
88
79
|
mockResponse = await self.mockResolver.resolve(method, url);
|
|
89
80
|
}
|
|
90
81
|
return mockResponse;
|
|
91
82
|
};
|
|
92
|
-
// Interceptar mudanças de estado
|
|
93
|
-
const originalOnReadyStateChange = xhr.onreadystatechange;
|
|
94
|
-
// Verificar mock e potencialmente interceptar
|
|
95
83
|
checkMockWithRetry().then(mockResponse => {
|
|
96
84
|
if (mockResponse) {
|
|
97
|
-
//
|
|
85
|
+
// Mock encontrado - fazer fetch interno para simular
|
|
98
86
|
requestMetadata.source = types_1.RequestSource.MOCK;
|
|
99
87
|
requestMetadata.status = mockResponse.status || 200;
|
|
100
88
|
requestMetadata.response = mockResponse.response;
|
|
101
|
-
// Aplicar delay se configurado
|
|
102
89
|
const delay = mockResponse.delay || 0;
|
|
103
90
|
setTimeout(() => {
|
|
104
91
|
const duration = Date.now() - (xhr._fluwaStartTime || 0);
|
|
105
92
|
requestMetadata.duration = duration;
|
|
106
93
|
self.requestLogger.logComplete(requestMetadata).catch(() => { });
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
94
|
+
// Criar resposta fake e simular como se fosse enviada pelo servidor
|
|
95
|
+
try {
|
|
96
|
+
const responseJSON = JSON.stringify(mockResponse.response);
|
|
97
|
+
const responseStatus = mockResponse.status || 200;
|
|
98
|
+
// Injetar resposta no xhr (pode não funcionar perfeitamente, mas tenta)
|
|
99
|
+
xhr.status = responseStatus;
|
|
100
|
+
xhr.statusText = 'Mock';
|
|
101
|
+
xhr.responseText = responseJSON;
|
|
102
|
+
xhr.response = mockResponse.response;
|
|
103
|
+
xhr.readyState = 4;
|
|
104
|
+
// Disparar evento de completion
|
|
105
|
+
const event = new ProgressEvent('readystatechange', {});
|
|
106
|
+
if (xhr.onreadystatechange) {
|
|
107
|
+
xhr.onreadystatechange.call(xhr, event);
|
|
116
108
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
self.originalSend.apply(xhr, [body]);
|
|
109
|
+
// Disparar evento de load como fallback
|
|
110
|
+
if (xhr.onload) {
|
|
111
|
+
xhr.onload.call(xhr, event);
|
|
121
112
|
}
|
|
122
113
|
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
self.logger.debug('Erro ao simular resposta, usando fallback');
|
|
116
|
+
// Fallback: fazer request real mesmo assim
|
|
117
|
+
self.originalSend.apply(xhr, [body]);
|
|
118
|
+
}
|
|
123
119
|
}, delay);
|
|
124
|
-
// NÃO chamar send original para requisições mockadas
|
|
125
120
|
return;
|
|
126
121
|
}
|
|
127
|
-
// Sem mock - fazer request real
|
|
122
|
+
// Sem mock - fazer request real
|
|
123
|
+
const originalOnReadyStateChange = xhr.onreadystatechange;
|
|
128
124
|
xhr.onreadystatechange = function (event) {
|
|
129
125
|
if (xhr.readyState === 4) {
|
|
130
|
-
// Requisição completou
|
|
131
126
|
requestMetadata.status = xhr.status;
|
|
132
|
-
// Tentar extrair response
|
|
133
127
|
try {
|
|
134
128
|
if (xhr.responseType === '' || xhr.responseType === 'text') {
|
|
135
129
|
if (xhr.responseText) {
|
|
@@ -159,51 +153,12 @@ class XMLHttpRequestInterceptor {
|
|
|
159
153
|
requestMetadata.duration = duration;
|
|
160
154
|
self.requestLogger.logComplete(requestMetadata).catch(() => { });
|
|
161
155
|
}
|
|
162
|
-
// Chamar handler original
|
|
163
156
|
if (originalOnReadyStateChange) {
|
|
164
157
|
originalOnReadyStateChange.call(this, event);
|
|
165
158
|
}
|
|
166
159
|
};
|
|
167
|
-
// Chamar send original
|
|
168
160
|
self.originalSend.apply(xhr, [body]);
|
|
169
161
|
}).catch(() => {
|
|
170
|
-
// Erro ao verificar mock - fazer request real
|
|
171
|
-
xhr.onreadystatechange = function (event) {
|
|
172
|
-
if (xhr.readyState === 4) {
|
|
173
|
-
requestMetadata.status = xhr.status;
|
|
174
|
-
try {
|
|
175
|
-
if (xhr.responseType === '' || xhr.responseType === 'text') {
|
|
176
|
-
if (xhr.responseText) {
|
|
177
|
-
requestMetadata.response = self.safeParseBody(xhr.responseText);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
else if (xhr.response) {
|
|
181
|
-
if (typeof xhr.response === 'string') {
|
|
182
|
-
requestMetadata.response = self.safeParseBody(xhr.response);
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
requestMetadata.response = `[${xhr.responseType}]`;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
catch (e) {
|
|
190
|
-
try {
|
|
191
|
-
if (xhr.responseText) {
|
|
192
|
-
requestMetadata.response = xhr.responseText;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
requestMetadata.response = undefined;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
const duration = Date.now() - (xhr._fluwaStartTime || 0);
|
|
200
|
-
requestMetadata.duration = duration;
|
|
201
|
-
self.requestLogger.logComplete(requestMetadata).catch(() => { });
|
|
202
|
-
}
|
|
203
|
-
if (originalOnReadyStateChange) {
|
|
204
|
-
originalOnReadyStateChange.call(this, event);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
162
|
self.originalSend.apply(xhr, [body]);
|
|
208
163
|
});
|
|
209
164
|
};
|