@fluwa-tool/sdk 1.0.50 → 1.0.52
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.
|
@@ -82,7 +82,7 @@ class XMLHttpRequestInterceptor {
|
|
|
82
82
|
};
|
|
83
83
|
checkMockWithRetry().then(mockResponse => {
|
|
84
84
|
if (mockResponse) {
|
|
85
|
-
// Mock encontrado -
|
|
85
|
+
// Mock encontrado - usar proxy do Fluwa Server
|
|
86
86
|
self.logger.debug(`🎯 [XMLHttpRequestInterceptor] Mock encontrado para ${method} ${url}`, {
|
|
87
87
|
status: mockResponse.status,
|
|
88
88
|
hasResponse: !!mockResponse.response,
|
|
@@ -90,143 +90,41 @@ class XMLHttpRequestInterceptor {
|
|
|
90
90
|
requestMetadata.source = types_1.RequestSource.MOCK;
|
|
91
91
|
requestMetadata.status = mockResponse.status || 200;
|
|
92
92
|
requestMetadata.response = mockResponse.response;
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Simular readyState progression usando defineProperty (Hermes engine compat)
|
|
105
|
-
const setReadyState = (state) => {
|
|
106
|
-
try {
|
|
107
|
-
Object.defineProperty(xhr, 'readyState', {
|
|
108
|
-
value: state,
|
|
109
|
-
writable: true,
|
|
110
|
-
configurable: true,
|
|
111
|
-
});
|
|
112
|
-
self.logger.debug(`📊 [XMLHttpRequestInterceptor] readyState = ${state}`);
|
|
113
|
-
}
|
|
114
|
-
catch (e) {
|
|
115
|
-
// Fallback: try direct assignment se defineProperty falhar
|
|
116
|
-
xhr.readyState = state;
|
|
117
|
-
self.logger.debug(`📊 [XMLHttpRequestInterceptor] readyState = ${state} (fallback)`);
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
// Primeiro: configurar todas as propriedades de resposta ANTES de começar readyState
|
|
121
|
-
self.logger.debug(`🔧 [XMLHttpRequestInterceptor] Configurando propriedades de resposta`);
|
|
122
|
-
try {
|
|
123
|
-
// Override status (read-only property in Hermes)
|
|
124
|
-
try {
|
|
125
|
-
Object.defineProperty(xhr, 'status', {
|
|
126
|
-
value: mockResponse.status || 200,
|
|
127
|
-
writable: true,
|
|
128
|
-
configurable: true,
|
|
129
|
-
});
|
|
130
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] status = ${mockResponse.status || 200}`);
|
|
131
|
-
}
|
|
132
|
-
catch (statusErr) {
|
|
133
|
-
self.logger.debug(`⚠️ [XMLHttpRequestInterceptor] Não foi possível setar status:`, statusErr);
|
|
134
|
-
}
|
|
135
|
-
// Override responseText (read-only property in Hermes)
|
|
136
|
-
try {
|
|
137
|
-
Object.defineProperty(xhr, 'responseText', {
|
|
138
|
-
value: JSON.stringify(mockResponse.response),
|
|
139
|
-
writable: true,
|
|
140
|
-
configurable: true,
|
|
141
|
-
});
|
|
142
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] responseText configurado`);
|
|
143
|
-
}
|
|
144
|
-
catch (textErr) {
|
|
145
|
-
self.logger.debug(`⚠️ [XMLHttpRequestInterceptor] Não foi possível setar responseText:`, textErr);
|
|
146
|
-
}
|
|
147
|
-
// Override response (read-only property in Hermes)
|
|
148
|
-
try {
|
|
149
|
-
Object.defineProperty(xhr, 'response', {
|
|
150
|
-
value: mockResponse.response,
|
|
151
|
-
writable: true,
|
|
152
|
-
configurable: true,
|
|
153
|
-
});
|
|
154
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] response configurado`);
|
|
155
|
-
}
|
|
156
|
-
catch (respErr) {
|
|
157
|
-
self.logger.debug(`⚠️ [XMLHttpRequestInterceptor] Não foi possível setar response:`, respErr);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (e) {
|
|
161
|
-
self.logger.debug('❌ Erro ao injetar propriedades mock:', e);
|
|
162
|
-
}
|
|
163
|
-
// Simular readyState progression - apenas chamar callbacks diretos
|
|
164
|
-
// (dispatchEvent pode não funcionar em React Native)
|
|
165
|
-
const fireCallback = (state, delayMs) => {
|
|
166
|
-
setTimeout(() => {
|
|
167
|
-
setReadyState(state);
|
|
168
|
-
self.logger.debug(`📞 [XMLHttpRequestInterceptor] readyState=${state} - Tentando chamar onreadystatechange`);
|
|
169
|
-
if (xhr.onreadystatechange && typeof xhr.onreadystatechange === 'function') {
|
|
170
|
-
try {
|
|
171
|
-
xhr.onreadystatechange();
|
|
172
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] onreadystatechange chamado com sucesso`);
|
|
173
|
-
}
|
|
174
|
-
catch (e) {
|
|
175
|
-
self.logger.debug(`❌ Erro ao chamar onreadystatechange(${state}):`, e);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
self.logger.debug(`⚠️ [XMLHttpRequestInterceptor] onreadystatechange não é função:`, typeof xhr.onreadystatechange);
|
|
180
|
-
}
|
|
181
|
-
}, delayMs);
|
|
182
|
-
};
|
|
183
|
-
// Disparar callbacks para cada readyState
|
|
184
|
-
fireCallback(1, 50); // readyState = 1 em 50ms
|
|
185
|
-
fireCallback(2, 100); // readyState = 2 em 100ms
|
|
186
|
-
fireCallback(3, 150); // readyState = 3 em 150ms
|
|
187
|
-
// Final: readyState = 4 com callbacks
|
|
188
|
-
setTimeout(() => {
|
|
189
|
-
setReadyState(4);
|
|
190
|
-
self.logger.debug(`📞 [XMLHttpRequestInterceptor] readyState=4 - Tentando chamar onreadystatechange`);
|
|
191
|
-
// Chamar onreadystatechange
|
|
192
|
-
if (xhr.onreadystatechange && typeof xhr.onreadystatechange === 'function') {
|
|
193
|
-
try {
|
|
194
|
-
xhr.onreadystatechange();
|
|
195
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] onreadystatechange(4) chamado com sucesso`);
|
|
196
|
-
}
|
|
197
|
-
catch (e) {
|
|
198
|
-
self.logger.debug(`❌ Erro ao chamar onreadystatechange(4):`, e);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
self.logger.debug(`⚠️ [XMLHttpRequestInterceptor] onreadystatechange não é função em readyState=4`);
|
|
203
|
-
}
|
|
204
|
-
// Chamar onload
|
|
205
|
-
self.logger.debug(`📞 [XMLHttpRequestInterceptor] Tentando chamar onload`);
|
|
206
|
-
if (xhr.onload && typeof xhr.onload === 'function') {
|
|
207
|
-
try {
|
|
208
|
-
xhr.onload();
|
|
209
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] onload chamado com sucesso`);
|
|
210
|
-
}
|
|
211
|
-
catch (e) {
|
|
212
|
-
self.logger.debug(`❌ Erro ao chamar onload:`, e);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
self.logger.debug(`⚠️ [XMLHttpRequestInterceptor] onload não é função`);
|
|
217
|
-
}
|
|
218
|
-
self.logger.debug(`✅ [XMLHttpRequestInterceptor] Simulação de resposta COMPLETA`);
|
|
219
|
-
}, 200);
|
|
220
|
-
};
|
|
221
|
-
// Executar após o delay do mock
|
|
222
|
-
if (delay > 0) {
|
|
223
|
-
setTimeout(executeSimulation, delay);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
executeSimulation();
|
|
227
|
-
}
|
|
228
|
-
}, 50); // 50ms para axios anexar handlers
|
|
93
|
+
// ✅ NOVA ABORDAGEM: Redirecionar para endpoint do Fluwa que retorna o mock
|
|
94
|
+
// Em vez de tentar simular a resposta XHR, fazemos uma requisição REAL para o Fluwa Server
|
|
95
|
+
const mockProxyUrl = `http://192.168.0.6:5555/api/mock-proxy`;
|
|
96
|
+
self.logger.debug(`🔀 [XMLHttpRequestInterceptor] Redirecionando para proxy do Fluwa: ${mockProxyUrl}`);
|
|
97
|
+
// Modifi car URL e corpo para chamar o endpoint proxy
|
|
98
|
+
const mockRequestBody = JSON.stringify({
|
|
99
|
+
originalMethod: method,
|
|
100
|
+
originalUrl: url,
|
|
101
|
+
mockStatus: mockResponse.status || 200,
|
|
102
|
+
mockResponse: mockResponse.response,
|
|
103
|
+
mockDelay: mockResponse.delay || 0,
|
|
229
104
|
});
|
|
105
|
+
// Chamar originalSend com URL do proxy
|
|
106
|
+
// Isso faz axios fazer uma requisição REAL para o Fluwa Server
|
|
107
|
+
// que retorna o mock como resposta HTTP normal
|
|
108
|
+
try {
|
|
109
|
+
// Restaurar para o método proxy (POST para o endpoint /api/mock-proxy)
|
|
110
|
+
self.originalOpen.call(xhr, 'POST', mockProxyUrl, true);
|
|
111
|
+
// Copiar headers originais
|
|
112
|
+
Object.keys(headers).forEach(header => {
|
|
113
|
+
self.originalSetRequestHeader.call(xhr, header, headers[header]);
|
|
114
|
+
});
|
|
115
|
+
// Adicionar header especial para o Fluwa Server saber que é um mock proxy
|
|
116
|
+
self.originalSetRequestHeader.call(xhr, 'X-Fluwa-Mock-Proxy', 'true');
|
|
117
|
+
const duration = Date.now() - (xhr._fluwaStartTime || 0);
|
|
118
|
+
requestMetadata.duration = duration;
|
|
119
|
+
self.requestLogger.logComplete(requestMetadata).catch(() => { });
|
|
120
|
+
self.logger.debug(`✅ [XMLHttpRequestInterceptor] Enviando mock via proxy do Fluwa`);
|
|
121
|
+
self.originalSend.call(xhr, mockRequestBody);
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
self.logger.debug(`❌ [XMLHttpRequestInterceptor] Erro ao chamar proxy:`, e);
|
|
125
|
+
// Fallback: tentar fazer requisição real
|
|
126
|
+
self.originalSend.apply(xhr, [body]);
|
|
127
|
+
}
|
|
230
128
|
return;
|
|
231
129
|
}
|
|
232
130
|
// Sem mock - fazer request real
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,47 @@ let xmlHttpRequestInterceptor;
|
|
|
52
52
|
let mockResolver;
|
|
53
53
|
let urlFilter = null; // URL filter para evitar loops infinitos
|
|
54
54
|
// ============================================
|
|
55
|
+
// CONFIGURAÇÃO DE AXIOS
|
|
56
|
+
// ============================================
|
|
57
|
+
/**
|
|
58
|
+
* Forçar axios a usar fetch em vez de XMLHttpRequest
|
|
59
|
+
* Permite que FetchInterceptor mocke requisições de axios
|
|
60
|
+
*/
|
|
61
|
+
function configureAxiosToUseFetch(logger) {
|
|
62
|
+
try {
|
|
63
|
+
// Verificar se axios está disponível globalmente
|
|
64
|
+
const globalObj = typeof window !== 'undefined' ? window : globalThis;
|
|
65
|
+
const axios = globalObj.axios;
|
|
66
|
+
if (!axios) {
|
|
67
|
+
logger.debug('axios não encontrado globalmente - vai ser necessário importar manualmente');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Configurar axios para usar fetch adapter
|
|
71
|
+
// Isso faz com que axios use fetch internamente, que é interceptado por FetchInterceptor
|
|
72
|
+
axios.defaults.adapter = async (config) => {
|
|
73
|
+
logger.debug(`📡 [axios -> fetch] Usando fetch para: ${config.method?.toUpperCase()} ${config.url}`);
|
|
74
|
+
const fetchConfig = {
|
|
75
|
+
method: config.method?.toUpperCase() || 'GET',
|
|
76
|
+
headers: config.headers || {},
|
|
77
|
+
body: config.data,
|
|
78
|
+
};
|
|
79
|
+
const response = await fetch(config.url, fetchConfig);
|
|
80
|
+
return {
|
|
81
|
+
data: await response.json(),
|
|
82
|
+
status: response.status,
|
|
83
|
+
statusText: response.statusText,
|
|
84
|
+
headers: response.headers,
|
|
85
|
+
config,
|
|
86
|
+
request: {},
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
logger.success('✅ axios configurado para usar fetch (FetchInterceptor ativo)');
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.debug('Erro ao configurar axios para fetch:', error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ============================================
|
|
55
96
|
// INICIALIZAÇÃO
|
|
56
97
|
// ============================================
|
|
57
98
|
/**
|
|
@@ -91,11 +132,12 @@ async function initFluwaTool(partialConfig = {}) {
|
|
|
91
132
|
logger.debug(`URL Filter configurado com ${urlFilter.getExcludedPatterns().length} padrões excluídos`);
|
|
92
133
|
// 7. Criar interceptador de fetch
|
|
93
134
|
fetchInterceptor = new FetchInterceptor_1.FetchInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName(), urlFilter);
|
|
94
|
-
// 7b. Criar interceptador de XMLHttpRequest (
|
|
135
|
+
// 7b. Criar interceptador de XMLHttpRequest (DESABILITADO)
|
|
136
|
+
// axios agora usa fetch via configureAxiosToUseFetch(), então não precisa mais de XHR
|
|
95
137
|
xmlHttpRequestInterceptor = new XMLHttpRequestInterceptor_1.XMLHttpRequestInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName(), urlFilter);
|
|
96
138
|
// 8. Instalar interceptadores
|
|
97
139
|
fetchInterceptor.install();
|
|
98
|
-
xmlHttpRequestInterceptor.install();
|
|
140
|
+
// xmlHttpRequestInterceptor.install(); // ❌ Desabilitado - axios agora usa fetch
|
|
99
141
|
// 9. Conectar WebSocket
|
|
100
142
|
logger.debug('Conectando ao WebSocket...');
|
|
101
143
|
try {
|
|
@@ -113,6 +155,9 @@ async function initFluwaTool(partialConfig = {}) {
|
|
|
113
155
|
});
|
|
114
156
|
isInitialized = true;
|
|
115
157
|
logger.success('Fluwa-Tool inicializado com sucesso!');
|
|
158
|
+
// ✅ FORÇA AXIOS USAR FETCH EM VEZ DE XMLHttpRequest
|
|
159
|
+
// Isso permite que FetchInterceptor mocke requisições de axios
|
|
160
|
+
configureAxiosToUseFetch(logger);
|
|
116
161
|
}
|
|
117
162
|
catch (error) {
|
|
118
163
|
logger.error('Erro ao inicializar Fluwa', error);
|