@fluwa-tool/sdk 1.0.31 → 1.0.32

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.
@@ -5,6 +5,7 @@
5
5
  import { ILogger } from '../../core/Logger';
6
6
  import { IRequestLogger } from './RequestLogger';
7
7
  import { IMockResolver } from './MockResolver';
8
+ import { IUrlFilter } from './UrlFilter';
8
9
  export interface IFetchInterceptor {
9
10
  install(): void;
10
11
  uninstall(): void;
@@ -22,7 +23,8 @@ export declare class FetchInterceptor implements IFetchInterceptor {
22
23
  private originalFetch;
23
24
  private isInstalled;
24
25
  private isIntercepting;
25
- constructor(logger: ILogger, requestLogger: IRequestLogger, mockResolver: IMockResolver, sessionId: string, appName: string);
26
+ private urlFilter;
27
+ constructor(logger: ILogger, requestLogger: IRequestLogger, mockResolver: IMockResolver, sessionId: string, appName: string, urlFilter?: IUrlFilter);
26
28
  /**
27
29
  * Instalar o interceptador
28
30
  * Substitui fetch global
@@ -11,7 +11,7 @@ const types_1 = require("../../types");
11
11
  * Preserva fetch original e sobrescreve com versão interceptada
12
12
  */
13
13
  class FetchInterceptor {
14
- constructor(logger, requestLogger, mockResolver, sessionId, appName) {
14
+ constructor(logger, requestLogger, mockResolver, sessionId, appName, urlFilter) {
15
15
  this.logger = logger;
16
16
  this.requestLogger = requestLogger;
17
17
  this.mockResolver = mockResolver;
@@ -20,6 +20,8 @@ class FetchInterceptor {
20
20
  this.originalFetch = null;
21
21
  this.isInstalled = false;
22
22
  this.isIntercepting = false; // Flag para prevenir re-intercepção
23
+ this.urlFilter = null; // URL filter para evitar loops infinitos
24
+ this.urlFilter = urlFilter || null;
23
25
  }
24
26
  /**
25
27
  * Instalar o interceptador
@@ -65,18 +67,25 @@ class FetchInterceptor {
65
67
  return async (...args) => {
66
68
  const startTime = performance.now();
67
69
  const [resource, init] = args;
70
+ // Extrair URL da requisição (necessário para o filter)
71
+ const url = typeof resource === 'string' ? resource : (resource instanceof Request ? resource.url : resource.toString());
68
72
  // Evitar re-intercepção: se já estamos interceptando, usar fetch original
69
73
  if (this.isIntercepting) {
70
74
  return this.originalFetch.apply(globalThis, args);
71
75
  }
72
- // Ignorar requisições internas do Fluwa (header X-Fluwa-Internal)
76
+ // Verificar URL Filter: ignorar requisições para servidor Fluwa ou URLs excluídas
77
+ // Isso previne loops infinitos onde o servidor Fluwa faz requisições que são interceptadas
78
+ if (this.urlFilter && !this.urlFilter.shouldIntercept(url)) {
79
+ this.logger.debug(`🔧 [FetchInterceptor] Ignorando URL excluída: ${url} (bypass filtering)`);
80
+ return this.originalFetch.apply(globalThis, args);
81
+ }
82
+ // Ignorar requisições internas do Fluwa (header X-Fluwa-Internal - legacy support)
73
83
  if (this.isFluwaInternalRequest(init)) {
74
84
  // Usar fetch original para requisições internas
75
85
  return this.originalFetch.apply(globalThis, args);
76
86
  }
77
87
  // Extrair informações da requisição
78
88
  const method = (init?.method || 'GET').toUpperCase();
79
- const url = typeof resource === 'string' ? resource : (resource instanceof Request ? resource.url : resource.toString());
80
89
  const requestId = this.generateId();
81
90
  const requestMetadata = {
82
91
  id: requestId,
@@ -0,0 +1,134 @@
1
+ /**
2
+ * 🔧 URL Filter System for Fluwa SDK
3
+ *
4
+ * Provides a robust filtering mechanism to prevent intercepting internal Fluwa server
5
+ * requests, avoiding infinite request loops and ensuring proper request tracking.
6
+ *
7
+ * Problem: Fluwa SDK intercepts ALL HTTP requests, including those made by Fluwa Server
8
+ * itself to the Fluwa server (POST /api/requests, GET /api/scenarios/active).
9
+ * This creates infinite loops where internal requests are tracked and re-triggered.
10
+ *
11
+ * Solution: Filter URLs BEFORE they reach the Fluwa interceptors (fetch, XHR).
12
+ * Only requests NOT in the exclusion list will be tracked by Fluwa.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const filter = createUrlFilter({
17
+ * serverUrl: 'http://192.168.0.6:5555',
18
+ * excludedUrls: ['/api/requests', '/api/scenarios'],
19
+ * mode: 'startsWith',
20
+ * debug: true
21
+ * });
22
+ *
23
+ * // Check if URL should be intercepted
24
+ * const shouldIntercept = filter.shouldIntercept('https://api.example.com/users');
25
+ * ```
26
+ */
27
+ /**
28
+ * Configuration object for URL filtering
29
+ */
30
+ export interface UrlFilterConfig {
31
+ /** Base URL of the Fluwa server (e.g., 'http://192.168.0.6:5555') */
32
+ serverUrl: string;
33
+ /** Additional URLs to exclude from interception (optional) */
34
+ excludedUrls?: string[];
35
+ /** Matching strategy for URL comparison */
36
+ mode?: 'startsWith' | 'exact' | 'regex';
37
+ /** Enable debug logging for filter decisions */
38
+ debug?: boolean;
39
+ }
40
+ /**
41
+ * Result of a URL filtering check
42
+ */
43
+ export interface FilterCheckResult {
44
+ /** Whether the URL should be intercepted by Fluwa */
45
+ shouldIntercept: boolean;
46
+ /** Reason why the URL was filtered (for debugging) */
47
+ reason?: string;
48
+ /** Which rule matched this URL (for debugging) */
49
+ matchedRule?: string;
50
+ }
51
+ /**
52
+ * URL Filter interface with filtering methods
53
+ */
54
+ export interface IUrlFilter {
55
+ /**
56
+ * Check if a URL should be intercepted by Fluwa
57
+ * @param url - Full URL or path to check
58
+ * @returns Whether the URL should be intercepted
59
+ */
60
+ shouldIntercept(url: string): boolean;
61
+ /**
62
+ * Get detailed information about why a URL was filtered
63
+ * @param url - Full URL or path to check
64
+ * @returns Detailed filter result with reasoning
65
+ */
66
+ checkUrl(url: string): FilterCheckResult;
67
+ /**
68
+ * Get the list of all excluded URL patterns
69
+ * @returns Array of excluded patterns
70
+ */
71
+ getExcludedPatterns(): string[];
72
+ }
73
+ /**
74
+ * UrlFilter implementation
75
+ * Encapsulates URL filtering logic with support for multiple matching strategies
76
+ */
77
+ export declare class UrlFilter implements IUrlFilter {
78
+ private normalizedServerUrl;
79
+ private normalizedExcludedUrls;
80
+ private matchMode;
81
+ private debug;
82
+ constructor(config: UrlFilterConfig);
83
+ /**
84
+ * Normalize URLs for consistent comparison
85
+ * - Remove trailing slashes
86
+ * - Handle both full URLs and paths
87
+ */
88
+ private normalizeUrl;
89
+ /**
90
+ * Check if URL matches using the configured matching mode
91
+ */
92
+ private matchesPattern;
93
+ /**
94
+ * Detailed URL check with reasoning
95
+ * Returns why a URL was filtered or allowed
96
+ */
97
+ checkUrl(url: string): FilterCheckResult;
98
+ /**
99
+ * Simple yes/no check for URL interception
100
+ * Useful for early filtering before deeper processing
101
+ */
102
+ shouldIntercept(url: string): boolean;
103
+ /**
104
+ * Get all excluded patterns for debugging and introspection
105
+ */
106
+ getExcludedPatterns(): string[];
107
+ }
108
+ /**
109
+ * Standard exclusion patterns for internal Fluwa server requests
110
+ * These are the known endpoints that should NOT be tracked by Fluwa SDK
111
+ */
112
+ export declare const FLUWA_INTERNAL_PATHS: string[];
113
+ /**
114
+ * Factory function to create a pre-configured filter for Fluwa SDK
115
+ * Automatically excludes known internal server paths
116
+ *
117
+ * @param serverUrl - Base URL of the Fluwa server
118
+ * @param additionalExclusions - Extra URLs to exclude (optional)
119
+ * @param debug - Enable debug logging
120
+ * @returns Configured UrlFilter instance
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const filter = createFluwaSdkFilter('http://192.168.0.6:5555', [
125
+ * '/custom-internal-endpoint'
126
+ * ]);
127
+ *
128
+ * // Check if request should bypass Fluwa interception
129
+ * if (!filter.shouldIntercept(requestUrl)) {
130
+ * // Make request without Fluwa tracking
131
+ * }
132
+ * ```
133
+ */
134
+ export declare function createFluwaSdkFilter(serverUrl: string, additionalExclusions?: string[], debug?: boolean): IUrlFilter;
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ /**
3
+ * 🔧 URL Filter System for Fluwa SDK
4
+ *
5
+ * Provides a robust filtering mechanism to prevent intercepting internal Fluwa server
6
+ * requests, avoiding infinite request loops and ensuring proper request tracking.
7
+ *
8
+ * Problem: Fluwa SDK intercepts ALL HTTP requests, including those made by Fluwa Server
9
+ * itself to the Fluwa server (POST /api/requests, GET /api/scenarios/active).
10
+ * This creates infinite loops where internal requests are tracked and re-triggered.
11
+ *
12
+ * Solution: Filter URLs BEFORE they reach the Fluwa interceptors (fetch, XHR).
13
+ * Only requests NOT in the exclusion list will be tracked by Fluwa.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const filter = createUrlFilter({
18
+ * serverUrl: 'http://192.168.0.6:5555',
19
+ * excludedUrls: ['/api/requests', '/api/scenarios'],
20
+ * mode: 'startsWith',
21
+ * debug: true
22
+ * });
23
+ *
24
+ * // Check if URL should be intercepted
25
+ * const shouldIntercept = filter.shouldIntercept('https://api.example.com/users');
26
+ * ```
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.FLUWA_INTERNAL_PATHS = exports.UrlFilter = void 0;
30
+ exports.createFluwaSdkFilter = createFluwaSdkFilter;
31
+ /**
32
+ * UrlFilter implementation
33
+ * Encapsulates URL filtering logic with support for multiple matching strategies
34
+ */
35
+ class UrlFilter {
36
+ constructor(config) {
37
+ const { serverUrl, excludedUrls = [], mode = 'startsWith', debug = false } = config;
38
+ this.normalizedServerUrl = this.normalizeUrl(serverUrl);
39
+ this.normalizedExcludedUrls = excludedUrls.map((url) => this.normalizeUrl(url));
40
+ this.matchMode = mode;
41
+ this.debug = debug;
42
+ }
43
+ /**
44
+ * Normalize URLs for consistent comparison
45
+ * - Remove trailing slashes
46
+ * - Handle both full URLs and paths
47
+ */
48
+ normalizeUrl(url) {
49
+ try {
50
+ // Handle full URLs
51
+ if (url.startsWith('http://') || url.startsWith('https://')) {
52
+ return url.replace(/\/$/, '');
53
+ }
54
+ // Handle relative paths
55
+ return url.replace(/\/$/, '');
56
+ }
57
+ catch {
58
+ return url;
59
+ }
60
+ }
61
+ /**
62
+ * Check if URL matches using the configured matching mode
63
+ */
64
+ matchesPattern(url, pattern) {
65
+ const normalizedUrl = this.normalizeUrl(url);
66
+ switch (this.matchMode) {
67
+ case 'exact':
68
+ return normalizedUrl === pattern;
69
+ case 'regex': {
70
+ try {
71
+ const regex = new RegExp(pattern);
72
+ return regex.test(normalizedUrl);
73
+ }
74
+ catch (error) {
75
+ console.warn(`🔧 [UrlFilter] Invalid regex pattern: "${pattern}"`, error);
76
+ return false;
77
+ }
78
+ }
79
+ case 'startsWith':
80
+ default:
81
+ return normalizedUrl.startsWith(pattern);
82
+ }
83
+ }
84
+ /**
85
+ * Detailed URL check with reasoning
86
+ * Returns why a URL was filtered or allowed
87
+ */
88
+ checkUrl(url) {
89
+ const normalizedUrl = this.normalizeUrl(url);
90
+ // Check if URL is the Fluwa server itself
91
+ if (this.matchesPattern(normalizedUrl, this.normalizedServerUrl)) {
92
+ const result = {
93
+ shouldIntercept: false,
94
+ reason: 'URL is Fluwa server (internal request)',
95
+ matchedRule: 'serverUrl',
96
+ };
97
+ if (this.debug) {
98
+ console.log(`🔧 [UrlFilter] Excluded: ${url} - ${result.reason}`);
99
+ }
100
+ return result;
101
+ }
102
+ // Check against explicitly excluded URLs
103
+ for (const excludedUrl of this.normalizedExcludedUrls) {
104
+ if (this.matchesPattern(normalizedUrl, excludedUrl)) {
105
+ const result = {
106
+ shouldIntercept: false,
107
+ reason: `URL matches excluded pattern: "${excludedUrl}"`,
108
+ matchedRule: excludedUrl,
109
+ };
110
+ if (this.debug) {
111
+ console.log(`🔧 [UrlFilter] Excluded: ${url} - ${result.reason}`);
112
+ }
113
+ return result;
114
+ }
115
+ }
116
+ // URL should be intercepted by Fluwa
117
+ const result = {
118
+ shouldIntercept: true,
119
+ reason: 'URL should be tracked by Fluwa',
120
+ };
121
+ if (this.debug) {
122
+ console.log(`🔧 [UrlFilter] Intercepting: ${url}`);
123
+ }
124
+ return result;
125
+ }
126
+ /**
127
+ * Simple yes/no check for URL interception
128
+ * Useful for early filtering before deeper processing
129
+ */
130
+ shouldIntercept(url) {
131
+ return this.checkUrl(url).shouldIntercept;
132
+ }
133
+ /**
134
+ * Get all excluded patterns for debugging and introspection
135
+ */
136
+ getExcludedPatterns() {
137
+ return [this.normalizedServerUrl, ...this.normalizedExcludedUrls];
138
+ }
139
+ }
140
+ exports.UrlFilter = UrlFilter;
141
+ /**
142
+ * Standard exclusion patterns for internal Fluwa server requests
143
+ * These are the known endpoints that should NOT be tracked by Fluwa SDK
144
+ */
145
+ exports.FLUWA_INTERNAL_PATHS = [
146
+ '/api/requests', // Request registration endpoint
147
+ '/api/scenarios', // Scenario management
148
+ '/api/recordings', // Recording management
149
+ '/health', // Health check endpoint
150
+ ];
151
+ /**
152
+ * Factory function to create a pre-configured filter for Fluwa SDK
153
+ * Automatically excludes known internal server paths
154
+ *
155
+ * @param serverUrl - Base URL of the Fluwa server
156
+ * @param additionalExclusions - Extra URLs to exclude (optional)
157
+ * @param debug - Enable debug logging
158
+ * @returns Configured UrlFilter instance
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * const filter = createFluwaSdkFilter('http://192.168.0.6:5555', [
163
+ * '/custom-internal-endpoint'
164
+ * ]);
165
+ *
166
+ * // Check if request should bypass Fluwa interception
167
+ * if (!filter.shouldIntercept(requestUrl)) {
168
+ * // Make request without Fluwa tracking
169
+ * }
170
+ * ```
171
+ */
172
+ function createFluwaSdkFilter(serverUrl, additionalExclusions, debug) {
173
+ return new UrlFilter({
174
+ serverUrl,
175
+ excludedUrls: [...exports.FLUWA_INTERNAL_PATHS, ...(additionalExclusions || [])],
176
+ mode: 'startsWith',
177
+ debug,
178
+ });
179
+ }
@@ -5,6 +5,7 @@
5
5
  import { ILogger } from '../../core/Logger';
6
6
  import { IRequestLogger } from './RequestLogger';
7
7
  import { IMockResolver } from './MockResolver';
8
+ import { IUrlFilter } from './UrlFilter';
8
9
  export interface IXMLHttpRequestInterceptor {
9
10
  install(): void;
10
11
  uninstall(): void;
@@ -19,7 +20,8 @@ export declare class XMLHttpRequestInterceptor implements IXMLHttpRequestInterce
19
20
  private originalSend;
20
21
  private originalSetRequestHeader;
21
22
  private isInstalled;
22
- constructor(logger: ILogger, requestLogger: IRequestLogger, mockResolver: IMockResolver, sessionId: string, appName: string);
23
+ private urlFilter;
24
+ constructor(logger: ILogger, requestLogger: IRequestLogger, mockResolver: IMockResolver, sessionId: string, appName: string, urlFilter?: IUrlFilter);
23
25
  install(): void;
24
26
  uninstall(): void;
25
27
  private safeParseBody;
@@ -7,13 +7,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.XMLHttpRequestInterceptor = void 0;
8
8
  const types_1 = require("../../types");
9
9
  class XMLHttpRequestInterceptor {
10
- constructor(logger, requestLogger, mockResolver, sessionId, appName) {
10
+ constructor(logger, requestLogger, mockResolver, sessionId, appName, urlFilter) {
11
11
  this.logger = logger;
12
12
  this.requestLogger = requestLogger;
13
13
  this.mockResolver = mockResolver;
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
18
+ this.urlFilter = urlFilter || null;
17
19
  }
18
20
  install() {
19
21
  if (this.isInstalled) {
@@ -58,6 +60,12 @@ class XMLHttpRequestInterceptor {
58
60
  const url = xhr._fluwaUrl;
59
61
  const requestId = xhr._fluwaRequestId;
60
62
  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
+ if (self.urlFilter && !self.urlFilter.shouldIntercept(url)) {
66
+ self.logger.debug(`🔧 [XMLHttpRequestInterceptor] Ignorando URL excluída: ${url} (bypass filtering)`);
67
+ return self.originalSend.apply(this, [body]);
68
+ }
61
69
  const requestMetadata = {
62
70
  id: requestId,
63
71
  method,
package/dist/index.d.ts CHANGED
@@ -27,3 +27,4 @@ export declare function isFluwaTooIialized(): boolean;
27
27
  export * from './types';
28
28
  export { Logger, LogLevel } from './core/Logger';
29
29
  export { ConfigManager } from './core/Config';
30
+ export { UrlFilter, createFluwaSdkFilter, FLUWA_INTERNAL_PATHS, type UrlFilterConfig, type FilterCheckResult, type IUrlFilter, } from './features/network/UrlFilter';
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
22
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.ConfigManager = exports.LogLevel = exports.Logger = void 0;
25
+ exports.FLUWA_INTERNAL_PATHS = exports.createFluwaSdkFilter = exports.UrlFilter = exports.ConfigManager = exports.LogLevel = exports.Logger = void 0;
26
26
  exports.initFluwaTool = initFluwaTool;
27
27
  exports.disableFluwaTool = disableFluwaTool;
28
28
  exports.enableFluwaTool = enableFluwaTool;
@@ -36,6 +36,7 @@ const FetchInterceptor_1 = require("./features/network/FetchInterceptor");
36
36
  const XMLHttpRequestInterceptor_1 = require("./features/network/XMLHttpRequestInterceptor");
37
37
  const RequestLogger_1 = require("./features/network/RequestLogger");
38
38
  const MockResolver_1 = require("./features/network/MockResolver");
39
+ const UrlFilter_1 = require("./features/network/UrlFilter");
39
40
  const IdGenerator_1 = require("./core/IdGenerator");
40
41
  // ============================================
41
42
  // ESTADO GLOBAL
@@ -49,6 +50,7 @@ let wsClient;
49
50
  let fetchInterceptor;
50
51
  let xmlHttpRequestInterceptor;
51
52
  let mockResolver;
53
+ let urlFilter = null; // URL filter para evitar loops infinitos
52
54
  // ============================================
53
55
  // INICIALIZAÇÃO
54
56
  // ============================================
@@ -82,14 +84,19 @@ async function initFluwaTool(partialConfig = {}) {
82
84
  mockResolver = new MockResolver_1.MockResolver(httpClient, logger);
83
85
  // 5. Criar logger de requisições
84
86
  const requestLogger = new RequestLogger_1.RequestLogger(httpClient, logger);
85
- // 6. Criar interceptador de fetch
86
- fetchInterceptor = new FetchInterceptor_1.FetchInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName());
87
- // 6b. Criar interceptador de XMLHttpRequest (para axios, jQuery, etc)
88
- xmlHttpRequestInterceptor = new XMLHttpRequestInterceptor_1.XMLHttpRequestInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName());
89
- // 7. Instalar interceptadores
87
+ // 6. Criar URL Filter para evitar loops infinitos
88
+ // Automatically excludes Fluwa server URLs and internal endpoints
89
+ const { excludedUrls } = config.getConfig();
90
+ urlFilter = (0, UrlFilter_1.createFluwaSdkFilter)(serverUrl, excludedUrls, config.getConfig().debug);
91
+ logger.debug(`URL Filter configurado com ${urlFilter.getExcludedPatterns().length} padrões excluídos`);
92
+ // 7. Criar interceptador de fetch
93
+ fetchInterceptor = new FetchInterceptor_1.FetchInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName(), urlFilter);
94
+ // 7b. Criar interceptador de XMLHttpRequest (para axios, jQuery, etc)
95
+ xmlHttpRequestInterceptor = new XMLHttpRequestInterceptor_1.XMLHttpRequestInterceptor(logger, requestLogger, mockResolver, sessionId, config.getAppName(), urlFilter);
96
+ // 8. Instalar interceptadores
90
97
  fetchInterceptor.install();
91
98
  xmlHttpRequestInterceptor.install();
92
- // 8. Conectar WebSocket
99
+ // 9. Conectar WebSocket
93
100
  logger.debug('Conectando ao WebSocket...');
94
101
  try {
95
102
  await wsClient.connect();
@@ -98,7 +105,7 @@ async function initFluwaTool(partialConfig = {}) {
98
105
  catch (error) {
99
106
  logger.warn('Falha ao conectar WebSocket, continuando em modo offline', error);
100
107
  }
101
- // 9. Enviar init session
108
+ // 10. Enviar init session
102
109
  wsClient.send({
103
110
  type: types_1.WebSocketMessageType.INIT_SESSION,
104
111
  sessionId,
@@ -182,3 +189,7 @@ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () {
182
189
  Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return Logger_2.LogLevel; } });
183
190
  var Config_2 = require("./core/Config");
184
191
  Object.defineProperty(exports, "ConfigManager", { enumerable: true, get: function () { return Config_2.ConfigManager; } });
192
+ var UrlFilter_2 = require("./features/network/UrlFilter");
193
+ Object.defineProperty(exports, "UrlFilter", { enumerable: true, get: function () { return UrlFilter_2.UrlFilter; } });
194
+ Object.defineProperty(exports, "createFluwaSdkFilter", { enumerable: true, get: function () { return UrlFilter_2.createFluwaSdkFilter; } });
195
+ Object.defineProperty(exports, "FLUWA_INTERNAL_PATHS", { enumerable: true, get: function () { return UrlFilter_2.FLUWA_INTERNAL_PATHS; } });
@@ -13,6 +13,8 @@ export interface FluwaConfig {
13
13
  debug?: boolean;
14
14
  /** Timeout para requisições (ms) */
15
15
  requestTimeout?: number;
16
+ /** URLs adicionais para excluir da interception (evita loops infinitos) */
17
+ excludedUrls?: string[];
16
18
  }
17
19
  export declare enum HttpMethod {
18
20
  GET = "GET",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluwa-tool/sdk",
3
- "version": "1.0.31",
3
+ "version": "1.0.32",
4
4
  "description": "Fluwa DevTools SDK for network interception and mocking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",