@devlas/dte-sii 2.12.4 → 2.12.5

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/CafSolicitor.js CHANGED
@@ -601,4 +601,8 @@ class CafSolicitor {
601
601
 
602
602
  CafSolicitor._lastSolicitudAt = 0; // ms timestamp of last solicitar() call — for rate limiting
603
603
 
604
+ /** Retorna la sesión SII cacheada para un ambiente+rut, o null si no existe. */
605
+ CafSolicitor.getSession = (ambiente, rutEmisor) =>
606
+ _sessionRegistry.get(`${ambiente.toLowerCase()}::${rutEmisor}`) ?? null;
607
+
604
608
  module.exports = CafSolicitor;
package/FolioService.js CHANGED
@@ -57,14 +57,22 @@ class FolioService {
57
57
  this.cafDir = options.cafDir || path.join(this.baseDir, 'debug', 'auto-caf');
58
58
  this.debugDir = options.debugDir || path.join(this.baseDir, 'debug');
59
59
 
60
- // Sesión SII
61
- this.session = new SiiSession({
62
- ambiente: this.ambiente,
63
- certificado: options.certificado,
64
- pfxPath: options.pfxPath,
65
- pfxBuffer: options.pfxBuffer,
66
- pfxPassword: options.pfxPassword,
67
- });
60
+ // Sesión SII — priorizar reutilización para evitar bans del SII
61
+ // Orden: (1) sesión explícita, (2) registro de CafSolicitor, (3) nueva sesión
62
+ const cachedSession = CafSolicitor.getSession(this.ambiente, this.rutEmisor);
63
+ if (options.session) {
64
+ this.session = options.session;
65
+ } else if (cachedSession) {
66
+ this.session = cachedSession;
67
+ } else {
68
+ this.session = new SiiSession({
69
+ ambiente: this.ambiente,
70
+ certificado: options.certificado,
71
+ pfxPath: options.pfxPath,
72
+ pfxBuffer: options.pfxBuffer,
73
+ pfxPassword: options.pfxPassword,
74
+ });
75
+ }
68
76
 
69
77
  // Cargar sesión compartida si está disponible
70
78
  this.sessionPath = options.sessionPath || process.env.SII_SESSION_PATH;
@@ -352,7 +360,7 @@ class FolioService {
352
360
  * @param {string} [params.motivo]
353
361
  * @returns {Promise<{ok:boolean, anulados:Array, rechazados:Array, totalAnulados:number, totalRechazados:number}>}
354
362
  */
355
- async anularFolios({ tipoDte, folioDesde = null, folioHasta = null, motivo = 'Folios no utilizados' }) {
363
+ async anularFolios({ tipoDte, folioDesde = null, folioHasta = null, motivo = 'Folios no utilizados', maxRangos = 50 }) {
356
364
  const debugStampA = new Date().toISOString().replace(/[:.]/g, '-');
357
365
  const debugDirA = path.join(this.debugDir, 'auto-caf', 'anulacion', debugStampA);
358
366
  fs.mkdirSync(debugDirA, { recursive: true });
@@ -375,6 +383,9 @@ class FolioService {
375
383
  return !vistos.has(`${r.folioDesde}-${r.folioHasta}`);
376
384
  });
377
385
 
386
+ // Limitar a los más recientes para evitar operaciones masivas
387
+ if (rangos.length > maxRangos) rangos = rangos.slice(-maxRangos);
388
+
378
389
  if (rangos.length === 0) {
379
390
  console.log(`[FolioService] Pasada ${pasada + 1}: sin rangos nuevos, finalizando`);
380
391
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devlas/dte-sii",
3
- "version": "2.12.4",
3
+ "version": "2.12.5",
4
4
  "description": "Facturación y boletas electrónicas para el SII de Chile. Genera, timbra, firma y envía DTEs, libros electrónicos y automatiza la certificación.",
5
5
  "main": "index.js",
6
6
  "types": "dte-sii.d.ts",