@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.
@@ -3,7 +3,6 @@ import { RequestOptions } from "../types/common";
3
3
  import { EventEmitter } from "./event-emitter";
4
4
  export declare class ApiClient {
5
5
  private baseUrl;
6
- private fallbackBaseUrl;
7
6
  private organization;
8
7
  private token;
9
8
  private eventEmitter;
@@ -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 primaryUrl = buildUrl(this.baseUrl, endpoint, params);
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
- // Obtener token legacy
248
- const legacyToken = window.__LEGACY_TOKEN__ ||
249
- sessionStorage.getItem("legacy_token") ||
250
- null;
251
- if (legacyToken) {
252
- headers.set("Authorization", `Bearer ${legacyToken}`);
253
- if (this.debug) {
254
- console.log("🔐 Using legacy token for:", endpoint);
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
- else {
263
- console.warn("⚠️ No token available for endpoint:", endpoint);
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, primaryUrl, data);
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: primaryUrl,
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: "include",
100
+ credentials: this.credentials,
286
101
  };
287
102
  if (data && method !== "GET") {
288
103
  fetchOptions.body = JSON.stringify(data);
289
- if (this.debug) {
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
- // Otros errores (no 404)
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 (_b) {
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, primaryUrl, data);
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: primaryUrl,
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: primaryUrl,
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
- * Login con POST JSON (evita el modal del navegador).
7
- * El servidor setea cookie HttpOnly (zero_token).
8
- */
9
- async login(credentials) {
10
- try {
11
- const response = await fetch(`${this.apiClient['baseUrl']}/auth/login`, {
12
- method: 'POST',
13
- headers: {
14
- 'Content-Type': 'application/json',
15
- 'X-Organization': this.apiClient['organization'] || 'default-org'
16
- },
17
- credentials: 'include', // ← Importante para cookies
18
- body: JSON.stringify({
19
- email: credentials.email,
20
- password: credentials.password
21
- })
22
- });
23
- if (!response.ok) {
24
- if (response.status === 401) {
25
- throw new Error('Invalid credentials');
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
- return this.apiClient.getToken() !== null;
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);
@@ -1,6 +1,5 @@
1
1
  export interface SdkConfig {
2
2
  baseUrl: string;
3
- fallbackBaseUrl?: string;
4
3
  organization: string;
5
4
  token?: string | null;
6
5
  cache?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerosls/clm-sdk",
3
- "version": "1.1.8",
3
+ "version": "1.1.10",
4
4
  "description": "SDK for ZeroCLM API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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
- /*private async request<T>(
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
- // Primer intento con baseUrl normal
137
- const primaryUrl = buildUrl(this.baseUrl, endpoint, params);
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
- // Obtener token legacy
147
- const legacyToken =
148
- (window as any).__LEGACY_TOKEN__ ||
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 (legacyToken) {
153
- headers.set("Authorization", `Bearer ${legacyToken}`);
154
- if (this.debug) {
155
- console.log("🔐 Using legacy token for:", endpoint);
156
- }
157
- } else if (this.token) {
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
- const useCache = this.cacheEnabled && options.useCache !== false;
166
- if (useCache && method === "GET") {
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.eventEmitter.emit("beforeRequest", {
178
- url: primaryUrl,
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, primaryUrl, data);
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: primaryUrl,
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: "include",
183
+ credentials: this.credentials,
368
184
  };
369
185
 
370
186
  if (data && method !== "GET") {
371
187
  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}`);
188
+ console.log(`📤 ${method} Body:`, data);
379
189
  }
380
190
 
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
- }
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, primaryUrl, data);
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: primaryUrl,
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: primaryUrl,
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
- // auth-api.ts
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
- * Login con POST JSON (evita el modal del navegador).
14
- * El servidor setea cookie HttpOnly (zero_token).
15
- */
16
- async login(credentials: LoginCredentials): Promise<{ ok: boolean }> {
17
- try {
18
- const response = await fetch(`${this.apiClient['baseUrl']}/auth/login`, {
19
- method: 'POST',
20
- headers: {
21
- 'Content-Type': 'application/json',
22
- 'X-Organization': this.apiClient['organization'] || 'default-org'
23
- },
24
- credentials: 'include', // ← Importante para cookies
25
- body: JSON.stringify({
26
- email: credentials.email,
27
- password: credentials.password
28
- })
29
- });
30
-
31
- if (!response.ok) {
32
- if (response.status === 401) {
33
- throw new Error('Invalid credentials');
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
- const data = await response.json();
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
- } catch (error) {
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>("/auth/refresh", request);
54
- if ((response as any)?.token) this.apiClient.setToken((response as any).token);
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
- return this.apiClient.getToken() !== null;
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,6 +1,5 @@
1
1
  export interface SdkConfig {
2
2
  baseUrl: string;
3
- fallbackBaseUrl?: string;
4
3
  organization: string;
5
4
  token?: string | null;
6
5
  cache?: {
@@ -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
- }