ksef-client-ts 0.6.1 → 0.6.2

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/README.md CHANGED
@@ -6,7 +6,7 @@ TypeScript client for the Polish National e-Invoice System (KSeF) API v2.
6
6
 
7
7
  ## Features
8
8
 
9
- - **Complete API coverage** — KSeF API v2.3.0, types aligned with the official OpenAPI spec
9
+ - **Complete API coverage** — KSeF API v2.4.0, types aligned with the official OpenAPI spec
10
10
  - **Offline invoice mode** — full lifecycle for all 4 KSeF offline modes with QR KOD I + KOD II signing, deadline tracking, local storage, and technical correction
11
11
  - **Full-featured CLI** — `ksef` with 15 command groups for auth, sessions, invoices, offline, batch upload, export, and more
12
12
  - **High-level workflows** — auth, online/batch sessions, invoice export — full lifecycle in a single call
package/dist/cli.js CHANGED
@@ -97,12 +97,14 @@ var init_ksef_unauthorized_error = __esm({
97
97
  detail;
98
98
  traceId;
99
99
  instance;
100
+ timestamp;
100
101
  constructor(problemDetails) {
101
102
  super(problemDetails.detail || "Unauthorized");
102
103
  this.name = "KSeFUnauthorizedError";
103
104
  this.detail = problemDetails.detail;
104
105
  this.traceId = problemDetails.traceId;
105
106
  this.instance = problemDetails.instance;
107
+ this.timestamp = problemDetails.timestamp;
106
108
  }
107
109
  };
108
110
  }
@@ -121,6 +123,7 @@ var init_ksef_forbidden_error = __esm({
121
123
  instance;
122
124
  security;
123
125
  traceId;
126
+ timestamp;
124
127
  constructor(problemDetails) {
125
128
  super(problemDetails.detail || "Forbidden");
126
129
  this.name = "KSeFForbiddenError";
@@ -129,6 +132,7 @@ var init_ksef_forbidden_error = __esm({
129
132
  this.instance = problemDetails.instance;
130
133
  this.security = problemDetails.security;
131
134
  this.traceId = problemDetails.traceId;
135
+ this.timestamp = problemDetails.timestamp;
132
136
  }
133
137
  };
134
138
  }
@@ -219,6 +223,69 @@ var init_config = __esm({
219
223
  }
220
224
  });
221
225
 
226
+ // src/errors/ksef-gone-error.ts
227
+ var KSeFGoneError;
228
+ var init_ksef_gone_error = __esm({
229
+ "src/errors/ksef-gone-error.ts"() {
230
+ "use strict";
231
+ init_ksef_error();
232
+ KSeFGoneError = class extends KSeFError {
233
+ statusCode = 410;
234
+ detail;
235
+ instance;
236
+ traceId;
237
+ timestamp;
238
+ constructor(problemDetails) {
239
+ super(problemDetails.detail || "Operation status no longer available (retention expired)");
240
+ this.name = "KSeFGoneError";
241
+ this.detail = problemDetails.detail;
242
+ this.instance = problemDetails.instance;
243
+ this.traceId = problemDetails.traceId;
244
+ this.timestamp = problemDetails.timestamp;
245
+ }
246
+ };
247
+ }
248
+ });
249
+
250
+ // src/errors/error-codes.ts
251
+ function hasErrorCode(body, code) {
252
+ return !!body?.exception?.exceptionDetailList?.some((d) => d.exceptionCode === code);
253
+ }
254
+ var KSeFErrorCode;
255
+ var init_error_codes = __esm({
256
+ "src/errors/error-codes.ts"() {
257
+ "use strict";
258
+ KSeFErrorCode = {
259
+ BatchTimeout: 21208,
260
+ DuplicateInvoice: 440
261
+ };
262
+ }
263
+ });
264
+
265
+ // src/errors/ksef-batch-timeout-error.ts
266
+ var KSeFBatchTimeoutError;
267
+ var init_ksef_batch_timeout_error = __esm({
268
+ "src/errors/ksef-batch-timeout-error.ts"() {
269
+ "use strict";
270
+ init_ksef_api_error();
271
+ init_error_codes();
272
+ KSeFBatchTimeoutError = class _KSeFBatchTimeoutError extends KSeFApiError {
273
+ errorCode = KSeFErrorCode.BatchTimeout;
274
+ constructor(message, statusCode, errorResponse) {
275
+ super(message, statusCode, errorResponse);
276
+ this.name = "KSeFBatchTimeoutError";
277
+ }
278
+ static fromResponse(statusCode, body) {
279
+ const detail = body?.exception?.exceptionDetailList?.find(
280
+ (d) => d.exceptionCode === KSeFErrorCode.BatchTimeout
281
+ );
282
+ const message = detail?.exceptionDescription?.trim() || "Batch session timed out before the server completed processing (KSeF 21208).";
283
+ return new _KSeFBatchTimeoutError(message, statusCode, body);
284
+ }
285
+ };
286
+ }
287
+ });
288
+
222
289
  // src/http/route-builder.ts
223
290
  var RouteBuilder;
224
291
  var init_route_builder = __esm({
@@ -396,6 +463,9 @@ var init_rest_client = __esm({
396
463
  init_ksef_rate_limit_error();
397
464
  init_ksef_unauthorized_error();
398
465
  init_ksef_forbidden_error();
466
+ init_ksef_gone_error();
467
+ init_ksef_batch_timeout_error();
468
+ init_error_codes();
399
469
  init_route_builder();
400
470
  init_transport();
401
471
  init_retry_policy();
@@ -536,18 +606,33 @@ var init_rest_client = __esm({
536
606
  );
537
607
  }
538
608
  if (response.status === 401) {
539
- const body = parseJson();
540
- if (body?.detail) {
541
- throw new KSeFUnauthorizedError(body);
609
+ const body2 = parseJson();
610
+ if (body2?.detail) {
611
+ throw new KSeFUnauthorizedError(body2);
542
612
  }
543
613
  }
544
614
  if (response.status === 403) {
545
- const body = parseJson();
546
- if (body?.reasonCode) {
547
- throw new KSeFForbiddenError(body);
615
+ const body2 = parseJson();
616
+ if (body2?.reasonCode) {
617
+ throw new KSeFForbiddenError(body2);
548
618
  }
549
619
  }
550
- throw KSeFApiError.fromResponse(response.status, parseJson());
620
+ if (response.status === 410) {
621
+ const body2 = parseJson();
622
+ throw new KSeFGoneError({
623
+ title: body2?.title || "Gone",
624
+ status: body2?.status || 410,
625
+ detail: body2?.detail || "Operation status no longer available (retention expired)",
626
+ instance: body2?.instance,
627
+ traceId: body2?.traceId,
628
+ timestamp: body2?.timestamp
629
+ });
630
+ }
631
+ const body = parseJson();
632
+ if (hasErrorCode(body, KSeFErrorCode.BatchTimeout)) {
633
+ throw KSeFBatchTimeoutError.fromResponse(response.status, body);
634
+ }
635
+ throw KSeFApiError.fromResponse(response.status, body);
551
636
  }
552
637
  };
553
638
  }
@@ -1503,9 +1588,12 @@ var init_errors = __esm({
1503
1588
  init_ksef_rate_limit_error();
1504
1589
  init_ksef_unauthorized_error();
1505
1590
  init_ksef_forbidden_error();
1591
+ init_ksef_gone_error();
1506
1592
  init_ksef_auth_status_error();
1507
1593
  init_ksef_session_expired_error();
1508
1594
  init_ksef_validation_error();
1595
+ init_ksef_batch_timeout_error();
1596
+ init_error_codes();
1509
1597
  }
1510
1598
  });
1511
1599
 
@@ -3060,6 +3148,7 @@ var init_client = __esm({
3060
3148
  const tokens = await this.auth.getAccessToken(authToken);
3061
3149
  this.authManager.setAccessToken(tokens.accessToken.token);
3062
3150
  this.authManager.setRefreshToken(tokens.refreshToken.token);
3151
+ return { clientIp: challenge2.clientIp };
3063
3152
  }
3064
3153
  async loginWithCertificate(certPem, keyPem, nip, keyPassword) {
3065
3154
  const challenge2 = await this.auth.getChallenge();
@@ -3072,11 +3161,12 @@ var init_client = __esm({
3072
3161
  const tokens = await this.auth.getAccessToken(authToken);
3073
3162
  this.authManager.setAccessToken(tokens.accessToken.token);
3074
3163
  this.authManager.setRefreshToken(tokens.refreshToken.token);
3164
+ return { clientIp: challenge2.clientIp };
3075
3165
  }
3076
3166
  async loginWithPkcs12(p12, password, nip) {
3077
3167
  const { Pkcs12Loader: Pkcs12Loader2 } = await Promise.resolve().then(() => (init_pkcs12_loader(), pkcs12_loader_exports));
3078
3168
  const { certificatePem, privateKeyPem } = Pkcs12Loader2.load(p12, password);
3079
- await this.loginWithCertificate(certificatePem, privateKeyPem, nip);
3169
+ return this.loginWithCertificate(certificatePem, privateKeyPem, nip);
3080
3170
  }
3081
3171
  async awaitAuthReady(referenceNumber, authToken) {
3082
3172
  for (let i = 0; i < 30; i++) {
@@ -6056,17 +6146,18 @@ var login = defineCommand2({
6056
6146
  throw new Error("NIP is required. Provide --nip or set it via `ksef config set --nip <nip>`.");
6057
6147
  }
6058
6148
  const token = args.token ?? loadCredentials()?.token;
6149
+ let loginResult;
6059
6150
  if (token) {
6060
- await client.loginWithToken(token, nip);
6151
+ loginResult = await client.loginWithToken(token, nip);
6061
6152
  } else if (args.p12) {
6062
6153
  const fs15 = await import("fs");
6063
6154
  const p12Buffer = fs15.readFileSync(args.p12);
6064
- await client.loginWithPkcs12(p12Buffer, args["p12-password"] ?? "", nip);
6155
+ loginResult = await client.loginWithPkcs12(p12Buffer, args["p12-password"] ?? "", nip);
6065
6156
  } else if (args.cert && args.key) {
6066
6157
  const fs15 = await import("fs");
6067
6158
  const certPem = fs15.readFileSync(args.cert, "utf-8");
6068
6159
  const keyPem = fs15.readFileSync(args.key, "utf-8");
6069
- await client.loginWithCertificate(certPem, keyPem, nip, args["key-password"]);
6160
+ loginResult = await client.loginWithCertificate(certPem, keyPem, nip, args["key-password"]);
6070
6161
  } else {
6071
6162
  throw new Error("Provide --token, --p12, or both --cert and --key for authentication.");
6072
6163
  }
@@ -6081,7 +6172,12 @@ var login = defineCommand2({
6081
6172
  if (args.env && args.env !== config.environment) {
6082
6173
  saveConfig({ ...config, environment: session.environment });
6083
6174
  }
6084
- outputSuccess("Logged in successfully.");
6175
+ if (args.json) {
6176
+ console.log(JSON.stringify({ status: "ok", clientIp: loginResult.clientIp }, null, 2));
6177
+ } else {
6178
+ consola6.info(`Seen client IP: ${loginResult.clientIp}`);
6179
+ outputSuccess("Logged in successfully.");
6180
+ }
6085
6181
  });
6086
6182
  }
6087
6183
  });
@@ -6244,6 +6340,8 @@ var loginExternal = defineCommand2({
6244
6340
  process.stderr.write(`Challenge: ${challengeResult.challenge}
6245
6341
  `);
6246
6342
  process.stderr.write(`Timestamp: ${challengeResult.timestamp}
6343
+ `);
6344
+ process.stderr.write(`Seen client IP: ${challengeResult.clientIp}
6247
6345
  `);
6248
6346
  process.stderr.write(`Note: Sign this XML and submit with --submit before the challenge expires.
6249
6347
  `);
@@ -6444,6 +6542,7 @@ var list = defineCommand3({
6444
6542
  reference: s.referenceNumber,
6445
6543
  status: `${s.status.code} \u2014 ${s.status.description}`,
6446
6544
  created: s.dateCreated,
6545
+ updated: s.dateUpdated,
6447
6546
  total: s.totalInvoiceCount,
6448
6547
  success: s.successfulInvoiceCount,
6449
6548
  failed: s.failedInvoiceCount
@@ -6452,6 +6551,7 @@ var list = defineCommand3({
6452
6551
  { key: "reference", label: "Reference" },
6453
6552
  { key: "status", label: "Status" },
6454
6553
  { key: "created", label: "Created" },
6554
+ { key: "updated", label: "Updated" },
6455
6555
  { key: "total", label: "Total" },
6456
6556
  { key: "success", label: "Success" },
6457
6557
  { key: "failed", label: "Failed" }
@@ -7078,8 +7178,8 @@ var QUERY_FILTER_ARGS = {
7078
7178
  dateType: { type: "string", description: "Date type: Issue|Invoicing|PermanentStorage (default: Invoicing)" },
7079
7179
  sellerNip: { type: "string", description: "Filter by seller NIP" },
7080
7180
  buyerNip: { type: "string", description: "Filter by buyer NIP" },
7081
- amountFrom: { type: "string", description: "Minimum amount" },
7082
- amountTo: { type: "string", description: "Maximum amount" },
7181
+ amountFrom: { type: "string", description: "Minimum amount (negative values allowed)" },
7182
+ amountTo: { type: "string", description: "Maximum amount (negative values allowed)" },
7083
7183
  amountType: { type: "string", description: "Amount type: Brutto|Netto|Vat (default: Brutto)" },
7084
7184
  currency: { type: "string", description: "Currency code (e.g. PLN, EUR)" }
7085
7185
  };