@frontmcp/utils 1.9.2 → 1.9.4
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/class-brand/class-brand.d.ts +37 -0
- package/class-brand/index.d.ts +1 -0
- package/crypto/browser.d.ts +5 -0
- package/crypto/browser.js +33 -5
- package/crypto/node.d.ts +1 -1
- package/esm/crypto/browser.mjs +27 -4
- package/esm/index.mjs +159 -238
- package/fs/fs.d.ts +20 -0
- package/fs/index.d.ts +1 -1
- package/index.d.ts +3 -2
- package/index.js +164 -240
- package/package.json +6 -2
- package/storage/adapters/redis.d.ts +9 -1
- package/storage/index.d.ts +1 -1
- package/storage/redis-url.d.ts +25 -3
package/esm/index.mjs
CHANGED
|
@@ -117,6 +117,9 @@ async function fileExists(p) {
|
|
|
117
117
|
return false;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
+
function fileExistsSync(p) {
|
|
121
|
+
return getFs().existsSync(p);
|
|
122
|
+
}
|
|
120
123
|
async function readJSON(jsonPath) {
|
|
121
124
|
try {
|
|
122
125
|
const fsp = getFsp();
|
|
@@ -2539,186 +2542,25 @@ var init_key_persistence2 = __esm({
|
|
|
2539
2542
|
}
|
|
2540
2543
|
});
|
|
2541
2544
|
|
|
2542
|
-
// libs/utils/src/crypto/node.ts
|
|
2543
|
-
var node_exports = {};
|
|
2544
|
-
__export(node_exports, {
|
|
2545
|
-
createSignedJwt: () => createSignedJwt,
|
|
2546
|
-
cryptoProvider: () => nodeCrypto,
|
|
2547
|
-
generateRsaKeyPair: () => generateRsaKeyPair,
|
|
2548
|
-
isRsaPssAlg: () => isRsaPssAlg,
|
|
2549
|
-
jwtAlgToNodeAlg: () => jwtAlgToNodeAlg,
|
|
2550
|
-
nodeCrypto: () => nodeCrypto,
|
|
2551
|
-
pemToPublicJwk: () => pemToPublicJwk,
|
|
2552
|
-
rsaSign: () => rsaSign,
|
|
2553
|
-
rsaSignBase64Url: () => rsaSignBase64Url,
|
|
2554
|
-
rsaVerify: () => rsaVerify,
|
|
2555
|
-
rsaVerifySync: () => rsaVerifySync
|
|
2556
|
-
});
|
|
2557
|
-
import crypto2 from "node:crypto";
|
|
2558
|
-
function toUint8Array(buf) {
|
|
2559
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
2560
|
-
}
|
|
2561
|
-
function toBuffer(data) {
|
|
2562
|
-
if (typeof data === "string") {
|
|
2563
|
-
return Buffer.from(data, "utf8");
|
|
2564
|
-
}
|
|
2565
|
-
return Buffer.from(data);
|
|
2566
|
-
}
|
|
2567
|
-
function generateRsaKeyPair(modulusLength = 2048, alg = "RS256") {
|
|
2568
|
-
const kid = `rsa-key-${Date.now()}-${crypto2.randomBytes(8).toString("hex")}`;
|
|
2569
|
-
const { privateKey, publicKey } = crypto2.generateKeyPairSync("rsa", {
|
|
2570
|
-
modulusLength
|
|
2571
|
-
});
|
|
2572
|
-
const exported = publicKey.export({ format: "jwk" });
|
|
2573
|
-
const publicJwk = {
|
|
2574
|
-
...exported,
|
|
2575
|
-
kid,
|
|
2576
|
-
alg,
|
|
2577
|
-
use: "sig",
|
|
2578
|
-
kty: "RSA"
|
|
2579
|
-
};
|
|
2580
|
-
return { privateKey, publicKey, publicJwk };
|
|
2581
|
-
}
|
|
2582
|
-
function rsaSign(algorithm, data, privateKey, options) {
|
|
2583
|
-
const signingKey = options ? { key: privateKey, ...options } : privateKey;
|
|
2584
|
-
return crypto2.sign(algorithm, data, signingKey);
|
|
2585
|
-
}
|
|
2586
|
-
function rsaVerify(jwtAlg, data, publicJwk, signature) {
|
|
2587
|
-
const publicKey = crypto2.createPublicKey({ key: publicJwk, format: "jwk" });
|
|
2588
|
-
const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
|
|
2589
|
-
const verifyKey = isRsaPssAlg(jwtAlg) ? {
|
|
2590
|
-
key: publicKey,
|
|
2591
|
-
padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
|
|
2592
|
-
saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
|
|
2593
|
-
} : publicKey;
|
|
2594
|
-
return crypto2.verify(nodeAlgorithm, data, verifyKey, signature);
|
|
2595
|
-
}
|
|
2596
|
-
function rsaSignBase64Url(jwtAlg, data, privateJwk) {
|
|
2597
|
-
const privateKey = crypto2.createPrivateKey({ key: privateJwk, format: "jwk" });
|
|
2598
|
-
const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
|
|
2599
|
-
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
2600
|
-
const sig = isRsaPssAlg(jwtAlg) ? rsaSign(nodeAlgorithm, buf, privateKey, {
|
|
2601
|
-
padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
|
|
2602
|
-
saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
|
|
2603
|
-
}) : rsaSign(nodeAlgorithm, buf, privateKey);
|
|
2604
|
-
return sig.toString("base64url");
|
|
2605
|
-
}
|
|
2606
|
-
function rsaVerifySync(jwtAlg, data, publicJwk, signature) {
|
|
2607
|
-
try {
|
|
2608
|
-
const publicKey = crypto2.createPublicKey({ key: publicJwk, format: "jwk" });
|
|
2609
|
-
const dataBuf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
2610
|
-
const sigBuf = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
|
|
2611
|
-
if (jwtAlg === "EdDSA") {
|
|
2612
|
-
return crypto2.verify(null, dataBuf, publicKey, sigBuf);
|
|
2613
|
-
}
|
|
2614
|
-
const nodeAlgorithm = jwtAlgToNodeAlg(jwtAlg);
|
|
2615
|
-
const verifyKey = isRsaPssAlg(jwtAlg) ? {
|
|
2616
|
-
key: publicKey,
|
|
2617
|
-
padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
|
|
2618
|
-
saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
|
|
2619
|
-
} : publicKey;
|
|
2620
|
-
return crypto2.verify(nodeAlgorithm, dataBuf, verifyKey, sigBuf);
|
|
2621
|
-
} catch {
|
|
2622
|
-
return false;
|
|
2623
|
-
}
|
|
2624
|
-
}
|
|
2625
|
-
function pemToPublicJwk(pem) {
|
|
2626
|
-
const key = crypto2.createPublicKey({ key: pem, format: "pem" });
|
|
2627
|
-
return key.export({ format: "jwk" });
|
|
2628
|
-
}
|
|
2629
|
-
function createSignedJwt(payload, privateKey, kid, alg = "RS256") {
|
|
2630
|
-
const header = { alg, typ: "JWT", kid };
|
|
2631
|
-
const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
2632
|
-
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
2633
|
-
const signatureInput = `${headerB64}.${payloadB64}`;
|
|
2634
|
-
const nodeAlgorithm = jwtAlgToNodeAlg(alg);
|
|
2635
|
-
const signature = rsaSign(
|
|
2636
|
-
nodeAlgorithm,
|
|
2637
|
-
Buffer.from(signatureInput),
|
|
2638
|
-
privateKey,
|
|
2639
|
-
isRsaPssAlg(alg) ? {
|
|
2640
|
-
padding: crypto2.constants.RSA_PKCS1_PSS_PADDING,
|
|
2641
|
-
saltLength: crypto2.constants.RSA_PSS_SALTLEN_DIGEST
|
|
2642
|
-
} : void 0
|
|
2643
|
-
);
|
|
2644
|
-
const signatureB64 = signature.toString("base64url");
|
|
2645
|
-
return `${headerB64}.${payloadB64}.${signatureB64}`;
|
|
2646
|
-
}
|
|
2647
|
-
var nodeCrypto;
|
|
2648
|
-
var init_node = __esm({
|
|
2649
|
-
"libs/utils/src/crypto/node.ts"() {
|
|
2650
|
-
"use strict";
|
|
2651
|
-
init_jwt_alg();
|
|
2652
|
-
init_jwt_alg();
|
|
2653
|
-
nodeCrypto = {
|
|
2654
|
-
randomUUID() {
|
|
2655
|
-
return crypto2.randomUUID();
|
|
2656
|
-
},
|
|
2657
|
-
randomBytes(length) {
|
|
2658
|
-
return toUint8Array(crypto2.randomBytes(length));
|
|
2659
|
-
},
|
|
2660
|
-
sha256(data) {
|
|
2661
|
-
const hash = crypto2.createHash("sha256").update(toBuffer(data)).digest();
|
|
2662
|
-
return toUint8Array(hash);
|
|
2663
|
-
},
|
|
2664
|
-
sha256Hex(data) {
|
|
2665
|
-
return crypto2.createHash("sha256").update(toBuffer(data)).digest("hex");
|
|
2666
|
-
},
|
|
2667
|
-
hmacSha256(key, data) {
|
|
2668
|
-
const hmac2 = crypto2.createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest();
|
|
2669
|
-
return toUint8Array(hmac2);
|
|
2670
|
-
},
|
|
2671
|
-
hkdfSha256(ikm, salt, info, length) {
|
|
2672
|
-
const ikmBuf = Buffer.from(ikm);
|
|
2673
|
-
const saltBuf = salt.length > 0 ? Buffer.from(salt) : Buffer.alloc(32);
|
|
2674
|
-
const prk = crypto2.createHmac("sha256", saltBuf).update(ikmBuf).digest();
|
|
2675
|
-
const hashLen = 32;
|
|
2676
|
-
const n = Math.ceil(length / hashLen);
|
|
2677
|
-
const chunks = [];
|
|
2678
|
-
let prev = Buffer.alloc(0);
|
|
2679
|
-
for (let i = 1; i <= n; i++) {
|
|
2680
|
-
prev = crypto2.createHmac("sha256", prk).update(Buffer.concat([prev, Buffer.from(info), Buffer.from([i])])).digest();
|
|
2681
|
-
chunks.push(prev);
|
|
2682
|
-
}
|
|
2683
|
-
return toUint8Array(Buffer.concat(chunks).subarray(0, length));
|
|
2684
|
-
},
|
|
2685
|
-
encryptAesGcm(key, plaintext, iv) {
|
|
2686
|
-
const cipher = crypto2.createCipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
|
|
2687
|
-
const encrypted = Buffer.concat([cipher.update(Buffer.from(plaintext)), cipher.final()]);
|
|
2688
|
-
const tag = cipher.getAuthTag();
|
|
2689
|
-
return {
|
|
2690
|
-
ciphertext: toUint8Array(encrypted),
|
|
2691
|
-
tag: toUint8Array(tag)
|
|
2692
|
-
};
|
|
2693
|
-
},
|
|
2694
|
-
decryptAesGcm(key, ciphertext, iv, tag) {
|
|
2695
|
-
const decipher = crypto2.createDecipheriv("aes-256-gcm", Buffer.from(key), Buffer.from(iv));
|
|
2696
|
-
decipher.setAuthTag(Buffer.from(tag));
|
|
2697
|
-
const decrypted = Buffer.concat([decipher.update(Buffer.from(ciphertext)), decipher.final()]);
|
|
2698
|
-
return toUint8Array(decrypted);
|
|
2699
|
-
},
|
|
2700
|
-
timingSafeEqual(a, b) {
|
|
2701
|
-
if (a.length !== b.length) return false;
|
|
2702
|
-
return crypto2.timingSafeEqual(Buffer.from(a), Buffer.from(b));
|
|
2703
|
-
}
|
|
2704
|
-
};
|
|
2705
|
-
}
|
|
2706
|
-
});
|
|
2707
|
-
|
|
2708
2545
|
// libs/utils/src/crypto/browser.ts
|
|
2709
2546
|
var browser_exports = {};
|
|
2710
2547
|
__export(browser_exports, {
|
|
2711
2548
|
browserCrypto: () => browserCrypto,
|
|
2712
2549
|
cryptoProvider: () => browserCrypto,
|
|
2550
|
+
generateRsaKeyPair: () => generateRsaKeyPair,
|
|
2713
2551
|
isRsaPssAlg: () => isRsaPssAlg,
|
|
2714
2552
|
jwtAlgToWebCryptoAlg: () => jwtAlgToWebCryptoAlg,
|
|
2715
|
-
|
|
2553
|
+
pemToPublicJwk: () => pemToPublicJwk,
|
|
2554
|
+
rsaSignBase64Url: () => rsaSignBase64Url,
|
|
2555
|
+
rsaVerify: () => rsaVerify,
|
|
2556
|
+
rsaVerifyBrowser: () => rsaVerifyBrowser,
|
|
2557
|
+
rsaVerifySync: () => rsaVerifySync
|
|
2716
2558
|
});
|
|
2717
|
-
import {
|
|
2718
|
-
import { hmac } from "@noble/hashes/hmac.js";
|
|
2559
|
+
import { gcm } from "@noble/ciphers/aes.js";
|
|
2719
2560
|
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
2561
|
+
import { hmac } from "@noble/hashes/hmac.js";
|
|
2562
|
+
import { sha256 as sha256Hash } from "@noble/hashes/sha2.js";
|
|
2720
2563
|
import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils.js";
|
|
2721
|
-
import { gcm } from "@noble/ciphers/aes.js";
|
|
2722
2564
|
function toBytes(data) {
|
|
2723
2565
|
if (typeof data === "string") {
|
|
2724
2566
|
return new TextEncoder().encode(data);
|
|
@@ -2746,6 +2588,24 @@ function constantTimeEqual(a, b) {
|
|
|
2746
2588
|
}
|
|
2747
2589
|
return result === 0;
|
|
2748
2590
|
}
|
|
2591
|
+
function nodeOnly(name) {
|
|
2592
|
+
throw new Error(`${name} is only available in Node.js runtimes`);
|
|
2593
|
+
}
|
|
2594
|
+
function rsaVerify() {
|
|
2595
|
+
return nodeOnly("rsaVerify");
|
|
2596
|
+
}
|
|
2597
|
+
function rsaSignBase64Url() {
|
|
2598
|
+
return nodeOnly("rsaSignBase64Url");
|
|
2599
|
+
}
|
|
2600
|
+
function rsaVerifySync() {
|
|
2601
|
+
return nodeOnly("rsaVerifySync");
|
|
2602
|
+
}
|
|
2603
|
+
function pemToPublicJwk() {
|
|
2604
|
+
return nodeOnly("pemToPublicJwk");
|
|
2605
|
+
}
|
|
2606
|
+
function generateRsaKeyPair() {
|
|
2607
|
+
return nodeOnly("generateRsaKeyPair");
|
|
2608
|
+
}
|
|
2749
2609
|
async function rsaVerifyBrowser(jwtAlg, data, publicJwk, signature) {
|
|
2750
2610
|
if (typeof globalThis.crypto?.subtle === "undefined") {
|
|
2751
2611
|
throw new Error("WebCrypto API (crypto.subtle) is not available in this environment");
|
|
@@ -2825,40 +2685,40 @@ var init_browser = __esm({
|
|
|
2825
2685
|
});
|
|
2826
2686
|
|
|
2827
2687
|
// libs/utils/src/crypto/index.ts
|
|
2828
|
-
import
|
|
2688
|
+
import * as platformCrypto from "#crypto-provider";
|
|
2829
2689
|
function getCrypto() {
|
|
2830
|
-
return
|
|
2690
|
+
return platformCrypto.cryptoProvider;
|
|
2831
2691
|
}
|
|
2832
|
-
function
|
|
2692
|
+
function rsaVerify3(jwtAlg, data, publicJwk, signature) {
|
|
2833
2693
|
if (isNode()) {
|
|
2834
|
-
return Promise.resolve(
|
|
2694
|
+
return Promise.resolve(platformCrypto.rsaVerify(jwtAlg, data, publicJwk, signature));
|
|
2835
2695
|
}
|
|
2836
2696
|
const { rsaVerifyBrowser: rsaVerifyBrowser2 } = (init_browser(), __toCommonJS(browser_exports));
|
|
2837
2697
|
return rsaVerifyBrowser2(jwtAlg, data, publicJwk, signature);
|
|
2838
2698
|
}
|
|
2839
|
-
function
|
|
2699
|
+
function rsaSignBase64Url3(jwtAlg, data, privateJwk) {
|
|
2840
2700
|
if (!isNode()) {
|
|
2841
2701
|
throw new Error("rsaSignBase64Url is only available in Node.js runtimes");
|
|
2842
2702
|
}
|
|
2843
|
-
return
|
|
2703
|
+
return platformCrypto.rsaSignBase64Url(jwtAlg, data, privateJwk);
|
|
2844
2704
|
}
|
|
2845
|
-
function
|
|
2705
|
+
function rsaVerifySync3(jwtAlg, data, publicJwk, signature) {
|
|
2846
2706
|
if (!isNode()) {
|
|
2847
2707
|
throw new Error("rsaVerifySync is only available in Node.js runtimes; use the async rsaVerify in browsers");
|
|
2848
2708
|
}
|
|
2849
|
-
return
|
|
2709
|
+
return platformCrypto.rsaVerifySync(jwtAlg, data, publicJwk, signature);
|
|
2850
2710
|
}
|
|
2851
|
-
function
|
|
2711
|
+
function pemToPublicJwk3(pem) {
|
|
2852
2712
|
if (!isNode()) {
|
|
2853
2713
|
throw new Error("pemToPublicJwk is only available in Node.js runtimes");
|
|
2854
2714
|
}
|
|
2855
|
-
return
|
|
2715
|
+
return platformCrypto.pemToPublicJwk(pem);
|
|
2856
2716
|
}
|
|
2857
|
-
function
|
|
2717
|
+
function generateRsaKeyPair3(modulusLength, alg) {
|
|
2858
2718
|
if (!isNode()) {
|
|
2859
2719
|
throw new Error("generateRsaKeyPair is only available in Node.js runtimes");
|
|
2860
2720
|
}
|
|
2861
|
-
return
|
|
2721
|
+
return platformCrypto.generateRsaKeyPair(modulusLength, alg);
|
|
2862
2722
|
}
|
|
2863
2723
|
function randomUUID() {
|
|
2864
2724
|
return getCrypto().randomUUID();
|
|
@@ -3023,37 +2883,55 @@ function decodeOrRaw(encoded) {
|
|
|
3023
2883
|
return encoded;
|
|
3024
2884
|
}
|
|
3025
2885
|
}
|
|
3026
|
-
function
|
|
2886
|
+
function integerOrUndefined(text) {
|
|
2887
|
+
const value = Number.parseInt(text ?? "", 10);
|
|
2888
|
+
return Number.isNaN(value) ? void 0 : value;
|
|
2889
|
+
}
|
|
2890
|
+
function readRedisUrl(rawUrl) {
|
|
3027
2891
|
let url;
|
|
3028
2892
|
try {
|
|
3029
2893
|
url = new URL(rawUrl);
|
|
3030
2894
|
} catch {
|
|
3031
2895
|
return void 0;
|
|
3032
2896
|
}
|
|
3033
|
-
|
|
3034
|
-
const
|
|
3035
|
-
const
|
|
3036
|
-
const
|
|
3037
|
-
const
|
|
3038
|
-
|
|
2897
|
+
if (url.protocol !== "redis:" && url.protocol !== "rediss:") return void 0;
|
|
2898
|
+
const query = Object.fromEntries(url.searchParams);
|
|
2899
|
+
const { host, port, username, password, db, ...otherOptions } = query;
|
|
2900
|
+
const queryOptions = {};
|
|
2901
|
+
for (const [name, value = ""] of Object.entries(otherOptions)) {
|
|
2902
|
+
queryOptions[name] = name === "family" ? integerOrUndefined(value) ?? value : value;
|
|
2903
|
+
}
|
|
2904
|
+
return {
|
|
2905
|
+
host: url.hostname.replace(/^\[(.*)\]$/, "$1") || host,
|
|
2906
|
+
port: integerOrUndefined(url.port || port),
|
|
2907
|
+
username: decodeOrRaw(url.username) || username || void 0,
|
|
2908
|
+
password: decodeOrRaw(url.password) || password || void 0,
|
|
2909
|
+
db: integerOrUndefined(url.pathname.replace(/^\/+/, "") || db),
|
|
2910
|
+
tls: url.protocol === "rediss:",
|
|
2911
|
+
queryOptions
|
|
2912
|
+
};
|
|
2913
|
+
}
|
|
2914
|
+
function mergeRedisUrlFields(rawUrl, fields) {
|
|
2915
|
+
const connection = readRedisUrl(rawUrl);
|
|
2916
|
+
if (!connection) return void 0;
|
|
3039
2917
|
const fillIns = {};
|
|
3040
2918
|
const conflicts = [];
|
|
3041
|
-
if (fields.host !== void 0 && fields.host !==
|
|
2919
|
+
if (fields.host !== void 0 && fields.host !== connection.host) conflicts.push("host");
|
|
3042
2920
|
if (fields.port !== void 0) {
|
|
3043
|
-
if (
|
|
3044
|
-
else if (fields.port !==
|
|
2921
|
+
if (connection.port === void 0) fillIns.port = fields.port;
|
|
2922
|
+
else if (fields.port !== connection.port) conflicts.push("port");
|
|
3045
2923
|
}
|
|
3046
2924
|
if (fields.password !== void 0) {
|
|
3047
|
-
if (
|
|
3048
|
-
else if (fields.password !==
|
|
2925
|
+
if (connection.password === void 0) fillIns.password = fields.password;
|
|
2926
|
+
else if (fields.password !== connection.password) conflicts.push("password");
|
|
3049
2927
|
}
|
|
3050
2928
|
if (fields.db !== void 0) {
|
|
3051
|
-
if (
|
|
3052
|
-
else if (fields.db !==
|
|
2929
|
+
if (connection.db === void 0) fillIns.db = fields.db;
|
|
2930
|
+
else if (fields.db !== connection.db) conflicts.push("db");
|
|
3053
2931
|
}
|
|
3054
|
-
if (fields.tls === true && !
|
|
3055
|
-
if (fields.tls === false &&
|
|
3056
|
-
return { fillIns, conflicts };
|
|
2932
|
+
if (fields.tls === true && !connection.tls) fillIns.tls = true;
|
|
2933
|
+
if (fields.tls === false && connection.tls) conflicts.push("tls");
|
|
2934
|
+
return { connection, fillIns, conflicts };
|
|
3057
2935
|
}
|
|
3058
2936
|
function describeRedisUrlConflicts(conflicts) {
|
|
3059
2937
|
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.`;
|
|
@@ -3103,28 +2981,49 @@ function getRedisClass() {
|
|
|
3103
2981
|
});
|
|
3104
2982
|
}
|
|
3105
2983
|
}
|
|
3106
|
-
function
|
|
2984
|
+
function resolveUrlOptions(connectionUrl, options) {
|
|
3107
2985
|
const { url: configUrl, ...siblingFields } = { url: void 0, ...options.config };
|
|
3108
2986
|
if (options.url && configUrl && configUrl !== options.url) {
|
|
3109
2987
|
throw new StorageConfigError("redis", "redis.url and redis.config.url name different servers; set one of them.");
|
|
3110
2988
|
}
|
|
3111
|
-
|
|
3112
|
-
|
|
2989
|
+
return urlConnectionOptions(connectionUrl, siblingFields);
|
|
2990
|
+
}
|
|
2991
|
+
function urlConnectionOptions(url, fields) {
|
|
2992
|
+
const merge = mergeRedisUrlFields(url, fields);
|
|
2993
|
+
if (!merge) return void 0;
|
|
2994
|
+
if (merge.conflicts.length > 0) {
|
|
3113
2995
|
throw new StorageConfigError("redis", describeRedisUrlConflicts(merge.conflicts));
|
|
3114
2996
|
}
|
|
3115
|
-
|
|
2997
|
+
const { queryOptions, tls, ...stated } = merge.connection;
|
|
2998
|
+
return { ...queryOptions, ...stated, ...toFillInOptions(merge.fillIns), ...tls ? { tls: {} } : {} };
|
|
2999
|
+
}
|
|
3000
|
+
function toFillInOptions({ port, password, db, tls }) {
|
|
3001
|
+
return {
|
|
3002
|
+
...port !== void 0 ? { port } : {},
|
|
3003
|
+
...password !== void 0 ? { password } : {},
|
|
3004
|
+
...db !== void 0 ? { db } : {},
|
|
3005
|
+
...tls ? { tls: {} } : {}
|
|
3006
|
+
};
|
|
3116
3007
|
}
|
|
3117
3008
|
function createRedisClient(options) {
|
|
3009
|
+
const urlOptions = options.url ? urlConnectionOptions(options.url, options) : void 0;
|
|
3118
3010
|
const RedisClass = getRedisClass();
|
|
3119
3011
|
const baseOptions = { lazyConnect: false, maxRetriesPerRequest: 3 };
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3012
|
+
let client;
|
|
3013
|
+
if (urlOptions) {
|
|
3014
|
+
client = new RedisClass({ ...baseOptions, ...urlOptions });
|
|
3015
|
+
} else if (options.url) {
|
|
3016
|
+
client = new RedisClass(options.url, baseOptions);
|
|
3017
|
+
} else {
|
|
3018
|
+
client = new RedisClass({
|
|
3019
|
+
...baseOptions,
|
|
3020
|
+
host: options.host ?? "localhost",
|
|
3021
|
+
port: options.port ?? 6379,
|
|
3022
|
+
password: options.password,
|
|
3023
|
+
db: options.db ?? 0,
|
|
3024
|
+
tls: options.tls ? {} : void 0
|
|
3025
|
+
});
|
|
3026
|
+
}
|
|
3128
3027
|
attachRedisErrorListener(client, { label: options.label ?? "redis", logger: options.logger });
|
|
3129
3028
|
return client;
|
|
3130
3029
|
}
|
|
@@ -3149,7 +3048,8 @@ var init_redis = __esm({
|
|
|
3149
3048
|
keyPrefix;
|
|
3150
3049
|
subscriptionHandlers = /* @__PURE__ */ new Map();
|
|
3151
3050
|
connectionUrl;
|
|
3152
|
-
|
|
3051
|
+
/** The connection options of a URL this adapter reads itself; undefined for one only ioredis reads. */
|
|
3052
|
+
urlOptions;
|
|
3153
3053
|
constructor(options = {}) {
|
|
3154
3054
|
super();
|
|
3155
3055
|
const hasClient = options.client !== void 0;
|
|
@@ -3173,7 +3073,7 @@ var init_redis = __esm({
|
|
|
3173
3073
|
this.keyPrefix = options.keyPrefix ?? "";
|
|
3174
3074
|
const configUrl = options.config?.url;
|
|
3175
3075
|
this.connectionUrl = options.url ?? (typeof configUrl === "string" ? configUrl : void 0);
|
|
3176
|
-
this.
|
|
3076
|
+
this.urlOptions = this.connectionUrl ? resolveUrlOptions(this.connectionUrl, options) : void 0;
|
|
3177
3077
|
}
|
|
3178
3078
|
// ============================================
|
|
3179
3079
|
// Connection Lifecycle
|
|
@@ -3195,12 +3095,7 @@ var init_redis = __esm({
|
|
|
3195
3095
|
if (this.options.client) {
|
|
3196
3096
|
client = this.options.client;
|
|
3197
3097
|
} else {
|
|
3198
|
-
|
|
3199
|
-
if (this.connectionUrl) {
|
|
3200
|
-
client = new RedisClass(this.connectionUrl, this.buildRedisOptions());
|
|
3201
|
-
} else {
|
|
3202
|
-
client = new RedisClass(this.buildRedisOptions());
|
|
3203
|
-
}
|
|
3098
|
+
client = this.newClient();
|
|
3204
3099
|
client.on("error", recordSocketError);
|
|
3205
3100
|
}
|
|
3206
3101
|
await client.ping();
|
|
@@ -3434,15 +3329,7 @@ var init_redis = __esm({
|
|
|
3434
3329
|
*/
|
|
3435
3330
|
buildRedisOptions() {
|
|
3436
3331
|
if (this.connectionUrl) {
|
|
3437
|
-
|
|
3438
|
-
return {
|
|
3439
|
-
...port !== void 0 ? { port } : {},
|
|
3440
|
-
...password !== void 0 ? { password } : {},
|
|
3441
|
-
...db !== void 0 ? { db } : {},
|
|
3442
|
-
...tls ? { tls: {} } : {},
|
|
3443
|
-
lazyConnect: false,
|
|
3444
|
-
maxRetriesPerRequest: 3
|
|
3445
|
-
};
|
|
3332
|
+
return { lazyConnect: false, maxRetriesPerRequest: 3, ...this.urlOptions };
|
|
3446
3333
|
}
|
|
3447
3334
|
const config = this.options.config;
|
|
3448
3335
|
if (!config || typeof config.url === "string" || config.host === void 0) {
|
|
@@ -3458,16 +3345,23 @@ var init_redis = __esm({
|
|
|
3458
3345
|
maxRetriesPerRequest: 3
|
|
3459
3346
|
};
|
|
3460
3347
|
}
|
|
3348
|
+
/**
|
|
3349
|
+
* Create a client this adapter owns. A URL only ioredis reads goes to it as is.
|
|
3350
|
+
*/
|
|
3351
|
+
newClient() {
|
|
3352
|
+
const RedisClass = getRedisClass();
|
|
3353
|
+
if (this.connectionUrl && !this.urlOptions) {
|
|
3354
|
+
return new RedisClass(this.connectionUrl, this.buildRedisOptions());
|
|
3355
|
+
}
|
|
3356
|
+
return new RedisClass(this.buildRedisOptions());
|
|
3357
|
+
}
|
|
3461
3358
|
/**
|
|
3462
3359
|
* Create subscriber connection.
|
|
3463
3360
|
*/
|
|
3464
3361
|
async createSubscriber() {
|
|
3465
|
-
const RedisClass = getRedisClass();
|
|
3466
3362
|
let subscriber;
|
|
3467
|
-
if (this.connectionUrl) {
|
|
3468
|
-
subscriber =
|
|
3469
|
-
} else if (this.options.config) {
|
|
3470
|
-
subscriber = new RedisClass(this.buildRedisOptions());
|
|
3363
|
+
if (this.connectionUrl || this.options.config) {
|
|
3364
|
+
subscriber = this.newClient();
|
|
3471
3365
|
} else if (this.options.client) {
|
|
3472
3366
|
subscriber = this.options.client.duplicate();
|
|
3473
3367
|
} else {
|
|
@@ -4992,6 +4886,30 @@ function safeJsonForScript(value) {
|
|
|
4992
4886
|
}
|
|
4993
4887
|
}
|
|
4994
4888
|
|
|
4889
|
+
// libs/utils/src/class-brand/class-brand.ts
|
|
4890
|
+
var CLASS_BRAND = /* @__PURE__ */ Symbol.for("@frontmcp/class-brand");
|
|
4891
|
+
var ordinaryHasInstance = Function.prototype[Symbol.hasInstance];
|
|
4892
|
+
function ownBrandOf(klass) {
|
|
4893
|
+
if (typeof klass !== "function" || !Object.prototype.hasOwnProperty.call(klass, CLASS_BRAND)) return void 0;
|
|
4894
|
+
return klass[CLASS_BRAND];
|
|
4895
|
+
}
|
|
4896
|
+
function classOfPrototype(proto) {
|
|
4897
|
+
return Object.getOwnPropertyDescriptor(proto, "constructor")?.value;
|
|
4898
|
+
}
|
|
4899
|
+
function brandClass(klass, brand) {
|
|
4900
|
+
Object.defineProperty(klass, CLASS_BRAND, { value: brand, enumerable: false, writable: false, configurable: false });
|
|
4901
|
+
}
|
|
4902
|
+
function isBrandedInstance(klass, value) {
|
|
4903
|
+
if (ordinaryHasInstance.call(klass, value)) return true;
|
|
4904
|
+
if (typeof value !== "object" || value === null) return false;
|
|
4905
|
+
const brand = ownBrandOf(klass);
|
|
4906
|
+
if (brand === void 0) return false;
|
|
4907
|
+
for (let proto = Object.getPrototypeOf(value); proto !== null; proto = Object.getPrototypeOf(proto)) {
|
|
4908
|
+
if (ownBrandOf(classOfPrototype(proto)) === brand) return true;
|
|
4909
|
+
}
|
|
4910
|
+
return false;
|
|
4911
|
+
}
|
|
4912
|
+
|
|
4995
4913
|
// libs/utils/src/serialization/serialization.ts
|
|
4996
4914
|
function safeStringify(value, space) {
|
|
4997
4915
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
@@ -6016,6 +5934,7 @@ export {
|
|
|
6016
5934
|
base64urlDecode,
|
|
6017
5935
|
base64urlEncode,
|
|
6018
5936
|
basename,
|
|
5937
|
+
brandClass,
|
|
6019
5938
|
buildPrefix,
|
|
6020
5939
|
buildSetCookie,
|
|
6021
5940
|
bytesToHex,
|
|
@@ -6066,11 +5985,12 @@ export {
|
|
|
6066
5985
|
extractTemplateParams,
|
|
6067
5986
|
extractUriScheme,
|
|
6068
5987
|
fileExists,
|
|
5988
|
+
fileExistsSync,
|
|
6069
5989
|
findNonFiniteNumber,
|
|
6070
5990
|
generateCodeChallenge,
|
|
6071
5991
|
generateCodeVerifier,
|
|
6072
5992
|
generatePkcePair,
|
|
6073
|
-
|
|
5993
|
+
generateRsaKeyPair3 as generateRsaKeyPair,
|
|
6074
5994
|
generateSecret,
|
|
6075
5995
|
getAsyncContextMode,
|
|
6076
5996
|
getCookie,
|
|
@@ -6092,6 +6012,7 @@ export {
|
|
|
6092
6012
|
inferMimeType,
|
|
6093
6013
|
isAbsolute,
|
|
6094
6014
|
isAsymmetricKeyData,
|
|
6015
|
+
isBrandedInstance,
|
|
6095
6016
|
isBrowser,
|
|
6096
6017
|
isDebug,
|
|
6097
6018
|
isDevelopment,
|
|
@@ -6135,7 +6056,7 @@ export {
|
|
|
6135
6056
|
join as pathJoin,
|
|
6136
6057
|
resolve as pathResolve,
|
|
6137
6058
|
pathToFileURL,
|
|
6138
|
-
|
|
6059
|
+
pemToPublicJwk3 as pemToPublicJwk,
|
|
6139
6060
|
processPlatformToolCalls,
|
|
6140
6061
|
randomBytes,
|
|
6141
6062
|
randomUUID,
|
|
@@ -6150,9 +6071,9 @@ export {
|
|
|
6150
6071
|
resetRuntimeContext,
|
|
6151
6072
|
resolveSecretPath,
|
|
6152
6073
|
rm,
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6074
|
+
rsaSignBase64Url3 as rsaSignBase64Url,
|
|
6075
|
+
rsaVerify3 as rsaVerify,
|
|
6076
|
+
rsaVerifySync3 as rsaVerifySync,
|
|
6156
6077
|
runCmd,
|
|
6157
6078
|
runRequestExclusive,
|
|
6158
6079
|
safeExec,
|
package/fs/fs.d.ts
CHANGED
|
@@ -137,6 +137,21 @@ export declare function unlink(p: string): Promise<void>;
|
|
|
137
137
|
* await fileExists('/path/to/file.txt') // true or false
|
|
138
138
|
*/
|
|
139
139
|
export declare function fileExists(p: string): Promise<boolean>;
|
|
140
|
+
/**
|
|
141
|
+
* Check whether a file or directory exists, synchronously.
|
|
142
|
+
*
|
|
143
|
+
* **Node.js only** - throws an error if called in browser.
|
|
144
|
+
*
|
|
145
|
+
* Use this only where async is not possible (e.g. resolving a command line
|
|
146
|
+
* before a synchronous `spawn`). Prefer {@link fileExists} otherwise.
|
|
147
|
+
*
|
|
148
|
+
* @param p - Path to check
|
|
149
|
+
* @returns true if the path exists, false otherwise
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* fileExistsSync('/path/to/file.txt') // true or false
|
|
153
|
+
*/
|
|
154
|
+
export declare function fileExistsSync(p: string): boolean;
|
|
140
155
|
/**
|
|
141
156
|
* Read and parse a JSON file.
|
|
142
157
|
*
|
|
@@ -343,6 +358,11 @@ export declare function access(p: string, mode?: number): Promise<void>;
|
|
|
343
358
|
export declare function runCmd(cmd: string, args: string[], opts?: {
|
|
344
359
|
cwd?: string;
|
|
345
360
|
env?: NodeJS.ProcessEnv;
|
|
361
|
+
/**
|
|
362
|
+
* Pass `args` to the child unquoted (Windows only). Set it when the arguments
|
|
363
|
+
* are already quoted for `cmd.exe /d /s /c`; ignored on other platforms.
|
|
364
|
+
*/
|
|
365
|
+
windowsVerbatimArguments?: boolean;
|
|
346
366
|
}): Promise<void>;
|
|
347
367
|
/**
|
|
348
368
|
* Handle returned by {@link watchFile}. `close()` stops the watch and is safe
|
package/fs/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, readdirSync, realpath, rm, mkdtemp, symlink, access, fileExists, readJSON, writeJSON, ensureDir, ensureDirSync, isDirEmpty, runCmd, watchFile, getSpawnFn, } from './fs';
|
|
1
|
+
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, readdirSync, realpath, rm, mkdtemp, symlink, access, fileExists, fileExistsSync, readJSON, writeJSON, ensureDir, ensureDirSync, isDirEmpty, runCmd, watchFile, getSpawnFn, } from './fs';
|
|
2
2
|
export type { FileWatcherHandle, SymlinkType } from './fs';
|
package/index.d.ts
CHANGED
|
@@ -15,9 +15,10 @@ export { validateBaseUrl, buildSetCookie, parseCookies, getCookie, isLocalhost,
|
|
|
15
15
|
export type { CookieOptions, SecureDetectionRequest } from './http';
|
|
16
16
|
export { classifyIpAddress, expandIpv6, extractEmbeddedIpv4, parseIpv4, isRedirectResponse } from './net';
|
|
17
17
|
export type { IpAddressClassification, IpAddressRange, SpecialPurposeIpRange, RedirectCandidate } from './net';
|
|
18
|
-
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, readdirSync, realpath, rm, mkdtemp, symlink, access, fileExists, readJSON, writeJSON, ensureDir, ensureDirSync, isDirEmpty, runCmd, watchFile, getSpawnFn, } from './fs';
|
|
18
|
+
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, readdirSync, realpath, rm, mkdtemp, symlink, access, fileExists, fileExistsSync, readJSON, writeJSON, ensureDir, ensureDirSync, isDirEmpty, runCmd, watchFile, getSpawnFn, } from './fs';
|
|
19
19
|
export type { FileWatcherHandle } from './fs';
|
|
20
20
|
export { escapeHtml, escapeHtmlAttr, escapeJsString, escapeScriptClose, safeJsonForScript } from './escape';
|
|
21
|
+
export { brandClass, isBrandedInstance } from './class-brand';
|
|
21
22
|
export { safeStringify } from './serialization';
|
|
22
23
|
export { getCrypto, rsaVerify, rsaVerifySync, pemToPublicJwk, generateRsaKeyPair, rsaSignBase64Url, type RsaJwk, type RsaKeyPair, jwtAlgToNodeAlg, isRsaPssAlg, randomUUID, randomBytes, sha256, sha256Hex, sha256Base64url, hmacSha256, hkdfSha256, encryptAesGcm, decryptAesGcm, timingSafeEqual, bytesToHex, base64urlEncode, base64urlDecode, base64Encode, base64Decode, isNode, isBrowser, assertNode, EncryptedBlobError, encryptValue, decryptValue, tryDecryptValue, serializeBlob, deserializeBlob, tryDeserializeBlob, isValidEncryptedBlob, encryptAndSerialize, deserializeAndDecrypt, tryDeserializeAndDecrypt, generateCodeVerifier, generateCodeChallenge, verifyCodeChallenge, generatePkcePair, isValidCodeVerifier, isValidCodeChallenge, MIN_CODE_VERIFIER_LENGTH, MAX_CODE_VERIFIER_LENGTH, DEFAULT_CODE_VERIFIER_LENGTH, PkceError, type PkcePair, type SecretData, type SecretPersistenceOptions, type SecretValidationResult, secretDataSchema, validateSecretData, parseSecretData, isSecretPersistenceEnabled, resolveSecretPath, loadSecret, saveSecret, deleteSecret, generateSecret, createSecretData, getOrCreateSecret, clearCachedSecret, isSecretCached, type SignedData, type HmacSigningConfig, signData, verifyData, isSignedData, verifyOrParseData, type BaseKeyData, type SecretKeyData, type AsymmetricKeyData, type AnyKeyData, type KeyPersistenceOptions, type CreateKeyPersistenceOptions, type CreateSecretOptions, type CreateAsymmetricOptions, type KeyValidationResult, asymmetricAlgSchema, secretKeyDataSchema, asymmetricKeyDataSchema, anyKeyDataSchema, validateKeyData, parseKeyData, isSecretKeyData, isAsymmetricKeyData, KeyPersistence, createKeyPersistence, createKeyPersistenceWithStorage, } from './crypto';
|
|
23
24
|
export type { CryptoProvider, EncBlob, EncryptedBlob } from './crypto';
|
|
@@ -27,7 +28,7 @@ export { getEnv, getNodeEnv, getCwd, isProduction, isDevelopment, getEnvFlag, is
|
|
|
27
28
|
export type { RuntimeContext, EntryAvailability } from './env';
|
|
28
29
|
export { analyzePattern, isPatternSafe, createSafeRegExp, safeTest, safeMatch, safeReplace, safeExec, isInputLengthSafe, DEFAULT_MAX_INPUT_LENGTH, REDOS_THRESHOLDS, trimLeading, trimTrailing, trimBoth, trimChars, extractBracedParams, expandTemplate, hasTemplatePlaceholders, collapseChar, collapseWhitespace, type SafeRegexOptions, type PatternAnalysisResult, } from './regex';
|
|
29
30
|
export { createStorage, createMemoryStorage, getDetectedStorageType, NamespacedStorageImpl, createRootStorage, createNamespacedStorage, buildPrefix, NAMESPACE_SEPARATOR, StorageError, StorageConnectionError, StorageOperationError, StorageNotSupportedError, StorageConfigError, StorageTTLError, StoragePatternError, StorageNotConnectedError, EncryptedStorageError, BaseStorageAdapter, MemoryStorageAdapter, RedisStorageAdapter, createRedisClient, VercelKvStorageAdapter, createVercelKvClient, type VercelKvConnection, UpstashStorageAdapter, FileSystemStorageAdapter, type FileSystemAdapterOptions, TypedStorage, type TypedStorageOptions, type TypedSetOptions, type TypedSetEntry, EncryptedTypedStorage, type EncryptedTypedStorageOptions, type EncryptedSetOptions, type EncryptedSetEntry, type EncryptionKey, type StoredEncryptedBlob, type ClientKeyBinding, globToRegex, matchesPattern, validatePattern, escapeGlob, MAX_TTL_SECONDS, validateTTL, validateOptionalTTL, ttlToExpiresAt, expiresAtToTTL, isExpired, normalizeTTL, attachRedisErrorListener, DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS, mergeRedisUrlFields, describeRedisUrlConflicts, } from './storage';
|
|
30
|
-
export type { StorageAdapter, NamespacedStorage, RootStorage, SetOptions, SetEntry, MessageHandler, Unsubscribe, MemoryAdapterOptions, RedisAdapterOptions, RedisHostConnectionConfig, RedisUrlConnectionConfig, RedisUrlFillInConfig, VercelKvAdapterOptions, UpstashAdapterOptions, StorageType, StorageConfig, RedisErrorListenerOptions, RedisUrlMerge, RedisUrlSiblingFields, CreateRedisClientOptions, ErrorEmitterClient, } from './storage';
|
|
31
|
+
export type { StorageAdapter, NamespacedStorage, RootStorage, SetOptions, SetEntry, MessageHandler, Unsubscribe, MemoryAdapterOptions, RedisAdapterOptions, RedisHostConnectionConfig, RedisUrlConnectionConfig, RedisUrlFillInConfig, VercelKvAdapterOptions, UpstashAdapterOptions, StorageType, StorageConfig, RedisErrorListenerOptions, RedisUrlConnection, RedisUrlMerge, RedisUrlSiblingFields, CreateRedisClientOptions, ErrorEmitterClient, } from './storage';
|
|
31
32
|
export { processPlatformToolCalls } from './llm';
|
|
32
33
|
export type { CallToolFn, OpenAIToolCallItem, OpenAIToolResponse, ClaudeToolUseBlock, ClaudeToolResultBlock, VercelToolCallInfo, PlatformToolCallsInput, PlatformToolCallsOutput, SupportedPlatform, } from './llm';
|
|
33
34
|
export { getMachineId, setMachineIdOverride } from './machine-id';
|