@zerosls/clm-sdk 1.1.7 → 1.1.8
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 +195 -5
- package/package.json +1 -1
- package/src/core/api-client.ts +199 -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,8 +57,187 @@ 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
|
+
}*/
|
|
239
|
+
// core/api-client.ts
|
|
59
240
|
async request(method, endpoint, data, params, options = {}) {
|
|
60
|
-
// ✅ Primer intento con baseUrl normal
|
|
61
241
|
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
62
242
|
const base = buildHeaders(this.token, {
|
|
63
243
|
"X-Organization": this.organization,
|
|
@@ -124,6 +304,11 @@ export class ApiClient {
|
|
|
124
304
|
}
|
|
125
305
|
// ✅ Segundo intento con fallback
|
|
126
306
|
const fallbackResponse = await fetch(fallbackUrl, fetchOptions);
|
|
307
|
+
// ✅ Manejar 204 No Content
|
|
308
|
+
if (fallbackResponse.status === 204) {
|
|
309
|
+
console.log(`✅ Fallback exitoso (204 No Content): ${endpoint}`);
|
|
310
|
+
return {}; // Retornar objeto vacío
|
|
311
|
+
}
|
|
127
312
|
if (!fallbackResponse.ok) {
|
|
128
313
|
let errorData;
|
|
129
314
|
try {
|
|
@@ -132,7 +317,7 @@ export class ApiClient {
|
|
|
132
317
|
catch (_a) {
|
|
133
318
|
errorData = { message: fallbackResponse.statusText };
|
|
134
319
|
}
|
|
135
|
-
console.error(`❌ Fallback
|
|
320
|
+
console.error(`❌ Fallback falló ${fallbackResponse.status}:`, errorData);
|
|
136
321
|
if (fallbackResponse.status === 401) {
|
|
137
322
|
this.eventEmitter.emit("authError", {
|
|
138
323
|
statusCode: 401,
|
|
@@ -141,9 +326,9 @@ export class ApiClient {
|
|
|
141
326
|
}
|
|
142
327
|
return errorData;
|
|
143
328
|
}
|
|
144
|
-
// ✅ Fallback exitoso
|
|
329
|
+
// ✅ Fallback exitoso con contenido
|
|
145
330
|
const fallbackData = await parseResponse(fallbackResponse);
|
|
146
|
-
console.log(`✅ Fallback exitoso
|
|
331
|
+
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
147
332
|
this.eventEmitter.emit("afterRequest", {
|
|
148
333
|
url: fallbackUrl,
|
|
149
334
|
method,
|
|
@@ -151,6 +336,11 @@ export class ApiClient {
|
|
|
151
336
|
});
|
|
152
337
|
return fallbackData;
|
|
153
338
|
}
|
|
339
|
+
// ✅ Manejar 204 No Content en primer intento
|
|
340
|
+
if (response.status === 204) {
|
|
341
|
+
console.log(`✅ Request exitoso (204 No Content): ${endpoint}`);
|
|
342
|
+
return {}; // Retornar objeto vacío
|
|
343
|
+
}
|
|
154
344
|
// ✅ Otros errores (no 404)
|
|
155
345
|
if (!response.ok) {
|
|
156
346
|
let errorData;
|
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,204 @@ 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
|
+
|
|
309
|
+
// core/api-client.ts
|
|
310
|
+
private async request<T>(
|
|
311
|
+
method: string,
|
|
312
|
+
endpoint: string,
|
|
313
|
+
data?: any,
|
|
314
|
+
params?: Record<string, any>,
|
|
315
|
+
options: RequestOptions = {}
|
|
316
|
+
): Promise<T> {
|
|
317
|
+
const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
|
|
318
|
+
|
|
319
|
+
const base: HeadersInit = buildHeaders(this.token, {
|
|
320
|
+
"X-Organization": this.organization,
|
|
321
|
+
...(options.headers || {}),
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const headers = new Headers(base);
|
|
325
|
+
|
|
326
|
+
// ✅ Obtener token legacy
|
|
327
|
+
const legacyToken =
|
|
328
|
+
(window as any).__LEGACY_TOKEN__ ||
|
|
329
|
+
sessionStorage.getItem("legacy_token") ||
|
|
330
|
+
null;
|
|
331
|
+
|
|
332
|
+
if (legacyToken) {
|
|
333
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
334
|
+
if (this.debug) {
|
|
335
|
+
console.log("🔐 Using legacy token for:", endpoint);
|
|
336
|
+
}
|
|
337
|
+
} else if (this.token) {
|
|
338
|
+
if (this.debug) {
|
|
339
|
+
console.log("🔐 Using v1 token for:", endpoint);
|
|
340
|
+
}
|
|
341
|
+
} else {
|
|
342
|
+
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
346
|
+
if (useCache && method === "GET") {
|
|
347
|
+
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
348
|
+
const cachedData = this.cache.get<T>(cacheKey);
|
|
349
|
+
if (cachedData) {
|
|
350
|
+
if (this.debug) {
|
|
351
|
+
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
352
|
+
}
|
|
353
|
+
return cachedData;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
this.eventEmitter.emit("beforeRequest", {
|
|
358
|
+
url: primaryUrl,
|
|
359
|
+
method,
|
|
360
|
+
data,
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
try {
|
|
364
|
+
const fetchOptions: RequestInit = {
|
|
365
|
+
method,
|
|
366
|
+
headers,
|
|
367
|
+
credentials: "include",
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
if (data && method !== "GET") {
|
|
371
|
+
fetchOptions.body = JSON.stringify(data);
|
|
372
|
+
if (this.debug) {
|
|
373
|
+
console.log(`📤 ${method} Body:`, data);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (this.debug) {
|
|
378
|
+
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ✅ Primer intento
|
|
382
|
+
const response = await fetch(primaryUrl, fetchOptions);
|
|
383
|
+
|
|
384
|
+
// ✅ Si es 404, intentar con fallback URL
|
|
385
|
+
if (response.status === 404) {
|
|
386
|
+
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
387
|
+
|
|
388
|
+
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
389
|
+
|
|
390
|
+
if (this.debug) {
|
|
391
|
+
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// ✅ Segundo intento con fallback
|
|
395
|
+
const fallbackResponse = await fetch(fallbackUrl, fetchOptions);
|
|
396
|
+
|
|
397
|
+
// ✅ Manejar 204 No Content
|
|
398
|
+
if (fallbackResponse.status === 204) {
|
|
399
|
+
console.log(`✅ Fallback exitoso (204 No Content): ${endpoint}`);
|
|
400
|
+
return {} as T; // Retornar objeto vacío
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (!fallbackResponse.ok) {
|
|
404
|
+
let errorData;
|
|
405
|
+
try {
|
|
406
|
+
errorData = await fallbackResponse.json();
|
|
407
|
+
} catch {
|
|
408
|
+
errorData = { message: fallbackResponse.statusText };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
console.error(
|
|
412
|
+
`❌ Fallback falló ${fallbackResponse.status}:`,
|
|
413
|
+
errorData
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
if (fallbackResponse.status === 401) {
|
|
417
|
+
this.eventEmitter.emit("authError", {
|
|
418
|
+
statusCode: 401,
|
|
419
|
+
message: errorData.message || "Authentication required",
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
return errorData as T;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// ✅ Fallback exitoso con contenido
|
|
427
|
+
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
428
|
+
|
|
429
|
+
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
430
|
+
|
|
431
|
+
this.eventEmitter.emit("afterRequest", {
|
|
432
|
+
url: fallbackUrl,
|
|
433
|
+
method,
|
|
434
|
+
response: fallbackData,
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
return fallbackData;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// ✅ Manejar 204 No Content en primer intento
|
|
441
|
+
if (response.status === 204) {
|
|
442
|
+
console.log(`✅ Request exitoso (204 No Content): ${endpoint}`);
|
|
443
|
+
return {} as T; // Retornar objeto vacío
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// ✅ Otros errores (no 404)
|
|
447
|
+
if (!response.ok) {
|
|
448
|
+
let errorData;
|
|
449
|
+
try {
|
|
450
|
+
errorData = await response.json();
|
|
451
|
+
} catch {
|
|
452
|
+
errorData = { message: response.statusText };
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
456
|
+
|
|
457
|
+
if (response.status === 401) {
|
|
458
|
+
this.eventEmitter.emit("authError", {
|
|
459
|
+
statusCode: 401,
|
|
460
|
+
message: errorData.message || "Authentication required",
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return errorData as T;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// ✅ Respuesta exitosa del primer intento
|
|
468
|
+
const responseData = await parseResponse<T>(response);
|
|
469
|
+
|
|
470
|
+
if (useCache && method === "GET") {
|
|
471
|
+
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
472
|
+
const cacheTime = options.cacheTime || undefined;
|
|
473
|
+
this.cache.set(cacheKey, responseData, cacheTime);
|
|
474
|
+
|
|
475
|
+
if (this.debug) {
|
|
476
|
+
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
this.eventEmitter.emit("afterRequest", {
|
|
481
|
+
url: primaryUrl,
|
|
482
|
+
method,
|
|
483
|
+
response: responseData,
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
return responseData;
|
|
487
|
+
} catch (error) {
|
|
488
|
+
this.eventEmitter.emit("requestError", {
|
|
489
|
+
url: primaryUrl,
|
|
490
|
+
method,
|
|
491
|
+
error,
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
if (error instanceof ApiError) {
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
|
|
302
498
|
throw new ApiError((error as Error).message || "Network error", 0, {
|
|
303
499
|
originalError: error,
|
|
304
500
|
});
|
|
305
501
|
}
|
|
306
502
|
}
|
|
307
|
-
}
|
|
503
|
+
}
|