ksef-client-ts 0.3.0 → 0.4.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/dist/index.cjs CHANGED
@@ -1108,6 +1108,36 @@ var init_batch_session = __esm({
1108
1108
  });
1109
1109
  await Promise.all(tasks);
1110
1110
  }
1111
+ /**
1112
+ * Upload parts sequentially (not in parallel) because each part uses a
1113
+ * streaming body (`duplex: 'half'`). Parallel streaming uploads can cause
1114
+ * backpressure issues and exceed memory limits for large payloads.
1115
+ */
1116
+ async sendPartsWithStream(openResponse, parts) {
1117
+ const uploadRequests = openResponse.partUploadRequests;
1118
+ for (const part of parts) {
1119
+ const uploadReq = uploadRequests.find(
1120
+ (r) => r.ordinalNumber === part.ordinalNumber
1121
+ );
1122
+ if (!uploadReq) {
1123
+ throw new Error(`No upload request found for part ${part.ordinalNumber}`);
1124
+ }
1125
+ const headers = {};
1126
+ for (const [k, v] of Object.entries(uploadReq.headers)) {
1127
+ if (v != null) headers[k] = v;
1128
+ }
1129
+ const resp = await fetch(uploadReq.url, {
1130
+ method: uploadReq.method,
1131
+ headers,
1132
+ body: part.dataStream,
1133
+ // @ts-expect-error -- Node 18+ undici supports duplex for streaming body
1134
+ duplex: "half"
1135
+ });
1136
+ if (!resp.ok) {
1137
+ throw new Error(`Upload failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
1138
+ }
1139
+ }
1140
+ }
1111
1141
  async closeSession(batchRef) {
1112
1142
  const req = RestRequest.post(Routes.Sessions.Batch.close(batchRef));
1113
1143
  await this.restClient.executeVoid(req);
@@ -1805,6 +1835,28 @@ var init_cryptography_service = __esm({
1805
1835
  const cipher = crypto2.createCipheriv("aes-256-cbc", key, iv);
1806
1836
  return new Uint8Array(Buffer.concat([cipher.update(content), cipher.final()]));
1807
1837
  }
1838
+ /**
1839
+ * Encrypt with AES-256-CBC as a streaming transform.
1840
+ * Returns a ReadableStream that yields encrypted chunks as the input is read.
1841
+ */
1842
+ encryptAES256Stream(input, key, iv) {
1843
+ const cipher = crypto2.createCipheriv("aes-256-cbc", key, iv);
1844
+ const transform = new TransformStream({
1845
+ transform(chunk, controller) {
1846
+ const encrypted = cipher.update(chunk);
1847
+ if (encrypted.length > 0) {
1848
+ controller.enqueue(new Uint8Array(encrypted));
1849
+ }
1850
+ },
1851
+ flush(controller) {
1852
+ const final = cipher.final();
1853
+ if (final.length > 0) {
1854
+ controller.enqueue(new Uint8Array(final));
1855
+ }
1856
+ }
1857
+ });
1858
+ return input.pipeThrough(transform);
1859
+ }
1808
1860
  /** Decrypt with AES-256-CBC. */
1809
1861
  decryptAES256(content, key, iv) {
1810
1862
  const decipher = crypto2.createDecipheriv("aes-256-cbc", key, iv);
@@ -1877,6 +1929,23 @@ var init_cryptography_service = __esm({
1877
1929
  const hash = crypto2.createHash("sha256").update(file).digest("base64");
1878
1930
  return { hashSHA: hash, fileSize: file.length };
1879
1931
  }
1932
+ /** Compute SHA-256 hash (base64) and byte length from a ReadableStream. */
1933
+ async getFileMetadataFromStream(stream) {
1934
+ const hash = crypto2.createHash("sha256");
1935
+ let fileSize = 0;
1936
+ const reader = stream.getReader();
1937
+ try {
1938
+ for (; ; ) {
1939
+ const { done, value } = await reader.read();
1940
+ if (done) break;
1941
+ hash.update(value);
1942
+ fileSize += value.byteLength;
1943
+ }
1944
+ } finally {
1945
+ reader.releaseLock();
1946
+ }
1947
+ return { hashSHA: hash.digest("base64"), fileSize };
1948
+ }
1880
1949
  // ---------------------------------------------------------------------------
1881
1950
  // CSR generation
1882
1951
  // ---------------------------------------------------------------------------
@@ -6791,6 +6860,32 @@ var init_pkcs12_loader = __esm({
6791
6860
  }
6792
6861
  });
6793
6862
 
6863
+ // src/crypto/auth-xml-builder.ts
6864
+ function buildUnsignedAuthTokenRequestXml(options) {
6865
+ const { challenge, contextIdentifier, subjectIdentifierType = "certificateSubject" } = options;
6866
+ const identifierElement = `<${contextIdentifier.type}>${xmlEscape(contextIdentifier.value)}</${contextIdentifier.type}>`;
6867
+ return [
6868
+ '<?xml version="1.0" encoding="utf-8"?>',
6869
+ `<AuthTokenRequest xmlns="${AUTH_TOKEN_REQUEST_NS}">`,
6870
+ `<Challenge>${xmlEscape(challenge)}</Challenge>`,
6871
+ `<ContextIdentifier>`,
6872
+ identifierElement,
6873
+ `</ContextIdentifier>`,
6874
+ `<SubjectIdentifierType>${xmlEscape(subjectIdentifierType)}</SubjectIdentifierType>`,
6875
+ `</AuthTokenRequest>`
6876
+ ].join("");
6877
+ }
6878
+ function xmlEscape(str) {
6879
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
6880
+ }
6881
+ var AUTH_TOKEN_REQUEST_NS;
6882
+ var init_auth_xml_builder = __esm({
6883
+ "src/crypto/auth-xml-builder.ts"() {
6884
+ "use strict";
6885
+ AUTH_TOKEN_REQUEST_NS = "http://ksef.mf.gov.pl/auth/token/2.0";
6886
+ }
6887
+ });
6888
+
6794
6889
  // src/qr/verification-link-service.ts
6795
6890
  var import_node_crypto, VerificationLinkService;
6796
6891
  var init_verification_link_service = __esm({
@@ -6855,19 +6950,11 @@ __export(client_exports, {
6855
6950
  buildAuthTokenRequestXml: () => buildAuthTokenRequestXml
6856
6951
  });
6857
6952
  function buildAuthTokenRequestXml(challenge, nip, subjectIdentifierType = "certificateSubject") {
6858
- return [
6859
- '<?xml version="1.0" encoding="utf-8"?>',
6860
- `<AuthTokenRequest xmlns="${AUTH_TOKEN_REQUEST_NS}">`,
6861
- `<Challenge>${xmlEscape(challenge)}</Challenge>`,
6862
- `<ContextIdentifier>`,
6863
- `<Nip>${xmlEscape(nip)}</Nip>`,
6864
- `</ContextIdentifier>`,
6865
- `<SubjectIdentifierType>${xmlEscape(subjectIdentifierType)}</SubjectIdentifierType>`,
6866
- `</AuthTokenRequest>`
6867
- ].join("");
6868
- }
6869
- function xmlEscape(str) {
6870
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
6953
+ return buildUnsignedAuthTokenRequestXml({
6954
+ challenge,
6955
+ contextIdentifier: { type: "Nip", value: nip },
6956
+ subjectIdentifierType
6957
+ });
6871
6958
  }
6872
6959
  function buildRestClientConfig(options, authManager) {
6873
6960
  const config = { authManager };
@@ -6894,7 +6981,7 @@ function buildRestClientConfig(options, authManager) {
6894
6981
  }
6895
6982
  return config;
6896
6983
  }
6897
- var KSeFClient, AUTH_TOKEN_REQUEST_NS;
6984
+ var KSeFClient;
6898
6985
  var init_client = __esm({
6899
6986
  "src/client.ts"() {
6900
6987
  "use strict";
@@ -6920,6 +7007,7 @@ var init_client = __esm({
6920
7007
  init_certificate_fetcher();
6921
7008
  init_cryptography_service();
6922
7009
  init_verification_link_service();
7010
+ init_auth_xml_builder();
6923
7011
  KSeFClient = class {
6924
7012
  auth;
6925
7013
  activeSessions;
@@ -7013,7 +7101,6 @@ var init_client = __esm({
7013
7101
  this.authManager.setRefreshToken(void 0);
7014
7102
  }
7015
7103
  };
7016
- AUTH_TOKEN_REQUEST_NS = "http://ksef.mf.gov.pl/auth/token/2.0";
7017
7104
  }
7018
7105
  });
7019
7106
 
@@ -7043,6 +7130,11 @@ __export(index_exports, {
7043
7130
  ENFORCE_XADES_COMPLIANCE: () => ENFORCE_XADES_COMPLIANCE,
7044
7131
  EntityPermissionGrantBuilder: () => EntityPermissionGrantBuilder,
7045
7132
  Environment: () => Environment,
7133
+ FORM_CODES: () => FORM_CODES,
7134
+ FORM_CODE_KEYS: () => FORM_CODE_KEYS,
7135
+ FileHwmStore: () => FileHwmStore,
7136
+ INVOICE_TYPES_BY_SYSTEM_CODE: () => INVOICE_TYPES_BY_SYSTEM_CODE,
7137
+ InMemoryHwmStore: () => InMemoryHwmStore,
7046
7138
  InternalId: () => InternalId,
7047
7139
  InvoiceDownloadService: () => InvoiceDownloadService,
7048
7140
  InvoiceQueryFilterBuilder: () => InvoiceQueryFilterBuilder,
@@ -7088,21 +7180,29 @@ __export(index_exports, {
7088
7180
  SessionStatusService: () => SessionStatusService,
7089
7181
  Sha256Base64: () => Sha256Base64,
7090
7182
  SignatureService: () => SignatureService,
7183
+ SystemCode: () => SystemCode,
7091
7184
  TestDataService: () => TestDataService,
7092
7185
  TokenService: () => TokenService,
7093
7186
  UpoVersion: () => UpoVersion,
7094
7187
  VatUe: () => VatUe,
7095
7188
  VerificationLinkService: () => VerificationLinkService,
7096
7189
  authenticateWithCertificate: () => authenticateWithCertificate,
7190
+ authenticateWithExternalSignature: () => authenticateWithExternalSignature,
7097
7191
  authenticateWithPkcs12: () => authenticateWithPkcs12,
7098
7192
  authenticateWithToken: () => authenticateWithToken,
7193
+ buildUnsignedAuthTokenRequestXml: () => buildUnsignedAuthTokenRequestXml,
7099
7194
  calculateBackoff: () => calculateBackoff,
7195
+ createZip: () => createZip,
7196
+ deduplicateByKsefNumber: () => deduplicateByKsefNumber,
7100
7197
  defaultPresignedUrlPolicy: () => defaultPresignedUrlPolicy,
7101
7198
  defaultRateLimitPolicy: () => defaultRateLimitPolicy,
7102
7199
  defaultRetryPolicy: () => defaultRetryPolicy,
7103
7200
  defaultTransport: () => defaultTransport,
7104
7201
  exportAndDownload: () => exportAndDownload,
7105
7202
  exportInvoices: () => exportInvoices,
7203
+ getEffectiveStartDate: () => getEffectiveStartDate,
7204
+ getFormCode: () => getFormCode,
7205
+ incrementalExportAndDownload: () => incrementalExportAndDownload,
7106
7206
  isRetryableError: () => isRetryableError,
7107
7207
  isRetryableStatus: () => isRetryableStatus,
7108
7208
  isValidBase64: () => isValidBase64,
@@ -7122,11 +7222,19 @@ __export(index_exports, {
7122
7222
  isValidVatUe: () => isValidVatUe,
7123
7223
  openOnlineSession: () => openOnlineSession,
7124
7224
  openSendAndClose: () => openSendAndClose,
7225
+ parseFormCode: () => parseFormCode,
7125
7226
  parseRetryAfter: () => parseRetryAfter,
7227
+ parseUpoXml: () => parseUpoXml,
7126
7228
  pollUntil: () => pollUntil,
7127
7229
  resolveOptions: () => resolveOptions,
7128
7230
  sleep: () => sleep,
7231
+ unzip: () => unzip,
7232
+ updateContinuationPoint: () => updateContinuationPoint,
7129
7233
  uploadBatch: () => uploadBatch,
7234
+ uploadBatchParsed: () => uploadBatchParsed,
7235
+ uploadBatchStream: () => uploadBatchStream,
7236
+ uploadBatchStreamParsed: () => uploadBatchStreamParsed,
7237
+ validateFormCodeForSession: () => validateFormCodeForSession,
7130
7238
  validatePresignedUrl: () => validatePresignedUrl
7131
7239
  });
7132
7240
  module.exports = __toCommonJS(index_exports);
@@ -7259,6 +7367,65 @@ var SUBUNIT_NAME_MAX_LENGTH = 256;
7259
7367
  var PERMISSION_DESCRIPTION_MIN_LENGTH = 5;
7260
7368
  var PERMISSION_DESCRIPTION_MAX_LENGTH = 256;
7261
7369
 
7370
+ // src/models/document-structures/types.ts
7371
+ var SystemCode = {
7372
+ FA_2: "FA (2)",
7373
+ FA_3: "FA (3)",
7374
+ PEF_3: "PEF (3)",
7375
+ PEF_KOR_3: "PEF_KOR (3)",
7376
+ FA_RR_1: "FA_RR (1)"
7377
+ };
7378
+ var FORM_CODES = {
7379
+ FA_2: { systemCode: "FA (2)", schemaVersion: "1-0E", value: "FA" },
7380
+ FA_3: { systemCode: "FA (3)", schemaVersion: "1-0E", value: "FA" },
7381
+ PEF_3: { systemCode: "PEF (3)", schemaVersion: "2-1", value: "PEF" },
7382
+ PEF_KOR_3: { systemCode: "PEF_KOR (3)", schemaVersion: "2-1", value: "PEF" },
7383
+ FA_RR_1_LEGACY: { systemCode: "FA_RR (1)", schemaVersion: "1-0E", value: "RR" },
7384
+ FA_RR_1_TRANSITION: { systemCode: "FA_RR (1)", schemaVersion: "1-1E", value: "RR" },
7385
+ FA_RR_1: { systemCode: "FA_RR (1)", schemaVersion: "1-1E", value: "FA_RR" }
7386
+ };
7387
+ var INVOICE_TYPES_BY_SYSTEM_CODE = {
7388
+ [SystemCode.FA_2]: ["Vat", "Zal", "Kor", "Roz", "Upr", "KorZal", "KorRoz"],
7389
+ [SystemCode.FA_3]: ["Vat", "Zal", "Kor", "Roz", "Upr", "KorZal", "KorRoz"],
7390
+ [SystemCode.PEF_3]: ["VatPef", "VatPefSp", "KorPef"],
7391
+ [SystemCode.PEF_KOR_3]: ["KorPef"],
7392
+ [SystemCode.FA_RR_1]: ["VatRr", "KorVatRr"]
7393
+ };
7394
+ var FORM_CODE_KEYS = {
7395
+ FA2: FORM_CODES.FA_2,
7396
+ FA3: FORM_CODES.FA_3,
7397
+ PEF3: FORM_CODES.PEF_3,
7398
+ PEFKOR3: FORM_CODES.PEF_KOR_3,
7399
+ FARR1: FORM_CODES.FA_RR_1
7400
+ };
7401
+
7402
+ // src/models/document-structures/helpers.ts
7403
+ var SYSTEM_CODE_TO_FORM_CODE = {
7404
+ [SystemCode.FA_2]: FORM_CODES.FA_2,
7405
+ [SystemCode.FA_3]: FORM_CODES.FA_3,
7406
+ [SystemCode.PEF_3]: FORM_CODES.PEF_3,
7407
+ [SystemCode.PEF_KOR_3]: FORM_CODES.PEF_KOR_3,
7408
+ [SystemCode.FA_RR_1]: FORM_CODES.FA_RR_1
7409
+ };
7410
+ var ALL_FORM_CODES = Object.values(FORM_CODES);
7411
+ var BATCH_DISALLOWED_SYSTEM_CODES = /* @__PURE__ */ new Set([
7412
+ SystemCode.PEF_3,
7413
+ SystemCode.PEF_KOR_3
7414
+ ]);
7415
+ function getFormCode(systemCode) {
7416
+ return SYSTEM_CODE_TO_FORM_CODE[systemCode];
7417
+ }
7418
+ function parseFormCode(raw) {
7419
+ const match = ALL_FORM_CODES.find(
7420
+ (fc) => fc.systemCode === raw.systemCode && fc.schemaVersion === raw.schemaVersion && fc.value === raw.value
7421
+ );
7422
+ return match ?? raw;
7423
+ }
7424
+ function validateFormCodeForSession(formCode, sessionType) {
7425
+ if (sessionType === "online") return true;
7426
+ return !BATCH_DISALLOWED_SYSTEM_CODES.has(formCode.systemCode);
7427
+ }
7428
+
7262
7429
  // src/services/index.ts
7263
7430
  init_auth();
7264
7431
  init_active_sessions();
@@ -7675,6 +7842,108 @@ var BatchFileBuilder = class {
7675
7842
  encryptedParts
7676
7843
  };
7677
7844
  }
7845
+ /**
7846
+ * Stream-based variant: two-pass build from a stream factory.
7847
+ *
7848
+ * Pass 1: consume stream to compute ZIP hash.
7849
+ * Pass 2: re-create stream, split into parts, encrypt each, compute per-part metadata.
7850
+ *
7851
+ * @param zipStreamFactory - Factory that creates a fresh ReadableStream of the ZIP data
7852
+ * @param zipSize - Total ZIP byte size (from fs.stat or known in advance)
7853
+ * @param encryptStreamFn - Stream-to-stream AES-256-CBC encryption function
7854
+ * @param hashStreamFn - Stream-to-FileMetadata hashing function
7855
+ * @param options - Optional configuration
7856
+ */
7857
+ static async buildFromStream(zipStreamFactory, zipSize, encryptStreamFn, hashStreamFn, options) {
7858
+ const maxPartSize = options?.maxPartSize ?? BATCH_MAX_PART_SIZE;
7859
+ if (maxPartSize <= 0) {
7860
+ throw new KSeFValidationError("maxPartSize must be a positive number");
7861
+ }
7862
+ if (zipSize === 0) {
7863
+ throw new KSeFValidationError("ZIP data must not be empty");
7864
+ }
7865
+ if (zipSize > BATCH_MAX_TOTAL_SIZE) {
7866
+ throw new KSeFValidationError(
7867
+ `ZIP size ${zipSize} exceeds maximum of ${BATCH_MAX_TOTAL_SIZE} bytes (5 GB)`
7868
+ );
7869
+ }
7870
+ const partCount = Math.ceil(zipSize / maxPartSize);
7871
+ if (partCount > BATCH_MAX_PARTS) {
7872
+ throw new KSeFValidationError(
7873
+ `Data requires ${partCount} parts, exceeding maximum of ${BATCH_MAX_PARTS}`
7874
+ );
7875
+ }
7876
+ const zipMeta = await hashStreamFn(zipStreamFactory());
7877
+ const fileParts = [];
7878
+ const streamParts = [];
7879
+ const reader = zipStreamFactory().getReader();
7880
+ let pending = [];
7881
+ let pendingSize = 0;
7882
+ for (let partIndex = 0; partIndex < partCount; partIndex++) {
7883
+ const isLastPart = partIndex === partCount - 1;
7884
+ const targetSize = isLastPart ? zipSize - partIndex * maxPartSize : maxPartSize;
7885
+ while (pendingSize < targetSize) {
7886
+ const { done, value } = await reader.read();
7887
+ if (done) break;
7888
+ pending.push(value);
7889
+ pendingSize += value.byteLength;
7890
+ }
7891
+ const buffer = new Uint8Array(Buffer.concat(pending));
7892
+ const partData = buffer.subarray(0, targetSize);
7893
+ if (buffer.byteLength > targetSize) {
7894
+ const remainder = buffer.subarray(targetSize);
7895
+ pending = [remainder];
7896
+ pendingSize = remainder.byteLength;
7897
+ } else {
7898
+ pending = [];
7899
+ pendingSize = 0;
7900
+ }
7901
+ const partStream = new ReadableStream({
7902
+ start(controller) {
7903
+ controller.enqueue(partData);
7904
+ controller.close();
7905
+ }
7906
+ });
7907
+ const encryptedStream = encryptStreamFn(partStream);
7908
+ const encryptedChunks = [];
7909
+ const encReader = encryptedStream.getReader();
7910
+ for (; ; ) {
7911
+ const { done, value } = await encReader.read();
7912
+ if (done) break;
7913
+ encryptedChunks.push(value);
7914
+ }
7915
+ const encryptedData = new Uint8Array(Buffer.concat(encryptedChunks));
7916
+ const encryptedMeta = sha256Base64(encryptedData);
7917
+ fileParts.push({
7918
+ ordinalNumber: partIndex + 1,
7919
+ fileSize: encryptedData.byteLength,
7920
+ fileHash: encryptedMeta
7921
+ });
7922
+ const uploadStream = new ReadableStream({
7923
+ start(controller) {
7924
+ controller.enqueue(encryptedData);
7925
+ controller.close();
7926
+ }
7927
+ });
7928
+ streamParts.push({
7929
+ dataStream: uploadStream,
7930
+ metadata: {
7931
+ hashSHA: encryptedMeta,
7932
+ fileSize: encryptedData.byteLength
7933
+ },
7934
+ ordinalNumber: partIndex + 1
7935
+ });
7936
+ }
7937
+ reader.releaseLock();
7938
+ return {
7939
+ batchFile: {
7940
+ fileSize: zipSize,
7941
+ fileHash: zipMeta.hashSHA,
7942
+ fileParts
7943
+ },
7944
+ streamParts
7945
+ };
7946
+ }
7678
7947
  };
7679
7948
  function splitBuffer(data, maxPartSize) {
7680
7949
  if (data.length <= maxPartSize) {
@@ -7778,6 +8047,7 @@ ${lines.join("\n")}
7778
8047
 
7779
8048
  // src/crypto/index.ts
7780
8049
  init_pkcs12_loader();
8050
+ init_auth_xml_builder();
7781
8051
 
7782
8052
  // src/qr/index.ts
7783
8053
  init_verification_link_service();
@@ -7841,6 +8111,94 @@ function escapeXml2(str) {
7841
8111
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
7842
8112
  }
7843
8113
 
8114
+ // src/utils/zip.ts
8115
+ var import_yazl = require("yazl");
8116
+ var import_yauzl = require("yauzl");
8117
+ var DEFAULT_UNZIP_OPTIONS = {
8118
+ maxFiles: 1e4,
8119
+ maxTotalUncompressedSize: 2e9,
8120
+ maxFileUncompressedSize: 5e8,
8121
+ maxCompressionRatio: 200
8122
+ };
8123
+ async function createZip(entries) {
8124
+ return new Promise((resolve, reject) => {
8125
+ const zipfile = new import_yazl.ZipFile();
8126
+ for (const entry of entries) {
8127
+ zipfile.addBuffer(Buffer.from(entry.content), entry.fileName);
8128
+ }
8129
+ const chunks = [];
8130
+ zipfile.outputStream.on("data", (chunk) => chunks.push(chunk));
8131
+ zipfile.outputStream.on("error", (err) => reject(err));
8132
+ zipfile.outputStream.on("end", () => resolve(Buffer.concat(chunks)));
8133
+ zipfile.end();
8134
+ });
8135
+ }
8136
+ async function unzip(buffer, options = {}) {
8137
+ const limits = { ...DEFAULT_UNZIP_OPTIONS, ...options };
8138
+ return new Promise((resolve, reject) => {
8139
+ (0, import_yauzl.fromBuffer)(buffer, { lazyEntries: true }, (err, zipfile) => {
8140
+ if (err || !zipfile) {
8141
+ reject(err ?? new Error("Failed to open zip buffer"));
8142
+ return;
8143
+ }
8144
+ const files = /* @__PURE__ */ new Map();
8145
+ let totalUncompressed = 0;
8146
+ zipfile.readEntry();
8147
+ zipfile.on("entry", (entry) => {
8148
+ if (entry.fileName.endsWith("/")) {
8149
+ zipfile.readEntry();
8150
+ return;
8151
+ }
8152
+ if (limits.maxFiles > 0 && files.size >= limits.maxFiles) {
8153
+ reject(new Error("zip contains too many files"));
8154
+ return;
8155
+ }
8156
+ const uncompressedSize = entry.uncompressedSize ?? 0;
8157
+ const compressedSize = entry.compressedSize ?? 0;
8158
+ if (limits.maxFileUncompressedSize > 0 && uncompressedSize > limits.maxFileUncompressedSize) {
8159
+ reject(new Error("zip entry exceeds max_file_uncompressed_size"));
8160
+ return;
8161
+ }
8162
+ if (limits.maxTotalUncompressedSize > 0) {
8163
+ totalUncompressed += uncompressedSize;
8164
+ if (totalUncompressed > limits.maxTotalUncompressedSize) {
8165
+ reject(new Error("zip exceeds max_total_uncompressed_size"));
8166
+ return;
8167
+ }
8168
+ }
8169
+ if (limits.maxCompressionRatio !== null) {
8170
+ if (compressedSize === 0 && uncompressedSize > 0) {
8171
+ reject(new Error("zip entry has suspicious compression metadata"));
8172
+ return;
8173
+ }
8174
+ if (compressedSize > 0 && uncompressedSize > 0) {
8175
+ const ratio = uncompressedSize / compressedSize;
8176
+ if (ratio > limits.maxCompressionRatio) {
8177
+ reject(new Error("zip entry exceeds max_compression_ratio"));
8178
+ return;
8179
+ }
8180
+ }
8181
+ }
8182
+ zipfile.openReadStream(entry, (streamErr, stream) => {
8183
+ if (streamErr || !stream) {
8184
+ reject(streamErr ?? new Error("Failed to read zip entry"));
8185
+ return;
8186
+ }
8187
+ const chunks = [];
8188
+ stream.on("data", (chunk) => chunks.push(chunk));
8189
+ stream.on("error", (streamError) => reject(streamError));
8190
+ stream.on("end", () => {
8191
+ files.set(entry.fileName, Buffer.concat(chunks));
8192
+ zipfile.readEntry();
8193
+ });
8194
+ });
8195
+ });
8196
+ zipfile.on("end", () => resolve(files));
8197
+ zipfile.on("error", (zipErr) => reject(zipErr));
8198
+ });
8199
+ });
8200
+ }
8201
+
7844
8202
  // src/workflows/polling.ts
7845
8203
  async function pollUntil(action, condition, options) {
7846
8204
  const intervalMs = options?.intervalMs ?? 2e3;
@@ -7858,17 +8216,150 @@ async function pollUntil(action, condition, options) {
7858
8216
  );
7859
8217
  }
7860
8218
 
8219
+ // src/xml/upo-parser.ts
8220
+ var import_fast_xml_parser = require("fast-xml-parser");
8221
+ init_ksef_validation_error();
8222
+ function isRecord(value) {
8223
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8224
+ }
8225
+ function requireRecord(value, at) {
8226
+ if (!isRecord(value)) {
8227
+ throw KSeFValidationError.fromField(at, `Expected object at ${at}`);
8228
+ }
8229
+ return value;
8230
+ }
8231
+ function requireString(value, at) {
8232
+ if (typeof value !== "string" || value.length === 0) {
8233
+ throw KSeFValidationError.fromField(at, `Expected non-empty string at ${at}`);
8234
+ }
8235
+ return value;
8236
+ }
8237
+ function optionalRecord(value) {
8238
+ return isRecord(value) ? value : void 0;
8239
+ }
8240
+ function optionalString(value) {
8241
+ return typeof value === "string" && value.length > 0 ? value : void 0;
8242
+ }
8243
+ function requireNumberFromString(value, at) {
8244
+ const raw = requireString(value, at);
8245
+ const parsed = Number.parseInt(raw, 10);
8246
+ if (!Number.isFinite(parsed)) {
8247
+ throw KSeFValidationError.fromField(at, `Expected integer at ${at}, got "${raw}"`);
8248
+ }
8249
+ return parsed;
8250
+ }
8251
+ function ensureArray(value) {
8252
+ if (value == null) return [];
8253
+ return Array.isArray(value) ? value : [value];
8254
+ }
8255
+ function parseIdKontekstu(obj) {
8256
+ const nip = optionalString(obj.Nip);
8257
+ if (nip) return { kind: "Nip", nip };
8258
+ const idWewnetrzny = optionalString(obj.IdWewnetrzny);
8259
+ if (idWewnetrzny) return { kind: "IdWewnetrzny", idWewnetrzny };
8260
+ const idZlozonyVatUE = optionalString(obj.IdZlozonyVatUE);
8261
+ if (idZlozonyVatUE) return { kind: "IdZlozonyVatUE", idZlozonyVatUE };
8262
+ const idDostawcyUslugPeppol = optionalString(obj.IdDostawcyUslugPeppol);
8263
+ if (idDostawcyUslugPeppol) return { kind: "IdDostawcyUslugPeppol", idDostawcyUslugPeppol };
8264
+ throw KSeFValidationError.fromField(
8265
+ "Uwierzytelnienie.IdKontekstu",
8266
+ "Unsupported context identifier. Expected Nip | IdWewnetrzny | IdZlozonyVatUE | IdDostawcyUslugPeppol"
8267
+ );
8268
+ }
8269
+ function parseProof(obj) {
8270
+ const tokenRef = optionalString(obj.NumerReferencyjnyTokenaKSeF);
8271
+ if (tokenRef) return { kind: "NumerReferencyjnyTokenaKSeF", numerReferencyjnyTokenaKSeF: tokenRef };
8272
+ const docHash = optionalString(obj.SkrotDokumentuUwierzytelniajacego);
8273
+ if (docHash) return { kind: "SkrotDokumentuUwierzytelniajacego", skrotDokumentuUwierzytelniajacego: docHash };
8274
+ throw KSeFValidationError.fromField(
8275
+ "Uwierzytelnienie",
8276
+ "Unsupported auth proof. Expected NumerReferencyjnyTokenaKSeF | SkrotDokumentuUwierzytelniajacego"
8277
+ );
8278
+ }
8279
+ function parseUwierzytelnienie(obj) {
8280
+ const idKontekstu = parseIdKontekstu(
8281
+ requireRecord(obj.IdKontekstu, "Uwierzytelnienie.IdKontekstu")
8282
+ );
8283
+ const proof = parseProof(obj);
8284
+ return { idKontekstu, proof };
8285
+ }
8286
+ function parseOpisPotwierdzenia(obj) {
8287
+ return {
8288
+ strona: requireNumberFromString(obj.Strona, "OpisPotwierdzenia.Strona"),
8289
+ liczbaStron: requireNumberFromString(obj.LiczbaStron, "OpisPotwierdzenia.LiczbaStron"),
8290
+ zakresDokumentowOd: requireNumberFromString(obj.ZakresDokumentowOd, "OpisPotwierdzenia.ZakresDokumentowOd"),
8291
+ zakresDokumentowDo: requireNumberFromString(obj.ZakresDokumentowDo, "OpisPotwierdzenia.ZakresDokumentowDo"),
8292
+ calkowitaLiczbaDokumentow: requireNumberFromString(obj.CalkowitaLiczbaDokumentow, "OpisPotwierdzenia.CalkowitaLiczbaDokumentow")
8293
+ };
8294
+ }
8295
+ function parseDokument(obj) {
8296
+ return {
8297
+ nipSprzedawcy: requireString(obj.NipSprzedawcy, "Dokument.NipSprzedawcy"),
8298
+ numerKSeFDokumentu: requireString(obj.NumerKSeFDokumentu, "Dokument.NumerKSeFDokumentu"),
8299
+ numerFaktury: requireString(obj.NumerFaktury, "Dokument.NumerFaktury"),
8300
+ dataWystawieniaFaktury: requireString(obj.DataWystawieniaFaktury, "Dokument.DataWystawieniaFaktury"),
8301
+ dataPrzeslaniaDokumentu: requireString(obj.DataPrzeslaniaDokumentu, "Dokument.DataPrzeslaniaDokumentu"),
8302
+ dataNadaniaNumeruKSeF: requireString(obj.DataNadaniaNumeruKSeF, "Dokument.DataNadaniaNumeruKSeF"),
8303
+ skrotDokumentu: requireString(obj.SkrotDokumentu, "Dokument.SkrotDokumentu"),
8304
+ trybWysylki: requireString(obj.TrybWysylki, "Dokument.TrybWysylki")
8305
+ };
8306
+ }
8307
+ var upoParser = new import_fast_xml_parser.XMLParser({
8308
+ ignoreAttributes: false,
8309
+ attributeNamePrefix: "@_",
8310
+ parseTagValue: false,
8311
+ parseAttributeValue: false,
8312
+ removeNSPrefix: true,
8313
+ trimValues: false
8314
+ });
8315
+ function parseUpoXml(xml) {
8316
+ const text = Buffer.isBuffer(xml) ? xml.toString("utf8") : xml;
8317
+ const parsed = upoParser.parse(text);
8318
+ const potwierdzenie = requireRecord(parsed?.Potwierdzenie, "Potwierdzenie");
8319
+ const opisPotwierdzenia = optionalRecord(potwierdzenie.OpisPotwierdzenia);
8320
+ const dokumenty = ensureArray(potwierdzenie.Dokument).map(
8321
+ (doc, i) => parseDokument(requireRecord(doc, `Dokument[${i}]`))
8322
+ );
8323
+ if (dokumenty.length === 0) {
8324
+ throw KSeFValidationError.fromField("Dokument", "Expected at least one Dokument in UPO");
8325
+ }
8326
+ return {
8327
+ nazwaPodmiotuPrzyjmujacego: requireString(potwierdzenie.NazwaPodmiotuPrzyjmujacego, "NazwaPodmiotuPrzyjmujacego"),
8328
+ numerReferencyjnySesji: requireString(potwierdzenie.NumerReferencyjnySesji, "NumerReferencyjnySesji"),
8329
+ uwierzytelnienie: parseUwierzytelnienie(requireRecord(potwierdzenie.Uwierzytelnienie, "Uwierzytelnienie")),
8330
+ ...opisPotwierdzenia && { opisPotwierdzenia: parseOpisPotwierdzenia(opisPotwierdzenia) },
8331
+ nazwaStrukturyLogicznej: requireString(potwierdzenie.NazwaStrukturyLogicznej, "NazwaStrukturyLogicznej"),
8332
+ kodFormularza: requireString(potwierdzenie.KodFormularza, "KodFormularza"),
8333
+ dokumenty
8334
+ };
8335
+ }
8336
+
7861
8337
  // src/workflows/online-session-workflow.ts
7862
- var DEFAULT_FORM_CODE = { systemCode: "FA", schemaVersion: "3", value: "FA (3)" };
7863
8338
  async function openOnlineSession(client, options) {
7864
8339
  await client.crypto.init();
7865
8340
  const encData = client.crypto.getEncryptionData();
7866
- const formCode = options?.formCode ?? DEFAULT_FORM_CODE;
8341
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
7867
8342
  const openResp = await client.onlineSession.openSession(
7868
8343
  { formCode, encryption: encData.encryptionInfo },
7869
8344
  options?.upoVersion
7870
8345
  );
7871
8346
  const sessionRef = openResp.referenceNumber;
8347
+ async function fetchUpo(pollOpts) {
8348
+ const result = await pollUntil(
8349
+ () => client.sessionStatus.getSessionStatus(sessionRef),
8350
+ (s) => s.status.code === 200 || s.status.code >= 400,
8351
+ { ...pollOpts, description: `UPO for session ${sessionRef}` }
8352
+ );
8353
+ if (result.status.code !== 200) {
8354
+ throw new Error(`Session failed: ${result.status.code} \u2014 ${result.status.description}`);
8355
+ }
8356
+ return {
8357
+ pages: result.upo?.pages ?? [],
8358
+ invoiceCount: result.invoiceCount,
8359
+ successfulInvoiceCount: result.successfulInvoiceCount,
8360
+ failedInvoiceCount: result.failedInvoiceCount
8361
+ };
8362
+ }
7872
8363
  return {
7873
8364
  sessionRef,
7874
8365
  validUntil: openResp.validUntil,
@@ -7890,20 +8381,16 @@ async function openOnlineSession(client, options) {
7890
8381
  await client.onlineSession.closeSession(sessionRef);
7891
8382
  },
7892
8383
  async waitForUpo(pollOpts) {
7893
- const result = await pollUntil(
7894
- () => client.sessionStatus.getSessionStatus(sessionRef),
7895
- (s) => s.status.code === 200 || s.status.code >= 400,
7896
- { ...pollOpts, description: `UPO for session ${sessionRef}` }
7897
- );
7898
- if (result.status.code !== 200) {
7899
- throw new Error(`Session failed: ${result.status.code} \u2014 ${result.status.description}`);
7900
- }
7901
- return {
7902
- pages: result.upo?.pages ?? [],
7903
- invoiceCount: result.invoiceCount,
7904
- successfulInvoiceCount: result.successfulInvoiceCount,
7905
- failedInvoiceCount: result.failedInvoiceCount
7906
- };
8384
+ return fetchUpo(pollOpts);
8385
+ },
8386
+ async waitForUpoParsed(pollOpts) {
8387
+ const upoInfo = await fetchUpo(pollOpts);
8388
+ const parsed = [];
8389
+ for (const page of upoInfo.pages) {
8390
+ const result = await client.sessionStatus.getSessionUpo(sessionRef, page.referenceNumber);
8391
+ parsed.push(parseUpoXml(result.upo));
8392
+ }
8393
+ return { ...upoInfo, parsed };
7907
8394
  }
7908
8395
  };
7909
8396
  }
@@ -7917,11 +8404,10 @@ async function openSendAndClose(client, invoices, options) {
7917
8404
  }
7918
8405
 
7919
8406
  // src/workflows/batch-session-workflow.ts
7920
- var DEFAULT_FORM_CODE2 = { systemCode: "FA", schemaVersion: "3", value: "FA (3)" };
7921
8407
  async function uploadBatch(client, zipData, options) {
7922
8408
  await client.crypto.init();
7923
8409
  const encData = client.crypto.getEncryptionData();
7924
- const formCode = options?.formCode ?? DEFAULT_FORM_CODE2;
8410
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
7925
8411
  const encryptFn = (part) => client.crypto.encryptAES256(part, encData.cipherKey, encData.cipherIv);
7926
8412
  const { batchFile, encryptedParts } = BatchFileBuilder.build(zipData, encryptFn, {
7927
8413
  maxPartSize: options?.maxPartSize
@@ -7963,6 +8449,72 @@ async function uploadBatch(client, zipData, options) {
7963
8449
  }
7964
8450
  };
7965
8451
  }
8452
+ async function uploadBatchStream(client, zipStreamFactory, zipSize, options) {
8453
+ await client.crypto.init();
8454
+ const encData = client.crypto.getEncryptionData();
8455
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
8456
+ const encryptStreamFn = (stream) => client.crypto.encryptAES256Stream(stream, encData.cipherKey, encData.cipherIv);
8457
+ const hashStreamFn = (stream) => client.crypto.getFileMetadataFromStream(stream);
8458
+ const { batchFile, streamParts } = await BatchFileBuilder.buildFromStream(
8459
+ zipStreamFactory,
8460
+ zipSize,
8461
+ encryptStreamFn,
8462
+ hashStreamFn,
8463
+ { maxPartSize: options?.maxPartSize }
8464
+ );
8465
+ const openResp = await client.batchSession.openSession(
8466
+ {
8467
+ formCode,
8468
+ encryption: encData.encryptionInfo,
8469
+ batchFile,
8470
+ offlineMode: options?.offlineMode
8471
+ },
8472
+ options?.upoVersion
8473
+ );
8474
+ await client.batchSession.sendPartsWithStream(openResp, streamParts);
8475
+ await client.batchSession.closeSession(openResp.referenceNumber);
8476
+ const result = await pollUntil(
8477
+ () => client.sessionStatus.getSessionStatus(openResp.referenceNumber),
8478
+ (s) => s.status.code === 200 || s.status.code >= 400,
8479
+ { ...options?.pollOptions, description: `UPO for batch ${openResp.referenceNumber}` }
8480
+ );
8481
+ if (result.status.code !== 200) {
8482
+ throw new Error(`Batch session failed: ${result.status.code} \u2014 ${result.status.description}`);
8483
+ }
8484
+ return {
8485
+ sessionRef: openResp.referenceNumber,
8486
+ upo: {
8487
+ pages: result.upo?.pages ?? [],
8488
+ invoiceCount: result.invoiceCount,
8489
+ successfulInvoiceCount: result.successfulInvoiceCount,
8490
+ failedInvoiceCount: result.failedInvoiceCount
8491
+ }
8492
+ };
8493
+ }
8494
+ async function uploadBatchStreamParsed(client, zipStreamFactory, zipSize, options) {
8495
+ const result = await uploadBatchStream(client, zipStreamFactory, zipSize, options);
8496
+ const parsed = [];
8497
+ for (const page of result.upo.pages) {
8498
+ const upoResult = await client.sessionStatus.getSessionUpo(result.sessionRef, page.referenceNumber);
8499
+ parsed.push(parseUpoXml(upoResult.upo));
8500
+ }
8501
+ return {
8502
+ sessionRef: result.sessionRef,
8503
+ upo: { ...result.upo, parsed }
8504
+ };
8505
+ }
8506
+ async function uploadBatchParsed(client, zipData, options) {
8507
+ const result = await uploadBatch(client, zipData, options);
8508
+ const parsed = [];
8509
+ for (const page of result.upo.pages) {
8510
+ const upoResult = await client.sessionStatus.getSessionUpo(result.sessionRef, page.referenceNumber);
8511
+ parsed.push(parseUpoXml(upoResult.upo));
8512
+ }
8513
+ return {
8514
+ sessionRef: result.sessionRef,
8515
+ upo: { ...result.upo, parsed }
8516
+ };
8517
+ }
7966
8518
 
7967
8519
  // src/workflows/invoice-export-workflow.ts
7968
8520
  async function doExport(client, filters, options) {
@@ -7986,6 +8538,7 @@ async function doExport(client, filters, options) {
7986
8538
  }
7987
8539
  return {
7988
8540
  encData,
8541
+ referenceNumber: opResp.referenceNumber,
7989
8542
  result: {
7990
8543
  parts: result.package.parts.map((p) => ({
7991
8544
  ordinalNumber: p.ordinalNumber,
@@ -7998,7 +8551,8 @@ async function doExport(client, filters, options) {
7998
8551
  })),
7999
8552
  invoiceCount: result.package.invoiceCount,
8000
8553
  isTruncated: result.package.isTruncated,
8001
- permanentStorageHwmDate: result.package.permanentStorageHwmDate
8554
+ permanentStorageHwmDate: result.package.permanentStorageHwmDate,
8555
+ lastPermanentStorageDate: result.package.lastPermanentStorageDate
8002
8556
  }
8003
8557
  };
8004
8558
  }
@@ -8019,13 +8573,144 @@ async function exportAndDownload(client, filters, options) {
8019
8573
  const decrypted = client.crypto.decryptAES256(encryptedData, encData.cipherKey, encData.cipherIv);
8020
8574
  decryptedParts.push(decrypted);
8021
8575
  }
8576
+ if (options?.extract) {
8577
+ const zipBuffer = Buffer.concat(decryptedParts);
8578
+ const files = await unzip(zipBuffer, options.unzipOptions);
8579
+ return { ...exportResult, files };
8580
+ }
8022
8581
  return {
8023
8582
  ...exportResult,
8024
8583
  decryptedParts
8025
8584
  };
8026
8585
  }
8027
8586
 
8587
+ // src/workflows/hwm-coordinator.ts
8588
+ function updateContinuationPoint(points, subjectType, pkg) {
8589
+ if (pkg.isTruncated && pkg.lastPermanentStorageDate) {
8590
+ points[subjectType] = pkg.lastPermanentStorageDate;
8591
+ } else if (pkg.permanentStorageHwmDate) {
8592
+ points[subjectType] = pkg.permanentStorageHwmDate;
8593
+ } else {
8594
+ delete points[subjectType];
8595
+ }
8596
+ }
8597
+ function getEffectiveStartDate(points, subjectType, windowFrom) {
8598
+ return points[subjectType] ?? windowFrom;
8599
+ }
8600
+ function deduplicateByKsefNumber(entries) {
8601
+ const seen = /* @__PURE__ */ new Set();
8602
+ return entries.filter((entry) => {
8603
+ const key = entry.ksefNumber.toLowerCase();
8604
+ if (seen.has(key)) return false;
8605
+ seen.add(key);
8606
+ return true;
8607
+ });
8608
+ }
8609
+
8610
+ // src/workflows/incremental-export-workflow.ts
8611
+ async function incrementalExportAndDownload(client, options) {
8612
+ const maxIterations = options.maxIterations ?? 20;
8613
+ const points = options.continuationPoints;
8614
+ if (options.store) {
8615
+ const loaded = await options.store.load();
8616
+ for (const [key, value] of Object.entries(loaded)) {
8617
+ if (value !== void 0 && points[key] === void 0) {
8618
+ points[key] = value;
8619
+ }
8620
+ }
8621
+ }
8622
+ const referenceNumbers = [];
8623
+ const decryptedParts = [];
8624
+ let previousFrom;
8625
+ let iteration = 0;
8626
+ for (; iteration < maxIterations; iteration++) {
8627
+ const effectiveFrom = getEffectiveStartDate(points, options.subjectType, options.windowFrom);
8628
+ if (previousFrom !== void 0 && effectiveFrom === previousFrom) {
8629
+ break;
8630
+ }
8631
+ previousFrom = effectiveFrom;
8632
+ const filters = options.filtersFactory ? options.filtersFactory(effectiveFrom, options.windowTo) : buildDefaultFilters(options.subjectType, effectiveFrom, options.windowTo);
8633
+ const { result, encData, referenceNumber } = await doExport(client, filters, {
8634
+ onlyMetadata: options.onlyMetadata,
8635
+ pollOptions: options.pollOptions
8636
+ });
8637
+ referenceNumbers.push(referenceNumber);
8638
+ const download = options.transport ?? fetch;
8639
+ for (const part of result.parts) {
8640
+ const resp = await download(part.url, { method: part.method });
8641
+ if (!resp.ok) {
8642
+ throw new Error(`Download failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
8643
+ }
8644
+ const encryptedData = new Uint8Array(await resp.arrayBuffer());
8645
+ const decrypted = client.crypto.decryptAES256(encryptedData, encData.cipherKey, encData.cipherIv);
8646
+ decryptedParts.push(decrypted);
8647
+ }
8648
+ updateContinuationPoint(points, options.subjectType, {
8649
+ isTruncated: result.isTruncated,
8650
+ lastPermanentStorageDate: result.lastPermanentStorageDate,
8651
+ permanentStorageHwmDate: result.permanentStorageHwmDate
8652
+ });
8653
+ if (options.store) {
8654
+ await options.store.save(points);
8655
+ }
8656
+ options.onIterationComplete?.(iteration, result);
8657
+ if (!result.isTruncated) {
8658
+ iteration++;
8659
+ break;
8660
+ }
8661
+ }
8662
+ return {
8663
+ referenceNumbers,
8664
+ invoices: [],
8665
+ decryptedParts,
8666
+ continuationPoints: points,
8667
+ iterationCount: iteration
8668
+ };
8669
+ }
8670
+ function buildDefaultFilters(subjectType, from, to) {
8671
+ return {
8672
+ subjectType,
8673
+ dateRange: {
8674
+ dateType: "PermanentStorage",
8675
+ from,
8676
+ to
8677
+ }
8678
+ };
8679
+ }
8680
+
8681
+ // src/workflows/hwm-storage.ts
8682
+ var fs = __toESM(require("fs/promises"), 1);
8683
+ var InMemoryHwmStore = class {
8684
+ points = {};
8685
+ async load() {
8686
+ return { ...this.points };
8687
+ }
8688
+ async save(points) {
8689
+ this.points = { ...points };
8690
+ }
8691
+ };
8692
+ var FileHwmStore = class {
8693
+ constructor(filePath) {
8694
+ this.filePath = filePath;
8695
+ }
8696
+ async load() {
8697
+ try {
8698
+ const data = await fs.readFile(this.filePath, "utf-8");
8699
+ return JSON.parse(data);
8700
+ } catch (err) {
8701
+ if (err.code === "ENOENT") {
8702
+ return {};
8703
+ }
8704
+ throw err;
8705
+ }
8706
+ }
8707
+ async save(points) {
8708
+ await fs.writeFile(this.filePath, JSON.stringify(points, null, 2), "utf-8");
8709
+ }
8710
+ };
8711
+
8028
8712
  // src/workflows/auth-workflow.ts
8713
+ init_auth_xml_builder();
8029
8714
  async function authenticateWithToken(client, options) {
8030
8715
  const challenge = await client.auth.getChallenge();
8031
8716
  await client.crypto.init();
@@ -8079,6 +8764,34 @@ async function authenticateWithCertificate(client, options) {
8079
8764
  refreshTokenValidUntil: tokens.refreshToken.validUntil
8080
8765
  };
8081
8766
  }
8767
+ async function authenticateWithExternalSignature(client, options) {
8768
+ const challenge = await client.auth.getChallenge();
8769
+ const unsignedXml = buildUnsignedAuthTokenRequestXml({
8770
+ challenge: challenge.challenge,
8771
+ contextIdentifier: options.contextIdentifier
8772
+ });
8773
+ const signedXml = await options.signXml(unsignedXml);
8774
+ const submitResult = await client.auth.submitXadesAuthRequest(
8775
+ signedXml,
8776
+ options.verifyCertificateChain ?? false,
8777
+ options.enforceXadesCompliance ?? false
8778
+ );
8779
+ const authToken = submitResult.authenticationToken.token;
8780
+ await pollUntil(
8781
+ () => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
8782
+ (s) => s.status.code !== 100,
8783
+ { ...options.pollOptions, description: `auth ${submitResult.referenceNumber}` }
8784
+ );
8785
+ const tokens = await client.auth.getAccessToken(authToken);
8786
+ client.authManager.setAccessToken(tokens.accessToken.token);
8787
+ client.authManager.setRefreshToken(tokens.refreshToken.token);
8788
+ return {
8789
+ accessToken: tokens.accessToken.token,
8790
+ accessTokenValidUntil: tokens.accessToken.validUntil,
8791
+ refreshToken: tokens.refreshToken.token,
8792
+ refreshTokenValidUntil: tokens.refreshToken.validUntil
8793
+ };
8794
+ }
8082
8795
  async function authenticateWithPkcs12(client, options) {
8083
8796
  const { Pkcs12Loader: Pkcs12Loader2 } = await Promise.resolve().then(() => (init_pkcs12_loader(), pkcs12_loader_exports));
8084
8797
  const { certificatePem, privateKeyPem } = Pkcs12Loader2.load(options.p12, options.password);
@@ -8119,6 +8832,11 @@ init_client();
8119
8832
  ENFORCE_XADES_COMPLIANCE,
8120
8833
  EntityPermissionGrantBuilder,
8121
8834
  Environment,
8835
+ FORM_CODES,
8836
+ FORM_CODE_KEYS,
8837
+ FileHwmStore,
8838
+ INVOICE_TYPES_BY_SYSTEM_CODE,
8839
+ InMemoryHwmStore,
8122
8840
  InternalId,
8123
8841
  InvoiceDownloadService,
8124
8842
  InvoiceQueryFilterBuilder,
@@ -8164,21 +8882,29 @@ init_client();
8164
8882
  SessionStatusService,
8165
8883
  Sha256Base64,
8166
8884
  SignatureService,
8885
+ SystemCode,
8167
8886
  TestDataService,
8168
8887
  TokenService,
8169
8888
  UpoVersion,
8170
8889
  VatUe,
8171
8890
  VerificationLinkService,
8172
8891
  authenticateWithCertificate,
8892
+ authenticateWithExternalSignature,
8173
8893
  authenticateWithPkcs12,
8174
8894
  authenticateWithToken,
8895
+ buildUnsignedAuthTokenRequestXml,
8175
8896
  calculateBackoff,
8897
+ createZip,
8898
+ deduplicateByKsefNumber,
8176
8899
  defaultPresignedUrlPolicy,
8177
8900
  defaultRateLimitPolicy,
8178
8901
  defaultRetryPolicy,
8179
8902
  defaultTransport,
8180
8903
  exportAndDownload,
8181
8904
  exportInvoices,
8905
+ getEffectiveStartDate,
8906
+ getFormCode,
8907
+ incrementalExportAndDownload,
8182
8908
  isRetryableError,
8183
8909
  isRetryableStatus,
8184
8910
  isValidBase64,
@@ -8198,11 +8924,19 @@ init_client();
8198
8924
  isValidVatUe,
8199
8925
  openOnlineSession,
8200
8926
  openSendAndClose,
8927
+ parseFormCode,
8201
8928
  parseRetryAfter,
8929
+ parseUpoXml,
8202
8930
  pollUntil,
8203
8931
  resolveOptions,
8204
8932
  sleep,
8933
+ unzip,
8934
+ updateContinuationPoint,
8205
8935
  uploadBatch,
8936
+ uploadBatchParsed,
8937
+ uploadBatchStream,
8938
+ uploadBatchStreamParsed,
8939
+ validateFormCodeForSession,
8206
8940
  validatePresignedUrl
8207
8941
  });
8208
8942
  //# sourceMappingURL=index.cjs.map