@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
- * Intercepta requisições axios, jQuery, XMLHttpRequest nativo
3
+ * Usa fetch interno quando 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
- * Intercepta requisições axios, jQuery, XMLHttpRequest nativo
4
+ * Usa fetch interno quando 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; // URL filter para evitar loops infinitos
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} (bypass filtering)`);
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
- // Tentar encontrar mock (com pequeno delay para WebSocket carregar)
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, 150));
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
- // Mock encontrado - fazer fetch interno para obter a resposta
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
- // Simular que a resposta chegou (chamar onreadystatechange)
108
- if (originalOnReadyStateChange) {
109
- try {
110
- // Injetar dados da resposta no xhr
111
- xhr._fluwaStatus = mockResponse.status || 200;
112
- xhr._fluwaResponse = mockResponse.response;
113
- xhr._fluwaResponseText = JSON.stringify(mockResponse.response);
114
- // Chamar handler como se a requisição tivesse completado
115
- originalOnReadyStateChange.call(xhr);
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
- catch (error) {
118
- self.logger.debug('Erro ao simular resposta mockada:', error);
119
- // Se der erro, deixar passar para o servidor real
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 normalmente
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluwa-tool/sdk",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "description": "Fluwa DevTools SDK for network interception and mocking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",