@zerosls/clm-sdk 1.1.8 → 1.1.10
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.d.ts +0 -1
- package/dist/core/api-client.js +23 -261
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -9
- package/dist/modules/v1/auth/auth-api.d.ts +3 -5
- package/dist/modules/v1/auth/auth-api.js +46 -35
- package/dist/types/sdk.d.ts +0 -1
- package/package.json +1 -1
- package/src/core/api-client.ts +25 -279
- package/src/index.ts +0 -14
- package/src/modules/v1/auth/auth-api.ts +66 -42
- package/src/types/sdk.ts +0 -1
- package/dist/core/legacy-api-client.d.ts +0 -26
- package/dist/core/legacy-api-client.js +0 -35
- package/src/core/legacy-api-client.ts +0 -66
package/dist/core/api-client.js
CHANGED
|
@@ -6,8 +6,6 @@ export class ApiClient {
|
|
|
6
6
|
var _a, _b;
|
|
7
7
|
this.token = null;
|
|
8
8
|
this.baseUrl = config.baseUrl;
|
|
9
|
-
this.fallbackBaseUrl =
|
|
10
|
-
config.fallbackBaseUrl || "http://216.250.117.119/ZeroServicesQA/api/v1";
|
|
11
9
|
this.organization = config.organization;
|
|
12
10
|
this.token = config.token || null;
|
|
13
11
|
this.eventEmitter = eventEmitter;
|
|
@@ -57,214 +55,31 @@ export class ApiClient {
|
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
}
|
|
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
|
|
240
58
|
async request(method, endpoint, data, params, options = {}) {
|
|
241
|
-
const
|
|
59
|
+
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
242
60
|
const base = buildHeaders(this.token, {
|
|
243
61
|
"X-Organization": this.organization,
|
|
244
62
|
...(options.headers || {}),
|
|
245
63
|
});
|
|
246
64
|
const headers = new Headers(base);
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
else if (this.token) {
|
|
258
|
-
if (this.debug) {
|
|
259
|
-
console.log("🔐 Using v1 token for:", endpoint);
|
|
65
|
+
const legacyPattern = /(^|\/)legacy(\/|$)/i;
|
|
66
|
+
const isLegacyEndpoint = legacyPattern.test(endpoint);
|
|
67
|
+
const isLegacyLogin = /(^|\/)legacy\/login$/i.test(endpoint);
|
|
68
|
+
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
69
|
+
const legacyToken = (typeof window !== "undefined" && window.__LEGACY_TOKEN__) ||
|
|
70
|
+
(typeof sessionStorage !== "undefined" &&
|
|
71
|
+
sessionStorage.getItem("legacy_token")) ||
|
|
72
|
+
null;
|
|
73
|
+
if (legacyToken) {
|
|
74
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
260
75
|
}
|
|
261
76
|
}
|
|
262
|
-
|
|
263
|
-
|
|
77
|
+
if (!isLegacyEndpoint && !this.token) {
|
|
78
|
+
headers.delete("Authorization");
|
|
264
79
|
}
|
|
265
80
|
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
266
81
|
if (useCache && method === "GET") {
|
|
267
|
-
const cacheKey = generateCacheKey(method,
|
|
82
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
268
83
|
const cachedData = this.cache.get(cacheKey);
|
|
269
84
|
if (cachedData) {
|
|
270
85
|
if (this.debug) {
|
|
@@ -274,7 +89,7 @@ export class ApiClient {
|
|
|
274
89
|
}
|
|
275
90
|
}
|
|
276
91
|
this.eventEmitter.emit("beforeRequest", {
|
|
277
|
-
url
|
|
92
|
+
url,
|
|
278
93
|
method,
|
|
279
94
|
data,
|
|
280
95
|
});
|
|
@@ -282,72 +97,20 @@ export class ApiClient {
|
|
|
282
97
|
const fetchOptions = {
|
|
283
98
|
method,
|
|
284
99
|
headers,
|
|
285
|
-
credentials:
|
|
100
|
+
credentials: this.credentials,
|
|
286
101
|
};
|
|
287
102
|
if (data && method !== "GET") {
|
|
288
103
|
fetchOptions.body = JSON.stringify(data);
|
|
289
|
-
|
|
290
|
-
console.log(`📤 ${method} Body:`, data);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (this.debug) {
|
|
294
|
-
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
295
|
-
}
|
|
296
|
-
// ✅ Primer intento
|
|
297
|
-
const response = await fetch(primaryUrl, fetchOptions);
|
|
298
|
-
// ✅ Si es 404, intentar con fallback URL
|
|
299
|
-
if (response.status === 404) {
|
|
300
|
-
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
301
|
-
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
302
|
-
if (this.debug) {
|
|
303
|
-
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
304
|
-
}
|
|
305
|
-
// ✅ Segundo intento con fallback
|
|
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
|
-
}
|
|
312
|
-
if (!fallbackResponse.ok) {
|
|
313
|
-
let errorData;
|
|
314
|
-
try {
|
|
315
|
-
errorData = await fallbackResponse.json();
|
|
316
|
-
}
|
|
317
|
-
catch (_a) {
|
|
318
|
-
errorData = { message: fallbackResponse.statusText };
|
|
319
|
-
}
|
|
320
|
-
console.error(`❌ Fallback falló ${fallbackResponse.status}:`, errorData);
|
|
321
|
-
if (fallbackResponse.status === 401) {
|
|
322
|
-
this.eventEmitter.emit("authError", {
|
|
323
|
-
statusCode: 401,
|
|
324
|
-
message: errorData.message || "Authentication required",
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
return errorData;
|
|
328
|
-
}
|
|
329
|
-
// ✅ Fallback exitoso con contenido
|
|
330
|
-
const fallbackData = await parseResponse(fallbackResponse);
|
|
331
|
-
console.log(`✅ Fallback exitoso: ${endpoint}`);
|
|
332
|
-
this.eventEmitter.emit("afterRequest", {
|
|
333
|
-
url: fallbackUrl,
|
|
334
|
-
method,
|
|
335
|
-
response: fallbackData,
|
|
336
|
-
});
|
|
337
|
-
return fallbackData;
|
|
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
|
|
104
|
+
console.log(`📤 ${method} Body:`, data);
|
|
343
105
|
}
|
|
344
|
-
|
|
106
|
+
console.log(`🌐 ${method} ${url}`, fetchOptions);
|
|
107
|
+
const response = await fetch(url, fetchOptions);
|
|
345
108
|
if (!response.ok) {
|
|
346
109
|
let errorData;
|
|
347
110
|
try {
|
|
348
111
|
errorData = await response.json();
|
|
349
112
|
}
|
|
350
|
-
catch (
|
|
113
|
+
catch (_a) {
|
|
351
114
|
errorData = { message: response.statusText };
|
|
352
115
|
}
|
|
353
116
|
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
@@ -359,10 +122,9 @@ export class ApiClient {
|
|
|
359
122
|
}
|
|
360
123
|
return errorData;
|
|
361
124
|
}
|
|
362
|
-
// ✅ Respuesta exitosa del primer intento
|
|
363
125
|
const responseData = await parseResponse(response);
|
|
364
126
|
if (useCache && method === "GET") {
|
|
365
|
-
const cacheKey = generateCacheKey(method,
|
|
127
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
366
128
|
const cacheTime = options.cacheTime || undefined;
|
|
367
129
|
this.cache.set(cacheKey, responseData, cacheTime);
|
|
368
130
|
if (this.debug) {
|
|
@@ -370,7 +132,7 @@ export class ApiClient {
|
|
|
370
132
|
}
|
|
371
133
|
}
|
|
372
134
|
this.eventEmitter.emit("afterRequest", {
|
|
373
|
-
url
|
|
135
|
+
url,
|
|
374
136
|
method,
|
|
375
137
|
response: responseData,
|
|
376
138
|
});
|
|
@@ -378,7 +140,7 @@ export class ApiClient {
|
|
|
378
140
|
}
|
|
379
141
|
catch (error) {
|
|
380
142
|
this.eventEmitter.emit("requestError", {
|
|
381
|
-
url
|
|
143
|
+
url,
|
|
382
144
|
method,
|
|
383
145
|
error,
|
|
384
146
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,6 @@ import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/cla
|
|
|
12
12
|
*/
|
|
13
13
|
export declare class ClmSdk {
|
|
14
14
|
private apiClient;
|
|
15
|
-
private legacyClient;
|
|
16
15
|
private eventEmitter;
|
|
17
16
|
private cacheInstance;
|
|
18
17
|
auth: AuthApi;
|
|
@@ -23,8 +22,6 @@ export declare class ClmSdk {
|
|
|
23
22
|
areas: AreasApi;
|
|
24
23
|
classificationTypes: ClassificationTypesApi;
|
|
25
24
|
constructor(config: Partial<SdkConfig>);
|
|
26
|
-
legacyLogin(userName: string, password: string): Promise<import("./core/legacy-api-client").LegacyLoginResponse>;
|
|
27
|
-
legacyLogout(): void;
|
|
28
25
|
/**
|
|
29
26
|
* Access to events system
|
|
30
27
|
*/
|
|
@@ -43,6 +40,5 @@ export * from "./modules/v1/auth/types";
|
|
|
43
40
|
export * from "./modules/v1/users/types";
|
|
44
41
|
export * from "./modules/v1/notifications/types";
|
|
45
42
|
export * from "./modules/v1/_logs/types";
|
|
46
|
-
export * from "./core/legacy-api-client";
|
|
47
43
|
export * from "./modules/legacy/areas/types";
|
|
48
44
|
export * from "./modules/legacy/classificationtypes/types";
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,6 @@ import { LogsApi } from "./modules/v1/_logs/logs-api";
|
|
|
11
11
|
// Legacy
|
|
12
12
|
import { AreasApi } from "./modules/legacy/areas/areas-api";
|
|
13
13
|
import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/classificationtypes-api";
|
|
14
|
-
import { LegacyApiClient } from "./core/legacy-api-client";
|
|
15
14
|
/**
|
|
16
15
|
* Main SDK for consuming CLM API
|
|
17
16
|
*/
|
|
@@ -31,7 +30,6 @@ export class ClmSdk {
|
|
|
31
30
|
// Initialize core utilities
|
|
32
31
|
this.cacheInstance = new Cache((_a = fullConfig.cache) === null || _a === void 0 ? void 0 : _a.ttl);
|
|
33
32
|
this.apiClient = new ApiClient(fullConfig, this.eventEmitter);
|
|
34
|
-
this.legacyClient = new LegacyApiClient("http://216.250.117.119/ZeroServicesQA/api/v1");
|
|
35
33
|
// Initialize modules v1
|
|
36
34
|
this.auth = new AuthApi(this.apiClient);
|
|
37
35
|
this.users = new UsersApi(this.apiClient);
|
|
@@ -42,12 +40,6 @@ export class ClmSdk {
|
|
|
42
40
|
this.areas = new AreasApi(this.apiClient);
|
|
43
41
|
this.classificationTypes = new ClassificationTypesApi(this.apiClient);
|
|
44
42
|
}
|
|
45
|
-
async legacyLogin(userName, password) {
|
|
46
|
-
return await this.legacyClient.login(userName, password);
|
|
47
|
-
}
|
|
48
|
-
legacyLogout() {
|
|
49
|
-
this.legacyClient.logout();
|
|
50
|
-
}
|
|
51
43
|
/**
|
|
52
44
|
* Access to events system
|
|
53
45
|
*/
|
|
@@ -63,6 +55,5 @@ export * from "./modules/v1/users/types";
|
|
|
63
55
|
export * from "./modules/v1/notifications/types";
|
|
64
56
|
export * from "./modules/v1/_logs/types";
|
|
65
57
|
// Export legacy types
|
|
66
|
-
export * from "./core/legacy-api-client";
|
|
67
58
|
export * from "./modules/legacy/areas/types";
|
|
68
59
|
export * from "./modules/legacy/classificationtypes/types";
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { ApiClient } from "../../../core/api-client";
|
|
2
2
|
import { LoginCredentials, LoginResponse, RefreshTokenRequest } from "./types";
|
|
3
|
+
type LoginMode = "new" | "legacy";
|
|
3
4
|
export declare class AuthApi {
|
|
4
5
|
private apiClient;
|
|
5
6
|
constructor(apiClient: ApiClient);
|
|
6
|
-
|
|
7
|
-
* Login con POST JSON (evita el modal del navegador).
|
|
8
|
-
* El servidor setea cookie HttpOnly (zero_token).
|
|
9
|
-
*/
|
|
10
|
-
login(credentials: LoginCredentials): Promise<{
|
|
7
|
+
login(credentials: LoginCredentials, mode?: LoginMode): Promise<{
|
|
11
8
|
ok: boolean;
|
|
12
9
|
}>;
|
|
13
10
|
refreshToken(request?: RefreshTokenRequest): Promise<LoginResponse>;
|
|
@@ -15,3 +12,4 @@ export declare class AuthApi {
|
|
|
15
12
|
isAuthenticated(): boolean;
|
|
16
13
|
setToken(token: string | null): void;
|
|
17
14
|
}
|
|
15
|
+
export {};
|
|
@@ -2,40 +2,42 @@ export class AuthApi {
|
|
|
2
2
|
constructor(apiClient) {
|
|
3
3
|
this.apiClient = apiClient;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
async login(credentials, mode = "new") {
|
|
6
|
+
var _a;
|
|
7
|
+
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
8
|
+
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
9
|
+
method: "POST",
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
"X-Organization": this.apiClient["organization"] || "default-org",
|
|
13
|
+
},
|
|
14
|
+
credentials: "include",
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
email: credentials.email,
|
|
17
|
+
password: credentials.password,
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
if (response.status === 401)
|
|
22
|
+
throw new Error("Invalid credentials");
|
|
23
|
+
throw new Error(`Login failed: ${response.status}`);
|
|
24
|
+
}
|
|
25
|
+
const data = await response.json().catch(() => null);
|
|
26
|
+
// ✅ Si es legacy, guarda Bearer token para siguientes llamadas legacy
|
|
27
|
+
if (mode === "legacy") {
|
|
28
|
+
const legacyToken = ((_a = data === null || data === void 0 ? void 0 : data.dataResult) === null || _a === void 0 ? void 0 : _a.token) || (data === null || data === void 0 ? void 0 : data.token);
|
|
29
|
+
if (legacyToken) {
|
|
30
|
+
if (typeof sessionStorage !== "undefined") {
|
|
31
|
+
sessionStorage.setItem("legacy_token", legacyToken);
|
|
32
|
+
}
|
|
33
|
+
if (typeof window !== "undefined") {
|
|
34
|
+
window.__LEGACY_TOKEN__ = legacyToken;
|
|
26
35
|
}
|
|
27
|
-
throw new Error(`Login failed: ${response.status}`);
|
|
28
36
|
}
|
|
29
|
-
const data = await response.json();
|
|
30
|
-
// No guardar token en memoria, solo usar cookie
|
|
31
|
-
this.apiClient.setToken(null);
|
|
32
|
-
console.log('✅ Login exitoso, cookie establecida');
|
|
33
|
-
return { ok: true };
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.error('❌ SDK Login error:', error);
|
|
37
|
-
throw error;
|
|
38
37
|
}
|
|
38
|
+
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
39
|
+
this.apiClient.setToken(null);
|
|
40
|
+
return { ok: true };
|
|
39
41
|
}
|
|
40
42
|
async refreshToken(request) {
|
|
41
43
|
const response = await this.apiClient.post("/auth/refresh", request);
|
|
@@ -47,15 +49,24 @@ export class AuthApi {
|
|
|
47
49
|
try {
|
|
48
50
|
await this.apiClient.post("/auth/logout");
|
|
49
51
|
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
console.error("Error during logout:", error);
|
|
52
|
-
}
|
|
53
52
|
finally {
|
|
53
|
+
// limpia token nuevo
|
|
54
54
|
this.apiClient.setToken(null);
|
|
55
|
+
// limpia legacy token
|
|
56
|
+
if (typeof sessionStorage !== "undefined") {
|
|
57
|
+
sessionStorage.removeItem("legacy_token");
|
|
58
|
+
}
|
|
59
|
+
if (typeof window !== "undefined") {
|
|
60
|
+
delete window.__LEGACY_TOKEN__;
|
|
61
|
+
}
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
isAuthenticated() {
|
|
58
|
-
|
|
65
|
+
const hasToken = this.apiClient.getToken() !== null;
|
|
66
|
+
const hasLegacy = (typeof sessionStorage !== "undefined" &&
|
|
67
|
+
!!sessionStorage.getItem("legacy_token")) ||
|
|
68
|
+
(typeof window !== "undefined" && !!window.__LEGACY_TOKEN__);
|
|
69
|
+
return hasToken || hasLegacy;
|
|
59
70
|
}
|
|
60
71
|
setToken(token) {
|
|
61
72
|
this.apiClient.setToken(token);
|
package/dist/types/sdk.d.ts
CHANGED
package/package.json
CHANGED
package/src/core/api-client.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// core/api-client.ts
|
|
2
1
|
import { SdkConfig, SdkEventType, SdkEvents } from "../types/sdk";
|
|
3
2
|
import { PaginatedResponse, RequestOptions } from "../types/common";
|
|
4
3
|
import { EventEmitter } from "./event-emitter";
|
|
@@ -13,7 +12,6 @@ import {
|
|
|
13
12
|
|
|
14
13
|
export class ApiClient {
|
|
15
14
|
private baseUrl: string;
|
|
16
|
-
private fallbackBaseUrl: string; // ✅ URL de respaldo
|
|
17
15
|
private organization: string;
|
|
18
16
|
private token: string | null = null;
|
|
19
17
|
private eventEmitter: EventEmitter;
|
|
@@ -24,8 +22,6 @@ export class ApiClient {
|
|
|
24
22
|
|
|
25
23
|
constructor(config: SdkConfig, eventEmitter: EventEmitter) {
|
|
26
24
|
this.baseUrl = config.baseUrl;
|
|
27
|
-
this.fallbackBaseUrl =
|
|
28
|
-
config.fallbackBaseUrl || "http://216.250.117.119/ZeroServicesQA/api/v1";
|
|
29
25
|
this.organization = config.organization;
|
|
30
26
|
this.token = config.token || null;
|
|
31
27
|
this.eventEmitter = eventEmitter;
|
|
@@ -126,16 +122,15 @@ export class ApiClient {
|
|
|
126
122
|
}
|
|
127
123
|
}
|
|
128
124
|
|
|
129
|
-
|
|
125
|
+
private async request<T>(
|
|
130
126
|
method: string,
|
|
131
127
|
endpoint: string,
|
|
132
128
|
data?: any,
|
|
133
129
|
params?: Record<string, any>,
|
|
134
130
|
options: RequestOptions = {}
|
|
135
131
|
): Promise<T> {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
const url = buildUrl(this.baseUrl, endpoint, params);
|
|
133
|
+
|
|
139
134
|
const base: HeadersInit = buildHeaders(this.token, {
|
|
140
135
|
"X-Organization": this.organization,
|
|
141
136
|
...(options.headers || {}),
|
|
@@ -143,208 +138,29 @@ export class ApiClient {
|
|
|
143
138
|
|
|
144
139
|
const headers = new Headers(base);
|
|
145
140
|
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
sessionStorage.getItem("legacy_token") ||
|
|
150
|
-
null;
|
|
141
|
+
const legacyPattern = /(^|\/)legacy(\/|$)/i;
|
|
142
|
+
const isLegacyEndpoint = legacyPattern.test(endpoint);
|
|
143
|
+
const isLegacyLogin = /(^|\/)legacy\/login$/i.test(endpoint);
|
|
151
144
|
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (this.debug) {
|
|
159
|
-
console.log("🔐 Using v1 token for:", endpoint);
|
|
160
|
-
}
|
|
161
|
-
} else {
|
|
162
|
-
console.warn("⚠️ No token available for endpoint:", endpoint);
|
|
163
|
-
}
|
|
145
|
+
if (isLegacyEndpoint && !isLegacyLogin) {
|
|
146
|
+
const legacyToken =
|
|
147
|
+
(typeof window !== "undefined" && (window as any).__LEGACY_TOKEN__) ||
|
|
148
|
+
(typeof sessionStorage !== "undefined" &&
|
|
149
|
+
sessionStorage.getItem("legacy_token")) ||
|
|
150
|
+
null;
|
|
164
151
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
168
|
-
const cachedData = this.cache.get<T>(cacheKey);
|
|
169
|
-
if (cachedData) {
|
|
170
|
-
if (this.debug) {
|
|
171
|
-
console.log(`[SDK-Cache] Hit: ${cacheKey}`);
|
|
172
|
-
}
|
|
173
|
-
return cachedData;
|
|
152
|
+
if (legacyToken) {
|
|
153
|
+
headers.set("Authorization", `Bearer ${legacyToken}`);
|
|
174
154
|
}
|
|
175
155
|
}
|
|
176
156
|
|
|
177
|
-
this.
|
|
178
|
-
|
|
179
|
-
method,
|
|
180
|
-
data,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
const fetchOptions: RequestInit = {
|
|
185
|
-
method,
|
|
186
|
-
headers,
|
|
187
|
-
credentials: "include",
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
if (data && method !== "GET") {
|
|
191
|
-
fetchOptions.body = JSON.stringify(data);
|
|
192
|
-
if (this.debug) {
|
|
193
|
-
console.log(`📤 ${method} Body:`, data);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (this.debug) {
|
|
198
|
-
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// ✅ Primer intento
|
|
202
|
-
const response = await fetch(primaryUrl, fetchOptions);
|
|
203
|
-
|
|
204
|
-
// ✅ Si es 404, intentar con fallback URL
|
|
205
|
-
if (response.status === 404) {
|
|
206
|
-
console.warn(`⚠️ 404 en ${primaryUrl}, intentando con fallback...`);
|
|
207
|
-
|
|
208
|
-
const fallbackUrl = buildUrl(this.fallbackBaseUrl, endpoint, params);
|
|
209
|
-
|
|
210
|
-
if (this.debug) {
|
|
211
|
-
console.log(`🔄 Retry: ${method} ${fallbackUrl}`);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// ✅ Segundo intento con fallback
|
|
215
|
-
const fallbackResponse = await fetch(fallbackUrl, fetchOptions);
|
|
216
|
-
|
|
217
|
-
if (!fallbackResponse.ok) {
|
|
218
|
-
let errorData;
|
|
219
|
-
try {
|
|
220
|
-
errorData = await fallbackResponse.json();
|
|
221
|
-
} catch {
|
|
222
|
-
errorData = { message: fallbackResponse.statusText };
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
console.error(`❌ Fallback también falló ${fallbackResponse.status}:`, errorData);
|
|
226
|
-
|
|
227
|
-
if (fallbackResponse.status === 401) {
|
|
228
|
-
this.eventEmitter.emit("authError", {
|
|
229
|
-
statusCode: 401,
|
|
230
|
-
message: errorData.message || "Authentication required",
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return errorData as T;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// ✅ Fallback exitoso
|
|
238
|
-
const fallbackData = await parseResponse<T>(fallbackResponse);
|
|
239
|
-
|
|
240
|
-
console.log(`✅ Fallback exitoso para: ${endpoint}`);
|
|
241
|
-
|
|
242
|
-
this.eventEmitter.emit("afterRequest", {
|
|
243
|
-
url: fallbackUrl,
|
|
244
|
-
method,
|
|
245
|
-
response: fallbackData,
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
return fallbackData;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// ✅ Otros errores (no 404)
|
|
252
|
-
if (!response.ok) {
|
|
253
|
-
let errorData;
|
|
254
|
-
try {
|
|
255
|
-
errorData = await response.json();
|
|
256
|
-
} catch {
|
|
257
|
-
errorData = { message: response.statusText };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
console.error(`❌ ${method} ${response.status}:`, errorData);
|
|
261
|
-
|
|
262
|
-
if (response.status === 401) {
|
|
263
|
-
this.eventEmitter.emit("authError", {
|
|
264
|
-
statusCode: 401,
|
|
265
|
-
message: errorData.message || "Authentication required",
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return errorData as T;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ✅ Respuesta exitosa del primer intento
|
|
273
|
-
const responseData = await parseResponse<T>(response);
|
|
274
|
-
|
|
275
|
-
if (useCache && method === "GET") {
|
|
276
|
-
const cacheKey = generateCacheKey(method, primaryUrl, data);
|
|
277
|
-
const cacheTime = options.cacheTime || undefined;
|
|
278
|
-
this.cache.set(cacheKey, responseData, cacheTime);
|
|
279
|
-
|
|
280
|
-
if (this.debug) {
|
|
281
|
-
console.log(`[SDK-Cache] Set: ${cacheKey}`);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
this.eventEmitter.emit("afterRequest", {
|
|
286
|
-
url: primaryUrl,
|
|
287
|
-
method,
|
|
288
|
-
response: responseData,
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
return responseData;
|
|
292
|
-
} catch (error) {
|
|
293
|
-
this.eventEmitter.emit("requestError", {
|
|
294
|
-
url: primaryUrl,
|
|
295
|
-
method,
|
|
296
|
-
error,
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
if (error instanceof ApiError) {
|
|
300
|
-
throw error;
|
|
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);
|
|
157
|
+
if (!isLegacyEndpoint && !this.token) {
|
|
158
|
+
headers.delete("Authorization");
|
|
343
159
|
}
|
|
344
160
|
|
|
345
161
|
const useCache = this.cacheEnabled && options.useCache !== false;
|
|
346
162
|
if (useCache && method === "GET") {
|
|
347
|
-
const cacheKey = generateCacheKey(method,
|
|
163
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
348
164
|
const cachedData = this.cache.get<T>(cacheKey);
|
|
349
165
|
if (cachedData) {
|
|
350
166
|
if (this.debug) {
|
|
@@ -355,7 +171,7 @@ export class ApiClient {
|
|
|
355
171
|
}
|
|
356
172
|
|
|
357
173
|
this.eventEmitter.emit("beforeRequest", {
|
|
358
|
-
url
|
|
174
|
+
url,
|
|
359
175
|
method,
|
|
360
176
|
data,
|
|
361
177
|
});
|
|
@@ -364,86 +180,17 @@ export class ApiClient {
|
|
|
364
180
|
const fetchOptions: RequestInit = {
|
|
365
181
|
method,
|
|
366
182
|
headers,
|
|
367
|
-
credentials:
|
|
183
|
+
credentials: this.credentials,
|
|
368
184
|
};
|
|
369
185
|
|
|
370
186
|
if (data && method !== "GET") {
|
|
371
187
|
fetchOptions.body = JSON.stringify(data);
|
|
372
|
-
|
|
373
|
-
console.log(`📤 ${method} Body:`, data);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (this.debug) {
|
|
378
|
-
console.log(`🌐 ${method} ${primaryUrl}`);
|
|
188
|
+
console.log(`📤 ${method} Body:`, data);
|
|
379
189
|
}
|
|
380
190
|
|
|
381
|
-
|
|
382
|
-
const response = await fetch(
|
|
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
|
-
}
|
|
191
|
+
console.log(`🌐 ${method} ${url}`, fetchOptions);
|
|
192
|
+
const response = await fetch(url, fetchOptions);
|
|
445
193
|
|
|
446
|
-
// ✅ Otros errores (no 404)
|
|
447
194
|
if (!response.ok) {
|
|
448
195
|
let errorData;
|
|
449
196
|
try {
|
|
@@ -464,11 +211,10 @@ export class ApiClient {
|
|
|
464
211
|
return errorData as T;
|
|
465
212
|
}
|
|
466
213
|
|
|
467
|
-
// ✅ Respuesta exitosa del primer intento
|
|
468
214
|
const responseData = await parseResponse<T>(response);
|
|
469
215
|
|
|
470
216
|
if (useCache && method === "GET") {
|
|
471
|
-
const cacheKey = generateCacheKey(method,
|
|
217
|
+
const cacheKey = generateCacheKey(method, url, data);
|
|
472
218
|
const cacheTime = options.cacheTime || undefined;
|
|
473
219
|
this.cache.set(cacheKey, responseData, cacheTime);
|
|
474
220
|
|
|
@@ -478,7 +224,7 @@ export class ApiClient {
|
|
|
478
224
|
}
|
|
479
225
|
|
|
480
226
|
this.eventEmitter.emit("afterRequest", {
|
|
481
|
-
url
|
|
227
|
+
url,
|
|
482
228
|
method,
|
|
483
229
|
response: responseData,
|
|
484
230
|
});
|
|
@@ -486,7 +232,7 @@ export class ApiClient {
|
|
|
486
232
|
return responseData;
|
|
487
233
|
} catch (error) {
|
|
488
234
|
this.eventEmitter.emit("requestError", {
|
|
489
|
-
url
|
|
235
|
+
url,
|
|
490
236
|
method,
|
|
491
237
|
error,
|
|
492
238
|
});
|
package/src/index.ts
CHANGED
|
@@ -15,14 +15,12 @@ import { LogsApi } from "./modules/v1/_logs/logs-api";
|
|
|
15
15
|
// Legacy
|
|
16
16
|
import { AreasApi } from "./modules/legacy/areas/areas-api";
|
|
17
17
|
import { ClassificationTypesApi } from "./modules/legacy/classificationtypes/classificationtypes-api";
|
|
18
|
-
import { LegacyApiClient } from "./core/legacy-api-client";
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* Main SDK for consuming CLM API
|
|
22
21
|
*/
|
|
23
22
|
export class ClmSdk {
|
|
24
23
|
private apiClient: ApiClient;
|
|
25
|
-
private legacyClient: LegacyApiClient;
|
|
26
24
|
private eventEmitter: EventEmitter;
|
|
27
25
|
private cacheInstance: Cache;
|
|
28
26
|
|
|
@@ -47,10 +45,6 @@ export class ClmSdk {
|
|
|
47
45
|
this.cacheInstance = new Cache(fullConfig.cache?.ttl);
|
|
48
46
|
this.apiClient = new ApiClient(fullConfig, this.eventEmitter);
|
|
49
47
|
|
|
50
|
-
this.legacyClient = new LegacyApiClient(
|
|
51
|
-
"http://216.250.117.119/ZeroServicesQA/api/v1"
|
|
52
|
-
);
|
|
53
|
-
|
|
54
48
|
// Initialize modules v1
|
|
55
49
|
this.auth = new AuthApi(this.apiClient);
|
|
56
50
|
this.users = new UsersApi(this.apiClient);
|
|
@@ -63,13 +57,6 @@ export class ClmSdk {
|
|
|
63
57
|
this.classificationTypes = new ClassificationTypesApi(this.apiClient);
|
|
64
58
|
}
|
|
65
59
|
|
|
66
|
-
async legacyLogin(userName: string, password: string) {
|
|
67
|
-
return await this.legacyClient.login(userName, password);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
legacyLogout(): void {
|
|
71
|
-
this.legacyClient.logout();
|
|
72
|
-
}
|
|
73
60
|
|
|
74
61
|
/**
|
|
75
62
|
* Access to events system
|
|
@@ -100,6 +87,5 @@ export * from "./modules/v1/notifications/types";
|
|
|
100
87
|
export * from "./modules/v1/_logs/types";
|
|
101
88
|
|
|
102
89
|
// Export legacy types
|
|
103
|
-
export * from "./core/legacy-api-client";
|
|
104
90
|
export * from "./modules/legacy/areas/types";
|
|
105
91
|
export * from "./modules/legacy/classificationtypes/types";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import { ApiClient } from "../../../core/api-client";
|
|
1
|
+
import { ApiClient } from "../../../core/api-client";
|
|
3
2
|
import { LoginCredentials, LoginResponse, RefreshTokenRequest } from "./types";
|
|
4
3
|
|
|
4
|
+
type LoginMode = "new" | "legacy";
|
|
5
|
+
|
|
5
6
|
export class AuthApi {
|
|
6
7
|
private apiClient: ApiClient;
|
|
7
8
|
|
|
@@ -9,67 +10,90 @@ export class AuthApi {
|
|
|
9
10
|
this.apiClient = apiClient;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
13
|
+
async login(
|
|
14
|
+
credentials: LoginCredentials,
|
|
15
|
+
mode: LoginMode = "new"
|
|
16
|
+
): Promise<{ ok: boolean }> {
|
|
17
|
+
const path = mode === "legacy" ? "/legacy/login" : "/auth/login";
|
|
18
|
+
|
|
19
|
+
const response = await fetch(`${this.apiClient["baseUrl"]}${path}`, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: {
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
"X-Organization": this.apiClient["organization"] || "default-org",
|
|
24
|
+
},
|
|
25
|
+
credentials: "include",
|
|
26
|
+
body: JSON.stringify({
|
|
27
|
+
email: credentials.email,
|
|
28
|
+
password: credentials.password,
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
if (response.status === 401) throw new Error("Invalid credentials");
|
|
34
|
+
throw new Error(`Login failed: ${response.status}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const data: any = await response.json().catch(() => null);
|
|
38
|
+
|
|
39
|
+
// ✅ Si es legacy, guarda Bearer token para siguientes llamadas legacy
|
|
40
|
+
if (mode === "legacy") {
|
|
41
|
+
const legacyToken = data?.dataResult?.token || data?.token;
|
|
42
|
+
|
|
43
|
+
if (legacyToken) {
|
|
44
|
+
if (typeof sessionStorage !== "undefined") {
|
|
45
|
+
sessionStorage.setItem("legacy_token", legacyToken);
|
|
46
|
+
}
|
|
47
|
+
if (typeof window !== "undefined") {
|
|
48
|
+
(window as any).__LEGACY_TOKEN__ = legacyToken;
|
|
34
49
|
}
|
|
35
|
-
throw new Error(`Login failed: ${response.status}`);
|
|
36
50
|
}
|
|
51
|
+
}
|
|
37
52
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// No guardar token en memoria, solo usar cookie
|
|
41
|
-
this.apiClient.setToken(null);
|
|
42
|
-
|
|
43
|
-
console.log('✅ Login exitoso, cookie establecida');
|
|
44
|
-
return { ok: true };
|
|
53
|
+
// ✅ Nuevo: cookie HttpOnly, no guardes token en memoria del SDK
|
|
54
|
+
this.apiClient.setToken(null);
|
|
45
55
|
|
|
46
|
-
|
|
47
|
-
console.error('❌ SDK Login error:', error);
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
56
|
+
return { ok: true };
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
async refreshToken(request?: RefreshTokenRequest): Promise<LoginResponse> {
|
|
53
|
-
const response = await this.apiClient.post<LoginResponse>(
|
|
54
|
-
|
|
60
|
+
const response = await this.apiClient.post<LoginResponse>(
|
|
61
|
+
"/auth/refresh",
|
|
62
|
+
request
|
|
63
|
+
);
|
|
64
|
+
if ((response as any)?.token)
|
|
65
|
+
this.apiClient.setToken((response as any).token);
|
|
55
66
|
return response;
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
async logout(): Promise<void> {
|
|
59
70
|
try {
|
|
60
71
|
await this.apiClient.post<void>("/auth/logout");
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error("Error during logout:", error);
|
|
63
72
|
} finally {
|
|
73
|
+
// limpia token nuevo
|
|
64
74
|
this.apiClient.setToken(null);
|
|
75
|
+
|
|
76
|
+
// limpia legacy token
|
|
77
|
+
if (typeof sessionStorage !== "undefined") {
|
|
78
|
+
sessionStorage.removeItem("legacy_token");
|
|
79
|
+
}
|
|
80
|
+
if (typeof window !== "undefined") {
|
|
81
|
+
delete (window as any).__LEGACY_TOKEN__;
|
|
82
|
+
}
|
|
65
83
|
}
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
isAuthenticated(): boolean {
|
|
69
|
-
|
|
87
|
+
const hasToken = this.apiClient.getToken() !== null;
|
|
88
|
+
const hasLegacy =
|
|
89
|
+
(typeof sessionStorage !== "undefined" &&
|
|
90
|
+
!!sessionStorage.getItem("legacy_token")) ||
|
|
91
|
+
(typeof window !== "undefined" && !!(window as any).__LEGACY_TOKEN__);
|
|
92
|
+
|
|
93
|
+
return hasToken || hasLegacy;
|
|
70
94
|
}
|
|
71
95
|
|
|
72
96
|
setToken(token: string | null): void {
|
|
73
97
|
this.apiClient.setToken(token);
|
|
74
98
|
}
|
|
75
|
-
}
|
|
99
|
+
}
|
package/src/types/sdk.ts
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export interface LegacyLoginRequest {
|
|
2
|
-
userName: string;
|
|
3
|
-
password: string;
|
|
4
|
-
}
|
|
5
|
-
export interface LegacyLoginResponse {
|
|
6
|
-
dataResult: {
|
|
7
|
-
token: string;
|
|
8
|
-
userType: string;
|
|
9
|
-
userId: string;
|
|
10
|
-
userName: string;
|
|
11
|
-
area: string;
|
|
12
|
-
id_Area: number;
|
|
13
|
-
id_Role: string;
|
|
14
|
-
};
|
|
15
|
-
statusResponse: {
|
|
16
|
-
code: number;
|
|
17
|
-
success: boolean;
|
|
18
|
-
message: string;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
export declare class LegacyApiClient {
|
|
22
|
-
private baseUrl;
|
|
23
|
-
constructor(baseUrl: string);
|
|
24
|
-
login(userName: string, password: string): Promise<LegacyLoginResponse>;
|
|
25
|
-
logout(): void;
|
|
26
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export class LegacyApiClient {
|
|
2
|
-
constructor(baseUrl) {
|
|
3
|
-
this.baseUrl = baseUrl;
|
|
4
|
-
}
|
|
5
|
-
async login(userName, password) {
|
|
6
|
-
var _a, _b;
|
|
7
|
-
const url = `${this.baseUrl}/auth/login`;
|
|
8
|
-
const response = await fetch(url, {
|
|
9
|
-
method: 'POST',
|
|
10
|
-
headers: { 'Content-Type': 'application/json' },
|
|
11
|
-
credentials: 'include',
|
|
12
|
-
body: JSON.stringify({ userName, password }),
|
|
13
|
-
});
|
|
14
|
-
if (!response.ok) {
|
|
15
|
-
const errorData = await response.json().catch(() => ({
|
|
16
|
-
statusResponse: {
|
|
17
|
-
code: response.status,
|
|
18
|
-
success: false,
|
|
19
|
-
message: response.statusText
|
|
20
|
-
}
|
|
21
|
-
}));
|
|
22
|
-
throw new Error(((_a = errorData.statusResponse) === null || _a === void 0 ? void 0 : _a.message) || 'Legacy login failed');
|
|
23
|
-
}
|
|
24
|
-
const data = await response.json();
|
|
25
|
-
if ((_b = data.dataResult) === null || _b === void 0 ? void 0 : _b.token) {
|
|
26
|
-
sessionStorage.setItem('legacy_token', data.dataResult.token);
|
|
27
|
-
window.__LEGACY_TOKEN__ = data.dataResult.token;
|
|
28
|
-
}
|
|
29
|
-
return data;
|
|
30
|
-
}
|
|
31
|
-
logout() {
|
|
32
|
-
sessionStorage.removeItem('legacy_token');
|
|
33
|
-
delete window.__LEGACY_TOKEN__;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export interface LegacyLoginRequest {
|
|
2
|
-
userName: string;
|
|
3
|
-
password: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface LegacyLoginResponse {
|
|
7
|
-
dataResult: {
|
|
8
|
-
token: string;
|
|
9
|
-
userType: string;
|
|
10
|
-
userId: string;
|
|
11
|
-
userName: string;
|
|
12
|
-
area: string;
|
|
13
|
-
id_Area: number;
|
|
14
|
-
id_Role: string;
|
|
15
|
-
};
|
|
16
|
-
statusResponse: {
|
|
17
|
-
code: number;
|
|
18
|
-
success: boolean;
|
|
19
|
-
message: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class LegacyApiClient {
|
|
24
|
-
private baseUrl: string;
|
|
25
|
-
|
|
26
|
-
constructor(baseUrl: string) {
|
|
27
|
-
this.baseUrl = baseUrl;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async login(userName: string, password: string): Promise<LegacyLoginResponse> {
|
|
31
|
-
const url = `${this.baseUrl}/auth/login`;
|
|
32
|
-
|
|
33
|
-
const response = await fetch(url, {
|
|
34
|
-
method: 'POST',
|
|
35
|
-
headers: { 'Content-Type': 'application/json' },
|
|
36
|
-
credentials: 'include',
|
|
37
|
-
body: JSON.stringify({ userName, password }),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
const errorData = await response.json().catch(() => ({
|
|
42
|
-
statusResponse: {
|
|
43
|
-
code: response.status,
|
|
44
|
-
success: false,
|
|
45
|
-
message: response.statusText
|
|
46
|
-
}
|
|
47
|
-
}));
|
|
48
|
-
|
|
49
|
-
throw new Error(errorData.statusResponse?.message || 'Legacy login failed');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const data: LegacyLoginResponse = await response.json();
|
|
53
|
-
|
|
54
|
-
if (data.dataResult?.token) {
|
|
55
|
-
sessionStorage.setItem('legacy_token', data.dataResult.token);
|
|
56
|
-
(window as any).__LEGACY_TOKEN__ = data.dataResult.token;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return data;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
logout(): void {
|
|
63
|
-
sessionStorage.removeItem('legacy_token');
|
|
64
|
-
delete (window as any).__LEGACY_TOKEN__;
|
|
65
|
-
}
|
|
66
|
-
}
|