ksef-client-ts 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/cli.js +970 -248
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1087 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +330 -17
- package/dist/index.d.ts +330 -17
- package/dist/index.js +1062 -78
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -43,7 +43,8 @@ function resolveOptions(options = {}) {
|
|
|
43
43
|
apiVersion: options.apiVersion ?? DEFAULT_API_VERSION,
|
|
44
44
|
timeout: options.timeout ?? DEFAULT_TIMEOUT,
|
|
45
45
|
customHeaders: options.customHeaders ?? {},
|
|
46
|
-
environmentName: options.environment ?? (options.baseUrl ? void 0 : "TEST")
|
|
46
|
+
environmentName: options.environment ?? (options.baseUrl ? void 0 : "TEST"),
|
|
47
|
+
errorFormat: options.errorFormat ?? "problem-details"
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
var DEFAULT_API_VERSION, DEFAULT_TIMEOUT;
|
|
@@ -99,6 +100,9 @@ var init_ksef_api_error = __esm({
|
|
|
99
100
|
const message = details?.length ? details.map((d) => d.exceptionDescription ?? "").filter(Boolean).join("; ") || `KSeF API error: HTTP ${statusCode}` : `KSeF API error: HTTP ${statusCode}`;
|
|
100
101
|
return new _KSeFApiError(message, statusCode, body);
|
|
101
102
|
}
|
|
103
|
+
toProblemFields() {
|
|
104
|
+
return { detail: this.message };
|
|
105
|
+
}
|
|
102
106
|
};
|
|
103
107
|
}
|
|
104
108
|
});
|
|
@@ -110,17 +114,20 @@ var init_ksef_rate_limit_error = __esm({
|
|
|
110
114
|
"use strict";
|
|
111
115
|
init_ksef_api_error();
|
|
112
116
|
KSeFRateLimitError = class _KSeFRateLimitError extends KSeFApiError {
|
|
117
|
+
statusCode = 429;
|
|
113
118
|
retryAfterSeconds;
|
|
114
119
|
retryAfterDate;
|
|
115
120
|
recommendedDelay;
|
|
116
|
-
|
|
121
|
+
problem;
|
|
122
|
+
constructor(message, statusCode, errorResponse, retryAfterSeconds, retryAfterDate, problem) {
|
|
117
123
|
super(message, statusCode, errorResponse);
|
|
118
124
|
this.name = "KSeFRateLimitError";
|
|
119
125
|
this.retryAfterSeconds = retryAfterSeconds;
|
|
120
126
|
this.retryAfterDate = retryAfterDate;
|
|
121
127
|
this.recommendedDelay = retryAfterSeconds ?? 60;
|
|
128
|
+
this.problem = problem;
|
|
122
129
|
}
|
|
123
|
-
static fromRetryAfterHeader(statusCode, retryAfterHeader, body) {
|
|
130
|
+
static fromRetryAfterHeader(statusCode, retryAfterHeader, body, problem) {
|
|
124
131
|
let retryAfterSeconds;
|
|
125
132
|
let retryAfterDate;
|
|
126
133
|
if (retryAfterHeader) {
|
|
@@ -135,8 +142,16 @@ var init_ksef_rate_limit_error = __esm({
|
|
|
135
142
|
}
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
|
-
const message = retryAfterSeconds != null ? `Rate limited. Retry after ${retryAfterSeconds}s` : "Rate limited by KSeF API";
|
|
139
|
-
return new _KSeFRateLimitError(message, statusCode, body, retryAfterSeconds, retryAfterDate);
|
|
145
|
+
const message = retryAfterSeconds != null ? `Rate limited. Retry after ${retryAfterSeconds}s` : problem?.detail ?? "Rate limited by KSeF API";
|
|
146
|
+
return new _KSeFRateLimitError(message, statusCode, body, retryAfterSeconds, retryAfterDate, problem);
|
|
147
|
+
}
|
|
148
|
+
toProblemFields() {
|
|
149
|
+
return {
|
|
150
|
+
detail: this.problem?.detail,
|
|
151
|
+
traceId: this.problem?.traceId,
|
|
152
|
+
instance: this.problem?.instance,
|
|
153
|
+
timestamp: this.problem?.timestamp
|
|
154
|
+
};
|
|
140
155
|
}
|
|
141
156
|
};
|
|
142
157
|
}
|
|
@@ -147,18 +162,28 @@ var KSeFUnauthorizedError;
|
|
|
147
162
|
var init_ksef_unauthorized_error = __esm({
|
|
148
163
|
"src/errors/ksef-unauthorized-error.ts"() {
|
|
149
164
|
"use strict";
|
|
150
|
-
|
|
151
|
-
KSeFUnauthorizedError = class extends
|
|
165
|
+
init_ksef_api_error();
|
|
166
|
+
KSeFUnauthorizedError = class extends KSeFApiError {
|
|
152
167
|
statusCode = 401;
|
|
153
168
|
detail;
|
|
154
169
|
traceId;
|
|
155
170
|
instance;
|
|
171
|
+
timestamp;
|
|
156
172
|
constructor(problemDetails) {
|
|
157
|
-
super(problemDetails.detail || "Unauthorized");
|
|
173
|
+
super(problemDetails.detail || "Unauthorized", 401);
|
|
158
174
|
this.name = "KSeFUnauthorizedError";
|
|
159
175
|
this.detail = problemDetails.detail;
|
|
160
176
|
this.traceId = problemDetails.traceId;
|
|
161
177
|
this.instance = problemDetails.instance;
|
|
178
|
+
this.timestamp = problemDetails.timestamp;
|
|
179
|
+
}
|
|
180
|
+
toProblemFields() {
|
|
181
|
+
return {
|
|
182
|
+
detail: this.detail,
|
|
183
|
+
traceId: this.traceId,
|
|
184
|
+
instance: this.instance,
|
|
185
|
+
timestamp: this.timestamp
|
|
186
|
+
};
|
|
162
187
|
}
|
|
163
188
|
};
|
|
164
189
|
}
|
|
@@ -169,22 +194,101 @@ var KSeFForbiddenError;
|
|
|
169
194
|
var init_ksef_forbidden_error = __esm({
|
|
170
195
|
"src/errors/ksef-forbidden-error.ts"() {
|
|
171
196
|
"use strict";
|
|
172
|
-
|
|
173
|
-
KSeFForbiddenError = class extends
|
|
197
|
+
init_ksef_api_error();
|
|
198
|
+
KSeFForbiddenError = class extends KSeFApiError {
|
|
174
199
|
statusCode = 403;
|
|
175
200
|
detail;
|
|
176
201
|
reasonCode;
|
|
177
202
|
instance;
|
|
178
203
|
security;
|
|
179
204
|
traceId;
|
|
205
|
+
timestamp;
|
|
180
206
|
constructor(problemDetails) {
|
|
181
|
-
super(problemDetails.detail || "Forbidden");
|
|
207
|
+
super(problemDetails.detail || "Forbidden", 403);
|
|
182
208
|
this.name = "KSeFForbiddenError";
|
|
183
209
|
this.detail = problemDetails.detail;
|
|
184
210
|
this.reasonCode = problemDetails.reasonCode;
|
|
185
211
|
this.instance = problemDetails.instance;
|
|
186
212
|
this.security = problemDetails.security;
|
|
187
213
|
this.traceId = problemDetails.traceId;
|
|
214
|
+
this.timestamp = problemDetails.timestamp;
|
|
215
|
+
}
|
|
216
|
+
toProblemFields() {
|
|
217
|
+
return {
|
|
218
|
+
detail: this.detail,
|
|
219
|
+
reasonCode: this.reasonCode,
|
|
220
|
+
security: this.security,
|
|
221
|
+
traceId: this.traceId,
|
|
222
|
+
instance: this.instance,
|
|
223
|
+
timestamp: this.timestamp
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// src/errors/ksef-gone-error.ts
|
|
231
|
+
var KSeFGoneError;
|
|
232
|
+
var init_ksef_gone_error = __esm({
|
|
233
|
+
"src/errors/ksef-gone-error.ts"() {
|
|
234
|
+
"use strict";
|
|
235
|
+
init_ksef_api_error();
|
|
236
|
+
KSeFGoneError = class extends KSeFApiError {
|
|
237
|
+
statusCode = 410;
|
|
238
|
+
detail;
|
|
239
|
+
instance;
|
|
240
|
+
traceId;
|
|
241
|
+
timestamp;
|
|
242
|
+
constructor(problemDetails) {
|
|
243
|
+
super(problemDetails.detail || "Operation status no longer available (retention expired)", 410);
|
|
244
|
+
this.name = "KSeFGoneError";
|
|
245
|
+
this.detail = problemDetails.detail;
|
|
246
|
+
this.instance = problemDetails.instance;
|
|
247
|
+
this.traceId = problemDetails.traceId;
|
|
248
|
+
this.timestamp = problemDetails.timestamp;
|
|
249
|
+
}
|
|
250
|
+
toProblemFields() {
|
|
251
|
+
return {
|
|
252
|
+
detail: this.detail,
|
|
253
|
+
traceId: this.traceId,
|
|
254
|
+
instance: this.instance,
|
|
255
|
+
timestamp: this.timestamp
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// src/errors/ksef-bad-request-error.ts
|
|
263
|
+
var KSeFBadRequestError;
|
|
264
|
+
var init_ksef_bad_request_error = __esm({
|
|
265
|
+
"src/errors/ksef-bad-request-error.ts"() {
|
|
266
|
+
"use strict";
|
|
267
|
+
init_ksef_api_error();
|
|
268
|
+
KSeFBadRequestError = class extends KSeFApiError {
|
|
269
|
+
statusCode = 400;
|
|
270
|
+
detail;
|
|
271
|
+
instance;
|
|
272
|
+
errors;
|
|
273
|
+
traceId;
|
|
274
|
+
timestamp;
|
|
275
|
+
constructor(problemDetails) {
|
|
276
|
+
super(problemDetails.detail || problemDetails.title || "Bad Request", 400);
|
|
277
|
+
this.name = "KSeFBadRequestError";
|
|
278
|
+
this.detail = problemDetails.detail;
|
|
279
|
+
this.instance = problemDetails.instance;
|
|
280
|
+
this.errors = problemDetails.errors ?? [];
|
|
281
|
+
this.traceId = problemDetails.traceId;
|
|
282
|
+
this.timestamp = problemDetails.timestamp;
|
|
283
|
+
}
|
|
284
|
+
toProblemFields() {
|
|
285
|
+
return {
|
|
286
|
+
detail: this.detail,
|
|
287
|
+
errors: this.errors.length ? this.errors : void 0,
|
|
288
|
+
traceId: this.traceId,
|
|
289
|
+
instance: this.instance,
|
|
290
|
+
timestamp: this.timestamp
|
|
291
|
+
};
|
|
188
292
|
}
|
|
189
293
|
};
|
|
190
294
|
}
|
|
@@ -252,6 +356,55 @@ var init_ksef_validation_error = __esm({
|
|
|
252
356
|
}
|
|
253
357
|
});
|
|
254
358
|
|
|
359
|
+
// src/errors/error-codes.ts
|
|
360
|
+
function hasErrorCode(body, code) {
|
|
361
|
+
return !!body?.exception?.exceptionDetailList?.some((d) => d.exceptionCode === code);
|
|
362
|
+
}
|
|
363
|
+
var KSeFErrorCode;
|
|
364
|
+
var init_error_codes = __esm({
|
|
365
|
+
"src/errors/error-codes.ts"() {
|
|
366
|
+
"use strict";
|
|
367
|
+
KSeFErrorCode = {
|
|
368
|
+
BatchTimeout: 21208,
|
|
369
|
+
DuplicateInvoice: 440
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// src/errors/ksef-batch-timeout-error.ts
|
|
375
|
+
var KSeFBatchTimeoutError;
|
|
376
|
+
var init_ksef_batch_timeout_error = __esm({
|
|
377
|
+
"src/errors/ksef-batch-timeout-error.ts"() {
|
|
378
|
+
"use strict";
|
|
379
|
+
init_ksef_api_error();
|
|
380
|
+
init_error_codes();
|
|
381
|
+
KSeFBatchTimeoutError = class _KSeFBatchTimeoutError extends KSeFApiError {
|
|
382
|
+
errorCode = KSeFErrorCode.BatchTimeout;
|
|
383
|
+
constructor(message, statusCode, errorResponse) {
|
|
384
|
+
super(message, statusCode, errorResponse);
|
|
385
|
+
this.name = "KSeFBatchTimeoutError";
|
|
386
|
+
}
|
|
387
|
+
static fromResponse(statusCode, body) {
|
|
388
|
+
const detail = body?.exception?.exceptionDetailList?.find(
|
|
389
|
+
(d) => d.exceptionCode === KSeFErrorCode.BatchTimeout
|
|
390
|
+
);
|
|
391
|
+
const message = detail?.exceptionDescription?.trim() || "Batch session timed out before the server completed processing (KSeF 21208).";
|
|
392
|
+
return new _KSeFBatchTimeoutError(message, statusCode, body);
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// src/errors/assert-never.ts
|
|
399
|
+
function assertNever(value) {
|
|
400
|
+
throw new Error(`Unexpected value: ${String(value)}`);
|
|
401
|
+
}
|
|
402
|
+
var init_assert_never = __esm({
|
|
403
|
+
"src/errors/assert-never.ts"() {
|
|
404
|
+
"use strict";
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
|
|
255
408
|
// src/errors/index.ts
|
|
256
409
|
var init_errors = __esm({
|
|
257
410
|
"src/errors/index.ts"() {
|
|
@@ -261,9 +414,14 @@ var init_errors = __esm({
|
|
|
261
414
|
init_ksef_rate_limit_error();
|
|
262
415
|
init_ksef_unauthorized_error();
|
|
263
416
|
init_ksef_forbidden_error();
|
|
417
|
+
init_ksef_gone_error();
|
|
418
|
+
init_ksef_bad_request_error();
|
|
264
419
|
init_ksef_auth_status_error();
|
|
265
420
|
init_ksef_session_expired_error();
|
|
266
421
|
init_ksef_validation_error();
|
|
422
|
+
init_ksef_batch_timeout_error();
|
|
423
|
+
init_error_codes();
|
|
424
|
+
init_assert_never();
|
|
267
425
|
}
|
|
268
426
|
});
|
|
269
427
|
|
|
@@ -512,6 +670,27 @@ var init_presigned_url_policy = __esm({
|
|
|
512
670
|
|
|
513
671
|
// src/http/rest-client.ts
|
|
514
672
|
import { consola } from "consola";
|
|
673
|
+
function isBadRequestProblem(value) {
|
|
674
|
+
if (typeof value !== "object" || value === null) return false;
|
|
675
|
+
const v = value;
|
|
676
|
+
if (typeof v.title !== "string") return false;
|
|
677
|
+
if (v.status !== void 0 && typeof v.status !== "number") return false;
|
|
678
|
+
if (v.errors !== void 0) {
|
|
679
|
+
if (!Array.isArray(v.errors)) return false;
|
|
680
|
+
for (const item of v.errors) {
|
|
681
|
+
if (typeof item !== "object" || item === null) return false;
|
|
682
|
+
const detail = item;
|
|
683
|
+
if (typeof detail.code !== "number") return false;
|
|
684
|
+
if (typeof detail.description !== "string") return false;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return true;
|
|
688
|
+
}
|
|
689
|
+
function isTooManyRequestsProblem(value) {
|
|
690
|
+
if (typeof value !== "object" || value === null) return false;
|
|
691
|
+
const v = value;
|
|
692
|
+
return typeof v.title === "string" && (v.status === void 0 || typeof v.status === "number") && (v.detail === void 0 || typeof v.detail === "string") && (v.instance === void 0 || typeof v.instance === "string") && (v.traceId === void 0 || typeof v.traceId === "string") && (v.timestamp === void 0 || typeof v.timestamp === "string");
|
|
693
|
+
}
|
|
515
694
|
var RestClient;
|
|
516
695
|
var init_rest_client = __esm({
|
|
517
696
|
"src/http/rest-client.ts"() {
|
|
@@ -520,6 +699,10 @@ var init_rest_client = __esm({
|
|
|
520
699
|
init_ksef_rate_limit_error();
|
|
521
700
|
init_ksef_unauthorized_error();
|
|
522
701
|
init_ksef_forbidden_error();
|
|
702
|
+
init_ksef_gone_error();
|
|
703
|
+
init_ksef_bad_request_error();
|
|
704
|
+
init_ksef_batch_timeout_error();
|
|
705
|
+
init_error_codes();
|
|
523
706
|
init_route_builder();
|
|
524
707
|
init_transport();
|
|
525
708
|
init_retry_policy();
|
|
@@ -606,6 +789,10 @@ var init_rest_client = __esm({
|
|
|
606
789
|
...this.options.customHeaders,
|
|
607
790
|
...request.getHeaders()
|
|
608
791
|
};
|
|
792
|
+
const hasHeader = (name) => Object.keys(headers).some((header) => header.toLowerCase() === name.toLowerCase());
|
|
793
|
+
if (this.options.errorFormat !== "legacy" && !hasHeader("x-error-format")) {
|
|
794
|
+
headers["X-Error-Format"] = "problem-details";
|
|
795
|
+
}
|
|
609
796
|
if (!headers["Authorization"] && this.authManager) {
|
|
610
797
|
const token = overrideToken ?? this.authManager.getAccessToken();
|
|
611
798
|
if (token) {
|
|
@@ -644,34 +831,70 @@ var init_rest_client = __esm({
|
|
|
644
831
|
async ensureSuccess(response) {
|
|
645
832
|
if (response.ok) return;
|
|
646
833
|
const text = await response.text().catch(() => "");
|
|
834
|
+
let jsonCache = null;
|
|
647
835
|
const parseJson = () => {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
836
|
+
if (jsonCache === null) {
|
|
837
|
+
try {
|
|
838
|
+
jsonCache = { value: JSON.parse(text) };
|
|
839
|
+
} catch {
|
|
840
|
+
jsonCache = { value: void 0 };
|
|
841
|
+
}
|
|
652
842
|
}
|
|
843
|
+
return jsonCache.value;
|
|
653
844
|
};
|
|
654
|
-
|
|
845
|
+
const tryParseProblem = (guard) => {
|
|
655
846
|
const parsed = parseJson();
|
|
847
|
+
return parsed !== void 0 && guard(parsed) ? parsed : void 0;
|
|
848
|
+
};
|
|
849
|
+
if (response.status === 400) {
|
|
850
|
+
const problem = tryParseProblem(isBadRequestProblem);
|
|
851
|
+
if (problem) {
|
|
852
|
+
throw new KSeFBadRequestError(problem);
|
|
853
|
+
}
|
|
854
|
+
const legacy = parseJson();
|
|
855
|
+
if (hasErrorCode(legacy, KSeFErrorCode.BatchTimeout)) {
|
|
856
|
+
throw KSeFBatchTimeoutError.fromResponse(400, legacy);
|
|
857
|
+
}
|
|
858
|
+
throw KSeFApiError.fromResponse(400, legacy);
|
|
859
|
+
}
|
|
860
|
+
if (response.status === 429) {
|
|
861
|
+
const problem = tryParseProblem(isTooManyRequestsProblem);
|
|
862
|
+
const legacy = problem ? void 0 : parseJson();
|
|
656
863
|
throw KSeFRateLimitError.fromRetryAfterHeader(
|
|
657
864
|
response.status,
|
|
658
865
|
response.headers.get("Retry-After"),
|
|
659
|
-
|
|
866
|
+
legacy,
|
|
867
|
+
problem
|
|
660
868
|
);
|
|
661
869
|
}
|
|
662
870
|
if (response.status === 401) {
|
|
663
|
-
const
|
|
664
|
-
if (
|
|
665
|
-
throw new KSeFUnauthorizedError(
|
|
871
|
+
const body2 = parseJson();
|
|
872
|
+
if (body2?.detail) {
|
|
873
|
+
throw new KSeFUnauthorizedError(body2);
|
|
666
874
|
}
|
|
667
875
|
}
|
|
668
876
|
if (response.status === 403) {
|
|
669
|
-
const
|
|
670
|
-
if (
|
|
671
|
-
throw new KSeFForbiddenError(
|
|
877
|
+
const body2 = parseJson();
|
|
878
|
+
if (body2?.reasonCode) {
|
|
879
|
+
throw new KSeFForbiddenError(body2);
|
|
672
880
|
}
|
|
673
881
|
}
|
|
674
|
-
|
|
882
|
+
if (response.status === 410) {
|
|
883
|
+
const body2 = parseJson();
|
|
884
|
+
throw new KSeFGoneError({
|
|
885
|
+
title: body2?.title || "Gone",
|
|
886
|
+
status: body2?.status || 410,
|
|
887
|
+
detail: body2?.detail || "Operation status no longer available (retention expired)",
|
|
888
|
+
instance: body2?.instance,
|
|
889
|
+
traceId: body2?.traceId,
|
|
890
|
+
timestamp: body2?.timestamp
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
const body = parseJson();
|
|
894
|
+
if (hasErrorCode(body, KSeFErrorCode.BatchTimeout)) {
|
|
895
|
+
throw KSeFBatchTimeoutError.fromResponse(response.status, body);
|
|
896
|
+
}
|
|
897
|
+
throw KSeFApiError.fromResponse(response.status, body);
|
|
675
898
|
}
|
|
676
899
|
};
|
|
677
900
|
}
|
|
@@ -2590,6 +2813,115 @@ var init_schema_registry = __esm({
|
|
|
2590
2813
|
}
|
|
2591
2814
|
});
|
|
2592
2815
|
|
|
2816
|
+
// src/validation/char-validity.ts
|
|
2817
|
+
function validateCharValidity(xml) {
|
|
2818
|
+
return [...findProcessingInstructions(xml), ...findDiscouragedUnicode(xml)];
|
|
2819
|
+
}
|
|
2820
|
+
function findProcessingInstructionTokens(xml) {
|
|
2821
|
+
const tokens = [];
|
|
2822
|
+
for (let i = 0; i < xml.length; ) {
|
|
2823
|
+
if (xml.startsWith("<!--", i)) {
|
|
2824
|
+
const end = xml.indexOf("-->", i + 4);
|
|
2825
|
+
i = end === -1 ? xml.length : end + 3;
|
|
2826
|
+
continue;
|
|
2827
|
+
}
|
|
2828
|
+
if (xml.startsWith("<![CDATA[", i)) {
|
|
2829
|
+
const end = xml.indexOf("]]>", i + 9);
|
|
2830
|
+
i = end === -1 ? xml.length : end + 3;
|
|
2831
|
+
continue;
|
|
2832
|
+
}
|
|
2833
|
+
if (xml.startsWith("<?", i)) {
|
|
2834
|
+
const end = xml.indexOf("?>", i + 2);
|
|
2835
|
+
if (end === -1) break;
|
|
2836
|
+
tokens.push({ token: xml.slice(i, end + 2), index: i });
|
|
2837
|
+
i = end + 2;
|
|
2838
|
+
continue;
|
|
2839
|
+
}
|
|
2840
|
+
i += 1;
|
|
2841
|
+
}
|
|
2842
|
+
return tokens;
|
|
2843
|
+
}
|
|
2844
|
+
function findProcessingInstructions(xml) {
|
|
2845
|
+
const errors = [];
|
|
2846
|
+
const matches = findProcessingInstructionTokens(xml);
|
|
2847
|
+
if (matches.length === 0) return errors;
|
|
2848
|
+
const firstMatch = matches[0];
|
|
2849
|
+
const firstTarget = firstMatch.token.match(PI_TARGET_RE)?.[1];
|
|
2850
|
+
const hasBom = xml.charCodeAt(0) === 65279;
|
|
2851
|
+
const prologPosition = hasBom ? 1 : 0;
|
|
2852
|
+
const firstIsProlog = firstMatch.index === prologPosition && firstTarget === "xml";
|
|
2853
|
+
for (let i = 0; i < matches.length; i++) {
|
|
2854
|
+
if (i === 0 && firstIsProlog) continue;
|
|
2855
|
+
const m = matches[i];
|
|
2856
|
+
const target = m.token.match(PI_TARGET_RE)?.[1] ?? "?";
|
|
2857
|
+
errors.push({
|
|
2858
|
+
code: "XML_PROCESSING_INSTRUCTION",
|
|
2859
|
+
message: `Processing instruction <?${target}?> at offset ${m.index} is not allowed (only <?xml ... ?> prolog is permitted)`,
|
|
2860
|
+
path: `offset:${m.index}`
|
|
2861
|
+
});
|
|
2862
|
+
}
|
|
2863
|
+
return errors;
|
|
2864
|
+
}
|
|
2865
|
+
function findDiscouragedUnicode(xml) {
|
|
2866
|
+
const errors = [];
|
|
2867
|
+
const seenRanges = /* @__PURE__ */ new Set();
|
|
2868
|
+
let utf16Offset = 0;
|
|
2869
|
+
for (const ch of xml) {
|
|
2870
|
+
const cp = ch.codePointAt(0);
|
|
2871
|
+
const idx = rangeIndex(cp);
|
|
2872
|
+
if (idx >= 0 && !seenRanges.has(idx)) {
|
|
2873
|
+
seenRanges.add(idx);
|
|
2874
|
+
errors.push({
|
|
2875
|
+
code: "XML_DISCOURAGED_UNICODE",
|
|
2876
|
+
message: `Discouraged Unicode character U+${cp.toString(16).toUpperCase().padStart(4, "0")} found at offset ${utf16Offset} (W3C XML 1.0 \xA72.2 rejects this range)`,
|
|
2877
|
+
path: `offset:${utf16Offset}`
|
|
2878
|
+
});
|
|
2879
|
+
}
|
|
2880
|
+
utf16Offset += ch.length;
|
|
2881
|
+
}
|
|
2882
|
+
return errors;
|
|
2883
|
+
}
|
|
2884
|
+
function rangeIndex(cp) {
|
|
2885
|
+
let lo = 0;
|
|
2886
|
+
let hi = DISCOURAGED_UNICODE_RANGES.length - 1;
|
|
2887
|
+
while (lo <= hi) {
|
|
2888
|
+
const mid = lo + hi >> 1;
|
|
2889
|
+
const [start, end] = DISCOURAGED_UNICODE_RANGES[mid];
|
|
2890
|
+
if (cp < start) hi = mid - 1;
|
|
2891
|
+
else if (cp > end) lo = mid + 1;
|
|
2892
|
+
else return mid;
|
|
2893
|
+
}
|
|
2894
|
+
return -1;
|
|
2895
|
+
}
|
|
2896
|
+
var DISCOURAGED_UNICODE_RANGES, PI_TARGET_RE;
|
|
2897
|
+
var init_char_validity = __esm({
|
|
2898
|
+
"src/validation/char-validity.ts"() {
|
|
2899
|
+
"use strict";
|
|
2900
|
+
DISCOURAGED_UNICODE_RANGES = [
|
|
2901
|
+
[127, 132],
|
|
2902
|
+
[134, 159],
|
|
2903
|
+
[64976, 65007],
|
|
2904
|
+
[131070, 131071],
|
|
2905
|
+
[196606, 196607],
|
|
2906
|
+
[262142, 262143],
|
|
2907
|
+
[327678, 327679],
|
|
2908
|
+
[393214, 393215],
|
|
2909
|
+
[458750, 458751],
|
|
2910
|
+
[524286, 524287],
|
|
2911
|
+
[589822, 589823],
|
|
2912
|
+
[655358, 655359],
|
|
2913
|
+
[720894, 720895],
|
|
2914
|
+
[786430, 786431],
|
|
2915
|
+
[851966, 851967],
|
|
2916
|
+
[917502, 917503],
|
|
2917
|
+
[983038, 983039],
|
|
2918
|
+
[1048574, 1048575],
|
|
2919
|
+
[1114110, 1114111]
|
|
2920
|
+
];
|
|
2921
|
+
PI_TARGET_RE = /^<\?(\S+)/;
|
|
2922
|
+
}
|
|
2923
|
+
});
|
|
2924
|
+
|
|
2593
2925
|
// src/validation/invoice-validator.ts
|
|
2594
2926
|
var invoice_validator_exports = {};
|
|
2595
2927
|
__export(invoice_validator_exports, {
|
|
@@ -2742,6 +3074,12 @@ function collectDateErrors(obj, rootElement, errors) {
|
|
|
2742
3074
|
}
|
|
2743
3075
|
}
|
|
2744
3076
|
async function validate(xml, options) {
|
|
3077
|
+
if (!options?.skipCharValidity) {
|
|
3078
|
+
const l1aErrors = validateCharValidity(xml);
|
|
3079
|
+
if (l1aErrors.length > 0) {
|
|
3080
|
+
return { valid: false, schemaType: null, errors: l1aErrors };
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
2745
3083
|
const parsed = xml && xml.trim() ? xmlToObject(xml) : void 0;
|
|
2746
3084
|
const l1 = validateWellFormedness(xml, parsed);
|
|
2747
3085
|
if (!l1.valid) return l1;
|
|
@@ -2768,6 +3106,7 @@ var init_invoice_validator = __esm({
|
|
|
2768
3106
|
"use strict";
|
|
2769
3107
|
init_xml_to_object();
|
|
2770
3108
|
init_schema_registry();
|
|
3109
|
+
init_char_validity();
|
|
2771
3110
|
init_patterns();
|
|
2772
3111
|
}
|
|
2773
3112
|
});
|
|
@@ -3232,9 +3571,10 @@ var PermissionsService;
|
|
|
3232
3571
|
var init_permissions = __esm({
|
|
3233
3572
|
"src/services/permissions.ts"() {
|
|
3234
3573
|
"use strict";
|
|
3574
|
+
init_ksef_validation_error();
|
|
3235
3575
|
init_rest_request();
|
|
3236
3576
|
init_routes();
|
|
3237
|
-
PermissionsService = class {
|
|
3577
|
+
PermissionsService = class _PermissionsService {
|
|
3238
3578
|
restClient;
|
|
3239
3579
|
constructor(restClient) {
|
|
3240
3580
|
this.restClient = restClient;
|
|
@@ -3292,6 +3632,7 @@ var init_permissions = __esm({
|
|
|
3292
3632
|
}
|
|
3293
3633
|
// Search methods
|
|
3294
3634
|
async queryPersonalGrants(options, pageOffset, pageSize) {
|
|
3635
|
+
_PermissionsService.validateContextIdentifier(options?.contextIdentifier);
|
|
3295
3636
|
const req = RestRequest.post(Routes.Permissions.Query.personalGrants).body(options ?? {});
|
|
3296
3637
|
if (pageOffset !== void 0) req.query("pageOffset", String(pageOffset));
|
|
3297
3638
|
if (pageSize !== void 0) req.query("pageSize", String(pageSize));
|
|
@@ -3320,6 +3661,7 @@ var init_permissions = __esm({
|
|
|
3320
3661
|
return response.body;
|
|
3321
3662
|
}
|
|
3322
3663
|
async queryEntitiesGrants(options, pageOffset, pageSize) {
|
|
3664
|
+
_PermissionsService.validateContextIdentifier(options?.contextIdentifier);
|
|
3323
3665
|
const req = RestRequest.post(Routes.Permissions.Query.entitiesGrants).body(options ?? {});
|
|
3324
3666
|
if (pageOffset !== void 0) req.query("pageOffset", String(pageOffset));
|
|
3325
3667
|
if (pageSize !== void 0) req.query("pageSize", String(pageSize));
|
|
@@ -3358,17 +3700,90 @@ var init_permissions = __esm({
|
|
|
3358
3700
|
const response = await this.restClient.execute(req);
|
|
3359
3701
|
return response.body;
|
|
3360
3702
|
}
|
|
3703
|
+
static validateContextIdentifier(ctx) {
|
|
3704
|
+
if (!ctx) return;
|
|
3705
|
+
if (ctx.type === "InternalId") {
|
|
3706
|
+
const len = ctx.value.length;
|
|
3707
|
+
if (len < 10 || len > 16) {
|
|
3708
|
+
throw KSeFValidationError.fromField(
|
|
3709
|
+
"contextIdentifier.value",
|
|
3710
|
+
`InternalId must be 10-16 characters, got ${len}`
|
|
3711
|
+
);
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3361
3715
|
};
|
|
3362
3716
|
}
|
|
3363
3717
|
});
|
|
3364
3718
|
|
|
3719
|
+
// src/utils/jwt.ts
|
|
3720
|
+
function decodeJwtPayload(token) {
|
|
3721
|
+
const parts = token.split(".");
|
|
3722
|
+
if (parts.length !== 3) return null;
|
|
3723
|
+
try {
|
|
3724
|
+
const payload = parts[1];
|
|
3725
|
+
const json = Buffer.from(payload, "base64url").toString("utf-8");
|
|
3726
|
+
return JSON.parse(json);
|
|
3727
|
+
} catch {
|
|
3728
|
+
return null;
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
function tryParseJson(value) {
|
|
3732
|
+
if (typeof value !== "string") return void 0;
|
|
3733
|
+
try {
|
|
3734
|
+
return JSON.parse(value);
|
|
3735
|
+
} catch {
|
|
3736
|
+
return void 0;
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
function tryParseJsonArray(value) {
|
|
3740
|
+
if (typeof value !== "string") return void 0;
|
|
3741
|
+
try {
|
|
3742
|
+
const parsed = JSON.parse(value);
|
|
3743
|
+
return Array.isArray(parsed) && parsed.every((item) => typeof item === "string") ? parsed : void 0;
|
|
3744
|
+
} catch {
|
|
3745
|
+
return void 0;
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
function parseKSeFTokenContext(token) {
|
|
3749
|
+
const raw = decodeJwtPayload(token);
|
|
3750
|
+
if (!raw) return null;
|
|
3751
|
+
return {
|
|
3752
|
+
type: typeof raw["typ"] === "string" ? raw["typ"] : void 0,
|
|
3753
|
+
contextIdentifierType: typeof raw["cit"] === "string" ? raw["cit"] : void 0,
|
|
3754
|
+
contextIdentifierValue: typeof raw["civ"] === "string" ? raw["civ"] : void 0,
|
|
3755
|
+
authMethod: typeof raw["aum"] === "string" ? raw["aum"] : void 0,
|
|
3756
|
+
permissions: tryParseJsonArray(raw["per"]),
|
|
3757
|
+
subjectDetails: tryParseJson(raw["sud"]),
|
|
3758
|
+
authorSubjectIdentifier: tryParseJson(raw["asi"]),
|
|
3759
|
+
issuedAt: typeof raw["iat"] === "number" ? raw["iat"] : void 0,
|
|
3760
|
+
expiresAt: typeof raw["exp"] === "number" ? raw["exp"] : void 0
|
|
3761
|
+
};
|
|
3762
|
+
}
|
|
3763
|
+
var init_jwt = __esm({
|
|
3764
|
+
"src/utils/jwt.ts"() {
|
|
3765
|
+
"use strict";
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
|
|
3365
3769
|
// src/services/tokens.ts
|
|
3366
|
-
|
|
3770
|
+
function toTokenAuthorIdentifierType(value) {
|
|
3771
|
+
return TOKEN_AUTHOR_IDENTIFIER_TYPES.has(value) ? value : void 0;
|
|
3772
|
+
}
|
|
3773
|
+
var TOKEN_AUTHOR_IDENTIFIER_TYPES, TokenService;
|
|
3367
3774
|
var init_tokens = __esm({
|
|
3368
3775
|
"src/services/tokens.ts"() {
|
|
3369
3776
|
"use strict";
|
|
3370
3777
|
init_rest_request();
|
|
3371
3778
|
init_routes();
|
|
3779
|
+
init_jwt();
|
|
3780
|
+
init_ksef_api_error();
|
|
3781
|
+
init_ksef_error();
|
|
3782
|
+
TOKEN_AUTHOR_IDENTIFIER_TYPES = /* @__PURE__ */ new Set([
|
|
3783
|
+
"Nip",
|
|
3784
|
+
"Pesel",
|
|
3785
|
+
"Fingerprint"
|
|
3786
|
+
]);
|
|
3372
3787
|
TokenService = class {
|
|
3373
3788
|
restClient;
|
|
3374
3789
|
constructor(restClient) {
|
|
@@ -3403,6 +3818,73 @@ var init_tokens = __esm({
|
|
|
3403
3818
|
const req = RestRequest.delete(Routes.Tokens.byReference(ref));
|
|
3404
3819
|
await this.restClient.executeVoid(req);
|
|
3405
3820
|
}
|
|
3821
|
+
/**
|
|
3822
|
+
* Resolves the reference number of the token currently in use for authentication.
|
|
3823
|
+
* The only JWT payload field treated as authoritative is the KSeF-specific `trn`
|
|
3824
|
+
* (token reference number). Standard RFC 7519 claims such as `jti` are NOT a safe
|
|
3825
|
+
* fallback — a `jti` that differs from the KSeF reference would cause a DELETE to
|
|
3826
|
+
* hit a non-existent path, which `revokeSelf` treats as already-revoked, falsely
|
|
3827
|
+
* reporting success while leaving the token active on the server. When `trn` is
|
|
3828
|
+
* absent, we fall back to `GET /tokens` filtered by author and context; requires
|
|
3829
|
+
* exactly one active match and returns undefined when ambiguous.
|
|
3830
|
+
*/
|
|
3831
|
+
async findSelfReferenceNumber(accessToken) {
|
|
3832
|
+
if (!accessToken) return void 0;
|
|
3833
|
+
const payload = decodeJwtPayload(accessToken);
|
|
3834
|
+
if (payload && typeof payload["trn"] === "string" && payload["trn"].length > 0) {
|
|
3835
|
+
return payload["trn"];
|
|
3836
|
+
}
|
|
3837
|
+
const ctx = parseKSeFTokenContext(accessToken);
|
|
3838
|
+
const author = ctx?.authorSubjectIdentifier;
|
|
3839
|
+
if (!author?.type || !author.value) return void 0;
|
|
3840
|
+
if (!ctx?.contextIdentifierType || !ctx?.contextIdentifierValue) return void 0;
|
|
3841
|
+
const authorType = toTokenAuthorIdentifierType(author.type);
|
|
3842
|
+
if (!authorType) return void 0;
|
|
3843
|
+
let continuationToken;
|
|
3844
|
+
let match;
|
|
3845
|
+
do {
|
|
3846
|
+
const list = await this.queryTokens({
|
|
3847
|
+
status: ["Active"],
|
|
3848
|
+
authorIdentifier: author.value,
|
|
3849
|
+
authorIdentifierType: authorType,
|
|
3850
|
+
pageSize: 50,
|
|
3851
|
+
continuationToken
|
|
3852
|
+
});
|
|
3853
|
+
for (const t of list.tokens) {
|
|
3854
|
+
if (t.status === "Active" && t.contextIdentifier?.value === ctx.contextIdentifierValue && t.contextIdentifier?.type === ctx.contextIdentifierType) {
|
|
3855
|
+
if (match) return void 0;
|
|
3856
|
+
match = t.referenceNumber;
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3859
|
+
continuationToken = list.continuationToken ?? void 0;
|
|
3860
|
+
} while (continuationToken);
|
|
3861
|
+
return match;
|
|
3862
|
+
}
|
|
3863
|
+
/**
|
|
3864
|
+
* Revokes the token currently used for authentication.
|
|
3865
|
+
* Treats 404/409/410 on DELETE as "already revoked" and returns successfully with
|
|
3866
|
+
* `alreadyRevoked: true` so callers can still clear local state.
|
|
3867
|
+
*/
|
|
3868
|
+
async revokeSelf(opts = {}) {
|
|
3869
|
+
let ref = opts.referenceNumber;
|
|
3870
|
+
if (!ref && opts.accessToken) {
|
|
3871
|
+
ref = await this.findSelfReferenceNumber(opts.accessToken);
|
|
3872
|
+
}
|
|
3873
|
+
if (!ref) {
|
|
3874
|
+
throw new KSeFError(
|
|
3875
|
+
"Could not determine the current token reference number: no cache, JWT lacks the field, and the active-token list had 0 or 2+ matches in the current context."
|
|
3876
|
+
);
|
|
3877
|
+
}
|
|
3878
|
+
try {
|
|
3879
|
+
await this.revokeToken(ref);
|
|
3880
|
+
return { referenceNumber: ref, alreadyRevoked: false };
|
|
3881
|
+
} catch (err) {
|
|
3882
|
+
if (err instanceof KSeFApiError && (err.statusCode === 404 || err.statusCode === 409 || err.statusCode === 410)) {
|
|
3883
|
+
return { referenceNumber: ref, alreadyRevoked: true };
|
|
3884
|
+
}
|
|
3885
|
+
throw err;
|
|
3886
|
+
}
|
|
3887
|
+
}
|
|
3406
3888
|
};
|
|
3407
3889
|
}
|
|
3408
3890
|
});
|
|
@@ -4031,8 +4513,8 @@ function computeRootDigest(doc) {
|
|
|
4031
4513
|
return crypto3.createHash("sha256").update(canonical, "utf-8").digest("base64");
|
|
4032
4514
|
}
|
|
4033
4515
|
function computeSignedPropertiesDigest(qualifyingPropertiesXml) {
|
|
4034
|
-
const
|
|
4035
|
-
const qpDoc =
|
|
4516
|
+
const parser2 = new DOMParser2();
|
|
4517
|
+
const qpDoc = parser2.parseFromString(qualifyingPropertiesXml, "text/xml");
|
|
4036
4518
|
const signedProps = findElementByLocalName(qpDoc.documentElement, "SignedProperties");
|
|
4037
4519
|
if (!signedProps) {
|
|
4038
4520
|
throw new Error("SignedProperties element not found in QualifyingProperties");
|
|
@@ -4184,8 +4666,8 @@ var init_signature_service = __esm({
|
|
|
4184
4666
|
const isEc = privateKey.asymmetricKeyType === "ec";
|
|
4185
4667
|
const signatureAlgorithm = isEc ? ECDSA_SHA256_SIGNATURE : RSA_SHA256_SIGNATURE;
|
|
4186
4668
|
const signingTime = new Date(Date.now() + CLOCK_SKEW_BUFFER_MS).toISOString();
|
|
4187
|
-
const
|
|
4188
|
-
const doc =
|
|
4669
|
+
const parser2 = new DOMParser2();
|
|
4670
|
+
const doc = parser2.parseFromString(xml, "text/xml");
|
|
4189
4671
|
const root = doc.documentElement;
|
|
4190
4672
|
if (!root) {
|
|
4191
4673
|
throw new Error("XML document has no root element");
|
|
@@ -4205,7 +4687,7 @@ var init_signature_service = __esm({
|
|
|
4205
4687
|
rootDigest,
|
|
4206
4688
|
signedPropertiesDigest
|
|
4207
4689
|
);
|
|
4208
|
-
const signedInfoDoc =
|
|
4690
|
+
const signedInfoDoc = parser2.parseFromString(signedInfoXml, "text/xml");
|
|
4209
4691
|
const canonicalSignedInfo = canonicalize(signedInfoDoc.documentElement);
|
|
4210
4692
|
const signatureValue = computeSignatureValue(
|
|
4211
4693
|
canonicalSignedInfo,
|
|
@@ -4218,7 +4700,7 @@ var init_signature_service = __esm({
|
|
|
4218
4700
|
certBase64,
|
|
4219
4701
|
qualifyingPropertiesXml
|
|
4220
4702
|
);
|
|
4221
|
-
const signatureDoc =
|
|
4703
|
+
const signatureDoc = parser2.parseFromString(signatureXml, "text/xml");
|
|
4222
4704
|
const importedNode = doc.importNode(signatureDoc.documentElement, true);
|
|
4223
4705
|
root.appendChild(importedNode);
|
|
4224
4706
|
return new XMLSerializer().serializeToString(doc);
|
|
@@ -5057,6 +5539,7 @@ var init_client = __esm({
|
|
|
5057
5539
|
const tokens = await this.auth.getAccessToken(authToken);
|
|
5058
5540
|
this.authManager.setAccessToken(tokens.accessToken.token);
|
|
5059
5541
|
this.authManager.setRefreshToken(tokens.refreshToken.token);
|
|
5542
|
+
return { clientIp: challenge.clientIp };
|
|
5060
5543
|
}
|
|
5061
5544
|
async loginWithCertificate(certPem, keyPem, nip, keyPassword) {
|
|
5062
5545
|
const challenge = await this.auth.getChallenge();
|
|
@@ -5069,11 +5552,12 @@ var init_client = __esm({
|
|
|
5069
5552
|
const tokens = await this.auth.getAccessToken(authToken);
|
|
5070
5553
|
this.authManager.setAccessToken(tokens.accessToken.token);
|
|
5071
5554
|
this.authManager.setRefreshToken(tokens.refreshToken.token);
|
|
5555
|
+
return { clientIp: challenge.clientIp };
|
|
5072
5556
|
}
|
|
5073
5557
|
async loginWithPkcs12(p12, password, nip) {
|
|
5074
5558
|
const { Pkcs12Loader: Pkcs12Loader2 } = await Promise.resolve().then(() => (init_pkcs12_loader(), pkcs12_loader_exports));
|
|
5075
5559
|
const { certificatePem, privateKeyPem } = Pkcs12Loader2.load(p12, password);
|
|
5076
|
-
|
|
5560
|
+
return this.loginWithCertificate(certificatePem, privateKeyPem, nip);
|
|
5077
5561
|
}
|
|
5078
5562
|
async awaitAuthReady(referenceNumber, authToken) {
|
|
5079
5563
|
for (let i = 0; i < 30; i++) {
|
|
@@ -5125,6 +5609,7 @@ var PERMISSION_DESCRIPTION_MAX_LENGTH = 256;
|
|
|
5125
5609
|
init_xml_to_object();
|
|
5126
5610
|
init_schema_registry();
|
|
5127
5611
|
init_invoice_validator();
|
|
5612
|
+
init_char_validity();
|
|
5128
5613
|
|
|
5129
5614
|
// src/models/index.ts
|
|
5130
5615
|
init_document_structures();
|
|
@@ -5816,51 +6301,7 @@ function escapeXml2(str) {
|
|
|
5816
6301
|
|
|
5817
6302
|
// src/utils/index.ts
|
|
5818
6303
|
init_zip();
|
|
5819
|
-
|
|
5820
|
-
// src/utils/jwt.ts
|
|
5821
|
-
function decodeJwtPayload(token) {
|
|
5822
|
-
const parts = token.split(".");
|
|
5823
|
-
if (parts.length !== 3) return null;
|
|
5824
|
-
try {
|
|
5825
|
-
const payload = parts[1];
|
|
5826
|
-
const json = Buffer.from(payload, "base64url").toString("utf-8");
|
|
5827
|
-
return JSON.parse(json);
|
|
5828
|
-
} catch {
|
|
5829
|
-
return null;
|
|
5830
|
-
}
|
|
5831
|
-
}
|
|
5832
|
-
function tryParseJson(value) {
|
|
5833
|
-
if (typeof value !== "string") return void 0;
|
|
5834
|
-
try {
|
|
5835
|
-
return JSON.parse(value);
|
|
5836
|
-
} catch {
|
|
5837
|
-
return void 0;
|
|
5838
|
-
}
|
|
5839
|
-
}
|
|
5840
|
-
function tryParseJsonArray(value) {
|
|
5841
|
-
if (typeof value !== "string") return void 0;
|
|
5842
|
-
try {
|
|
5843
|
-
const parsed = JSON.parse(value);
|
|
5844
|
-
return Array.isArray(parsed) && parsed.every((item) => typeof item === "string") ? parsed : void 0;
|
|
5845
|
-
} catch {
|
|
5846
|
-
return void 0;
|
|
5847
|
-
}
|
|
5848
|
-
}
|
|
5849
|
-
function parseKSeFTokenContext(token) {
|
|
5850
|
-
const raw = decodeJwtPayload(token);
|
|
5851
|
-
if (!raw) return null;
|
|
5852
|
-
return {
|
|
5853
|
-
type: typeof raw["typ"] === "string" ? raw["typ"] : void 0,
|
|
5854
|
-
contextIdentifierType: typeof raw["cit"] === "string" ? raw["cit"] : void 0,
|
|
5855
|
-
contextIdentifierValue: typeof raw["civ"] === "string" ? raw["civ"] : void 0,
|
|
5856
|
-
authMethod: typeof raw["aum"] === "string" ? raw["aum"] : void 0,
|
|
5857
|
-
permissions: tryParseJsonArray(raw["per"]),
|
|
5858
|
-
subjectDetails: tryParseJson(raw["sud"]),
|
|
5859
|
-
authorSubjectIdentifier: tryParseJson(raw["asi"]),
|
|
5860
|
-
issuedAt: typeof raw["iat"] === "number" ? raw["iat"] : void 0,
|
|
5861
|
-
expiresAt: typeof raw["exp"] === "number" ? raw["exp"] : void 0
|
|
5862
|
-
};
|
|
5863
|
-
}
|
|
6304
|
+
init_jwt();
|
|
5864
6305
|
|
|
5865
6306
|
// src/utils/hash.ts
|
|
5866
6307
|
import crypto6 from "crypto";
|
|
@@ -6056,6 +6497,524 @@ function nonEmptyString(value) {
|
|
|
6056
6497
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
6057
6498
|
}
|
|
6058
6499
|
|
|
6500
|
+
// src/xml/xml-engine.ts
|
|
6501
|
+
import { XMLBuilder, XMLParser as XMLParser3 } from "fast-xml-parser";
|
|
6502
|
+
var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>\n';
|
|
6503
|
+
var parser = new XMLParser3({
|
|
6504
|
+
ignoreAttributes: false,
|
|
6505
|
+
preserveOrder: true,
|
|
6506
|
+
attributeNamePrefix: "@_",
|
|
6507
|
+
textNodeName: "#text",
|
|
6508
|
+
allowBooleanAttributes: true,
|
|
6509
|
+
// Preserve leading zeros and keep everything as strings — KSeF fields like
|
|
6510
|
+
// KRS (`\d{10}`) and NIP (`\d{10}`) would otherwise be lossy through parse.
|
|
6511
|
+
parseTagValue: false,
|
|
6512
|
+
parseAttributeValue: false,
|
|
6513
|
+
trimValues: false
|
|
6514
|
+
});
|
|
6515
|
+
var builder = new XMLBuilder({
|
|
6516
|
+
ignoreAttributes: false,
|
|
6517
|
+
preserveOrder: true,
|
|
6518
|
+
attributeNamePrefix: "@_",
|
|
6519
|
+
textNodeName: "#text",
|
|
6520
|
+
format: false,
|
|
6521
|
+
suppressBooleanAttributes: false,
|
|
6522
|
+
suppressEmptyNode: false,
|
|
6523
|
+
processEntities: true
|
|
6524
|
+
});
|
|
6525
|
+
function createObjectBuilder(pretty = false) {
|
|
6526
|
+
return new XMLBuilder({
|
|
6527
|
+
ignoreAttributes: false,
|
|
6528
|
+
preserveOrder: false,
|
|
6529
|
+
attributeNamePrefix: "@_",
|
|
6530
|
+
textNodeName: "#text",
|
|
6531
|
+
format: pretty,
|
|
6532
|
+
suppressBooleanAttributes: false,
|
|
6533
|
+
suppressEmptyNode: false,
|
|
6534
|
+
processEntities: true
|
|
6535
|
+
});
|
|
6536
|
+
}
|
|
6537
|
+
function prependDeclaration(xml) {
|
|
6538
|
+
return xml.startsWith("<?xml") ? xml : `${XML_DECLARATION}${xml}`;
|
|
6539
|
+
}
|
|
6540
|
+
function parseXml(xml) {
|
|
6541
|
+
return parser.parse(xml);
|
|
6542
|
+
}
|
|
6543
|
+
function buildXml(document) {
|
|
6544
|
+
return prependDeclaration(builder.build(document));
|
|
6545
|
+
}
|
|
6546
|
+
function buildXmlFromObject(document, options) {
|
|
6547
|
+
return prependDeclaration(createObjectBuilder(options?.pretty).build(document));
|
|
6548
|
+
}
|
|
6549
|
+
function stripBom(input) {
|
|
6550
|
+
return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
|
|
6551
|
+
}
|
|
6552
|
+
|
|
6553
|
+
// src/xml/order-map.ts
|
|
6554
|
+
var ORDER_MAP = {
|
|
6555
|
+
Faktura: ["Naglowek", "Podmiot1", "Podmiot2", "Podmiot3", "Fa", "Stopka"],
|
|
6556
|
+
Naglowek: ["KodFormularza", "WariantFormularza", "DataWytworzeniaFa", "SystemInfo"],
|
|
6557
|
+
Podmiot1: [
|
|
6558
|
+
"PrefiksPodatnika",
|
|
6559
|
+
"NrEORI",
|
|
6560
|
+
"DaneIdentyfikacyjne",
|
|
6561
|
+
"Adres",
|
|
6562
|
+
"AdresKoresp",
|
|
6563
|
+
"DaneKontaktowe",
|
|
6564
|
+
"StatusInfoPodatnika"
|
|
6565
|
+
],
|
|
6566
|
+
Podmiot2: [
|
|
6567
|
+
"NrEORI",
|
|
6568
|
+
"DaneIdentyfikacyjne",
|
|
6569
|
+
"Adres",
|
|
6570
|
+
"AdresKoresp",
|
|
6571
|
+
"DaneKontaktowe",
|
|
6572
|
+
"NrKlienta",
|
|
6573
|
+
"IDNabywcy",
|
|
6574
|
+
"JST",
|
|
6575
|
+
"GV"
|
|
6576
|
+
],
|
|
6577
|
+
Podmiot3: [
|
|
6578
|
+
"IDNabywcy",
|
|
6579
|
+
"NrEORI",
|
|
6580
|
+
"DaneIdentyfikacyjne",
|
|
6581
|
+
"Adres",
|
|
6582
|
+
"AdresKoresp",
|
|
6583
|
+
"DaneKontaktowe",
|
|
6584
|
+
"Rola",
|
|
6585
|
+
"Udzial"
|
|
6586
|
+
],
|
|
6587
|
+
DaneIdentyfikacyjne: [
|
|
6588
|
+
"NIP",
|
|
6589
|
+
"IDWew",
|
|
6590
|
+
"KodUE",
|
|
6591
|
+
"NrVatUE",
|
|
6592
|
+
"KodKraju",
|
|
6593
|
+
"NrID",
|
|
6594
|
+
"BrakID",
|
|
6595
|
+
"Nazwa",
|
|
6596
|
+
"Identyfikator",
|
|
6597
|
+
"KRS"
|
|
6598
|
+
],
|
|
6599
|
+
Adres: ["KodKraju", "AdresL1", "AdresL2", "AdresL3"],
|
|
6600
|
+
DaneKontaktowe: ["Email", "Telefon"],
|
|
6601
|
+
Fa: [
|
|
6602
|
+
"KodWaluty",
|
|
6603
|
+
"P_1",
|
|
6604
|
+
"P_1M",
|
|
6605
|
+
"P_2",
|
|
6606
|
+
"WZ",
|
|
6607
|
+
"P_6",
|
|
6608
|
+
"OkresFa",
|
|
6609
|
+
// Multi-rate interleave per VAT group — DO NOT flatten into P_13_* block then P_14_* block.
|
|
6610
|
+
// See smekcio TS d1ec8fe and the "multi-rate interleave" regression test.
|
|
6611
|
+
"P_13_1",
|
|
6612
|
+
"P_14_1",
|
|
6613
|
+
"P_14_1W",
|
|
6614
|
+
"P_13_2",
|
|
6615
|
+
"P_14_2",
|
|
6616
|
+
"P_14_2W",
|
|
6617
|
+
"P_13_3",
|
|
6618
|
+
"P_14_3",
|
|
6619
|
+
"P_14_3W",
|
|
6620
|
+
"P_13_4",
|
|
6621
|
+
"P_14_4",
|
|
6622
|
+
"P_14_4W",
|
|
6623
|
+
"P_13_5",
|
|
6624
|
+
"P_14_5",
|
|
6625
|
+
"P_13_6_1",
|
|
6626
|
+
"P_13_6_2",
|
|
6627
|
+
"P_13_6_3",
|
|
6628
|
+
"P_13_7",
|
|
6629
|
+
"P_13_8",
|
|
6630
|
+
"P_13_9",
|
|
6631
|
+
"P_13_10",
|
|
6632
|
+
"P_13_11",
|
|
6633
|
+
"P_15",
|
|
6634
|
+
"KursWalutyZ",
|
|
6635
|
+
"Adnotacje",
|
|
6636
|
+
"RodzajFaktury",
|
|
6637
|
+
"PrzyczynaKorekty",
|
|
6638
|
+
"TypKorekty",
|
|
6639
|
+
"DaneFaKorygowanej",
|
|
6640
|
+
"OkresFaKorygowanej",
|
|
6641
|
+
"NrFaKorygowany",
|
|
6642
|
+
"Podmiot1K",
|
|
6643
|
+
"Podmiot2K",
|
|
6644
|
+
"Podmiot3K",
|
|
6645
|
+
"ZaliczkaCzesciowa",
|
|
6646
|
+
"FP",
|
|
6647
|
+
"TP",
|
|
6648
|
+
"DodatkowyOpis",
|
|
6649
|
+
"FakturaZaliczkowa",
|
|
6650
|
+
"ZwrotAkcyzy",
|
|
6651
|
+
"FaWiersz",
|
|
6652
|
+
"FaWiersze",
|
|
6653
|
+
"Rozliczenie",
|
|
6654
|
+
"Platnosc"
|
|
6655
|
+
],
|
|
6656
|
+
Adnotacje: ["P_16", "P_17", "P_18", "P_18A", "Zwolnienie", "NoweSrodkiTransportu", "P_23", "PMarzy"],
|
|
6657
|
+
OkresFa: ["P_6_Od", "P_6_Do"],
|
|
6658
|
+
FaWiersz: [
|
|
6659
|
+
"NrWierszaFa",
|
|
6660
|
+
"UU_ID",
|
|
6661
|
+
"P_6A",
|
|
6662
|
+
"P_7",
|
|
6663
|
+
"Indeks",
|
|
6664
|
+
"GTIN",
|
|
6665
|
+
"PKWiU",
|
|
6666
|
+
"CN",
|
|
6667
|
+
"PKOB",
|
|
6668
|
+
"P_8A",
|
|
6669
|
+
"P_8B",
|
|
6670
|
+
"P_9A",
|
|
6671
|
+
"P_9B",
|
|
6672
|
+
"P_10",
|
|
6673
|
+
"P_11",
|
|
6674
|
+
"P_11A",
|
|
6675
|
+
"P_11Vat",
|
|
6676
|
+
"P_12",
|
|
6677
|
+
"P_12_XII",
|
|
6678
|
+
"P_12_Zal_15",
|
|
6679
|
+
"KwotaAkcyzy",
|
|
6680
|
+
"GTU",
|
|
6681
|
+
"Procedura",
|
|
6682
|
+
"KursWaluty",
|
|
6683
|
+
"StanPrzed"
|
|
6684
|
+
]
|
|
6685
|
+
};
|
|
6686
|
+
function comparePKey(a, b) {
|
|
6687
|
+
const normalize = (value) => value.replace(/^P_/, "").split("_").map((part) => Number.isNaN(Number(part)) ? part : Number(part));
|
|
6688
|
+
const aParts = normalize(a);
|
|
6689
|
+
const bParts = normalize(b);
|
|
6690
|
+
const max = Math.max(aParts.length, bParts.length);
|
|
6691
|
+
for (let i = 0; i < max; i += 1) {
|
|
6692
|
+
const left = aParts[i];
|
|
6693
|
+
const right = bParts[i];
|
|
6694
|
+
if (left === void 0) return -1;
|
|
6695
|
+
if (right === void 0) return 1;
|
|
6696
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
6697
|
+
if (left !== right) return left - right;
|
|
6698
|
+
continue;
|
|
6699
|
+
}
|
|
6700
|
+
const leftStr = String(left);
|
|
6701
|
+
const rightStr = String(right);
|
|
6702
|
+
if (leftStr !== rightStr) return leftStr < rightStr ? -1 : 1;
|
|
6703
|
+
}
|
|
6704
|
+
return 0;
|
|
6705
|
+
}
|
|
6706
|
+
function isObject(value) {
|
|
6707
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6708
|
+
}
|
|
6709
|
+
function normalizeValueForKey(key, value) {
|
|
6710
|
+
if (Array.isArray(value)) {
|
|
6711
|
+
return value.map(
|
|
6712
|
+
(item) => isObject(item) ? orderXmlObject(item, key) : normalizeValue(item)
|
|
6713
|
+
);
|
|
6714
|
+
}
|
|
6715
|
+
if (isObject(value)) return orderXmlObject(value, key);
|
|
6716
|
+
return value;
|
|
6717
|
+
}
|
|
6718
|
+
function normalizeValue(value) {
|
|
6719
|
+
if (Array.isArray(value)) return value.map((item) => normalizeValue(item));
|
|
6720
|
+
if (isObject(value)) return orderXmlObject(value);
|
|
6721
|
+
return value;
|
|
6722
|
+
}
|
|
6723
|
+
function orderXmlObject(value, contextKey) {
|
|
6724
|
+
const order = contextKey ? ORDER_MAP[contextKey] : void 0;
|
|
6725
|
+
const keys = Object.keys(value);
|
|
6726
|
+
const used = /* @__PURE__ */ new Set();
|
|
6727
|
+
const ordered = {};
|
|
6728
|
+
if (order) {
|
|
6729
|
+
for (const key of order) {
|
|
6730
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
6731
|
+
const item = value[key];
|
|
6732
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
6733
|
+
used.add(key);
|
|
6734
|
+
}
|
|
6735
|
+
}
|
|
6736
|
+
}
|
|
6737
|
+
const pKeys = keys.filter((key) => !used.has(key) && key.startsWith("P_")).sort(comparePKey);
|
|
6738
|
+
for (const key of pKeys) {
|
|
6739
|
+
const item = value[key];
|
|
6740
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
6741
|
+
used.add(key);
|
|
6742
|
+
}
|
|
6743
|
+
for (const key of keys) {
|
|
6744
|
+
if (used.has(key)) continue;
|
|
6745
|
+
const item = value[key];
|
|
6746
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
6747
|
+
}
|
|
6748
|
+
return ordered;
|
|
6749
|
+
}
|
|
6750
|
+
|
|
6751
|
+
// src/xml/faktura-builder.ts
|
|
6752
|
+
var FAKTURA_NAMESPACE = {
|
|
6753
|
+
FA2: "http://crd.gov.pl/wzor/2023/06/29/12648/",
|
|
6754
|
+
FA3: "http://crd.gov.pl/wzor/2025/06/25/13775/"
|
|
6755
|
+
};
|
|
6756
|
+
var ETD_NAMESPACE = {
|
|
6757
|
+
FA2: "http://crd.gov.pl/xml/schematy/2020/10/08/eDokumenty",
|
|
6758
|
+
FA3: "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/"
|
|
6759
|
+
};
|
|
6760
|
+
function toKodFormularza(formCode) {
|
|
6761
|
+
return {
|
|
6762
|
+
"@_kodSystemowy": formCode.systemCode,
|
|
6763
|
+
"@_wersjaSchemy": formCode.schemaVersion,
|
|
6764
|
+
"#text": formCode.value
|
|
6765
|
+
};
|
|
6766
|
+
}
|
|
6767
|
+
function isFormCodeShape(value) {
|
|
6768
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
6769
|
+
const candidate = value;
|
|
6770
|
+
return typeof candidate.systemCode === "string" && typeof candidate.schemaVersion === "string" && typeof candidate.value === "string";
|
|
6771
|
+
}
|
|
6772
|
+
function isObject2(value) {
|
|
6773
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6774
|
+
}
|
|
6775
|
+
function normalizeTopLevelChild(key, value) {
|
|
6776
|
+
if (key === "Naglowek" && isObject2(value)) {
|
|
6777
|
+
return normalizeNaglowek(value);
|
|
6778
|
+
}
|
|
6779
|
+
if (Array.isArray(value)) {
|
|
6780
|
+
return value.map((item) => isObject2(item) ? orderXmlObject(item, key) : item);
|
|
6781
|
+
}
|
|
6782
|
+
if (isObject2(value)) return orderXmlObject(value, key);
|
|
6783
|
+
return value;
|
|
6784
|
+
}
|
|
6785
|
+
function normalizeNaglowek(value) {
|
|
6786
|
+
const result = {};
|
|
6787
|
+
for (const [key, item] of Object.entries(value)) {
|
|
6788
|
+
if (item === void 0) continue;
|
|
6789
|
+
if (key === "KodFormularza" && isFormCodeShape(item)) {
|
|
6790
|
+
result[key] = toKodFormularza(item);
|
|
6791
|
+
continue;
|
|
6792
|
+
}
|
|
6793
|
+
if (Array.isArray(item)) {
|
|
6794
|
+
result[key] = item.map(
|
|
6795
|
+
(entry) => isObject2(entry) ? orderXmlObject(entry, key) : entry
|
|
6796
|
+
);
|
|
6797
|
+
continue;
|
|
6798
|
+
}
|
|
6799
|
+
if (isObject2(item)) {
|
|
6800
|
+
result[key] = orderXmlObject(item, key);
|
|
6801
|
+
continue;
|
|
6802
|
+
}
|
|
6803
|
+
result[key] = item;
|
|
6804
|
+
}
|
|
6805
|
+
return result;
|
|
6806
|
+
}
|
|
6807
|
+
function normalizeTopLevel(input) {
|
|
6808
|
+
const result = {};
|
|
6809
|
+
for (const [key, value] of Object.entries(input)) {
|
|
6810
|
+
if (value === void 0) continue;
|
|
6811
|
+
result[key] = normalizeTopLevelChild(key, value);
|
|
6812
|
+
}
|
|
6813
|
+
return result;
|
|
6814
|
+
}
|
|
6815
|
+
function buildFakturaXml(faktura, options = {}) {
|
|
6816
|
+
const schema = options.schema ?? "FA3";
|
|
6817
|
+
const fakturaNamespace = options.fakturaNamespace ?? FAKTURA_NAMESPACE[schema];
|
|
6818
|
+
const etdNamespace = options.etdNamespace ?? ETD_NAMESPACE[schema];
|
|
6819
|
+
const normalized = normalizeTopLevel(faktura);
|
|
6820
|
+
const ordered = orderXmlObject(normalized, "Faktura");
|
|
6821
|
+
const document = {
|
|
6822
|
+
Faktura: {
|
|
6823
|
+
...ordered,
|
|
6824
|
+
"@_xmlns": fakturaNamespace,
|
|
6825
|
+
"@_xmlns:etd": etdNamespace
|
|
6826
|
+
}
|
|
6827
|
+
};
|
|
6828
|
+
return buildXmlFromObject(document, { pretty: options.pretty });
|
|
6829
|
+
}
|
|
6830
|
+
function isFakturaInput(input) {
|
|
6831
|
+
if (!isObject2(input)) return false;
|
|
6832
|
+
const candidate = input;
|
|
6833
|
+
if (!Object.prototype.hasOwnProperty.call(candidate, "Naglowek")) return false;
|
|
6834
|
+
if (!Object.prototype.hasOwnProperty.call(candidate, "Fa")) return false;
|
|
6835
|
+
return isObject2(candidate.Naglowek) && isObject2(candidate.Fa);
|
|
6836
|
+
}
|
|
6837
|
+
|
|
6838
|
+
// src/xml/pef-builder.ts
|
|
6839
|
+
init_ksef_validation_error();
|
|
6840
|
+
var PEF_NAMESPACE = {
|
|
6841
|
+
PEF: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
|
|
6842
|
+
PEF_KOR: "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
|
|
6843
|
+
};
|
|
6844
|
+
var UBL_EXT_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2";
|
|
6845
|
+
var UBL_CBC_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";
|
|
6846
|
+
var UBL_CAC_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2";
|
|
6847
|
+
var UBL_CBC_PL_NS = "urn:pl:extended:CommonBasicComponents-2";
|
|
6848
|
+
var UBL_CAC_PL_NS = "urn:pl:extended:CommonAggregateComponents-2";
|
|
6849
|
+
function isPefUblDocumentInput(input) {
|
|
6850
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) return false;
|
|
6851
|
+
const obj = input;
|
|
6852
|
+
const invoice = obj.Invoice;
|
|
6853
|
+
const creditNote = obj.CreditNote;
|
|
6854
|
+
const hasInvoice = typeof invoice === "object" && invoice !== null && !Array.isArray(invoice);
|
|
6855
|
+
const hasCreditNote = typeof creditNote === "object" && creditNote !== null && !Array.isArray(creditNote);
|
|
6856
|
+
return hasInvoice !== hasCreditNote;
|
|
6857
|
+
}
|
|
6858
|
+
function inferSchema(input) {
|
|
6859
|
+
return "Invoice" in input ? "PEF" : "PEF_KOR";
|
|
6860
|
+
}
|
|
6861
|
+
function isNonArrayObject(value) {
|
|
6862
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6863
|
+
}
|
|
6864
|
+
function assertPefShape(input) {
|
|
6865
|
+
if (!isNonArrayObject(input)) {
|
|
6866
|
+
throw new KSeFValidationError("PEF input must be a non-array object.");
|
|
6867
|
+
}
|
|
6868
|
+
const hasInvoiceKey = "Invoice" in input;
|
|
6869
|
+
const hasCreditNoteKey = "CreditNote" in input;
|
|
6870
|
+
if (hasInvoiceKey && hasCreditNoteKey) {
|
|
6871
|
+
throw new KSeFValidationError(
|
|
6872
|
+
"PEF input must contain exactly one of `Invoice` or `CreditNote`, not both."
|
|
6873
|
+
);
|
|
6874
|
+
}
|
|
6875
|
+
if (!hasInvoiceKey && !hasCreditNoteKey) {
|
|
6876
|
+
throw new KSeFValidationError(
|
|
6877
|
+
"PEF input must contain either an `Invoice` or a `CreditNote` root element."
|
|
6878
|
+
);
|
|
6879
|
+
}
|
|
6880
|
+
const rootKey = hasInvoiceKey ? "Invoice" : "CreditNote";
|
|
6881
|
+
if (!isNonArrayObject(input[rootKey])) {
|
|
6882
|
+
throw new KSeFValidationError(
|
|
6883
|
+
`PEF \`${rootKey}\` value must be a non-array object.`
|
|
6884
|
+
);
|
|
6885
|
+
}
|
|
6886
|
+
}
|
|
6887
|
+
function buildPefXml(input, options = {}) {
|
|
6888
|
+
assertPefShape(input);
|
|
6889
|
+
const inferred = inferSchema(input);
|
|
6890
|
+
const schema = options.schema ?? input.schema ?? inferred;
|
|
6891
|
+
if (schema !== inferred) {
|
|
6892
|
+
throw new KSeFValidationError(
|
|
6893
|
+
`PEF schema mismatch: expected ${inferred} based on root element, got ${schema}.`
|
|
6894
|
+
);
|
|
6895
|
+
}
|
|
6896
|
+
const commonNamespaces = {
|
|
6897
|
+
"@_xmlns:ext": UBL_EXT_NS,
|
|
6898
|
+
"@_xmlns:cbc": UBL_CBC_NS,
|
|
6899
|
+
"@_xmlns:cac": UBL_CAC_NS,
|
|
6900
|
+
"@_xmlns:cbc-pl": UBL_CBC_PL_NS,
|
|
6901
|
+
"@_xmlns:cac-pl": UBL_CAC_PL_NS
|
|
6902
|
+
};
|
|
6903
|
+
const document = "Invoice" in input ? {
|
|
6904
|
+
Invoice: {
|
|
6905
|
+
...input.Invoice,
|
|
6906
|
+
"@_xmlns": PEF_NAMESPACE.PEF,
|
|
6907
|
+
...commonNamespaces
|
|
6908
|
+
}
|
|
6909
|
+
} : {
|
|
6910
|
+
CreditNote: {
|
|
6911
|
+
...input.CreditNote,
|
|
6912
|
+
"@_xmlns": PEF_NAMESPACE.PEF_KOR,
|
|
6913
|
+
...commonNamespaces
|
|
6914
|
+
}
|
|
6915
|
+
};
|
|
6916
|
+
return buildXmlFromObject(document, { pretty: options.pretty });
|
|
6917
|
+
}
|
|
6918
|
+
|
|
6919
|
+
// src/xml/invoice-serializer.ts
|
|
6920
|
+
init_ksef_validation_error();
|
|
6921
|
+
var FAKTURA_SCHEMAS = /* @__PURE__ */ new Set(["FA2", "FA3"]);
|
|
6922
|
+
var PEF_SCHEMAS = /* @__PURE__ */ new Set(["PEF", "PEF_KOR"]);
|
|
6923
|
+
function isNonArrayObject2(value) {
|
|
6924
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6925
|
+
}
|
|
6926
|
+
function classifyUnknownObject(input) {
|
|
6927
|
+
const looksLikeFaktura = "Naglowek" in input || "Fa" in input || "Podmiot1" in input || "Podmiot2" in input;
|
|
6928
|
+
const hasInvoice = "Invoice" in input;
|
|
6929
|
+
const hasCreditNote = "CreditNote" in input;
|
|
6930
|
+
if (hasInvoice && hasCreditNote) {
|
|
6931
|
+
return new KSeFValidationError(
|
|
6932
|
+
"Input must contain exactly one of `Invoice` or `CreditNote`, not both."
|
|
6933
|
+
);
|
|
6934
|
+
}
|
|
6935
|
+
if (hasInvoice !== hasCreditNote) {
|
|
6936
|
+
const rootKey = hasInvoice ? "Invoice" : "CreditNote";
|
|
6937
|
+
if (!isNonArrayObject2(input[rootKey])) {
|
|
6938
|
+
return KSeFValidationError.fromField(
|
|
6939
|
+
rootKey,
|
|
6940
|
+
`PEF \`${rootKey}\` value must be a non-array object.`
|
|
6941
|
+
);
|
|
6942
|
+
}
|
|
6943
|
+
}
|
|
6944
|
+
if (looksLikeFaktura) {
|
|
6945
|
+
const missing = [];
|
|
6946
|
+
if (!("Naglowek" in input)) missing.push("Naglowek");
|
|
6947
|
+
if (!("Fa" in input)) missing.push("Fa");
|
|
6948
|
+
if (missing.length > 0) {
|
|
6949
|
+
return KSeFValidationError.fromField(
|
|
6950
|
+
missing[0],
|
|
6951
|
+
`Faktura input is missing required top-level key(s): ${missing.join(", ")}.`
|
|
6952
|
+
);
|
|
6953
|
+
}
|
|
6954
|
+
for (const key of ["Naglowek", "Fa"]) {
|
|
6955
|
+
if (!isNonArrayObject2(input[key])) {
|
|
6956
|
+
return KSeFValidationError.fromField(
|
|
6957
|
+
key,
|
|
6958
|
+
`Faktura \`${key}\` value must be a non-null, non-array object.`
|
|
6959
|
+
);
|
|
6960
|
+
}
|
|
6961
|
+
}
|
|
6962
|
+
return new KSeFValidationError(
|
|
6963
|
+
"Faktura-like input failed shape validation: `Naglowek` and `Fa` must be own enumerable properties on the input object."
|
|
6964
|
+
);
|
|
6965
|
+
}
|
|
6966
|
+
return new KSeFValidationError(
|
|
6967
|
+
"Unsupported invoice input shape: expected `FakturaInput` (with `Naglowek` + `Fa`) or `PefUblDocumentInput` (with `Invoice` or `CreditNote`)."
|
|
6968
|
+
);
|
|
6969
|
+
}
|
|
6970
|
+
function serializeInvoiceXml(input, options) {
|
|
6971
|
+
if (Buffer.isBuffer(input)) return input;
|
|
6972
|
+
if (typeof input === "string") {
|
|
6973
|
+
return Buffer.from(stripBom(input), "utf8");
|
|
6974
|
+
}
|
|
6975
|
+
if (Array.isArray(input)) {
|
|
6976
|
+
return Buffer.from(stripBom(buildXml(input)), "utf8");
|
|
6977
|
+
}
|
|
6978
|
+
if (input && typeof input === "object") {
|
|
6979
|
+
const schema = options?.schema;
|
|
6980
|
+
if (isPefUblDocumentInput(input)) {
|
|
6981
|
+
if (schema && !PEF_SCHEMAS.has(schema)) {
|
|
6982
|
+
throw new KSeFValidationError(
|
|
6983
|
+
`schema option ${schema} is not compatible with a PEF / PEF_KOR input.`
|
|
6984
|
+
);
|
|
6985
|
+
}
|
|
6986
|
+
const pefSchema = schema === "PEF" || schema === "PEF_KOR" ? schema : void 0;
|
|
6987
|
+
const xml = buildPefXml(input, {
|
|
6988
|
+
schema: pefSchema,
|
|
6989
|
+
pretty: options?.pretty
|
|
6990
|
+
});
|
|
6991
|
+
return Buffer.from(stripBom(xml), "utf8");
|
|
6992
|
+
}
|
|
6993
|
+
if (isFakturaInput(input)) {
|
|
6994
|
+
if (schema && !FAKTURA_SCHEMAS.has(schema)) {
|
|
6995
|
+
throw new KSeFValidationError(
|
|
6996
|
+
`schema option ${schema} is not compatible with a Faktura input.`
|
|
6997
|
+
);
|
|
6998
|
+
}
|
|
6999
|
+
const fakturaSchema = schema === "FA2" || schema === "FA3" ? schema : void 0;
|
|
7000
|
+
const xml = buildFakturaXml(input, {
|
|
7001
|
+
schema: fakturaSchema,
|
|
7002
|
+
fakturaNamespace: options?.fakturaNamespace,
|
|
7003
|
+
etdNamespace: options?.etdNamespace,
|
|
7004
|
+
pretty: options?.pretty
|
|
7005
|
+
});
|
|
7006
|
+
return Buffer.from(stripBom(xml), "utf8");
|
|
7007
|
+
}
|
|
7008
|
+
throw classifyUnknownObject(input);
|
|
7009
|
+
}
|
|
7010
|
+
throw new KSeFValidationError(
|
|
7011
|
+
"Unsupported invoice input type: expected Buffer, string, XmlDocument, FakturaInput, or PefUblDocumentInput."
|
|
7012
|
+
);
|
|
7013
|
+
}
|
|
7014
|
+
function buildRawXmlString(document, options) {
|
|
7015
|
+
return buildXmlFromObject(document, options);
|
|
7016
|
+
}
|
|
7017
|
+
|
|
6059
7018
|
// src/workflows/online-session-workflow.ts
|
|
6060
7019
|
init_invoice_validator();
|
|
6061
7020
|
init_ksef_validation_error();
|
|
@@ -6784,10 +7743,13 @@ export {
|
|
|
6784
7743
|
CertificateService,
|
|
6785
7744
|
CryptographyService,
|
|
6786
7745
|
DEFAULT_FORM_CODE,
|
|
7746
|
+
DISCOURAGED_UNICODE_RANGES,
|
|
6787
7747
|
DefaultAuthManager,
|
|
6788
7748
|
ENFORCE_XADES_COMPLIANCE,
|
|
7749
|
+
ETD_NAMESPACE,
|
|
6789
7750
|
EntityPermissionGrantBuilder,
|
|
6790
7751
|
Environment,
|
|
7752
|
+
FAKTURA_NAMESPACE,
|
|
6791
7753
|
FORM_CODES,
|
|
6792
7754
|
FORM_CODE_KEYS,
|
|
6793
7755
|
FileHwmStore,
|
|
@@ -6804,9 +7766,13 @@ export {
|
|
|
6804
7766
|
KSEF_FEATURE_HEADER,
|
|
6805
7767
|
KSeFApiError,
|
|
6806
7768
|
KSeFAuthStatusError,
|
|
7769
|
+
KSeFBadRequestError,
|
|
7770
|
+
KSeFBatchTimeoutError,
|
|
6807
7771
|
KSeFClient,
|
|
6808
7772
|
KSeFError,
|
|
7773
|
+
KSeFErrorCode,
|
|
6809
7774
|
KSeFForbiddenError,
|
|
7775
|
+
KSeFGoneError,
|
|
6810
7776
|
KSeFRateLimitError,
|
|
6811
7777
|
KSeFSessionExpiredError,
|
|
6812
7778
|
KSeFUnauthorizedError,
|
|
@@ -6818,8 +7784,10 @@ export {
|
|
|
6818
7784
|
LimitsService,
|
|
6819
7785
|
Nip,
|
|
6820
7786
|
NipVatUe,
|
|
7787
|
+
ORDER_MAP,
|
|
6821
7788
|
OfflineInvoiceWorkflow,
|
|
6822
7789
|
OnlineSessionService,
|
|
7790
|
+
PEF_NAMESPACE,
|
|
6823
7791
|
PERMISSION_DESCRIPTION_MAX_LENGTH,
|
|
6824
7792
|
PERMISSION_DESCRIPTION_MIN_LENGTH,
|
|
6825
7793
|
PeppolId,
|
|
@@ -6849,14 +7817,21 @@ export {
|
|
|
6849
7817
|
VatUe,
|
|
6850
7818
|
VerificationLinkService,
|
|
6851
7819
|
addBusinessDays,
|
|
7820
|
+
assertNever,
|
|
6852
7821
|
authenticateWithCertificate,
|
|
6853
7822
|
authenticateWithExternalSignature,
|
|
6854
7823
|
authenticateWithPkcs12,
|
|
6855
7824
|
authenticateWithToken,
|
|
6856
7825
|
batchValidationDetails,
|
|
7826
|
+
buildFakturaXml,
|
|
7827
|
+
buildPefXml,
|
|
7828
|
+
buildRawXmlString,
|
|
6857
7829
|
buildUnsignedAuthTokenRequestXml,
|
|
7830
|
+
buildXml,
|
|
7831
|
+
buildXmlFromObject,
|
|
6858
7832
|
calculateBackoff,
|
|
6859
7833
|
calculateOfflineDeadline,
|
|
7834
|
+
comparePKey,
|
|
6860
7835
|
createZip,
|
|
6861
7836
|
decodeJwtPayload,
|
|
6862
7837
|
deduplicateByKsefNumber,
|
|
@@ -6875,6 +7850,9 @@ export {
|
|
|
6875
7850
|
getTimeUntilDeadline,
|
|
6876
7851
|
incrementalExportAndDownload,
|
|
6877
7852
|
isExpired,
|
|
7853
|
+
isFakturaInput,
|
|
7854
|
+
isFormCodeShape,
|
|
7855
|
+
isPefUblDocumentInput,
|
|
6878
7856
|
isPolishHoliday,
|
|
6879
7857
|
isRetryableError,
|
|
6880
7858
|
isRetryableStatus,
|
|
@@ -6896,16 +7874,21 @@ export {
|
|
|
6896
7874
|
nextBusinessDay,
|
|
6897
7875
|
openOnlineSession,
|
|
6898
7876
|
openSendAndClose,
|
|
7877
|
+
orderXmlObject,
|
|
6899
7878
|
parseFormCode,
|
|
6900
7879
|
parseKSeFTokenContext,
|
|
6901
7880
|
parseRetryAfter,
|
|
6902
7881
|
parseUpoXml,
|
|
7882
|
+
parseXml,
|
|
6903
7883
|
pollUntil,
|
|
6904
7884
|
resolveOptions,
|
|
6905
7885
|
resumeOnlineSession,
|
|
6906
7886
|
runWithConcurrency,
|
|
7887
|
+
serializeInvoiceXml,
|
|
6907
7888
|
sha256Base642 as sha256Base64,
|
|
6908
7889
|
sleep,
|
|
7890
|
+
stripBom,
|
|
7891
|
+
toKodFormularza,
|
|
6909
7892
|
unzip,
|
|
6910
7893
|
updateContinuationPoint,
|
|
6911
7894
|
uploadBatch,
|
|
@@ -6915,6 +7898,7 @@ export {
|
|
|
6915
7898
|
validate,
|
|
6916
7899
|
validateBatch,
|
|
6917
7900
|
validateBusinessRules,
|
|
7901
|
+
validateCharValidity,
|
|
6918
7902
|
validateFormCodeForSession,
|
|
6919
7903
|
validatePresignedUrl,
|
|
6920
7904
|
validateSchema,
|