@albertomarturelo/sii-core 0.9.0 → 0.10.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 (53) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/adapters/fake/index.d.ts +3 -1
  3. package/dist/adapters/fake/index.d.ts.map +1 -1
  4. package/dist/adapters/fake/index.js +2 -1
  5. package/dist/adapters/fake/index.js.map +1 -1
  6. package/dist/adapters/node/portal.d.ts.map +1 -1
  7. package/dist/adapters/node/portal.js +11 -4
  8. package/dist/adapters/node/portal.js.map +1 -1
  9. package/dist/adapters/node/response.d.ts +12 -4
  10. package/dist/adapters/node/response.d.ts.map +1 -1
  11. package/dist/adapters/node/response.js +32 -7
  12. package/dist/adapters/node/response.js.map +1 -1
  13. package/dist/auth/auth.d.ts +28 -5
  14. package/dist/auth/auth.d.ts.map +1 -1
  15. package/dist/auth/auth.js +136 -30
  16. package/dist/auth/auth.js.map +1 -1
  17. package/dist/auth/session.d.ts +16 -1
  18. package/dist/auth/session.d.ts.map +1 -1
  19. package/dist/auth/session.js +12 -0
  20. package/dist/auth/session.js.map +1 -1
  21. package/dist/auth/www2-login.d.ts +28 -0
  22. package/dist/auth/www2-login.d.ts.map +1 -0
  23. package/dist/auth/www2-login.js +101 -0
  24. package/dist/auth/www2-login.js.map +1 -0
  25. package/dist/config/config.d.ts +13 -0
  26. package/dist/config/config.d.ts.map +1 -1
  27. package/dist/config/config.js +13 -0
  28. package/dist/config/config.js.map +1 -1
  29. package/dist/errors/errors.d.ts +25 -0
  30. package/dist/errors/errors.d.ts.map +1 -1
  31. package/dist/errors/errors.js +25 -0
  32. package/dist/errors/errors.js.map +1 -1
  33. package/dist/index.d.ts +3 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/portal/carpeta-tributaria-regular.d.ts +30 -0
  38. package/dist/portal/carpeta-tributaria-regular.d.ts.map +1 -0
  39. package/dist/portal/carpeta-tributaria-regular.js +142 -0
  40. package/dist/portal/carpeta-tributaria-regular.js.map +1 -0
  41. package/dist/portal/www2-session.d.ts +13 -0
  42. package/dist/portal/www2-session.d.ts.map +1 -0
  43. package/dist/portal/www2-session.js +61 -0
  44. package/dist/portal/www2-session.js.map +1 -0
  45. package/dist/tasks/auth.d.ts +9 -6
  46. package/dist/tasks/auth.d.ts.map +1 -1
  47. package/dist/tasks/auth.js +8 -5
  48. package/dist/tasks/auth.js.map +1 -1
  49. package/dist/tasks/carpeta.d.ts +9 -0
  50. package/dist/tasks/carpeta.d.ts.map +1 -0
  51. package/dist/tasks/carpeta.js +49 -0
  52. package/dist/tasks/carpeta.js.map +1 -0
  53. package/package.json +1 -1
@@ -9,6 +9,12 @@ export declare class NotAuthenticatedError extends SiiError {
9
9
  * so a generic catch still treats it as "not authenticated". */
10
10
  export declare class SessionExpiredError extends NotAuthenticatedError {
11
11
  }
12
+ /** The www2 APP SESSION (the second cookies-only layer `www2.sii.cl/app/*` needs — ADR-026) is
13
+ * missing or expired: `/app/session/status` did not answer a session JSON. A subclass of
14
+ * NotAuthenticated because the fix is a login (`sii auth login --www2`), never a retry — but
15
+ * DISTINCT from `SessionExpiredError` (the classic Mi SII session may be perfectly alive). */
16
+ export declare class Www2SessionError extends NotAuthenticatedError {
17
+ }
12
18
  /** Browser login was not completed (timeout / window closed). No partial
13
19
  * session is ever written. */
14
20
  export declare class LoginFailedError extends SiiError {
@@ -22,6 +28,17 @@ export declare class CredentialNotFoundError extends SiiError {
22
28
  /** Invalid user input: bad RUT, an operate target not in the operable set, etc. */
23
29
  export declare class ValidationError extends SiiError {
24
30
  }
31
+ /** An authenticated `requestJson` got a body that is NOT JSON and NOT the login wall —
32
+ * the response reached its destination host (no `LOGIN_HOST` bounce, not HTML) but the
33
+ * body does not parse. Observed 2026-09-11 (GH-111) on the cte-api
34
+ * `obtenerValorParametro` (URL cited in `adapters/node/response.ts`): HTTP 200
35
+ * `text/plain;charset=utf-8` with a bare URL — a live session, a wrong endpoint. Carries
36
+ * the endpoint, HTTP status, content-type and the first ~80 chars of the body VERBATIM
37
+ * (ADR-004), so a facade can tell a SII quirk from a dead session (`SessionExpiredError`)
38
+ * without a second round-trip. NOT a subclass of NotAuthenticated on purpose: re-login
39
+ * would not fix it. */
40
+ export declare class UnexpectedResponseError extends SiiError {
41
+ }
25
42
  /** SII rejected a portal/SDI facade request (error envelope or unparseable
26
43
  * response). Carries SII's message verbatim — never translated (ADR-004). */
27
44
  export declare class RepresentacionError extends SiiError {
@@ -65,4 +82,12 @@ export declare class PeticionesError extends SiiError {
65
82
  * `SessionExpiredError`, not this. */
66
83
  export declare class DteError extends SiiError {
67
84
  }
85
+ /** SII rejected a Carpeta Tributaria (`cte-api`) request, the body was not the observed shape
86
+ * ("scraper roto" — e.g. `/instituciones` not serving an array), the operation is invalid for
87
+ * its session-keyed contract (a representing pointer, ADR-005), OR the user's `--institucion` is
88
+ * not in SII's LIVE list (the message names the valid codes; no round-trip is spent). SII's
89
+ * message verbatim where one exists — never translated (ADR-004). Never retried; a missing www2
90
+ * app session is `Www2SessionError` and a `LOGIN_HOST` bounce `SessionExpiredError`, not this. */
91
+ export declare class CarpetaError extends SiiError {
92
+ }
68
93
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM;CAI5B;AAED,mEAAmE;AACnE,qBAAa,qBAAsB,SAAQ,QAAQ;CAAG;AAEtD;;iEAEiE;AACjE,qBAAa,mBAAoB,SAAQ,qBAAqB;CAAG;AAEjE;+BAC+B;AAC/B,qBAAa,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD,mFAAmF;AACnF,qBAAa,cAAe,SAAQ,QAAQ;CAAG;AAE/C,oFAAoF;AACpF,qBAAa,uBAAwB,SAAQ,QAAQ;CAAG;AAExD,mFAAmF;AACnF,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;8EAC8E;AAC9E,qBAAa,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;uFACuF;AACvF,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;8EAC8E;AAC9E,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;wFAGwF;AACxF,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;eAGe;AACf,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;;;gFAKgF;AAChF,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;;;;;;;;uCAQuC;AACvC,qBAAa,QAAS,SAAQ,QAAQ;CAAG"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM;CAI5B;AAED,mEAAmE;AACnE,qBAAa,qBAAsB,SAAQ,QAAQ;CAAG;AAEtD;;iEAEiE;AACjE,qBAAa,mBAAoB,SAAQ,qBAAqB;CAAG;AAEjE;;;+FAG+F;AAC/F,qBAAa,gBAAiB,SAAQ,qBAAqB;CAAG;AAE9D;+BAC+B;AAC/B,qBAAa,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD,mFAAmF;AACnF,qBAAa,cAAe,SAAQ,QAAQ;CAAG;AAE/C,oFAAoF;AACpF,qBAAa,uBAAwB,SAAQ,QAAQ;CAAG;AAExD,mFAAmF;AACnF,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;;;;;;;;wBAQwB;AACxB,qBAAa,uBAAwB,SAAQ,QAAQ;CAAG;AAExD;8EAC8E;AAC9E,qBAAa,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;uFACuF;AACvF,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;8EAC8E;AAC9E,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;wFAGwF;AACxF,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;eAGe;AACf,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;;;gFAKgF;AAChF,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;;;;;;;;uCAQuC;AACvC,qBAAa,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;;;mGAKmG;AACnG,qBAAa,YAAa,SAAQ,QAAQ;CAAG"}
@@ -15,6 +15,12 @@ export class NotAuthenticatedError extends SiiError {
15
15
  * so a generic catch still treats it as "not authenticated". */
16
16
  export class SessionExpiredError extends NotAuthenticatedError {
17
17
  }
18
+ /** The www2 APP SESSION (the second cookies-only layer `www2.sii.cl/app/*` needs — ADR-026) is
19
+ * missing or expired: `/app/session/status` did not answer a session JSON. A subclass of
20
+ * NotAuthenticated because the fix is a login (`sii auth login --www2`), never a retry — but
21
+ * DISTINCT from `SessionExpiredError` (the classic Mi SII session may be perfectly alive). */
22
+ export class Www2SessionError extends NotAuthenticatedError {
23
+ }
18
24
  /** Browser login was not completed (timeout / window closed). No partial
19
25
  * session is ever written. */
20
26
  export class LoginFailedError extends SiiError {
@@ -28,6 +34,17 @@ export class CredentialNotFoundError extends SiiError {
28
34
  /** Invalid user input: bad RUT, an operate target not in the operable set, etc. */
29
35
  export class ValidationError extends SiiError {
30
36
  }
37
+ /** An authenticated `requestJson` got a body that is NOT JSON and NOT the login wall —
38
+ * the response reached its destination host (no `LOGIN_HOST` bounce, not HTML) but the
39
+ * body does not parse. Observed 2026-09-11 (GH-111) on the cte-api
40
+ * `obtenerValorParametro` (URL cited in `adapters/node/response.ts`): HTTP 200
41
+ * `text/plain;charset=utf-8` with a bare URL — a live session, a wrong endpoint. Carries
42
+ * the endpoint, HTTP status, content-type and the first ~80 chars of the body VERBATIM
43
+ * (ADR-004), so a facade can tell a SII quirk from a dead session (`SessionExpiredError`)
44
+ * without a second round-trip. NOT a subclass of NotAuthenticated on purpose: re-login
45
+ * would not fix it. */
46
+ export class UnexpectedResponseError extends SiiError {
47
+ }
31
48
  /** SII rejected a portal/SDI facade request (error envelope or unparseable
32
49
  * response). Carries SII's message verbatim — never translated (ADR-004). */
33
50
  export class RepresentacionError extends SiiError {
@@ -71,4 +88,12 @@ export class PeticionesError extends SiiError {
71
88
  * `SessionExpiredError`, not this. */
72
89
  export class DteError extends SiiError {
73
90
  }
91
+ /** SII rejected a Carpeta Tributaria (`cte-api`) request, the body was not the observed shape
92
+ * ("scraper roto" — e.g. `/instituciones` not serving an array), the operation is invalid for
93
+ * its session-keyed contract (a representing pointer, ADR-005), OR the user's `--institucion` is
94
+ * not in SII's LIVE list (the message names the valid codes; no round-trip is spent). SII's
95
+ * message verbatim where one exists — never translated (ADR-004). Never retried; a missing www2
96
+ * app session is `Www2SessionError` and a `LOGIN_HOST` bounce `SessionExpiredError`, not this. */
97
+ export class CarpetaError extends SiiError {
98
+ }
74
99
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,2EAA2E;AAC3E,kEAAkE;AAElE,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF;AAED,mEAAmE;AACnE,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;CAAG;AAEtD;;iEAEiE;AACjE,MAAM,OAAO,mBAAoB,SAAQ,qBAAqB;CAAG;AAEjE;+BAC+B;AAC/B,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD,mFAAmF;AACnF,MAAM,OAAO,cAAe,SAAQ,QAAQ;CAAG;AAE/C,oFAAoF;AACpF,MAAM,OAAO,uBAAwB,SAAQ,QAAQ;CAAG;AAExD,mFAAmF;AACnF,MAAM,OAAO,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;8EAC8E;AAC9E,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;uFACuF;AACvF,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;8EAC8E;AAC9E,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;wFAGwF;AACxF,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;eAGe;AACf,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;;;gFAKgF;AAChF,MAAM,OAAO,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;;;;;;;;uCAQuC;AACvC,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,2EAA2E;AAC3E,kEAAkE;AAElE,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF;AAED,mEAAmE;AACnE,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;CAAG;AAEtD;;iEAEiE;AACjE,MAAM,OAAO,mBAAoB,SAAQ,qBAAqB;CAAG;AAEjE;;;+FAG+F;AAC/F,MAAM,OAAO,gBAAiB,SAAQ,qBAAqB;CAAG;AAE9D;+BAC+B;AAC/B,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD,mFAAmF;AACnF,MAAM,OAAO,cAAe,SAAQ,QAAQ;CAAG;AAE/C,oFAAoF;AACpF,MAAM,OAAO,uBAAwB,SAAQ,QAAQ;CAAG;AAExD,mFAAmF;AACnF,MAAM,OAAO,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;;;;;;;;wBAQwB;AACxB,MAAM,OAAO,uBAAwB,SAAQ,QAAQ;CAAG;AAExD;8EAC8E;AAC9E,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;uFACuF;AACvF,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;8EAC8E;AAC9E,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;wFAGwF;AACxF,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;eAGe;AACf,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;;;gFAKgF;AAChF,MAAM,OAAO,eAAgB,SAAQ,QAAQ;CAAG;AAEhD;;;;;;;;uCAQuC;AACvC,MAAM,OAAO,QAAS,SAAQ,QAAQ;CAAG;AAEzC;;;;;mGAKmG;AACnG,MAAM,OAAO,YAAa,SAAQ,QAAQ;CAAG"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { login, logout, authStatus, statusRefresh, whoami } from './tasks/auth.js';
2
- export type { AuthIdentity, AuthLoginResult, AuthLogoutResult, AuthStatusLocal, AuthWhoami, } from './tasks/auth.js';
2
+ export type { AuthIdentity, AuthIdentityRefresh, AuthLoginResult, AuthLogoutResult, AuthStatusLocal, AuthWhoami, AuthWww2Status, LoginOptions, } from './tasks/auth.js';
3
3
  export { operate, operateSelf, operatingStatus, listOperable } from './tasks/operate.js';
4
4
  export type { OperateResult, OperableList } from './tasks/operate.js';
5
5
  export { describeOperating, formatOperableEntry } from './identity/index.js';
@@ -16,6 +16,8 @@ export type { DteAutorizados, DteAutorizado, DteBorradorArgs, DteBorradorRow, Dt
16
16
  export type { BteMensual, BteBoleta, BteTotales, BteSide, BteEmitArgs, BteEmitResult, BteEmitida, BtePreview, BteRetiene, BteLineaEmision, } from './tasks/bte.js';
17
17
  export { peticionesList } from './tasks/peticiones.js';
18
18
  export type { PeticionesResult, Peticion, EstadoPeticion } from './tasks/peticiones.js';
19
+ export { carpetaInstituciones } from './tasks/carpeta.js';
20
+ export type { CarpetaInstitucion } from './tasks/carpeta.js';
19
21
  export type { AuditEntry, AuditSink, Clock, CredentialLoginOptions, InteractiveLoginOptions, KeyValueStore, PortalDriver, PortalSession, Runtime, SecretStore, } from './seams/index.js';
20
22
  export { Rut } from './rut/index.js';
21
23
  export { formatMoney, formatRut } from './format/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ export { f29Formulario, f29Overview, f29Pdf, f29Status, F29_GRUPO_LABELS, F29_PD
14
14
  export { bteList, bteEmitPreview, bteEmit } from './tasks/bte.js';
15
15
  export { dteAuthorized, dteEmpresas, dteBorradorList, dteBorradorSave, dteBorradorDelete, dtePreviewPdf, dteEmitidos, dtePdf, TIPOS_DTE, MAX_ITEMS, } from './tasks/dte.js';
16
16
  export { peticionesList } from './tasks/peticiones.js';
17
+ export { carpetaInstituciones } from './tasks/carpeta.js';
17
18
  // --- shared primitives ---
18
19
  export { Rut } from './rut/index.js';
19
20
  export { formatMoney, formatRut } from './format/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,gFAAgF;AAChF,6EAA6E;AAE7E,uCAAuC;AACvC,mFAAmF;AACnF,mGAAmG;AACnG,gDAAgD;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAQnF,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzF,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAUjE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAaxF,OAAO,EACL,aAAa,EACb,WAAW,EACX,MAAM,EACN,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAkBxB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,MAAM,EACN,SAAS,EACT,SAAS,GACV,MAAM,gBAAgB,CAAC;AA+BxB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAmBvD,4BAA4B;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtD,cAAc,mBAAmB,CAAC;AAElC,2EAA2E;AAC3E,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,gFAAgF;AAChF,6EAA6E;AAE7E,uCAAuC;AACvC,mFAAmF;AACnF,mGAAmG;AACnG,gDAAgD;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAWnF,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzF,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAUjE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAaxF,OAAO,EACL,aAAa,EACb,WAAW,EACX,MAAM,EACN,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAkBxB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,MAAM,EACN,SAAS,EACT,SAAS,GACV,MAAM,gBAAgB,CAAC;AA+BxB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAmB1D,4BAA4B;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtD,cAAc,mBAAmB,CAAC;AAElC,2EAA2E;AAC3E,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { Www2Session } from './www2-session.js';
2
+ import type { PortalSession } from '../seams/index.js';
3
+ /** A destination institution the Carpeta can be addressed to — SII's live catalog row, curated
4
+ * (all 8 observed keys; a public registry of entities, no taxpayer data). `codigo` is the
5
+ * `enfinCodigo` that `/generar` demands (#109); kept as a STRING because SII zero-pads some
6
+ * (`"016"`, `"059"`) and not others (`"1005"`) and compares it verbatim. */
7
+ export interface CarpetaInstitucion {
8
+ readonly codigo: string;
9
+ readonly descripcion: string | null;
10
+ readonly abreviacion: string | null;
11
+ /** SII's institution class (`enfinTipo`, observed 3 = corredora, 4 = otra; catalog-defined). */
12
+ readonly tipo: number | null;
13
+ /** The institution's own RUT (canonical), or null. Public entity data. */
14
+ readonly rut: string | null;
15
+ readonly vigenteDesde: string | null;
16
+ /** null = still vigente (observed on every row so far). */
17
+ readonly vigenteHasta: string | null;
18
+ }
19
+ /** `GET …/{userId}/…/instituciones` — SII's live list of destination institutions. `userId`
20
+ * comes from `readWww2Session` (the SPA keys the path by it verbatim). Empty array = a
21
+ * legitimate "no rows"; a non-array body = "scraper roto". */
22
+ export declare function fetchInstituciones(session: PortalSession, app: Www2Session): Promise<readonly CarpetaInstitucion[]>;
23
+ /** App-session read + `/instituciones` in one call: the read behind `sii carpeta instituciones`.
24
+ * A multi-step flow (#109) reads the session ONCE and calls the `fetch*` steps itself. */
25
+ export declare function listInstituciones(session: PortalSession): Promise<readonly CarpetaInstitucion[]>;
26
+ /** Validate the user's `--institucion` against SII's LIVE list and return the matching row.
27
+ * Fails BEFORE any `/generar` POST, naming the valid codes (like `--empresa` vs the MIPYME
28
+ * chooser, ADR-023) — a stale code never costs a SII round-trip. The consumer is #109. */
29
+ export declare function resolveInstitucion(codigo: string, instituciones: readonly CarpetaInstitucion[]): CarpetaInstitucion;
30
+ //# sourceMappingURL=carpeta-tributaria-regular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carpeta-tributaria-regular.d.ts","sourceRoot":"","sources":["../../src/portal/carpeta-tributaria-regular.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAavD;;;6EAG6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gGAAgG;IAChG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AA+DD;;+DAE+D;AAC/D,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CA0BxC;AAED;2FAC2F;AAC3F,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAGxC;AAED;;2FAE2F;AAC3F,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAC3C,kBAAkB,CAapB"}
@@ -0,0 +1,142 @@
1
+ // Carpeta Tributaria Regular — typed facade over the `www2.sii.cl` `cte-api-carpetatributaria`
2
+ // JSON facade (`PortalSession.requestJson`). First-hand-observed, no third-party library
3
+ // (ADR-004); full wire contract + the auth-layer finding in docs/sii-contract/carpeta-tributaria.md.
4
+ //
5
+ // The SPA is `https://www2.sii.cl/carpetatributaria/generarcteregular`; its API lives under
6
+ // `/app/cte-api-carpetatributaria/{userId}/recurso/v2/carpeta-tributaria/…`. Observed 2026-09-11
7
+ // (#110), from the shipped bundles (`carpetatributaria/js/app.c2aeeb0d.js`, the shared session
8
+ // library in `chunk-vendors.659f67b1.js`) and live probes:
9
+ //
10
+ // 1. THE APP SESSION. `www2.sii.cl/app/*` needs the www2 app session, a second cookies-only
11
+ // layer the classic jar does not carry (ADR-026) — read FIRST via the shared
12
+ // `portal/www2-session.ts`, whose `userId` keys every path below verbatim. Missing ⇒
13
+ // `Www2SessionError` (a NotAuthenticated), never a warm-up retry.
14
+ // 2. (The session read and its observations live in `www2-session.ts`.)
15
+ // 3. LIVE CATALOG. `/instituciones` is the ONLY source of a valid `enfinCodigo` (what `/generar`
16
+ // demands, #109). The codes drift — a hardcoded catalog went stale and SII rejected it — so
17
+ // this module never ships one: the user's choice is validated against SII's list at call
18
+ // time, like `--empresa` against the MIPYME chooser (ADR-023).
19
+ //
20
+ // Auth: SESSION-KEYED like F29 (ADR-005): the app session IS the principal; the task rejects a
21
+ // representing pointer up front. PII: the institution rows are a public catalog — curated, no
22
+ // `raw`. Nothing here touches the Carpeta document itself (#109, ADR-022 descriptor).
23
+ import { z } from 'zod';
24
+ import { HOSTS, WWW2_APP_CARPETA } from '../config/index.js';
25
+ import { CarpetaError, NotAuthenticatedError } from '../errors/index.js';
26
+ import { Rut } from '../rut/index.js';
27
+ import { readWww2Session } from './www2-session.js';
28
+ /** The SPA page ("Generar Carpeta Tributaria Regular"): the `Referer` the API expects and the
29
+ * `originalUrl` the session read carries (observed 2026-09-11). Also the `--www2` login page. */
30
+ const GENERAR_PAGE = WWW2_APP_CARPETA;
31
+ const API = `${HOSTS.portalApp}/app/cte-api-carpetatributaria`;
32
+ // The SPA's XHR headers (observed 2026-09-11): a JSON Accept + the page as Referer.
33
+ const HEADERS = {
34
+ Accept: 'application/json, text/plain, */*',
35
+ Referer: GENERAR_PAGE,
36
+ };
37
+ // --- Wire shapes (zod-at-the-boundary, ADR-011) ---------------------------------------
38
+ // `.loose()` rows: unobserved fields survive; projection is alias-tolerant (observed name
39
+ // first — ADR-004). `/instituciones` answers a BARE JSON ARRAY (no SDI `respEstado` envelope —
40
+ // this is the newer `cte-api`, not the www4 SDI facades).
41
+ const Row = z.record(z.string(), z.unknown());
42
+ const Instituciones = z.array(Row);
43
+ // Observed 2026-09-12 on `/instituciones` (67 rows): `{enfinCodigo, enfinDescripcion,
44
+ // enfinAbreviacion, enfinFechaVigDesde, enfinFechaVigHasta, enfinTipo, enfinRutInstitucion,
45
+ // enfinDvInstitucion}` — the SPA itself reads `e.enfinCodigo` / `e.enfinAbreviacion`.
46
+ const ALIASES = {
47
+ codigo: ['enfinCodigo', 'codigo'],
48
+ descripcion: ['enfinDescripcion', 'descripcion'],
49
+ abreviacion: ['enfinAbreviacion', 'abreviacion'],
50
+ tipo: ['enfinTipo', 'tipo'],
51
+ rutDigits: ['enfinRutInstitucion', 'rutInstitucion'],
52
+ dv: ['enfinDvInstitucion', 'dvInstitucion'],
53
+ vigenteDesde: ['enfinFechaVigDesde', 'fechaVigDesde'],
54
+ vigenteHasta: ['enfinFechaVigHasta', 'fechaVigHasta'],
55
+ };
56
+ function aliasGet(row, keys) {
57
+ for (const k of keys)
58
+ if (row[k] !== undefined && row[k] !== null)
59
+ return row[k];
60
+ return undefined;
61
+ }
62
+ const asStr = (v) => {
63
+ if (typeof v === 'string')
64
+ return v.trim() === '' ? null : v.trim();
65
+ if (typeof v === 'number')
66
+ return String(v);
67
+ return null;
68
+ };
69
+ const asInt = (v) => {
70
+ if (typeof v === 'number' && Number.isInteger(v))
71
+ return v;
72
+ if (typeof v === 'string' && /^\d+$/.test(v.trim()))
73
+ return Number(v.trim());
74
+ return null;
75
+ };
76
+ // `enfinRutInstitucion` (digits) + `enfinDvInstitucion` → canonical, Mod-11-checked; null if odd.
77
+ const canonicalRutFrom = (digits, dv) => digits === undefined || dv === undefined
78
+ ? null
79
+ : (Rut.tryParse(`${String(digits)}-${String(dv).trim()}`)?.canonical ?? null);
80
+ function curate(row) {
81
+ const codigo = asStr(aliasGet(row, ALIASES.codigo));
82
+ if (codigo === null) {
83
+ // A row without its key field means the shape moved: fail loud, never guess (ADR-004).
84
+ throw new CarpetaError('Scraper roto: una fila de /instituciones (Carpeta Tributaria) no trae `enfinCodigo`; ' +
85
+ 'el SII cambió la forma de la lista.');
86
+ }
87
+ return {
88
+ codigo,
89
+ descripcion: asStr(aliasGet(row, ALIASES.descripcion)),
90
+ abreviacion: asStr(aliasGet(row, ALIASES.abreviacion)),
91
+ tipo: asInt(aliasGet(row, ALIASES.tipo)),
92
+ rut: canonicalRutFrom(aliasGet(row, ALIASES.rutDigits), aliasGet(row, ALIASES.dv)),
93
+ vigenteDesde: asStr(aliasGet(row, ALIASES.vigenteDesde)),
94
+ vigenteHasta: asStr(aliasGet(row, ALIASES.vigenteHasta)),
95
+ };
96
+ }
97
+ /** `GET …/{userId}/…/instituciones` — SII's live list of destination institutions. `userId`
98
+ * comes from `readWww2Session` (the SPA keys the path by it verbatim). Empty array = a
99
+ * legitimate "no rows"; a non-array body = "scraper roto". */
100
+ export async function fetchInstituciones(session, app) {
101
+ let raw;
102
+ try {
103
+ raw = await session.requestJson(`${API}/${encodeURIComponent(app.userId)}/recurso/v2/carpeta-tributaria/instituciones`, { method: 'GET', headers: HEADERS });
104
+ }
105
+ catch (e) {
106
+ // A dead session is an ACTIONABLE NotAuthenticated (the seam detects the login wall) — let
107
+ // it through verbatim. Anything else (a 401 body, the wrong endpoint) is a typed CarpetaError
108
+ // carrying the seam's verbatim detail (ADR-004), never a raw Playwright error.
109
+ if (e instanceof NotAuthenticatedError)
110
+ throw e;
111
+ throw new CarpetaError(`Respuesta inesperada del SII en /instituciones (Carpeta Tributaria): ${e instanceof Error ? e.message : String(e)}`);
112
+ }
113
+ const parsed = Instituciones.safeParse(raw);
114
+ if (!parsed.success) {
115
+ throw new CarpetaError('Scraper roto: /instituciones (Carpeta Tributaria) no devolvió un arreglo JSON de ' +
116
+ 'instituciones; el SII cambió la forma de la lista.');
117
+ }
118
+ return parsed.data.map(curate);
119
+ }
120
+ /** App-session read + `/instituciones` in one call: the read behind `sii carpeta instituciones`.
121
+ * A multi-step flow (#109) reads the session ONCE and calls the `fetch*` steps itself. */
122
+ export async function listInstituciones(session) {
123
+ const app = await readWww2Session(session, GENERAR_PAGE);
124
+ return fetchInstituciones(session, app);
125
+ }
126
+ /** Validate the user's `--institucion` against SII's LIVE list and return the matching row.
127
+ * Fails BEFORE any `/generar` POST, naming the valid codes (like `--empresa` vs the MIPYME
128
+ * chooser, ADR-023) — a stale code never costs a SII round-trip. The consumer is #109. */
129
+ export function resolveInstitucion(codigo, instituciones) {
130
+ const wanted = codigo.trim();
131
+ const hit = instituciones.find((i) => i.codigo === wanted);
132
+ if (hit)
133
+ return hit;
134
+ const opciones = instituciones
135
+ .map((i) => `${i.codigo}${i.abreviacion ? ` (${i.abreviacion})` : ''}`)
136
+ .join(', ');
137
+ throw new CarpetaError(`La institución "${wanted}" no está en la lista vigente del SII para la Carpeta Tributaria. ` +
138
+ (instituciones.length === 0
139
+ ? 'El SII no devolvió instituciones.'
140
+ : `Códigos válidos (sii carpeta instituciones): ${opciones}.`));
141
+ }
142
+ //# sourceMappingURL=carpeta-tributaria-regular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carpeta-tributaria-regular.js","sourceRoot":"","sources":["../../src/portal/carpeta-tributaria-regular.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { PortalSession } from '../seams/index.js';
2
+ /** The www2 app session as `/app/session/status` describes it. Only `userId` is load-bearing
3
+ * (it keys every `/app/<name>-api` path); the rest is kept for diagnostics. */
4
+ export interface Www2Session {
5
+ readonly userId: string;
6
+ readonly userAuthType: string | null;
7
+ }
8
+ /** Read the www2 app session (see the header). Resolves `{userId}` when one exists; raises the
9
+ * ACTIONABLE `Www2SessionError` (a `NotAuthenticated`) when www2 answers anything but a 200
10
+ * session JSON — the classic session alone never reaches this layer. `originalUrl` is the app
11
+ * page the SPA would pass (observed optional; the answer is the same without it). Never retried. */
12
+ export declare function readWww2Session(session: PortalSession, originalUrl?: string): Promise<Www2Session>;
13
+ //# sourceMappingURL=www2-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"www2-session.d.ts","sourceRoot":"","sources":["../../src/portal/www2-session.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD;gFACgF;AAChF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAKD;;;qGAGqG;AACrG,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
@@ -0,0 +1,61 @@
1
+ // The www2 APP SESSION — the second cookies-only layer every `www2.sii.cl/app/*` facade needs
2
+ // (ADR-026). Shared by all www2 apps (first: Carpeta Tributaria, `carpeta-tributaria-regular.ts`),
3
+ // so a new app reuses this read instead of inventing a per-app warm-up.
4
+ //
5
+ // Observed 2026-09-11/12 (#110; docs/sii-contract/carpeta-tributaria.md): the classic `.sii.cl`
6
+ // cookies the cookies-only login holds reach www1/www3/www4/loa but NOT `/app/<name>-api/*` — those
7
+ // answer a bare 401 until the OAuth2 flow (`/app/session/login` → `/oauthsii-v1/` → `/app/session/
8
+ // create`) minted the httpOnly `.sii.cl` pair `X-SII-STATE-CT` + `X-SII-STATE-TYPE` (~100 min). The
9
+ // SPA's own liveness read is `GET /app/session/status` (session library `j()`): 200 → JSON
10
+ // `{seconds, userId, userProfiles, userAuthType, authTime, userRte}` committed to vuex; anything
11
+ // else → no session (the SPA then bounces to `/bifurcacion`). Every app keys its API paths by
12
+ // `session.userId` VERBATIM (the canonical `<body>-<dv>` RUT, observed) — so this read is where a
13
+ // facade gets its path key; it never formats a RUT for it.
14
+ //
15
+ // Reached via `requestText`: a non-JSON 401 body is EXPECTED here, and a dead classic jar is still
16
+ // caught URL-based (the `LOGIN_HOST` bounce → `SessionExpiredError`).
17
+ import { z } from 'zod';
18
+ import { HOSTS } from '../config/index.js';
19
+ import { Www2SessionError } from '../errors/index.js';
20
+ const SESSION_STATUS_URL = `${HOSTS.portalApp}/app/session/status`;
21
+ // Observed 2026-09-12 (live app session). `.loose()`: the other fields ride along unvalidated.
22
+ const SessionJson = z.object({ userId: z.union([z.string(), z.number()]) }).loose();
23
+ /** Read the www2 app session (see the header). Resolves `{userId}` when one exists; raises the
24
+ * ACTIONABLE `Www2SessionError` (a `NotAuthenticated`) when www2 answers anything but a 200
25
+ * session JSON — the classic session alone never reaches this layer. `originalUrl` is the app
26
+ * page the SPA would pass (observed optional; the answer is the same without it). Never retried. */
27
+ export async function readWww2Session(session, originalUrl) {
28
+ const url = originalUrl === undefined
29
+ ? SESSION_STATUS_URL
30
+ : `${SESSION_STATUS_URL}?originalUrl=${encodeURIComponent(originalUrl)}`;
31
+ const res = await session.requestText(url, {
32
+ method: 'GET',
33
+ headers: {
34
+ Accept: 'application/json, text/plain, */*',
35
+ ...(originalUrl === undefined ? {} : { Referer: originalUrl }),
36
+ },
37
+ });
38
+ let parsed = null;
39
+ if (res.status === 200) {
40
+ try {
41
+ parsed = JSON.parse(res.body);
42
+ }
43
+ catch {
44
+ parsed = null; // the SPA shell HTML (a 200 on a cold hit) is "no session" too
45
+ }
46
+ }
47
+ const app = parsed === null ? null : SessionJson.safeParse(parsed);
48
+ if (!app || !app.success) {
49
+ throw new Www2SessionError('No hay sesión en la plataforma www2 del SII (www2.sii.cl/app/*), que autoriza con una ' +
50
+ 'sesión propia (login OAuth) y no con la sesión de Mi SII que esta herramienta guarda ' +
51
+ `(HTTP ${res.status}${res.status === 200 ? ' sin JSON de sesión' : ''} en ` +
52
+ '/app/session/status). Iniciarla aún no está soportado — ADR-026 la define como un ' +
53
+ 'segundo login en el navegador (`sii auth login --www2`, pendiente).');
54
+ }
55
+ const authType = app.data['userAuthType'];
56
+ return {
57
+ userId: String(app.data.userId),
58
+ userAuthType: typeof authType === 'string' ? authType : null,
59
+ };
60
+ }
61
+ //# sourceMappingURL=www2-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"www2-session.js","sourceRoot":"","sources":["../../src/portal/www2-session.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mGAAmG;AACnG,wEAAwE;AACxE,EAAE;AACF,gGAAgG;AAChG,oGAAoG;AACpG,mGAAmG;AACnG,oGAAoG;AACpG,2FAA2F;AAC3F,iGAAiG;AACjG,8FAA8F;AAC9F,kGAAkG;AAClG,2DAA2D;AAC3D,EAAE;AACF,mGAAmG;AACnG,sEAAsE;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,SAAS,qBAAqB,CAAC;AASnE,+FAA+F;AAC/F,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAEpF;;;qGAGqG;AACrG,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAsB,EACtB,WAAoB;IAEpB,MAAM,GAAG,GACP,WAAW,KAAK,SAAS;QACvB,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,GAAG,kBAAkB,gBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IAC7E,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,MAAM,EAAE,mCAAmC;YAC3C,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;SAC/D;KACF,CAAC,CAAC;IACH,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAY,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,IAAI,CAAC,CAAC,+DAA+D;QAChF,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,gBAAgB,CACxB,wFAAwF;YACtF,uFAAuF;YACvF,SAAS,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM;YAC3E,oFAAoF;YACpF,qEAAqE,CACxE,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B,YAAY,EAAE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;KAC7D,CAAC;AACJ,CAAC"}
@@ -1,6 +1,8 @@
1
- import type { AuthIdentity, AuthLoginResult, AuthLogoutResult, AuthStatusLocal, AuthWhoami } from '../auth/index.js';
1
+ import type { AuthIdentity, AuthIdentityRefresh, AuthLoginResult, AuthLogoutResult, AuthStatusLocal, AuthWhoami, AuthWww2Status, LoginOptions } from '../auth/index.js';
2
2
  import type { Runtime } from '../seams/index.js';
3
- export declare function login(runtime: Runtime): Promise<AuthLoginResult>;
3
+ /** Browser login (ADR-006). `www2: true` also mints the www2 app-session layer in the same headed
4
+ * browser (ADR-026) — the user types the Clave into SII's OAuth page; never a password argument. */
5
+ export declare function login(runtime: Runtime, options?: LoginOptions): Promise<AuthLoginResult>;
4
6
  /** CLI-only (ADR-010): RUT + Clave from the console → headless login → cookies
5
7
  * only. The Clave is used once and never stored. NEVER expose over MCP. */
6
8
  export declare function consoleLogin(runtime: Runtime, credentials: {
@@ -13,12 +15,13 @@ export declare function keyringLogin(runtime: Runtime, args: {
13
15
  rut: string;
14
16
  }): Promise<AuthLoginResult>;
15
17
  export declare function logout(runtime: Runtime): Promise<AuthLogoutResult>;
16
- /** Pure local read (no portal call). */
18
+ /** Pure local read (no portal call). The www2 layer's `authenticated` is decided by its stored
19
+ * cookie expiry against the clock. */
17
20
  export declare function authStatus(runtime: Runtime): Promise<AuthStatusLocal>;
18
- /** Curated identity readback from the portal (needs a live session). */
19
- export declare function statusRefresh(runtime: Runtime): Promise<AuthIdentity>;
21
+ /** Curated identity readback from the portal (needs a live session) + the www2 layer read live. */
22
+ export declare function statusRefresh(runtime: Runtime): Promise<AuthIdentityRefresh>;
20
23
  /** whoami — the authenticated principal's own razón social/nombre + email (own PII).
21
24
  * Live portal read; session-keyed (ignores the operate pointer). */
22
25
  export declare function whoami(runtime: Runtime): Promise<AuthWhoami>;
23
- export type { AuthIdentity, AuthLoginResult, AuthLogoutResult, AuthStatusLocal, AuthWhoami };
26
+ export type { AuthIdentity, AuthIdentityRefresh, AuthLoginResult, AuthLogoutResult, AuthStatusLocal, AuthWhoami, AuthWww2Status, LoginOptions, };
24
27
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tasks/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,wBAAgB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAEhE;AAED;4EAC4E;AAC5E,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED;2FAC2F;AAC3F,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAE9F;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAElE;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAErE;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAErE;AAED;qEACqE;AACrE,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAE5D;AAED,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tasks/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,cAAc,EACd,YAAY,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;qGACqG;AACrG,wBAAgB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAE5F;AAED;4EAC4E;AAC5E,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,eAAe,CAAC,CAE1B;AAED;2FAC2F;AAC3F,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAE9F;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAElE;AAED;uCACuC;AACvC,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAErE;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAE5E;AAED;qEACqE;AACrE,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAE5D;AAED,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,cAAc,EACd,YAAY,GACb,CAAC"}
@@ -1,7 +1,9 @@
1
1
  // Public auth API the surfaces call. Uniform: every operation takes a Runtime.
2
2
  import * as auth from '../auth/index.js';
3
- export function login(runtime) {
4
- return auth.login(runtime);
3
+ /** Browser login (ADR-006). `www2: true` also mints the www2 app-session layer in the same headed
4
+ * browser (ADR-026) — the user types the Clave into SII's OAuth page; never a password argument. */
5
+ export function login(runtime, options = {}) {
6
+ return auth.login(runtime, options);
5
7
  }
6
8
  /** CLI-only (ADR-010): RUT + Clave from the console → headless login → cookies
7
9
  * only. The Clave is used once and never stored. NEVER expose over MCP. */
@@ -16,11 +18,12 @@ export function keyringLogin(runtime, args) {
16
18
  export function logout(runtime) {
17
19
  return auth.logout(runtime);
18
20
  }
19
- /** Pure local read (no portal call). */
21
+ /** Pure local read (no portal call). The www2 layer's `authenticated` is decided by its stored
22
+ * cookie expiry against the clock. */
20
23
  export function authStatus(runtime) {
21
- return auth.localStatus(runtime.store);
24
+ return auth.localStatus(runtime.store, runtime.clock.now());
22
25
  }
23
- /** Curated identity readback from the portal (needs a live session). */
26
+ /** Curated identity readback from the portal (needs a live session) + the www2 layer read live. */
24
27
  export function statusRefresh(runtime) {
25
28
  return auth.statusRefresh(runtime);
26
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tasks/auth.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AAUzC,MAAM,UAAU,KAAK,CAAC,OAAgB;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED;4EAC4E;AAC5E,MAAM,UAAU,YAAY,CAC1B,OAAgB,EAChB,WAA2C;IAE3C,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAED;2FAC2F;AAC3F,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,IAAqB;IAClE,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAgB;IACrC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,MAAM,CAAC,OAAgB;IACrC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tasks/auth.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,KAAK,IAAI,MAAM,kBAAkB,CAAC;AAazC;qGACqG;AACrG,MAAM,UAAU,KAAK,CAAC,OAAgB,EAAE,UAAwB,EAAE;IAChE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;4EAC4E;AAC5E,MAAM,UAAU,YAAY,CAC1B,OAAgB,EAChB,WAA2C;IAE3C,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAED;2FAC2F;AAC3F,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,IAAqB;IAClE,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAgB;IACrC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;uCACuC;AACvC,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,MAAM,CAAC,OAAgB;IACrC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { CarpetaInstitucion } from '../portal/carpeta-tributaria-regular.js';
2
+ import type { Runtime } from '../seams/index.js';
3
+ export type { CarpetaInstitucion } from '../portal/carpeta-tributaria-regular.js';
4
+ /** SII's LIVE list of destination institutions for the Carpeta Tributaria Regular — the
5
+ * `enfinCodigo` catalog `carpeta regular --institucion` is validated against. Never cached, never
6
+ * hardcoded: the codes drift (#110). Public catalog rows (no taxpayer data); the audit records
7
+ * the read (rut + count) only. */
8
+ export declare function carpetaInstituciones(runtime: Runtime): Promise<readonly CarpetaInstitucion[]>;
9
+ //# sourceMappingURL=carpeta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carpeta.d.ts","sourceRoot":"","sources":["../../src/tasks/carpeta.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,KAAK,EAAc,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE7D,YAAY,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAkBlF;;;mCAGmC;AACnC,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAoBxC"}
@@ -0,0 +1,49 @@
1
+ // Public Carpeta Tributaria tasks the surfaces call (ADR-003). Wraps the `cte-api` facade in
2
+ // `withSession` and writes ONE audit receipt per call.
3
+ //
4
+ // Carpeta is SESSION-KEYED (ADR-005): the app serves the principal's own Carpeta, so the tasks
5
+ // read `ctx.sessionRut`, take NO `--rut`, and reject a representing operate pointer up front
6
+ // (same posture as F29). The www2 `cte-api` also needs the www2 APP SESSION (ADR-026): the
7
+ // facade reads it first (`portal/www2-session.ts`) and raises `Www2SessionError` (a
8
+ // NotAuthenticated) when it is missing — minting it is `sii auth login --www2`, pending.
9
+ //
10
+ // #110 ships `carpetaInstituciones` (the live `enfinCodigo` catalog); #109 adds `carpetaRegular`
11
+ // (the PDF, ADR-022 descriptor) on top of the same facade.
12
+ import { assertOperatingSelf, withSession } from '../auth/index.js';
13
+ import { recordAudit } from '../audit/index.js';
14
+ import { CarpetaError } from '../errors/index.js';
15
+ import { listInstituciones } from '../portal/carpeta-tributaria-regular.js';
16
+ function audit(runtime, action, result, extra) {
17
+ recordAudit(runtime, { action, result, ...extra });
18
+ }
19
+ // Session-keyed (ADR-005): the shared guard, with this surface's own error + wording.
20
+ const assertSelfOperating = (runtime) => assertOperatingSelf(runtime, (empresa) => new CarpetaError(`La Carpeta Tributaria es session-keyed: el SII autoriza por el titular de la sesión, no ` +
21
+ `por el RUT operado (${empresa}). Para la carpeta de esa empresa, inicia sesión como ` +
22
+ 'ella (`sii auth logout` y luego `sii auth login`).'));
23
+ /** SII's LIVE list of destination institutions for the Carpeta Tributaria Regular — the
24
+ * `enfinCodigo` catalog `carpeta regular --institucion` is validated against. Never cached, never
25
+ * hardcoded: the codes drift (#110). Public catalog rows (no taxpayer data); the audit records
26
+ * the read (rut + count) only. */
27
+ export async function carpetaInstituciones(runtime) {
28
+ await assertSelfOperating(runtime);
29
+ const start = runtime.clock.now().getTime();
30
+ try {
31
+ const { res, rut } = await withSession(runtime, async (session, ctx) => ({
32
+ // session-keyed: the www2 app session IS the principal (the facade reads its userId);
33
+ // the audit records the classic principal we acted for.
34
+ res: await listInstituciones(session),
35
+ rut: ctx.sessionRut,
36
+ }));
37
+ audit(runtime, 'carpeta_instituciones', 'ok', {
38
+ rut,
39
+ count: res.length,
40
+ durationMs: runtime.clock.now().getTime() - start,
41
+ });
42
+ return res;
43
+ }
44
+ catch (e) {
45
+ audit(runtime, 'carpeta_instituciones', 'failed', {});
46
+ throw e;
47
+ }
48
+ }
49
+ //# sourceMappingURL=carpeta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carpeta.js","sourceRoot":"","sources":["../../src/tasks/carpeta.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,uDAAuD;AACvD,EAAE;AACF,+FAA+F;AAC/F,6FAA6F;AAC7F,2FAA2F;AAC3F,oFAAoF;AACpF,yFAAyF;AACzF,EAAE;AACF,iGAAiG;AACjG,2DAA2D;AAC3D,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAM5E,SAAS,KAAK,CAAC,OAAgB,EAAE,MAAc,EAAE,MAAc,EAAE,KAA0B;IACzF,WAAW,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,sFAAsF;AACtF,MAAM,mBAAmB,GAAG,CAAC,OAAgB,EAAiB,EAAE,CAC9D,mBAAmB,CACjB,OAAO,EACP,CAAC,OAAO,EAAE,EAAE,CACV,IAAI,YAAY,CACd,0FAA0F;IACxF,uBAAuB,OAAO,wDAAwD;IACtF,oDAAoD,CACvD,CACJ,CAAC;AAEJ;;;mCAGmC;AACnC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB;IAEhB,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;YACvE,sFAAsF;YACtF,wDAAwD;YACxD,GAAG,EAAE,MAAM,iBAAiB,CAAC,OAAO,CAAC;YACrC,GAAG,EAAE,GAAG,CAAC,UAAU;SACpB,CAAC,CAAC,CAAC;QACJ,KAAK,CAAC,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE;YAC5C,GAAG;YACH,KAAK,EAAE,GAAG,CAAC,MAAM;YACjB,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,KAAK,CAAC,OAAO,EAAE,uBAAuB,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@albertomarturelo/sii-core",
3
- "version": "0.9.0",
3
+ "version": "0.10.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",