@albertomarturelo/sii-core 0.9.0 → 0.11.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 (90) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/dist/adapters/fake/index.d.ts +20 -4
  3. package/dist/adapters/fake/index.d.ts.map +1 -1
  4. package/dist/adapters/fake/index.js +38 -4
  5. package/dist/adapters/fake/index.js.map +1 -1
  6. package/dist/adapters/node/cookie-jar.d.ts +35 -0
  7. package/dist/adapters/node/cookie-jar.d.ts.map +1 -0
  8. package/dist/adapters/node/cookie-jar.js +211 -0
  9. package/dist/adapters/node/cookie-jar.js.map +1 -0
  10. package/dist/adapters/node/http.d.ts +12 -0
  11. package/dist/adapters/node/http.d.ts.map +1 -0
  12. package/dist/adapters/node/http.js +262 -0
  13. package/dist/adapters/node/http.js.map +1 -0
  14. package/dist/adapters/node/portal.d.ts.map +1 -1
  15. package/dist/adapters/node/portal.js +18 -8
  16. package/dist/adapters/node/portal.js.map +1 -1
  17. package/dist/adapters/node/response.d.ts +12 -4
  18. package/dist/adapters/node/response.d.ts.map +1 -1
  19. package/dist/adapters/node/response.js +36 -8
  20. package/dist/adapters/node/response.js.map +1 -1
  21. package/dist/auth/auth.d.ts +55 -6
  22. package/dist/auth/auth.d.ts.map +1 -1
  23. package/dist/auth/auth.js +238 -56
  24. package/dist/auth/auth.js.map +1 -1
  25. package/dist/auth/datos-cntr.d.ts +23 -0
  26. package/dist/auth/datos-cntr.d.ts.map +1 -0
  27. package/dist/auth/datos-cntr.js +81 -0
  28. package/dist/auth/datos-cntr.js.map +1 -0
  29. package/dist/auth/index.d.ts +1 -0
  30. package/dist/auth/index.d.ts.map +1 -1
  31. package/dist/auth/login-block.d.ts +23 -0
  32. package/dist/auth/login-block.d.ts.map +1 -0
  33. package/dist/auth/login-block.js +53 -0
  34. package/dist/auth/login-block.js.map +1 -0
  35. package/dist/auth/login-error.d.ts +20 -3
  36. package/dist/auth/login-error.d.ts.map +1 -1
  37. package/dist/auth/login-error.js +20 -5
  38. package/dist/auth/login-error.js.map +1 -1
  39. package/dist/auth/session.d.ts +29 -2
  40. package/dist/auth/session.d.ts.map +1 -1
  41. package/dist/auth/session.js +35 -2
  42. package/dist/auth/session.js.map +1 -1
  43. package/dist/auth/www2-login.d.ts +28 -0
  44. package/dist/auth/www2-login.d.ts.map +1 -0
  45. package/dist/auth/www2-login.js +101 -0
  46. package/dist/auth/www2-login.js.map +1 -0
  47. package/dist/cli.d.ts +2 -2
  48. package/dist/cli.d.ts.map +1 -1
  49. package/dist/cli.js +4 -1
  50. package/dist/cli.js.map +1 -1
  51. package/dist/config/config.d.ts +21 -0
  52. package/dist/config/config.d.ts.map +1 -1
  53. package/dist/config/config.js +21 -0
  54. package/dist/config/config.js.map +1 -1
  55. package/dist/errors/errors.d.ts +59 -2
  56. package/dist/errors/errors.d.ts.map +1 -1
  57. package/dist/errors/errors.js +55 -2
  58. package/dist/errors/errors.js.map +1 -1
  59. package/dist/index.d.ts +3 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/node.d.ts +7 -3
  64. package/dist/node.d.ts.map +1 -1
  65. package/dist/node.js +10 -4
  66. package/dist/node.js.map +1 -1
  67. package/dist/portal/carpeta-tributaria-regular.d.ts +30 -0
  68. package/dist/portal/carpeta-tributaria-regular.d.ts.map +1 -0
  69. package/dist/portal/carpeta-tributaria-regular.js +142 -0
  70. package/dist/portal/carpeta-tributaria-regular.js.map +1 -0
  71. package/dist/portal/www2-session.d.ts +13 -0
  72. package/dist/portal/www2-session.d.ts.map +1 -0
  73. package/dist/portal/www2-session.js +61 -0
  74. package/dist/portal/www2-session.js.map +1 -0
  75. package/dist/seams/index.d.ts +7 -0
  76. package/dist/seams/index.d.ts.map +1 -1
  77. package/dist/tasks/auth.d.ts +23 -6
  78. package/dist/tasks/auth.d.ts.map +1 -1
  79. package/dist/tasks/auth.js +20 -5
  80. package/dist/tasks/auth.js.map +1 -1
  81. package/dist/tasks/bte.d.ts.map +1 -1
  82. package/dist/tasks/bte.js +4 -2
  83. package/dist/tasks/bte.js.map +1 -1
  84. package/dist/tasks/carpeta.d.ts +9 -0
  85. package/dist/tasks/carpeta.d.ts.map +1 -0
  86. package/dist/tasks/carpeta.js +49 -0
  87. package/dist/tasks/carpeta.js.map +1 -0
  88. package/dist/tasks/dte.js +8 -8
  89. package/dist/tasks/dte.js.map +1 -1
  90. package/package.json +1 -1
@@ -9,19 +9,68 @@ 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
- /** Browser login was not completed (timeout / window closed). No partial
13
- * session is ever written. */
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
+ }
18
+ /** Why a login was rejected, as DATA so a downstream consumer never regex-parses the
19
+ * message (#124). `'wrong-clave'` ONLY for SII's observed wrong-Clave código; every
20
+ * other código, a changed page shape, a timeout or the generic fallback is `'unknown'`
21
+ * — the safe direction (a consumer treats unknown as "blocked", never as "retry"). */
22
+ export type LoginFailureReason = 'wrong-clave' | 'unknown';
23
+ /** Browser login was not completed (timeout / window closed) OR SII rejected the Clave.
24
+ * No partial session is ever written. Carries the classified `reason` + SII's message
25
+ * `codigo` (when the page printed one) alongside the verbatim message, so a consumer
26
+ * reads them as data (#124). Both are additive: `new LoginFailedError(msg)` still works
27
+ * (`reason: 'unknown'`, `codigo: null`). */
14
28
  export declare class LoginFailedError extends SiiError {
29
+ readonly reason: LoginFailureReason;
30
+ readonly codigo: string | null;
31
+ constructor(message: string, opts?: {
32
+ reason?: LoginFailureReason;
33
+ codigo?: string | null;
34
+ });
15
35
  }
16
36
  /** SII server-side rate limit / block. NEVER retry — surface verbatim and stop. */
17
37
  export declare class RateLimitError extends SiiError {
18
38
  }
39
+ /** A surface needs a JS engine (SII's own page JS must run — BTE inline maps, MIPYME's
40
+ * in-page `validaFacEx`) but the runtime carries no `browser` engine: the default HTTP
41
+ * `PortalDriver` cannot `evaluate`/`interactiveLogin` (ADR-027). Actionable — names the
42
+ * Playwright install — never a silent fallback. */
43
+ export declare class BrowserRequiredError extends SiiError {
44
+ }
45
+ /** The login POST was redirected into SII's Queue-it waiting room (`salaespera.sii.cl`),
46
+ * the peak-load queue an HTTP client cannot pass (observed in the browser jar, ADR-027).
47
+ * NOT a credential failure and NOT retryable here — surface it and stop. */
48
+ export declare class LoginQueuedError extends LoginFailedError {
49
+ }
50
+ /** A NON-interactive login (`--clave-env` / `--clave-stdin` / `--keyring`) refused WITHOUT
51
+ * contacting SII because the rejection latch is set for that RUT: SII rejected a Clave for
52
+ * it earlier, and an unattended retry of the same stale value is how an account gets locked
53
+ * (ADR-028). Carries the latched `codigo`/`reason`. Lifted by an interactive login or
54
+ * `sii auth unblock`. A LoginFailed subclass, so it keeps that exit code. */
55
+ export declare class LoginBlockedError extends LoginFailedError {
56
+ }
19
57
  /** A stored credential was required (e.g. unattended re-mint) but none resolved. */
20
58
  export declare class CredentialNotFoundError extends SiiError {
21
59
  }
22
60
  /** Invalid user input: bad RUT, an operate target not in the operable set, etc. */
23
61
  export declare class ValidationError extends SiiError {
24
62
  }
63
+ /** An authenticated `requestJson` got a body that is NOT JSON and NOT the login wall —
64
+ * the response reached its destination host (no `LOGIN_HOST` bounce, not HTML) but the
65
+ * body does not parse. Observed 2026-09-11 (GH-111) on the cte-api
66
+ * `obtenerValorParametro` (URL cited in `adapters/node/response.ts`): HTTP 200
67
+ * `text/plain;charset=utf-8` with a bare URL — a live session, a wrong endpoint. Carries
68
+ * the endpoint, HTTP status, content-type and the first ~80 chars of the body VERBATIM
69
+ * (ADR-004), so a facade can tell a SII quirk from a dead session (`SessionExpiredError`)
70
+ * without a second round-trip. NOT a subclass of NotAuthenticated on purpose: re-login
71
+ * would not fix it. */
72
+ export declare class UnexpectedResponseError extends SiiError {
73
+ }
25
74
  /** SII rejected a portal/SDI facade request (error envelope or unparseable
26
75
  * response). Carries SII's message verbatim — never translated (ADR-004). */
27
76
  export declare class RepresentacionError extends SiiError {
@@ -65,4 +114,12 @@ export declare class PeticionesError extends SiiError {
65
114
  * `SessionExpiredError`, not this. */
66
115
  export declare class DteError extends SiiError {
67
116
  }
117
+ /** SII rejected a Carpeta Tributaria (`cte-api`) request, the body was not the observed shape
118
+ * ("scraper roto" — e.g. `/instituciones` not serving an array), the operation is invalid for
119
+ * its session-keyed contract (a representing pointer, ADR-005), OR the user's `--institucion` is
120
+ * not in SII's LIVE list (the message names the valid codes; no round-trip is spent). SII's
121
+ * message verbatim where one exists — never translated (ADR-004). Never retried; a missing www2
122
+ * app session is `Www2SessionError` and a `LOGIN_HOST` bounce `SessionExpiredError`, not this. */
123
+ export declare class CarpetaError extends SiiError {
124
+ }
68
125
  //# 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;;;uFAGuF;AACvF,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAAC;AAE3D;;;;6CAI6C;AAC7C,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;gBACnB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAK5F;AAED,mFAAmF;AACnF,qBAAa,cAAe,SAAQ,QAAQ;CAAG;AAE/C;;;oDAGoD;AACpD,qBAAa,oBAAqB,SAAQ,QAAQ;CAAG;AAErD;;6EAE6E;AAC7E,qBAAa,gBAAiB,SAAQ,gBAAgB;CAAG;AAEzD;;;;8EAI8E;AAC9E,qBAAa,iBAAkB,SAAQ,gBAAgB;CAAG;AAE1D,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,19 +15,64 @@ 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
- /** Browser login was not completed (timeout / window closed). No partial
19
- * session is ever written. */
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
+ }
24
+ /** Browser login was not completed (timeout / window closed) OR SII rejected the Clave.
25
+ * No partial session is ever written. Carries the classified `reason` + SII's message
26
+ * `codigo` (when the page printed one) alongside the verbatim message, so a consumer
27
+ * reads them as data (#124). Both are additive: `new LoginFailedError(msg)` still works
28
+ * (`reason: 'unknown'`, `codigo: null`). */
20
29
  export class LoginFailedError extends SiiError {
30
+ reason;
31
+ codigo;
32
+ constructor(message, opts) {
33
+ super(message);
34
+ this.reason = opts?.reason ?? 'unknown';
35
+ this.codigo = opts?.codigo ?? null;
36
+ }
21
37
  }
22
38
  /** SII server-side rate limit / block. NEVER retry — surface verbatim and stop. */
23
39
  export class RateLimitError extends SiiError {
24
40
  }
41
+ /** A surface needs a JS engine (SII's own page JS must run — BTE inline maps, MIPYME's
42
+ * in-page `validaFacEx`) but the runtime carries no `browser` engine: the default HTTP
43
+ * `PortalDriver` cannot `evaluate`/`interactiveLogin` (ADR-027). Actionable — names the
44
+ * Playwright install — never a silent fallback. */
45
+ export class BrowserRequiredError extends SiiError {
46
+ }
47
+ /** The login POST was redirected into SII's Queue-it waiting room (`salaespera.sii.cl`),
48
+ * the peak-load queue an HTTP client cannot pass (observed in the browser jar, ADR-027).
49
+ * NOT a credential failure and NOT retryable here — surface it and stop. */
50
+ export class LoginQueuedError extends LoginFailedError {
51
+ }
52
+ /** A NON-interactive login (`--clave-env` / `--clave-stdin` / `--keyring`) refused WITHOUT
53
+ * contacting SII because the rejection latch is set for that RUT: SII rejected a Clave for
54
+ * it earlier, and an unattended retry of the same stale value is how an account gets locked
55
+ * (ADR-028). Carries the latched `codigo`/`reason`. Lifted by an interactive login or
56
+ * `sii auth unblock`. A LoginFailed subclass, so it keeps that exit code. */
57
+ export class LoginBlockedError extends LoginFailedError {
58
+ }
25
59
  /** A stored credential was required (e.g. unattended re-mint) but none resolved. */
26
60
  export class CredentialNotFoundError extends SiiError {
27
61
  }
28
62
  /** Invalid user input: bad RUT, an operate target not in the operable set, etc. */
29
63
  export class ValidationError extends SiiError {
30
64
  }
65
+ /** An authenticated `requestJson` got a body that is NOT JSON and NOT the login wall —
66
+ * the response reached its destination host (no `LOGIN_HOST` bounce, not HTML) but the
67
+ * body does not parse. Observed 2026-09-11 (GH-111) on the cte-api
68
+ * `obtenerValorParametro` (URL cited in `adapters/node/response.ts`): HTTP 200
69
+ * `text/plain;charset=utf-8` with a bare URL — a live session, a wrong endpoint. Carries
70
+ * the endpoint, HTTP status, content-type and the first ~80 chars of the body VERBATIM
71
+ * (ADR-004), so a facade can tell a SII quirk from a dead session (`SessionExpiredError`)
72
+ * without a second round-trip. NOT a subclass of NotAuthenticated on purpose: re-login
73
+ * would not fix it. */
74
+ export class UnexpectedResponseError extends SiiError {
75
+ }
31
76
  /** SII rejected a portal/SDI facade request (error envelope or unparseable
32
77
  * response). Carries SII's message verbatim — never translated (ADR-004). */
33
78
  export class RepresentacionError extends SiiError {
@@ -71,4 +116,12 @@ export class PeticionesError extends SiiError {
71
116
  * `SessionExpiredError`, not this. */
72
117
  export class DteError extends SiiError {
73
118
  }
119
+ /** SII rejected a Carpeta Tributaria (`cte-api`) request, the body was not the observed shape
120
+ * ("scraper roto" — e.g. `/instituciones` not serving an array), the operation is invalid for
121
+ * its session-keyed contract (a representing pointer, ADR-005), OR the user's `--institucion` is
122
+ * not in SII's LIVE list (the message names the valid codes; no round-trip is spent). SII's
123
+ * message verbatim where one exists — never translated (ADR-004). Never retried; a missing www2
124
+ * app session is `Www2SessionError` and a `LOGIN_HOST` bounce `SessionExpiredError`, not this. */
125
+ export class CarpetaError extends SiiError {
126
+ }
74
127
  //# 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;AAQ9D;;;;6CAI6C;AAC7C,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IACnC,MAAM,CAAqB;IAC3B,MAAM,CAAgB;IAC/B,YAAY,OAAe,EAAE,IAA8D;QACzF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,SAAS,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC;IACrC,CAAC;CACF;AAED,mFAAmF;AACnF,MAAM,OAAO,cAAe,SAAQ,QAAQ;CAAG;AAE/C;;;oDAGoD;AACpD,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;CAAG;AAErD;;6EAE6E;AAC7E,MAAM,OAAO,gBAAiB,SAAQ,gBAAgB;CAAG;AAEzD;;;;8EAI8E;AAC9E,MAAM,OAAO,iBAAkB,SAAQ,gBAAgB;CAAG;AAE1D,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, LoginBlockEntry, 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;AAYnF,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"}
package/dist/node.d.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import type { Runtime } from './seams/index.js';
2
2
  export { DOCUMENTOS_DIR, FileAuditSink, FileKeyValueStore, NodeFileSink, SII_DIR, SystemClock, } from './adapters/node/index.js';
3
3
  export { KeyringSecretStore } from './adapters/node/keyring.js';
4
+ export { HttpPortalDriver } from './adapters/node/http.js';
4
5
  export { PlaywrightPortalDriver } from './adapters/node/portal.js';
5
6
  /** Composition root: the Node default adapters, any seam replaceable (ADR-016).
6
- * e.g. `createNodeRuntime({ audit: myAuditSink })` keeps the other three defaults.
7
- * The default portal is the Playwright driver — its `playwright` OPTIONAL peer is
8
- * loaded lazily on first use, so composing (or overriding `portal`) never needs it.
7
+ * e.g. `createNodeRuntime({ audit: myAuditSink })` keeps the other defaults.
8
+ * The default `portal` is the browser-free HTTP driver (ADR-027); `browser` is the
9
+ * Playwright engine, used only where SII's own page JS must run (BTE list, MIPYME) and
10
+ * by the MCP's headed / www2 logins. Constructing the Playwright driver is free — its
11
+ * `playwright` OPTIONAL peer loads lazily on the first browser call — so a runtime that
12
+ * never touches JS never loads Chromium.
9
13
  * `secrets` is DELIBERATELY not defaulted here: the OS keyring is wired by the CLI's
10
14
  * composition root alone (`createNodeRuntime({ secrets: new KeyringSecretStore() })`),
11
15
  * so the MCP server — which builds from this same function — carries no keyring at all
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;2BAO2B;AAC3B,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAS3E"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;;;2BAU2B;AAC3B,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,OAAO,CAAC,OAAO,CAAM,GAAG,OAAO,CAU3E"}
package/dist/node.js CHANGED
@@ -3,14 +3,19 @@
3
3
  // library's tasks/primitives never evaluates node:* or playwright — a consumer
4
4
  // that injects its own seams (ADR-003) stays free of them entirely.
5
5
  import { FileAuditSink, FileKeyValueStore, NodeFileSink, SystemClock, } from './adapters/node/index.js';
6
+ import { HttpPortalDriver } from './adapters/node/http.js';
6
7
  import { PlaywrightPortalDriver } from './adapters/node/portal.js';
7
8
  export { DOCUMENTOS_DIR, FileAuditSink, FileKeyValueStore, NodeFileSink, SII_DIR, SystemClock, } from './adapters/node/index.js';
8
9
  export { KeyringSecretStore } from './adapters/node/keyring.js';
10
+ export { HttpPortalDriver } from './adapters/node/http.js';
9
11
  export { PlaywrightPortalDriver } from './adapters/node/portal.js';
10
12
  /** Composition root: the Node default adapters, any seam replaceable (ADR-016).
11
- * e.g. `createNodeRuntime({ audit: myAuditSink })` keeps the other three defaults.
12
- * The default portal is the Playwright driver — its `playwright` OPTIONAL peer is
13
- * loaded lazily on first use, so composing (or overriding `portal`) never needs it.
13
+ * e.g. `createNodeRuntime({ audit: myAuditSink })` keeps the other defaults.
14
+ * The default `portal` is the browser-free HTTP driver (ADR-027); `browser` is the
15
+ * Playwright engine, used only where SII's own page JS must run (BTE list, MIPYME) and
16
+ * by the MCP's headed / www2 logins. Constructing the Playwright driver is free — its
17
+ * `playwright` OPTIONAL peer loads lazily on the first browser call — so a runtime that
18
+ * never touches JS never loads Chromium.
14
19
  * `secrets` is DELIBERATELY not defaulted here: the OS keyring is wired by the CLI's
15
20
  * composition root alone (`createNodeRuntime({ secrets: new KeyringSecretStore() })`),
16
21
  * so the MCP server — which builds from this same function — carries no keyring at all
@@ -20,7 +25,8 @@ export function createNodeRuntime(overrides = {}) {
20
25
  clock: new SystemClock(),
21
26
  audit: new FileAuditSink(),
22
27
  store: new FileKeyValueStore(),
23
- portal: new PlaywrightPortalDriver(),
28
+ portal: new HttpPortalDriver(),
29
+ browser: new PlaywrightPortalDriver(),
24
30
  files: new NodeFileSink(),
25
31
  ...overrides,
26
32
  };
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,gFAAgF;AAChF,+EAA+E;AAC/E,oEAAoE;AACpE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;2BAO2B;AAC3B,MAAM,UAAU,iBAAiB,CAAC,YAA8B,EAAE;IAChE,OAAO;QACL,KAAK,EAAE,IAAI,WAAW,EAAE;QACxB,KAAK,EAAE,IAAI,aAAa,EAAE;QAC1B,KAAK,EAAE,IAAI,iBAAiB,EAAE;QAC9B,MAAM,EAAE,IAAI,sBAAsB,EAAE;QACpC,KAAK,EAAE,IAAI,YAAY,EAAE;QACzB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,gFAAgF;AAChF,+EAA+E;AAC/E,oEAAoE;AACpE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;;;;;;;;;2BAU2B;AAC3B,MAAM,UAAU,iBAAiB,CAAC,YAA8B,EAAE;IAChE,OAAO;QACL,KAAK,EAAE,IAAI,WAAW,EAAE;QACxB,KAAK,EAAE,IAAI,aAAa,EAAE;QAC1B,KAAK,EAAE,IAAI,iBAAiB,EAAE;QAC9B,MAAM,EAAE,IAAI,gBAAgB,EAAE;QAC9B,OAAO,EAAE,IAAI,sBAAsB,EAAE;QACrC,KAAK,EAAE,IAAI,YAAY,EAAE;QACzB,GAAG,SAAS;KACb,CAAC;AACJ,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":"AAAA,+FAA+F;AAC/F,yFAAyF;AACzF,qGAAqG;AACrG,EAAE;AACF,4FAA4F;AAC5F,iGAAiG;AACjG,+FAA+F;AAC/F,2DAA2D;AAC3D,EAAE;AACF,8FAA8F;AAC9F,kFAAkF;AAClF,0FAA0F;AAC1F,uEAAuE;AACvE,0EAA0E;AAC1E,mGAAmG;AACnG,iGAAiG;AACjG,8FAA8F;AAC9F,oEAAoE;AACpE,EAAE;AACF,+FAA+F;AAC/F,8FAA8F;AAC9F,sFAAsF;AACtF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpD;kGACkG;AAClG,MAAM,YAAY,GAAG,gBAAgB,CAAC;AACtC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,SAAS,gCAAgC,CAAC;AAE/D,oFAAoF;AACpF,MAAM,OAAO,GAA2B;IACtC,MAAM,EAAE,mCAAmC;IAC3C,OAAO,EAAE,YAAY;CACtB,CAAC;AAmBF,yFAAyF;AACzF,0FAA0F;AAC1F,+FAA+F;AAC/F,0DAA0D;AAC1D,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9C,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEnC,sFAAsF;AACtF,4FAA4F;AAC5F,sFAAsF;AACtF,MAAM,OAAO,GAAG;IACd,MAAM,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;IACjC,WAAW,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC;IAChD,WAAW,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC;IAChD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,CAAC,qBAAqB,EAAE,gBAAgB,CAAC;IACpD,EAAE,EAAE,CAAC,oBAAoB,EAAE,eAAe,CAAC;IAC3C,YAAY,EAAE,CAAC,oBAAoB,EAAE,eAAe,CAAC;IACrD,YAAY,EAAE,CAAC,oBAAoB,EAAE,eAAe,CAAC;CAC7C,CAAC;AAEX,SAAS,QAAQ,CAAC,GAA4B,EAAE,IAAuB;IACrE,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IACjF,OAAO,SAAS,CAAC;AACnB,CAAC;AACD,MAAM,KAAK,GAAG,CAAC,CAAU,EAAiB,EAAE;IAC1C,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AACF,MAAM,KAAK,GAAG,CAAC,CAAU,EAAiB,EAAE;IAC1C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AACF,kGAAkG;AAClG,MAAM,gBAAgB,GAAG,CAAC,MAAe,EAAE,EAAW,EAAiB,EAAE,CACvE,MAAM,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS;IACtC,CAAC,CAAC,IAAI;IACN,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC;AAElF,SAAS,MAAM,CAAC,GAA4B;IAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,uFAAuF;QACvF,MAAM,IAAI,YAAY,CACpB,uFAAuF;YACrF,qCAAqC,CACxC,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM;QACN,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACtD,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,GAAG,EAAE,gBAAgB,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAClF,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QACxD,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;KACzD,CAAC;AACJ,CAAC;AAED;;+DAE+D;AAC/D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAsB,EACtB,GAAgB;IAEhB,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAC7B,GAAG,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,8CAA8C,EACtF,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CACpC,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,2FAA2F;QAC3F,8FAA8F;QAC9F,+EAA+E;QAC/E,IAAI,CAAC,YAAY,qBAAqB;YAAE,MAAM,CAAC,CAAC;QAChD,MAAM,IAAI,YAAY,CACpB,wEACE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAC3C,EAAE,CACH,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,YAAY,CACpB,mFAAmF;YACjF,oDAAoD,CACvD,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;2FAC2F;AAC3F,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAsB;IAEtB,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACzD,OAAO,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED;;2FAE2F;AAC3F,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,aAA4C;IAE5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAC3D,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,MAAM,QAAQ,GAAG,aAAa;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SACtE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,YAAY,CACpB,mBAAmB,MAAM,oEAAoE;QAC3F,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;YACzB,CAAC,CAAC,mCAAmC;YACrC,CAAC,CAAC,gDAAgD,QAAQ,GAAG,CAAC,CACnE,CAAC;AACJ,CAAC"}
@@ -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"}
@@ -184,5 +184,12 @@ export interface Runtime {
184
184
  * never by the MCP server's, so that surface has no keyring BY CONSTRUCTION and not
185
185
  * by "no code happens to call it" (ADR-006 / ADR-025). */
186
186
  readonly secrets?: SecretReader;
187
+ /** OPTIONAL JS engine (the lazy Playwright driver). The default `portal` is the browser-free
188
+ * HTTP driver (ADR-027); a surface that must run SII's OWN page JS (BTE inline maps, MIPYME
189
+ * `validaFacEx`) acquires this via `withSession(…, { engine: 'browser' })`, and the headed /
190
+ * www2 logins (MCP-only) use it directly. Absent ⇒ those paths raise `BrowserRequiredError`.
191
+ * `createNodeRuntime` wires the Playwright driver here; constructing it is free (it lazy-loads
192
+ * Chromium only on first browser call), so a runtime that never needs JS never loads it. */
193
+ readonly browser?: PortalDriver;
187
194
  }
188
195
  //# sourceMappingURL=index.d.ts.map