@frontmcp/plugin-dashboard 1.9.1 → 1.9.3

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/index.js CHANGED
@@ -103,22 +103,22 @@ var require_node = __commonJS({
103
103
  mod
104
104
  ));
105
105
  var __toCommonJS2 = (mod) => __copyProps2(__defProp3({}, "__esModule", { value: true }), mod);
106
- var node_exports2 = {};
107
- __export3(node_exports2, {
108
- createSignedJwt: () => createSignedJwt2,
109
- cryptoProvider: () => nodeCrypto2,
110
- generateRsaKeyPair: () => generateRsaKeyPair2,
106
+ var node_exports = {};
107
+ __export3(node_exports, {
108
+ createSignedJwt: () => createSignedJwt,
109
+ cryptoProvider: () => nodeCrypto,
110
+ generateRsaKeyPair: () => generateRsaKeyPair3,
111
111
  isRsaPssAlg: () => isRsaPssAlg2,
112
- jwtAlgToNodeAlg: () => jwtAlgToNodeAlg2,
113
- nodeCrypto: () => nodeCrypto2,
114
- pemToPublicJwk: () => pemToPublicJwk2,
115
- rsaSign: () => rsaSign2,
116
- rsaSignBase64Url: () => rsaSignBase64Url2,
117
- rsaVerify: () => rsaVerify2,
118
- rsaVerifySync: () => rsaVerifySync2
112
+ jwtAlgToNodeAlg: () => jwtAlgToNodeAlg,
113
+ nodeCrypto: () => nodeCrypto,
114
+ pemToPublicJwk: () => pemToPublicJwk3,
115
+ rsaSign: () => rsaSign,
116
+ rsaSignBase64Url: () => rsaSignBase64Url3,
117
+ rsaVerify: () => rsaVerify3,
118
+ rsaVerifySync: () => rsaVerifySync3
119
119
  });
120
- module2.exports = __toCommonJS2(node_exports2);
121
- var import_node_crypto2 = __toESM2(require("node:crypto"));
120
+ module2.exports = __toCommonJS2(node_exports);
121
+ var import_node_crypto = __toESM2(require("node:crypto"));
122
122
  var JWT_ALG_TO_NODE_DIGEST2 = {
123
123
  RS256: "RSA-SHA256",
124
124
  RS384: "RSA-SHA384",
@@ -128,7 +128,7 @@ var require_node = __commonJS({
128
128
  PS384: "RSA-SHA384",
129
129
  PS512: "RSA-SHA512"
130
130
  };
131
- function jwtAlgToNodeAlg2(jwtAlg) {
131
+ function jwtAlgToNodeAlg(jwtAlg) {
132
132
  const nodeAlg = JWT_ALG_TO_NODE_DIGEST2[jwtAlg];
133
133
  if (!nodeAlg) {
134
134
  throw new Error(`Unsupported JWT algorithm: ${jwtAlg}`);
@@ -138,70 +138,70 @@ var require_node = __commonJS({
138
138
  function isRsaPssAlg2(jwtAlg) {
139
139
  return jwtAlg.startsWith("PS");
140
140
  }
141
- function toUint8Array2(buf) {
141
+ function toUint8Array(buf) {
142
142
  return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
143
143
  }
144
- function toBuffer2(data) {
144
+ function toBuffer(data) {
145
145
  if (typeof data === "string") {
146
146
  return Buffer.from(data, "utf8");
147
147
  }
148
148
  return Buffer.from(data);
149
149
  }
150
- var nodeCrypto2 = {
150
+ var nodeCrypto = {
151
151
  randomUUID() {
152
- return import_node_crypto2.default.randomUUID();
152
+ return import_node_crypto.default.randomUUID();
153
153
  },
154
154
  randomBytes(length) {
155
- return toUint8Array2(import_node_crypto2.default.randomBytes(length));
155
+ return toUint8Array(import_node_crypto.default.randomBytes(length));
156
156
  },
157
157
  sha256(data) {
158
- const hash = import_node_crypto2.default.createHash("sha256").update(toBuffer2(data)).digest();
159
- return toUint8Array2(hash);
158
+ const hash = import_node_crypto.default.createHash("sha256").update(toBuffer(data)).digest();
159
+ return toUint8Array(hash);
160
160
  },
161
161
  sha256Hex(data) {
162
- return import_node_crypto2.default.createHash("sha256").update(toBuffer2(data)).digest("hex");
162
+ return import_node_crypto.default.createHash("sha256").update(toBuffer(data)).digest("hex");
163
163
  },
164
164
  hmacSha256(key, data) {
165
- const hmac2 = import_node_crypto2.default.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
166
- return toUint8Array2(hmac2);
165
+ const hmac2 = import_node_crypto.default.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
166
+ return toUint8Array(hmac2);
167
167
  },
168
168
  hkdfSha256(ikm, salt, info, length) {
169
169
  const ikmBuf = Buffer.from(ikm);
170
170
  const saltBuf = salt.length > 0 ? Buffer.from(salt) : Buffer.alloc(32);
171
- const prk = import_node_crypto2.default.createHmac("sha256", saltBuf).update(ikmBuf).digest();
171
+ const prk = import_node_crypto.default.createHmac("sha256", saltBuf).update(ikmBuf).digest();
172
172
  const hashLen = 32;
173
173
  const n = Math.ceil(length / hashLen);
174
174
  const chunks = [];
175
175
  let prev = Buffer.alloc(0);
176
176
  for (let i = 1; i <= n; i++) {
177
- prev = import_node_crypto2.default.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
177
+ prev = import_node_crypto.default.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
178
178
  chunks.push(prev);
179
179
  }
180
- return toUint8Array2(Buffer.concat(chunks).subarray(0, length));
180
+ return toUint8Array(Buffer.concat(chunks).subarray(0, length));
181
181
  },
182
182
  encryptAesGcm(key, plaintext, iv) {
183
- const cipher = import_node_crypto2.default.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
183
+ const cipher = import_node_crypto.default.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
184
184
  const encrypted = Buffer.concat([cipher.update(Buffer.from(plaintext)), cipher.final()]);
185
185
  const tag = cipher.getAuthTag();
186
186
  return {
187
- ciphertext: toUint8Array2(encrypted),
188
- tag: toUint8Array2(tag)
187
+ ciphertext: toUint8Array(encrypted),
188
+ tag: toUint8Array(tag)
189
189
  };
190
190
  },
191
191
  decryptAesGcm(key, ciphertext, iv, tag) {
192
- const decipher = import_node_crypto2.default.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
192
+ const decipher = import_node_crypto.default.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
193
193
  decipher.setAuthTag(Buffer.from(tag));
194
194
  const decrypted = Buffer.concat([decipher.update(Buffer.from(ciphertext)), decipher.final()]);
195
- return toUint8Array2(decrypted);
195
+ return toUint8Array(decrypted);
196
196
  },
197
197
  timingSafeEqual(a, b) {
198
198
  if (a.length !== b.length) return false;
199
- return import_node_crypto2.default.timingSafeEqual(Buffer.from(a), Buffer.from(b));
199
+ return import_node_crypto.default.timingSafeEqual(Buffer.from(a), Buffer.from(b));
200
200
  }
201
201
  };
202
- function generateRsaKeyPair2(modulusLength = 2048, alg = "RS256") {
203
- const kid = `rsa-key-${Date.now()}-${import_node_crypto2.default.randomBytes(8).toString("hex")}`;
204
- const { privateKey, publicKey } = import_node_crypto2.default.generateKeyPairSync("rsa", {
202
+ function generateRsaKeyPair3(modulusLength = 2048, alg = "RS256") {
203
+ const kid = `rsa-key-${Date.now()}-${import_node_crypto.default.randomBytes(8).toString("hex")}`;
204
+ const { privateKey, publicKey } = import_node_crypto.default.generateKeyPairSync("rsa", {
205
205
  modulusLength
206
206
  });
207
207
  const exported = publicKey.export({ format: "jwk" });
@@ -214,66 +214,66 @@ var require_node = __commonJS({
214
214
  };
215
215
  return { privateKey, publicKey, publicJwk };
216
216
  }
217
- function rsaSign2(algorithm, data, privateKey, options) {
217
+ function rsaSign(algorithm, data, privateKey, options) {
218
218
  const signingKey = options ? { key: privateKey, ...options } : privateKey;
219
- return import_node_crypto2.default.sign(algorithm, data, signingKey);
219
+ return import_node_crypto.default.sign(algorithm, data, signingKey);
220
220
  }
221
- function rsaVerify2(jwtAlg, data, publicJwk, signature) {
222
- const publicKey = import_node_crypto2.default.createPublicKey({ key: publicJwk, format: "jwk" });
223
- const nodeAlgorithm = jwtAlgToNodeAlg2(jwtAlg);
221
+ function rsaVerify3(jwtAlg, data, publicJwk, signature) {
222
+ const publicKey = import_node_crypto.default.createPublicKey({ key: publicJwk, format: "jwk" });
223
+ const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
224
224
  const verifyKey = isRsaPssAlg2(jwtAlg) ? {
225
225
  key: publicKey,
226
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
227
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
226
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
227
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
228
228
  } : publicKey;
229
- return import_node_crypto2.default.verify(nodeAlgorithm, data, verifyKey, signature);
229
+ return import_node_crypto.default.verify(nodeAlgorithm, data, verifyKey, signature);
230
230
  }
231
- function rsaSignBase64Url2(jwtAlg, data, privateJwk) {
232
- const privateKey = import_node_crypto2.default.createPrivateKey({ key: privateJwk, format: "jwk" });
233
- const nodeAlgorithm = jwtAlgToNodeAlg2(jwtAlg);
231
+ function rsaSignBase64Url3(jwtAlg, data, privateJwk) {
232
+ const privateKey = import_node_crypto.default.createPrivateKey({ key: privateJwk, format: "jwk" });
233
+ const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
234
234
  const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
235
- const sig = isRsaPssAlg2(jwtAlg) ? rsaSign2(nodeAlgorithm, buf, privateKey, {
236
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
237
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
238
- }) : rsaSign2(nodeAlgorithm, buf, privateKey);
235
+ const sig = isRsaPssAlg2(jwtAlg) ? rsaSign(nodeAlgorithm, buf, privateKey, {
236
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
237
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
238
+ }) : rsaSign(nodeAlgorithm, buf, privateKey);
239
239
  return sig.toString("base64url");
240
240
  }
241
- function rsaVerifySync2(jwtAlg, data, publicJwk, signature) {
241
+ function rsaVerifySync3(jwtAlg, data, publicJwk, signature) {
242
242
  try {
243
- const publicKey = import_node_crypto2.default.createPublicKey({ key: publicJwk, format: "jwk" });
243
+ const publicKey = import_node_crypto.default.createPublicKey({ key: publicJwk, format: "jwk" });
244
244
  const dataBuf = Buffer.isBuffer(data) ? data : Buffer.from(data);
245
245
  const sigBuf = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
246
246
  if (jwtAlg === "EdDSA") {
247
- return import_node_crypto2.default.verify(null, dataBuf, publicKey, sigBuf);
247
+ return import_node_crypto.default.verify(null, dataBuf, publicKey, sigBuf);
248
248
  }
249
- const nodeAlgorithm = jwtAlgToNodeAlg2(jwtAlg);
249
+ const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
250
250
  const verifyKey = isRsaPssAlg2(jwtAlg) ? {
251
251
  key: publicKey,
252
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
253
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
252
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
253
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
254
254
  } : publicKey;
255
- return import_node_crypto2.default.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
255
+ return import_node_crypto.default.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
256
256
  } catch {
257
257
  return false;
258
258
  }
259
259
  }
260
- function pemToPublicJwk2(pem) {
261
- const key = import_node_crypto2.default.createPublicKey({ key: pem, format: "pem" });
260
+ function pemToPublicJwk3(pem) {
261
+ const key = import_node_crypto.default.createPublicKey({ key: pem, format: "pem" });
262
262
  return key.export({ format: "jwk" });
263
263
  }
264
- function createSignedJwt2(payload, privateKey, kid, alg = "RS256") {
264
+ function createSignedJwt(payload, privateKey, kid, alg = "RS256") {
265
265
  const header = { alg, typ: "JWT", kid };
266
266
  const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
267
267
  const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
268
268
  const signatureInput = `${headerB64}.${payloadB64}`;
269
- const nodeAlgorithm = jwtAlgToNodeAlg2(alg);
270
- const signature = rsaSign2(
269
+ const nodeAlgorithm = jwtAlgToNodeAlg(alg);
270
+ const signature = rsaSign(
271
271
  nodeAlgorithm,
272
272
  Buffer.from(signatureInput),
273
273
  privateKey,
274
274
  isRsaPssAlg2(alg) ? {
275
- padding: import_node_crypto2.default.constants.RSA_PKCS1_PSS_PADDING,
276
- saltLength: import_node_crypto2.default.constants.RSA_PSS_SALTLEN_DIGEST
275
+ padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
276
+ saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
277
277
  } : void 0
278
278
  );
279
279
  const signatureB64 = signature.toString("base64url");
@@ -446,13 +446,12 @@ var import_sdk2 = require("@frontmcp/sdk");
446
446
  var import_lazy_zod2 = require("@frontmcp/lazy-zod");
447
447
  var import_lazy_zod3 = require("@frontmcp/lazy-zod");
448
448
  var import_event_emitter = __toESM(require_node_event_emitter(), 1);
449
- var import_node_crypto = __toESM(require("node:crypto"), 1);
450
- var import_sha2 = require("@noble/hashes/sha2.js");
451
- var import_hmac = require("@noble/hashes/hmac.js");
449
+ var import_aes = require("@noble/ciphers/aes.js");
452
450
  var import_hkdf = require("@noble/hashes/hkdf.js");
451
+ var import_hmac = require("@noble/hashes/hmac.js");
452
+ var import_sha2 = require("@noble/hashes/sha2.js");
453
453
  var import_utils = require("@noble/hashes/utils.js");
454
- var import_aes = require("@noble/ciphers/aes.js");
455
- var import_crypto_provider = __toESM(require_node(), 1);
454
+ var platformCrypto = __toESM(require_node(), 1);
456
455
  var import_ast = require("@enclave-vm/ast");
457
456
  var import_meta = {};
458
457
  var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : void 0;
@@ -559,13 +558,6 @@ var init_fs2 = __esm({
559
558
  init_fs();
560
559
  }
561
560
  });
562
- function jwtAlgToNodeAlg(jwtAlg) {
563
- const nodeAlg = JWT_ALG_TO_NODE_DIGEST[jwtAlg];
564
- if (!nodeAlg) {
565
- throw new Error(`Unsupported JWT algorithm: ${jwtAlg}`);
566
- }
567
- return nodeAlg;
568
- }
569
561
  function isRsaPssAlg(jwtAlg) {
570
562
  return jwtAlg.startsWith("PS");
571
563
  }
@@ -2352,176 +2344,18 @@ var init_key_persistence2 = __esm({
2352
2344
  init_factory();
2353
2345
  }
2354
2346
  });
2355
- var node_exports = {};
2356
- __export2(node_exports, {
2357
- createSignedJwt: () => createSignedJwt,
2358
- cryptoProvider: () => nodeCrypto,
2359
- generateRsaKeyPair: () => generateRsaKeyPair,
2360
- isRsaPssAlg: () => isRsaPssAlg,
2361
- jwtAlgToNodeAlg: () => jwtAlgToNodeAlg,
2362
- nodeCrypto: () => nodeCrypto,
2363
- pemToPublicJwk: () => pemToPublicJwk,
2364
- rsaSign: () => rsaSign,
2365
- rsaSignBase64Url: () => rsaSignBase64Url,
2366
- rsaVerify: () => rsaVerify,
2367
- rsaVerifySync: () => rsaVerifySync
2368
- });
2369
- function toUint8Array(buf) {
2370
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
2371
- }
2372
- function toBuffer(data) {
2373
- if (typeof data === "string") {
2374
- return Buffer.from(data, "utf8");
2375
- }
2376
- return Buffer.from(data);
2377
- }
2378
- function generateRsaKeyPair(modulusLength = 2048, alg = "RS256") {
2379
- const kid = `rsa-key-${Date.now()}-${import_node_crypto.default.randomBytes(8).toString("hex")}`;
2380
- const { privateKey, publicKey } = import_node_crypto.default.generateKeyPairSync("rsa", {
2381
- modulusLength
2382
- });
2383
- const exported = publicKey.export({ format: "jwk" });
2384
- const publicJwk = {
2385
- ...exported,
2386
- kid,
2387
- alg,
2388
- use: "sig",
2389
- kty: "RSA"
2390
- };
2391
- return { privateKey, publicKey, publicJwk };
2392
- }
2393
- function rsaSign(algorithm, data, privateKey, options) {
2394
- const signingKey = options ? { key: privateKey, ...options } : privateKey;
2395
- return import_node_crypto.default.sign(algorithm, data, signingKey);
2396
- }
2397
- function rsaVerify(jwtAlg, data, publicJwk, signature) {
2398
- const publicKey = import_node_crypto.default.createPublicKey({ key: publicJwk, format: "jwk" });
2399
- const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
2400
- const verifyKey = isRsaPssAlg(jwtAlg) ? {
2401
- key: publicKey,
2402
- padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
2403
- saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
2404
- } : publicKey;
2405
- return import_node_crypto.default.verify(nodeAlgorithm, data, verifyKey, signature);
2406
- }
2407
- function rsaSignBase64Url(jwtAlg, data, privateJwk) {
2408
- const privateKey = import_node_crypto.default.createPrivateKey({ key: privateJwk, format: "jwk" });
2409
- const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
2410
- const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
2411
- const sig = isRsaPssAlg(jwtAlg) ? rsaSign(nodeAlgorithm, buf, privateKey, {
2412
- padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
2413
- saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
2414
- }) : rsaSign(nodeAlgorithm, buf, privateKey);
2415
- return sig.toString("base64url");
2416
- }
2417
- function rsaVerifySync(jwtAlg, data, publicJwk, signature) {
2418
- try {
2419
- const publicKey = import_node_crypto.default.createPublicKey({ key: publicJwk, format: "jwk" });
2420
- const dataBuf = Buffer.isBuffer(data) ? data : Buffer.from(data);
2421
- const sigBuf = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
2422
- if (jwtAlg === "EdDSA") {
2423
- return import_node_crypto.default.verify(null, dataBuf, publicKey, sigBuf);
2424
- }
2425
- const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
2426
- const verifyKey = isRsaPssAlg(jwtAlg) ? {
2427
- key: publicKey,
2428
- padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
2429
- saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
2430
- } : publicKey;
2431
- return import_node_crypto.default.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
2432
- } catch {
2433
- return false;
2434
- }
2435
- }
2436
- function pemToPublicJwk(pem) {
2437
- const key = import_node_crypto.default.createPublicKey({ key: pem, format: "pem" });
2438
- return key.export({ format: "jwk" });
2439
- }
2440
- function createSignedJwt(payload, privateKey, kid, alg = "RS256") {
2441
- const header = { alg, typ: "JWT", kid };
2442
- const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
2443
- const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
2444
- const signatureInput = `${headerB64}.${payloadB64}`;
2445
- const nodeAlgorithm = jwtAlgToNodeAlg(alg);
2446
- const signature = rsaSign(
2447
- nodeAlgorithm,
2448
- Buffer.from(signatureInput),
2449
- privateKey,
2450
- isRsaPssAlg(alg) ? {
2451
- padding: import_node_crypto.default.constants.RSA_PKCS1_PSS_PADDING,
2452
- saltLength: import_node_crypto.default.constants.RSA_PSS_SALTLEN_DIGEST
2453
- } : void 0
2454
- );
2455
- const signatureB64 = signature.toString("base64url");
2456
- return `${headerB64}.${payloadB64}.${signatureB64}`;
2457
- }
2458
- var nodeCrypto;
2459
- var init_node = __esm({
2460
- "libs/utils/src/crypto/node.ts"() {
2461
- "use strict";
2462
- init_jwt_alg();
2463
- init_jwt_alg();
2464
- nodeCrypto = {
2465
- randomUUID() {
2466
- return import_node_crypto.default.randomUUID();
2467
- },
2468
- randomBytes(length) {
2469
- return toUint8Array(import_node_crypto.default.randomBytes(length));
2470
- },
2471
- sha256(data) {
2472
- const hash = import_node_crypto.default.createHash("sha256").update(toBuffer(data)).digest();
2473
- return toUint8Array(hash);
2474
- },
2475
- sha256Hex(data) {
2476
- return import_node_crypto.default.createHash("sha256").update(toBuffer(data)).digest("hex");
2477
- },
2478
- hmacSha256(key, data) {
2479
- const hmac2 = import_node_crypto.default.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
2480
- return toUint8Array(hmac2);
2481
- },
2482
- hkdfSha256(ikm, salt, info, length) {
2483
- const ikmBuf = Buffer.from(ikm);
2484
- const saltBuf = salt.length > 0 ? Buffer.from(salt) : Buffer.alloc(32);
2485
- const prk = import_node_crypto.default.createHmac("sha256", saltBuf).update(ikmBuf).digest();
2486
- const hashLen = 32;
2487
- const n = Math.ceil(length / hashLen);
2488
- const chunks = [];
2489
- let prev = Buffer.alloc(0);
2490
- for (let i = 1; i <= n; i++) {
2491
- prev = import_node_crypto.default.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
2492
- chunks.push(prev);
2493
- }
2494
- return toUint8Array(Buffer.concat(chunks).subarray(0, length));
2495
- },
2496
- encryptAesGcm(key, plaintext, iv) {
2497
- const cipher = import_node_crypto.default.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
2498
- const encrypted = Buffer.concat([cipher.update(Buffer.from(plaintext)), cipher.final()]);
2499
- const tag = cipher.getAuthTag();
2500
- return {
2501
- ciphertext: toUint8Array(encrypted),
2502
- tag: toUint8Array(tag)
2503
- };
2504
- },
2505
- decryptAesGcm(key, ciphertext, iv, tag) {
2506
- const decipher = import_node_crypto.default.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
2507
- decipher.setAuthTag(Buffer.from(tag));
2508
- const decrypted = Buffer.concat([decipher.update(Buffer.from(ciphertext)), decipher.final()]);
2509
- return toUint8Array(decrypted);
2510
- },
2511
- timingSafeEqual(a, b) {
2512
- if (a.length !== b.length) return false;
2513
- return import_node_crypto.default.timingSafeEqual(Buffer.from(a), Buffer.from(b));
2514
- }
2515
- };
2516
- }
2517
- });
2518
2347
  var browser_exports = {};
2519
2348
  __export2(browser_exports, {
2520
2349
  browserCrypto: () => browserCrypto,
2521
2350
  cryptoProvider: () => browserCrypto,
2351
+ generateRsaKeyPair: () => generateRsaKeyPair2,
2522
2352
  isRsaPssAlg: () => isRsaPssAlg,
2523
2353
  jwtAlgToWebCryptoAlg: () => jwtAlgToWebCryptoAlg,
2524
- rsaVerifyBrowser: () => rsaVerifyBrowser
2354
+ pemToPublicJwk: () => pemToPublicJwk2,
2355
+ rsaSignBase64Url: () => rsaSignBase64Url2,
2356
+ rsaVerify: () => rsaVerify2,
2357
+ rsaVerifyBrowser: () => rsaVerifyBrowser,
2358
+ rsaVerifySync: () => rsaVerifySync2
2525
2359
  });
2526
2360
  function toBytes(data) {
2527
2361
  if (typeof data === "string") {
@@ -2550,6 +2384,24 @@ function constantTimeEqual(a, b) {
2550
2384
  }
2551
2385
  return result === 0;
2552
2386
  }
2387
+ function nodeOnly(name) {
2388
+ throw new Error(`${name} is only available in Node.js runtimes`);
2389
+ }
2390
+ function rsaVerify2() {
2391
+ return nodeOnly("rsaVerify");
2392
+ }
2393
+ function rsaSignBase64Url2() {
2394
+ return nodeOnly("rsaSignBase64Url");
2395
+ }
2396
+ function rsaVerifySync2() {
2397
+ return nodeOnly("rsaVerifySync");
2398
+ }
2399
+ function pemToPublicJwk2() {
2400
+ return nodeOnly("pemToPublicJwk");
2401
+ }
2402
+ function generateRsaKeyPair2() {
2403
+ return nodeOnly("generateRsaKeyPair");
2404
+ }
2553
2405
  async function rsaVerifyBrowser(jwtAlg, data, publicJwk, signature) {
2554
2406
  if (typeof globalThis.crypto?.subtle === "undefined") {
2555
2407
  throw new Error("WebCrypto API (crypto.subtle) is not available in this environment");
@@ -2628,7 +2480,7 @@ var init_browser = __esm({
2628
2480
  }
2629
2481
  });
2630
2482
  function getCrypto() {
2631
- return import_crypto_provider.cryptoProvider;
2483
+ return platformCrypto.cryptoProvider;
2632
2484
  }
2633
2485
  function randomBytes(length) {
2634
2486
  if (!Number.isInteger(length) || length <= 0) {
@@ -2748,6 +2600,71 @@ var init_redis_error_listener = __esm({
2748
2600
  DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS = 3e4;
2749
2601
  }
2750
2602
  });
2603
+ function decodeOrRaw(encoded) {
2604
+ try {
2605
+ return decodeURIComponent(encoded);
2606
+ } catch {
2607
+ return encoded;
2608
+ }
2609
+ }
2610
+ function integerOrUndefined(text) {
2611
+ const value = Number.parseInt(text ?? "", 10);
2612
+ return Number.isNaN(value) ? void 0 : value;
2613
+ }
2614
+ function readRedisUrl(rawUrl) {
2615
+ let url;
2616
+ try {
2617
+ url = new URL(rawUrl);
2618
+ } catch {
2619
+ return void 0;
2620
+ }
2621
+ if (url.protocol !== "redis:" && url.protocol !== "rediss:") return void 0;
2622
+ const query = Object.fromEntries(url.searchParams);
2623
+ const { host, port, username, password, db, ...otherOptions } = query;
2624
+ const queryOptions = {};
2625
+ for (const [name, value = ""] of Object.entries(otherOptions)) {
2626
+ queryOptions[name] = name === "family" ? integerOrUndefined(value) ?? value : value;
2627
+ }
2628
+ return {
2629
+ host: url.hostname.replace(/^\[(.*)\]$/, "$1") || host,
2630
+ port: integerOrUndefined(url.port || port),
2631
+ username: decodeOrRaw(url.username) || username || void 0,
2632
+ password: decodeOrRaw(url.password) || password || void 0,
2633
+ db: integerOrUndefined(url.pathname.replace(/^\/+/, "") || db),
2634
+ tls: url.protocol === "rediss:",
2635
+ queryOptions
2636
+ };
2637
+ }
2638
+ function mergeRedisUrlFields(rawUrl, fields) {
2639
+ const connection = readRedisUrl(rawUrl);
2640
+ if (!connection) return void 0;
2641
+ const fillIns = {};
2642
+ const conflicts = [];
2643
+ if (fields.host !== void 0 && fields.host !== connection.host) conflicts.push("host");
2644
+ if (fields.port !== void 0) {
2645
+ if (connection.port === void 0) fillIns.port = fields.port;
2646
+ else if (fields.port !== connection.port) conflicts.push("port");
2647
+ }
2648
+ if (fields.password !== void 0) {
2649
+ if (connection.password === void 0) fillIns.password = fields.password;
2650
+ else if (fields.password !== connection.password) conflicts.push("password");
2651
+ }
2652
+ if (fields.db !== void 0) {
2653
+ if (connection.db === void 0) fillIns.db = fields.db;
2654
+ else if (fields.db !== connection.db) conflicts.push("db");
2655
+ }
2656
+ if (fields.tls === true && !connection.tls) fillIns.tls = true;
2657
+ if (fields.tls === false && connection.tls) conflicts.push("tls");
2658
+ return { connection, fillIns, conflicts };
2659
+ }
2660
+ function describeRedisUrlConflicts(conflicts) {
2661
+ return `redis ${conflicts.join(", ")} contradict${conflicts.length === 1 ? "s" : ""} redis.url. Fields beside a url only fill in what the URL leaves out (port, password, db, tls); put the value in the URL or drop the field.`;
2662
+ }
2663
+ var init_redis_url = __esm({
2664
+ "libs/utils/src/storage/redis-url.ts"() {
2665
+ "use strict";
2666
+ }
2667
+ });
2751
2668
  var init_utils = __esm({
2752
2669
  "libs/utils/src/storage/utils/index.ts"() {
2753
2670
  "use strict";
@@ -2782,17 +2699,49 @@ function getRedisClass() {
2782
2699
  });
2783
2700
  }
2784
2701
  }
2702
+ function resolveUrlOptions(connectionUrl, options) {
2703
+ const { url: configUrl, ...siblingFields } = { url: void 0, ...options.config };
2704
+ if (options.url && configUrl && configUrl !== options.url) {
2705
+ throw new StorageConfigError("redis", "redis.url and redis.config.url name different servers; set one of them.");
2706
+ }
2707
+ return urlConnectionOptions(connectionUrl, siblingFields);
2708
+ }
2709
+ function urlConnectionOptions(url, fields) {
2710
+ const merge = mergeRedisUrlFields(url, fields);
2711
+ if (!merge) return void 0;
2712
+ if (merge.conflicts.length > 0) {
2713
+ throw new StorageConfigError("redis", describeRedisUrlConflicts(merge.conflicts));
2714
+ }
2715
+ const { queryOptions, tls, ...stated } = merge.connection;
2716
+ return { ...queryOptions, ...stated, ...toFillInOptions(merge.fillIns), ...tls ? { tls: {} } : {} };
2717
+ }
2718
+ function toFillInOptions({ port, password, db, tls }) {
2719
+ return {
2720
+ ...port !== void 0 ? { port } : {},
2721
+ ...password !== void 0 ? { password } : {},
2722
+ ...db !== void 0 ? { db } : {},
2723
+ ...tls ? { tls: {} } : {}
2724
+ };
2725
+ }
2785
2726
  function createRedisClient(options) {
2727
+ const urlOptions = options.url ? urlConnectionOptions(options.url, options) : void 0;
2786
2728
  const RedisClass = getRedisClass();
2787
2729
  const baseOptions = { lazyConnect: false, maxRetriesPerRequest: 3 };
2788
- const client = options.url ? new RedisClass(options.url, baseOptions) : new RedisClass({
2789
- ...baseOptions,
2790
- host: options.host ?? "localhost",
2791
- port: options.port ?? 6379,
2792
- password: options.password,
2793
- db: options.db ?? 0,
2794
- tls: options.tls ? {} : void 0
2795
- });
2730
+ let client;
2731
+ if (urlOptions) {
2732
+ client = new RedisClass({ ...baseOptions, ...urlOptions });
2733
+ } else if (options.url) {
2734
+ client = new RedisClass(options.url, baseOptions);
2735
+ } else {
2736
+ client = new RedisClass({
2737
+ ...baseOptions,
2738
+ host: options.host ?? "localhost",
2739
+ port: options.port ?? 6379,
2740
+ password: options.password,
2741
+ db: options.db ?? 0,
2742
+ tls: options.tls ? {} : void 0
2743
+ });
2744
+ }
2796
2745
  attachRedisErrorListener(client, { label: options.label ?? "redis", logger: options.logger });
2797
2746
  return client;
2798
2747
  }
@@ -2802,6 +2751,7 @@ var init_redis = __esm({
2802
2751
  "use strict";
2803
2752
  init_errors();
2804
2753
  init_redis_error_listener();
2754
+ init_redis_url();
2805
2755
  init_utils();
2806
2756
  init_compare_and_delete();
2807
2757
  init_base();
@@ -2815,6 +2765,9 @@ var init_redis = __esm({
2815
2765
  connecting;
2816
2766
  keyPrefix;
2817
2767
  subscriptionHandlers = /* @__PURE__ */ new Map();
2768
+ connectionUrl;
2769
+ /** The connection options of a URL this adapter reads itself; undefined for one only ioredis reads. */
2770
+ urlOptions;
2818
2771
  constructor(options = {}) {
2819
2772
  super();
2820
2773
  const hasClient = options.client !== void 0;
@@ -2836,6 +2789,9 @@ var init_redis = __esm({
2836
2789
  this.options = options;
2837
2790
  this.ownsClient = !hasClient;
2838
2791
  this.keyPrefix = options.keyPrefix ?? "";
2792
+ const configUrl = options.config?.url;
2793
+ this.connectionUrl = options.url ?? (typeof configUrl === "string" ? configUrl : void 0);
2794
+ this.urlOptions = this.connectionUrl ? resolveUrlOptions(this.connectionUrl, options) : void 0;
2839
2795
  }
2840
2796
  // ============================================
2841
2797
  // Connection Lifecycle
@@ -2857,12 +2813,7 @@ var init_redis = __esm({
2857
2813
  if (this.options.client) {
2858
2814
  client = this.options.client;
2859
2815
  } else {
2860
- const RedisClass = getRedisClass();
2861
- if (this.options.url) {
2862
- client = new RedisClass(this.options.url, this.buildRedisOptions());
2863
- } else {
2864
- client = new RedisClass(this.buildRedisOptions());
2865
- }
2816
+ client = this.newClient();
2866
2817
  client.on("error", recordSocketError);
2867
2818
  }
2868
2819
  await client.ping();
@@ -3095,14 +3046,11 @@ var init_redis = __esm({
3095
3046
  * Build Redis options from config.
3096
3047
  */
3097
3048
  buildRedisOptions() {
3098
- if (this.options.url) {
3099
- return {
3100
- lazyConnect: false,
3101
- maxRetriesPerRequest: 3
3102
- };
3049
+ if (this.connectionUrl) {
3050
+ return { lazyConnect: false, maxRetriesPerRequest: 3, ...this.urlOptions };
3103
3051
  }
3104
3052
  const config = this.options.config;
3105
- if (!config) {
3053
+ if (!config || typeof config.url === "string" || config.host === void 0) {
3106
3054
  throw new StorageConfigError("redis", "Redis config is required when URL is not provided");
3107
3055
  }
3108
3056
  return {
@@ -3115,16 +3063,23 @@ var init_redis = __esm({
3115
3063
  maxRetriesPerRequest: 3
3116
3064
  };
3117
3065
  }
3066
+ /**
3067
+ * Create a client this adapter owns. A URL only ioredis reads goes to it as is.
3068
+ */
3069
+ newClient() {
3070
+ const RedisClass = getRedisClass();
3071
+ if (this.connectionUrl && !this.urlOptions) {
3072
+ return new RedisClass(this.connectionUrl, this.buildRedisOptions());
3073
+ }
3074
+ return new RedisClass(this.buildRedisOptions());
3075
+ }
3118
3076
  /**
3119
3077
  * Create subscriber connection.
3120
3078
  */
3121
3079
  async createSubscriber() {
3122
- const RedisClass = getRedisClass();
3123
3080
  let subscriber;
3124
- if (this.options.url) {
3125
- subscriber = new RedisClass(this.options.url);
3126
- } else if (this.options.config) {
3127
- subscriber = new RedisClass(this.buildRedisOptions());
3081
+ if (this.connectionUrl || this.options.config) {
3082
+ subscriber = this.newClient();
3128
3083
  } else if (this.options.client) {
3129
3084
  subscriber = this.options.client.duplicate();
3130
3085
  } else {
@@ -3171,7 +3126,8 @@ var init_redis = __esm({
3171
3126
  });
3172
3127
  var vercel_kv_exports = {};
3173
3128
  __export2(vercel_kv_exports, {
3174
- VercelKvStorageAdapter: () => VercelKvStorageAdapter
3129
+ VercelKvStorageAdapter: () => VercelKvStorageAdapter,
3130
+ createVercelKvClient: () => createVercelKvClient
3175
3131
  });
3176
3132
  async function loadVercelKv() {
3177
3133
  try {
@@ -3183,6 +3139,15 @@ async function loadVercelKv() {
3183
3139
  throw new Error("@vercel/kv is required for Vercel KV storage adapter. Install it with: npm install @vercel/kv");
3184
3140
  }
3185
3141
  }
3142
+ async function createVercelKvClient(connection = {}) {
3143
+ const url = connection.url ?? process.env["KV_REST_API_URL"];
3144
+ const token = connection.token ?? process.env["KV_REST_API_TOKEN"];
3145
+ if (!url || !token) {
3146
+ throw new StorageConfigError("vercel-kv", "Pass url and token, or set KV_REST_API_URL and KV_REST_API_TOKEN.");
3147
+ }
3148
+ const { createClient } = await loadVercelKv();
3149
+ return createClient({ url, token, cache: void 0, automaticDeserialization: false });
3150
+ }
3186
3151
  var VercelKvStorageAdapter;
3187
3152
  var init_vercel_kv = __esm({
3188
3153
  "libs/utils/src/storage/adapters/vercel-kv.ts"() {
@@ -3215,13 +3180,7 @@ var init_vercel_kv = __esm({
3215
3180
  async connect() {
3216
3181
  if (this.connected) return;
3217
3182
  try {
3218
- const { createClient } = await loadVercelKv();
3219
- const url = this.options.url;
3220
- const token = this.options.token;
3221
- if (!url || !token) {
3222
- throw new StorageConfigError("vercel-kv", "URL and token are required");
3223
- }
3224
- this.client = createClient({ url, token, cache: void 0, automaticDeserialization: false });
3183
+ this.client = await createVercelKvClient({ url: this.options.url, token: this.options.token });
3225
3184
  await this.client.exists("__healthcheck__");
3226
3185
  this.connected = true;
3227
3186
  } catch (e) {
@@ -3392,9 +3351,12 @@ var upstash_exports = {};
3392
3351
  __export2(upstash_exports, {
3393
3352
  UpstashStorageAdapter: () => UpstashStorageAdapter
3394
3353
  });
3395
- function getUpstashRedis() {
3354
+ async function loadUpstashRedis() {
3396
3355
  try {
3397
- return __require("@upstash/redis");
3356
+ const mod = await import("@upstash/redis");
3357
+ const resolved = typeof mod.Redis === "function" ? mod : mod.default;
3358
+ if (!resolved || typeof resolved.Redis !== "function") throw new Error("Redis missing");
3359
+ return resolved;
3398
3360
  } catch {
3399
3361
  throw new Error(
3400
3362
  "@upstash/redis is required for Upstash storage adapter. Install it with: npm install @upstash/redis"
@@ -3440,7 +3402,7 @@ var init_upstash = __esm({
3440
3402
  async connect() {
3441
3403
  if (this.connected) return;
3442
3404
  try {
3443
- const { Redis } = getUpstashRedis();
3405
+ const { Redis } = await loadUpstashRedis();
3444
3406
  const url = this.options.url;
3445
3407
  const token = this.options.token;
3446
3408
  if (!url || !token) {
@@ -3929,6 +3891,7 @@ init_errors();
3929
3891
  init_errors();
3930
3892
  init_memory();
3931
3893
  init_redis_error_listener();
3894
+ init_redis_url();
3932
3895
  init_errors();
3933
3896
  init_crypto();
3934
3897
  init_errors();