ksef-client-ts 0.6.2 → 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 +2 -1
- package/dist/cli.js +922 -300
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +986 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +292 -16
- package/dist/index.d.ts +292 -16
- package/dist/index.js +964 -73
- 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,21 +184,29 @@ 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;
|
|
178
193
|
timestamp;
|
|
179
194
|
constructor(problemDetails) {
|
|
180
|
-
super(problemDetails.detail || "Unauthorized");
|
|
195
|
+
super(problemDetails.detail || "Unauthorized", 401);
|
|
181
196
|
this.name = "KSeFUnauthorizedError";
|
|
182
197
|
this.detail = problemDetails.detail;
|
|
183
198
|
this.traceId = problemDetails.traceId;
|
|
184
199
|
this.instance = problemDetails.instance;
|
|
185
200
|
this.timestamp = problemDetails.timestamp;
|
|
186
201
|
}
|
|
202
|
+
toProblemFields() {
|
|
203
|
+
return {
|
|
204
|
+
detail: this.detail,
|
|
205
|
+
traceId: this.traceId,
|
|
206
|
+
instance: this.instance,
|
|
207
|
+
timestamp: this.timestamp
|
|
208
|
+
};
|
|
209
|
+
}
|
|
187
210
|
};
|
|
188
211
|
}
|
|
189
212
|
});
|
|
@@ -193,8 +216,8 @@ var KSeFForbiddenError;
|
|
|
193
216
|
var init_ksef_forbidden_error = __esm({
|
|
194
217
|
"src/errors/ksef-forbidden-error.ts"() {
|
|
195
218
|
"use strict";
|
|
196
|
-
|
|
197
|
-
KSeFForbiddenError = class extends
|
|
219
|
+
init_ksef_api_error();
|
|
220
|
+
KSeFForbiddenError = class extends KSeFApiError {
|
|
198
221
|
statusCode = 403;
|
|
199
222
|
detail;
|
|
200
223
|
reasonCode;
|
|
@@ -203,7 +226,7 @@ var init_ksef_forbidden_error = __esm({
|
|
|
203
226
|
traceId;
|
|
204
227
|
timestamp;
|
|
205
228
|
constructor(problemDetails) {
|
|
206
|
-
super(problemDetails.detail || "Forbidden");
|
|
229
|
+
super(problemDetails.detail || "Forbidden", 403);
|
|
207
230
|
this.name = "KSeFForbiddenError";
|
|
208
231
|
this.detail = problemDetails.detail;
|
|
209
232
|
this.reasonCode = problemDetails.reasonCode;
|
|
@@ -212,6 +235,16 @@ var init_ksef_forbidden_error = __esm({
|
|
|
212
235
|
this.traceId = problemDetails.traceId;
|
|
213
236
|
this.timestamp = problemDetails.timestamp;
|
|
214
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
|
+
}
|
|
215
248
|
};
|
|
216
249
|
}
|
|
217
250
|
});
|
|
@@ -221,21 +254,64 @@ var KSeFGoneError;
|
|
|
221
254
|
var init_ksef_gone_error = __esm({
|
|
222
255
|
"src/errors/ksef-gone-error.ts"() {
|
|
223
256
|
"use strict";
|
|
224
|
-
|
|
225
|
-
KSeFGoneError = class extends
|
|
257
|
+
init_ksef_api_error();
|
|
258
|
+
KSeFGoneError = class extends KSeFApiError {
|
|
226
259
|
statusCode = 410;
|
|
227
260
|
detail;
|
|
228
261
|
instance;
|
|
229
262
|
traceId;
|
|
230
263
|
timestamp;
|
|
231
264
|
constructor(problemDetails) {
|
|
232
|
-
super(problemDetails.detail || "Operation status no longer available (retention expired)");
|
|
265
|
+
super(problemDetails.detail || "Operation status no longer available (retention expired)", 410);
|
|
233
266
|
this.name = "KSeFGoneError";
|
|
234
267
|
this.detail = problemDetails.detail;
|
|
235
268
|
this.instance = problemDetails.instance;
|
|
236
269
|
this.traceId = problemDetails.traceId;
|
|
237
270
|
this.timestamp = problemDetails.timestamp;
|
|
238
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
|
+
};
|
|
314
|
+
}
|
|
239
315
|
};
|
|
240
316
|
}
|
|
241
317
|
});
|
|
@@ -341,6 +417,16 @@ var init_ksef_batch_timeout_error = __esm({
|
|
|
341
417
|
}
|
|
342
418
|
});
|
|
343
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
|
+
|
|
344
430
|
// src/errors/index.ts
|
|
345
431
|
var init_errors = __esm({
|
|
346
432
|
"src/errors/index.ts"() {
|
|
@@ -351,11 +437,13 @@ var init_errors = __esm({
|
|
|
351
437
|
init_ksef_unauthorized_error();
|
|
352
438
|
init_ksef_forbidden_error();
|
|
353
439
|
init_ksef_gone_error();
|
|
440
|
+
init_ksef_bad_request_error();
|
|
354
441
|
init_ksef_auth_status_error();
|
|
355
442
|
init_ksef_session_expired_error();
|
|
356
443
|
init_ksef_validation_error();
|
|
357
444
|
init_ksef_batch_timeout_error();
|
|
358
445
|
init_error_codes();
|
|
446
|
+
init_assert_never();
|
|
359
447
|
}
|
|
360
448
|
});
|
|
361
449
|
|
|
@@ -603,6 +691,27 @@ var init_presigned_url_policy = __esm({
|
|
|
603
691
|
});
|
|
604
692
|
|
|
605
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
|
+
}
|
|
606
715
|
var import_consola, RestClient;
|
|
607
716
|
var init_rest_client = __esm({
|
|
608
717
|
"src/http/rest-client.ts"() {
|
|
@@ -613,6 +722,7 @@ var init_rest_client = __esm({
|
|
|
613
722
|
init_ksef_unauthorized_error();
|
|
614
723
|
init_ksef_forbidden_error();
|
|
615
724
|
init_ksef_gone_error();
|
|
725
|
+
init_ksef_bad_request_error();
|
|
616
726
|
init_ksef_batch_timeout_error();
|
|
617
727
|
init_error_codes();
|
|
618
728
|
init_route_builder();
|
|
@@ -701,6 +811,10 @@ var init_rest_client = __esm({
|
|
|
701
811
|
...this.options.customHeaders,
|
|
702
812
|
...request.getHeaders()
|
|
703
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
|
+
}
|
|
704
818
|
if (!headers["Authorization"] && this.authManager) {
|
|
705
819
|
const token = overrideToken ?? this.authManager.getAccessToken();
|
|
706
820
|
if (token) {
|
|
@@ -739,19 +853,40 @@ var init_rest_client = __esm({
|
|
|
739
853
|
async ensureSuccess(response) {
|
|
740
854
|
if (response.ok) return;
|
|
741
855
|
const text = await response.text().catch(() => "");
|
|
856
|
+
let jsonCache = null;
|
|
742
857
|
const parseJson = () => {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
858
|
+
if (jsonCache === null) {
|
|
859
|
+
try {
|
|
860
|
+
jsonCache = { value: JSON.parse(text) };
|
|
861
|
+
} catch {
|
|
862
|
+
jsonCache = { value: void 0 };
|
|
863
|
+
}
|
|
747
864
|
}
|
|
865
|
+
return jsonCache.value;
|
|
748
866
|
};
|
|
749
|
-
|
|
867
|
+
const tryParseProblem = (guard) => {
|
|
750
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();
|
|
751
885
|
throw KSeFRateLimitError.fromRetryAfterHeader(
|
|
752
886
|
response.status,
|
|
753
887
|
response.headers.get("Retry-After"),
|
|
754
|
-
|
|
888
|
+
legacy,
|
|
889
|
+
problem
|
|
755
890
|
);
|
|
756
891
|
}
|
|
757
892
|
if (response.status === 401) {
|
|
@@ -2701,6 +2836,115 @@ var init_schema_registry = __esm({
|
|
|
2701
2836
|
}
|
|
2702
2837
|
});
|
|
2703
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
|
+
|
|
2704
2948
|
// src/validation/invoice-validator.ts
|
|
2705
2949
|
var invoice_validator_exports = {};
|
|
2706
2950
|
__export(invoice_validator_exports, {
|
|
@@ -2853,6 +3097,12 @@ function collectDateErrors(obj, rootElement, errors) {
|
|
|
2853
3097
|
}
|
|
2854
3098
|
}
|
|
2855
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
|
+
}
|
|
2856
3106
|
const parsed = xml && xml.trim() ? xmlToObject(xml) : void 0;
|
|
2857
3107
|
const l1 = validateWellFormedness(xml, parsed);
|
|
2858
3108
|
if (!l1.valid) return l1;
|
|
@@ -2879,6 +3129,7 @@ var init_invoice_validator = __esm({
|
|
|
2879
3129
|
"use strict";
|
|
2880
3130
|
init_xml_to_object();
|
|
2881
3131
|
init_schema_registry();
|
|
3132
|
+
init_char_validity();
|
|
2882
3133
|
init_patterns();
|
|
2883
3134
|
}
|
|
2884
3135
|
});
|
|
@@ -3343,9 +3594,10 @@ var PermissionsService;
|
|
|
3343
3594
|
var init_permissions = __esm({
|
|
3344
3595
|
"src/services/permissions.ts"() {
|
|
3345
3596
|
"use strict";
|
|
3597
|
+
init_ksef_validation_error();
|
|
3346
3598
|
init_rest_request();
|
|
3347
3599
|
init_routes();
|
|
3348
|
-
PermissionsService = class {
|
|
3600
|
+
PermissionsService = class _PermissionsService {
|
|
3349
3601
|
restClient;
|
|
3350
3602
|
constructor(restClient) {
|
|
3351
3603
|
this.restClient = restClient;
|
|
@@ -3403,6 +3655,7 @@ var init_permissions = __esm({
|
|
|
3403
3655
|
}
|
|
3404
3656
|
// Search methods
|
|
3405
3657
|
async queryPersonalGrants(options, pageOffset, pageSize) {
|
|
3658
|
+
_PermissionsService.validateContextIdentifier(options?.contextIdentifier);
|
|
3406
3659
|
const req = RestRequest.post(Routes.Permissions.Query.personalGrants).body(options ?? {});
|
|
3407
3660
|
if (pageOffset !== void 0) req.query("pageOffset", String(pageOffset));
|
|
3408
3661
|
if (pageSize !== void 0) req.query("pageSize", String(pageSize));
|
|
@@ -3431,6 +3684,7 @@ var init_permissions = __esm({
|
|
|
3431
3684
|
return response.body;
|
|
3432
3685
|
}
|
|
3433
3686
|
async queryEntitiesGrants(options, pageOffset, pageSize) {
|
|
3687
|
+
_PermissionsService.validateContextIdentifier(options?.contextIdentifier);
|
|
3434
3688
|
const req = RestRequest.post(Routes.Permissions.Query.entitiesGrants).body(options ?? {});
|
|
3435
3689
|
if (pageOffset !== void 0) req.query("pageOffset", String(pageOffset));
|
|
3436
3690
|
if (pageSize !== void 0) req.query("pageSize", String(pageSize));
|
|
@@ -3469,17 +3723,90 @@ var init_permissions = __esm({
|
|
|
3469
3723
|
const response = await this.restClient.execute(req);
|
|
3470
3724
|
return response.body;
|
|
3471
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
|
+
}
|
|
3472
3738
|
};
|
|
3473
3739
|
}
|
|
3474
3740
|
});
|
|
3475
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
|
+
|
|
3476
3792
|
// src/services/tokens.ts
|
|
3477
|
-
|
|
3793
|
+
function toTokenAuthorIdentifierType(value) {
|
|
3794
|
+
return TOKEN_AUTHOR_IDENTIFIER_TYPES.has(value) ? value : void 0;
|
|
3795
|
+
}
|
|
3796
|
+
var TOKEN_AUTHOR_IDENTIFIER_TYPES, TokenService;
|
|
3478
3797
|
var init_tokens = __esm({
|
|
3479
3798
|
"src/services/tokens.ts"() {
|
|
3480
3799
|
"use strict";
|
|
3481
3800
|
init_rest_request();
|
|
3482
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
|
+
]);
|
|
3483
3810
|
TokenService = class {
|
|
3484
3811
|
restClient;
|
|
3485
3812
|
constructor(restClient) {
|
|
@@ -3514,6 +3841,73 @@ var init_tokens = __esm({
|
|
|
3514
3841
|
const req = RestRequest.delete(Routes.Tokens.byReference(ref));
|
|
3515
3842
|
await this.restClient.executeVoid(req);
|
|
3516
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
|
+
}
|
|
3517
3911
|
};
|
|
3518
3912
|
}
|
|
3519
3913
|
});
|
|
@@ -4139,8 +4533,8 @@ function computeRootDigest(doc) {
|
|
|
4139
4533
|
return crypto3.createHash("sha256").update(canonical, "utf-8").digest("base64");
|
|
4140
4534
|
}
|
|
4141
4535
|
function computeSignedPropertiesDigest(qualifyingPropertiesXml) {
|
|
4142
|
-
const
|
|
4143
|
-
const qpDoc =
|
|
4536
|
+
const parser2 = new import_xmldom2.DOMParser();
|
|
4537
|
+
const qpDoc = parser2.parseFromString(qualifyingPropertiesXml, "text/xml");
|
|
4144
4538
|
const signedProps = findElementByLocalName(qpDoc.documentElement, "SignedProperties");
|
|
4145
4539
|
if (!signedProps) {
|
|
4146
4540
|
throw new Error("SignedProperties element not found in QualifyingProperties");
|
|
@@ -4295,8 +4689,8 @@ var init_signature_service = __esm({
|
|
|
4295
4689
|
const isEc = privateKey.asymmetricKeyType === "ec";
|
|
4296
4690
|
const signatureAlgorithm = isEc ? ECDSA_SHA256_SIGNATURE : RSA_SHA256_SIGNATURE;
|
|
4297
4691
|
const signingTime = new Date(Date.now() + CLOCK_SKEW_BUFFER_MS).toISOString();
|
|
4298
|
-
const
|
|
4299
|
-
const doc =
|
|
4692
|
+
const parser2 = new import_xmldom2.DOMParser();
|
|
4693
|
+
const doc = parser2.parseFromString(xml, "text/xml");
|
|
4300
4694
|
const root = doc.documentElement;
|
|
4301
4695
|
if (!root) {
|
|
4302
4696
|
throw new Error("XML document has no root element");
|
|
@@ -4316,7 +4710,7 @@ var init_signature_service = __esm({
|
|
|
4316
4710
|
rootDigest,
|
|
4317
4711
|
signedPropertiesDigest
|
|
4318
4712
|
);
|
|
4319
|
-
const signedInfoDoc =
|
|
4713
|
+
const signedInfoDoc = parser2.parseFromString(signedInfoXml, "text/xml");
|
|
4320
4714
|
const canonicalSignedInfo = canonicalize(signedInfoDoc.documentElement);
|
|
4321
4715
|
const signatureValue = computeSignatureValue(
|
|
4322
4716
|
canonicalSignedInfo,
|
|
@@ -4329,7 +4723,7 @@ var init_signature_service = __esm({
|
|
|
4329
4723
|
certBase64,
|
|
4330
4724
|
qualifyingPropertiesXml
|
|
4331
4725
|
);
|
|
4332
|
-
const signatureDoc =
|
|
4726
|
+
const signatureDoc = parser2.parseFromString(signatureXml, "text/xml");
|
|
4333
4727
|
const importedNode = doc.importNode(signatureDoc.documentElement, true);
|
|
4334
4728
|
root.appendChild(importedNode);
|
|
4335
4729
|
return new import_xmldom2.XMLSerializer().serializeToString(doc);
|
|
@@ -5229,10 +5623,13 @@ __export(index_exports, {
|
|
|
5229
5623
|
CertificateService: () => CertificateService,
|
|
5230
5624
|
CryptographyService: () => CryptographyService,
|
|
5231
5625
|
DEFAULT_FORM_CODE: () => DEFAULT_FORM_CODE,
|
|
5626
|
+
DISCOURAGED_UNICODE_RANGES: () => DISCOURAGED_UNICODE_RANGES,
|
|
5232
5627
|
DefaultAuthManager: () => DefaultAuthManager,
|
|
5233
5628
|
ENFORCE_XADES_COMPLIANCE: () => ENFORCE_XADES_COMPLIANCE,
|
|
5629
|
+
ETD_NAMESPACE: () => ETD_NAMESPACE,
|
|
5234
5630
|
EntityPermissionGrantBuilder: () => EntityPermissionGrantBuilder,
|
|
5235
5631
|
Environment: () => Environment,
|
|
5632
|
+
FAKTURA_NAMESPACE: () => FAKTURA_NAMESPACE,
|
|
5236
5633
|
FORM_CODES: () => FORM_CODES,
|
|
5237
5634
|
FORM_CODE_KEYS: () => FORM_CODE_KEYS,
|
|
5238
5635
|
FileHwmStore: () => FileHwmStore,
|
|
@@ -5249,6 +5646,7 @@ __export(index_exports, {
|
|
|
5249
5646
|
KSEF_FEATURE_HEADER: () => KSEF_FEATURE_HEADER,
|
|
5250
5647
|
KSeFApiError: () => KSeFApiError,
|
|
5251
5648
|
KSeFAuthStatusError: () => KSeFAuthStatusError,
|
|
5649
|
+
KSeFBadRequestError: () => KSeFBadRequestError,
|
|
5252
5650
|
KSeFBatchTimeoutError: () => KSeFBatchTimeoutError,
|
|
5253
5651
|
KSeFClient: () => KSeFClient,
|
|
5254
5652
|
KSeFError: () => KSeFError,
|
|
@@ -5266,8 +5664,10 @@ __export(index_exports, {
|
|
|
5266
5664
|
LimitsService: () => LimitsService,
|
|
5267
5665
|
Nip: () => Nip,
|
|
5268
5666
|
NipVatUe: () => NipVatUe,
|
|
5667
|
+
ORDER_MAP: () => ORDER_MAP,
|
|
5269
5668
|
OfflineInvoiceWorkflow: () => OfflineInvoiceWorkflow,
|
|
5270
5669
|
OnlineSessionService: () => OnlineSessionService,
|
|
5670
|
+
PEF_NAMESPACE: () => PEF_NAMESPACE,
|
|
5271
5671
|
PERMISSION_DESCRIPTION_MAX_LENGTH: () => PERMISSION_DESCRIPTION_MAX_LENGTH,
|
|
5272
5672
|
PERMISSION_DESCRIPTION_MIN_LENGTH: () => PERMISSION_DESCRIPTION_MIN_LENGTH,
|
|
5273
5673
|
PeppolId: () => PeppolId,
|
|
@@ -5297,14 +5697,21 @@ __export(index_exports, {
|
|
|
5297
5697
|
VatUe: () => VatUe,
|
|
5298
5698
|
VerificationLinkService: () => VerificationLinkService,
|
|
5299
5699
|
addBusinessDays: () => addBusinessDays,
|
|
5700
|
+
assertNever: () => assertNever,
|
|
5300
5701
|
authenticateWithCertificate: () => authenticateWithCertificate,
|
|
5301
5702
|
authenticateWithExternalSignature: () => authenticateWithExternalSignature,
|
|
5302
5703
|
authenticateWithPkcs12: () => authenticateWithPkcs12,
|
|
5303
5704
|
authenticateWithToken: () => authenticateWithToken,
|
|
5304
5705
|
batchValidationDetails: () => batchValidationDetails,
|
|
5706
|
+
buildFakturaXml: () => buildFakturaXml,
|
|
5707
|
+
buildPefXml: () => buildPefXml,
|
|
5708
|
+
buildRawXmlString: () => buildRawXmlString,
|
|
5305
5709
|
buildUnsignedAuthTokenRequestXml: () => buildUnsignedAuthTokenRequestXml,
|
|
5710
|
+
buildXml: () => buildXml,
|
|
5711
|
+
buildXmlFromObject: () => buildXmlFromObject,
|
|
5306
5712
|
calculateBackoff: () => calculateBackoff,
|
|
5307
5713
|
calculateOfflineDeadline: () => calculateOfflineDeadline,
|
|
5714
|
+
comparePKey: () => comparePKey,
|
|
5308
5715
|
createZip: () => createZip,
|
|
5309
5716
|
decodeJwtPayload: () => decodeJwtPayload,
|
|
5310
5717
|
deduplicateByKsefNumber: () => deduplicateByKsefNumber,
|
|
@@ -5323,6 +5730,9 @@ __export(index_exports, {
|
|
|
5323
5730
|
getTimeUntilDeadline: () => getTimeUntilDeadline,
|
|
5324
5731
|
incrementalExportAndDownload: () => incrementalExportAndDownload,
|
|
5325
5732
|
isExpired: () => isExpired,
|
|
5733
|
+
isFakturaInput: () => isFakturaInput,
|
|
5734
|
+
isFormCodeShape: () => isFormCodeShape,
|
|
5735
|
+
isPefUblDocumentInput: () => isPefUblDocumentInput,
|
|
5326
5736
|
isPolishHoliday: () => isPolishHoliday,
|
|
5327
5737
|
isRetryableError: () => isRetryableError,
|
|
5328
5738
|
isRetryableStatus: () => isRetryableStatus,
|
|
@@ -5344,16 +5754,21 @@ __export(index_exports, {
|
|
|
5344
5754
|
nextBusinessDay: () => nextBusinessDay,
|
|
5345
5755
|
openOnlineSession: () => openOnlineSession,
|
|
5346
5756
|
openSendAndClose: () => openSendAndClose,
|
|
5757
|
+
orderXmlObject: () => orderXmlObject,
|
|
5347
5758
|
parseFormCode: () => parseFormCode,
|
|
5348
5759
|
parseKSeFTokenContext: () => parseKSeFTokenContext,
|
|
5349
5760
|
parseRetryAfter: () => parseRetryAfter,
|
|
5350
5761
|
parseUpoXml: () => parseUpoXml,
|
|
5762
|
+
parseXml: () => parseXml,
|
|
5351
5763
|
pollUntil: () => pollUntil,
|
|
5352
5764
|
resolveOptions: () => resolveOptions,
|
|
5353
5765
|
resumeOnlineSession: () => resumeOnlineSession,
|
|
5354
5766
|
runWithConcurrency: () => runWithConcurrency,
|
|
5767
|
+
serializeInvoiceXml: () => serializeInvoiceXml,
|
|
5355
5768
|
sha256Base64: () => sha256Base642,
|
|
5356
5769
|
sleep: () => sleep,
|
|
5770
|
+
stripBom: () => stripBom,
|
|
5771
|
+
toKodFormularza: () => toKodFormularza,
|
|
5357
5772
|
unzip: () => unzip,
|
|
5358
5773
|
updateContinuationPoint: () => updateContinuationPoint,
|
|
5359
5774
|
uploadBatch: () => uploadBatch,
|
|
@@ -5363,6 +5778,7 @@ __export(index_exports, {
|
|
|
5363
5778
|
validate: () => validate,
|
|
5364
5779
|
validateBatch: () => validateBatch,
|
|
5365
5780
|
validateBusinessRules: () => validateBusinessRules,
|
|
5781
|
+
validateCharValidity: () => validateCharValidity,
|
|
5366
5782
|
validateFormCodeForSession: () => validateFormCodeForSession,
|
|
5367
5783
|
validatePresignedUrl: () => validatePresignedUrl,
|
|
5368
5784
|
validateSchema: () => validateSchema,
|
|
@@ -5402,6 +5818,7 @@ var PERMISSION_DESCRIPTION_MAX_LENGTH = 256;
|
|
|
5402
5818
|
init_xml_to_object();
|
|
5403
5819
|
init_schema_registry();
|
|
5404
5820
|
init_invoice_validator();
|
|
5821
|
+
init_char_validity();
|
|
5405
5822
|
|
|
5406
5823
|
// src/models/index.ts
|
|
5407
5824
|
init_document_structures();
|
|
@@ -6093,51 +6510,7 @@ function escapeXml2(str) {
|
|
|
6093
6510
|
|
|
6094
6511
|
// src/utils/index.ts
|
|
6095
6512
|
init_zip();
|
|
6096
|
-
|
|
6097
|
-
// src/utils/jwt.ts
|
|
6098
|
-
function decodeJwtPayload(token) {
|
|
6099
|
-
const parts = token.split(".");
|
|
6100
|
-
if (parts.length !== 3) return null;
|
|
6101
|
-
try {
|
|
6102
|
-
const payload = parts[1];
|
|
6103
|
-
const json = Buffer.from(payload, "base64url").toString("utf-8");
|
|
6104
|
-
return JSON.parse(json);
|
|
6105
|
-
} catch {
|
|
6106
|
-
return null;
|
|
6107
|
-
}
|
|
6108
|
-
}
|
|
6109
|
-
function tryParseJson(value) {
|
|
6110
|
-
if (typeof value !== "string") return void 0;
|
|
6111
|
-
try {
|
|
6112
|
-
return JSON.parse(value);
|
|
6113
|
-
} catch {
|
|
6114
|
-
return void 0;
|
|
6115
|
-
}
|
|
6116
|
-
}
|
|
6117
|
-
function tryParseJsonArray(value) {
|
|
6118
|
-
if (typeof value !== "string") return void 0;
|
|
6119
|
-
try {
|
|
6120
|
-
const parsed = JSON.parse(value);
|
|
6121
|
-
return Array.isArray(parsed) && parsed.every((item) => typeof item === "string") ? parsed : void 0;
|
|
6122
|
-
} catch {
|
|
6123
|
-
return void 0;
|
|
6124
|
-
}
|
|
6125
|
-
}
|
|
6126
|
-
function parseKSeFTokenContext(token) {
|
|
6127
|
-
const raw = decodeJwtPayload(token);
|
|
6128
|
-
if (!raw) return null;
|
|
6129
|
-
return {
|
|
6130
|
-
type: typeof raw["typ"] === "string" ? raw["typ"] : void 0,
|
|
6131
|
-
contextIdentifierType: typeof raw["cit"] === "string" ? raw["cit"] : void 0,
|
|
6132
|
-
contextIdentifierValue: typeof raw["civ"] === "string" ? raw["civ"] : void 0,
|
|
6133
|
-
authMethod: typeof raw["aum"] === "string" ? raw["aum"] : void 0,
|
|
6134
|
-
permissions: tryParseJsonArray(raw["per"]),
|
|
6135
|
-
subjectDetails: tryParseJson(raw["sud"]),
|
|
6136
|
-
authorSubjectIdentifier: tryParseJson(raw["asi"]),
|
|
6137
|
-
issuedAt: typeof raw["iat"] === "number" ? raw["iat"] : void 0,
|
|
6138
|
-
expiresAt: typeof raw["exp"] === "number" ? raw["exp"] : void 0
|
|
6139
|
-
};
|
|
6140
|
-
}
|
|
6513
|
+
init_jwt();
|
|
6141
6514
|
|
|
6142
6515
|
// src/utils/hash.ts
|
|
6143
6516
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
@@ -6333,6 +6706,524 @@ function nonEmptyString(value) {
|
|
|
6333
6706
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
6334
6707
|
}
|
|
6335
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
|
+
|
|
6336
7227
|
// src/workflows/online-session-workflow.ts
|
|
6337
7228
|
init_invoice_validator();
|
|
6338
7229
|
init_ksef_validation_error();
|
|
@@ -7062,10 +7953,13 @@ init_client();
|
|
|
7062
7953
|
CertificateService,
|
|
7063
7954
|
CryptographyService,
|
|
7064
7955
|
DEFAULT_FORM_CODE,
|
|
7956
|
+
DISCOURAGED_UNICODE_RANGES,
|
|
7065
7957
|
DefaultAuthManager,
|
|
7066
7958
|
ENFORCE_XADES_COMPLIANCE,
|
|
7959
|
+
ETD_NAMESPACE,
|
|
7067
7960
|
EntityPermissionGrantBuilder,
|
|
7068
7961
|
Environment,
|
|
7962
|
+
FAKTURA_NAMESPACE,
|
|
7069
7963
|
FORM_CODES,
|
|
7070
7964
|
FORM_CODE_KEYS,
|
|
7071
7965
|
FileHwmStore,
|
|
@@ -7082,6 +7976,7 @@ init_client();
|
|
|
7082
7976
|
KSEF_FEATURE_HEADER,
|
|
7083
7977
|
KSeFApiError,
|
|
7084
7978
|
KSeFAuthStatusError,
|
|
7979
|
+
KSeFBadRequestError,
|
|
7085
7980
|
KSeFBatchTimeoutError,
|
|
7086
7981
|
KSeFClient,
|
|
7087
7982
|
KSeFError,
|
|
@@ -7099,8 +7994,10 @@ init_client();
|
|
|
7099
7994
|
LimitsService,
|
|
7100
7995
|
Nip,
|
|
7101
7996
|
NipVatUe,
|
|
7997
|
+
ORDER_MAP,
|
|
7102
7998
|
OfflineInvoiceWorkflow,
|
|
7103
7999
|
OnlineSessionService,
|
|
8000
|
+
PEF_NAMESPACE,
|
|
7104
8001
|
PERMISSION_DESCRIPTION_MAX_LENGTH,
|
|
7105
8002
|
PERMISSION_DESCRIPTION_MIN_LENGTH,
|
|
7106
8003
|
PeppolId,
|
|
@@ -7130,14 +8027,21 @@ init_client();
|
|
|
7130
8027
|
VatUe,
|
|
7131
8028
|
VerificationLinkService,
|
|
7132
8029
|
addBusinessDays,
|
|
8030
|
+
assertNever,
|
|
7133
8031
|
authenticateWithCertificate,
|
|
7134
8032
|
authenticateWithExternalSignature,
|
|
7135
8033
|
authenticateWithPkcs12,
|
|
7136
8034
|
authenticateWithToken,
|
|
7137
8035
|
batchValidationDetails,
|
|
8036
|
+
buildFakturaXml,
|
|
8037
|
+
buildPefXml,
|
|
8038
|
+
buildRawXmlString,
|
|
7138
8039
|
buildUnsignedAuthTokenRequestXml,
|
|
8040
|
+
buildXml,
|
|
8041
|
+
buildXmlFromObject,
|
|
7139
8042
|
calculateBackoff,
|
|
7140
8043
|
calculateOfflineDeadline,
|
|
8044
|
+
comparePKey,
|
|
7141
8045
|
createZip,
|
|
7142
8046
|
decodeJwtPayload,
|
|
7143
8047
|
deduplicateByKsefNumber,
|
|
@@ -7156,6 +8060,9 @@ init_client();
|
|
|
7156
8060
|
getTimeUntilDeadline,
|
|
7157
8061
|
incrementalExportAndDownload,
|
|
7158
8062
|
isExpired,
|
|
8063
|
+
isFakturaInput,
|
|
8064
|
+
isFormCodeShape,
|
|
8065
|
+
isPefUblDocumentInput,
|
|
7159
8066
|
isPolishHoliday,
|
|
7160
8067
|
isRetryableError,
|
|
7161
8068
|
isRetryableStatus,
|
|
@@ -7177,16 +8084,21 @@ init_client();
|
|
|
7177
8084
|
nextBusinessDay,
|
|
7178
8085
|
openOnlineSession,
|
|
7179
8086
|
openSendAndClose,
|
|
8087
|
+
orderXmlObject,
|
|
7180
8088
|
parseFormCode,
|
|
7181
8089
|
parseKSeFTokenContext,
|
|
7182
8090
|
parseRetryAfter,
|
|
7183
8091
|
parseUpoXml,
|
|
8092
|
+
parseXml,
|
|
7184
8093
|
pollUntil,
|
|
7185
8094
|
resolveOptions,
|
|
7186
8095
|
resumeOnlineSession,
|
|
7187
8096
|
runWithConcurrency,
|
|
8097
|
+
serializeInvoiceXml,
|
|
7188
8098
|
sha256Base64,
|
|
7189
8099
|
sleep,
|
|
8100
|
+
stripBom,
|
|
8101
|
+
toKodFormularza,
|
|
7190
8102
|
unzip,
|
|
7191
8103
|
updateContinuationPoint,
|
|
7192
8104
|
uploadBatch,
|
|
@@ -7196,6 +8108,7 @@ init_client();
|
|
|
7196
8108
|
validate,
|
|
7197
8109
|
validateBatch,
|
|
7198
8110
|
validateBusinessRules,
|
|
8111
|
+
validateCharValidity,
|
|
7199
8112
|
validateFormCodeForSession,
|
|
7200
8113
|
validatePresignedUrl,
|
|
7201
8114
|
validateSchema,
|