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/cli.js CHANGED
@@ -32,6 +32,74 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
32
32
  mod
33
33
  ));
34
34
 
35
+ // src/errors/ksef-error.ts
36
+ var KSeFError;
37
+ var init_ksef_error = __esm({
38
+ "src/errors/ksef-error.ts"() {
39
+ "use strict";
40
+ KSeFError = class extends Error {
41
+ constructor(message) {
42
+ super(message);
43
+ this.name = "KSeFError";
44
+ }
45
+ };
46
+ }
47
+ });
48
+
49
+ // src/errors/ksef-validation-error.ts
50
+ var KSeFValidationError;
51
+ var init_ksef_validation_error = __esm({
52
+ "src/errors/ksef-validation-error.ts"() {
53
+ "use strict";
54
+ init_ksef_error();
55
+ KSeFValidationError = class _KSeFValidationError extends KSeFError {
56
+ details;
57
+ constructor(message, details = []) {
58
+ super(message);
59
+ this.name = "KSeFValidationError";
60
+ this.details = details;
61
+ }
62
+ static fromField(field, message) {
63
+ return new _KSeFValidationError(message, [{ field, message }]);
64
+ }
65
+ static fromMessages(messages2) {
66
+ const details = messages2.map((m) => ({ message: m }));
67
+ return new _KSeFValidationError(messages2.join("; "), details);
68
+ }
69
+ };
70
+ }
71
+ });
72
+
73
+ // src/crypto/auth-xml-builder.ts
74
+ var auth_xml_builder_exports = {};
75
+ __export(auth_xml_builder_exports, {
76
+ buildUnsignedAuthTokenRequestXml: () => buildUnsignedAuthTokenRequestXml
77
+ });
78
+ function buildUnsignedAuthTokenRequestXml(options) {
79
+ const { challenge: challenge2, contextIdentifier, subjectIdentifierType = "certificateSubject" } = options;
80
+ const identifierElement = `<${contextIdentifier.type}>${xmlEscape(contextIdentifier.value)}</${contextIdentifier.type}>`;
81
+ return [
82
+ '<?xml version="1.0" encoding="utf-8"?>',
83
+ `<AuthTokenRequest xmlns="${AUTH_TOKEN_REQUEST_NS}">`,
84
+ `<Challenge>${xmlEscape(challenge2)}</Challenge>`,
85
+ `<ContextIdentifier>`,
86
+ identifierElement,
87
+ `</ContextIdentifier>`,
88
+ `<SubjectIdentifierType>${xmlEscape(subjectIdentifierType)}</SubjectIdentifierType>`,
89
+ `</AuthTokenRequest>`
90
+ ].join("");
91
+ }
92
+ function xmlEscape(str) {
93
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
94
+ }
95
+ var AUTH_TOKEN_REQUEST_NS;
96
+ var init_auth_xml_builder = __esm({
97
+ "src/crypto/auth-xml-builder.ts"() {
98
+ "use strict";
99
+ AUTH_TOKEN_REQUEST_NS = "http://ksef.mf.gov.pl/auth/token/2.0";
100
+ }
101
+ });
102
+
35
103
  // node_modules/@xmldom/xmldom/lib/conventions.js
36
104
  var require_conventions = __commonJS({
37
105
  "node_modules/@xmldom/xmldom/lib/conventions.js"(exports) {
@@ -456,7 +524,7 @@ var require_dom = __commonJS({
456
524
  * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
457
525
  * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
458
526
  */
459
- hasFeature: function(feature, version) {
527
+ hasFeature: function(feature, version2) {
460
528
  return true;
461
529
  },
462
530
  /**
@@ -577,8 +645,8 @@ var require_dom = __commonJS({
577
645
  }
578
646
  },
579
647
  // Introduced in DOM Level 2:
580
- isSupported: function(feature, version) {
581
- return this.ownerDocument.implementation.hasFeature(feature, version);
648
+ isSupported: function(feature, version2) {
649
+ return this.ownerDocument.implementation.hasFeature(feature, version2);
582
650
  },
583
651
  // Introduced in DOM Level 2:
584
652
  hasAttributes: function() {
@@ -4845,8 +4913,542 @@ var init_pkcs12_loader = __esm({
4845
4913
  }
4846
4914
  });
4847
4915
 
4916
+ // src/workflows/polling.ts
4917
+ async function pollUntil(action, condition, options) {
4918
+ const intervalMs = options?.intervalMs ?? 2e3;
4919
+ const maxAttempts = options?.maxAttempts ?? 60;
4920
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
4921
+ const result = await action();
4922
+ if (condition(result)) return result;
4923
+ options?.onProgress?.(attempt, maxAttempts);
4924
+ if (attempt < maxAttempts) {
4925
+ await new Promise((r) => setTimeout(r, intervalMs));
4926
+ }
4927
+ }
4928
+ throw new Error(
4929
+ `Polling timeout: ${options?.description ?? "condition"} after ${maxAttempts} attempts`
4930
+ );
4931
+ }
4932
+ var init_polling = __esm({
4933
+ "src/workflows/polling.ts"() {
4934
+ "use strict";
4935
+ }
4936
+ });
4937
+
4938
+ // src/models/document-structures/types.ts
4939
+ var SystemCode, FORM_CODES, INVOICE_TYPES_BY_SYSTEM_CODE, FORM_CODE_KEYS;
4940
+ var init_types = __esm({
4941
+ "src/models/document-structures/types.ts"() {
4942
+ "use strict";
4943
+ SystemCode = {
4944
+ FA_2: "FA (2)",
4945
+ FA_3: "FA (3)",
4946
+ PEF_3: "PEF (3)",
4947
+ PEF_KOR_3: "PEF_KOR (3)",
4948
+ FA_RR_1: "FA_RR (1)"
4949
+ };
4950
+ FORM_CODES = {
4951
+ FA_2: { systemCode: "FA (2)", schemaVersion: "1-0E", value: "FA" },
4952
+ FA_3: { systemCode: "FA (3)", schemaVersion: "1-0E", value: "FA" },
4953
+ PEF_3: { systemCode: "PEF (3)", schemaVersion: "2-1", value: "PEF" },
4954
+ PEF_KOR_3: { systemCode: "PEF_KOR (3)", schemaVersion: "2-1", value: "PEF" },
4955
+ FA_RR_1_LEGACY: { systemCode: "FA_RR (1)", schemaVersion: "1-0E", value: "RR" },
4956
+ FA_RR_1_TRANSITION: { systemCode: "FA_RR (1)", schemaVersion: "1-1E", value: "RR" },
4957
+ FA_RR_1: { systemCode: "FA_RR (1)", schemaVersion: "1-1E", value: "FA_RR" }
4958
+ };
4959
+ INVOICE_TYPES_BY_SYSTEM_CODE = {
4960
+ [SystemCode.FA_2]: ["Vat", "Zal", "Kor", "Roz", "Upr", "KorZal", "KorRoz"],
4961
+ [SystemCode.FA_3]: ["Vat", "Zal", "Kor", "Roz", "Upr", "KorZal", "KorRoz"],
4962
+ [SystemCode.PEF_3]: ["VatPef", "VatPefSp", "KorPef"],
4963
+ [SystemCode.PEF_KOR_3]: ["KorPef"],
4964
+ [SystemCode.FA_RR_1]: ["VatRr", "KorVatRr"]
4965
+ };
4966
+ FORM_CODE_KEYS = {
4967
+ FA2: FORM_CODES.FA_2,
4968
+ FA3: FORM_CODES.FA_3,
4969
+ PEF3: FORM_CODES.PEF_3,
4970
+ PEFKOR3: FORM_CODES.PEF_KOR_3,
4971
+ FARR1: FORM_CODES.FA_RR_1
4972
+ };
4973
+ }
4974
+ });
4975
+
4976
+ // src/models/document-structures/helpers.ts
4977
+ function validateFormCodeForSession(formCode, sessionType) {
4978
+ if (sessionType === "online") return true;
4979
+ return !BATCH_DISALLOWED_SYSTEM_CODES.has(formCode.systemCode);
4980
+ }
4981
+ var SYSTEM_CODE_TO_FORM_CODE, ALL_FORM_CODES, BATCH_DISALLOWED_SYSTEM_CODES;
4982
+ var init_helpers = __esm({
4983
+ "src/models/document-structures/helpers.ts"() {
4984
+ "use strict";
4985
+ init_types();
4986
+ SYSTEM_CODE_TO_FORM_CODE = {
4987
+ [SystemCode.FA_2]: FORM_CODES.FA_2,
4988
+ [SystemCode.FA_3]: FORM_CODES.FA_3,
4989
+ [SystemCode.PEF_3]: FORM_CODES.PEF_3,
4990
+ [SystemCode.PEF_KOR_3]: FORM_CODES.PEF_KOR_3,
4991
+ [SystemCode.FA_RR_1]: FORM_CODES.FA_RR_1
4992
+ };
4993
+ ALL_FORM_CODES = Object.values(FORM_CODES);
4994
+ BATCH_DISALLOWED_SYSTEM_CODES = /* @__PURE__ */ new Set([
4995
+ SystemCode.PEF_3,
4996
+ SystemCode.PEF_KOR_3
4997
+ ]);
4998
+ }
4999
+ });
5000
+
5001
+ // src/models/document-structures/index.ts
5002
+ var init_document_structures = __esm({
5003
+ "src/models/document-structures/index.ts"() {
5004
+ "use strict";
5005
+ init_types();
5006
+ init_helpers();
5007
+ }
5008
+ });
5009
+
5010
+ // src/xml/upo-parser.ts
5011
+ import { XMLParser } from "fast-xml-parser";
5012
+ function isRecord(value) {
5013
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5014
+ }
5015
+ function requireRecord(value, at) {
5016
+ if (!isRecord(value)) {
5017
+ throw KSeFValidationError.fromField(at, `Expected object at ${at}`);
5018
+ }
5019
+ return value;
5020
+ }
5021
+ function requireString(value, at) {
5022
+ if (typeof value !== "string" || value.length === 0) {
5023
+ throw KSeFValidationError.fromField(at, `Expected non-empty string at ${at}`);
5024
+ }
5025
+ return value;
5026
+ }
5027
+ function optionalRecord(value) {
5028
+ return isRecord(value) ? value : void 0;
5029
+ }
5030
+ function optionalString(value) {
5031
+ return typeof value === "string" && value.length > 0 ? value : void 0;
5032
+ }
5033
+ function requireNumberFromString(value, at) {
5034
+ const raw = requireString(value, at);
5035
+ const parsed = Number.parseInt(raw, 10);
5036
+ if (!Number.isFinite(parsed)) {
5037
+ throw KSeFValidationError.fromField(at, `Expected integer at ${at}, got "${raw}"`);
5038
+ }
5039
+ return parsed;
5040
+ }
5041
+ function ensureArray(value) {
5042
+ if (value == null) return [];
5043
+ return Array.isArray(value) ? value : [value];
5044
+ }
5045
+ function parseIdKontekstu(obj) {
5046
+ const nip = optionalString(obj.Nip);
5047
+ if (nip) return { kind: "Nip", nip };
5048
+ const idWewnetrzny = optionalString(obj.IdWewnetrzny);
5049
+ if (idWewnetrzny) return { kind: "IdWewnetrzny", idWewnetrzny };
5050
+ const idZlozonyVatUE = optionalString(obj.IdZlozonyVatUE);
5051
+ if (idZlozonyVatUE) return { kind: "IdZlozonyVatUE", idZlozonyVatUE };
5052
+ const idDostawcyUslugPeppol = optionalString(obj.IdDostawcyUslugPeppol);
5053
+ if (idDostawcyUslugPeppol) return { kind: "IdDostawcyUslugPeppol", idDostawcyUslugPeppol };
5054
+ throw KSeFValidationError.fromField(
5055
+ "Uwierzytelnienie.IdKontekstu",
5056
+ "Unsupported context identifier. Expected Nip | IdWewnetrzny | IdZlozonyVatUE | IdDostawcyUslugPeppol"
5057
+ );
5058
+ }
5059
+ function parseProof(obj) {
5060
+ const tokenRef = optionalString(obj.NumerReferencyjnyTokenaKSeF);
5061
+ if (tokenRef) return { kind: "NumerReferencyjnyTokenaKSeF", numerReferencyjnyTokenaKSeF: tokenRef };
5062
+ const docHash = optionalString(obj.SkrotDokumentuUwierzytelniajacego);
5063
+ if (docHash) return { kind: "SkrotDokumentuUwierzytelniajacego", skrotDokumentuUwierzytelniajacego: docHash };
5064
+ throw KSeFValidationError.fromField(
5065
+ "Uwierzytelnienie",
5066
+ "Unsupported auth proof. Expected NumerReferencyjnyTokenaKSeF | SkrotDokumentuUwierzytelniajacego"
5067
+ );
5068
+ }
5069
+ function parseUwierzytelnienie(obj) {
5070
+ const idKontekstu = parseIdKontekstu(
5071
+ requireRecord(obj.IdKontekstu, "Uwierzytelnienie.IdKontekstu")
5072
+ );
5073
+ const proof = parseProof(obj);
5074
+ return { idKontekstu, proof };
5075
+ }
5076
+ function parseOpisPotwierdzenia(obj) {
5077
+ return {
5078
+ strona: requireNumberFromString(obj.Strona, "OpisPotwierdzenia.Strona"),
5079
+ liczbaStron: requireNumberFromString(obj.LiczbaStron, "OpisPotwierdzenia.LiczbaStron"),
5080
+ zakresDokumentowOd: requireNumberFromString(obj.ZakresDokumentowOd, "OpisPotwierdzenia.ZakresDokumentowOd"),
5081
+ zakresDokumentowDo: requireNumberFromString(obj.ZakresDokumentowDo, "OpisPotwierdzenia.ZakresDokumentowDo"),
5082
+ calkowitaLiczbaDokumentow: requireNumberFromString(obj.CalkowitaLiczbaDokumentow, "OpisPotwierdzenia.CalkowitaLiczbaDokumentow")
5083
+ };
5084
+ }
5085
+ function parseDokument(obj) {
5086
+ return {
5087
+ nipSprzedawcy: requireString(obj.NipSprzedawcy, "Dokument.NipSprzedawcy"),
5088
+ numerKSeFDokumentu: requireString(obj.NumerKSeFDokumentu, "Dokument.NumerKSeFDokumentu"),
5089
+ numerFaktury: requireString(obj.NumerFaktury, "Dokument.NumerFaktury"),
5090
+ dataWystawieniaFaktury: requireString(obj.DataWystawieniaFaktury, "Dokument.DataWystawieniaFaktury"),
5091
+ dataPrzeslaniaDokumentu: requireString(obj.DataPrzeslaniaDokumentu, "Dokument.DataPrzeslaniaDokumentu"),
5092
+ dataNadaniaNumeruKSeF: requireString(obj.DataNadaniaNumeruKSeF, "Dokument.DataNadaniaNumeruKSeF"),
5093
+ skrotDokumentu: requireString(obj.SkrotDokumentu, "Dokument.SkrotDokumentu"),
5094
+ trybWysylki: requireString(obj.TrybWysylki, "Dokument.TrybWysylki")
5095
+ };
5096
+ }
5097
+ function parseUpoXml(xml) {
5098
+ const text = Buffer.isBuffer(xml) ? xml.toString("utf8") : xml;
5099
+ const parsed = upoParser.parse(text);
5100
+ const potwierdzenie = requireRecord(parsed?.Potwierdzenie, "Potwierdzenie");
5101
+ const opisPotwierdzenia = optionalRecord(potwierdzenie.OpisPotwierdzenia);
5102
+ const dokumenty = ensureArray(potwierdzenie.Dokument).map(
5103
+ (doc, i) => parseDokument(requireRecord(doc, `Dokument[${i}]`))
5104
+ );
5105
+ if (dokumenty.length === 0) {
5106
+ throw KSeFValidationError.fromField("Dokument", "Expected at least one Dokument in UPO");
5107
+ }
5108
+ return {
5109
+ nazwaPodmiotuPrzyjmujacego: requireString(potwierdzenie.NazwaPodmiotuPrzyjmujacego, "NazwaPodmiotuPrzyjmujacego"),
5110
+ numerReferencyjnySesji: requireString(potwierdzenie.NumerReferencyjnySesji, "NumerReferencyjnySesji"),
5111
+ uwierzytelnienie: parseUwierzytelnienie(requireRecord(potwierdzenie.Uwierzytelnienie, "Uwierzytelnienie")),
5112
+ ...opisPotwierdzenia && { opisPotwierdzenia: parseOpisPotwierdzenia(opisPotwierdzenia) },
5113
+ nazwaStrukturyLogicznej: requireString(potwierdzenie.NazwaStrukturyLogicznej, "NazwaStrukturyLogicznej"),
5114
+ kodFormularza: requireString(potwierdzenie.KodFormularza, "KodFormularza"),
5115
+ dokumenty
5116
+ };
5117
+ }
5118
+ var upoParser;
5119
+ var init_upo_parser = __esm({
5120
+ "src/xml/upo-parser.ts"() {
5121
+ "use strict";
5122
+ init_ksef_validation_error();
5123
+ upoParser = new XMLParser({
5124
+ ignoreAttributes: false,
5125
+ attributeNamePrefix: "@_",
5126
+ parseTagValue: false,
5127
+ parseAttributeValue: false,
5128
+ removeNSPrefix: true,
5129
+ trimValues: false
5130
+ });
5131
+ }
5132
+ });
5133
+
5134
+ // src/xml/index.ts
5135
+ var init_xml = __esm({
5136
+ "src/xml/index.ts"() {
5137
+ "use strict";
5138
+ init_upo_parser();
5139
+ }
5140
+ });
5141
+
5142
+ // src/builders/batch-file.ts
5143
+ import * as crypto4 from "crypto";
5144
+ function splitBuffer(data, maxPartSize) {
5145
+ if (data.length <= maxPartSize) {
5146
+ return [data];
5147
+ }
5148
+ const parts = [];
5149
+ for (let offset = 0; offset < data.length; offset += maxPartSize) {
5150
+ parts.push(data.subarray(offset, Math.min(offset + maxPartSize, data.length)));
5151
+ }
5152
+ return parts;
5153
+ }
5154
+ function sha256Base64(data) {
5155
+ return crypto4.createHash("sha256").update(data).digest("base64");
5156
+ }
5157
+ var BATCH_MAX_PART_SIZE, BATCH_MAX_TOTAL_SIZE, BATCH_MAX_PARTS, BatchFileBuilder;
5158
+ var init_batch_file = __esm({
5159
+ "src/builders/batch-file.ts"() {
5160
+ "use strict";
5161
+ init_ksef_validation_error();
5162
+ BATCH_MAX_PART_SIZE = 1e8;
5163
+ BATCH_MAX_TOTAL_SIZE = 5e9;
5164
+ BATCH_MAX_PARTS = 50;
5165
+ BatchFileBuilder = class {
5166
+ /**
5167
+ * Build batch file metadata and encrypted parts from a raw ZIP.
5168
+ *
5169
+ * @param zipBytes - Unencrypted ZIP data
5170
+ * @param encryptFn - AES-256-CBC encryption function (called per part)
5171
+ * @param options - Optional configuration
5172
+ */
5173
+ static build(zipBytes, encryptFn, options) {
5174
+ const maxPartSize = options?.maxPartSize ?? BATCH_MAX_PART_SIZE;
5175
+ if (maxPartSize <= 0) {
5176
+ throw new KSeFValidationError("maxPartSize must be a positive number");
5177
+ }
5178
+ if (zipBytes.length === 0) {
5179
+ throw new KSeFValidationError("ZIP data must not be empty");
5180
+ }
5181
+ if (zipBytes.length > BATCH_MAX_TOTAL_SIZE) {
5182
+ throw new KSeFValidationError(
5183
+ `ZIP size ${zipBytes.length} exceeds maximum of ${BATCH_MAX_TOTAL_SIZE} bytes (5 GB)`
5184
+ );
5185
+ }
5186
+ const rawParts = splitBuffer(zipBytes, maxPartSize);
5187
+ if (rawParts.length > BATCH_MAX_PARTS) {
5188
+ throw new KSeFValidationError(
5189
+ `Data requires ${rawParts.length} parts, exceeding maximum of ${BATCH_MAX_PARTS}`
5190
+ );
5191
+ }
5192
+ const zipHash = sha256Base64(zipBytes);
5193
+ const encryptedParts = [];
5194
+ const fileParts = rawParts.map((raw, i) => {
5195
+ const encrypted = encryptFn(raw);
5196
+ encryptedParts.push(encrypted);
5197
+ return {
5198
+ ordinalNumber: i + 1,
5199
+ fileSize: encrypted.length,
5200
+ fileHash: sha256Base64(encrypted)
5201
+ };
5202
+ });
5203
+ return {
5204
+ batchFile: {
5205
+ fileSize: zipBytes.length,
5206
+ fileHash: zipHash,
5207
+ fileParts
5208
+ },
5209
+ encryptedParts
5210
+ };
5211
+ }
5212
+ /**
5213
+ * Stream-based variant: two-pass build from a stream factory.
5214
+ *
5215
+ * Pass 1: consume stream to compute ZIP hash.
5216
+ * Pass 2: re-create stream, split into parts, encrypt each, compute per-part metadata.
5217
+ *
5218
+ * @param zipStreamFactory - Factory that creates a fresh ReadableStream of the ZIP data
5219
+ * @param zipSize - Total ZIP byte size (from fs.stat or known in advance)
5220
+ * @param encryptStreamFn - Stream-to-stream AES-256-CBC encryption function
5221
+ * @param hashStreamFn - Stream-to-FileMetadata hashing function
5222
+ * @param options - Optional configuration
5223
+ */
5224
+ static async buildFromStream(zipStreamFactory, zipSize, encryptStreamFn, hashStreamFn, options) {
5225
+ const maxPartSize = options?.maxPartSize ?? BATCH_MAX_PART_SIZE;
5226
+ if (maxPartSize <= 0) {
5227
+ throw new KSeFValidationError("maxPartSize must be a positive number");
5228
+ }
5229
+ if (zipSize === 0) {
5230
+ throw new KSeFValidationError("ZIP data must not be empty");
5231
+ }
5232
+ if (zipSize > BATCH_MAX_TOTAL_SIZE) {
5233
+ throw new KSeFValidationError(
5234
+ `ZIP size ${zipSize} exceeds maximum of ${BATCH_MAX_TOTAL_SIZE} bytes (5 GB)`
5235
+ );
5236
+ }
5237
+ const partCount = Math.ceil(zipSize / maxPartSize);
5238
+ if (partCount > BATCH_MAX_PARTS) {
5239
+ throw new KSeFValidationError(
5240
+ `Data requires ${partCount} parts, exceeding maximum of ${BATCH_MAX_PARTS}`
5241
+ );
5242
+ }
5243
+ const zipMeta = await hashStreamFn(zipStreamFactory());
5244
+ const fileParts = [];
5245
+ const streamParts = [];
5246
+ const reader = zipStreamFactory().getReader();
5247
+ let pending = [];
5248
+ let pendingSize = 0;
5249
+ for (let partIndex = 0; partIndex < partCount; partIndex++) {
5250
+ const isLastPart = partIndex === partCount - 1;
5251
+ const targetSize = isLastPart ? zipSize - partIndex * maxPartSize : maxPartSize;
5252
+ while (pendingSize < targetSize) {
5253
+ const { done, value } = await reader.read();
5254
+ if (done) break;
5255
+ pending.push(value);
5256
+ pendingSize += value.byteLength;
5257
+ }
5258
+ const buffer = new Uint8Array(Buffer.concat(pending));
5259
+ const partData = buffer.subarray(0, targetSize);
5260
+ if (buffer.byteLength > targetSize) {
5261
+ const remainder = buffer.subarray(targetSize);
5262
+ pending = [remainder];
5263
+ pendingSize = remainder.byteLength;
5264
+ } else {
5265
+ pending = [];
5266
+ pendingSize = 0;
5267
+ }
5268
+ const partStream = new ReadableStream({
5269
+ start(controller) {
5270
+ controller.enqueue(partData);
5271
+ controller.close();
5272
+ }
5273
+ });
5274
+ const encryptedStream = encryptStreamFn(partStream);
5275
+ const encryptedChunks = [];
5276
+ const encReader = encryptedStream.getReader();
5277
+ for (; ; ) {
5278
+ const { done, value } = await encReader.read();
5279
+ if (done) break;
5280
+ encryptedChunks.push(value);
5281
+ }
5282
+ const encryptedData = new Uint8Array(Buffer.concat(encryptedChunks));
5283
+ const encryptedMeta = sha256Base64(encryptedData);
5284
+ fileParts.push({
5285
+ ordinalNumber: partIndex + 1,
5286
+ fileSize: encryptedData.byteLength,
5287
+ fileHash: encryptedMeta
5288
+ });
5289
+ const uploadStream = new ReadableStream({
5290
+ start(controller) {
5291
+ controller.enqueue(encryptedData);
5292
+ controller.close();
5293
+ }
5294
+ });
5295
+ streamParts.push({
5296
+ dataStream: uploadStream,
5297
+ metadata: {
5298
+ hashSHA: encryptedMeta,
5299
+ fileSize: encryptedData.byteLength
5300
+ },
5301
+ ordinalNumber: partIndex + 1
5302
+ });
5303
+ }
5304
+ reader.releaseLock();
5305
+ return {
5306
+ batchFile: {
5307
+ fileSize: zipSize,
5308
+ fileHash: zipMeta.hashSHA,
5309
+ fileParts
5310
+ },
5311
+ streamParts
5312
+ };
5313
+ }
5314
+ };
5315
+ }
5316
+ });
5317
+
5318
+ // src/workflows/batch-session-workflow.ts
5319
+ var batch_session_workflow_exports = {};
5320
+ __export(batch_session_workflow_exports, {
5321
+ uploadBatch: () => uploadBatch,
5322
+ uploadBatchParsed: () => uploadBatchParsed,
5323
+ uploadBatchStream: () => uploadBatchStream,
5324
+ uploadBatchStreamParsed: () => uploadBatchStreamParsed
5325
+ });
5326
+ async function uploadBatch(client, zipData, options) {
5327
+ await client.crypto.init();
5328
+ const encData = client.crypto.getEncryptionData();
5329
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
5330
+ const encryptFn = (part) => client.crypto.encryptAES256(part, encData.cipherKey, encData.cipherIv);
5331
+ const { batchFile, encryptedParts } = BatchFileBuilder.build(zipData, encryptFn, {
5332
+ maxPartSize: options?.maxPartSize
5333
+ });
5334
+ const openResp = await client.batchSession.openSession(
5335
+ {
5336
+ formCode,
5337
+ encryption: encData.encryptionInfo,
5338
+ batchFile,
5339
+ offlineMode: options?.offlineMode
5340
+ },
5341
+ options?.upoVersion
5342
+ );
5343
+ const sendingParts = encryptedParts.map((part, i) => ({
5344
+ data: part.buffer.slice(part.byteOffset, part.byteOffset + part.byteLength),
5345
+ metadata: {
5346
+ hashSHA: batchFile.fileParts[i].fileHash,
5347
+ fileSize: batchFile.fileParts[i].fileSize
5348
+ },
5349
+ ordinalNumber: i + 1
5350
+ }));
5351
+ await client.batchSession.sendParts(openResp, sendingParts);
5352
+ await client.batchSession.closeSession(openResp.referenceNumber);
5353
+ const result = await pollUntil(
5354
+ () => client.sessionStatus.getSessionStatus(openResp.referenceNumber),
5355
+ (s) => s.status.code === 200 || s.status.code >= 400,
5356
+ { ...options?.pollOptions, description: `UPO for batch ${openResp.referenceNumber}` }
5357
+ );
5358
+ if (result.status.code !== 200) {
5359
+ throw new Error(`Batch session failed: ${result.status.code} \u2014 ${result.status.description}`);
5360
+ }
5361
+ return {
5362
+ sessionRef: openResp.referenceNumber,
5363
+ upo: {
5364
+ pages: result.upo?.pages ?? [],
5365
+ invoiceCount: result.invoiceCount,
5366
+ successfulInvoiceCount: result.successfulInvoiceCount,
5367
+ failedInvoiceCount: result.failedInvoiceCount
5368
+ }
5369
+ };
5370
+ }
5371
+ async function uploadBatchStream(client, zipStreamFactory, zipSize, options) {
5372
+ await client.crypto.init();
5373
+ const encData = client.crypto.getEncryptionData();
5374
+ const formCode = options?.formCode ?? FORM_CODES.FA_2;
5375
+ const encryptStreamFn = (stream) => client.crypto.encryptAES256Stream(stream, encData.cipherKey, encData.cipherIv);
5376
+ const hashStreamFn = (stream) => client.crypto.getFileMetadataFromStream(stream);
5377
+ const { batchFile, streamParts } = await BatchFileBuilder.buildFromStream(
5378
+ zipStreamFactory,
5379
+ zipSize,
5380
+ encryptStreamFn,
5381
+ hashStreamFn,
5382
+ { maxPartSize: options?.maxPartSize }
5383
+ );
5384
+ const openResp = await client.batchSession.openSession(
5385
+ {
5386
+ formCode,
5387
+ encryption: encData.encryptionInfo,
5388
+ batchFile,
5389
+ offlineMode: options?.offlineMode
5390
+ },
5391
+ options?.upoVersion
5392
+ );
5393
+ await client.batchSession.sendPartsWithStream(openResp, streamParts);
5394
+ await client.batchSession.closeSession(openResp.referenceNumber);
5395
+ const result = await pollUntil(
5396
+ () => client.sessionStatus.getSessionStatus(openResp.referenceNumber),
5397
+ (s) => s.status.code === 200 || s.status.code >= 400,
5398
+ { ...options?.pollOptions, description: `UPO for batch ${openResp.referenceNumber}` }
5399
+ );
5400
+ if (result.status.code !== 200) {
5401
+ throw new Error(`Batch session failed: ${result.status.code} \u2014 ${result.status.description}`);
5402
+ }
5403
+ return {
5404
+ sessionRef: openResp.referenceNumber,
5405
+ upo: {
5406
+ pages: result.upo?.pages ?? [],
5407
+ invoiceCount: result.invoiceCount,
5408
+ successfulInvoiceCount: result.successfulInvoiceCount,
5409
+ failedInvoiceCount: result.failedInvoiceCount
5410
+ }
5411
+ };
5412
+ }
5413
+ async function uploadBatchStreamParsed(client, zipStreamFactory, zipSize, options) {
5414
+ const result = await uploadBatchStream(client, zipStreamFactory, zipSize, options);
5415
+ const parsed = [];
5416
+ for (const page of result.upo.pages) {
5417
+ const upoResult = await client.sessionStatus.getSessionUpo(result.sessionRef, page.referenceNumber);
5418
+ parsed.push(parseUpoXml(upoResult.upo));
5419
+ }
5420
+ return {
5421
+ sessionRef: result.sessionRef,
5422
+ upo: { ...result.upo, parsed }
5423
+ };
5424
+ }
5425
+ async function uploadBatchParsed(client, zipData, options) {
5426
+ const result = await uploadBatch(client, zipData, options);
5427
+ const parsed = [];
5428
+ for (const page of result.upo.pages) {
5429
+ const upoResult = await client.sessionStatus.getSessionUpo(result.sessionRef, page.referenceNumber);
5430
+ parsed.push(parseUpoXml(upoResult.upo));
5431
+ }
5432
+ return {
5433
+ sessionRef: result.sessionRef,
5434
+ upo: { ...result.upo, parsed }
5435
+ };
5436
+ }
5437
+ var init_batch_session_workflow = __esm({
5438
+ "src/workflows/batch-session-workflow.ts"() {
5439
+ "use strict";
5440
+ init_document_structures();
5441
+ init_batch_file();
5442
+ init_polling();
5443
+ init_xml();
5444
+ }
5445
+ });
5446
+
4848
5447
  // src/cli/index.ts
4849
- import { defineCommand as defineCommand15, runMain } from "citty";
5448
+ import { readFileSync as readFileSync6 } from "fs";
5449
+ import { fileURLToPath } from "url";
5450
+ import { dirname as dirname2, resolve } from "path";
5451
+ import { defineCommand as defineCommand16, runMain } from "citty";
4850
5452
 
4851
5453
  // src/cli/commands/config.ts
4852
5454
  import { defineCommand } from "citty";
@@ -4935,15 +5537,8 @@ function outputWarning(msg) {
4935
5537
  // src/cli/error-handler.ts
4936
5538
  import { consola as consola2 } from "consola";
4937
5539
 
4938
- // src/errors/ksef-error.ts
4939
- var KSeFError = class extends Error {
4940
- constructor(message) {
4941
- super(message);
4942
- this.name = "KSeFError";
4943
- }
4944
- };
4945
-
4946
5540
  // src/errors/ksef-api-error.ts
5541
+ init_ksef_error();
4947
5542
  var KSeFApiError = class _KSeFApiError extends KSeFError {
4948
5543
  statusCode;
4949
5544
  errorResponse;
@@ -4993,6 +5588,7 @@ var KSeFRateLimitError = class _KSeFRateLimitError extends KSeFApiError {
4993
5588
  };
4994
5589
 
4995
5590
  // src/errors/ksef-unauthorized-error.ts
5591
+ init_ksef_error();
4996
5592
  var KSeFUnauthorizedError = class extends KSeFError {
4997
5593
  statusCode = 401;
4998
5594
  detail;
@@ -5008,6 +5604,7 @@ var KSeFUnauthorizedError = class extends KSeFError {
5008
5604
  };
5009
5605
 
5010
5606
  // src/errors/ksef-forbidden-error.ts
5607
+ init_ksef_error();
5011
5608
  var KSeFForbiddenError = class extends KSeFError {
5012
5609
  statusCode = 403;
5013
5610
  detail;
@@ -5144,6 +5741,9 @@ var configCommand = defineCommand({
5144
5741
  });
5145
5742
 
5146
5743
  // src/cli/commands/auth.ts
5744
+ import * as fs3 from "fs";
5745
+ import * as path3 from "path";
5746
+ import * as os3 from "os";
5147
5747
  import { defineCommand as defineCommand2 } from "citty";
5148
5748
 
5149
5749
  // src/cli/client-factory.ts
@@ -5194,8 +5794,8 @@ var RouteBuilder = class {
5194
5794
  this.apiVersion = apiVersion;
5195
5795
  }
5196
5796
  build(endpoint, apiVersion) {
5197
- const version = apiVersion ?? this.apiVersion;
5198
- return `/${version}/${endpoint}`;
5797
+ const version2 = apiVersion ?? this.apiVersion;
5798
+ return `/${version2}/${endpoint}`;
5199
5799
  }
5200
5800
  };
5201
5801
 
@@ -5247,27 +5847,11 @@ function isRetryableStatus(status6, policy) {
5247
5847
  return policy.retryableStatusCodes.includes(status6);
5248
5848
  }
5249
5849
  function sleep(ms) {
5250
- return new Promise((resolve) => setTimeout(resolve, ms));
5850
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
5251
5851
  }
5252
5852
 
5253
- // src/errors/ksef-validation-error.ts
5254
- var KSeFValidationError = class _KSeFValidationError extends KSeFError {
5255
- details;
5256
- constructor(message, details = []) {
5257
- super(message);
5258
- this.name = "KSeFValidationError";
5259
- this.details = details;
5260
- }
5261
- static fromField(field, message) {
5262
- return new _KSeFValidationError(message, [{ field, message }]);
5263
- }
5264
- static fromMessages(messages2) {
5265
- const details = messages2.map((m) => ({ message: m }));
5266
- return new _KSeFValidationError(messages2.join("; "), details);
5267
- }
5268
- };
5269
-
5270
5853
  // src/http/presigned-url-policy.ts
5854
+ init_ksef_validation_error();
5271
5855
  function defaultPresignedUrlPolicy() {
5272
5856
  return {
5273
5857
  allowedHosts: ["*.ksef.mf.gov.pl"],
@@ -5455,9 +6039,9 @@ var RestClient = class {
5455
6039
  return response;
5456
6040
  }
5457
6041
  buildUrl(request) {
5458
- const path5 = this.routeBuilder.build(request.path);
6042
+ const path7 = this.routeBuilder.build(request.path);
5459
6043
  const base = this.options.baseUrl;
5460
- const url2 = new URL(`${base}${path5}`);
6044
+ const url2 = new URL(`${base}${path7}`);
5461
6045
  const query2 = request.getQuery();
5462
6046
  for (const [key, value] of query2) {
5463
6047
  url2.searchParams.append(key, value);
@@ -5518,7 +6102,7 @@ var TokenBucket = class {
5518
6102
  return;
5519
6103
  }
5520
6104
  const waitMs = Math.ceil((1 - this.tokens) / this.refillRate);
5521
- await new Promise((resolve) => setTimeout(resolve, waitMs));
6105
+ await new Promise((resolve2) => setTimeout(resolve2, waitMs));
5522
6106
  this.refill();
5523
6107
  this.tokens -= 1;
5524
6108
  }
@@ -5539,8 +6123,8 @@ var RateLimitPolicy = class {
5539
6123
  this.endpointLimits = config.endpointLimits ?? {};
5540
6124
  }
5541
6125
  async acquire(endpoint) {
5542
- return new Promise((resolve, reject) => {
5543
- this.chain = this.chain.then(() => this.doAcquire(endpoint)).then(resolve, reject);
6126
+ return new Promise((resolve2, reject) => {
6127
+ this.chain = this.chain.then(() => this.doAcquire(endpoint)).then(resolve2, reject);
5544
6128
  });
5545
6129
  }
5546
6130
  async doAcquire(endpoint) {
@@ -5604,21 +6188,21 @@ var RestRequest = class _RestRequest {
5604
6188
  _query = [];
5605
6189
  _presigned = false;
5606
6190
  _skipAuthRetry = false;
5607
- constructor(method, path5) {
6191
+ constructor(method, path7) {
5608
6192
  this.method = method;
5609
- this.path = path5;
6193
+ this.path = path7;
5610
6194
  }
5611
- static get(path5) {
5612
- return new _RestRequest("GET", path5);
6195
+ static get(path7) {
6196
+ return new _RestRequest("GET", path7);
5613
6197
  }
5614
- static post(path5) {
5615
- return new _RestRequest("POST", path5);
6198
+ static post(path7) {
6199
+ return new _RestRequest("POST", path7);
5616
6200
  }
5617
- static put(path5) {
5618
- return new _RestRequest("PUT", path5);
6201
+ static put(path7) {
6202
+ return new _RestRequest("PUT", path7);
5619
6203
  }
5620
- static delete(path5) {
5621
- return new _RestRequest("DELETE", path5);
6204
+ static delete(path7) {
6205
+ return new _RestRequest("DELETE", path7);
5622
6206
  }
5623
6207
  body(data) {
5624
6208
  this._body = data;
@@ -5912,6 +6496,36 @@ var BatchSessionService = class {
5912
6496
  });
5913
6497
  await Promise.all(tasks);
5914
6498
  }
6499
+ /**
6500
+ * Upload parts sequentially (not in parallel) because each part uses a
6501
+ * streaming body (`duplex: 'half'`). Parallel streaming uploads can cause
6502
+ * backpressure issues and exceed memory limits for large payloads.
6503
+ */
6504
+ async sendPartsWithStream(openResponse, parts) {
6505
+ const uploadRequests = openResponse.partUploadRequests;
6506
+ for (const part of parts) {
6507
+ const uploadReq = uploadRequests.find(
6508
+ (r) => r.ordinalNumber === part.ordinalNumber
6509
+ );
6510
+ if (!uploadReq) {
6511
+ throw new Error(`No upload request found for part ${part.ordinalNumber}`);
6512
+ }
6513
+ const headers = {};
6514
+ for (const [k, v] of Object.entries(uploadReq.headers)) {
6515
+ if (v != null) headers[k] = v;
6516
+ }
6517
+ const resp = await fetch(uploadReq.url, {
6518
+ method: uploadReq.method,
6519
+ headers,
6520
+ body: part.dataStream,
6521
+ // @ts-expect-error -- Node 18+ undici supports duplex for streaming body
6522
+ duplex: "half"
6523
+ });
6524
+ if (!resp.ok) {
6525
+ throw new Error(`Upload failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
6526
+ }
6527
+ }
6528
+ }
5915
6529
  async closeSession(batchRef) {
5916
6530
  const req = RestRequest.post(Routes.Sessions.Batch.close(batchRef));
5917
6531
  await this.restClient.executeVoid(req);
@@ -6235,6 +6849,18 @@ var CertificateApiService = class {
6235
6849
  }
6236
6850
  };
6237
6851
 
6852
+ // src/errors/index.ts
6853
+ init_ksef_error();
6854
+
6855
+ // src/errors/ksef-auth-status-error.ts
6856
+ init_ksef_error();
6857
+
6858
+ // src/errors/ksef-session-expired-error.ts
6859
+ init_ksef_error();
6860
+
6861
+ // src/errors/index.ts
6862
+ init_ksef_validation_error();
6863
+
6238
6864
  // src/services/lighthouse.ts
6239
6865
  var LighthouseService = class {
6240
6866
  lighthouseUrl;
@@ -6243,20 +6869,20 @@ var LighthouseService = class {
6243
6869
  this.lighthouseUrl = options.lighthouseUrl;
6244
6870
  this.timeout = options.timeout;
6245
6871
  }
6246
- async fetchJson(path5) {
6872
+ async fetchJson(path7) {
6247
6873
  if (!this.lighthouseUrl) {
6248
6874
  throw new KSeFError(
6249
6875
  "Lighthouse API is not available for the DEMO environment. Use TEST or PROD instead."
6250
6876
  );
6251
6877
  }
6252
- const response = await fetch(`${this.lighthouseUrl}${path5}`, {
6878
+ const response = await fetch(`${this.lighthouseUrl}${path7}`, {
6253
6879
  headers: { Accept: "application/json" },
6254
6880
  signal: AbortSignal.timeout(this.timeout)
6255
6881
  });
6256
6882
  if (!response.ok) {
6257
6883
  const body = await response.text();
6258
6884
  throw new KSeFError(
6259
- `Lighthouse ${path5} failed: HTTP ${response.status} \u2014 ${body}`
6885
+ `Lighthouse ${path7} failed: HTTP ${response.status} \u2014 ${body}`
6260
6886
  );
6261
6887
  }
6262
6888
  return await response.json();
@@ -6309,6 +6935,7 @@ var PeppolService = class {
6309
6935
  };
6310
6936
 
6311
6937
  // src/services/test-data.ts
6938
+ init_ksef_error();
6312
6939
  var TestDataService = class {
6313
6940
  restClient;
6314
6941
  environmentName;
@@ -6498,6 +7125,28 @@ var CryptographyService = class {
6498
7125
  const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
6499
7126
  return new Uint8Array(Buffer.concat([cipher.update(content), cipher.final()]));
6500
7127
  }
7128
+ /**
7129
+ * Encrypt with AES-256-CBC as a streaming transform.
7130
+ * Returns a ReadableStream that yields encrypted chunks as the input is read.
7131
+ */
7132
+ encryptAES256Stream(input, key, iv) {
7133
+ const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
7134
+ const transform = new TransformStream({
7135
+ transform(chunk, controller) {
7136
+ const encrypted = cipher.update(chunk);
7137
+ if (encrypted.length > 0) {
7138
+ controller.enqueue(new Uint8Array(encrypted));
7139
+ }
7140
+ },
7141
+ flush(controller) {
7142
+ const final = cipher.final();
7143
+ if (final.length > 0) {
7144
+ controller.enqueue(new Uint8Array(final));
7145
+ }
7146
+ }
7147
+ });
7148
+ return input.pipeThrough(transform);
7149
+ }
6501
7150
  /** Decrypt with AES-256-CBC. */
6502
7151
  decryptAES256(content, key, iv) {
6503
7152
  const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
@@ -6570,6 +7219,23 @@ var CryptographyService = class {
6570
7219
  const hash = crypto.createHash("sha256").update(file).digest("base64");
6571
7220
  return { hashSHA: hash, fileSize: file.length };
6572
7221
  }
7222
+ /** Compute SHA-256 hash (base64) and byte length from a ReadableStream. */
7223
+ async getFileMetadataFromStream(stream) {
7224
+ const hash = crypto.createHash("sha256");
7225
+ let fileSize = 0;
7226
+ const reader = stream.getReader();
7227
+ try {
7228
+ for (; ; ) {
7229
+ const { done, value } = await reader.read();
7230
+ if (done) break;
7231
+ hash.update(value);
7232
+ fileSize += value.byteLength;
7233
+ }
7234
+ } finally {
7235
+ reader.releaseLock();
7236
+ }
7237
+ return { hashSHA: hash.digest("base64"), fileSize };
7238
+ }
6573
7239
  // ---------------------------------------------------------------------------
6574
7240
  // CSR generation
6575
7241
  // ---------------------------------------------------------------------------
@@ -6746,6 +7412,7 @@ var VerificationLinkService = class {
6746
7412
  };
6747
7413
 
6748
7414
  // src/client.ts
7415
+ init_auth_xml_builder();
6749
7416
  var KSeFClient = class {
6750
7417
  auth;
6751
7418
  activeSessions;
@@ -6839,21 +7506,12 @@ var KSeFClient = class {
6839
7506
  this.authManager.setRefreshToken(void 0);
6840
7507
  }
6841
7508
  };
6842
- var AUTH_TOKEN_REQUEST_NS = "http://ksef.mf.gov.pl/auth/token/2.0";
6843
7509
  function buildAuthTokenRequestXml(challenge2, nip, subjectIdentifierType = "certificateSubject") {
6844
- return [
6845
- '<?xml version="1.0" encoding="utf-8"?>',
6846
- `<AuthTokenRequest xmlns="${AUTH_TOKEN_REQUEST_NS}">`,
6847
- `<Challenge>${xmlEscape(challenge2)}</Challenge>`,
6848
- `<ContextIdentifier>`,
6849
- `<Nip>${xmlEscape(nip)}</Nip>`,
6850
- `</ContextIdentifier>`,
6851
- `<SubjectIdentifierType>${xmlEscape(subjectIdentifierType)}</SubjectIdentifierType>`,
6852
- `</AuthTokenRequest>`
6853
- ].join("");
6854
- }
6855
- function xmlEscape(str) {
6856
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
7510
+ return buildUnsignedAuthTokenRequestXml({
7511
+ challenge: challenge2,
7512
+ contextIdentifier: { type: "Nip", value: nip },
7513
+ subjectIdentifierType
7514
+ });
6857
7515
  }
6858
7516
  function buildRestClientConfig(options, authManager) {
6859
7517
  const config = { authManager };
@@ -6963,6 +7621,29 @@ function requireSession(globalOpts) {
6963
7621
  }
6964
7622
 
6965
7623
  // src/cli/commands/auth.ts
7624
+ init_polling();
7625
+ var PENDING_CHALLENGE_FILE = path3.join(os3.homedir(), ".ksef", "pending-challenge.json");
7626
+ function savePendingChallenge(data) {
7627
+ const dir = path3.dirname(PENDING_CHALLENGE_FILE);
7628
+ fs3.mkdirSync(dir, { recursive: true });
7629
+ fs3.writeFileSync(PENDING_CHALLENGE_FILE, JSON.stringify(data, null, 2) + "\n", {
7630
+ encoding: "utf-8",
7631
+ mode: 384
7632
+ });
7633
+ }
7634
+ function clearPendingChallenge() {
7635
+ try {
7636
+ fs3.unlinkSync(PENDING_CHALLENGE_FILE);
7637
+ } catch {
7638
+ }
7639
+ }
7640
+ async function readStdin(stream = process.stdin) {
7641
+ const chunks = [];
7642
+ for await (const chunk of stream) {
7643
+ chunks.push(chunk);
7644
+ }
7645
+ return Buffer.concat(chunks).toString("utf-8");
7646
+ }
6966
7647
  function getGlobalOpts(args) {
6967
7648
  return {
6968
7649
  env: args.env,
@@ -7015,13 +7696,13 @@ var login = defineCommand2({
7015
7696
  if (args.token) {
7016
7697
  await client.loginWithToken(args.token, nip);
7017
7698
  } else if (args.p12) {
7018
- const fs7 = await import("fs");
7019
- const p12Buffer = fs7.readFileSync(args.p12);
7699
+ const fs10 = await import("fs");
7700
+ const p12Buffer = fs10.readFileSync(args.p12);
7020
7701
  await client.loginWithPkcs12(p12Buffer, args["p12-password"] ?? "", nip);
7021
7702
  } else if (args.cert && args.key) {
7022
- const fs7 = await import("fs");
7023
- const certPem = fs7.readFileSync(args.cert, "utf-8");
7024
- const keyPem = fs7.readFileSync(args.key, "utf-8");
7703
+ const fs10 = await import("fs");
7704
+ const certPem = fs10.readFileSync(args.cert, "utf-8");
7705
+ const keyPem = fs10.readFileSync(args.key, "utf-8");
7025
7706
  await client.loginWithCertificate(certPem, keyPem, nip);
7026
7707
  } else {
7027
7708
  throw new Error("Provide --token, --p12, or both --cert and --key for authentication.");
@@ -7123,15 +7804,109 @@ var whoami = defineCommand2({
7123
7804
  });
7124
7805
  }
7125
7806
  });
7126
- var authCommand = defineCommand2({
7127
- meta: { name: "auth", description: "Authentication commands" },
7128
- subCommands: { challenge, login, status, logout, refresh, whoami }
7129
- });
7130
-
7131
- // src/cli/commands/session.ts
7132
- import * as fs3 from "fs";
7807
+ var loginExternal = defineCommand2({
7808
+ meta: { name: "login-external", description: "Authenticate with externally-signed XAdES XML" },
7809
+ args: {
7810
+ generate: { type: "boolean", description: "Generate unsigned auth request XML" },
7811
+ submit: { type: "boolean", description: "Submit externally-signed XML" },
7812
+ nip: { type: "string", description: "NIP number (or identifier value for non-Nip context types)" },
7813
+ "context-type": { type: "string", description: "Context identifier type: Nip, InternalId, NipVatUe, PeppolId (default: Nip)" },
7814
+ output: { type: "string", description: "Write unsigned XML to file instead of stdout (--generate)" },
7815
+ input: { type: "string", description: "Read signed XML from file instead of stdin (--submit)" },
7816
+ env: { type: "string", description: "Environment (test/demo/prod)" },
7817
+ json: { type: "boolean", description: "Output as JSON" },
7818
+ verbose: { type: "boolean", description: "Show HTTP request/response details" },
7819
+ timeout: { type: "string", description: "Request timeout (ms)" }
7820
+ },
7821
+ run({ args }) {
7822
+ return withErrorHandler(async () => {
7823
+ const globalOpts = getGlobalOpts(args);
7824
+ const config = loadConfig();
7825
+ const nip = args.nip ?? config.nip;
7826
+ if (!nip) {
7827
+ throw new Error("NIP/identifier is required. Provide --nip or set it via `ksef config set --nip <nip>`.");
7828
+ }
7829
+ const contextType = args["context-type"] ?? "Nip";
7830
+ const validTypes = ["Nip", "InternalId", "NipVatUe", "PeppolId"];
7831
+ if (!validTypes.includes(contextType)) {
7832
+ throw new Error(`Invalid --context-type "${contextType}". Must be one of: ${validTypes.join(", ")}`);
7833
+ }
7834
+ if (!args.generate && !args.submit) {
7835
+ throw new Error("Specify --generate to create unsigned XML, or --submit to send signed XML.");
7836
+ }
7837
+ const client = createClient(globalOpts);
7838
+ if (args.generate) {
7839
+ const { buildUnsignedAuthTokenRequestXml: buildUnsignedAuthTokenRequestXml2 } = await Promise.resolve().then(() => (init_auth_xml_builder(), auth_xml_builder_exports));
7840
+ const challengeResult = await client.auth.getChallenge();
7841
+ const unsignedXml = buildUnsignedAuthTokenRequestXml2({
7842
+ challenge: challengeResult.challenge,
7843
+ contextIdentifier: { type: contextType, value: nip }
7844
+ });
7845
+ if (args.output) {
7846
+ fs3.writeFileSync(args.output, unsignedXml, "utf-8");
7847
+ process.stderr.write(`Unsigned XML written to ${args.output}
7848
+ `);
7849
+ } else {
7850
+ process.stdout.write(unsignedXml);
7851
+ }
7852
+ savePendingChallenge({
7853
+ challenge: challengeResult.challenge,
7854
+ timestamp: challengeResult.timestamp,
7855
+ contextIdentifier: { type: contextType, value: nip },
7856
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
7857
+ });
7858
+ process.stderr.write(`Challenge: ${challengeResult.challenge}
7859
+ `);
7860
+ process.stderr.write(`Timestamp: ${challengeResult.timestamp}
7861
+ `);
7862
+ process.stderr.write(`Note: Sign this XML and submit with --submit before the challenge expires.
7863
+ `);
7864
+ }
7865
+ if (args.submit) {
7866
+ let signedXml;
7867
+ if (args.input) {
7868
+ signedXml = fs3.readFileSync(args.input, "utf-8");
7869
+ } else {
7870
+ signedXml = await readStdin();
7871
+ }
7872
+ if (!signedXml.trim()) {
7873
+ throw new Error("No signed XML provided. Pipe signed XML to stdin or use --input <file>.");
7874
+ }
7875
+ const submitResult = await client.auth.submitXadesAuthRequest(signedXml);
7876
+ const authToken = submitResult.authenticationToken.token;
7877
+ await pollUntil(
7878
+ () => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
7879
+ (s) => s.status.code !== 100,
7880
+ { intervalMs: 1e3, maxAttempts: 30, description: `auth ${submitResult.referenceNumber}` }
7881
+ );
7882
+ const tokens = await client.auth.getAccessToken(authToken);
7883
+ const session = {
7884
+ accessToken: tokens.accessToken.token,
7885
+ refreshToken: tokens.refreshToken.token,
7886
+ expiresAt: tokens.accessToken.validUntil,
7887
+ environment: args.env ?? config.environment
7888
+ };
7889
+ saveSession(session);
7890
+ if (args.env && args.env !== config.environment) {
7891
+ saveConfig({ ...config, environment: session.environment });
7892
+ }
7893
+ clearPendingChallenge();
7894
+ outputSuccess("Logged in successfully via external signature.");
7895
+ }
7896
+ });
7897
+ }
7898
+ });
7899
+ var authCommand = defineCommand2({
7900
+ meta: { name: "auth", description: "Authentication commands" },
7901
+ subCommands: { challenge, login, "login-external": loginExternal, status, logout, refresh, whoami }
7902
+ });
7903
+
7904
+ // src/cli/commands/session.ts
7905
+ import * as fs4 from "fs";
7133
7906
  import { defineCommand as defineCommand3 } from "citty";
7134
7907
  import { consola as consola5 } from "consola";
7908
+ init_document_structures();
7909
+ init_xml();
7135
7910
  function getGlobalOpts2(args) {
7136
7911
  return {
7137
7912
  env: args.env,
@@ -7145,6 +7920,7 @@ var open = defineCommand3({
7145
7920
  meta: { name: "open", description: "Open a KSeF session (online or batch)" },
7146
7921
  args: {
7147
7922
  batch: { type: "boolean", description: "Open a batch session instead of online" },
7923
+ formCode: { type: "string", description: "Document type: FA2, FA3, PEF3, PEFKOR3, FARR1 (default: FA2)" },
7148
7924
  env: { type: "string", description: "Environment (test/demo/prod)" },
7149
7925
  json: { type: "boolean", description: "Output as JSON" },
7150
7926
  verbose: { type: "boolean", description: "Show HTTP request/response details" },
@@ -7162,7 +7938,15 @@ var open = defineCommand3({
7162
7938
  }
7163
7939
  await client.crypto.init();
7164
7940
  const encryptionData = client.crypto.getEncryptionData();
7165
- const formCode = { systemCode: "FA (2)", schemaVersion: "1-0E", value: "FA" };
7941
+ const formCodeKey = args.formCode;
7942
+ let formCode = FORM_CODES.FA_2;
7943
+ if (formCodeKey) {
7944
+ const resolved = FORM_CODE_KEYS[formCodeKey];
7945
+ if (!resolved) {
7946
+ throw new Error(`Invalid form code "${formCodeKey}". Valid keys: ${Object.keys(FORM_CODE_KEYS).join(", ")}`);
7947
+ }
7948
+ formCode = resolved;
7949
+ }
7166
7950
  if (args.batch) {
7167
7951
  throw new Error("Batch session open is used internally by `ksef invoice send <dir>`. Use `ksef session open` for online sessions.");
7168
7952
  }
@@ -7400,6 +8184,7 @@ var upo = defineCommand3({
7400
8184
  upoRef: { type: "string", description: "UPO reference" },
7401
8185
  ksefNumber: { type: "string", description: "KSeF invoice number" },
7402
8186
  invoiceRef: { type: "string", description: "Invoice reference" },
8187
+ parsed: { type: "boolean", description: "Parse UPO XML and output as JSON" },
7403
8188
  o: { type: "string", description: "Output file path" },
7404
8189
  env: { type: "string", description: "Environment (test/demo/prod)" },
7405
8190
  json: { type: "boolean", description: "Output as JSON" },
@@ -7421,12 +8206,23 @@ var upo = defineCommand3({
7421
8206
  } else {
7422
8207
  throw new Error("Provide one of: --upo-ref, --ksef-number, or --invoice-ref");
7423
8208
  }
8209
+ if (args.parsed) {
8210
+ const parsed = parseUpoXml(result.upo);
8211
+ const json = JSON.stringify(parsed, null, 2);
8212
+ if (args.o) {
8213
+ fs4.writeFileSync(args.o, json, "utf-8");
8214
+ outputSuccess(`Parsed UPO saved to ${args.o}`);
8215
+ } else {
8216
+ console.log(json);
8217
+ }
8218
+ return;
8219
+ }
7424
8220
  if (args.json) {
7425
8221
  outputResult(result, { json: true });
7426
8222
  return;
7427
8223
  }
7428
8224
  if (args.o) {
7429
- fs3.writeFileSync(args.o, result.upo, "utf-8");
8225
+ fs4.writeFileSync(args.o, result.upo, "utf-8");
7430
8226
  outputSuccess(`UPO saved to ${args.o}`);
7431
8227
  } else {
7432
8228
  console.log(result.upo);
@@ -7556,10 +8352,173 @@ var sessionCommand = defineCommand3({
7556
8352
  });
7557
8353
 
7558
8354
  // src/cli/commands/invoice.ts
7559
- import * as fs4 from "fs";
7560
- import * as path3 from "path";
8355
+ import * as fs7 from "fs";
8356
+ import * as path5 from "path";
8357
+ import { Readable } from "stream";
8358
+ import { defineCommand as defineCommand5 } from "citty";
8359
+ import { consola as consola7 } from "consola";
8360
+ init_document_structures();
8361
+
8362
+ // src/cli/commands/export-incremental.ts
8363
+ import * as fs6 from "fs";
8364
+ import * as path4 from "path";
7561
8365
  import { defineCommand as defineCommand4 } from "citty";
7562
8366
  import { consola as consola6 } from "consola";
8367
+
8368
+ // src/workflows/hwm-storage.ts
8369
+ import * as fs5 from "fs/promises";
8370
+ var FileHwmStore = class {
8371
+ constructor(filePath) {
8372
+ this.filePath = filePath;
8373
+ }
8374
+ async load() {
8375
+ try {
8376
+ const data = await fs5.readFile(this.filePath, "utf-8");
8377
+ return JSON.parse(data);
8378
+ } catch (err) {
8379
+ if (err.code === "ENOENT") {
8380
+ return {};
8381
+ }
8382
+ throw err;
8383
+ }
8384
+ }
8385
+ async save(points) {
8386
+ await fs5.writeFile(this.filePath, JSON.stringify(points, null, 2), "utf-8");
8387
+ }
8388
+ };
8389
+
8390
+ // src/utils/zip.ts
8391
+ import { ZipFile } from "yazl";
8392
+ import { fromBuffer } from "yauzl";
8393
+
8394
+ // src/workflows/invoice-export-workflow.ts
8395
+ init_polling();
8396
+ async function doExport(client, filters, options) {
8397
+ await client.crypto.init();
8398
+ const encData = client.crypto.getEncryptionData();
8399
+ const opResp = await client.invoices.exportInvoices({
8400
+ encryption: encData.encryptionInfo,
8401
+ filters,
8402
+ onlyMetadata: options?.onlyMetadata
8403
+ });
8404
+ const result = await pollUntil(
8405
+ () => client.invoices.getInvoiceExportStatus(opResp.referenceNumber),
8406
+ (s) => s.status.code === 200 || s.status.code >= 400,
8407
+ { ...options?.pollOptions, description: `export ${opResp.referenceNumber}` }
8408
+ );
8409
+ if (result.status.code !== 200) {
8410
+ throw new Error(`Export failed: ${result.status.code} \u2014 ${result.status.description}`);
8411
+ }
8412
+ if (!result.package) {
8413
+ throw new Error("Export completed but no package available");
8414
+ }
8415
+ return {
8416
+ encData,
8417
+ referenceNumber: opResp.referenceNumber,
8418
+ result: {
8419
+ parts: result.package.parts.map((p) => ({
8420
+ ordinalNumber: p.ordinalNumber,
8421
+ url: p.url,
8422
+ method: p.method,
8423
+ partSize: p.partSize,
8424
+ encryptedPartSize: p.encryptedPartSize,
8425
+ encryptedPartHash: p.encryptedPartHash,
8426
+ expirationDate: p.expirationDate
8427
+ })),
8428
+ invoiceCount: result.package.invoiceCount,
8429
+ isTruncated: result.package.isTruncated,
8430
+ permanentStorageHwmDate: result.package.permanentStorageHwmDate,
8431
+ lastPermanentStorageDate: result.package.lastPermanentStorageDate
8432
+ }
8433
+ };
8434
+ }
8435
+
8436
+ // src/workflows/hwm-coordinator.ts
8437
+ function updateContinuationPoint(points, subjectType, pkg2) {
8438
+ if (pkg2.isTruncated && pkg2.lastPermanentStorageDate) {
8439
+ points[subjectType] = pkg2.lastPermanentStorageDate;
8440
+ } else if (pkg2.permanentStorageHwmDate) {
8441
+ points[subjectType] = pkg2.permanentStorageHwmDate;
8442
+ } else {
8443
+ delete points[subjectType];
8444
+ }
8445
+ }
8446
+ function getEffectiveStartDate(points, subjectType, windowFrom) {
8447
+ return points[subjectType] ?? windowFrom;
8448
+ }
8449
+
8450
+ // src/workflows/incremental-export-workflow.ts
8451
+ async function incrementalExportAndDownload(client, options) {
8452
+ const maxIterations = options.maxIterations ?? 20;
8453
+ const points = options.continuationPoints;
8454
+ if (options.store) {
8455
+ const loaded = await options.store.load();
8456
+ for (const [key, value] of Object.entries(loaded)) {
8457
+ if (value !== void 0 && points[key] === void 0) {
8458
+ points[key] = value;
8459
+ }
8460
+ }
8461
+ }
8462
+ const referenceNumbers = [];
8463
+ const decryptedParts = [];
8464
+ let previousFrom;
8465
+ let iteration = 0;
8466
+ for (; iteration < maxIterations; iteration++) {
8467
+ const effectiveFrom = getEffectiveStartDate(points, options.subjectType, options.windowFrom);
8468
+ if (previousFrom !== void 0 && effectiveFrom === previousFrom) {
8469
+ break;
8470
+ }
8471
+ previousFrom = effectiveFrom;
8472
+ const filters = options.filtersFactory ? options.filtersFactory(effectiveFrom, options.windowTo) : buildDefaultFilters(options.subjectType, effectiveFrom, options.windowTo);
8473
+ const { result, encData, referenceNumber } = await doExport(client, filters, {
8474
+ onlyMetadata: options.onlyMetadata,
8475
+ pollOptions: options.pollOptions
8476
+ });
8477
+ referenceNumbers.push(referenceNumber);
8478
+ const download = options.transport ?? fetch;
8479
+ for (const part of result.parts) {
8480
+ const resp = await download(part.url, { method: part.method });
8481
+ if (!resp.ok) {
8482
+ throw new Error(`Download failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
8483
+ }
8484
+ const encryptedData = new Uint8Array(await resp.arrayBuffer());
8485
+ const decrypted = client.crypto.decryptAES256(encryptedData, encData.cipherKey, encData.cipherIv);
8486
+ decryptedParts.push(decrypted);
8487
+ }
8488
+ updateContinuationPoint(points, options.subjectType, {
8489
+ isTruncated: result.isTruncated,
8490
+ lastPermanentStorageDate: result.lastPermanentStorageDate,
8491
+ permanentStorageHwmDate: result.permanentStorageHwmDate
8492
+ });
8493
+ if (options.store) {
8494
+ await options.store.save(points);
8495
+ }
8496
+ options.onIterationComplete?.(iteration, result);
8497
+ if (!result.isTruncated) {
8498
+ iteration++;
8499
+ break;
8500
+ }
8501
+ }
8502
+ return {
8503
+ referenceNumbers,
8504
+ invoices: [],
8505
+ decryptedParts,
8506
+ continuationPoints: points,
8507
+ iterationCount: iteration
8508
+ };
8509
+ }
8510
+ function buildDefaultFilters(subjectType, from, to) {
8511
+ return {
8512
+ subjectType,
8513
+ dateRange: {
8514
+ dateType: "PermanentStorage",
8515
+ from,
8516
+ to
8517
+ }
8518
+ };
8519
+ }
8520
+
8521
+ // src/cli/commands/export-incremental.ts
7563
8522
  function getGlobalOpts3(args) {
7564
8523
  return {
7565
8524
  env: args.env,
@@ -7569,6 +8528,101 @@ function getGlobalOpts3(args) {
7569
8528
  nip: args.nip
7570
8529
  };
7571
8530
  }
8531
+ var exportIncremental = defineCommand4({
8532
+ meta: { name: "export-incremental", description: "Incremental invoice export with HWM state persistence" },
8533
+ args: {
8534
+ from: { type: "string", description: "Start date (YYYY-MM-DD) \u2014 required", required: true },
8535
+ to: { type: "string", description: "End date (YYYY-MM-DD)" },
8536
+ subjectType: { type: "string", description: "Subject type: Subject1|Subject2|Subject3|SubjectAuthorized (default: Subject1)" },
8537
+ stateFile: { type: "string", description: "HWM state file path (default: ./ksef-hwm-state.json)" },
8538
+ outputDir: { type: "string", description: "Output directory for exported parts (default: ./ksef-exports/)" },
8539
+ maxIterations: { type: "string", description: "Max export iterations (default: 20)" },
8540
+ env: { type: "string", description: "Environment (test/demo/prod)" },
8541
+ json: { type: "boolean", description: "Output as JSON" },
8542
+ verbose: { type: "boolean", description: "Show HTTP request/response details" },
8543
+ timeout: { type: "string", description: "Request timeout (ms)" },
8544
+ nip: { type: "string", description: "NIP number" }
8545
+ },
8546
+ run({ args }) {
8547
+ return withErrorHandler(async () => {
8548
+ const globalOpts = getGlobalOpts3(args);
8549
+ const { client } = requireSession(globalOpts);
8550
+ const from = args.from;
8551
+ const to = args.to ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8552
+ const subjectType = args.subjectType ?? "Subject1";
8553
+ const stateFile = args.stateFile ?? "./ksef-hwm-state.json";
8554
+ const outputDir = args.outputDir ?? "./ksef-exports";
8555
+ const maxIterations = args.maxIterations ? parseInt(args.maxIterations, 10) : 20;
8556
+ const isJson = args.json;
8557
+ const store = new FileHwmStore(stateFile);
8558
+ const continuationPoints = {};
8559
+ if (!fs6.existsSync(outputDir)) {
8560
+ fs6.mkdirSync(outputDir, { recursive: true });
8561
+ }
8562
+ if (!isJson) {
8563
+ consola6.start(`Incremental export: ${from} \u2192 ${to}, subject: ${subjectType}`);
8564
+ consola6.info(`State file: ${stateFile}`);
8565
+ consola6.info(`Output dir: ${outputDir}`);
8566
+ }
8567
+ const iterationParts = [];
8568
+ const result = await incrementalExportAndDownload(client, {
8569
+ subjectType,
8570
+ windowFrom: from,
8571
+ windowTo: to,
8572
+ continuationPoints,
8573
+ maxIterations,
8574
+ store,
8575
+ pollOptions: { intervalMs: 2e3 },
8576
+ onIterationComplete: (iteration, iterResult) => {
8577
+ iterationParts.push({ iteration, partCount: iterResult.parts.length });
8578
+ if (!isJson) {
8579
+ const hwmDate = continuationPoints[subjectType] ?? "complete";
8580
+ consola6.info(
8581
+ `Iteration ${iteration + 1}: ${iterResult.invoiceCount} invoices, truncated: ${iterResult.isTruncated}, HWM: ${hwmDate}`
8582
+ );
8583
+ }
8584
+ }
8585
+ });
8586
+ let partIndex = 0;
8587
+ for (const { iteration, partCount } of iterationParts) {
8588
+ for (let p = 0; p < partCount; p++) {
8589
+ if (partIndex < result.decryptedParts.length) {
8590
+ const fileName = `iter-${String(iteration + 1).padStart(3, "0")}-part-${String(p + 1).padStart(3, "0")}.zip`;
8591
+ const filePath = path4.join(outputDir, fileName);
8592
+ fs6.writeFileSync(filePath, result.decryptedParts[partIndex]);
8593
+ partIndex++;
8594
+ }
8595
+ }
8596
+ }
8597
+ if (isJson) {
8598
+ outputResult({
8599
+ referenceNumbers: result.referenceNumbers,
8600
+ iterationCount: result.iterationCount,
8601
+ totalParts: result.decryptedParts.length,
8602
+ continuationPoints: result.continuationPoints,
8603
+ outputDir
8604
+ }, { json: true });
8605
+ } else {
8606
+ outputSuccess(
8607
+ `Export complete: ${result.iterationCount} iterations, ${result.decryptedParts.length} parts downloaded`
8608
+ );
8609
+ consola6.info(`Final HWM: ${continuationPoints[subjectType] ?? "complete"}`);
8610
+ consola6.info(`Output: ${outputDir}`);
8611
+ }
8612
+ });
8613
+ }
8614
+ });
8615
+
8616
+ // src/cli/commands/invoice.ts
8617
+ function getGlobalOpts4(args) {
8618
+ return {
8619
+ env: args.env,
8620
+ json: args.json,
8621
+ verbose: args.verbose,
8622
+ timeout: args.timeout,
8623
+ nip: args.nip
8624
+ };
8625
+ }
7572
8626
  function buildQueryFilters(args) {
7573
8627
  const from = args.from;
7574
8628
  if (!from) {
@@ -7612,11 +8666,13 @@ var QUERY_FILTER_ARGS = {
7612
8666
  amountType: { type: "string", description: "Amount type: Brutto|Netto|Vat (default: Brutto)" },
7613
8667
  currency: { type: "string", description: "Currency code (e.g. PLN, EUR)" }
7614
8668
  };
7615
- var send = defineCommand4({
8669
+ var send = defineCommand5({
7616
8670
  meta: { name: "send", description: "Send invoice(s) \u2014 single XML file or directory for batch" },
7617
8671
  args: {
7618
- path: { type: "positional", description: "Path to XML file or directory of XMLs", required: true },
8672
+ path: { type: "positional", description: "Path to XML file, directory of XMLs, or ZIP for batch", required: true },
7619
8673
  sessionRef: { type: "string", description: "Override online session reference" },
8674
+ stream: { type: "boolean", description: "Use stream-based batch upload (for ZIP files, reduces memory usage)" },
8675
+ formCode: { type: "string", description: "Document type: FA2, FA3, PEF3, PEFKOR3, FARR1 (default: FA2)" },
7620
8676
  env: { type: "string", description: "Environment (test/demo/prod)" },
7621
8677
  json: { type: "boolean", description: "Output as JSON" },
7622
8678
  verbose: { type: "boolean", description: "Show HTTP request/response details" },
@@ -7625,29 +8681,65 @@ var send = defineCommand4({
7625
8681
  },
7626
8682
  run({ args }) {
7627
8683
  return withErrorHandler(async () => {
7628
- const globalOpts = getGlobalOpts3(args);
8684
+ const globalOpts = getGlobalOpts4(args);
7629
8685
  const { client, session } = requireSession(globalOpts);
7630
8686
  const config = loadConfig();
7631
8687
  const nip = args.nip ?? config.nip;
7632
8688
  const filePath = args.path;
7633
- if (!fs4.existsSync(filePath)) {
8689
+ const formCodeKey = args.formCode;
8690
+ let formCode = FORM_CODES.FA_2;
8691
+ if (formCodeKey) {
8692
+ const resolved = FORM_CODE_KEYS[formCodeKey];
8693
+ if (!resolved) {
8694
+ throw new Error(`Invalid form code "${formCodeKey}". Valid keys: ${Object.keys(FORM_CODE_KEYS).join(", ")}`);
8695
+ }
8696
+ formCode = resolved;
8697
+ }
8698
+ if (!fs7.existsSync(filePath)) {
7634
8699
  throw new Error(`Path not found: ${filePath}`);
7635
8700
  }
7636
- const stat = fs4.statSync(filePath);
8701
+ const stat = fs7.statSync(filePath);
8702
+ if (args.stream) {
8703
+ if (!filePath.endsWith(".zip") || stat.isDirectory()) {
8704
+ throw new Error("--stream requires a .zip file path.");
8705
+ }
8706
+ if (!nip) {
8707
+ throw new Error("NIP is required. Provide --nip or set it via `ksef config set --nip <nip>`.");
8708
+ }
8709
+ if (!validateFormCodeForSession(formCode, "batch")) {
8710
+ throw new Error(`Document type "${formCode.systemCode}" is not supported in batch sessions. PEF/PEF_KOR require online sessions.`);
8711
+ }
8712
+ const { uploadBatchStream: uploadBatchStream2 } = await Promise.resolve().then(() => (init_batch_session_workflow(), batch_session_workflow_exports));
8713
+ const zipSize = stat.size;
8714
+ const zipStreamFactory = () => Readable.toWeb(fs7.createReadStream(filePath));
8715
+ if (!args.json) consola7.start(`Sending batch via stream (${(zipSize / 1e6).toFixed(1)} MB)...`);
8716
+ const result = await uploadBatchStream2(client, zipStreamFactory, zipSize, {
8717
+ formCode,
8718
+ pollOptions: { intervalMs: 3e3 }
8719
+ });
8720
+ if (args.json) {
8721
+ outputResult(result, { json: true });
8722
+ } else {
8723
+ outputSuccess(`Batch sent via stream. Ref: ${result.sessionRef}, invoices: ${result.upo.invoiceCount ?? "unknown"}`);
8724
+ }
8725
+ return;
8726
+ }
7637
8727
  if (stat.isDirectory()) {
7638
- const xmlFiles = fs4.readdirSync(filePath).filter((f) => f.endsWith(".xml")).map((f) => path3.join(filePath, f));
8728
+ const xmlFiles = fs7.readdirSync(filePath).filter((f) => f.endsWith(".xml")).map((f) => path5.join(filePath, f));
7639
8729
  if (xmlFiles.length === 0) {
7640
8730
  throw new Error(`No XML files found in ${filePath}`);
7641
8731
  }
7642
8732
  if (!nip) {
7643
8733
  throw new Error("NIP is required. Provide --nip or set it via `ksef config set --nip <nip>`.");
7644
8734
  }
7645
- if (!args.json) consola6.start(`Sending ${xmlFiles.length} invoices via batch session...`);
8735
+ if (!validateFormCodeForSession(formCode, "batch")) {
8736
+ throw new Error(`Document type "${formCode.systemCode}" is not supported in batch sessions. PEF/PEF_KOR require online sessions.`);
8737
+ }
8738
+ if (!args.json) consola7.start(`Sending ${xmlFiles.length} invoices via batch session...`);
7646
8739
  await client.crypto.init();
7647
8740
  const encryptionData = client.crypto.getEncryptionData();
7648
- const formCode = { systemCode: "FA (2)", schemaVersion: "1-0E", value: "FA" };
7649
8741
  const parts = xmlFiles.map((file, i) => {
7650
- const content = fs4.readFileSync(file);
8742
+ const content = fs7.readFileSync(file);
7651
8743
  const metadata = client.crypto.getFileMetadata(new Uint8Array(content));
7652
8744
  return {
7653
8745
  data: content.buffer,
@@ -7655,7 +8747,7 @@ var send = defineCommand4({
7655
8747
  ordinalNumber: i + 1
7656
8748
  };
7657
8749
  });
7658
- const totalContent = Buffer.concat(xmlFiles.map((f) => fs4.readFileSync(f)));
8750
+ const totalContent = Buffer.concat(xmlFiles.map((f) => fs7.readFileSync(f)));
7659
8751
  const totalMetadata = client.crypto.getFileMetadata(new Uint8Array(totalContent));
7660
8752
  const batchFileInfo = {
7661
8753
  fileSize: totalMetadata.fileSize,
@@ -7683,10 +8775,10 @@ var send = defineCommand4({
7683
8775
  if (!ref) {
7684
8776
  throw new Error("No active online session. Run `ksef session open` or provide --session-ref.");
7685
8777
  }
7686
- if (!args.json) consola6.start("Sending invoice...");
8778
+ if (!args.json) consola7.start("Sending invoice...");
7687
8779
  await client.crypto.init();
7688
8780
  const encryptionData = client.crypto.getEncryptionData();
7689
- const xmlContent = fs4.readFileSync(filePath);
8781
+ const xmlContent = fs7.readFileSync(filePath);
7690
8782
  const xmlBytes = new Uint8Array(xmlContent);
7691
8783
  const plainMetadata = client.crypto.getFileMetadata(xmlBytes);
7692
8784
  const encrypted = client.crypto.encryptAES256(xmlBytes, encryptionData.cipherKey, encryptionData.cipherIv);
@@ -7707,7 +8799,7 @@ var send = defineCommand4({
7707
8799
  });
7708
8800
  }
7709
8801
  });
7710
- var get = defineCommand4({
8802
+ var get = defineCommand5({
7711
8803
  meta: { name: "get", description: "Download invoice by KSeF number" },
7712
8804
  args: {
7713
8805
  ksefNumber: { type: "positional", description: "KSeF invoice number", required: true },
@@ -7719,7 +8811,7 @@ var get = defineCommand4({
7719
8811
  },
7720
8812
  run({ args }) {
7721
8813
  return withErrorHandler(async () => {
7722
- const globalOpts = getGlobalOpts3(args);
8814
+ const globalOpts = getGlobalOpts4(args);
7723
8815
  const { client } = requireSession(globalOpts);
7724
8816
  const xml = await client.invoices.getInvoice(args.ksefNumber);
7725
8817
  if (args.json) {
@@ -7727,7 +8819,7 @@ var get = defineCommand4({
7727
8819
  return;
7728
8820
  }
7729
8821
  if (args.o) {
7730
- fs4.writeFileSync(args.o, xml, "utf-8");
8822
+ fs7.writeFileSync(args.o, xml, "utf-8");
7731
8823
  outputSuccess(`Invoice saved to ${args.o}`);
7732
8824
  } else {
7733
8825
  console.log(xml);
@@ -7735,7 +8827,7 @@ var get = defineCommand4({
7735
8827
  });
7736
8828
  }
7737
8829
  });
7738
- var query = defineCommand4({
8830
+ var query = defineCommand5({
7739
8831
  meta: { name: "query", description: "Query invoice metadata" },
7740
8832
  args: {
7741
8833
  ...QUERY_FILTER_ARGS,
@@ -7749,7 +8841,7 @@ var query = defineCommand4({
7749
8841
  },
7750
8842
  run({ args }) {
7751
8843
  return withErrorHandler(async () => {
7752
- const globalOpts = getGlobalOpts3(args);
8844
+ const globalOpts = getGlobalOpts4(args);
7753
8845
  const { client } = requireSession(globalOpts);
7754
8846
  const filters = buildQueryFilters(args);
7755
8847
  const pageOffset = args.page ? parseInt(args.page, 10) : void 0;
@@ -7764,7 +8856,7 @@ var query = defineCommand4({
7764
8856
  return;
7765
8857
  }
7766
8858
  if (result.invoices.length === 0) {
7767
- consola6.info("No invoices found matching the criteria.");
8859
+ consola7.info("No invoices found matching the criteria.");
7768
8860
  return;
7769
8861
  }
7770
8862
  outputTable(
@@ -7787,12 +8879,12 @@ var query = defineCommand4({
7787
8879
  { json: false }
7788
8880
  );
7789
8881
  if (result.hasMore) {
7790
- consola6.info("More results available. Use --page to fetch the next page.");
8882
+ consola7.info("More results available. Use --page to fetch the next page.");
7791
8883
  }
7792
8884
  });
7793
8885
  }
7794
8886
  });
7795
- var exportCmd = defineCommand4({
8887
+ var exportCmd = defineCommand5({
7796
8888
  meta: { name: "export", description: "Start invoice export" },
7797
8889
  args: {
7798
8890
  ...QUERY_FILTER_ARGS,
@@ -7804,9 +8896,9 @@ var exportCmd = defineCommand4({
7804
8896
  },
7805
8897
  run({ args }) {
7806
8898
  return withErrorHandler(async () => {
7807
- const globalOpts = getGlobalOpts3(args);
8899
+ const globalOpts = getGlobalOpts4(args);
7808
8900
  const { client } = requireSession(globalOpts);
7809
- if (!args.json) consola6.start("Starting invoice export...");
8901
+ if (!args.json) consola7.start("Starting invoice export...");
7810
8902
  await client.crypto.init();
7811
8903
  const encryptionData = client.crypto.getEncryptionData();
7812
8904
  const filters = buildQueryFilters(args);
@@ -7817,12 +8909,12 @@ var exportCmd = defineCommand4({
7817
8909
  outputResult(result, { json: true });
7818
8910
  } else {
7819
8911
  outputSuccess(`Export started. Ref: ${result.referenceNumber}`);
7820
- consola6.info("Check status with: ksef invoice export-status " + result.referenceNumber);
8912
+ consola7.info("Check status with: ksef invoice export-status " + result.referenceNumber);
7821
8913
  }
7822
8914
  });
7823
8915
  }
7824
8916
  });
7825
- var exportStatus = defineCommand4({
8917
+ var exportStatus = defineCommand5({
7826
8918
  meta: { name: "export-status", description: "Check invoice export status" },
7827
8919
  args: {
7828
8920
  ref: { type: "positional", description: "Export reference number", required: true },
@@ -7833,22 +8925,22 @@ var exportStatus = defineCommand4({
7833
8925
  },
7834
8926
  run({ args }) {
7835
8927
  return withErrorHandler(async () => {
7836
- const globalOpts = getGlobalOpts3(args);
8928
+ const globalOpts = getGlobalOpts4(args);
7837
8929
  const { client } = requireSession(globalOpts);
7838
8930
  const result = await client.invoices.getInvoiceExportStatus(args.ref);
7839
8931
  if (args.json) {
7840
8932
  outputResult(result, { json: true });
7841
8933
  return;
7842
8934
  }
7843
- consola6.info(`Status: ${result.status.code} \u2014 ${result.status.description}`);
8935
+ consola7.info(`Status: ${result.status.code} \u2014 ${result.status.description}`);
7844
8936
  if (result.completedDate) {
7845
- consola6.info(`Completed: ${result.completedDate}`);
8937
+ consola7.info(`Completed: ${result.completedDate}`);
7846
8938
  }
7847
8939
  if (result.packageExpirationDate) {
7848
- consola6.info(`Package expires: ${result.packageExpirationDate}`);
8940
+ consola7.info(`Package expires: ${result.packageExpirationDate}`);
7849
8941
  }
7850
8942
  if (result.package) {
7851
- consola6.info(`Invoices: ${result.package.invoiceCount}, Size: ${result.package.size} bytes`);
8943
+ consola7.info(`Invoices: ${result.package.invoiceCount}, Size: ${result.package.size} bytes`);
7852
8944
  if (result.package.parts.length > 0) {
7853
8945
  outputTable(
7854
8946
  result.package.parts.map((p) => ({
@@ -7872,14 +8964,14 @@ var exportStatus = defineCommand4({
7872
8964
  });
7873
8965
  }
7874
8966
  });
7875
- var invoiceCommand = defineCommand4({
8967
+ var invoiceCommand = defineCommand5({
7876
8968
  meta: { name: "invoice", description: "Invoice commands" },
7877
- subCommands: { send, get, query, export: exportCmd, "export-status": exportStatus }
8969
+ subCommands: { send, get, query, export: exportCmd, "export-status": exportStatus, "export-incremental": exportIncremental }
7878
8970
  });
7879
8971
 
7880
8972
  // src/cli/commands/permission.ts
7881
- import { defineCommand as defineCommand5 } from "citty";
7882
- function getGlobalOpts4(args) {
8973
+ import { defineCommand as defineCommand6 } from "citty";
8974
+ function getGlobalOpts5(args) {
7883
8975
  return {
7884
8976
  env: args.env,
7885
8977
  json: args.json,
@@ -7888,7 +8980,7 @@ function getGlobalOpts4(args) {
7888
8980
  nip: args.nip
7889
8981
  };
7890
8982
  }
7891
- var grant = defineCommand5({
8983
+ var grant = defineCommand6({
7892
8984
  meta: { name: "grant", description: "Grant permissions to a subject" },
7893
8985
  args: {
7894
8986
  type: { type: "string", description: "Grant type: person, entity, authorization, indirect, subunit, eu-entity-admin, eu-entity-representative", required: true },
@@ -7913,7 +9005,7 @@ var grant = defineCommand5({
7913
9005
  },
7914
9006
  run({ args }) {
7915
9007
  return withErrorHandler(async () => {
7916
- const globalOpts = getGlobalOpts4(args);
9008
+ const globalOpts = getGlobalOpts5(args);
7917
9009
  const { client } = requireSession(globalOpts);
7918
9010
  let result;
7919
9011
  switch (args.type) {
@@ -8069,7 +9161,7 @@ var grant = defineCommand5({
8069
9161
  });
8070
9162
  }
8071
9163
  });
8072
- var revoke2 = defineCommand5({
9164
+ var revoke2 = defineCommand6({
8073
9165
  meta: { name: "revoke", description: "Revoke a permission grant" },
8074
9166
  args: {
8075
9167
  grantId: { type: "positional", description: "Grant ID to revoke", required: true },
@@ -8082,7 +9174,7 @@ var revoke2 = defineCommand5({
8082
9174
  },
8083
9175
  run({ args }) {
8084
9176
  return withErrorHandler(async () => {
8085
- const globalOpts = getGlobalOpts4(args);
9177
+ const globalOpts = getGlobalOpts5(args);
8086
9178
  const { client } = requireSession(globalOpts);
8087
9179
  let result;
8088
9180
  if (args.authorization) {
@@ -8098,7 +9190,7 @@ var revoke2 = defineCommand5({
8098
9190
  });
8099
9191
  }
8100
9192
  });
8101
- var search = defineCommand5({
9193
+ var search = defineCommand6({
8102
9194
  meta: { name: "search", description: "Search permissions" },
8103
9195
  args: {
8104
9196
  type: { type: "string", description: "Search type: personal, persons, subunits, entities, entities-grants, subordinate-entities, authorizations, eu-entities", required: true },
@@ -8115,7 +9207,7 @@ var search = defineCommand5({
8115
9207
  },
8116
9208
  run({ args }) {
8117
9209
  return withErrorHandler(async () => {
8118
- const globalOpts = getGlobalOpts4(args);
9210
+ const globalOpts = getGlobalOpts5(args);
8119
9211
  const { client } = requireSession(globalOpts);
8120
9212
  const page = args.page ? parseInt(args.page, 10) : void 0;
8121
9213
  const pageSize = args.pageSize ? parseInt(args.pageSize, 10) : void 0;
@@ -8337,7 +9429,7 @@ var search = defineCommand5({
8337
9429
  });
8338
9430
  }
8339
9431
  });
8340
- var status3 = defineCommand5({
9432
+ var status3 = defineCommand6({
8341
9433
  meta: { name: "status", description: "Check permission operation status" },
8342
9434
  args: {
8343
9435
  ref: { type: "positional", description: "Operation reference number", required: true },
@@ -8349,7 +9441,7 @@ var status3 = defineCommand5({
8349
9441
  },
8350
9442
  run({ args }) {
8351
9443
  return withErrorHandler(async () => {
8352
- const globalOpts = getGlobalOpts4(args);
9444
+ const globalOpts = getGlobalOpts5(args);
8353
9445
  const { client } = requireSession(globalOpts);
8354
9446
  const result = await client.permissions.getOperationStatus(args.ref);
8355
9447
  if (args.json) {
@@ -8363,7 +9455,7 @@ var status3 = defineCommand5({
8363
9455
  });
8364
9456
  }
8365
9457
  });
8366
- var attachmentStatus = defineCommand5({
9458
+ var attachmentStatus = defineCommand6({
8367
9459
  meta: { name: "attachment-status", description: "Check if attachment permissions are allowed" },
8368
9460
  args: {
8369
9461
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -8374,7 +9466,7 @@ var attachmentStatus = defineCommand5({
8374
9466
  },
8375
9467
  run({ args }) {
8376
9468
  return withErrorHandler(async () => {
8377
- const globalOpts = getGlobalOpts4(args);
9469
+ const globalOpts = getGlobalOpts5(args);
8378
9470
  const { client } = requireSession(globalOpts);
8379
9471
  const result = await client.permissions.getAttachmentStatus();
8380
9472
  if (args.json) {
@@ -8387,15 +9479,15 @@ var attachmentStatus = defineCommand5({
8387
9479
  });
8388
9480
  }
8389
9481
  });
8390
- var permissionCommand = defineCommand5({
9482
+ var permissionCommand = defineCommand6({
8391
9483
  meta: { name: "permission", description: "Permission management commands" },
8392
9484
  subCommands: { grant, revoke: revoke2, search, status: status3, "attachment-status": attachmentStatus }
8393
9485
  });
8394
9486
 
8395
9487
  // src/cli/commands/token.ts
8396
- import { defineCommand as defineCommand6 } from "citty";
8397
- import { consola as consola7 } from "consola";
8398
- function getGlobalOpts5(args) {
9488
+ import { defineCommand as defineCommand7 } from "citty";
9489
+ import { consola as consola8 } from "consola";
9490
+ function getGlobalOpts6(args) {
8399
9491
  return {
8400
9492
  env: args.env,
8401
9493
  json: args.json,
@@ -8404,7 +9496,7 @@ function getGlobalOpts5(args) {
8404
9496
  nip: args.nip
8405
9497
  };
8406
9498
  }
8407
- var generate = defineCommand6({
9499
+ var generate = defineCommand7({
8408
9500
  meta: { name: "generate", description: "Generate a new KSeF token" },
8409
9501
  args: {
8410
9502
  permissions: { type: "string", description: "Comma-separated permissions (e.g. InvoiceRead,InvoiceWrite)", required: true },
@@ -8417,7 +9509,7 @@ var generate = defineCommand6({
8417
9509
  },
8418
9510
  run({ args }) {
8419
9511
  return withErrorHandler(async () => {
8420
- const globalOpts = getGlobalOpts5(args);
9512
+ const globalOpts = getGlobalOpts6(args);
8421
9513
  const { client } = requireSession(globalOpts);
8422
9514
  if (!args.permissions) {
8423
9515
  throw new Error("--permissions is required. Provide comma-separated values (e.g. InvoiceRead,InvoiceWrite).");
@@ -8440,7 +9532,7 @@ var generate = defineCommand6({
8440
9532
  });
8441
9533
  }
8442
9534
  });
8443
- var list2 = defineCommand6({
9535
+ var list2 = defineCommand7({
8444
9536
  meta: { name: "list", description: "List KSeF tokens" },
8445
9537
  args: {
8446
9538
  status: { type: "string", description: "Comma-separated statuses (e.g. Active,Pending)" },
@@ -8457,7 +9549,7 @@ var list2 = defineCommand6({
8457
9549
  },
8458
9550
  run({ args }) {
8459
9551
  return withErrorHandler(async () => {
8460
- const globalOpts = getGlobalOpts5(args);
9552
+ const globalOpts = getGlobalOpts6(args);
8461
9553
  const { client } = requireSession(globalOpts);
8462
9554
  const options = {
8463
9555
  continuationToken: args.continue,
@@ -8494,12 +9586,12 @@ var list2 = defineCommand6({
8494
9586
  { json: false }
8495
9587
  );
8496
9588
  if (result.continuationToken) {
8497
- consola7.info(`More results available. Continuation token: ${result.continuationToken}`);
9589
+ consola8.info(`More results available. Continuation token: ${result.continuationToken}`);
8498
9590
  }
8499
9591
  });
8500
9592
  }
8501
9593
  });
8502
- var get2 = defineCommand6({
9594
+ var get2 = defineCommand7({
8503
9595
  meta: { name: "get", description: "Get token details" },
8504
9596
  args: {
8505
9597
  ref: { type: "positional", description: "Token reference number", required: true },
@@ -8511,7 +9603,7 @@ var get2 = defineCommand6({
8511
9603
  },
8512
9604
  run({ args }) {
8513
9605
  return withErrorHandler(async () => {
8514
- const globalOpts = getGlobalOpts5(args);
9606
+ const globalOpts = getGlobalOpts6(args);
8515
9607
  const { client } = requireSession(globalOpts);
8516
9608
  const ref = args.ref;
8517
9609
  const result = await client.tokens.getToken(ref);
@@ -8532,7 +9624,7 @@ var get2 = defineCommand6({
8532
9624
  });
8533
9625
  }
8534
9626
  });
8535
- var revoke3 = defineCommand6({
9627
+ var revoke3 = defineCommand7({
8536
9628
  meta: { name: "revoke", description: "Revoke a KSeF token" },
8537
9629
  args: {
8538
9630
  ref: { type: "positional", description: "Token reference number", required: true },
@@ -8544,7 +9636,7 @@ var revoke3 = defineCommand6({
8544
9636
  },
8545
9637
  run({ args }) {
8546
9638
  return withErrorHandler(async () => {
8547
- const globalOpts = getGlobalOpts5(args);
9639
+ const globalOpts = getGlobalOpts6(args);
8548
9640
  const { client } = requireSession(globalOpts);
8549
9641
  const ref = args.ref;
8550
9642
  await client.tokens.revokeToken(ref);
@@ -8556,24 +9648,24 @@ var revoke3 = defineCommand6({
8556
9648
  });
8557
9649
  }
8558
9650
  });
8559
- var tokenCommand = defineCommand6({
9651
+ var tokenCommand = defineCommand7({
8560
9652
  meta: { name: "token", description: "Token management commands" },
8561
9653
  subCommands: { generate, list: list2, get: get2, revoke: revoke3 }
8562
9654
  });
8563
9655
 
8564
9656
  // src/cli/commands/cert.ts
8565
- import { defineCommand as defineCommand7 } from "citty";
8566
- import { consola as consola8 } from "consola";
8567
- import fs5 from "fs";
8568
- import path4 from "path";
9657
+ import { defineCommand as defineCommand8 } from "citty";
9658
+ import { consola as consola9 } from "consola";
9659
+ import fs8 from "fs";
9660
+ import path6 from "path";
8569
9661
 
8570
9662
  // src/crypto/certificate-service.ts
8571
- import * as crypto4 from "crypto";
9663
+ import * as crypto5 from "crypto";
8572
9664
  import * as x5092 from "@peculiar/x509";
8573
9665
  var CertificateService = class {
8574
9666
  static getSha256Fingerprint(certPem) {
8575
9667
  const der = extractDerFromPem2(certPem);
8576
- return crypto4.createHash("sha256").update(der).digest("hex").toUpperCase();
9668
+ return crypto5.createHash("sha256").update(der).digest("hex").toUpperCase();
8577
9669
  }
8578
9670
  static async generatePersonalCertificate(givenName, surname, serialNumber, commonName, method = "RSA") {
8579
9671
  const nameParts = [];
@@ -8596,7 +9688,7 @@ var CertificateService = class {
8596
9688
  }
8597
9689
  };
8598
9690
  async function generateSelfSigned(subject2, method) {
8599
- x5092.cryptoProvider.set(crypto4.webcrypto);
9691
+ x5092.cryptoProvider.set(crypto5.webcrypto);
8600
9692
  let algorithm;
8601
9693
  let signingAlgorithm;
8602
9694
  if (method === "ECDSA") {
@@ -8611,7 +9703,7 @@ async function generateSelfSigned(subject2, method) {
8611
9703
  };
8612
9704
  signingAlgorithm = algorithm;
8613
9705
  }
8614
- const keys = await crypto4.webcrypto.subtle.generateKey(
9706
+ const keys = await crypto5.webcrypto.subtle.generateKey(
8615
9707
  algorithm,
8616
9708
  true,
8617
9709
  ["sign", "verify"]
@@ -8628,9 +9720,9 @@ async function generateSelfSigned(subject2, method) {
8628
9720
  serialNumber: Date.now().toString(16)
8629
9721
  });
8630
9722
  const certPem = cert.toString("pem");
8631
- const pkcs8 = await crypto4.webcrypto.subtle.exportKey("pkcs8", keys.privateKey);
9723
+ const pkcs8 = await crypto5.webcrypto.subtle.exportKey("pkcs8", keys.privateKey);
8632
9724
  const privateKeyPem = pemEncode2(new Uint8Array(pkcs8), "PRIVATE KEY");
8633
- const fingerprint = crypto4.createHash("sha256").update(Buffer.from(cert.rawData)).digest("hex").toUpperCase();
9725
+ const fingerprint = crypto5.createHash("sha256").update(Buffer.from(cert.rawData)).digest("hex").toUpperCase();
8634
9726
  return { certificatePem: certPem, privateKeyPem, fingerprint };
8635
9727
  }
8636
9728
  function extractDerFromPem2(pem) {
@@ -8649,7 +9741,7 @@ ${lines.join("\n")}
8649
9741
  }
8650
9742
 
8651
9743
  // src/cli/commands/cert.ts
8652
- function getGlobalOpts6(args) {
9744
+ function getGlobalOpts7(args) {
8653
9745
  return {
8654
9746
  env: args.env,
8655
9747
  json: args.json,
@@ -8658,7 +9750,7 @@ function getGlobalOpts6(args) {
8658
9750
  nip: args.nip
8659
9751
  };
8660
9752
  }
8661
- var generate2 = defineCommand7({
9753
+ var generate2 = defineCommand8({
8662
9754
  meta: { name: "generate", description: "Generate a self-signed certificate locally" },
8663
9755
  args: {
8664
9756
  type: { type: "string", description: "Certificate type: personal or company-seal", required: true },
@@ -8683,21 +9775,21 @@ var generate2 = defineCommand7({
8683
9775
  const certType = args.type;
8684
9776
  const cn = args.cn;
8685
9777
  const method = args.method || "RSA";
8686
- const outDir = path4.resolve(args.out || ".");
9778
+ const outDir = path6.resolve(args.out || ".");
8687
9779
  if (certType !== "personal" && certType !== "company-seal") {
8688
9780
  throw new Error('--type must be "personal" or "company-seal".');
8689
9781
  }
8690
9782
  if (method !== "RSA" && method !== "ECDSA") {
8691
9783
  throw new Error('--method must be "RSA" or "ECDSA".');
8692
9784
  }
8693
- fs5.mkdirSync(outDir, { recursive: true });
8694
- const certPath = path4.join(outDir, "cert.pem");
8695
- const keyPath = path4.join(outDir, "key.pem");
9785
+ fs8.mkdirSync(outDir, { recursive: true });
9786
+ const certPath = path6.join(outDir, "cert.pem");
9787
+ const keyPath = path6.join(outDir, "key.pem");
8696
9788
  if (!args.force) {
8697
- if (fs5.existsSync(certPath)) {
9789
+ if (fs8.existsSync(certPath)) {
8698
9790
  throw new Error(`File already exists: ${certPath}. Use --force to overwrite.`);
8699
9791
  }
8700
- if (fs5.existsSync(keyPath)) {
9792
+ if (fs8.existsSync(keyPath)) {
8701
9793
  throw new Error(`File already exists: ${keyPath}. Use --force to overwrite.`);
8702
9794
  }
8703
9795
  }
@@ -8724,8 +9816,8 @@ var generate2 = defineCommand7({
8724
9816
  method
8725
9817
  );
8726
9818
  }
8727
- fs5.writeFileSync(certPath, result.certificatePem, "utf-8");
8728
- fs5.writeFileSync(keyPath, result.privateKeyPem, "utf-8");
9819
+ fs8.writeFileSync(certPath, result.certificatePem, "utf-8");
9820
+ fs8.writeFileSync(keyPath, result.privateKeyPem, "utf-8");
8729
9821
  if (args.json) {
8730
9822
  outputResult({ certPath, keyPath, fingerprint: result.fingerprint }, { json: true });
8731
9823
  } else {
@@ -8739,7 +9831,7 @@ var generate2 = defineCommand7({
8739
9831
  });
8740
9832
  }
8741
9833
  });
8742
- var enroll = defineCommand7({
9834
+ var enroll = defineCommand8({
8743
9835
  meta: { name: "enroll", description: "Submit certificate enrollment" },
8744
9836
  args: {
8745
9837
  cert: { type: "string", description: "Path to certificate PEM file", required: true },
@@ -8754,9 +9846,9 @@ var enroll = defineCommand7({
8754
9846
  },
8755
9847
  run({ args }) {
8756
9848
  return withErrorHandler(async () => {
8757
- const globalOpts = getGlobalOpts6(args);
9849
+ const globalOpts = getGlobalOpts7(args);
8758
9850
  const { client } = requireSession(globalOpts);
8759
- const certPem = fs5.readFileSync(args.cert, "utf-8");
9851
+ const certPem = fs8.readFileSync(args.cert, "utf-8");
8760
9852
  await client.crypto.init();
8761
9853
  const request = {
8762
9854
  certificateName: args.name,
@@ -8777,7 +9869,7 @@ var enroll = defineCommand7({
8777
9869
  });
8778
9870
  }
8779
9871
  });
8780
- var status4 = defineCommand7({
9872
+ var status4 = defineCommand8({
8781
9873
  meta: { name: "status", description: "Check certificate enrollment status" },
8782
9874
  args: {
8783
9875
  ref: { type: "positional", description: "Enrollment reference number", required: true },
@@ -8789,7 +9881,7 @@ var status4 = defineCommand7({
8789
9881
  },
8790
9882
  run({ args }) {
8791
9883
  return withErrorHandler(async () => {
8792
- const globalOpts = getGlobalOpts6(args);
9884
+ const globalOpts = getGlobalOpts7(args);
8793
9885
  const { client } = requireSession(globalOpts);
8794
9886
  const ref = args.ref;
8795
9887
  const result = await client.certificates.getEnrollmentStatus(ref);
@@ -8809,7 +9901,7 @@ var status4 = defineCommand7({
8809
9901
  });
8810
9902
  }
8811
9903
  });
8812
- var list3 = defineCommand7({
9904
+ var list3 = defineCommand8({
8813
9905
  meta: { name: "list", description: "Query certificates" },
8814
9906
  args: {
8815
9907
  serial: { type: "string", description: "Filter by serial number" },
@@ -8827,7 +9919,7 @@ var list3 = defineCommand7({
8827
9919
  },
8828
9920
  run({ args }) {
8829
9921
  return withErrorHandler(async () => {
8830
- const globalOpts = getGlobalOpts6(args);
9922
+ const globalOpts = getGlobalOpts7(args);
8831
9923
  const { client } = requireSession(globalOpts);
8832
9924
  const request = {
8833
9925
  certificateSerialNumber: args.serial,
@@ -8867,12 +9959,12 @@ var list3 = defineCommand7({
8867
9959
  { json: false }
8868
9960
  );
8869
9961
  if (result.hasMore) {
8870
- consola8.info("More results available. Use --page to paginate.");
9962
+ consola9.info("More results available. Use --page to paginate.");
8871
9963
  }
8872
9964
  });
8873
9965
  }
8874
9966
  });
8875
- var revoke4 = defineCommand7({
9967
+ var revoke4 = defineCommand8({
8876
9968
  meta: { name: "revoke", description: "Revoke a certificate" },
8877
9969
  args: {
8878
9970
  serial: { type: "positional", description: "Certificate serial number", required: true },
@@ -8885,7 +9977,7 @@ var revoke4 = defineCommand7({
8885
9977
  },
8886
9978
  run({ args }) {
8887
9979
  return withErrorHandler(async () => {
8888
- const globalOpts = getGlobalOpts6(args);
9980
+ const globalOpts = getGlobalOpts7(args);
8889
9981
  const { client } = requireSession(globalOpts);
8890
9982
  const serial = args.serial;
8891
9983
  await client.certificates.revoke(serial, {
@@ -8899,7 +9991,7 @@ var revoke4 = defineCommand7({
8899
9991
  });
8900
9992
  }
8901
9993
  });
8902
- var limits = defineCommand7({
9994
+ var limits = defineCommand8({
8903
9995
  meta: { name: "limits", description: "View certificate limits" },
8904
9996
  args: {
8905
9997
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -8910,7 +10002,7 @@ var limits = defineCommand7({
8910
10002
  },
8911
10003
  run({ args }) {
8912
10004
  return withErrorHandler(async () => {
8913
- const globalOpts = getGlobalOpts6(args);
10005
+ const globalOpts = getGlobalOpts7(args);
8914
10006
  const { client } = requireSession(globalOpts);
8915
10007
  const result = await client.certificates.getLimits();
8916
10008
  if (args.json) {
@@ -8927,7 +10019,7 @@ var limits = defineCommand7({
8927
10019
  });
8928
10020
  }
8929
10021
  });
8930
- var enrollmentData = defineCommand7({
10022
+ var enrollmentData = defineCommand8({
8931
10023
  meta: { name: "enrollment-data", description: "Get enrollment data template from KSeF" },
8932
10024
  args: {
8933
10025
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -8938,7 +10030,7 @@ var enrollmentData = defineCommand7({
8938
10030
  },
8939
10031
  run({ args }) {
8940
10032
  return withErrorHandler(async () => {
8941
- const globalOpts = getGlobalOpts6(args);
10033
+ const globalOpts = getGlobalOpts7(args);
8942
10034
  const { client } = requireSession(globalOpts);
8943
10035
  const result = await client.certificates.getEnrollmentData();
8944
10036
  if (args.json) {
@@ -8958,7 +10050,7 @@ var enrollmentData = defineCommand7({
8958
10050
  });
8959
10051
  }
8960
10052
  });
8961
- var retrieve = defineCommand7({
10053
+ var retrieve = defineCommand8({
8962
10054
  meta: { name: "retrieve", description: "Retrieve certificates by serial numbers" },
8963
10055
  args: {
8964
10056
  serial: { type: "string", description: "Comma-separated certificate serial numbers", required: true },
@@ -8970,7 +10062,7 @@ var retrieve = defineCommand7({
8970
10062
  },
8971
10063
  run({ args }) {
8972
10064
  return withErrorHandler(async () => {
8973
- const globalOpts = getGlobalOpts6(args);
10065
+ const globalOpts = getGlobalOpts7(args);
8974
10066
  const { client } = requireSession(globalOpts);
8975
10067
  const serials = args.serial.split(",").map((s) => s.trim()).filter(Boolean);
8976
10068
  if (serials.length === 0) {
@@ -9001,14 +10093,14 @@ var retrieve = defineCommand7({
9001
10093
  });
9002
10094
  }
9003
10095
  });
9004
- var certCommand = defineCommand7({
10096
+ var certCommand = defineCommand8({
9005
10097
  meta: { name: "cert", description: "Certificate management commands" },
9006
10098
  subCommands: { generate: generate2, enroll, status: status4, list: list3, revoke: revoke4, limits, "enrollment-data": enrollmentData, retrieve }
9007
10099
  });
9008
10100
 
9009
10101
  // src/cli/commands/qr.ts
9010
- import * as fs6 from "fs";
9011
- import { defineCommand as defineCommand8 } from "citty";
10102
+ import * as fs9 from "fs";
10103
+ import { defineCommand as defineCommand9 } from "citty";
9012
10104
 
9013
10105
  // src/qr/qrcode-service.ts
9014
10106
  import * as QRCode from "qrcode";
@@ -9070,7 +10162,7 @@ function escapeXml2(str) {
9070
10162
  }
9071
10163
 
9072
10164
  // src/cli/commands/qr.ts
9073
- function getGlobalOpts7(args) {
10165
+ function getGlobalOpts8(args) {
9074
10166
  return {
9075
10167
  env: args.env,
9076
10168
  json: args.json,
@@ -9079,7 +10171,7 @@ function getGlobalOpts7(args) {
9079
10171
  nip: args.nip
9080
10172
  };
9081
10173
  }
9082
- var invoice2 = defineCommand8({
10174
+ var invoice2 = defineCommand9({
9083
10175
  meta: { name: "invoice", description: "Generate invoice QR code" },
9084
10176
  args: {
9085
10177
  nip: { type: "string", description: "NIP number", required: true },
@@ -9096,7 +10188,7 @@ var invoice2 = defineCommand8({
9096
10188
  },
9097
10189
  run({ args }) {
9098
10190
  return withErrorHandler(async () => {
9099
- const globalOpts = getGlobalOpts7(args);
10191
+ const globalOpts = getGlobalOpts8(args);
9100
10192
  const client = createClient(globalOpts);
9101
10193
  const size = args.size ? parseInt(args.size, 10) : 300;
9102
10194
  const format = args.format ?? "png";
@@ -9109,7 +10201,7 @@ var invoice2 = defineCommand8({
9109
10201
  if (format === "svg") {
9110
10202
  const svg = args.label ? await QrCodeService.generateQrCodeSvgWithLabel(url2, args.label, { width: size }) : await QrCodeService.generateQrCodeSvg(url2, { width: size });
9111
10203
  if (args.o) {
9112
- fs6.writeFileSync(args.o, svg);
10204
+ fs9.writeFileSync(args.o, svg);
9113
10205
  outputSuccess(`QR code saved to ${args.o}
9114
10206
  URL: ${url2}`);
9115
10207
  } else {
@@ -9118,7 +10210,7 @@ URL: ${url2}`);
9118
10210
  } else {
9119
10211
  const buffer = await QrCodeService.generateQrCode(url2, { width: size });
9120
10212
  if (args.o) {
9121
- fs6.writeFileSync(args.o, buffer);
10213
+ fs9.writeFileSync(args.o, buffer);
9122
10214
  outputSuccess(`QR code saved to ${args.o}
9123
10215
  URL: ${url2}`);
9124
10216
  } else {
@@ -9128,7 +10220,7 @@ URL: ${url2}`);
9128
10220
  });
9129
10221
  }
9130
10222
  });
9131
- var certificate = defineCommand8({
10223
+ var certificate = defineCommand9({
9132
10224
  meta: { name: "certificate", description: "Generate certificate QR code" },
9133
10225
  args: {
9134
10226
  "context-type": { type: "string", description: "Context identifier type", required: true },
@@ -9149,11 +10241,11 @@ var certificate = defineCommand8({
9149
10241
  },
9150
10242
  run({ args }) {
9151
10243
  return withErrorHandler(async () => {
9152
- const globalOpts = getGlobalOpts7(args);
10244
+ const globalOpts = getGlobalOpts8(args);
9153
10245
  const client = createClient(globalOpts);
9154
10246
  const size = args.size ? parseInt(args.size, 10) : 300;
9155
10247
  const format = args.format ?? "png";
9156
- const privateKeyPem = fs6.readFileSync(args.key, "utf-8");
10248
+ const privateKeyPem = fs9.readFileSync(args.key, "utf-8");
9157
10249
  const url2 = client.qr.buildCertificateVerificationUrl(
9158
10250
  args["context-type"],
9159
10251
  args["context-id"],
@@ -9170,7 +10262,7 @@ var certificate = defineCommand8({
9170
10262
  if (format === "svg") {
9171
10263
  const svg = args.label ? await QrCodeService.generateQrCodeSvgWithLabel(url2, args.label, { width: size }) : await QrCodeService.generateQrCodeSvg(url2, { width: size });
9172
10264
  if (args.o) {
9173
- fs6.writeFileSync(args.o, svg);
10265
+ fs9.writeFileSync(args.o, svg);
9174
10266
  outputSuccess(`QR code saved to ${args.o}
9175
10267
  URL: ${url2}`);
9176
10268
  } else {
@@ -9179,7 +10271,7 @@ URL: ${url2}`);
9179
10271
  } else {
9180
10272
  const buffer = await QrCodeService.generateQrCode(url2, { width: size });
9181
10273
  if (args.o) {
9182
- fs6.writeFileSync(args.o, buffer);
10274
+ fs9.writeFileSync(args.o, buffer);
9183
10275
  outputSuccess(`QR code saved to ${args.o}
9184
10276
  URL: ${url2}`);
9185
10277
  } else {
@@ -9189,7 +10281,7 @@ URL: ${url2}`);
9189
10281
  });
9190
10282
  }
9191
10283
  });
9192
- var url = defineCommand8({
10284
+ var url = defineCommand9({
9193
10285
  meta: { name: "url", description: "Print invoice verification URL (no QR image)" },
9194
10286
  args: {
9195
10287
  nip: { type: "string", description: "NIP number", required: true },
@@ -9202,7 +10294,7 @@ var url = defineCommand8({
9202
10294
  },
9203
10295
  run({ args }) {
9204
10296
  return withErrorHandler(async () => {
9205
- const globalOpts = getGlobalOpts7(args);
10297
+ const globalOpts = getGlobalOpts8(args);
9206
10298
  const client = createClient(globalOpts);
9207
10299
  const verificationUrl = client.qr.buildInvoiceVerificationUrl(args.nip, args.date, args.hash);
9208
10300
  if (args.json) {
@@ -9213,14 +10305,14 @@ var url = defineCommand8({
9213
10305
  });
9214
10306
  }
9215
10307
  });
9216
- var qrCommand = defineCommand8({
10308
+ var qrCommand = defineCommand9({
9217
10309
  meta: { name: "qr", description: "QR code generation commands" },
9218
10310
  subCommands: { invoice: invoice2, certificate, url }
9219
10311
  });
9220
10312
 
9221
10313
  // src/cli/commands/lighthouse.ts
9222
- import { defineCommand as defineCommand9 } from "citty";
9223
- function getGlobalOpts8(args) {
10314
+ import { defineCommand as defineCommand10 } from "citty";
10315
+ function getGlobalOpts9(args) {
9224
10316
  return {
9225
10317
  env: args.env ?? "prod",
9226
10318
  json: args.json,
@@ -9229,7 +10321,7 @@ function getGlobalOpts8(args) {
9229
10321
  nip: args.nip
9230
10322
  };
9231
10323
  }
9232
- var status5 = defineCommand9({
10324
+ var status5 = defineCommand10({
9233
10325
  meta: { name: "status", description: "Check KSeF system status" },
9234
10326
  args: {
9235
10327
  env: { type: "string", description: "Environment (test/prod, default: prod)" },
@@ -9240,7 +10332,7 @@ var status5 = defineCommand9({
9240
10332
  },
9241
10333
  run({ args }) {
9242
10334
  return withErrorHandler(async () => {
9243
- const globalOpts = getGlobalOpts8(args);
10335
+ const globalOpts = getGlobalOpts9(args);
9244
10336
  const client = createClient(globalOpts);
9245
10337
  const result = await client.lighthouse.getStatus();
9246
10338
  if (args.json) {
@@ -9257,7 +10349,7 @@ var status5 = defineCommand9({
9257
10349
  });
9258
10350
  }
9259
10351
  });
9260
- var messages = defineCommand9({
10352
+ var messages = defineCommand10({
9261
10353
  meta: { name: "messages", description: "View KSeF system messages" },
9262
10354
  args: {
9263
10355
  env: { type: "string", description: "Environment (test/prod, default: prod)" },
@@ -9268,7 +10360,7 @@ var messages = defineCommand9({
9268
10360
  },
9269
10361
  run({ args }) {
9270
10362
  return withErrorHandler(async () => {
9271
- const globalOpts = getGlobalOpts8(args);
10363
+ const globalOpts = getGlobalOpts9(args);
9272
10364
  const client = createClient(globalOpts);
9273
10365
  const msgs = await client.lighthouse.getMessages();
9274
10366
  if (args.json) {
@@ -9299,14 +10391,14 @@ var messages = defineCommand9({
9299
10391
  });
9300
10392
  }
9301
10393
  });
9302
- var lighthouseCommand = defineCommand9({
10394
+ var lighthouseCommand = defineCommand10({
9303
10395
  meta: { name: "lighthouse", description: "KSeF system status commands" },
9304
10396
  subCommands: { status: status5, messages }
9305
10397
  });
9306
10398
 
9307
10399
  // src/cli/commands/test-data.ts
9308
- import { defineCommand as defineCommand10 } from "citty";
9309
- function getGlobalOpts9(args) {
10400
+ import { defineCommand as defineCommand11 } from "citty";
10401
+ function getGlobalOpts10(args) {
9310
10402
  return {
9311
10403
  env: args.env,
9312
10404
  json: args.json,
@@ -9328,7 +10420,7 @@ function outputDone(json) {
9328
10420
  outputSuccess("Done.");
9329
10421
  }
9330
10422
  }
9331
- var createSubject = defineCommand10({
10423
+ var createSubject = defineCommand11({
9332
10424
  meta: { name: "create-subject", description: "Create a test subject" },
9333
10425
  args: {
9334
10426
  nip: { type: "string", description: "Subject NIP", required: true },
@@ -9342,7 +10434,7 @@ var createSubject = defineCommand10({
9342
10434
  },
9343
10435
  run({ args }) {
9344
10436
  return withErrorHandler(async () => {
9345
- const globalOpts = getGlobalOpts9(args);
10437
+ const globalOpts = getGlobalOpts10(args);
9346
10438
  requireNonProd(globalOpts);
9347
10439
  const request = {
9348
10440
  subjectNip: args.nip,
@@ -9355,7 +10447,7 @@ var createSubject = defineCommand10({
9355
10447
  });
9356
10448
  }
9357
10449
  });
9358
- var removeSubject = defineCommand10({
10450
+ var removeSubject = defineCommand11({
9359
10451
  meta: { name: "remove-subject", description: "Remove a test subject" },
9360
10452
  args: {
9361
10453
  nip: { type: "string", description: "Subject NIP", required: true },
@@ -9366,7 +10458,7 @@ var removeSubject = defineCommand10({
9366
10458
  },
9367
10459
  run({ args }) {
9368
10460
  return withErrorHandler(async () => {
9369
- const globalOpts = getGlobalOpts9(args);
10461
+ const globalOpts = getGlobalOpts10(args);
9370
10462
  requireNonProd(globalOpts);
9371
10463
  const request = { subjectNip: args.nip };
9372
10464
  await createClient(globalOpts).testData.removeSubject(request);
@@ -9374,7 +10466,7 @@ var removeSubject = defineCommand10({
9374
10466
  });
9375
10467
  }
9376
10468
  });
9377
- var createPerson = defineCommand10({
10469
+ var createPerson = defineCommand11({
9378
10470
  meta: { name: "create-person", description: "Create a test person" },
9379
10471
  args: {
9380
10472
  nip: { type: "string", description: "Person NIP", required: true },
@@ -9390,7 +10482,7 @@ var createPerson = defineCommand10({
9390
10482
  },
9391
10483
  run({ args }) {
9392
10484
  return withErrorHandler(async () => {
9393
- const globalOpts = getGlobalOpts9(args);
10485
+ const globalOpts = getGlobalOpts10(args);
9394
10486
  requireNonProd(globalOpts);
9395
10487
  const request = {
9396
10488
  nip: args.nip,
@@ -9405,7 +10497,7 @@ var createPerson = defineCommand10({
9405
10497
  });
9406
10498
  }
9407
10499
  });
9408
- var removePerson = defineCommand10({
10500
+ var removePerson = defineCommand11({
9409
10501
  meta: { name: "remove-person", description: "Remove a test person" },
9410
10502
  args: {
9411
10503
  nip: { type: "string", description: "Person NIP", required: true },
@@ -9416,7 +10508,7 @@ var removePerson = defineCommand10({
9416
10508
  },
9417
10509
  run({ args }) {
9418
10510
  return withErrorHandler(async () => {
9419
- const globalOpts = getGlobalOpts9(args);
10511
+ const globalOpts = getGlobalOpts10(args);
9420
10512
  requireNonProd(globalOpts);
9421
10513
  const request = { nip: args.nip };
9422
10514
  await createClient(globalOpts).testData.removePerson(request);
@@ -9424,7 +10516,7 @@ var removePerson = defineCommand10({
9424
10516
  });
9425
10517
  }
9426
10518
  });
9427
- var grantPermissions = defineCommand10({
10519
+ var grantPermissions = defineCommand11({
9428
10520
  meta: { name: "grant-permissions", description: "Grant test data permissions" },
9429
10521
  args: {
9430
10522
  "context-nip": { type: "string", description: "Context NIP", required: true },
@@ -9439,7 +10531,7 @@ var grantPermissions = defineCommand10({
9439
10531
  },
9440
10532
  run({ args }) {
9441
10533
  return withErrorHandler(async () => {
9442
- const globalOpts = getGlobalOpts9(args);
10534
+ const globalOpts = getGlobalOpts10(args);
9443
10535
  requireNonProd(globalOpts);
9444
10536
  const permissions = args.permissions.split(",").map((p) => ({ permissionType: p.trim(), description: "" }));
9445
10537
  const request = {
@@ -9455,7 +10547,7 @@ var grantPermissions = defineCommand10({
9455
10547
  });
9456
10548
  }
9457
10549
  });
9458
- var revokePermissions = defineCommand10({
10550
+ var revokePermissions = defineCommand11({
9459
10551
  meta: { name: "revoke-permissions", description: "Revoke test data permissions" },
9460
10552
  args: {
9461
10553
  "context-nip": { type: "string", description: "Context NIP", required: true },
@@ -9469,7 +10561,7 @@ var revokePermissions = defineCommand10({
9469
10561
  },
9470
10562
  run({ args }) {
9471
10563
  return withErrorHandler(async () => {
9472
- const globalOpts = getGlobalOpts9(args);
10564
+ const globalOpts = getGlobalOpts10(args);
9473
10565
  requireNonProd(globalOpts);
9474
10566
  const request = {
9475
10567
  contextIdentifier: { type: "Nip", value: args["context-nip"] },
@@ -9483,7 +10575,7 @@ var revokePermissions = defineCommand10({
9483
10575
  });
9484
10576
  }
9485
10577
  });
9486
- var enableAttachment = defineCommand10({
10578
+ var enableAttachment = defineCommand11({
9487
10579
  meta: { name: "enable-attachment", description: "Enable attachment permission for a subject" },
9488
10580
  args: {
9489
10581
  nip: { type: "string", description: "Subject NIP", required: true },
@@ -9494,7 +10586,7 @@ var enableAttachment = defineCommand10({
9494
10586
  },
9495
10587
  run({ args }) {
9496
10588
  return withErrorHandler(async () => {
9497
- const globalOpts = getGlobalOpts9(args);
10589
+ const globalOpts = getGlobalOpts10(args);
9498
10590
  requireNonProd(globalOpts);
9499
10591
  const request = { nip: args.nip };
9500
10592
  await createClient(globalOpts).testData.enableAttachment(request);
@@ -9502,7 +10594,7 @@ var enableAttachment = defineCommand10({
9502
10594
  });
9503
10595
  }
9504
10596
  });
9505
- var disableAttachment = defineCommand10({
10597
+ var disableAttachment = defineCommand11({
9506
10598
  meta: { name: "disable-attachment", description: "Disable attachment permission for a subject" },
9507
10599
  args: {
9508
10600
  nip: { type: "string", description: "Subject NIP", required: true },
@@ -9514,7 +10606,7 @@ var disableAttachment = defineCommand10({
9514
10606
  },
9515
10607
  run({ args }) {
9516
10608
  return withErrorHandler(async () => {
9517
- const globalOpts = getGlobalOpts9(args);
10609
+ const globalOpts = getGlobalOpts10(args);
9518
10610
  requireNonProd(globalOpts);
9519
10611
  const request = {
9520
10612
  nip: args.nip,
@@ -9525,7 +10617,7 @@ var disableAttachment = defineCommand10({
9525
10617
  });
9526
10618
  }
9527
10619
  });
9528
- var changeSessionLimits = defineCommand10({
10620
+ var changeSessionLimits = defineCommand11({
9529
10621
  meta: { name: "change-session-limits", description: "Change session limits in current context" },
9530
10622
  args: {
9531
10623
  "online-max-size": { type: "string", description: "Online session: max invoice size in MB (0-5)", required: true },
@@ -9542,7 +10634,7 @@ var changeSessionLimits = defineCommand10({
9542
10634
  },
9543
10635
  run({ args }) {
9544
10636
  return withErrorHandler(async () => {
9545
- const globalOpts = getGlobalOpts9(args);
10637
+ const globalOpts = getGlobalOpts10(args);
9546
10638
  requireNonProd(globalOpts);
9547
10639
  const { client } = requireSession(globalOpts);
9548
10640
  const request = {
@@ -9562,7 +10654,7 @@ var changeSessionLimits = defineCommand10({
9562
10654
  });
9563
10655
  }
9564
10656
  });
9565
- var restoreSessionLimits = defineCommand10({
10657
+ var restoreSessionLimits = defineCommand11({
9566
10658
  meta: { name: "restore-session-limits", description: "Restore default session limits" },
9567
10659
  args: {
9568
10660
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9573,7 +10665,7 @@ var restoreSessionLimits = defineCommand10({
9573
10665
  },
9574
10666
  run({ args }) {
9575
10667
  return withErrorHandler(async () => {
9576
- const globalOpts = getGlobalOpts9(args);
10668
+ const globalOpts = getGlobalOpts10(args);
9577
10669
  requireNonProd(globalOpts);
9578
10670
  const { client } = requireSession(globalOpts);
9579
10671
  await client.testData.restoreDefaultSessionLimits();
@@ -9581,7 +10673,7 @@ var restoreSessionLimits = defineCommand10({
9581
10673
  });
9582
10674
  }
9583
10675
  });
9584
- var changeCertLimits = defineCommand10({
10676
+ var changeCertLimits = defineCommand11({
9585
10677
  meta: { name: "change-cert-limits", description: "Change subject limits (enrollment/certificate) in current subject" },
9586
10678
  args: {
9587
10679
  "identifier-type": { type: "string", description: "Subject identifier type (Nip/Pesel/Fingerprint)" },
@@ -9595,7 +10687,7 @@ var changeCertLimits = defineCommand10({
9595
10687
  },
9596
10688
  run({ args }) {
9597
10689
  return withErrorHandler(async () => {
9598
- const globalOpts = getGlobalOpts9(args);
10690
+ const globalOpts = getGlobalOpts10(args);
9599
10691
  requireNonProd(globalOpts);
9600
10692
  const { client } = requireSession(globalOpts);
9601
10693
  const request = {
@@ -9608,7 +10700,7 @@ var changeCertLimits = defineCommand10({
9608
10700
  });
9609
10701
  }
9610
10702
  });
9611
- var restoreCertLimits = defineCommand10({
10703
+ var restoreCertLimits = defineCommand11({
9612
10704
  meta: { name: "restore-cert-limits", description: "Restore default certificates limit" },
9613
10705
  args: {
9614
10706
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9619,7 +10711,7 @@ var restoreCertLimits = defineCommand10({
9619
10711
  },
9620
10712
  run({ args }) {
9621
10713
  return withErrorHandler(async () => {
9622
- const globalOpts = getGlobalOpts9(args);
10714
+ const globalOpts = getGlobalOpts10(args);
9623
10715
  requireNonProd(globalOpts);
9624
10716
  const { client } = requireSession(globalOpts);
9625
10717
  await client.testData.restoreDefaultCertificatesLimit();
@@ -9627,7 +10719,7 @@ var restoreCertLimits = defineCommand10({
9627
10719
  });
9628
10720
  }
9629
10721
  });
9630
- var setRateLimits = defineCommand10({
10722
+ var setRateLimits = defineCommand11({
9631
10723
  meta: { name: "set-rate-limits", description: "Set effective API rate limits" },
9632
10724
  args: {
9633
10725
  limits: { type: "string", description: "Rate limits as JSON string (ApiRateLimitsOverride)", required: true },
@@ -9639,7 +10731,7 @@ var setRateLimits = defineCommand10({
9639
10731
  },
9640
10732
  run({ args }) {
9641
10733
  return withErrorHandler(async () => {
9642
- const globalOpts = getGlobalOpts9(args);
10734
+ const globalOpts = getGlobalOpts10(args);
9643
10735
  requireNonProd(globalOpts);
9644
10736
  const { client } = requireSession(globalOpts);
9645
10737
  const request = {
@@ -9650,7 +10742,7 @@ var setRateLimits = defineCommand10({
9650
10742
  });
9651
10743
  }
9652
10744
  });
9653
- var restoreRateLimits = defineCommand10({
10745
+ var restoreRateLimits = defineCommand11({
9654
10746
  meta: { name: "restore-rate-limits", description: "Restore default API rate limits" },
9655
10747
  args: {
9656
10748
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9661,7 +10753,7 @@ var restoreRateLimits = defineCommand10({
9661
10753
  },
9662
10754
  run({ args }) {
9663
10755
  return withErrorHandler(async () => {
9664
- const globalOpts = getGlobalOpts9(args);
10756
+ const globalOpts = getGlobalOpts10(args);
9665
10757
  requireNonProd(globalOpts);
9666
10758
  const { client } = requireSession(globalOpts);
9667
10759
  await client.testData.restoreDefaultRateLimits();
@@ -9669,7 +10761,7 @@ var restoreRateLimits = defineCommand10({
9669
10761
  });
9670
10762
  }
9671
10763
  });
9672
- var setProductionRateLimits = defineCommand10({
10764
+ var setProductionRateLimits = defineCommand11({
9673
10765
  meta: { name: "set-production-rate-limits", description: "Set production API rate limits" },
9674
10766
  args: {
9675
10767
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9680,7 +10772,7 @@ var setProductionRateLimits = defineCommand10({
9680
10772
  },
9681
10773
  run({ args }) {
9682
10774
  return withErrorHandler(async () => {
9683
- const globalOpts = getGlobalOpts9(args);
10775
+ const globalOpts = getGlobalOpts10(args);
9684
10776
  requireNonProd(globalOpts);
9685
10777
  const { client } = requireSession(globalOpts);
9686
10778
  await client.testData.setProductionRateLimits();
@@ -9688,7 +10780,7 @@ var setProductionRateLimits = defineCommand10({
9688
10780
  });
9689
10781
  }
9690
10782
  });
9691
- var blockContext = defineCommand10({
10783
+ var blockContext = defineCommand11({
9692
10784
  meta: { name: "block-context", description: "Block a context" },
9693
10785
  args: {
9694
10786
  "context-value": { type: "string", description: "Context identifier value", required: true },
@@ -9701,7 +10793,7 @@ var blockContext = defineCommand10({
9701
10793
  },
9702
10794
  run({ args }) {
9703
10795
  return withErrorHandler(async () => {
9704
- const globalOpts = getGlobalOpts9(args);
10796
+ const globalOpts = getGlobalOpts10(args);
9705
10797
  requireNonProd(globalOpts);
9706
10798
  const { client } = requireSession(globalOpts);
9707
10799
  const request = {
@@ -9715,7 +10807,7 @@ var blockContext = defineCommand10({
9715
10807
  });
9716
10808
  }
9717
10809
  });
9718
- var unblockContext = defineCommand10({
10810
+ var unblockContext = defineCommand11({
9719
10811
  meta: { name: "unblock-context", description: "Unblock a context" },
9720
10812
  args: {
9721
10813
  "context-value": { type: "string", description: "Context identifier value", required: true },
@@ -9728,7 +10820,7 @@ var unblockContext = defineCommand10({
9728
10820
  },
9729
10821
  run({ args }) {
9730
10822
  return withErrorHandler(async () => {
9731
- const globalOpts = getGlobalOpts9(args);
10823
+ const globalOpts = getGlobalOpts10(args);
9732
10824
  requireNonProd(globalOpts);
9733
10825
  const { client } = requireSession(globalOpts);
9734
10826
  const request = {
@@ -9742,7 +10834,7 @@ var unblockContext = defineCommand10({
9742
10834
  });
9743
10835
  }
9744
10836
  });
9745
- var testDataCommand = defineCommand10({
10837
+ var testDataCommand = defineCommand11({
9746
10838
  meta: { name: "test-data", description: "Test environment data management (test/demo only)" },
9747
10839
  subCommands: {
9748
10840
  "create-subject": createSubject,
@@ -9766,8 +10858,8 @@ var testDataCommand = defineCommand10({
9766
10858
  });
9767
10859
 
9768
10860
  // src/cli/commands/limits.ts
9769
- import { defineCommand as defineCommand11 } from "citty";
9770
- function getGlobalOpts10(args) {
10861
+ import { defineCommand as defineCommand12 } from "citty";
10862
+ function getGlobalOpts11(args) {
9771
10863
  return {
9772
10864
  env: args.env,
9773
10865
  json: args.json,
@@ -9776,7 +10868,7 @@ function getGlobalOpts10(args) {
9776
10868
  nip: args.nip
9777
10869
  };
9778
10870
  }
9779
- var context = defineCommand11({
10871
+ var context = defineCommand12({
9780
10872
  meta: { name: "context", description: "View effective context limits" },
9781
10873
  args: {
9782
10874
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9786,7 +10878,7 @@ var context = defineCommand11({
9786
10878
  },
9787
10879
  run({ args }) {
9788
10880
  return withErrorHandler(async () => {
9789
- const globalOpts = getGlobalOpts10(args);
10881
+ const globalOpts = getGlobalOpts11(args);
9790
10882
  const { client } = requireSession(globalOpts);
9791
10883
  const result = await client.limits.getContextLimits();
9792
10884
  if (args.json) {
@@ -9804,7 +10896,7 @@ var context = defineCommand11({
9804
10896
  });
9805
10897
  }
9806
10898
  });
9807
- var subject = defineCommand11({
10899
+ var subject = defineCommand12({
9808
10900
  meta: { name: "subject", description: "View effective subject limits" },
9809
10901
  args: {
9810
10902
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9814,7 +10906,7 @@ var subject = defineCommand11({
9814
10906
  },
9815
10907
  run({ args }) {
9816
10908
  return withErrorHandler(async () => {
9817
- const globalOpts = getGlobalOpts10(args);
10909
+ const globalOpts = getGlobalOpts11(args);
9818
10910
  const { client } = requireSession(globalOpts);
9819
10911
  const result = await client.limits.getSubjectLimits();
9820
10912
  if (args.json) {
@@ -9828,7 +10920,7 @@ var subject = defineCommand11({
9828
10920
  });
9829
10921
  }
9830
10922
  });
9831
- var rate = defineCommand11({
10923
+ var rate = defineCommand12({
9832
10924
  meta: { name: "rate", description: "View effective API rate limits" },
9833
10925
  args: {
9834
10926
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9838,7 +10930,7 @@ var rate = defineCommand11({
9838
10930
  },
9839
10931
  run({ args }) {
9840
10932
  return withErrorHandler(async () => {
9841
- const globalOpts = getGlobalOpts10(args);
10933
+ const globalOpts = getGlobalOpts11(args);
9842
10934
  const { client } = requireSession(globalOpts);
9843
10935
  const result = await client.limits.getRateLimits();
9844
10936
  if (args.json) {
@@ -9864,15 +10956,15 @@ var rate = defineCommand11({
9864
10956
  });
9865
10957
  }
9866
10958
  });
9867
- var limitsCommand = defineCommand11({
10959
+ var limitsCommand = defineCommand12({
9868
10960
  meta: { name: "limits", description: "View KSeF API limits" },
9869
10961
  subCommands: { context, subject, rate }
9870
10962
  });
9871
10963
 
9872
10964
  // src/cli/commands/peppol.ts
9873
- import { defineCommand as defineCommand12 } from "citty";
9874
- import { consola as consola9 } from "consola";
9875
- function getGlobalOpts11(args) {
10965
+ import { defineCommand as defineCommand13 } from "citty";
10966
+ import { consola as consola10 } from "consola";
10967
+ function getGlobalOpts12(args) {
9876
10968
  return {
9877
10969
  env: args.env,
9878
10970
  json: args.json,
@@ -9881,7 +10973,7 @@ function getGlobalOpts11(args) {
9881
10973
  nip: args.nip
9882
10974
  };
9883
10975
  }
9884
- var providers = defineCommand12({
10976
+ var providers = defineCommand13({
9885
10977
  meta: { name: "providers", description: "Query Peppol providers" },
9886
10978
  args: {
9887
10979
  page: { type: "string", description: "Page offset" },
@@ -9893,7 +10985,7 @@ var providers = defineCommand12({
9893
10985
  },
9894
10986
  run({ args }) {
9895
10987
  return withErrorHandler(async () => {
9896
- const globalOpts = getGlobalOpts11(args);
10988
+ const globalOpts = getGlobalOpts12(args);
9897
10989
  const { client } = requireSession(globalOpts);
9898
10990
  const pageOffset = args.page ? parseInt(args.page, 10) : void 0;
9899
10991
  const pageSize = args.pageSize ? parseInt(args.pageSize, 10) : void 0;
@@ -9920,20 +11012,20 @@ var providers = defineCommand12({
9920
11012
  { json: false }
9921
11013
  );
9922
11014
  if (result.hasMore) {
9923
- consola9.info("More results available. Use --page to paginate.");
11015
+ consola10.info("More results available. Use --page to paginate.");
9924
11016
  }
9925
11017
  });
9926
11018
  }
9927
11019
  });
9928
- var peppolCommand = defineCommand12({
11020
+ var peppolCommand = defineCommand13({
9929
11021
  meta: { name: "peppol", description: "Peppol integration commands" },
9930
11022
  subCommands: { providers }
9931
11023
  });
9932
11024
 
9933
11025
  // src/cli/commands/doctor.ts
9934
- import { defineCommand as defineCommand13 } from "citty";
9935
- import { consola as consola10 } from "consola";
9936
- function getGlobalOpts12(args) {
11026
+ import { defineCommand as defineCommand14 } from "citty";
11027
+ import { consola as consola11 } from "consola";
11028
+ function getGlobalOpts13(args) {
9937
11029
  return {
9938
11030
  env: args.env,
9939
11031
  json: args.json,
@@ -9942,7 +11034,7 @@ function getGlobalOpts12(args) {
9942
11034
  verbose: args.verbose
9943
11035
  };
9944
11036
  }
9945
- var doctorCommand = defineCommand13({
11037
+ var doctorCommand = defineCommand14({
9946
11038
  meta: { name: "doctor", description: "Check CLI configuration and connectivity" },
9947
11039
  args: {
9948
11040
  env: { type: "string", description: "Environment (test/demo/prod)" },
@@ -9953,7 +11045,7 @@ var doctorCommand = defineCommand13({
9953
11045
  },
9954
11046
  run({ args }) {
9955
11047
  return withErrorHandler(async () => {
9956
- const globalOpts = getGlobalOpts12(args);
11048
+ const globalOpts = getGlobalOpts13(args);
9957
11049
  const checks = [];
9958
11050
  try {
9959
11051
  const config = loadConfig();
@@ -10023,14 +11115,14 @@ var doctorCommand = defineCommand13({
10023
11115
  }
10024
11116
  for (const check of checks) {
10025
11117
  const icon = check.status === "pass" ? "\u2713" : check.status === "warn" ? "\u26A0" : "\u2717";
10026
- const log = check.status === "pass" ? consola10.success : check.status === "warn" ? consola10.warn : consola10.error;
11118
+ const log = check.status === "pass" ? consola11.success : check.status === "warn" ? consola11.warn : consola11.error;
10027
11119
  log(`${icon} ${check.message}`);
10028
11120
  }
10029
11121
  if (passed === total) {
10030
- consola10.success(`
11122
+ consola11.success(`
10031
11123
  ${passed}/${total} checks passed.`);
10032
11124
  } else {
10033
- consola10.warn(`
11125
+ consola11.warn(`
10034
11126
  ${passed}/${total} checks passed.`);
10035
11127
  }
10036
11128
  });
@@ -10038,7 +11130,7 @@ ${passed}/${total} checks passed.`);
10038
11130
  });
10039
11131
 
10040
11132
  // src/cli/commands/completion.ts
10041
- import { defineCommand as defineCommand14 } from "citty";
11133
+ import { defineCommand as defineCommand15 } from "citty";
10042
11134
  var COMMAND_TREE = {
10043
11135
  config: ["set", "show", "reset"],
10044
11136
  auth: ["challenge", "login", "status", "logout", "refresh", "whoami"],
@@ -10130,34 +11222,37 @@ function generateFish() {
10130
11222
  }
10131
11223
  return lines.join("\n") + "\n";
10132
11224
  }
10133
- var bash = defineCommand14({
11225
+ var bash = defineCommand15({
10134
11226
  meta: { name: "bash", description: "Generate bash completion script" },
10135
11227
  run() {
10136
11228
  console.log(generateBash());
10137
11229
  }
10138
11230
  });
10139
- var zsh = defineCommand14({
11231
+ var zsh = defineCommand15({
10140
11232
  meta: { name: "zsh", description: "Generate zsh completion script" },
10141
11233
  run() {
10142
11234
  console.log(generateZsh());
10143
11235
  }
10144
11236
  });
10145
- var fish = defineCommand14({
11237
+ var fish = defineCommand15({
10146
11238
  meta: { name: "fish", description: "Generate fish completion script" },
10147
11239
  run() {
10148
11240
  console.log(generateFish());
10149
11241
  }
10150
11242
  });
10151
- var completionCommand = defineCommand14({
11243
+ var completionCommand = defineCommand15({
10152
11244
  meta: { name: "completion", description: "Generate shell completion scripts" },
10153
11245
  subCommands: { bash, zsh, fish }
10154
11246
  });
10155
11247
 
10156
11248
  // src/cli/index.ts
10157
- var main = defineCommand15({
11249
+ var __dirname = dirname2(fileURLToPath(import.meta.url));
11250
+ var pkg = JSON.parse(readFileSync6(resolve(__dirname, "..", "package.json"), "utf-8"));
11251
+ var version = pkg.version;
11252
+ var main = defineCommand16({
10158
11253
  meta: {
10159
11254
  name: "ksef",
10160
- version: "0.1.0",
11255
+ version,
10161
11256
  description: "CLI for the Polish National e-Invoice System (KSeF)"
10162
11257
  },
10163
11258
  subCommands: {