@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; // 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,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
- // Tentar encontrar mock (com pequeno delay para WebSocket carregar)
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, 150));
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
- // Mock encontrado - fazer fetch interno para obter a resposta
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 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);
116
- }
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]);
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 normalmente
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
  };
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.41",
4
4
  "description": "Fluwa DevTools SDK for network interception and mocking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",