@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.
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/adapter.d.ts +16 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +19 -0
- package/dist/adapter.js.map +1 -0
- package/dist/client.d.ts +48 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +107 -0
- package/dist/client.js.map +1 -0
- package/dist/crypto.d.ts +22 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +30 -0
- package/dist/crypto.js.map +1 -0
- package/dist/endpoints.d.ts +20 -0
- package/dist/endpoints.d.ts.map +1 -0
- package/dist/endpoints.js +26 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/index.d.ts +30 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/index.js +2 -0
- package/dist/generated/index.js.map +1 -0
- package/dist/generated/ksef-api.d.ts +10424 -0
- package/dist/generated/ksef-api.d.ts.map +1 -0
- package/dist/generated/ksef-api.js +6 -0
- package/dist/generated/ksef-api.js.map +1 -0
- package/dist/http.d.ts +24 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +120 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/invoices.d.ts +32 -0
- package/dist/invoices.d.ts.map +1 -0
- package/dist/invoices.js +130 -0
- package/dist/invoices.js.map +1 -0
- package/dist/public-key.d.ts +6 -0
- package/dist/public-key.d.ts.map +1 -0
- package/dist/public-key.js +37 -0
- package/dist/public-key.js.map +1 -0
- package/dist/retry.d.ts +19 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +59 -0
- package/dist/retry.js.map +1 -0
- package/dist/session.d.ts +29 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +109 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/xml.d.ts +12 -0
- package/dist/xml.d.ts.map +1 -0
- package/dist/xml.js +65 -0
- package/dist/xml.js.map +1 -0
- package/package.json +47 -0
package/dist/invoices.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { PATHS } from './endpoints.js';
|
|
2
|
+
import { KsefApiError } from './errors.js';
|
|
3
|
+
import { parseInvoiceXml } from './xml.js';
|
|
4
|
+
function toIsoDate(date) {
|
|
5
|
+
if (date.includes('T'))
|
|
6
|
+
return date;
|
|
7
|
+
return new Date(`${date}T00:00:00.000Z`).toISOString();
|
|
8
|
+
}
|
|
9
|
+
function toIsoDateEnd(date) {
|
|
10
|
+
if (date.includes('T'))
|
|
11
|
+
return date;
|
|
12
|
+
return new Date(`${date}T23:59:59.999Z`).toISOString();
|
|
13
|
+
}
|
|
14
|
+
function toGroszeInt(amount) {
|
|
15
|
+
if (amount === undefined || amount === null)
|
|
16
|
+
return undefined;
|
|
17
|
+
if (!Number.isFinite(amount))
|
|
18
|
+
return undefined;
|
|
19
|
+
return Math.round(amount * 100);
|
|
20
|
+
}
|
|
21
|
+
export async function mapWithConcurrency(items, concurrency, mapper) {
|
|
22
|
+
const results = new Array(items.length);
|
|
23
|
+
let cursor = 0;
|
|
24
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) || 1 }, async () => {
|
|
25
|
+
while (cursor < items.length) {
|
|
26
|
+
const index = cursor++;
|
|
27
|
+
const item = items[index];
|
|
28
|
+
results[index] = await mapper(item, index);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
await Promise.all(workers);
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
export async function queryInvoiceMetadataPage(http, accessToken, body, pageSize, pageOffset) {
|
|
35
|
+
return http.request({
|
|
36
|
+
method: 'POST',
|
|
37
|
+
path: PATHS.queryMetadata,
|
|
38
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
39
|
+
query: { pageSize, pageOffset },
|
|
40
|
+
body,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export async function fetchInvoiceXml(http, accessToken, ksefNumber) {
|
|
44
|
+
return http.request({
|
|
45
|
+
method: 'GET',
|
|
46
|
+
path: PATHS.invoiceByKsefNumber(ksefNumber),
|
|
47
|
+
headers: {
|
|
48
|
+
Authorization: `Bearer ${accessToken}`,
|
|
49
|
+
Accept: 'application/xml',
|
|
50
|
+
},
|
|
51
|
+
responseType: 'text',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function nullish(value) {
|
|
55
|
+
return value ?? undefined;
|
|
56
|
+
}
|
|
57
|
+
function mapMetadataToRaw(meta) {
|
|
58
|
+
const invoicingDate = nullish(meta.invoicingDate);
|
|
59
|
+
const issueDate = nullish(meta.issueDate);
|
|
60
|
+
const permanentStorageDate = nullish(meta.permanentStorageDate);
|
|
61
|
+
const dateValue = invoicingDate?.slice(0, 10) ?? issueDate ?? permanentStorageDate ?? '';
|
|
62
|
+
return {
|
|
63
|
+
ksefReferenceNumber: meta.ksefNumber,
|
|
64
|
+
invoiceNumber: meta.invoiceNumber,
|
|
65
|
+
subjectNip: nullish(meta.seller?.nip) ?? '',
|
|
66
|
+
subjectName: nullish(meta.seller?.name),
|
|
67
|
+
invoicingDate: dateValue,
|
|
68
|
+
xml: '',
|
|
69
|
+
grossAmountGrosze: toGroszeInt(meta.grossAmount ?? undefined),
|
|
70
|
+
currency: nullish(meta.currency) ?? 'PLN',
|
|
71
|
+
buyerNip: nullish(meta.buyer?.identifier?.value),
|
|
72
|
+
buyerName: nullish(meta.buyer?.name),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function fetchInvoices(http, params) {
|
|
76
|
+
const pageSize = params.pageSize ?? 100;
|
|
77
|
+
const pageOffset = params.pageOffset ?? 0;
|
|
78
|
+
const concurrency = params.concurrency ?? 5;
|
|
79
|
+
const body = {
|
|
80
|
+
subjectType: params.subjectType ?? 'Subject2',
|
|
81
|
+
dateRange: {
|
|
82
|
+
dateType: params.dateType ?? 'Invoicing',
|
|
83
|
+
from: toIsoDate(params.dateFrom),
|
|
84
|
+
to: toIsoDateEnd(params.dateTo),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
const all = [];
|
|
88
|
+
let currentOffset = pageOffset;
|
|
89
|
+
// Termination rules per KSeF 2.0 spec (/invoices/query/metadata description):
|
|
90
|
+
// - hasMore === false → done
|
|
91
|
+
// - hasMore === true, isTruncated=false → increment pageOffset
|
|
92
|
+
// - hasMore === true, isTruncated=true → hit the 10k technical limit;
|
|
93
|
+
// caller must narrow the dateRange and reset pageOffset. We surface
|
|
94
|
+
// this as a typed error so reconciliation callers can handle it.
|
|
95
|
+
const MAX_PAGES = 10_000;
|
|
96
|
+
for (let page = 0; page < MAX_PAGES; page++) {
|
|
97
|
+
const response = await queryInvoiceMetadataPage(http, params.accessToken, body, pageSize, currentOffset);
|
|
98
|
+
const items = response.invoices ?? [];
|
|
99
|
+
all.push(...items);
|
|
100
|
+
if (response.hasMore !== true)
|
|
101
|
+
break;
|
|
102
|
+
if (items.length === 0)
|
|
103
|
+
break;
|
|
104
|
+
if (response.isTruncated === true) {
|
|
105
|
+
throw new KsefApiError('KSeF metadata query hit the 10000-record technical limit (isTruncated=true). ' +
|
|
106
|
+
'Narrow the dateRange to a shorter window and re-issue the query.', undefined, undefined, 'QUERY_TRUNCATED', { collected: all.length, lastDate: items.at(-1)?.invoicingDate ?? undefined });
|
|
107
|
+
}
|
|
108
|
+
currentOffset += pageSize;
|
|
109
|
+
}
|
|
110
|
+
const mapped = all.map(mapMetadataToRaw);
|
|
111
|
+
if (params.includeXml === true && mapped.length > 0) {
|
|
112
|
+
const enriched = await mapWithConcurrency(mapped, concurrency, async (raw) => {
|
|
113
|
+
try {
|
|
114
|
+
const xml = await fetchInvoiceXml(http, params.accessToken, raw.ksefReferenceNumber);
|
|
115
|
+
const parsed = parseInvoiceXml(xml);
|
|
116
|
+
return {
|
|
117
|
+
...raw,
|
|
118
|
+
xml,
|
|
119
|
+
grossAmountGrosze: raw.grossAmountGrosze ?? parsed.grossAmountGrosze,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return raw;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return { invoices: enriched, total: enriched.length };
|
|
127
|
+
}
|
|
128
|
+
return { invoices: mapped, total: mapped.length };
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=invoices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoices.js","sourceRoot":"","sources":["../src/invoices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAkC1C,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACnC,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAA;AACxD,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACnC,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAA;AACxD,CAAC;AAED,SAAS,WAAW,CAAC,MAAiC;IACpD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAA;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAmB,EACnB,WAAmB,EACnB,MAA8C;IAE9C,MAAM,OAAO,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE;QAC1F,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAA;YACtB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAM,CAAA;YAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC,CAAC,CAAA;IACF,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1B,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,IAAgB,EAChB,WAAmB,EACnB,IAAsB,EACtB,QAAgB,EAChB,UAAkB;IAElB,OAAO,IAAI,CAAC,OAAO,CAA+B;QAChD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK,CAAC,aAAa;QACzB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE;QACnD,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE;QAC/B,IAAI;KACL,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAgB,EAChB,WAAmB,EACnB,UAAkB;IAElB,OAAO,IAAI,CAAC,OAAO,CAAS;QAC1B,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK,CAAC,mBAAmB,CAAC,UAAU,CAAC;QAC3C,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,WAAW,EAAE;YACtC,MAAM,EAAE,iBAAiB;SAC1B;QACD,YAAY,EAAE,MAAM;KACrB,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,OAAO,CAAI,KAA2B;IAC7C,OAAO,KAAK,IAAI,SAAS,CAAA;AAC3B,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAyB;IACjD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACzC,MAAM,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IAC/D,MAAM,SAAS,GACb,aAAa,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,SAAS,IAAI,oBAAoB,IAAI,EAAE,CAAA;IACxE,OAAO;QACL,mBAAmB,EAAE,IAAI,CAAC,UAAU;QACpC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE;QAC3C,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;QACvC,aAAa,EAAE,SAAS;QACxB,GAAG,EAAE,EAAE;QACP,iBAAiB,EAAE,WAAW,CAAC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;QAC7D,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK;QACzC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC;QAChD,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;KACrC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAgB,EAChB,MAA+B;IAE/B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAA;IACvC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,CAAA;IACzC,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAA;IAE3C,MAAM,IAAI,GAAqB;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,UAAU;QAC7C,SAAS,EAAE;YACT,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,WAAW;YACxC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;YAChC,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;SAChC;KACF,CAAA;IAED,MAAM,GAAG,GAA0B,EAAE,CAAA;IACrC,IAAI,aAAa,GAAG,UAAU,CAAA;IAE9B,8EAA8E;IAC9E,4CAA4C;IAC5C,gEAAgE;IAChE,wEAAwE;IACxE,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,SAAS,GAAG,MAAM,CAAA;IACxB,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC7C,IAAI,EACJ,MAAM,CAAC,WAAW,EAClB,IAAI,EACJ,QAAQ,EACR,aAAa,CACd,CAAA;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAA;QACrC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;QAClB,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI;YAAE,MAAK;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAK;QAC7B,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,YAAY,CACpB,+EAA+E;gBAC7E,kEAAkE,EACpE,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,IAAI,SAAS,EAAE,CAC9E,CAAA;QACH,CAAC;QACD,aAAa,IAAI,QAAQ,CAAA;IAC3B,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAExC,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC3E,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAA;gBACpF,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;gBACnC,OAAO;oBACL,GAAG,GAAG;oBACN,GAAG;oBACH,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,IAAI,MAAM,CAAC,iBAAiB;iBACrE,CAAA;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,CAAA;YACZ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAA;IACvD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;AACnD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HttpClient } from './http.js';
|
|
2
|
+
import type { KsefPublicKeyCertificate } from './generated/index.js';
|
|
3
|
+
export type PublicKeyCertificate = KsefPublicKeyCertificate;
|
|
4
|
+
export declare function fetchPublicKeyCertificates(http: HttpClient): Promise<PublicKeyCertificate[]>;
|
|
5
|
+
export declare function fetchKsefTokenEncryptionKey(http: HttpClient): Promise<string>;
|
|
6
|
+
//# sourceMappingURL=public-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-key.d.ts","sourceRoot":"","sources":["../src/public-key.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAEpE,MAAM,MAAM,oBAAoB,GAAG,wBAAwB,CAAA;AAe3D,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,oBAAoB,EAAE,CAAC,CASjC;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BnF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PATHS } from './endpoints.js';
|
|
2
|
+
import { KsefApiError } from './errors.js';
|
|
3
|
+
function base64ToCertPem(base64) {
|
|
4
|
+
const normalized = base64.replace(/\s+/g, '');
|
|
5
|
+
const chunks = normalized.match(/.{1,64}/g) ?? [normalized];
|
|
6
|
+
return `-----BEGIN CERTIFICATE-----\n${chunks.join('\n')}\n-----END CERTIFICATE-----\n`;
|
|
7
|
+
}
|
|
8
|
+
function isActive(cert, now = new Date()) {
|
|
9
|
+
const from = new Date(cert.validFrom);
|
|
10
|
+
const to = new Date(cert.validTo);
|
|
11
|
+
if (Number.isNaN(from.getTime()) || Number.isNaN(to.getTime()))
|
|
12
|
+
return false;
|
|
13
|
+
return from <= now && now <= to;
|
|
14
|
+
}
|
|
15
|
+
export async function fetchPublicKeyCertificates(http) {
|
|
16
|
+
const response = await http.request({
|
|
17
|
+
method: 'GET',
|
|
18
|
+
path: PATHS.publicKeyCertificates,
|
|
19
|
+
});
|
|
20
|
+
if (Array.isArray(response))
|
|
21
|
+
return response;
|
|
22
|
+
return response.items ?? [];
|
|
23
|
+
}
|
|
24
|
+
export async function fetchKsefTokenEncryptionKey(http) {
|
|
25
|
+
const certs = await fetchPublicKeyCertificates(http);
|
|
26
|
+
if (certs.length === 0) {
|
|
27
|
+
throw new KsefApiError('KSeF public-key-certificates endpoint returned no certificates', undefined, undefined, 'NO_PUBLIC_KEY');
|
|
28
|
+
}
|
|
29
|
+
const now = new Date();
|
|
30
|
+
const candidate = certs.find((c) => c.usage.includes('KsefTokenEncryption') && isActive(c, now)) ??
|
|
31
|
+
certs.find((c) => c.usage.includes('KsefTokenEncryption'));
|
|
32
|
+
if (!candidate) {
|
|
33
|
+
throw new KsefApiError('No KsefTokenEncryption certificate available from KSeF public-key-certificates endpoint', undefined, undefined, 'NO_TOKEN_ENCRYPTION_KEY');
|
|
34
|
+
}
|
|
35
|
+
return base64ToCertPem(candidate.certificate);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=public-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-key.js","sourceRoot":"","sources":["../src/public-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM1C,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC3D,OAAO,gCAAgC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAA;AACzF,CAAC;AAED,SAAS,QAAQ,CAAC,IAA0B,EAAE,MAAY,IAAI,IAAI,EAAE;IAClE,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACrC,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAA;IAC5E,OAAO,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAA;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,IAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK,CAAC,qBAAqB;KAClC,CACF,CAAA;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC5C,OAAO,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAA;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,IAAgB;IAChE,MAAM,KAAK,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,CAAA;IACpD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,YAAY,CACpB,gEAAgE,EAChE,SAAS,EACT,SAAS,EACT,eAAe,CAChB,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,MAAM,SAAS,GACb,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9E,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAA;IAE5D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,YAAY,CACpB,yFAAyF,EACzF,SAAS,EACT,SAAS,EACT,yBAAyB,CAC1B,CAAA;IACH,CAAC;IAED,OAAO,eAAe,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;AAC/C,CAAC"}
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface HttpRetryOptions {
|
|
2
|
+
maxAttempts?: number;
|
|
3
|
+
baseDelayMs?: number;
|
|
4
|
+
maxDelayMs?: number;
|
|
5
|
+
maxRetryAfterMs?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Retry wrapper that honours `Retry-After` on rate-limit errors.
|
|
9
|
+
*
|
|
10
|
+
* - `KsefRateLimitError` (HTTP 429): waits `retryAfter * 1000` ms, clamped
|
|
11
|
+
* to `maxRetryAfterMs`. This is critical for `/invoices/query/metadata`
|
|
12
|
+
* (8 req/s, 16 req/min) where fixed exponential backoff would burst
|
|
13
|
+
* straight back into another 429.
|
|
14
|
+
* - `KsefApiError` 5xx or undefined status (network error): exponential
|
|
15
|
+
* backoff with jitter.
|
|
16
|
+
* - Anything else (4xx except 429, unknown errors): thrown immediately.
|
|
17
|
+
*/
|
|
18
|
+
export declare function withHttpRetry<T>(fn: () => Promise<T>, opts?: HttpRetryOptions): Promise<T>;
|
|
19
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAmBD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,CAAC,EAAE,gBAAgB,GACtB,OAAO,CAAC,CAAC,CAAC,CA8BZ"}
|
package/dist/retry.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { KsefApiError, KsefRateLimitError } from './errors.js';
|
|
2
|
+
const DEFAULTS = {
|
|
3
|
+
maxAttempts: 3,
|
|
4
|
+
baseDelayMs: 1000,
|
|
5
|
+
maxDelayMs: 10_000,
|
|
6
|
+
maxRetryAfterMs: 30_000,
|
|
7
|
+
};
|
|
8
|
+
function isRetryableStatus(status) {
|
|
9
|
+
if (status === undefined)
|
|
10
|
+
return true;
|
|
11
|
+
if (status === 429)
|
|
12
|
+
return true;
|
|
13
|
+
return status >= 500 && status <= 599;
|
|
14
|
+
}
|
|
15
|
+
function sleep(ms) {
|
|
16
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Retry wrapper that honours `Retry-After` on rate-limit errors.
|
|
20
|
+
*
|
|
21
|
+
* - `KsefRateLimitError` (HTTP 429): waits `retryAfter * 1000` ms, clamped
|
|
22
|
+
* to `maxRetryAfterMs`. This is critical for `/invoices/query/metadata`
|
|
23
|
+
* (8 req/s, 16 req/min) where fixed exponential backoff would burst
|
|
24
|
+
* straight back into another 429.
|
|
25
|
+
* - `KsefApiError` 5xx or undefined status (network error): exponential
|
|
26
|
+
* backoff with jitter.
|
|
27
|
+
* - Anything else (4xx except 429, unknown errors): thrown immediately.
|
|
28
|
+
*/
|
|
29
|
+
export async function withHttpRetry(fn, opts) {
|
|
30
|
+
const cfg = { ...DEFAULTS, ...opts };
|
|
31
|
+
let lastError;
|
|
32
|
+
for (let attempt = 1; attempt <= cfg.maxAttempts; attempt++) {
|
|
33
|
+
try {
|
|
34
|
+
return await fn();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
lastError = error;
|
|
38
|
+
const isLastAttempt = attempt === cfg.maxAttempts;
|
|
39
|
+
if (error instanceof KsefRateLimitError) {
|
|
40
|
+
if (isLastAttempt)
|
|
41
|
+
throw error;
|
|
42
|
+
const waitMs = Math.min(error.retryAfter * 1000, cfg.maxRetryAfterMs);
|
|
43
|
+
await sleep(Math.max(waitMs, cfg.baseDelayMs));
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (error instanceof KsefApiError) {
|
|
47
|
+
if (!isRetryableStatus(error.statusCode) || isLastAttempt)
|
|
48
|
+
throw error;
|
|
49
|
+
const expo = cfg.baseDelayMs * Math.pow(2, attempt - 1);
|
|
50
|
+
const jitter = Math.random() * cfg.baseDelayMs * 0.1;
|
|
51
|
+
await sleep(Math.min(expo + jitter, cfg.maxDelayMs));
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
throw lastError;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAS9D,MAAM,QAAQ,GAA+B;IAC3C,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,MAAM;IAClB,eAAe,EAAE,MAAM;CACxB,CAAA;AAED,SAAS,iBAAiB,CAAC,MAA0B;IACnD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACrC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IAC/B,OAAO,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAA;AACvC,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAC1D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAoB,EACpB,IAAuB;IAEvB,MAAM,GAAG,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAA;IACpC,IAAI,SAAkB,CAAA;IAEtB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,GAAG,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QAC5D,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAA;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAA;YACjB,MAAM,aAAa,GAAG,OAAO,KAAK,GAAG,CAAC,WAAW,CAAA;YAEjD,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;gBACxC,IAAI,aAAa;oBAAE,MAAM,KAAK,CAAA;gBAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,EAAE,GAAG,CAAC,eAAe,CAAC,CAAA;gBACrE,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;gBAC9C,SAAQ;YACV,CAAC;YAED,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;gBAClC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,aAAa;oBAAE,MAAM,KAAK,CAAA;gBACtE,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAA;gBACvD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,GAAG,GAAG,CAAA;gBACpD,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;gBACpD,SAAQ;YACV,CAAC;YAED,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { HttpClient } from './http.js';
|
|
2
|
+
import type { KsefAuthenticationChallengeResponse, KsefAuthenticationInitResponse, KsefAuthenticationOperationStatusResponse, KsefAuthenticationTokenRefreshResponse, KsefAuthenticationTokensResponse } from './generated/index.js';
|
|
3
|
+
export type ChallengeResponse = KsefAuthenticationChallengeResponse;
|
|
4
|
+
export type AuthenticationTokenResponse = KsefAuthenticationInitResponse;
|
|
5
|
+
export type AuthenticationOperationStatusResponse = KsefAuthenticationOperationStatusResponse;
|
|
6
|
+
export type RedeemedTokens = KsefAuthenticationTokensResponse;
|
|
7
|
+
export type RefreshTokenResponse = KsefAuthenticationTokenRefreshResponse;
|
|
8
|
+
export interface ActiveSession {
|
|
9
|
+
accessToken: string;
|
|
10
|
+
refreshToken: string;
|
|
11
|
+
accessExpiresAt: Date;
|
|
12
|
+
referenceNumber: string;
|
|
13
|
+
}
|
|
14
|
+
export interface InitSessionInput {
|
|
15
|
+
nip: string;
|
|
16
|
+
ksefToken: string;
|
|
17
|
+
publicKeyPem: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function initKsefSession(http: HttpClient, input: InitSessionInput): Promise<ActiveSession>;
|
|
20
|
+
export declare function refreshAccessToken(http: HttpClient, session: ActiveSession): Promise<ActiveSession>;
|
|
21
|
+
export declare function shouldRefresh(session: ActiveSession, now?: Date, bufferMs?: number): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Best-effort session revocation. Swallows all errors — revocation failures
|
|
24
|
+
* are never user-actionable and must not mask the real result of the
|
|
25
|
+
* preceding operation (e.g. a successful `fetchInvoices()` should not be
|
|
26
|
+
* turned into a failure because teardown hit a 429 or network blip).
|
|
27
|
+
*/
|
|
28
|
+
export declare function revokeCurrentSession(http: HttpClient, session: ActiveSession): Promise<void>;
|
|
29
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EACV,mCAAmC,EACnC,8BAA8B,EAC9B,yCAAyC,EACzC,sCAAsC,EACtC,gCAAgC,EAEjC,MAAM,sBAAsB,CAAA;AAI7B,MAAM,MAAM,iBAAiB,GAAG,mCAAmC,CAAA;AACnE,MAAM,MAAM,2BAA2B,GAAG,8BAA8B,CAAA;AACxE,MAAM,MAAM,qCAAqC,GAAG,yCAAyC,CAAA;AAC7F,MAAM,MAAM,cAAc,GAAG,gCAAgC,CAAA;AAC7D,MAAM,MAAM,oBAAoB,GAAG,sCAAsC,CAAA;AAEzE,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,IAAI,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAwDD,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,aAAa,CAAC,CAmExB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,aAAa,CAAC,CAYxB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,aAAa,EACtB,GAAG,GAAE,IAAiB,EACtB,QAAQ,GAAE,MAAkC,GAC3C,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { buildEncryptedToken } from './crypto.js';
|
|
2
|
+
import { PATHS } from './endpoints.js';
|
|
3
|
+
import { KsefApiError } from './errors.js';
|
|
4
|
+
const DEFAULT_REFRESH_BUFFER_MS = 60_000;
|
|
5
|
+
const AUTH_POLL_MAX_ATTEMPTS = 30;
|
|
6
|
+
const AUTH_POLL_DELAY_MS = 1000;
|
|
7
|
+
function sleep(ms) {
|
|
8
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9
|
+
}
|
|
10
|
+
async function waitForAuthSuccess(http, referenceNumber, authenticationToken) {
|
|
11
|
+
for (let attempt = 0; attempt < AUTH_POLL_MAX_ATTEMPTS; attempt++) {
|
|
12
|
+
const status = await http.request({
|
|
13
|
+
method: 'GET',
|
|
14
|
+
path: PATHS.authStatus(referenceNumber),
|
|
15
|
+
headers: { Authorization: `Bearer ${authenticationToken}` },
|
|
16
|
+
});
|
|
17
|
+
const code = status.status?.code;
|
|
18
|
+
if (code === 200)
|
|
19
|
+
return;
|
|
20
|
+
if (typeof code === 'number' && code >= 400) {
|
|
21
|
+
throw new KsefApiError(`Authentication failed: ${status.status.description}${status.status.details ? ` — ${status.status.details.join('; ')}` : ''}`, code, undefined, 'AUTH_FAILED');
|
|
22
|
+
}
|
|
23
|
+
await sleep(AUTH_POLL_DELAY_MS);
|
|
24
|
+
}
|
|
25
|
+
throw new KsefApiError(`Authentication polling timed out after ${AUTH_POLL_MAX_ATTEMPTS} attempts`, undefined, undefined, 'AUTH_POLL_TIMEOUT');
|
|
26
|
+
}
|
|
27
|
+
function parseValidUntil(validUntil) {
|
|
28
|
+
const d = new Date(validUntil);
|
|
29
|
+
if (Number.isNaN(d.getTime())) {
|
|
30
|
+
throw new KsefApiError(`Invalid validUntil timestamp: ${validUntil}`, undefined, undefined, 'INVALID_TOKEN_EXPIRY');
|
|
31
|
+
}
|
|
32
|
+
return d;
|
|
33
|
+
}
|
|
34
|
+
export async function initKsefSession(http, input) {
|
|
35
|
+
// NOTE: `/auth/challenge` takes no request body in KSeF 2.0 PR. The endpoint
|
|
36
|
+
// is unauthenticated and returns a challenge bound to the caller's IP.
|
|
37
|
+
const challenge = await http.request({
|
|
38
|
+
method: 'POST',
|
|
39
|
+
path: PATHS.authChallenge,
|
|
40
|
+
});
|
|
41
|
+
if (!challenge.challenge || typeof challenge.challenge !== 'string') {
|
|
42
|
+
throw new KsefApiError('Invalid challenge response: missing challenge field', undefined, undefined, 'INVALID_CHALLENGE');
|
|
43
|
+
}
|
|
44
|
+
if (typeof challenge.timestampMs !== 'number' ||
|
|
45
|
+
!Number.isFinite(challenge.timestampMs) ||
|
|
46
|
+
challenge.timestampMs <= 0) {
|
|
47
|
+
throw new KsefApiError(`Invalid challenge timestampMs: ${JSON.stringify(challenge.timestampMs)}`, undefined, undefined, 'INVALID_CHALLENGE_TIMESTAMP');
|
|
48
|
+
}
|
|
49
|
+
// Per KSeF 2.0 spec: RSA-OAEP(SHA-256) over `"{ksefToken}|{timestampMs}"`,
|
|
50
|
+
// where `timestampMs` is the exact integer returned by `/auth/challenge`.
|
|
51
|
+
const encryptedToken = buildEncryptedToken(input.ksefToken, String(challenge.timestampMs), input.publicKeyPem);
|
|
52
|
+
const authRequestBody = {
|
|
53
|
+
challenge: challenge.challenge,
|
|
54
|
+
contextIdentifier: { type: 'Nip', value: input.nip },
|
|
55
|
+
encryptedToken,
|
|
56
|
+
};
|
|
57
|
+
const authResponse = await http.request({
|
|
58
|
+
method: 'POST',
|
|
59
|
+
path: PATHS.authKsefToken,
|
|
60
|
+
body: authRequestBody,
|
|
61
|
+
});
|
|
62
|
+
// Poll until server-side authentication completes (OCSP/CRL verification).
|
|
63
|
+
await waitForAuthSuccess(http, authResponse.referenceNumber, authResponse.authenticationToken.token);
|
|
64
|
+
const redeemed = await http.request({
|
|
65
|
+
method: 'POST',
|
|
66
|
+
path: PATHS.authRedeem,
|
|
67
|
+
headers: { Authorization: `Bearer ${authResponse.authenticationToken.token}` },
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
accessToken: redeemed.accessToken.token,
|
|
71
|
+
refreshToken: redeemed.refreshToken.token,
|
|
72
|
+
accessExpiresAt: parseValidUntil(redeemed.accessToken.validUntil),
|
|
73
|
+
referenceNumber: authResponse.referenceNumber,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export async function refreshAccessToken(http, session) {
|
|
77
|
+
const refreshed = await http.request({
|
|
78
|
+
method: 'POST',
|
|
79
|
+
path: PATHS.authRefresh,
|
|
80
|
+
headers: { Authorization: `Bearer ${session.refreshToken}` },
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
...session,
|
|
84
|
+
accessToken: refreshed.accessToken.token,
|
|
85
|
+
accessExpiresAt: parseValidUntil(refreshed.accessToken.validUntil),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export function shouldRefresh(session, now = new Date(), bufferMs = DEFAULT_REFRESH_BUFFER_MS) {
|
|
89
|
+
return session.accessExpiresAt.getTime() - now.getTime() <= bufferMs;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Best-effort session revocation. Swallows all errors — revocation failures
|
|
93
|
+
* are never user-actionable and must not mask the real result of the
|
|
94
|
+
* preceding operation (e.g. a successful `fetchInvoices()` should not be
|
|
95
|
+
* turned into a failure because teardown hit a 429 or network blip).
|
|
96
|
+
*/
|
|
97
|
+
export async function revokeCurrentSession(http, session) {
|
|
98
|
+
try {
|
|
99
|
+
await http.request({
|
|
100
|
+
method: 'DELETE',
|
|
101
|
+
path: PATHS.sessionRevokeCurrent,
|
|
102
|
+
headers: { Authorization: `Bearer ${session.accessToken}` },
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// intentionally swallowed
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/xml.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ParsedInvoiceFields {
|
|
2
|
+
invoiceNumber: string;
|
|
3
|
+
sellerNip: string;
|
|
4
|
+
sellerName?: string;
|
|
5
|
+
buyerNip: string;
|
|
6
|
+
buyerName?: string;
|
|
7
|
+
invoicingDate: string;
|
|
8
|
+
grossAmountGrosze: number;
|
|
9
|
+
currency: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseInvoiceXml(xml: string): ParsedInvoiceFields;
|
|
12
|
+
//# sourceMappingURL=xml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAgED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CA0BhE"}
|
package/dist/xml.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { XMLParser } from 'fast-xml-parser';
|
|
2
|
+
const MAX_INVOICE_XML_BYTES = 5 * 1024 * 1024;
|
|
3
|
+
const parser = new XMLParser({
|
|
4
|
+
ignoreAttributes: true,
|
|
5
|
+
parseTagValue: false,
|
|
6
|
+
removeNSPrefix: true,
|
|
7
|
+
trimValues: true,
|
|
8
|
+
});
|
|
9
|
+
function pickFakturaRoot(doc) {
|
|
10
|
+
if (!doc || typeof doc !== 'object')
|
|
11
|
+
return undefined;
|
|
12
|
+
const keys = Object.keys(doc);
|
|
13
|
+
for (const key of keys) {
|
|
14
|
+
if (key === 'Faktura' || key.endsWith(':Faktura')) {
|
|
15
|
+
return doc[key];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function toGrosze(value) {
|
|
21
|
+
if (value === undefined || value === null)
|
|
22
|
+
return 0;
|
|
23
|
+
const raw = typeof value === 'string' ? value.replace(/\s+/g, '').replace(',', '.') : String(value);
|
|
24
|
+
const asNumber = Number(raw);
|
|
25
|
+
if (!Number.isFinite(asNumber))
|
|
26
|
+
return 0;
|
|
27
|
+
return Math.round(asNumber * 100);
|
|
28
|
+
}
|
|
29
|
+
function displayName(dane) {
|
|
30
|
+
if (!dane)
|
|
31
|
+
return undefined;
|
|
32
|
+
if (dane.Nazwa)
|
|
33
|
+
return dane.Nazwa;
|
|
34
|
+
const person = [dane.ImiePierwsze, dane.Nazwisko].filter(Boolean).join(' ').trim();
|
|
35
|
+
return person.length > 0 ? person : undefined;
|
|
36
|
+
}
|
|
37
|
+
function extractNip(dane) {
|
|
38
|
+
if (!dane || dane.NIP === undefined || dane.NIP === null)
|
|
39
|
+
return '';
|
|
40
|
+
return String(dane.NIP).replace(/\D/g, '');
|
|
41
|
+
}
|
|
42
|
+
export function parseInvoiceXml(xml) {
|
|
43
|
+
if (xml.length > MAX_INVOICE_XML_BYTES) {
|
|
44
|
+
throw new Error(`Invoice XML exceeds ${MAX_INVOICE_XML_BYTES} byte limit (${xml.length} bytes)`);
|
|
45
|
+
}
|
|
46
|
+
const parsed = parser.parse(xml);
|
|
47
|
+
const faktura = pickFakturaRoot(parsed);
|
|
48
|
+
if (!faktura) {
|
|
49
|
+
throw new Error('Invalid invoice XML: missing Faktura root element');
|
|
50
|
+
}
|
|
51
|
+
const fa = faktura.Fa ?? {};
|
|
52
|
+
const seller = faktura.Podmiot1?.DaneIdentyfikacyjne;
|
|
53
|
+
const buyer = faktura.Podmiot2?.DaneIdentyfikacyjne;
|
|
54
|
+
return {
|
|
55
|
+
invoiceNumber: fa.P_2 ?? '',
|
|
56
|
+
invoicingDate: fa.P_1 ?? '',
|
|
57
|
+
sellerNip: extractNip(seller),
|
|
58
|
+
sellerName: displayName(seller),
|
|
59
|
+
buyerNip: extractNip(buyer),
|
|
60
|
+
buyerName: displayName(buyer),
|
|
61
|
+
grossAmountGrosze: toGrosze(fa.P_15),
|
|
62
|
+
currency: fa.KodWaluty ?? 'PLN',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=xml.js.map
|
package/dist/xml.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml.js","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,qBAAqB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAqC7C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,KAAK;IACpB,cAAc,EAAE,IAAI;IACpB,UAAU,EAAE,IAAI;CACjB,CAAC,CAAA;AAEF,SAAS,eAAe,CAAC,GAAY;IACnC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAA8B,CAAC,CAAA;IACxD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAClD,OAAQ,GAAkC,CAAC,GAAG,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAkC;IAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,CAAC,CAAA;IACnD,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACnG,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,CAAA;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAA;AACnC,CAAC;AAED,SAAS,WAAW,CAAC,IAA+B;IAClD,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3B,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,CAAA;IACjC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAClF,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AAC/C,CAAC;AAED,SAAS,UAAU,CAAC,IAA+B;IACjD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IACnE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,GAAG,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,uBAAuB,qBAAqB,gBAAgB,GAAG,CAAC,MAAM,SAAS,CAChF,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAY,CAAA;IAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IAEnD,OAAO;QACL,aAAa,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE;QAC3B,aAAa,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE;QAC3B,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC;QAC7B,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC;QAC/B,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC;QAC3B,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC;QAC7B,iBAAiB,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;QACpC,QAAQ,EAAE,EAAE,CAAC,SAAS,IAAI,KAAK;KAChC,CAAA;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ksefnik/http",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "KSeF HTTP adapter — authentication, challenge, sessions, invoice fetch (Polish e-Invoice API v2)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "CodeFormers",
|
|
7
|
+
"homepage": "https://ksefnik.pl",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/CodeFormers-it/ksefnik.git",
|
|
11
|
+
"directory": "packages/http"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["ksef", "ksefnik", "http", "adapter", "einvoice", "poland", "api"],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"files": ["dist", "!dist/**/__tests__", "!dist/**/*.test.*", "README.md", "LICENSE"],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc --build",
|
|
29
|
+
"dev": "tsc --build --watch",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"smoke": "node --env-file=../../.env scripts/smoke-test.mjs",
|
|
33
|
+
"generate": "openapi-typescript https://api.ksef.mf.gov.pl/docs/v2/openapi.json -o src/generated/ksef-api.ts --alphabetize --export-type"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@ksefnik/shared": "workspace:^",
|
|
37
|
+
"@ksefnik/core": "workspace:^",
|
|
38
|
+
"fast-xml-parser": "^4.5.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^22",
|
|
42
|
+
"typescript": "^5.7",
|
|
43
|
+
"vitest": "^3.2",
|
|
44
|
+
"msw": "^2.7.0",
|
|
45
|
+
"openapi-typescript": "^7.4.4"
|
|
46
|
+
}
|
|
47
|
+
}
|