@utilia-os/sdk-js 1.2.0 → 1.5.0
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/README.md +83 -10
- package/dist/index.d.mts +290 -64
- package/dist/index.d.ts +290 -64
- package/dist/index.js +136 -14
- package/dist/index.mjs +136 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
SDK JavaScript/TypeScript para integrar aplicaciones externas con UTILIA OS.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Instalación
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @utilia-os/sdk-js
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Configuración
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
import { UtiliaSDK } from '@utilia-os/sdk-js';
|
|
@@ -29,7 +29,7 @@ Antes de crear tickets, identifica al usuario en tu sistema:
|
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
31
|
const user = await sdk.users.identify({
|
|
32
|
-
externalId: 'user-123', // ID
|
|
32
|
+
externalId: 'user-123', // ID único en tu sistema (requerido)
|
|
33
33
|
email: 'user@example.com', // opcional
|
|
34
34
|
name: 'Juan Perez', // opcional
|
|
35
35
|
avatarUrl: 'https://...', // opcional
|
|
@@ -49,10 +49,10 @@ const ticket = await sdk.tickets.create({
|
|
|
49
49
|
email: 'user@example.com',
|
|
50
50
|
name: 'Juan Perez',
|
|
51
51
|
},
|
|
52
|
-
title: 'Problema con la
|
|
52
|
+
title: 'Problema con la facturación',
|
|
53
53
|
description: 'No puedo ver mis facturas del mes pasado...',
|
|
54
54
|
category: 'PROBLEMA', // CONSULTA | PROBLEMA | SUGERENCIA | OTRO
|
|
55
|
-
priority: 'MEDIA', // BAJA | MEDIA | ALTA |
|
|
55
|
+
priority: 'MEDIA', // BAJA | MEDIA | ALTA | CRÍTICA
|
|
56
56
|
context: { // opcional
|
|
57
57
|
url: window.location.href,
|
|
58
58
|
appVersion: '1.2.3',
|
|
@@ -104,7 +104,7 @@ await sdk.tickets.close('ticket-uuid', 'user-123');
|
|
|
104
104
|
await sdk.tickets.reopen('ticket-uuid', 'user-123');
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
### Obtener Mensajes No
|
|
107
|
+
### Obtener Mensajes No Leídos
|
|
108
108
|
|
|
109
109
|
```typescript
|
|
110
110
|
const { count } = await sdk.tickets.getUnreadCount('user-123');
|
|
@@ -113,6 +113,72 @@ if (count > 0) {
|
|
|
113
113
|
}
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
+
### Actualizaciones en Tiempo Real (SSE)
|
|
117
|
+
|
|
118
|
+
Recibe notificaciones cuando un agente responde, cambia el estado, resuelve o cierra un ticket:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const stream = sdk.tickets.streamUpdates('user-123', {
|
|
122
|
+
onTicketUpdated: (event) => {
|
|
123
|
+
console.log(`Ticket ${event.ticketKey} actualizado: ${event.type}`);
|
|
124
|
+
// event.type: 'comment-added' | 'status-changed'
|
|
125
|
+
// Refrescar la UI del ticket
|
|
126
|
+
},
|
|
127
|
+
onError: (error) => {
|
|
128
|
+
console.error('Error en conexion SSE:', error);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Para cerrar la conexion cuando ya no se necesite:
|
|
133
|
+
stream.close();
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
> **Nota:** En Node.js se requiere un polyfill como `eventsource` (`npm install eventsource`).
|
|
137
|
+
|
|
138
|
+
### Reportar Error
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
const result = await sdk.errors.report({
|
|
142
|
+
message: 'Error al procesar pago',
|
|
143
|
+
module: 'payment-processor',
|
|
144
|
+
severity: 'critical',
|
|
145
|
+
stack: error.stack,
|
|
146
|
+
endpoint: '/api/payments',
|
|
147
|
+
method: 'POST',
|
|
148
|
+
context: {
|
|
149
|
+
gatewayId: 'stripe',
|
|
150
|
+
orderId: 'order-456',
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
console.log(result.hash); // Hash único del error
|
|
155
|
+
console.log(result.deduplicated); // true si el error ya existía
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Listar Errores
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const result = await sdk.errors.list({
|
|
162
|
+
severity: ['critical', 'high'],
|
|
163
|
+
resolved: false,
|
|
164
|
+
limit: 20,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
console.log(result.errors);
|
|
168
|
+
console.log(result.pagination.total);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Estadísticas de Errores
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
const stats = await sdk.errors.stats();
|
|
175
|
+
|
|
176
|
+
console.log(stats.total); // Total de errores
|
|
177
|
+
console.log(stats.unresolved); // Errores sin resolver
|
|
178
|
+
console.log(stats.bySeverity); // { critical: 5, high: 10, ... }
|
|
179
|
+
console.log(stats.byModule); // { auth: 3, payments: 7, ... }
|
|
180
|
+
```
|
|
181
|
+
|
|
116
182
|
## Manejo de Errores
|
|
117
183
|
|
|
118
184
|
```typescript
|
|
@@ -124,13 +190,13 @@ try {
|
|
|
124
190
|
if (error instanceof UtiliaSDKError) {
|
|
125
191
|
switch (error.code) {
|
|
126
192
|
case ErrorCode.UNAUTHORIZED:
|
|
127
|
-
console.error('API Key
|
|
193
|
+
console.error('API Key inválida');
|
|
128
194
|
break;
|
|
129
195
|
case ErrorCode.RATE_LIMITED:
|
|
130
196
|
console.error('Demasiadas peticiones, espera antes de reintentar');
|
|
131
197
|
break;
|
|
132
198
|
case ErrorCode.VALIDATION_ERROR:
|
|
133
|
-
console.error('Datos
|
|
199
|
+
console.error('Datos inválidos:', error.message);
|
|
134
200
|
break;
|
|
135
201
|
case ErrorCode.NOT_FOUND:
|
|
136
202
|
console.error('Recurso no encontrado');
|
|
@@ -141,7 +207,7 @@ try {
|
|
|
141
207
|
|
|
142
208
|
// Verificar si se puede reintentar
|
|
143
209
|
if (error.isRetryable()) {
|
|
144
|
-
// Implementar
|
|
210
|
+
// Implementar lógica de reintento
|
|
145
211
|
}
|
|
146
212
|
}
|
|
147
213
|
}
|
|
@@ -153,7 +219,7 @@ El SDK exporta todos los tipos TypeScript necesarios:
|
|
|
153
219
|
|
|
154
220
|
```typescript
|
|
155
221
|
import type {
|
|
156
|
-
//
|
|
222
|
+
// Configuración
|
|
157
223
|
UtiliaSDKConfig,
|
|
158
224
|
|
|
159
225
|
// Tickets
|
|
@@ -169,6 +235,13 @@ import type {
|
|
|
169
235
|
IdentifyUserInput,
|
|
170
236
|
ExternalUser,
|
|
171
237
|
|
|
238
|
+
// Errores del sistema
|
|
239
|
+
ReportErrorInput,
|
|
240
|
+
ReportedError,
|
|
241
|
+
SystemError,
|
|
242
|
+
ErrorFilters,
|
|
243
|
+
ErrorStats,
|
|
244
|
+
|
|
172
245
|
// Comunes
|
|
173
246
|
TicketStatus,
|
|
174
247
|
TicketCategory,
|
package/dist/index.d.mts
CHANGED
|
@@ -85,6 +85,23 @@ declare class UtiliaClient {
|
|
|
85
85
|
postForm<T>(url: string, formData: FormData, onProgress?: (progress: number) => void): Promise<T>;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Tipos comunes compartidos en el SDK
|
|
90
|
+
*/
|
|
91
|
+
type TicketStatus = 'OPEN' | 'IN_REVIEW' | 'RESOLVED' | 'CLOSED';
|
|
92
|
+
type TicketCategory = 'CONSULTA' | 'PROBLEMA' | 'SUGERENCIA' | 'OTRO';
|
|
93
|
+
type TicketPriority = 'BAJA' | 'MEDIA' | 'ALTA' | 'CRITICA';
|
|
94
|
+
interface PaginationMeta {
|
|
95
|
+
page: number;
|
|
96
|
+
limit: number;
|
|
97
|
+
total: number;
|
|
98
|
+
totalPages: number;
|
|
99
|
+
}
|
|
100
|
+
interface PaginatedResponse<T> {
|
|
101
|
+
data: T[];
|
|
102
|
+
pagination: PaginationMeta;
|
|
103
|
+
}
|
|
104
|
+
|
|
88
105
|
/**
|
|
89
106
|
* Tipos relacionados con archivos adjuntos
|
|
90
107
|
*/
|
|
@@ -130,69 +147,6 @@ interface FileQuota {
|
|
|
130
147
|
usagePercent: number;
|
|
131
148
|
}
|
|
132
149
|
|
|
133
|
-
/**
|
|
134
|
-
* Servicio de archivos adjuntos
|
|
135
|
-
* Permite subir archivos para adjuntar a tickets
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
declare class FilesService {
|
|
139
|
-
private readonly client;
|
|
140
|
-
private readonly basePath;
|
|
141
|
-
constructor(client: UtiliaClient);
|
|
142
|
-
/**
|
|
143
|
-
* Subir un archivo para adjuntar a tickets
|
|
144
|
-
*
|
|
145
|
-
* @param file - Archivo a subir (File o Blob)
|
|
146
|
-
* @param options - Opciones de subida
|
|
147
|
-
* @returns Archivo subido con su ID
|
|
148
|
-
*
|
|
149
|
-
* @example Browser
|
|
150
|
-
* ```typescript
|
|
151
|
-
* // Desde input file
|
|
152
|
-
* const input = document.querySelector('input[type="file"]');
|
|
153
|
-
* const file = input.files[0];
|
|
154
|
-
* const uploaded = await sdk.files.upload(file);
|
|
155
|
-
*
|
|
156
|
-
* // Usar en ticket
|
|
157
|
-
* await sdk.tickets.create({
|
|
158
|
-
* ...ticketData,
|
|
159
|
-
* attachmentIds: [uploaded.id],
|
|
160
|
-
* });
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
upload(file: File | Blob, options?: UploadFileOptions): Promise<UploadedFile>;
|
|
164
|
-
/**
|
|
165
|
-
* Obtener URL de descarga para un archivo
|
|
166
|
-
*
|
|
167
|
-
* @param fileId - ID del archivo
|
|
168
|
-
* @returns URL temporal de descarga
|
|
169
|
-
*/
|
|
170
|
-
getUrl(fileId: string): Promise<string>;
|
|
171
|
-
/**
|
|
172
|
-
* Obtener informacion de quota de almacenamiento
|
|
173
|
-
*
|
|
174
|
-
* @returns Informacion de uso y limites
|
|
175
|
-
*/
|
|
176
|
-
getQuota(): Promise<FileQuota>;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Tipos comunes compartidos en el SDK
|
|
181
|
-
*/
|
|
182
|
-
type TicketStatus = 'OPEN' | 'IN_REVIEW' | 'RESOLVED' | 'CLOSED';
|
|
183
|
-
type TicketCategory = 'CONSULTA' | 'PROBLEMA' | 'SUGERENCIA' | 'OTRO';
|
|
184
|
-
type TicketPriority = 'BAJA' | 'MEDIA' | 'ALTA' | 'CRITICA';
|
|
185
|
-
interface PaginationMeta {
|
|
186
|
-
page: number;
|
|
187
|
-
limit: number;
|
|
188
|
-
total: number;
|
|
189
|
-
totalPages: number;
|
|
190
|
-
}
|
|
191
|
-
interface PaginatedResponse<T> {
|
|
192
|
-
data: T[];
|
|
193
|
-
pagination: PaginationMeta;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
150
|
/**
|
|
197
151
|
* Tipos relacionados con tickets de soporte
|
|
198
152
|
*/
|
|
@@ -410,6 +364,237 @@ interface ExternalUser {
|
|
|
410
364
|
};
|
|
411
365
|
}
|
|
412
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Tipos relacionados con errores del sistema
|
|
369
|
+
*/
|
|
370
|
+
/**
|
|
371
|
+
* Nivel de severidad de un error
|
|
372
|
+
*/
|
|
373
|
+
type ErrorSeverity = 'critical' | 'high' | 'medium' | 'low';
|
|
374
|
+
/**
|
|
375
|
+
* Metodo HTTP asociado a un error
|
|
376
|
+
*/
|
|
377
|
+
type ErrorHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
378
|
+
/**
|
|
379
|
+
* Datos de entrada para reportar un error
|
|
380
|
+
*/
|
|
381
|
+
interface ReportErrorInput {
|
|
382
|
+
/** Mensaje descriptivo del error (1-2000 caracteres) */
|
|
383
|
+
message: string;
|
|
384
|
+
/** Nivel de severidad del error */
|
|
385
|
+
severity?: ErrorSeverity;
|
|
386
|
+
/** Modulo o area donde ocurrio el error (1-100 caracteres) */
|
|
387
|
+
module: string;
|
|
388
|
+
/** Stack trace del error */
|
|
389
|
+
stack?: string;
|
|
390
|
+
/** Archivo donde ocurrio el error */
|
|
391
|
+
file?: string;
|
|
392
|
+
/** Linea del archivo donde ocurrio el error */
|
|
393
|
+
line?: number;
|
|
394
|
+
/** Funcion donde ocurrio el error */
|
|
395
|
+
function?: string;
|
|
396
|
+
/** Endpoint relacionado con el error */
|
|
397
|
+
endpoint?: string;
|
|
398
|
+
/** Metodo HTTP de la peticion que causo el error */
|
|
399
|
+
method?: ErrorHttpMethod;
|
|
400
|
+
/** ID del usuario afectado */
|
|
401
|
+
userId?: string;
|
|
402
|
+
/** ID de la peticion donde ocurrio el error */
|
|
403
|
+
requestId?: string;
|
|
404
|
+
/** Contexto adicional del error */
|
|
405
|
+
context?: Record<string, unknown>;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Respuesta al reportar un error
|
|
409
|
+
*/
|
|
410
|
+
interface ReportedError {
|
|
411
|
+
/** Indica si el error fue registrado correctamente */
|
|
412
|
+
success: boolean;
|
|
413
|
+
/** Hash unico del error (para deduplicacion) */
|
|
414
|
+
hash: string;
|
|
415
|
+
/** Indica si el error ya existia y se incremento su contador */
|
|
416
|
+
deduplicated: boolean;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Error del sistema en listados
|
|
420
|
+
*/
|
|
421
|
+
interface SystemError {
|
|
422
|
+
/** ID unico del error */
|
|
423
|
+
id: string;
|
|
424
|
+
/** Hash de deduplicacion */
|
|
425
|
+
hash: string;
|
|
426
|
+
/** Mensaje del error */
|
|
427
|
+
message: string;
|
|
428
|
+
/** Modulo donde ocurrio */
|
|
429
|
+
module: string;
|
|
430
|
+
/** Nivel de severidad */
|
|
431
|
+
severity: ErrorSeverity;
|
|
432
|
+
/** Archivo donde ocurrio */
|
|
433
|
+
file?: string;
|
|
434
|
+
/** Linea del archivo */
|
|
435
|
+
line?: number;
|
|
436
|
+
/** Endpoint relacionado */
|
|
437
|
+
endpoint?: string;
|
|
438
|
+
/** Numero de ocurrencias */
|
|
439
|
+
count: number;
|
|
440
|
+
/** Fecha de la primera ocurrencia */
|
|
441
|
+
firstOccurrence: string;
|
|
442
|
+
/** Fecha de la ultima ocurrencia */
|
|
443
|
+
lastOccurrence: string;
|
|
444
|
+
/** Indica si el error esta resuelto */
|
|
445
|
+
resolved: boolean;
|
|
446
|
+
/** Fecha en que se resolvio */
|
|
447
|
+
resolvedAt?: string;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Filtros para listar errores
|
|
451
|
+
*/
|
|
452
|
+
interface ErrorFilters {
|
|
453
|
+
/** Filtrar por niveles de severidad */
|
|
454
|
+
severity?: ErrorSeverity[];
|
|
455
|
+
/** Filtrar por modulo */
|
|
456
|
+
module?: string;
|
|
457
|
+
/** Filtrar por estado de resolucion */
|
|
458
|
+
resolved?: boolean;
|
|
459
|
+
/** Numero maximo de resultados (default: 50, max: 200) */
|
|
460
|
+
limit?: number;
|
|
461
|
+
/** Desplazamiento para paginacion */
|
|
462
|
+
offset?: number;
|
|
463
|
+
/** Fecha de inicio (ISO 8601) */
|
|
464
|
+
from?: string;
|
|
465
|
+
/** Fecha de fin (ISO 8601) */
|
|
466
|
+
to?: string;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Estadisticas de errores
|
|
470
|
+
*/
|
|
471
|
+
interface ErrorStats {
|
|
472
|
+
/** Total de errores registrados */
|
|
473
|
+
total: number;
|
|
474
|
+
/** Errores sin resolver */
|
|
475
|
+
unresolved: number;
|
|
476
|
+
/** Distribucion por severidad */
|
|
477
|
+
bySeverity: Record<string, number>;
|
|
478
|
+
/** Distribucion por modulo */
|
|
479
|
+
byModule: Record<string, number>;
|
|
480
|
+
/** Errores mas frecuentes */
|
|
481
|
+
topErrors: Array<{
|
|
482
|
+
hash: string;
|
|
483
|
+
message: string;
|
|
484
|
+
count: number;
|
|
485
|
+
severity: string;
|
|
486
|
+
}>;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Servicio de errores del sistema
|
|
491
|
+
* Maneja todas las operaciones relacionadas con el reporte y consulta de errores
|
|
492
|
+
*/
|
|
493
|
+
|
|
494
|
+
declare class ErrorsService {
|
|
495
|
+
private readonly client;
|
|
496
|
+
private readonly basePath;
|
|
497
|
+
constructor(client: UtiliaClient);
|
|
498
|
+
/**
|
|
499
|
+
* Reportar un error del sistema
|
|
500
|
+
*
|
|
501
|
+
* @param data - Datos del error a reportar
|
|
502
|
+
* @returns Resultado del reporte con hash de deduplicacion
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```typescript
|
|
506
|
+
* const result = await sdk.errors.report({
|
|
507
|
+
* message: 'Error al procesar pago',
|
|
508
|
+
* module: 'pagos',
|
|
509
|
+
* severity: 'critical',
|
|
510
|
+
* stack: error.stack,
|
|
511
|
+
* endpoint: '/api/payments',
|
|
512
|
+
* method: 'POST',
|
|
513
|
+
* });
|
|
514
|
+
* console.log(result.hash); // Hash unico del error
|
|
515
|
+
* console.log(result.deduplicated); // true si ya existia
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
report(data: ReportErrorInput): Promise<ReportedError>;
|
|
519
|
+
/**
|
|
520
|
+
* Listar errores reportados por esta aplicacion
|
|
521
|
+
*
|
|
522
|
+
* @param filters - Filtros opcionales (severidad, modulo, paginacion)
|
|
523
|
+
* @returns Lista paginada de errores
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* const result = await sdk.errors.list({
|
|
528
|
+
* severity: ['critical', 'high'],
|
|
529
|
+
* resolved: false,
|
|
530
|
+
* limit: 20,
|
|
531
|
+
* });
|
|
532
|
+
* console.log(result.data); // Array de errores
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
list(filters?: ErrorFilters): Promise<PaginatedResponse<SystemError>>;
|
|
536
|
+
/**
|
|
537
|
+
* Obtener estadisticas de errores de esta aplicacion
|
|
538
|
+
*
|
|
539
|
+
* @returns Estadisticas agregadas de errores
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* ```typescript
|
|
543
|
+
* const stats = await sdk.errors.stats();
|
|
544
|
+
* console.log(stats.total); // Total de errores
|
|
545
|
+
* console.log(stats.unresolved); // Errores sin resolver
|
|
546
|
+
* console.log(stats.bySeverity); // { critical: 5, high: 10, ... }
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
stats(): Promise<ErrorStats>;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Servicio de archivos adjuntos
|
|
554
|
+
* Permite subir archivos para adjuntar a tickets
|
|
555
|
+
*/
|
|
556
|
+
|
|
557
|
+
declare class FilesService {
|
|
558
|
+
private readonly client;
|
|
559
|
+
private readonly basePath;
|
|
560
|
+
constructor(client: UtiliaClient);
|
|
561
|
+
/**
|
|
562
|
+
* Subir un archivo para adjuntar a tickets
|
|
563
|
+
*
|
|
564
|
+
* @param file - Archivo a subir (File o Blob)
|
|
565
|
+
* @param options - Opciones de subida
|
|
566
|
+
* @returns Archivo subido con su ID
|
|
567
|
+
*
|
|
568
|
+
* @example Browser
|
|
569
|
+
* ```typescript
|
|
570
|
+
* // Desde input file
|
|
571
|
+
* const input = document.querySelector('input[type="file"]');
|
|
572
|
+
* const file = input.files[0];
|
|
573
|
+
* const uploaded = await sdk.files.upload(file);
|
|
574
|
+
*
|
|
575
|
+
* // Usar en ticket
|
|
576
|
+
* await sdk.tickets.create({
|
|
577
|
+
* ...ticketData,
|
|
578
|
+
* attachmentIds: [uploaded.id],
|
|
579
|
+
* });
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
upload(file: File | Blob, options?: UploadFileOptions): Promise<UploadedFile>;
|
|
583
|
+
/**
|
|
584
|
+
* Obtener URL de descarga para un archivo
|
|
585
|
+
*
|
|
586
|
+
* @param fileId - ID del archivo
|
|
587
|
+
* @returns URL temporal de descarga
|
|
588
|
+
*/
|
|
589
|
+
getUrl(fileId: string): Promise<string>;
|
|
590
|
+
/**
|
|
591
|
+
* Obtener informacion de quota de almacenamiento
|
|
592
|
+
*
|
|
593
|
+
* @returns Informacion de uso y limites
|
|
594
|
+
*/
|
|
595
|
+
getQuota(): Promise<FileQuota>;
|
|
596
|
+
}
|
|
597
|
+
|
|
413
598
|
/**
|
|
414
599
|
* Servicio de tickets de soporte
|
|
415
600
|
* Maneja todas las operaciones relacionadas con tickets
|
|
@@ -503,6 +688,40 @@ declare class TicketsService {
|
|
|
503
688
|
* ```
|
|
504
689
|
*/
|
|
505
690
|
addMessage(ticketId: string, userId: string, data: AddMessageInput): Promise<CreatedMessage>;
|
|
691
|
+
/**
|
|
692
|
+
* Suscribirse a actualizaciones de tickets en tiempo real via SSE.
|
|
693
|
+
* Recibe eventos cuando un agente responde, cambia el estado, resuelve o cierra un ticket.
|
|
694
|
+
*
|
|
695
|
+
* Requiere un entorno con EventSource nativo (navegador) o un polyfill como 'eventsource'.
|
|
696
|
+
*
|
|
697
|
+
* @param userId - ID externo del usuario (opcional, filtra eventos por usuario)
|
|
698
|
+
* @param options - Callbacks para eventos y errores
|
|
699
|
+
* @returns Objeto con metodo close() para cerrar la conexion
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* const stream = sdk.tickets.streamUpdates('user-123', {
|
|
704
|
+
* onTicketUpdated: (event) => {
|
|
705
|
+
* console.log(`Ticket ${event.ticketKey} actualizado: ${event.type}`);
|
|
706
|
+
* // Refrescar la UI del ticket
|
|
707
|
+
* },
|
|
708
|
+
* });
|
|
709
|
+
*
|
|
710
|
+
* // Para cerrar la conexion:
|
|
711
|
+
* stream.close();
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
streamUpdates(userId?: string, options?: {
|
|
715
|
+
onTicketUpdated?: (event: {
|
|
716
|
+
ticketId: string;
|
|
717
|
+
ticketKey: string;
|
|
718
|
+
type: string;
|
|
719
|
+
externalUserId?: string;
|
|
720
|
+
}) => void;
|
|
721
|
+
onError?: (error: Error) => void;
|
|
722
|
+
}): {
|
|
723
|
+
close: () => void;
|
|
724
|
+
};
|
|
506
725
|
/**
|
|
507
726
|
* Cerrar un ticket
|
|
508
727
|
* Solo el usuario que creo el ticket puede cerrarlo
|
|
@@ -1019,9 +1238,12 @@ declare class UtiliaSDKError extends Error {
|
|
|
1019
1238
|
readonly requestId?: string;
|
|
1020
1239
|
/** Codigo de estado HTTP de la respuesta */
|
|
1021
1240
|
readonly statusCode?: number;
|
|
1241
|
+
/** Codigo de error de negocio especifico del backend (ej: TICKET_NOT_FOUND, FILE_INVALID_MIME) */
|
|
1242
|
+
readonly errorCode?: string;
|
|
1022
1243
|
constructor(code: ErrorCode, message: string, options?: {
|
|
1023
1244
|
requestId?: string;
|
|
1024
1245
|
statusCode?: number;
|
|
1246
|
+
errorCode?: string;
|
|
1025
1247
|
});
|
|
1026
1248
|
/**
|
|
1027
1249
|
* Serializa el error a un objeto JSON
|
|
@@ -1029,6 +1251,7 @@ declare class UtiliaSDKError extends Error {
|
|
|
1029
1251
|
toJSON(): {
|
|
1030
1252
|
name: string;
|
|
1031
1253
|
code: ErrorCode;
|
|
1254
|
+
errorCode: string | undefined;
|
|
1032
1255
|
message: string;
|
|
1033
1256
|
timestamp: string;
|
|
1034
1257
|
requestId: string | undefined;
|
|
@@ -1098,12 +1321,15 @@ declare const SDK_LIMITS: {
|
|
|
1098
1321
|
* Clase principal del SDK de UTILIA OS
|
|
1099
1322
|
*
|
|
1100
1323
|
* Proporciona acceso a todos los servicios disponibles:
|
|
1324
|
+
* - `errors`: Reporte y consulta de errores del sistema
|
|
1101
1325
|
* - `files`: Operaciones con archivos adjuntos
|
|
1102
1326
|
* - `tickets`: Operaciones con tickets de soporte
|
|
1103
1327
|
* - `users`: Operaciones con usuarios externos
|
|
1104
1328
|
* - `ai`: Funcionalidades de IA (transcripcion, sugerencias)
|
|
1105
1329
|
*/
|
|
1106
1330
|
declare class UtiliaSDK {
|
|
1331
|
+
/** Servicio de errores del sistema */
|
|
1332
|
+
readonly errors: ErrorsService;
|
|
1107
1333
|
/** Servicio de archivos adjuntos */
|
|
1108
1334
|
readonly files: FilesService;
|
|
1109
1335
|
/** Servicio de tickets de soporte */
|
|
@@ -1139,4 +1365,4 @@ declare class UtiliaSDK {
|
|
|
1139
1365
|
constructor(config: UtiliaSDKConfig);
|
|
1140
1366
|
}
|
|
1141
1367
|
|
|
1142
|
-
export { type AddMessageInput, type AiJobStatus, type AiSuggestInput, type AiSuggestions, type AiUserAction, type CreateTicketInput, type CreateTicketUser, type CreatedMessage, type CreatedTicket, ErrorCode, type ExternalUser, type FileQuota, type GetSuggestionsOptions, type IdentifyUserInput, type MessageAuthor, type PaginatedResponse, type PaginationMeta, type RequestConfig, SDK_LIMITS, type SseEvent, type StreamSuggestionsHandle, type StreamSuggestionsOptions, type StreamTranscriptionOptions, type TicketAttachment, type TicketCategory, type TicketContext, type TicketDetail, type TicketFilters, type TicketListItem, type TicketMessage, type TicketPriority, type TicketReporter, type TicketStatus, type TrackAiActionInput, type TranscriptionJobStatus, type UnreadCount, type UploadFileOptions, type UploadedFile, UtiliaSDK, type UtiliaSDKConfig, UtiliaSDKError };
|
|
1368
|
+
export { type AddMessageInput, type AiJobStatus, type AiSuggestInput, type AiSuggestions, type AiUserAction, type CreateTicketInput, type CreateTicketUser, type CreatedMessage, type CreatedTicket, ErrorCode, type ErrorFilters, type ErrorHttpMethod, type ErrorSeverity, type ErrorStats, type ExternalUser, type FileQuota, type GetSuggestionsOptions, type IdentifyUserInput, type MessageAuthor, type PaginatedResponse, type PaginationMeta, type ReportErrorInput, type ReportedError, type RequestConfig, SDK_LIMITS, type SseEvent, type StreamSuggestionsHandle, type StreamSuggestionsOptions, type StreamTranscriptionOptions, type SystemError, type TicketAttachment, type TicketCategory, type TicketContext, type TicketDetail, type TicketFilters, type TicketListItem, type TicketMessage, type TicketPriority, type TicketReporter, type TicketStatus, type TrackAiActionInput, type TranscriptionJobStatus, type UnreadCount, type UploadFileOptions, type UploadedFile, UtiliaSDK, type UtiliaSDKConfig, UtiliaSDKError };
|
package/dist/index.d.ts
CHANGED
|
@@ -85,6 +85,23 @@ declare class UtiliaClient {
|
|
|
85
85
|
postForm<T>(url: string, formData: FormData, onProgress?: (progress: number) => void): Promise<T>;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Tipos comunes compartidos en el SDK
|
|
90
|
+
*/
|
|
91
|
+
type TicketStatus = 'OPEN' | 'IN_REVIEW' | 'RESOLVED' | 'CLOSED';
|
|
92
|
+
type TicketCategory = 'CONSULTA' | 'PROBLEMA' | 'SUGERENCIA' | 'OTRO';
|
|
93
|
+
type TicketPriority = 'BAJA' | 'MEDIA' | 'ALTA' | 'CRITICA';
|
|
94
|
+
interface PaginationMeta {
|
|
95
|
+
page: number;
|
|
96
|
+
limit: number;
|
|
97
|
+
total: number;
|
|
98
|
+
totalPages: number;
|
|
99
|
+
}
|
|
100
|
+
interface PaginatedResponse<T> {
|
|
101
|
+
data: T[];
|
|
102
|
+
pagination: PaginationMeta;
|
|
103
|
+
}
|
|
104
|
+
|
|
88
105
|
/**
|
|
89
106
|
* Tipos relacionados con archivos adjuntos
|
|
90
107
|
*/
|
|
@@ -130,69 +147,6 @@ interface FileQuota {
|
|
|
130
147
|
usagePercent: number;
|
|
131
148
|
}
|
|
132
149
|
|
|
133
|
-
/**
|
|
134
|
-
* Servicio de archivos adjuntos
|
|
135
|
-
* Permite subir archivos para adjuntar a tickets
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
declare class FilesService {
|
|
139
|
-
private readonly client;
|
|
140
|
-
private readonly basePath;
|
|
141
|
-
constructor(client: UtiliaClient);
|
|
142
|
-
/**
|
|
143
|
-
* Subir un archivo para adjuntar a tickets
|
|
144
|
-
*
|
|
145
|
-
* @param file - Archivo a subir (File o Blob)
|
|
146
|
-
* @param options - Opciones de subida
|
|
147
|
-
* @returns Archivo subido con su ID
|
|
148
|
-
*
|
|
149
|
-
* @example Browser
|
|
150
|
-
* ```typescript
|
|
151
|
-
* // Desde input file
|
|
152
|
-
* const input = document.querySelector('input[type="file"]');
|
|
153
|
-
* const file = input.files[0];
|
|
154
|
-
* const uploaded = await sdk.files.upload(file);
|
|
155
|
-
*
|
|
156
|
-
* // Usar en ticket
|
|
157
|
-
* await sdk.tickets.create({
|
|
158
|
-
* ...ticketData,
|
|
159
|
-
* attachmentIds: [uploaded.id],
|
|
160
|
-
* });
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
upload(file: File | Blob, options?: UploadFileOptions): Promise<UploadedFile>;
|
|
164
|
-
/**
|
|
165
|
-
* Obtener URL de descarga para un archivo
|
|
166
|
-
*
|
|
167
|
-
* @param fileId - ID del archivo
|
|
168
|
-
* @returns URL temporal de descarga
|
|
169
|
-
*/
|
|
170
|
-
getUrl(fileId: string): Promise<string>;
|
|
171
|
-
/**
|
|
172
|
-
* Obtener informacion de quota de almacenamiento
|
|
173
|
-
*
|
|
174
|
-
* @returns Informacion de uso y limites
|
|
175
|
-
*/
|
|
176
|
-
getQuota(): Promise<FileQuota>;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Tipos comunes compartidos en el SDK
|
|
181
|
-
*/
|
|
182
|
-
type TicketStatus = 'OPEN' | 'IN_REVIEW' | 'RESOLVED' | 'CLOSED';
|
|
183
|
-
type TicketCategory = 'CONSULTA' | 'PROBLEMA' | 'SUGERENCIA' | 'OTRO';
|
|
184
|
-
type TicketPriority = 'BAJA' | 'MEDIA' | 'ALTA' | 'CRITICA';
|
|
185
|
-
interface PaginationMeta {
|
|
186
|
-
page: number;
|
|
187
|
-
limit: number;
|
|
188
|
-
total: number;
|
|
189
|
-
totalPages: number;
|
|
190
|
-
}
|
|
191
|
-
interface PaginatedResponse<T> {
|
|
192
|
-
data: T[];
|
|
193
|
-
pagination: PaginationMeta;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
150
|
/**
|
|
197
151
|
* Tipos relacionados con tickets de soporte
|
|
198
152
|
*/
|
|
@@ -410,6 +364,237 @@ interface ExternalUser {
|
|
|
410
364
|
};
|
|
411
365
|
}
|
|
412
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Tipos relacionados con errores del sistema
|
|
369
|
+
*/
|
|
370
|
+
/**
|
|
371
|
+
* Nivel de severidad de un error
|
|
372
|
+
*/
|
|
373
|
+
type ErrorSeverity = 'critical' | 'high' | 'medium' | 'low';
|
|
374
|
+
/**
|
|
375
|
+
* Metodo HTTP asociado a un error
|
|
376
|
+
*/
|
|
377
|
+
type ErrorHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
378
|
+
/**
|
|
379
|
+
* Datos de entrada para reportar un error
|
|
380
|
+
*/
|
|
381
|
+
interface ReportErrorInput {
|
|
382
|
+
/** Mensaje descriptivo del error (1-2000 caracteres) */
|
|
383
|
+
message: string;
|
|
384
|
+
/** Nivel de severidad del error */
|
|
385
|
+
severity?: ErrorSeverity;
|
|
386
|
+
/** Modulo o area donde ocurrio el error (1-100 caracteres) */
|
|
387
|
+
module: string;
|
|
388
|
+
/** Stack trace del error */
|
|
389
|
+
stack?: string;
|
|
390
|
+
/** Archivo donde ocurrio el error */
|
|
391
|
+
file?: string;
|
|
392
|
+
/** Linea del archivo donde ocurrio el error */
|
|
393
|
+
line?: number;
|
|
394
|
+
/** Funcion donde ocurrio el error */
|
|
395
|
+
function?: string;
|
|
396
|
+
/** Endpoint relacionado con el error */
|
|
397
|
+
endpoint?: string;
|
|
398
|
+
/** Metodo HTTP de la peticion que causo el error */
|
|
399
|
+
method?: ErrorHttpMethod;
|
|
400
|
+
/** ID del usuario afectado */
|
|
401
|
+
userId?: string;
|
|
402
|
+
/** ID de la peticion donde ocurrio el error */
|
|
403
|
+
requestId?: string;
|
|
404
|
+
/** Contexto adicional del error */
|
|
405
|
+
context?: Record<string, unknown>;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Respuesta al reportar un error
|
|
409
|
+
*/
|
|
410
|
+
interface ReportedError {
|
|
411
|
+
/** Indica si el error fue registrado correctamente */
|
|
412
|
+
success: boolean;
|
|
413
|
+
/** Hash unico del error (para deduplicacion) */
|
|
414
|
+
hash: string;
|
|
415
|
+
/** Indica si el error ya existia y se incremento su contador */
|
|
416
|
+
deduplicated: boolean;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Error del sistema en listados
|
|
420
|
+
*/
|
|
421
|
+
interface SystemError {
|
|
422
|
+
/** ID unico del error */
|
|
423
|
+
id: string;
|
|
424
|
+
/** Hash de deduplicacion */
|
|
425
|
+
hash: string;
|
|
426
|
+
/** Mensaje del error */
|
|
427
|
+
message: string;
|
|
428
|
+
/** Modulo donde ocurrio */
|
|
429
|
+
module: string;
|
|
430
|
+
/** Nivel de severidad */
|
|
431
|
+
severity: ErrorSeverity;
|
|
432
|
+
/** Archivo donde ocurrio */
|
|
433
|
+
file?: string;
|
|
434
|
+
/** Linea del archivo */
|
|
435
|
+
line?: number;
|
|
436
|
+
/** Endpoint relacionado */
|
|
437
|
+
endpoint?: string;
|
|
438
|
+
/** Numero de ocurrencias */
|
|
439
|
+
count: number;
|
|
440
|
+
/** Fecha de la primera ocurrencia */
|
|
441
|
+
firstOccurrence: string;
|
|
442
|
+
/** Fecha de la ultima ocurrencia */
|
|
443
|
+
lastOccurrence: string;
|
|
444
|
+
/** Indica si el error esta resuelto */
|
|
445
|
+
resolved: boolean;
|
|
446
|
+
/** Fecha en que se resolvio */
|
|
447
|
+
resolvedAt?: string;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Filtros para listar errores
|
|
451
|
+
*/
|
|
452
|
+
interface ErrorFilters {
|
|
453
|
+
/** Filtrar por niveles de severidad */
|
|
454
|
+
severity?: ErrorSeverity[];
|
|
455
|
+
/** Filtrar por modulo */
|
|
456
|
+
module?: string;
|
|
457
|
+
/** Filtrar por estado de resolucion */
|
|
458
|
+
resolved?: boolean;
|
|
459
|
+
/** Numero maximo de resultados (default: 50, max: 200) */
|
|
460
|
+
limit?: number;
|
|
461
|
+
/** Desplazamiento para paginacion */
|
|
462
|
+
offset?: number;
|
|
463
|
+
/** Fecha de inicio (ISO 8601) */
|
|
464
|
+
from?: string;
|
|
465
|
+
/** Fecha de fin (ISO 8601) */
|
|
466
|
+
to?: string;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Estadisticas de errores
|
|
470
|
+
*/
|
|
471
|
+
interface ErrorStats {
|
|
472
|
+
/** Total de errores registrados */
|
|
473
|
+
total: number;
|
|
474
|
+
/** Errores sin resolver */
|
|
475
|
+
unresolved: number;
|
|
476
|
+
/** Distribucion por severidad */
|
|
477
|
+
bySeverity: Record<string, number>;
|
|
478
|
+
/** Distribucion por modulo */
|
|
479
|
+
byModule: Record<string, number>;
|
|
480
|
+
/** Errores mas frecuentes */
|
|
481
|
+
topErrors: Array<{
|
|
482
|
+
hash: string;
|
|
483
|
+
message: string;
|
|
484
|
+
count: number;
|
|
485
|
+
severity: string;
|
|
486
|
+
}>;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Servicio de errores del sistema
|
|
491
|
+
* Maneja todas las operaciones relacionadas con el reporte y consulta de errores
|
|
492
|
+
*/
|
|
493
|
+
|
|
494
|
+
declare class ErrorsService {
|
|
495
|
+
private readonly client;
|
|
496
|
+
private readonly basePath;
|
|
497
|
+
constructor(client: UtiliaClient);
|
|
498
|
+
/**
|
|
499
|
+
* Reportar un error del sistema
|
|
500
|
+
*
|
|
501
|
+
* @param data - Datos del error a reportar
|
|
502
|
+
* @returns Resultado del reporte con hash de deduplicacion
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```typescript
|
|
506
|
+
* const result = await sdk.errors.report({
|
|
507
|
+
* message: 'Error al procesar pago',
|
|
508
|
+
* module: 'pagos',
|
|
509
|
+
* severity: 'critical',
|
|
510
|
+
* stack: error.stack,
|
|
511
|
+
* endpoint: '/api/payments',
|
|
512
|
+
* method: 'POST',
|
|
513
|
+
* });
|
|
514
|
+
* console.log(result.hash); // Hash unico del error
|
|
515
|
+
* console.log(result.deduplicated); // true si ya existia
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
report(data: ReportErrorInput): Promise<ReportedError>;
|
|
519
|
+
/**
|
|
520
|
+
* Listar errores reportados por esta aplicacion
|
|
521
|
+
*
|
|
522
|
+
* @param filters - Filtros opcionales (severidad, modulo, paginacion)
|
|
523
|
+
* @returns Lista paginada de errores
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* const result = await sdk.errors.list({
|
|
528
|
+
* severity: ['critical', 'high'],
|
|
529
|
+
* resolved: false,
|
|
530
|
+
* limit: 20,
|
|
531
|
+
* });
|
|
532
|
+
* console.log(result.data); // Array de errores
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
list(filters?: ErrorFilters): Promise<PaginatedResponse<SystemError>>;
|
|
536
|
+
/**
|
|
537
|
+
* Obtener estadisticas de errores de esta aplicacion
|
|
538
|
+
*
|
|
539
|
+
* @returns Estadisticas agregadas de errores
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* ```typescript
|
|
543
|
+
* const stats = await sdk.errors.stats();
|
|
544
|
+
* console.log(stats.total); // Total de errores
|
|
545
|
+
* console.log(stats.unresolved); // Errores sin resolver
|
|
546
|
+
* console.log(stats.bySeverity); // { critical: 5, high: 10, ... }
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
stats(): Promise<ErrorStats>;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Servicio de archivos adjuntos
|
|
554
|
+
* Permite subir archivos para adjuntar a tickets
|
|
555
|
+
*/
|
|
556
|
+
|
|
557
|
+
declare class FilesService {
|
|
558
|
+
private readonly client;
|
|
559
|
+
private readonly basePath;
|
|
560
|
+
constructor(client: UtiliaClient);
|
|
561
|
+
/**
|
|
562
|
+
* Subir un archivo para adjuntar a tickets
|
|
563
|
+
*
|
|
564
|
+
* @param file - Archivo a subir (File o Blob)
|
|
565
|
+
* @param options - Opciones de subida
|
|
566
|
+
* @returns Archivo subido con su ID
|
|
567
|
+
*
|
|
568
|
+
* @example Browser
|
|
569
|
+
* ```typescript
|
|
570
|
+
* // Desde input file
|
|
571
|
+
* const input = document.querySelector('input[type="file"]');
|
|
572
|
+
* const file = input.files[0];
|
|
573
|
+
* const uploaded = await sdk.files.upload(file);
|
|
574
|
+
*
|
|
575
|
+
* // Usar en ticket
|
|
576
|
+
* await sdk.tickets.create({
|
|
577
|
+
* ...ticketData,
|
|
578
|
+
* attachmentIds: [uploaded.id],
|
|
579
|
+
* });
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
upload(file: File | Blob, options?: UploadFileOptions): Promise<UploadedFile>;
|
|
583
|
+
/**
|
|
584
|
+
* Obtener URL de descarga para un archivo
|
|
585
|
+
*
|
|
586
|
+
* @param fileId - ID del archivo
|
|
587
|
+
* @returns URL temporal de descarga
|
|
588
|
+
*/
|
|
589
|
+
getUrl(fileId: string): Promise<string>;
|
|
590
|
+
/**
|
|
591
|
+
* Obtener informacion de quota de almacenamiento
|
|
592
|
+
*
|
|
593
|
+
* @returns Informacion de uso y limites
|
|
594
|
+
*/
|
|
595
|
+
getQuota(): Promise<FileQuota>;
|
|
596
|
+
}
|
|
597
|
+
|
|
413
598
|
/**
|
|
414
599
|
* Servicio de tickets de soporte
|
|
415
600
|
* Maneja todas las operaciones relacionadas con tickets
|
|
@@ -503,6 +688,40 @@ declare class TicketsService {
|
|
|
503
688
|
* ```
|
|
504
689
|
*/
|
|
505
690
|
addMessage(ticketId: string, userId: string, data: AddMessageInput): Promise<CreatedMessage>;
|
|
691
|
+
/**
|
|
692
|
+
* Suscribirse a actualizaciones de tickets en tiempo real via SSE.
|
|
693
|
+
* Recibe eventos cuando un agente responde, cambia el estado, resuelve o cierra un ticket.
|
|
694
|
+
*
|
|
695
|
+
* Requiere un entorno con EventSource nativo (navegador) o un polyfill como 'eventsource'.
|
|
696
|
+
*
|
|
697
|
+
* @param userId - ID externo del usuario (opcional, filtra eventos por usuario)
|
|
698
|
+
* @param options - Callbacks para eventos y errores
|
|
699
|
+
* @returns Objeto con metodo close() para cerrar la conexion
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* const stream = sdk.tickets.streamUpdates('user-123', {
|
|
704
|
+
* onTicketUpdated: (event) => {
|
|
705
|
+
* console.log(`Ticket ${event.ticketKey} actualizado: ${event.type}`);
|
|
706
|
+
* // Refrescar la UI del ticket
|
|
707
|
+
* },
|
|
708
|
+
* });
|
|
709
|
+
*
|
|
710
|
+
* // Para cerrar la conexion:
|
|
711
|
+
* stream.close();
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
streamUpdates(userId?: string, options?: {
|
|
715
|
+
onTicketUpdated?: (event: {
|
|
716
|
+
ticketId: string;
|
|
717
|
+
ticketKey: string;
|
|
718
|
+
type: string;
|
|
719
|
+
externalUserId?: string;
|
|
720
|
+
}) => void;
|
|
721
|
+
onError?: (error: Error) => void;
|
|
722
|
+
}): {
|
|
723
|
+
close: () => void;
|
|
724
|
+
};
|
|
506
725
|
/**
|
|
507
726
|
* Cerrar un ticket
|
|
508
727
|
* Solo el usuario que creo el ticket puede cerrarlo
|
|
@@ -1019,9 +1238,12 @@ declare class UtiliaSDKError extends Error {
|
|
|
1019
1238
|
readonly requestId?: string;
|
|
1020
1239
|
/** Codigo de estado HTTP de la respuesta */
|
|
1021
1240
|
readonly statusCode?: number;
|
|
1241
|
+
/** Codigo de error de negocio especifico del backend (ej: TICKET_NOT_FOUND, FILE_INVALID_MIME) */
|
|
1242
|
+
readonly errorCode?: string;
|
|
1022
1243
|
constructor(code: ErrorCode, message: string, options?: {
|
|
1023
1244
|
requestId?: string;
|
|
1024
1245
|
statusCode?: number;
|
|
1246
|
+
errorCode?: string;
|
|
1025
1247
|
});
|
|
1026
1248
|
/**
|
|
1027
1249
|
* Serializa el error a un objeto JSON
|
|
@@ -1029,6 +1251,7 @@ declare class UtiliaSDKError extends Error {
|
|
|
1029
1251
|
toJSON(): {
|
|
1030
1252
|
name: string;
|
|
1031
1253
|
code: ErrorCode;
|
|
1254
|
+
errorCode: string | undefined;
|
|
1032
1255
|
message: string;
|
|
1033
1256
|
timestamp: string;
|
|
1034
1257
|
requestId: string | undefined;
|
|
@@ -1098,12 +1321,15 @@ declare const SDK_LIMITS: {
|
|
|
1098
1321
|
* Clase principal del SDK de UTILIA OS
|
|
1099
1322
|
*
|
|
1100
1323
|
* Proporciona acceso a todos los servicios disponibles:
|
|
1324
|
+
* - `errors`: Reporte y consulta de errores del sistema
|
|
1101
1325
|
* - `files`: Operaciones con archivos adjuntos
|
|
1102
1326
|
* - `tickets`: Operaciones con tickets de soporte
|
|
1103
1327
|
* - `users`: Operaciones con usuarios externos
|
|
1104
1328
|
* - `ai`: Funcionalidades de IA (transcripcion, sugerencias)
|
|
1105
1329
|
*/
|
|
1106
1330
|
declare class UtiliaSDK {
|
|
1331
|
+
/** Servicio de errores del sistema */
|
|
1332
|
+
readonly errors: ErrorsService;
|
|
1107
1333
|
/** Servicio de archivos adjuntos */
|
|
1108
1334
|
readonly files: FilesService;
|
|
1109
1335
|
/** Servicio de tickets de soporte */
|
|
@@ -1139,4 +1365,4 @@ declare class UtiliaSDK {
|
|
|
1139
1365
|
constructor(config: UtiliaSDKConfig);
|
|
1140
1366
|
}
|
|
1141
1367
|
|
|
1142
|
-
export { type AddMessageInput, type AiJobStatus, type AiSuggestInput, type AiSuggestions, type AiUserAction, type CreateTicketInput, type CreateTicketUser, type CreatedMessage, type CreatedTicket, ErrorCode, type ExternalUser, type FileQuota, type GetSuggestionsOptions, type IdentifyUserInput, type MessageAuthor, type PaginatedResponse, type PaginationMeta, type RequestConfig, SDK_LIMITS, type SseEvent, type StreamSuggestionsHandle, type StreamSuggestionsOptions, type StreamTranscriptionOptions, type TicketAttachment, type TicketCategory, type TicketContext, type TicketDetail, type TicketFilters, type TicketListItem, type TicketMessage, type TicketPriority, type TicketReporter, type TicketStatus, type TrackAiActionInput, type TranscriptionJobStatus, type UnreadCount, type UploadFileOptions, type UploadedFile, UtiliaSDK, type UtiliaSDKConfig, UtiliaSDKError };
|
|
1368
|
+
export { type AddMessageInput, type AiJobStatus, type AiSuggestInput, type AiSuggestions, type AiUserAction, type CreateTicketInput, type CreateTicketUser, type CreatedMessage, type CreatedTicket, ErrorCode, type ErrorFilters, type ErrorHttpMethod, type ErrorSeverity, type ErrorStats, type ExternalUser, type FileQuota, type GetSuggestionsOptions, type IdentifyUserInput, type MessageAuthor, type PaginatedResponse, type PaginationMeta, type ReportErrorInput, type ReportedError, type RequestConfig, SDK_LIMITS, type SseEvent, type StreamSuggestionsHandle, type StreamSuggestionsOptions, type StreamTranscriptionOptions, type SystemError, type TicketAttachment, type TicketCategory, type TicketContext, type TicketDetail, type TicketFilters, type TicketListItem, type TicketMessage, type TicketPriority, type TicketReporter, type TicketStatus, type TrackAiActionInput, type TranscriptionJobStatus, type UnreadCount, type UploadFileOptions, type UploadedFile, UtiliaSDK, type UtiliaSDKConfig, UtiliaSDKError };
|
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ var UtiliaSDKError = class _UtiliaSDKError extends Error {
|
|
|
59
59
|
this.timestamp = /* @__PURE__ */ new Date();
|
|
60
60
|
this.requestId = options?.requestId;
|
|
61
61
|
this.statusCode = options?.statusCode;
|
|
62
|
+
this.errorCode = options?.errorCode;
|
|
62
63
|
if (Error.captureStackTrace) {
|
|
63
64
|
Error.captureStackTrace(this, _UtiliaSDKError);
|
|
64
65
|
}
|
|
@@ -70,6 +71,7 @@ var UtiliaSDKError = class _UtiliaSDKError extends Error {
|
|
|
70
71
|
return {
|
|
71
72
|
name: this.name,
|
|
72
73
|
code: this.code,
|
|
74
|
+
errorCode: this.errorCode,
|
|
73
75
|
message: this.message,
|
|
74
76
|
timestamp: this.timestamp.toISOString(),
|
|
75
77
|
requestId: this.requestId,
|
|
@@ -146,7 +148,9 @@ var UtiliaClient = class {
|
|
|
146
148
|
toSDKError(error) {
|
|
147
149
|
const requestId = error.response?.headers?.["x-request-id"] || error.config?._requestId;
|
|
148
150
|
const statusCode = error.response?.status;
|
|
149
|
-
const
|
|
151
|
+
const data = error.response?.data;
|
|
152
|
+
const errorCode = data?.errorCode;
|
|
153
|
+
const errorOptions = { requestId, statusCode, errorCode };
|
|
150
154
|
if (!error.response) {
|
|
151
155
|
if (error.code === "ECONNABORTED") {
|
|
152
156
|
return new UtiliaSDKError("NETWORK_ERROR" /* NETWORK_ERROR */, "Timeout: la solicitud excedio el tiempo limite", errorOptions);
|
|
@@ -154,7 +158,6 @@ var UtiliaClient = class {
|
|
|
154
158
|
return new UtiliaSDKError("NETWORK_ERROR" /* NETWORK_ERROR */, "Error de conexion: no se pudo conectar con el servidor", errorOptions);
|
|
155
159
|
}
|
|
156
160
|
const status = error.response.status;
|
|
157
|
-
const data = error.response.data;
|
|
158
161
|
const message = data?.message || data?.error || error.message;
|
|
159
162
|
switch (status) {
|
|
160
163
|
case 401:
|
|
@@ -317,18 +320,6 @@ var UtiliaClient = class {
|
|
|
317
320
|
}
|
|
318
321
|
};
|
|
319
322
|
|
|
320
|
-
// src/constants.ts
|
|
321
|
-
var SDK_LIMITS = {
|
|
322
|
-
TICKET_TITLE_MIN: 5,
|
|
323
|
-
TICKET_TITLE_MAX: 500,
|
|
324
|
-
TICKET_DESCRIPTION_MIN: 10,
|
|
325
|
-
MESSAGE_CONTENT_MIN: 1,
|
|
326
|
-
MESSAGE_CONTENT_MAX: 5e3,
|
|
327
|
-
FILE_NAME_MAX: 255,
|
|
328
|
-
EXTERNAL_ID_MAX: 255,
|
|
329
|
-
AVATAR_URL_MAX: 2048
|
|
330
|
-
};
|
|
331
|
-
|
|
332
323
|
// src/utils/validators.ts
|
|
333
324
|
function validateEmail(email) {
|
|
334
325
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -371,6 +362,88 @@ function validateRequired(value, fieldName) {
|
|
|
371
362
|
}
|
|
372
363
|
}
|
|
373
364
|
|
|
365
|
+
// src/services/errors.service.ts
|
|
366
|
+
var ErrorsService = class {
|
|
367
|
+
constructor(client) {
|
|
368
|
+
this.basePath = "/external/v1/errors";
|
|
369
|
+
this.client = client;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Reportar un error del sistema
|
|
373
|
+
*
|
|
374
|
+
* @param data - Datos del error a reportar
|
|
375
|
+
* @returns Resultado del reporte con hash de deduplicacion
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```typescript
|
|
379
|
+
* const result = await sdk.errors.report({
|
|
380
|
+
* message: 'Error al procesar pago',
|
|
381
|
+
* module: 'pagos',
|
|
382
|
+
* severity: 'critical',
|
|
383
|
+
* stack: error.stack,
|
|
384
|
+
* endpoint: '/api/payments',
|
|
385
|
+
* method: 'POST',
|
|
386
|
+
* });
|
|
387
|
+
* console.log(result.hash); // Hash unico del error
|
|
388
|
+
* console.log(result.deduplicated); // true si ya existia
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
async report(data) {
|
|
392
|
+
validateRequired(data.message, "message");
|
|
393
|
+
validateRequired(data.module, "module");
|
|
394
|
+
return this.client.post(`${this.basePath}/report`, data);
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Listar errores reportados por esta aplicacion
|
|
398
|
+
*
|
|
399
|
+
* @param filters - Filtros opcionales (severidad, modulo, paginacion)
|
|
400
|
+
* @returns Lista paginada de errores
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* const result = await sdk.errors.list({
|
|
405
|
+
* severity: ['critical', 'high'],
|
|
406
|
+
* resolved: false,
|
|
407
|
+
* limit: 20,
|
|
408
|
+
* });
|
|
409
|
+
* console.log(result.data); // Array de errores
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
async list(filters) {
|
|
413
|
+
return this.client.get(this.basePath, {
|
|
414
|
+
params: filters ? { ...filters } : void 0
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Obtener estadisticas de errores de esta aplicacion
|
|
419
|
+
*
|
|
420
|
+
* @returns Estadisticas agregadas de errores
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```typescript
|
|
424
|
+
* const stats = await sdk.errors.stats();
|
|
425
|
+
* console.log(stats.total); // Total de errores
|
|
426
|
+
* console.log(stats.unresolved); // Errores sin resolver
|
|
427
|
+
* console.log(stats.bySeverity); // { critical: 5, high: 10, ... }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
async stats() {
|
|
431
|
+
return this.client.get(`${this.basePath}/stats`);
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
// src/constants.ts
|
|
436
|
+
var SDK_LIMITS = {
|
|
437
|
+
TICKET_TITLE_MIN: 5,
|
|
438
|
+
TICKET_TITLE_MAX: 500,
|
|
439
|
+
TICKET_DESCRIPTION_MIN: 10,
|
|
440
|
+
MESSAGE_CONTENT_MIN: 1,
|
|
441
|
+
MESSAGE_CONTENT_MAX: 5e3,
|
|
442
|
+
FILE_NAME_MAX: 255,
|
|
443
|
+
EXTERNAL_ID_MAX: 255,
|
|
444
|
+
AVATAR_URL_MAX: 2048
|
|
445
|
+
};
|
|
446
|
+
|
|
374
447
|
// src/services/files.service.ts
|
|
375
448
|
var FilesService = class {
|
|
376
449
|
constructor(client) {
|
|
@@ -562,6 +635,54 @@ var TicketsService = class {
|
|
|
562
635
|
{ params: { userId } }
|
|
563
636
|
);
|
|
564
637
|
}
|
|
638
|
+
/**
|
|
639
|
+
* Suscribirse a actualizaciones de tickets en tiempo real via SSE.
|
|
640
|
+
* Recibe eventos cuando un agente responde, cambia el estado, resuelve o cierra un ticket.
|
|
641
|
+
*
|
|
642
|
+
* Requiere un entorno con EventSource nativo (navegador) o un polyfill como 'eventsource'.
|
|
643
|
+
*
|
|
644
|
+
* @param userId - ID externo del usuario (opcional, filtra eventos por usuario)
|
|
645
|
+
* @param options - Callbacks para eventos y errores
|
|
646
|
+
* @returns Objeto con metodo close() para cerrar la conexion
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```typescript
|
|
650
|
+
* const stream = sdk.tickets.streamUpdates('user-123', {
|
|
651
|
+
* onTicketUpdated: (event) => {
|
|
652
|
+
* console.log(`Ticket ${event.ticketKey} actualizado: ${event.type}`);
|
|
653
|
+
* // Refrescar la UI del ticket
|
|
654
|
+
* },
|
|
655
|
+
* });
|
|
656
|
+
*
|
|
657
|
+
* // Para cerrar la conexion:
|
|
658
|
+
* stream.close();
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
streamUpdates(userId, options) {
|
|
662
|
+
if (typeof EventSource === "undefined") {
|
|
663
|
+
throw new Error(
|
|
664
|
+
'EventSource no esta disponible en este entorno. Para Node.js, instala un polyfill como "eventsource" y asignalo a globalThis.EventSource.'
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
const queryParams = userId ? `?userId=${encodeURIComponent(userId)}` : "";
|
|
668
|
+
const sseUrl = this.client.buildSseUrl(`${this.basePath}/events${queryParams}`);
|
|
669
|
+
const eventSource = new EventSource(sseUrl);
|
|
670
|
+
eventSource.onmessage = (event) => {
|
|
671
|
+
try {
|
|
672
|
+
const data = JSON.parse(event.data);
|
|
673
|
+
if (data.event === "ticket-updated" && options?.onTicketUpdated) {
|
|
674
|
+
options.onTicketUpdated(data);
|
|
675
|
+
}
|
|
676
|
+
} catch {
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
eventSource.onerror = () => {
|
|
680
|
+
options?.onError?.(new Error("Error en la conexion SSE"));
|
|
681
|
+
};
|
|
682
|
+
return {
|
|
683
|
+
close: () => eventSource.close()
|
|
684
|
+
};
|
|
685
|
+
}
|
|
565
686
|
/**
|
|
566
687
|
* Cerrar un ticket
|
|
567
688
|
* Solo el usuario que creo el ticket puede cerrarlo
|
|
@@ -1090,6 +1211,7 @@ var UtiliaSDK = class {
|
|
|
1090
1211
|
*/
|
|
1091
1212
|
constructor(config) {
|
|
1092
1213
|
const client = new UtiliaClient(config);
|
|
1214
|
+
this.errors = new ErrorsService(client);
|
|
1093
1215
|
this.files = new FilesService(client);
|
|
1094
1216
|
this.tickets = new TicketsService(client);
|
|
1095
1217
|
this.users = new UsersService(client);
|
package/dist/index.mjs
CHANGED
|
@@ -20,6 +20,7 @@ var UtiliaSDKError = class _UtiliaSDKError extends Error {
|
|
|
20
20
|
this.timestamp = /* @__PURE__ */ new Date();
|
|
21
21
|
this.requestId = options?.requestId;
|
|
22
22
|
this.statusCode = options?.statusCode;
|
|
23
|
+
this.errorCode = options?.errorCode;
|
|
23
24
|
if (Error.captureStackTrace) {
|
|
24
25
|
Error.captureStackTrace(this, _UtiliaSDKError);
|
|
25
26
|
}
|
|
@@ -31,6 +32,7 @@ var UtiliaSDKError = class _UtiliaSDKError extends Error {
|
|
|
31
32
|
return {
|
|
32
33
|
name: this.name,
|
|
33
34
|
code: this.code,
|
|
35
|
+
errorCode: this.errorCode,
|
|
34
36
|
message: this.message,
|
|
35
37
|
timestamp: this.timestamp.toISOString(),
|
|
36
38
|
requestId: this.requestId,
|
|
@@ -107,7 +109,9 @@ var UtiliaClient = class {
|
|
|
107
109
|
toSDKError(error) {
|
|
108
110
|
const requestId = error.response?.headers?.["x-request-id"] || error.config?._requestId;
|
|
109
111
|
const statusCode = error.response?.status;
|
|
110
|
-
const
|
|
112
|
+
const data = error.response?.data;
|
|
113
|
+
const errorCode = data?.errorCode;
|
|
114
|
+
const errorOptions = { requestId, statusCode, errorCode };
|
|
111
115
|
if (!error.response) {
|
|
112
116
|
if (error.code === "ECONNABORTED") {
|
|
113
117
|
return new UtiliaSDKError("NETWORK_ERROR" /* NETWORK_ERROR */, "Timeout: la solicitud excedio el tiempo limite", errorOptions);
|
|
@@ -115,7 +119,6 @@ var UtiliaClient = class {
|
|
|
115
119
|
return new UtiliaSDKError("NETWORK_ERROR" /* NETWORK_ERROR */, "Error de conexion: no se pudo conectar con el servidor", errorOptions);
|
|
116
120
|
}
|
|
117
121
|
const status = error.response.status;
|
|
118
|
-
const data = error.response.data;
|
|
119
122
|
const message = data?.message || data?.error || error.message;
|
|
120
123
|
switch (status) {
|
|
121
124
|
case 401:
|
|
@@ -278,18 +281,6 @@ var UtiliaClient = class {
|
|
|
278
281
|
}
|
|
279
282
|
};
|
|
280
283
|
|
|
281
|
-
// src/constants.ts
|
|
282
|
-
var SDK_LIMITS = {
|
|
283
|
-
TICKET_TITLE_MIN: 5,
|
|
284
|
-
TICKET_TITLE_MAX: 500,
|
|
285
|
-
TICKET_DESCRIPTION_MIN: 10,
|
|
286
|
-
MESSAGE_CONTENT_MIN: 1,
|
|
287
|
-
MESSAGE_CONTENT_MAX: 5e3,
|
|
288
|
-
FILE_NAME_MAX: 255,
|
|
289
|
-
EXTERNAL_ID_MAX: 255,
|
|
290
|
-
AVATAR_URL_MAX: 2048
|
|
291
|
-
};
|
|
292
|
-
|
|
293
284
|
// src/utils/validators.ts
|
|
294
285
|
function validateEmail(email) {
|
|
295
286
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -332,6 +323,88 @@ function validateRequired(value, fieldName) {
|
|
|
332
323
|
}
|
|
333
324
|
}
|
|
334
325
|
|
|
326
|
+
// src/services/errors.service.ts
|
|
327
|
+
var ErrorsService = class {
|
|
328
|
+
constructor(client) {
|
|
329
|
+
this.basePath = "/external/v1/errors";
|
|
330
|
+
this.client = client;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Reportar un error del sistema
|
|
334
|
+
*
|
|
335
|
+
* @param data - Datos del error a reportar
|
|
336
|
+
* @returns Resultado del reporte con hash de deduplicacion
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```typescript
|
|
340
|
+
* const result = await sdk.errors.report({
|
|
341
|
+
* message: 'Error al procesar pago',
|
|
342
|
+
* module: 'pagos',
|
|
343
|
+
* severity: 'critical',
|
|
344
|
+
* stack: error.stack,
|
|
345
|
+
* endpoint: '/api/payments',
|
|
346
|
+
* method: 'POST',
|
|
347
|
+
* });
|
|
348
|
+
* console.log(result.hash); // Hash unico del error
|
|
349
|
+
* console.log(result.deduplicated); // true si ya existia
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
async report(data) {
|
|
353
|
+
validateRequired(data.message, "message");
|
|
354
|
+
validateRequired(data.module, "module");
|
|
355
|
+
return this.client.post(`${this.basePath}/report`, data);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Listar errores reportados por esta aplicacion
|
|
359
|
+
*
|
|
360
|
+
* @param filters - Filtros opcionales (severidad, modulo, paginacion)
|
|
361
|
+
* @returns Lista paginada de errores
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```typescript
|
|
365
|
+
* const result = await sdk.errors.list({
|
|
366
|
+
* severity: ['critical', 'high'],
|
|
367
|
+
* resolved: false,
|
|
368
|
+
* limit: 20,
|
|
369
|
+
* });
|
|
370
|
+
* console.log(result.data); // Array de errores
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
async list(filters) {
|
|
374
|
+
return this.client.get(this.basePath, {
|
|
375
|
+
params: filters ? { ...filters } : void 0
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Obtener estadisticas de errores de esta aplicacion
|
|
380
|
+
*
|
|
381
|
+
* @returns Estadisticas agregadas de errores
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```typescript
|
|
385
|
+
* const stats = await sdk.errors.stats();
|
|
386
|
+
* console.log(stats.total); // Total de errores
|
|
387
|
+
* console.log(stats.unresolved); // Errores sin resolver
|
|
388
|
+
* console.log(stats.bySeverity); // { critical: 5, high: 10, ... }
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
async stats() {
|
|
392
|
+
return this.client.get(`${this.basePath}/stats`);
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
// src/constants.ts
|
|
397
|
+
var SDK_LIMITS = {
|
|
398
|
+
TICKET_TITLE_MIN: 5,
|
|
399
|
+
TICKET_TITLE_MAX: 500,
|
|
400
|
+
TICKET_DESCRIPTION_MIN: 10,
|
|
401
|
+
MESSAGE_CONTENT_MIN: 1,
|
|
402
|
+
MESSAGE_CONTENT_MAX: 5e3,
|
|
403
|
+
FILE_NAME_MAX: 255,
|
|
404
|
+
EXTERNAL_ID_MAX: 255,
|
|
405
|
+
AVATAR_URL_MAX: 2048
|
|
406
|
+
};
|
|
407
|
+
|
|
335
408
|
// src/services/files.service.ts
|
|
336
409
|
var FilesService = class {
|
|
337
410
|
constructor(client) {
|
|
@@ -523,6 +596,54 @@ var TicketsService = class {
|
|
|
523
596
|
{ params: { userId } }
|
|
524
597
|
);
|
|
525
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* Suscribirse a actualizaciones de tickets en tiempo real via SSE.
|
|
601
|
+
* Recibe eventos cuando un agente responde, cambia el estado, resuelve o cierra un ticket.
|
|
602
|
+
*
|
|
603
|
+
* Requiere un entorno con EventSource nativo (navegador) o un polyfill como 'eventsource'.
|
|
604
|
+
*
|
|
605
|
+
* @param userId - ID externo del usuario (opcional, filtra eventos por usuario)
|
|
606
|
+
* @param options - Callbacks para eventos y errores
|
|
607
|
+
* @returns Objeto con metodo close() para cerrar la conexion
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```typescript
|
|
611
|
+
* const stream = sdk.tickets.streamUpdates('user-123', {
|
|
612
|
+
* onTicketUpdated: (event) => {
|
|
613
|
+
* console.log(`Ticket ${event.ticketKey} actualizado: ${event.type}`);
|
|
614
|
+
* // Refrescar la UI del ticket
|
|
615
|
+
* },
|
|
616
|
+
* });
|
|
617
|
+
*
|
|
618
|
+
* // Para cerrar la conexion:
|
|
619
|
+
* stream.close();
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
streamUpdates(userId, options) {
|
|
623
|
+
if (typeof EventSource === "undefined") {
|
|
624
|
+
throw new Error(
|
|
625
|
+
'EventSource no esta disponible en este entorno. Para Node.js, instala un polyfill como "eventsource" y asignalo a globalThis.EventSource.'
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
const queryParams = userId ? `?userId=${encodeURIComponent(userId)}` : "";
|
|
629
|
+
const sseUrl = this.client.buildSseUrl(`${this.basePath}/events${queryParams}`);
|
|
630
|
+
const eventSource = new EventSource(sseUrl);
|
|
631
|
+
eventSource.onmessage = (event) => {
|
|
632
|
+
try {
|
|
633
|
+
const data = JSON.parse(event.data);
|
|
634
|
+
if (data.event === "ticket-updated" && options?.onTicketUpdated) {
|
|
635
|
+
options.onTicketUpdated(data);
|
|
636
|
+
}
|
|
637
|
+
} catch {
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
eventSource.onerror = () => {
|
|
641
|
+
options?.onError?.(new Error("Error en la conexion SSE"));
|
|
642
|
+
};
|
|
643
|
+
return {
|
|
644
|
+
close: () => eventSource.close()
|
|
645
|
+
};
|
|
646
|
+
}
|
|
526
647
|
/**
|
|
527
648
|
* Cerrar un ticket
|
|
528
649
|
* Solo el usuario que creo el ticket puede cerrarlo
|
|
@@ -1051,6 +1172,7 @@ var UtiliaSDK = class {
|
|
|
1051
1172
|
*/
|
|
1052
1173
|
constructor(config) {
|
|
1053
1174
|
const client = new UtiliaClient(config);
|
|
1175
|
+
this.errors = new ErrorsService(client);
|
|
1054
1176
|
this.files = new FilesService(client);
|
|
1055
1177
|
this.tickets = new TicketsService(client);
|
|
1056
1178
|
this.users = new UsersService(client);
|