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.cjs
CHANGED
|
@@ -65,7 +65,8 @@ function resolveOptions(options = {}) {
|
|
|
65
65
|
apiVersion: options.apiVersion ?? DEFAULT_API_VERSION,
|
|
66
66
|
timeout: options.timeout ?? DEFAULT_TIMEOUT,
|
|
67
67
|
customHeaders: options.customHeaders ?? {},
|
|
68
|
-
environmentName: options.environment ?? (options.baseUrl ? void 0 : "TEST")
|
|
68
|
+
environmentName: options.environment ?? (options.baseUrl ? void 0 : "TEST"),
|
|
69
|
+
errorFormat: options.errorFormat ?? "problem-details"
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
var DEFAULT_API_VERSION, DEFAULT_TIMEOUT;
|
|
@@ -121,6 +122,9 @@ var init_ksef_api_error = __esm({
|
|
|
121
122
|
const message = details?.length ? details.map((d) => d.exceptionDescription ?? "").filter(Boolean).join("; ") || `KSeF API error: HTTP ${statusCode}` : `KSeF API error: HTTP ${statusCode}`;
|
|
122
123
|
return new _KSeFApiError(message, statusCode, body);
|
|
123
124
|
}
|
|
125
|
+
toProblemFields() {
|
|
126
|
+
return { detail: this.message };
|
|
127
|
+
}
|
|
124
128
|
};
|
|
125
129
|
}
|
|
126
130
|
});
|
|
@@ -132,17 +136,20 @@ var init_ksef_rate_limit_error = __esm({
|
|
|
132
136
|
"use strict";
|
|
133
137
|
init_ksef_api_error();
|
|
134
138
|
KSeFRateLimitError = class _KSeFRateLimitError extends KSeFApiError {
|
|
139
|
+
statusCode = 429;
|
|
135
140
|
retryAfterSeconds;
|
|
136
141
|
retryAfterDate;
|
|
137
142
|
recommendedDelay;
|
|
138
|
-
|
|
143
|
+
problem;
|
|
144
|
+
constructor(message, statusCode, errorResponse, retryAfterSeconds, retryAfterDate, problem) {
|
|
139
145
|
super(message, statusCode, errorResponse);
|
|
140
146
|
this.name = "KSeFRateLimitError";
|
|
141
147
|
this.retryAfterSeconds = retryAfterSeconds;
|
|
142
148
|
this.retryAfterDate = retryAfterDate;
|
|
143
149
|
this.recommendedDelay = retryAfterSeconds ?? 60;
|
|
150
|
+
this.problem = problem;
|
|
144
151
|
}
|
|
145
|
-
static fromRetryAfterHeader(statusCode, retryAfterHeader, body) {
|
|
152
|
+
static fromRetryAfterHeader(statusCode, retryAfterHeader, body, problem) {
|
|
146
153
|
let retryAfterSeconds;
|
|
147
154
|
let retryAfterDate;
|
|
148
155
|
if (retryAfterHeader) {
|
|
@@ -157,8 +164,16 @@ var init_ksef_rate_limit_error = __esm({
|
|
|
157
164
|
}
|
|
158
165
|
}
|
|
159
166
|
}
|
|
160
|
-
const message = retryAfterSeconds != null ? `Rate limited. Retry after ${retryAfterSeconds}s` : "Rate limited by KSeF API";
|
|
161
|
-
return new _KSeFRateLimitError(message, statusCode, body, retryAfterSeconds, retryAfterDate);
|
|
167
|
+
const message = retryAfterSeconds != null ? `Rate limited. Retry after ${retryAfterSeconds}s` : problem?.detail ?? "Rate limited by KSeF API";
|
|
168
|
+
return new _KSeFRateLimitError(message, statusCode, body, retryAfterSeconds, retryAfterDate, problem);
|
|
169
|
+
}
|
|
170
|
+
toProblemFields() {
|
|
171
|
+
return {
|
|
172
|
+
detail: this.problem?.detail,
|
|
173
|
+
traceId: this.problem?.traceId,
|
|
174
|
+
instance: this.problem?.instance,
|
|
175
|
+
timestamp: this.problem?.timestamp
|
|
176
|
+
};
|
|
162
177
|
}
|
|
163
178
|
};
|
|
164
179
|
}
|
|
@@ -169,18 +184,28 @@ var KSeFUnauthorizedError;
|
|
|
169
184
|
var init_ksef_unauthorized_error = __esm({
|
|
170
185
|
"src/errors/ksef-unauthorized-error.ts"() {
|
|
171
186
|
"use strict";
|
|
172
|
-
|
|
173
|
-
KSeFUnauthorizedError = class extends
|
|
187
|
+
init_ksef_api_error();
|
|
188
|
+
KSeFUnauthorizedError = class extends KSeFApiError {
|
|
174
189
|
statusCode = 401;
|
|
175
190
|
detail;
|
|
176
191
|
traceId;
|
|
177
192
|
instance;
|
|
193
|
+
timestamp;
|
|
178
194
|
constructor(problemDetails) {
|
|
179
|
-
super(problemDetails.detail || "Unauthorized");
|
|
195
|
+
super(problemDetails.detail || "Unauthorized", 401);
|
|
180
196
|
this.name = "KSeFUnauthorizedError";
|
|
181
197
|
this.detail = problemDetails.detail;
|
|
182
198
|
this.traceId = problemDetails.traceId;
|
|
183
199
|
this.instance = problemDetails.instance;
|
|
200
|
+
this.timestamp = problemDetails.timestamp;
|
|
201
|
+
}
|
|
202
|
+
toProblemFields() {
|
|
203
|
+
return {
|
|
204
|
+
detail: this.detail,
|
|
205
|
+
traceId: this.traceId,
|
|
206
|
+
instance: this.instance,
|
|
207
|
+
timestamp: this.timestamp
|
|
208
|
+
};
|
|
184
209
|
}
|
|
185
210
|
};
|
|
186
211
|
}
|
|
@@ -191,22 +216,101 @@ var KSeFForbiddenError;
|
|
|
191
216
|
var init_ksef_forbidden_error = __esm({
|
|
192
217
|
"src/errors/ksef-forbidden-error.ts"() {
|
|
193
218
|
"use strict";
|
|
194
|
-
|
|
195
|
-
KSeFForbiddenError = class extends
|
|
219
|
+
init_ksef_api_error();
|
|
220
|
+
KSeFForbiddenError = class extends KSeFApiError {
|
|
196
221
|
statusCode = 403;
|
|
197
222
|
detail;
|
|
198
223
|
reasonCode;
|
|
199
224
|
instance;
|
|
200
225
|
security;
|
|
201
226
|
traceId;
|
|
227
|
+
timestamp;
|
|
202
228
|
constructor(problemDetails) {
|
|
203
|
-
super(problemDetails.detail || "Forbidden");
|
|
229
|
+
super(problemDetails.detail || "Forbidden", 403);
|
|
204
230
|
this.name = "KSeFForbiddenError";
|
|
205
231
|
this.detail = problemDetails.detail;
|
|
206
232
|
this.reasonCode = problemDetails.reasonCode;
|
|
207
233
|
this.instance = problemDetails.instance;
|
|
208
234
|
this.security = problemDetails.security;
|
|
209
235
|
this.traceId = problemDetails.traceId;
|
|
236
|
+
this.timestamp = problemDetails.timestamp;
|
|
237
|
+
}
|
|
238
|
+
toProblemFields() {
|
|
239
|
+
return {
|
|
240
|
+
detail: this.detail,
|
|
241
|
+
reasonCode: this.reasonCode,
|
|
242
|
+
security: this.security,
|
|
243
|
+
traceId: this.traceId,
|
|
244
|
+
instance: this.instance,
|
|
245
|
+
timestamp: this.timestamp
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// src/errors/ksef-gone-error.ts
|
|
253
|
+
var KSeFGoneError;
|
|
254
|
+
var init_ksef_gone_error = __esm({
|
|
255
|
+
"src/errors/ksef-gone-error.ts"() {
|
|
256
|
+
"use strict";
|
|
257
|
+
init_ksef_api_error();
|
|
258
|
+
KSeFGoneError = class extends KSeFApiError {
|
|
259
|
+
statusCode = 410;
|
|
260
|
+
detail;
|
|
261
|
+
instance;
|
|
262
|
+
traceId;
|
|
263
|
+
timestamp;
|
|
264
|
+
constructor(problemDetails) {
|
|
265
|
+
super(problemDetails.detail || "Operation status no longer available (retention expired)", 410);
|
|
266
|
+
this.name = "KSeFGoneError";
|
|
267
|
+
this.detail = problemDetails.detail;
|
|
268
|
+
this.instance = problemDetails.instance;
|
|
269
|
+
this.traceId = problemDetails.traceId;
|
|
270
|
+
this.timestamp = problemDetails.timestamp;
|
|
271
|
+
}
|
|
272
|
+
toProblemFields() {
|
|
273
|
+
return {
|
|
274
|
+
detail: this.detail,
|
|
275
|
+
traceId: this.traceId,
|
|
276
|
+
instance: this.instance,
|
|
277
|
+
timestamp: this.timestamp
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// src/errors/ksef-bad-request-error.ts
|
|
285
|
+
var KSeFBadRequestError;
|
|
286
|
+
var init_ksef_bad_request_error = __esm({
|
|
287
|
+
"src/errors/ksef-bad-request-error.ts"() {
|
|
288
|
+
"use strict";
|
|
289
|
+
init_ksef_api_error();
|
|
290
|
+
KSeFBadRequestError = class extends KSeFApiError {
|
|
291
|
+
statusCode = 400;
|
|
292
|
+
detail;
|
|
293
|
+
instance;
|
|
294
|
+
errors;
|
|
295
|
+
traceId;
|
|
296
|
+
timestamp;
|
|
297
|
+
constructor(problemDetails) {
|
|
298
|
+
super(problemDetails.detail || problemDetails.title || "Bad Request", 400);
|
|
299
|
+
this.name = "KSeFBadRequestError";
|
|
300
|
+
this.detail = problemDetails.detail;
|
|
301
|
+
this.instance = problemDetails.instance;
|
|
302
|
+
this.errors = problemDetails.errors ?? [];
|
|
303
|
+
this.traceId = problemDetails.traceId;
|
|
304
|
+
this.timestamp = problemDetails.timestamp;
|
|
305
|
+
}
|
|
306
|
+
toProblemFields() {
|
|
307
|
+
return {
|
|
308
|
+
detail: this.detail,
|
|
309
|
+
errors: this.errors.length ? this.errors : void 0,
|
|
310
|
+
traceId: this.traceId,
|
|
311
|
+
instance: this.instance,
|
|
312
|
+
timestamp: this.timestamp
|
|
313
|
+
};
|
|
210
314
|
}
|
|
211
315
|
};
|
|
212
316
|
}
|
|
@@ -274,6 +378,55 @@ var init_ksef_validation_error = __esm({
|
|
|
274
378
|
}
|
|
275
379
|
});
|
|
276
380
|
|
|
381
|
+
// src/errors/error-codes.ts
|
|
382
|
+
function hasErrorCode(body, code) {
|
|
383
|
+
return !!body?.exception?.exceptionDetailList?.some((d) => d.exceptionCode === code);
|
|
384
|
+
}
|
|
385
|
+
var KSeFErrorCode;
|
|
386
|
+
var init_error_codes = __esm({
|
|
387
|
+
"src/errors/error-codes.ts"() {
|
|
388
|
+
"use strict";
|
|
389
|
+
KSeFErrorCode = {
|
|
390
|
+
BatchTimeout: 21208,
|
|
391
|
+
DuplicateInvoice: 440
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// src/errors/ksef-batch-timeout-error.ts
|
|
397
|
+
var KSeFBatchTimeoutError;
|
|
398
|
+
var init_ksef_batch_timeout_error = __esm({
|
|
399
|
+
"src/errors/ksef-batch-timeout-error.ts"() {
|
|
400
|
+
"use strict";
|
|
401
|
+
init_ksef_api_error();
|
|
402
|
+
init_error_codes();
|
|
403
|
+
KSeFBatchTimeoutError = class _KSeFBatchTimeoutError extends KSeFApiError {
|
|
404
|
+
errorCode = KSeFErrorCode.BatchTimeout;
|
|
405
|
+
constructor(message, statusCode, errorResponse) {
|
|
406
|
+
super(message, statusCode, errorResponse);
|
|
407
|
+
this.name = "KSeFBatchTimeoutError";
|
|
408
|
+
}
|
|
409
|
+
static fromResponse(statusCode, body) {
|
|
410
|
+
const detail = body?.exception?.exceptionDetailList?.find(
|
|
411
|
+
(d) => d.exceptionCode === KSeFErrorCode.BatchTimeout
|
|
412
|
+
);
|
|
413
|
+
const message = detail?.exceptionDescription?.trim() || "Batch session timed out before the server completed processing (KSeF 21208).";
|
|
414
|
+
return new _KSeFBatchTimeoutError(message, statusCode, body);
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// src/errors/assert-never.ts
|
|
421
|
+
function assertNever(value) {
|
|
422
|
+
throw new Error(`Unexpected value: ${String(value)}`);
|
|
423
|
+
}
|
|
424
|
+
var init_assert_never = __esm({
|
|
425
|
+
"src/errors/assert-never.ts"() {
|
|
426
|
+
"use strict";
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
277
430
|
// src/errors/index.ts
|
|
278
431
|
var init_errors = __esm({
|
|
279
432
|
"src/errors/index.ts"() {
|
|
@@ -283,9 +436,14 @@ var init_errors = __esm({
|
|
|
283
436
|
init_ksef_rate_limit_error();
|
|
284
437
|
init_ksef_unauthorized_error();
|
|
285
438
|
init_ksef_forbidden_error();
|
|
439
|
+
init_ksef_gone_error();
|
|
440
|
+
init_ksef_bad_request_error();
|
|
286
441
|
init_ksef_auth_status_error();
|
|
287
442
|
init_ksef_session_expired_error();
|
|
288
443
|
init_ksef_validation_error();
|
|
444
|
+
init_ksef_batch_timeout_error();
|
|
445
|
+
init_error_codes();
|
|
446
|
+
init_assert_never();
|
|
289
447
|
}
|
|
290
448
|
});
|
|
291
449
|
|
|
@@ -533,6 +691,27 @@ var init_presigned_url_policy = __esm({
|
|
|
533
691
|
});
|
|
534
692
|
|
|
535
693
|
// src/http/rest-client.ts
|
|
694
|
+
function isBadRequestProblem(value) {
|
|
695
|
+
if (typeof value !== "object" || value === null) return false;
|
|
696
|
+
const v = value;
|
|
697
|
+
if (typeof v.title !== "string") return false;
|
|
698
|
+
if (v.status !== void 0 && typeof v.status !== "number") return false;
|
|
699
|
+
if (v.errors !== void 0) {
|
|
700
|
+
if (!Array.isArray(v.errors)) return false;
|
|
701
|
+
for (const item of v.errors) {
|
|
702
|
+
if (typeof item !== "object" || item === null) return false;
|
|
703
|
+
const detail = item;
|
|
704
|
+
if (typeof detail.code !== "number") return false;
|
|
705
|
+
if (typeof detail.description !== "string") return false;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
function isTooManyRequestsProblem(value) {
|
|
711
|
+
if (typeof value !== "object" || value === null) return false;
|
|
712
|
+
const v = value;
|
|
713
|
+
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");
|
|
714
|
+
}
|
|
536
715
|
var import_consola, RestClient;
|
|
537
716
|
var init_rest_client = __esm({
|
|
538
717
|
"src/http/rest-client.ts"() {
|
|
@@ -542,6 +721,10 @@ var init_rest_client = __esm({
|
|
|
542
721
|
init_ksef_rate_limit_error();
|
|
543
722
|
init_ksef_unauthorized_error();
|
|
544
723
|
init_ksef_forbidden_error();
|
|
724
|
+
init_ksef_gone_error();
|
|
725
|
+
init_ksef_bad_request_error();
|
|
726
|
+
init_ksef_batch_timeout_error();
|
|
727
|
+
init_error_codes();
|
|
545
728
|
init_route_builder();
|
|
546
729
|
init_transport();
|
|
547
730
|
init_retry_policy();
|
|
@@ -628,6 +811,10 @@ var init_rest_client = __esm({
|
|
|
628
811
|
...this.options.customHeaders,
|
|
629
812
|
...request.getHeaders()
|
|
630
813
|
};
|
|
814
|
+
const hasHeader = (name) => Object.keys(headers).some((header) => header.toLowerCase() === name.toLowerCase());
|
|
815
|
+
if (this.options.errorFormat !== "legacy" && !hasHeader("x-error-format")) {
|
|
816
|
+
headers["X-Error-Format"] = "problem-details";
|
|
817
|
+
}
|
|
631
818
|
if (!headers["Authorization"] && this.authManager) {
|
|
632
819
|
const token = overrideToken ?? this.authManager.getAccessToken();
|
|
633
820
|
if (token) {
|
|
@@ -666,34 +853,70 @@ var init_rest_client = __esm({
|
|
|
666
853
|
async ensureSuccess(response) {
|
|
667
854
|
if (response.ok) return;
|
|
668
855
|
const text = await response.text().catch(() => "");
|
|
856
|
+
let jsonCache = null;
|
|
669
857
|
const parseJson = () => {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
858
|
+
if (jsonCache === null) {
|
|
859
|
+
try {
|
|
860
|
+
jsonCache = { value: JSON.parse(text) };
|
|
861
|
+
} catch {
|
|
862
|
+
jsonCache = { value: void 0 };
|
|
863
|
+
}
|
|
674
864
|
}
|
|
865
|
+
return jsonCache.value;
|
|
675
866
|
};
|
|
676
|
-
|
|
867
|
+
const tryParseProblem = (guard) => {
|
|
677
868
|
const parsed = parseJson();
|
|
869
|
+
return parsed !== void 0 && guard(parsed) ? parsed : void 0;
|
|
870
|
+
};
|
|
871
|
+
if (response.status === 400) {
|
|
872
|
+
const problem = tryParseProblem(isBadRequestProblem);
|
|
873
|
+
if (problem) {
|
|
874
|
+
throw new KSeFBadRequestError(problem);
|
|
875
|
+
}
|
|
876
|
+
const legacy = parseJson();
|
|
877
|
+
if (hasErrorCode(legacy, KSeFErrorCode.BatchTimeout)) {
|
|
878
|
+
throw KSeFBatchTimeoutError.fromResponse(400, legacy);
|
|
879
|
+
}
|
|
880
|
+
throw KSeFApiError.fromResponse(400, legacy);
|
|
881
|
+
}
|
|
882
|
+
if (response.status === 429) {
|
|
883
|
+
const problem = tryParseProblem(isTooManyRequestsProblem);
|
|
884
|
+
const legacy = problem ? void 0 : parseJson();
|
|
678
885
|
throw KSeFRateLimitError.fromRetryAfterHeader(
|
|
679
886
|
response.status,
|
|
680
887
|
response.headers.get("Retry-After"),
|
|
681
|
-
|
|
888
|
+
legacy,
|
|
889
|
+
problem
|
|
682
890
|
);
|
|
683
891
|
}
|
|
684
892
|
if (response.status === 401) {
|
|
685
|
-
const
|
|
686
|
-
if (
|
|
687
|
-
throw new KSeFUnauthorizedError(
|
|
893
|
+
const body2 = parseJson();
|
|
894
|
+
if (body2?.detail) {
|
|
895
|
+
throw new KSeFUnauthorizedError(body2);
|
|
688
896
|
}
|
|
689
897
|
}
|
|
690
898
|
if (response.status === 403) {
|
|
691
|
-
const
|
|
692
|
-
if (
|
|
693
|
-
throw new KSeFForbiddenError(
|
|
899
|
+
const body2 = parseJson();
|
|
900
|
+
if (body2?.reasonCode) {
|
|
901
|
+
throw new KSeFForbiddenError(body2);
|
|
694
902
|
}
|
|
695
903
|
}
|
|
696
|
-
|
|
904
|
+
if (response.status === 410) {
|
|
905
|
+
const body2 = parseJson();
|
|
906
|
+
throw new KSeFGoneError({
|
|
907
|
+
title: body2?.title || "Gone",
|
|
908
|
+
status: body2?.status || 410,
|
|
909
|
+
detail: body2?.detail || "Operation status no longer available (retention expired)",
|
|
910
|
+
instance: body2?.instance,
|
|
911
|
+
traceId: body2?.traceId,
|
|
912
|
+
timestamp: body2?.timestamp
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
const body = parseJson();
|
|
916
|
+
if (hasErrorCode(body, KSeFErrorCode.BatchTimeout)) {
|
|
917
|
+
throw KSeFBatchTimeoutError.fromResponse(response.status, body);
|
|
918
|
+
}
|
|
919
|
+
throw KSeFApiError.fromResponse(response.status, body);
|
|
697
920
|
}
|
|
698
921
|
};
|
|
699
922
|
}
|
|
@@ -2613,6 +2836,115 @@ var init_schema_registry = __esm({
|
|
|
2613
2836
|
}
|
|
2614
2837
|
});
|
|
2615
2838
|
|
|
2839
|
+
// src/validation/char-validity.ts
|
|
2840
|
+
function validateCharValidity(xml) {
|
|
2841
|
+
return [...findProcessingInstructions(xml), ...findDiscouragedUnicode(xml)];
|
|
2842
|
+
}
|
|
2843
|
+
function findProcessingInstructionTokens(xml) {
|
|
2844
|
+
const tokens = [];
|
|
2845
|
+
for (let i = 0; i < xml.length; ) {
|
|
2846
|
+
if (xml.startsWith("<!--", i)) {
|
|
2847
|
+
const end = xml.indexOf("-->", i + 4);
|
|
2848
|
+
i = end === -1 ? xml.length : end + 3;
|
|
2849
|
+
continue;
|
|
2850
|
+
}
|
|
2851
|
+
if (xml.startsWith("<![CDATA[", i)) {
|
|
2852
|
+
const end = xml.indexOf("]]>", i + 9);
|
|
2853
|
+
i = end === -1 ? xml.length : end + 3;
|
|
2854
|
+
continue;
|
|
2855
|
+
}
|
|
2856
|
+
if (xml.startsWith("<?", i)) {
|
|
2857
|
+
const end = xml.indexOf("?>", i + 2);
|
|
2858
|
+
if (end === -1) break;
|
|
2859
|
+
tokens.push({ token: xml.slice(i, end + 2), index: i });
|
|
2860
|
+
i = end + 2;
|
|
2861
|
+
continue;
|
|
2862
|
+
}
|
|
2863
|
+
i += 1;
|
|
2864
|
+
}
|
|
2865
|
+
return tokens;
|
|
2866
|
+
}
|
|
2867
|
+
function findProcessingInstructions(xml) {
|
|
2868
|
+
const errors = [];
|
|
2869
|
+
const matches = findProcessingInstructionTokens(xml);
|
|
2870
|
+
if (matches.length === 0) return errors;
|
|
2871
|
+
const firstMatch = matches[0];
|
|
2872
|
+
const firstTarget = firstMatch.token.match(PI_TARGET_RE)?.[1];
|
|
2873
|
+
const hasBom = xml.charCodeAt(0) === 65279;
|
|
2874
|
+
const prologPosition = hasBom ? 1 : 0;
|
|
2875
|
+
const firstIsProlog = firstMatch.index === prologPosition && firstTarget === "xml";
|
|
2876
|
+
for (let i = 0; i < matches.length; i++) {
|
|
2877
|
+
if (i === 0 && firstIsProlog) continue;
|
|
2878
|
+
const m = matches[i];
|
|
2879
|
+
const target = m.token.match(PI_TARGET_RE)?.[1] ?? "?";
|
|
2880
|
+
errors.push({
|
|
2881
|
+
code: "XML_PROCESSING_INSTRUCTION",
|
|
2882
|
+
message: `Processing instruction <?${target}?> at offset ${m.index} is not allowed (only <?xml ... ?> prolog is permitted)`,
|
|
2883
|
+
path: `offset:${m.index}`
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2886
|
+
return errors;
|
|
2887
|
+
}
|
|
2888
|
+
function findDiscouragedUnicode(xml) {
|
|
2889
|
+
const errors = [];
|
|
2890
|
+
const seenRanges = /* @__PURE__ */ new Set();
|
|
2891
|
+
let utf16Offset = 0;
|
|
2892
|
+
for (const ch of xml) {
|
|
2893
|
+
const cp = ch.codePointAt(0);
|
|
2894
|
+
const idx = rangeIndex(cp);
|
|
2895
|
+
if (idx >= 0 && !seenRanges.has(idx)) {
|
|
2896
|
+
seenRanges.add(idx);
|
|
2897
|
+
errors.push({
|
|
2898
|
+
code: "XML_DISCOURAGED_UNICODE",
|
|
2899
|
+
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)`,
|
|
2900
|
+
path: `offset:${utf16Offset}`
|
|
2901
|
+
});
|
|
2902
|
+
}
|
|
2903
|
+
utf16Offset += ch.length;
|
|
2904
|
+
}
|
|
2905
|
+
return errors;
|
|
2906
|
+
}
|
|
2907
|
+
function rangeIndex(cp) {
|
|
2908
|
+
let lo = 0;
|
|
2909
|
+
let hi = DISCOURAGED_UNICODE_RANGES.length - 1;
|
|
2910
|
+
while (lo <= hi) {
|
|
2911
|
+
const mid = lo + hi >> 1;
|
|
2912
|
+
const [start, end] = DISCOURAGED_UNICODE_RANGES[mid];
|
|
2913
|
+
if (cp < start) hi = mid - 1;
|
|
2914
|
+
else if (cp > end) lo = mid + 1;
|
|
2915
|
+
else return mid;
|
|
2916
|
+
}
|
|
2917
|
+
return -1;
|
|
2918
|
+
}
|
|
2919
|
+
var DISCOURAGED_UNICODE_RANGES, PI_TARGET_RE;
|
|
2920
|
+
var init_char_validity = __esm({
|
|
2921
|
+
"src/validation/char-validity.ts"() {
|
|
2922
|
+
"use strict";
|
|
2923
|
+
DISCOURAGED_UNICODE_RANGES = [
|
|
2924
|
+
[127, 132],
|
|
2925
|
+
[134, 159],
|
|
2926
|
+
[64976, 65007],
|
|
2927
|
+
[131070, 131071],
|
|
2928
|
+
[196606, 196607],
|
|
2929
|
+
[262142, 262143],
|
|
2930
|
+
[327678, 327679],
|
|
2931
|
+
[393214, 393215],
|
|
2932
|
+
[458750, 458751],
|
|
2933
|
+
[524286, 524287],
|
|
2934
|
+
[589822, 589823],
|
|
2935
|
+
[655358, 655359],
|
|
2936
|
+
[720894, 720895],
|
|
2937
|
+
[786430, 786431],
|
|
2938
|
+
[851966, 851967],
|
|
2939
|
+
[917502, 917503],
|
|
2940
|
+
[983038, 983039],
|
|
2941
|
+
[1048574, 1048575],
|
|
2942
|
+
[1114110, 1114111]
|
|
2943
|
+
];
|
|
2944
|
+
PI_TARGET_RE = /^<\?(\S+)/;
|
|
2945
|
+
}
|
|
2946
|
+
});
|
|
2947
|
+
|
|
2616
2948
|
// src/validation/invoice-validator.ts
|
|
2617
2949
|
var invoice_validator_exports = {};
|
|
2618
2950
|
__export(invoice_validator_exports, {
|
|
@@ -2765,6 +3097,12 @@ function collectDateErrors(obj, rootElement, errors) {
|
|
|
2765
3097
|
}
|
|
2766
3098
|
}
|
|
2767
3099
|
async function validate(xml, options) {
|
|
3100
|
+
if (!options?.skipCharValidity) {
|
|
3101
|
+
const l1aErrors = validateCharValidity(xml);
|
|
3102
|
+
if (l1aErrors.length > 0) {
|
|
3103
|
+
return { valid: false, schemaType: null, errors: l1aErrors };
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
2768
3106
|
const parsed = xml && xml.trim() ? xmlToObject(xml) : void 0;
|
|
2769
3107
|
const l1 = validateWellFormedness(xml, parsed);
|
|
2770
3108
|
if (!l1.valid) return l1;
|
|
@@ -2791,6 +3129,7 @@ var init_invoice_validator = __esm({
|
|
|
2791
3129
|
"use strict";
|
|
2792
3130
|
init_xml_to_object();
|
|
2793
3131
|
init_schema_registry();
|
|
3132
|
+
init_char_validity();
|
|
2794
3133
|
init_patterns();
|
|
2795
3134
|
}
|
|
2796
3135
|
});
|
|
@@ -3255,9 +3594,10 @@ var PermissionsService;
|
|
|
3255
3594
|
var init_permissions = __esm({
|
|
3256
3595
|
"src/services/permissions.ts"() {
|
|
3257
3596
|
"use strict";
|
|
3597
|
+
init_ksef_validation_error();
|
|
3258
3598
|
init_rest_request();
|
|
3259
3599
|
init_routes();
|
|
3260
|
-
PermissionsService = class {
|
|
3600
|
+
PermissionsService = class _PermissionsService {
|
|
3261
3601
|
restClient;
|
|
3262
3602
|
constructor(restClient) {
|
|
3263
3603
|
this.restClient = restClient;
|
|
@@ -3315,6 +3655,7 @@ var init_permissions = __esm({
|
|
|
3315
3655
|
}
|
|
3316
3656
|
// Search methods
|
|
3317
3657
|
async queryPersonalGrants(options, pageOffset, pageSize) {
|
|
3658
|
+
_PermissionsService.validateContextIdentifier(options?.contextIdentifier);
|
|
3318
3659
|
const req = RestRequest.post(Routes.Permissions.Query.personalGrants).body(options ?? {});
|
|
3319
3660
|
if (pageOffset !== void 0) req.query("pageOffset", String(pageOffset));
|
|
3320
3661
|
if (pageSize !== void 0) req.query("pageSize", String(pageSize));
|
|
@@ -3343,6 +3684,7 @@ var init_permissions = __esm({
|
|
|
3343
3684
|
return response.body;
|
|
3344
3685
|
}
|
|
3345
3686
|
async queryEntitiesGrants(options, pageOffset, pageSize) {
|
|
3687
|
+
_PermissionsService.validateContextIdentifier(options?.contextIdentifier);
|
|
3346
3688
|
const req = RestRequest.post(Routes.Permissions.Query.entitiesGrants).body(options ?? {});
|
|
3347
3689
|
if (pageOffset !== void 0) req.query("pageOffset", String(pageOffset));
|
|
3348
3690
|
if (pageSize !== void 0) req.query("pageSize", String(pageSize));
|
|
@@ -3381,17 +3723,90 @@ var init_permissions = __esm({
|
|
|
3381
3723
|
const response = await this.restClient.execute(req);
|
|
3382
3724
|
return response.body;
|
|
3383
3725
|
}
|
|
3726
|
+
static validateContextIdentifier(ctx) {
|
|
3727
|
+
if (!ctx) return;
|
|
3728
|
+
if (ctx.type === "InternalId") {
|
|
3729
|
+
const len = ctx.value.length;
|
|
3730
|
+
if (len < 10 || len > 16) {
|
|
3731
|
+
throw KSeFValidationError.fromField(
|
|
3732
|
+
"contextIdentifier.value",
|
|
3733
|
+
`InternalId must be 10-16 characters, got ${len}`
|
|
3734
|
+
);
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3384
3738
|
};
|
|
3385
3739
|
}
|
|
3386
3740
|
});
|
|
3387
3741
|
|
|
3742
|
+
// src/utils/jwt.ts
|
|
3743
|
+
function decodeJwtPayload(token) {
|
|
3744
|
+
const parts = token.split(".");
|
|
3745
|
+
if (parts.length !== 3) return null;
|
|
3746
|
+
try {
|
|
3747
|
+
const payload = parts[1];
|
|
3748
|
+
const json = Buffer.from(payload, "base64url").toString("utf-8");
|
|
3749
|
+
return JSON.parse(json);
|
|
3750
|
+
} catch {
|
|
3751
|
+
return null;
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
function tryParseJson(value) {
|
|
3755
|
+
if (typeof value !== "string") return void 0;
|
|
3756
|
+
try {
|
|
3757
|
+
return JSON.parse(value);
|
|
3758
|
+
} catch {
|
|
3759
|
+
return void 0;
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
function tryParseJsonArray(value) {
|
|
3763
|
+
if (typeof value !== "string") return void 0;
|
|
3764
|
+
try {
|
|
3765
|
+
const parsed = JSON.parse(value);
|
|
3766
|
+
return Array.isArray(parsed) && parsed.every((item) => typeof item === "string") ? parsed : void 0;
|
|
3767
|
+
} catch {
|
|
3768
|
+
return void 0;
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
function parseKSeFTokenContext(token) {
|
|
3772
|
+
const raw = decodeJwtPayload(token);
|
|
3773
|
+
if (!raw) return null;
|
|
3774
|
+
return {
|
|
3775
|
+
type: typeof raw["typ"] === "string" ? raw["typ"] : void 0,
|
|
3776
|
+
contextIdentifierType: typeof raw["cit"] === "string" ? raw["cit"] : void 0,
|
|
3777
|
+
contextIdentifierValue: typeof raw["civ"] === "string" ? raw["civ"] : void 0,
|
|
3778
|
+
authMethod: typeof raw["aum"] === "string" ? raw["aum"] : void 0,
|
|
3779
|
+
permissions: tryParseJsonArray(raw["per"]),
|
|
3780
|
+
subjectDetails: tryParseJson(raw["sud"]),
|
|
3781
|
+
authorSubjectIdentifier: tryParseJson(raw["asi"]),
|
|
3782
|
+
issuedAt: typeof raw["iat"] === "number" ? raw["iat"] : void 0,
|
|
3783
|
+
expiresAt: typeof raw["exp"] === "number" ? raw["exp"] : void 0
|
|
3784
|
+
};
|
|
3785
|
+
}
|
|
3786
|
+
var init_jwt = __esm({
|
|
3787
|
+
"src/utils/jwt.ts"() {
|
|
3788
|
+
"use strict";
|
|
3789
|
+
}
|
|
3790
|
+
});
|
|
3791
|
+
|
|
3388
3792
|
// src/services/tokens.ts
|
|
3389
|
-
|
|
3793
|
+
function toTokenAuthorIdentifierType(value) {
|
|
3794
|
+
return TOKEN_AUTHOR_IDENTIFIER_TYPES.has(value) ? value : void 0;
|
|
3795
|
+
}
|
|
3796
|
+
var TOKEN_AUTHOR_IDENTIFIER_TYPES, TokenService;
|
|
3390
3797
|
var init_tokens = __esm({
|
|
3391
3798
|
"src/services/tokens.ts"() {
|
|
3392
3799
|
"use strict";
|
|
3393
3800
|
init_rest_request();
|
|
3394
3801
|
init_routes();
|
|
3802
|
+
init_jwt();
|
|
3803
|
+
init_ksef_api_error();
|
|
3804
|
+
init_ksef_error();
|
|
3805
|
+
TOKEN_AUTHOR_IDENTIFIER_TYPES = /* @__PURE__ */ new Set([
|
|
3806
|
+
"Nip",
|
|
3807
|
+
"Pesel",
|
|
3808
|
+
"Fingerprint"
|
|
3809
|
+
]);
|
|
3395
3810
|
TokenService = class {
|
|
3396
3811
|
restClient;
|
|
3397
3812
|
constructor(restClient) {
|
|
@@ -3426,6 +3841,73 @@ var init_tokens = __esm({
|
|
|
3426
3841
|
const req = RestRequest.delete(Routes.Tokens.byReference(ref));
|
|
3427
3842
|
await this.restClient.executeVoid(req);
|
|
3428
3843
|
}
|
|
3844
|
+
/**
|
|
3845
|
+
* Resolves the reference number of the token currently in use for authentication.
|
|
3846
|
+
* The only JWT payload field treated as authoritative is the KSeF-specific `trn`
|
|
3847
|
+
* (token reference number). Standard RFC 7519 claims such as `jti` are NOT a safe
|
|
3848
|
+
* fallback — a `jti` that differs from the KSeF reference would cause a DELETE to
|
|
3849
|
+
* hit a non-existent path, which `revokeSelf` treats as already-revoked, falsely
|
|
3850
|
+
* reporting success while leaving the token active on the server. When `trn` is
|
|
3851
|
+
* absent, we fall back to `GET /tokens` filtered by author and context; requires
|
|
3852
|
+
* exactly one active match and returns undefined when ambiguous.
|
|
3853
|
+
*/
|
|
3854
|
+
async findSelfReferenceNumber(accessToken) {
|
|
3855
|
+
if (!accessToken) return void 0;
|
|
3856
|
+
const payload = decodeJwtPayload(accessToken);
|
|
3857
|
+
if (payload && typeof payload["trn"] === "string" && payload["trn"].length > 0) {
|
|
3858
|
+
return payload["trn"];
|
|
3859
|
+
}
|
|
3860
|
+
const ctx = parseKSeFTokenContext(accessToken);
|
|
3861
|
+
const author = ctx?.authorSubjectIdentifier;
|
|
3862
|
+
if (!author?.type || !author.value) return void 0;
|
|
3863
|
+
if (!ctx?.contextIdentifierType || !ctx?.contextIdentifierValue) return void 0;
|
|
3864
|
+
const authorType = toTokenAuthorIdentifierType(author.type);
|
|
3865
|
+
if (!authorType) return void 0;
|
|
3866
|
+
let continuationToken;
|
|
3867
|
+
let match;
|
|
3868
|
+
do {
|
|
3869
|
+
const list = await this.queryTokens({
|
|
3870
|
+
status: ["Active"],
|
|
3871
|
+
authorIdentifier: author.value,
|
|
3872
|
+
authorIdentifierType: authorType,
|
|
3873
|
+
pageSize: 50,
|
|
3874
|
+
continuationToken
|
|
3875
|
+
});
|
|
3876
|
+
for (const t of list.tokens) {
|
|
3877
|
+
if (t.status === "Active" && t.contextIdentifier?.value === ctx.contextIdentifierValue && t.contextIdentifier?.type === ctx.contextIdentifierType) {
|
|
3878
|
+
if (match) return void 0;
|
|
3879
|
+
match = t.referenceNumber;
|
|
3880
|
+
}
|
|
3881
|
+
}
|
|
3882
|
+
continuationToken = list.continuationToken ?? void 0;
|
|
3883
|
+
} while (continuationToken);
|
|
3884
|
+
return match;
|
|
3885
|
+
}
|
|
3886
|
+
/**
|
|
3887
|
+
* Revokes the token currently used for authentication.
|
|
3888
|
+
* Treats 404/409/410 on DELETE as "already revoked" and returns successfully with
|
|
3889
|
+
* `alreadyRevoked: true` so callers can still clear local state.
|
|
3890
|
+
*/
|
|
3891
|
+
async revokeSelf(opts = {}) {
|
|
3892
|
+
let ref = opts.referenceNumber;
|
|
3893
|
+
if (!ref && opts.accessToken) {
|
|
3894
|
+
ref = await this.findSelfReferenceNumber(opts.accessToken);
|
|
3895
|
+
}
|
|
3896
|
+
if (!ref) {
|
|
3897
|
+
throw new KSeFError(
|
|
3898
|
+
"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."
|
|
3899
|
+
);
|
|
3900
|
+
}
|
|
3901
|
+
try {
|
|
3902
|
+
await this.revokeToken(ref);
|
|
3903
|
+
return { referenceNumber: ref, alreadyRevoked: false };
|
|
3904
|
+
} catch (err) {
|
|
3905
|
+
if (err instanceof KSeFApiError && (err.statusCode === 404 || err.statusCode === 409 || err.statusCode === 410)) {
|
|
3906
|
+
return { referenceNumber: ref, alreadyRevoked: true };
|
|
3907
|
+
}
|
|
3908
|
+
throw err;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3429
3911
|
};
|
|
3430
3912
|
}
|
|
3431
3913
|
});
|
|
@@ -4051,8 +4533,8 @@ function computeRootDigest(doc) {
|
|
|
4051
4533
|
return crypto3.createHash("sha256").update(canonical, "utf-8").digest("base64");
|
|
4052
4534
|
}
|
|
4053
4535
|
function computeSignedPropertiesDigest(qualifyingPropertiesXml) {
|
|
4054
|
-
const
|
|
4055
|
-
const qpDoc =
|
|
4536
|
+
const parser2 = new import_xmldom2.DOMParser();
|
|
4537
|
+
const qpDoc = parser2.parseFromString(qualifyingPropertiesXml, "text/xml");
|
|
4056
4538
|
const signedProps = findElementByLocalName(qpDoc.documentElement, "SignedProperties");
|
|
4057
4539
|
if (!signedProps) {
|
|
4058
4540
|
throw new Error("SignedProperties element not found in QualifyingProperties");
|
|
@@ -4207,8 +4689,8 @@ var init_signature_service = __esm({
|
|
|
4207
4689
|
const isEc = privateKey.asymmetricKeyType === "ec";
|
|
4208
4690
|
const signatureAlgorithm = isEc ? ECDSA_SHA256_SIGNATURE : RSA_SHA256_SIGNATURE;
|
|
4209
4691
|
const signingTime = new Date(Date.now() + CLOCK_SKEW_BUFFER_MS).toISOString();
|
|
4210
|
-
const
|
|
4211
|
-
const doc =
|
|
4692
|
+
const parser2 = new import_xmldom2.DOMParser();
|
|
4693
|
+
const doc = parser2.parseFromString(xml, "text/xml");
|
|
4212
4694
|
const root = doc.documentElement;
|
|
4213
4695
|
if (!root) {
|
|
4214
4696
|
throw new Error("XML document has no root element");
|
|
@@ -4228,7 +4710,7 @@ var init_signature_service = __esm({
|
|
|
4228
4710
|
rootDigest,
|
|
4229
4711
|
signedPropertiesDigest
|
|
4230
4712
|
);
|
|
4231
|
-
const signedInfoDoc =
|
|
4713
|
+
const signedInfoDoc = parser2.parseFromString(signedInfoXml, "text/xml");
|
|
4232
4714
|
const canonicalSignedInfo = canonicalize(signedInfoDoc.documentElement);
|
|
4233
4715
|
const signatureValue = computeSignatureValue(
|
|
4234
4716
|
canonicalSignedInfo,
|
|
@@ -4241,7 +4723,7 @@ var init_signature_service = __esm({
|
|
|
4241
4723
|
certBase64,
|
|
4242
4724
|
qualifyingPropertiesXml
|
|
4243
4725
|
);
|
|
4244
|
-
const signatureDoc =
|
|
4726
|
+
const signatureDoc = parser2.parseFromString(signatureXml, "text/xml");
|
|
4245
4727
|
const importedNode = doc.importNode(signatureDoc.documentElement, true);
|
|
4246
4728
|
root.appendChild(importedNode);
|
|
4247
4729
|
return new import_xmldom2.XMLSerializer().serializeToString(doc);
|
|
@@ -5080,6 +5562,7 @@ var init_client = __esm({
|
|
|
5080
5562
|
const tokens = await this.auth.getAccessToken(authToken);
|
|
5081
5563
|
this.authManager.setAccessToken(tokens.accessToken.token);
|
|
5082
5564
|
this.authManager.setRefreshToken(tokens.refreshToken.token);
|
|
5565
|
+
return { clientIp: challenge.clientIp };
|
|
5083
5566
|
}
|
|
5084
5567
|
async loginWithCertificate(certPem, keyPem, nip, keyPassword) {
|
|
5085
5568
|
const challenge = await this.auth.getChallenge();
|
|
@@ -5092,11 +5575,12 @@ var init_client = __esm({
|
|
|
5092
5575
|
const tokens = await this.auth.getAccessToken(authToken);
|
|
5093
5576
|
this.authManager.setAccessToken(tokens.accessToken.token);
|
|
5094
5577
|
this.authManager.setRefreshToken(tokens.refreshToken.token);
|
|
5578
|
+
return { clientIp: challenge.clientIp };
|
|
5095
5579
|
}
|
|
5096
5580
|
async loginWithPkcs12(p12, password, nip) {
|
|
5097
5581
|
const { Pkcs12Loader: Pkcs12Loader2 } = await Promise.resolve().then(() => (init_pkcs12_loader(), pkcs12_loader_exports));
|
|
5098
5582
|
const { certificatePem, privateKeyPem } = Pkcs12Loader2.load(p12, password);
|
|
5099
|
-
|
|
5583
|
+
return this.loginWithCertificate(certificatePem, privateKeyPem, nip);
|
|
5100
5584
|
}
|
|
5101
5585
|
async awaitAuthReady(referenceNumber, authToken) {
|
|
5102
5586
|
for (let i = 0; i < 30; i++) {
|
|
@@ -5139,10 +5623,13 @@ __export(index_exports, {
|
|
|
5139
5623
|
CertificateService: () => CertificateService,
|
|
5140
5624
|
CryptographyService: () => CryptographyService,
|
|
5141
5625
|
DEFAULT_FORM_CODE: () => DEFAULT_FORM_CODE,
|
|
5626
|
+
DISCOURAGED_UNICODE_RANGES: () => DISCOURAGED_UNICODE_RANGES,
|
|
5142
5627
|
DefaultAuthManager: () => DefaultAuthManager,
|
|
5143
5628
|
ENFORCE_XADES_COMPLIANCE: () => ENFORCE_XADES_COMPLIANCE,
|
|
5629
|
+
ETD_NAMESPACE: () => ETD_NAMESPACE,
|
|
5144
5630
|
EntityPermissionGrantBuilder: () => EntityPermissionGrantBuilder,
|
|
5145
5631
|
Environment: () => Environment,
|
|
5632
|
+
FAKTURA_NAMESPACE: () => FAKTURA_NAMESPACE,
|
|
5146
5633
|
FORM_CODES: () => FORM_CODES,
|
|
5147
5634
|
FORM_CODE_KEYS: () => FORM_CODE_KEYS,
|
|
5148
5635
|
FileHwmStore: () => FileHwmStore,
|
|
@@ -5159,9 +5646,13 @@ __export(index_exports, {
|
|
|
5159
5646
|
KSEF_FEATURE_HEADER: () => KSEF_FEATURE_HEADER,
|
|
5160
5647
|
KSeFApiError: () => KSeFApiError,
|
|
5161
5648
|
KSeFAuthStatusError: () => KSeFAuthStatusError,
|
|
5649
|
+
KSeFBadRequestError: () => KSeFBadRequestError,
|
|
5650
|
+
KSeFBatchTimeoutError: () => KSeFBatchTimeoutError,
|
|
5162
5651
|
KSeFClient: () => KSeFClient,
|
|
5163
5652
|
KSeFError: () => KSeFError,
|
|
5653
|
+
KSeFErrorCode: () => KSeFErrorCode,
|
|
5164
5654
|
KSeFForbiddenError: () => KSeFForbiddenError,
|
|
5655
|
+
KSeFGoneError: () => KSeFGoneError,
|
|
5165
5656
|
KSeFRateLimitError: () => KSeFRateLimitError,
|
|
5166
5657
|
KSeFSessionExpiredError: () => KSeFSessionExpiredError,
|
|
5167
5658
|
KSeFUnauthorizedError: () => KSeFUnauthorizedError,
|
|
@@ -5173,8 +5664,10 @@ __export(index_exports, {
|
|
|
5173
5664
|
LimitsService: () => LimitsService,
|
|
5174
5665
|
Nip: () => Nip,
|
|
5175
5666
|
NipVatUe: () => NipVatUe,
|
|
5667
|
+
ORDER_MAP: () => ORDER_MAP,
|
|
5176
5668
|
OfflineInvoiceWorkflow: () => OfflineInvoiceWorkflow,
|
|
5177
5669
|
OnlineSessionService: () => OnlineSessionService,
|
|
5670
|
+
PEF_NAMESPACE: () => PEF_NAMESPACE,
|
|
5178
5671
|
PERMISSION_DESCRIPTION_MAX_LENGTH: () => PERMISSION_DESCRIPTION_MAX_LENGTH,
|
|
5179
5672
|
PERMISSION_DESCRIPTION_MIN_LENGTH: () => PERMISSION_DESCRIPTION_MIN_LENGTH,
|
|
5180
5673
|
PeppolId: () => PeppolId,
|
|
@@ -5204,14 +5697,21 @@ __export(index_exports, {
|
|
|
5204
5697
|
VatUe: () => VatUe,
|
|
5205
5698
|
VerificationLinkService: () => VerificationLinkService,
|
|
5206
5699
|
addBusinessDays: () => addBusinessDays,
|
|
5700
|
+
assertNever: () => assertNever,
|
|
5207
5701
|
authenticateWithCertificate: () => authenticateWithCertificate,
|
|
5208
5702
|
authenticateWithExternalSignature: () => authenticateWithExternalSignature,
|
|
5209
5703
|
authenticateWithPkcs12: () => authenticateWithPkcs12,
|
|
5210
5704
|
authenticateWithToken: () => authenticateWithToken,
|
|
5211
5705
|
batchValidationDetails: () => batchValidationDetails,
|
|
5706
|
+
buildFakturaXml: () => buildFakturaXml,
|
|
5707
|
+
buildPefXml: () => buildPefXml,
|
|
5708
|
+
buildRawXmlString: () => buildRawXmlString,
|
|
5212
5709
|
buildUnsignedAuthTokenRequestXml: () => buildUnsignedAuthTokenRequestXml,
|
|
5710
|
+
buildXml: () => buildXml,
|
|
5711
|
+
buildXmlFromObject: () => buildXmlFromObject,
|
|
5213
5712
|
calculateBackoff: () => calculateBackoff,
|
|
5214
5713
|
calculateOfflineDeadline: () => calculateOfflineDeadline,
|
|
5714
|
+
comparePKey: () => comparePKey,
|
|
5215
5715
|
createZip: () => createZip,
|
|
5216
5716
|
decodeJwtPayload: () => decodeJwtPayload,
|
|
5217
5717
|
deduplicateByKsefNumber: () => deduplicateByKsefNumber,
|
|
@@ -5230,6 +5730,9 @@ __export(index_exports, {
|
|
|
5230
5730
|
getTimeUntilDeadline: () => getTimeUntilDeadline,
|
|
5231
5731
|
incrementalExportAndDownload: () => incrementalExportAndDownload,
|
|
5232
5732
|
isExpired: () => isExpired,
|
|
5733
|
+
isFakturaInput: () => isFakturaInput,
|
|
5734
|
+
isFormCodeShape: () => isFormCodeShape,
|
|
5735
|
+
isPefUblDocumentInput: () => isPefUblDocumentInput,
|
|
5233
5736
|
isPolishHoliday: () => isPolishHoliday,
|
|
5234
5737
|
isRetryableError: () => isRetryableError,
|
|
5235
5738
|
isRetryableStatus: () => isRetryableStatus,
|
|
@@ -5251,16 +5754,21 @@ __export(index_exports, {
|
|
|
5251
5754
|
nextBusinessDay: () => nextBusinessDay,
|
|
5252
5755
|
openOnlineSession: () => openOnlineSession,
|
|
5253
5756
|
openSendAndClose: () => openSendAndClose,
|
|
5757
|
+
orderXmlObject: () => orderXmlObject,
|
|
5254
5758
|
parseFormCode: () => parseFormCode,
|
|
5255
5759
|
parseKSeFTokenContext: () => parseKSeFTokenContext,
|
|
5256
5760
|
parseRetryAfter: () => parseRetryAfter,
|
|
5257
5761
|
parseUpoXml: () => parseUpoXml,
|
|
5762
|
+
parseXml: () => parseXml,
|
|
5258
5763
|
pollUntil: () => pollUntil,
|
|
5259
5764
|
resolveOptions: () => resolveOptions,
|
|
5260
5765
|
resumeOnlineSession: () => resumeOnlineSession,
|
|
5261
5766
|
runWithConcurrency: () => runWithConcurrency,
|
|
5767
|
+
serializeInvoiceXml: () => serializeInvoiceXml,
|
|
5262
5768
|
sha256Base64: () => sha256Base642,
|
|
5263
5769
|
sleep: () => sleep,
|
|
5770
|
+
stripBom: () => stripBom,
|
|
5771
|
+
toKodFormularza: () => toKodFormularza,
|
|
5264
5772
|
unzip: () => unzip,
|
|
5265
5773
|
updateContinuationPoint: () => updateContinuationPoint,
|
|
5266
5774
|
uploadBatch: () => uploadBatch,
|
|
@@ -5270,6 +5778,7 @@ __export(index_exports, {
|
|
|
5270
5778
|
validate: () => validate,
|
|
5271
5779
|
validateBatch: () => validateBatch,
|
|
5272
5780
|
validateBusinessRules: () => validateBusinessRules,
|
|
5781
|
+
validateCharValidity: () => validateCharValidity,
|
|
5273
5782
|
validateFormCodeForSession: () => validateFormCodeForSession,
|
|
5274
5783
|
validatePresignedUrl: () => validatePresignedUrl,
|
|
5275
5784
|
validateSchema: () => validateSchema,
|
|
@@ -5309,6 +5818,7 @@ var PERMISSION_DESCRIPTION_MAX_LENGTH = 256;
|
|
|
5309
5818
|
init_xml_to_object();
|
|
5310
5819
|
init_schema_registry();
|
|
5311
5820
|
init_invoice_validator();
|
|
5821
|
+
init_char_validity();
|
|
5312
5822
|
|
|
5313
5823
|
// src/models/index.ts
|
|
5314
5824
|
init_document_structures();
|
|
@@ -6000,51 +6510,7 @@ function escapeXml2(str) {
|
|
|
6000
6510
|
|
|
6001
6511
|
// src/utils/index.ts
|
|
6002
6512
|
init_zip();
|
|
6003
|
-
|
|
6004
|
-
// src/utils/jwt.ts
|
|
6005
|
-
function decodeJwtPayload(token) {
|
|
6006
|
-
const parts = token.split(".");
|
|
6007
|
-
if (parts.length !== 3) return null;
|
|
6008
|
-
try {
|
|
6009
|
-
const payload = parts[1];
|
|
6010
|
-
const json = Buffer.from(payload, "base64url").toString("utf-8");
|
|
6011
|
-
return JSON.parse(json);
|
|
6012
|
-
} catch {
|
|
6013
|
-
return null;
|
|
6014
|
-
}
|
|
6015
|
-
}
|
|
6016
|
-
function tryParseJson(value) {
|
|
6017
|
-
if (typeof value !== "string") return void 0;
|
|
6018
|
-
try {
|
|
6019
|
-
return JSON.parse(value);
|
|
6020
|
-
} catch {
|
|
6021
|
-
return void 0;
|
|
6022
|
-
}
|
|
6023
|
-
}
|
|
6024
|
-
function tryParseJsonArray(value) {
|
|
6025
|
-
if (typeof value !== "string") return void 0;
|
|
6026
|
-
try {
|
|
6027
|
-
const parsed = JSON.parse(value);
|
|
6028
|
-
return Array.isArray(parsed) && parsed.every((item) => typeof item === "string") ? parsed : void 0;
|
|
6029
|
-
} catch {
|
|
6030
|
-
return void 0;
|
|
6031
|
-
}
|
|
6032
|
-
}
|
|
6033
|
-
function parseKSeFTokenContext(token) {
|
|
6034
|
-
const raw = decodeJwtPayload(token);
|
|
6035
|
-
if (!raw) return null;
|
|
6036
|
-
return {
|
|
6037
|
-
type: typeof raw["typ"] === "string" ? raw["typ"] : void 0,
|
|
6038
|
-
contextIdentifierType: typeof raw["cit"] === "string" ? raw["cit"] : void 0,
|
|
6039
|
-
contextIdentifierValue: typeof raw["civ"] === "string" ? raw["civ"] : void 0,
|
|
6040
|
-
authMethod: typeof raw["aum"] === "string" ? raw["aum"] : void 0,
|
|
6041
|
-
permissions: tryParseJsonArray(raw["per"]),
|
|
6042
|
-
subjectDetails: tryParseJson(raw["sud"]),
|
|
6043
|
-
authorSubjectIdentifier: tryParseJson(raw["asi"]),
|
|
6044
|
-
issuedAt: typeof raw["iat"] === "number" ? raw["iat"] : void 0,
|
|
6045
|
-
expiresAt: typeof raw["exp"] === "number" ? raw["exp"] : void 0
|
|
6046
|
-
};
|
|
6047
|
-
}
|
|
6513
|
+
init_jwt();
|
|
6048
6514
|
|
|
6049
6515
|
// src/utils/hash.ts
|
|
6050
6516
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
@@ -6240,6 +6706,524 @@ function nonEmptyString(value) {
|
|
|
6240
6706
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
6241
6707
|
}
|
|
6242
6708
|
|
|
6709
|
+
// src/xml/xml-engine.ts
|
|
6710
|
+
var import_fast_xml_parser3 = require("fast-xml-parser");
|
|
6711
|
+
var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>\n';
|
|
6712
|
+
var parser = new import_fast_xml_parser3.XMLParser({
|
|
6713
|
+
ignoreAttributes: false,
|
|
6714
|
+
preserveOrder: true,
|
|
6715
|
+
attributeNamePrefix: "@_",
|
|
6716
|
+
textNodeName: "#text",
|
|
6717
|
+
allowBooleanAttributes: true,
|
|
6718
|
+
// Preserve leading zeros and keep everything as strings — KSeF fields like
|
|
6719
|
+
// KRS (`\d{10}`) and NIP (`\d{10}`) would otherwise be lossy through parse.
|
|
6720
|
+
parseTagValue: false,
|
|
6721
|
+
parseAttributeValue: false,
|
|
6722
|
+
trimValues: false
|
|
6723
|
+
});
|
|
6724
|
+
var builder = new import_fast_xml_parser3.XMLBuilder({
|
|
6725
|
+
ignoreAttributes: false,
|
|
6726
|
+
preserveOrder: true,
|
|
6727
|
+
attributeNamePrefix: "@_",
|
|
6728
|
+
textNodeName: "#text",
|
|
6729
|
+
format: false,
|
|
6730
|
+
suppressBooleanAttributes: false,
|
|
6731
|
+
suppressEmptyNode: false,
|
|
6732
|
+
processEntities: true
|
|
6733
|
+
});
|
|
6734
|
+
function createObjectBuilder(pretty = false) {
|
|
6735
|
+
return new import_fast_xml_parser3.XMLBuilder({
|
|
6736
|
+
ignoreAttributes: false,
|
|
6737
|
+
preserveOrder: false,
|
|
6738
|
+
attributeNamePrefix: "@_",
|
|
6739
|
+
textNodeName: "#text",
|
|
6740
|
+
format: pretty,
|
|
6741
|
+
suppressBooleanAttributes: false,
|
|
6742
|
+
suppressEmptyNode: false,
|
|
6743
|
+
processEntities: true
|
|
6744
|
+
});
|
|
6745
|
+
}
|
|
6746
|
+
function prependDeclaration(xml) {
|
|
6747
|
+
return xml.startsWith("<?xml") ? xml : `${XML_DECLARATION}${xml}`;
|
|
6748
|
+
}
|
|
6749
|
+
function parseXml(xml) {
|
|
6750
|
+
return parser.parse(xml);
|
|
6751
|
+
}
|
|
6752
|
+
function buildXml(document) {
|
|
6753
|
+
return prependDeclaration(builder.build(document));
|
|
6754
|
+
}
|
|
6755
|
+
function buildXmlFromObject(document, options) {
|
|
6756
|
+
return prependDeclaration(createObjectBuilder(options?.pretty).build(document));
|
|
6757
|
+
}
|
|
6758
|
+
function stripBom(input) {
|
|
6759
|
+
return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
|
|
6760
|
+
}
|
|
6761
|
+
|
|
6762
|
+
// src/xml/order-map.ts
|
|
6763
|
+
var ORDER_MAP = {
|
|
6764
|
+
Faktura: ["Naglowek", "Podmiot1", "Podmiot2", "Podmiot3", "Fa", "Stopka"],
|
|
6765
|
+
Naglowek: ["KodFormularza", "WariantFormularza", "DataWytworzeniaFa", "SystemInfo"],
|
|
6766
|
+
Podmiot1: [
|
|
6767
|
+
"PrefiksPodatnika",
|
|
6768
|
+
"NrEORI",
|
|
6769
|
+
"DaneIdentyfikacyjne",
|
|
6770
|
+
"Adres",
|
|
6771
|
+
"AdresKoresp",
|
|
6772
|
+
"DaneKontaktowe",
|
|
6773
|
+
"StatusInfoPodatnika"
|
|
6774
|
+
],
|
|
6775
|
+
Podmiot2: [
|
|
6776
|
+
"NrEORI",
|
|
6777
|
+
"DaneIdentyfikacyjne",
|
|
6778
|
+
"Adres",
|
|
6779
|
+
"AdresKoresp",
|
|
6780
|
+
"DaneKontaktowe",
|
|
6781
|
+
"NrKlienta",
|
|
6782
|
+
"IDNabywcy",
|
|
6783
|
+
"JST",
|
|
6784
|
+
"GV"
|
|
6785
|
+
],
|
|
6786
|
+
Podmiot3: [
|
|
6787
|
+
"IDNabywcy",
|
|
6788
|
+
"NrEORI",
|
|
6789
|
+
"DaneIdentyfikacyjne",
|
|
6790
|
+
"Adres",
|
|
6791
|
+
"AdresKoresp",
|
|
6792
|
+
"DaneKontaktowe",
|
|
6793
|
+
"Rola",
|
|
6794
|
+
"Udzial"
|
|
6795
|
+
],
|
|
6796
|
+
DaneIdentyfikacyjne: [
|
|
6797
|
+
"NIP",
|
|
6798
|
+
"IDWew",
|
|
6799
|
+
"KodUE",
|
|
6800
|
+
"NrVatUE",
|
|
6801
|
+
"KodKraju",
|
|
6802
|
+
"NrID",
|
|
6803
|
+
"BrakID",
|
|
6804
|
+
"Nazwa",
|
|
6805
|
+
"Identyfikator",
|
|
6806
|
+
"KRS"
|
|
6807
|
+
],
|
|
6808
|
+
Adres: ["KodKraju", "AdresL1", "AdresL2", "AdresL3"],
|
|
6809
|
+
DaneKontaktowe: ["Email", "Telefon"],
|
|
6810
|
+
Fa: [
|
|
6811
|
+
"KodWaluty",
|
|
6812
|
+
"P_1",
|
|
6813
|
+
"P_1M",
|
|
6814
|
+
"P_2",
|
|
6815
|
+
"WZ",
|
|
6816
|
+
"P_6",
|
|
6817
|
+
"OkresFa",
|
|
6818
|
+
// Multi-rate interleave per VAT group — DO NOT flatten into P_13_* block then P_14_* block.
|
|
6819
|
+
// See smekcio TS d1ec8fe and the "multi-rate interleave" regression test.
|
|
6820
|
+
"P_13_1",
|
|
6821
|
+
"P_14_1",
|
|
6822
|
+
"P_14_1W",
|
|
6823
|
+
"P_13_2",
|
|
6824
|
+
"P_14_2",
|
|
6825
|
+
"P_14_2W",
|
|
6826
|
+
"P_13_3",
|
|
6827
|
+
"P_14_3",
|
|
6828
|
+
"P_14_3W",
|
|
6829
|
+
"P_13_4",
|
|
6830
|
+
"P_14_4",
|
|
6831
|
+
"P_14_4W",
|
|
6832
|
+
"P_13_5",
|
|
6833
|
+
"P_14_5",
|
|
6834
|
+
"P_13_6_1",
|
|
6835
|
+
"P_13_6_2",
|
|
6836
|
+
"P_13_6_3",
|
|
6837
|
+
"P_13_7",
|
|
6838
|
+
"P_13_8",
|
|
6839
|
+
"P_13_9",
|
|
6840
|
+
"P_13_10",
|
|
6841
|
+
"P_13_11",
|
|
6842
|
+
"P_15",
|
|
6843
|
+
"KursWalutyZ",
|
|
6844
|
+
"Adnotacje",
|
|
6845
|
+
"RodzajFaktury",
|
|
6846
|
+
"PrzyczynaKorekty",
|
|
6847
|
+
"TypKorekty",
|
|
6848
|
+
"DaneFaKorygowanej",
|
|
6849
|
+
"OkresFaKorygowanej",
|
|
6850
|
+
"NrFaKorygowany",
|
|
6851
|
+
"Podmiot1K",
|
|
6852
|
+
"Podmiot2K",
|
|
6853
|
+
"Podmiot3K",
|
|
6854
|
+
"ZaliczkaCzesciowa",
|
|
6855
|
+
"FP",
|
|
6856
|
+
"TP",
|
|
6857
|
+
"DodatkowyOpis",
|
|
6858
|
+
"FakturaZaliczkowa",
|
|
6859
|
+
"ZwrotAkcyzy",
|
|
6860
|
+
"FaWiersz",
|
|
6861
|
+
"FaWiersze",
|
|
6862
|
+
"Rozliczenie",
|
|
6863
|
+
"Platnosc"
|
|
6864
|
+
],
|
|
6865
|
+
Adnotacje: ["P_16", "P_17", "P_18", "P_18A", "Zwolnienie", "NoweSrodkiTransportu", "P_23", "PMarzy"],
|
|
6866
|
+
OkresFa: ["P_6_Od", "P_6_Do"],
|
|
6867
|
+
FaWiersz: [
|
|
6868
|
+
"NrWierszaFa",
|
|
6869
|
+
"UU_ID",
|
|
6870
|
+
"P_6A",
|
|
6871
|
+
"P_7",
|
|
6872
|
+
"Indeks",
|
|
6873
|
+
"GTIN",
|
|
6874
|
+
"PKWiU",
|
|
6875
|
+
"CN",
|
|
6876
|
+
"PKOB",
|
|
6877
|
+
"P_8A",
|
|
6878
|
+
"P_8B",
|
|
6879
|
+
"P_9A",
|
|
6880
|
+
"P_9B",
|
|
6881
|
+
"P_10",
|
|
6882
|
+
"P_11",
|
|
6883
|
+
"P_11A",
|
|
6884
|
+
"P_11Vat",
|
|
6885
|
+
"P_12",
|
|
6886
|
+
"P_12_XII",
|
|
6887
|
+
"P_12_Zal_15",
|
|
6888
|
+
"KwotaAkcyzy",
|
|
6889
|
+
"GTU",
|
|
6890
|
+
"Procedura",
|
|
6891
|
+
"KursWaluty",
|
|
6892
|
+
"StanPrzed"
|
|
6893
|
+
]
|
|
6894
|
+
};
|
|
6895
|
+
function comparePKey(a, b) {
|
|
6896
|
+
const normalize = (value) => value.replace(/^P_/, "").split("_").map((part) => Number.isNaN(Number(part)) ? part : Number(part));
|
|
6897
|
+
const aParts = normalize(a);
|
|
6898
|
+
const bParts = normalize(b);
|
|
6899
|
+
const max = Math.max(aParts.length, bParts.length);
|
|
6900
|
+
for (let i = 0; i < max; i += 1) {
|
|
6901
|
+
const left = aParts[i];
|
|
6902
|
+
const right = bParts[i];
|
|
6903
|
+
if (left === void 0) return -1;
|
|
6904
|
+
if (right === void 0) return 1;
|
|
6905
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
6906
|
+
if (left !== right) return left - right;
|
|
6907
|
+
continue;
|
|
6908
|
+
}
|
|
6909
|
+
const leftStr = String(left);
|
|
6910
|
+
const rightStr = String(right);
|
|
6911
|
+
if (leftStr !== rightStr) return leftStr < rightStr ? -1 : 1;
|
|
6912
|
+
}
|
|
6913
|
+
return 0;
|
|
6914
|
+
}
|
|
6915
|
+
function isObject(value) {
|
|
6916
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6917
|
+
}
|
|
6918
|
+
function normalizeValueForKey(key, value) {
|
|
6919
|
+
if (Array.isArray(value)) {
|
|
6920
|
+
return value.map(
|
|
6921
|
+
(item) => isObject(item) ? orderXmlObject(item, key) : normalizeValue(item)
|
|
6922
|
+
);
|
|
6923
|
+
}
|
|
6924
|
+
if (isObject(value)) return orderXmlObject(value, key);
|
|
6925
|
+
return value;
|
|
6926
|
+
}
|
|
6927
|
+
function normalizeValue(value) {
|
|
6928
|
+
if (Array.isArray(value)) return value.map((item) => normalizeValue(item));
|
|
6929
|
+
if (isObject(value)) return orderXmlObject(value);
|
|
6930
|
+
return value;
|
|
6931
|
+
}
|
|
6932
|
+
function orderXmlObject(value, contextKey) {
|
|
6933
|
+
const order = contextKey ? ORDER_MAP[contextKey] : void 0;
|
|
6934
|
+
const keys = Object.keys(value);
|
|
6935
|
+
const used = /* @__PURE__ */ new Set();
|
|
6936
|
+
const ordered = {};
|
|
6937
|
+
if (order) {
|
|
6938
|
+
for (const key of order) {
|
|
6939
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
6940
|
+
const item = value[key];
|
|
6941
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
6942
|
+
used.add(key);
|
|
6943
|
+
}
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
const pKeys = keys.filter((key) => !used.has(key) && key.startsWith("P_")).sort(comparePKey);
|
|
6947
|
+
for (const key of pKeys) {
|
|
6948
|
+
const item = value[key];
|
|
6949
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
6950
|
+
used.add(key);
|
|
6951
|
+
}
|
|
6952
|
+
for (const key of keys) {
|
|
6953
|
+
if (used.has(key)) continue;
|
|
6954
|
+
const item = value[key];
|
|
6955
|
+
if (item !== void 0) ordered[key] = normalizeValueForKey(key, item);
|
|
6956
|
+
}
|
|
6957
|
+
return ordered;
|
|
6958
|
+
}
|
|
6959
|
+
|
|
6960
|
+
// src/xml/faktura-builder.ts
|
|
6961
|
+
var FAKTURA_NAMESPACE = {
|
|
6962
|
+
FA2: "http://crd.gov.pl/wzor/2023/06/29/12648/",
|
|
6963
|
+
FA3: "http://crd.gov.pl/wzor/2025/06/25/13775/"
|
|
6964
|
+
};
|
|
6965
|
+
var ETD_NAMESPACE = {
|
|
6966
|
+
FA2: "http://crd.gov.pl/xml/schematy/2020/10/08/eDokumenty",
|
|
6967
|
+
FA3: "http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/"
|
|
6968
|
+
};
|
|
6969
|
+
function toKodFormularza(formCode) {
|
|
6970
|
+
return {
|
|
6971
|
+
"@_kodSystemowy": formCode.systemCode,
|
|
6972
|
+
"@_wersjaSchemy": formCode.schemaVersion,
|
|
6973
|
+
"#text": formCode.value
|
|
6974
|
+
};
|
|
6975
|
+
}
|
|
6976
|
+
function isFormCodeShape(value) {
|
|
6977
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
6978
|
+
const candidate = value;
|
|
6979
|
+
return typeof candidate.systemCode === "string" && typeof candidate.schemaVersion === "string" && typeof candidate.value === "string";
|
|
6980
|
+
}
|
|
6981
|
+
function isObject2(value) {
|
|
6982
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6983
|
+
}
|
|
6984
|
+
function normalizeTopLevelChild(key, value) {
|
|
6985
|
+
if (key === "Naglowek" && isObject2(value)) {
|
|
6986
|
+
return normalizeNaglowek(value);
|
|
6987
|
+
}
|
|
6988
|
+
if (Array.isArray(value)) {
|
|
6989
|
+
return value.map((item) => isObject2(item) ? orderXmlObject(item, key) : item);
|
|
6990
|
+
}
|
|
6991
|
+
if (isObject2(value)) return orderXmlObject(value, key);
|
|
6992
|
+
return value;
|
|
6993
|
+
}
|
|
6994
|
+
function normalizeNaglowek(value) {
|
|
6995
|
+
const result = {};
|
|
6996
|
+
for (const [key, item] of Object.entries(value)) {
|
|
6997
|
+
if (item === void 0) continue;
|
|
6998
|
+
if (key === "KodFormularza" && isFormCodeShape(item)) {
|
|
6999
|
+
result[key] = toKodFormularza(item);
|
|
7000
|
+
continue;
|
|
7001
|
+
}
|
|
7002
|
+
if (Array.isArray(item)) {
|
|
7003
|
+
result[key] = item.map(
|
|
7004
|
+
(entry) => isObject2(entry) ? orderXmlObject(entry, key) : entry
|
|
7005
|
+
);
|
|
7006
|
+
continue;
|
|
7007
|
+
}
|
|
7008
|
+
if (isObject2(item)) {
|
|
7009
|
+
result[key] = orderXmlObject(item, key);
|
|
7010
|
+
continue;
|
|
7011
|
+
}
|
|
7012
|
+
result[key] = item;
|
|
7013
|
+
}
|
|
7014
|
+
return result;
|
|
7015
|
+
}
|
|
7016
|
+
function normalizeTopLevel(input) {
|
|
7017
|
+
const result = {};
|
|
7018
|
+
for (const [key, value] of Object.entries(input)) {
|
|
7019
|
+
if (value === void 0) continue;
|
|
7020
|
+
result[key] = normalizeTopLevelChild(key, value);
|
|
7021
|
+
}
|
|
7022
|
+
return result;
|
|
7023
|
+
}
|
|
7024
|
+
function buildFakturaXml(faktura, options = {}) {
|
|
7025
|
+
const schema = options.schema ?? "FA3";
|
|
7026
|
+
const fakturaNamespace = options.fakturaNamespace ?? FAKTURA_NAMESPACE[schema];
|
|
7027
|
+
const etdNamespace = options.etdNamespace ?? ETD_NAMESPACE[schema];
|
|
7028
|
+
const normalized = normalizeTopLevel(faktura);
|
|
7029
|
+
const ordered = orderXmlObject(normalized, "Faktura");
|
|
7030
|
+
const document = {
|
|
7031
|
+
Faktura: {
|
|
7032
|
+
...ordered,
|
|
7033
|
+
"@_xmlns": fakturaNamespace,
|
|
7034
|
+
"@_xmlns:etd": etdNamespace
|
|
7035
|
+
}
|
|
7036
|
+
};
|
|
7037
|
+
return buildXmlFromObject(document, { pretty: options.pretty });
|
|
7038
|
+
}
|
|
7039
|
+
function isFakturaInput(input) {
|
|
7040
|
+
if (!isObject2(input)) return false;
|
|
7041
|
+
const candidate = input;
|
|
7042
|
+
if (!Object.prototype.hasOwnProperty.call(candidate, "Naglowek")) return false;
|
|
7043
|
+
if (!Object.prototype.hasOwnProperty.call(candidate, "Fa")) return false;
|
|
7044
|
+
return isObject2(candidate.Naglowek) && isObject2(candidate.Fa);
|
|
7045
|
+
}
|
|
7046
|
+
|
|
7047
|
+
// src/xml/pef-builder.ts
|
|
7048
|
+
init_ksef_validation_error();
|
|
7049
|
+
var PEF_NAMESPACE = {
|
|
7050
|
+
PEF: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
|
|
7051
|
+
PEF_KOR: "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
|
|
7052
|
+
};
|
|
7053
|
+
var UBL_EXT_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2";
|
|
7054
|
+
var UBL_CBC_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";
|
|
7055
|
+
var UBL_CAC_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2";
|
|
7056
|
+
var UBL_CBC_PL_NS = "urn:pl:extended:CommonBasicComponents-2";
|
|
7057
|
+
var UBL_CAC_PL_NS = "urn:pl:extended:CommonAggregateComponents-2";
|
|
7058
|
+
function isPefUblDocumentInput(input) {
|
|
7059
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) return false;
|
|
7060
|
+
const obj = input;
|
|
7061
|
+
const invoice = obj.Invoice;
|
|
7062
|
+
const creditNote = obj.CreditNote;
|
|
7063
|
+
const hasInvoice = typeof invoice === "object" && invoice !== null && !Array.isArray(invoice);
|
|
7064
|
+
const hasCreditNote = typeof creditNote === "object" && creditNote !== null && !Array.isArray(creditNote);
|
|
7065
|
+
return hasInvoice !== hasCreditNote;
|
|
7066
|
+
}
|
|
7067
|
+
function inferSchema(input) {
|
|
7068
|
+
return "Invoice" in input ? "PEF" : "PEF_KOR";
|
|
7069
|
+
}
|
|
7070
|
+
function isNonArrayObject(value) {
|
|
7071
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7072
|
+
}
|
|
7073
|
+
function assertPefShape(input) {
|
|
7074
|
+
if (!isNonArrayObject(input)) {
|
|
7075
|
+
throw new KSeFValidationError("PEF input must be a non-array object.");
|
|
7076
|
+
}
|
|
7077
|
+
const hasInvoiceKey = "Invoice" in input;
|
|
7078
|
+
const hasCreditNoteKey = "CreditNote" in input;
|
|
7079
|
+
if (hasInvoiceKey && hasCreditNoteKey) {
|
|
7080
|
+
throw new KSeFValidationError(
|
|
7081
|
+
"PEF input must contain exactly one of `Invoice` or `CreditNote`, not both."
|
|
7082
|
+
);
|
|
7083
|
+
}
|
|
7084
|
+
if (!hasInvoiceKey && !hasCreditNoteKey) {
|
|
7085
|
+
throw new KSeFValidationError(
|
|
7086
|
+
"PEF input must contain either an `Invoice` or a `CreditNote` root element."
|
|
7087
|
+
);
|
|
7088
|
+
}
|
|
7089
|
+
const rootKey = hasInvoiceKey ? "Invoice" : "CreditNote";
|
|
7090
|
+
if (!isNonArrayObject(input[rootKey])) {
|
|
7091
|
+
throw new KSeFValidationError(
|
|
7092
|
+
`PEF \`${rootKey}\` value must be a non-array object.`
|
|
7093
|
+
);
|
|
7094
|
+
}
|
|
7095
|
+
}
|
|
7096
|
+
function buildPefXml(input, options = {}) {
|
|
7097
|
+
assertPefShape(input);
|
|
7098
|
+
const inferred = inferSchema(input);
|
|
7099
|
+
const schema = options.schema ?? input.schema ?? inferred;
|
|
7100
|
+
if (schema !== inferred) {
|
|
7101
|
+
throw new KSeFValidationError(
|
|
7102
|
+
`PEF schema mismatch: expected ${inferred} based on root element, got ${schema}.`
|
|
7103
|
+
);
|
|
7104
|
+
}
|
|
7105
|
+
const commonNamespaces = {
|
|
7106
|
+
"@_xmlns:ext": UBL_EXT_NS,
|
|
7107
|
+
"@_xmlns:cbc": UBL_CBC_NS,
|
|
7108
|
+
"@_xmlns:cac": UBL_CAC_NS,
|
|
7109
|
+
"@_xmlns:cbc-pl": UBL_CBC_PL_NS,
|
|
7110
|
+
"@_xmlns:cac-pl": UBL_CAC_PL_NS
|
|
7111
|
+
};
|
|
7112
|
+
const document = "Invoice" in input ? {
|
|
7113
|
+
Invoice: {
|
|
7114
|
+
...input.Invoice,
|
|
7115
|
+
"@_xmlns": PEF_NAMESPACE.PEF,
|
|
7116
|
+
...commonNamespaces
|
|
7117
|
+
}
|
|
7118
|
+
} : {
|
|
7119
|
+
CreditNote: {
|
|
7120
|
+
...input.CreditNote,
|
|
7121
|
+
"@_xmlns": PEF_NAMESPACE.PEF_KOR,
|
|
7122
|
+
...commonNamespaces
|
|
7123
|
+
}
|
|
7124
|
+
};
|
|
7125
|
+
return buildXmlFromObject(document, { pretty: options.pretty });
|
|
7126
|
+
}
|
|
7127
|
+
|
|
7128
|
+
// src/xml/invoice-serializer.ts
|
|
7129
|
+
init_ksef_validation_error();
|
|
7130
|
+
var FAKTURA_SCHEMAS = /* @__PURE__ */ new Set(["FA2", "FA3"]);
|
|
7131
|
+
var PEF_SCHEMAS = /* @__PURE__ */ new Set(["PEF", "PEF_KOR"]);
|
|
7132
|
+
function isNonArrayObject2(value) {
|
|
7133
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7134
|
+
}
|
|
7135
|
+
function classifyUnknownObject(input) {
|
|
7136
|
+
const looksLikeFaktura = "Naglowek" in input || "Fa" in input || "Podmiot1" in input || "Podmiot2" in input;
|
|
7137
|
+
const hasInvoice = "Invoice" in input;
|
|
7138
|
+
const hasCreditNote = "CreditNote" in input;
|
|
7139
|
+
if (hasInvoice && hasCreditNote) {
|
|
7140
|
+
return new KSeFValidationError(
|
|
7141
|
+
"Input must contain exactly one of `Invoice` or `CreditNote`, not both."
|
|
7142
|
+
);
|
|
7143
|
+
}
|
|
7144
|
+
if (hasInvoice !== hasCreditNote) {
|
|
7145
|
+
const rootKey = hasInvoice ? "Invoice" : "CreditNote";
|
|
7146
|
+
if (!isNonArrayObject2(input[rootKey])) {
|
|
7147
|
+
return KSeFValidationError.fromField(
|
|
7148
|
+
rootKey,
|
|
7149
|
+
`PEF \`${rootKey}\` value must be a non-array object.`
|
|
7150
|
+
);
|
|
7151
|
+
}
|
|
7152
|
+
}
|
|
7153
|
+
if (looksLikeFaktura) {
|
|
7154
|
+
const missing = [];
|
|
7155
|
+
if (!("Naglowek" in input)) missing.push("Naglowek");
|
|
7156
|
+
if (!("Fa" in input)) missing.push("Fa");
|
|
7157
|
+
if (missing.length > 0) {
|
|
7158
|
+
return KSeFValidationError.fromField(
|
|
7159
|
+
missing[0],
|
|
7160
|
+
`Faktura input is missing required top-level key(s): ${missing.join(", ")}.`
|
|
7161
|
+
);
|
|
7162
|
+
}
|
|
7163
|
+
for (const key of ["Naglowek", "Fa"]) {
|
|
7164
|
+
if (!isNonArrayObject2(input[key])) {
|
|
7165
|
+
return KSeFValidationError.fromField(
|
|
7166
|
+
key,
|
|
7167
|
+
`Faktura \`${key}\` value must be a non-null, non-array object.`
|
|
7168
|
+
);
|
|
7169
|
+
}
|
|
7170
|
+
}
|
|
7171
|
+
return new KSeFValidationError(
|
|
7172
|
+
"Faktura-like input failed shape validation: `Naglowek` and `Fa` must be own enumerable properties on the input object."
|
|
7173
|
+
);
|
|
7174
|
+
}
|
|
7175
|
+
return new KSeFValidationError(
|
|
7176
|
+
"Unsupported invoice input shape: expected `FakturaInput` (with `Naglowek` + `Fa`) or `PefUblDocumentInput` (with `Invoice` or `CreditNote`)."
|
|
7177
|
+
);
|
|
7178
|
+
}
|
|
7179
|
+
function serializeInvoiceXml(input, options) {
|
|
7180
|
+
if (Buffer.isBuffer(input)) return input;
|
|
7181
|
+
if (typeof input === "string") {
|
|
7182
|
+
return Buffer.from(stripBom(input), "utf8");
|
|
7183
|
+
}
|
|
7184
|
+
if (Array.isArray(input)) {
|
|
7185
|
+
return Buffer.from(stripBom(buildXml(input)), "utf8");
|
|
7186
|
+
}
|
|
7187
|
+
if (input && typeof input === "object") {
|
|
7188
|
+
const schema = options?.schema;
|
|
7189
|
+
if (isPefUblDocumentInput(input)) {
|
|
7190
|
+
if (schema && !PEF_SCHEMAS.has(schema)) {
|
|
7191
|
+
throw new KSeFValidationError(
|
|
7192
|
+
`schema option ${schema} is not compatible with a PEF / PEF_KOR input.`
|
|
7193
|
+
);
|
|
7194
|
+
}
|
|
7195
|
+
const pefSchema = schema === "PEF" || schema === "PEF_KOR" ? schema : void 0;
|
|
7196
|
+
const xml = buildPefXml(input, {
|
|
7197
|
+
schema: pefSchema,
|
|
7198
|
+
pretty: options?.pretty
|
|
7199
|
+
});
|
|
7200
|
+
return Buffer.from(stripBom(xml), "utf8");
|
|
7201
|
+
}
|
|
7202
|
+
if (isFakturaInput(input)) {
|
|
7203
|
+
if (schema && !FAKTURA_SCHEMAS.has(schema)) {
|
|
7204
|
+
throw new KSeFValidationError(
|
|
7205
|
+
`schema option ${schema} is not compatible with a Faktura input.`
|
|
7206
|
+
);
|
|
7207
|
+
}
|
|
7208
|
+
const fakturaSchema = schema === "FA2" || schema === "FA3" ? schema : void 0;
|
|
7209
|
+
const xml = buildFakturaXml(input, {
|
|
7210
|
+
schema: fakturaSchema,
|
|
7211
|
+
fakturaNamespace: options?.fakturaNamespace,
|
|
7212
|
+
etdNamespace: options?.etdNamespace,
|
|
7213
|
+
pretty: options?.pretty
|
|
7214
|
+
});
|
|
7215
|
+
return Buffer.from(stripBom(xml), "utf8");
|
|
7216
|
+
}
|
|
7217
|
+
throw classifyUnknownObject(input);
|
|
7218
|
+
}
|
|
7219
|
+
throw new KSeFValidationError(
|
|
7220
|
+
"Unsupported invoice input type: expected Buffer, string, XmlDocument, FakturaInput, or PefUblDocumentInput."
|
|
7221
|
+
);
|
|
7222
|
+
}
|
|
7223
|
+
function buildRawXmlString(document, options) {
|
|
7224
|
+
return buildXmlFromObject(document, options);
|
|
7225
|
+
}
|
|
7226
|
+
|
|
6243
7227
|
// src/workflows/online-session-workflow.ts
|
|
6244
7228
|
init_invoice_validator();
|
|
6245
7229
|
init_ksef_validation_error();
|
|
@@ -6969,10 +7953,13 @@ init_client();
|
|
|
6969
7953
|
CertificateService,
|
|
6970
7954
|
CryptographyService,
|
|
6971
7955
|
DEFAULT_FORM_CODE,
|
|
7956
|
+
DISCOURAGED_UNICODE_RANGES,
|
|
6972
7957
|
DefaultAuthManager,
|
|
6973
7958
|
ENFORCE_XADES_COMPLIANCE,
|
|
7959
|
+
ETD_NAMESPACE,
|
|
6974
7960
|
EntityPermissionGrantBuilder,
|
|
6975
7961
|
Environment,
|
|
7962
|
+
FAKTURA_NAMESPACE,
|
|
6976
7963
|
FORM_CODES,
|
|
6977
7964
|
FORM_CODE_KEYS,
|
|
6978
7965
|
FileHwmStore,
|
|
@@ -6989,9 +7976,13 @@ init_client();
|
|
|
6989
7976
|
KSEF_FEATURE_HEADER,
|
|
6990
7977
|
KSeFApiError,
|
|
6991
7978
|
KSeFAuthStatusError,
|
|
7979
|
+
KSeFBadRequestError,
|
|
7980
|
+
KSeFBatchTimeoutError,
|
|
6992
7981
|
KSeFClient,
|
|
6993
7982
|
KSeFError,
|
|
7983
|
+
KSeFErrorCode,
|
|
6994
7984
|
KSeFForbiddenError,
|
|
7985
|
+
KSeFGoneError,
|
|
6995
7986
|
KSeFRateLimitError,
|
|
6996
7987
|
KSeFSessionExpiredError,
|
|
6997
7988
|
KSeFUnauthorizedError,
|
|
@@ -7003,8 +7994,10 @@ init_client();
|
|
|
7003
7994
|
LimitsService,
|
|
7004
7995
|
Nip,
|
|
7005
7996
|
NipVatUe,
|
|
7997
|
+
ORDER_MAP,
|
|
7006
7998
|
OfflineInvoiceWorkflow,
|
|
7007
7999
|
OnlineSessionService,
|
|
8000
|
+
PEF_NAMESPACE,
|
|
7008
8001
|
PERMISSION_DESCRIPTION_MAX_LENGTH,
|
|
7009
8002
|
PERMISSION_DESCRIPTION_MIN_LENGTH,
|
|
7010
8003
|
PeppolId,
|
|
@@ -7034,14 +8027,21 @@ init_client();
|
|
|
7034
8027
|
VatUe,
|
|
7035
8028
|
VerificationLinkService,
|
|
7036
8029
|
addBusinessDays,
|
|
8030
|
+
assertNever,
|
|
7037
8031
|
authenticateWithCertificate,
|
|
7038
8032
|
authenticateWithExternalSignature,
|
|
7039
8033
|
authenticateWithPkcs12,
|
|
7040
8034
|
authenticateWithToken,
|
|
7041
8035
|
batchValidationDetails,
|
|
8036
|
+
buildFakturaXml,
|
|
8037
|
+
buildPefXml,
|
|
8038
|
+
buildRawXmlString,
|
|
7042
8039
|
buildUnsignedAuthTokenRequestXml,
|
|
8040
|
+
buildXml,
|
|
8041
|
+
buildXmlFromObject,
|
|
7043
8042
|
calculateBackoff,
|
|
7044
8043
|
calculateOfflineDeadline,
|
|
8044
|
+
comparePKey,
|
|
7045
8045
|
createZip,
|
|
7046
8046
|
decodeJwtPayload,
|
|
7047
8047
|
deduplicateByKsefNumber,
|
|
@@ -7060,6 +8060,9 @@ init_client();
|
|
|
7060
8060
|
getTimeUntilDeadline,
|
|
7061
8061
|
incrementalExportAndDownload,
|
|
7062
8062
|
isExpired,
|
|
8063
|
+
isFakturaInput,
|
|
8064
|
+
isFormCodeShape,
|
|
8065
|
+
isPefUblDocumentInput,
|
|
7063
8066
|
isPolishHoliday,
|
|
7064
8067
|
isRetryableError,
|
|
7065
8068
|
isRetryableStatus,
|
|
@@ -7081,16 +8084,21 @@ init_client();
|
|
|
7081
8084
|
nextBusinessDay,
|
|
7082
8085
|
openOnlineSession,
|
|
7083
8086
|
openSendAndClose,
|
|
8087
|
+
orderXmlObject,
|
|
7084
8088
|
parseFormCode,
|
|
7085
8089
|
parseKSeFTokenContext,
|
|
7086
8090
|
parseRetryAfter,
|
|
7087
8091
|
parseUpoXml,
|
|
8092
|
+
parseXml,
|
|
7088
8093
|
pollUntil,
|
|
7089
8094
|
resolveOptions,
|
|
7090
8095
|
resumeOnlineSession,
|
|
7091
8096
|
runWithConcurrency,
|
|
8097
|
+
serializeInvoiceXml,
|
|
7092
8098
|
sha256Base64,
|
|
7093
8099
|
sleep,
|
|
8100
|
+
stripBom,
|
|
8101
|
+
toKodFormularza,
|
|
7094
8102
|
unzip,
|
|
7095
8103
|
updateContinuationPoint,
|
|
7096
8104
|
uploadBatch,
|
|
@@ -7100,6 +8108,7 @@ init_client();
|
|
|
7100
8108
|
validate,
|
|
7101
8109
|
validateBatch,
|
|
7102
8110
|
validateBusinessRules,
|
|
8111
|
+
validateCharValidity,
|
|
7103
8112
|
validateFormCodeForSession,
|
|
7104
8113
|
validatePresignedUrl,
|
|
7105
8114
|
validateSchema,
|