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/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
- constructor(message, statusCode, errorResponse, retryAfterSeconds, retryAfterDate) {
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
- init_ksef_error();
173
- KSeFUnauthorizedError = class extends KSeFError {
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
- init_ksef_error();
195
- KSeFForbiddenError = class extends KSeFError {
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
- try {
671
- return JSON.parse(text);
672
- } catch {
673
- return void 0;
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
- if (response.status === 429) {
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
- parsed
888
+ legacy,
889
+ problem
682
890
  );
683
891
  }
684
892
  if (response.status === 401) {
685
- const body = parseJson();
686
- if (body?.detail) {
687
- throw new KSeFUnauthorizedError(body);
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 body = parseJson();
692
- if (body?.reasonCode) {
693
- throw new KSeFForbiddenError(body);
899
+ const body2 = parseJson();
900
+ if (body2?.reasonCode) {
901
+ throw new KSeFForbiddenError(body2);
694
902
  }
695
903
  }
696
- throw KSeFApiError.fromResponse(response.status, parseJson());
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
- var TokenService;
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 parser = new import_xmldom2.DOMParser();
4055
- const qpDoc = parser.parseFromString(qualifyingPropertiesXml, "text/xml");
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 parser = new import_xmldom2.DOMParser();
4211
- const doc = parser.parseFromString(xml, "text/xml");
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 = parser.parseFromString(signedInfoXml, "text/xml");
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 = parser.parseFromString(signatureXml, "text/xml");
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
- await this.loginWithCertificate(certificatePem, privateKeyPem, nip);
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,