@zerosls/clm-sdk 1.1.7 → 1.1.9
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.
- package/dist/core/api-client.js +243 -36
- package/package.json +1 -1
- package/src/core/api-client.ts +219 -3
package/dist/core/api-client.js
CHANGED
|
@@ -6,7 +6,8 @@ export class ApiClient {
|
|
|
6
6
|
var _a, _b;
|
|
7
7
|
this.token = null;
|
|
8
8
|
this.baseUrl = config.baseUrl;
|
|
9
|
-
this.fallbackBaseUrl =
|
|
9
|
+
this.fallbackBaseUrl =
|
|
10
|
+
config.fallbackBaseUrl || "http://216.250.117.119/ZeroServicesQA/api/v1";
|
|
10
11
|
this.organization = config.organization;
|
|
11
12
|
this.token = config.token || null;
|
|
12
13
|
this.eventEmitter = eventEmitter;
|
|
@@ -56,32 +57,220 @@ export class ApiClient {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
/*private async request<T>(
|
|
61
|
+
method: string,
|
|
62
|
+
endpoint: string,
|
|
63
|
+
data?: any,
|
|
64
|
+
params?: Record<string, any>,
|
|
65
|
+
options: RequestOptions = {}
|
|
66
|
+
): Promise<T> {
|
|
67
|
+
// ✅ Primer intento con baseUrl normal
|
|
68
|
+
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
69
|
+
|
|
70
|
+
const base: HeadersInit = buildHeaders(this.token, {
|
|
71
|
+
"X-Organization": this.organization,
|
|
72
|
+
...(options.headers || {}),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const headers = new Headers(base);
|
|
76
|
+
|
|
77
|
+
// ✅ Obtener token legacy
|
|
78
|
+
const legacyToken =
|
|
79
|
+
(window as any).__LEGACY_TOKEN__ ||
|
|
80
|
+
sessionStorage.getItem("legacy_token") ||
|
|
81
|
+
null;
|
|
82
|
+
|
|
83
|
+
if (legacyToken) {
|
|
84
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
85
|
+
if (this.debug) {
|
|
86
|
+
console.log("🔐 Using legacy token for:", endpoint);
|
|
87
|
+
}
|
|
88
|
+
} else if (this.token) {
|
|
89
|
+
if (this.debug) {
|
|
90
|
+
console.log("🔐 Using v1 token for:", endpoint);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
97
|
+
if (useCache && method === "GET") {
|
|
98
|
+
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
99
|
+
const cachedData = this.cache.get<T>(cacheKey);
|
|
100
|
+
if (cachedData) {
|
|
101
|
+
if (this.debug) {
|
|
102
|
+
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
103
|
+
}
|
|
104
|
+
return cachedData;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.eventEmitter.emit("beforeRequest", {
|
|
109
|
+
url: primaryUrl,
|
|
110
|
+
method,
|
|
111
|
+
data,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const fetchOptions: RequestInit = {
|
|
116
|
+
method,
|
|
117
|
+
headers,
|
|
118
|
+
credentials: "include",
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (data && method !== "GET") {
|
|
122
|
+
fetchOptions.body = JSON.stringify(data);
|
|
123
|
+
if (this.debug) {
|
|
124
|
+
console.log(`📤 ${method} Body:`, data);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (this.debug) {
|
|
129
|
+
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ✅ Primer intento
|
|
133
|
+
const response = await fetch(primaryUrl, fetchOptions);
|
|
134
|
+
|
|
135
|
+
// ✅ Si es 404, intentar con fallback URL
|
|
136
|
+
if (response.status === 404) {
|
|
137
|
+
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
138
|
+
|
|
139
|
+
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
140
|
+
|
|
141
|
+
if (this.debug) {
|
|
142
|
+
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ✅ Segundo intento con fallback
|
|
146
|
+
const fallbackResponse = await fetch(fallbackUrl, fetchOptions);
|
|
147
|
+
|
|
148
|
+
if (!fallbackResponse.ok) {
|
|
149
|
+
let errorData;
|
|
150
|
+
try {
|
|
151
|
+
errorData = await fallbackResponse.json();
|
|
152
|
+
} catch {
|
|
153
|
+
errorData = { message: fallbackResponse.statusText };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
console.error(`❌ Fallback también falló ${fallbackResponse.status}:`, errorData);
|
|
157
|
+
|
|
158
|
+
if (fallbackResponse.status === 401) {
|
|
159
|
+
this.eventEmitter.emit("authError", {
|
|
160
|
+
statusCode: 401,
|
|
161
|
+
message: errorData.message || "Authentication required",
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return errorData as T;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ✅ Fallback exitoso
|
|
169
|
+
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
170
|
+
|
|
171
|
+
console.log(`✅ Fallback exitoso para: ${endpoint}`);
|
|
172
|
+
|
|
173
|
+
this.eventEmitter.emit("afterRequest", {
|
|
174
|
+
url: fallbackUrl,
|
|
175
|
+
method,
|
|
176
|
+
response: fallbackData,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return fallbackData;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ✅ Otros errores (no 404)
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
let errorData;
|
|
185
|
+
try {
|
|
186
|
+
errorData = await response.json();
|
|
187
|
+
} catch {
|
|
188
|
+
errorData = { message: response.statusText };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
192
|
+
|
|
193
|
+
if (response.status === 401) {
|
|
194
|
+
this.eventEmitter.emit("authError", {
|
|
195
|
+
statusCode: 401,
|
|
196
|
+
message: errorData.message || "Authentication required",
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return errorData as T;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ✅ Respuesta exitosa del primer intento
|
|
204
|
+
const responseData = await parseResponse<T>(response);
|
|
205
|
+
|
|
206
|
+
if (useCache && method === "GET") {
|
|
207
|
+
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
208
|
+
const cacheTime = options.cacheTime || undefined;
|
|
209
|
+
this.cache.set(cacheKey, responseData, cacheTime);
|
|
210
|
+
|
|
211
|
+
if (this.debug) {
|
|
212
|
+
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this.eventEmitter.emit("afterRequest", {
|
|
217
|
+
url: primaryUrl,
|
|
218
|
+
method,
|
|
219
|
+
response: responseData,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
return responseData;
|
|
223
|
+
} catch (error) {
|
|
224
|
+
this.eventEmitter.emit("requestError", {
|
|
225
|
+
url: primaryUrl,
|
|
226
|
+
method,
|
|
227
|
+
error,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
if (error instanceof ApiError) {
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
235
|
+
originalError: error,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}*/
|
|
59
239
|
async request(method, endpoint, data, params, options = {}) {
|
|
60
|
-
// ✅ Primer intento con baseUrl normal
|
|
61
240
|
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
62
|
-
const
|
|
241
|
+
const baseHeaders = buildHeaders(this.token, {
|
|
63
242
|
"X-Organization": this.organization,
|
|
64
243
|
...(options.headers || {}),
|
|
65
244
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
245
|
+
// ✅ Función helper para debug de headers
|
|
246
|
+
const headersToObject = (headers) => {
|
|
247
|
+
const obj = {};
|
|
248
|
+
headers.forEach((value, key) => {
|
|
249
|
+
obj[key] = value;
|
|
250
|
+
});
|
|
251
|
+
return obj;
|
|
252
|
+
};
|
|
253
|
+
const createHeaders = () => {
|
|
254
|
+
const headers = new Headers(baseHeaders);
|
|
255
|
+
const legacyToken = window.__LEGACY_TOKEN__ ||
|
|
256
|
+
sessionStorage.getItem("legacy_token") ||
|
|
257
|
+
null;
|
|
258
|
+
if (legacyToken) {
|
|
259
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
260
|
+
if (this.debug) {
|
|
261
|
+
console.log("🔐 Using legacy token for:", endpoint);
|
|
262
|
+
}
|
|
75
263
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
264
|
+
else if (this.token) {
|
|
265
|
+
if (this.debug) {
|
|
266
|
+
console.log("🔐 Using v1 token for:", endpoint);
|
|
267
|
+
}
|
|
80
268
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
269
|
+
else {
|
|
270
|
+
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
271
|
+
}
|
|
272
|
+
return headers;
|
|
273
|
+
};
|
|
85
274
|
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
86
275
|
if (useCache && method === "GET") {
|
|
87
276
|
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
@@ -99,31 +288,48 @@ export class ApiClient {
|
|
|
99
288
|
data,
|
|
100
289
|
});
|
|
101
290
|
try {
|
|
102
|
-
|
|
103
|
-
method,
|
|
104
|
-
headers,
|
|
105
|
-
credentials: "include",
|
|
106
|
-
};
|
|
291
|
+
let body;
|
|
107
292
|
if (data && method !== "GET") {
|
|
108
|
-
|
|
293
|
+
body = JSON.stringify(data);
|
|
109
294
|
if (this.debug) {
|
|
110
295
|
console.log(`📤 ${method} Body:`, data);
|
|
111
296
|
}
|
|
112
297
|
}
|
|
298
|
+
// ✅ Primer intento
|
|
299
|
+
const headers1 = createHeaders();
|
|
300
|
+
const fetchOptions1 = {
|
|
301
|
+
method,
|
|
302
|
+
headers: headers1,
|
|
303
|
+
credentials: "include",
|
|
304
|
+
...(body && { body }),
|
|
305
|
+
};
|
|
113
306
|
if (this.debug) {
|
|
114
307
|
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
308
|
+
console.log("📋 Headers:", headersToObject(headers1)); // ✅ CORREGIDO
|
|
115
309
|
}
|
|
116
|
-
|
|
117
|
-
const response = await fetch(primaryUrl, fetchOptions);
|
|
118
|
-
// ✅ Si es 404, intentar con fallback URL
|
|
310
|
+
const response = await fetch(primaryUrl, fetchOptions1);
|
|
119
311
|
if (response.status === 404) {
|
|
120
312
|
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
121
313
|
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
122
314
|
if (this.debug) {
|
|
123
315
|
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
124
316
|
}
|
|
125
|
-
// ✅ Segundo intento
|
|
126
|
-
const
|
|
317
|
+
// ✅ Segundo intento
|
|
318
|
+
const headers2 = createHeaders();
|
|
319
|
+
const fetchOptions2 = {
|
|
320
|
+
method,
|
|
321
|
+
headers: headers2,
|
|
322
|
+
credentials: "include",
|
|
323
|
+
...(body && { body }),
|
|
324
|
+
};
|
|
325
|
+
if (this.debug) {
|
|
326
|
+
console.log("📋 Fallback Headers:", headersToObject(headers2)); // ✅ CORREGIDO
|
|
327
|
+
}
|
|
328
|
+
const fallbackResponse = await fetch(fallbackUrl, fetchOptions2);
|
|
329
|
+
if (fallbackResponse.status === 204) {
|
|
330
|
+
console.log(`✅ Fallback exitoso (204 No Content): ${endpoint}`);
|
|
331
|
+
return {};
|
|
332
|
+
}
|
|
127
333
|
if (!fallbackResponse.ok) {
|
|
128
334
|
let errorData;
|
|
129
335
|
try {
|
|
@@ -132,7 +338,7 @@ export class ApiClient {
|
|
|
132
338
|
catch (_a) {
|
|
133
339
|
errorData = { message: fallbackResponse.statusText };
|
|
134
340
|
}
|
|
135
|
-
console.error(`❌ Fallback
|
|
341
|
+
console.error(`❌ Fallback falló ${fallbackResponse.status}:`, errorData);
|
|
136
342
|
if (fallbackResponse.status === 401) {
|
|
137
343
|
this.eventEmitter.emit("authError", {
|
|
138
344
|
statusCode: 401,
|
|
@@ -141,9 +347,8 @@ export class ApiClient {
|
|
|
141
347
|
}
|
|
142
348
|
return errorData;
|
|
143
349
|
}
|
|
144
|
-
// ✅ Fallback exitoso
|
|
145
350
|
const fallbackData = await parseResponse(fallbackResponse);
|
|
146
|
-
console.log(`✅ Fallback exitoso
|
|
351
|
+
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
147
352
|
this.eventEmitter.emit("afterRequest", {
|
|
148
353
|
url: fallbackUrl,
|
|
149
354
|
method,
|
|
@@ -151,7 +356,10 @@ export class ApiClient {
|
|
|
151
356
|
});
|
|
152
357
|
return fallbackData;
|
|
153
358
|
}
|
|
154
|
-
|
|
359
|
+
if (response.status === 204) {
|
|
360
|
+
console.log(`✅ Request exitoso (204 No Content): ${endpoint}`);
|
|
361
|
+
return {};
|
|
362
|
+
}
|
|
155
363
|
if (!response.ok) {
|
|
156
364
|
let errorData;
|
|
157
365
|
try {
|
|
@@ -169,7 +377,6 @@ export class ApiClient {
|
|
|
169
377
|
}
|
|
170
378
|
return errorData;
|
|
171
379
|
}
|
|
172
|
-
// ✅ Respuesta exitosa del primer intento
|
|
173
380
|
const responseData = await parseResponse(response);
|
|
174
381
|
if (useCache && method === "GET") {
|
|
175
382
|
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
package/package.json
CHANGED
package/src/core/api-client.ts
CHANGED
|
@@ -24,7 +24,8 @@ export class ApiClient {
|
|
|
24
24
|
|
|
25
25
|
constructor(config: SdkConfig, eventEmitter: EventEmitter) {
|
|
26
26
|
this.baseUrl = config.baseUrl;
|
|
27
|
-
this.fallbackBaseUrl =
|
|
27
|
+
this.fallbackBaseUrl =
|
|
28
|
+
config.fallbackBaseUrl || "http://216.250.117.119/ZeroServicesQA/api/v1";
|
|
28
29
|
this.organization = config.organization;
|
|
29
30
|
this.token = config.token || null;
|
|
30
31
|
this.eventEmitter = eventEmitter;
|
|
@@ -125,7 +126,7 @@ export class ApiClient {
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
private async request<T>(
|
|
129
|
+
/*private async request<T>(
|
|
129
130
|
method: string,
|
|
130
131
|
endpoint: string,
|
|
131
132
|
data?: any,
|
|
@@ -299,9 +300,224 @@ export class ApiClient {
|
|
|
299
300
|
throw error;
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
304
|
+
originalError: error,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}*/
|
|
308
|
+
private async request<T>(
|
|
309
|
+
method: string,
|
|
310
|
+
endpoint: string,
|
|
311
|
+
data?: any,
|
|
312
|
+
params?: Record<string, any>,
|
|
313
|
+
options: RequestOptions = {}
|
|
314
|
+
): Promise<T> {
|
|
315
|
+
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
316
|
+
|
|
317
|
+
const baseHeaders: HeadersInit = buildHeaders(this.token, {
|
|
318
|
+
"X-Organization": this.organization,
|
|
319
|
+
...(options.headers || {}),
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// ✅ Función helper para debug de headers
|
|
323
|
+
const headersToObject = (headers: Headers): Record<string, string> => {
|
|
324
|
+
const obj: Record<string, string> = {};
|
|
325
|
+
headers.forEach((value, key) => {
|
|
326
|
+
obj[key] = value;
|
|
327
|
+
});
|
|
328
|
+
return obj;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const createHeaders = (): Headers => {
|
|
332
|
+
const headers = new Headers(baseHeaders);
|
|
333
|
+
|
|
334
|
+
const legacyToken =
|
|
335
|
+
(window as any).__LEGACY_TOKEN__ ||
|
|
336
|
+
sessionStorage.getItem("legacy_token") ||
|
|
337
|
+
null;
|
|
338
|
+
|
|
339
|
+
if (legacyToken) {
|
|
340
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
341
|
+
if (this.debug) {
|
|
342
|
+
console.log("🔐 Using legacy token for:", endpoint);
|
|
343
|
+
}
|
|
344
|
+
} else if (this.token) {
|
|
345
|
+
if (this.debug) {
|
|
346
|
+
console.log("🔐 Using v1 token for:", endpoint);
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return headers;
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
356
|
+
if (useCache && method === "GET") {
|
|
357
|
+
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
358
|
+
const cachedData = this.cache.get<T>(cacheKey);
|
|
359
|
+
if (cachedData) {
|
|
360
|
+
if (this.debug) {
|
|
361
|
+
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
362
|
+
}
|
|
363
|
+
return cachedData;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
this.eventEmitter.emit("beforeRequest", {
|
|
368
|
+
url: primaryUrl,
|
|
369
|
+
method,
|
|
370
|
+
data,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
let body: string | undefined;
|
|
375
|
+
if (data && method !== "GET") {
|
|
376
|
+
body = JSON.stringify(data);
|
|
377
|
+
if (this.debug) {
|
|
378
|
+
console.log(`📤 ${method} Body:`, data);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// ✅ Primer intento
|
|
383
|
+
const headers1 = createHeaders();
|
|
384
|
+
const fetchOptions1: RequestInit = {
|
|
385
|
+
method,
|
|
386
|
+
headers: headers1,
|
|
387
|
+
credentials: "include",
|
|
388
|
+
...(body && { body }),
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
if (this.debug) {
|
|
392
|
+
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
393
|
+
console.log("📋 Headers:", headersToObject(headers1)); // ✅ CORREGIDO
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const response = await fetch(primaryUrl, fetchOptions1);
|
|
397
|
+
|
|
398
|
+
if (response.status === 404) {
|
|
399
|
+
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
400
|
+
|
|
401
|
+
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
402
|
+
|
|
403
|
+
if (this.debug) {
|
|
404
|
+
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// ✅ Segundo intento
|
|
408
|
+
const headers2 = createHeaders();
|
|
409
|
+
const fetchOptions2: RequestInit = {
|
|
410
|
+
method,
|
|
411
|
+
headers: headers2,
|
|
412
|
+
credentials: "include",
|
|
413
|
+
...(body && { body }),
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
if (this.debug) {
|
|
417
|
+
console.log("📋 Fallback Headers:", headersToObject(headers2)); // ✅ CORREGIDO
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const fallbackResponse = await fetch(fallbackUrl, fetchOptions2);
|
|
421
|
+
|
|
422
|
+
if (fallbackResponse.status === 204) {
|
|
423
|
+
console.log(`✅ Fallback exitoso (204 No Content): ${endpoint}`);
|
|
424
|
+
return {} as T;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (!fallbackResponse.ok) {
|
|
428
|
+
let errorData;
|
|
429
|
+
try {
|
|
430
|
+
errorData = await fallbackResponse.json();
|
|
431
|
+
} catch {
|
|
432
|
+
errorData = { message: fallbackResponse.statusText };
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
console.error(
|
|
436
|
+
`❌ Fallback falló ${fallbackResponse.status}:`,
|
|
437
|
+
errorData
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
if (fallbackResponse.status === 401) {
|
|
441
|
+
this.eventEmitter.emit("authError", {
|
|
442
|
+
statusCode: 401,
|
|
443
|
+
message: errorData.message || "Authentication required",
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return errorData as T;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
451
|
+
|
|
452
|
+
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
453
|
+
|
|
454
|
+
this.eventEmitter.emit("afterRequest", {
|
|
455
|
+
url: fallbackUrl,
|
|
456
|
+
method,
|
|
457
|
+
response: fallbackData,
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
return fallbackData;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (response.status === 204) {
|
|
464
|
+
console.log(`✅ Request exitoso (204 No Content): ${endpoint}`);
|
|
465
|
+
return {} as T;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (!response.ok) {
|
|
469
|
+
let errorData;
|
|
470
|
+
try {
|
|
471
|
+
errorData = await response.json();
|
|
472
|
+
} catch {
|
|
473
|
+
errorData = { message: response.statusText };
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
477
|
+
|
|
478
|
+
if (response.status === 401) {
|
|
479
|
+
this.eventEmitter.emit("authError", {
|
|
480
|
+
statusCode: 401,
|
|
481
|
+
message: errorData.message || "Authentication required",
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return errorData as T;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const responseData = await parseResponse<T>(response);
|
|
489
|
+
|
|
490
|
+
if (useCache && method === "GET") {
|
|
491
|
+
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
492
|
+
const cacheTime = options.cacheTime || undefined;
|
|
493
|
+
this.cache.set(cacheKey, responseData, cacheTime);
|
|
494
|
+
|
|
495
|
+
if (this.debug) {
|
|
496
|
+
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
this.eventEmitter.emit("afterRequest", {
|
|
501
|
+
url: primaryUrl,
|
|
502
|
+
method,
|
|
503
|
+
response: responseData,
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
return responseData;
|
|
507
|
+
} catch (error) {
|
|
508
|
+
this.eventEmitter.emit("requestError", {
|
|
509
|
+
url: primaryUrl,
|
|
510
|
+
method,
|
|
511
|
+
error,
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
if (error instanceof ApiError) {
|
|
515
|
+
throw error;
|
|
516
|
+
}
|
|
517
|
+
|
|
302
518
|
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
303
519
|
originalError: error,
|
|
304
520
|
});
|
|
305
521
|
}
|
|
306
522
|
}
|
|
307
|
-
}
|
|
523
|
+
}
|