@albertomarturelo/sii-core 0.7.0 → 0.9.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/dist/adapters/fake/index.d.ts +11 -1
  3. package/dist/adapters/fake/index.d.ts.map +1 -1
  4. package/dist/adapters/fake/index.js +19 -0
  5. package/dist/adapters/fake/index.js.map +1 -1
  6. package/dist/adapters/node/keyring.d.ts +12 -0
  7. package/dist/adapters/node/keyring.d.ts.map +1 -0
  8. package/dist/adapters/node/keyring.js +58 -0
  9. package/dist/adapters/node/keyring.js.map +1 -0
  10. package/dist/auth/auth.d.ts +14 -1
  11. package/dist/auth/auth.d.ts.map +1 -1
  12. package/dist/auth/auth.js +46 -4
  13. package/dist/auth/auth.js.map +1 -1
  14. package/dist/cli.d.ts +1 -1
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +3 -1
  17. package/dist/cli.js.map +1 -1
  18. package/dist/config/config.d.ts +15 -0
  19. package/dist/config/config.d.ts.map +1 -1
  20. package/dist/config/config.js +15 -0
  21. package/dist/config/config.js.map +1 -1
  22. package/dist/errors/errors.d.ts +5 -1
  23. package/dist/errors/errors.d.ts.map +1 -1
  24. package/dist/errors/errors.js +5 -1
  25. package/dist/errors/errors.js.map +1 -1
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/node.d.ts +6 -1
  31. package/dist/node.d.ts.map +1 -1
  32. package/dist/node.js +6 -1
  33. package/dist/node.js.map +1 -1
  34. package/dist/portal/dte-mipyme.d.ts +228 -0
  35. package/dist/portal/dte-mipyme.d.ts.map +1 -0
  36. package/dist/portal/dte-mipyme.js +890 -0
  37. package/dist/portal/dte-mipyme.js.map +1 -0
  38. package/dist/seams/index.d.ts +8 -1
  39. package/dist/seams/index.d.ts.map +1 -1
  40. package/dist/tasks/auth.d.ts +5 -0
  41. package/dist/tasks/auth.d.ts.map +1 -1
  42. package/dist/tasks/auth.js +5 -0
  43. package/dist/tasks/auth.js.map +1 -1
  44. package/dist/tasks/dte.d.ts +124 -0
  45. package/dist/tasks/dte.d.ts.map +1 -1
  46. package/dist/tasks/dte.js +471 -5
  47. package/dist/tasks/dte.js.map +1 -1
  48. package/package.json +2 -1
package/dist/tasks/dte.js CHANGED
@@ -1,11 +1,477 @@
1
- // Public DTE task API the surfaces call (ADR-003). Unlike rcv/f22/f29, `dteAuthorized`
2
- // is PUBLIC and login-free: it does NOT use `withSession` and works for ANY RUT
3
- // (counterparties included) without a session — the consulta touches no account, an
4
- // in-bounds class of access (ADR-004 ToS carve-out / ADR-014). The RUT is Mod-11-validated
5
- // locally BEFORE any request so a malformed RUT never becomes a wasted call.
1
+ // Public DTE task API the surfaces call (ADR-003) — the WHOLE `dte` artifact (ADR-024):
2
+ // `dteAuthorized` (public, login-free, palena — ADR-014) at the bottom, and the MIPYME portal
3
+ // surface (borradores + emitidos, empresa-keyed — ADR-023) below this header.
4
+ //
5
+ // The MIPYME half — BORRADORES ONLY: it creates, lists, previews and deletes DRAFT facturas in the SII's free facturación
6
+ // portal. It NEVER signs or emits a DTE (ADR-023): the portal's `mipeGenXMLFirma.cgi` step is
7
+ // out of scope, so nothing here can produce a legally-binding document.
8
+ //
9
+ // EMPRESA-KEYED (ADR-023). Unlike RCV (body-RUT) or F22 (session-keyed), the MIPYME portal has
10
+ // its OWN authorization list — the empresas that registered this user as "usuario autorizado",
11
+ // read live from `mipeSelEmpresa.cgi`. So `empresa` is validated against THAT list, not the
12
+ // operate pointer's operable set, and every task selects the empresa before acting.
13
+ //
14
+ // PII: a factura is receptor + emisor identity end to end, so rows are CURATED with NO `raw`
15
+ // (ADR-004), and the audit receipt carries only the empresa RUT, the borrador id and counts —
16
+ // never the receptor, the montos or the item glosas (ADR-006).
17
+ import { withSession } from '../auth/index.js';
6
18
  import { recordAudit } from '../audit/index.js';
7
19
  import { Rut } from '../rut/index.js';
8
20
  import { fetchDteAutorizados } from '../portal/dte-public.js';
21
+ import { DteError, SiiError, ValidationError } from '../errors/index.js';
22
+ import { DEFAULT_SETTINGS } from '../config/index.js';
23
+ import { FORMA_PAGO, MAX_ITEMS, TIPOS_DTE, fetchBorradores, fetchEmitidaPdf, fetchEmitidas, fetchEmpresas, fetchPreviewPdf, fillFactura, eliminaBorrador, grabaBorrador, isTipoDte, loadBorrador, resolveAndSelectEmpresa, } from '../portal/dte-mipyme.js';
24
+ export { TIPOS_DTE, MAX_ITEMS } from '../portal/dte-mipyme.js';
25
+ /** How far `dtePdf` walks the emitted listing when it is addressed by SII's internal
26
+ * `codigo`, which has no server-side filter (a `folio` does, so it needs one page). Bounded so
27
+ * a wrong codigo costs a known number of round trips, not an unbounded crawl (ADR-004). */
28
+ const MAX_PAGINAS_EMITIDAS = 20;
29
+ /** Inter-call pace (ms) between consecutive POSTs to SII. The MIPYME CGIs are the legacy,
30
+ * session-stateful kind and were observed to start timing out under a fast sequence, so this
31
+ * floors at 1000 ms rather than deriving a smaller value from `rateLimitRps`. Writes are NEVER
32
+ * retried (ADR-004); see `readOnlyRetry` for the read-only exception. */
33
+ const PACE_MS = 1000;
34
+ const pacingMs = () => Math.max(PACE_MS, Math.round(1000 / DEFAULT_SETTINGS.rateLimitRps));
35
+ /** A transport failure that never reached SII's application layer — the connection timed out or
36
+ * was reset. Deliberately NOT status-derived:
37
+ *
38
+ * * **429 is excluded.** CONVENTIONS is explicit — "Never retry after a SII rate-limit / block.
39
+ * It is server-side and timed; surface the message verbatim and stop." A 429 IS that signal,
40
+ * so retrying it is the forbidden behaviour, not an exception this module gets to make.
41
+ * * **5xx is excluded too**, because at this layer there is no status code to key off: the
42
+ * seams surface transport failures as `Error`, and sniffing `\b5\d{2}\b` out of prose would
43
+ * retry any message that happens to contain a three-digit number. Matching on prose is
44
+ * fragile, so the check keys off Playwright's structured `TimeoutError` name plus the two
45
+ * connection-level codes Node puts in `message`.
46
+ *
47
+ * Anything that reached SII — a business rejection, a validation failure, an unexpected HTML
48
+ * body, a dead session — is surfaced immediately (ADR-004). */
49
+ function isTransportFailure(e) {
50
+ if (!(e instanceof Error))
51
+ return false;
52
+ if (e instanceof SiiError)
53
+ return false; // reached SII: never retried
54
+ return e.name === 'TimeoutError' || /ECONNRESET|ECONNREFUSED|socket hang up/i.test(e.message);
55
+ }
56
+ /** Retry a READ-ONLY call at most twice, and ONLY on a transport failure (above). Never on a
57
+ * write, a validation error, or anything SII answered. Backoff is exponential with jitter so
58
+ * concurrent callers do not resonate; the jitter is derived from the `Clock` seam rather than
59
+ * a nondeterministic source, so the core stays deterministic under a fake clock (ADR-003). */
60
+ async function readOnlyRetry(runtime, fn) {
61
+ let lastError;
62
+ for (let attempt = 0; attempt <= 2; attempt += 1) {
63
+ try {
64
+ return await fn();
65
+ }
66
+ catch (e) {
67
+ lastError = e;
68
+ if (!isTransportFailure(e) || attempt === 2)
69
+ throw e;
70
+ const jitter = runtime.clock.now().getTime() % 250;
71
+ await runtime.clock.sleep(PACE_MS * 2 ** attempt + jitter);
72
+ }
73
+ }
74
+ throw lastError;
75
+ }
76
+ function audit(runtime, action, result, extra) {
77
+ recordAudit(runtime, { action, result, ...extra });
78
+ }
79
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
80
+ const todayIso = (runtime) => {
81
+ const d = runtime.clock.now();
82
+ const p = (n) => String(n).padStart(2, '0');
83
+ return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
84
+ };
85
+ function assertTipo(tipo) {
86
+ const t = tipo ?? 33;
87
+ if (!isTipoDte(t)) {
88
+ throw new ValidationError(`Tipo de DTE no soportado: ${t}. Disponibles: ${Object.entries(TIPOS_DTE)
89
+ .map(([k, v]) => `${k} (${v})`)
90
+ .join(', ')}.`);
91
+ }
92
+ return t;
93
+ }
94
+ /** Validate + normalize into the facade's input. Throws BEFORE any SII call so a malformed
95
+ * document never costs a round trip (the Mod-11-before-submit rule, ADR-004). */
96
+ function validate(runtime, args) {
97
+ const empresa = Rut.parse(args.empresa);
98
+ const receptor = Rut.parse(args.receptor.rut);
99
+ const tipoDte = assertTipo(args.tipoDte);
100
+ const fechaEmision = args.fechaEmision ?? todayIso(runtime);
101
+ if (!ISO_DATE.test(fechaEmision)) {
102
+ throw new ValidationError(`Fecha de emisión inválida: "${fechaEmision}" (formato YYYY-MM-DD).`);
103
+ }
104
+ if (args.ciudadEmisor.trim() === '') {
105
+ // SII leaves this blank on the form yet its own validator demands it (observed 2026-09-08).
106
+ throw new ValidationError('Falta la ciudad del emisor: el SII la exige pero no la trae precargada en el formulario.');
107
+ }
108
+ if (args.items.length === 0 || args.items.length > MAX_ITEMS) {
109
+ throw new ValidationError(`La factura necesita entre 1 y ${MAX_ITEMS} líneas de detalle.`);
110
+ }
111
+ args.items.forEach((it, i) => {
112
+ const n = i + 1;
113
+ if (it.nombre.trim() === '')
114
+ throw new ValidationError(`Línea ${n}: falta el nombre del ítem.`);
115
+ if (!Number.isFinite(it.cantidad) || it.cantidad <= 0) {
116
+ throw new ValidationError(`Línea ${n}: cantidad debe ser un número positivo.`);
117
+ }
118
+ if (!Number.isInteger(it.precioUnitario) || it.precioUnitario <= 0) {
119
+ throw new ValidationError(`Línea ${n}: precio unitario debe ser un entero positivo.`);
120
+ }
121
+ const d = it.descuentoPct;
122
+ if (d !== undefined && (!Number.isFinite(d) || d < 0 || d >= 100)) {
123
+ throw new ValidationError(`Línea ${n}: descuento debe estar entre 0 y 99 (%).`);
124
+ }
125
+ });
126
+ const formaPago = args.formaPago ?? 'credito';
127
+ if (!(formaPago in FORMA_PAGO)) {
128
+ throw new ValidationError(`Forma de pago inválida: "${formaPago}" (usa ${Object.keys(FORMA_PAGO).join(', ')}).`);
129
+ }
130
+ return {
131
+ empresa,
132
+ tipoDte,
133
+ input: {
134
+ tipoDte,
135
+ fechaEmision,
136
+ ciudadEmisor: args.ciudadEmisor.trim(),
137
+ receptor: {
138
+ rut: String(receptor.body),
139
+ dv: receptor.dv,
140
+ razonSocial: args.receptor.razonSocial,
141
+ direccion: args.receptor.direccion,
142
+ comuna: args.receptor.comuna,
143
+ ciudad: args.receptor.ciudad,
144
+ giro: args.receptor.giro,
145
+ ...(args.receptor.contacto ? { contacto: args.receptor.contacto } : {}),
146
+ },
147
+ items: args.items,
148
+ formaPago,
149
+ ...(args.borradorId ? { borradorId: args.borradorId } : {}),
150
+ },
151
+ };
152
+ }
153
+ /** The empresas this user may invoice for in the MIPYME portal — the live authorized list.
154
+ * Read-only; this is what a surface offers when the user has not picked an `--empresa`. */
155
+ export async function dteEmpresas(runtime, args = {}) {
156
+ const tipoDte = assertTipo(args.tipoDte);
157
+ try {
158
+ // The retry wraps the READ only. Wrapping `withSession` would tear down and rebuild the
159
+ // browser context on every attempt — and, worse, replay `mipeSelEmpresa.cgi`, which is
160
+ // server-side session state, not a read.
161
+ const res = await withSession(runtime, (session) => readOnlyRetry(runtime, () => fetchEmpresas(session, tipoDte, () => runtime.clock.sleep(pacingMs()))));
162
+ audit(runtime, 'dte_empresas', 'ok', { count: res.length });
163
+ return res;
164
+ }
165
+ catch (e) {
166
+ audit(runtime, 'dte_empresas', 'failed', {});
167
+ throw e;
168
+ }
169
+ }
170
+ /** The saved borradores of `empresa`. Curated rows, no `raw` (they are receptor PII). */
171
+ export async function dteBorradorList(runtime, args) {
172
+ const empresa = Rut.parse(args.empresa);
173
+ const tipoDte = assertTipo(args.tipoDte);
174
+ const start = runtime.clock.now().getTime();
175
+ try {
176
+ const res = await withSession(runtime, async (session) => {
177
+ const emp = await resolveAndSelectEmpresa(session, empresa, tipoDte, () => runtime.clock.sleep(pacingMs()));
178
+ await runtime.clock.sleep(pacingMs());
179
+ // retry the READ only — never the empresa selection, which mutates session state
180
+ return {
181
+ empresa: emp,
182
+ borradores: await readOnlyRetry(runtime, () => fetchBorradores(session)),
183
+ };
184
+ });
185
+ audit(runtime, 'dte_borrador_list', 'ok', {
186
+ rut: empresa.canonical,
187
+ count: res.borradores.length,
188
+ durationMs: runtime.clock.now().getTime() - start,
189
+ });
190
+ return res;
191
+ }
192
+ catch (e) {
193
+ audit(runtime, 'dte_borrador_list', 'failed', { rut: empresa.canonical });
194
+ throw e;
195
+ }
196
+ }
197
+ /** Create (or, with `borradorId`, update) a borrador. The document is validated by SII's OWN
198
+ * client-side validator first, so a rejection surfaces SII's Spanish message verbatim and
199
+ * costs no write. The new id is resolved by diffing the borradores list around the save —
200
+ * `mipeGrabaBorrador.cgi` returns only a confirmation page (observed). */
201
+ export async function dteBorradorSave(runtime, args) {
202
+ const { empresa, tipoDte, input } = validate(runtime, args);
203
+ const start = runtime.clock.now().getTime();
204
+ try {
205
+ const res = await withSession(runtime, async (session) => {
206
+ const emp = await resolveAndSelectEmpresa(session, empresa, tipoDte, () => runtime.clock.sleep(pacingMs()));
207
+ const before = input.borradorId ? [] : (await fetchBorradores(session)).map((b) => b.id);
208
+ await runtime.clock.sleep(pacingMs());
209
+ const filled = await fillFactura(session, emp, { ...input, empresa: emp.rut });
210
+ await runtime.clock.sleep(pacingMs());
211
+ await grabaBorrador(session, filled); // a WRITE — never retried (ADR-004)
212
+ await runtime.clock.sleep(pacingMs());
213
+ const id = input.borradorId
214
+ ? input.borradorId
215
+ : ((await fetchBorradores(session)).find((b) => !before.includes(b.id))?.id ?? null);
216
+ return {
217
+ id,
218
+ empresa: emp,
219
+ tipoDte,
220
+ tipoDteDesc: TIPOS_DTE[tipoDte],
221
+ actualizado: input.borradorId !== undefined,
222
+ totales: filled.totales,
223
+ avisos: filled.avisos,
224
+ };
225
+ });
226
+ // Audit the WRITE with identifiers only — never the receptor, montos or glosas (ADR-006).
227
+ audit(runtime, 'dte_borrador_save', 'ok', {
228
+ rut: empresa.canonical,
229
+ borradorId: res.id,
230
+ tipoDte,
231
+ items: input.items.length,
232
+ durationMs: runtime.clock.now().getTime() - start,
233
+ });
234
+ return res;
235
+ }
236
+ catch (e) {
237
+ audit(runtime, 'dte_borrador_save', 'failed', { rut: empresa.canonical, tipoDte });
238
+ throw e; // never retried after a SII error (ADR-004)
239
+ }
240
+ }
241
+ /** Delete a borrador. Irreversible on SII's side, so the surfaces gate it behind a confirm. */
242
+ export async function dteBorradorDelete(runtime, args) {
243
+ const empresa = Rut.parse(args.empresa);
244
+ // `tipoDte` is only a HINT here: the listing knows each borrador's real type, and deleting is
245
+ // the one irreversible operation — navigating with the wrong PTDC_CODIGO would fail
246
+ // confusingly. So resolve it from the listing and only fall back to the argument.
247
+ const hinted = assertTipo(args.tipoDte);
248
+ if (!/^\d+$/.test(args.borradorId)) {
249
+ throw new ValidationError(`Id de borrador inválido: "${args.borradorId}" (son dígitos).`);
250
+ }
251
+ const start = runtime.clock.now().getTime();
252
+ try {
253
+ const res = await withSession(runtime, async (session) => {
254
+ const emp = await resolveAndSelectEmpresa(session, empresa, hinted, () => runtime.clock.sleep(pacingMs()));
255
+ await runtime.clock.sleep(pacingMs());
256
+ const row = (await fetchBorradores(session)).find((b) => b.id === args.borradorId);
257
+ if (!row) {
258
+ throw new DteError(`El borrador ${args.borradorId} no existe en ${emp.rut}. Revisa \`dte borrador list\`.`);
259
+ }
260
+ const tipoDte = isTipoDte(row.tipoDte) ? row.tipoDte : hinted;
261
+ await runtime.clock.sleep(pacingMs());
262
+ const filled = await loadBorrador(session, emp, tipoDte, args.borradorId);
263
+ await runtime.clock.sleep(pacingMs());
264
+ await eliminaBorrador(session, filled); // a WRITE — never retried (ADR-004)
265
+ return { empresa: emp, borradorId: args.borradorId, tipoDte, eliminado: true };
266
+ });
267
+ audit(runtime, 'dte_borrador_delete', 'ok', {
268
+ rut: empresa.canonical,
269
+ borradorId: args.borradorId,
270
+ tipoDte: res.tipoDte,
271
+ durationMs: runtime.clock.now().getTime() - start,
272
+ });
273
+ return res;
274
+ }
275
+ catch (e) {
276
+ audit(runtime, 'dte_borrador_delete', 'failed', {
277
+ rut: empresa.canonical,
278
+ borradorId: args.borradorId,
279
+ });
280
+ throw e;
281
+ }
282
+ }
283
+ /** The "Validar y visualizar" PDF of a document that has NOT been emitted — stamped
284
+ * "VISTA PREVIA / DOCUMENTO NO VALIDO", no folio. Builds the document from `args` (an existing
285
+ * borrador can be re-previewed by passing its `borradorId`), fetches SII's PDF and writes it
286
+ * through the `FileSink` seam. `directorio` is REQUIRED: the pure core cannot know `$HOME`,
287
+ * so each surface applies its own default (ADR-022). */
288
+ export async function dtePreviewPdf(runtime, args) {
289
+ const { empresa, tipoDte, input } = validate(runtime, args);
290
+ const files = runtime.files;
291
+ if (!files) {
292
+ throw new DteError('Este runtime no tiene un FileSink configurado, así que no puede escribir el PDF. ' +
293
+ 'Usa `createNodeRuntime()` o inyecta `files`.');
294
+ }
295
+ const start = runtime.clock.now().getTime();
296
+ try {
297
+ const res = await withSession(runtime, async (session) => {
298
+ const emp = await resolveAndSelectEmpresa(session, empresa, tipoDte, () => runtime.clock.sleep(pacingMs()));
299
+ await runtime.clock.sleep(pacingMs());
300
+ const filled = await fillFactura(session, emp, { ...input, empresa: emp.rut });
301
+ await runtime.clock.sleep(pacingMs());
302
+ const bytes = await fetchPreviewPdf(session, filled, () => runtime.clock.sleep(pacingMs()));
303
+ // SII's own Content-Disposition is generic and carries no receptor/fecha, so compose the
304
+ // name here (ADR-022): deterministic, so re-previewing refreshes in place.
305
+ const archivo = `borrador-${tipoDte}-${empresa.canonical}-${input.fechaEmision}-${input.receptor.rut}.pdf`;
306
+ const path = await files.write(args.directorio, archivo, bytes);
307
+ return {
308
+ path,
309
+ archivo,
310
+ bytes: bytes.length,
311
+ contentType: 'application/pdf',
312
+ totales: filled.totales,
313
+ empresa: emp,
314
+ tipoDte,
315
+ avisos: filled.avisos,
316
+ };
317
+ });
318
+ audit(runtime, 'dte_preview_pdf', 'ok', {
319
+ rut: empresa.canonical,
320
+ tipoDte,
321
+ bytes: res.bytes,
322
+ durationMs: runtime.clock.now().getTime() - start,
323
+ });
324
+ return res;
325
+ }
326
+ catch (e) {
327
+ audit(runtime, 'dte_preview_pdf', 'failed', { rut: empresa.canonical, tipoDte });
328
+ throw e;
329
+ }
330
+ }
331
+ // --- Documentos emitidos (read-only; ADR-023's boundary is untouched) ----------------
332
+ /** The DTEs already EMITTED by `empresa`. Read-only — nothing here issues or signs.
333
+ *
334
+ * `tipoDte` does NOT filter the listing (use `tipoDoc` for that). It only picks the `OPCION`
335
+ * of the chooser GET, i.e. which destination `mipeSelEmpresa.cgi` is asked to forward to.
336
+ * Empresa selection is SESSION state independent of that destination, so any wired value
337
+ * scopes the session identically — but it is load-bearing on the single-empresa path, where
338
+ * SII answers a launcher that jumps to whatever `OPCION` named (#95). Kept explicit rather
339
+ * than hidden, and defaulted to 33. */
340
+ export async function dteEmitidos(runtime, args) {
341
+ const empresa = Rut.parse(args.empresa);
342
+ const tipoDte = assertTipo(args.tipoDte);
343
+ if (args.receptor !== undefined)
344
+ Rut.parse(args.receptor); // Mod-11 before any session
345
+ for (const [k, v] of [
346
+ ['desde', args.desde],
347
+ ['hasta', args.hasta],
348
+ ]) {
349
+ if (v !== undefined && !ISO_DATE.test(v)) {
350
+ throw new ValidationError(`--${k} inválida: "${v}" (formato YYYY-MM-DD).`);
351
+ }
352
+ }
353
+ const start = runtime.clock.now().getTime();
354
+ try {
355
+ const res = await withSession(runtime, async (session) => {
356
+ const emp = await resolveAndSelectEmpresa(session, empresa, tipoDte, () => runtime.clock.sleep(pacingMs()));
357
+ await runtime.clock.sleep(pacingMs());
358
+ const { empresa: _drop, tipoDte: _t, ...filtro } = args;
359
+ // retry the READ only — never the empresa selection, which mutates session state
360
+ return {
361
+ empresa: emp,
362
+ documentos: await readOnlyRetry(runtime, () => fetchEmitidas(session, filtro)),
363
+ };
364
+ });
365
+ audit(runtime, 'dte_emitidos', 'ok', {
366
+ rut: empresa.canonical,
367
+ count: res.documentos.length,
368
+ durationMs: runtime.clock.now().getTime() - start,
369
+ });
370
+ return res;
371
+ }
372
+ catch (e) {
373
+ audit(runtime, 'dte_emitidos', 'failed', { rut: empresa.canonical });
374
+ throw e;
375
+ }
376
+ }
377
+ /** Download an ALREADY EMITTED document as a PDF, addressed by its `folio` (what a human has)
378
+ * or by SII's internal `codigo`. The folio is resolved through the listing, so a wrong folio
379
+ * fails with a clear message instead of an opaque SII page. `directorio` is REQUIRED — the
380
+ * pure core cannot know `$HOME`; each surface applies its own default (ADR-022).
381
+ *
382
+ * A `folio` is resolved by asking SII to filter on it, so it is found whatever page it lives
383
+ * on. A `codigo` (SII's internal id) has no server-side filter, so the listing is WALKED page
384
+ * by page — paced via `Clock.sleep`, bounded, and the not-found error says how far it looked.
385
+ * `tipoDte` is the chooser's `OPCION`, not a filter — see `dteEmitidos`. */
386
+ export async function dtePdf(runtime, args) {
387
+ const empresa = Rut.parse(args.empresa);
388
+ const tipoDte = assertTipo(args.tipoDte);
389
+ if (args.folio === undefined && args.codigo === undefined) {
390
+ throw new ValidationError('Indica el folio del documento (o su código interno).');
391
+ }
392
+ if (args.folio !== undefined && (!Number.isInteger(args.folio) || args.folio <= 0)) {
393
+ throw new ValidationError(`Folio inválido: "${args.folio}" (entero positivo).`);
394
+ }
395
+ const files = runtime.files;
396
+ if (!files) {
397
+ throw new DteError('Este runtime no tiene un FileSink configurado, así que no puede escribir el PDF. ' +
398
+ 'Usa `createNodeRuntime()` o inyecta `files`.');
399
+ }
400
+ const start = runtime.clock.now().getTime();
401
+ try {
402
+ const res = await withSession(runtime, async (session) => {
403
+ const emp = await resolveAndSelectEmpresa(session, empresa, tipoDte, () => runtime.clock.sleep(pacingMs()));
404
+ await runtime.clock.sleep(pacingMs());
405
+ let doc;
406
+ let paginas = 0;
407
+ let listadoAgotado = false;
408
+ const folio = args.folio;
409
+ if (folio !== undefined) {
410
+ // SII filters on the folio server-side, so one page is enough whatever page it is on.
411
+ doc = (await readOnlyRetry(runtime, () => fetchEmitidas(session, { folio }))).find((d) => d.folio === folio);
412
+ }
413
+ else {
414
+ // `codigo` has no server-side filter — walk the listing, paced (ADR-004), bounded.
415
+ let previa = '';
416
+ for (let pagina = 1; pagina <= MAX_PAGINAS_EMITIDAS; pagina += 1) {
417
+ if (pagina > 1)
418
+ await runtime.clock.sleep(pacingMs());
419
+ const page = await readOnlyRetry(runtime, () => fetchEmitidas(session, { pagina }));
420
+ paginas = pagina;
421
+ doc = page.find((d) => d.codigo === args.codigo);
422
+ if (doc)
423
+ break;
424
+ // Stop on an empty page OR on a page identical to the previous one. A legacy CGI may
425
+ // CLAMP an out-of-range `NUM_PAG` to the last page rather than emptying it, and this
426
+ // one's behaviour past the end is NOT observed — without this guard a wrong codigo
427
+ // would re-scan the same rows until the bound, hammering SII (ADR-004).
428
+ const firma = page.map((d) => d.codigo).join(',');
429
+ if (page.length === 0 || firma === previa) {
430
+ listadoAgotado = true;
431
+ break;
432
+ }
433
+ previa = firma;
434
+ }
435
+ }
436
+ if (!doc) {
437
+ throw new DteError(args.folio !== undefined
438
+ ? `No se encontró un documento emitido con folio ${args.folio} en ${emp.rut}. ` +
439
+ 'Revisa `dte emitidos`.'
440
+ : `No se encontró un documento emitido con código ${args.codigo} en ${emp.rut} ` +
441
+ (listadoAgotado
442
+ ? `tras recorrer el listado completo (${paginas} página(s)). `
443
+ : `tras revisar ${paginas} página(s), el tope del recorrido — si conoces el ` +
444
+ 'folio, búscalo con `--folio`, que el SII filtra server-side. ') +
445
+ 'Revisa `dte emitidos`.');
446
+ }
447
+ await runtime.clock.sleep(pacingMs());
448
+ const bytes = await fetchEmitidaPdf(session, doc.codigo);
449
+ // SII's Content-Disposition is just `<rut>.pdf` — carries no folio, so compose the name
450
+ // here (ADR-022): deterministic, so re-downloading refreshes in place.
451
+ const archivo = `dte-${doc.folio ?? doc.codigo}-${empresa.canonical}-${doc.fecha ?? 'sin-fecha'}.pdf`;
452
+ const path = await files.write(args.directorio, archivo, bytes);
453
+ return {
454
+ path,
455
+ archivo,
456
+ bytes: bytes.length,
457
+ contentType: 'application/pdf',
458
+ empresa: emp,
459
+ documento: doc,
460
+ };
461
+ });
462
+ audit(runtime, 'dte_pdf', 'ok', {
463
+ rut: empresa.canonical,
464
+ folio: res.documento.folio,
465
+ bytes: res.bytes,
466
+ durationMs: runtime.clock.now().getTime() - start,
467
+ });
468
+ return res;
469
+ }
470
+ catch (e) {
471
+ audit(runtime, 'dte_pdf', 'failed', { rut: empresa.canonical, folio: args.folio ?? null });
472
+ throw e;
473
+ }
474
+ }
9
475
  export async function dteAuthorized(runtime, args) {
10
476
  const rut = Rut.parse(args.rut); // fail fast on a bad RUT — no request issued
11
477
  const start = runtime.clock.now().getTime();
@@ -1 +1 @@
1
- {"version":3,"file":"dte.js","sourceRoot":"","sources":["../../src/tasks/dte.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,gFAAgF;AAChF,oFAAoF;AACpF,2FAA2F;AAC3F,6EAA6E;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAW9D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAgB,EAChB,IAAuB;IAEvB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,6CAA6C;IAC9E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3D,qFAAqF;QACrF,gFAAgF;QAChF,WAAW,CAAC,OAAO,EAAE;YACnB,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,IAAI;YACZ,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK;SAClD,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,WAAW,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1F,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"dte.js","sourceRoot":"","sources":["../../src/tasks/dte.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@albertomarturelo/sii-core",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "Shared SII domain core: rut, config (prod hostnames), contracts, tasks, seams. A Node library; external side-effects (portal, secrets, audit, clock) are injected via seams (ADR-003).",
6
6
  "license": "MIT",
@@ -46,6 +46,7 @@
46
46
  }
47
47
  },
48
48
  "devDependencies": {
49
+ "@napi-rs/keyring": "2.0.0",
49
50
  "playwright": "^1.49.0"
50
51
  },
51
52
  "scripts": {