ksef-client-ts 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cli.js +1677 -303
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +713 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -2
- package/dist/index.d.ts +70 -2
- package/dist/index.js +693 -65
- package/dist/index.js.map +1 -1
- package/docs/schemas/FA/bazowe/ElementarneTypyDanych_v10-0E.xsd +1 -0
- package/docs/schemas/FA/bazowe/KodyKrajow_v10-0E.xsd +1283 -0
- package/docs/schemas/FA/bazowe/StrukturyDanych_v10-0E.xsd +1 -0
- package/docs/schemas/FA/schemat_FA(2)_v1-0E.xsd +3661 -0
- package/docs/schemas/FA/schemat_FA(3)_v1-0E.xsd +3950 -0
- package/docs/schemas/PEF/Schemat_PEF(3)_v2-1.xsd +977 -0
- package/docs/schemas/PEF/Schemat_PEF_KOR(3)_v2-1.xsd +926 -0
- package/docs/schemas/PEF/bazowe/20241206_PEFPL-CommonAggregateComponents-2.1-v1.4.34.xsd +428 -0
- package/docs/schemas/PEF/bazowe/20241206_PEFPL-CommonBasicComponents-2.1-v1.4.34.xsd +65 -0
- package/docs/schemas/PEF/bazowe/CCTS_CCT_SchemaModule-2.1.xsd +731 -0
- package/docs/schemas/PEF/bazowe/UBL-CommonAggregateComponents-2.1.xsd +39799 -0
- package/docs/schemas/PEF/bazowe/UBL-CommonBasicComponents-2.1.xsd +5389 -0
- package/docs/schemas/PEF/bazowe/UBL-CommonExtensionComponents-2.1.xsd +223 -0
- package/docs/schemas/PEF/bazowe/UBL-CommonSignatureComponents-2.1.xsd +101 -0
- package/docs/schemas/PEF/bazowe/UBL-ExtensionContentDataType-2.1.xsd +89 -0
- package/docs/schemas/PEF/bazowe/UBL-QualifiedDataTypes-2.1.xsd +69 -0
- package/docs/schemas/PEF/bazowe/UBL-SignatureAggregateComponents-2.1.xsd +138 -0
- package/docs/schemas/PEF/bazowe/UBL-SignatureBasicComponents-2.1.xsd +78 -0
- package/docs/schemas/PEF/bazowe/UBL-UnqualifiedDataTypes-2.1.xsd +553 -0
- package/docs/schemas/PEF/bazowe/UBL-XAdESv132-2.1.xsd +476 -0
- package/docs/schemas/PEF/bazowe/UBL-XAdESv141-2.1.xsd +25 -0
- package/docs/schemas/PEF/bazowe/UBL-xmldsig-core-schema-2.1.xsd +323 -0
- package/docs/schemas/PEF/bazowe/commontypes.xsd +735 -0
- package/docs/schemas/PEF/bazowe/isotypes.xsd +3158 -0
- package/docs/schemas/RR/schemat_FA_RR(1)_v1-1E.xsd +2188 -0
- package/docs/schemas/RR/schemat_RR(1)_v1-0E.xsd +2188 -0
- package/docs/schemas/RR/schemat_RR(1)_v1-1E.xsd +2188 -0
- package/package.json +12 -2
package/dist/cli.js
CHANGED
|
@@ -320,6 +320,50 @@ var init_ksef_batch_timeout_error = __esm({
|
|
|
320
320
|
}
|
|
321
321
|
});
|
|
322
322
|
|
|
323
|
+
// src/errors/ksef-circuit-open-error.ts
|
|
324
|
+
var KSeFCircuitOpenError;
|
|
325
|
+
var init_ksef_circuit_open_error = __esm({
|
|
326
|
+
"src/errors/ksef-circuit-open-error.ts"() {
|
|
327
|
+
"use strict";
|
|
328
|
+
init_ksef_error();
|
|
329
|
+
KSeFCircuitOpenError = class extends KSeFError {
|
|
330
|
+
endpoint;
|
|
331
|
+
openedAt;
|
|
332
|
+
retryAfterMs;
|
|
333
|
+
constructor(endpoint, openedAt, retryAfterMs) {
|
|
334
|
+
super(
|
|
335
|
+
`Circuit breaker is open for '${endpoint}'. Retry after ${Math.round(retryAfterMs)}ms.`
|
|
336
|
+
);
|
|
337
|
+
this.name = "KSeFCircuitOpenError";
|
|
338
|
+
this.endpoint = endpoint;
|
|
339
|
+
this.openedAt = openedAt;
|
|
340
|
+
this.retryAfterMs = retryAfterMs;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// src/errors/ksef-xsd-validation-error.ts
|
|
347
|
+
var KSeFXsdValidationError;
|
|
348
|
+
var init_ksef_xsd_validation_error = __esm({
|
|
349
|
+
"src/errors/ksef-xsd-validation-error.ts"() {
|
|
350
|
+
"use strict";
|
|
351
|
+
init_ksef_error();
|
|
352
|
+
KSeFXsdValidationError = class extends KSeFError {
|
|
353
|
+
schemaFile;
|
|
354
|
+
errors;
|
|
355
|
+
constructor(schemaFile, errors) {
|
|
356
|
+
const preview = errors.slice(0, 3).join("; ");
|
|
357
|
+
const extra = errors.length > 3 ? ` (+${errors.length - 3} more)` : "";
|
|
358
|
+
super(`XSD validation failed against ${schemaFile}: ${preview}${extra}`);
|
|
359
|
+
this.name = "KSeFXsdValidationError";
|
|
360
|
+
this.schemaFile = schemaFile;
|
|
361
|
+
this.errors = errors;
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
323
367
|
// src/errors/assert-never.ts
|
|
324
368
|
var init_assert_never = __esm({
|
|
325
369
|
"src/errors/assert-never.ts"() {
|
|
@@ -342,6 +386,8 @@ var init_errors = __esm({
|
|
|
342
386
|
init_ksef_session_expired_error();
|
|
343
387
|
init_ksef_validation_error();
|
|
344
388
|
init_ksef_batch_timeout_error();
|
|
389
|
+
init_ksef_circuit_open_error();
|
|
390
|
+
init_ksef_xsd_validation_error();
|
|
345
391
|
init_error_codes();
|
|
346
392
|
init_assert_never();
|
|
347
393
|
}
|
|
@@ -617,6 +663,7 @@ var init_rest_client = __esm({
|
|
|
617
663
|
transport;
|
|
618
664
|
retryPolicy;
|
|
619
665
|
rateLimitPolicy;
|
|
666
|
+
circuitBreakerPolicy;
|
|
620
667
|
authManager;
|
|
621
668
|
presignedUrlPolicy;
|
|
622
669
|
constructor(options, config) {
|
|
@@ -625,6 +672,7 @@ var init_rest_client = __esm({
|
|
|
625
672
|
this.transport = config?.transport ?? defaultTransport;
|
|
626
673
|
this.retryPolicy = config?.retryPolicy ?? defaultRetryPolicy();
|
|
627
674
|
this.rateLimitPolicy = config?.rateLimitPolicy ?? null;
|
|
675
|
+
this.circuitBreakerPolicy = config?.circuitBreakerPolicy ?? null;
|
|
628
676
|
this.authManager = config?.authManager;
|
|
629
677
|
this.presignedUrlPolicy = config?.presignedUrlPolicy;
|
|
630
678
|
}
|
|
@@ -649,18 +697,32 @@ var init_rest_client = __esm({
|
|
|
649
697
|
if (request.isPresigned() && this.presignedUrlPolicy) {
|
|
650
698
|
validatePresignedUrl(url2, this.presignedUrlPolicy);
|
|
651
699
|
}
|
|
700
|
+
let ownsProbeSlot = false;
|
|
701
|
+
if (this.circuitBreakerPolicy) {
|
|
702
|
+
const claimed = this.circuitBreakerPolicy.ensureClosed(request.path);
|
|
703
|
+
if (claimed) ownsProbeSlot = true;
|
|
704
|
+
}
|
|
652
705
|
if (this.rateLimitPolicy) {
|
|
653
|
-
|
|
706
|
+
try {
|
|
707
|
+
await this.rateLimitPolicy.acquire(request.path);
|
|
708
|
+
} catch (error) {
|
|
709
|
+
if (ownsProbeSlot) this.circuitBreakerPolicy?.releaseProbe(request.path);
|
|
710
|
+
throw error;
|
|
711
|
+
}
|
|
654
712
|
}
|
|
655
713
|
let lastError;
|
|
656
714
|
for (let attempt = 0; attempt <= this.retryPolicy.maxRetries; attempt++) {
|
|
715
|
+
if (this.circuitBreakerPolicy) {
|
|
716
|
+
const claimed = this.circuitBreakerPolicy.ensureClosed(request.path, ownsProbeSlot);
|
|
717
|
+
if (claimed) ownsProbeSlot = true;
|
|
718
|
+
}
|
|
657
719
|
try {
|
|
658
|
-
|
|
720
|
+
let response = await this.doRequest(request, url2);
|
|
659
721
|
if (response.status === 401 && this.authManager && attempt === 0 && !request.isSkipAuthRetry()) {
|
|
660
722
|
const newToken = await this.authManager.onUnauthorized();
|
|
661
723
|
if (newToken) {
|
|
662
724
|
consola3.debug("Auth token refreshed, retrying request");
|
|
663
|
-
|
|
725
|
+
response = await this.doRequest(request, url2, newToken);
|
|
664
726
|
}
|
|
665
727
|
}
|
|
666
728
|
if (isRetryableStatus(response.status, this.retryPolicy) && attempt < this.retryPolicy.maxRetries) {
|
|
@@ -670,10 +732,17 @@ var init_rest_client = __esm({
|
|
|
670
732
|
consola3.debug(`Retryable ${response.status}, attempt ${attempt + 1}/${this.retryPolicy.maxRetries}, waiting ${Math.round(delayMs)}ms`);
|
|
671
733
|
await sleep(delayMs);
|
|
672
734
|
if (is429 && this.rateLimitPolicy) {
|
|
673
|
-
|
|
735
|
+
try {
|
|
736
|
+
await this.rateLimitPolicy.acquire(request.path);
|
|
737
|
+
} catch (error) {
|
|
738
|
+
this.recordCircuitOutcome(request.path, 429);
|
|
739
|
+
ownsProbeSlot = false;
|
|
740
|
+
throw error;
|
|
741
|
+
}
|
|
674
742
|
}
|
|
675
743
|
continue;
|
|
676
744
|
}
|
|
745
|
+
this.recordCircuitOutcome(request.path, response.status);
|
|
677
746
|
return response;
|
|
678
747
|
} catch (error) {
|
|
679
748
|
lastError = error;
|
|
@@ -683,11 +752,22 @@ var init_rest_client = __esm({
|
|
|
683
752
|
await sleep(delayMs);
|
|
684
753
|
continue;
|
|
685
754
|
}
|
|
755
|
+
if (isRetryableError(error, this.retryPolicy) || ownsProbeSlot) {
|
|
756
|
+
this.circuitBreakerPolicy?.recordFailure(request.path);
|
|
757
|
+
}
|
|
686
758
|
throw error;
|
|
687
759
|
}
|
|
688
760
|
}
|
|
689
761
|
throw lastError;
|
|
690
762
|
}
|
|
763
|
+
recordCircuitOutcome(path12, status7) {
|
|
764
|
+
if (!this.circuitBreakerPolicy) return;
|
|
765
|
+
if (status7 >= 500) {
|
|
766
|
+
this.circuitBreakerPolicy.recordFailure(path12);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
this.circuitBreakerPolicy.recordSuccess(path12);
|
|
770
|
+
}
|
|
691
771
|
async doRequest(request, url2, overrideToken) {
|
|
692
772
|
const headers = {
|
|
693
773
|
...this.options.customHeaders,
|
|
@@ -723,9 +803,9 @@ var init_rest_client = __esm({
|
|
|
723
803
|
return response;
|
|
724
804
|
}
|
|
725
805
|
buildUrl(request) {
|
|
726
|
-
const
|
|
806
|
+
const path12 = this.routeBuilder.build(request.path);
|
|
727
807
|
const base = this.options.baseUrl;
|
|
728
|
-
const url2 = new URL(`${base}${
|
|
808
|
+
const url2 = new URL(`${base}${path12}`);
|
|
729
809
|
const query2 = request.getQuery();
|
|
730
810
|
for (const [key, value] of query2) {
|
|
731
811
|
url2.searchParams.append(key, value);
|
|
@@ -869,6 +949,141 @@ var init_rate_limit_policy = __esm({
|
|
|
869
949
|
}
|
|
870
950
|
});
|
|
871
951
|
|
|
952
|
+
// src/http/circuit-breaker-policy.ts
|
|
953
|
+
import { consola as consola4 } from "consola";
|
|
954
|
+
var GLOBAL_KEY, CircuitBreakerPolicy;
|
|
955
|
+
var init_circuit_breaker_policy = __esm({
|
|
956
|
+
"src/http/circuit-breaker-policy.ts"() {
|
|
957
|
+
"use strict";
|
|
958
|
+
init_ksef_circuit_open_error();
|
|
959
|
+
GLOBAL_KEY = "__global__";
|
|
960
|
+
CircuitBreakerPolicy = class _CircuitBreakerPolicy {
|
|
961
|
+
failureThreshold;
|
|
962
|
+
openMs;
|
|
963
|
+
scope;
|
|
964
|
+
states = /* @__PURE__ */ new Map();
|
|
965
|
+
constructor(config = {}) {
|
|
966
|
+
const failureThreshold = config.failureThreshold ?? 5;
|
|
967
|
+
const openMs = config.openMs ?? 3e4;
|
|
968
|
+
if (!Number.isInteger(failureThreshold) || failureThreshold <= 0) {
|
|
969
|
+
throw new RangeError("CircuitBreakerPolicy: failureThreshold must be a positive integer");
|
|
970
|
+
}
|
|
971
|
+
if (!Number.isFinite(openMs) || openMs <= 0) {
|
|
972
|
+
throw new RangeError("CircuitBreakerPolicy: openMs must be > 0");
|
|
973
|
+
}
|
|
974
|
+
const scope = config.scope ?? "global";
|
|
975
|
+
if (scope !== "global" && scope !== "endpoint") {
|
|
976
|
+
throw new RangeError(
|
|
977
|
+
"CircuitBreakerPolicy: scope must be 'global' or 'endpoint'"
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
this.failureThreshold = failureThreshold;
|
|
981
|
+
this.openMs = openMs;
|
|
982
|
+
this.scope = scope;
|
|
983
|
+
}
|
|
984
|
+
// Returns true iff this call just claimed the single probe slot for the
|
|
985
|
+
// caller. The caller MUST pass `alreadyOwnsProbe=true` on subsequent
|
|
986
|
+
// re-checks for the same logical request (e.g. a retry loop) so the probe
|
|
987
|
+
// owner cannot deadlock itself on its own in-flight slot.
|
|
988
|
+
ensureClosed(endpoint, alreadyOwnsProbe = false) {
|
|
989
|
+
const key = this.keyFor(endpoint);
|
|
990
|
+
const state = this.states.get(key);
|
|
991
|
+
if (!state || state.openedAt === null) return false;
|
|
992
|
+
const now = performance.now();
|
|
993
|
+
const elapsed = now - state.openedAt;
|
|
994
|
+
if (elapsed >= this.openMs) {
|
|
995
|
+
if (alreadyOwnsProbe) return false;
|
|
996
|
+
if (state.probeInFlight) {
|
|
997
|
+
throw new KSeFCircuitOpenError(endpoint, state.openedAt, 0);
|
|
998
|
+
}
|
|
999
|
+
state.probeInFlight = true;
|
|
1000
|
+
consola4.debug(`Circuit breaker: probe after cooldown for '${key}'`);
|
|
1001
|
+
return true;
|
|
1002
|
+
}
|
|
1003
|
+
const retryAfterMs = Math.max(0, this.openMs - elapsed);
|
|
1004
|
+
throw new KSeFCircuitOpenError(endpoint, state.openedAt, retryAfterMs);
|
|
1005
|
+
}
|
|
1006
|
+
recordSuccess(endpoint) {
|
|
1007
|
+
const key = this.keyFor(endpoint);
|
|
1008
|
+
const state = this.states.get(key);
|
|
1009
|
+
if (!state) return;
|
|
1010
|
+
if (state.openedAt !== null || state.failures > 0) {
|
|
1011
|
+
consola4.debug(`Circuit breaker: reset for '${key}'`);
|
|
1012
|
+
}
|
|
1013
|
+
this.states.delete(key);
|
|
1014
|
+
}
|
|
1015
|
+
// Release a claimed probe slot WITHOUT observing an outcome. Use this when
|
|
1016
|
+
// the probe attempt was aborted before reaching upstream (e.g. rate-limit
|
|
1017
|
+
// acquire rejected, client cancellation). We have no new information about
|
|
1018
|
+
// upstream health, so the breaker must stay OPEN — but we do restart the
|
|
1019
|
+
// cooldown clock so the next probe attempt waits a fresh `openMs`,
|
|
1020
|
+
// preventing a tight loop of aborted probes from spamming the limiter.
|
|
1021
|
+
releaseProbe(endpoint) {
|
|
1022
|
+
const key = this.keyFor(endpoint);
|
|
1023
|
+
const state = this.states.get(key);
|
|
1024
|
+
if (!state || !state.probeInFlight) return;
|
|
1025
|
+
state.probeInFlight = false;
|
|
1026
|
+
if (state.openedAt !== null) {
|
|
1027
|
+
state.openedAt = performance.now();
|
|
1028
|
+
}
|
|
1029
|
+
consola4.debug(`Circuit breaker: probe aborted (not observed) for '${key}', cooldown restarted`);
|
|
1030
|
+
}
|
|
1031
|
+
recordFailure(endpoint) {
|
|
1032
|
+
const key = this.keyFor(endpoint);
|
|
1033
|
+
const now = performance.now();
|
|
1034
|
+
let state = this.states.get(key);
|
|
1035
|
+
if (!state) {
|
|
1036
|
+
state = { failures: 0, openedAt: null, lastFailureAt: null, probeInFlight: false };
|
|
1037
|
+
this.states.set(key, state);
|
|
1038
|
+
}
|
|
1039
|
+
if (state.openedAt !== null && state.probeInFlight) {
|
|
1040
|
+
state.openedAt = now;
|
|
1041
|
+
state.failures = this.failureThreshold;
|
|
1042
|
+
state.lastFailureAt = now;
|
|
1043
|
+
state.probeInFlight = false;
|
|
1044
|
+
consola4.debug(`Circuit breaker: probe failed, re-opened for '${key}'`);
|
|
1045
|
+
this.maybeSweepStaleClosed(now, key);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
const slidingStale = state.lastFailureAt !== null && now - state.lastFailureAt > this.openMs;
|
|
1049
|
+
state.failures = slidingStale ? 1 : state.failures + 1;
|
|
1050
|
+
state.lastFailureAt = now;
|
|
1051
|
+
if (state.openedAt === null && state.failures >= this.failureThreshold) {
|
|
1052
|
+
state.openedAt = now;
|
|
1053
|
+
consola4.debug(
|
|
1054
|
+
`Circuit breaker: opened for '${key}' after ${state.failures} failures (cooldown ${this.openMs}ms)`
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
this.maybeSweepStaleClosed(now, key);
|
|
1058
|
+
}
|
|
1059
|
+
keyFor(endpoint) {
|
|
1060
|
+
return this.scope === "global" ? GLOBAL_KEY : endpoint;
|
|
1061
|
+
}
|
|
1062
|
+
// Prevent unbounded map growth under `scope: 'endpoint'` when callers hit
|
|
1063
|
+
// many distinct parameterized paths (e.g. `auth/sessions/{ref}`) that each
|
|
1064
|
+
// fail once and are never revisited. Global scope is always a single entry.
|
|
1065
|
+
//
|
|
1066
|
+
// Runs amortized O(n) — gated on a size threshold so small workloads pay
|
|
1067
|
+
// nothing. Only evicts states that are genuinely settled: closed, no probe
|
|
1068
|
+
// in flight, and with the last failure older than two cooldowns.
|
|
1069
|
+
maybeSweepStaleClosed(now, keepKey) {
|
|
1070
|
+
if (this.scope !== "endpoint") return;
|
|
1071
|
+
if (this.states.size <= _CircuitBreakerPolicy.sweepThreshold) return;
|
|
1072
|
+
const staleBefore = now - 2 * this.openMs;
|
|
1073
|
+
for (const [key, state] of this.states) {
|
|
1074
|
+
if (key === keepKey) continue;
|
|
1075
|
+
if (state.openedAt !== null) continue;
|
|
1076
|
+
if (state.probeInFlight) continue;
|
|
1077
|
+
if (state.lastFailureAt !== null && state.lastFailureAt < staleBefore) {
|
|
1078
|
+
this.states.delete(key);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
static sweepThreshold = 64;
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1086
|
+
|
|
872
1087
|
// src/http/auth-manager.ts
|
|
873
1088
|
var DefaultAuthManager;
|
|
874
1089
|
var init_auth_manager = __esm({
|
|
@@ -932,21 +1147,21 @@ var init_rest_request = __esm({
|
|
|
932
1147
|
_query = [];
|
|
933
1148
|
_presigned = false;
|
|
934
1149
|
_skipAuthRetry = false;
|
|
935
|
-
constructor(method,
|
|
1150
|
+
constructor(method, path12) {
|
|
936
1151
|
this.method = method;
|
|
937
|
-
this.path =
|
|
1152
|
+
this.path = path12;
|
|
938
1153
|
}
|
|
939
|
-
static get(
|
|
940
|
-
return new _RestRequest("GET",
|
|
1154
|
+
static get(path12) {
|
|
1155
|
+
return new _RestRequest("GET", path12);
|
|
941
1156
|
}
|
|
942
|
-
static post(
|
|
943
|
-
return new _RestRequest("POST",
|
|
1157
|
+
static post(path12) {
|
|
1158
|
+
return new _RestRequest("POST", path12);
|
|
944
1159
|
}
|
|
945
|
-
static put(
|
|
946
|
-
return new _RestRequest("PUT",
|
|
1160
|
+
static put(path12) {
|
|
1161
|
+
return new _RestRequest("PUT", path12);
|
|
947
1162
|
}
|
|
948
|
-
static delete(
|
|
949
|
-
return new _RestRequest("DELETE",
|
|
1163
|
+
static delete(path12) {
|
|
1164
|
+
return new _RestRequest("DELETE", path12);
|
|
950
1165
|
}
|
|
951
1166
|
body(data) {
|
|
952
1167
|
this._body = data;
|
|
@@ -1885,20 +2100,20 @@ var init_lighthouse = __esm({
|
|
|
1885
2100
|
this.lighthouseUrl = options.lighthouseUrl;
|
|
1886
2101
|
this.timeout = options.timeout;
|
|
1887
2102
|
}
|
|
1888
|
-
async fetchJson(
|
|
2103
|
+
async fetchJson(path12) {
|
|
1889
2104
|
if (!this.lighthouseUrl) {
|
|
1890
2105
|
throw new KSeFError(
|
|
1891
2106
|
"Lighthouse API is not available for the DEMO environment. Use TEST or PROD instead."
|
|
1892
2107
|
);
|
|
1893
2108
|
}
|
|
1894
|
-
const response = await fetch(`${this.lighthouseUrl}${
|
|
2109
|
+
const response = await fetch(`${this.lighthouseUrl}${path12}`, {
|
|
1895
2110
|
headers: { Accept: "application/json" },
|
|
1896
2111
|
signal: AbortSignal.timeout(this.timeout)
|
|
1897
2112
|
});
|
|
1898
2113
|
if (!response.ok) {
|
|
1899
2114
|
const body = await response.text();
|
|
1900
2115
|
throw new KSeFError(
|
|
1901
|
-
`Lighthouse ${
|
|
2116
|
+
`Lighthouse ${path12} failed: HTTP ${response.status} \u2014 ${body}`
|
|
1902
2117
|
);
|
|
1903
2118
|
}
|
|
1904
2119
|
return await response.json();
|
|
@@ -2443,11 +2658,11 @@ var init_verification_link_service = __esm({
|
|
|
2443
2658
|
* Build certificate verification URL (Code II).
|
|
2444
2659
|
* Format: {baseQrUrl}/certificate/{contextType}/{contextId}/{sellerNip}/{certSerial}/{hash_base64url}/{signature_base64url}
|
|
2445
2660
|
*/
|
|
2446
|
-
buildCertificateVerificationUrl(contextType, contextId, sellerNip, certSerial, invoiceHashBase64, privateKeyPem) {
|
|
2661
|
+
buildCertificateVerificationUrl(contextType, contextId, sellerNip, certSerial, invoiceHashBase64, privateKeyPem, privateKeyPassword) {
|
|
2447
2662
|
const hashBase64Url = this.base64ToBase64Url(invoiceHashBase64);
|
|
2448
2663
|
const pathWithoutSignature = `${this.baseQrUrl}/certificate/${contextType}/${contextId}/${sellerNip}/${certSerial}/${hashBase64Url}`;
|
|
2449
2664
|
const dataToSign = pathWithoutSignature.replace(/^https?:\/\//, "");
|
|
2450
|
-
const key = crypto2.createPrivateKey(privateKeyPem);
|
|
2665
|
+
const key = privateKeyPassword !== void 0 ? crypto2.createPrivateKey({ key: privateKeyPem, format: "pem", passphrase: privateKeyPassword }) : crypto2.createPrivateKey(privateKeyPem);
|
|
2451
2666
|
let signature;
|
|
2452
2667
|
if (key.asymmetricKeyType === "rsa") {
|
|
2453
2668
|
signature = crypto2.sign("sha256", Buffer.from(dataToSign), {
|
|
@@ -2761,7 +2976,8 @@ var init_offline_invoice_workflow = __esm({
|
|
|
2761
2976
|
input.sellerNip,
|
|
2762
2977
|
options.certificate.certificateSerial,
|
|
2763
2978
|
invoiceHashBase64,
|
|
2764
|
-
options.certificate.privateKeyPem
|
|
2979
|
+
options.certificate.privateKeyPem,
|
|
2980
|
+
options.certificate.password
|
|
2765
2981
|
);
|
|
2766
2982
|
}
|
|
2767
2983
|
const submitBy = options?.customDeadline ? typeof options.customDeadline === "string" ? options.customDeadline : options.customDeadline.toISOString() : calculateOfflineDeadline(mode, input.invoiceDate, options?.maintenanceWindow).toISOString();
|
|
@@ -2951,7 +3167,8 @@ var init_offline_invoice_workflow = __esm({
|
|
|
2951
3167
|
original.sellerNip,
|
|
2952
3168
|
options.certificate.certificateSerial,
|
|
2953
3169
|
correctedHashBase64,
|
|
2954
|
-
options.certificate.privateKeyPem
|
|
3170
|
+
options.certificate.privateKeyPem,
|
|
3171
|
+
options.certificate.password
|
|
2955
3172
|
);
|
|
2956
3173
|
}
|
|
2957
3174
|
const correctionMetadata = {
|
|
@@ -3016,6 +3233,40 @@ __export(signature_service_exports, {
|
|
|
3016
3233
|
import * as crypto4 from "crypto";
|
|
3017
3234
|
import { ExclusiveCanonicalization } from "xml-crypto";
|
|
3018
3235
|
import { DOMParser, XMLSerializer } from "@xmldom/xmldom";
|
|
3236
|
+
function pickRsaAlgo() {
|
|
3237
|
+
return {
|
|
3238
|
+
nodeHashName: "sha256",
|
|
3239
|
+
signatureUri: RSA_SHA256_SIGNATURE_URI,
|
|
3240
|
+
digestUri: DIGEST_URI.sha256
|
|
3241
|
+
};
|
|
3242
|
+
}
|
|
3243
|
+
function pickEcdsaAlgo(privateKey) {
|
|
3244
|
+
const curve = privateKey.asymmetricKeyDetails?.namedCurve;
|
|
3245
|
+
switch (curve) {
|
|
3246
|
+
case "prime256v1":
|
|
3247
|
+
return {
|
|
3248
|
+
nodeHashName: "sha256",
|
|
3249
|
+
signatureUri: ECDSA_SIGNATURE_URI.sha256,
|
|
3250
|
+
digestUri: DIGEST_URI.sha256
|
|
3251
|
+
};
|
|
3252
|
+
case "secp384r1":
|
|
3253
|
+
return {
|
|
3254
|
+
nodeHashName: "sha384",
|
|
3255
|
+
signatureUri: ECDSA_SIGNATURE_URI.sha384,
|
|
3256
|
+
digestUri: DIGEST_URI.sha384
|
|
3257
|
+
};
|
|
3258
|
+
case "secp521r1":
|
|
3259
|
+
return {
|
|
3260
|
+
nodeHashName: "sha512",
|
|
3261
|
+
signatureUri: ECDSA_SIGNATURE_URI.sha512,
|
|
3262
|
+
digestUri: DIGEST_URI.sha512
|
|
3263
|
+
};
|
|
3264
|
+
default:
|
|
3265
|
+
throw new KSeFError(
|
|
3266
|
+
`Unsupported ECDSA curve: ${curve ?? "unknown"}. Supported: P-256 (prime256v1), P-384 (secp384r1), P-521 (secp521r1).`
|
|
3267
|
+
);
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3019
3270
|
function extractDerFromPem(pem) {
|
|
3020
3271
|
const base64 = pem.replace(/-----BEGIN [A-Z\s]+-----/g, "").replace(/-----END [A-Z\s]+-----/g, "").replace(/\s+/g, "");
|
|
3021
3272
|
return Buffer.from(base64, "base64");
|
|
@@ -3030,12 +3281,12 @@ function canonicalize(elem) {
|
|
|
3030
3281
|
const c14n = new ExclusiveCanonicalization();
|
|
3031
3282
|
return c14n.process(elem, {});
|
|
3032
3283
|
}
|
|
3033
|
-
function computeRootDigest(doc) {
|
|
3284
|
+
function computeRootDigest(doc, hashName) {
|
|
3034
3285
|
const root = doc.documentElement;
|
|
3035
3286
|
const canonical = canonicalize(root);
|
|
3036
|
-
return crypto4.createHash(
|
|
3287
|
+
return crypto4.createHash(hashName).update(canonical, "utf-8").digest("base64");
|
|
3037
3288
|
}
|
|
3038
|
-
function computeSignedPropertiesDigest(qualifyingPropertiesXml) {
|
|
3289
|
+
function computeSignedPropertiesDigest(qualifyingPropertiesXml, hashName) {
|
|
3039
3290
|
const parser2 = new DOMParser();
|
|
3040
3291
|
const qpDoc = parser2.parseFromString(qualifyingPropertiesXml, "text/xml");
|
|
3041
3292
|
const signedProps = findElementByLocalName(qpDoc.documentElement, "SignedProperties");
|
|
@@ -3043,9 +3294,9 @@ function computeSignedPropertiesDigest(qualifyingPropertiesXml) {
|
|
|
3043
3294
|
throw new Error("SignedProperties element not found in QualifyingProperties");
|
|
3044
3295
|
}
|
|
3045
3296
|
const canonical = canonicalize(signedProps);
|
|
3046
|
-
return crypto4.createHash(
|
|
3297
|
+
return crypto4.createHash(hashName).update(canonical, "utf-8").digest("base64");
|
|
3047
3298
|
}
|
|
3048
|
-
function buildSignedInfo(signatureAlgorithm, rootDigest, signedPropertiesDigest) {
|
|
3299
|
+
function buildSignedInfo(signatureAlgorithm, digestAlgorithm, rootDigest, signedPropertiesDigest) {
|
|
3049
3300
|
return [
|
|
3050
3301
|
`<ds:SignedInfo xmlns:ds="${DS_NS}">`,
|
|
3051
3302
|
`<ds:CanonicalizationMethod Algorithm="${EXC_C14N_ALGORITHM}"/>`,
|
|
@@ -3056,7 +3307,7 @@ function buildSignedInfo(signatureAlgorithm, rootDigest, signedPropertiesDigest)
|
|
|
3056
3307
|
`<ds:Transform Algorithm="${ENVELOPED_SIGNATURE_TRANSFORM}"/>`,
|
|
3057
3308
|
`<ds:Transform Algorithm="${EXC_C14N_ALGORITHM}"/>`,
|
|
3058
3309
|
`</ds:Transforms>`,
|
|
3059
|
-
`<ds:DigestMethod Algorithm="${
|
|
3310
|
+
`<ds:DigestMethod Algorithm="${digestAlgorithm}"/>`,
|
|
3060
3311
|
`<ds:DigestValue>${rootDigest}</ds:DigestValue>`,
|
|
3061
3312
|
`</ds:Reference>`,
|
|
3062
3313
|
// Reference 2: SignedProperties
|
|
@@ -3064,22 +3315,22 @@ function buildSignedInfo(signatureAlgorithm, rootDigest, signedPropertiesDigest)
|
|
|
3064
3315
|
`<ds:Transforms>`,
|
|
3065
3316
|
`<ds:Transform Algorithm="${EXC_C14N_ALGORITHM}"/>`,
|
|
3066
3317
|
`</ds:Transforms>`,
|
|
3067
|
-
`<ds:DigestMethod Algorithm="${
|
|
3318
|
+
`<ds:DigestMethod Algorithm="${digestAlgorithm}"/>`,
|
|
3068
3319
|
`<ds:DigestValue>${signedPropertiesDigest}</ds:DigestValue>`,
|
|
3069
3320
|
`</ds:Reference>`,
|
|
3070
3321
|
`</ds:SignedInfo>`
|
|
3071
3322
|
].join("");
|
|
3072
3323
|
}
|
|
3073
|
-
function computeSignatureValue(canonicalSignedInfo, privateKey, isEc) {
|
|
3324
|
+
function computeSignatureValue(canonicalSignedInfo, privateKey, isEc, hashName) {
|
|
3074
3325
|
const data = Buffer.from(canonicalSignedInfo, "utf-8");
|
|
3075
3326
|
let signature;
|
|
3076
3327
|
if (isEc) {
|
|
3077
|
-
signature = crypto4.sign(
|
|
3328
|
+
signature = crypto4.sign(hashName, data, {
|
|
3078
3329
|
key: privateKey,
|
|
3079
3330
|
dsaEncoding: "ieee-p1363"
|
|
3080
3331
|
});
|
|
3081
3332
|
} else {
|
|
3082
|
-
signature = crypto4.sign(
|
|
3333
|
+
signature = crypto4.sign(hashName, data, privateKey);
|
|
3083
3334
|
}
|
|
3084
3335
|
return signature.toString("base64");
|
|
3085
3336
|
}
|
|
@@ -3100,7 +3351,7 @@ function buildSignatureElement(signedInfoXml, signatureValue, certBase64, qualif
|
|
|
3100
3351
|
`</ds:Signature>`
|
|
3101
3352
|
].join("");
|
|
3102
3353
|
}
|
|
3103
|
-
function buildQualifyingProperties(signatureId, signedPropertiesId, certDigest, issuerName, serialNumber, signingTime) {
|
|
3354
|
+
function buildQualifyingProperties(signatureId, signedPropertiesId, certDigest, issuerName, serialNumber, signingTime, digestAlgorithm) {
|
|
3104
3355
|
return [
|
|
3105
3356
|
`<xades:QualifyingProperties`,
|
|
3106
3357
|
` Target="#${signatureId}"`,
|
|
@@ -3112,7 +3363,7 @@ function buildQualifyingProperties(signatureId, signedPropertiesId, certDigest,
|
|
|
3112
3363
|
`<xades:SigningCertificate>`,
|
|
3113
3364
|
`<xades:Cert>`,
|
|
3114
3365
|
`<xades:CertDigest>`,
|
|
3115
|
-
`<DigestMethod Algorithm="${
|
|
3366
|
+
`<DigestMethod Algorithm="${digestAlgorithm}"/>`,
|
|
3116
3367
|
`<DigestValue>${certDigest}</DigestValue>`,
|
|
3117
3368
|
`</xades:CertDigest>`,
|
|
3118
3369
|
`<xades:IssuerSerial>`,
|
|
@@ -3148,18 +3399,27 @@ function wrapBase64(base64) {
|
|
|
3148
3399
|
}
|
|
3149
3400
|
return lines.join("\n");
|
|
3150
3401
|
}
|
|
3151
|
-
var XADES_NS, DS_NS, SIGNED_PROPERTIES_TYPE,
|
|
3402
|
+
var XADES_NS, DS_NS, SIGNED_PROPERTIES_TYPE, EXC_C14N_ALGORITHM, ENVELOPED_SIGNATURE_TRANSFORM, DIGEST_URI, ECDSA_SIGNATURE_URI, RSA_SHA256_SIGNATURE_URI, CLOCK_SKEW_BUFFER_MS, SIGNATURE_ID, SIGNED_PROPERTIES_ID, SignatureService;
|
|
3152
3403
|
var init_signature_service = __esm({
|
|
3153
3404
|
"src/crypto/signature-service.ts"() {
|
|
3154
3405
|
"use strict";
|
|
3406
|
+
init_ksef_error();
|
|
3155
3407
|
XADES_NS = "http://uri.etsi.org/01903/v1.3.2#";
|
|
3156
3408
|
DS_NS = "http://www.w3.org/2000/09/xmldsig#";
|
|
3157
3409
|
SIGNED_PROPERTIES_TYPE = "http://uri.etsi.org/01903#SignedProperties";
|
|
3158
|
-
SHA256_DIGEST_METHOD = "http://www.w3.org/2001/04/xmlenc#sha256";
|
|
3159
3410
|
EXC_C14N_ALGORITHM = "http://www.w3.org/2001/10/xml-exc-c14n#";
|
|
3160
3411
|
ENVELOPED_SIGNATURE_TRANSFORM = "http://www.w3.org/2000/09/xmldsig#enveloped-signature";
|
|
3161
|
-
|
|
3162
|
-
|
|
3412
|
+
DIGEST_URI = {
|
|
3413
|
+
sha256: "http://www.w3.org/2001/04/xmlenc#sha256",
|
|
3414
|
+
sha384: "http://www.w3.org/2001/04/xmldsig-more#sha384",
|
|
3415
|
+
sha512: "http://www.w3.org/2001/04/xmlenc#sha512"
|
|
3416
|
+
};
|
|
3417
|
+
ECDSA_SIGNATURE_URI = {
|
|
3418
|
+
sha256: "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
|
|
3419
|
+
sha384: "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384",
|
|
3420
|
+
sha512: "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
|
|
3421
|
+
};
|
|
3422
|
+
RSA_SHA256_SIGNATURE_URI = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
|
3163
3423
|
CLOCK_SKEW_BUFFER_MS = -6e4;
|
|
3164
3424
|
SIGNATURE_ID = "Signature";
|
|
3165
3425
|
SIGNED_PROPERTIES_ID = "SignedProperties";
|
|
@@ -3179,15 +3439,21 @@ var init_signature_service = __esm({
|
|
|
3179
3439
|
}
|
|
3180
3440
|
const certDer = extractDerFromPem(certPem);
|
|
3181
3441
|
const certBase64 = certDer.toString("base64");
|
|
3182
|
-
const certDigest = crypto4.createHash("sha256").update(certDer).digest("base64");
|
|
3183
3442
|
const x5093 = new crypto4.X509Certificate(certPem);
|
|
3184
3443
|
const issuerName = normalizeIssuerDn(x5093.issuer);
|
|
3185
3444
|
const serialNumber = hexSerialToDecimal(x5093.serialNumber);
|
|
3186
3445
|
const privateKey = crypto4.createPrivateKey(
|
|
3187
3446
|
passphrase ? { key: privateKeyPem, format: "pem", passphrase } : privateKeyPem
|
|
3188
3447
|
);
|
|
3189
|
-
const
|
|
3190
|
-
|
|
3448
|
+
const keyType = privateKey.asymmetricKeyType;
|
|
3449
|
+
if (keyType !== "ec" && keyType !== "rsa") {
|
|
3450
|
+
throw new KSeFError(
|
|
3451
|
+
`Unsupported private key type: ${keyType ?? "unknown"}. Supported: RSA and ECDSA.`
|
|
3452
|
+
);
|
|
3453
|
+
}
|
|
3454
|
+
const isEc = keyType === "ec";
|
|
3455
|
+
const algo = isEc ? pickEcdsaAlgo(privateKey) : pickRsaAlgo();
|
|
3456
|
+
const certDigest = crypto4.createHash(algo.nodeHashName).update(certDer).digest("base64");
|
|
3191
3457
|
const signingTime = new Date(Date.now() + CLOCK_SKEW_BUFFER_MS).toISOString();
|
|
3192
3458
|
const parser2 = new DOMParser();
|
|
3193
3459
|
const doc = parser2.parseFromString(xml, "text/xml");
|
|
@@ -3201,12 +3467,17 @@ var init_signature_service = __esm({
|
|
|
3201
3467
|
certDigest,
|
|
3202
3468
|
issuerName,
|
|
3203
3469
|
serialNumber,
|
|
3204
|
-
signingTime
|
|
3470
|
+
signingTime,
|
|
3471
|
+
algo.digestUri
|
|
3472
|
+
);
|
|
3473
|
+
const rootDigest = computeRootDigest(doc, algo.nodeHashName);
|
|
3474
|
+
const signedPropertiesDigest = computeSignedPropertiesDigest(
|
|
3475
|
+
qualifyingPropertiesXml,
|
|
3476
|
+
algo.nodeHashName
|
|
3205
3477
|
);
|
|
3206
|
-
const rootDigest = computeRootDigest(doc);
|
|
3207
|
-
const signedPropertiesDigest = computeSignedPropertiesDigest(qualifyingPropertiesXml);
|
|
3208
3478
|
const signedInfoXml = buildSignedInfo(
|
|
3209
|
-
|
|
3479
|
+
algo.signatureUri,
|
|
3480
|
+
algo.digestUri,
|
|
3210
3481
|
rootDigest,
|
|
3211
3482
|
signedPropertiesDigest
|
|
3212
3483
|
);
|
|
@@ -3215,7 +3486,8 @@ var init_signature_service = __esm({
|
|
|
3215
3486
|
const signatureValue = computeSignatureValue(
|
|
3216
3487
|
canonicalSignedInfo,
|
|
3217
3488
|
privateKey,
|
|
3218
|
-
isEc
|
|
3489
|
+
isEc,
|
|
3490
|
+
algo.nodeHashName
|
|
3219
3491
|
);
|
|
3220
3492
|
const signatureXml = buildSignatureElement(
|
|
3221
3493
|
signedInfoXml,
|
|
@@ -3312,6 +3584,11 @@ function buildRestClientConfig(options, authManager) {
|
|
|
3312
3584
|
endpointLimits: options.rateLimit.endpointLimits
|
|
3313
3585
|
});
|
|
3314
3586
|
}
|
|
3587
|
+
if (options?.circuitBreaker === null) {
|
|
3588
|
+
config.circuitBreakerPolicy = null;
|
|
3589
|
+
} else if (options?.circuitBreaker) {
|
|
3590
|
+
config.circuitBreakerPolicy = new CircuitBreakerPolicy(options.circuitBreaker);
|
|
3591
|
+
}
|
|
3315
3592
|
if (options?.presignedUrlHosts) {
|
|
3316
3593
|
const base = defaultPresignedUrlPolicy();
|
|
3317
3594
|
config.presignedUrlPolicy = {
|
|
@@ -3329,6 +3606,7 @@ var init_client = __esm({
|
|
|
3329
3606
|
init_rest_client();
|
|
3330
3607
|
init_retry_policy();
|
|
3331
3608
|
init_rate_limit_policy();
|
|
3609
|
+
init_circuit_breaker_policy();
|
|
3332
3610
|
init_presigned_url_policy();
|
|
3333
3611
|
init_auth_manager();
|
|
3334
3612
|
init_auth();
|
|
@@ -3655,10 +3933,35 @@ var init_invoice_field_extractor = __esm({
|
|
|
3655
3933
|
|
|
3656
3934
|
// src/xml/xml-engine.ts
|
|
3657
3935
|
import { XMLBuilder, XMLParser as XMLParser3 } from "fast-xml-parser";
|
|
3658
|
-
|
|
3936
|
+
function createObjectBuilder(pretty = false) {
|
|
3937
|
+
return new XMLBuilder({
|
|
3938
|
+
ignoreAttributes: false,
|
|
3939
|
+
preserveOrder: false,
|
|
3940
|
+
attributeNamePrefix: "@_",
|
|
3941
|
+
textNodeName: "#text",
|
|
3942
|
+
format: pretty,
|
|
3943
|
+
suppressBooleanAttributes: false,
|
|
3944
|
+
suppressEmptyNode: false,
|
|
3945
|
+
processEntities: true
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
function prependDeclaration(xml) {
|
|
3949
|
+
return xml.startsWith("<?xml") ? xml : `${XML_DECLARATION}${xml}`;
|
|
3950
|
+
}
|
|
3951
|
+
function buildXml(document) {
|
|
3952
|
+
return prependDeclaration(builder.build(document));
|
|
3953
|
+
}
|
|
3954
|
+
function buildXmlFromObject(document, options) {
|
|
3955
|
+
return prependDeclaration(createObjectBuilder(options?.pretty).build(document));
|
|
3956
|
+
}
|
|
3957
|
+
function stripBom(input) {
|
|
3958
|
+
return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
|
|
3959
|
+
}
|
|
3960
|
+
var XML_DECLARATION, parser, builder;
|
|
3659
3961
|
var init_xml_engine = __esm({
|
|
3660
3962
|
"src/xml/xml-engine.ts"() {
|
|
3661
3963
|
"use strict";
|
|
3964
|
+
XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>\n';
|
|
3662
3965
|
parser = new XMLParser3({
|
|
3663
3966
|
ignoreAttributes: false,
|
|
3664
3967
|
preserveOrder: true,
|
|
@@ -3685,31 +3988,485 @@ var init_xml_engine = __esm({
|
|
|
3685
3988
|
});
|
|
3686
3989
|
|
|
3687
3990
|
// src/xml/order-map.ts
|
|
3991
|
+
function comparePKey(a, b) {
|
|
3992
|
+
const normalize = (value) => value.replace(/^P_/, "").split("_").map((part) => Number.isNaN(Number(part)) ? part : Number(part));
|
|
3993
|
+
const aParts = normalize(a);
|
|
3994
|
+
const bParts = normalize(b);
|
|
3995
|
+
const max = Math.max(aParts.length, bParts.length);
|
|
3996
|
+
for (let i = 0; i < max; i += 1) {
|
|
3997
|
+
const left = aParts[i];
|
|
3998
|
+
const right = bParts[i];
|
|
3999
|
+
if (left === void 0) return -1;
|
|
4000
|
+
if (right === void 0) return 1;
|
|
4001
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
4002
|
+
if (left !== right) return left - right;
|
|
4003
|
+
continue;
|
|
4004
|
+
}
|
|
4005
|
+
const leftStr = String(left);
|
|
4006
|
+
const rightStr = String(right);
|
|
4007
|
+
if (leftStr !== rightStr) return leftStr < rightStr ? -1 : 1;
|
|
4008
|
+
}
|
|
4009
|
+
return 0;
|
|
4010
|
+
}
|
|
4011
|
+
function isObject(value) {
|
|
4012
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4013
|
+
}
|
|
4014
|
+
function normalizeValueForKey(key, value) {
|
|
4015
|
+
if (Array.isArray(value)) {
|
|
4016
|
+
return value.map(
|
|
4017
|
+
(item) => isObject(item) ? orderXmlObject(item, key) : normalizeValue(item)
|
|
4018
|
+
);
|
|
4019
|
+
}
|
|
4020
|
+
if (isObject(value)) return orderXmlObject(value, key);
|
|
4021
|
+
return value;
|
|
4022
|
+
}
|
|
4023
|
+
function normalizeValue(value) {
|
|
4024
|
+
if (Array.isArray(value)) return value.map((item) => normalizeValue(item));
|
|
4025
|
+
if (isObject(value)) return orderXmlObject(value);
|
|
4026
|
+
return value;
|
|
4027
|
+
}
|
|
4028
|
+
function orderXmlObject(value, contextKey) {
|
|
4029
|
+
const order = contextKey ? ORDER_MAP[contextKey] : void 0;
|
|
4030
|
+
const keys = Object.keys(value);
|
|
4031
|
+
const used = /* @__PURE__ */ new Set();
|
|
4032
|
+
const ordered = {};
|
|
4033
|
+
if (order) {
|
|
4034
|
+
for (const key of order) {
|
|
4035
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
4036
|
+
const item = value[key];
|
|
4037
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
4038
|
+
used.add(key);
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
const pKeys = keys.filter((key) => !used.has(key) && key.startsWith("P_")).sort(comparePKey);
|
|
4043
|
+
for (const key of pKeys) {
|
|
4044
|
+
const item = value[key];
|
|
4045
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
4046
|
+
used.add(key);
|
|
4047
|
+
}
|
|
4048
|
+
for (const key of keys) {
|
|
4049
|
+
if (used.has(key)) continue;
|
|
4050
|
+
const item = value[key];
|
|
4051
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
4052
|
+
}
|
|
4053
|
+
return ordered;
|
|
4054
|
+
}
|
|
4055
|
+
var ORDER_MAP;
|
|
3688
4056
|
var init_order_map = __esm({
|
|
3689
4057
|
"src/xml/order-map.ts"() {
|
|
3690
4058
|
"use strict";
|
|
4059
|
+
ORDER_MAP = {
|
|
4060
|
+
Faktura: ["Naglowek", "Podmiot1", "Podmiot2", "Podmiot3", "Fa", "Stopka"],
|
|
4061
|
+
Naglowek: ["KodFormularza", "WariantFormularza", "DataWytworzeniaFa", "SystemInfo"],
|
|
4062
|
+
Podmiot1: [
|
|
4063
|
+
"PrefiksPodatnika",
|
|
4064
|
+
"NrEORI",
|
|
4065
|
+
"DaneIdentyfikacyjne",
|
|
4066
|
+
"Adres",
|
|
4067
|
+
"AdresKoresp",
|
|
4068
|
+
"DaneKontaktowe",
|
|
4069
|
+
"StatusInfoPodatnika"
|
|
4070
|
+
],
|
|
4071
|
+
Podmiot2: [
|
|
4072
|
+
"NrEORI",
|
|
4073
|
+
"DaneIdentyfikacyjne",
|
|
4074
|
+
"Adres",
|
|
4075
|
+
"AdresKoresp",
|
|
4076
|
+
"DaneKontaktowe",
|
|
4077
|
+
"NrKlienta",
|
|
4078
|
+
"IDNabywcy",
|
|
4079
|
+
"JST",
|
|
4080
|
+
"GV"
|
|
4081
|
+
],
|
|
4082
|
+
Podmiot3: [
|
|
4083
|
+
"IDNabywcy",
|
|
4084
|
+
"NrEORI",
|
|
4085
|
+
"DaneIdentyfikacyjne",
|
|
4086
|
+
"Adres",
|
|
4087
|
+
"AdresKoresp",
|
|
4088
|
+
"DaneKontaktowe",
|
|
4089
|
+
"Rola",
|
|
4090
|
+
"Udzial"
|
|
4091
|
+
],
|
|
4092
|
+
DaneIdentyfikacyjne: [
|
|
4093
|
+
"NIP",
|
|
4094
|
+
"IDWew",
|
|
4095
|
+
"KodUE",
|
|
4096
|
+
"NrVatUE",
|
|
4097
|
+
"KodKraju",
|
|
4098
|
+
"NrID",
|
|
4099
|
+
"BrakID",
|
|
4100
|
+
"Nazwa",
|
|
4101
|
+
"Identyfikator",
|
|
4102
|
+
"KRS"
|
|
4103
|
+
],
|
|
4104
|
+
Adres: ["KodKraju", "AdresL1", "AdresL2", "AdresL3"],
|
|
4105
|
+
DaneKontaktowe: ["Email", "Telefon"],
|
|
4106
|
+
Fa: [
|
|
4107
|
+
"KodWaluty",
|
|
4108
|
+
"P_1",
|
|
4109
|
+
"P_1M",
|
|
4110
|
+
"P_2",
|
|
4111
|
+
"WZ",
|
|
4112
|
+
"P_6",
|
|
4113
|
+
"OkresFa",
|
|
4114
|
+
// Multi-rate interleave per VAT group — DO NOT flatten into P_13_* block then P_14_* block.
|
|
4115
|
+
// See smekcio TS d1ec8fe and the "multi-rate interleave" regression test.
|
|
4116
|
+
"P_13_1",
|
|
4117
|
+
"P_14_1",
|
|
4118
|
+
"P_14_1W",
|
|
4119
|
+
"P_13_2",
|
|
4120
|
+
"P_14_2",
|
|
4121
|
+
"P_14_2W",
|
|
4122
|
+
"P_13_3",
|
|
4123
|
+
"P_14_3",
|
|
4124
|
+
"P_14_3W",
|
|
4125
|
+
"P_13_4",
|
|
4126
|
+
"P_14_4",
|
|
4127
|
+
"P_14_4W",
|
|
4128
|
+
"P_13_5",
|
|
4129
|
+
"P_14_5",
|
|
4130
|
+
"P_13_6_1",
|
|
4131
|
+
"P_13_6_2",
|
|
4132
|
+
"P_13_6_3",
|
|
4133
|
+
"P_13_7",
|
|
4134
|
+
"P_13_8",
|
|
4135
|
+
"P_13_9",
|
|
4136
|
+
"P_13_10",
|
|
4137
|
+
"P_13_11",
|
|
4138
|
+
"P_15",
|
|
4139
|
+
"KursWalutyZ",
|
|
4140
|
+
"Adnotacje",
|
|
4141
|
+
"RodzajFaktury",
|
|
4142
|
+
"PrzyczynaKorekty",
|
|
4143
|
+
"TypKorekty",
|
|
4144
|
+
"DaneFaKorygowanej",
|
|
4145
|
+
"OkresFaKorygowanej",
|
|
4146
|
+
"NrFaKorygowany",
|
|
4147
|
+
"Podmiot1K",
|
|
4148
|
+
"Podmiot2K",
|
|
4149
|
+
"Podmiot3K",
|
|
4150
|
+
"ZaliczkaCzesciowa",
|
|
4151
|
+
"FP",
|
|
4152
|
+
"TP",
|
|
4153
|
+
"DodatkowyOpis",
|
|
4154
|
+
"FakturaZaliczkowa",
|
|
4155
|
+
"ZwrotAkcyzy",
|
|
4156
|
+
"FaWiersz",
|
|
4157
|
+
"FaWiersze",
|
|
4158
|
+
"Rozliczenie",
|
|
4159
|
+
"Platnosc"
|
|
4160
|
+
],
|
|
4161
|
+
Adnotacje: ["P_16", "P_17", "P_18", "P_18A", "Zwolnienie", "NoweSrodkiTransportu", "P_23", "PMarzy"],
|
|
4162
|
+
OkresFa: ["P_6_Od", "P_6_Do"],
|
|
4163
|
+
FaWiersz: [
|
|
4164
|
+
"NrWierszaFa",
|
|
4165
|
+
"UU_ID",
|
|
4166
|
+
"P_6A",
|
|
4167
|
+
"P_7",
|
|
4168
|
+
"Indeks",
|
|
4169
|
+
"GTIN",
|
|
4170
|
+
"PKWiU",
|
|
4171
|
+
"CN",
|
|
4172
|
+
"PKOB",
|
|
4173
|
+
"P_8A",
|
|
4174
|
+
"P_8B",
|
|
4175
|
+
"P_9A",
|
|
4176
|
+
"P_9B",
|
|
4177
|
+
"P_10",
|
|
4178
|
+
"P_11",
|
|
4179
|
+
"P_11A",
|
|
4180
|
+
"P_11Vat",
|
|
4181
|
+
"P_12",
|
|
4182
|
+
"P_12_XII",
|
|
4183
|
+
"P_12_Zal_15",
|
|
4184
|
+
"KwotaAkcyzy",
|
|
4185
|
+
"GTU",
|
|
4186
|
+
"Procedura",
|
|
4187
|
+
"KursWaluty",
|
|
4188
|
+
"StanPrzed"
|
|
4189
|
+
]
|
|
4190
|
+
};
|
|
3691
4191
|
}
|
|
3692
4192
|
});
|
|
3693
4193
|
|
|
3694
4194
|
// src/xml/faktura-builder.ts
|
|
4195
|
+
function toKodFormularza(formCode) {
|
|
4196
|
+
return {
|
|
4197
|
+
"@_kodSystemowy": formCode.systemCode,
|
|
4198
|
+
"@_wersjaSchemy": formCode.schemaVersion,
|
|
4199
|
+
"#text": formCode.value
|
|
4200
|
+
};
|
|
4201
|
+
}
|
|
4202
|
+
function isFormCodeShape(value) {
|
|
4203
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
4204
|
+
const candidate = value;
|
|
4205
|
+
return typeof candidate.systemCode === "string" && typeof candidate.schemaVersion === "string" && typeof candidate.value === "string";
|
|
4206
|
+
}
|
|
4207
|
+
function isObject2(value) {
|
|
4208
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4209
|
+
}
|
|
4210
|
+
function normalizeTopLevelChild(key, value) {
|
|
4211
|
+
if (key === "Naglowek" && isObject2(value)) {
|
|
4212
|
+
return normalizeNaglowek(value);
|
|
4213
|
+
}
|
|
4214
|
+
if (Array.isArray(value)) {
|
|
4215
|
+
return value.map((item) => isObject2(item) ? orderXmlObject(item, key) : item);
|
|
4216
|
+
}
|
|
4217
|
+
if (isObject2(value)) return orderXmlObject(value, key);
|
|
4218
|
+
return value;
|
|
4219
|
+
}
|
|
4220
|
+
function normalizeNaglowek(value) {
|
|
4221
|
+
const result = {};
|
|
4222
|
+
for (const [key, item] of Object.entries(value)) {
|
|
4223
|
+
if (item === void 0) continue;
|
|
4224
|
+
if (key === "KodFormularza" && isFormCodeShape(item)) {
|
|
4225
|
+
result[key] = toKodFormularza(item);
|
|
4226
|
+
continue;
|
|
4227
|
+
}
|
|
4228
|
+
if (Array.isArray(item)) {
|
|
4229
|
+
result[key] = item.map(
|
|
4230
|
+
(entry) => isObject2(entry) ? orderXmlObject(entry, key) : entry
|
|
4231
|
+
);
|
|
4232
|
+
continue;
|
|
4233
|
+
}
|
|
4234
|
+
if (isObject2(item)) {
|
|
4235
|
+
result[key] = orderXmlObject(item, key);
|
|
4236
|
+
continue;
|
|
4237
|
+
}
|
|
4238
|
+
result[key] = item;
|
|
4239
|
+
}
|
|
4240
|
+
return result;
|
|
4241
|
+
}
|
|
4242
|
+
function normalizeTopLevel(input) {
|
|
4243
|
+
const result = {};
|
|
4244
|
+
for (const [key, value] of Object.entries(input)) {
|
|
4245
|
+
if (value === void 0) continue;
|
|
4246
|
+
result[key] = normalizeTopLevelChild(key, value);
|
|
4247
|
+
}
|
|
4248
|
+
return result;
|
|
4249
|
+
}
|
|
4250
|
+
function buildFakturaXml(faktura, options = {}) {
|
|
4251
|
+
const schema = options.schema ?? "FA3";
|
|
4252
|
+
const fakturaNamespace = options.fakturaNamespace ?? FAKTURA_NAMESPACE[schema];
|
|
4253
|
+
const etdNamespace = options.etdNamespace ?? ETD_NAMESPACE[schema];
|
|
4254
|
+
const normalized = normalizeTopLevel(faktura);
|
|
4255
|
+
const ordered = orderXmlObject(normalized, "Faktura");
|
|
4256
|
+
const document = {
|
|
4257
|
+
Faktura: {
|
|
4258
|
+
...ordered,
|
|
4259
|
+
"@_xmlns": fakturaNamespace,
|
|
4260
|
+
"@_xmlns:etd": etdNamespace
|
|
4261
|
+
}
|
|
4262
|
+
};
|
|
4263
|
+
return buildXmlFromObject(document, { pretty: options.pretty });
|
|
4264
|
+
}
|
|
4265
|
+
function isFakturaInput(input) {
|
|
4266
|
+
if (!isObject2(input)) return false;
|
|
4267
|
+
const candidate = input;
|
|
4268
|
+
if (!Object.prototype.hasOwnProperty.call(candidate, "Naglowek")) return false;
|
|
4269
|
+
if (!Object.prototype.hasOwnProperty.call(candidate, "Fa")) return false;
|
|
4270
|
+
return isObject2(candidate.Naglowek) && isObject2(candidate.Fa);
|
|
4271
|
+
}
|
|
4272
|
+
var FAKTURA_NAMESPACE, ETD_NAMESPACE;
|
|
3695
4273
|
var init_faktura_builder = __esm({
|
|
3696
4274
|
"src/xml/faktura-builder.ts"() {
|
|
3697
4275
|
"use strict";
|
|
3698
4276
|
init_xml_engine();
|
|
3699
4277
|
init_order_map();
|
|
4278
|
+
FAKTURA_NAMESPACE = {
|
|
4279
|
+
FA2: "http://crd.gov.pl/wzor/2023/06/29/12648/",
|
|
4280
|
+
FA3: "http://crd.gov.pl/wzor/2025/06/25/13775/"
|
|
4281
|
+
};
|
|
4282
|
+
ETD_NAMESPACE = {
|
|
4283
|
+
FA2: "http://crd.gov.pl/xml/schematy/2020/10/08/eDokumenty",
|
|
4284
|
+
FA3: "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/"
|
|
4285
|
+
};
|
|
3700
4286
|
}
|
|
3701
4287
|
});
|
|
3702
4288
|
|
|
3703
4289
|
// src/xml/pef-builder.ts
|
|
4290
|
+
function isPefUblDocumentInput(input) {
|
|
4291
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) return false;
|
|
4292
|
+
const obj = input;
|
|
4293
|
+
const invoice3 = obj.Invoice;
|
|
4294
|
+
const creditNote = obj.CreditNote;
|
|
4295
|
+
const hasInvoice = typeof invoice3 === "object" && invoice3 !== null && !Array.isArray(invoice3);
|
|
4296
|
+
const hasCreditNote = typeof creditNote === "object" && creditNote !== null && !Array.isArray(creditNote);
|
|
4297
|
+
return hasInvoice !== hasCreditNote;
|
|
4298
|
+
}
|
|
4299
|
+
function inferSchema(input) {
|
|
4300
|
+
return "Invoice" in input ? "PEF" : "PEF_KOR";
|
|
4301
|
+
}
|
|
4302
|
+
function isNonArrayObject(value) {
|
|
4303
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4304
|
+
}
|
|
4305
|
+
function assertPefShape(input) {
|
|
4306
|
+
if (!isNonArrayObject(input)) {
|
|
4307
|
+
throw new KSeFValidationError("PEF input must be a non-array object.");
|
|
4308
|
+
}
|
|
4309
|
+
const hasInvoiceKey = "Invoice" in input;
|
|
4310
|
+
const hasCreditNoteKey = "CreditNote" in input;
|
|
4311
|
+
if (hasInvoiceKey && hasCreditNoteKey) {
|
|
4312
|
+
throw new KSeFValidationError(
|
|
4313
|
+
"PEF input must contain exactly one of `Invoice` or `CreditNote`, not both."
|
|
4314
|
+
);
|
|
4315
|
+
}
|
|
4316
|
+
if (!hasInvoiceKey && !hasCreditNoteKey) {
|
|
4317
|
+
throw new KSeFValidationError(
|
|
4318
|
+
"PEF input must contain either an `Invoice` or a `CreditNote` root element."
|
|
4319
|
+
);
|
|
4320
|
+
}
|
|
4321
|
+
const rootKey = hasInvoiceKey ? "Invoice" : "CreditNote";
|
|
4322
|
+
if (!isNonArrayObject(input[rootKey])) {
|
|
4323
|
+
throw new KSeFValidationError(
|
|
4324
|
+
`PEF \`${rootKey}\` value must be a non-array object.`
|
|
4325
|
+
);
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
function buildPefXml(input, options = {}) {
|
|
4329
|
+
assertPefShape(input);
|
|
4330
|
+
const inferred = inferSchema(input);
|
|
4331
|
+
const schema = options.schema ?? input.schema ?? inferred;
|
|
4332
|
+
if (schema !== inferred) {
|
|
4333
|
+
throw new KSeFValidationError(
|
|
4334
|
+
`PEF schema mismatch: expected ${inferred} based on root element, got ${schema}.`
|
|
4335
|
+
);
|
|
4336
|
+
}
|
|
4337
|
+
const commonNamespaces = {
|
|
4338
|
+
"@_xmlns:ext": UBL_EXT_NS,
|
|
4339
|
+
"@_xmlns:cbc": UBL_CBC_NS,
|
|
4340
|
+
"@_xmlns:cac": UBL_CAC_NS,
|
|
4341
|
+
"@_xmlns:cbc-pl": UBL_CBC_PL_NS,
|
|
4342
|
+
"@_xmlns:cac-pl": UBL_CAC_PL_NS
|
|
4343
|
+
};
|
|
4344
|
+
const document = "Invoice" in input ? {
|
|
4345
|
+
Invoice: {
|
|
4346
|
+
...input.Invoice,
|
|
4347
|
+
"@_xmlns": PEF_NAMESPACE.PEF,
|
|
4348
|
+
...commonNamespaces
|
|
4349
|
+
}
|
|
4350
|
+
} : {
|
|
4351
|
+
CreditNote: {
|
|
4352
|
+
...input.CreditNote,
|
|
4353
|
+
"@_xmlns": PEF_NAMESPACE.PEF_KOR,
|
|
4354
|
+
...commonNamespaces
|
|
4355
|
+
}
|
|
4356
|
+
};
|
|
4357
|
+
return buildXmlFromObject(document, { pretty: options.pretty });
|
|
4358
|
+
}
|
|
4359
|
+
var PEF_NAMESPACE, UBL_EXT_NS, UBL_CBC_NS, UBL_CAC_NS, UBL_CBC_PL_NS, UBL_CAC_PL_NS;
|
|
3704
4360
|
var init_pef_builder = __esm({
|
|
3705
4361
|
"src/xml/pef-builder.ts"() {
|
|
3706
4362
|
"use strict";
|
|
3707
4363
|
init_ksef_validation_error();
|
|
3708
4364
|
init_xml_engine();
|
|
4365
|
+
PEF_NAMESPACE = {
|
|
4366
|
+
PEF: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
|
|
4367
|
+
PEF_KOR: "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
|
|
4368
|
+
};
|
|
4369
|
+
UBL_EXT_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2";
|
|
4370
|
+
UBL_CBC_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";
|
|
4371
|
+
UBL_CAC_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2";
|
|
4372
|
+
UBL_CBC_PL_NS = "urn:pl:extended:CommonBasicComponents-2";
|
|
4373
|
+
UBL_CAC_PL_NS = "urn:pl:extended:CommonAggregateComponents-2";
|
|
3709
4374
|
}
|
|
3710
4375
|
});
|
|
3711
4376
|
|
|
3712
4377
|
// src/xml/invoice-serializer.ts
|
|
4378
|
+
function isNonArrayObject2(value) {
|
|
4379
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4380
|
+
}
|
|
4381
|
+
function classifyUnknownObject(input) {
|
|
4382
|
+
const looksLikeFaktura = "Naglowek" in input || "Fa" in input || "Podmiot1" in input || "Podmiot2" in input;
|
|
4383
|
+
const hasInvoice = "Invoice" in input;
|
|
4384
|
+
const hasCreditNote = "CreditNote" in input;
|
|
4385
|
+
if (hasInvoice && hasCreditNote) {
|
|
4386
|
+
return new KSeFValidationError(
|
|
4387
|
+
"Input must contain exactly one of `Invoice` or `CreditNote`, not both."
|
|
4388
|
+
);
|
|
4389
|
+
}
|
|
4390
|
+
if (hasInvoice !== hasCreditNote) {
|
|
4391
|
+
const rootKey = hasInvoice ? "Invoice" : "CreditNote";
|
|
4392
|
+
if (!isNonArrayObject2(input[rootKey])) {
|
|
4393
|
+
return KSeFValidationError.fromField(
|
|
4394
|
+
rootKey,
|
|
4395
|
+
`PEF \`${rootKey}\` value must be a non-array object.`
|
|
4396
|
+
);
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
if (looksLikeFaktura) {
|
|
4400
|
+
const missing = [];
|
|
4401
|
+
if (!("Naglowek" in input)) missing.push("Naglowek");
|
|
4402
|
+
if (!("Fa" in input)) missing.push("Fa");
|
|
4403
|
+
if (missing.length > 0) {
|
|
4404
|
+
return KSeFValidationError.fromField(
|
|
4405
|
+
missing[0],
|
|
4406
|
+
`Faktura input is missing required top-level key(s): ${missing.join(", ")}.`
|
|
4407
|
+
);
|
|
4408
|
+
}
|
|
4409
|
+
for (const key of ["Naglowek", "Fa"]) {
|
|
4410
|
+
if (!isNonArrayObject2(input[key])) {
|
|
4411
|
+
return KSeFValidationError.fromField(
|
|
4412
|
+
key,
|
|
4413
|
+
`Faktura \`${key}\` value must be a non-null, non-array object.`
|
|
4414
|
+
);
|
|
4415
|
+
}
|
|
4416
|
+
}
|
|
4417
|
+
return new KSeFValidationError(
|
|
4418
|
+
"Faktura-like input failed shape validation: `Naglowek` and `Fa` must be own enumerable properties on the input object."
|
|
4419
|
+
);
|
|
4420
|
+
}
|
|
4421
|
+
return new KSeFValidationError(
|
|
4422
|
+
"Unsupported invoice input shape: expected `FakturaInput` (with `Naglowek` + `Fa`) or `PefUblDocumentInput` (with `Invoice` or `CreditNote`)."
|
|
4423
|
+
);
|
|
4424
|
+
}
|
|
4425
|
+
function serializeInvoiceXml(input, options) {
|
|
4426
|
+
if (Buffer.isBuffer(input)) return input;
|
|
4427
|
+
if (typeof input === "string") {
|
|
4428
|
+
return Buffer.from(stripBom(input), "utf8");
|
|
4429
|
+
}
|
|
4430
|
+
if (Array.isArray(input)) {
|
|
4431
|
+
return Buffer.from(stripBom(buildXml(input)), "utf8");
|
|
4432
|
+
}
|
|
4433
|
+
if (input && typeof input === "object") {
|
|
4434
|
+
const schema = options?.schema;
|
|
4435
|
+
if (isPefUblDocumentInput(input)) {
|
|
4436
|
+
if (schema && !PEF_SCHEMAS.has(schema)) {
|
|
4437
|
+
throw new KSeFValidationError(
|
|
4438
|
+
`schema option ${schema} is not compatible with a PEF / PEF_KOR input.`
|
|
4439
|
+
);
|
|
4440
|
+
}
|
|
4441
|
+
const pefSchema = schema === "PEF" || schema === "PEF_KOR" ? schema : void 0;
|
|
4442
|
+
const xml = buildPefXml(input, {
|
|
4443
|
+
schema: pefSchema,
|
|
4444
|
+
pretty: options?.pretty
|
|
4445
|
+
});
|
|
4446
|
+
return Buffer.from(stripBom(xml), "utf8");
|
|
4447
|
+
}
|
|
4448
|
+
if (isFakturaInput(input)) {
|
|
4449
|
+
if (schema && !FAKTURA_SCHEMAS.has(schema)) {
|
|
4450
|
+
throw new KSeFValidationError(
|
|
4451
|
+
`schema option ${schema} is not compatible with a Faktura input.`
|
|
4452
|
+
);
|
|
4453
|
+
}
|
|
4454
|
+
const fakturaSchema = schema === "FA2" || schema === "FA3" ? schema : void 0;
|
|
4455
|
+
const xml = buildFakturaXml(input, {
|
|
4456
|
+
schema: fakturaSchema,
|
|
4457
|
+
fakturaNamespace: options?.fakturaNamespace,
|
|
4458
|
+
etdNamespace: options?.etdNamespace,
|
|
4459
|
+
pretty: options?.pretty
|
|
4460
|
+
});
|
|
4461
|
+
return Buffer.from(stripBom(xml), "utf8");
|
|
4462
|
+
}
|
|
4463
|
+
throw classifyUnknownObject(input);
|
|
4464
|
+
}
|
|
4465
|
+
throw new KSeFValidationError(
|
|
4466
|
+
"Unsupported invoice input type: expected Buffer, string, XmlDocument, FakturaInput, or PefUblDocumentInput."
|
|
4467
|
+
);
|
|
4468
|
+
}
|
|
4469
|
+
var FAKTURA_SCHEMAS, PEF_SCHEMAS;
|
|
3713
4470
|
var init_invoice_serializer = __esm({
|
|
3714
4471
|
"src/xml/invoice-serializer.ts"() {
|
|
3715
4472
|
"use strict";
|
|
@@ -3717,6 +4474,8 @@ var init_invoice_serializer = __esm({
|
|
|
3717
4474
|
init_faktura_builder();
|
|
3718
4475
|
init_pef_builder();
|
|
3719
4476
|
init_xml_engine();
|
|
4477
|
+
FAKTURA_SCHEMAS = /* @__PURE__ */ new Set(["FA2", "FA3"]);
|
|
4478
|
+
PEF_SCHEMAS = /* @__PURE__ */ new Set(["PEF", "PEF_KOR"]);
|
|
3720
4479
|
}
|
|
3721
4480
|
});
|
|
3722
4481
|
|
|
@@ -5581,11 +6340,11 @@ async function validateSchema(xml, options, _parsed) {
|
|
|
5581
6340
|
const prefix = rootElement ? `/${rootElement}/` : "/";
|
|
5582
6341
|
const validationErrors = result.error.issues.map((issue) => {
|
|
5583
6342
|
const zodPath = issue.path.join("/");
|
|
5584
|
-
const
|
|
6343
|
+
const path12 = zodPath ? `${prefix}${zodPath}` : rootElement ? `/${rootElement}` : void 0;
|
|
5585
6344
|
return {
|
|
5586
6345
|
code: mapZodErrorCode(issue),
|
|
5587
6346
|
message: issue.message,
|
|
5588
|
-
path:
|
|
6347
|
+
path: path12
|
|
5589
6348
|
};
|
|
5590
6349
|
});
|
|
5591
6350
|
return { valid: false, schemaType, errors: validationErrors };
|
|
@@ -5625,9 +6384,9 @@ function validateBusinessRules(xml, _parsed) {
|
|
|
5625
6384
|
collectDateErrors(object, rootElement, errors);
|
|
5626
6385
|
return { valid: errors.length === 0, schemaType, errors };
|
|
5627
6386
|
}
|
|
5628
|
-
function collectNipPeselErrors(obj,
|
|
6387
|
+
function collectNipPeselErrors(obj, path12, errors) {
|
|
5629
6388
|
for (const [key, value] of Object.entries(obj)) {
|
|
5630
|
-
const currentPath =
|
|
6389
|
+
const currentPath = path12 ? `${path12}/${key}` : key;
|
|
5631
6390
|
if (key === "NIP" && typeof value === "string") {
|
|
5632
6391
|
if (!isValidNip(value)) {
|
|
5633
6392
|
errors.push({
|
|
@@ -6043,10 +6802,10 @@ var init_batch_session_workflow = __esm({
|
|
|
6043
6802
|
});
|
|
6044
6803
|
|
|
6045
6804
|
// src/cli/index.ts
|
|
6046
|
-
import { readFileSync as
|
|
6047
|
-
import { fileURLToPath } from "url";
|
|
6048
|
-
import { dirname as
|
|
6049
|
-
import { defineCommand as
|
|
6805
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
6806
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6807
|
+
import { dirname as dirname3, resolve } from "path";
|
|
6808
|
+
import { defineCommand as defineCommand19, runMain } from "citty";
|
|
6050
6809
|
|
|
6051
6810
|
// src/cli/commands/config.ts
|
|
6052
6811
|
import { defineCommand } from "citty";
|
|
@@ -6306,7 +7065,13 @@ async function withErrorHandler(fn, opts) {
|
|
|
6306
7065
|
await fn();
|
|
6307
7066
|
} catch (error) {
|
|
6308
7067
|
renderCliError(error, opts);
|
|
6309
|
-
|
|
7068
|
+
let code = 1;
|
|
7069
|
+
try {
|
|
7070
|
+
code = opts?.exitCode?.(error) ?? 1;
|
|
7071
|
+
} catch {
|
|
7072
|
+
code = 1;
|
|
7073
|
+
}
|
|
7074
|
+
process.exit(code);
|
|
6310
7075
|
}
|
|
6311
7076
|
}
|
|
6312
7077
|
|
|
@@ -6386,14 +7151,14 @@ var configCommand = defineCommand({
|
|
|
6386
7151
|
// src/cli/commands/auth.ts
|
|
6387
7152
|
import * as fs5 from "fs";
|
|
6388
7153
|
import { defineCommand as defineCommand2 } from "citty";
|
|
6389
|
-
import { consola as
|
|
7154
|
+
import { consola as consola7 } from "consola";
|
|
6390
7155
|
|
|
6391
7156
|
// src/cli/client-factory.ts
|
|
6392
7157
|
init_client();
|
|
6393
|
-
import { consola as
|
|
7158
|
+
import { consola as consola6 } from "consola";
|
|
6394
7159
|
|
|
6395
7160
|
// src/cli/session-recovery.ts
|
|
6396
|
-
import { consola as
|
|
7161
|
+
import { consola as consola5 } from "consola";
|
|
6397
7162
|
|
|
6398
7163
|
// src/cli/credentials-store.ts
|
|
6399
7164
|
import * as fs3 from "fs";
|
|
@@ -6460,7 +7225,7 @@ async function recoverSession(globalOpts) {
|
|
|
6460
7225
|
const session = loadSession();
|
|
6461
7226
|
if (session && isSessionExpired(session) && session.refreshToken) {
|
|
6462
7227
|
try {
|
|
6463
|
-
|
|
7228
|
+
consola5.info("Session expired, refreshing token...");
|
|
6464
7229
|
const opts = globalOpts.env ? globalOpts : { ...globalOpts, env: session.environment };
|
|
6465
7230
|
const client = createClient(opts);
|
|
6466
7231
|
client.authManager.setAccessToken(session.accessToken);
|
|
@@ -6477,7 +7242,7 @@ async function recoverSession(globalOpts) {
|
|
|
6477
7242
|
const credentials = loadCredentials();
|
|
6478
7243
|
const config = loadConfig();
|
|
6479
7244
|
if (credentials?.token && config.nip) {
|
|
6480
|
-
|
|
7245
|
+
consola5.info("Logging in with stored credentials...");
|
|
6481
7246
|
const env = globalOpts.env ?? session?.environment ?? config.environment;
|
|
6482
7247
|
const opts = { ...globalOpts, env };
|
|
6483
7248
|
const client = createClient(opts);
|
|
@@ -6509,7 +7274,7 @@ async function recoverSession(globalOpts) {
|
|
|
6509
7274
|
// src/cli/client-factory.ts
|
|
6510
7275
|
function createClient(globalOpts) {
|
|
6511
7276
|
if (globalOpts.verbose) {
|
|
6512
|
-
|
|
7277
|
+
consola6.level = 4;
|
|
6513
7278
|
}
|
|
6514
7279
|
const config = loadConfig();
|
|
6515
7280
|
const env = globalOpts.env ?? config.environment;
|
|
@@ -6522,7 +7287,7 @@ function createClient(globalOpts) {
|
|
|
6522
7287
|
}
|
|
6523
7288
|
async function requireSession(globalOpts) {
|
|
6524
7289
|
if (globalOpts.verbose) {
|
|
6525
|
-
|
|
7290
|
+
consola6.level = 4;
|
|
6526
7291
|
}
|
|
6527
7292
|
const session = loadSession();
|
|
6528
7293
|
if (session && !isSessionExpired(session)) {
|
|
@@ -6613,7 +7378,7 @@ var login = defineCommand2({
|
|
|
6613
7378
|
const globalOpts = getGlobalOpts(args);
|
|
6614
7379
|
const config = loadConfig();
|
|
6615
7380
|
if (!args.env) {
|
|
6616
|
-
|
|
7381
|
+
consola7.info(`Using default environment: ${config.environment}`);
|
|
6617
7382
|
}
|
|
6618
7383
|
const client = createClient(globalOpts);
|
|
6619
7384
|
const nip = args.nip ?? config.nip;
|
|
@@ -6625,13 +7390,13 @@ var login = defineCommand2({
|
|
|
6625
7390
|
if (token) {
|
|
6626
7391
|
loginResult = await client.loginWithToken(token, nip);
|
|
6627
7392
|
} else if (args.p12) {
|
|
6628
|
-
const
|
|
6629
|
-
const p12Buffer =
|
|
7393
|
+
const fs17 = await import("fs");
|
|
7394
|
+
const p12Buffer = fs17.readFileSync(args.p12);
|
|
6630
7395
|
loginResult = await client.loginWithPkcs12(p12Buffer, args["p12-password"] ?? "", nip);
|
|
6631
7396
|
} else if (args.cert && args.key) {
|
|
6632
|
-
const
|
|
6633
|
-
const certPem =
|
|
6634
|
-
const keyPem =
|
|
7397
|
+
const fs17 = await import("fs");
|
|
7398
|
+
const certPem = fs17.readFileSync(args.cert, "utf-8");
|
|
7399
|
+
const keyPem = fs17.readFileSync(args.key, "utf-8");
|
|
6635
7400
|
loginResult = await client.loginWithCertificate(certPem, keyPem, nip, args["key-password"]);
|
|
6636
7401
|
} else {
|
|
6637
7402
|
throw new Error("Provide --token, --p12, or both --cert and --key for authentication.");
|
|
@@ -6664,7 +7429,7 @@ var login = defineCommand2({
|
|
|
6664
7429
|
if (args.json) {
|
|
6665
7430
|
console.log(JSON.stringify({ status: "ok", clientIp: loginResult.clientIp }, null, 2));
|
|
6666
7431
|
} else {
|
|
6667
|
-
|
|
7432
|
+
consola7.info(`Seen client IP: ${loginResult.clientIp}`);
|
|
6668
7433
|
outputSuccess("Logged in successfully.");
|
|
6669
7434
|
}
|
|
6670
7435
|
}, { json: Boolean(args.json) });
|
|
@@ -6850,7 +7615,7 @@ var whoami = defineCommand2({
|
|
|
6850
7615
|
}
|
|
6851
7616
|
}
|
|
6852
7617
|
if (restored) {
|
|
6853
|
-
|
|
7618
|
+
consola7.info("Session restored from stored credentials.");
|
|
6854
7619
|
}
|
|
6855
7620
|
const context2 = parseKSeFTokenContext(session.accessToken);
|
|
6856
7621
|
const info = {
|
|
@@ -6982,7 +7747,7 @@ var authCommand = defineCommand2({
|
|
|
6982
7747
|
// src/cli/commands/session.ts
|
|
6983
7748
|
import * as fs6 from "fs";
|
|
6984
7749
|
import { defineCommand as defineCommand3 } from "citty";
|
|
6985
|
-
import { consola as
|
|
7750
|
+
import { consola as consola8 } from "consola";
|
|
6986
7751
|
init_document_structures();
|
|
6987
7752
|
init_xml();
|
|
6988
7753
|
function getGlobalOpts2(args) {
|
|
@@ -7028,7 +7793,7 @@ var open = defineCommand3({
|
|
|
7028
7793
|
if (args.batch) {
|
|
7029
7794
|
throw new Error("Batch session open is used internally by `ksef invoice send <dir>`. Use `ksef session open` for online sessions.");
|
|
7030
7795
|
}
|
|
7031
|
-
if (!args.json)
|
|
7796
|
+
if (!args.json) consola8.start("Opening online session...");
|
|
7032
7797
|
const result = await client.onlineSession.openSession(
|
|
7033
7798
|
{ formCode, encryption: encryptionData.encryptionInfo }
|
|
7034
7799
|
);
|
|
@@ -7065,7 +7830,7 @@ var close = defineCommand3({
|
|
|
7065
7830
|
if (!ref) {
|
|
7066
7831
|
throw new Error("No session reference. Provide a ref or run `ksef session open` first.");
|
|
7067
7832
|
}
|
|
7068
|
-
if (!args.json)
|
|
7833
|
+
if (!args.json) consola8.start("Closing session...");
|
|
7069
7834
|
await client.onlineSession.closeSession(ref);
|
|
7070
7835
|
clearOnlineSessionRef();
|
|
7071
7836
|
outputSuccess(`Session ${ref} closed.`);
|
|
@@ -7153,7 +7918,7 @@ var list = defineCommand3({
|
|
|
7153
7918
|
{ json: false }
|
|
7154
7919
|
);
|
|
7155
7920
|
if (result.continuationToken) {
|
|
7156
|
-
|
|
7921
|
+
consola8.info(`More results available. Continuation token: ${result.continuationToken}`);
|
|
7157
7922
|
}
|
|
7158
7923
|
}, { json: Boolean(args.json) });
|
|
7159
7924
|
}
|
|
@@ -7204,7 +7969,7 @@ var invoices = defineCommand3({
|
|
|
7204
7969
|
{ json: false }
|
|
7205
7970
|
);
|
|
7206
7971
|
if (result.continuationToken) {
|
|
7207
|
-
|
|
7972
|
+
consola8.info(`More results available. Continuation token: ${result.continuationToken}`);
|
|
7208
7973
|
}
|
|
7209
7974
|
}, { json: Boolean(args.json) });
|
|
7210
7975
|
}
|
|
@@ -7255,7 +8020,7 @@ var failed = defineCommand3({
|
|
|
7255
8020
|
{ json: false }
|
|
7256
8021
|
);
|
|
7257
8022
|
if (result.continuationToken) {
|
|
7258
|
-
|
|
8023
|
+
consola8.info(`More results available. Continuation token: ${result.continuationToken}`);
|
|
7259
8024
|
}
|
|
7260
8025
|
}, { json: Boolean(args.json) });
|
|
7261
8026
|
}
|
|
@@ -7354,7 +8119,7 @@ var active = defineCommand3({
|
|
|
7354
8119
|
{ json: false }
|
|
7355
8120
|
);
|
|
7356
8121
|
if (result.continuationToken) {
|
|
7357
|
-
|
|
8122
|
+
consola8.info(`More results available. Continuation token: ${result.continuationToken}`);
|
|
7358
8123
|
}
|
|
7359
8124
|
}, { json: Boolean(args.json) });
|
|
7360
8125
|
}
|
|
@@ -7435,18 +8200,18 @@ var sessionCommand = defineCommand3({
|
|
|
7435
8200
|
});
|
|
7436
8201
|
|
|
7437
8202
|
// src/cli/commands/invoice.ts
|
|
7438
|
-
import * as
|
|
7439
|
-
import * as
|
|
8203
|
+
import * as fs11 from "fs";
|
|
8204
|
+
import * as path8 from "path";
|
|
7440
8205
|
import { Readable } from "stream";
|
|
7441
|
-
import { defineCommand as
|
|
7442
|
-
import { consola as
|
|
8206
|
+
import { defineCommand as defineCommand6 } from "citty";
|
|
8207
|
+
import { consola as consola11 } from "consola";
|
|
7443
8208
|
init_document_structures();
|
|
7444
8209
|
|
|
7445
8210
|
// src/cli/commands/export-incremental.ts
|
|
7446
8211
|
import * as fs8 from "fs";
|
|
7447
8212
|
import * as path5 from "path";
|
|
7448
8213
|
import { defineCommand as defineCommand4 } from "citty";
|
|
7449
|
-
import { consola as
|
|
8214
|
+
import { consola as consola9 } from "consola";
|
|
7450
8215
|
|
|
7451
8216
|
// src/workflows/hwm-storage.ts
|
|
7452
8217
|
import * as fs7 from "fs/promises";
|
|
@@ -7666,9 +8431,9 @@ var exportIncremental = defineCommand4({
|
|
|
7666
8431
|
fs8.mkdirSync(outputDir, { recursive: true });
|
|
7667
8432
|
}
|
|
7668
8433
|
if (!isJson) {
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
8434
|
+
consola9.start(`Incremental export: ${from} \u2192 ${to}, subject: ${subjectType}`);
|
|
8435
|
+
consola9.info(`State file: ${stateFile}`);
|
|
8436
|
+
consola9.info(`Output dir: ${outputDir}`);
|
|
7672
8437
|
}
|
|
7673
8438
|
const iterationParts = [];
|
|
7674
8439
|
const result = await incrementalExportAndDownload(client, {
|
|
@@ -7684,7 +8449,7 @@ var exportIncremental = defineCommand4({
|
|
|
7684
8449
|
iterationParts.push({ iteration, partCount: iterResult.parts.length });
|
|
7685
8450
|
if (!isJson) {
|
|
7686
8451
|
const hwmDate = continuationPoints[subjectType] ?? "complete";
|
|
7687
|
-
|
|
8452
|
+
consola9.info(
|
|
7688
8453
|
`Iteration ${iteration + 1}: ${iterResult.invoiceCount} invoices, truncated: ${iterResult.isTruncated}, HWM: ${hwmDate}`
|
|
7689
8454
|
);
|
|
7690
8455
|
}
|
|
@@ -7713,13 +8478,619 @@ var exportIncremental = defineCommand4({
|
|
|
7713
8478
|
outputSuccess(
|
|
7714
8479
|
`Export complete: ${result.iterationCount} iterations, ${result.decryptedParts.length} parts downloaded`
|
|
7715
8480
|
);
|
|
7716
|
-
|
|
7717
|
-
|
|
8481
|
+
consola9.info(`Final HWM: ${continuationPoints[subjectType] ?? "complete"}`);
|
|
8482
|
+
consola9.info(`Output: ${outputDir}`);
|
|
7718
8483
|
}
|
|
7719
8484
|
}, { json: Boolean(args.json) });
|
|
7720
8485
|
}
|
|
7721
8486
|
});
|
|
7722
8487
|
|
|
8488
|
+
// src/cli/commands/invoice-build.ts
|
|
8489
|
+
import { defineCommand as defineCommand5 } from "citty";
|
|
8490
|
+
import { consola as consola10 } from "consola";
|
|
8491
|
+
init_xml();
|
|
8492
|
+
init_invoice_validator();
|
|
8493
|
+
|
|
8494
|
+
// src/validation/xsd-validator.ts
|
|
8495
|
+
import { createRequire } from "module";
|
|
8496
|
+
import * as fs9 from "fs";
|
|
8497
|
+
import * as path6 from "path";
|
|
8498
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
8499
|
+
var cachedPkgRoot = null;
|
|
8500
|
+
function locatePackageRoot() {
|
|
8501
|
+
if (cachedPkgRoot !== null) return cachedPkgRoot;
|
|
8502
|
+
let dir = path6.dirname(fileURLToPath(import.meta.url));
|
|
8503
|
+
const root = path6.parse(dir).root;
|
|
8504
|
+
while (dir !== root) {
|
|
8505
|
+
const candidate = path6.join(dir, "docs", "schemas");
|
|
8506
|
+
if (fs9.existsSync(candidate)) {
|
|
8507
|
+
cachedPkgRoot = dir;
|
|
8508
|
+
return dir;
|
|
8509
|
+
}
|
|
8510
|
+
dir = path6.dirname(dir);
|
|
8511
|
+
}
|
|
8512
|
+
throw new Error("Could not locate ksef-client-ts package root (docs/schemas not found).");
|
|
8513
|
+
}
|
|
8514
|
+
var XSD_RELATIVE = {
|
|
8515
|
+
FA2: ["FA", "schemat_FA(2)_v1-0E.xsd"],
|
|
8516
|
+
FA3: ["FA", "schemat_FA(3)_v1-0E.xsd"],
|
|
8517
|
+
PEF: ["PEF", "Schemat_PEF(3)_v2-1.xsd"],
|
|
8518
|
+
PEF_KOR: ["PEF", "Schemat_PEF_KOR(3)_v2-1.xsd"]
|
|
8519
|
+
};
|
|
8520
|
+
function resolveXsdFor(schema) {
|
|
8521
|
+
const rel = XSD_RELATIVE[schema];
|
|
8522
|
+
if (!rel) throw new Error(`Unknown invoice schema: ${String(schema)}`);
|
|
8523
|
+
return path6.join(locatePackageRoot(), "docs", "schemas", ...rel);
|
|
8524
|
+
}
|
|
8525
|
+
var requireModule = createRequire(import.meta.url);
|
|
8526
|
+
var libxmljs = null;
|
|
8527
|
+
var libxmljsLoadError = null;
|
|
8528
|
+
try {
|
|
8529
|
+
libxmljs = requireModule("libxmljs2");
|
|
8530
|
+
} catch (err) {
|
|
8531
|
+
const code = err?.code;
|
|
8532
|
+
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
8533
|
+
libxmljs = null;
|
|
8534
|
+
} else {
|
|
8535
|
+
libxmljs = null;
|
|
8536
|
+
libxmljsLoadError = err instanceof Error ? err : new Error(String(err));
|
|
8537
|
+
}
|
|
8538
|
+
}
|
|
8539
|
+
var MISSING_LIBXMLJS_MESSAGE_PREFIX = "libxmljs2 is not installed";
|
|
8540
|
+
function isMissingLibxmljsError(err) {
|
|
8541
|
+
return err instanceof Error && err.message.startsWith(MISSING_LIBXMLJS_MESSAGE_PREFIX);
|
|
8542
|
+
}
|
|
8543
|
+
var EXTERNAL_STRUKTURY_DANYCH_URL = /schemaLocation="http:\/\/crd\.gov\.pl\/xml\/schematy\/dziedzinowe\/mf\/2022\/01\/05\/eD\/DefinicjeTypy\/StrukturyDanych_v10-0E\.xsd"/;
|
|
8544
|
+
function rewriteSchemaLocations(xsdContent) {
|
|
8545
|
+
if (!EXTERNAL_STRUKTURY_DANYCH_URL.test(xsdContent)) {
|
|
8546
|
+
return xsdContent;
|
|
8547
|
+
}
|
|
8548
|
+
const bazoweStrukturyPath = path6.join(
|
|
8549
|
+
locatePackageRoot(),
|
|
8550
|
+
"docs",
|
|
8551
|
+
"schemas",
|
|
8552
|
+
"FA",
|
|
8553
|
+
"bazowe",
|
|
8554
|
+
"StrukturyDanych_v10-0E.xsd"
|
|
8555
|
+
);
|
|
8556
|
+
const bazoweStrukturyUrl = pathToFileURL(bazoweStrukturyPath).href;
|
|
8557
|
+
const rewritten = xsdContent.replace(
|
|
8558
|
+
EXTERNAL_STRUKTURY_DANYCH_URL,
|
|
8559
|
+
`schemaLocation="${bazoweStrukturyUrl}"`
|
|
8560
|
+
);
|
|
8561
|
+
if (rewritten === xsdContent) {
|
|
8562
|
+
throw new Error(
|
|
8563
|
+
"FA XSD schemaLocation rewrite produced no replacement despite URL being present; regex likely out of sync with docs/schemas/FA/. Re-check after `yarn sync-schemas`."
|
|
8564
|
+
);
|
|
8565
|
+
}
|
|
8566
|
+
return rewritten;
|
|
8567
|
+
}
|
|
8568
|
+
function validateAgainstXsd(xml, xsdPath) {
|
|
8569
|
+
if (!libxmljs) {
|
|
8570
|
+
const loadSuffix = libxmljsLoadError ? ` (load failed: ${libxmljsLoadError.message})` : "";
|
|
8571
|
+
throw new Error(
|
|
8572
|
+
`${MISSING_LIBXMLJS_MESSAGE_PREFIX}${loadSuffix}; cannot run XSD validation. Install it as an optional peer dependency (e.g. \`yarn add -O libxmljs2\` or \`npm i -O libxmljs2\`).`
|
|
8573
|
+
);
|
|
8574
|
+
}
|
|
8575
|
+
const xsdDir = path6.dirname(xsdPath);
|
|
8576
|
+
const rawXsd = fs9.readFileSync(xsdPath, "utf8");
|
|
8577
|
+
const rewrittenXsd = rewriteSchemaLocations(rawXsd);
|
|
8578
|
+
const baseUrl = pathToFileURL(xsdDir + path6.sep).href;
|
|
8579
|
+
let schemaDoc;
|
|
8580
|
+
try {
|
|
8581
|
+
schemaDoc = libxmljs.parseXml(rewrittenXsd, { baseUrl });
|
|
8582
|
+
} catch (err) {
|
|
8583
|
+
return { valid: false, errors: [`XSD parse failed: ${err.message}`] };
|
|
8584
|
+
}
|
|
8585
|
+
let xmlDoc;
|
|
8586
|
+
try {
|
|
8587
|
+
xmlDoc = libxmljs.parseXml(xml);
|
|
8588
|
+
} catch (err) {
|
|
8589
|
+
return { valid: false, errors: [`XML parse failed: ${err.message}`] };
|
|
8590
|
+
}
|
|
8591
|
+
const valid = xmlDoc.validate(schemaDoc);
|
|
8592
|
+
const errors = valid ? [] : xmlDoc.validationErrors.map((err) => err.message.trim());
|
|
8593
|
+
return { valid, errors };
|
|
8594
|
+
}
|
|
8595
|
+
|
|
8596
|
+
// src/cli/commands/invoice-build.ts
|
|
8597
|
+
init_ksef_validation_error();
|
|
8598
|
+
init_ksef_xsd_validation_error();
|
|
8599
|
+
|
|
8600
|
+
// src/cli/commands/invoice-build-helpers.ts
|
|
8601
|
+
init_ksef_validation_error();
|
|
8602
|
+
init_ksef_xsd_validation_error();
|
|
8603
|
+
import * as fs10 from "fs";
|
|
8604
|
+
import * as path7 from "path";
|
|
8605
|
+
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
8606
|
+
|
|
8607
|
+
// src/cli/commands/invoice-build-templates/fa2.json
|
|
8608
|
+
var fa2_default = {
|
|
8609
|
+
Naglowek: {
|
|
8610
|
+
KodFormularza: { systemCode: "FA (2)", schemaVersion: "1-0E", value: "FA" },
|
|
8611
|
+
WariantFormularza: 2,
|
|
8612
|
+
DataWytworzeniaFa: "2026-04-18T00:00:00Z",
|
|
8613
|
+
SystemInfo: "ksef-client-ts"
|
|
8614
|
+
},
|
|
8615
|
+
Podmiot1: {
|
|
8616
|
+
DaneIdentyfikacyjne: { NIP: "1111111111", Nazwa: "Sample Seller" },
|
|
8617
|
+
Adres: { KodKraju: "PL", AdresL1: "ul. Przykladowa 1", AdresL2: "00-001 Warszawa" }
|
|
8618
|
+
},
|
|
8619
|
+
Podmiot2: {
|
|
8620
|
+
DaneIdentyfikacyjne: { NIP: "2222222222", Nazwa: "Sample Buyer" },
|
|
8621
|
+
Adres: { KodKraju: "PL", AdresL1: "ul. Klientowska 2", AdresL2: "00-002 Warszawa" },
|
|
8622
|
+
DaneKontaktowe: { Email: "buyer@example.com" }
|
|
8623
|
+
},
|
|
8624
|
+
Fa: {
|
|
8625
|
+
KodWaluty: "PLN",
|
|
8626
|
+
P_1: "2026-04-18",
|
|
8627
|
+
P_2: "FA/2026/0001",
|
|
8628
|
+
P_13_1: "100.00",
|
|
8629
|
+
P_14_1: "23.00",
|
|
8630
|
+
P_15: "123.00",
|
|
8631
|
+
Adnotacje: {
|
|
8632
|
+
P_16: "2",
|
|
8633
|
+
P_17: "2",
|
|
8634
|
+
P_18: "2",
|
|
8635
|
+
P_18A: "2",
|
|
8636
|
+
Zwolnienie: { P_19N: "1" },
|
|
8637
|
+
NoweSrodkiTransportu: { P_22N: "1" },
|
|
8638
|
+
P_23: "2",
|
|
8639
|
+
PMarzy: { P_PMarzyN: "1" }
|
|
8640
|
+
},
|
|
8641
|
+
RodzajFaktury: "VAT",
|
|
8642
|
+
FaWiersz: [
|
|
8643
|
+
{
|
|
8644
|
+
NrWierszaFa: 1,
|
|
8645
|
+
P_7: "Sample product",
|
|
8646
|
+
P_8A: "szt.",
|
|
8647
|
+
P_8B: "1.00",
|
|
8648
|
+
P_9A: "100.00",
|
|
8649
|
+
P_11: "100.00",
|
|
8650
|
+
P_12: "23"
|
|
8651
|
+
}
|
|
8652
|
+
]
|
|
8653
|
+
}
|
|
8654
|
+
};
|
|
8655
|
+
|
|
8656
|
+
// src/cli/commands/invoice-build-templates/fa3.json
|
|
8657
|
+
var fa3_default = {
|
|
8658
|
+
Naglowek: {
|
|
8659
|
+
KodFormularza: { systemCode: "FA (3)", schemaVersion: "1-0E", value: "FA" },
|
|
8660
|
+
WariantFormularza: 3,
|
|
8661
|
+
DataWytworzeniaFa: "2026-04-18T00:00:00Z",
|
|
8662
|
+
SystemInfo: "ksef-client-ts"
|
|
8663
|
+
},
|
|
8664
|
+
Podmiot1: {
|
|
8665
|
+
DaneIdentyfikacyjne: { NIP: "1111111111", Nazwa: "Sample Seller" },
|
|
8666
|
+
Adres: { KodKraju: "PL", AdresL1: "ul. Przykladowa 1", AdresL2: "00-001 Warszawa" },
|
|
8667
|
+
DaneKontaktowe: { Email: "seller@example.com" }
|
|
8668
|
+
},
|
|
8669
|
+
Podmiot2: {
|
|
8670
|
+
DaneIdentyfikacyjne: { NIP: "2222222222", Nazwa: "Sample Buyer" },
|
|
8671
|
+
Adres: { KodKraju: "PL", AdresL1: "ul. Klientowska 2", AdresL2: "00-002 Warszawa" },
|
|
8672
|
+
DaneKontaktowe: { Email: "buyer@example.com" },
|
|
8673
|
+
JST: "2",
|
|
8674
|
+
GV: "2"
|
|
8675
|
+
},
|
|
8676
|
+
Fa: {
|
|
8677
|
+
KodWaluty: "PLN",
|
|
8678
|
+
P_1: "2026-04-18",
|
|
8679
|
+
P_2: "FA/2026/0001",
|
|
8680
|
+
P_13_1: "100.00",
|
|
8681
|
+
P_14_1: "23.00",
|
|
8682
|
+
P_15: "123.00",
|
|
8683
|
+
Adnotacje: {
|
|
8684
|
+
P_16: "2",
|
|
8685
|
+
P_17: "2",
|
|
8686
|
+
P_18: "2",
|
|
8687
|
+
P_18A: "2",
|
|
8688
|
+
Zwolnienie: { P_19N: "1" },
|
|
8689
|
+
NoweSrodkiTransportu: { P_22N: "1" },
|
|
8690
|
+
P_23: "2",
|
|
8691
|
+
PMarzy: { P_PMarzyN: "1" }
|
|
8692
|
+
},
|
|
8693
|
+
RodzajFaktury: "VAT",
|
|
8694
|
+
FaWiersz: [
|
|
8695
|
+
{
|
|
8696
|
+
NrWierszaFa: 1,
|
|
8697
|
+
P_7: "Sample product",
|
|
8698
|
+
P_8A: "szt.",
|
|
8699
|
+
P_8B: "1.00",
|
|
8700
|
+
P_9A: "100.00",
|
|
8701
|
+
P_11: "100.00",
|
|
8702
|
+
P_12: "23"
|
|
8703
|
+
}
|
|
8704
|
+
]
|
|
8705
|
+
}
|
|
8706
|
+
};
|
|
8707
|
+
|
|
8708
|
+
// src/cli/commands/invoice-build-templates/pef.json
|
|
8709
|
+
var pef_default = {
|
|
8710
|
+
Invoice: {
|
|
8711
|
+
"cbc:CustomizationID": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
|
|
8712
|
+
"cbc:ProfileID": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
|
|
8713
|
+
"cbc:ID": "INV/2026/0001",
|
|
8714
|
+
"cbc:IssueDate": "2026-04-18",
|
|
8715
|
+
"cbc:DueDate": "2026-05-18",
|
|
8716
|
+
"cbc:InvoiceTypeCode": "380",
|
|
8717
|
+
"cbc:DocumentCurrencyCode": "PLN",
|
|
8718
|
+
"cac:AccountingSupplierParty": {
|
|
8719
|
+
"cac:Party": {
|
|
8720
|
+
"cac:PartyName": { "cbc:Name": "Sample Seller" },
|
|
8721
|
+
"cac:PostalAddress": {
|
|
8722
|
+
"cbc:StreetName": "ul. Przykladowa 1",
|
|
8723
|
+
"cbc:CityName": "Warszawa",
|
|
8724
|
+
"cbc:PostalZone": "00-001",
|
|
8725
|
+
"cac:Country": { "cbc:IdentificationCode": "PL" }
|
|
8726
|
+
},
|
|
8727
|
+
"cac:PartyTaxScheme": {
|
|
8728
|
+
"cbc:CompanyID": "PL1111111111",
|
|
8729
|
+
"cac:TaxScheme": { "cbc:ID": "VAT" }
|
|
8730
|
+
},
|
|
8731
|
+
"cac:PartyLegalEntity": {
|
|
8732
|
+
"cbc:RegistrationName": "Sample Seller",
|
|
8733
|
+
"cbc:CompanyID": "1111111111"
|
|
8734
|
+
}
|
|
8735
|
+
}
|
|
8736
|
+
},
|
|
8737
|
+
"cac:AccountingCustomerParty": {
|
|
8738
|
+
"cac:Party": {
|
|
8739
|
+
"cac:PartyName": { "cbc:Name": "Sample Buyer" },
|
|
8740
|
+
"cac:PostalAddress": {
|
|
8741
|
+
"cbc:StreetName": "ul. Klientowska 2",
|
|
8742
|
+
"cbc:CityName": "Warszawa",
|
|
8743
|
+
"cbc:PostalZone": "00-002",
|
|
8744
|
+
"cac:Country": { "cbc:IdentificationCode": "PL" }
|
|
8745
|
+
},
|
|
8746
|
+
"cac:PartyLegalEntity": {
|
|
8747
|
+
"cbc:RegistrationName": "Sample Buyer",
|
|
8748
|
+
"cbc:CompanyID": "2222222222"
|
|
8749
|
+
}
|
|
8750
|
+
}
|
|
8751
|
+
},
|
|
8752
|
+
"cac:TaxTotal": [
|
|
8753
|
+
{ "cbc:TaxAmount": { "@_currencyID": "PLN", "#text": "23.00" } }
|
|
8754
|
+
],
|
|
8755
|
+
"cac:LegalMonetaryTotal": {
|
|
8756
|
+
"cbc:LineExtensionAmount": { "@_currencyID": "PLN", "#text": "100.00" },
|
|
8757
|
+
"cbc:TaxExclusiveAmount": { "@_currencyID": "PLN", "#text": "100.00" },
|
|
8758
|
+
"cbc:TaxInclusiveAmount": { "@_currencyID": "PLN", "#text": "123.00" },
|
|
8759
|
+
"cbc:PayableAmount": { "@_currencyID": "PLN", "#text": "123.00" }
|
|
8760
|
+
},
|
|
8761
|
+
"cac:InvoiceLine": [
|
|
8762
|
+
{
|
|
8763
|
+
"cbc:ID": "1",
|
|
8764
|
+
"cbc:InvoicedQuantity": { "@_unitCode": "C62", "#text": "1" },
|
|
8765
|
+
"cbc:LineExtensionAmount": { "@_currencyID": "PLN", "#text": "100.00" },
|
|
8766
|
+
"cac:Item": { "cbc:Name": "Sample product" },
|
|
8767
|
+
"cac:Price": {
|
|
8768
|
+
"cbc:PriceAmount": { "@_currencyID": "PLN", "#text": "100.00" }
|
|
8769
|
+
}
|
|
8770
|
+
}
|
|
8771
|
+
]
|
|
8772
|
+
}
|
|
8773
|
+
};
|
|
8774
|
+
|
|
8775
|
+
// src/cli/commands/invoice-build-templates/pef-kor.json
|
|
8776
|
+
var pef_kor_default = {
|
|
8777
|
+
CreditNote: {
|
|
8778
|
+
"cbc:CustomizationID": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
|
|
8779
|
+
"cbc:ProfileID": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
|
|
8780
|
+
"cbc:ID": "COR/2026/0001",
|
|
8781
|
+
"cbc:IssueDate": "2026-04-18",
|
|
8782
|
+
"cbc:CreditNoteTypeCode": "381",
|
|
8783
|
+
"cbc:DocumentCurrencyCode": "PLN",
|
|
8784
|
+
"cac:BillingReference": {
|
|
8785
|
+
"cac:InvoiceDocumentReference": {
|
|
8786
|
+
"cbc:ID": "INV/2026/0001",
|
|
8787
|
+
"cbc:IssueDate": "2026-03-01"
|
|
8788
|
+
}
|
|
8789
|
+
},
|
|
8790
|
+
"cac:AccountingSupplierParty": {
|
|
8791
|
+
"cac:Party": {
|
|
8792
|
+
"cac:PartyName": { "cbc:Name": "Sample Seller" },
|
|
8793
|
+
"cac:PostalAddress": {
|
|
8794
|
+
"cbc:StreetName": "ul. Przykladowa 1",
|
|
8795
|
+
"cbc:CityName": "Warszawa",
|
|
8796
|
+
"cbc:PostalZone": "00-001",
|
|
8797
|
+
"cac:Country": { "cbc:IdentificationCode": "PL" }
|
|
8798
|
+
},
|
|
8799
|
+
"cac:PartyTaxScheme": {
|
|
8800
|
+
"cbc:CompanyID": "PL1111111111",
|
|
8801
|
+
"cac:TaxScheme": { "cbc:ID": "VAT" }
|
|
8802
|
+
},
|
|
8803
|
+
"cac:PartyLegalEntity": {
|
|
8804
|
+
"cbc:RegistrationName": "Sample Seller",
|
|
8805
|
+
"cbc:CompanyID": "1111111111"
|
|
8806
|
+
}
|
|
8807
|
+
}
|
|
8808
|
+
},
|
|
8809
|
+
"cac:AccountingCustomerParty": {
|
|
8810
|
+
"cac:Party": {
|
|
8811
|
+
"cac:PartyName": { "cbc:Name": "Sample Buyer" },
|
|
8812
|
+
"cac:PostalAddress": {
|
|
8813
|
+
"cbc:StreetName": "ul. Klientowska 2",
|
|
8814
|
+
"cbc:CityName": "Warszawa",
|
|
8815
|
+
"cbc:PostalZone": "00-002",
|
|
8816
|
+
"cac:Country": { "cbc:IdentificationCode": "PL" }
|
|
8817
|
+
},
|
|
8818
|
+
"cac:PartyLegalEntity": {
|
|
8819
|
+
"cbc:RegistrationName": "Sample Buyer",
|
|
8820
|
+
"cbc:CompanyID": "2222222222"
|
|
8821
|
+
}
|
|
8822
|
+
}
|
|
8823
|
+
},
|
|
8824
|
+
"cac:TaxTotal": [
|
|
8825
|
+
{ "cbc:TaxAmount": { "@_currencyID": "PLN", "#text": "-23.00" } }
|
|
8826
|
+
],
|
|
8827
|
+
"cac:LegalMonetaryTotal": {
|
|
8828
|
+
"cbc:LineExtensionAmount": { "@_currencyID": "PLN", "#text": "-100.00" },
|
|
8829
|
+
"cbc:TaxExclusiveAmount": { "@_currencyID": "PLN", "#text": "-100.00" },
|
|
8830
|
+
"cbc:TaxInclusiveAmount": { "@_currencyID": "PLN", "#text": "-123.00" },
|
|
8831
|
+
"cbc:PayableAmount": { "@_currencyID": "PLN", "#text": "-123.00" }
|
|
8832
|
+
},
|
|
8833
|
+
"cac:CreditNoteLine": [
|
|
8834
|
+
{
|
|
8835
|
+
"cbc:ID": "1",
|
|
8836
|
+
"cbc:CreditedQuantity": { "@_unitCode": "C62", "#text": "1" },
|
|
8837
|
+
"cbc:LineExtensionAmount": { "@_currencyID": "PLN", "#text": "-100.00" },
|
|
8838
|
+
"cac:Item": { "cbc:Name": "Sample product (corrected)" },
|
|
8839
|
+
"cac:Price": {
|
|
8840
|
+
"cbc:PriceAmount": { "@_currencyID": "PLN", "#text": "100.00" }
|
|
8841
|
+
}
|
|
8842
|
+
}
|
|
8843
|
+
]
|
|
8844
|
+
}
|
|
8845
|
+
};
|
|
8846
|
+
|
|
8847
|
+
// src/cli/commands/invoice-build-helpers.ts
|
|
8848
|
+
var VALID_SCHEMAS = ["FA2", "FA3", "PEF", "PEF_KOR"];
|
|
8849
|
+
var VALID_FORMATS = ["auto", "json", "yaml"];
|
|
8850
|
+
var TEMPLATES = {
|
|
8851
|
+
FA2: fa2_default,
|
|
8852
|
+
FA3: fa3_default,
|
|
8853
|
+
PEF: pef_default,
|
|
8854
|
+
PEF_KOR: pef_kor_default
|
|
8855
|
+
};
|
|
8856
|
+
async function readInput(input, format) {
|
|
8857
|
+
const raw = input === "-" ? await readStdin2() : fs10.readFileSync(input, "utf-8");
|
|
8858
|
+
const resolvedFormat = format === "auto" ? inferFormatFromPath(input) : format;
|
|
8859
|
+
return { raw, format: resolvedFormat };
|
|
8860
|
+
}
|
|
8861
|
+
async function readStdin2() {
|
|
8862
|
+
const chunks = [];
|
|
8863
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
8864
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
8865
|
+
}
|
|
8866
|
+
function inferFormatFromPath(input) {
|
|
8867
|
+
if (input === "-") return "json";
|
|
8868
|
+
const ext = path7.extname(input).toLowerCase();
|
|
8869
|
+
if (ext === ".yml" || ext === ".yaml") return "yaml";
|
|
8870
|
+
return "json";
|
|
8871
|
+
}
|
|
8872
|
+
function parseInput(raw, format) {
|
|
8873
|
+
if (format === "yaml") return parseYaml(raw);
|
|
8874
|
+
return JSON.parse(raw);
|
|
8875
|
+
}
|
|
8876
|
+
function inferSchema2(parsed) {
|
|
8877
|
+
if (typeof parsed !== "object" || parsed === null) return "FA3";
|
|
8878
|
+
const obj = parsed;
|
|
8879
|
+
if ("Invoice" in obj) return "PEF";
|
|
8880
|
+
if ("CreditNote" in obj) return "PEF_KOR";
|
|
8881
|
+
const naglowek = obj.Naglowek;
|
|
8882
|
+
if (typeof naglowek === "object" && naglowek !== null) {
|
|
8883
|
+
const formCode = naglowek.KodFormularza;
|
|
8884
|
+
if (typeof formCode === "object" && formCode !== null) {
|
|
8885
|
+
const systemCode = formCode.systemCode;
|
|
8886
|
+
if (systemCode === "FA (2)") return "FA2";
|
|
8887
|
+
}
|
|
8888
|
+
}
|
|
8889
|
+
return "FA3";
|
|
8890
|
+
}
|
|
8891
|
+
function writeOutput(xml, output) {
|
|
8892
|
+
if (!output || output === "-") {
|
|
8893
|
+
process.stdout.write(xml);
|
|
8894
|
+
return;
|
|
8895
|
+
}
|
|
8896
|
+
fs10.writeFileSync(output, xml);
|
|
8897
|
+
}
|
|
8898
|
+
function emitTemplate(schema) {
|
|
8899
|
+
const id = schema.toUpperCase();
|
|
8900
|
+
const template = TEMPLATES[id];
|
|
8901
|
+
if (!template) {
|
|
8902
|
+
throw KSeFValidationError.fromField(
|
|
8903
|
+
"template",
|
|
8904
|
+
`Template must be one of: ${VALID_SCHEMAS.join(", ")}.`
|
|
8905
|
+
);
|
|
8906
|
+
}
|
|
8907
|
+
process.stdout.write(JSON.stringify(template, null, 2) + "\n");
|
|
8908
|
+
}
|
|
8909
|
+
function buildDrySummary(parsed, schema) {
|
|
8910
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
8911
|
+
return { schema, sections: [] };
|
|
8912
|
+
}
|
|
8913
|
+
const obj = parsed;
|
|
8914
|
+
const sections = Object.keys(obj);
|
|
8915
|
+
const summary = { schema, sections };
|
|
8916
|
+
if (schema === "FA2" || schema === "FA3") {
|
|
8917
|
+
const fa = obj.Fa;
|
|
8918
|
+
if (typeof fa === "object" && fa !== null) {
|
|
8919
|
+
const p2 = fa.P_2;
|
|
8920
|
+
if (typeof p2 === "string" || typeof p2 === "number") {
|
|
8921
|
+
summary.invoiceNumber = String(p2);
|
|
8922
|
+
}
|
|
8923
|
+
const wiersz = fa.FaWiersz;
|
|
8924
|
+
if (Array.isArray(wiersz)) summary.lineCount = wiersz.length;
|
|
8925
|
+
else if (typeof wiersz === "object" && wiersz !== null) summary.lineCount = 1;
|
|
8926
|
+
}
|
|
8927
|
+
} else {
|
|
8928
|
+
const root = schema === "PEF" ? obj.Invoice : obj.CreditNote;
|
|
8929
|
+
if (root) {
|
|
8930
|
+
const id = root["cbc:ID"];
|
|
8931
|
+
if (typeof id === "string" || typeof id === "number") {
|
|
8932
|
+
summary.invoiceNumber = String(id);
|
|
8933
|
+
}
|
|
8934
|
+
const lines = schema === "PEF" ? root["cac:InvoiceLine"] : root["cac:CreditNoteLine"];
|
|
8935
|
+
if (Array.isArray(lines)) summary.lineCount = lines.length;
|
|
8936
|
+
else if (typeof lines === "object" && lines !== null) summary.lineCount = 1;
|
|
8937
|
+
}
|
|
8938
|
+
}
|
|
8939
|
+
return summary;
|
|
8940
|
+
}
|
|
8941
|
+
function mapBuildExitCode(error) {
|
|
8942
|
+
if (error instanceof SyntaxError) return 2;
|
|
8943
|
+
if (error instanceof YAMLParseError) return 2;
|
|
8944
|
+
if (error instanceof KSeFXsdValidationError) return 4;
|
|
8945
|
+
if (isMissingLibxmljsError(error)) return 4;
|
|
8946
|
+
if (error instanceof KSeFValidationError) return 3;
|
|
8947
|
+
if (typeof error === "object" && error !== null && "code" in error) {
|
|
8948
|
+
const code = error.code;
|
|
8949
|
+
if (typeof code === "string" && IO_ERRNO_CODES.has(code)) {
|
|
8950
|
+
return 5;
|
|
8951
|
+
}
|
|
8952
|
+
}
|
|
8953
|
+
return void 0;
|
|
8954
|
+
}
|
|
8955
|
+
var IO_ERRNO_CODES = /* @__PURE__ */ new Set([
|
|
8956
|
+
"ENOENT",
|
|
8957
|
+
"EACCES",
|
|
8958
|
+
"EPERM",
|
|
8959
|
+
"EISDIR",
|
|
8960
|
+
"ENOTDIR",
|
|
8961
|
+
"ENOSPC",
|
|
8962
|
+
"EROFS",
|
|
8963
|
+
"EMFILE",
|
|
8964
|
+
"ENFILE",
|
|
8965
|
+
"EIO",
|
|
8966
|
+
"EDQUOT",
|
|
8967
|
+
"EBADF",
|
|
8968
|
+
"EEXIST",
|
|
8969
|
+
"ENAMETOOLONG",
|
|
8970
|
+
"ELOOP",
|
|
8971
|
+
"ETXTBSY"
|
|
8972
|
+
]);
|
|
8973
|
+
|
|
8974
|
+
// src/cli/commands/invoice-build.ts
|
|
8975
|
+
var invoiceBuild = defineCommand5({
|
|
8976
|
+
meta: {
|
|
8977
|
+
name: "build",
|
|
8978
|
+
description: "Build invoice XML from structured JSON/YAML input"
|
|
8979
|
+
},
|
|
8980
|
+
args: {
|
|
8981
|
+
input: {
|
|
8982
|
+
type: "positional",
|
|
8983
|
+
required: false,
|
|
8984
|
+
description: 'Input file path, or "-" to read from stdin'
|
|
8985
|
+
},
|
|
8986
|
+
schema: {
|
|
8987
|
+
type: "string",
|
|
8988
|
+
description: "Explicit schema: FA2|FA3|PEF|PEF_KOR (default: inferred from input)"
|
|
8989
|
+
},
|
|
8990
|
+
output: {
|
|
8991
|
+
type: "string",
|
|
8992
|
+
alias: "o",
|
|
8993
|
+
description: 'Output file path; omit or "-" for stdout'
|
|
8994
|
+
},
|
|
8995
|
+
pretty: {
|
|
8996
|
+
type: "boolean",
|
|
8997
|
+
description: "Pretty-print XML with 2-space indentation"
|
|
8998
|
+
},
|
|
8999
|
+
validate: {
|
|
9000
|
+
type: "boolean",
|
|
9001
|
+
description: "Run schema validation on the serialized XML"
|
|
9002
|
+
},
|
|
9003
|
+
"validate-xsd": {
|
|
9004
|
+
type: "boolean",
|
|
9005
|
+
description: "Run XSD validation on the serialized XML (requires libxmljs2)"
|
|
9006
|
+
},
|
|
9007
|
+
"dry-run": {
|
|
9008
|
+
type: "boolean",
|
|
9009
|
+
description: "Parse and summarise input; do not emit XML"
|
|
9010
|
+
},
|
|
9011
|
+
format: {
|
|
9012
|
+
type: "string",
|
|
9013
|
+
description: "Input format: json|yaml (default: infer from file extension)"
|
|
9014
|
+
},
|
|
9015
|
+
template: {
|
|
9016
|
+
type: "string",
|
|
9017
|
+
description: "Print a skeleton JSON for FA2|FA3|PEF|PEF_KOR and exit"
|
|
9018
|
+
},
|
|
9019
|
+
json: {
|
|
9020
|
+
type: "boolean",
|
|
9021
|
+
description: "Machine-readable output (for --dry-run / error messages)"
|
|
9022
|
+
}
|
|
9023
|
+
},
|
|
9024
|
+
async run({ args }) {
|
|
9025
|
+
await withErrorHandler(
|
|
9026
|
+
async () => {
|
|
9027
|
+
if (args.template) {
|
|
9028
|
+
emitTemplate(args.template);
|
|
9029
|
+
return;
|
|
9030
|
+
}
|
|
9031
|
+
if (!args.input) {
|
|
9032
|
+
throw new Error(
|
|
9033
|
+
'Input file required. Provide a path or use "-" to read from stdin.'
|
|
9034
|
+
);
|
|
9035
|
+
}
|
|
9036
|
+
const formatRaw = args.format;
|
|
9037
|
+
if (formatRaw && !VALID_FORMATS.includes(formatRaw)) {
|
|
9038
|
+
throw KSeFValidationError.fromField(
|
|
9039
|
+
"format",
|
|
9040
|
+
`Format must be one of: ${VALID_FORMATS.join(", ")}.`
|
|
9041
|
+
);
|
|
9042
|
+
}
|
|
9043
|
+
const formatOption = formatRaw ?? "auto";
|
|
9044
|
+
const { raw, format } = await readInput(args.input, formatOption);
|
|
9045
|
+
const parsed = parseInput(raw, format);
|
|
9046
|
+
const explicitSchemaRaw = args.schema;
|
|
9047
|
+
if (explicitSchemaRaw && !VALID_SCHEMAS.includes(explicitSchemaRaw)) {
|
|
9048
|
+
throw KSeFValidationError.fromField(
|
|
9049
|
+
"schema",
|
|
9050
|
+
`Schema must be one of: ${VALID_SCHEMAS.join(", ")}.`
|
|
9051
|
+
);
|
|
9052
|
+
}
|
|
9053
|
+
const explicitSchema = explicitSchemaRaw;
|
|
9054
|
+
const schema = explicitSchema ?? inferSchema2(parsed);
|
|
9055
|
+
if (args["dry-run"]) {
|
|
9056
|
+
const summary = buildDrySummary(parsed, schema);
|
|
9057
|
+
if (args.json) {
|
|
9058
|
+
outputResult(summary, { json: true });
|
|
9059
|
+
} else {
|
|
9060
|
+
consola10.info(`Schema: ${summary.schema}${explicitSchema ? "" : " (inferred)"}`);
|
|
9061
|
+
consola10.info(`Invoice #: ${summary.invoiceNumber ?? "(not set)"}`);
|
|
9062
|
+
consola10.info(`Sections: ${summary.sections.join(", ")}`);
|
|
9063
|
+
if (summary.lineCount !== void 0) {
|
|
9064
|
+
consola10.info(`Line count: ${summary.lineCount}`);
|
|
9065
|
+
}
|
|
9066
|
+
}
|
|
9067
|
+
return;
|
|
9068
|
+
}
|
|
9069
|
+
const xml = serializeInvoiceXml(parsed, {
|
|
9070
|
+
schema,
|
|
9071
|
+
pretty: Boolean(args.pretty)
|
|
9072
|
+
});
|
|
9073
|
+
const xmlStr = args.validate || args["validate-xsd"] ? xml.toString("utf-8") : "";
|
|
9074
|
+
if (args.validate) {
|
|
9075
|
+
const result = await validate(xmlStr);
|
|
9076
|
+
if (!result.valid) {
|
|
9077
|
+
throw KSeFValidationError.fromMessages(result.errors.map((e) => e.message));
|
|
9078
|
+
}
|
|
9079
|
+
}
|
|
9080
|
+
if (args["validate-xsd"]) {
|
|
9081
|
+
const xsdPath = resolveXsdFor(schema);
|
|
9082
|
+
const xsdResult = validateAgainstXsd(xmlStr, xsdPath);
|
|
9083
|
+
if (!xsdResult.valid) {
|
|
9084
|
+
throw new KSeFXsdValidationError(xsdPath, xsdResult.errors);
|
|
9085
|
+
}
|
|
9086
|
+
}
|
|
9087
|
+
writeOutput(xml, args.output);
|
|
9088
|
+
},
|
|
9089
|
+
{ json: Boolean(args.json), exitCode: mapBuildExitCode }
|
|
9090
|
+
);
|
|
9091
|
+
}
|
|
9092
|
+
});
|
|
9093
|
+
|
|
7723
9094
|
// src/cli/commands/invoice.ts
|
|
7724
9095
|
init_invoice_validator();
|
|
7725
9096
|
init_ksef_validation_error();
|
|
@@ -7777,7 +9148,7 @@ var QUERY_FILTER_ARGS = {
|
|
|
7777
9148
|
amountType: { type: "string", description: "Amount type: Brutto|Netto|Vat (default: Brutto)" },
|
|
7778
9149
|
currency: { type: "string", description: "Currency code (e.g. PLN, EUR)" }
|
|
7779
9150
|
};
|
|
7780
|
-
var send =
|
|
9151
|
+
var send = defineCommand6({
|
|
7781
9152
|
meta: { name: "send", description: "Send invoice(s) \u2014 single XML file or directory for batch" },
|
|
7782
9153
|
args: {
|
|
7783
9154
|
path: { type: "positional", description: "Path to XML file, directory of XMLs, or ZIP for batch", required: true },
|
|
@@ -7812,13 +9183,13 @@ var send = defineCommand5({
|
|
|
7812
9183
|
}
|
|
7813
9184
|
formCode = resolved;
|
|
7814
9185
|
}
|
|
7815
|
-
if (!
|
|
9186
|
+
if (!fs11.existsSync(filePath)) {
|
|
7816
9187
|
throw new Error(`Path not found: ${filePath}`);
|
|
7817
9188
|
}
|
|
7818
|
-
const stat =
|
|
9189
|
+
const stat = fs11.statSync(filePath);
|
|
7819
9190
|
if (args.stream) {
|
|
7820
9191
|
if (args.validate) {
|
|
7821
|
-
|
|
9192
|
+
consola11.warn("--validate is not supported in stream mode. Run `ksef invoice validate <path>` before sending, or remove --stream.");
|
|
7822
9193
|
}
|
|
7823
9194
|
if (!filePath.endsWith(".zip") || stat.isDirectory()) {
|
|
7824
9195
|
throw new Error("--stream requires a .zip file path.");
|
|
@@ -7831,8 +9202,8 @@ var send = defineCommand5({
|
|
|
7831
9202
|
}
|
|
7832
9203
|
const { uploadBatchStream: uploadBatchStream2 } = await Promise.resolve().then(() => (init_batch_session_workflow(), batch_session_workflow_exports));
|
|
7833
9204
|
const zipSize = stat.size;
|
|
7834
|
-
const zipStreamFactory = () => Readable.toWeb(
|
|
7835
|
-
if (!args.json)
|
|
9205
|
+
const zipStreamFactory = () => Readable.toWeb(fs11.createReadStream(filePath));
|
|
9206
|
+
if (!args.json) consola11.start(`Sending batch via stream (${(zipSize / 1e6).toFixed(1)} MB)...`);
|
|
7836
9207
|
const result = await uploadBatchStream2(client, zipStreamFactory, zipSize, {
|
|
7837
9208
|
formCode,
|
|
7838
9209
|
pollOptions: { intervalMs: 3e3 },
|
|
@@ -7846,7 +9217,7 @@ var send = defineCommand5({
|
|
|
7846
9217
|
return;
|
|
7847
9218
|
}
|
|
7848
9219
|
if (stat.isDirectory()) {
|
|
7849
|
-
const xmlFiles =
|
|
9220
|
+
const xmlFiles = fs11.readdirSync(filePath).filter((f) => f.endsWith(".xml")).map((f) => path8.join(filePath, f));
|
|
7850
9221
|
if (xmlFiles.length === 0) {
|
|
7851
9222
|
throw new Error(`No XML files found in ${filePath}`);
|
|
7852
9223
|
}
|
|
@@ -7856,14 +9227,14 @@ var send = defineCommand5({
|
|
|
7856
9227
|
if (!validateFormCodeForSession(formCode, "batch")) {
|
|
7857
9228
|
throw new Error(`Document type "${formCode.systemCode}" is not supported in batch sessions. PEF/PEF_KOR require online sessions.`);
|
|
7858
9229
|
}
|
|
7859
|
-
const fileBuffers = xmlFiles.map((file) => ({ file, content:
|
|
9230
|
+
const fileBuffers = xmlFiles.map((file) => ({ file, content: fs11.readFileSync(file) }));
|
|
7860
9231
|
if (args.validate) {
|
|
7861
9232
|
const { validateBatch: validateBatch2, batchValidationDetails: batchValidationDetails2 } = await Promise.resolve().then(() => (init_invoice_validator(), invoice_validator_exports));
|
|
7862
9233
|
const invoicesToValidate = fileBuffers.map(({ file, content }) => ({
|
|
7863
|
-
fileName:
|
|
9234
|
+
fileName: path8.basename(file),
|
|
7864
9235
|
xml: content.toString("utf-8")
|
|
7865
9236
|
}));
|
|
7866
|
-
if (!args.json)
|
|
9237
|
+
if (!args.json) consola11.start(`Validating ${invoicesToValidate.length} invoices...`);
|
|
7867
9238
|
const batchResult = await validateBatch2(invoicesToValidate);
|
|
7868
9239
|
if (!batchResult.valid) {
|
|
7869
9240
|
const invalidCount = batchResult.results.filter((r) => !r.result.valid).length;
|
|
@@ -7872,9 +9243,9 @@ var send = defineCommand5({
|
|
|
7872
9243
|
batchValidationDetails2(batchResult)
|
|
7873
9244
|
);
|
|
7874
9245
|
}
|
|
7875
|
-
if (!args.json)
|
|
9246
|
+
if (!args.json) consola11.success(`All ${xmlFiles.length} invoices valid.`);
|
|
7876
9247
|
}
|
|
7877
|
-
if (!args.json)
|
|
9248
|
+
if (!args.json) consola11.start(`Sending ${xmlFiles.length} invoices via batch session...`);
|
|
7878
9249
|
await client.crypto.init();
|
|
7879
9250
|
const encryptionData = client.crypto.getEncryptionData();
|
|
7880
9251
|
const parts = fileBuffers.map(({ content }, i) => {
|
|
@@ -7913,7 +9284,7 @@ var send = defineCommand5({
|
|
|
7913
9284
|
if (!ref) {
|
|
7914
9285
|
throw new Error("No active online session. Run `ksef session open` or provide --session-ref.");
|
|
7915
9286
|
}
|
|
7916
|
-
const xmlContent =
|
|
9287
|
+
const xmlContent = fs11.readFileSync(filePath);
|
|
7917
9288
|
if (args.validate) {
|
|
7918
9289
|
const xmlStr = xmlContent.toString("utf-8");
|
|
7919
9290
|
const validationResult = await validate(xmlStr);
|
|
@@ -7923,9 +9294,9 @@ var send = defineCommand5({
|
|
|
7923
9294
|
validationResult.errors.map((e) => ({ field: e.path, message: e.message }))
|
|
7924
9295
|
);
|
|
7925
9296
|
}
|
|
7926
|
-
if (!args.json)
|
|
9297
|
+
if (!args.json) consola11.success("Validation passed.");
|
|
7927
9298
|
}
|
|
7928
|
-
if (!args.json)
|
|
9299
|
+
if (!args.json) consola11.start("Sending invoice...");
|
|
7929
9300
|
await client.crypto.init();
|
|
7930
9301
|
const storedEnc = loadEncryptionData();
|
|
7931
9302
|
if (!storedEnc) {
|
|
@@ -7951,7 +9322,7 @@ var send = defineCommand5({
|
|
|
7951
9322
|
}, { json: Boolean(args.json) });
|
|
7952
9323
|
}
|
|
7953
9324
|
});
|
|
7954
|
-
var get =
|
|
9325
|
+
var get = defineCommand6({
|
|
7955
9326
|
meta: { name: "get", description: "Download invoice by KSeF number" },
|
|
7956
9327
|
args: {
|
|
7957
9328
|
ksefNumber: { type: "positional", description: "KSeF invoice number", required: true },
|
|
@@ -7971,7 +9342,7 @@ var get = defineCommand5({
|
|
|
7971
9342
|
return;
|
|
7972
9343
|
}
|
|
7973
9344
|
if (args.o) {
|
|
7974
|
-
|
|
9345
|
+
fs11.writeFileSync(args.o, xml, "utf-8");
|
|
7975
9346
|
outputSuccess(`Invoice saved to ${args.o}`);
|
|
7976
9347
|
} else {
|
|
7977
9348
|
console.log(xml);
|
|
@@ -7979,7 +9350,7 @@ var get = defineCommand5({
|
|
|
7979
9350
|
}, { json: Boolean(args.json) });
|
|
7980
9351
|
}
|
|
7981
9352
|
});
|
|
7982
|
-
var query =
|
|
9353
|
+
var query = defineCommand6({
|
|
7983
9354
|
meta: { name: "query", description: "Query invoice metadata" },
|
|
7984
9355
|
args: {
|
|
7985
9356
|
...QUERY_FILTER_ARGS,
|
|
@@ -8008,7 +9379,7 @@ var query = defineCommand5({
|
|
|
8008
9379
|
return;
|
|
8009
9380
|
}
|
|
8010
9381
|
if (result.invoices.length === 0) {
|
|
8011
|
-
|
|
9382
|
+
consola11.info("No invoices found matching the criteria.");
|
|
8012
9383
|
return;
|
|
8013
9384
|
}
|
|
8014
9385
|
outputTable(
|
|
@@ -8031,12 +9402,12 @@ var query = defineCommand5({
|
|
|
8031
9402
|
{ json: false }
|
|
8032
9403
|
);
|
|
8033
9404
|
if (result.hasMore) {
|
|
8034
|
-
|
|
9405
|
+
consola11.info("More results available. Use --page to fetch the next page.");
|
|
8035
9406
|
}
|
|
8036
9407
|
}, { json: Boolean(args.json) });
|
|
8037
9408
|
}
|
|
8038
9409
|
});
|
|
8039
|
-
var exportCmd =
|
|
9410
|
+
var exportCmd = defineCommand6({
|
|
8040
9411
|
meta: { name: "export", description: "Start invoice export" },
|
|
8041
9412
|
args: {
|
|
8042
9413
|
...QUERY_FILTER_ARGS,
|
|
@@ -8051,7 +9422,7 @@ var exportCmd = defineCommand5({
|
|
|
8051
9422
|
return withErrorHandler(async () => {
|
|
8052
9423
|
const globalOpts = getGlobalOpts4(args);
|
|
8053
9424
|
const { client } = await requireSession(globalOpts);
|
|
8054
|
-
if (!args.json)
|
|
9425
|
+
if (!args.json) consola11.start("Starting invoice export...");
|
|
8055
9426
|
await client.crypto.init();
|
|
8056
9427
|
const encryptionData = client.crypto.getEncryptionData();
|
|
8057
9428
|
const filters = buildQueryFilters(args);
|
|
@@ -8062,12 +9433,12 @@ var exportCmd = defineCommand5({
|
|
|
8062
9433
|
outputResult(result, { json: true });
|
|
8063
9434
|
} else {
|
|
8064
9435
|
outputSuccess(`Export started. Ref: ${result.referenceNumber}`);
|
|
8065
|
-
|
|
9436
|
+
consola11.info("Check status with: ksef invoice export-status " + result.referenceNumber);
|
|
8066
9437
|
}
|
|
8067
9438
|
}, { json: Boolean(args.json) });
|
|
8068
9439
|
}
|
|
8069
9440
|
});
|
|
8070
|
-
var exportStatus =
|
|
9441
|
+
var exportStatus = defineCommand6({
|
|
8071
9442
|
meta: { name: "export-status", description: "Check invoice export status" },
|
|
8072
9443
|
args: {
|
|
8073
9444
|
ref: { type: "positional", description: "Export reference number", required: true },
|
|
@@ -8085,15 +9456,15 @@ var exportStatus = defineCommand5({
|
|
|
8085
9456
|
outputResult(result, { json: true });
|
|
8086
9457
|
return;
|
|
8087
9458
|
}
|
|
8088
|
-
|
|
9459
|
+
consola11.info(`Status: ${result.status.code} \u2014 ${result.status.description}`);
|
|
8089
9460
|
if (result.completedDate) {
|
|
8090
|
-
|
|
9461
|
+
consola11.info(`Completed: ${result.completedDate}`);
|
|
8091
9462
|
}
|
|
8092
9463
|
if (result.packageExpirationDate) {
|
|
8093
|
-
|
|
9464
|
+
consola11.info(`Package expires: ${result.packageExpirationDate}`);
|
|
8094
9465
|
}
|
|
8095
9466
|
if (result.package) {
|
|
8096
|
-
|
|
9467
|
+
consola11.info(`Invoices: ${result.package.invoiceCount}, Size: ${result.package.size} bytes`);
|
|
8097
9468
|
if (result.package.parts.length > 0) {
|
|
8098
9469
|
outputTable(
|
|
8099
9470
|
result.package.parts.map((p) => ({
|
|
@@ -8118,7 +9489,7 @@ var exportStatus = defineCommand5({
|
|
|
8118
9489
|
}
|
|
8119
9490
|
});
|
|
8120
9491
|
var VALID_SCHEMA_TYPES = SCHEMA_TYPES;
|
|
8121
|
-
var validateCmd =
|
|
9492
|
+
var validateCmd = defineCommand6({
|
|
8122
9493
|
meta: { name: "validate", description: "Validate invoice XML against KSeF schema" },
|
|
8123
9494
|
args: {
|
|
8124
9495
|
files: { type: "positional", description: "XML file(s) or directory to validate", required: true },
|
|
@@ -8133,13 +9504,13 @@ var validateCmd = defineCommand5({
|
|
|
8133
9504
|
}
|
|
8134
9505
|
const inputPath = args.files;
|
|
8135
9506
|
const filePaths = [];
|
|
8136
|
-
if (
|
|
8137
|
-
const xmlFiles =
|
|
9507
|
+
if (fs11.existsSync(inputPath) && fs11.statSync(inputPath).isDirectory()) {
|
|
9508
|
+
const xmlFiles = fs11.readdirSync(inputPath).filter((f) => f.endsWith(".xml")).sort().map((f) => path8.join(inputPath, f));
|
|
8138
9509
|
if (xmlFiles.length === 0) {
|
|
8139
9510
|
throw new Error(`No XML files found in ${inputPath}`);
|
|
8140
9511
|
}
|
|
8141
9512
|
filePaths.push(...xmlFiles);
|
|
8142
|
-
} else if (
|
|
9513
|
+
} else if (fs11.existsSync(inputPath)) {
|
|
8143
9514
|
filePaths.push(inputPath);
|
|
8144
9515
|
} else {
|
|
8145
9516
|
throw new Error(`File not found: ${inputPath}`);
|
|
@@ -8148,28 +9519,28 @@ var validateCmd = defineCommand5({
|
|
|
8148
9519
|
let invalidCount = 0;
|
|
8149
9520
|
const allResults = [];
|
|
8150
9521
|
for (const file of filePaths) {
|
|
8151
|
-
const xml =
|
|
9522
|
+
const xml = fs11.readFileSync(file, "utf-8");
|
|
8152
9523
|
const result = await validate(xml, schemaOverride ? { schema: schemaOverride } : void 0);
|
|
8153
9524
|
if (result.valid) {
|
|
8154
9525
|
validCount++;
|
|
8155
9526
|
if (!args.json) {
|
|
8156
|
-
|
|
9527
|
+
consola11.success(`${path8.basename(file)}: valid (${result.schemaType})`);
|
|
8157
9528
|
if (result.schemaType === "PEF3" || result.schemaType === "PEF_KOR3") {
|
|
8158
|
-
|
|
9529
|
+
consola11.warn("PEF validation covers wrapper structure only \u2014 UBL content is not validated.");
|
|
8159
9530
|
}
|
|
8160
9531
|
}
|
|
8161
9532
|
} else {
|
|
8162
9533
|
invalidCount++;
|
|
8163
9534
|
if (!args.json) {
|
|
8164
|
-
|
|
9535
|
+
consola11.error(`${path8.basename(file)}: INVALID (${result.schemaType ?? "unknown schema"})`);
|
|
8165
9536
|
for (const err of result.errors) {
|
|
8166
9537
|
const loc = err.path ? ` at ${err.path}` : "";
|
|
8167
|
-
|
|
9538
|
+
consola11.log(` [${err.code}]${loc}: ${err.message}`);
|
|
8168
9539
|
}
|
|
8169
9540
|
}
|
|
8170
9541
|
}
|
|
8171
9542
|
allResults.push({
|
|
8172
|
-
file:
|
|
9543
|
+
file: path8.basename(file),
|
|
8173
9544
|
valid: result.valid,
|
|
8174
9545
|
schemaType: result.schemaType,
|
|
8175
9546
|
errors: result.errors
|
|
@@ -8178,8 +9549,8 @@ var validateCmd = defineCommand5({
|
|
|
8178
9549
|
if (args.json) {
|
|
8179
9550
|
outputResult({ files: allResults, summary: { total: filePaths.length, valid: validCount, invalid: invalidCount } }, { json: true });
|
|
8180
9551
|
} else if (filePaths.length > 1) {
|
|
8181
|
-
|
|
8182
|
-
|
|
9552
|
+
consola11.log("");
|
|
9553
|
+
consola11.info(`Summary: ${validCount} valid, ${invalidCount} invalid, ${filePaths.length} total`);
|
|
8183
9554
|
}
|
|
8184
9555
|
if (invalidCount > 0) {
|
|
8185
9556
|
process.exitCode = 1;
|
|
@@ -8187,13 +9558,13 @@ var validateCmd = defineCommand5({
|
|
|
8187
9558
|
}, { json: Boolean(args.json) });
|
|
8188
9559
|
}
|
|
8189
9560
|
});
|
|
8190
|
-
var invoiceCommand =
|
|
9561
|
+
var invoiceCommand = defineCommand6({
|
|
8191
9562
|
meta: { name: "invoice", description: "Invoice commands" },
|
|
8192
|
-
subCommands: { send, get, query, validate: validateCmd, export: exportCmd, "export-status": exportStatus, "export-incremental": exportIncremental }
|
|
9563
|
+
subCommands: { send, build: invoiceBuild, get, query, validate: validateCmd, export: exportCmd, "export-status": exportStatus, "export-incremental": exportIncremental }
|
|
8193
9564
|
});
|
|
8194
9565
|
|
|
8195
9566
|
// src/cli/commands/permission.ts
|
|
8196
|
-
import { defineCommand as
|
|
9567
|
+
import { defineCommand as defineCommand7 } from "citty";
|
|
8197
9568
|
init_ksef_validation_error();
|
|
8198
9569
|
function getGlobalOpts5(args) {
|
|
8199
9570
|
return {
|
|
@@ -8204,7 +9575,7 @@ function getGlobalOpts5(args) {
|
|
|
8204
9575
|
nip: args.nip
|
|
8205
9576
|
};
|
|
8206
9577
|
}
|
|
8207
|
-
var grant =
|
|
9578
|
+
var grant = defineCommand7({
|
|
8208
9579
|
meta: { name: "grant", description: "Grant permissions to a subject" },
|
|
8209
9580
|
args: {
|
|
8210
9581
|
type: { type: "string", description: "Grant type: person, entity, authorization, indirect, subunit, eu-entity-admin, eu-entity-representative", required: true },
|
|
@@ -8386,7 +9757,7 @@ var grant = defineCommand6({
|
|
|
8386
9757
|
}, { json: Boolean(args.json) });
|
|
8387
9758
|
}
|
|
8388
9759
|
});
|
|
8389
|
-
var revoke2 =
|
|
9760
|
+
var revoke2 = defineCommand7({
|
|
8390
9761
|
meta: { name: "revoke", description: "Revoke a permission grant" },
|
|
8391
9762
|
args: {
|
|
8392
9763
|
grantId: { type: "positional", description: "Grant ID to revoke", required: true },
|
|
@@ -8415,7 +9786,7 @@ var revoke2 = defineCommand6({
|
|
|
8415
9786
|
}, { json: Boolean(args.json) });
|
|
8416
9787
|
}
|
|
8417
9788
|
});
|
|
8418
|
-
var search =
|
|
9789
|
+
var search = defineCommand7({
|
|
8419
9790
|
meta: { name: "search", description: "Search permissions" },
|
|
8420
9791
|
args: {
|
|
8421
9792
|
type: { type: "string", description: "Search type: personal, persons, subunits, entities, entities-grants, subordinate-entities, authorizations, eu-entities", required: true },
|
|
@@ -8681,7 +10052,7 @@ var search = defineCommand6({
|
|
|
8681
10052
|
}, { json: Boolean(args.json) });
|
|
8682
10053
|
}
|
|
8683
10054
|
});
|
|
8684
|
-
var status3 =
|
|
10055
|
+
var status3 = defineCommand7({
|
|
8685
10056
|
meta: { name: "status", description: "Check permission operation status" },
|
|
8686
10057
|
args: {
|
|
8687
10058
|
ref: { type: "positional", description: "Operation reference number", required: true },
|
|
@@ -8707,7 +10078,7 @@ var status3 = defineCommand6({
|
|
|
8707
10078
|
}, { json: Boolean(args.json) });
|
|
8708
10079
|
}
|
|
8709
10080
|
});
|
|
8710
|
-
var attachmentStatus =
|
|
10081
|
+
var attachmentStatus = defineCommand7({
|
|
8711
10082
|
meta: { name: "attachment-status", description: "Check if attachment permissions are allowed" },
|
|
8712
10083
|
args: {
|
|
8713
10084
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -8731,14 +10102,14 @@ var attachmentStatus = defineCommand6({
|
|
|
8731
10102
|
}, { json: Boolean(args.json) });
|
|
8732
10103
|
}
|
|
8733
10104
|
});
|
|
8734
|
-
var permissionCommand =
|
|
10105
|
+
var permissionCommand = defineCommand7({
|
|
8735
10106
|
meta: { name: "permission", description: "Permission management commands" },
|
|
8736
10107
|
subCommands: { grant, revoke: revoke2, search, status: status3, "attachment-status": attachmentStatus }
|
|
8737
10108
|
});
|
|
8738
10109
|
|
|
8739
10110
|
// src/cli/commands/token.ts
|
|
8740
|
-
import { defineCommand as
|
|
8741
|
-
import { consola as
|
|
10111
|
+
import { defineCommand as defineCommand8 } from "citty";
|
|
10112
|
+
import { consola as consola12 } from "consola";
|
|
8742
10113
|
function getGlobalOpts6(args) {
|
|
8743
10114
|
return {
|
|
8744
10115
|
env: args.env,
|
|
@@ -8748,7 +10119,7 @@ function getGlobalOpts6(args) {
|
|
|
8748
10119
|
nip: args.nip
|
|
8749
10120
|
};
|
|
8750
10121
|
}
|
|
8751
|
-
var generate =
|
|
10122
|
+
var generate = defineCommand8({
|
|
8752
10123
|
meta: { name: "generate", description: "Generate a new KSeF token" },
|
|
8753
10124
|
args: {
|
|
8754
10125
|
permissions: { type: "string", description: "Comma-separated permissions (e.g. InvoiceRead,InvoiceWrite)", required: true },
|
|
@@ -8784,7 +10155,7 @@ var generate = defineCommand7({
|
|
|
8784
10155
|
}, { json: Boolean(args.json) });
|
|
8785
10156
|
}
|
|
8786
10157
|
});
|
|
8787
|
-
var list2 =
|
|
10158
|
+
var list2 = defineCommand8({
|
|
8788
10159
|
meta: { name: "list", description: "List KSeF tokens" },
|
|
8789
10160
|
args: {
|
|
8790
10161
|
status: { type: "string", description: "Comma-separated statuses (e.g. Active,Pending)" },
|
|
@@ -8838,12 +10209,12 @@ var list2 = defineCommand7({
|
|
|
8838
10209
|
{ json: false }
|
|
8839
10210
|
);
|
|
8840
10211
|
if (result.continuationToken) {
|
|
8841
|
-
|
|
10212
|
+
consola12.info(`More results available. Continuation token: ${result.continuationToken}`);
|
|
8842
10213
|
}
|
|
8843
10214
|
}, { json: Boolean(args.json) });
|
|
8844
10215
|
}
|
|
8845
10216
|
});
|
|
8846
|
-
var get2 =
|
|
10217
|
+
var get2 = defineCommand8({
|
|
8847
10218
|
meta: { name: "get", description: "Get token details" },
|
|
8848
10219
|
args: {
|
|
8849
10220
|
ref: { type: "positional", description: "Token reference number", required: true },
|
|
@@ -8876,7 +10247,7 @@ var get2 = defineCommand7({
|
|
|
8876
10247
|
}, { json: Boolean(args.json) });
|
|
8877
10248
|
}
|
|
8878
10249
|
});
|
|
8879
|
-
var revoke3 =
|
|
10250
|
+
var revoke3 = defineCommand8({
|
|
8880
10251
|
meta: { name: "revoke", description: "Revoke a KSeF token" },
|
|
8881
10252
|
args: {
|
|
8882
10253
|
ref: { type: "positional", description: "Token reference number", required: true },
|
|
@@ -8900,16 +10271,16 @@ var revoke3 = defineCommand7({
|
|
|
8900
10271
|
}, { json: Boolean(args.json) });
|
|
8901
10272
|
}
|
|
8902
10273
|
});
|
|
8903
|
-
var tokenCommand =
|
|
10274
|
+
var tokenCommand = defineCommand8({
|
|
8904
10275
|
meta: { name: "token", description: "Token management commands" },
|
|
8905
10276
|
subCommands: { generate, list: list2, get: get2, revoke: revoke3 }
|
|
8906
10277
|
});
|
|
8907
10278
|
|
|
8908
10279
|
// src/cli/commands/cert.ts
|
|
8909
|
-
import { defineCommand as
|
|
8910
|
-
import { consola as
|
|
8911
|
-
import
|
|
8912
|
-
import
|
|
10280
|
+
import { defineCommand as defineCommand9 } from "citty";
|
|
10281
|
+
import { consola as consola13 } from "consola";
|
|
10282
|
+
import fs12 from "fs";
|
|
10283
|
+
import path9 from "path";
|
|
8913
10284
|
|
|
8914
10285
|
// src/crypto/certificate-service.ts
|
|
8915
10286
|
import * as crypto7 from "crypto";
|
|
@@ -9002,7 +10373,7 @@ function getGlobalOpts7(args) {
|
|
|
9002
10373
|
nip: args.nip
|
|
9003
10374
|
};
|
|
9004
10375
|
}
|
|
9005
|
-
var generate2 =
|
|
10376
|
+
var generate2 = defineCommand9({
|
|
9006
10377
|
meta: { name: "generate", description: "Generate a self-signed certificate locally" },
|
|
9007
10378
|
args: {
|
|
9008
10379
|
type: { type: "string", description: "Certificate type: personal or company-seal", required: true },
|
|
@@ -9027,21 +10398,21 @@ var generate2 = defineCommand8({
|
|
|
9027
10398
|
const certType = args.type;
|
|
9028
10399
|
const cn = args.cn;
|
|
9029
10400
|
const method = args.method || "RSA";
|
|
9030
|
-
const outDir =
|
|
10401
|
+
const outDir = path9.resolve(args.out || ".");
|
|
9031
10402
|
if (certType !== "personal" && certType !== "company-seal") {
|
|
9032
10403
|
throw new Error('--type must be "personal" or "company-seal".');
|
|
9033
10404
|
}
|
|
9034
10405
|
if (method !== "RSA" && method !== "ECDSA") {
|
|
9035
10406
|
throw new Error('--method must be "RSA" or "ECDSA".');
|
|
9036
10407
|
}
|
|
9037
|
-
|
|
9038
|
-
const certPath =
|
|
9039
|
-
const keyPath =
|
|
10408
|
+
fs12.mkdirSync(outDir, { recursive: true });
|
|
10409
|
+
const certPath = path9.join(outDir, "cert.pem");
|
|
10410
|
+
const keyPath = path9.join(outDir, "key.pem");
|
|
9040
10411
|
if (!args.force) {
|
|
9041
|
-
if (
|
|
10412
|
+
if (fs12.existsSync(certPath)) {
|
|
9042
10413
|
throw new Error(`File already exists: ${certPath}. Use --force to overwrite.`);
|
|
9043
10414
|
}
|
|
9044
|
-
if (
|
|
10415
|
+
if (fs12.existsSync(keyPath)) {
|
|
9045
10416
|
throw new Error(`File already exists: ${keyPath}. Use --force to overwrite.`);
|
|
9046
10417
|
}
|
|
9047
10418
|
}
|
|
@@ -9068,8 +10439,8 @@ var generate2 = defineCommand8({
|
|
|
9068
10439
|
method
|
|
9069
10440
|
);
|
|
9070
10441
|
}
|
|
9071
|
-
|
|
9072
|
-
|
|
10442
|
+
fs12.writeFileSync(certPath, result.certificatePem, "utf-8");
|
|
10443
|
+
fs12.writeFileSync(keyPath, result.privateKeyPem, "utf-8");
|
|
9073
10444
|
if (args.json) {
|
|
9074
10445
|
outputResult({ certPath, keyPath, fingerprint: result.fingerprint }, { json: true });
|
|
9075
10446
|
} else {
|
|
@@ -9083,7 +10454,7 @@ var generate2 = defineCommand8({
|
|
|
9083
10454
|
}, { json: Boolean(args.json) });
|
|
9084
10455
|
}
|
|
9085
10456
|
});
|
|
9086
|
-
var enroll =
|
|
10457
|
+
var enroll = defineCommand9({
|
|
9087
10458
|
meta: { name: "enroll", description: "Submit certificate enrollment" },
|
|
9088
10459
|
args: {
|
|
9089
10460
|
cert: { type: "string", description: "Path to certificate PEM file", required: true },
|
|
@@ -9100,7 +10471,7 @@ var enroll = defineCommand8({
|
|
|
9100
10471
|
return withErrorHandler(async () => {
|
|
9101
10472
|
const globalOpts = getGlobalOpts7(args);
|
|
9102
10473
|
const { client } = await requireSession(globalOpts);
|
|
9103
|
-
const certPem =
|
|
10474
|
+
const certPem = fs12.readFileSync(args.cert, "utf-8");
|
|
9104
10475
|
await client.crypto.init();
|
|
9105
10476
|
const request = {
|
|
9106
10477
|
certificateName: args.name,
|
|
@@ -9121,7 +10492,7 @@ var enroll = defineCommand8({
|
|
|
9121
10492
|
}, { json: Boolean(args.json) });
|
|
9122
10493
|
}
|
|
9123
10494
|
});
|
|
9124
|
-
var status4 =
|
|
10495
|
+
var status4 = defineCommand9({
|
|
9125
10496
|
meta: { name: "status", description: "Check certificate enrollment status" },
|
|
9126
10497
|
args: {
|
|
9127
10498
|
ref: { type: "positional", description: "Enrollment reference number", required: true },
|
|
@@ -9153,7 +10524,7 @@ var status4 = defineCommand8({
|
|
|
9153
10524
|
}, { json: Boolean(args.json) });
|
|
9154
10525
|
}
|
|
9155
10526
|
});
|
|
9156
|
-
var list3 =
|
|
10527
|
+
var list3 = defineCommand9({
|
|
9157
10528
|
meta: { name: "list", description: "Query certificates" },
|
|
9158
10529
|
args: {
|
|
9159
10530
|
serial: { type: "string", description: "Filter by serial number" },
|
|
@@ -9211,12 +10582,12 @@ var list3 = defineCommand8({
|
|
|
9211
10582
|
{ json: false }
|
|
9212
10583
|
);
|
|
9213
10584
|
if (result.hasMore) {
|
|
9214
|
-
|
|
10585
|
+
consola13.info("More results available. Use --page to paginate.");
|
|
9215
10586
|
}
|
|
9216
10587
|
}, { json: Boolean(args.json) });
|
|
9217
10588
|
}
|
|
9218
10589
|
});
|
|
9219
|
-
var revoke4 =
|
|
10590
|
+
var revoke4 = defineCommand9({
|
|
9220
10591
|
meta: { name: "revoke", description: "Revoke a certificate" },
|
|
9221
10592
|
args: {
|
|
9222
10593
|
serial: { type: "positional", description: "Certificate serial number", required: true },
|
|
@@ -9243,7 +10614,7 @@ var revoke4 = defineCommand8({
|
|
|
9243
10614
|
}, { json: Boolean(args.json) });
|
|
9244
10615
|
}
|
|
9245
10616
|
});
|
|
9246
|
-
var limits =
|
|
10617
|
+
var limits = defineCommand9({
|
|
9247
10618
|
meta: { name: "limits", description: "View certificate limits" },
|
|
9248
10619
|
args: {
|
|
9249
10620
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -9271,7 +10642,7 @@ var limits = defineCommand8({
|
|
|
9271
10642
|
}, { json: Boolean(args.json) });
|
|
9272
10643
|
}
|
|
9273
10644
|
});
|
|
9274
|
-
var enrollmentData =
|
|
10645
|
+
var enrollmentData = defineCommand9({
|
|
9275
10646
|
meta: { name: "enrollment-data", description: "Get enrollment data template from KSeF" },
|
|
9276
10647
|
args: {
|
|
9277
10648
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -9302,7 +10673,7 @@ var enrollmentData = defineCommand8({
|
|
|
9302
10673
|
}, { json: Boolean(args.json) });
|
|
9303
10674
|
}
|
|
9304
10675
|
});
|
|
9305
|
-
var retrieve =
|
|
10676
|
+
var retrieve = defineCommand9({
|
|
9306
10677
|
meta: { name: "retrieve", description: "Retrieve certificates by serial numbers" },
|
|
9307
10678
|
args: {
|
|
9308
10679
|
serial: { type: "string", description: "Comma-separated certificate serial numbers", required: true },
|
|
@@ -9345,14 +10716,14 @@ var retrieve = defineCommand8({
|
|
|
9345
10716
|
}, { json: Boolean(args.json) });
|
|
9346
10717
|
}
|
|
9347
10718
|
});
|
|
9348
|
-
var certCommand =
|
|
10719
|
+
var certCommand = defineCommand9({
|
|
9349
10720
|
meta: { name: "cert", description: "Certificate management commands" },
|
|
9350
10721
|
subCommands: { generate: generate2, enroll, status: status4, list: list3, revoke: revoke4, limits, "enrollment-data": enrollmentData, retrieve }
|
|
9351
10722
|
});
|
|
9352
10723
|
|
|
9353
10724
|
// src/cli/commands/qr.ts
|
|
9354
|
-
import * as
|
|
9355
|
-
import { defineCommand as
|
|
10725
|
+
import * as fs13 from "fs";
|
|
10726
|
+
import { defineCommand as defineCommand10 } from "citty";
|
|
9356
10727
|
|
|
9357
10728
|
// src/qr/qrcode-service.ts
|
|
9358
10729
|
import * as QRCode from "qrcode";
|
|
@@ -9423,7 +10794,7 @@ function getGlobalOpts8(args) {
|
|
|
9423
10794
|
nip: args.nip
|
|
9424
10795
|
};
|
|
9425
10796
|
}
|
|
9426
|
-
var invoice2 =
|
|
10797
|
+
var invoice2 = defineCommand10({
|
|
9427
10798
|
meta: { name: "invoice", description: "Generate invoice QR code" },
|
|
9428
10799
|
args: {
|
|
9429
10800
|
nip: { type: "string", description: "NIP number", required: true },
|
|
@@ -9455,7 +10826,7 @@ var invoice2 = defineCommand9({
|
|
|
9455
10826
|
const effectiveLabel = args.offline ? "OFFLINE" : args.label;
|
|
9456
10827
|
const svg = effectiveLabel ? await QrCodeService.generateQrCodeSvgWithLabel(url2, effectiveLabel, { width: size }) : await QrCodeService.generateQrCodeSvg(url2, { width: size });
|
|
9457
10828
|
if (args.o) {
|
|
9458
|
-
|
|
10829
|
+
fs13.writeFileSync(args.o, svg);
|
|
9459
10830
|
outputSuccess(`QR code saved to ${args.o}
|
|
9460
10831
|
URL: ${url2}`);
|
|
9461
10832
|
} else {
|
|
@@ -9464,7 +10835,7 @@ URL: ${url2}`);
|
|
|
9464
10835
|
} else {
|
|
9465
10836
|
const buffer = await QrCodeService.generateQrCode(url2, { width: size });
|
|
9466
10837
|
if (args.o) {
|
|
9467
|
-
|
|
10838
|
+
fs13.writeFileSync(args.o, buffer);
|
|
9468
10839
|
outputSuccess(`QR code saved to ${args.o}
|
|
9469
10840
|
URL: ${url2}`);
|
|
9470
10841
|
} else {
|
|
@@ -9474,7 +10845,7 @@ URL: ${url2}`);
|
|
|
9474
10845
|
}, { json: Boolean(args.json) });
|
|
9475
10846
|
}
|
|
9476
10847
|
});
|
|
9477
|
-
var certificate =
|
|
10848
|
+
var certificate = defineCommand10({
|
|
9478
10849
|
meta: { name: "certificate", description: "Generate certificate QR code" },
|
|
9479
10850
|
args: {
|
|
9480
10851
|
"context-type": { type: "string", description: "Context identifier type", required: true },
|
|
@@ -9483,6 +10854,7 @@ var certificate = defineCommand9({
|
|
|
9483
10854
|
"cert-serial": { type: "string", description: "Certificate serial number", required: true },
|
|
9484
10855
|
hash: { type: "string", description: "Certificate hash (base64)", required: true },
|
|
9485
10856
|
key: { type: "string", description: "Path to PEM private key file", required: true },
|
|
10857
|
+
"key-password": { type: "string", description: "Password for encrypted PEM private key" },
|
|
9486
10858
|
format: { type: "string", description: "Output format: png or svg (default: png)" },
|
|
9487
10859
|
size: { type: "string", description: "QR code size in pixels (default: 300)" },
|
|
9488
10860
|
label: { type: "string", description: "Label text (SVG only)" },
|
|
@@ -9499,14 +10871,16 @@ var certificate = defineCommand9({
|
|
|
9499
10871
|
const client = createClient(globalOpts);
|
|
9500
10872
|
const size = args.size ? parseInt(args.size, 10) : 300;
|
|
9501
10873
|
const format = args.format ?? "png";
|
|
9502
|
-
const privateKeyPem =
|
|
10874
|
+
const privateKeyPem = fs13.readFileSync(args.key, "utf-8");
|
|
10875
|
+
const keyPassword = args["key-password"];
|
|
9503
10876
|
const url2 = client.qr.buildCertificateVerificationUrl(
|
|
9504
10877
|
args["context-type"],
|
|
9505
10878
|
args["context-id"],
|
|
9506
10879
|
args["seller-nip"],
|
|
9507
10880
|
args["cert-serial"],
|
|
9508
10881
|
args.hash,
|
|
9509
|
-
privateKeyPem
|
|
10882
|
+
privateKeyPem,
|
|
10883
|
+
keyPassword
|
|
9510
10884
|
);
|
|
9511
10885
|
if (args.json) {
|
|
9512
10886
|
const result = await QrCodeService.generateResult(url2, { width: size });
|
|
@@ -9516,7 +10890,7 @@ var certificate = defineCommand9({
|
|
|
9516
10890
|
if (format === "svg") {
|
|
9517
10891
|
const svg = args.label ? await QrCodeService.generateQrCodeSvgWithLabel(url2, args.label, { width: size }) : await QrCodeService.generateQrCodeSvg(url2, { width: size });
|
|
9518
10892
|
if (args.o) {
|
|
9519
|
-
|
|
10893
|
+
fs13.writeFileSync(args.o, svg);
|
|
9520
10894
|
outputSuccess(`QR code saved to ${args.o}
|
|
9521
10895
|
URL: ${url2}`);
|
|
9522
10896
|
} else {
|
|
@@ -9525,7 +10899,7 @@ URL: ${url2}`);
|
|
|
9525
10899
|
} else {
|
|
9526
10900
|
const buffer = await QrCodeService.generateQrCode(url2, { width: size });
|
|
9527
10901
|
if (args.o) {
|
|
9528
|
-
|
|
10902
|
+
fs13.writeFileSync(args.o, buffer);
|
|
9529
10903
|
outputSuccess(`QR code saved to ${args.o}
|
|
9530
10904
|
URL: ${url2}`);
|
|
9531
10905
|
} else {
|
|
@@ -9535,7 +10909,7 @@ URL: ${url2}`);
|
|
|
9535
10909
|
}, { json: Boolean(args.json) });
|
|
9536
10910
|
}
|
|
9537
10911
|
});
|
|
9538
|
-
var url =
|
|
10912
|
+
var url = defineCommand10({
|
|
9539
10913
|
meta: { name: "url", description: "Print invoice verification URL (no QR image)" },
|
|
9540
10914
|
args: {
|
|
9541
10915
|
nip: { type: "string", description: "NIP number", required: true },
|
|
@@ -9559,13 +10933,13 @@ var url = defineCommand9({
|
|
|
9559
10933
|
}, { json: Boolean(args.json) });
|
|
9560
10934
|
}
|
|
9561
10935
|
});
|
|
9562
|
-
var qrCommand =
|
|
10936
|
+
var qrCommand = defineCommand10({
|
|
9563
10937
|
meta: { name: "qr", description: "QR code generation commands" },
|
|
9564
10938
|
subCommands: { invoice: invoice2, certificate, url }
|
|
9565
10939
|
});
|
|
9566
10940
|
|
|
9567
10941
|
// src/cli/commands/lighthouse.ts
|
|
9568
|
-
import { defineCommand as
|
|
10942
|
+
import { defineCommand as defineCommand11 } from "citty";
|
|
9569
10943
|
function getGlobalOpts9(args) {
|
|
9570
10944
|
return {
|
|
9571
10945
|
env: args.env ?? "prod",
|
|
@@ -9575,7 +10949,7 @@ function getGlobalOpts9(args) {
|
|
|
9575
10949
|
nip: args.nip
|
|
9576
10950
|
};
|
|
9577
10951
|
}
|
|
9578
|
-
var status5 =
|
|
10952
|
+
var status5 = defineCommand11({
|
|
9579
10953
|
meta: { name: "status", description: "Check KSeF system status" },
|
|
9580
10954
|
args: {
|
|
9581
10955
|
env: { type: "string", description: "Environment (test/prod, default: prod)" },
|
|
@@ -9603,7 +10977,7 @@ var status5 = defineCommand10({
|
|
|
9603
10977
|
}, { json: Boolean(args.json) });
|
|
9604
10978
|
}
|
|
9605
10979
|
});
|
|
9606
|
-
var messages =
|
|
10980
|
+
var messages = defineCommand11({
|
|
9607
10981
|
meta: { name: "messages", description: "View KSeF system messages" },
|
|
9608
10982
|
args: {
|
|
9609
10983
|
env: { type: "string", description: "Environment (test/prod, default: prod)" },
|
|
@@ -9645,13 +11019,13 @@ var messages = defineCommand10({
|
|
|
9645
11019
|
}, { json: Boolean(args.json) });
|
|
9646
11020
|
}
|
|
9647
11021
|
});
|
|
9648
|
-
var lighthouseCommand =
|
|
11022
|
+
var lighthouseCommand = defineCommand11({
|
|
9649
11023
|
meta: { name: "lighthouse", description: "KSeF system status commands" },
|
|
9650
11024
|
subCommands: { status: status5, messages }
|
|
9651
11025
|
});
|
|
9652
11026
|
|
|
9653
11027
|
// src/cli/commands/test-data.ts
|
|
9654
|
-
import { defineCommand as
|
|
11028
|
+
import { defineCommand as defineCommand12 } from "citty";
|
|
9655
11029
|
function getGlobalOpts10(args) {
|
|
9656
11030
|
return {
|
|
9657
11031
|
env: args.env,
|
|
@@ -9674,7 +11048,7 @@ function outputDone(json) {
|
|
|
9674
11048
|
outputSuccess("Done.");
|
|
9675
11049
|
}
|
|
9676
11050
|
}
|
|
9677
|
-
var createSubject =
|
|
11051
|
+
var createSubject = defineCommand12({
|
|
9678
11052
|
meta: { name: "create-subject", description: "Create a test subject" },
|
|
9679
11053
|
args: {
|
|
9680
11054
|
nip: { type: "string", description: "Subject NIP", required: true },
|
|
@@ -9701,7 +11075,7 @@ var createSubject = defineCommand11({
|
|
|
9701
11075
|
}, { json: Boolean(args.json) });
|
|
9702
11076
|
}
|
|
9703
11077
|
});
|
|
9704
|
-
var removeSubject =
|
|
11078
|
+
var removeSubject = defineCommand12({
|
|
9705
11079
|
meta: { name: "remove-subject", description: "Remove a test subject" },
|
|
9706
11080
|
args: {
|
|
9707
11081
|
nip: { type: "string", description: "Subject NIP", required: true },
|
|
@@ -9720,7 +11094,7 @@ var removeSubject = defineCommand11({
|
|
|
9720
11094
|
}, { json: Boolean(args.json) });
|
|
9721
11095
|
}
|
|
9722
11096
|
});
|
|
9723
|
-
var createPerson =
|
|
11097
|
+
var createPerson = defineCommand12({
|
|
9724
11098
|
meta: { name: "create-person", description: "Create a test person" },
|
|
9725
11099
|
args: {
|
|
9726
11100
|
nip: { type: "string", description: "Person NIP", required: true },
|
|
@@ -9751,7 +11125,7 @@ var createPerson = defineCommand11({
|
|
|
9751
11125
|
}, { json: Boolean(args.json) });
|
|
9752
11126
|
}
|
|
9753
11127
|
});
|
|
9754
|
-
var removePerson =
|
|
11128
|
+
var removePerson = defineCommand12({
|
|
9755
11129
|
meta: { name: "remove-person", description: "Remove a test person" },
|
|
9756
11130
|
args: {
|
|
9757
11131
|
nip: { type: "string", description: "Person NIP", required: true },
|
|
@@ -9770,7 +11144,7 @@ var removePerson = defineCommand11({
|
|
|
9770
11144
|
}, { json: Boolean(args.json) });
|
|
9771
11145
|
}
|
|
9772
11146
|
});
|
|
9773
|
-
var grantPermissions =
|
|
11147
|
+
var grantPermissions = defineCommand12({
|
|
9774
11148
|
meta: { name: "grant-permissions", description: "Grant test data permissions" },
|
|
9775
11149
|
args: {
|
|
9776
11150
|
"context-nip": { type: "string", description: "Context NIP", required: true },
|
|
@@ -9801,7 +11175,7 @@ var grantPermissions = defineCommand11({
|
|
|
9801
11175
|
}, { json: Boolean(args.json) });
|
|
9802
11176
|
}
|
|
9803
11177
|
});
|
|
9804
|
-
var revokePermissions =
|
|
11178
|
+
var revokePermissions = defineCommand12({
|
|
9805
11179
|
meta: { name: "revoke-permissions", description: "Revoke test data permissions" },
|
|
9806
11180
|
args: {
|
|
9807
11181
|
"context-nip": { type: "string", description: "Context NIP", required: true },
|
|
@@ -9829,7 +11203,7 @@ var revokePermissions = defineCommand11({
|
|
|
9829
11203
|
}, { json: Boolean(args.json) });
|
|
9830
11204
|
}
|
|
9831
11205
|
});
|
|
9832
|
-
var enableAttachment =
|
|
11206
|
+
var enableAttachment = defineCommand12({
|
|
9833
11207
|
meta: { name: "enable-attachment", description: "Enable attachment permission for a subject" },
|
|
9834
11208
|
args: {
|
|
9835
11209
|
nip: { type: "string", description: "Subject NIP", required: true },
|
|
@@ -9848,7 +11222,7 @@ var enableAttachment = defineCommand11({
|
|
|
9848
11222
|
}, { json: Boolean(args.json) });
|
|
9849
11223
|
}
|
|
9850
11224
|
});
|
|
9851
|
-
var disableAttachment =
|
|
11225
|
+
var disableAttachment = defineCommand12({
|
|
9852
11226
|
meta: { name: "disable-attachment", description: "Disable attachment permission for a subject" },
|
|
9853
11227
|
args: {
|
|
9854
11228
|
nip: { type: "string", description: "Subject NIP", required: true },
|
|
@@ -9871,7 +11245,7 @@ var disableAttachment = defineCommand11({
|
|
|
9871
11245
|
}, { json: Boolean(args.json) });
|
|
9872
11246
|
}
|
|
9873
11247
|
});
|
|
9874
|
-
var changeSessionLimits =
|
|
11248
|
+
var changeSessionLimits = defineCommand12({
|
|
9875
11249
|
meta: { name: "change-session-limits", description: "Change session limits in current context" },
|
|
9876
11250
|
args: {
|
|
9877
11251
|
"online-max-size": { type: "string", description: "Online session: max invoice size in MB (0-5)", required: true },
|
|
@@ -9908,7 +11282,7 @@ var changeSessionLimits = defineCommand11({
|
|
|
9908
11282
|
}, { json: Boolean(args.json) });
|
|
9909
11283
|
}
|
|
9910
11284
|
});
|
|
9911
|
-
var restoreSessionLimits =
|
|
11285
|
+
var restoreSessionLimits = defineCommand12({
|
|
9912
11286
|
meta: { name: "restore-session-limits", description: "Restore default session limits" },
|
|
9913
11287
|
args: {
|
|
9914
11288
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -9927,7 +11301,7 @@ var restoreSessionLimits = defineCommand11({
|
|
|
9927
11301
|
}, { json: Boolean(args.json) });
|
|
9928
11302
|
}
|
|
9929
11303
|
});
|
|
9930
|
-
var changeCertLimits =
|
|
11304
|
+
var changeCertLimits = defineCommand12({
|
|
9931
11305
|
meta: { name: "change-cert-limits", description: "Change subject limits (enrollment/certificate) in current subject" },
|
|
9932
11306
|
args: {
|
|
9933
11307
|
"identifier-type": { type: "string", description: "Subject identifier type (Nip/Pesel/Fingerprint)" },
|
|
@@ -9954,7 +11328,7 @@ var changeCertLimits = defineCommand11({
|
|
|
9954
11328
|
}, { json: Boolean(args.json) });
|
|
9955
11329
|
}
|
|
9956
11330
|
});
|
|
9957
|
-
var restoreCertLimits =
|
|
11331
|
+
var restoreCertLimits = defineCommand12({
|
|
9958
11332
|
meta: { name: "restore-cert-limits", description: "Restore default certificates limit" },
|
|
9959
11333
|
args: {
|
|
9960
11334
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -9973,7 +11347,7 @@ var restoreCertLimits = defineCommand11({
|
|
|
9973
11347
|
}, { json: Boolean(args.json) });
|
|
9974
11348
|
}
|
|
9975
11349
|
});
|
|
9976
|
-
var setRateLimits =
|
|
11350
|
+
var setRateLimits = defineCommand12({
|
|
9977
11351
|
meta: { name: "set-rate-limits", description: "Set effective API rate limits" },
|
|
9978
11352
|
args: {
|
|
9979
11353
|
limits: { type: "string", description: "Rate limits as JSON string (ApiRateLimitsOverride)", required: true },
|
|
@@ -9996,7 +11370,7 @@ var setRateLimits = defineCommand11({
|
|
|
9996
11370
|
}, { json: Boolean(args.json) });
|
|
9997
11371
|
}
|
|
9998
11372
|
});
|
|
9999
|
-
var restoreRateLimits =
|
|
11373
|
+
var restoreRateLimits = defineCommand12({
|
|
10000
11374
|
meta: { name: "restore-rate-limits", description: "Restore default API rate limits" },
|
|
10001
11375
|
args: {
|
|
10002
11376
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -10015,7 +11389,7 @@ var restoreRateLimits = defineCommand11({
|
|
|
10015
11389
|
}, { json: Boolean(args.json) });
|
|
10016
11390
|
}
|
|
10017
11391
|
});
|
|
10018
|
-
var setProductionRateLimits =
|
|
11392
|
+
var setProductionRateLimits = defineCommand12({
|
|
10019
11393
|
meta: { name: "set-production-rate-limits", description: "Set production API rate limits" },
|
|
10020
11394
|
args: {
|
|
10021
11395
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -10034,7 +11408,7 @@ var setProductionRateLimits = defineCommand11({
|
|
|
10034
11408
|
}, { json: Boolean(args.json) });
|
|
10035
11409
|
}
|
|
10036
11410
|
});
|
|
10037
|
-
var blockContext =
|
|
11411
|
+
var blockContext = defineCommand12({
|
|
10038
11412
|
meta: { name: "block-context", description: "Block a context" },
|
|
10039
11413
|
args: {
|
|
10040
11414
|
"context-value": { type: "string", description: "Context identifier value", required: true },
|
|
@@ -10061,7 +11435,7 @@ var blockContext = defineCommand11({
|
|
|
10061
11435
|
}, { json: Boolean(args.json) });
|
|
10062
11436
|
}
|
|
10063
11437
|
});
|
|
10064
|
-
var unblockContext =
|
|
11438
|
+
var unblockContext = defineCommand12({
|
|
10065
11439
|
meta: { name: "unblock-context", description: "Unblock a context" },
|
|
10066
11440
|
args: {
|
|
10067
11441
|
"context-value": { type: "string", description: "Context identifier value", required: true },
|
|
@@ -10088,7 +11462,7 @@ var unblockContext = defineCommand11({
|
|
|
10088
11462
|
}, { json: Boolean(args.json) });
|
|
10089
11463
|
}
|
|
10090
11464
|
});
|
|
10091
|
-
var testDataCommand =
|
|
11465
|
+
var testDataCommand = defineCommand12({
|
|
10092
11466
|
meta: { name: "test-data", description: "Test environment data management (test/demo only)" },
|
|
10093
11467
|
subCommands: {
|
|
10094
11468
|
"create-subject": createSubject,
|
|
@@ -10112,7 +11486,7 @@ var testDataCommand = defineCommand11({
|
|
|
10112
11486
|
});
|
|
10113
11487
|
|
|
10114
11488
|
// src/cli/commands/limits.ts
|
|
10115
|
-
import { defineCommand as
|
|
11489
|
+
import { defineCommand as defineCommand13 } from "citty";
|
|
10116
11490
|
function getGlobalOpts11(args) {
|
|
10117
11491
|
return {
|
|
10118
11492
|
env: args.env,
|
|
@@ -10122,7 +11496,7 @@ function getGlobalOpts11(args) {
|
|
|
10122
11496
|
nip: args.nip
|
|
10123
11497
|
};
|
|
10124
11498
|
}
|
|
10125
|
-
var context =
|
|
11499
|
+
var context = defineCommand13({
|
|
10126
11500
|
meta: { name: "context", description: "View effective context limits" },
|
|
10127
11501
|
args: {
|
|
10128
11502
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -10150,7 +11524,7 @@ var context = defineCommand12({
|
|
|
10150
11524
|
}, { json: Boolean(args.json) });
|
|
10151
11525
|
}
|
|
10152
11526
|
});
|
|
10153
|
-
var subject =
|
|
11527
|
+
var subject = defineCommand13({
|
|
10154
11528
|
meta: { name: "subject", description: "View effective subject limits" },
|
|
10155
11529
|
args: {
|
|
10156
11530
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -10174,7 +11548,7 @@ var subject = defineCommand12({
|
|
|
10174
11548
|
}, { json: Boolean(args.json) });
|
|
10175
11549
|
}
|
|
10176
11550
|
});
|
|
10177
|
-
var rate =
|
|
11551
|
+
var rate = defineCommand13({
|
|
10178
11552
|
meta: { name: "rate", description: "View effective API rate limits" },
|
|
10179
11553
|
args: {
|
|
10180
11554
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -10210,14 +11584,14 @@ var rate = defineCommand12({
|
|
|
10210
11584
|
}, { json: Boolean(args.json) });
|
|
10211
11585
|
}
|
|
10212
11586
|
});
|
|
10213
|
-
var limitsCommand =
|
|
11587
|
+
var limitsCommand = defineCommand13({
|
|
10214
11588
|
meta: { name: "limits", description: "View KSeF API limits" },
|
|
10215
11589
|
subCommands: { context, subject, rate }
|
|
10216
11590
|
});
|
|
10217
11591
|
|
|
10218
11592
|
// src/cli/commands/peppol.ts
|
|
10219
|
-
import { defineCommand as
|
|
10220
|
-
import { consola as
|
|
11593
|
+
import { defineCommand as defineCommand14 } from "citty";
|
|
11594
|
+
import { consola as consola14 } from "consola";
|
|
10221
11595
|
function getGlobalOpts12(args) {
|
|
10222
11596
|
return {
|
|
10223
11597
|
env: args.env,
|
|
@@ -10227,7 +11601,7 @@ function getGlobalOpts12(args) {
|
|
|
10227
11601
|
nip: args.nip
|
|
10228
11602
|
};
|
|
10229
11603
|
}
|
|
10230
|
-
var providers =
|
|
11604
|
+
var providers = defineCommand14({
|
|
10231
11605
|
meta: { name: "providers", description: "Query Peppol providers" },
|
|
10232
11606
|
args: {
|
|
10233
11607
|
page: { type: "string", description: "Page offset" },
|
|
@@ -10266,19 +11640,19 @@ var providers = defineCommand13({
|
|
|
10266
11640
|
{ json: false }
|
|
10267
11641
|
);
|
|
10268
11642
|
if (result.hasMore) {
|
|
10269
|
-
|
|
11643
|
+
consola14.info("More results available. Use --page to paginate.");
|
|
10270
11644
|
}
|
|
10271
11645
|
}, { json: Boolean(args.json) });
|
|
10272
11646
|
}
|
|
10273
11647
|
});
|
|
10274
|
-
var peppolCommand =
|
|
11648
|
+
var peppolCommand = defineCommand14({
|
|
10275
11649
|
meta: { name: "peppol", description: "Peppol integration commands" },
|
|
10276
11650
|
subCommands: { providers }
|
|
10277
11651
|
});
|
|
10278
11652
|
|
|
10279
11653
|
// src/cli/commands/doctor.ts
|
|
10280
|
-
import { defineCommand as
|
|
10281
|
-
import { consola as
|
|
11654
|
+
import { defineCommand as defineCommand15 } from "citty";
|
|
11655
|
+
import { consola as consola15 } from "consola";
|
|
10282
11656
|
function getGlobalOpts13(args) {
|
|
10283
11657
|
return {
|
|
10284
11658
|
env: args.env,
|
|
@@ -10288,7 +11662,7 @@ function getGlobalOpts13(args) {
|
|
|
10288
11662
|
verbose: args.verbose
|
|
10289
11663
|
};
|
|
10290
11664
|
}
|
|
10291
|
-
var doctorCommand =
|
|
11665
|
+
var doctorCommand = defineCommand15({
|
|
10292
11666
|
meta: { name: "doctor", description: "Check CLI configuration and connectivity" },
|
|
10293
11667
|
args: {
|
|
10294
11668
|
env: { type: "string", description: "Environment (test/demo/prod)" },
|
|
@@ -10369,14 +11743,14 @@ var doctorCommand = defineCommand14({
|
|
|
10369
11743
|
}
|
|
10370
11744
|
for (const check of checks) {
|
|
10371
11745
|
const icon = check.status === "pass" ? "\u2713" : check.status === "warn" ? "\u26A0" : "\u2717";
|
|
10372
|
-
const log = check.status === "pass" ?
|
|
11746
|
+
const log = check.status === "pass" ? consola15.success : check.status === "warn" ? consola15.warn : consola15.error;
|
|
10373
11747
|
log(`${icon} ${check.message}`);
|
|
10374
11748
|
}
|
|
10375
11749
|
if (passed === total) {
|
|
10376
|
-
|
|
11750
|
+
consola15.success(`
|
|
10377
11751
|
${passed}/${total} checks passed.`);
|
|
10378
11752
|
} else {
|
|
10379
|
-
|
|
11753
|
+
consola15.warn(`
|
|
10380
11754
|
${passed}/${total} checks passed.`);
|
|
10381
11755
|
}
|
|
10382
11756
|
}, { json: Boolean(args.json) });
|
|
@@ -10384,7 +11758,7 @@ ${passed}/${total} checks passed.`);
|
|
|
10384
11758
|
});
|
|
10385
11759
|
|
|
10386
11760
|
// src/cli/commands/completion.ts
|
|
10387
|
-
import { defineCommand as
|
|
11761
|
+
import { defineCommand as defineCommand16 } from "citty";
|
|
10388
11762
|
var COMMAND_TREE = {
|
|
10389
11763
|
config: ["set", "show", "reset"],
|
|
10390
11764
|
auth: ["challenge", "login", "status", "logout", "refresh", "whoami"],
|
|
@@ -10476,35 +11850,35 @@ function generateFish() {
|
|
|
10476
11850
|
}
|
|
10477
11851
|
return lines.join("\n") + "\n";
|
|
10478
11852
|
}
|
|
10479
|
-
var bash =
|
|
11853
|
+
var bash = defineCommand16({
|
|
10480
11854
|
meta: { name: "bash", description: "Generate bash completion script" },
|
|
10481
11855
|
run() {
|
|
10482
11856
|
console.log(generateBash());
|
|
10483
11857
|
}
|
|
10484
11858
|
});
|
|
10485
|
-
var zsh =
|
|
11859
|
+
var zsh = defineCommand16({
|
|
10486
11860
|
meta: { name: "zsh", description: "Generate zsh completion script" },
|
|
10487
11861
|
run() {
|
|
10488
11862
|
console.log(generateZsh());
|
|
10489
11863
|
}
|
|
10490
11864
|
});
|
|
10491
|
-
var fish =
|
|
11865
|
+
var fish = defineCommand16({
|
|
10492
11866
|
meta: { name: "fish", description: "Generate fish completion script" },
|
|
10493
11867
|
run() {
|
|
10494
11868
|
console.log(generateFish());
|
|
10495
11869
|
}
|
|
10496
11870
|
});
|
|
10497
|
-
var completionCommand =
|
|
11871
|
+
var completionCommand = defineCommand16({
|
|
10498
11872
|
meta: { name: "completion", description: "Generate shell completion scripts" },
|
|
10499
11873
|
subCommands: { bash, zsh, fish }
|
|
10500
11874
|
});
|
|
10501
11875
|
|
|
10502
11876
|
// src/cli/commands/setup.ts
|
|
10503
|
-
import * as
|
|
10504
|
-
import * as
|
|
11877
|
+
import * as fs14 from "fs";
|
|
11878
|
+
import * as path10 from "path";
|
|
10505
11879
|
import * as os5 from "os";
|
|
10506
|
-
import { defineCommand as
|
|
10507
|
-
import { consola as
|
|
11880
|
+
import { defineCommand as defineCommand17 } from "citty";
|
|
11881
|
+
import { consola as consola16 } from "consola";
|
|
10508
11882
|
init_patterns();
|
|
10509
11883
|
init_auth_xml_builder();
|
|
10510
11884
|
init_polling();
|
|
@@ -10533,8 +11907,8 @@ function openFolder(folderPath) {
|
|
|
10533
11907
|
}
|
|
10534
11908
|
|
|
10535
11909
|
// src/cli/commands/setup.ts
|
|
10536
|
-
var KSEF_DIR =
|
|
10537
|
-
var AUTH_XML_FILE =
|
|
11910
|
+
var KSEF_DIR = path10.join(os5.homedir(), ".ksef");
|
|
11911
|
+
var AUTH_XML_FILE = path10.join(KSEF_DIR, "auth.xml");
|
|
10538
11912
|
var SIGNING_URL = "https://podpis.gov.pl/podpisz-dokument-elektronicznie/";
|
|
10539
11913
|
var ALL_PERMISSIONS = [
|
|
10540
11914
|
{ value: "InvoiceRead", label: "InvoiceRead \u2014 Read invoices" },
|
|
@@ -10547,36 +11921,36 @@ var ALL_PERMISSIONS = [
|
|
|
10547
11921
|
];
|
|
10548
11922
|
function expandTilde(p) {
|
|
10549
11923
|
if (p.startsWith("~")) {
|
|
10550
|
-
return
|
|
11924
|
+
return path10.join(os5.homedir(), p.slice(1));
|
|
10551
11925
|
}
|
|
10552
11926
|
return p;
|
|
10553
11927
|
}
|
|
10554
11928
|
async function promptNip() {
|
|
10555
11929
|
while (true) {
|
|
10556
|
-
const nip = await
|
|
11930
|
+
const nip = await consola16.prompt("Enter your NIP (10 digits):", {
|
|
10557
11931
|
type: "text",
|
|
10558
11932
|
cancel: "reject"
|
|
10559
11933
|
});
|
|
10560
11934
|
if (isValidNip(nip.trim())) {
|
|
10561
11935
|
return nip.trim();
|
|
10562
11936
|
}
|
|
10563
|
-
|
|
11937
|
+
consola16.warn("Invalid NIP. Must be a valid 10-digit Polish tax identification number.");
|
|
10564
11938
|
}
|
|
10565
11939
|
}
|
|
10566
11940
|
async function promptSignedXmlPath() {
|
|
10567
11941
|
while (true) {
|
|
10568
|
-
const raw = await
|
|
11942
|
+
const raw = await consola16.prompt("Path to signed XML file:", {
|
|
10569
11943
|
type: "text",
|
|
10570
11944
|
cancel: "reject"
|
|
10571
11945
|
});
|
|
10572
11946
|
const resolved = expandTilde(raw.trim());
|
|
10573
|
-
if (
|
|
11947
|
+
if (fs14.existsSync(resolved)) {
|
|
10574
11948
|
return resolved;
|
|
10575
11949
|
}
|
|
10576
|
-
|
|
11950
|
+
consola16.warn(`File not found: ${resolved}`);
|
|
10577
11951
|
}
|
|
10578
11952
|
}
|
|
10579
|
-
var setupCommand =
|
|
11953
|
+
var setupCommand = defineCommand17({
|
|
10580
11954
|
meta: { name: "setup", description: "Interactive setup wizard for KSeF CLI" },
|
|
10581
11955
|
args: {
|
|
10582
11956
|
env: { type: "string", description: "Environment (test/demo/prod)" }
|
|
@@ -10588,17 +11962,17 @@ var setupCommand = defineCommand16({
|
|
|
10588
11962
|
"Interactive terminal required. Use `ksef auth login-external` and `ksef token generate` for non-interactive setup."
|
|
10589
11963
|
);
|
|
10590
11964
|
}
|
|
10591
|
-
|
|
11965
|
+
consola16.box("KSeF CLI Setup Wizard");
|
|
10592
11966
|
const existingSession = loadSession();
|
|
10593
11967
|
const existingCredentials = loadCredentials();
|
|
10594
11968
|
if (existingSession || existingCredentials?.token) {
|
|
10595
|
-
const overwrite = await
|
|
11969
|
+
const overwrite = await consola16.prompt("An existing session or token was found. Overwrite?", {
|
|
10596
11970
|
type: "confirm",
|
|
10597
11971
|
initial: false,
|
|
10598
11972
|
cancel: "reject"
|
|
10599
11973
|
});
|
|
10600
11974
|
if (!overwrite) {
|
|
10601
|
-
|
|
11975
|
+
consola16.info("Setup cancelled.");
|
|
10602
11976
|
return;
|
|
10603
11977
|
}
|
|
10604
11978
|
}
|
|
@@ -10606,25 +11980,25 @@ var setupCommand = defineCommand16({
|
|
|
10606
11980
|
const env = args.env ?? config.environment;
|
|
10607
11981
|
const nip = await promptNip();
|
|
10608
11982
|
saveConfig({ ...config, nip, environment: env });
|
|
10609
|
-
|
|
11983
|
+
consola16.info(`Config saved: NIP=${nip}, env=${env}`);
|
|
10610
11984
|
const client = createClient({ env });
|
|
10611
11985
|
let useSelfSigned = false;
|
|
10612
11986
|
if (env === "test") {
|
|
10613
|
-
useSelfSigned = await
|
|
11987
|
+
useSelfSigned = await consola16.prompt("Test environment detected. Use self-signed certificate for quick auth?", {
|
|
10614
11988
|
type: "confirm",
|
|
10615
11989
|
initial: true,
|
|
10616
11990
|
cancel: "reject"
|
|
10617
11991
|
});
|
|
10618
11992
|
}
|
|
10619
11993
|
if (useSelfSigned) {
|
|
10620
|
-
|
|
11994
|
+
consola16.info("Generating self-signed certificate...");
|
|
10621
11995
|
const cert = await CertificateService.generateCompanySeal(
|
|
10622
11996
|
"CLI Setup",
|
|
10623
11997
|
`VATPL-${nip}`,
|
|
10624
11998
|
`CLI Setup ${nip}`,
|
|
10625
11999
|
"RSA"
|
|
10626
12000
|
);
|
|
10627
|
-
|
|
12001
|
+
consola16.info("Authenticating with self-signed certificate...");
|
|
10628
12002
|
await client.loginWithCertificate(cert.certificatePem, cert.privateKeyPem, nip);
|
|
10629
12003
|
const session = {
|
|
10630
12004
|
accessToken: client.authManager.getAccessToken(),
|
|
@@ -10636,15 +12010,15 @@ var setupCommand = defineCommand16({
|
|
|
10636
12010
|
} else {
|
|
10637
12011
|
let authenticated = false;
|
|
10638
12012
|
while (!authenticated) {
|
|
10639
|
-
|
|
12013
|
+
consola16.info("Requesting authorization challenge from KSeF...");
|
|
10640
12014
|
const challengeResult = await client.auth.getChallenge();
|
|
10641
12015
|
const unsignedXml = buildUnsignedAuthTokenRequestXml({
|
|
10642
12016
|
challenge: challengeResult.challenge,
|
|
10643
12017
|
contextIdentifier: { type: "Nip", value: nip }
|
|
10644
12018
|
});
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
|
|
12019
|
+
fs14.mkdirSync(KSEF_DIR, { recursive: true });
|
|
12020
|
+
fs14.writeFileSync(AUTH_XML_FILE, unsignedXml, "utf-8");
|
|
12021
|
+
consola16.info(`Unsigned XML saved to ${AUTH_XML_FILE}`);
|
|
10648
12022
|
savePendingChallenge({
|
|
10649
12023
|
challenge: challengeResult.challenge,
|
|
10650
12024
|
timestamp: challengeResult.timestamp,
|
|
@@ -10653,9 +12027,9 @@ var setupCommand = defineCommand16({
|
|
|
10653
12027
|
});
|
|
10654
12028
|
const opened = await openFolder(KSEF_DIR);
|
|
10655
12029
|
if (!opened) {
|
|
10656
|
-
|
|
12030
|
+
consola16.info(`Open the folder manually: ${KSEF_DIR}`);
|
|
10657
12031
|
}
|
|
10658
|
-
|
|
12032
|
+
consola16.box([
|
|
10659
12033
|
"Sign the XML file using a qualified signature:",
|
|
10660
12034
|
"",
|
|
10661
12035
|
` 1. Open: ${SIGNING_URL}`,
|
|
@@ -10664,12 +12038,12 @@ var setupCommand = defineCommand16({
|
|
|
10664
12038
|
" 4. Download the signed XML file"
|
|
10665
12039
|
].join("\n"));
|
|
10666
12040
|
const signedXmlPath = await promptSignedXmlPath();
|
|
10667
|
-
const signedXml =
|
|
12041
|
+
const signedXml = fs14.readFileSync(signedXmlPath, "utf-8");
|
|
10668
12042
|
try {
|
|
10669
|
-
|
|
12043
|
+
consola16.info("Submitting signed XML to KSeF...");
|
|
10670
12044
|
const submitResult = await client.auth.submitXadesAuthRequest(signedXml);
|
|
10671
12045
|
const authToken = submitResult.authenticationToken.token;
|
|
10672
|
-
|
|
12046
|
+
consola16.info("Waiting for authorization...");
|
|
10673
12047
|
await pollUntil(
|
|
10674
12048
|
() => client.auth.getAuthStatus(submitResult.referenceNumber, authToken),
|
|
10675
12049
|
(s) => s.status.code !== 100,
|
|
@@ -10688,36 +12062,36 @@ var setupCommand = defineCommand16({
|
|
|
10688
12062
|
outputSuccess("Authenticated successfully via external signature.");
|
|
10689
12063
|
} catch (error) {
|
|
10690
12064
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10691
|
-
|
|
10692
|
-
const retry = await
|
|
12065
|
+
consola16.error(`Authentication failed: ${msg}`);
|
|
12066
|
+
const retry = await consola16.prompt("Get a new challenge and try again?", {
|
|
10693
12067
|
type: "confirm",
|
|
10694
12068
|
initial: true,
|
|
10695
12069
|
cancel: "reject"
|
|
10696
12070
|
});
|
|
10697
12071
|
if (!retry) {
|
|
10698
|
-
|
|
12072
|
+
consola16.info("Setup incomplete. Your NIP and environment are saved. Run `ksef auth login-external` to authenticate later.");
|
|
10699
12073
|
return;
|
|
10700
12074
|
}
|
|
10701
12075
|
}
|
|
10702
12076
|
}
|
|
10703
12077
|
}
|
|
10704
|
-
const generateToken = await
|
|
12078
|
+
const generateToken = await consola16.prompt("Generate a long-lived API token?", {
|
|
10705
12079
|
type: "confirm",
|
|
10706
12080
|
initial: true,
|
|
10707
12081
|
cancel: "reject"
|
|
10708
12082
|
});
|
|
10709
12083
|
if (generateToken) {
|
|
10710
12084
|
try {
|
|
10711
|
-
const selectedPermissions = await
|
|
12085
|
+
const selectedPermissions = await consola16.prompt("Select token permissions:", {
|
|
10712
12086
|
type: "multiselect",
|
|
10713
12087
|
options: ALL_PERMISSIONS,
|
|
10714
12088
|
cancel: "reject"
|
|
10715
12089
|
});
|
|
10716
12090
|
if (selectedPermissions.length === 0) {
|
|
10717
|
-
|
|
12091
|
+
consola16.warn("No permissions selected. Skipping token generation.");
|
|
10718
12092
|
} else {
|
|
10719
12093
|
const defaultDescription = `KSeF CLI API Token ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
10720
|
-
const description = await
|
|
12094
|
+
const description = await consola16.prompt(`Token description (${defaultDescription}):`, {
|
|
10721
12095
|
type: "text",
|
|
10722
12096
|
default: defaultDescription,
|
|
10723
12097
|
cancel: "reject"
|
|
@@ -10739,19 +12113,19 @@ var setupCommand = defineCommand16({
|
|
|
10739
12113
|
environment: env
|
|
10740
12114
|
};
|
|
10741
12115
|
saveSession(newSession);
|
|
10742
|
-
|
|
12116
|
+
consola16.info("Re-authenticated with generated token.");
|
|
10743
12117
|
} catch {
|
|
10744
|
-
|
|
12118
|
+
consola16.warn("Token saved but re-login failed. Run `ksef auth login` to authenticate with the stored token.");
|
|
10745
12119
|
}
|
|
10746
12120
|
}
|
|
10747
12121
|
} catch (error) {
|
|
10748
12122
|
const msg = error instanceof Error ? error.message : String(error);
|
|
10749
|
-
|
|
10750
|
-
|
|
12123
|
+
consola16.error(`Token generation failed: ${msg}`);
|
|
12124
|
+
consola16.info("Your session is still active. Run `ksef token generate` to create a token later.");
|
|
10751
12125
|
}
|
|
10752
12126
|
}
|
|
10753
12127
|
const finalCredentials = loadCredentials();
|
|
10754
|
-
|
|
12128
|
+
consola16.box([
|
|
10755
12129
|
"Setup complete!",
|
|
10756
12130
|
"",
|
|
10757
12131
|
` Environment: ${env}`,
|
|
@@ -10769,13 +12143,13 @@ var setupCommand = defineCommand16({
|
|
|
10769
12143
|
});
|
|
10770
12144
|
|
|
10771
12145
|
// src/cli/commands/offline.ts
|
|
10772
|
-
import * as
|
|
10773
|
-
import { defineCommand as
|
|
10774
|
-
import { consola as
|
|
12146
|
+
import * as fs16 from "fs";
|
|
12147
|
+
import { defineCommand as defineCommand18 } from "citty";
|
|
12148
|
+
import { consola as consola17 } from "consola";
|
|
10775
12149
|
|
|
10776
12150
|
// src/offline/file-storage.ts
|
|
10777
|
-
import * as
|
|
10778
|
-
import * as
|
|
12151
|
+
import * as fs15 from "fs/promises";
|
|
12152
|
+
import * as path11 from "path";
|
|
10779
12153
|
import * as os6 from "os";
|
|
10780
12154
|
|
|
10781
12155
|
// src/offline/storage.ts
|
|
@@ -10796,7 +12170,7 @@ function matchesFilter(invoice3, filter) {
|
|
|
10796
12170
|
// src/offline/file-storage.ts
|
|
10797
12171
|
function resolveDir(dir) {
|
|
10798
12172
|
if (dir === "~" || dir.startsWith("~/")) {
|
|
10799
|
-
return
|
|
12173
|
+
return path11.join(os6.homedir(), dir.slice(1));
|
|
10800
12174
|
}
|
|
10801
12175
|
return dir;
|
|
10802
12176
|
}
|
|
@@ -10812,23 +12186,23 @@ var FileOfflineInvoiceStorage = class {
|
|
|
10812
12186
|
this.dir = resolveDir(directory ?? "~/.ksef/offline");
|
|
10813
12187
|
}
|
|
10814
12188
|
async ensureDir() {
|
|
10815
|
-
await
|
|
12189
|
+
await fs15.mkdir(this.dir, { recursive: true });
|
|
10816
12190
|
}
|
|
10817
12191
|
filePath(id) {
|
|
10818
12192
|
validateId(id);
|
|
10819
|
-
return
|
|
12193
|
+
return path11.join(this.dir, `${id}.json`);
|
|
10820
12194
|
}
|
|
10821
12195
|
async save(invoice3) {
|
|
10822
12196
|
await this.ensureDir();
|
|
10823
12197
|
const file = this.filePath(invoice3.id);
|
|
10824
12198
|
const tmp = `${file}.tmp`;
|
|
10825
|
-
await
|
|
10826
|
-
await
|
|
12199
|
+
await fs15.writeFile(tmp, JSON.stringify(invoice3, null, 2));
|
|
12200
|
+
await fs15.rename(tmp, file);
|
|
10827
12201
|
}
|
|
10828
12202
|
async get(id) {
|
|
10829
12203
|
const file = this.filePath(id);
|
|
10830
12204
|
try {
|
|
10831
|
-
return JSON.parse(await
|
|
12205
|
+
return JSON.parse(await fs15.readFile(file, "utf-8"));
|
|
10832
12206
|
} catch (err) {
|
|
10833
12207
|
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
10834
12208
|
return null;
|
|
@@ -10840,7 +12214,7 @@ var FileOfflineInvoiceStorage = class {
|
|
|
10840
12214
|
async list(filter) {
|
|
10841
12215
|
let files;
|
|
10842
12216
|
try {
|
|
10843
|
-
files = (await
|
|
12217
|
+
files = (await fs15.readdir(this.dir)).filter((f) => f.endsWith(".json"));
|
|
10844
12218
|
} catch {
|
|
10845
12219
|
return [];
|
|
10846
12220
|
}
|
|
@@ -10848,7 +12222,7 @@ var FileOfflineInvoiceStorage = class {
|
|
|
10848
12222
|
for (const file of files) {
|
|
10849
12223
|
try {
|
|
10850
12224
|
const data = JSON.parse(
|
|
10851
|
-
await
|
|
12225
|
+
await fs15.readFile(path11.join(this.dir, file), "utf-8")
|
|
10852
12226
|
);
|
|
10853
12227
|
if (!filter || matchesFilter(data, filter)) {
|
|
10854
12228
|
results.push(data);
|
|
@@ -10874,7 +12248,7 @@ var FileOfflineInvoiceStorage = class {
|
|
|
10874
12248
|
async delete(id) {
|
|
10875
12249
|
const file = this.filePath(id);
|
|
10876
12250
|
try {
|
|
10877
|
-
await
|
|
12251
|
+
await fs15.unlink(file);
|
|
10878
12252
|
} catch (e) {
|
|
10879
12253
|
if (e instanceof Error && "code" in e && e.code !== "ENOENT") throw e;
|
|
10880
12254
|
}
|
|
@@ -10903,7 +12277,7 @@ var globalArgs = {
|
|
|
10903
12277
|
nip: { type: "string", description: "NIP number" },
|
|
10904
12278
|
"store-dir": { type: "string", description: "Offline invoice store directory" }
|
|
10905
12279
|
};
|
|
10906
|
-
var generate3 =
|
|
12280
|
+
var generate3 = defineCommand18({
|
|
10907
12281
|
meta: { name: "generate", description: "Generate offline invoice metadata with QR codes" },
|
|
10908
12282
|
args: {
|
|
10909
12283
|
...globalArgs,
|
|
@@ -10922,10 +12296,10 @@ var generate3 = defineCommand17({
|
|
|
10922
12296
|
const globalOpts = getGlobalOpts14(args);
|
|
10923
12297
|
const config = loadConfig();
|
|
10924
12298
|
const xmlPath = args.xml;
|
|
10925
|
-
if (!
|
|
12299
|
+
if (!fs16.existsSync(xmlPath)) {
|
|
10926
12300
|
throw new Error(`File not found: ${xmlPath}`);
|
|
10927
12301
|
}
|
|
10928
|
-
const invoiceXml =
|
|
12302
|
+
const invoiceXml = fs16.readFileSync(xmlPath, "utf-8");
|
|
10929
12303
|
const sellerNip = args.nip ?? config.nip;
|
|
10930
12304
|
if (!sellerNip) {
|
|
10931
12305
|
throw new Error("NIP is required. Use --nip or set via `ksef config set --nip`");
|
|
@@ -10938,7 +12312,7 @@ var generate3 = defineCommand17({
|
|
|
10938
12312
|
throw new Error("--cert-serial is required when using --key");
|
|
10939
12313
|
}
|
|
10940
12314
|
const certificate2 = args.key ? {
|
|
10941
|
-
privateKeyPem:
|
|
12315
|
+
privateKeyPem: fs16.readFileSync(args.key, "utf-8"),
|
|
10942
12316
|
certificateSerial: args["cert-serial"]
|
|
10943
12317
|
} : void 0;
|
|
10944
12318
|
const validModes = ["offline24", "offline", "awaryjny", "awaria_calkowita"];
|
|
@@ -10964,7 +12338,7 @@ var generate3 = defineCommand17({
|
|
|
10964
12338
|
);
|
|
10965
12339
|
if (args["qr-out"]) {
|
|
10966
12340
|
const outDir = args["qr-out"];
|
|
10967
|
-
|
|
12341
|
+
fs16.mkdirSync(outDir, { recursive: true });
|
|
10968
12342
|
const format = args["qr-format"] ?? "png";
|
|
10969
12343
|
if (format !== "png" && format !== "svg") {
|
|
10970
12344
|
throw new Error(`Invalid --qr-format "${format}". Must be one of: png, svg`);
|
|
@@ -10972,17 +12346,17 @@ var generate3 = defineCommand17({
|
|
|
10972
12346
|
const shortId = metadata.id.slice(0, 8);
|
|
10973
12347
|
if (format === "svg") {
|
|
10974
12348
|
const svg1 = await QrCodeService.generateQrCodeSvgWithLabel(metadata.kod1Url, "OFFLINE");
|
|
10975
|
-
|
|
12349
|
+
fs16.writeFileSync(`${outDir}/${shortId}-kod1.svg`, svg1);
|
|
10976
12350
|
if (metadata.kod2Url) {
|
|
10977
12351
|
const svg2 = await QrCodeService.generateQrCodeSvgWithLabel(metadata.kod2Url, "CERTYFIKAT");
|
|
10978
|
-
|
|
12352
|
+
fs16.writeFileSync(`${outDir}/${shortId}-kod2.svg`, svg2);
|
|
10979
12353
|
}
|
|
10980
12354
|
} else {
|
|
10981
12355
|
const png1 = await QrCodeService.generateQrCode(metadata.kod1Url);
|
|
10982
|
-
|
|
12356
|
+
fs16.writeFileSync(`${outDir}/${shortId}-kod1.png`, png1);
|
|
10983
12357
|
if (metadata.kod2Url) {
|
|
10984
12358
|
const png2 = await QrCodeService.generateQrCode(metadata.kod2Url);
|
|
10985
|
-
|
|
12359
|
+
fs16.writeFileSync(`${outDir}/${shortId}-kod2.png`, png2);
|
|
10986
12360
|
}
|
|
10987
12361
|
}
|
|
10988
12362
|
outputSuccess(`QR codes saved to ${outDir}/`);
|
|
@@ -11005,7 +12379,7 @@ var generate3 = defineCommand17({
|
|
|
11005
12379
|
}, { json: Boolean(args.json) });
|
|
11006
12380
|
}
|
|
11007
12381
|
});
|
|
11008
|
-
var list4 =
|
|
12382
|
+
var list4 = defineCommand18({
|
|
11009
12383
|
meta: { name: "list", description: "List stored offline invoices" },
|
|
11010
12384
|
args: {
|
|
11011
12385
|
...globalArgs,
|
|
@@ -11054,7 +12428,7 @@ var list4 = defineCommand17({
|
|
|
11054
12428
|
}, { json: Boolean(args.json) });
|
|
11055
12429
|
}
|
|
11056
12430
|
});
|
|
11057
|
-
var status6 =
|
|
12431
|
+
var status6 = defineCommand18({
|
|
11058
12432
|
meta: { name: "status", description: "Show offline invoice details" },
|
|
11059
12433
|
args: {
|
|
11060
12434
|
...globalArgs,
|
|
@@ -11090,7 +12464,7 @@ var status6 = defineCommand17({
|
|
|
11090
12464
|
}, { json: Boolean(args.json) });
|
|
11091
12465
|
}
|
|
11092
12466
|
});
|
|
11093
|
-
var submit =
|
|
12467
|
+
var submit = defineCommand18({
|
|
11094
12468
|
meta: { name: "submit", description: "Submit offline invoices to KSeF" },
|
|
11095
12469
|
args: {
|
|
11096
12470
|
...globalArgs,
|
|
@@ -11146,7 +12520,7 @@ var submit = defineCommand17({
|
|
|
11146
12520
|
}, { json: Boolean(args.json) });
|
|
11147
12521
|
}
|
|
11148
12522
|
});
|
|
11149
|
-
var correct =
|
|
12523
|
+
var correct = defineCommand18({
|
|
11150
12524
|
meta: { name: "correct", description: "Technical correction for rejected offline invoice" },
|
|
11151
12525
|
args: {
|
|
11152
12526
|
...globalArgs,
|
|
@@ -11159,10 +12533,10 @@ var correct = defineCommand17({
|
|
|
11159
12533
|
const { client } = await requireSession(globalOpts);
|
|
11160
12534
|
const storage = getStorage(args);
|
|
11161
12535
|
const xmlPath = args.xml;
|
|
11162
|
-
if (!
|
|
12536
|
+
if (!fs16.existsSync(xmlPath)) {
|
|
11163
12537
|
throw new Error(`File not found: ${xmlPath}`);
|
|
11164
12538
|
}
|
|
11165
|
-
const correctedXml =
|
|
12539
|
+
const correctedXml = fs16.readFileSync(xmlPath, "utf-8");
|
|
11166
12540
|
const result = await client.offline.correct(client, {
|
|
11167
12541
|
rejectedInvoiceId: args.id,
|
|
11168
12542
|
correctedInvoiceXml: correctedXml,
|
|
@@ -11176,7 +12550,7 @@ var correct = defineCommand17({
|
|
|
11176
12550
|
}, { json: Boolean(args.json) });
|
|
11177
12551
|
}
|
|
11178
12552
|
});
|
|
11179
|
-
var del =
|
|
12553
|
+
var del = defineCommand18({
|
|
11180
12554
|
meta: { name: "delete", description: "Delete offline invoice from local store" },
|
|
11181
12555
|
args: {
|
|
11182
12556
|
...globalArgs,
|
|
@@ -11199,12 +12573,12 @@ var del = defineCommand17({
|
|
|
11199
12573
|
`${expired.length} expired invoice(s) would be deleted. Use --force to confirm in non-interactive mode.`
|
|
11200
12574
|
);
|
|
11201
12575
|
}
|
|
11202
|
-
const confirmed = await
|
|
12576
|
+
const confirmed = await consola17.prompt(
|
|
11203
12577
|
`Delete ${expired.length} expired invoice(s)?`,
|
|
11204
12578
|
{ type: "confirm", initial: false }
|
|
11205
12579
|
);
|
|
11206
12580
|
if (!confirmed) {
|
|
11207
|
-
|
|
12581
|
+
consola17.info("Cancelled.");
|
|
11208
12582
|
return;
|
|
11209
12583
|
}
|
|
11210
12584
|
}
|
|
@@ -11226,16 +12600,16 @@ var del = defineCommand17({
|
|
|
11226
12600
|
}, { json: Boolean(args.json) });
|
|
11227
12601
|
}
|
|
11228
12602
|
});
|
|
11229
|
-
var offlineCommand =
|
|
12603
|
+
var offlineCommand = defineCommand18({
|
|
11230
12604
|
meta: { name: "offline", description: "Offline invoice management" },
|
|
11231
12605
|
subCommands: { generate: generate3, list: list4, status: status6, submit, correct, delete: del }
|
|
11232
12606
|
});
|
|
11233
12607
|
|
|
11234
12608
|
// src/cli/index.ts
|
|
11235
|
-
var __dirname =
|
|
11236
|
-
var pkg = JSON.parse(
|
|
12609
|
+
var __dirname = dirname3(fileURLToPath2(import.meta.url));
|
|
12610
|
+
var pkg = JSON.parse(readFileSync11(resolve(__dirname, "..", "package.json"), "utf-8"));
|
|
11237
12611
|
var version = pkg.version;
|
|
11238
|
-
var main =
|
|
12612
|
+
var main = defineCommand19({
|
|
11239
12613
|
meta: {
|
|
11240
12614
|
name: "ksef",
|
|
11241
12615
|
version,
|