@albertomarturelo/sii-core 0.3.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 (200) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/LICENSE +21 -0
  3. package/README.md +108 -0
  4. package/dist/adapters/fake/index.d.ts +98 -0
  5. package/dist/adapters/fake/index.d.ts.map +1 -0
  6. package/dist/adapters/fake/index.js +131 -0
  7. package/dist/adapters/fake/index.js.map +1 -0
  8. package/dist/adapters/node/index.d.ts +22 -0
  9. package/dist/adapters/node/index.d.ts.map +1 -0
  10. package/dist/adapters/node/index.js +65 -0
  11. package/dist/adapters/node/index.js.map +1 -0
  12. package/dist/adapters/node/portal.d.ts +8 -0
  13. package/dist/adapters/node/portal.d.ts.map +1 -0
  14. package/dist/adapters/node/portal.js +222 -0
  15. package/dist/adapters/node/portal.js.map +1 -0
  16. package/dist/adapters/node/response.d.ts +21 -0
  17. package/dist/adapters/node/response.d.ts.map +1 -0
  18. package/dist/adapters/node/response.js +48 -0
  19. package/dist/adapters/node/response.js.map +1 -0
  20. package/dist/audit/audit.d.ts +8 -0
  21. package/dist/audit/audit.d.ts.map +1 -0
  22. package/dist/audit/audit.js +15 -0
  23. package/dist/audit/audit.js.map +1 -0
  24. package/dist/audit/index.d.ts +2 -0
  25. package/dist/audit/index.d.ts.map +1 -0
  26. package/dist/audit/index.js +2 -0
  27. package/dist/audit/index.js.map +1 -0
  28. package/dist/auth/auth.d.ts +43 -0
  29. package/dist/auth/auth.d.ts.map +1 -0
  30. package/dist/auth/auth.js +219 -0
  31. package/dist/auth/auth.js.map +1 -0
  32. package/dist/auth/index.d.ts +3 -0
  33. package/dist/auth/index.d.ts.map +1 -0
  34. package/dist/auth/index.js +3 -0
  35. package/dist/auth/index.js.map +1 -0
  36. package/dist/auth/login-error.d.ts +8 -0
  37. package/dist/auth/login-error.d.ts.map +1 -0
  38. package/dist/auth/login-error.js +18 -0
  39. package/dist/auth/login-error.js.map +1 -0
  40. package/dist/auth/session.d.ts +31 -0
  41. package/dist/auth/session.d.ts.map +1 -0
  42. package/dist/auth/session.js +52 -0
  43. package/dist/auth/session.js.map +1 -0
  44. package/dist/cli.d.ts +3 -0
  45. package/dist/cli.d.ts.map +1 -0
  46. package/dist/cli.js +6 -0
  47. package/dist/cli.js.map +1 -0
  48. package/dist/config/config.d.ts +38 -0
  49. package/dist/config/config.d.ts.map +1 -0
  50. package/dist/config/config.js +40 -0
  51. package/dist/config/config.js.map +1 -0
  52. package/dist/config/index.d.ts +2 -0
  53. package/dist/config/index.d.ts.map +1 -0
  54. package/dist/config/index.js +2 -0
  55. package/dist/config/index.js.map +1 -0
  56. package/dist/errors/errors.d.ts +56 -0
  57. package/dist/errors/errors.d.ts.map +1 -0
  58. package/dist/errors/errors.js +62 -0
  59. package/dist/errors/errors.js.map +1 -0
  60. package/dist/errors/index.d.ts +2 -0
  61. package/dist/errors/index.d.ts.map +1 -0
  62. package/dist/errors/index.js +2 -0
  63. package/dist/errors/index.js.map +1 -0
  64. package/dist/format/format.d.ts +5 -0
  65. package/dist/format/format.d.ts.map +1 -0
  66. package/dist/format/format.js +14 -0
  67. package/dist/format/format.js.map +1 -0
  68. package/dist/format/index.d.ts +2 -0
  69. package/dist/format/index.d.ts.map +1 -0
  70. package/dist/format/index.js +2 -0
  71. package/dist/format/index.js.map +1 -0
  72. package/dist/identity/identity.d.ts +56 -0
  73. package/dist/identity/identity.d.ts.map +1 -0
  74. package/dist/identity/identity.js +93 -0
  75. package/dist/identity/identity.js.map +1 -0
  76. package/dist/identity/index.d.ts +2 -0
  77. package/dist/identity/index.d.ts.map +1 -0
  78. package/dist/identity/index.js +2 -0
  79. package/dist/identity/index.js.map +1 -0
  80. package/dist/index.d.ts +24 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +24 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/node.d.ts +9 -0
  85. package/dist/node.d.ts.map +1 -0
  86. package/dist/node.js +22 -0
  87. package/dist/node.js.map +1 -0
  88. package/dist/periodo/anio.d.ts +15 -0
  89. package/dist/periodo/anio.d.ts.map +1 -0
  90. package/dist/periodo/anio.js +42 -0
  91. package/dist/periodo/anio.js.map +1 -0
  92. package/dist/periodo/index.d.ts +3 -0
  93. package/dist/periodo/index.d.ts.map +1 -0
  94. package/dist/periodo/index.js +3 -0
  95. package/dist/periodo/index.js.map +1 -0
  96. package/dist/periodo/periodo.d.ts +19 -0
  97. package/dist/periodo/periodo.d.ts.map +1 -0
  98. package/dist/periodo/periodo.js +55 -0
  99. package/dist/periodo/periodo.js.map +1 -0
  100. package/dist/portal/bte-comunas.d.ts +9 -0
  101. package/dist/portal/bte-comunas.d.ts.map +1 -0
  102. package/dist/portal/bte-comunas.js +400 -0
  103. package/dist/portal/bte-comunas.js.map +1 -0
  104. package/dist/portal/bte-emit.d.ts +70 -0
  105. package/dist/portal/bte-emit.d.ts.map +1 -0
  106. package/dist/portal/bte-emit.js +266 -0
  107. package/dist/portal/bte-emit.js.map +1 -0
  108. package/dist/portal/bte.d.ts +55 -0
  109. package/dist/portal/bte.d.ts.map +1 -0
  110. package/dist/portal/bte.js +215 -0
  111. package/dist/portal/bte.js.map +1 -0
  112. package/dist/portal/dte-public.d.ts +36 -0
  113. package/dist/portal/dte-public.d.ts.map +1 -0
  114. package/dist/portal/dte-public.js +192 -0
  115. package/dist/portal/dte-public.js.map +1 -0
  116. package/dist/portal/f22/declaraciones.d.ts +37 -0
  117. package/dist/portal/f22/declaraciones.d.ts.map +1 -0
  118. package/dist/portal/f22/declaraciones.js +86 -0
  119. package/dist/portal/f22/declaraciones.js.map +1 -0
  120. package/dist/portal/f22/grid.d.ts +14 -0
  121. package/dist/portal/f22/grid.d.ts.map +1 -0
  122. package/dist/portal/f22/grid.js +51 -0
  123. package/dist/portal/f22/grid.js.map +1 -0
  124. package/dist/portal/f22/historial.d.ts +34 -0
  125. package/dist/portal/f22/historial.d.ts.map +1 -0
  126. package/dist/portal/f22/historial.js +66 -0
  127. package/dist/portal/f22/historial.js.map +1 -0
  128. package/dist/portal/f22/index.d.ts +7 -0
  129. package/dist/portal/f22/index.d.ts.map +1 -0
  130. package/dist/portal/f22/index.js +11 -0
  131. package/dist/portal/f22/index.js.map +1 -0
  132. package/dist/portal/f22/observaciones.d.ts +20 -0
  133. package/dist/portal/f22/observaciones.d.ts.map +1 -0
  134. package/dist/portal/f22/observaciones.js +38 -0
  135. package/dist/portal/f22/observaciones.js.map +1 -0
  136. package/dist/portal/f22/shared.d.ts +32 -0
  137. package/dist/portal/f22/shared.d.ts.map +1 -0
  138. package/dist/portal/f22/shared.js +130 -0
  139. package/dist/portal/f22/shared.js.map +1 -0
  140. package/dist/portal/f22-codigos.d.ts +28 -0
  141. package/dist/portal/f22-codigos.d.ts.map +1 -0
  142. package/dist/portal/f22-codigos.js +141 -0
  143. package/dist/portal/f22-codigos.js.map +1 -0
  144. package/dist/portal/f29-codigos.d.ts +15 -0
  145. package/dist/portal/f29-codigos.d.ts.map +1 -0
  146. package/dist/portal/f29-codigos.js +552 -0
  147. package/dist/portal/f29-codigos.js.map +1 -0
  148. package/dist/portal/f29.d.ts +62 -0
  149. package/dist/portal/f29.d.ts.map +1 -0
  150. package/dist/portal/f29.js +244 -0
  151. package/dist/portal/f29.js.map +1 -0
  152. package/dist/portal/rcv.d.ts +62 -0
  153. package/dist/portal/rcv.d.ts.map +1 -0
  154. package/dist/portal/rcv.js +252 -0
  155. package/dist/portal/rcv.js.map +1 -0
  156. package/dist/portal/representacion.d.ts +24 -0
  157. package/dist/portal/representacion.d.ts.map +1 -0
  158. package/dist/portal/representacion.js +153 -0
  159. package/dist/portal/representacion.js.map +1 -0
  160. package/dist/rut/index.d.ts +2 -0
  161. package/dist/rut/index.d.ts.map +1 -0
  162. package/dist/rut/index.js +2 -0
  163. package/dist/rut/index.js.map +1 -0
  164. package/dist/rut/rut.d.ts +16 -0
  165. package/dist/rut/rut.d.ts.map +1 -0
  166. package/dist/rut/rut.js +70 -0
  167. package/dist/rut/rut.js.map +1 -0
  168. package/dist/seams/index.d.ts +126 -0
  169. package/dist/seams/index.d.ts.map +1 -0
  170. package/dist/seams/index.js +6 -0
  171. package/dist/seams/index.js.map +1 -0
  172. package/dist/tasks/auth.d.ts +16 -0
  173. package/dist/tasks/auth.d.ts.map +1 -0
  174. package/dist/tasks/auth.js +22 -0
  175. package/dist/tasks/auth.js.map +1 -0
  176. package/dist/tasks/bte.d.ts +52 -0
  177. package/dist/tasks/bte.d.ts.map +1 -0
  178. package/dist/tasks/bte.js +169 -0
  179. package/dist/tasks/bte.js.map +1 -0
  180. package/dist/tasks/dte.d.ts +9 -0
  181. package/dist/tasks/dte.d.ts.map +1 -0
  182. package/dist/tasks/dte.js +30 -0
  183. package/dist/tasks/dte.js.map +1 -0
  184. package/dist/tasks/f22.d.ts +69 -0
  185. package/dist/tasks/f22.d.ts.map +1 -0
  186. package/dist/tasks/f22.js +189 -0
  187. package/dist/tasks/f22.js.map +1 -0
  188. package/dist/tasks/f29.d.ts +67 -0
  189. package/dist/tasks/f29.d.ts.map +1 -0
  190. package/dist/tasks/f29.js +213 -0
  191. package/dist/tasks/f29.js.map +1 -0
  192. package/dist/tasks/operate.d.ts +22 -0
  193. package/dist/tasks/operate.d.ts.map +1 -0
  194. package/dist/tasks/operate.js +34 -0
  195. package/dist/tasks/operate.js.map +1 -0
  196. package/dist/tasks/rcv.d.ts +17 -0
  197. package/dist/tasks/rcv.d.ts.map +1 -0
  198. package/dist/tasks/rcv.js +76 -0
  199. package/dist/tasks/rcv.js.map +1 -0
  200. package/package.json +54 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,114 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@albertomarturelo/sii-core` are documented here. The format is
4
+ loosely based on [Keep a Changelog](https://keepachangelog.com/); the package is
5
+ pre-1.0, so MINOR bumps may carry breaking changes (pin or use `~` downstream).
6
+
7
+ ## 0.3.0 — 2026-07-02
8
+
9
+ First release on the **public npm registry** under `@albertomarturelo/sii-core`
10
+ (ADR-018 / ADR-019). Prior `0.1.0` / `0.2.0` were private on GitHub Packages.
11
+
12
+ > **Note on `bteEmit`:** the emission *preview* (`bteEmitPreview`) is live-validated;
13
+ > the final issue POST in `bteEmit` is coded to a real capture but **not yet
14
+ > live-validated end-to-end** and is guarded behind explicit confirmation — treat it
15
+ > as experimental until #62 lands.
16
+
17
+ ### Changed
18
+
19
+ - **Renamed `@altumstack/sii-core` → `@albertomarturelo/sii-core`, now MIT-licensed
20
+ and published to the public npm registry** (ADR-018, ADR-019). Consumers install
21
+ with a plain `npm install @albertomarturelo/sii-core` — no GitHub Packages token or
22
+ `.npmrc` scope mapping. The earlier `0.1.0` / `0.2.0` releases were private on GitHub
23
+ Packages under the old scope (ADR-015; superseded).
24
+
25
+ ### Added
26
+
27
+ - **BHE emission — the first WRITE surface (`bteEmit` / `bteEmitPreview`, ADR-017).**
28
+ Issue a Boleta de Honorarios Electrónica: `bteEmitPreview` runs SII's flow to the
29
+ confirmation step and returns the server-computed retención/líquido WITHOUT issuing;
30
+ `bteEmit` issues and returns the código de barras (folio) + PDF URL, with an optional
31
+ email send. Session-keyed (rejects a representing pointer); local validation (Mod-11
32
+ receptor, positive monto, ±3-month date, region/comuna) before any session; the audit
33
+ receipt carries the folio but never the receptor / monto / glosa. Retención is
34
+ server-side (the emitter reads the vigente rate from the form, never a hardcoded table).
35
+ - **`PortalSession.requestForm`** — an authenticated `x-www-form-urlencoded` POST
36
+ from the logged-in session (cookies ride along), returning the decoded text body.
37
+ The primitive behind the legacy HTML write flows (BHE emission, ADR-017); the
38
+ authenticated peer of `PublicRequest.form`. Login-wall detection is URL-based
39
+ (landing on `LOGIN_HOST` → `SessionExpiredError`), since an HTML body is expected.
40
+ - **`portal/bte-comunas`** — the SII region/comuna code table (16 regiones / 346
41
+ comunas), ported verbatim from `GLB_comunas.js`, for local region-comuna validation.
42
+
43
+ ## 0.2.0 — 2026-07-02
44
+
45
+ ### Breaking
46
+
47
+ - **`createNodeRuntime` moved to the `@altumstack/sii-core/node` subpath**
48
+ (ADR-016). The main barrel is now statically pure — importing it evaluates
49
+ no `node:*` module and no playwright, so tasks/primitives work in any
50
+ bundled/sandboxed context. Update:
51
+ `import { createNodeRuntime } from '@altumstack/sii-core/node'`.
52
+ - **`playwright` is now an OPTIONAL peer dependency** (was a hard dependency).
53
+ Only the default `PortalDriver` needs it, and it is loaded lazily on first
54
+ use. If you drive the default driver, install it yourself
55
+ (`npm i playwright` + `npx playwright install chromium`); if you inject your
56
+ own `PortalDriver`, you no longer need bundler stubs or
57
+ `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD`.
58
+
59
+ ### Fixed
60
+
61
+ - `f29Overview` with no arguments no longer fails with a cryptic
62
+ `ValidationError` (the MCP `f29_overview` tool used to send empty strings):
63
+ it now defaults to the current calendar year to date, resolved through the
64
+ injected `Clock`.
65
+
66
+ ### Changed
67
+
68
+ - **`f29Overview` owns the range policy** (`{ desde?, hasta?, anio? }`): `anio`
69
+ — or a bare-`YYYY` `desde` — means the whole calendar year (an explicit
70
+ `hasta` may narrow it); `desde` (YYYY-MM) alone means that single month;
71
+ nothing means the current year to date. The CLI and MCP pass their raw
72
+ arguments through, so both surfaces share one semantics. Existing
73
+ `{ desde, hasta }` calls behave as before.
74
+
75
+ ### Internal
76
+
77
+ - `portal/f22` split into per-view modules (`declaraciones` / `grid` /
78
+ `observaciones` / `historial` over a `shared` wire layer); the module barrel
79
+ re-exports the same names, so the public surface is unchanged.
80
+
81
+ ### Added
82
+
83
+ - `createNodeRuntime(overrides?: Partial<Runtime>)` — any seam replaceable
84
+ while keeping the other Node defaults.
85
+ - The Node default adapters are exported from `./node`: `SystemClock`,
86
+ `FileKeyValueStore`, `FileAuditSink`, `PlaywrightPortalDriver`, `SII_DIR`.
87
+ - `sideEffects: false` — the package is tree-shakeable.
88
+ - **`format` helpers** — `formatMoney` (es-CL thousands, `—` for null) and
89
+ `formatRut` (canonical → dotted display form), plus `describeOperating`
90
+ (the shared `Operando como …` line, next to `formatOperableEntry`). The CLI
91
+ and MCP consumed verbatim private copies of all three; now every consumer
92
+ shares one rendering.
93
+
94
+ ## 0.1.0 — 2026-06-30
95
+
96
+ Initial published release (private, GitHub Packages). Renamed from the in-repo
97
+ workspace package `@sii/core` (ADR-015).
98
+
99
+ ### Added
100
+
101
+ - **auth** — browser cookies-only login, console login (`@altumstack/sii-core/cli`
102
+ subpath), logout, local + refresh status; `withSession` session-acquisition
103
+ primitive.
104
+ - **identity / operate** — single-account, operate-centric model (ADR-005):
105
+ operating RUT resolution (`--rut` > pointer > self), operable set.
106
+ - **read surfaces** — `rcv` (summary/list, body-RUT), `f22`
107
+ (status/formulario/observaciones/historial, session-keyed), `f29`
108
+ (formulario/overview/status, Fase 1 SDI-JSON, session-keyed), `bte`
109
+ (list, session-keyed), `dte` (authorized, public/login-free).
110
+ - **seams** — `PortalDriver` (+ `requestPublic`), `SecretStore`,
111
+ `KeyValueStore`, `AuditSink`, `Clock`, with Node default adapters
112
+ (`createNodeRuntime`) and in-memory fakes for tests.
113
+ - **primitives** — `rut` (Mod-11), `periodo` (YYYYMM) + `anio` (YYYY),
114
+ `config` (prod hostnames + rate limits), append-only `audit`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alberto Marturelo Lorenzo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # @albertomarturelo/sii-core
2
+
3
+ The shared SII (Servicio de Impuestos Internos, Chile) domain core — the engine
4
+ behind the `sii` CLI and the `sii-mcp` server. A Node library: every legal and
5
+ operational guardrail (throttling, audit, credential handling, the operate-centric
6
+ identity model) lives here, so a consumer that codes against the task layer gets
7
+ the same rails the first-party surfaces do.
8
+
9
+ > **Open source (MIT).** See [ADR-018](../../docs/decisions/018-public-release-mit-license.md)
10
+ > and [ADR-019](../../docs/decisions/019-publish-public-npm-personal-scope.md). Published to
11
+ > the **public npm registry**. (Earlier `0.x` releases were private on GitHub Packages under
12
+ > the `@altumstack` scope — ADR-015; superseded.)
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pnpm add @albertomarturelo/sii-core
18
+ # or: npm install @albertomarturelo/sii-core
19
+ ```
20
+
21
+ `zod` comes along as a dependency. **`playwright` is an OPTIONAL peer** (ADR-016):
22
+ only the default `PortalDriver` (the `@albertomarturelo/sii-core/node` subpath) needs it.
23
+ If you use that default driver — i.e. you actually drive a real browser against
24
+ SII — install it plus the Chromium binary once:
25
+
26
+ ```bash
27
+ pnpm add playwright
28
+ pnpm exec playwright install chromium
29
+ ```
30
+
31
+ If you inject your own `PortalDriver` (or only use the tasks/primitives), skip
32
+ this entirely — nothing in the main barrel imports playwright or `node:*`.
33
+
34
+ ## Usage
35
+
36
+ A consumer builds a `Runtime` (the composition root that wires the Node default
37
+ adapters, from the `./node` subpath) and calls **tasks** — the public operations.
38
+ Never reach past the task layer into a sub-module; that bypasses the guardrails
39
+ (ADR-003).
40
+
41
+ ```ts
42
+ import { authStatus, rcvSummary } from '@albertomarturelo/sii-core';
43
+ import { createNodeRuntime } from '@albertomarturelo/sii-core/node';
44
+
45
+ const runtime = createNodeRuntime();
46
+
47
+ // Who is the current session operating as? (pure-local read)
48
+ const status = await authStatus(runtime);
49
+
50
+ // Read the RCV compra summary for a period (body-RUT surface — `rut` optional).
51
+ const resumen = await rcvSummary(runtime, { periodo: '2026-05', side: 'compra' });
52
+ console.log(JSON.stringify(resumen, null, 2));
53
+ ```
54
+
55
+ Tasks return plain JSON-serializable objects (no `Date`/`Map`/`Set`) — that is the
56
+ library contract (ADR-012). Authentication is an explicit verb: tasks consume a
57
+ live session or raise `NotAuthenticated`; only `login` mints one. Logging in opens
58
+ a real browser where the user types their Clave (cookies-only; the password never
59
+ crosses the library boundary — ADR-006).
60
+
61
+ ### Injecting your own seams
62
+
63
+ The external side-effects are interfaces (`PortalDriver`, `KeyValueStore`,
64
+ `AuditSink`, `Clock`, …). `createNodeRuntime` accepts a `Partial<Runtime>` of
65
+ overrides, so partial reuse is a supported path — e.g. Node defaults with your
66
+ own audit sink and portal driver (an embedding app's mediated browser):
67
+
68
+ ```ts
69
+ import { createNodeRuntime } from '@albertomarturelo/sii-core/node';
70
+
71
+ const runtime = createNodeRuntime({ audit: myAuditSink, portal: myPortalDriver });
72
+ ```
73
+
74
+ In-memory fakes ship under `testing` so a consumer's tests never touch the real
75
+ SII, keyring, or clock — assemble a `Runtime` from them:
76
+
77
+ ```ts
78
+ import { testing, type Runtime } from '@albertomarturelo/sii-core';
79
+
80
+ const runtime: Runtime = {
81
+ clock: new testing.FixedClock(new Date('2026-06-29T12:00:00Z')),
82
+ audit: new testing.RecordingAuditSink(),
83
+ store: new testing.InMemoryKeyValueStore(),
84
+ portal: new testing.FakePortalDriver({ requestPublic: () => '<html>…</html>' }),
85
+ };
86
+ ```
87
+
88
+ ## What's inside
89
+
90
+ - **auth / identity** — single-account, operate-centric session model (ADR-005).
91
+ - **read surfaces** — `rcv`, `f22`, `f29`, `bte`, `dte` (authorized, public).
92
+ - **primitives** — `Rut` (Mod-11), `Periodo` / `Anio`, prod `HOSTS`, audit.
93
+
94
+ See [`docs/ARCHITECTURE.md`](../../docs/ARCHITECTURE.md) and
95
+ [`docs/ROADMAP.md`](../../docs/ROADMAP.md) for the full picture, and
96
+ [`CHANGELOG.md`](./CHANGELOG.md) for release notes.
97
+
98
+ ## Releasing (maintainers)
99
+
100
+ Bump `version` in `package.json`, then push a matching `v*` tag — the
101
+ `publish-core` GitHub Action builds and publishes to GitHub Packages on tag
102
+ (ADR-015):
103
+
104
+ ```bash
105
+ # after bumping version to e.g. 0.2.0 and merging to main
106
+ git tag v0.2.0
107
+ git push origin v0.2.0
108
+ ```
@@ -0,0 +1,98 @@
1
+ import type { AuditEntry, AuditSink, Clock, CredentialLoginOptions, FormRequest, InteractiveLoginOptions, JsonRequest, KeyValueStore, PortalDriver, PortalSession, PublicRequest, PublicResponse } from '../../seams/index.js';
2
+ export declare class FixedClock implements Clock {
3
+ private current;
4
+ /** Each `sleep(ms)` is recorded (not awaited) so a test can assert pacing without
5
+ * actually waiting. */
6
+ readonly slept: number[];
7
+ constructor(current: Date);
8
+ now(): Date;
9
+ set(d: Date): void;
10
+ sleep(ms: number): Promise<void>;
11
+ }
12
+ export declare class RecordingAuditSink implements AuditSink {
13
+ readonly entries: AuditEntry[];
14
+ record(entry: AuditEntry): void;
15
+ }
16
+ export declare class InMemoryKeyValueStore implements KeyValueStore {
17
+ private readonly data;
18
+ read<T>(key: string): Promise<T | null>;
19
+ write<T>(key: string, value: T): Promise<void>;
20
+ delete(key: string): Promise<void>;
21
+ }
22
+ export interface FakeSessionScript {
23
+ /** URL the session "lands on" after goto (defaults to the requested URL). */
24
+ landingUrl?: string;
25
+ /** Result for `evaluate(expression)`. */
26
+ evaluate?: (expression: string) => unknown;
27
+ /** Result for `requestJson(url, options)` — the SDI facade JSON envelope. */
28
+ requestJson?: (url: string, options?: JsonRequest) => unknown;
29
+ /** Result for `requestForm(url, options)` — an authenticated form-POST (BHE emit,
30
+ * ADR-017). Return the decoded body string (status 200) or a full PublicResponse. */
31
+ requestForm?: (url: string, options?: FormRequest) => PublicResponse | string;
32
+ /** Cookie name → value map for `cookie(url, name)`. */
33
+ cookies?: Record<string, string>;
34
+ storageState?: unknown;
35
+ }
36
+ export declare class FakePortalSession implements PortalSession {
37
+ private readonly script;
38
+ closed: boolean;
39
+ /** The last requestJson call — lets a test assert the URL/body sent to SII. */
40
+ lastRequest: {
41
+ url: string;
42
+ options?: JsonRequest;
43
+ } | null;
44
+ /** Every URL passed to goto, in order — lets a goto/evaluate facade (BTE) assert
45
+ * navigation + pagination without a real browser. */
46
+ readonly gotos: string[];
47
+ constructor(script?: FakeSessionScript);
48
+ goto(url: string): Promise<string>;
49
+ evaluate<T>(expression: string): Promise<T>;
50
+ requestJson(url: string, options?: JsonRequest): Promise<unknown>;
51
+ /** The last requestForm call — lets a test assert the emit form fields sent to SII. */
52
+ lastFormRequest: {
53
+ url: string;
54
+ options?: FormRequest;
55
+ } | null;
56
+ requestForm(url: string, options?: FormRequest): Promise<PublicResponse>;
57
+ cookie(_url: string, name: string): Promise<string | null>;
58
+ storageState(): Promise<unknown>;
59
+ close(): Promise<void>;
60
+ }
61
+ export interface FakeDriverScript {
62
+ loginSession?: FakeSessionScript | (() => FakeSessionScript);
63
+ credentialSession?: FakeSessionScript | (() => FakeSessionScript);
64
+ restoreSession?: FakeSessionScript | (() => FakeSessionScript);
65
+ /** When set, interactiveLogin rejects with this (simulate timeout / window close). */
66
+ failLogin?: Error;
67
+ /** When set, credentialLogin rejects with this (simulate bad Clave / lock / timeout). */
68
+ failCredentialLogin?: Error;
69
+ /** Result for `requestPublic(url, options)` — a public (unauthenticated) consulta.
70
+ * Return the decoded body string (status defaults to 200) or a full PublicResponse. */
71
+ requestPublic?: (url: string, options?: PublicRequest) => PublicResponse | string;
72
+ /** When set, requestPublic rejects with this (simulate a network / CGI failure). */
73
+ failPublic?: Error;
74
+ }
75
+ export declare class FakePortalDriver implements PortalDriver {
76
+ private readonly script;
77
+ interactiveLoginCalls: number;
78
+ credentialLoginCalls: number;
79
+ restoreCalls: number;
80
+ /** The last RUT + Clave passed to credentialLogin — lets a test assert the Clave
81
+ * reached the driver but was NOT persisted anywhere (cookies-only, ADR-010). */
82
+ lastCredential: {
83
+ rut: string;
84
+ clave: string;
85
+ } | null;
86
+ constructor(script?: FakeDriverScript);
87
+ interactiveLogin(_options: InteractiveLoginOptions): Promise<PortalSession>;
88
+ credentialLogin(options: CredentialLoginOptions): Promise<PortalSession>;
89
+ restore(_storageState: unknown): Promise<PortalSession>;
90
+ requestPublicCalls: number;
91
+ /** The last public request — lets a test assert the URL/form sent (no session). */
92
+ lastPublicRequest: {
93
+ url: string;
94
+ options?: PublicRequest;
95
+ } | null;
96
+ requestPublic(url: string, options?: PublicRequest): Promise<PublicResponse>;
97
+ }
98
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/fake/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ export class FixedClock {
2
+ current;
3
+ /** Each `sleep(ms)` is recorded (not awaited) so a test can assert pacing without
4
+ * actually waiting. */
5
+ slept = [];
6
+ constructor(current) {
7
+ this.current = current;
8
+ }
9
+ now() {
10
+ return this.current;
11
+ }
12
+ set(d) {
13
+ this.current = d;
14
+ }
15
+ sleep(ms) {
16
+ this.slept.push(ms);
17
+ return Promise.resolve();
18
+ }
19
+ }
20
+ export class RecordingAuditSink {
21
+ entries = [];
22
+ record(entry) {
23
+ this.entries.push(entry);
24
+ }
25
+ }
26
+ export class InMemoryKeyValueStore {
27
+ data = new Map();
28
+ async read(key) {
29
+ const raw = this.data.get(key);
30
+ return raw === undefined ? null : JSON.parse(raw);
31
+ }
32
+ async write(key, value) {
33
+ this.data.set(key, JSON.stringify(value));
34
+ }
35
+ async delete(key) {
36
+ this.data.delete(key);
37
+ }
38
+ }
39
+ export class FakePortalSession {
40
+ script;
41
+ closed = false;
42
+ /** The last requestJson call — lets a test assert the URL/body sent to SII. */
43
+ lastRequest = null;
44
+ /** Every URL passed to goto, in order — lets a goto/evaluate facade (BTE) assert
45
+ * navigation + pagination without a real browser. */
46
+ gotos = [];
47
+ constructor(script = {}) {
48
+ this.script = script;
49
+ }
50
+ async goto(url) {
51
+ this.gotos.push(url);
52
+ return this.script.landingUrl ?? url;
53
+ }
54
+ async evaluate(expression) {
55
+ return (this.script.evaluate?.(expression) ?? null);
56
+ }
57
+ async requestJson(url, options) {
58
+ this.lastRequest = options ? { url, options } : { url };
59
+ return this.script.requestJson?.(url, options) ?? null;
60
+ }
61
+ /** The last requestForm call — lets a test assert the emit form fields sent to SII. */
62
+ lastFormRequest = null;
63
+ async requestForm(url, options) {
64
+ this.lastFormRequest = options ? { url, options } : { url };
65
+ const r = this.script.requestForm?.(url, options);
66
+ if (r === undefined)
67
+ return { status: 200, body: '' };
68
+ return typeof r === 'string' ? { status: 200, body: r } : r;
69
+ }
70
+ async cookie(_url, name) {
71
+ return this.script.cookies?.[name] ?? null;
72
+ }
73
+ async storageState() {
74
+ return this.script.storageState ?? { cookies: [] };
75
+ }
76
+ async close() {
77
+ this.closed = true;
78
+ }
79
+ }
80
+ export class FakePortalDriver {
81
+ script;
82
+ interactiveLoginCalls = 0;
83
+ credentialLoginCalls = 0;
84
+ restoreCalls = 0;
85
+ /** The last RUT + Clave passed to credentialLogin — lets a test assert the Clave
86
+ * reached the driver but was NOT persisted anywhere (cookies-only, ADR-010). */
87
+ lastCredential = null;
88
+ constructor(script = {}) {
89
+ this.script = script;
90
+ }
91
+ async interactiveLogin(_options) {
92
+ this.interactiveLoginCalls++;
93
+ if (this.script.failLogin)
94
+ throw this.script.failLogin;
95
+ const s = typeof this.script.loginSession === 'function'
96
+ ? this.script.loginSession()
97
+ : this.script.loginSession;
98
+ return new FakePortalSession(s ?? {});
99
+ }
100
+ async credentialLogin(options) {
101
+ this.credentialLoginCalls++;
102
+ this.lastCredential = { rut: options.rut, clave: options.clave };
103
+ if (this.script.failCredentialLogin)
104
+ throw this.script.failCredentialLogin;
105
+ const s = typeof this.script.credentialSession === 'function'
106
+ ? this.script.credentialSession()
107
+ : this.script.credentialSession;
108
+ return new FakePortalSession(s ?? {});
109
+ }
110
+ async restore(_storageState) {
111
+ this.restoreCalls++;
112
+ const s = typeof this.script.restoreSession === 'function'
113
+ ? this.script.restoreSession()
114
+ : this.script.restoreSession;
115
+ return new FakePortalSession(s ?? {});
116
+ }
117
+ requestPublicCalls = 0;
118
+ /** The last public request — lets a test assert the URL/form sent (no session). */
119
+ lastPublicRequest = null;
120
+ async requestPublic(url, options) {
121
+ this.requestPublicCalls++;
122
+ this.lastPublicRequest = options ? { url, options } : { url };
123
+ if (this.script.failPublic)
124
+ throw this.script.failPublic;
125
+ const r = this.script.requestPublic?.(url, options);
126
+ if (r === undefined)
127
+ return { status: 200, body: '' };
128
+ return typeof r === 'string' ? { status: 200, body: r } : r;
129
+ }
130
+ }
131
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/fake/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { AuditEntry, AuditSink, Clock, KeyValueStore } from '../../seams/index.js';
2
+ export declare const SII_DIR: string;
3
+ export declare class SystemClock implements Clock {
4
+ now(): Date;
5
+ sleep(ms: number): Promise<void>;
6
+ }
7
+ /** fs-backed JSON store: ~/.sii/<key>.json, dir 0700 / files 0600, atomic write. */
8
+ export declare class FileKeyValueStore implements KeyValueStore {
9
+ private readonly baseDir;
10
+ constructor(baseDir?: string);
11
+ private pathFor;
12
+ read<T>(key: string): Promise<T | null>;
13
+ write<T>(key: string, value: T): Promise<void>;
14
+ delete(key: string): Promise<void>;
15
+ }
16
+ /** Append-only JSONL receipt: ~/.sii/audit.jsonl. Best-effort, never throws. */
17
+ export declare class FileAuditSink implements AuditSink {
18
+ private readonly path;
19
+ constructor(path?: string);
20
+ record(entry: AuditEntry): void;
21
+ }
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAExF,eAAO,MAAM,OAAO,QAA0B,CAAC;AAE/C,qBAAa,WAAY,YAAW,KAAK;IACvC,GAAG,IAAI,IAAI;IAGX,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGjC;AAED,oFAAoF;AACpF,qBAAa,iBAAkB,YAAW,aAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAgB;IACtD,OAAO,CAAC,OAAO;IAGT,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAQvC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOzC;AAED,gFAAgF;AAChF,qBAAa,aAAc,YAAW,SAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,GAAE,MAAqC;IACxE,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAQhC"}
@@ -0,0 +1,65 @@
1
+ // Node default adapters used by createNodeRuntime(). No SII network here — the
2
+ // Playwright PortalDriver lands with the auth increment (ADR-008).
3
+ import { promises as fsp, appendFileSync, mkdirSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { dirname, join } from 'node:path';
6
+ export const SII_DIR = join(homedir(), '.sii');
7
+ export class SystemClock {
8
+ now() {
9
+ return new Date();
10
+ }
11
+ sleep(ms) {
12
+ return new Promise((resolve) => setTimeout(resolve, ms));
13
+ }
14
+ }
15
+ /** fs-backed JSON store: ~/.sii/<key>.json, dir 0700 / files 0600, atomic write. */
16
+ export class FileKeyValueStore {
17
+ baseDir;
18
+ constructor(baseDir = SII_DIR) {
19
+ this.baseDir = baseDir;
20
+ }
21
+ pathFor(key) {
22
+ return join(this.baseDir, `${key}.json`);
23
+ }
24
+ async read(key) {
25
+ try {
26
+ const raw = await fsp.readFile(this.pathFor(key), 'utf8');
27
+ return JSON.parse(raw);
28
+ }
29
+ catch {
30
+ return null; // missing / garbage degrades to null (pure read)
31
+ }
32
+ }
33
+ async write(key, value) {
34
+ await fsp.mkdir(this.baseDir, { recursive: true, mode: 0o700 });
35
+ const target = this.pathFor(key);
36
+ const tmp = `${target}.tmp`;
37
+ await fsp.writeFile(tmp, JSON.stringify(value, null, 2), { mode: 0o600 });
38
+ await fsp.rename(tmp, target);
39
+ }
40
+ async delete(key) {
41
+ try {
42
+ await fsp.unlink(this.pathFor(key));
43
+ }
44
+ catch {
45
+ // already gone
46
+ }
47
+ }
48
+ }
49
+ /** Append-only JSONL receipt: ~/.sii/audit.jsonl. Best-effort, never throws. */
50
+ export class FileAuditSink {
51
+ path;
52
+ constructor(path = join(SII_DIR, 'audit.jsonl')) {
53
+ this.path = path;
54
+ }
55
+ record(entry) {
56
+ try {
57
+ mkdirSync(dirname(this.path), { recursive: true, mode: 0o700 });
58
+ appendFileSync(this.path, `${JSON.stringify(entry)}\n`, { mode: 0o600 });
59
+ }
60
+ catch {
61
+ // a receipt is never a gatekeeper — failures degrade silently (ADR-004)
62
+ }
63
+ }
64
+ }
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/node/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,OAAO,WAAW;IACtB,GAAG;QACD,OAAO,IAAI,IAAI,EAAE,CAAC;IACpB,CAAC;IACD,KAAK,CAAC,EAAU;QACd,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF;AAED,oFAAoF;AACpF,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,UAAkB,OAAO;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAClD,OAAO,CAAC,GAAW;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,IAAI,CAAI,GAAW;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,CAAC,iDAAiD;QAChE,CAAC;IACH,CAAC;IACD,KAAK,CAAC,KAAK,CAAI,GAAW,EAAE,KAAQ;QAClC,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,GAAG,MAAM,MAAM,CAAC;QAC5B,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,OAAe,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC;QAA3C,SAAI,GAAJ,IAAI,CAAuC;IAAG,CAAC;IAC5E,MAAM,CAAC,KAAiB;QACtB,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAChE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3E,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;QAC1E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { CredentialLoginOptions, InteractiveLoginOptions, PortalDriver, PortalSession, PublicRequest, PublicResponse } from '../../seams/index.js';
2
+ export declare class PlaywrightPortalDriver implements PortalDriver {
3
+ interactiveLogin(options: InteractiveLoginOptions): Promise<PortalSession>;
4
+ credentialLogin(options: CredentialLoginOptions): Promise<PortalSession>;
5
+ restore(storageState: unknown): Promise<PortalSession>;
6
+ requestPublic(url: string, options?: PublicRequest): Promise<PublicResponse>;
7
+ }
8
+ //# sourceMappingURL=portal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/portal.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,sBAAsB,EAEtB,uBAAuB,EAEvB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,sBAAsB,CAAC;AA8H9B,qBAAa,sBAAuB,YAAW,YAAY;IACnD,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC;IAuB1E,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC;IAuCxE,OAAO,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBtD,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;CA0BvF"}