ksef-client-ts 0.9.0 → 0.9.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/dist/index.cjs CHANGED
@@ -401,6 +401,25 @@ var init_ksef_validation_error = __esm({
401
401
  }
402
402
  });
403
403
 
404
+ // src/errors/ksef-metadata-pagination-error.ts
405
+ var KSeFMetadataPaginationError;
406
+ var init_ksef_metadata_pagination_error = __esm({
407
+ "src/errors/ksef-metadata-pagination-error.ts"() {
408
+ "use strict";
409
+ init_cjs_shims();
410
+ init_ksef_error();
411
+ KSeFMetadataPaginationError = class extends KSeFError {
412
+ /** The boundary date value that failed to advance. */
413
+ boundaryValue;
414
+ constructor(message, boundaryValue) {
415
+ super(message);
416
+ this.name = "KSeFMetadataPaginationError";
417
+ this.boundaryValue = boundaryValue;
418
+ }
419
+ };
420
+ }
421
+ });
422
+
404
423
  // src/errors/error-codes.ts
405
424
  function hasErrorCode(body, code) {
406
425
  return !!body?.exception?.exceptionDetailList?.some((d) => d.exceptionCode === code);
@@ -548,6 +567,7 @@ var init_errors = __esm({
548
567
  init_ksef_auth_status_error();
549
568
  init_ksef_session_expired_error();
550
569
  init_ksef_validation_error();
570
+ init_ksef_metadata_pagination_error();
551
571
  init_ksef_batch_timeout_error();
552
572
  init_ksef_unknown_public_key_error();
553
573
  init_ksef_circuit_open_error();
@@ -1569,6 +1589,9 @@ function isValidCertificateName(value) {
1569
1589
  function isValidCertificateFingerprint(value) {
1570
1590
  return CertificateFingerprint.test(value);
1571
1591
  }
1592
+ function isValidCertificateSerialNumber(value) {
1593
+ return CertificateSerialNumber.test(value);
1594
+ }
1572
1595
  function isValidBase64(value) {
1573
1596
  return Base64String.test(value);
1574
1597
  }
@@ -1578,7 +1601,7 @@ function isValidIp4Address(value) {
1578
1601
  function isValidSha256Base64(value) {
1579
1602
  return Sha256Base64.test(value);
1580
1603
  }
1581
- var NIP_PATTERN_CORE, VAT_UE_PATTERN_CORE, Nip, VatUe, NipVatUe, InternalId, PeppolId, ReferenceNumber, KsefNumber, KsefNumberV35, KsefNumberV36, CertificateName, Pesel, CertificateFingerprint, Base64String, Ip4Address, Ip4Range, Ip4Mask, Sha256Base64, NIP_WEIGHTS, PESEL_WEIGHTS, CRC8_POLY;
1604
+ var NIP_PATTERN_CORE, VAT_UE_PATTERN_CORE, Nip, VatUe, NipVatUe, InternalId, PeppolId, ReferenceNumber, KsefNumber, KsefNumberV35, KsefNumberV36, CertificateName, Pesel, CertificateFingerprint, CertificateSerialNumber, Base64String, Ip4Address, Ip4Range, Ip4Mask, Sha256Base64, NIP_WEIGHTS, PESEL_WEIGHTS, CRC8_POLY;
1582
1605
  var init_patterns = __esm({
1583
1606
  "src/validation/patterns.ts"() {
1584
1607
  "use strict";
@@ -1597,6 +1620,7 @@ var init_patterns = __esm({
1597
1620
  CertificateName = /^[a-zA-Z0-9_\- ąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+$/;
1598
1621
  Pesel = /^\d{2}(?:0[1-9]|1[0-2]|2[1-9]|3[0-2]|4[1-9]|5[0-2]|6[1-9]|7[0-2]|8[1-9]|9[0-2])\d{7}$/;
1599
1622
  CertificateFingerprint = /^[0-9A-F]{64}$/;
1623
+ CertificateSerialNumber = /^[0-9A-F]{16}$/;
1600
1624
  Base64String = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
1601
1625
  Ip4Address = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
1602
1626
  Ip4Range = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}-((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
@@ -4053,6 +4077,8 @@ var init_certificates = __esm({
4053
4077
  init_cjs_shims();
4054
4078
  init_rest_request();
4055
4079
  init_routes();
4080
+ init_ksef_validation_error();
4081
+ init_patterns();
4056
4082
  CertificateApiService = class {
4057
4083
  restClient;
4058
4084
  constructor(restClient) {
@@ -4079,6 +4105,14 @@ var init_certificates = __esm({
4079
4105
  return response.body;
4080
4106
  }
4081
4107
  async retrieve(request) {
4108
+ for (const serial of request.certificateSerialNumbers ?? []) {
4109
+ if (!isValidCertificateSerialNumber(serial)) {
4110
+ throw KSeFValidationError.fromField(
4111
+ "certificateSerialNumbers",
4112
+ `Invalid certificate serial number "${serial}": must be exactly 16 uppercase hex characters (^[0-9A-F]{16}$)`
4113
+ );
4114
+ }
4115
+ }
4082
4116
  const req = RestRequest.post(Routes.Certificates.retrieve).body(request);
4083
4117
  const response = await this.restClient.execute(req);
4084
4118
  return response.body;
@@ -6069,6 +6103,7 @@ __export(index_exports, {
6069
6103
  CertificateFetcher: () => CertificateFetcher,
6070
6104
  CertificateFingerprint: () => CertificateFingerprint,
6071
6105
  CertificateName: () => CertificateName,
6106
+ CertificateSerialNumber: () => CertificateSerialNumber,
6072
6107
  CertificateService: () => CertificateService,
6073
6108
  CircuitBreakerPolicy: () => CircuitBreakerPolicy,
6074
6109
  CryptographyService: () => CryptographyService,
@@ -6105,6 +6140,7 @@ __export(index_exports, {
6105
6140
  KSeFErrorCode: () => KSeFErrorCode,
6106
6141
  KSeFForbiddenError: () => KSeFForbiddenError,
6107
6142
  KSeFGoneError: () => KSeFGoneError,
6143
+ KSeFMetadataPaginationError: () => KSeFMetadataPaginationError,
6108
6144
  KSeFRateLimitError: () => KSeFRateLimitError,
6109
6145
  KSeFSessionExpiredError: () => KSeFSessionExpiredError,
6110
6146
  KSeFUnauthorizedError: () => KSeFUnauthorizedError,
@@ -6166,6 +6202,7 @@ __export(index_exports, {
6166
6202
  buildXmlFromObject: () => buildXmlFromObject,
6167
6203
  calculateBackoff: () => calculateBackoff,
6168
6204
  calculateOfflineDeadline: () => calculateOfflineDeadline,
6205
+ collectAllInvoiceMetadata: () => collectAllInvoiceMetadata,
6169
6206
  comparePKey: () => comparePKey,
6170
6207
  createTarGz: () => createTarGz,
6171
6208
  createZip: () => createZip,
@@ -6198,6 +6235,7 @@ __export(index_exports, {
6198
6235
  isValidBase64: () => isValidBase64,
6199
6236
  isValidCertificateFingerprint: () => isValidCertificateFingerprint,
6200
6237
  isValidCertificateName: () => isValidCertificateName,
6238
+ isValidCertificateSerialNumber: () => isValidCertificateSerialNumber,
6201
6239
  isValidInternalId: () => isValidInternalId,
6202
6240
  isValidIp4Address: () => isValidIp4Address,
6203
6241
  isValidKsefNumber: () => isValidKsefNumber,
@@ -6221,6 +6259,7 @@ __export(index_exports, {
6221
6259
  parseUpoXml: () => parseUpoXml,
6222
6260
  parseXml: () => parseXml,
6223
6261
  pollUntil: () => pollUntil,
6262
+ queryAllInvoiceMetadata: () => queryAllInvoiceMetadata,
6224
6263
  resolveOptions: () => resolveOptions,
6225
6264
  resolveXsdFor: () => resolveXsdFor,
6226
6265
  resumeOnlineSession: () => resumeOnlineSession,
@@ -8451,6 +8490,33 @@ var FileHwmStore = class {
8451
8490
  init_cjs_shims();
8452
8491
  init_auth_xml_builder();
8453
8492
  init_with_key_rotation_retry();
8493
+ init_ksef_auth_status_error();
8494
+ var AUTH_STATUS_SUCCESS = 200;
8495
+ var AUTH_STATUS_IN_PROGRESS = 100;
8496
+ async function awaitAuthentication(client, referenceNumber, authToken, pollOptions) {
8497
+ const final = await pollUntil(
8498
+ () => client.auth.getAuthStatus(referenceNumber, authToken),
8499
+ (s) => s.status.code !== AUTH_STATUS_IN_PROGRESS,
8500
+ { ...pollOptions, description: `auth ${referenceNumber}` }
8501
+ );
8502
+ if (final.status.code !== AUTH_STATUS_SUCCESS) {
8503
+ const details = final.status.details?.length ? ` (${final.status.details.join("; ")})` : "";
8504
+ throw new KSeFAuthStatusError(
8505
+ `Authentication failed with status ${final.status.code}: ${final.status.description}${details}`,
8506
+ referenceNumber,
8507
+ final.status.description
8508
+ );
8509
+ }
8510
+ const tokens = await client.auth.getAccessToken(authToken);
8511
+ client.authManager.setAccessToken(tokens.accessToken.token);
8512
+ client.authManager.setRefreshToken(tokens.refreshToken.token);
8513
+ return {
8514
+ accessToken: tokens.accessToken.token,
8515
+ accessTokenValidUntil: tokens.accessToken.validUntil,
8516
+ refreshToken: tokens.refreshToken.token,
8517
+ refreshTokenValidUntil: tokens.refreshToken.validUntil
8518
+ };
8519
+ }
8454
8520
  async function authenticateWithToken(client, options) {
8455
8521
  const challenge = await client.auth.getChallenge();
8456
8522
  await client.crypto.init();
@@ -8465,20 +8531,7 @@ async function authenticateWithToken(client, options) {
8465
8531
  });
8466
8532
  });
8467
8533
  const authToken = submitResult.authenticationToken.token;
8468
- await pollUntil(
8469
- () => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
8470
- (s) => s.status.code !== 100,
8471
- { ...options.pollOptions, description: `auth ${submitResult.referenceNumber}` }
8472
- );
8473
- const tokens = await client.auth.getAccessToken(authToken);
8474
- client.authManager.setAccessToken(tokens.accessToken.token);
8475
- client.authManager.setRefreshToken(tokens.refreshToken.token);
8476
- return {
8477
- accessToken: tokens.accessToken.token,
8478
- accessTokenValidUntil: tokens.accessToken.validUntil,
8479
- refreshToken: tokens.refreshToken.token,
8480
- refreshTokenValidUntil: tokens.refreshToken.validUntil
8481
- };
8534
+ return awaitAuthentication(client, submitResult.referenceNumber, authToken, options.pollOptions);
8482
8535
  }
8483
8536
  async function authenticateWithCertificate(client, options) {
8484
8537
  const challenge = await client.auth.getChallenge();
@@ -8492,20 +8545,7 @@ async function authenticateWithCertificate(client, options) {
8492
8545
  options.enforceXadesCompliance ?? false
8493
8546
  );
8494
8547
  const authToken = submitResult.authenticationToken.token;
8495
- await pollUntil(
8496
- () => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
8497
- (s) => s.status.code !== 100,
8498
- { ...options.pollOptions, description: `auth ${submitResult.referenceNumber}` }
8499
- );
8500
- const tokens = await client.auth.getAccessToken(authToken);
8501
- client.authManager.setAccessToken(tokens.accessToken.token);
8502
- client.authManager.setRefreshToken(tokens.refreshToken.token);
8503
- return {
8504
- accessToken: tokens.accessToken.token,
8505
- accessTokenValidUntil: tokens.accessToken.validUntil,
8506
- refreshToken: tokens.refreshToken.token,
8507
- refreshTokenValidUntil: tokens.refreshToken.validUntil
8508
- };
8548
+ return awaitAuthentication(client, submitResult.referenceNumber, authToken, options.pollOptions);
8509
8549
  }
8510
8550
  async function authenticateWithExternalSignature(client, options) {
8511
8551
  const challenge = await client.auth.getChallenge();
@@ -8520,20 +8560,7 @@ async function authenticateWithExternalSignature(client, options) {
8520
8560
  options.enforceXadesCompliance ?? false
8521
8561
  );
8522
8562
  const authToken = submitResult.authenticationToken.token;
8523
- await pollUntil(
8524
- () => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
8525
- (s) => s.status.code !== 100,
8526
- { ...options.pollOptions, description: `auth ${submitResult.referenceNumber}` }
8527
- );
8528
- const tokens = await client.auth.getAccessToken(authToken);
8529
- client.authManager.setAccessToken(tokens.accessToken.token);
8530
- client.authManager.setRefreshToken(tokens.refreshToken.token);
8531
- return {
8532
- accessToken: tokens.accessToken.token,
8533
- accessTokenValidUntil: tokens.accessToken.validUntil,
8534
- refreshToken: tokens.refreshToken.token,
8535
- refreshTokenValidUntil: tokens.refreshToken.validUntil
8536
- };
8563
+ return awaitAuthentication(client, submitResult.referenceNumber, authToken, options.pollOptions);
8537
8564
  }
8538
8565
  async function authenticateWithPkcs12(client, options) {
8539
8566
  const { Pkcs12Loader: Pkcs12Loader2 } = await Promise.resolve().then(() => (init_pkcs12_loader(), pkcs12_loader_exports));
@@ -8548,6 +8575,95 @@ async function authenticateWithPkcs12(client, options) {
8548
8575
  });
8549
8576
  }
8550
8577
 
8578
+ // src/workflows/metadata-query-paging.ts
8579
+ init_cjs_shims();
8580
+ init_ksef_metadata_pagination_error();
8581
+ init_ksef_validation_error();
8582
+ var DEFAULT_PAGE_SIZE = 100;
8583
+ var DEFAULT_MAX_BOUNDARY_CROSSINGS = 1e3;
8584
+ function boundaryFieldFor(dateType) {
8585
+ switch (dateType) {
8586
+ case "Issue":
8587
+ return "issueDate";
8588
+ case "Invoicing":
8589
+ return "invoicingDate";
8590
+ case "PermanentStorage":
8591
+ return "permanentStorageDate";
8592
+ }
8593
+ }
8594
+ async function* queryAllInvoiceMetadata(client, filters, options = {}) {
8595
+ const sortOrder = options.sortOrder ?? "Asc";
8596
+ const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;
8597
+ const maxBoundaryCrossings = options.maxBoundaryCrossings ?? DEFAULT_MAX_BOUNDARY_CROSSINGS;
8598
+ if (!Number.isInteger(pageSize) || pageSize <= 0) {
8599
+ throw new KSeFValidationError("`pageSize` must be a positive integer.");
8600
+ }
8601
+ if (!Number.isInteger(maxBoundaryCrossings) || maxBoundaryCrossings < 0) {
8602
+ throw new KSeFValidationError("`maxBoundaryCrossings` must be a non-negative integer.");
8603
+ }
8604
+ const boundaryField = boundaryFieldFor(filters.dateRange.dateType);
8605
+ let dateRange = { ...filters.dateRange };
8606
+ let boundaryCrossings = 0;
8607
+ let carryKeys = /* @__PURE__ */ new Set();
8608
+ let carryValue;
8609
+ for (; ; ) {
8610
+ let pageIndex = 0;
8611
+ let lastBoundaryValue;
8612
+ let isTruncated = false;
8613
+ let boundaryKeys = /* @__PURE__ */ new Set();
8614
+ for (; ; ) {
8615
+ const window = { ...filters, dateRange };
8616
+ const response = await client.invoices.queryInvoiceMetadata(
8617
+ window,
8618
+ pageIndex,
8619
+ pageSize,
8620
+ sortOrder
8621
+ );
8622
+ isTruncated = response.isTruncated;
8623
+ for (const invoice of response.invoices) {
8624
+ const boundaryValue = invoice[boundaryField];
8625
+ const key = invoice.ksefNumber.toLowerCase();
8626
+ if (boundaryValue === carryValue && carryKeys.has(key)) continue;
8627
+ if (boundaryValue !== lastBoundaryValue) {
8628
+ lastBoundaryValue = boundaryValue;
8629
+ boundaryKeys = /* @__PURE__ */ new Set();
8630
+ }
8631
+ boundaryKeys.add(key);
8632
+ yield invoice;
8633
+ }
8634
+ if (response.hasMore) {
8635
+ pageIndex += 1;
8636
+ continue;
8637
+ }
8638
+ break;
8639
+ }
8640
+ if (!isTruncated || lastBoundaryValue === void 0) return;
8641
+ const previousBoundary = sortOrder === "Asc" ? dateRange.from : dateRange.to;
8642
+ if (previousBoundary === lastBoundaryValue) {
8643
+ throw new KSeFMetadataPaginationError(
8644
+ `Metadata paging stalled: a truncated window did not advance past ${boundaryField}=${lastBoundaryValue}. The result set likely exceeds the server cap within a single ${boundaryField} value; narrow the query further.`,
8645
+ lastBoundaryValue
8646
+ );
8647
+ }
8648
+ if (++boundaryCrossings > maxBoundaryCrossings) {
8649
+ throw new KSeFMetadataPaginationError(
8650
+ `Metadata paging exceeded ${maxBoundaryCrossings} truncation boundaries; aborting to avoid an unbounded loop.`,
8651
+ lastBoundaryValue
8652
+ );
8653
+ }
8654
+ carryKeys = boundaryKeys;
8655
+ carryValue = lastBoundaryValue;
8656
+ dateRange = sortOrder === "Asc" ? { ...dateRange, from: lastBoundaryValue } : { ...dateRange, to: lastBoundaryValue };
8657
+ }
8658
+ }
8659
+ async function collectAllInvoiceMetadata(client, filters, options = {}) {
8660
+ const all = [];
8661
+ for await (const invoice of queryAllInvoiceMetadata(client, filters, options)) {
8662
+ all.push(invoice);
8663
+ }
8664
+ return all;
8665
+ }
8666
+
8551
8667
  // src/offline/index.ts
8552
8668
  init_cjs_shims();
8553
8669
  init_deadline();
@@ -8706,6 +8822,7 @@ init_client();
8706
8822
  CertificateFetcher,
8707
8823
  CertificateFingerprint,
8708
8824
  CertificateName,
8825
+ CertificateSerialNumber,
8709
8826
  CertificateService,
8710
8827
  CircuitBreakerPolicy,
8711
8828
  CryptographyService,
@@ -8742,6 +8859,7 @@ init_client();
8742
8859
  KSeFErrorCode,
8743
8860
  KSeFForbiddenError,
8744
8861
  KSeFGoneError,
8862
+ KSeFMetadataPaginationError,
8745
8863
  KSeFRateLimitError,
8746
8864
  KSeFSessionExpiredError,
8747
8865
  KSeFUnauthorizedError,
@@ -8803,6 +8921,7 @@ init_client();
8803
8921
  buildXmlFromObject,
8804
8922
  calculateBackoff,
8805
8923
  calculateOfflineDeadline,
8924
+ collectAllInvoiceMetadata,
8806
8925
  comparePKey,
8807
8926
  createTarGz,
8808
8927
  createZip,
@@ -8835,6 +8954,7 @@ init_client();
8835
8954
  isValidBase64,
8836
8955
  isValidCertificateFingerprint,
8837
8956
  isValidCertificateName,
8957
+ isValidCertificateSerialNumber,
8838
8958
  isValidInternalId,
8839
8959
  isValidIp4Address,
8840
8960
  isValidKsefNumber,
@@ -8858,6 +8978,7 @@ init_client();
8858
8978
  parseUpoXml,
8859
8979
  parseXml,
8860
8980
  pollUntil,
8981
+ queryAllInvoiceMetadata,
8861
8982
  resolveOptions,
8862
8983
  resolveXsdFor,
8863
8984
  resumeOnlineSession,