@h-ai/crypto 1.0.0-beta.18 → 1.0.0-beta.19

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.en.md CHANGED
@@ -27,6 +27,8 @@ A cryptography module for asymmetric encryption, hashing, symmetric encryption,
27
27
 
28
28
  ### Quick start
29
29
 
30
+ Concurrent `close()` invalidates an unfinished `init()`, so late initialization cannot reopen the module. Wait for that initialization to settle before initializing again.
31
+
30
32
  ```ts
31
33
  import { crypto } from '@h-ai/crypto'
32
34
 
package/README.ja.md CHANGED
@@ -29,6 +29,8 @@
29
29
 
30
30
  ### クイックスタート
31
31
 
32
+ 並行する `close()` は未完了の `init()` を無効にし、遅い初期化がモジュールを再開しないようにします。その初期化の完了を待ってから再初期化できます。
33
+
32
34
  ```ts
33
35
  import { crypto } from '@h-ai/crypto'
34
36
 
package/README.md CHANGED
@@ -27,6 +27,8 @@
27
27
 
28
28
  ### 快速开始
29
29
 
30
+ 并发调用 `close()` 会使尚未完成的 `init()` 失效,迟到初始化不会重新打开模块;等待该次初始化返回后可再次初始化。
31
+
30
32
  ```ts
31
33
  import { crypto } from '@h-ai/crypto'
32
34
 
package/dist/index.d.ts CHANGED
@@ -2229,4 +2229,5 @@ interface ReldbTransportKeyStore extends TransportKeyStore {
2229
2229
  */
2230
2230
  declare function createReldbTransportKeyStore(options: CreateReldbTransportKeyStoreOptions): ReldbTransportKeyStore;
2231
2231
 
2232
- export { type AsymmetricEncryptOptions, type AsymmetricOperations, type CipherMode, type CreateRedisTransportKeyStoreOptions, type CreateReldbTransportKeyStoreOptions, type CryptoFunctions, type EncryptWithIVResult, type EncryptedPayload, type EncryptedRequestPayload, HaiCryptoError, type HashOperations, type HashOptions, type KeyExchangeRequest, type KeyExchangeResponse, type KeyPair, type PasswordConfig, type PasswordOperations, type ReadTransportBodyOptions, type ReldbTransportKeyStore, type SignOptions, type SymmetricCbcEncryptedPayload, type SymmetricCiphertextEncoding, type SymmetricDecryptInput, type SymmetricEncryptOptions, type SymmetricEncryptedPayload, type SymmetricMode, type SymmetricOperations, TRANSPORT_BODY_LIMITS, TRANSPORT_PLAINTEXT_RANGE, TRANSPORT_PROTOCOL, TRANSPORT_TIME_LIMITS, type TransportBodyLimits, TransportBodyTooLargeError, type TransportClient, type TransportCreateServerOptions, type TransportCryptoServiceLike, type TransportEncryptionManager, type TransportKeyPair, type TransportKeyStore, type TransportMessageContext, type TransportOperations, type TransportRequestContext, type TransportServerKeyRing, TransportTimeError, authenticateTransportRequest, createInMemoryKeyStore, createRedisTransportKeyStore, createReldbTransportKeyStore, createTransportBodyPolicy, createTransportErrorResponse, crypto, isValidSM2PublicKey, parseTransportServerKeyRing, readTransportBody, resolveTransportBodyLimits };
2232
+ export { HaiCryptoError, TRANSPORT_BODY_LIMITS, TRANSPORT_PLAINTEXT_RANGE, TRANSPORT_PROTOCOL, TRANSPORT_TIME_LIMITS, TransportBodyTooLargeError, TransportTimeError, authenticateTransportRequest, createInMemoryKeyStore, createRedisTransportKeyStore, createReldbTransportKeyStore, createTransportBodyPolicy, createTransportErrorResponse, crypto, isValidSM2PublicKey, parseTransportServerKeyRing, readTransportBody, resolveTransportBodyLimits };
2233
+ export type { AsymmetricEncryptOptions, AsymmetricOperations, CipherMode, CreateRedisTransportKeyStoreOptions, CreateReldbTransportKeyStoreOptions, CryptoFunctions, EncryptWithIVResult, EncryptedPayload, EncryptedRequestPayload, HashOperations, HashOptions, KeyExchangeRequest, KeyExchangeResponse, KeyPair, PasswordConfig, PasswordOperations, ReadTransportBodyOptions, ReldbTransportKeyStore, SignOptions, SymmetricCbcEncryptedPayload, SymmetricCiphertextEncoding, SymmetricDecryptInput, SymmetricEncryptOptions, SymmetricEncryptedPayload, SymmetricMode, SymmetricOperations, TransportBodyLimits, TransportClient, TransportCreateServerOptions, TransportCryptoServiceLike, TransportEncryptionManager, TransportKeyPair, TransportKeyStore, TransportMessageContext, TransportOperations, TransportRequestContext, TransportServerKeyRing };
package/dist/index.js CHANGED
@@ -385,7 +385,11 @@ function createSM2() {
385
385
  } catch (error) {
386
386
  return err(
387
387
  HaiCryptoError.KEY_GENERATION_FAILED,
388
- cryptoM("crypto_sm2KeyPairGenerateFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
388
+ cryptoM("crypto_sm2KeyPairGenerateFailed", {
389
+ params: {
390
+ error: error instanceof Error ? error.message : String(error)
391
+ }
392
+ }),
389
393
  error
390
394
  );
391
395
  }
@@ -424,7 +428,11 @@ function createSM2() {
424
428
  } catch (error) {
425
429
  return err(
426
430
  HaiCryptoError.ENCRYPTION_FAILED,
427
- cryptoM("crypto_sm2EncryptFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
431
+ cryptoM("crypto_sm2EncryptFailed", {
432
+ params: {
433
+ error: error instanceof Error ? error.message : String(error)
434
+ }
435
+ }),
428
436
  error
429
437
  );
430
438
  }
@@ -463,7 +471,11 @@ function createSM2() {
463
471
  } catch (error) {
464
472
  return err(
465
473
  HaiCryptoError.DECRYPTION_FAILED,
466
- cryptoM("crypto_sm2DecryptFailedWithError", { params: { error: error instanceof Error ? error.message : String(error) } }),
474
+ cryptoM("crypto_sm2DecryptFailedWithError", {
475
+ params: {
476
+ error: error instanceof Error ? error.message : String(error)
477
+ }
478
+ }),
467
479
  error
468
480
  );
469
481
  }
@@ -498,7 +510,11 @@ function createSM2() {
498
510
  } catch (error) {
499
511
  return err(
500
512
  HaiCryptoError.SIGN_FAILED,
501
- cryptoM("crypto_sm2SignFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
513
+ cryptoM("crypto_sm2SignFailed", {
514
+ params: {
515
+ error: error instanceof Error ? error.message : String(error)
516
+ }
517
+ }),
502
518
  error
503
519
  );
504
520
  }
@@ -529,7 +545,11 @@ function createSM2() {
529
545
  } catch (error) {
530
546
  return err(
531
547
  HaiCryptoError.VERIFY_FAILED,
532
- cryptoM("crypto_sm2VerifyFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
548
+ cryptoM("crypto_sm2VerifyFailed", {
549
+ params: {
550
+ error: error instanceof Error ? error.message : String(error)
551
+ }
552
+ }),
533
553
  error
534
554
  );
535
555
  }
@@ -595,7 +615,11 @@ function createSM3() {
595
615
  } catch (error) {
596
616
  return err(
597
617
  HaiCryptoError.HASH_FAILED,
598
- cryptoM("crypto_sm3HashFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
618
+ cryptoM("crypto_sm3HashFailed", {
619
+ params: {
620
+ error: error instanceof Error ? error.message : String(error)
621
+ }
622
+ }),
599
623
  error
600
624
  );
601
625
  }
@@ -634,7 +658,11 @@ function createSM3() {
634
658
  } catch (error) {
635
659
  return err(
636
660
  HaiCryptoError.HMAC_FAILED,
637
- cryptoM("crypto_sm3HmacFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
661
+ cryptoM("crypto_sm3HmacFailed", {
662
+ params: {
663
+ error: error instanceof Error ? error.message : String(error)
664
+ }
665
+ }),
638
666
  error
639
667
  );
640
668
  }
@@ -655,7 +683,11 @@ function createSM3() {
655
683
  } catch (error) {
656
684
  return err(
657
685
  HaiCryptoError.HASH_FAILED,
658
- cryptoM("crypto_sm3VerifyFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
686
+ cryptoM("crypto_sm3VerifyFailed", {
687
+ params: {
688
+ error: error instanceof Error ? error.message : String(error)
689
+ }
690
+ }),
659
691
  error
660
692
  );
661
693
  }
@@ -743,7 +775,11 @@ function createSM4() {
743
775
  } catch (error) {
744
776
  return err(
745
777
  HaiCryptoError.ENCRYPTION_FAILED,
746
- cryptoM("crypto_sm4EncryptFailed", { params: { error: error instanceof Error ? error.message : String(error) } }),
778
+ cryptoM("crypto_sm4EncryptFailed", {
779
+ params: {
780
+ error: error instanceof Error ? error.message : String(error)
781
+ }
782
+ }),
747
783
  error
748
784
  );
749
785
  }
@@ -791,7 +827,11 @@ function createSM4() {
791
827
  } catch (error) {
792
828
  return err(
793
829
  HaiCryptoError.DECRYPTION_FAILED,
794
- cryptoM("crypto_sm4DecryptFailedWithError", { params: { error: error instanceof Error ? error.message : String(error) } }),
830
+ cryptoM("crypto_sm4DecryptFailedWithError", {
831
+ params: {
832
+ error: error instanceof Error ? error.message : String(error)
833
+ }
834
+ }),
795
835
  error
796
836
  );
797
837
  }
@@ -827,7 +867,12 @@ function createSM4() {
827
867
  * @returns 成功时返回明文;失败时同 decrypt
828
868
  */
829
869
  decryptWithIV(ciphertext, key, iv) {
830
- return this.decrypt({ mode: "cbc", ciphertext, iv, encoding: "hex" }, key);
870
+ return this.decrypt({
871
+ mode: "cbc",
872
+ ciphertext,
873
+ iv,
874
+ encoding: "hex"
875
+ }, key);
831
876
  },
832
877
  /** 校验密钥格式是否合法(32 字符十六进制) */
833
878
  isValidKey(key) {
@@ -873,8 +918,11 @@ function resolveTransportBodyLimits(maxPlaintextBytes, options = {}) {
873
918
  maxPlaintextBytes = required ?? TRANSPORT_BODY_LIMITS.plaintextBytes;
874
919
  if (!Number.isSafeInteger(maxPlaintextBytes) || maxPlaintextBytes < TRANSPORT_PLAINTEXT_RANGE.min || maxPlaintextBytes > TRANSPORT_PLAINTEXT_RANGE.max)
875
920
  throw new RangeError(cryptoM("crypto_transportBodyLimitInvalid"));
876
- if (required !== void 0 && maxPlaintextBytes < required)
877
- throw new RangeError(cryptoM("crypto_transportBodyLimitConflict", { params: { limit: maxPlaintextBytes, required } }));
921
+ if (required !== void 0 && maxPlaintextBytes < required) {
922
+ throw new RangeError(cryptoM("crypto_transportBodyLimitConflict", {
923
+ params: { limit: maxPlaintextBytes, required }
924
+ }));
925
+ }
878
926
  return Object.freeze({ ...TRANSPORT_BODY_LIMITS, plaintextBytes: maxPlaintextBytes, encryptedPayloadBytes: 2 * maxPlaintextBytes + 32768 });
879
927
  }
880
928
  var TransportBodyTooLargeError = class extends RangeError {
@@ -946,7 +994,10 @@ function createTransportBodyPolicy(maxPlaintextBytes, routes = {}) {
946
994
  const entries = Object.entries(routes);
947
995
  if (entries.length > 100 || entries.some(([path]) => !path.startsWith("/") || path.includes("?") || path.includes("#") || path.split("/").some((part) => part.includes("*") && part !== "*")))
948
996
  throw new RangeError(cryptoM("crypto_transportBodyLimitInvalid"));
949
- const configured = entries.map(([path, bytes]) => ({ parts: path.split("/"), limits: resolveTransportBodyLimits(bytes) }));
997
+ const configured = entries.map(([path, bytes]) => ({
998
+ parts: path.split("/"),
999
+ limits: resolveTransportBodyLimits(bytes)
1000
+ }));
950
1001
  const maximum = resolveTransportBodyLimits(Math.max(ordinary.plaintextBytes, ...configured.map((route) => route.limits.plaintextBytes)));
951
1002
  let small = 0;
952
1003
  let large = 0;
@@ -957,22 +1008,26 @@ function createTransportBodyPolicy(maxPlaintextBytes, routes = {}) {
957
1008
  const matching = configured.filter((route) => route.parts.length === parts.length && route.parts.every((part, index) => part === "*" || part === parts[index]));
958
1009
  const limits = matching.length ? matching.reduce((left, right) => left.limits.plaintextBytes < right.limits.plaintextBytes ? left : right).limits : ordinary;
959
1010
  const heavy = matching.length > 0 && limits.plaintextBytes > TRANSPORT_BODY_LIMITS.plaintextBytes;
960
- if (heavy ? large >= 2 : small >= 16)
1011
+ if (heavy ? large >= 2 : small >= 16) {
961
1012
  return null;
1013
+ }
962
1014
  if (heavy)
963
1015
  large++;
964
1016
  else
965
1017
  small++;
966
1018
  let released = false;
967
- return { limits, release() {
968
- if (released)
969
- return;
970
- released = true;
971
- if (heavy)
972
- large--;
973
- else
974
- small--;
975
- } };
1019
+ return {
1020
+ limits,
1021
+ release() {
1022
+ if (released)
1023
+ return;
1024
+ released = true;
1025
+ if (heavy)
1026
+ large--;
1027
+ else
1028
+ small--;
1029
+ }
1030
+ };
976
1031
  }
977
1032
  };
978
1033
  }
@@ -1045,7 +1100,14 @@ function sealTransportPayload(service, plaintext, context, direction, status, re
1045
1100
  const wrapped = service.asymmetric.encrypt(JSON.stringify([encryptionKey, authenticationKey]), recipientPublicKey);
1046
1101
  if (!encrypted.success || !wrapped.success)
1047
1102
  return transportAuthenticationFailure();
1048
- const payload = { context: { ...context }, direction, status, encryptedKey: wrapped.data, ciphertext: encrypted.data.ciphertext, iv: encrypted.data.iv };
1103
+ const payload = {
1104
+ context: { ...context },
1105
+ direction,
1106
+ status,
1107
+ encryptedKey: wrapped.data,
1108
+ ciphertext: encrypted.data.ciphertext,
1109
+ iv: encrypted.data.iv
1110
+ };
1049
1111
  const text = authenticatedText(payload);
1050
1112
  const tag = service.hash.hmac(text, authenticationKey);
1051
1113
  if (!tag.success)
@@ -1103,7 +1165,11 @@ function sameTransportContext(a, b) {
1103
1165
  var TransportTimeError = class extends Error {
1104
1166
  constructor(context, serverTime) {
1105
1167
  const validTime = typeof serverTime === "number" && Number.isSafeInteger(serverTime) && serverTime >= 0 && serverTime <= 864e13 ? serverTime : void 0;
1106
- const message = validTime === void 0 ? cryptoM("crypto_transportTimeInvalid") : cryptoM("crypto_transportTimeInvalidWithServerTime", { params: { serverTime: new Date(validTime).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, " UTC") } });
1168
+ const message = validTime === void 0 ? cryptoM("crypto_transportTimeInvalid") : cryptoM("crypto_transportTimeInvalidWithServerTime", {
1169
+ params: {
1170
+ serverTime: new Date(validTime).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, " UTC")
1171
+ }
1172
+ });
1107
1173
  super(message);
1108
1174
  this.context = context;
1109
1175
  this.name = "TransportTimeError";
@@ -1116,14 +1182,23 @@ var TransportTimeError = class extends Error {
1116
1182
  async function createTransportErrorResponse(error, authenticated) {
1117
1183
  const isTimeError = error instanceof TransportTimeError;
1118
1184
  const status = isTimeError ? 400 : error.direction === "request" ? 413 : 500;
1119
- const publicError = { code: error.code, message: isTimeError ? cryptoM("crypto_transportTimeInvalid") : error.message, httpStatus: status, details: isTimeError ? void 0 : {
1120
- direction: error.direction,
1121
- stage: error.stage,
1122
- limitBytes: error.limitBytes,
1123
- actualBytes: error.actualBytes
1124
- } };
1185
+ const publicError = {
1186
+ code: error.code,
1187
+ message: isTimeError ? cryptoM("crypto_transportTimeInvalid") : error.message,
1188
+ httpStatus: status,
1189
+ details: isTimeError ? void 0 : {
1190
+ direction: error.direction,
1191
+ stage: error.stage,
1192
+ limitBytes: error.limitBytes,
1193
+ actualBytes: error.actualBytes
1194
+ }
1195
+ };
1125
1196
  if (authenticated) {
1126
- const encryptedError = isTimeError && error.serverTime !== void 0 ? { ...publicError, message: error.message, details: { serverTime: error.serverTime } } : publicError;
1197
+ const encryptedError = isTimeError && error.serverTime !== void 0 ? {
1198
+ ...publicError,
1199
+ message: error.message,
1200
+ details: { serverTime: error.serverTime }
1201
+ } : publicError;
1127
1202
  const body = JSON.stringify({ success: false, error: encryptedError });
1128
1203
  const encrypted = await authenticated.manager.encryptResponse(authenticated.context, body, status);
1129
1204
  if (encrypted.success) {
@@ -1135,7 +1210,10 @@ async function createTransportErrorResponse(error, authenticated) {
1135
1210
  return Response.json(encrypted.data, { status, headers });
1136
1211
  }
1137
1212
  }
1138
- return new Response(JSON.stringify({ success: false, error: publicError }), { status, headers: { "Content-Type": "application/json; charset=utf-8" } });
1213
+ return new Response(JSON.stringify({ success: false, error: publicError }), {
1214
+ status,
1215
+ headers: { "Content-Type": "application/json; charset=utf-8" }
1216
+ });
1139
1217
  }
1140
1218
 
1141
1219
  // src/transport/crypto-transport-client.ts
@@ -1175,7 +1253,9 @@ function createTransportClient(options) {
1175
1253
  if (!response.ok) {
1176
1254
  void response.body?.cancel().catch(() => {
1177
1255
  });
1178
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeHttpFailed", { params: { status: response.status } }));
1256
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeHttpFailed", {
1257
+ params: { status: response.status }
1258
+ }));
1179
1259
  }
1180
1260
  let body;
1181
1261
  try {
@@ -1338,7 +1418,12 @@ function createTransportClient(options) {
1338
1418
  }
1339
1419
  if (envelope && new TextEncoder().encode(envelope).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)
1340
1420
  throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(envelope).byteLength, { direction: "response", stage: "header" });
1341
- payload = JSON.parse(envelope ?? await readTransportBody(response.body, { maxBytes: bodyLimits.encryptedPayloadBytes, direction: "response", stage: "encrypted", signal }));
1421
+ payload = JSON.parse(envelope ?? await readTransportBody(response.body, {
1422
+ maxBytes: bodyLimits.encryptedPayloadBytes,
1423
+ direction: "response",
1424
+ stage: "encrypted",
1425
+ signal
1426
+ }));
1342
1427
  } catch (error) {
1343
1428
  if (error instanceof TransportBodyTooLargeError)
1344
1429
  throw error;
@@ -1516,7 +1601,10 @@ function createTransportEncryption(cryptoService, options) {
1516
1601
  try {
1517
1602
  if (!isValidEncryptedPayload(payload, bodyLimits) || payload.direction !== "request" || payload.status !== 0)
1518
1603
  return transportAuthenticationFailure();
1519
- const authenticated = { ...payload, context: { ...payload.context } };
1604
+ const authenticated = {
1605
+ ...payload,
1606
+ context: { ...payload.context }
1607
+ };
1520
1608
  const c = authenticated.context;
1521
1609
  const pathHash = hashTransportPath(cryptoService, expected.path);
1522
1610
  if (!pathHash.success || c.clientId !== expected.clientId || c.method !== expected.method || c.pathHash !== pathHash.data) {
@@ -1559,6 +1647,7 @@ function createTransportEncryption(cryptoService, options) {
1559
1647
  var logger = core.logger.child({ module: "crypto", scope: "main" });
1560
1648
  var initialized = false;
1561
1649
  var initInProgress = false;
1650
+ var lifecycleGeneration = 0;
1562
1651
  var currentAsymmetric = null;
1563
1652
  var currentHash = null;
1564
1653
  var currentSymmetric = null;
@@ -1576,7 +1665,10 @@ function getCrypto() {
1576
1665
  }
1577
1666
  var transportOperations = {
1578
1667
  createServer: (options) => getCrypto().isInitialized ? createTransportEncryption(getCrypto(), options) : notInitialized.result(),
1579
- createClient: (options) => createTransportClient({ crypto: getCrypto(), ...options }),
1668
+ createClient: (options) => createTransportClient({
1669
+ crypto: getCrypto(),
1670
+ ...options
1671
+ }),
1580
1672
  protocol: TRANSPORT_PROTOCOL
1581
1673
  };
1582
1674
  var crypto2 = {
@@ -1593,15 +1685,24 @@ var crypto2 = {
1593
1685
  logger.warn("Crypto init already in progress, skipping concurrent call");
1594
1686
  return err(
1595
1687
  HaiCryptoError.INIT_FAILED,
1596
- cryptoM("crypto_initFailed", { params: { error: "Concurrent initialization detected" } })
1688
+ cryptoM("crypto_initFailed", {
1689
+ params: { error: "Concurrent initialization detected" }
1690
+ })
1597
1691
  );
1598
1692
  }
1599
1693
  initInProgress = true;
1694
+ const generation = ++lifecycleGeneration;
1600
1695
  try {
1601
1696
  await Promise.resolve();
1697
+ if (generation !== lifecycleGeneration)
1698
+ return notInitialized.result();
1602
1699
  if (initialized) {
1603
1700
  logger.warn("Crypto module is already initialized, reinitializing");
1604
- await crypto2.close();
1701
+ currentAsymmetric = null;
1702
+ currentHash = null;
1703
+ currentSymmetric = null;
1704
+ currentPassword = null;
1705
+ initialized = false;
1605
1706
  }
1606
1707
  logger.info("Initializing crypto module");
1607
1708
  currentAsymmetric = createSM2();
@@ -1621,7 +1722,9 @@ var crypto2 = {
1621
1722
  return err(
1622
1723
  HaiCryptoError.INIT_FAILED,
1623
1724
  cryptoM("crypto_initFailed", {
1624
- params: { error: error instanceof Error ? error.message : String(error) }
1725
+ params: {
1726
+ error: error instanceof Error ? error.message : String(error)
1727
+ }
1625
1728
  }),
1626
1729
  error
1627
1730
  );
@@ -1661,6 +1764,7 @@ var crypto2 = {
1661
1764
  * 关闭后访问 asymmetric/hash/symmetric/password 会返回 NOT_INITIALIZED 错误。
1662
1765
  */
1663
1766
  async close() {
1767
+ lifecycleGeneration++;
1664
1768
  if (!initialized) {
1665
1769
  logger.info("Crypto module already closed, skipping");
1666
1770
  return;
@@ -1954,7 +2058,10 @@ function createReldbTransportKeyStore(options) {
1954
2058
  }
1955
2059
  async function pruneRows(tx) {
1956
2060
  let removed = 0;
1957
- for (const [table, id, expiry] of [[TRANSPORT_KEY_TABLE, "client_id", "expires_at_ms"], [TRANSPORT_REQUEST_TABLE, "request_key", "expires_at"]]) {
2061
+ for (const [table, id, expiry] of [
2062
+ [TRANSPORT_KEY_TABLE, "client_id", "expires_at_ms"],
2063
+ [TRANSPORT_REQUEST_TABLE, "request_key", "expires_at"]
2064
+ ]) {
1958
2065
  removed += unwrapResult2("tx.execute", await tx.execute(
1959
2066
  `DELETE FROM ${table} WHERE ${expiry} <= ${nowSql()} AND ${id} IN (SELECT ${id} FROM (SELECT ${id} FROM ${table} WHERE ${expiry} <= ${nowSql()} LIMIT ${PRUNE_BATCH_SIZE}) AS expired)`
1960
2067
  )).changes;
@@ -2009,7 +2116,10 @@ function createReldbTransportKeyStore(options) {
2009
2116
  const insertSql = options.reldb.config?.type === "mysql" ? `INSERT IGNORE INTO ${TRANSPORT_REQUEST_TABLE} (request_key, expires_at) VALUES (?, ?)` : `INSERT INTO ${TRANSPORT_REQUEST_TABLE} (request_key, expires_at) VALUES (?, ?) ON CONFLICT (request_key) DO NOTHING`;
2010
2117
  const inserted = unwrapResult2("reldb.sql.execute", await options.reldb.sql.execute(
2011
2118
  insertSql,
2012
- [JSON.stringify([clientId, requestId]), expiresAt]
2119
+ [
2120
+ JSON.stringify([clientId, requestId]),
2121
+ expiresAt
2122
+ ]
2013
2123
  ));
2014
2124
  return inserted.changes === 1;
2015
2125
  },