@ksefnik/http 0.0.1

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/adapter.d.ts +16 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +19 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/client.d.ts +48 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +107 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/crypto.d.ts +22 -0
  12. package/dist/crypto.d.ts.map +1 -0
  13. package/dist/crypto.js +30 -0
  14. package/dist/crypto.js.map +1 -0
  15. package/dist/endpoints.d.ts +20 -0
  16. package/dist/endpoints.d.ts.map +1 -0
  17. package/dist/endpoints.js +26 -0
  18. package/dist/endpoints.js.map +1 -0
  19. package/dist/errors.d.ts +14 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +26 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/generated/index.d.ts +30 -0
  24. package/dist/generated/index.d.ts.map +1 -0
  25. package/dist/generated/index.js +2 -0
  26. package/dist/generated/index.js.map +1 -0
  27. package/dist/generated/ksef-api.d.ts +10424 -0
  28. package/dist/generated/ksef-api.d.ts.map +1 -0
  29. package/dist/generated/ksef-api.js +6 -0
  30. package/dist/generated/ksef-api.js.map +1 -0
  31. package/dist/http.d.ts +24 -0
  32. package/dist/http.d.ts.map +1 -0
  33. package/dist/http.js +120 -0
  34. package/dist/http.js.map +1 -0
  35. package/dist/index.d.ts +8 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +7 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/invoices.d.ts +32 -0
  40. package/dist/invoices.d.ts.map +1 -0
  41. package/dist/invoices.js +130 -0
  42. package/dist/invoices.js.map +1 -0
  43. package/dist/public-key.d.ts +6 -0
  44. package/dist/public-key.d.ts.map +1 -0
  45. package/dist/public-key.js +37 -0
  46. package/dist/public-key.js.map +1 -0
  47. package/dist/retry.d.ts +19 -0
  48. package/dist/retry.d.ts.map +1 -0
  49. package/dist/retry.js +59 -0
  50. package/dist/retry.js.map +1 -0
  51. package/dist/session.d.ts +29 -0
  52. package/dist/session.d.ts.map +1 -0
  53. package/dist/session.js +109 -0
  54. package/dist/session.js.map +1 -0
  55. package/dist/types.d.ts +8 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +2 -0
  58. package/dist/types.js.map +1 -0
  59. package/dist/xml.d.ts +12 -0
  60. package/dist/xml.d.ts.map +1 -0
  61. package/dist/xml.js +65 -0
  62. package/dist/xml.js.map +1 -0
  63. package/package.json +47 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CodeFormers-it
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,141 @@
1
+ # @ksefnik/http
2
+
3
+ Production HTTP client for **KSeF 2.0** (Krajowy System e-Faktur, Polish national e-invoicing system, live from 2026-02-01).
4
+
5
+ Implements the `KsefClient` interface from `@ksefnik/core` against the real `api.ksef.mf.gov.pl` endpoints. Plug it into the `Ksefnik` facade via `createHttpAdapter(...)` and you get end-to-end invoice retrieval, reconciliation, and MCP-mediated automation with zero additional code in consumers.
6
+
7
+ > **Research source of truth**: [CIRFMF/ksef-docs](https://github.com/CIRFMF/ksef-docs) — see [NOTES.md](./NOTES.md) for a summary of the auth flow, endpoint map, and rate limits used by this package.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pnpm add @ksefnik/http @ksefnik/core @ksefnik/shared
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { createKsefnik } from '@ksefnik/core'
19
+ import { createHttpAdapter } from '@ksefnik/http'
20
+ import { readFileSync } from 'node:fs'
21
+
22
+ const adapter = createHttpAdapter({
23
+ nip: '7010002137',
24
+ token: process.env.KSEF_TOKEN!,
25
+ environment: 'production',
26
+ publicKeyPem: readFileSync('./ksef-public-key.pem', 'utf8'),
27
+ })
28
+
29
+ const ksef = createKsefnik({
30
+ config: { nip: '7010002137', environment: 'production', token: process.env.KSEF_TOKEN! },
31
+ adapter,
32
+ })
33
+
34
+ await adapter.initSession?.()
35
+ const invoices = await ksef.invoices.fetch({ from: '2026-03-01', to: '2026-03-31' })
36
+ await adapter.closeSession?.()
37
+ ```
38
+
39
+ ## Environments
40
+
41
+ | Environment | Base URL |
42
+ |---|---|
43
+ | `production` | `https://api.ksef.mf.gov.pl/v2` |
44
+ | `demo` | `https://api-demo.ksef.mf.gov.pl/v2` |
45
+ | `test` | `https://api-test.ksef.mf.gov.pl/v2` |
46
+
47
+ ## Authentication flow (KSeF 2.0)
48
+
49
+ 1. `POST /auth/challenge` — server returns `{ challenge, timestamp }`.
50
+ 2. Client encrypts `"{ksefToken}|{timestamp}"` with RSA-OAEP SHA-256 using the MF public key.
51
+ 3. `POST /auth/ksef-token` — server returns `{ authenticationToken, referenceNumber }` (temporary JWT).
52
+ 4. `POST /auth/token/redeem` (`Authorization: Bearer <authenticationToken>`) — returns `{ accessToken, refreshToken }`.
53
+ 5. All subsequent calls use `Authorization: Bearer <accessToken>`.
54
+ 6. Before expiry the client transparently calls `POST /auth/token/refresh` with the refresh token.
55
+
56
+ Crypto: **RSA-OAEP SHA-256 only**, implemented via `node:crypto` `webcrypto.subtle`. Zero external dependencies.
57
+
58
+ ## Error handling
59
+
60
+ ```ts
61
+ import { KsefApiError, KsefAuthError, KsefRateLimitError } from '@ksefnik/http'
62
+
63
+ try {
64
+ await ksef.invoices.fetch(...)
65
+ } catch (error) {
66
+ if (error instanceof KsefAuthError) {
67
+ // 401/403 — refresh token expired, re-issue KSeF token in the portal
68
+ } else if (error instanceof KsefRateLimitError) {
69
+ // 429 — honour error.retryAfter (seconds) and retry
70
+ } else if (error instanceof KsefApiError) {
71
+ // 4xx/5xx with error.statusCode and error.detailCode
72
+ }
73
+ }
74
+ ```
75
+
76
+ The underlying `withRetry` from `@ksefnik/core` automatically retries `KsefRateLimitError` and `5xx` responses with exponential backoff.
77
+
78
+ ## Rate limits
79
+
80
+ Per [limity-api.md](https://github.com/CIRFMF/ksef-docs/blob/main/limity/limity-api.md):
81
+
82
+ | Endpoint | req/s | req/min | req/h |
83
+ |---|---|---|---|
84
+ | `POST /invoices/query/metadata` | 8 | 16 | 20 |
85
+ | `GET /invoices/ksef/{ref}` | 8 | 16 | 64 |
86
+ | Default | 10 | 30 | 120 |
87
+
88
+ `fetchInvoices` uses `mapWithConcurrency(5)` by default to stay well within the bursting envelope.
89
+
90
+ ## Not implemented in MVP
91
+
92
+ - `sendInvoice` — stub throws "not implemented".
93
+ - `getUpo` — stub throws "not implemented".
94
+ - Async export flow (`POST /invoices/exports` + polling) — v2.
95
+
96
+ ## Smoke test
97
+
98
+ ```bash
99
+ KSEF_TEST_NIP=... \
100
+ KSEF_TEST_TOKEN=... \
101
+ KSEF_TEST_PUBLIC_KEY_PATH=./ksef-test-pub.pem \
102
+ pnpm --filter @ksefnik/http smoke
103
+ ```
104
+
105
+ The smoke script talks to `api-test.ksef.mf.gov.pl` for manual end-to-end verification. It is **not** run in CI.
106
+
107
+ ## Type generation from OpenAPI
108
+
109
+ Types for every KSeF 2.0 request/response in `src/session.ts`, `src/invoices.ts`, and `src/public-key.ts` are **generated** from the live production contract via [openapi-typescript](https://github.com/openapi-ts/openapi-typescript). The hand-written runtime (HTTP layer, retry, error mapping, session orchestration) is kept, but the shapes themselves are single-source-of-truth from MF.
110
+
111
+ ```bash
112
+ pnpm --filter @ksefnik/http generate
113
+ ```
114
+
115
+ This fetches `https://api.ksef.mf.gov.pl/docs/v2/openapi.json` and writes `src/generated/ksef-api.ts` (≈10k lines, 253 schemas, 59 paths). The generated file is committed to git so the package builds without network access, but should be refreshed whenever MF publishes a spec change.
116
+
117
+ ### Workflow for contract changes
118
+
119
+ 1. `pnpm --filter @ksefnik/http generate` — pulls the latest contract
120
+ 2. `pnpm --filter @ksefnik/http build` — TypeScript flags any breaking changes at compile time (missing fields, renamed enums, nullability changes, etc.)
121
+ 3. Fix the callsites in `session.ts`/`invoices.ts`/`public-key.ts` until the build is green
122
+ 4. `pnpm --filter @ksefnik/http test` — unit + integration tests must stay green
123
+ 5. `KSEF_ENV=production pnpm --filter @ksefnik/http smoke` — live verification against the real API
124
+
125
+ ### What is generated vs hand-written
126
+
127
+ | Layer | Source |
128
+ |---|---|
129
+ | Request/response shapes (challenge, ksef-token, redeem, refresh, auth status, query metadata, public-key certs) | **generated** — `src/generated/ksef-api.ts` re-exported via `src/generated/index.ts` |
130
+ | Runtime HTTP client (`src/http.ts`) | hand-written — fetch, AbortSignal timeout, User-Agent, response parsing |
131
+ | Error mapping to `KsefAuthError`/`KsefRateLimitError`/`KsefApiError` | hand-written — `src/errors.ts` + `src/http.ts` |
132
+ | Retry with `Retry-After` honoring | hand-written — `src/retry.ts` |
133
+ | Auth flow orchestration (challenge → ksef-token → polling → redeem → refresh) | hand-written — `src/session.ts` |
134
+ | Pagination + `isTruncated` guard + concurrency | hand-written — `src/invoices.ts` |
135
+ | `KsefHttpClient` facade implementing `@ksefnik/core` `KsefClient` interface | hand-written — `src/client.ts` |
136
+
137
+ The generated file adds ~600KB to source control but adds **zero runtime cost** (pure `.d.ts`-style type exports — TSC erases them at build time).
138
+
139
+ ## License
140
+
141
+ MIT. Part of the [ksefnik](../../README.md) monorepo.
@@ -0,0 +1,16 @@
1
+ import type { KsefAdapter } from '@ksefnik/shared';
2
+ import { type KsefHttpClientOptions } from './client.js';
3
+ import type { KsefEnvironment } from './endpoints.js';
4
+ export interface CreateHttpAdapterOpts {
5
+ nip: string;
6
+ token: string;
7
+ environment: KsefEnvironment;
8
+ /**
9
+ * Optional pinned MF RSA public key (PEM/SPKI). When omitted, the client
10
+ * fetches it from `GET /security/public-key-certificates` on first session.
11
+ */
12
+ publicKeyPem?: string;
13
+ client?: Partial<Omit<KsefHttpClientOptions, 'environment' | 'publicKeyPem'>>;
14
+ }
15
+ export declare function createHttpAdapter(opts: CreateHttpAdapterOpts): KsefAdapter;
16
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,eAAe,CAAA;IAC5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,aAAa,GAAG,cAAc,CAAC,CAAC,CAAA;CAC9E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,WAAW,CAc1E"}
@@ -0,0 +1,19 @@
1
+ import { KsefAdapterImpl } from '@ksefnik/core';
2
+ import { KsefHttpClient } from './client.js';
3
+ export function createHttpAdapter(opts) {
4
+ if (!opts.nip)
5
+ throw new Error('createHttpAdapter: nip is required');
6
+ if (!opts.token)
7
+ throw new Error('createHttpAdapter: token is required');
8
+ const client = new KsefHttpClient({
9
+ environment: opts.environment,
10
+ publicKeyPem: opts.publicKeyPem,
11
+ ...opts.client,
12
+ });
13
+ return new KsefAdapterImpl(client, {
14
+ nip: opts.nip,
15
+ environment: opts.environment,
16
+ token: opts.token,
17
+ });
18
+ }
19
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAG/C,OAAO,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAA;AAexE,MAAM,UAAU,iBAAiB,CAAC,IAA2B;IAC3D,IAAI,CAAC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IACpE,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;IAExE,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QAChC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,GAAG,IAAI,CAAC,MAAM;KACf,CAAC,CAAA;IACF,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE;QACjC,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { type HttpRetryOptions } from './retry.js';
2
+ import type { KsefClient, KsefClientConfig, KsefSessionState, KsefRawInvoice } from '@ksefnik/core';
3
+ import { type KsefEnvironment } from './endpoints.js';
4
+ export interface KsefHttpClientOptions {
5
+ environment: KsefEnvironment;
6
+ /**
7
+ * MF RSA public key in PEM/SPKI format used for `/auth/ksef-token` encryption.
8
+ * If omitted, the client auto-fetches it from `GET /security/public-key-certificates`
9
+ * on first `initSession()` call and caches it for the lifetime of the client.
10
+ */
11
+ publicKeyPem?: string;
12
+ baseUrl?: string;
13
+ fetchImpl?: typeof fetch;
14
+ userAgent?: string;
15
+ timeoutMs?: number;
16
+ retry?: HttpRetryOptions;
17
+ }
18
+ export declare class KsefHttpClient implements KsefClient {
19
+ private readonly opts;
20
+ private readonly http;
21
+ private readonly retryOpts;
22
+ private cachedPublicKeyPem;
23
+ constructor(opts: KsefHttpClientOptions);
24
+ private resolvePublicKey;
25
+ initSession(config: KsefClientConfig): Promise<KsefSessionState>;
26
+ terminateSession(token: string): Promise<void>;
27
+ fetchInvoices(params: {
28
+ token: string;
29
+ dateFrom: string;
30
+ dateTo: string;
31
+ subjectNip?: string;
32
+ subjectType?: 'Subject1' | 'Subject2' | 'Subject3';
33
+ pageSize?: number;
34
+ pageOffset?: number;
35
+ }): Promise<{
36
+ invoices: KsefRawInvoice[];
37
+ total: number;
38
+ }>;
39
+ sendInvoice(): Promise<{
40
+ ksefReferenceNumber: string;
41
+ timestamp: string;
42
+ }>;
43
+ getUpo(): Promise<{
44
+ xml: string;
45
+ status: 'confirmed' | 'pending' | 'rejected';
46
+ }>;
47
+ }
48
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACf,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAYhE,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,eAAe,CAAA;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,gBAAgB,CAAA;CACzB;AAkCD,qBAAa,cAAe,YAAW,UAAU;IAKnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,kBAAkB,CAAoB;gBAEjB,IAAI,EAAE,qBAAqB;YAY1C,gBAAgB;IAOxB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwBhE,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,aAAa,CAAC,MAAM,EAAE;QAC1B,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAA;QAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA4BpD,WAAW,IAAI,OAAO,CAAC;QAAE,mBAAmB,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAM1E,MAAM,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAA;KAAE,CAAC;CAGvF"}
package/dist/client.js ADDED
@@ -0,0 +1,107 @@
1
+ import { withHttpRetry } from './retry.js';
2
+ import { ENDPOINTS } from './endpoints.js';
3
+ import { HttpClient } from './http.js';
4
+ import { initKsefSession, refreshAccessToken, revokeCurrentSession, shouldRefresh, } from './session.js';
5
+ import { fetchInvoices as fetchInvoicesHttp } from './invoices.js';
6
+ import { fetchKsefTokenEncryptionKey } from './public-key.js';
7
+ /**
8
+ * Delimiter between fields of the encoded session token. JWTs (access and
9
+ * refresh tokens returned by KSeF 2.0) are base64url-encoded and cannot
10
+ * contain `||`, so this round-trips safely through `KsefClient.fetchInvoices`.
11
+ */
12
+ const SESSION_TOKEN_SEPARATOR = '||';
13
+ function encodeSessionToken(session) {
14
+ return [
15
+ 'v1',
16
+ session.accessToken,
17
+ session.refreshToken,
18
+ session.accessExpiresAt.toISOString(),
19
+ session.referenceNumber,
20
+ ].join(SESSION_TOKEN_SEPARATOR);
21
+ }
22
+ function decodeSessionToken(token) {
23
+ const parts = token.split(SESSION_TOKEN_SEPARATOR);
24
+ if (parts.length !== 5 || parts[0] !== 'v1')
25
+ return null;
26
+ const [, accessToken, refreshToken, expiresAtIso, referenceNumber] = parts;
27
+ const accessExpiresAt = new Date(expiresAtIso);
28
+ if (Number.isNaN(accessExpiresAt.getTime()))
29
+ return null;
30
+ return { accessToken, refreshToken, accessExpiresAt, referenceNumber };
31
+ }
32
+ export class KsefHttpClient {
33
+ opts;
34
+ http;
35
+ retryOpts;
36
+ cachedPublicKeyPem;
37
+ constructor(opts) {
38
+ this.opts = opts;
39
+ const baseUrl = opts.baseUrl ?? ENDPOINTS[opts.environment];
40
+ this.http = new HttpClient({
41
+ baseUrl,
42
+ fetchImpl: opts.fetchImpl,
43
+ userAgent: opts.userAgent,
44
+ defaultTimeoutMs: opts.timeoutMs,
45
+ });
46
+ this.retryOpts = opts.retry ?? {};
47
+ this.cachedPublicKeyPem = opts.publicKeyPem;
48
+ }
49
+ async resolvePublicKey() {
50
+ if (this.cachedPublicKeyPem)
51
+ return this.cachedPublicKeyPem;
52
+ const pem = await fetchKsefTokenEncryptionKey(this.http);
53
+ this.cachedPublicKeyPem = pem;
54
+ return pem;
55
+ }
56
+ async initSession(config) {
57
+ if (!config.token) {
58
+ throw new Error('KsefHttpClient.initSession: config.token (KSeF token) is required');
59
+ }
60
+ const publicKeyPem = await this.resolvePublicKey();
61
+ const session = await withHttpRetry(() => initKsefSession(this.http, {
62
+ nip: config.nip,
63
+ ksefToken: config.token,
64
+ publicKeyPem,
65
+ }), this.retryOpts);
66
+ return {
67
+ token: encodeSessionToken(session),
68
+ nip: config.nip,
69
+ environment: config.environment,
70
+ expiresAt: session.accessExpiresAt,
71
+ referenceNumber: session.referenceNumber,
72
+ };
73
+ }
74
+ async terminateSession(token) {
75
+ const session = decodeSessionToken(token);
76
+ if (!session)
77
+ return;
78
+ await revokeCurrentSession(this.http, session);
79
+ }
80
+ async fetchInvoices(params) {
81
+ let session = decodeSessionToken(params.token);
82
+ if (!session) {
83
+ throw new Error('KsefHttpClient.fetchInvoices: invalid session token — expected the opaque ' +
84
+ 'string returned by initSession() (format `v1||access||refresh||validUntil||ref`), ' +
85
+ 'not a raw KSeF or JWT token');
86
+ }
87
+ if (shouldRefresh(session)) {
88
+ session = await withHttpRetry(() => refreshAccessToken(this.http, session), this.retryOpts);
89
+ }
90
+ const result = await withHttpRetry(() => fetchInvoicesHttp(this.http, {
91
+ accessToken: session.accessToken,
92
+ dateFrom: params.dateFrom,
93
+ dateTo: params.dateTo,
94
+ pageSize: params.pageSize,
95
+ pageOffset: params.pageOffset,
96
+ subjectType: params.subjectType ?? 'Subject2',
97
+ }), this.retryOpts);
98
+ return result;
99
+ }
100
+ async sendInvoice() {
101
+ throw new Error('KsefHttpClient.sendInvoice: not implemented in HTTP client MVP — see http_plan.md §H05.5');
102
+ }
103
+ async getUpo() {
104
+ throw new Error('KsefHttpClient.getUpo: not implemented in HTTP client MVP');
105
+ }
106
+ }
107
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Encrypts a payload with RSA-OAEP SHA-256 using the MF public key.
3
+ *
4
+ * Accepts either:
5
+ * - a `-----BEGIN PUBLIC KEY-----` PEM (SubjectPublicKeyInfo), or
6
+ * - a `-----BEGIN CERTIFICATE-----` PEM (X.509 certificate, as returned by
7
+ * KSeF 2.0 `GET /security/public-key-certificates`).
8
+ *
9
+ * `node:crypto.createPublicKey` transparently handles both.
10
+ */
11
+ export declare function rsaOaepEncrypt(plaintext: string | Uint8Array, publicKeyPemOrCert: string): string;
12
+ /**
13
+ * Builds the KSeF 2.0 encryptedToken payload for `POST /auth/ksef-token`.
14
+ *
15
+ * Format: RSA-OAEP(SHA-256) over the UTF-8 bytes of `"{ksefToken}|{timestampMs}"`,
16
+ * base64-encoded. `timestampMs` MUST be the integer from `timestampMs` field
17
+ * of the `/auth/challenge` response (Unix epoch milliseconds), passed as a
18
+ * decimal string. Using the sibling `timestamp` ISO string is rejected by
19
+ * the server (verified against `api.ksef.mf.gov.pl/v2` 2026-04-11).
20
+ */
21
+ export declare function buildEncryptedToken(ksefToken: string, timestampMs: string, publicKeyPemOrCert: string): string;
22
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,GAAG,UAAU,EAC9B,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAQR;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAER"}
package/dist/crypto.js ADDED
@@ -0,0 +1,30 @@
1
+ import { constants, createPublicKey, publicEncrypt } from 'node:crypto';
2
+ /**
3
+ * Encrypts a payload with RSA-OAEP SHA-256 using the MF public key.
4
+ *
5
+ * Accepts either:
6
+ * - a `-----BEGIN PUBLIC KEY-----` PEM (SubjectPublicKeyInfo), or
7
+ * - a `-----BEGIN CERTIFICATE-----` PEM (X.509 certificate, as returned by
8
+ * KSeF 2.0 `GET /security/public-key-certificates`).
9
+ *
10
+ * `node:crypto.createPublicKey` transparently handles both.
11
+ */
12
+ export function rsaOaepEncrypt(plaintext, publicKeyPemOrCert) {
13
+ const key = createPublicKey(publicKeyPemOrCert);
14
+ const data = typeof plaintext === 'string' ? Buffer.from(plaintext, 'utf8') : Buffer.from(plaintext);
15
+ const encrypted = publicEncrypt({ key, padding: constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' }, data);
16
+ return encrypted.toString('base64');
17
+ }
18
+ /**
19
+ * Builds the KSeF 2.0 encryptedToken payload for `POST /auth/ksef-token`.
20
+ *
21
+ * Format: RSA-OAEP(SHA-256) over the UTF-8 bytes of `"{ksefToken}|{timestampMs}"`,
22
+ * base64-encoded. `timestampMs` MUST be the integer from `timestampMs` field
23
+ * of the `/auth/challenge` response (Unix epoch milliseconds), passed as a
24
+ * decimal string. Using the sibling `timestamp` ISO string is rejected by
25
+ * the server (verified against `api.ksef.mf.gov.pl/v2` 2026-04-11).
26
+ */
27
+ export function buildEncryptedToken(ksefToken, timestampMs, publicKeyPemOrCert) {
28
+ return rsaOaepEncrypt(`${ksefToken}|${timestampMs}`, publicKeyPemOrCert);
29
+ }
30
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEvE;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAC5B,SAA8B,EAC9B,kBAA0B;IAE1B,MAAM,GAAG,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAA;IAC/C,MAAM,IAAI,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACpG,MAAM,SAAS,GAAG,aAAa,CAC7B,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACtE,IAAI,CACL,CAAA;IACD,OAAO,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,WAAmB,EACnB,kBAA0B;IAE1B,OAAO,cAAc,CAAC,GAAG,SAAS,IAAI,WAAW,EAAE,EAAE,kBAAkB,CAAC,CAAA;AAC1E,CAAC"}
@@ -0,0 +1,20 @@
1
+ export declare const ENDPOINTS: {
2
+ readonly production: "https://api.ksef.mf.gov.pl/v2";
3
+ readonly demo: "https://api-demo.ksef.mf.gov.pl/v2";
4
+ readonly test: "https://api-test.ksef.mf.gov.pl/v2";
5
+ };
6
+ export type KsefEnvironment = keyof typeof ENDPOINTS;
7
+ export declare const PATHS: {
8
+ readonly authChallenge: "/auth/challenge";
9
+ readonly authKsefToken: "/auth/ksef-token";
10
+ readonly authStatus: (referenceNumber: string) => string;
11
+ readonly authRedeem: "/auth/token/redeem";
12
+ readonly authRefresh: "/auth/token/refresh";
13
+ readonly sessionsList: "/auth/sessions";
14
+ readonly sessionRevokeCurrent: "/auth/sessions/current";
15
+ readonly sessionRevokeByRef: (referenceNumber: string) => string;
16
+ readonly queryMetadata: "/invoices/query/metadata";
17
+ readonly invoiceByKsefNumber: (ksefNumber: string) => string;
18
+ readonly publicKeyCertificates: "/security/public-key-certificates";
19
+ };
20
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;;;;CAIZ,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,SAAS,CAAA;AAapD,eAAO,MAAM,KAAK;;;2CAGc,MAAM,KAAG,MAAM;;;;;mDAMP,MAAM,KAAG,MAAM;;+CAGnB,MAAM,KAAG,MAAM;;CAGzC,CAAA"}
@@ -0,0 +1,26 @@
1
+ export const ENDPOINTS = {
2
+ production: 'https://api.ksef.mf.gov.pl/v2',
3
+ demo: 'https://api-demo.ksef.mf.gov.pl/v2',
4
+ test: 'https://api-test.ksef.mf.gov.pl/v2',
5
+ };
6
+ const SAFE_REF_RE = /^[A-Za-z0-9_-]{1,128}$/;
7
+ function assertSafeReference(value, field) {
8
+ if (!SAFE_REF_RE.test(value)) {
9
+ throw new Error(`Invalid ${field}: must match ${SAFE_REF_RE.toString()} (got: ${JSON.stringify(value)})`);
10
+ }
11
+ return value;
12
+ }
13
+ export const PATHS = {
14
+ authChallenge: '/auth/challenge',
15
+ authKsefToken: '/auth/ksef-token',
16
+ authStatus: (referenceNumber) => `/auth/${assertSafeReference(referenceNumber, 'referenceNumber')}`,
17
+ authRedeem: '/auth/token/redeem',
18
+ authRefresh: '/auth/token/refresh',
19
+ sessionsList: '/auth/sessions',
20
+ sessionRevokeCurrent: '/auth/sessions/current',
21
+ sessionRevokeByRef: (referenceNumber) => `/auth/sessions/${assertSafeReference(referenceNumber, 'referenceNumber')}`,
22
+ queryMetadata: '/invoices/query/metadata',
23
+ invoiceByKsefNumber: (ksefNumber) => `/invoices/ksef/${assertSafeReference(ksefNumber, 'ksefNumber')}`,
24
+ publicKeyCertificates: '/security/public-key-certificates',
25
+ };
26
+ //# sourceMappingURL=endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,UAAU,EAAE,+BAA+B;IAC3C,IAAI,EAAE,oCAAoC;IAC1C,IAAI,EAAE,oCAAoC;CAClC,CAAA;AAIV,MAAM,WAAW,GAAG,wBAAwB,CAAA;AAE5C,SAAS,mBAAmB,CAAC,KAAa,EAAE,KAAa;IACvD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,gBAAgB,WAAW,CAAC,QAAQ,EAAE,UAAU,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CACzF,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,aAAa,EAAE,iBAAiB;IAChC,aAAa,EAAE,kBAAkB;IACjC,UAAU,EAAE,CAAC,eAAuB,EAAU,EAAE,CAC9C,SAAS,mBAAmB,CAAC,eAAe,EAAE,iBAAiB,CAAC,EAAE;IACpE,UAAU,EAAE,oBAAoB;IAChC,WAAW,EAAE,qBAAqB;IAClC,YAAY,EAAE,gBAAgB;IAC9B,oBAAoB,EAAE,wBAAwB;IAC9C,kBAAkB,EAAE,CAAC,eAAuB,EAAU,EAAE,CACtD,kBAAkB,mBAAmB,CAAC,eAAe,EAAE,iBAAiB,CAAC,EAAE;IAC7E,aAAa,EAAE,0BAA0B;IACzC,mBAAmB,EAAE,CAAC,UAAkB,EAAU,EAAE,CAClD,kBAAkB,mBAAmB,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE;IACnE,qBAAqB,EAAE,mCAAmC;CAClD,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { KsefApiError as SharedKsefApiError } from '@ksefnik/shared';
2
+ export declare class KsefApiError extends SharedKsefApiError {
3
+ readonly requestId?: string | undefined;
4
+ readonly detailCode?: string | undefined;
5
+ constructor(message: string, statusCode?: number, requestId?: string | undefined, detailCode?: string | undefined, context?: Record<string, unknown>);
6
+ }
7
+ export declare class KsefAuthError extends KsefApiError {
8
+ constructor(message: string, statusCode: number, requestId?: string, detailCode?: string, context?: Record<string, unknown>);
9
+ }
10
+ export declare class KsefRateLimitError extends KsefApiError {
11
+ readonly retryAfter: number;
12
+ constructor(message: string, retryAfter: number, requestId?: string, context?: Record<string, unknown>);
13
+ }
14
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpE,qBAAa,YAAa,SAAQ,kBAAkB;aAIhC,SAAS,CAAC,EAAE,MAAM;aAClB,UAAU,CAAC,EAAE,MAAM;gBAHnC,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACH,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,UAAU,CAAC,EAAE,MAAM,YAAA,EACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAKpC;AAED,qBAAa,aAAc,SAAQ,YAAY;gBAE3C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAKpC;AAED,qBAAa,kBAAmB,SAAQ,YAAY;aAGhC,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClC,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAKpC"}
package/dist/errors.js ADDED
@@ -0,0 +1,26 @@
1
+ import { KsefApiError as SharedKsefApiError } from '@ksefnik/shared';
2
+ export class KsefApiError extends SharedKsefApiError {
3
+ requestId;
4
+ detailCode;
5
+ constructor(message, statusCode, requestId, detailCode, context) {
6
+ super(message, statusCode, context);
7
+ this.requestId = requestId;
8
+ this.detailCode = detailCode;
9
+ this.name = 'KsefApiError';
10
+ }
11
+ }
12
+ export class KsefAuthError extends KsefApiError {
13
+ constructor(message, statusCode, requestId, detailCode, context) {
14
+ super(message, statusCode, requestId, detailCode, context);
15
+ this.name = 'KsefAuthError';
16
+ }
17
+ }
18
+ export class KsefRateLimitError extends KsefApiError {
19
+ retryAfter;
20
+ constructor(message, retryAfter, requestId, context) {
21
+ super(message, 429, requestId, 'RATE_LIMIT', context);
22
+ this.retryAfter = retryAfter;
23
+ this.name = 'KsefRateLimitError';
24
+ }
25
+ }
26
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpE,MAAM,OAAO,YAAa,SAAQ,kBAAkB;IAIhC;IACA;IAJlB,YACE,OAAe,EACf,UAAmB,EACH,SAAkB,EAClB,UAAmB,EACnC,OAAiC;QAEjC,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;QAJnB,cAAS,GAAT,SAAS,CAAS;QAClB,eAAU,GAAV,UAAU,CAAS;QAInC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,YACE,OAAe,EACf,UAAkB,EAClB,SAAkB,EAClB,UAAmB,EACnB,OAAiC;QAEjC,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;QAC1D,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAGhC;IAFlB,YACE,OAAe,EACC,UAAkB,EAClC,SAAkB,EAClB,OAAiC;QAEjC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAA;QAJrC,eAAU,GAAV,UAAU,CAAQ;QAKlC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Re-exports from the openapi-typescript generated file. Consumers should
3
+ * import named type aliases from here rather than reaching into the raw
4
+ * `components["schemas"][...]` tree.
5
+ *
6
+ * Regenerate with: `pnpm --filter @ksefnik/http generate`
7
+ * Source of truth: https://api.ksef.mf.gov.pl/docs/v2/openapi.json
8
+ */
9
+ import type { components } from './ksef-api.js';
10
+ type Schemas = components['schemas'];
11
+ export type KsefAuthenticationChallengeResponse = Schemas['AuthenticationChallengeResponse'];
12
+ export type KsefInitTokenAuthenticationRequest = Schemas['InitTokenAuthenticationRequest'];
13
+ export type KsefAuthenticationInitResponse = Schemas['AuthenticationInitResponse'];
14
+ export type KsefAuthenticationOperationStatusResponse = Schemas['AuthenticationOperationStatusResponse'];
15
+ export type KsefAuthenticationTokensResponse = Schemas['AuthenticationTokensResponse'];
16
+ export type KsefAuthenticationTokenRefreshResponse = Schemas['AuthenticationTokenRefreshResponse'];
17
+ export type KsefTokenInfo = Schemas['TokenInfo'];
18
+ export type KsefAuthenticationContextIdentifier = Schemas['AuthenticationContextIdentifier'];
19
+ export type KsefAuthenticationContextIdentifierType = Schemas['AuthenticationContextIdentifierType'];
20
+ export type KsefPublicKeyCertificate = Schemas['PublicKeyCertificate'];
21
+ export type KsefPublicKeyCertificateUsage = Schemas['PublicKeyCertificateUsage'];
22
+ export type KsefInvoiceQueryFilters = Schemas['InvoiceQueryFilters'];
23
+ export type KsefInvoiceQuerySubjectType = Schemas['InvoiceQuerySubjectType'];
24
+ export type KsefInvoiceQueryDateType = Schemas['InvoiceQueryDateType'];
25
+ export type KsefQueryInvoicesMetadataResponse = Schemas['QueryInvoicesMetadataResponse'];
26
+ export type KsefInvoiceMetadata = Schemas['InvoiceMetadata'];
27
+ export type KsefInvoiceMetadataBuyer = Schemas['InvoiceMetadataBuyer'];
28
+ export type KsefInvoiceMetadataSeller = Schemas['InvoiceMetadataSeller'];
29
+ export type { components, paths, operations } from './ksef-api.js';
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE/C,KAAK,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;AAGpC,MAAM,MAAM,mCAAmC,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAA;AAC5F,MAAM,MAAM,kCAAkC,GAAG,OAAO,CAAC,gCAAgC,CAAC,CAAA;AAC1F,MAAM,MAAM,8BAA8B,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAA;AAClF,MAAM,MAAM,yCAAyC,GAAG,OAAO,CAAC,uCAAuC,CAAC,CAAA;AACxG,MAAM,MAAM,gCAAgC,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAA;AACtF,MAAM,MAAM,sCAAsC,GAAG,OAAO,CAAC,oCAAoC,CAAC,CAAA;AAClG,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AAChD,MAAM,MAAM,mCAAmC,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAA;AAC5F,MAAM,MAAM,uCAAuC,GAAG,OAAO,CAAC,qCAAqC,CAAC,CAAA;AAGpG,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;AACtE,MAAM,MAAM,6BAA6B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAA;AAGhF,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;AACpE,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAA;AAC5E,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;AACtE,MAAM,MAAM,iCAAiC,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAA;AACxF,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAC5D,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;AACtE,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;AAGxE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":""}