@frontmcp/utils 1.8.6 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/env/browser-env.d.ts +1 -0
- package/env/browser-env.js +5 -0
- package/env/browser-runtime-context.d.ts +2 -1
- package/env/browser-runtime-context.js +104 -0
- package/env/index.d.ts +1 -1
- package/env/node-env.d.ts +11 -0
- package/env/node-env.js +8 -2
- package/env/runtime-context.d.ts +12 -5
- package/env/runtime-context.js +192 -0
- package/esm/async-context/browser-async-context.mjs +3 -2
- package/esm/async-context/node-async-context.mjs +3 -2
- package/esm/crypto/browser.mjs +3 -2
- package/esm/crypto/node.mjs +3 -2
- package/esm/env/browser-env.mjs +7 -2
- package/esm/env/browser-runtime-context.mjs +77 -0
- package/esm/env/node-env.mjs +10 -4
- package/esm/env/runtime-context.mjs +172 -0
- package/esm/event-emitter/browser-event-emitter.mjs +3 -2
- package/esm/event-emitter/node-event-emitter.mjs +3 -2
- package/esm/index.mjs +251 -250
- package/esm/path/browser-path.mjs +50 -0
- package/esm/path/node-path.mjs +16 -0
- package/index.d.ts +3 -3
- package/index.js +261 -274
- package/package.json +26 -8
- package/path/browser-path.js +79 -0
- package/path/node-path.js +45 -0
- package/storage/adapters/base.d.ts +6 -1
- package/storage/adapters/cloudflare-kv.d.ts +1 -0
- package/storage/adapters/index.d.ts +2 -1
- package/storage/adapters/memory.d.ts +2 -1
- package/storage/adapters/redis.d.ts +19 -0
- package/storage/adapters/upstash.d.ts +2 -1
- package/storage/adapters/vercel-kv.d.ts +2 -1
- package/storage/index.d.ts +4 -2
- package/storage/namespace.d.ts +2 -1
- package/storage/redis-error-listener.d.ts +27 -0
- package/storage/types.d.ts +11 -0
- package/storage/utils/compare-and-delete.d.ts +2 -0
package/index.js
CHANGED
|
@@ -596,9 +596,9 @@ function createSecretData(options) {
|
|
|
596
596
|
}
|
|
597
597
|
async function getOrCreateSecret(options) {
|
|
598
598
|
const cacheKey = resolveSecretPath(options);
|
|
599
|
-
const
|
|
600
|
-
if (
|
|
601
|
-
return
|
|
599
|
+
const cached = secretCache.get(cacheKey);
|
|
600
|
+
if (cached) {
|
|
601
|
+
return cached;
|
|
602
602
|
}
|
|
603
603
|
const existing = generationPromises.get(cacheKey);
|
|
604
604
|
if (existing) {
|
|
@@ -836,8 +836,8 @@ var init_key_persistence = __esm({
|
|
|
836
836
|
*/
|
|
837
837
|
async get(kid) {
|
|
838
838
|
if (this.enableCache) {
|
|
839
|
-
const
|
|
840
|
-
if (
|
|
839
|
+
const cached = this.cache.get(kid);
|
|
840
|
+
if (cached) return cached;
|
|
841
841
|
}
|
|
842
842
|
const raw = await this.storage.get(kid);
|
|
843
843
|
if (!raw) return null;
|
|
@@ -1088,6 +1088,75 @@ var init_errors = __esm({
|
|
|
1088
1088
|
}
|
|
1089
1089
|
});
|
|
1090
1090
|
|
|
1091
|
+
// libs/utils/src/storage/utils/pattern.ts
|
|
1092
|
+
function globToRegex(pattern) {
|
|
1093
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
1094
|
+
throw new StoragePatternError(
|
|
1095
|
+
pattern.substring(0, 50) + "...",
|
|
1096
|
+
`Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
const wildcardCount = (pattern.match(/[*?]/g) || []).length;
|
|
1100
|
+
if (wildcardCount > MAX_WILDCARDS) {
|
|
1101
|
+
throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
|
|
1102
|
+
}
|
|
1103
|
+
if (pattern === "" || pattern === "*") {
|
|
1104
|
+
return /^.*$/;
|
|
1105
|
+
}
|
|
1106
|
+
let regexStr = "^";
|
|
1107
|
+
let prevChar = "";
|
|
1108
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
1109
|
+
const char = pattern[i];
|
|
1110
|
+
switch (char) {
|
|
1111
|
+
case "*":
|
|
1112
|
+
if (prevChar !== "*") {
|
|
1113
|
+
regexStr += ".*";
|
|
1114
|
+
}
|
|
1115
|
+
break;
|
|
1116
|
+
case "?":
|
|
1117
|
+
regexStr += ".";
|
|
1118
|
+
break;
|
|
1119
|
+
default:
|
|
1120
|
+
regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
|
|
1121
|
+
}
|
|
1122
|
+
prevChar = char;
|
|
1123
|
+
}
|
|
1124
|
+
regexStr += "$";
|
|
1125
|
+
try {
|
|
1126
|
+
return new RegExp(regexStr);
|
|
1127
|
+
} catch {
|
|
1128
|
+
throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
function matchesPattern(key, pattern) {
|
|
1132
|
+
const regex = globToRegex(pattern);
|
|
1133
|
+
return regex.test(key);
|
|
1134
|
+
}
|
|
1135
|
+
function validatePattern(pattern) {
|
|
1136
|
+
try {
|
|
1137
|
+
globToRegex(pattern);
|
|
1138
|
+
return { valid: true };
|
|
1139
|
+
} catch (e) {
|
|
1140
|
+
return {
|
|
1141
|
+
valid: false,
|
|
1142
|
+
error: e instanceof Error ? e.message : "Invalid pattern"
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
function escapeGlob(literal) {
|
|
1147
|
+
return literal.replace(/[*?\\]/g, "\\$&");
|
|
1148
|
+
}
|
|
1149
|
+
var MAX_PATTERN_LENGTH, MAX_WILDCARDS, REGEX_SPECIAL_CHARS;
|
|
1150
|
+
var init_pattern = __esm({
|
|
1151
|
+
"libs/utils/src/storage/utils/pattern.ts"() {
|
|
1152
|
+
"use strict";
|
|
1153
|
+
init_errors();
|
|
1154
|
+
MAX_PATTERN_LENGTH = 500;
|
|
1155
|
+
MAX_WILDCARDS = 20;
|
|
1156
|
+
REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
|
|
1091
1160
|
// libs/utils/src/storage/utils/ttl.ts
|
|
1092
1161
|
function validateTTL(ttlSeconds) {
|
|
1093
1162
|
if (typeof ttlSeconds !== "number") {
|
|
@@ -1202,6 +1271,17 @@ var init_base = __esm({
|
|
|
1202
1271
|
const matchedKeys = await this.keys(pattern);
|
|
1203
1272
|
return matchedKeys.length;
|
|
1204
1273
|
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Default: not supported, since a read followed by a delete is not atomic.
|
|
1276
|
+
* Override in adapters whose backend can compare and delete in one step.
|
|
1277
|
+
*/
|
|
1278
|
+
async deleteIfEquals(_key, _expectedValue) {
|
|
1279
|
+
throw new StorageNotSupportedError(
|
|
1280
|
+
"deleteIfEquals",
|
|
1281
|
+
this.backendName,
|
|
1282
|
+
"Use the memory, Redis, Upstash or Vercel KV adapter for an atomic compare-and-delete."
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1205
1285
|
// ============================================
|
|
1206
1286
|
// Pub/Sub (default: not supported)
|
|
1207
1287
|
// ============================================
|
|
@@ -1250,85 +1330,16 @@ var init_base = __esm({
|
|
|
1250
1330
|
}
|
|
1251
1331
|
});
|
|
1252
1332
|
|
|
1253
|
-
// libs/utils/src/storage/utils/pattern.ts
|
|
1254
|
-
function globToRegex(pattern) {
|
|
1255
|
-
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
1256
|
-
throw new StoragePatternError(
|
|
1257
|
-
pattern.substring(0, 50) + "...",
|
|
1258
|
-
`Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
|
|
1259
|
-
);
|
|
1260
|
-
}
|
|
1261
|
-
const wildcardCount = (pattern.match(/[*?]/g) || []).length;
|
|
1262
|
-
if (wildcardCount > MAX_WILDCARDS) {
|
|
1263
|
-
throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
|
|
1264
|
-
}
|
|
1265
|
-
if (pattern === "" || pattern === "*") {
|
|
1266
|
-
return /^.*$/;
|
|
1267
|
-
}
|
|
1268
|
-
let regexStr = "^";
|
|
1269
|
-
let prevChar = "";
|
|
1270
|
-
for (let i = 0; i < pattern.length; i++) {
|
|
1271
|
-
const char = pattern[i];
|
|
1272
|
-
switch (char) {
|
|
1273
|
-
case "*":
|
|
1274
|
-
if (prevChar !== "*") {
|
|
1275
|
-
regexStr += ".*";
|
|
1276
|
-
}
|
|
1277
|
-
break;
|
|
1278
|
-
case "?":
|
|
1279
|
-
regexStr += ".";
|
|
1280
|
-
break;
|
|
1281
|
-
default:
|
|
1282
|
-
regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
|
|
1283
|
-
}
|
|
1284
|
-
prevChar = char;
|
|
1285
|
-
}
|
|
1286
|
-
regexStr += "$";
|
|
1287
|
-
try {
|
|
1288
|
-
return new RegExp(regexStr);
|
|
1289
|
-
} catch {
|
|
1290
|
-
throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
function matchesPattern(key, pattern) {
|
|
1294
|
-
const regex = globToRegex(pattern);
|
|
1295
|
-
return regex.test(key);
|
|
1296
|
-
}
|
|
1297
|
-
function validatePattern(pattern) {
|
|
1298
|
-
try {
|
|
1299
|
-
globToRegex(pattern);
|
|
1300
|
-
return { valid: true };
|
|
1301
|
-
} catch (e) {
|
|
1302
|
-
return {
|
|
1303
|
-
valid: false,
|
|
1304
|
-
error: e instanceof Error ? e.message : "Invalid pattern"
|
|
1305
|
-
};
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
function escapeGlob(literal) {
|
|
1309
|
-
return literal.replace(/[*?\\]/g, "\\$&");
|
|
1310
|
-
}
|
|
1311
|
-
var MAX_PATTERN_LENGTH, MAX_WILDCARDS, REGEX_SPECIAL_CHARS;
|
|
1312
|
-
var init_pattern = __esm({
|
|
1313
|
-
"libs/utils/src/storage/utils/pattern.ts"() {
|
|
1314
|
-
"use strict";
|
|
1315
|
-
init_errors();
|
|
1316
|
-
MAX_PATTERN_LENGTH = 500;
|
|
1317
|
-
MAX_WILDCARDS = 20;
|
|
1318
|
-
REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
|
|
1319
|
-
}
|
|
1320
|
-
});
|
|
1321
|
-
|
|
1322
1333
|
// libs/utils/src/storage/adapters/memory.ts
|
|
1323
1334
|
var import_event_emitter, DEFAULT_SWEEP_INTERVAL_SECONDS, MAX_TIMEOUT_MS, MemoryStorageAdapter;
|
|
1324
1335
|
var init_memory = __esm({
|
|
1325
1336
|
"libs/utils/src/storage/adapters/memory.ts"() {
|
|
1326
1337
|
"use strict";
|
|
1327
1338
|
import_event_emitter = require("#event-emitter");
|
|
1328
|
-
init_base();
|
|
1329
1339
|
init_errors();
|
|
1330
1340
|
init_pattern();
|
|
1331
1341
|
init_ttl();
|
|
1342
|
+
init_base();
|
|
1332
1343
|
DEFAULT_SWEEP_INTERVAL_SECONDS = 60;
|
|
1333
1344
|
MAX_TIMEOUT_MS = 2147483647;
|
|
1334
1345
|
MemoryStorageAdapter = class extends BaseStorageAdapter {
|
|
@@ -1420,6 +1431,12 @@ var init_memory = __esm({
|
|
|
1420
1431
|
this.ensureConnected();
|
|
1421
1432
|
return this.deleteEntry(key);
|
|
1422
1433
|
}
|
|
1434
|
+
async deleteIfEquals(key, expectedValue) {
|
|
1435
|
+
this.ensureConnected();
|
|
1436
|
+
const entry = this.store.get(key);
|
|
1437
|
+
if (!entry || isExpired(entry.expiresAt) || entry.value !== expectedValue) return false;
|
|
1438
|
+
return this.deleteEntry(key);
|
|
1439
|
+
}
|
|
1423
1440
|
async exists(key) {
|
|
1424
1441
|
this.ensureConnected();
|
|
1425
1442
|
const entry = this.store.get(key);
|
|
@@ -2965,6 +2982,41 @@ var init_crypto = __esm({
|
|
|
2965
2982
|
}
|
|
2966
2983
|
});
|
|
2967
2984
|
|
|
2985
|
+
// libs/utils/src/storage/redis-error-listener.ts
|
|
2986
|
+
function attachRedisErrorListener(client, options = {}) {
|
|
2987
|
+
const label = options.label ?? "redis";
|
|
2988
|
+
const intervalMs = options.intervalMs ?? DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS;
|
|
2989
|
+
let lastLoggedAt = 0;
|
|
2990
|
+
let suppressed = 0;
|
|
2991
|
+
const listener = (error) => {
|
|
2992
|
+
const now = Date.now();
|
|
2993
|
+
if (lastLoggedAt !== 0 && now - lastLoggedAt < intervalMs) {
|
|
2994
|
+
suppressed++;
|
|
2995
|
+
return;
|
|
2996
|
+
}
|
|
2997
|
+
const extra = suppressed > 0 ? ` (${suppressed} similar error(s) suppressed)` : "";
|
|
2998
|
+
suppressed = 0;
|
|
2999
|
+
lastLoggedAt = now;
|
|
3000
|
+
const message = `[${label}] Redis connection error: ${error?.message ?? String(error)}${extra}`;
|
|
3001
|
+
if (options.logger) {
|
|
3002
|
+
options.logger.warn(message);
|
|
3003
|
+
} else {
|
|
3004
|
+
console.warn(message);
|
|
3005
|
+
}
|
|
3006
|
+
};
|
|
3007
|
+
client.on("error", listener);
|
|
3008
|
+
return () => {
|
|
3009
|
+
client.removeListener("error", listener);
|
|
3010
|
+
};
|
|
3011
|
+
}
|
|
3012
|
+
var DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS;
|
|
3013
|
+
var init_redis_error_listener = __esm({
|
|
3014
|
+
"libs/utils/src/storage/redis-error-listener.ts"() {
|
|
3015
|
+
"use strict";
|
|
3016
|
+
DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS = 3e4;
|
|
3017
|
+
}
|
|
3018
|
+
});
|
|
3019
|
+
|
|
2968
3020
|
// libs/utils/src/storage/utils/index.ts
|
|
2969
3021
|
var init_utils = __esm({
|
|
2970
3022
|
"libs/utils/src/storage/utils/index.ts"() {
|
|
@@ -2973,10 +3025,20 @@ var init_utils = __esm({
|
|
|
2973
3025
|
}
|
|
2974
3026
|
});
|
|
2975
3027
|
|
|
3028
|
+
// libs/utils/src/storage/utils/compare-and-delete.ts
|
|
3029
|
+
var COMPARE_AND_DELETE_SCRIPT;
|
|
3030
|
+
var init_compare_and_delete = __esm({
|
|
3031
|
+
"libs/utils/src/storage/utils/compare-and-delete.ts"() {
|
|
3032
|
+
"use strict";
|
|
3033
|
+
COMPARE_AND_DELETE_SCRIPT = `if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end return 0`;
|
|
3034
|
+
}
|
|
3035
|
+
});
|
|
3036
|
+
|
|
2976
3037
|
// libs/utils/src/storage/adapters/redis.ts
|
|
2977
3038
|
var redis_exports = {};
|
|
2978
3039
|
__export(redis_exports, {
|
|
2979
|
-
RedisStorageAdapter: () => RedisStorageAdapter
|
|
3040
|
+
RedisStorageAdapter: () => RedisStorageAdapter,
|
|
3041
|
+
createRedisClient: () => createRedisClient
|
|
2980
3042
|
});
|
|
2981
3043
|
function getRedisClass() {
|
|
2982
3044
|
try {
|
|
@@ -2994,12 +3056,28 @@ function getRedisClass() {
|
|
|
2994
3056
|
});
|
|
2995
3057
|
}
|
|
2996
3058
|
}
|
|
3059
|
+
function createRedisClient(options) {
|
|
3060
|
+
const RedisClass = getRedisClass();
|
|
3061
|
+
const baseOptions = { lazyConnect: false, maxRetriesPerRequest: 3 };
|
|
3062
|
+
const client = options.url ? new RedisClass(options.url, baseOptions) : new RedisClass({
|
|
3063
|
+
...baseOptions,
|
|
3064
|
+
host: options.host ?? "localhost",
|
|
3065
|
+
port: options.port ?? 6379,
|
|
3066
|
+
password: options.password,
|
|
3067
|
+
db: options.db ?? 0,
|
|
3068
|
+
tls: options.tls ? {} : void 0
|
|
3069
|
+
});
|
|
3070
|
+
attachRedisErrorListener(client, { label: options.label ?? "redis", logger: options.logger });
|
|
3071
|
+
return client;
|
|
3072
|
+
}
|
|
2997
3073
|
var RedisStorageAdapter;
|
|
2998
3074
|
var init_redis = __esm({
|
|
2999
3075
|
"libs/utils/src/storage/adapters/redis.ts"() {
|
|
3000
3076
|
"use strict";
|
|
3001
3077
|
init_errors();
|
|
3078
|
+
init_redis_error_listener();
|
|
3002
3079
|
init_utils();
|
|
3080
|
+
init_compare_and_delete();
|
|
3003
3081
|
init_base();
|
|
3004
3082
|
RedisStorageAdapter = class extends BaseStorageAdapter {
|
|
3005
3083
|
backendName = "redis";
|
|
@@ -3007,6 +3085,7 @@ var init_redis = __esm({
|
|
|
3007
3085
|
subscriber;
|
|
3008
3086
|
options;
|
|
3009
3087
|
ownsClient;
|
|
3088
|
+
detachErrorListener;
|
|
3010
3089
|
connecting;
|
|
3011
3090
|
keyPrefix;
|
|
3012
3091
|
subscriptionHandlers = /* @__PURE__ */ new Map();
|
|
@@ -3063,7 +3142,10 @@ var init_redis = __esm({
|
|
|
3063
3142
|
await client.ping();
|
|
3064
3143
|
this.client = client;
|
|
3065
3144
|
this.connected = true;
|
|
3066
|
-
if (this.ownsClient)
|
|
3145
|
+
if (this.ownsClient) {
|
|
3146
|
+
client.removeListener("error", recordSocketError);
|
|
3147
|
+
this.detachErrorListener = attachRedisErrorListener(client, { label: "RedisStorage" });
|
|
3148
|
+
}
|
|
3067
3149
|
} catch (e) {
|
|
3068
3150
|
if (this.ownsClient && client) {
|
|
3069
3151
|
try {
|
|
@@ -3084,6 +3166,8 @@ var init_redis = __esm({
|
|
|
3084
3166
|
if (this.ownsClient && this.client) {
|
|
3085
3167
|
await this.client.quit();
|
|
3086
3168
|
}
|
|
3169
|
+
this.detachErrorListener?.();
|
|
3170
|
+
this.detachErrorListener = void 0;
|
|
3087
3171
|
this.client = void 0;
|
|
3088
3172
|
this.connected = false;
|
|
3089
3173
|
this.subscriptionHandlers.clear();
|
|
@@ -3148,6 +3232,15 @@ var init_redis = __esm({
|
|
|
3148
3232
|
const result = await this.getConnectedClient().del(this.prefixKey(key));
|
|
3149
3233
|
return result > 0;
|
|
3150
3234
|
}
|
|
3235
|
+
async deleteIfEquals(key, expectedValue) {
|
|
3236
|
+
const deleted = await this.getConnectedClient().eval(
|
|
3237
|
+
COMPARE_AND_DELETE_SCRIPT,
|
|
3238
|
+
1,
|
|
3239
|
+
this.prefixKey(key),
|
|
3240
|
+
expectedValue
|
|
3241
|
+
);
|
|
3242
|
+
return deleted === 1;
|
|
3243
|
+
}
|
|
3151
3244
|
async exists(key) {
|
|
3152
3245
|
const result = await this.getConnectedClient().exists(this.prefixKey(key));
|
|
3153
3246
|
return result > 0;
|
|
@@ -3311,6 +3404,7 @@ var init_redis = __esm({
|
|
|
3311
3404
|
} else {
|
|
3312
3405
|
throw new StorageConfigError("redis", "Cannot create subscriber without url, config, or client");
|
|
3313
3406
|
}
|
|
3407
|
+
attachRedisErrorListener(subscriber, { label: "RedisStorage:subscriber" });
|
|
3314
3408
|
subscriber.on("message", (channel, message) => {
|
|
3315
3409
|
const handlers = this.subscriptionHandlers.get(channel);
|
|
3316
3410
|
if (handlers) {
|
|
@@ -3355,9 +3449,12 @@ var vercel_kv_exports = {};
|
|
|
3355
3449
|
__export(vercel_kv_exports, {
|
|
3356
3450
|
VercelKvStorageAdapter: () => VercelKvStorageAdapter
|
|
3357
3451
|
});
|
|
3358
|
-
function
|
|
3452
|
+
async function loadVercelKv() {
|
|
3359
3453
|
try {
|
|
3360
|
-
|
|
3454
|
+
const mod = await import("@vercel/kv");
|
|
3455
|
+
const resolved = typeof mod.createClient === "function" ? mod : mod.default;
|
|
3456
|
+
if (!resolved || typeof resolved.createClient !== "function") throw new Error("createClient missing");
|
|
3457
|
+
return resolved;
|
|
3361
3458
|
} catch {
|
|
3362
3459
|
throw new Error("@vercel/kv is required for Vercel KV storage adapter. Install it with: npm install @vercel/kv");
|
|
3363
3460
|
}
|
|
@@ -3366,9 +3463,10 @@ var VercelKvStorageAdapter;
|
|
|
3366
3463
|
var init_vercel_kv = __esm({
|
|
3367
3464
|
"libs/utils/src/storage/adapters/vercel-kv.ts"() {
|
|
3368
3465
|
"use strict";
|
|
3369
|
-
init_base();
|
|
3370
3466
|
init_errors();
|
|
3467
|
+
init_compare_and_delete();
|
|
3371
3468
|
init_ttl();
|
|
3469
|
+
init_base();
|
|
3372
3470
|
VercelKvStorageAdapter = class extends BaseStorageAdapter {
|
|
3373
3471
|
backendName = "vercel-kv";
|
|
3374
3472
|
client;
|
|
@@ -3393,17 +3491,13 @@ var init_vercel_kv = __esm({
|
|
|
3393
3491
|
async connect() {
|
|
3394
3492
|
if (this.connected) return;
|
|
3395
3493
|
try {
|
|
3396
|
-
const { createClient
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
const token = this.options.token;
|
|
3402
|
-
if (!url || !token) {
|
|
3403
|
-
throw new StorageConfigError("vercel-kv", "URL and token are required");
|
|
3404
|
-
}
|
|
3405
|
-
this.client = createClient({ url, token });
|
|
3494
|
+
const { createClient } = await loadVercelKv();
|
|
3495
|
+
const url = this.options.url;
|
|
3496
|
+
const token = this.options.token;
|
|
3497
|
+
if (!url || !token) {
|
|
3498
|
+
throw new StorageConfigError("vercel-kv", "URL and token are required");
|
|
3406
3499
|
}
|
|
3500
|
+
this.client = createClient({ url, token, cache: void 0 });
|
|
3407
3501
|
await this.client.exists("__healthcheck__");
|
|
3408
3502
|
this.connected = true;
|
|
3409
3503
|
} catch (e) {
|
|
@@ -3465,6 +3559,14 @@ var init_vercel_kv = __esm({
|
|
|
3465
3559
|
const result = await this.getConnectedClient().del(this.prefixKey(key));
|
|
3466
3560
|
return result > 0;
|
|
3467
3561
|
}
|
|
3562
|
+
async deleteIfEquals(key, expectedValue) {
|
|
3563
|
+
const deleted = await this.getConnectedClient().eval(
|
|
3564
|
+
COMPARE_AND_DELETE_SCRIPT,
|
|
3565
|
+
[this.prefixKey(key)],
|
|
3566
|
+
[expectedValue]
|
|
3567
|
+
);
|
|
3568
|
+
return deleted === 1;
|
|
3569
|
+
}
|
|
3468
3570
|
async exists(key) {
|
|
3469
3571
|
const result = await this.getConnectedClient().exists(this.prefixKey(key));
|
|
3470
3572
|
return result > 0;
|
|
@@ -3582,9 +3684,10 @@ var PUBSUB_POLL_INTERVAL_MS, UpstashStorageAdapter;
|
|
|
3582
3684
|
var init_upstash = __esm({
|
|
3583
3685
|
"libs/utils/src/storage/adapters/upstash.ts"() {
|
|
3584
3686
|
"use strict";
|
|
3585
|
-
init_base();
|
|
3586
3687
|
init_errors();
|
|
3688
|
+
init_compare_and_delete();
|
|
3587
3689
|
init_ttl();
|
|
3690
|
+
init_base();
|
|
3588
3691
|
PUBSUB_POLL_INTERVAL_MS = 100;
|
|
3589
3692
|
UpstashStorageAdapter = class extends BaseStorageAdapter {
|
|
3590
3693
|
backendName = "upstash";
|
|
@@ -3689,6 +3792,14 @@ var init_upstash = __esm({
|
|
|
3689
3792
|
const result = await this.getConnectedClient().del(this.prefixKey(key));
|
|
3690
3793
|
return result > 0;
|
|
3691
3794
|
}
|
|
3795
|
+
async deleteIfEquals(key, expectedValue) {
|
|
3796
|
+
const deleted = await this.getConnectedClient().eval(
|
|
3797
|
+
COMPARE_AND_DELETE_SCRIPT,
|
|
3798
|
+
[this.prefixKey(key)],
|
|
3799
|
+
[expectedValue]
|
|
3800
|
+
);
|
|
3801
|
+
return deleted === 1;
|
|
3802
|
+
}
|
|
3692
3803
|
async exists(key) {
|
|
3693
3804
|
const result = await this.getConnectedClient().exists(this.prefixKey(key));
|
|
3694
3805
|
return result > 0;
|
|
@@ -3878,7 +3989,9 @@ var init_cloudflare_kv = __esm({
|
|
|
3878
3989
|
constructor(options) {
|
|
3879
3990
|
super();
|
|
3880
3991
|
if (!options?.namespace) {
|
|
3881
|
-
throw new Error(
|
|
3992
|
+
throw new Error(
|
|
3993
|
+
"CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`)."
|
|
3994
|
+
);
|
|
3882
3995
|
}
|
|
3883
3996
|
this.kv = options.namespace;
|
|
3884
3997
|
this.keyPrefix = options.keyPrefix ?? "";
|
|
@@ -3972,6 +4085,13 @@ var init_cloudflare_kv = __esm({
|
|
|
3972
4085
|
"Cloudflare KV has no atomic increment (a get+put is racy under eventual consistency). Use a Durable Object for atomic counters."
|
|
3973
4086
|
);
|
|
3974
4087
|
}
|
|
4088
|
+
async deleteIfEquals(_key, _expectedValue) {
|
|
4089
|
+
throw new StorageNotSupportedError(
|
|
4090
|
+
"deleteIfEquals",
|
|
4091
|
+
this.backendName,
|
|
4092
|
+
"Cloudflare KV has no compare-and-set; use a Durable Object for an atomic compare-and-delete."
|
|
4093
|
+
);
|
|
4094
|
+
}
|
|
3975
4095
|
// ── Pub/Sub (unsupported) ────────────────────────────────────────────────
|
|
3976
4096
|
getPubSubSuggestion() {
|
|
3977
4097
|
return "Cloudflare KV does not support pub/sub. Use a Durable Object (or Queues) for fan-out.";
|
|
@@ -4007,6 +4127,7 @@ __export(index_exports, {
|
|
|
4007
4127
|
BaseStorageAdapter: () => BaseStorageAdapter,
|
|
4008
4128
|
DEFAULT_CODE_VERIFIER_LENGTH: () => DEFAULT_CODE_VERIFIER_LENGTH,
|
|
4009
4129
|
DEFAULT_MAX_INPUT_LENGTH: () => DEFAULT_MAX_INPUT_LENGTH,
|
|
4130
|
+
DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS: () => DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS,
|
|
4010
4131
|
EncryptedBlobError: () => EncryptedBlobError,
|
|
4011
4132
|
EncryptedStorageError: () => EncryptedStorageError,
|
|
4012
4133
|
EncryptedTypedStorage: () => EncryptedTypedStorage,
|
|
@@ -4039,16 +4160,17 @@ __export(index_exports, {
|
|
|
4039
4160
|
assertNode: () => assertNode,
|
|
4040
4161
|
asymmetricAlgSchema: () => asymmetricAlgSchema,
|
|
4041
4162
|
asymmetricKeyDataSchema: () => asymmetricKeyDataSchema,
|
|
4163
|
+
attachRedisErrorListener: () => attachRedisErrorListener,
|
|
4042
4164
|
awaitOutsideRequest: () => import_async_context.awaitOutsideRequest,
|
|
4043
4165
|
base64Decode: () => base64Decode,
|
|
4044
4166
|
base64Encode: () => base64Encode,
|
|
4045
4167
|
base64urlDecode: () => base64urlDecode,
|
|
4046
4168
|
base64urlEncode: () => base64urlEncode,
|
|
4047
|
-
basename: () =>
|
|
4169
|
+
basename: () => import_path2.basename,
|
|
4048
4170
|
buildPrefix: () => buildPrefix,
|
|
4049
4171
|
buildSetCookie: () => buildSetCookie,
|
|
4050
4172
|
bytesToHex: () => bytesToHex,
|
|
4051
|
-
checkEntryAvailability: () => checkEntryAvailability,
|
|
4173
|
+
checkEntryAvailability: () => import_runtime_context.checkEntryAvailability,
|
|
4052
4174
|
classifyIpAddress: () => classifyIpAddress,
|
|
4053
4175
|
clearCachedSecret: () => clearCachedSecret,
|
|
4054
4176
|
collapseChar: () => collapseChar,
|
|
@@ -4059,6 +4181,7 @@ __export(index_exports, {
|
|
|
4059
4181
|
createKeyPersistenceWithStorage: () => createKeyPersistenceWithStorage,
|
|
4060
4182
|
createMemoryStorage: () => createMemoryStorage,
|
|
4061
4183
|
createNamespacedStorage: () => createNamespacedStorage,
|
|
4184
|
+
createRedisClient: () => createRedisClient,
|
|
4062
4185
|
createRootStorage: () => createRootStorage,
|
|
4063
4186
|
createSafeRegExp: () => createSafeRegExp,
|
|
4064
4187
|
createSecretData: () => createSecretData,
|
|
@@ -4068,15 +4191,15 @@ __export(index_exports, {
|
|
|
4068
4191
|
deleteSecret: () => deleteSecret,
|
|
4069
4192
|
deserializeAndDecrypt: () => deserializeAndDecrypt,
|
|
4070
4193
|
deserializeBlob: () => deserializeBlob,
|
|
4071
|
-
detectRuntimeContext: () => detectRuntimeContext,
|
|
4072
|
-
dirname: () =>
|
|
4194
|
+
detectRuntimeContext: () => import_runtime_context.detectRuntimeContext,
|
|
4195
|
+
dirname: () => import_path2.dirname,
|
|
4073
4196
|
encryptAesGcm: () => encryptAesGcm,
|
|
4074
4197
|
encryptAndSerialize: () => encryptAndSerialize,
|
|
4075
4198
|
encryptValue: () => encryptValue,
|
|
4076
4199
|
ensureDir: () => ensureDir,
|
|
4077
4200
|
ensureDirSync: () => ensureDirSync,
|
|
4078
4201
|
ensureMaxLen: () => ensureMaxLen,
|
|
4079
|
-
entryAvailabilitySchema: () => entryAvailabilitySchema,
|
|
4202
|
+
entryAvailabilitySchema: () => import_runtime_context.entryAvailabilitySchema,
|
|
4080
4203
|
escapeGlob: () => escapeGlob,
|
|
4081
4204
|
escapeHtml: () => escapeHtml,
|
|
4082
4205
|
escapeHtmlAttr: () => escapeHtmlAttr,
|
|
@@ -4086,7 +4209,7 @@ __export(index_exports, {
|
|
|
4086
4209
|
expandTemplate: () => expandTemplate,
|
|
4087
4210
|
expandUriTemplate: () => expandUriTemplate,
|
|
4088
4211
|
expiresAtToTTL: () => expiresAtToTTL,
|
|
4089
|
-
extname: () =>
|
|
4212
|
+
extname: () => import_path2.extname,
|
|
4090
4213
|
extractBracedParams: () => extractBracedParams,
|
|
4091
4214
|
extractEmbeddedIpv4: () => extractEmbeddedIpv4,
|
|
4092
4215
|
extractTemplateParams: () => extractTemplateParams,
|
|
@@ -4101,13 +4224,14 @@ __export(index_exports, {
|
|
|
4101
4224
|
getAsyncContextMode: () => import_async_context.getAsyncContextMode,
|
|
4102
4225
|
getCookie: () => getCookie,
|
|
4103
4226
|
getCrypto: () => getCrypto,
|
|
4104
|
-
getCwd: () =>
|
|
4227
|
+
getCwd: () => import_env2.getCwd,
|
|
4105
4228
|
getDetectedStorageType: () => getDetectedStorageType,
|
|
4106
|
-
getEnv: () =>
|
|
4107
|
-
getEnvFlag: () =>
|
|
4229
|
+
getEnv: () => import_env2.getEnv,
|
|
4230
|
+
getEnvFlag: () => import_env2.getEnvFlag,
|
|
4108
4231
|
getMachineId: () => getMachineId,
|
|
4232
|
+
getNodeEnv: () => import_env2.getNodeEnv,
|
|
4109
4233
|
getOrCreateSecret: () => getOrCreateSecret,
|
|
4110
|
-
getRuntimeContext: () => getRuntimeContext,
|
|
4234
|
+
getRuntimeContext: () => import_runtime_context.getRuntimeContext,
|
|
4111
4235
|
getSpawnFn: () => getSpawnFn,
|
|
4112
4236
|
globToRegex: () => globToRegex,
|
|
4113
4237
|
hasTemplatePlaceholders: () => hasTemplatePlaceholders,
|
|
@@ -4115,27 +4239,27 @@ __export(index_exports, {
|
|
|
4115
4239
|
hmacSha256: () => hmacSha256,
|
|
4116
4240
|
idFromString: () => idFromString,
|
|
4117
4241
|
inferMimeType: () => inferMimeType,
|
|
4118
|
-
isAbsolute: () =>
|
|
4242
|
+
isAbsolute: () => import_path2.isAbsolute,
|
|
4119
4243
|
isAsymmetricKeyData: () => isAsymmetricKeyData,
|
|
4120
4244
|
isBrowser: () => isBrowser,
|
|
4121
|
-
isDebug: () =>
|
|
4122
|
-
isDevelopment: () =>
|
|
4245
|
+
isDebug: () => import_env2.isDebug,
|
|
4246
|
+
isDevelopment: () => import_env2.isDevelopment,
|
|
4123
4247
|
isDirEmpty: () => isDirEmpty,
|
|
4124
|
-
isEdgeRuntime: () =>
|
|
4125
|
-
isEntryAvailable: () => isEntryAvailable,
|
|
4248
|
+
isEdgeRuntime: () => import_env2.isEdgeRuntime,
|
|
4249
|
+
isEntryAvailable: () => import_runtime_context.isEntryAvailable,
|
|
4126
4250
|
isExpired: () => isExpired,
|
|
4127
4251
|
isInputLengthSafe: () => isInputLengthSafe,
|
|
4128
4252
|
isLocalhost: () => isLocalhost,
|
|
4129
4253
|
isNode: () => isNode,
|
|
4130
4254
|
isPatternSafe: () => isPatternSafe,
|
|
4131
|
-
isProduction: () =>
|
|
4255
|
+
isProduction: () => import_env2.isProduction,
|
|
4132
4256
|
isRedirectResponse: () => isRedirectResponse,
|
|
4133
4257
|
isRsaPssAlg: () => isRsaPssAlg,
|
|
4134
4258
|
isSecretCached: () => isSecretCached,
|
|
4135
4259
|
isSecretKeyData: () => isSecretKeyData,
|
|
4136
4260
|
isSecretPersistenceEnabled: () => isSecretPersistenceEnabled,
|
|
4137
4261
|
isSecureRequest: () => isSecureRequest,
|
|
4138
|
-
isServerless: () =>
|
|
4262
|
+
isServerless: () => import_env2.isServerless,
|
|
4139
4263
|
isSignedData: () => isSignedData,
|
|
4140
4264
|
isUriTemplate: () => isUriTemplate,
|
|
4141
4265
|
isValidCodeChallenge: () => isValidCodeChallenge,
|
|
@@ -4156,9 +4280,9 @@ __export(index_exports, {
|
|
|
4156
4280
|
parseKeyData: () => parseKeyData,
|
|
4157
4281
|
parseSecretData: () => parseSecretData,
|
|
4158
4282
|
parseUriTemplate: () => parseUriTemplate,
|
|
4159
|
-
pathJoin: () =>
|
|
4160
|
-
pathResolve: () =>
|
|
4161
|
-
pathToFileURL: () =>
|
|
4283
|
+
pathJoin: () => import_path2.join,
|
|
4284
|
+
pathResolve: () => import_path2.resolve,
|
|
4285
|
+
pathToFileURL: () => import_path2.pathToFileURL,
|
|
4162
4286
|
pemToPublicJwk: () => pemToPublicJwk2,
|
|
4163
4287
|
processPlatformToolCalls: () => processPlatformToolCalls,
|
|
4164
4288
|
randomBytes: () => randomBytes,
|
|
@@ -4171,7 +4295,7 @@ __export(index_exports, {
|
|
|
4171
4295
|
readdirSync: () => readdirSync,
|
|
4172
4296
|
realpath: () => realpath,
|
|
4173
4297
|
rename: () => rename,
|
|
4174
|
-
resetRuntimeContext: () => resetRuntimeContext,
|
|
4298
|
+
resetRuntimeContext: () => import_runtime_context.resetRuntimeContext,
|
|
4175
4299
|
resolveSecretPath: () => resolveSecretPath,
|
|
4176
4300
|
rm: () => rm,
|
|
4177
4301
|
rsaSignBase64Url: () => rsaSignBase64Url2,
|
|
@@ -4189,10 +4313,10 @@ __export(index_exports, {
|
|
|
4189
4313
|
saveSecret: () => saveSecret,
|
|
4190
4314
|
secretDataSchema: () => secretDataSchema,
|
|
4191
4315
|
secretKeyDataSchema: () => secretKeyDataSchema,
|
|
4192
|
-
sep: () =>
|
|
4316
|
+
sep: () => import_path2.sep,
|
|
4193
4317
|
sepFor: () => sepFor,
|
|
4194
4318
|
serializeBlob: () => serializeBlob,
|
|
4195
|
-
setEnv: () =>
|
|
4319
|
+
setEnv: () => import_env2.setEnv,
|
|
4196
4320
|
setMachineIdOverride: () => setMachineIdOverride,
|
|
4197
4321
|
sha256: () => sha256,
|
|
4198
4322
|
sha256Base64url: () => sha256Base64url,
|
|
@@ -4201,7 +4325,7 @@ __export(index_exports, {
|
|
|
4201
4325
|
signData: () => signData,
|
|
4202
4326
|
splitWords: () => splitWords,
|
|
4203
4327
|
stat: () => stat,
|
|
4204
|
-
supportsAnsi: () =>
|
|
4328
|
+
supportsAnsi: () => import_env2.supportsAnsi,
|
|
4205
4329
|
symlink: () => symlink,
|
|
4206
4330
|
timingSafeEqual: () => timingSafeEqual,
|
|
4207
4331
|
toCase: () => toCase,
|
|
@@ -4631,9 +4755,8 @@ function joinPath(...parts) {
|
|
|
4631
4755
|
return cleaned.length ? `/${cleaned.join("/")}` : "";
|
|
4632
4756
|
}
|
|
4633
4757
|
|
|
4634
|
-
// libs/utils/src/path/
|
|
4635
|
-
var
|
|
4636
|
-
var import_url = require("url");
|
|
4758
|
+
// libs/utils/src/path/index.ts
|
|
4759
|
+
var import_path2 = require("#path");
|
|
4637
4760
|
|
|
4638
4761
|
// libs/utils/src/content/content.ts
|
|
4639
4762
|
function sanitizeToJson(value) {
|
|
@@ -5051,161 +5174,14 @@ var import_async_context = require("#async-context");
|
|
|
5051
5174
|
var import_event_emitter2 = require("#event-emitter");
|
|
5052
5175
|
|
|
5053
5176
|
// libs/utils/src/env/index.ts
|
|
5054
|
-
var import_env3 = require("#env");
|
|
5055
|
-
|
|
5056
|
-
// libs/utils/src/env/runtime-context.ts
|
|
5057
|
-
var import_lazy_zod3 = require("@frontmcp/lazy-zod");
|
|
5058
5177
|
var import_env2 = require("#env");
|
|
5059
|
-
|
|
5060
|
-
// libs/utils/src/env/build-target.ts
|
|
5061
|
-
var cached;
|
|
5062
|
-
function getBuildTarget() {
|
|
5063
|
-
if (cached) return cached;
|
|
5064
|
-
cached = resolveBuildTarget();
|
|
5065
|
-
return cached;
|
|
5066
|
-
}
|
|
5067
|
-
function resolveBuildTarget() {
|
|
5068
|
-
const globalAny = globalThis;
|
|
5069
|
-
const fromGlobal = globalAny.FRONTMCP_BUILD_TARGET;
|
|
5070
|
-
if (typeof fromGlobal === "string" && isKnownTarget(fromGlobal)) return fromGlobal;
|
|
5071
|
-
const fromEnv = typeof process !== "undefined" ? process.env?.["FRONTMCP_BUILD_TARGET"] : void 0;
|
|
5072
|
-
if (typeof fromEnv === "string" && isKnownTarget(fromEnv)) return fromEnv;
|
|
5073
|
-
return "unknown";
|
|
5074
|
-
}
|
|
5075
|
-
function isKnownTarget(value) {
|
|
5076
|
-
return value === "unknown" || value === "node" || value === "distributed" || value === "cli" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "browser" || value === "sdk" || value === "mcpb";
|
|
5077
|
-
}
|
|
5078
|
-
|
|
5079
|
-
// libs/utils/src/env/provider.ts
|
|
5080
|
-
var cached2;
|
|
5081
|
-
function detectProvider() {
|
|
5082
|
-
if (cached2) return cached2;
|
|
5083
|
-
cached2 = detectProviderUncached();
|
|
5084
|
-
return cached2;
|
|
5085
|
-
}
|
|
5086
|
-
function detectProviderUncached() {
|
|
5087
|
-
const explicit = process.env["FRONTMCP_PROVIDER"];
|
|
5088
|
-
if (explicit && isKnownProvider(explicit)) return explicit;
|
|
5089
|
-
if (process.env["VERCEL"]) return "vercel";
|
|
5090
|
-
if (process.env["AWS_LAMBDA_FUNCTION_NAME"]) return "lambda";
|
|
5091
|
-
if (process.env["CF_PAGES"]) return "cloudflare";
|
|
5092
|
-
if (process.env["NETLIFY"]) return "netlify";
|
|
5093
|
-
if (process.env["AZURE_FUNCTIONS_ENVIRONMENT"]) return "azure";
|
|
5094
|
-
if (process.env["K_SERVICE"]) return "gcp";
|
|
5095
|
-
if (process.env["FLY_APP_NAME"]) return "fly";
|
|
5096
|
-
if (process.env["RENDER"]) return "render";
|
|
5097
|
-
if (process.env["RAILWAY_ENVIRONMENT"]) return "railway";
|
|
5098
|
-
try {
|
|
5099
|
-
const nodeFs = require("node:fs");
|
|
5100
|
-
if (nodeFs.existsSync("/.dockerenv")) return "docker";
|
|
5101
|
-
} catch {
|
|
5102
|
-
}
|
|
5103
|
-
return "bare";
|
|
5104
|
-
}
|
|
5105
|
-
function isKnownProvider(value) {
|
|
5106
|
-
return value === "bare" || value === "docker" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "netlify" || value === "azure" || value === "gcp" || value === "fly" || value === "render" || value === "railway";
|
|
5107
|
-
}
|
|
5108
|
-
|
|
5109
|
-
// libs/utils/src/env/runtime-context.ts
|
|
5110
|
-
var entryAvailabilitySchema = import_lazy_zod3.z.object({
|
|
5111
|
-
os: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
5112
|
-
platform: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
5113
|
-
runtime: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
5114
|
-
deployment: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
5115
|
-
provider: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
5116
|
-
target: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
5117
|
-
surface: import_lazy_zod3.z.array(import_lazy_zod3.z.enum(["mcp", "cli", "http-trigger", "job", "agent"])).optional(),
|
|
5118
|
-
env: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional()
|
|
5119
|
-
}).strict();
|
|
5120
|
-
var PROCESS_AXES = [
|
|
5121
|
-
// `os` and `platform` both compare against the same RuntimeContext value
|
|
5122
|
-
// — keeping `platform` as a deprecated alias lets pre-#417 metadata
|
|
5123
|
-
// continue to match without any code change.
|
|
5124
|
-
{ key: "os", ctxKey: "os" },
|
|
5125
|
-
{ key: "platform", ctxKey: "platform" },
|
|
5126
|
-
{ key: "runtime", ctxKey: "runtime" },
|
|
5127
|
-
{ key: "deployment", ctxKey: "deployment" },
|
|
5128
|
-
{ key: "provider", ctxKey: "provider" },
|
|
5129
|
-
{ key: "target", ctxKey: "target" },
|
|
5130
|
-
{ key: "env", ctxKey: "env" }
|
|
5131
|
-
];
|
|
5132
|
-
function isEntryAvailable(availability, ctx, callCtx) {
|
|
5133
|
-
if (!availability) return true;
|
|
5134
|
-
for (const { key, ctxKey } of PROCESS_AXES) {
|
|
5135
|
-
const allowed = availability[key];
|
|
5136
|
-
if (allowed === void 0) continue;
|
|
5137
|
-
if (allowed.length === 0) return false;
|
|
5138
|
-
if (!allowed.includes(ctx[ctxKey])) return false;
|
|
5139
|
-
}
|
|
5140
|
-
if (availability.surface !== void 0) {
|
|
5141
|
-
if (availability.surface.length === 0) return false;
|
|
5142
|
-
if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
|
|
5143
|
-
return false;
|
|
5144
|
-
}
|
|
5145
|
-
}
|
|
5146
|
-
return true;
|
|
5147
|
-
}
|
|
5148
|
-
function checkEntryAvailability(availability, ctx, callCtx) {
|
|
5149
|
-
if (!availability) return { available: true, missingAxes: [] };
|
|
5150
|
-
const missing = [];
|
|
5151
|
-
for (const { key, ctxKey } of PROCESS_AXES) {
|
|
5152
|
-
const allowed = availability[key];
|
|
5153
|
-
if (allowed === void 0) continue;
|
|
5154
|
-
if (allowed.length === 0 || !allowed.includes(ctx[ctxKey])) {
|
|
5155
|
-
missing.push(key);
|
|
5156
|
-
}
|
|
5157
|
-
}
|
|
5158
|
-
if (availability.surface !== void 0) {
|
|
5159
|
-
if (availability.surface.length === 0) {
|
|
5160
|
-
missing.push("surface");
|
|
5161
|
-
} else if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
|
|
5162
|
-
missing.push("surface");
|
|
5163
|
-
}
|
|
5164
|
-
}
|
|
5165
|
-
return { available: missing.length === 0, missingAxes: missing };
|
|
5166
|
-
}
|
|
5167
|
-
function detectRuntime() {
|
|
5168
|
-
if (typeof globalThis !== "undefined" && "Bun" in globalThis) return "bun";
|
|
5169
|
-
if (typeof globalThis !== "undefined" && "Deno" in globalThis) return "deno";
|
|
5170
|
-
if ((0, import_env2.isEdgeRuntime)()) return "edge";
|
|
5171
|
-
return "node";
|
|
5172
|
-
}
|
|
5173
|
-
function detectDeployment(runtime) {
|
|
5174
|
-
const explicit = process.env["FRONTMCP_DEPLOYMENT_MODE"];
|
|
5175
|
-
if (explicit === "distributed") return "distributed";
|
|
5176
|
-
if (explicit === "serverless") return "serverless";
|
|
5177
|
-
if (runtime === "browser") return "browser";
|
|
5178
|
-
if ((0, import_env2.isServerless)()) return "serverless";
|
|
5179
|
-
return "standalone";
|
|
5180
|
-
}
|
|
5181
|
-
function detectRuntimeContext() {
|
|
5182
|
-
const runtime = detectRuntime();
|
|
5183
|
-
const os = process.platform;
|
|
5184
|
-
return {
|
|
5185
|
-
os,
|
|
5186
|
-
platform: os,
|
|
5187
|
-
runtime,
|
|
5188
|
-
deployment: detectDeployment(runtime),
|
|
5189
|
-
provider: detectProvider(),
|
|
5190
|
-
target: getBuildTarget(),
|
|
5191
|
-
env: process.env["NODE_ENV"] || "development"
|
|
5192
|
-
};
|
|
5193
|
-
}
|
|
5194
|
-
var cached3;
|
|
5195
|
-
function getRuntimeContext() {
|
|
5196
|
-
if (!cached3) {
|
|
5197
|
-
cached3 = detectRuntimeContext();
|
|
5198
|
-
}
|
|
5199
|
-
return cached3;
|
|
5200
|
-
}
|
|
5201
|
-
function resetRuntimeContext() {
|
|
5202
|
-
cached3 = void 0;
|
|
5203
|
-
}
|
|
5178
|
+
var import_runtime_context = require("#runtime-context");
|
|
5204
5179
|
|
|
5205
5180
|
// libs/utils/src/storage/factory.ts
|
|
5206
5181
|
init_errors();
|
|
5207
5182
|
|
|
5208
5183
|
// libs/utils/src/storage/namespace.ts
|
|
5184
|
+
init_errors();
|
|
5209
5185
|
var NAMESPACE_SEPARATOR = ":";
|
|
5210
5186
|
function buildPrefix(name, id) {
|
|
5211
5187
|
if (id) {
|
|
@@ -5337,6 +5313,12 @@ var NamespacedStorageImpl = class _NamespacedStorageImpl {
|
|
|
5337
5313
|
async incrBy(key, amount) {
|
|
5338
5314
|
return this.adapter.incrBy(this.prefixKey(key), amount);
|
|
5339
5315
|
}
|
|
5316
|
+
async deleteIfEquals(key, expectedValue) {
|
|
5317
|
+
if (!this.adapter.deleteIfEquals) {
|
|
5318
|
+
throw new StorageNotSupportedError("deleteIfEquals", "this storage adapter");
|
|
5319
|
+
}
|
|
5320
|
+
return this.adapter.deleteIfEquals(this.prefixKey(key), expectedValue);
|
|
5321
|
+
}
|
|
5340
5322
|
// ============================================
|
|
5341
5323
|
// Pub/Sub (with channel prefixing)
|
|
5342
5324
|
// ============================================
|
|
@@ -5365,15 +5347,15 @@ function createNamespacedStorage(adapter, prefix) {
|
|
|
5365
5347
|
|
|
5366
5348
|
// libs/utils/src/storage/factory.ts
|
|
5367
5349
|
init_memory();
|
|
5368
|
-
var
|
|
5350
|
+
var import_env3 = require("#env");
|
|
5369
5351
|
function detectStorageType() {
|
|
5370
|
-
if ((0,
|
|
5352
|
+
if ((0, import_env3.getEnv)("UPSTASH_REDIS_REST_URL") && (0, import_env3.getEnv)("UPSTASH_REDIS_REST_TOKEN")) {
|
|
5371
5353
|
return "upstash";
|
|
5372
5354
|
}
|
|
5373
|
-
if ((0,
|
|
5355
|
+
if ((0, import_env3.getEnv)("KV_REST_API_URL") && (0, import_env3.getEnv)("KV_REST_API_TOKEN")) {
|
|
5374
5356
|
return "vercel-kv";
|
|
5375
5357
|
}
|
|
5376
|
-
if ((0,
|
|
5358
|
+
if ((0, import_env3.getEnv)("REDIS_URL") || (0, import_env3.getEnv)("REDIS_HOST")) {
|
|
5377
5359
|
return "redis";
|
|
5378
5360
|
}
|
|
5379
5361
|
return "memory";
|
|
@@ -5413,10 +5395,10 @@ async function createAdapter(type, config) {
|
|
|
5413
5395
|
}
|
|
5414
5396
|
async function createStorage(config = {}) {
|
|
5415
5397
|
let type = config.type ?? "auto";
|
|
5416
|
-
const fallback = config.fallback ?? ((0,
|
|
5398
|
+
const fallback = config.fallback ?? ((0, import_env3.isProduction)() ? "error" : "memory");
|
|
5417
5399
|
if (type === "auto") {
|
|
5418
5400
|
type = detectStorageType();
|
|
5419
|
-
if (type === "memory" && (0,
|
|
5401
|
+
if (type === "memory" && (0, import_env3.isProduction)()) {
|
|
5420
5402
|
console.warn(
|
|
5421
5403
|
"[storage] Warning: No distributed storage backend detected in production. Using in-memory storage. Set REDIS_URL, UPSTASH_REDIS_REST_URL, or KV_REST_API_URL."
|
|
5422
5404
|
);
|
|
@@ -5465,6 +5447,7 @@ function getDetectedStorageType() {
|
|
|
5465
5447
|
}
|
|
5466
5448
|
|
|
5467
5449
|
// libs/utils/src/storage/index.ts
|
|
5450
|
+
init_redis_error_listener();
|
|
5468
5451
|
init_errors();
|
|
5469
5452
|
|
|
5470
5453
|
// libs/utils/src/storage/typed-storage.ts
|
|
@@ -6120,6 +6103,7 @@ function setMachineIdOverride(id) {
|
|
|
6120
6103
|
BaseStorageAdapter,
|
|
6121
6104
|
DEFAULT_CODE_VERIFIER_LENGTH,
|
|
6122
6105
|
DEFAULT_MAX_INPUT_LENGTH,
|
|
6106
|
+
DEFAULT_REDIS_ERROR_LOG_INTERVAL_MS,
|
|
6123
6107
|
EncryptedBlobError,
|
|
6124
6108
|
EncryptedStorageError,
|
|
6125
6109
|
EncryptedTypedStorage,
|
|
@@ -6152,6 +6136,7 @@ function setMachineIdOverride(id) {
|
|
|
6152
6136
|
assertNode,
|
|
6153
6137
|
asymmetricAlgSchema,
|
|
6154
6138
|
asymmetricKeyDataSchema,
|
|
6139
|
+
attachRedisErrorListener,
|
|
6155
6140
|
awaitOutsideRequest,
|
|
6156
6141
|
base64Decode,
|
|
6157
6142
|
base64Encode,
|
|
@@ -6172,6 +6157,7 @@ function setMachineIdOverride(id) {
|
|
|
6172
6157
|
createKeyPersistenceWithStorage,
|
|
6173
6158
|
createMemoryStorage,
|
|
6174
6159
|
createNamespacedStorage,
|
|
6160
|
+
createRedisClient,
|
|
6175
6161
|
createRootStorage,
|
|
6176
6162
|
createSafeRegExp,
|
|
6177
6163
|
createSecretData,
|
|
@@ -6219,6 +6205,7 @@ function setMachineIdOverride(id) {
|
|
|
6219
6205
|
getEnv,
|
|
6220
6206
|
getEnvFlag,
|
|
6221
6207
|
getMachineId,
|
|
6208
|
+
getNodeEnv,
|
|
6222
6209
|
getOrCreateSecret,
|
|
6223
6210
|
getRuntimeContext,
|
|
6224
6211
|
getSpawnFn,
|