ksef-client-ts 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -988,6 +988,32 @@ var init_online_session = __esm({
988
988
  }
989
989
  });
990
990
 
991
+ // src/utils/concurrency.ts
992
+ async function runWithConcurrency(tasks, parallelism) {
993
+ if (tasks.length === 0) return;
994
+ const limit = Math.max(1, Math.min(parallelism, tasks.length));
995
+ const controller = new AbortController();
996
+ let index = 0;
997
+ const workers = Array.from({ length: limit }, async () => {
998
+ while (index < tasks.length && !controller.signal.aborted) {
999
+ const current = index;
1000
+ index += 1;
1001
+ try {
1002
+ await tasks[current](controller.signal);
1003
+ } catch (err) {
1004
+ controller.abort();
1005
+ throw err;
1006
+ }
1007
+ }
1008
+ });
1009
+ await Promise.all(workers);
1010
+ }
1011
+ var init_concurrency = __esm({
1012
+ "src/utils/concurrency.ts"() {
1013
+ "use strict";
1014
+ }
1015
+ });
1016
+
991
1017
  // src/services/batch-session.ts
992
1018
  var BatchSessionService;
993
1019
  var init_batch_session = __esm({
@@ -996,6 +1022,7 @@ var init_batch_session = __esm({
996
1022
  init_ksef_feature();
997
1023
  init_rest_request();
998
1024
  init_routes();
1025
+ init_concurrency();
999
1026
  BatchSessionService = class {
1000
1027
  restClient;
1001
1028
  constructor(restClient) {
@@ -1009,12 +1036,10 @@ var init_batch_session = __esm({
1009
1036
  const response = await this.restClient.execute(req);
1010
1037
  return response.body;
1011
1038
  }
1012
- async sendParts(openResponse, parts) {
1013
- const uploadRequests = openResponse.partUploadRequests;
1014
- const tasks = parts.map(async (part) => {
1015
- const uploadReq = uploadRequests.find(
1016
- (r) => r.ordinalNumber === part.ordinalNumber
1017
- );
1039
+ async sendParts(openResponse, parts, parallelism) {
1040
+ const uploadMap = new Map(openResponse.partUploadRequests.map((r) => [r.ordinalNumber, r]));
1041
+ const tasks = parts.map((part) => async (signal) => {
1042
+ const uploadReq = uploadMap.get(part.ordinalNumber);
1018
1043
  if (!uploadReq) {
1019
1044
  throw new Error(`No upload request found for part ${part.ordinalNumber}`);
1020
1045
  }
@@ -1022,25 +1047,38 @@ var init_batch_session = __esm({
1022
1047
  for (const [k, v] of Object.entries(uploadReq.headers)) {
1023
1048
  if (v != null) headers[k] = v;
1024
1049
  }
1025
- await fetch(uploadReq.url, {
1050
+ const resp = await fetch(uploadReq.url, {
1026
1051
  method: uploadReq.method,
1027
1052
  headers,
1028
- body: part.data
1053
+ body: part.data,
1054
+ signal
1029
1055
  });
1056
+ if (!resp.ok) {
1057
+ const body = await resp.text().catch(() => "");
1058
+ throw new Error(
1059
+ `Upload failed for part ${part.ordinalNumber}: HTTP ${resp.status}${body ? ` \u2014 ${body}` : ""}`
1060
+ );
1061
+ }
1030
1062
  });
1031
- await Promise.all(tasks);
1063
+ if (parallelism !== void 0) {
1064
+ await runWithConcurrency(tasks, parallelism);
1065
+ } else {
1066
+ const ac = new AbortController();
1067
+ await Promise.all(tasks.map((t) => t(ac.signal).catch((err) => {
1068
+ ac.abort();
1069
+ throw err;
1070
+ })));
1071
+ }
1032
1072
  }
1033
1073
  /**
1034
- * Upload parts sequentially (not in parallel) because each part uses a
1035
- * streaming body (`duplex: 'half'`). Parallel streaming uploads can cause
1036
- * backpressure issues and exceed memory limits for large payloads.
1074
+ * Upload parts using streaming bodies (`duplex: 'half'`).
1075
+ * By default uploads sequentially to avoid backpressure issues.
1076
+ * Pass `parallelism` to enable bounded concurrent uploads.
1037
1077
  */
1038
- async sendPartsWithStream(openResponse, parts) {
1039
- const uploadRequests = openResponse.partUploadRequests;
1040
- for (const part of parts) {
1041
- const uploadReq = uploadRequests.find(
1042
- (r) => r.ordinalNumber === part.ordinalNumber
1043
- );
1078
+ async sendPartsWithStream(openResponse, parts, parallelism) {
1079
+ const uploadMap = new Map(openResponse.partUploadRequests.map((r) => [r.ordinalNumber, r]));
1080
+ const uploadPart = async (part, signal) => {
1081
+ const uploadReq = uploadMap.get(part.ordinalNumber);
1044
1082
  if (!uploadReq) {
1045
1083
  throw new Error(`No upload request found for part ${part.ordinalNumber}`);
1046
1084
  }
@@ -1052,11 +1090,23 @@ var init_batch_session = __esm({
1052
1090
  method: uploadReq.method,
1053
1091
  headers,
1054
1092
  body: part.dataStream,
1093
+ signal,
1055
1094
  // @ts-expect-error -- Node 18+ undici supports duplex for streaming body
1056
1095
  duplex: "half"
1057
1096
  });
1058
1097
  if (!resp.ok) {
1059
- throw new Error(`Upload failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
1098
+ const body = await resp.text().catch(() => "");
1099
+ throw new Error(
1100
+ `Upload failed for part ${part.ordinalNumber}: HTTP ${resp.status}${body ? ` \u2014 ${body}` : ""}`
1101
+ );
1102
+ }
1103
+ };
1104
+ if (parallelism !== void 0) {
1105
+ await runWithConcurrency(parts.map((p) => (signal) => uploadPart(p, signal)), parallelism);
1106
+ } else {
1107
+ const { signal } = new AbortController();
1108
+ for (const part of parts) {
1109
+ await uploadPart(part, signal);
1060
1110
  }
1061
1111
  }
1062
1112
  }
@@ -1169,7 +1219,10 @@ var init_invoice_download = __esm({
1169
1219
  async getInvoice(ksefNumber) {
1170
1220
  const req = RestRequest.get(Routes.Invoices.byKsefNumber(ksefNumber));
1171
1221
  const response = await this.restClient.executeRaw(req);
1172
- return new TextDecoder().decode(response.body);
1222
+ return {
1223
+ xml: new TextDecoder().decode(response.body),
1224
+ hash: response.headers.get("x-ms-meta-hash") ?? void 0
1225
+ };
1173
1226
  }
1174
1227
  async queryInvoiceMetadata(filters, pageOffset, pageSize, sortOrder) {
1175
1228
  const req = RestRequest.post(Routes.Invoices.queryMetadata).body(filters);
@@ -2087,6 +2140,72 @@ var init_auth_xml_builder = __esm({
2087
2140
  }
2088
2141
  });
2089
2142
 
2143
+ // src/offline/holidays.ts
2144
+ function toDateKey(d) {
2145
+ return d.toISOString().slice(0, 10);
2146
+ }
2147
+ function dateKey(year, month, day) {
2148
+ return toDateKey(new Date(Date.UTC(year, month - 1, day)));
2149
+ }
2150
+ function addDays(d, n) {
2151
+ const result = new Date(d);
2152
+ result.setUTCDate(result.getUTCDate() + n);
2153
+ return result;
2154
+ }
2155
+ function computeEasterSunday(year) {
2156
+ const a = year % 19;
2157
+ const b = Math.floor(year / 100);
2158
+ const c = year % 100;
2159
+ const d = Math.floor(b / 4);
2160
+ const e = b % 4;
2161
+ const f = Math.floor((b + 8) / 25);
2162
+ const g = Math.floor((b - f + 1) / 3);
2163
+ const h = (19 * a + b - d - g + 15) % 30;
2164
+ const i = Math.floor(c / 4);
2165
+ const k = c % 4;
2166
+ const l = (32 + 2 * e + 2 * i - h - k) % 7;
2167
+ const m = Math.floor((a + 11 * h + 22 * l) / 451);
2168
+ const month = Math.floor((h + l - 7 * m + 114) / 31);
2169
+ const day = (h + l - 7 * m + 114) % 31 + 1;
2170
+ return new Date(Date.UTC(year, month - 1, day));
2171
+ }
2172
+ function getPolishHolidays(year) {
2173
+ const cached = holidayCache.get(year);
2174
+ if (cached) return cached;
2175
+ const easter = computeEasterSunday(year);
2176
+ const holidays = /* @__PURE__ */ new Set([
2177
+ // Fixed
2178
+ dateKey(year, 1, 1),
2179
+ dateKey(year, 1, 6),
2180
+ dateKey(year, 5, 1),
2181
+ dateKey(year, 5, 3),
2182
+ dateKey(year, 8, 15),
2183
+ dateKey(year, 11, 1),
2184
+ dateKey(year, 11, 11),
2185
+ dateKey(year, 12, 25),
2186
+ dateKey(year, 12, 26),
2187
+ // Wigilia — added by Dz.U. 2024 poz. 1965, effective from 2025
2188
+ ...year >= 2025 ? [dateKey(year, 12, 24)] : [],
2189
+ // Moveable
2190
+ toDateKey(easter),
2191
+ toDateKey(addDays(easter, 1)),
2192
+ toDateKey(addDays(easter, 49)),
2193
+ toDateKey(addDays(easter, 60))
2194
+ ]);
2195
+ holidayCache.set(year, holidays);
2196
+ return holidays;
2197
+ }
2198
+ function isPolishHoliday(date) {
2199
+ return getPolishHolidays(date.getUTCFullYear()).has(toDateKey(date));
2200
+ }
2201
+ var holidayCache;
2202
+ var init_holidays = __esm({
2203
+ "src/offline/holidays.ts"() {
2204
+ "use strict";
2205
+ holidayCache = /* @__PURE__ */ new Map();
2206
+ }
2207
+ });
2208
+
2090
2209
  // src/offline/deadline.ts
2091
2210
  function getDefaultReason(mode) {
2092
2211
  switch (mode) {
@@ -2103,7 +2222,7 @@ function getDefaultReason(mode) {
2103
2222
  function nextBusinessDay(from) {
2104
2223
  const d = new Date(from);
2105
2224
  d.setUTCDate(d.getUTCDate() + 1);
2106
- while (d.getUTCDay() === 0 || d.getUTCDay() === 6) {
2225
+ while (d.getUTCDay() === 0 || d.getUTCDay() === 6 || isPolishHoliday(d)) {
2107
2226
  d.setUTCDate(d.getUTCDate() + 1);
2108
2227
  }
2109
2228
  return d;
@@ -2116,7 +2235,7 @@ function addBusinessDays(from, days) {
2116
2235
  let remaining = days;
2117
2236
  while (remaining > 0) {
2118
2237
  d.setUTCDate(d.getUTCDate() + 1);
2119
- if (d.getUTCDay() !== 0 && d.getUTCDay() !== 6) {
2238
+ if (d.getUTCDay() !== 0 && d.getUTCDay() !== 6 && !isPolishHoliday(d)) {
2120
2239
  remaining--;
2121
2240
  }
2122
2241
  }
@@ -2162,6 +2281,7 @@ var FAR_FUTURE;
2162
2281
  var init_deadline = __esm({
2163
2282
  "src/offline/deadline.ts"() {
2164
2283
  "use strict";
2284
+ init_holidays();
2165
2285
  FAR_FUTURE = /* @__PURE__ */ new Date("9999-12-31T23:59:59Z");
2166
2286
  }
2167
2287
  });
@@ -2884,6 +3004,7 @@ var init_client = __esm({
2884
3004
  qr;
2885
3005
  options;
2886
3006
  authManager;
3007
+ _baseRestClientConfig;
2887
3008
  _offline;
2888
3009
  constructor(options) {
2889
3010
  this.options = resolveOptions(options);
@@ -2895,6 +3016,8 @@ var init_client = __esm({
2895
3016
  });
2896
3017
  this.authManager = authManager;
2897
3018
  const restClientConfig = buildRestClientConfig(options, authManager);
3019
+ const { authManager: _am, ...baseConfig } = restClientConfig;
3020
+ this._baseRestClientConfig = baseConfig;
2898
3021
  const restClient = new RestClient(this.options, restClientConfig);
2899
3022
  const fetcher = new CertificateFetcher(restClient);
2900
3023
  this.crypto = new CryptographyService(fetcher);
@@ -2919,6 +3042,10 @@ var init_client = __esm({
2919
3042
  }
2920
3043
  return this._offline;
2921
3044
  }
3045
+ /** @internal Create a RestClient with a different AuthManager, preserving transport/retry/rateLimit config. */
3046
+ createScopedRestClient(authManager) {
3047
+ return new RestClient(this.options, { ...this._baseRestClientConfig, authManager });
3048
+ }
2922
3049
  async loginWithToken(token, nip) {
2923
3050
  const challenge2 = await this.auth.getChallenge();
2924
3051
  await this.crypto.init();
@@ -5034,7 +5161,7 @@ var init_invoice_validator = __esm({
5034
5161
  });
5035
5162
 
5036
5163
  // src/builders/batch-file.ts
5037
- import * as crypto5 from "crypto";
5164
+ import * as crypto6 from "crypto";
5038
5165
  function splitBuffer(data, maxPartSize) {
5039
5166
  if (data.length <= maxPartSize) {
5040
5167
  return [data];
@@ -5045,8 +5172,8 @@ function splitBuffer(data, maxPartSize) {
5045
5172
  }
5046
5173
  return parts;
5047
5174
  }
5048
- function sha256Base64(data) {
5049
- return crypto5.createHash("sha256").update(data).digest("base64");
5175
+ function sha256Base642(data) {
5176
+ return crypto6.createHash("sha256").update(data).digest("base64");
5050
5177
  }
5051
5178
  var BATCH_MAX_PART_SIZE, BATCH_MAX_TOTAL_SIZE, BATCH_MAX_PARTS, BatchFileBuilder;
5052
5179
  var init_batch_file = __esm({
@@ -5083,7 +5210,7 @@ var init_batch_file = __esm({
5083
5210
  `Data requires ${rawParts.length} parts, exceeding maximum of ${BATCH_MAX_PARTS}`
5084
5211
  );
5085
5212
  }
5086
- const zipHash = sha256Base64(zipBytes);
5213
+ const zipHash = sha256Base642(zipBytes);
5087
5214
  const encryptedParts = [];
5088
5215
  const fileParts = rawParts.map((raw, i) => {
5089
5216
  const encrypted = encryptFn(raw);
@@ -5091,7 +5218,7 @@ var init_batch_file = __esm({
5091
5218
  return {
5092
5219
  ordinalNumber: i + 1,
5093
5220
  fileSize: encrypted.length,
5094
- fileHash: sha256Base64(encrypted)
5221
+ fileHash: sha256Base642(encrypted)
5095
5222
  };
5096
5223
  });
5097
5224
  return {
@@ -5174,7 +5301,7 @@ var init_batch_file = __esm({
5174
5301
  encryptedChunks.push(value);
5175
5302
  }
5176
5303
  const encryptedData = new Uint8Array(Buffer.concat(encryptedChunks));
5177
- const encryptedMeta = sha256Base64(encryptedData);
5304
+ const encryptedMeta = sha256Base642(encryptedData);
5178
5305
  fileParts.push({
5179
5306
  ordinalNumber: partIndex + 1,
5180
5307
  fileSize: encryptedData.byteLength,
@@ -5218,6 +5345,9 @@ __export(batch_session_workflow_exports, {
5218
5345
  uploadBatchStreamParsed: () => uploadBatchStreamParsed
5219
5346
  });
5220
5347
  async function uploadBatch(client, zipData, options) {
5348
+ if (options?.parallelism !== void 0 && (!Number.isInteger(options.parallelism) || options.parallelism < 1)) {
5349
+ throw new Error("parallelism must be a positive integer");
5350
+ }
5221
5351
  await client.crypto.init();
5222
5352
  if (options?.validate) {
5223
5353
  const { unzip: unzip2 } = await Promise.resolve().then(() => (init_zip(), zip_exports));
@@ -5260,7 +5390,7 @@ async function uploadBatch(client, zipData, options) {
5260
5390
  },
5261
5391
  ordinalNumber: i + 1
5262
5392
  }));
5263
- await client.batchSession.sendParts(openResp, sendingParts);
5393
+ await client.batchSession.sendParts(openResp, sendingParts, options?.parallelism);
5264
5394
  await client.batchSession.closeSession(openResp.referenceNumber);
5265
5395
  const result = await pollUntil(
5266
5396
  () => client.sessionStatus.getSessionStatus(openResp.referenceNumber),
@@ -5281,6 +5411,9 @@ async function uploadBatch(client, zipData, options) {
5281
5411
  };
5282
5412
  }
5283
5413
  async function uploadBatchStream(client, zipStreamFactory, zipSize, options) {
5414
+ if (options?.parallelism !== void 0 && (!Number.isInteger(options.parallelism) || options.parallelism < 1)) {
5415
+ throw new Error("parallelism must be a positive integer");
5416
+ }
5284
5417
  await client.crypto.init();
5285
5418
  const encData = client.crypto.getEncryptionData();
5286
5419
  const formCode = options?.formCode ?? DEFAULT_FORM_CODE;
@@ -5302,7 +5435,7 @@ async function uploadBatchStream(client, zipStreamFactory, zipSize, options) {
5302
5435
  },
5303
5436
  options?.upoVersion
5304
5437
  );
5305
- await client.batchSession.sendPartsWithStream(openResp, streamParts);
5438
+ await client.batchSession.sendPartsWithStream(openResp, streamParts, options?.parallelism);
5306
5439
  await client.batchSession.closeSession(openResp.referenceNumber);
5307
5440
  const result = await pollUntil(
5308
5441
  () => client.sessionStatus.getSessionStatus(openResp.referenceNumber),
@@ -6646,6 +6779,17 @@ var FileHwmStore = class {
6646
6779
  // src/workflows/invoice-export-workflow.ts
6647
6780
  init_zip();
6648
6781
  init_polling();
6782
+
6783
+ // src/utils/hash.ts
6784
+ import crypto5 from "crypto";
6785
+ function sha256Base64(data) {
6786
+ return crypto5.createHash("sha256").update(data).digest("base64");
6787
+ }
6788
+ function verifyHash(data, expectedHash) {
6789
+ return sha256Base64(data) === expectedHash;
6790
+ }
6791
+
6792
+ // src/workflows/invoice-export-workflow.ts
6649
6793
  async function doExport(client, filters, options) {
6650
6794
  await client.crypto.init();
6651
6795
  const encData = client.crypto.getEncryptionData();
@@ -6674,6 +6818,7 @@ async function doExport(client, filters, options) {
6674
6818
  url: p.url,
6675
6819
  method: p.method,
6676
6820
  partSize: p.partSize,
6821
+ partHash: p.partHash,
6677
6822
  encryptedPartSize: p.encryptedPartSize,
6678
6823
  encryptedPartHash: p.encryptedPartHash,
6679
6824
  expirationDate: p.expirationDate
@@ -6735,6 +6880,9 @@ async function incrementalExportAndDownload(client, options) {
6735
6880
  throw new Error(`Download failed for part ${part.ordinalNumber}: HTTP ${resp.status}`);
6736
6881
  }
6737
6882
  const encryptedData = new Uint8Array(await resp.arrayBuffer());
6883
+ if (options.verifyHash !== false && !verifyHash(encryptedData, part.encryptedPartHash)) {
6884
+ throw new Error(`Hash mismatch for export part ${part.ordinalNumber}`);
6885
+ }
6738
6886
  const decrypted = client.crypto.decryptAES256(encryptedData, encData.cipherKey, encData.cipherIv);
6739
6887
  decryptedParts.push(decrypted);
6740
6888
  }
@@ -6943,6 +7091,7 @@ var send = defineCommand5({
6943
7091
  stream: { type: "boolean", description: "Use stream-based batch upload (for ZIP files, reduces memory usage)" },
6944
7092
  formCode: { type: "string", description: "Document type: FA2, FA3, PEF3, PEFKOR3, FARR1 (default: FA3)" },
6945
7093
  validate: { type: "boolean", description: "Validate XML before sending" },
7094
+ parallelism: { type: "string", description: "Number of concurrent part uploads (batch mode)" },
6946
7095
  env: { type: "string", description: "Environment (test/demo/prod)" },
6947
7096
  json: { type: "boolean", description: "Output as JSON" },
6948
7097
  verbose: { type: "boolean", description: "Show HTTP request/response details" },
@@ -6956,6 +7105,10 @@ var send = defineCommand5({
6956
7105
  const config = loadConfig();
6957
7106
  const nip = args.nip ?? config.nip;
6958
7107
  const filePath = args.path;
7108
+ const parallelism = args.parallelism ? Number(args.parallelism) : void 0;
7109
+ if (parallelism !== void 0 && (!Number.isInteger(parallelism) || parallelism < 1)) {
7110
+ throw new Error("--parallelism must be a positive integer");
7111
+ }
6959
7112
  const formCodeKey = args.formCode;
6960
7113
  let formCode = DEFAULT_FORM_CODE;
6961
7114
  if (formCodeKey) {
@@ -6988,7 +7141,8 @@ var send = defineCommand5({
6988
7141
  if (!args.json) consola9.start(`Sending batch via stream (${(zipSize / 1e6).toFixed(1)} MB)...`);
6989
7142
  const result = await uploadBatchStream2(client, zipStreamFactory, zipSize, {
6990
7143
  formCode,
6991
- pollOptions: { intervalMs: 3e3 }
7144
+ pollOptions: { intervalMs: 3e3 },
7145
+ parallelism
6992
7146
  });
6993
7147
  if (args.json) {
6994
7148
  outputResult(result, { json: true });
@@ -7052,7 +7206,7 @@ var send = defineCommand5({
7052
7206
  { formCode, batchFile: batchFileInfo, encryption: encryptionData.encryptionInfo }
7053
7207
  );
7054
7208
  saveOnlineSessionRef(openResult.referenceNumber);
7055
- await client.batchSession.sendParts(openResult, parts);
7209
+ await client.batchSession.sendParts(openResult, parts, parallelism);
7056
7210
  await client.batchSession.closeSession(openResult.referenceNumber);
7057
7211
  clearOnlineSessionRef();
7058
7212
  if (args.json) {
@@ -7117,9 +7271,9 @@ var get = defineCommand5({
7117
7271
  return withErrorHandler(async () => {
7118
7272
  const globalOpts = getGlobalOpts4(args);
7119
7273
  const { client } = await requireSession(globalOpts);
7120
- const xml = await client.invoices.getInvoice(args.ksefNumber);
7274
+ const { xml, hash } = await client.invoices.getInvoice(args.ksefNumber);
7121
7275
  if (args.json) {
7122
- outputResult({ ksefNumber: args.ksefNumber, xml }, { json: true });
7276
+ outputResult({ ksefNumber: args.ksefNumber, xml, hash }, { json: true });
7123
7277
  return;
7124
7278
  }
7125
7279
  if (args.o) {
@@ -8036,12 +8190,12 @@ import fs10 from "fs";
8036
8190
  import path7 from "path";
8037
8191
 
8038
8192
  // src/crypto/certificate-service.ts
8039
- import * as crypto6 from "crypto";
8193
+ import * as crypto7 from "crypto";
8040
8194
  import * as x5092 from "@peculiar/x509";
8041
8195
  var CertificateService = class {
8042
8196
  static getSha256Fingerprint(certPem) {
8043
8197
  const der = extractDerFromPem2(certPem);
8044
- return crypto6.createHash("sha256").update(der).digest("hex").toUpperCase();
8198
+ return crypto7.createHash("sha256").update(der).digest("hex").toUpperCase();
8045
8199
  }
8046
8200
  static async generatePersonalCertificate(givenName, surname, serialNumber, commonName, method = "RSA") {
8047
8201
  const nameParts = [];
@@ -8064,7 +8218,7 @@ var CertificateService = class {
8064
8218
  }
8065
8219
  };
8066
8220
  async function generateSelfSigned(subject2, method) {
8067
- x5092.cryptoProvider.set(crypto6.webcrypto);
8221
+ x5092.cryptoProvider.set(crypto7.webcrypto);
8068
8222
  let algorithm;
8069
8223
  let signingAlgorithm;
8070
8224
  if (method === "ECDSA") {
@@ -8079,7 +8233,7 @@ async function generateSelfSigned(subject2, method) {
8079
8233
  };
8080
8234
  signingAlgorithm = algorithm;
8081
8235
  }
8082
- const keys = await crypto6.webcrypto.subtle.generateKey(
8236
+ const keys = await crypto7.webcrypto.subtle.generateKey(
8083
8237
  algorithm,
8084
8238
  true,
8085
8239
  ["sign", "verify"]
@@ -8096,9 +8250,9 @@ async function generateSelfSigned(subject2, method) {
8096
8250
  serialNumber: Date.now().toString(16)
8097
8251
  });
8098
8252
  const certPem = cert.toString("pem");
8099
- const pkcs8 = await crypto6.webcrypto.subtle.exportKey("pkcs8", keys.privateKey);
8253
+ const pkcs8 = await crypto7.webcrypto.subtle.exportKey("pkcs8", keys.privateKey);
8100
8254
  const privateKeyPem = pemEncode2(new Uint8Array(pkcs8), "PRIVATE KEY");
8101
- const fingerprint = crypto6.createHash("sha256").update(Buffer.from(cert.rawData)).digest("hex").toUpperCase();
8255
+ const fingerprint = crypto7.createHash("sha256").update(Buffer.from(cert.rawData)).digest("hex").toUpperCase();
8102
8256
  return { certificatePem: certPem, privateKeyPem, fingerprint };
8103
8257
  }
8104
8258
  function extractDerFromPem2(pem) {