falconhub-apilibrary 1.4.0-dev.113 → 1.4.0-dev.115

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/index.mjs CHANGED
@@ -1,451 +1,24 @@
1
- // src/core/API.ts
2
- var API = class {
3
- constructor(properties, cryptoService, authInterceptor, getAccessToken, getRefreshToken) {
4
- this.properties = properties;
5
- this.cryptoService = cryptoService;
6
- this.getAccessToken = getAccessToken;
7
- this.getRefreshToken = getRefreshToken;
8
- this.authInterceptor = authInterceptor;
9
- }
10
- /**
11
- * Ejecuta una request HTTP al API
12
- *
13
- * @param options - Opciones de la request
14
- * @returns Respuesta del tipo ResponseModel
15
- */
16
- async apiExecute(options) {
17
- const {
18
- endpoint,
19
- method,
20
- body,
21
- requiresAuth,
22
- timeStamp
23
- } = options;
24
- const context = {
25
- requestId: this.cryptoService.generateUniqueId(),
26
- startTime: Date.now(),
27
- retryCount: 0,
28
- metadata: {}
29
- };
30
- try {
31
- const url = `${this.properties.url}/${endpoint}`;
32
- const headers = {};
33
- if (body && method !== "GET") {
34
- headers["Content-Type"] = "application/json";
35
- }
36
- ;
37
- const accessToken = this.getAccessToken();
38
- if (accessToken) {
39
- headers["Authorization"] = `Bearer ${accessToken}`;
40
- }
41
- ;
42
- const newTimeStamp = timeStamp || (/* @__PURE__ */ new Date()).toISOString();
43
- headers["X-Origin-Request"] = this.properties.originRequest;
44
- headers["X-Timestamp"] = newTimeStamp;
45
- headers["X-Domain"] = this.properties.domain;
46
- headers["X-Device"] = this.properties.device;
47
- headers["X-Source"] = this.properties.source;
48
- let bodyString;
49
- if (body && method !== "GET") {
50
- bodyString = JSON.stringify(body);
51
- }
52
- ;
53
- const requestConfig = {
54
- url,
55
- method,
56
- headers,
57
- body: bodyString,
58
- requiresAuth
59
- };
60
- const modifiedConfig = this.authInterceptor ? await this.authInterceptor.onRequest(requestConfig, context) : requestConfig;
61
- const requestInit = {
62
- method: modifiedConfig.method,
63
- headers: modifiedConfig.headers,
64
- mode: "cors",
65
- credentials: "omit"
66
- };
67
- if (modifiedConfig.body && modifiedConfig.method !== "GET") {
68
- requestInit.body = typeof modifiedConfig.body === "string" ? modifiedConfig.body : JSON.stringify(modifiedConfig.body);
69
- }
70
- ;
71
- const response = await fetch(
72
- modifiedConfig.url,
73
- requestInit
74
- );
75
- const newAccessToken = response.headers.get("X-New-Access-Token");
76
- const newRefreshToken = response.headers.get("X-New-Refresh-Token");
77
- if (newAccessToken || newRefreshToken) {
78
- this.properties.onTokensRefreshed?.({
79
- accessToken: newAccessToken,
80
- refreshToken: newRefreshToken
81
- });
82
- }
83
- ;
84
- let result;
85
- try {
86
- result = await response.json();
87
- } catch (e) {
88
- return {
89
- success: false,
90
- message: `Error de servidor (${response.status}: ${response.statusText || "Formato de respuesta no reconocido"})`,
91
- data: null,
92
- responseTime: (/* @__PURE__ */ new Date()).toISOString()
93
- };
94
- }
95
- if (result && result.errors && typeof result.errors === "object") {
96
- const errorMessages = [];
97
- Object.values(result.errors).forEach((errors) => {
98
- if (Array.isArray(errors)) {
99
- errorMessages.push(...errors);
100
- } else if (typeof errors === "string") {
101
- errorMessages.push(errors);
102
- }
103
- });
104
- if (errorMessages.length > 0) {
105
- return {
106
- success: false,
107
- message: errorMessages.join(", "),
108
- data: result.data ?? null,
109
- responseTime: result.responseTime ?? (/* @__PURE__ */ new Date()).toISOString()
110
- };
111
- }
112
- }
113
- return result;
114
- } catch (error) {
115
- return {
116
- success: false,
117
- message: error instanceof Error ? error.message : "Error inesperado durante la petici\xF3n al API.",
118
- data: null,
119
- responseTime: (/* @__PURE__ */ new Date()).toISOString()
120
- };
121
- }
122
- ;
123
- }
124
- //#region REQUEST METHODS
125
- async executeGET(endpoint, requiresAuth = false) {
126
- return this.apiExecute({
127
- endpoint,
128
- method: "GET",
129
- requiresAuth
130
- });
131
- }
132
- async executePOST(endpoint, body, requiresAuth = true) {
133
- return this.apiExecute({
134
- endpoint,
135
- method: "POST",
136
- body,
137
- requiresAuth
138
- });
139
- }
140
- async executePATCH(endpoint, body, requiresAuth = true) {
141
- return this.apiExecute({
142
- endpoint,
143
- method: "PATCH",
144
- body,
145
- requiresAuth
146
- });
147
- }
148
- async executeDELETE(endpoint, body, requiresAuth = true) {
149
- return this.apiExecute({
150
- endpoint,
151
- method: "DELETE",
152
- body,
153
- requiresAuth
154
- });
155
- }
156
- async executePUT(endpoint, body, requiresAuth = true) {
157
- return this.apiExecute({
158
- endpoint,
159
- method: "PUT",
160
- body,
161
- requiresAuth
162
- });
163
- }
164
- async executePublicRequest(endpoint, method, body, timestamp) {
165
- return this.apiExecute({
166
- endpoint,
167
- method,
168
- body,
169
- requiresAuth: false,
170
- timeStamp: timestamp
171
- });
172
- }
173
- //#endregion
174
- };
175
-
176
- // src/core/CryptoService.ts
177
- import * as CryptoJS from "crypto-js";
178
- var CryptoService = class {
179
- /**
180
- * Genera un hash SHA256 de un texto (útil para fingerprints)
181
- *
182
- * @param text - Texto a hashear
183
- * @returns Hash en formato hexadecimal
184
- */
185
- sha256(text) {
186
- return CryptoJS.SHA256(text).toString(CryptoJS.enc.Hex);
187
- }
188
- /**
189
- * Genera un identificador único basado en timestamp y random
190
- * (útil para request IDs)
191
- *
192
- * @returns ID único
193
- */
194
- generateUniqueId() {
195
- const timestamp = Date.now().toString(36);
196
- const randomPart = Math.random().toString(36).substring(2, 15);
197
- return `${timestamp}-${randomPart}`;
198
- }
199
- };
200
-
201
- // src/core/TokenManager.ts
202
- var TokenManager = class {
203
- constructor(onTokensChanged, onSessionExpiring, onSessionExpired, onSessionRecovery, autoRefreshThresholdMinutes) {
204
- this.tokens = null;
205
- this.sessionCheckInterval = null;
206
- this.autoRefreshTimeout = null;
207
- this.hasNotifiedExpiring = false;
208
- this.autoRefreshThresholdMinutes = 5;
209
- this.onTokensChanged = onTokensChanged;
210
- this.onSessionExpiring = onSessionExpiring;
211
- this.onSessionExpired = onSessionExpired;
212
- this.onSessionRecovery = onSessionRecovery;
213
- this.autoRefreshThresholdMinutes = autoRefreshThresholdMinutes ?? 5;
214
- }
215
- /**
216
- * Guarda los tokens de autenticación y dispara el callback onTokensChanged.
217
- */
218
- setTokens(tokens) {
219
- this.tokens = tokens;
220
- this.hasNotifiedExpiring = false;
221
- this.onTokensChanged?.(this.tokens);
222
- if (!tokens.rememberMe) {
223
- this.startExpirationCheck();
224
- this.stopAutoRefreshTimer();
225
- } else {
226
- this.stopExpirationCheck();
227
- this.scheduleAutoRefresh();
228
- }
229
- ;
230
- }
231
- /**
232
- * Guarda los tokens sin disparar el callback onTokensChanged.
233
- * Usar para inyectar tokens desde storage externo (cookies/localStorage).
234
- */
235
- setTokensSilent(tokens) {
236
- this.tokens = tokens;
237
- this.hasNotifiedExpiring = false;
238
- if (!tokens.rememberMe) {
239
- this.startExpirationCheck();
240
- this.stopAutoRefreshTimer();
241
- } else {
242
- this.stopExpirationCheck();
243
- this.scheduleAutoRefresh();
244
- }
245
- ;
246
- }
247
- /**
248
- * Obtiene los tokens de autenticación almacenados.
249
- */
250
- getTokens() {
251
- return this.tokens;
252
- }
253
- /**
254
- * Limpia los tokens de autenticación almacenados y dispara el callback onTokensChanged.
255
- */
256
- clearTokens() {
257
- this.stopExpirationCheck();
258
- this.stopAutoRefreshTimer();
259
- this.tokens = null;
260
- this.onTokensChanged?.(this.tokens);
261
- }
262
- /**
263
- * Valida si existen tokens y si el access token no ha expirado.
264
- */
265
- hasValidTokens() {
266
- if (!this.tokens) return false;
267
- return Date.now() < this.tokens.expiresAt;
268
- }
269
- /**
270
- * Valida si el access token expirará dentro del umbral especificado (en minutos).
271
- */
272
- isTokenExpiringSoon(thresholdMinutes) {
273
- if (!this.tokens) return false;
274
- const thresholdMs = thresholdMinutes * 60 * 1e3;
275
- const timeLeft = this.tokens.expiresAt - Date.now();
276
- return timeLeft > 0 && timeLeft <= thresholdMs;
277
- }
278
- /**
279
- * Obtiene el tiempo restante hasta la expiración del access token en milisegundos.
280
- */
281
- getTimeUntilExpiry() {
282
- if (!this.tokens) return null;
283
- return Math.max(0, this.tokens.expiresAt - Date.now());
284
- }
285
- /**
286
- * Obtiene el access token almacenado.
287
- */
288
- getAccessToken() {
289
- return this.tokens ? this.tokens.accessToken : null;
290
- }
291
- /**
292
- * Obtiene el refresh token almacenado.
293
- */
294
- getRefreshToken() {
295
- return this.tokens ? this.tokens.refreshToken : null;
296
- }
297
- /**
298
- * Verifica si el auto-refresh debe ejecutarse
299
- * Solo si el usuario activó "rememberMe" durante el login
300
- */
301
- shouldAutoRefresh() {
302
- if (!this.tokens) return false;
303
- return this.tokens.rememberMe === true;
304
- }
305
- /**
306
- * Inicia el monitoreo de expiración para sesiones sin rememberMe
307
- * - Notifica cuando quedan 5 minutos (onSessionExpiring)
308
- */
309
- startExpirationCheck() {
310
- this.stopExpirationCheck();
311
- this.sessionCheckInterval = setInterval(async () => {
312
- if (!this.tokens) {
313
- this.stopExpirationCheck();
314
- return;
315
- }
316
- ;
317
- const timeLeft = this.getTimeUntilExpiry();
318
- if (timeLeft === null) return;
319
- const minutesLeft = Math.floor(timeLeft / (60 * 1e3));
320
- if (minutesLeft <= 5 && minutesLeft > 1 && !this.hasNotifiedExpiring) {
321
- this.hasNotifiedExpiring = true;
322
- this.onSessionExpiring?.(minutesLeft);
323
- }
324
- ;
325
- if (minutesLeft <= 1) {
326
- this.stopExpirationCheck();
327
- if (this.onSessionRecovery) {
328
- try {
329
- const recovered = await this.onSessionRecovery();
330
- if (recovered) return;
331
- } catch (error) {
332
- }
333
- }
334
- if (this.onSessionExpired) {
335
- await this.onSessionExpired();
336
- }
337
- ;
338
- }
339
- ;
340
- }, 6e4);
341
- }
342
- /**
343
- * Programa un auto-refresh proactivo para sesiones con rememberMe.
344
- * Se ejecuta X minutos antes de que expire el token
345
- */
346
- scheduleAutoRefresh() {
347
- this.stopAutoRefreshTimer();
348
- if (!this.tokens || !this.tokens.rememberMe) return;
349
- const timeLeft = this.getTimeUntilExpiry();
350
- if (timeLeft === null || timeLeft <= 0) return;
351
- const thresholdMs = this.autoRefreshThresholdMinutes * 60 * 1e3;
352
- const delay = Math.max(0, timeLeft - thresholdMs);
353
- this.autoRefreshTimeout = setTimeout(async () => {
354
- if (!this.tokens || !this.tokens.rememberMe) return;
355
- if (this.onSessionRecovery) {
356
- try {
357
- const recovered = await this.onSessionRecovery();
358
- if (recovered) return;
359
- } catch (error) {
360
- }
361
- }
362
- if (this.onSessionExpired) {
363
- await this.onSessionExpired();
364
- }
365
- }, delay);
366
- }
367
- /**
368
- * Detiene el monitoreo de expiración
369
- */
370
- stopExpirationCheck() {
371
- if (this.sessionCheckInterval) {
372
- clearInterval(this.sessionCheckInterval);
373
- this.sessionCheckInterval = null;
374
- }
375
- ;
376
- }
377
- /**
378
- * Detiene el timer de auto-refresh proactivo
379
- */
380
- stopAutoRefreshTimer() {
381
- if (this.autoRefreshTimeout) {
382
- clearTimeout(this.autoRefreshTimeout);
383
- this.autoRefreshTimeout = null;
384
- }
385
- ;
386
- }
387
- };
388
-
389
- // src/core/interceptors/AuthInterceptor.ts
390
- var AuthInterceptor = class {
391
- constructor(config) {
392
- this.name = "AuthInterceptor";
393
- this.refreshPromise = null;
394
- this.isRefreshing = false;
395
- this.config = {
396
- enabled: config.enabled ?? true,
397
- thresholdMinutes: config.thresholdMinutes ?? 5,
398
- isTokenExpiringSoon: config.isTokenExpiringSoon,
399
- hasValidTokens: config.hasValidTokens,
400
- shouldAutoRefresh: config.shouldAutoRefresh,
401
- refreshSession: config.refreshSession
402
- };
403
- }
404
- async onRequest(config, context) {
405
- if (!config.requiresAuth || !this.config.enabled) {
406
- return config;
407
- }
408
- ;
409
- if (!this.config.hasValidTokens()) {
410
- return config;
411
- }
412
- ;
413
- if (!this.config.shouldAutoRefresh()) {
414
- return config;
415
- }
416
- ;
417
- if (this.config.isTokenExpiringSoon()) {
418
- try {
419
- if (this.isRefreshing && this.refreshPromise) {
420
- await this.refreshPromise;
421
- } else {
422
- this.isRefreshing = true;
423
- this.refreshPromise = this.config.refreshSession();
424
- await this.refreshPromise;
425
- this.isRefreshing = false;
426
- this.refreshPromise = null;
427
- }
428
- ;
429
- } catch (error) {
430
- this.isRefreshing = false;
431
- this.refreshPromise = null;
432
- }
433
- ;
434
- }
435
- ;
436
- return config;
437
- }
438
- updateConfig(config) {
439
- this.config = {
440
- ...this.config,
441
- ...config
442
- };
443
- }
444
- reset() {
445
- this.isRefreshing = false;
446
- this.refreshPromise = null;
447
- }
1
+ // src/interfaces/Product/Blank/BlankInterface.ts
2
+ var BLANKS_BULK_COLUMN_MAP = {
3
+ "Titulo del Blank": "blank",
4
+ "SKU": "sku",
5
+ "Costo": "cost",
6
+ "Color": "color",
7
+ "Proveedor": "provider",
8
+ "Material": "material",
9
+ "Talla": "size",
10
+ "Activo": "isActive"
448
11
  };
12
+ var BLANKS_BULK_SPANISH_HEADERS = [
13
+ "Titulo del Blank",
14
+ "SKU",
15
+ "Costo",
16
+ "Color",
17
+ "Proveedor",
18
+ "Material",
19
+ "Talla",
20
+ "Activo"
21
+ ];
449
22
 
450
23
  // src/types/ErrorResponse.ts
451
24
  var ErrorResponse = class extends Error {
@@ -1244,6 +817,18 @@ var ProductService = class {
1244
817
  async deleteBlank(id) {
1245
818
  return this.api.executeDELETE(`${this.BASE_PATH}/blanks/${id}`);
1246
819
  }
820
+ /**
821
+ * Obtiene la plantilla para la carga masiva de blanks.
822
+ */
823
+ async getBlanksBulkTemplate() {
824
+ return this.api.executeGET(`${this.BASE_PATH}/blanks/bulk/template`, false);
825
+ }
826
+ /**
827
+ * Realiza una carga masiva de blanks.
828
+ */
829
+ async bulkCreateBlanks(request) {
830
+ return this.api.executePOST(`${this.BASE_PATH}/blanks/bulk`, request);
831
+ }
1247
832
  // #endregion
1248
833
  };
1249
834
 
@@ -1496,154 +1081,603 @@ var UserService = class {
1496
1081
  return this.api.executeGET(`${this.BASE_PATH}/admin/${id}`, true);
1497
1082
  }
1498
1083
  /**
1499
- * Obtiene la autenticación de un administrador.
1500
- * @param id - ID del usuario
1084
+ * Obtiene la autenticación de un administrador.
1085
+ * @param id - ID del usuario
1086
+ */
1087
+ async getAdminAuthentication(id) {
1088
+ return this.api.executeGET(`${this.BASE_PATH}/admin/authentication/${id}`, true);
1089
+ }
1090
+ /**
1091
+ * Actualiza un administrador existente.
1092
+ * @param id - ID del administrador
1093
+ * @param request - Nuevos datos del administrador
1094
+ */
1095
+ async updateAdmin(id, request) {
1096
+ return this.api.executePUT(`${this.BASE_PATH}/admin/${id}`, request);
1097
+ }
1098
+ /**
1099
+ * Activa o desactiva un administrador.
1100
+ * @param id - ID del administrador
1101
+ */
1102
+ async toggleAdminStatus(id) {
1103
+ return this.api.executePUT(`${this.BASE_PATH}/admin/${id}/toggle-status`);
1104
+ }
1105
+ /**
1106
+ * Actualiza la autenticación de un administrador.
1107
+ * @param id - ID del usuario
1108
+ * @param request - Nuevos datos de autenticación
1109
+ */
1110
+ async updateAdminAuthentication(id, request) {
1111
+ return this.api.executePUT(`${this.BASE_PATH}/admin/authentication/${id}`, request);
1112
+ }
1113
+ /**
1114
+ * Elimina un administrador.
1115
+ * @param id - ID del administrador
1116
+ */
1117
+ async deleteAdmin(id) {
1118
+ return this.api.executeDELETE(`${this.BASE_PATH}/admin/${id}`);
1119
+ }
1120
+ /**
1121
+ * Reenvía el correo de confirmación al usuario.
1122
+ * @param id - ID del usuario
1123
+ */
1124
+ async resendEmailConfirmation(id) {
1125
+ return this.api.executePOST(`${this.BASE_PATH}/admin/authentication/${id}/resend-confirmation`);
1126
+ }
1127
+ // #endregion
1128
+ // #region User Types
1129
+ /**
1130
+ * Obtiene todos los tipos de usuario con filtros opcionales.
1131
+ * @param filter - Filtros opcionales para la búsqueda
1132
+ */
1133
+ async getUserTypes(filter) {
1134
+ const endpoint = FilterBuilder.buildEndpoint(`${this.BASE_PATH}/catalogs/user-types`, filter);
1135
+ return this.api.executeGET(endpoint, true);
1136
+ }
1137
+ /**
1138
+ * Obtiene el modelo de filtros disponibles para tipos de usuario.
1139
+ */
1140
+ async getUserTypesFilters() {
1141
+ return this.api.executeGET(`${this.BASE_PATH}/catalogs/user-types/filters`, true);
1142
+ }
1143
+ /**
1144
+ * Obtiene un tipo de usuario por su ID.
1145
+ * @param id - ID del tipo de usuario
1146
+ */
1147
+ async getUserTypeById(id) {
1148
+ return this.api.executeGET(`${this.BASE_PATH}/catalogs/user-types/${id}`, true);
1149
+ }
1150
+ /**
1151
+ * Crea un nuevo tipo de usuario.
1152
+ * @param request - Datos del tipo de usuario a crear
1153
+ */
1154
+ async createUserType(request) {
1155
+ return this.api.executePOST(`${this.BASE_PATH}/catalogs/user-types`, request);
1156
+ }
1157
+ /**
1158
+ * Actualiza un tipo de usuario existente.
1159
+ * @param id - ID del tipo de usuario a actualizar
1160
+ * @param request - Nuevos datos del tipo de usuario
1161
+ */
1162
+ async updateUserType(id, request) {
1163
+ return this.api.executePUT(`${this.BASE_PATH}/catalogs/user-types/${id}`, request);
1164
+ }
1165
+ /**
1166
+ * Elimina un tipo de usuario.
1167
+ * @param id - ID del tipo de usuario a eliminar
1168
+ */
1169
+ async deleteUserType(id) {
1170
+ return this.api.executeDELETE(`${this.BASE_PATH}/catalogs/user-types/${id}`);
1171
+ }
1172
+ // #endregion
1173
+ // #region Roles
1174
+ /**
1175
+ * Obtiene todos los roles con filtros opcionales.
1176
+ * @param filter - Filtros opcionales para la búsqueda
1177
+ */
1178
+ async getRoles(filter) {
1179
+ const endpoint = FilterBuilder.buildEndpoint(`${this.BASE_PATH}/catalogs/roles`, filter);
1180
+ return this.api.executeGET(endpoint, true);
1181
+ }
1182
+ /**
1183
+ * Obtiene el modelo de filtros disponibles para roles.
1184
+ */
1185
+ async getRolesFilters() {
1186
+ return this.api.executeGET(`${this.BASE_PATH}/catalogs/roles/filters`, true);
1187
+ }
1188
+ /**
1189
+ * Obtiene un rol por su ID.
1190
+ * @param id - ID del rol
1191
+ */
1192
+ async getRoleById(id) {
1193
+ return this.api.executeGET(`${this.BASE_PATH}/catalogs/roles/${id}`, true);
1194
+ }
1195
+ /**
1196
+ * Obtiene los roles asociados a un tipo de usuario.
1197
+ * @param userTypeId - ID del tipo de usuario
1198
+ */
1199
+ async getRolesByUserType(userTypeId) {
1200
+ return this.api.executeGET(`${this.BASE_PATH}/catalogs/roles/user-type/${userTypeId}`, true);
1201
+ }
1202
+ /**
1203
+ * Crea un nuevo rol.
1204
+ * @param request - Datos del rol a crear
1501
1205
  */
1502
- async getAdminAuthentication(id) {
1503
- return this.api.executeGET(`${this.BASE_PATH}/admin/authentication/${id}`, true);
1206
+ async createRole(request) {
1207
+ return this.api.executePOST(`${this.BASE_PATH}/catalogs/roles`, request);
1504
1208
  }
1505
1209
  /**
1506
- * Actualiza un administrador existente.
1507
- * @param id - ID del administrador
1508
- * @param request - Nuevos datos del administrador
1210
+ * Actualiza un rol existente.
1211
+ * @param id - ID del rol a actualizar
1212
+ * @param request - Nuevos datos del rol
1509
1213
  */
1510
- async updateAdmin(id, request) {
1511
- return this.api.executePUT(`${this.BASE_PATH}/admin/${id}`, request);
1214
+ async updateRole(id, request) {
1215
+ return this.api.executePUT(`${this.BASE_PATH}/catalogs/roles/${id}`, request);
1512
1216
  }
1513
1217
  /**
1514
- * Activa o desactiva un administrador.
1515
- * @param id - ID del administrador
1218
+ * Activa o desactiva un rol.
1219
+ * @param id - ID del rol
1516
1220
  */
1517
- async toggleAdminStatus(id) {
1518
- return this.api.executePUT(`${this.BASE_PATH}/admin/${id}/toggle-status`);
1221
+ async toggleRoleStatus(id) {
1222
+ return this.api.executePUT(`${this.BASE_PATH}/catalogs/roles/${id}/toggle-status`);
1519
1223
  }
1520
1224
  /**
1521
- * Actualiza la autenticación de un administrador.
1522
- * @param id - ID del usuario
1523
- * @param request - Nuevos datos de autenticación
1225
+ * Elimina un rol.
1226
+ * @param id - ID del rol a eliminar
1524
1227
  */
1525
- async updateAdminAuthentication(id, request) {
1526
- return this.api.executePUT(`${this.BASE_PATH}/admin/authentication/${id}`, request);
1228
+ async deleteRole(id) {
1229
+ return this.api.executeDELETE(`${this.BASE_PATH}/catalogs/roles/${id}`);
1230
+ }
1231
+ // #endregion
1232
+ };
1233
+
1234
+ // src/core/API.ts
1235
+ var API = class {
1236
+ constructor(properties, cryptoService, authInterceptor, getAccessToken, getRefreshToken) {
1237
+ this.properties = properties;
1238
+ this.cryptoService = cryptoService;
1239
+ this.getAccessToken = getAccessToken;
1240
+ this.getRefreshToken = getRefreshToken;
1241
+ this.authInterceptor = authInterceptor;
1527
1242
  }
1528
1243
  /**
1529
- * Elimina un administrador.
1530
- * @param id - ID del administrador
1244
+ * Ejecuta una request HTTP al API
1245
+ *
1246
+ * @param options - Opciones de la request
1247
+ * @returns Respuesta del tipo ResponseModel
1531
1248
  */
1532
- async deleteAdmin(id) {
1533
- return this.api.executeDELETE(`${this.BASE_PATH}/admin/${id}`);
1249
+ async apiExecute(options) {
1250
+ const {
1251
+ endpoint,
1252
+ method,
1253
+ body,
1254
+ requiresAuth,
1255
+ timeStamp
1256
+ } = options;
1257
+ const context = {
1258
+ requestId: this.cryptoService.generateUniqueId(),
1259
+ startTime: Date.now(),
1260
+ retryCount: 0,
1261
+ metadata: {}
1262
+ };
1263
+ try {
1264
+ const url = `${this.properties.url}/${endpoint}`;
1265
+ const headers = {};
1266
+ if (body && method !== "GET") {
1267
+ headers["Content-Type"] = "application/json";
1268
+ }
1269
+ ;
1270
+ const accessToken = this.getAccessToken();
1271
+ if (accessToken) {
1272
+ headers["Authorization"] = `Bearer ${accessToken}`;
1273
+ }
1274
+ ;
1275
+ const newTimeStamp = timeStamp || (/* @__PURE__ */ new Date()).toISOString();
1276
+ headers["X-Origin-Request"] = this.properties.originRequest;
1277
+ headers["X-Timestamp"] = newTimeStamp;
1278
+ headers["X-Domain"] = this.properties.domain;
1279
+ headers["X-Device"] = this.properties.device;
1280
+ headers["X-Source"] = this.properties.source;
1281
+ let bodyString;
1282
+ if (body && method !== "GET") {
1283
+ bodyString = JSON.stringify(body);
1284
+ }
1285
+ ;
1286
+ const requestConfig = {
1287
+ url,
1288
+ method,
1289
+ headers,
1290
+ body: bodyString,
1291
+ requiresAuth
1292
+ };
1293
+ const modifiedConfig = this.authInterceptor ? await this.authInterceptor.onRequest(requestConfig, context) : requestConfig;
1294
+ const requestInit = {
1295
+ method: modifiedConfig.method,
1296
+ headers: modifiedConfig.headers,
1297
+ mode: "cors",
1298
+ credentials: "omit"
1299
+ };
1300
+ if (modifiedConfig.body && modifiedConfig.method !== "GET") {
1301
+ requestInit.body = typeof modifiedConfig.body === "string" ? modifiedConfig.body : JSON.stringify(modifiedConfig.body);
1302
+ }
1303
+ ;
1304
+ const response = await fetch(
1305
+ modifiedConfig.url,
1306
+ requestInit
1307
+ );
1308
+ const newAccessToken = response.headers.get("X-New-Access-Token");
1309
+ const newRefreshToken = response.headers.get("X-New-Refresh-Token");
1310
+ if (newAccessToken || newRefreshToken) {
1311
+ this.properties.onTokensRefreshed?.({
1312
+ accessToken: newAccessToken,
1313
+ refreshToken: newRefreshToken
1314
+ });
1315
+ }
1316
+ ;
1317
+ let result;
1318
+ try {
1319
+ result = await response.json();
1320
+ } catch (e) {
1321
+ return {
1322
+ success: false,
1323
+ message: `Error de servidor (${response.status}: ${response.statusText || "Formato de respuesta no reconocido"})`,
1324
+ data: null,
1325
+ responseTime: (/* @__PURE__ */ new Date()).toISOString()
1326
+ };
1327
+ }
1328
+ if (result && result.errors && typeof result.errors === "object") {
1329
+ const errorMessages = [];
1330
+ Object.values(result.errors).forEach((errors) => {
1331
+ if (Array.isArray(errors)) {
1332
+ errorMessages.push(...errors);
1333
+ } else if (typeof errors === "string") {
1334
+ errorMessages.push(errors);
1335
+ }
1336
+ });
1337
+ if (errorMessages.length > 0) {
1338
+ return {
1339
+ success: false,
1340
+ message: errorMessages.join(", "),
1341
+ data: result.data ?? null,
1342
+ responseTime: result.responseTime ?? (/* @__PURE__ */ new Date()).toISOString()
1343
+ };
1344
+ }
1345
+ }
1346
+ return result;
1347
+ } catch (error) {
1348
+ return {
1349
+ success: false,
1350
+ message: error instanceof Error ? error.message : "Error inesperado durante la petici\xF3n al API.",
1351
+ data: null,
1352
+ responseTime: (/* @__PURE__ */ new Date()).toISOString()
1353
+ };
1354
+ }
1355
+ ;
1356
+ }
1357
+ //#region REQUEST METHODS
1358
+ async executeGET(endpoint, requiresAuth = false) {
1359
+ return this.apiExecute({
1360
+ endpoint,
1361
+ method: "GET",
1362
+ requiresAuth
1363
+ });
1364
+ }
1365
+ async executePOST(endpoint, body, requiresAuth = true) {
1366
+ return this.apiExecute({
1367
+ endpoint,
1368
+ method: "POST",
1369
+ body,
1370
+ requiresAuth
1371
+ });
1372
+ }
1373
+ async executePATCH(endpoint, body, requiresAuth = true) {
1374
+ return this.apiExecute({
1375
+ endpoint,
1376
+ method: "PATCH",
1377
+ body,
1378
+ requiresAuth
1379
+ });
1380
+ }
1381
+ async executeDELETE(endpoint, body, requiresAuth = true) {
1382
+ return this.apiExecute({
1383
+ endpoint,
1384
+ method: "DELETE",
1385
+ body,
1386
+ requiresAuth
1387
+ });
1388
+ }
1389
+ async executePUT(endpoint, body, requiresAuth = true) {
1390
+ return this.apiExecute({
1391
+ endpoint,
1392
+ method: "PUT",
1393
+ body,
1394
+ requiresAuth
1395
+ });
1396
+ }
1397
+ async executePublicRequest(endpoint, method, body, timestamp) {
1398
+ return this.apiExecute({
1399
+ endpoint,
1400
+ method,
1401
+ body,
1402
+ requiresAuth: false,
1403
+ timeStamp: timestamp
1404
+ });
1534
1405
  }
1406
+ //#endregion
1407
+ };
1408
+
1409
+ // src/core/CryptoService.ts
1410
+ import * as CryptoJS from "crypto-js";
1411
+ var CryptoService = class {
1535
1412
  /**
1536
- * Reenvía el correo de confirmación al usuario.
1537
- * @param id - ID del usuario
1538
- */
1539
- async resendEmailConfirmation(id) {
1540
- return this.api.executePOST(`${this.BASE_PATH}/admin/authentication/${id}/resend-confirmation`);
1413
+ * Genera un hash SHA256 de un texto (útil para fingerprints)
1414
+ *
1415
+ * @param text - Texto a hashear
1416
+ * @returns Hash en formato hexadecimal
1417
+ */
1418
+ sha256(text) {
1419
+ return CryptoJS.SHA256(text).toString(CryptoJS.enc.Hex);
1420
+ }
1421
+ /**
1422
+ * Genera un identificador único basado en timestamp y random
1423
+ * (útil para request IDs)
1424
+ *
1425
+ * @returns ID único
1426
+ */
1427
+ generateUniqueId() {
1428
+ const timestamp = Date.now().toString(36);
1429
+ const randomPart = Math.random().toString(36).substring(2, 15);
1430
+ return `${timestamp}-${randomPart}`;
1431
+ }
1432
+ };
1433
+
1434
+ // src/core/TokenManager.ts
1435
+ var TokenManager = class {
1436
+ constructor(onTokensChanged, onSessionExpiring, onSessionExpired, onSessionRecovery, autoRefreshThresholdMinutes) {
1437
+ this.tokens = null;
1438
+ this.sessionCheckInterval = null;
1439
+ this.autoRefreshTimeout = null;
1440
+ this.hasNotifiedExpiring = false;
1441
+ this.autoRefreshThresholdMinutes = 5;
1442
+ this.onTokensChanged = onTokensChanged;
1443
+ this.onSessionExpiring = onSessionExpiring;
1444
+ this.onSessionExpired = onSessionExpired;
1445
+ this.onSessionRecovery = onSessionRecovery;
1446
+ this.autoRefreshThresholdMinutes = autoRefreshThresholdMinutes ?? 5;
1541
1447
  }
1542
- // #endregion
1543
- // #region User Types
1544
1448
  /**
1545
- * Obtiene todos los tipos de usuario con filtros opcionales.
1546
- * @param filter - Filtros opcionales para la búsqueda
1449
+ * Guarda los tokens de autenticación y dispara el callback onTokensChanged.
1547
1450
  */
1548
- async getUserTypes(filter) {
1549
- const endpoint = FilterBuilder.buildEndpoint(`${this.BASE_PATH}/catalogs/user-types`, filter);
1550
- return this.api.executeGET(endpoint, true);
1451
+ setTokens(tokens) {
1452
+ this.tokens = tokens;
1453
+ this.hasNotifiedExpiring = false;
1454
+ this.onTokensChanged?.(this.tokens);
1455
+ if (!tokens.rememberMe) {
1456
+ this.startExpirationCheck();
1457
+ this.stopAutoRefreshTimer();
1458
+ } else {
1459
+ this.stopExpirationCheck();
1460
+ this.scheduleAutoRefresh();
1461
+ }
1462
+ ;
1551
1463
  }
1552
1464
  /**
1553
- * Obtiene el modelo de filtros disponibles para tipos de usuario.
1465
+ * Guarda los tokens sin disparar el callback onTokensChanged.
1466
+ * Usar para inyectar tokens desde storage externo (cookies/localStorage).
1554
1467
  */
1555
- async getUserTypesFilters() {
1556
- return this.api.executeGET(`${this.BASE_PATH}/catalogs/user-types/filters`, true);
1468
+ setTokensSilent(tokens) {
1469
+ this.tokens = tokens;
1470
+ this.hasNotifiedExpiring = false;
1471
+ if (!tokens.rememberMe) {
1472
+ this.startExpirationCheck();
1473
+ this.stopAutoRefreshTimer();
1474
+ } else {
1475
+ this.stopExpirationCheck();
1476
+ this.scheduleAutoRefresh();
1477
+ }
1478
+ ;
1557
1479
  }
1558
1480
  /**
1559
- * Obtiene un tipo de usuario por su ID.
1560
- * @param id - ID del tipo de usuario
1481
+ * Obtiene los tokens de autenticación almacenados.
1561
1482
  */
1562
- async getUserTypeById(id) {
1563
- return this.api.executeGET(`${this.BASE_PATH}/catalogs/user-types/${id}`, true);
1483
+ getTokens() {
1484
+ return this.tokens;
1564
1485
  }
1565
1486
  /**
1566
- * Crea un nuevo tipo de usuario.
1567
- * @param request - Datos del tipo de usuario a crear
1487
+ * Limpia los tokens de autenticación almacenados y dispara el callback onTokensChanged.
1568
1488
  */
1569
- async createUserType(request) {
1570
- return this.api.executePOST(`${this.BASE_PATH}/catalogs/user-types`, request);
1489
+ clearTokens() {
1490
+ this.stopExpirationCheck();
1491
+ this.stopAutoRefreshTimer();
1492
+ this.tokens = null;
1493
+ this.onTokensChanged?.(this.tokens);
1571
1494
  }
1572
1495
  /**
1573
- * Actualiza un tipo de usuario existente.
1574
- * @param id - ID del tipo de usuario a actualizar
1575
- * @param request - Nuevos datos del tipo de usuario
1496
+ * Valida si existen tokens y si el access token no ha expirado.
1576
1497
  */
1577
- async updateUserType(id, request) {
1578
- return this.api.executePUT(`${this.BASE_PATH}/catalogs/user-types/${id}`, request);
1498
+ hasValidTokens() {
1499
+ if (!this.tokens) return false;
1500
+ return Date.now() < this.tokens.expiresAt;
1579
1501
  }
1580
1502
  /**
1581
- * Elimina un tipo de usuario.
1582
- * @param id - ID del tipo de usuario a eliminar
1503
+ * Valida si el access token expirará dentro del umbral especificado (en minutos).
1583
1504
  */
1584
- async deleteUserType(id) {
1585
- return this.api.executeDELETE(`${this.BASE_PATH}/catalogs/user-types/${id}`);
1505
+ isTokenExpiringSoon(thresholdMinutes) {
1506
+ if (!this.tokens) return false;
1507
+ const thresholdMs = thresholdMinutes * 60 * 1e3;
1508
+ const timeLeft = this.tokens.expiresAt - Date.now();
1509
+ return timeLeft > 0 && timeLeft <= thresholdMs;
1586
1510
  }
1587
- // #endregion
1588
- // #region Roles
1589
1511
  /**
1590
- * Obtiene todos los roles con filtros opcionales.
1591
- * @param filter - Filtros opcionales para la búsqueda
1512
+ * Obtiene el tiempo restante hasta la expiración del access token en milisegundos.
1592
1513
  */
1593
- async getRoles(filter) {
1594
- const endpoint = FilterBuilder.buildEndpoint(`${this.BASE_PATH}/catalogs/roles`, filter);
1595
- return this.api.executeGET(endpoint, true);
1514
+ getTimeUntilExpiry() {
1515
+ if (!this.tokens) return null;
1516
+ return Math.max(0, this.tokens.expiresAt - Date.now());
1596
1517
  }
1597
1518
  /**
1598
- * Obtiene el modelo de filtros disponibles para roles.
1519
+ * Obtiene el access token almacenado.
1599
1520
  */
1600
- async getRolesFilters() {
1601
- return this.api.executeGET(`${this.BASE_PATH}/catalogs/roles/filters`, true);
1521
+ getAccessToken() {
1522
+ return this.tokens ? this.tokens.accessToken : null;
1602
1523
  }
1603
1524
  /**
1604
- * Obtiene un rol por su ID.
1605
- * @param id - ID del rol
1525
+ * Obtiene el refresh token almacenado.
1606
1526
  */
1607
- async getRoleById(id) {
1608
- return this.api.executeGET(`${this.BASE_PATH}/catalogs/roles/${id}`, true);
1527
+ getRefreshToken() {
1528
+ return this.tokens ? this.tokens.refreshToken : null;
1609
1529
  }
1610
1530
  /**
1611
- * Obtiene los roles asociados a un tipo de usuario.
1612
- * @param userTypeId - ID del tipo de usuario
1531
+ * Verifica si el auto-refresh debe ejecutarse
1532
+ * Solo si el usuario activó "rememberMe" durante el login
1613
1533
  */
1614
- async getRolesByUserType(userTypeId) {
1615
- return this.api.executeGET(`${this.BASE_PATH}/catalogs/roles/user-type/${userTypeId}`, true);
1534
+ shouldAutoRefresh() {
1535
+ if (!this.tokens) return false;
1536
+ return this.tokens.rememberMe === true;
1616
1537
  }
1617
1538
  /**
1618
- * Crea un nuevo rol.
1619
- * @param request - Datos del rol a crear
1539
+ * Inicia el monitoreo de expiración para sesiones sin rememberMe
1540
+ * - Notifica cuando quedan 5 minutos (onSessionExpiring)
1620
1541
  */
1621
- async createRole(request) {
1622
- return this.api.executePOST(`${this.BASE_PATH}/catalogs/roles`, request);
1542
+ startExpirationCheck() {
1543
+ this.stopExpirationCheck();
1544
+ this.sessionCheckInterval = setInterval(async () => {
1545
+ if (!this.tokens) {
1546
+ this.stopExpirationCheck();
1547
+ return;
1548
+ }
1549
+ ;
1550
+ const timeLeft = this.getTimeUntilExpiry();
1551
+ if (timeLeft === null) return;
1552
+ const minutesLeft = Math.floor(timeLeft / (60 * 1e3));
1553
+ if (minutesLeft <= 5 && minutesLeft > 1 && !this.hasNotifiedExpiring) {
1554
+ this.hasNotifiedExpiring = true;
1555
+ this.onSessionExpiring?.(minutesLeft);
1556
+ }
1557
+ ;
1558
+ if (minutesLeft <= 1) {
1559
+ this.stopExpirationCheck();
1560
+ if (this.onSessionRecovery) {
1561
+ try {
1562
+ const recovered = await this.onSessionRecovery();
1563
+ if (recovered) return;
1564
+ } catch (error) {
1565
+ }
1566
+ }
1567
+ if (this.onSessionExpired) {
1568
+ await this.onSessionExpired();
1569
+ }
1570
+ ;
1571
+ }
1572
+ ;
1573
+ }, 6e4);
1623
1574
  }
1624
1575
  /**
1625
- * Actualiza un rol existente.
1626
- * @param id - ID del rol a actualizar
1627
- * @param request - Nuevos datos del rol
1576
+ * Programa un auto-refresh proactivo para sesiones con rememberMe.
1577
+ * Se ejecuta X minutos antes de que expire el token
1628
1578
  */
1629
- async updateRole(id, request) {
1630
- return this.api.executePUT(`${this.BASE_PATH}/catalogs/roles/${id}`, request);
1579
+ scheduleAutoRefresh() {
1580
+ this.stopAutoRefreshTimer();
1581
+ if (!this.tokens || !this.tokens.rememberMe) return;
1582
+ const timeLeft = this.getTimeUntilExpiry();
1583
+ if (timeLeft === null || timeLeft <= 0) return;
1584
+ const thresholdMs = this.autoRefreshThresholdMinutes * 60 * 1e3;
1585
+ const delay = Math.max(0, timeLeft - thresholdMs);
1586
+ this.autoRefreshTimeout = setTimeout(async () => {
1587
+ if (!this.tokens || !this.tokens.rememberMe) return;
1588
+ if (this.onSessionRecovery) {
1589
+ try {
1590
+ const recovered = await this.onSessionRecovery();
1591
+ if (recovered) return;
1592
+ } catch (error) {
1593
+ }
1594
+ }
1595
+ if (this.onSessionExpired) {
1596
+ await this.onSessionExpired();
1597
+ }
1598
+ }, delay);
1631
1599
  }
1632
1600
  /**
1633
- * Activa o desactiva un rol.
1634
- * @param id - ID del rol
1601
+ * Detiene el monitoreo de expiración
1635
1602
  */
1636
- async toggleRoleStatus(id) {
1637
- return this.api.executePUT(`${this.BASE_PATH}/catalogs/roles/${id}/toggle-status`);
1603
+ stopExpirationCheck() {
1604
+ if (this.sessionCheckInterval) {
1605
+ clearInterval(this.sessionCheckInterval);
1606
+ this.sessionCheckInterval = null;
1607
+ }
1608
+ ;
1638
1609
  }
1639
1610
  /**
1640
- * Elimina un rol.
1641
- * @param id - ID del rol a eliminar
1611
+ * Detiene el timer de auto-refresh proactivo
1642
1612
  */
1643
- async deleteRole(id) {
1644
- return this.api.executeDELETE(`${this.BASE_PATH}/catalogs/roles/${id}`);
1613
+ stopAutoRefreshTimer() {
1614
+ if (this.autoRefreshTimeout) {
1615
+ clearTimeout(this.autoRefreshTimeout);
1616
+ this.autoRefreshTimeout = null;
1617
+ }
1618
+ ;
1619
+ }
1620
+ };
1621
+
1622
+ // src/core/interceptors/AuthInterceptor.ts
1623
+ var AuthInterceptor = class {
1624
+ constructor(config) {
1625
+ this.name = "AuthInterceptor";
1626
+ this.refreshPromise = null;
1627
+ this.isRefreshing = false;
1628
+ this.config = {
1629
+ enabled: config.enabled ?? true,
1630
+ thresholdMinutes: config.thresholdMinutes ?? 5,
1631
+ isTokenExpiringSoon: config.isTokenExpiringSoon,
1632
+ hasValidTokens: config.hasValidTokens,
1633
+ shouldAutoRefresh: config.shouldAutoRefresh,
1634
+ refreshSession: config.refreshSession
1635
+ };
1636
+ }
1637
+ async onRequest(config, context) {
1638
+ if (!config.requiresAuth || !this.config.enabled) {
1639
+ return config;
1640
+ }
1641
+ ;
1642
+ if (!this.config.hasValidTokens()) {
1643
+ return config;
1644
+ }
1645
+ ;
1646
+ if (!this.config.shouldAutoRefresh()) {
1647
+ return config;
1648
+ }
1649
+ ;
1650
+ if (this.config.isTokenExpiringSoon()) {
1651
+ try {
1652
+ if (this.isRefreshing && this.refreshPromise) {
1653
+ await this.refreshPromise;
1654
+ } else {
1655
+ this.isRefreshing = true;
1656
+ this.refreshPromise = this.config.refreshSession();
1657
+ await this.refreshPromise;
1658
+ this.isRefreshing = false;
1659
+ this.refreshPromise = null;
1660
+ }
1661
+ ;
1662
+ } catch (error) {
1663
+ this.isRefreshing = false;
1664
+ this.refreshPromise = null;
1665
+ }
1666
+ ;
1667
+ }
1668
+ ;
1669
+ return config;
1670
+ }
1671
+ updateConfig(config) {
1672
+ this.config = {
1673
+ ...this.config,
1674
+ ...config
1675
+ };
1676
+ }
1677
+ reset() {
1678
+ this.isRefreshing = false;
1679
+ this.refreshPromise = null;
1645
1680
  }
1646
- // #endregion
1647
1681
  };
1648
1682
 
1649
1683
  // src/FalconHUBSDK.ts
@@ -1790,6 +1824,8 @@ export {
1790
1824
  API,
1791
1825
  AuthInterceptor,
1792
1826
  AuthService,
1827
+ BLANKS_BULK_COLUMN_MAP,
1828
+ BLANKS_BULK_SPANISH_HEADERS,
1793
1829
  CatalogService,
1794
1830
  CryptoService,
1795
1831
  FalconHUBSDK,