@fluwa-tool/sdk 1.0.1 → 1.0.27

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.
@@ -21,6 +21,7 @@ export declare class FetchInterceptor implements IFetchInterceptor {
21
21
  private appName;
22
22
  private originalFetch;
23
23
  private isInstalled;
24
+ private isIntercepting;
24
25
  constructor(logger: ILogger, requestLogger: IRequestLogger, mockResolver: IMockResolver, sessionId: string, appName: string);
25
26
  /**
26
27
  * Instalar o interceptador
@@ -48,4 +49,9 @@ export declare class FetchInterceptor implements IFetchInterceptor {
48
49
  * Sleep (para delays de mock)
49
50
  */
50
51
  private delay;
52
+ /**
53
+ * Verificar se requisição é interna do Fluwa
54
+ * Suporta headers como plain object ou Headers instance
55
+ */
56
+ private isFluwaInternalRequest;
51
57
  }
@@ -19,6 +19,7 @@ class FetchInterceptor {
19
19
  this.appName = appName;
20
20
  this.originalFetch = null;
21
21
  this.isInstalled = false;
22
+ this.isIntercepting = false; // Flag para prevenir re-intercepção
22
23
  }
23
24
  /**
24
25
  * Instalar o interceptador
@@ -64,13 +65,14 @@ class FetchInterceptor {
64
65
  return async (...args) => {
65
66
  const startTime = performance.now();
66
67
  const [resource, init] = args;
68
+ // Evitar re-intercepção: se já estamos interceptando, usar fetch original
69
+ if (this.isIntercepting) {
70
+ return this.originalFetch.apply(globalThis, args);
71
+ }
67
72
  // Ignorar requisições internas do Fluwa (header X-Fluwa-Internal)
68
- if (init?.headers && typeof init.headers === 'object') {
69
- const headers = init.headers;
70
- if (headers['X-Fluwa-Internal'] === 'true') {
71
- // Usar fetch original para requisições internas
72
- return this.originalFetch.apply(globalThis, args);
73
- }
73
+ if (this.isFluwaInternalRequest(init)) {
74
+ // Usar fetch original para requisições internas
75
+ return this.originalFetch.apply(globalThis, args);
74
76
  }
75
77
  // Extrair informações da requisição
76
78
  const method = (init?.method || 'GET').toUpperCase();
@@ -87,6 +89,8 @@ class FetchInterceptor {
87
89
  appName: this.appName,
88
90
  source: types_1.RequestSource.REAL, // Default, pode mudar se usar mock
89
91
  };
92
+ // Marcar que estamos interceptando para evitar re-intercepção
93
+ this.isIntercepting = true;
90
94
  try {
91
95
  // Registrar que começou
92
96
  await this.requestLogger.logStart(requestMetadata);
@@ -140,6 +144,10 @@ class FetchInterceptor {
140
144
  await this.requestLogger.logComplete(requestMetadata);
141
145
  throw error;
142
146
  }
147
+ finally {
148
+ // Sempre restaurar a flag
149
+ this.isIntercepting = false;
150
+ }
143
151
  };
144
152
  }
145
153
  /**
@@ -168,5 +176,24 @@ class FetchInterceptor {
168
176
  delay(ms) {
169
177
  return new Promise((resolve) => setTimeout(resolve, ms));
170
178
  }
179
+ /**
180
+ * Verificar se requisição é interna do Fluwa
181
+ * Suporta headers como plain object ou Headers instance
182
+ */
183
+ isFluwaInternalRequest(init) {
184
+ if (!init || !init.headers) {
185
+ return false;
186
+ }
187
+ const headers = init.headers;
188
+ // Verificar se é plain object
189
+ if (typeof headers === 'object' && headers.constructor === Object) {
190
+ return headers['X-Fluwa-Internal'] === 'true';
191
+ }
192
+ // Verificar se é Headers instance
193
+ if (headers instanceof Headers || (typeof headers?.get === 'function')) {
194
+ return headers.get('X-Fluwa-Internal') === 'true';
195
+ }
196
+ return false;
197
+ }
171
198
  }
172
199
  exports.FetchInterceptor = FetchInterceptor;
@@ -19,6 +19,7 @@ export declare class XMLHttpRequestInterceptor implements IXMLHttpRequestInterce
19
19
  private originalSend;
20
20
  private originalSetRequestHeader;
21
21
  private isInstalled;
22
+ private isIntercepting;
22
23
  constructor(logger: ILogger, requestLogger: IRequestLogger, mockResolver: IMockResolver, sessionId: string, appName: string);
23
24
  install(): void;
24
25
  uninstall(): void;
@@ -14,6 +14,7 @@ class XMLHttpRequestInterceptor {
14
14
  this.sessionId = sessionId;
15
15
  this.appName = appName;
16
16
  this.isInstalled = false;
17
+ this.isIntercepting = false; // Flag para prevenir re-intercepção
17
18
  }
18
19
  install() {
19
20
  if (this.isInstalled) {
@@ -54,6 +55,10 @@ class XMLHttpRequestInterceptor {
54
55
  this.originalSend = originalXHR.send;
55
56
  originalXHR.send = function (body) {
56
57
  const xhr = this;
58
+ // Evitar re-intercepção: se já estamos interceptando, usar send original
59
+ if (self.isIntercepting) {
60
+ return self.originalSend.apply(this, [body]);
61
+ }
57
62
  const method = (xhr._fluwaMethod || 'GET');
58
63
  const url = xhr._fluwaUrl;
59
64
  const requestId = xhr._fluwaRequestId;
@@ -69,6 +74,8 @@ class XMLHttpRequestInterceptor {
69
74
  appName: self.appName,
70
75
  source: types_1.RequestSource.REAL,
71
76
  };
77
+ // Marcar que estamos interceptando para evitar re-intercepção
78
+ self.isIntercepting = true;
72
79
  // Verificar se há mock
73
80
  self.mockResolver.resolve(method, url)
74
81
  .then((mockResponse) => {
@@ -110,6 +117,8 @@ class XMLHttpRequestInterceptor {
110
117
  const duration = Date.now() - (xhr._fluwaStartTime || 0);
111
118
  requestMetadata.duration = duration;
112
119
  self.requestLogger.logComplete(requestMetadata).catch(() => { });
120
+ // Restaurar a flag quando requisição completar
121
+ self.isIntercepting = false;
113
122
  }
114
123
  // Chamar handler original
115
124
  if (originalOnReadyStateChange) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluwa-tool/sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.27",
4
4
  "description": "Fluwa DevTools SDK for network interception and mocking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",