@fluwa-tool/sdk 1.0.40 → 1.0.41
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.
|
@@ -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,8 +55,6 @@ 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
59
|
self.logger.debug(`🔧 [XMLHttpRequestInterceptor] Ignorando URL excluída: ${url} (bypass filtering)`);
|
|
67
60
|
return self.originalSend.apply(this, [body]);
|
|
@@ -77,59 +70,55 @@ 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
|
+
const originalOnReadyStateChange = xhr.onreadystatechange;
|
|
75
|
+
// Verificar mock com retry
|
|
83
76
|
const checkMockWithRetry = async () => {
|
|
84
77
|
let mockResponse = await self.mockResolver.resolve(method, url);
|
|
85
|
-
// Se não encontrou, aguardar e tentar novamente
|
|
86
78
|
if (!mockResponse) {
|
|
87
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
79
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
88
80
|
mockResponse = await self.mockResolver.resolve(method, url);
|
|
89
81
|
}
|
|
90
82
|
return mockResponse;
|
|
91
83
|
};
|
|
92
|
-
// Interceptar mudanças de estado
|
|
93
|
-
const originalOnReadyStateChange = xhr.onreadystatechange;
|
|
94
|
-
// Verificar mock e potencialmente interceptar
|
|
95
84
|
checkMockWithRetry().then(mockResponse => {
|
|
96
85
|
if (mockResponse) {
|
|
97
|
-
//
|
|
86
|
+
// Mock encontrado - simular resposta
|
|
98
87
|
requestMetadata.source = types_1.RequestSource.MOCK;
|
|
99
88
|
requestMetadata.status = mockResponse.status || 200;
|
|
100
89
|
requestMetadata.response = mockResponse.response;
|
|
101
|
-
// Aplicar delay se configurado
|
|
102
90
|
const delay = mockResponse.delay || 0;
|
|
103
91
|
setTimeout(() => {
|
|
104
92
|
const duration = Date.now() - (xhr._fluwaStartTime || 0);
|
|
105
93
|
requestMetadata.duration = duration;
|
|
106
94
|
self.requestLogger.logComplete(requestMetadata).catch(() => { });
|
|
107
|
-
// Simular
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
xhr
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
95
|
+
// Simular readyState = 4 chamando onreadystatechange 3x
|
|
96
|
+
try {
|
|
97
|
+
// Chamar para cada readyState
|
|
98
|
+
for (let state = 1; state <= 4; state++) {
|
|
99
|
+
Object.defineProperty(xhr, 'readyState', { value: state, configurable: true, writable: true });
|
|
100
|
+
if (state === 4) {
|
|
101
|
+
Object.defineProperty(xhr, 'status', { value: mockResponse.status || 200, configurable: true, writable: true });
|
|
102
|
+
Object.defineProperty(xhr, 'statusText', { value: 'Mock', configurable: true, writable: true });
|
|
103
|
+
Object.defineProperty(xhr, 'responseText', { value: JSON.stringify(mockResponse.response), configurable: true, writable: true });
|
|
104
|
+
Object.defineProperty(xhr, 'response', { value: mockResponse.response, configurable: true, writable: true });
|
|
105
|
+
}
|
|
106
|
+
if (originalOnReadyStateChange) {
|
|
107
|
+
originalOnReadyStateChange.call(xhr);
|
|
108
|
+
}
|
|
121
109
|
}
|
|
122
110
|
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
self.logger.debug('Erro ao simular resposta mockada, fallback para servidor real:', error);
|
|
113
|
+
self.originalSend.apply(xhr, [body]);
|
|
114
|
+
}
|
|
123
115
|
}, delay);
|
|
124
|
-
// NÃO chamar send original para requisições mockadas
|
|
125
116
|
return;
|
|
126
117
|
}
|
|
127
|
-
// Sem mock - fazer request real
|
|
118
|
+
// Sem mock - fazer request real
|
|
128
119
|
xhr.onreadystatechange = function (event) {
|
|
129
120
|
if (xhr.readyState === 4) {
|
|
130
|
-
// Requisição completou
|
|
131
121
|
requestMetadata.status = xhr.status;
|
|
132
|
-
// Tentar extrair response
|
|
133
122
|
try {
|
|
134
123
|
if (xhr.responseType === '' || xhr.responseType === 'text') {
|
|
135
124
|
if (xhr.responseText) {
|
|
@@ -159,51 +148,12 @@ class XMLHttpRequestInterceptor {
|
|
|
159
148
|
requestMetadata.duration = duration;
|
|
160
149
|
self.requestLogger.logComplete(requestMetadata).catch(() => { });
|
|
161
150
|
}
|
|
162
|
-
// Chamar handler original
|
|
163
151
|
if (originalOnReadyStateChange) {
|
|
164
152
|
originalOnReadyStateChange.call(this, event);
|
|
165
153
|
}
|
|
166
154
|
};
|
|
167
|
-
// Chamar send original
|
|
168
155
|
self.originalSend.apply(xhr, [body]);
|
|
169
156
|
}).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
157
|
self.originalSend.apply(xhr, [body]);
|
|
208
158
|
});
|
|
209
159
|
};
|