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.js CHANGED
@@ -1106,6 +1106,36 @@ var init_batch_session = __esm({
1106
1106
  });
1107
1107
  await Promise.all(tasks);
1108
1108
  }
1109
+ /**
1110
+ * Upload parts sequentially (not in parallel) because each part uses a
1111
+ * streaming body (`duplex: 'half'`). Parallel streaming uploads can cause
1112
+ * backpressure issues and exceed memory limits for large payloads.
1113
+ */
1114
+ async sendPartsWithStream(openResponse, parts) {
1115
+ const uploadRequests = openResponse.partUploadRequests;
1116
+ for (const part of parts) {
1117
+ const uploadReq = uploadRequests.find(
1118
+ (r) => r.ordinalNumber === part.ordinalNumber
1119
+ );
1120
+ if (!uploadReq) {
1121
+ throw new Error(`No upload request found for part ${part.ordinalNumber}`);
1122
+ }
1123
+ const headers = {};
1124
+ for (const [k, v] of Object.entries(uploadReq.headers)) {
1125
+ if (v != null) headers[k] = v;
1126
+ }
1127
+ const resp = await fetch(uploadReq.url, {
1128
+ method: uploadReq.method,
1129
+ headers,
1130
+ body: part.dataStream,
1131
+ // @ts-expect-error -- Node 18+ undici supports duplex for streaming body
1132
+ duplex: "half"
1133
+ });
1134
+ if (!resp.ok) {
1135
+ throw new Error(`Upload failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
1136
+ }
1137
+ }
1138
+ }
1109
1139
  async closeSession(batchRef) {
1110
1140
  const req = RestRequest.post(Routes.Sessions.Batch.close(batchRef));
1111
1141
  await this.restClient.executeVoid(req);
@@ -1803,6 +1833,28 @@ var init_cryptography_service = __esm({
1803
1833
  const cipher = crypto2.createCipheriv("aes-256-cbc", key, iv);
1804
1834
  return new Uint8Array(Buffer.concat([cipher.update(content), cipher.final()]));
1805
1835
  }
1836
+ /**
1837
+ * Encrypt with AES-256-CBC as a streaming transform.
1838
+ * Returns a ReadableStream that yields encrypted chunks as the input is read.
1839
+ */
1840
+ encryptAES256Stream(input, key, iv) {
1841
+ const cipher = crypto2.createCipheriv("aes-256-cbc", key, iv);
1842
+ const transform = new TransformStream({
1843
+ transform(chunk, controller) {
1844
+ const encrypted = cipher.update(chunk);
1845
+ if (encrypted.length > 0) {
1846
+ controller.enqueue(new Uint8Array(encrypted));
1847
+ }
1848
+ },
1849
+ flush(controller) {
1850
+ const final = cipher.final();
1851
+ if (final.length > 0) {
1852
+ controller.enqueue(new Uint8Array(final));
1853
+ }
1854
+ }
1855
+ });
1856
+ return input.pipeThrough(transform);
1857
+ }
1806
1858
  /** Decrypt with AES-256-CBC. */
1807
1859
  decryptAES256(content, key, iv) {
1808
1860
  const decipher = crypto2.createDecipheriv("aes-256-cbc", key, iv);
@@ -1875,6 +1927,23 @@ var init_cryptography_service = __esm({
1875
1927
  const hash = crypto2.createHash("sha256").update(file).digest("base64");
1876
1928
  return { hashSHA: hash, fileSize: file.length };
1877
1929
  }
1930
+ /** Compute SHA-256 hash (base64) and byte length from a ReadableStream. */
1931
+ async getFileMetadataFromStream(stream) {
1932
+ const hash = crypto2.createHash("sha256");
1933
+ let fileSize = 0;
1934
+ const reader = stream.getReader();
1935
+ try {
1936
+ for (; ; ) {
1937
+ const { done, value } = await reader.read();
1938
+ if (done) break;
1939
+ hash.update(value);
1940
+ fileSize += value.byteLength;
1941
+ }
1942
+ } finally {
1943
+ reader.releaseLock();
1944
+ }
1945
+ return { hashSHA: hash.digest("base64"), fileSize };
1946
+ }
1878
1947
  // ---------------------------------------------------------------------------
1879
1948
  // CSR generation
1880
1949
  // ---------------------------------------------------------------------------
@@ -6789,6 +6858,32 @@ var init_pkcs12_loader = __esm({
6789
6858
  }
6790
6859
  });
6791
6860
 
6861
+ // src/crypto/auth-xml-builder.ts
6862
+ function buildUnsignedAuthTokenRequestXml(options) {
6863
+ const { challenge, contextIdentifier, subjectIdentifierType = "certificateSubject" } = options;
6864
+ const identifierElement = `<${contextIdentifier.type}>${xmlEscape(contextIdentifier.value)}</${contextIdentifier.type}>`;
6865
+ return [
6866
+ '<?xml version="1.0" encoding="utf-8"?>',
6867
+ `<AuthTokenRequest xmlns="${AUTH_TOKEN_REQUEST_NS}">`,
6868
+ `<Challenge>${xmlEscape(challenge)}</Challenge>`,
6869
+ `<ContextIdentifier>`,
6870
+ identifierElement,
6871
+ `</ContextIdentifier>`,
6872
+ `<SubjectIdentifierType>${xmlEscape(subjectIdentifierType)}</SubjectIdentifierType>`,
6873
+ `</AuthTokenRequest>`
6874
+ ].join("");
6875
+ }
6876
+ function xmlEscape(str) {
6877
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
6878
+ }
6879
+ var AUTH_TOKEN_REQUEST_NS;
6880
+ var init_auth_xml_builder = __esm({
6881
+ "src/crypto/auth-xml-builder.ts"() {
6882
+ "use strict";
6883
+ AUTH_TOKEN_REQUEST_NS = "http://ksef.mf.gov.pl/auth/token/2.0";
6884
+ }
6885
+ });
6886
+
6792
6887
  // src/qr/verification-link-service.ts
6793
6888
  import crypto5 from "crypto";
6794
6889
  var VerificationLinkService;
@@ -6853,19 +6948,11 @@ __export(client_exports, {
6853
6948
  buildAuthTokenRequestXml: () => buildAuthTokenRequestXml
6854
6949
  });
6855
6950
  function buildAuthTokenRequestXml(challenge, nip, subjectIdentifierType = "certificateSubject") {
6856
- return [
6857
- '<?xml version="1.0" encoding="utf-8"?>',
6858
- `<AuthTokenRequest xmlns="${AUTH_TOKEN_REQUEST_NS}">`,
6859
- `<Challenge>${xmlEscape(challenge)}</Challenge>`,
6860
- `<ContextIdentifier>`,
6861
- `<Nip>${xmlEscape(nip)}</Nip>`,
6862
- `</ContextIdentifier>`,
6863
- `<SubjectIdentifierType>${xmlEscape(subjectIdentifierType)}</SubjectIdentifierType>`,
6864
- `</AuthTokenRequest>`
6865
- ].join("");
6866
- }
6867
- function xmlEscape(str) {
6868
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
6951
+ return buildUnsignedAuthTokenRequestXml({
6952
+ challenge,
6953
+ contextIdentifier: { type: "Nip", value: nip },
6954
+ subjectIdentifierType
6955
+ });
6869
6956
  }
6870
6957
  function buildRestClientConfig(options, authManager) {
6871
6958
  const config = { authManager };
@@ -6892,7 +6979,7 @@ function buildRestClientConfig(options, authManager) {
6892
6979
  }
6893
6980
  return config;
6894
6981
  }
6895
- var KSeFClient, AUTH_TOKEN_REQUEST_NS;
6982
+ var KSeFClient;
6896
6983
  var init_client = __esm({
6897
6984
  "src/client.ts"() {
6898
6985
  "use strict";
@@ -6918,6 +7005,7 @@ var init_client = __esm({
6918
7005
  init_certificate_fetcher();
6919
7006
  init_cryptography_service();
6920
7007
  init_verification_link_service();
7008
+ init_auth_xml_builder();
6921
7009
  KSeFClient = class {
6922
7010
  auth;
6923
7011
  activeSessions;
@@ -7011,7 +7099,6 @@ var init_client = __esm({
7011
7099
  this.authManager.setRefreshToken(void 0);
7012
7100
  }
7013
7101
  };
7014
- AUTH_TOKEN_REQUEST_NS = "http://ksef.mf.gov.pl/auth/token/2.0";
7015
7102
  }
7016
7103
  });
7017
7104
 
@@ -7145,6 +7232,65 @@ var SUBUNIT_NAME_MAX_LENGTH = 256;
7145
7232
  var PERMISSION_DESCRIPTION_MIN_LENGTH = 5;
7146
7233
  var PERMISSION_DESCRIPTION_MAX_LENGTH = 256;
7147
7234
 
7235
+ // src/models/document-structures/types.ts
7236
+ var SystemCode = {
7237
+ FA_2: "FA (2)",
7238
+ FA_3: "FA (3)",
7239
+ PEF_3: "PEF (3)",
7240
+ PEF_KOR_3: "PEF_KOR (3)",
7241
+ FA_RR_1: "FA_RR (1)"
7242
+ };
7243
+ var FORM_CODES = {
7244
+ FA_2: { systemCode: "FA (2)", schemaVersion: "1-0E", value: "FA" },
7245
+ FA_3: { systemCode: "FA (3)", schemaVersion: "1-0E", value: "FA" },
7246
+ PEF_3: { systemCode: "PEF (3)", schemaVersion: "2-1", value: "PEF" },
7247
+ PEF_KOR_3: { systemCode: "PEF_KOR (3)", schemaVersion: "2-1", value: "PEF" },
7248
+ FA_RR_1_LEGACY: { systemCode: "FA_RR (1)", schemaVersion: "1-0E", value: "RR" },
7249
+ FA_RR_1_TRANSITION: { systemCode: "FA_RR (1)", schemaVersion: "1-1E", value: "RR" },
7250
+ FA_RR_1: { systemCode: "FA_RR (1)", schemaVersion: "1-1E", value: "FA_RR" }
7251
+ };
7252
+ var INVOICE_TYPES_BY_SYSTEM_CODE = {
7253
+ [SystemCode.FA_2]: ["Vat", "Zal", "Kor", "Roz", "Upr", "KorZal", "KorRoz"],
7254
+ [SystemCode.FA_3]: ["Vat", "Zal", "Kor", "Roz", "Upr", "KorZal", "KorRoz"],
7255
+ [SystemCode.PEF_3]: ["VatPef", "VatPefSp", "KorPef"],
7256
+ [SystemCode.PEF_KOR_3]: ["KorPef"],
7257
+ [SystemCode.FA_RR_1]: ["VatRr", "KorVatRr"]
7258
+ };
7259
+ var FORM_CODE_KEYS = {
7260
+ FA2: FORM_CODES.FA_2,
7261
+ FA3: FORM_CODES.FA_3,
7262
+ PEF3: FORM_CODES.PEF_3,
7263
+ PEFKOR3: FORM_CODES.PEF_KOR_3,
7264
+ FARR1: FORM_CODES.FA_RR_1
7265
+ };
7266
+
7267
+ // src/models/document-structures/helpers.ts
7268
+ var SYSTEM_CODE_TO_FORM_CODE = {
7269
+ [SystemCode.FA_2]: FORM_CODES.FA_2,
7270
+ [SystemCode.FA_3]: FORM_CODES.FA_3,
7271
+ [SystemCode.PEF_3]: FORM_CODES.PEF_3,
7272
+ [SystemCode.PEF_KOR_3]: FORM_CODES.PEF_KOR_3,
7273
+ [SystemCode.FA_RR_1]: FORM_CODES.FA_RR_1
7274
+ };
7275
+ var ALL_FORM_CODES = Object.values(FORM_CODES);
7276
+ var BATCH_DISALLOWED_SYSTEM_CODES = /* @__PURE__ */ new Set([
7277
+ SystemCode.PEF_3,
7278
+ SystemCode.PEF_KOR_3
7279
+ ]);
7280
+ function getFormCode(systemCode) {
7281
+ return SYSTEM_CODE_TO_FORM_CODE[systemCode];
7282
+ }
7283
+ function parseFormCode(raw) {
7284
+ const match = ALL_FORM_CODES.find(
7285
+ (fc) => fc.systemCode === raw.systemCode && fc.schemaVersion === raw.schemaVersion && fc.value === raw.value
7286
+ );
7287
+ return match ?? raw;
7288
+ }
7289
+ function validateFormCodeForSession(formCode, sessionType) {
7290
+ if (sessionType === "online") return true;
7291
+ return !BATCH_DISALLOWED_SYSTEM_CODES.has(formCode.systemCode);
7292
+ }
7293
+
7148
7294
  // src/services/index.ts
7149
7295
  init_auth();
7150
7296
  init_active_sessions();
@@ -7561,6 +7707,108 @@ var BatchFileBuilder = class {
7561
7707
  encryptedParts
7562
7708
  };
7563
7709
  }
7710
+ /**
7711
+ * Stream-based variant: two-pass build from a stream factory.
7712
+ *
7713
+ * Pass 1: consume stream to compute ZIP hash.
7714
+ * Pass 2: re-create stream, split into parts, encrypt each, compute per-part metadata.
7715
+ *
7716
+ * @param zipStreamFactory - Factory that creates a fresh ReadableStream of the ZIP data
7717
+ * @param zipSize - Total ZIP byte size (from fs.stat or known in advance)
7718
+ * @param encryptStreamFn - Stream-to-stream AES-256-CBC encryption function
7719
+ * @param hashStreamFn - Stream-to-FileMetadata hashing function
7720
+ * @param options - Optional configuration
7721
+ */
7722
+ static async buildFromStream(zipStreamFactory, zipSize, encryptStreamFn, hashStreamFn, options) {
7723
+ const maxPartSize = options?.maxPartSize ?? BATCH_MAX_PART_SIZE;
7724
+ if (maxPartSize <= 0) {
7725
+ throw new KSeFValidationError("maxPartSize must be a positive number");
7726
+ }
7727
+ if (zipSize === 0) {
7728
+ throw new KSeFValidationError("ZIP data must not be empty");
7729
+ }
7730
+ if (zipSize > BATCH_MAX_TOTAL_SIZE) {
7731
+ throw new KSeFValidationError(
7732
+ `ZIP size ${zipSize} exceeds maximum of ${BATCH_MAX_TOTAL_SIZE} bytes (5 GB)`
7733
+ );
7734
+ }
7735
+ const partCount = Math.ceil(zipSize / maxPartSize);
7736
+ if (partCount > BATCH_MAX_PARTS) {
7737
+ throw new KSeFValidationError(
7738
+ `Data requires ${partCount} parts, exceeding maximum of ${BATCH_MAX_PARTS}`
7739
+ );
7740
+ }
7741
+ const zipMeta = await hashStreamFn(zipStreamFactory());
7742
+ const fileParts = [];
7743
+ const streamParts = [];
7744
+ const reader = zipStreamFactory().getReader();
7745
+ let pending = [];
7746
+ let pendingSize = 0;
7747
+ for (let partIndex = 0; partIndex < partCount; partIndex++) {
7748
+ const isLastPart = partIndex === partCount - 1;
7749
+ const targetSize = isLastPart ? zipSize - partIndex * maxPartSize : maxPartSize;
7750
+ while (pendingSize < targetSize) {
7751
+ const { done, value } = await reader.read();
7752
+ if (done) break;
7753
+ pending.push(value);
7754
+ pendingSize += value.byteLength;
7755
+ }
7756
+ const buffer = new Uint8Array(Buffer.concat(pending));
7757
+ const partData = buffer.subarray(0, targetSize);
7758
+ if (buffer.byteLength > targetSize) {
7759
+ const remainder = buffer.subarray(targetSize);
7760
+ pending = [remainder];
7761
+ pendingSize = remainder.byteLength;
7762
+ } else {
7763
+ pending = [];
7764
+ pendingSize = 0;
7765
+ }
7766
+ const partStream = new ReadableStream({
7767
+ start(controller) {
7768
+ controller.enqueue(partData);
7769
+ controller.close();
7770
+ }
7771
+ });
7772
+ const encryptedStream = encryptStreamFn(partStream);
7773
+ const encryptedChunks = [];
7774
+ const encReader = encryptedStream.getReader();
7775
+ for (; ; ) {
7776
+ const { done, value } = await encReader.read();
7777
+ if (done) break;
7778
+ encryptedChunks.push(value);
7779
+ }
7780
+ const encryptedData = new Uint8Array(Buffer.concat(encryptedChunks));
7781
+ const encryptedMeta = sha256Base64(encryptedData);
7782
+ fileParts.push({
7783
+ ordinalNumber: partIndex + 1,
7784
+ fileSize: encryptedData.byteLength,
7785
+ fileHash: encryptedMeta
7786
+ });
7787
+ const uploadStream = new ReadableStream({
7788
+ start(controller) {
7789
+ controller.enqueue(encryptedData);
7790
+ controller.close();
7791
+ }
7792
+ });
7793
+ streamParts.push({
7794
+ dataStream: uploadStream,
7795
+ metadata: {
7796
+ hashSHA: encryptedMeta,
7797
+ fileSize: encryptedData.byteLength
7798
+ },
7799
+ ordinalNumber: partIndex + 1
7800
+ });
7801
+ }
7802
+ reader.releaseLock();
7803
+ return {
7804
+ batchFile: {
7805
+ fileSize: zipSize,
7806
+ fileHash: zipMeta.hashSHA,
7807
+ fileParts
7808
+ },
7809
+ streamParts
7810
+ };
7811
+ }
7564
7812
  };
7565
7813
  function splitBuffer(data, maxPartSize) {
7566
7814
  if (data.length <= maxPartSize) {
@@ -7664,6 +7912,7 @@ ${lines.join("\n")}
7664
7912
 
7665
7913
  // src/crypto/index.ts
7666
7914
  init_pkcs12_loader();
7915
+ init_auth_xml_builder();
7667
7916
 
7668
7917
  // src/qr/index.ts
7669
7918
  init_verification_link_service();
@@ -7727,6 +7976,94 @@ function escapeXml2(str) {
7727
7976
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
7728
7977
  }
7729
7978
 
7979
+ // src/utils/zip.ts
7980
+ import { ZipFile } from "yazl";
7981
+ import { fromBuffer } from "yauzl";
7982
+ var DEFAULT_UNZIP_OPTIONS = {
7983
+ maxFiles: 1e4,
7984
+ maxTotalUncompressedSize: 2e9,
7985
+ maxFileUncompressedSize: 5e8,
7986
+ maxCompressionRatio: 200
7987
+ };
7988
+ async function createZip(entries) {
7989
+ return new Promise((resolve, reject) => {
7990
+ const zipfile = new ZipFile();
7991
+ for (const entry of entries) {
7992
+ zipfile.addBuffer(Buffer.from(entry.content), entry.fileName);
7993
+ }
7994
+ const chunks = [];
7995
+ zipfile.outputStream.on("data", (chunk) => chunks.push(chunk));
7996
+ zipfile.outputStream.on("error", (err) => reject(err));
7997
+ zipfile.outputStream.on("end", () => resolve(Buffer.concat(chunks)));
7998
+ zipfile.end();
7999
+ });
8000
+ }
8001
+ async function unzip(buffer, options = {}) {
8002
+ const limits = { ...DEFAULT_UNZIP_OPTIONS, ...options };
8003
+ return new Promise((resolve, reject) => {
8004
+ fromBuffer(buffer, { lazyEntries: true }, (err, zipfile) => {
8005
+ if (err || !zipfile) {
8006
+ reject(err ?? new Error("Failed to open zip buffer"));
8007
+ return;
8008
+ }
8009
+ const files = /* @__PURE__ */ new Map();
8010
+ let totalUncompressed = 0;
8011
+ zipfile.readEntry();
8012
+ zipfile.on("entry", (entry) => {
8013
+ if (entry.fileName.endsWith("/")) {
8014
+ zipfile.readEntry();
8015
+ return;
8016
+ }
8017
+ if (limits.maxFiles > 0 && files.size >= limits.maxFiles) {
8018
+ reject(new Error("zip contains too many files"));
8019
+ return;
8020
+ }
8021
+ const uncompressedSize = entry.uncompressedSize ?? 0;
8022
+ const compressedSize = entry.compressedSize ?? 0;
8023
+ if (limits.maxFileUncompressedSize > 0 && uncompressedSize > limits.maxFileUncompressedSize) {
8024
+ reject(new Error("zip entry exceeds max_file_uncompressed_size"));
8025
+ return;
8026
+ }
8027
+ if (limits.maxTotalUncompressedSize > 0) {
8028
+ totalUncompressed += uncompressedSize;
8029
+ if (totalUncompressed > limits.maxTotalUncompressedSize) {
8030
+ reject(new Error("zip exceeds max_total_uncompressed_size"));
8031
+ return;
8032
+ }
8033
+ }
8034
+ if (limits.maxCompressionRatio !== null) {
8035
+ if (compressedSize === 0 && uncompressedSize > 0) {
8036
+ reject(new Error("zip entry has suspicious compression metadata"));
8037
+ return;
8038
+ }
8039
+ if (compressedSize > 0 && uncompressedSize > 0) {
8040
+ const ratio = uncompressedSize / compressedSize;
8041
+ if (ratio > limits.maxCompressionRatio) {
8042
+ reject(new Error("zip entry exceeds max_compression_ratio"));
8043
+ return;
8044
+ }
8045
+ }
8046
+ }
8047
+ zipfile.openReadStream(entry, (streamErr, stream) => {
8048
+ if (streamErr || !stream) {
8049
+ reject(streamErr ?? new Error("Failed to read zip entry"));
8050
+ return;
8051
+ }
8052
+ const chunks = [];
8053
+ stream.on("data", (chunk) => chunks.push(chunk));
8054
+ stream.on("error", (streamError) => reject(streamError));
8055
+ stream.on("end", () => {
8056
+ files.set(entry.fileName, Buffer.concat(chunks));
8057
+ zipfile.readEntry();
8058
+ });
8059
+ });
8060
+ });
8061
+ zipfile.on("end", () => resolve(files));
8062
+ zipfile.on("error", (zipErr) => reject(zipErr));
8063
+ });
8064
+ });
8065
+ }
8066
+
7730
8067
  // src/workflows/polling.ts
7731
8068
  async function pollUntil(action, condition, options) {
7732
8069
  const intervalMs = options?.intervalMs ?? 2e3;
@@ -7744,17 +8081,150 @@ async function pollUntil(action, condition, options) {
7744
8081
  );
7745
8082
  }
7746
8083
 
8084
+ // src/xml/upo-parser.ts
8085
+ init_ksef_validation_error();
8086
+ import { XMLParser } from "fast-xml-parser";
8087
+ function isRecord(value) {
8088
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8089
+ }
8090
+ function requireRecord(value, at) {
8091
+ if (!isRecord(value)) {
8092
+ throw KSeFValidationError.fromField(at, `Expected object at ${at}`);
8093
+ }
8094
+ return value;
8095
+ }
8096
+ function requireString(value, at) {
8097
+ if (typeof value !== "string" || value.length === 0) {
8098
+ throw KSeFValidationError.fromField(at, `Expected non-empty string at ${at}`);
8099
+ }
8100
+ return value;
8101
+ }
8102
+ function optionalRecord(value) {
8103
+ return isRecord(value) ? value : void 0;
8104
+ }
8105
+ function optionalString(value) {
8106
+ return typeof value === "string" && value.length > 0 ? value : void 0;
8107
+ }
8108
+ function requireNumberFromString(value, at) {
8109
+ const raw = requireString(value, at);
8110
+ const parsed = Number.parseInt(raw, 10);
8111
+ if (!Number.isFinite(parsed)) {
8112
+ throw KSeFValidationError.fromField(at, `Expected integer at ${at}, got "${raw}"`);
8113
+ }
8114
+ return parsed;
8115
+ }
8116
+ function ensureArray(value) {
8117
+ if (value == null) return [];
8118
+ return Array.isArray(value) ? value : [value];
8119
+ }
8120
+ function parseIdKontekstu(obj) {
8121
+ const nip = optionalString(obj.Nip);
8122
+ if (nip) return { kind: "Nip", nip };
8123
+ const idWewnetrzny = optionalString(obj.IdWewnetrzny);
8124
+ if (idWewnetrzny) return { kind: "IdWewnetrzny", idWewnetrzny };
8125
+ const idZlozonyVatUE = optionalString(obj.IdZlozonyVatUE);
8126
+ if (idZlozonyVatUE) return { kind: "IdZlozonyVatUE", idZlozonyVatUE };
8127
+ const idDostawcyUslugPeppol = optionalString(obj.IdDostawcyUslugPeppol);
8128
+ if (idDostawcyUslugPeppol) return { kind: "IdDostawcyUslugPeppol", idDostawcyUslugPeppol };
8129
+ throw KSeFValidationError.fromField(
8130
+ "Uwierzytelnienie.IdKontekstu",
8131
+ "Unsupported context identifier. Expected Nip | IdWewnetrzny | IdZlozonyVatUE | IdDostawcyUslugPeppol"
8132
+ );
8133
+ }
8134
+ function parseProof(obj) {
8135
+ const tokenRef = optionalString(obj.NumerReferencyjnyTokenaKSeF);
8136
+ if (tokenRef) return { kind: "NumerReferencyjnyTokenaKSeF", numerReferencyjnyTokenaKSeF: tokenRef };
8137
+ const docHash = optionalString(obj.SkrotDokumentuUwierzytelniajacego);
8138
+ if (docHash) return { kind: "SkrotDokumentuUwierzytelniajacego", skrotDokumentuUwierzytelniajacego: docHash };
8139
+ throw KSeFValidationError.fromField(
8140
+ "Uwierzytelnienie",
8141
+ "Unsupported auth proof. Expected NumerReferencyjnyTokenaKSeF | SkrotDokumentuUwierzytelniajacego"
8142
+ );
8143
+ }
8144
+ function parseUwierzytelnienie(obj) {
8145
+ const idKontekstu = parseIdKontekstu(
8146
+ requireRecord(obj.IdKontekstu, "Uwierzytelnienie.IdKontekstu")
8147
+ );
8148
+ const proof = parseProof(obj);
8149
+ return { idKontekstu, proof };
8150
+ }
8151
+ function parseOpisPotwierdzenia(obj) {
8152
+ return {
8153
+ strona: requireNumberFromString(obj.Strona, "OpisPotwierdzenia.Strona"),
8154
+ liczbaStron: requireNumberFromString(obj.LiczbaStron, "OpisPotwierdzenia.LiczbaStron"),
8155
+ zakresDokumentowOd: requireNumberFromString(obj.ZakresDokumentowOd, "OpisPotwierdzenia.ZakresDokumentowOd"),
8156
+ zakresDokumentowDo: requireNumberFromString(obj.ZakresDokumentowDo, "OpisPotwierdzenia.ZakresDokumentowDo"),
8157
+ calkowitaLiczbaDokumentow: requireNumberFromString(obj.CalkowitaLiczbaDokumentow, "OpisPotwierdzenia.CalkowitaLiczbaDokumentow")
8158
+ };
8159
+ }
8160
+ function parseDokument(obj) {
8161
+ return {
8162
+ nipSprzedawcy: requireString(obj.NipSprzedawcy, "Dokument.NipSprzedawcy"),
8163
+ numerKSeFDokumentu: requireString(obj.NumerKSeFDokumentu, "Dokument.NumerKSeFDokumentu"),
8164
+ numerFaktury: requireString(obj.NumerFaktury, "Dokument.NumerFaktury"),
8165
+ dataWystawieniaFaktury: requireString(obj.DataWystawieniaFaktury, "Dokument.DataWystawieniaFaktury"),
8166
+ dataPrzeslaniaDokumentu: requireString(obj.DataPrzeslaniaDokumentu, "Dokument.DataPrzeslaniaDokumentu"),
8167
+ dataNadaniaNumeruKSeF: requireString(obj.DataNadaniaNumeruKSeF, "Dokument.DataNadaniaNumeruKSeF"),
8168
+ skrotDokumentu: requireString(obj.SkrotDokumentu, "Dokument.SkrotDokumentu"),
8169
+ trybWysylki: requireString(obj.TrybWysylki, "Dokument.TrybWysylki")
8170
+ };
8171
+ }
8172
+ var upoParser = new XMLParser({
8173
+ ignoreAttributes: false,
8174
+ attributeNamePrefix: "@_",
8175
+ parseTagValue: false,
8176
+ parseAttributeValue: false,
8177
+ removeNSPrefix: true,
8178
+ trimValues: false
8179
+ });
8180
+ function parseUpoXml(xml) {
8181
+ const text = Buffer.isBuffer(xml) ? xml.toString("utf8") : xml;
8182
+ const parsed = upoParser.parse(text);
8183
+ const potwierdzenie = requireRecord(parsed?.Potwierdzenie, "Potwierdzenie");
8184
+ const opisPotwierdzenia = optionalRecord(potwierdzenie.OpisPotwierdzenia);
8185
+ const dokumenty = ensureArray(potwierdzenie.Dokument).map(
8186
+ (doc, i) => parseDokument(requireRecord(doc, `Dokument[${i}]`))
8187
+ );
8188
+ if (dokumenty.length === 0) {
8189
+ throw KSeFValidationError.fromField("Dokument", "Expected at least one Dokument in UPO");
8190
+ }
8191
+ return {
8192
+ nazwaPodmiotuPrzyjmujacego: requireString(potwierdzenie.NazwaPodmiotuPrzyjmujacego, "NazwaPodmiotuPrzyjmujacego"),
8193
+ numerReferencyjnySesji: requireString(potwierdzenie.NumerReferencyjnySesji, "NumerReferencyjnySesji"),
8194
+ uwierzytelnienie: parseUwierzytelnienie(requireRecord(potwierdzenie.Uwierzytelnienie, "Uwierzytelnienie")),
8195
+ ...opisPotwierdzenia && { opisPotwierdzenia: parseOpisPotwierdzenia(opisPotwierdzenia) },
8196
+ nazwaStrukturyLogicznej: requireString(potwierdzenie.NazwaStrukturyLogicznej, "NazwaStrukturyLogicznej"),
8197
+ kodFormularza: requireString(potwierdzenie.KodFormularza, "KodFormularza"),
8198
+ dokumenty
8199
+ };
8200
+ }
8201
+
7747
8202
  // src/workflows/online-session-workflow.ts
7748
- var DEFAULT_FORM_CODE = { systemCode: "FA", schemaVersion: "3", value: "FA (3)" };
7749
8203
  async function openOnlineSession(client, options) {
7750
8204
  await client.crypto.init();
7751
8205
  const encData = client.crypto.getEncryptionData();
7752
- const formCode = options?.formCode ?? DEFAULT_FORM_CODE;
8206
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
7753
8207
  const openResp = await client.onlineSession.openSession(
7754
8208
  { formCode, encryption: encData.encryptionInfo },
7755
8209
  options?.upoVersion
7756
8210
  );
7757
8211
  const sessionRef = openResp.referenceNumber;
8212
+ async function fetchUpo(pollOpts) {
8213
+ const result = await pollUntil(
8214
+ () => client.sessionStatus.getSessionStatus(sessionRef),
8215
+ (s) => s.status.code === 200 || s.status.code >= 400,
8216
+ { ...pollOpts, description: `UPO for session ${sessionRef}` }
8217
+ );
8218
+ if (result.status.code !== 200) {
8219
+ throw new Error(`Session failed: ${result.status.code} \u2014 ${result.status.description}`);
8220
+ }
8221
+ return {
8222
+ pages: result.upo?.pages ?? [],
8223
+ invoiceCount: result.invoiceCount,
8224
+ successfulInvoiceCount: result.successfulInvoiceCount,
8225
+ failedInvoiceCount: result.failedInvoiceCount
8226
+ };
8227
+ }
7758
8228
  return {
7759
8229
  sessionRef,
7760
8230
  validUntil: openResp.validUntil,
@@ -7776,20 +8246,16 @@ async function openOnlineSession(client, options) {
7776
8246
  await client.onlineSession.closeSession(sessionRef);
7777
8247
  },
7778
8248
  async waitForUpo(pollOpts) {
7779
- const result = await pollUntil(
7780
- () => client.sessionStatus.getSessionStatus(sessionRef),
7781
- (s) => s.status.code === 200 || s.status.code >= 400,
7782
- { ...pollOpts, description: `UPO for session ${sessionRef}` }
7783
- );
7784
- if (result.status.code !== 200) {
7785
- throw new Error(`Session failed: ${result.status.code} \u2014 ${result.status.description}`);
7786
- }
7787
- return {
7788
- pages: result.upo?.pages ?? [],
7789
- invoiceCount: result.invoiceCount,
7790
- successfulInvoiceCount: result.successfulInvoiceCount,
7791
- failedInvoiceCount: result.failedInvoiceCount
7792
- };
8249
+ return fetchUpo(pollOpts);
8250
+ },
8251
+ async waitForUpoParsed(pollOpts) {
8252
+ const upoInfo = await fetchUpo(pollOpts);
8253
+ const parsed = [];
8254
+ for (const page of upoInfo.pages) {
8255
+ const result = await client.sessionStatus.getSessionUpo(sessionRef, page.referenceNumber);
8256
+ parsed.push(parseUpoXml(result.upo));
8257
+ }
8258
+ return { ...upoInfo, parsed };
7793
8259
  }
7794
8260
  };
7795
8261
  }
@@ -7803,11 +8269,10 @@ async function openSendAndClose(client, invoices, options) {
7803
8269
  }
7804
8270
 
7805
8271
  // src/workflows/batch-session-workflow.ts
7806
- var DEFAULT_FORM_CODE2 = { systemCode: "FA", schemaVersion: "3", value: "FA (3)" };
7807
8272
  async function uploadBatch(client, zipData, options) {
7808
8273
  await client.crypto.init();
7809
8274
  const encData = client.crypto.getEncryptionData();
7810
- const formCode = options?.formCode ?? DEFAULT_FORM_CODE2;
8275
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
7811
8276
  const encryptFn = (part) => client.crypto.encryptAES256(part, encData.cipherKey, encData.cipherIv);
7812
8277
  const { batchFile, encryptedParts } = BatchFileBuilder.build(zipData, encryptFn, {
7813
8278
  maxPartSize: options?.maxPartSize
@@ -7849,6 +8314,72 @@ async function uploadBatch(client, zipData, options) {
7849
8314
  }
7850
8315
  };
7851
8316
  }
8317
+ async function uploadBatchStream(client, zipStreamFactory, zipSize, options) {
8318
+ await client.crypto.init();
8319
+ const encData = client.crypto.getEncryptionData();
8320
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
8321
+ const encryptStreamFn = (stream) => client.crypto.encryptAES256Stream(stream, encData.cipherKey, encData.cipherIv);
8322
+ const hashStreamFn = (stream) => client.crypto.getFileMetadataFromStream(stream);
8323
+ const { batchFile, streamParts } = await BatchFileBuilder.buildFromStream(
8324
+ zipStreamFactory,
8325
+ zipSize,
8326
+ encryptStreamFn,
8327
+ hashStreamFn,
8328
+ { maxPartSize: options?.maxPartSize }
8329
+ );
8330
+ const openResp = await client.batchSession.openSession(
8331
+ {
8332
+ formCode,
8333
+ encryption: encData.encryptionInfo,
8334
+ batchFile,
8335
+ offlineMode: options?.offlineMode
8336
+ },
8337
+ options?.upoVersion
8338
+ );
8339
+ await client.batchSession.sendPartsWithStream(openResp, streamParts);
8340
+ await client.batchSession.closeSession(openResp.referenceNumber);
8341
+ const result = await pollUntil(
8342
+ () => client.sessionStatus.getSessionStatus(openResp.referenceNumber),
8343
+ (s) => s.status.code === 200 || s.status.code >= 400,
8344
+ { ...options?.pollOptions, description: `UPO for batch ${openResp.referenceNumber}` }
8345
+ );
8346
+ if (result.status.code !== 200) {
8347
+ throw new Error(`Batch session failed: ${result.status.code} \u2014 ${result.status.description}`);
8348
+ }
8349
+ return {
8350
+ sessionRef: openResp.referenceNumber,
8351
+ upo: {
8352
+ pages: result.upo?.pages ?? [],
8353
+ invoiceCount: result.invoiceCount,
8354
+ successfulInvoiceCount: result.successfulInvoiceCount,
8355
+ failedInvoiceCount: result.failedInvoiceCount
8356
+ }
8357
+ };
8358
+ }
8359
+ async function uploadBatchStreamParsed(client, zipStreamFactory, zipSize, options) {
8360
+ const result = await uploadBatchStream(client, zipStreamFactory, zipSize, options);
8361
+ const parsed = [];
8362
+ for (const page of result.upo.pages) {
8363
+ const upoResult = await client.sessionStatus.getSessionUpo(result.sessionRef, page.referenceNumber);
8364
+ parsed.push(parseUpoXml(upoResult.upo));
8365
+ }
8366
+ return {
8367
+ sessionRef: result.sessionRef,
8368
+ upo: { ...result.upo, parsed }
8369
+ };
8370
+ }
8371
+ async function uploadBatchParsed(client, zipData, options) {
8372
+ const result = await uploadBatch(client, zipData, options);
8373
+ const parsed = [];
8374
+ for (const page of result.upo.pages) {
8375
+ const upoResult = await client.sessionStatus.getSessionUpo(result.sessionRef, page.referenceNumber);
8376
+ parsed.push(parseUpoXml(upoResult.upo));
8377
+ }
8378
+ return {
8379
+ sessionRef: result.sessionRef,
8380
+ upo: { ...result.upo, parsed }
8381
+ };
8382
+ }
7852
8383
 
7853
8384
  // src/workflows/invoice-export-workflow.ts
7854
8385
  async function doExport(client, filters, options) {
@@ -7872,6 +8403,7 @@ async function doExport(client, filters, options) {
7872
8403
  }
7873
8404
  return {
7874
8405
  encData,
8406
+ referenceNumber: opResp.referenceNumber,
7875
8407
  result: {
7876
8408
  parts: result.package.parts.map((p) => ({
7877
8409
  ordinalNumber: p.ordinalNumber,
@@ -7884,7 +8416,8 @@ async function doExport(client, filters, options) {
7884
8416
  })),
7885
8417
  invoiceCount: result.package.invoiceCount,
7886
8418
  isTruncated: result.package.isTruncated,
7887
- permanentStorageHwmDate: result.package.permanentStorageHwmDate
8419
+ permanentStorageHwmDate: result.package.permanentStorageHwmDate,
8420
+ lastPermanentStorageDate: result.package.lastPermanentStorageDate
7888
8421
  }
7889
8422
  };
7890
8423
  }
@@ -7905,13 +8438,144 @@ async function exportAndDownload(client, filters, options) {
7905
8438
  const decrypted = client.crypto.decryptAES256(encryptedData, encData.cipherKey, encData.cipherIv);
7906
8439
  decryptedParts.push(decrypted);
7907
8440
  }
8441
+ if (options?.extract) {
8442
+ const zipBuffer = Buffer.concat(decryptedParts);
8443
+ const files = await unzip(zipBuffer, options.unzipOptions);
8444
+ return { ...exportResult, files };
8445
+ }
7908
8446
  return {
7909
8447
  ...exportResult,
7910
8448
  decryptedParts
7911
8449
  };
7912
8450
  }
7913
8451
 
8452
+ // src/workflows/hwm-coordinator.ts
8453
+ function updateContinuationPoint(points, subjectType, pkg) {
8454
+ if (pkg.isTruncated && pkg.lastPermanentStorageDate) {
8455
+ points[subjectType] = pkg.lastPermanentStorageDate;
8456
+ } else if (pkg.permanentStorageHwmDate) {
8457
+ points[subjectType] = pkg.permanentStorageHwmDate;
8458
+ } else {
8459
+ delete points[subjectType];
8460
+ }
8461
+ }
8462
+ function getEffectiveStartDate(points, subjectType, windowFrom) {
8463
+ return points[subjectType] ?? windowFrom;
8464
+ }
8465
+ function deduplicateByKsefNumber(entries) {
8466
+ const seen = /* @__PURE__ */ new Set();
8467
+ return entries.filter((entry) => {
8468
+ const key = entry.ksefNumber.toLowerCase();
8469
+ if (seen.has(key)) return false;
8470
+ seen.add(key);
8471
+ return true;
8472
+ });
8473
+ }
8474
+
8475
+ // src/workflows/incremental-export-workflow.ts
8476
+ async function incrementalExportAndDownload(client, options) {
8477
+ const maxIterations = options.maxIterations ?? 20;
8478
+ const points = options.continuationPoints;
8479
+ if (options.store) {
8480
+ const loaded = await options.store.load();
8481
+ for (const [key, value] of Object.entries(loaded)) {
8482
+ if (value !== void 0 && points[key] === void 0) {
8483
+ points[key] = value;
8484
+ }
8485
+ }
8486
+ }
8487
+ const referenceNumbers = [];
8488
+ const decryptedParts = [];
8489
+ let previousFrom;
8490
+ let iteration = 0;
8491
+ for (; iteration < maxIterations; iteration++) {
8492
+ const effectiveFrom = getEffectiveStartDate(points, options.subjectType, options.windowFrom);
8493
+ if (previousFrom !== void 0 && effectiveFrom === previousFrom) {
8494
+ break;
8495
+ }
8496
+ previousFrom = effectiveFrom;
8497
+ const filters = options.filtersFactory ? options.filtersFactory(effectiveFrom, options.windowTo) : buildDefaultFilters(options.subjectType, effectiveFrom, options.windowTo);
8498
+ const { result, encData, referenceNumber } = await doExport(client, filters, {
8499
+ onlyMetadata: options.onlyMetadata,
8500
+ pollOptions: options.pollOptions
8501
+ });
8502
+ referenceNumbers.push(referenceNumber);
8503
+ const download = options.transport ?? fetch;
8504
+ for (const part of result.parts) {
8505
+ const resp = await download(part.url, { method: part.method });
8506
+ if (!resp.ok) {
8507
+ throw new Error(`Download failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
8508
+ }
8509
+ const encryptedData = new Uint8Array(await resp.arrayBuffer());
8510
+ const decrypted = client.crypto.decryptAES256(encryptedData, encData.cipherKey, encData.cipherIv);
8511
+ decryptedParts.push(decrypted);
8512
+ }
8513
+ updateContinuationPoint(points, options.subjectType, {
8514
+ isTruncated: result.isTruncated,
8515
+ lastPermanentStorageDate: result.lastPermanentStorageDate,
8516
+ permanentStorageHwmDate: result.permanentStorageHwmDate
8517
+ });
8518
+ if (options.store) {
8519
+ await options.store.save(points);
8520
+ }
8521
+ options.onIterationComplete?.(iteration, result);
8522
+ if (!result.isTruncated) {
8523
+ iteration++;
8524
+ break;
8525
+ }
8526
+ }
8527
+ return {
8528
+ referenceNumbers,
8529
+ invoices: [],
8530
+ decryptedParts,
8531
+ continuationPoints: points,
8532
+ iterationCount: iteration
8533
+ };
8534
+ }
8535
+ function buildDefaultFilters(subjectType, from, to) {
8536
+ return {
8537
+ subjectType,
8538
+ dateRange: {
8539
+ dateType: "PermanentStorage",
8540
+ from,
8541
+ to
8542
+ }
8543
+ };
8544
+ }
8545
+
8546
+ // src/workflows/hwm-storage.ts
8547
+ import * as fs from "fs/promises";
8548
+ var InMemoryHwmStore = class {
8549
+ points = {};
8550
+ async load() {
8551
+ return { ...this.points };
8552
+ }
8553
+ async save(points) {
8554
+ this.points = { ...points };
8555
+ }
8556
+ };
8557
+ var FileHwmStore = class {
8558
+ constructor(filePath) {
8559
+ this.filePath = filePath;
8560
+ }
8561
+ async load() {
8562
+ try {
8563
+ const data = await fs.readFile(this.filePath, "utf-8");
8564
+ return JSON.parse(data);
8565
+ } catch (err) {
8566
+ if (err.code === "ENOENT") {
8567
+ return {};
8568
+ }
8569
+ throw err;
8570
+ }
8571
+ }
8572
+ async save(points) {
8573
+ await fs.writeFile(this.filePath, JSON.stringify(points, null, 2), "utf-8");
8574
+ }
8575
+ };
8576
+
7914
8577
  // src/workflows/auth-workflow.ts
8578
+ init_auth_xml_builder();
7915
8579
  async function authenticateWithToken(client, options) {
7916
8580
  const challenge = await client.auth.getChallenge();
7917
8581
  await client.crypto.init();
@@ -7965,6 +8629,34 @@ async function authenticateWithCertificate(client, options) {
7965
8629
  refreshTokenValidUntil: tokens.refreshToken.validUntil
7966
8630
  };
7967
8631
  }
8632
+ async function authenticateWithExternalSignature(client, options) {
8633
+ const challenge = await client.auth.getChallenge();
8634
+ const unsignedXml = buildUnsignedAuthTokenRequestXml({
8635
+ challenge: challenge.challenge,
8636
+ contextIdentifier: options.contextIdentifier
8637
+ });
8638
+ const signedXml = await options.signXml(unsignedXml);
8639
+ const submitResult = await client.auth.submitXadesAuthRequest(
8640
+ signedXml,
8641
+ options.verifyCertificateChain ?? false,
8642
+ options.enforceXadesCompliance ?? false
8643
+ );
8644
+ const authToken = submitResult.authenticationToken.token;
8645
+ await pollUntil(
8646
+ () => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
8647
+ (s) => s.status.code !== 100,
8648
+ { ...options.pollOptions, description: `auth ${submitResult.referenceNumber}` }
8649
+ );
8650
+ const tokens = await client.auth.getAccessToken(authToken);
8651
+ client.authManager.setAccessToken(tokens.accessToken.token);
8652
+ client.authManager.setRefreshToken(tokens.refreshToken.token);
8653
+ return {
8654
+ accessToken: tokens.accessToken.token,
8655
+ accessTokenValidUntil: tokens.accessToken.validUntil,
8656
+ refreshToken: tokens.refreshToken.token,
8657
+ refreshTokenValidUntil: tokens.refreshToken.validUntil
8658
+ };
8659
+ }
7968
8660
  async function authenticateWithPkcs12(client, options) {
7969
8661
  const { Pkcs12Loader: Pkcs12Loader2 } = await Promise.resolve().then(() => (init_pkcs12_loader(), pkcs12_loader_exports));
7970
8662
  const { certificatePem, privateKeyPem } = Pkcs12Loader2.load(options.p12, options.password);
@@ -8004,6 +8696,11 @@ export {
8004
8696
  ENFORCE_XADES_COMPLIANCE,
8005
8697
  EntityPermissionGrantBuilder,
8006
8698
  Environment,
8699
+ FORM_CODES,
8700
+ FORM_CODE_KEYS,
8701
+ FileHwmStore,
8702
+ INVOICE_TYPES_BY_SYSTEM_CODE,
8703
+ InMemoryHwmStore,
8007
8704
  InternalId,
8008
8705
  InvoiceDownloadService,
8009
8706
  InvoiceQueryFilterBuilder,
@@ -8049,21 +8746,29 @@ export {
8049
8746
  SessionStatusService,
8050
8747
  Sha256Base64,
8051
8748
  SignatureService,
8749
+ SystemCode,
8052
8750
  TestDataService,
8053
8751
  TokenService,
8054
8752
  UpoVersion,
8055
8753
  VatUe,
8056
8754
  VerificationLinkService,
8057
8755
  authenticateWithCertificate,
8756
+ authenticateWithExternalSignature,
8058
8757
  authenticateWithPkcs12,
8059
8758
  authenticateWithToken,
8759
+ buildUnsignedAuthTokenRequestXml,
8060
8760
  calculateBackoff,
8761
+ createZip,
8762
+ deduplicateByKsefNumber,
8061
8763
  defaultPresignedUrlPolicy,
8062
8764
  defaultRateLimitPolicy,
8063
8765
  defaultRetryPolicy,
8064
8766
  defaultTransport,
8065
8767
  exportAndDownload,
8066
8768
  exportInvoices,
8769
+ getEffectiveStartDate,
8770
+ getFormCode,
8771
+ incrementalExportAndDownload,
8067
8772
  isRetryableError,
8068
8773
  isRetryableStatus,
8069
8774
  isValidBase64,
@@ -8083,11 +8788,19 @@ export {
8083
8788
  isValidVatUe,
8084
8789
  openOnlineSession,
8085
8790
  openSendAndClose,
8791
+ parseFormCode,
8086
8792
  parseRetryAfter,
8793
+ parseUpoXml,
8087
8794
  pollUntil,
8088
8795
  resolveOptions,
8089
8796
  sleep,
8797
+ unzip,
8798
+ updateContinuationPoint,
8090
8799
  uploadBatch,
8800
+ uploadBatchParsed,
8801
+ uploadBatchStream,
8802
+ uploadBatchStreamParsed,
8803
+ validateFormCodeForSession,
8091
8804
  validatePresignedUrl
8092
8805
  };
8093
8806
  //# sourceMappingURL=index.js.map