@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.
- package/CHANGELOG.md +101 -0
- package/dist/adapters/fake/index.d.ts +20 -4
- package/dist/adapters/fake/index.d.ts.map +1 -1
- package/dist/adapters/fake/index.js +38 -4
- package/dist/adapters/fake/index.js.map +1 -1
- package/dist/adapters/node/cookie-jar.d.ts +35 -0
- package/dist/adapters/node/cookie-jar.d.ts.map +1 -0
- package/dist/adapters/node/cookie-jar.js +211 -0
- package/dist/adapters/node/cookie-jar.js.map +1 -0
- package/dist/adapters/node/http.d.ts +12 -0
- package/dist/adapters/node/http.d.ts.map +1 -0
- package/dist/adapters/node/http.js +262 -0
- package/dist/adapters/node/http.js.map +1 -0
- package/dist/adapters/node/portal.d.ts.map +1 -1
- package/dist/adapters/node/portal.js +18 -8
- package/dist/adapters/node/portal.js.map +1 -1
- package/dist/adapters/node/response.d.ts +12 -4
- package/dist/adapters/node/response.d.ts.map +1 -1
- package/dist/adapters/node/response.js +36 -8
- package/dist/adapters/node/response.js.map +1 -1
- package/dist/auth/auth.d.ts +55 -6
- package/dist/auth/auth.d.ts.map +1 -1
- package/dist/auth/auth.js +238 -56
- package/dist/auth/auth.js.map +1 -1
- package/dist/auth/datos-cntr.d.ts +23 -0
- package/dist/auth/datos-cntr.d.ts.map +1 -0
- package/dist/auth/datos-cntr.js +81 -0
- package/dist/auth/datos-cntr.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/login-block.d.ts +23 -0
- package/dist/auth/login-block.d.ts.map +1 -0
- package/dist/auth/login-block.js +53 -0
- package/dist/auth/login-block.js.map +1 -0
- package/dist/auth/login-error.d.ts +20 -3
- package/dist/auth/login-error.d.ts.map +1 -1
- package/dist/auth/login-error.js +20 -5
- package/dist/auth/login-error.js.map +1 -1
- package/dist/auth/session.d.ts +29 -2
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +35 -2
- package/dist/auth/session.js.map +1 -1
- package/dist/auth/www2-login.d.ts +28 -0
- package/dist/auth/www2-login.d.ts.map +1 -0
- package/dist/auth/www2-login.js +101 -0
- package/dist/auth/www2-login.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/config/config.d.ts +21 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +21 -0
- package/dist/config/config.js.map +1 -1
- package/dist/errors/errors.d.ts +59 -2
- package/dist/errors/errors.d.ts.map +1 -1
- package/dist/errors/errors.js +55 -2
- package/dist/errors/errors.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +7 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +10 -4
- package/dist/node.js.map +1 -1
- package/dist/portal/carpeta-tributaria-regular.d.ts +30 -0
- package/dist/portal/carpeta-tributaria-regular.d.ts.map +1 -0
- package/dist/portal/carpeta-tributaria-regular.js +142 -0
- package/dist/portal/carpeta-tributaria-regular.js.map +1 -0
- package/dist/portal/www2-session.d.ts +13 -0
- package/dist/portal/www2-session.d.ts.map +1 -0
- package/dist/portal/www2-session.js +61 -0
- package/dist/portal/www2-session.js.map +1 -0
- package/dist/seams/index.d.ts +7 -0
- package/dist/seams/index.d.ts.map +1 -1
- package/dist/tasks/auth.d.ts +23 -6
- package/dist/tasks/auth.d.ts.map +1 -1
- package/dist/tasks/auth.js +20 -5
- package/dist/tasks/auth.js.map +1 -1
- package/dist/tasks/bte.d.ts.map +1 -1
- package/dist/tasks/bte.js +4 -2
- package/dist/tasks/bte.js.map +1 -1
- package/dist/tasks/carpeta.d.ts +9 -0
- package/dist/tasks/carpeta.d.ts.map +1 -0
- package/dist/tasks/carpeta.js +49 -0
- package/dist/tasks/carpeta.js.map +1 -0
- package/dist/tasks/dte.js +8 -8
- package/dist/tasks/dte.js.map +1 -1
- package/package.json +1 -1
package/dist/errors/errors.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
13
|
-
* session
|
|
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
|
|
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"}
|
package/dist/errors/errors.js
CHANGED
|
@@ -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
|
-
/**
|
|
19
|
-
* session
|
|
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
|
|
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACnF,YAAY,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,
|
|
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;
|
|
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
|
|
7
|
-
* The default portal is the
|
|
8
|
-
*
|
|
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
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"
|
|
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
|
|
12
|
-
* The default portal is the
|
|
13
|
-
*
|
|
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
|
|
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
|
|
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":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PortalSession } from '../seams/index.js';
|
|
2
|
+
/** The www2 app session as `/app/session/status` describes it. Only `userId` is load-bearing
|
|
3
|
+
* (it keys every `/app/<name>-api` path); the rest is kept for diagnostics. */
|
|
4
|
+
export interface Www2Session {
|
|
5
|
+
readonly userId: string;
|
|
6
|
+
readonly userAuthType: string | null;
|
|
7
|
+
}
|
|
8
|
+
/** Read the www2 app session (see the header). Resolves `{userId}` when one exists; raises the
|
|
9
|
+
* ACTIONABLE `Www2SessionError` (a `NotAuthenticated`) when www2 answers anything but a 200
|
|
10
|
+
* session JSON — the classic session alone never reaches this layer. `originalUrl` is the app
|
|
11
|
+
* page the SPA would pass (observed optional; the answer is the same without it). Never retried. */
|
|
12
|
+
export declare function readWww2Session(session: PortalSession, originalUrl?: string): Promise<Www2Session>;
|
|
13
|
+
//# sourceMappingURL=www2-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"www2-session.d.ts","sourceRoot":"","sources":["../../src/portal/www2-session.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD;gFACgF;AAChF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAKD;;;qGAGqG;AACrG,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// The www2 APP SESSION — the second cookies-only layer every `www2.sii.cl/app/*` facade needs
|
|
2
|
+
// (ADR-026). Shared by all www2 apps (first: Carpeta Tributaria, `carpeta-tributaria-regular.ts`),
|
|
3
|
+
// so a new app reuses this read instead of inventing a per-app warm-up.
|
|
4
|
+
//
|
|
5
|
+
// Observed 2026-09-11/12 (#110; docs/sii-contract/carpeta-tributaria.md): the classic `.sii.cl`
|
|
6
|
+
// cookies the cookies-only login holds reach www1/www3/www4/loa but NOT `/app/<name>-api/*` — those
|
|
7
|
+
// answer a bare 401 until the OAuth2 flow (`/app/session/login` → `/oauthsii-v1/` → `/app/session/
|
|
8
|
+
// create`) minted the httpOnly `.sii.cl` pair `X-SII-STATE-CT` + `X-SII-STATE-TYPE` (~100 min). The
|
|
9
|
+
// SPA's own liveness read is `GET /app/session/status` (session library `j()`): 200 → JSON
|
|
10
|
+
// `{seconds, userId, userProfiles, userAuthType, authTime, userRte}` committed to vuex; anything
|
|
11
|
+
// else → no session (the SPA then bounces to `/bifurcacion`). Every app keys its API paths by
|
|
12
|
+
// `session.userId` VERBATIM (the canonical `<body>-<dv>` RUT, observed) — so this read is where a
|
|
13
|
+
// facade gets its path key; it never formats a RUT for it.
|
|
14
|
+
//
|
|
15
|
+
// Reached via `requestText`: a non-JSON 401 body is EXPECTED here, and a dead classic jar is still
|
|
16
|
+
// caught URL-based (the `LOGIN_HOST` bounce → `SessionExpiredError`).
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import { HOSTS } from '../config/index.js';
|
|
19
|
+
import { Www2SessionError } from '../errors/index.js';
|
|
20
|
+
const SESSION_STATUS_URL = `${HOSTS.portalApp}/app/session/status`;
|
|
21
|
+
// Observed 2026-09-12 (live app session). `.loose()`: the other fields ride along unvalidated.
|
|
22
|
+
const SessionJson = z.object({ userId: z.union([z.string(), z.number()]) }).loose();
|
|
23
|
+
/** Read the www2 app session (see the header). Resolves `{userId}` when one exists; raises the
|
|
24
|
+
* ACTIONABLE `Www2SessionError` (a `NotAuthenticated`) when www2 answers anything but a 200
|
|
25
|
+
* session JSON — the classic session alone never reaches this layer. `originalUrl` is the app
|
|
26
|
+
* page the SPA would pass (observed optional; the answer is the same without it). Never retried. */
|
|
27
|
+
export async function readWww2Session(session, originalUrl) {
|
|
28
|
+
const url = originalUrl === undefined
|
|
29
|
+
? SESSION_STATUS_URL
|
|
30
|
+
: `${SESSION_STATUS_URL}?originalUrl=${encodeURIComponent(originalUrl)}`;
|
|
31
|
+
const res = await session.requestText(url, {
|
|
32
|
+
method: 'GET',
|
|
33
|
+
headers: {
|
|
34
|
+
Accept: 'application/json, text/plain, */*',
|
|
35
|
+
...(originalUrl === undefined ? {} : { Referer: originalUrl }),
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
let parsed = null;
|
|
39
|
+
if (res.status === 200) {
|
|
40
|
+
try {
|
|
41
|
+
parsed = JSON.parse(res.body);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
parsed = null; // the SPA shell HTML (a 200 on a cold hit) is "no session" too
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const app = parsed === null ? null : SessionJson.safeParse(parsed);
|
|
48
|
+
if (!app || !app.success) {
|
|
49
|
+
throw new Www2SessionError('No hay sesión en la plataforma www2 del SII (www2.sii.cl/app/*), que autoriza con una ' +
|
|
50
|
+
'sesión propia (login OAuth) y no con la sesión de Mi SII que esta herramienta guarda ' +
|
|
51
|
+
`(HTTP ${res.status}${res.status === 200 ? ' sin JSON de sesión' : ''} en ` +
|
|
52
|
+
'/app/session/status). Iniciarla aún no está soportado — ADR-026 la define como un ' +
|
|
53
|
+
'segundo login en el navegador (`sii auth login --www2`, pendiente).');
|
|
54
|
+
}
|
|
55
|
+
const authType = app.data['userAuthType'];
|
|
56
|
+
return {
|
|
57
|
+
userId: String(app.data.userId),
|
|
58
|
+
userAuthType: typeof authType === 'string' ? authType : null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=www2-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"www2-session.js","sourceRoot":"","sources":["../../src/portal/www2-session.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mGAAmG;AACnG,wEAAwE;AACxE,EAAE;AACF,gGAAgG;AAChG,oGAAoG;AACpG,mGAAmG;AACnG,oGAAoG;AACpG,2FAA2F;AAC3F,iGAAiG;AACjG,8FAA8F;AAC9F,kGAAkG;AAClG,2DAA2D;AAC3D,EAAE;AACF,mGAAmG;AACnG,sEAAsE;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,SAAS,qBAAqB,CAAC;AASnE,+FAA+F;AAC/F,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAEpF;;;qGAGqG;AACrG,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAsB,EACtB,WAAoB;IAEpB,MAAM,GAAG,GACP,WAAW,KAAK,SAAS;QACvB,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,GAAG,kBAAkB,gBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IAC7E,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,MAAM,EAAE,mCAAmC;YAC3C,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;SAC/D;KACF,CAAC,CAAC;IACH,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAY,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,IAAI,CAAC,CAAC,+DAA+D;QAChF,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,gBAAgB,CACxB,wFAAwF;YACtF,uFAAuF;YACvF,SAAS,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM;YAC3E,oFAAoF;YACpF,qEAAqE,CACxE,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B,YAAY,EAAE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;KAC7D,CAAC;AACJ,CAAC"}
|
package/dist/seams/index.d.ts
CHANGED
|
@@ -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
|