@frontmcp/utils 1.8.7 → 1.9.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
1
+ var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
2
2
  const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
3
3
  // __frontmcpCreateRequire
4
4
  var __defProp = Object.defineProperty;
@@ -595,9 +595,9 @@ function createSecretData(options) {
595
595
  }
596
596
  async function getOrCreateSecret(options) {
597
597
  const cacheKey = resolveSecretPath(options);
598
- const cached4 = secretCache.get(cacheKey);
599
- if (cached4) {
600
- return cached4;
598
+ const cached = secretCache.get(cacheKey);
599
+ if (cached) {
600
+ return cached;
601
601
  }
602
602
  const existing = generationPromises.get(cacheKey);
603
603
  if (existing) {
@@ -834,8 +834,8 @@ var init_key_persistence = __esm({
834
834
  */
835
835
  async get(kid) {
836
836
  if (this.enableCache) {
837
- const cached4 = this.cache.get(kid);
838
- if (cached4) return cached4;
837
+ const cached = this.cache.get(kid);
838
+ if (cached) return cached;
839
839
  }
840
840
  const raw = await this.storage.get(kid);
841
841
  if (!raw) return null;
@@ -1086,6 +1086,75 @@ var init_errors = __esm({
1086
1086
  }
1087
1087
  });
1088
1088
 
1089
+ // libs/utils/src/storage/utils/pattern.ts
1090
+ function globToRegex(pattern) {
1091
+ if (pattern.length > MAX_PATTERN_LENGTH) {
1092
+ throw new StoragePatternError(
1093
+ pattern.substring(0, 50) + "...",
1094
+ `Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
1095
+ );
1096
+ }
1097
+ const wildcardCount = (pattern.match(/[*?]/g) || []).length;
1098
+ if (wildcardCount > MAX_WILDCARDS) {
1099
+ throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
1100
+ }
1101
+ if (pattern === "" || pattern === "*") {
1102
+ return /^.*$/;
1103
+ }
1104
+ let regexStr = "^";
1105
+ let prevChar = "";
1106
+ for (let i = 0; i < pattern.length; i++) {
1107
+ const char = pattern[i];
1108
+ switch (char) {
1109
+ case "*":
1110
+ if (prevChar !== "*") {
1111
+ regexStr += ".*";
1112
+ }
1113
+ break;
1114
+ case "?":
1115
+ regexStr += ".";
1116
+ break;
1117
+ default:
1118
+ regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
1119
+ }
1120
+ prevChar = char;
1121
+ }
1122
+ regexStr += "$";
1123
+ try {
1124
+ return new RegExp(regexStr);
1125
+ } catch {
1126
+ throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
1127
+ }
1128
+ }
1129
+ function matchesPattern(key, pattern) {
1130
+ const regex = globToRegex(pattern);
1131
+ return regex.test(key);
1132
+ }
1133
+ function validatePattern(pattern) {
1134
+ try {
1135
+ globToRegex(pattern);
1136
+ return { valid: true };
1137
+ } catch (e) {
1138
+ return {
1139
+ valid: false,
1140
+ error: e instanceof Error ? e.message : "Invalid pattern"
1141
+ };
1142
+ }
1143
+ }
1144
+ function escapeGlob(literal) {
1145
+ return literal.replace(/[*?\\]/g, "\\$&");
1146
+ }
1147
+ var MAX_PATTERN_LENGTH, MAX_WILDCARDS, REGEX_SPECIAL_CHARS;
1148
+ var init_pattern = __esm({
1149
+ "libs/utils/src/storage/utils/pattern.ts"() {
1150
+ "use strict";
1151
+ init_errors();
1152
+ MAX_PATTERN_LENGTH = 500;
1153
+ MAX_WILDCARDS = 20;
1154
+ REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
1155
+ }
1156
+ });
1157
+
1089
1158
  // libs/utils/src/storage/utils/ttl.ts
1090
1159
  function validateTTL(ttlSeconds) {
1091
1160
  if (typeof ttlSeconds !== "number") {
@@ -1200,6 +1269,17 @@ var init_base = __esm({
1200
1269
  const matchedKeys = await this.keys(pattern);
1201
1270
  return matchedKeys.length;
1202
1271
  }
1272
+ /**
1273
+ * Default: not supported, since a read followed by a delete is not atomic.
1274
+ * Override in adapters whose backend can compare and delete in one step.
1275
+ */
1276
+ async deleteIfEquals(_key, _expectedValue) {
1277
+ throw new StorageNotSupportedError(
1278
+ "deleteIfEquals",
1279
+ this.backendName,
1280
+ "Use the memory, Redis, Upstash or Vercel KV adapter for an atomic compare-and-delete."
1281
+ );
1282
+ }
1203
1283
  // ============================================
1204
1284
  // Pub/Sub (default: not supported)
1205
1285
  // ============================================
@@ -1248,85 +1328,16 @@ var init_base = __esm({
1248
1328
  }
1249
1329
  });
1250
1330
 
1251
- // libs/utils/src/storage/utils/pattern.ts
1252
- function globToRegex(pattern) {
1253
- if (pattern.length > MAX_PATTERN_LENGTH) {
1254
- throw new StoragePatternError(
1255
- pattern.substring(0, 50) + "...",
1256
- `Pattern exceeds maximum length of ${MAX_PATTERN_LENGTH} characters`
1257
- );
1258
- }
1259
- const wildcardCount = (pattern.match(/[*?]/g) || []).length;
1260
- if (wildcardCount > MAX_WILDCARDS) {
1261
- throw new StoragePatternError(pattern, `Pattern has too many wildcards (max: ${MAX_WILDCARDS})`);
1262
- }
1263
- if (pattern === "" || pattern === "*") {
1264
- return /^.*$/;
1265
- }
1266
- let regexStr = "^";
1267
- let prevChar = "";
1268
- for (let i = 0; i < pattern.length; i++) {
1269
- const char = pattern[i];
1270
- switch (char) {
1271
- case "*":
1272
- if (prevChar !== "*") {
1273
- regexStr += ".*";
1274
- }
1275
- break;
1276
- case "?":
1277
- regexStr += ".";
1278
- break;
1279
- default:
1280
- regexStr += char.replace(REGEX_SPECIAL_CHARS, "\\$&");
1281
- }
1282
- prevChar = char;
1283
- }
1284
- regexStr += "$";
1285
- try {
1286
- return new RegExp(regexStr);
1287
- } catch {
1288
- throw new StoragePatternError(pattern, "Failed to compile pattern to regex");
1289
- }
1290
- }
1291
- function matchesPattern(key, pattern) {
1292
- const regex = globToRegex(pattern);
1293
- return regex.test(key);
1294
- }
1295
- function validatePattern(pattern) {
1296
- try {
1297
- globToRegex(pattern);
1298
- return { valid: true };
1299
- } catch (e) {
1300
- return {
1301
- valid: false,
1302
- error: e instanceof Error ? e.message : "Invalid pattern"
1303
- };
1304
- }
1305
- }
1306
- function escapeGlob(literal) {
1307
- return literal.replace(/[*?\\]/g, "\\$&");
1308
- }
1309
- var MAX_PATTERN_LENGTH, MAX_WILDCARDS, REGEX_SPECIAL_CHARS;
1310
- var init_pattern = __esm({
1311
- "libs/utils/src/storage/utils/pattern.ts"() {
1312
- "use strict";
1313
- init_errors();
1314
- MAX_PATTERN_LENGTH = 500;
1315
- MAX_WILDCARDS = 20;
1316
- REGEX_SPECIAL_CHARS = /[.+^${}()|[\]\\]/g;
1317
- }
1318
- });
1319
-
1320
1331
  // libs/utils/src/storage/adapters/memory.ts
1321
1332
  import { EventEmitter } from "#event-emitter";
1322
1333
  var DEFAULT_SWEEP_INTERVAL_SECONDS, MAX_TIMEOUT_MS, MemoryStorageAdapter;
1323
1334
  var init_memory = __esm({
1324
1335
  "libs/utils/src/storage/adapters/memory.ts"() {
1325
1336
  "use strict";
1326
- init_base();
1327
1337
  init_errors();
1328
1338
  init_pattern();
1329
1339
  init_ttl();
1340
+ init_base();
1330
1341
  DEFAULT_SWEEP_INTERVAL_SECONDS = 60;
1331
1342
  MAX_TIMEOUT_MS = 2147483647;
1332
1343
  MemoryStorageAdapter = class extends BaseStorageAdapter {
@@ -1418,6 +1429,12 @@ var init_memory = __esm({
1418
1429
  this.ensureConnected();
1419
1430
  return this.deleteEntry(key);
1420
1431
  }
1432
+ async deleteIfEquals(key, expectedValue) {
1433
+ this.ensureConnected();
1434
+ const entry = this.store.get(key);
1435
+ if (!entry || isExpired(entry.expiresAt) || entry.value !== expectedValue) return false;
1436
+ return this.deleteEntry(key);
1437
+ }
1421
1438
  async exists(key) {
1422
1439
  this.ensureConnected();
1423
1440
  const entry = this.store.get(key);
@@ -3006,6 +3023,15 @@ var init_utils = __esm({
3006
3023
  }
3007
3024
  });
3008
3025
 
3026
+ // libs/utils/src/storage/utils/compare-and-delete.ts
3027
+ var COMPARE_AND_DELETE_SCRIPT;
3028
+ var init_compare_and_delete = __esm({
3029
+ "libs/utils/src/storage/utils/compare-and-delete.ts"() {
3030
+ "use strict";
3031
+ COMPARE_AND_DELETE_SCRIPT = `if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end return 0`;
3032
+ }
3033
+ });
3034
+
3009
3035
  // libs/utils/src/storage/adapters/redis.ts
3010
3036
  var redis_exports = {};
3011
3037
  __export(redis_exports, {
@@ -3049,6 +3075,7 @@ var init_redis = __esm({
3049
3075
  init_errors();
3050
3076
  init_redis_error_listener();
3051
3077
  init_utils();
3078
+ init_compare_and_delete();
3052
3079
  init_base();
3053
3080
  RedisStorageAdapter = class extends BaseStorageAdapter {
3054
3081
  backendName = "redis";
@@ -3203,6 +3230,15 @@ var init_redis = __esm({
3203
3230
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3204
3231
  return result > 0;
3205
3232
  }
3233
+ async deleteIfEquals(key, expectedValue) {
3234
+ const deleted = await this.getConnectedClient().eval(
3235
+ COMPARE_AND_DELETE_SCRIPT,
3236
+ 1,
3237
+ this.prefixKey(key),
3238
+ expectedValue
3239
+ );
3240
+ return deleted === 1;
3241
+ }
3206
3242
  async exists(key) {
3207
3243
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3208
3244
  return result > 0;
@@ -3411,9 +3447,12 @@ var vercel_kv_exports = {};
3411
3447
  __export(vercel_kv_exports, {
3412
3448
  VercelKvStorageAdapter: () => VercelKvStorageAdapter
3413
3449
  });
3414
- function getVercelKv() {
3450
+ async function loadVercelKv() {
3415
3451
  try {
3416
- return __require("@vercel/kv");
3452
+ const mod = await import("@vercel/kv");
3453
+ const resolved = typeof mod.createClient === "function" ? mod : mod.default;
3454
+ if (!resolved || typeof resolved.createClient !== "function") throw new Error("createClient missing");
3455
+ return resolved;
3417
3456
  } catch {
3418
3457
  throw new Error("@vercel/kv is required for Vercel KV storage adapter. Install it with: npm install @vercel/kv");
3419
3458
  }
@@ -3422,9 +3461,10 @@ var VercelKvStorageAdapter;
3422
3461
  var init_vercel_kv = __esm({
3423
3462
  "libs/utils/src/storage/adapters/vercel-kv.ts"() {
3424
3463
  "use strict";
3425
- init_base();
3426
3464
  init_errors();
3465
+ init_compare_and_delete();
3427
3466
  init_ttl();
3467
+ init_base();
3428
3468
  VercelKvStorageAdapter = class extends BaseStorageAdapter {
3429
3469
  backendName = "vercel-kv";
3430
3470
  client;
@@ -3449,17 +3489,13 @@ var init_vercel_kv = __esm({
3449
3489
  async connect() {
3450
3490
  if (this.connected) return;
3451
3491
  try {
3452
- const { createClient, kv } = getVercelKv();
3453
- if (this.options.url === process.env["KV_REST_API_URL"]) {
3454
- this.client = kv;
3455
- } else {
3456
- const url = this.options.url;
3457
- const token = this.options.token;
3458
- if (!url || !token) {
3459
- throw new StorageConfigError("vercel-kv", "URL and token are required");
3460
- }
3461
- this.client = createClient({ url, token });
3492
+ const { createClient } = await loadVercelKv();
3493
+ const url = this.options.url;
3494
+ const token = this.options.token;
3495
+ if (!url || !token) {
3496
+ throw new StorageConfigError("vercel-kv", "URL and token are required");
3462
3497
  }
3498
+ this.client = createClient({ url, token, cache: void 0, automaticDeserialization: false });
3463
3499
  await this.client.exists("__healthcheck__");
3464
3500
  this.connected = true;
3465
3501
  } catch (e) {
@@ -3500,8 +3536,7 @@ var init_vercel_kv = __esm({
3500
3536
  // Core Operations
3501
3537
  // ============================================
3502
3538
  async get(key) {
3503
- const result = await this.getConnectedClient().get(this.prefixKey(key));
3504
- return result;
3539
+ return this.getConnectedClient().get(this.prefixKey(key));
3505
3540
  }
3506
3541
  async doSet(key, value, options) {
3507
3542
  const client = this.getConnectedClient();
@@ -3521,6 +3556,14 @@ var init_vercel_kv = __esm({
3521
3556
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3522
3557
  return result > 0;
3523
3558
  }
3559
+ async deleteIfEquals(key, expectedValue) {
3560
+ const deleted = await this.getConnectedClient().eval(
3561
+ COMPARE_AND_DELETE_SCRIPT,
3562
+ [this.prefixKey(key)],
3563
+ [expectedValue]
3564
+ );
3565
+ return deleted === 1;
3566
+ }
3524
3567
  async exists(key) {
3525
3568
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3526
3569
  return result > 0;
@@ -3638,9 +3681,10 @@ var PUBSUB_POLL_INTERVAL_MS, UpstashStorageAdapter;
3638
3681
  var init_upstash = __esm({
3639
3682
  "libs/utils/src/storage/adapters/upstash.ts"() {
3640
3683
  "use strict";
3641
- init_base();
3642
3684
  init_errors();
3685
+ init_compare_and_delete();
3643
3686
  init_ttl();
3687
+ init_base();
3644
3688
  PUBSUB_POLL_INTERVAL_MS = 100;
3645
3689
  UpstashStorageAdapter = class extends BaseStorageAdapter {
3646
3690
  backendName = "upstash";
@@ -3677,7 +3721,7 @@ var init_upstash = __esm({
3677
3721
  if (!url || !token) {
3678
3722
  throw new StorageConfigError("upstash", "URL and token are required");
3679
3723
  }
3680
- this.client = new Redis({ url, token });
3724
+ this.client = new Redis({ url, token, automaticDeserialization: false });
3681
3725
  await this.client.exists("__healthcheck__");
3682
3726
  this.connected = true;
3683
3727
  } catch (e) {
@@ -3724,8 +3768,7 @@ var init_upstash = __esm({
3724
3768
  // Core Operations
3725
3769
  // ============================================
3726
3770
  async get(key) {
3727
- const result = await this.getConnectedClient().get(this.prefixKey(key));
3728
- return result;
3771
+ return this.getConnectedClient().get(this.prefixKey(key));
3729
3772
  }
3730
3773
  async doSet(key, value, options) {
3731
3774
  const client = this.getConnectedClient();
@@ -3745,6 +3788,14 @@ var init_upstash = __esm({
3745
3788
  const result = await this.getConnectedClient().del(this.prefixKey(key));
3746
3789
  return result > 0;
3747
3790
  }
3791
+ async deleteIfEquals(key, expectedValue) {
3792
+ const deleted = await this.getConnectedClient().eval(
3793
+ COMPARE_AND_DELETE_SCRIPT,
3794
+ [this.prefixKey(key)],
3795
+ [expectedValue]
3796
+ );
3797
+ return deleted === 1;
3798
+ }
3748
3799
  async exists(key) {
3749
3800
  const result = await this.getConnectedClient().exists(this.prefixKey(key));
3750
3801
  return result > 0;
@@ -3934,7 +3985,9 @@ var init_cloudflare_kv = __esm({
3934
3985
  constructor(options) {
3935
3986
  super();
3936
3987
  if (!options?.namespace) {
3937
- throw new Error("CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`).");
3988
+ throw new Error(
3989
+ "CloudflareKvStorageAdapter: a bound KV `namespace` is required (resolve it from the Worker `env`)."
3990
+ );
3938
3991
  }
3939
3992
  this.kv = options.namespace;
3940
3993
  this.keyPrefix = options.keyPrefix ?? "";
@@ -4028,6 +4081,13 @@ var init_cloudflare_kv = __esm({
4028
4081
  "Cloudflare KV has no atomic increment (a get+put is racy under eventual consistency). Use a Durable Object for atomic counters."
4029
4082
  );
4030
4083
  }
4084
+ async deleteIfEquals(_key, _expectedValue) {
4085
+ throw new StorageNotSupportedError(
4086
+ "deleteIfEquals",
4087
+ this.backendName,
4088
+ "Cloudflare KV has no compare-and-set; use a Durable Object for an atomic compare-and-delete."
4089
+ );
4090
+ }
4031
4091
  // ── Pub/Sub (unsupported) ────────────────────────────────────────────────
4032
4092
  getPubSubSuggestion() {
4033
4093
  return "Cloudflare KV does not support pub/sub. Use a Durable Object (or Queues) for fan-out.";
@@ -4456,9 +4516,17 @@ function joinPath(...parts) {
4456
4516
  return cleaned.length ? `/${cleaned.join("/")}` : "";
4457
4517
  }
4458
4518
 
4459
- // libs/utils/src/path/node-path.ts
4460
- import { resolve, join, basename, dirname, extname, isAbsolute, sep } from "path";
4461
- import { pathToFileURL } from "url";
4519
+ // libs/utils/src/path/index.ts
4520
+ import {
4521
+ resolve,
4522
+ join,
4523
+ basename,
4524
+ dirname,
4525
+ extname,
4526
+ isAbsolute,
4527
+ pathToFileURL,
4528
+ sep
4529
+ } from "#path";
4462
4530
 
4463
4531
  // libs/utils/src/content/content.ts
4464
4532
  function sanitizeToJson(value) {
@@ -4885,175 +4953,30 @@ import { EventEmitter as EventEmitter2 } from "#event-emitter";
4885
4953
  import {
4886
4954
  getEnv as getEnv2,
4887
4955
  getCwd as getCwd2,
4956
+ getNodeEnv,
4888
4957
  isProduction,
4889
4958
  isDevelopment,
4890
4959
  getEnvFlag,
4891
4960
  isDebug,
4892
4961
  setEnv,
4893
- isEdgeRuntime as isEdgeRuntime2,
4894
- isServerless as isServerless2,
4962
+ isEdgeRuntime,
4963
+ isServerless,
4895
4964
  supportsAnsi
4896
4965
  } from "#env";
4897
-
4898
- // libs/utils/src/env/runtime-context.ts
4899
- import { z as z3 } from "@frontmcp/lazy-zod";
4900
- import { isEdgeRuntime, isServerless } from "#env";
4901
-
4902
- // libs/utils/src/env/build-target.ts
4903
- var cached;
4904
- function getBuildTarget() {
4905
- if (cached) return cached;
4906
- cached = resolveBuildTarget();
4907
- return cached;
4908
- }
4909
- function resolveBuildTarget() {
4910
- const globalAny = globalThis;
4911
- const fromGlobal = globalAny.FRONTMCP_BUILD_TARGET;
4912
- if (typeof fromGlobal === "string" && isKnownTarget(fromGlobal)) return fromGlobal;
4913
- const fromEnv = typeof process !== "undefined" ? process.env?.["FRONTMCP_BUILD_TARGET"] : void 0;
4914
- if (typeof fromEnv === "string" && isKnownTarget(fromEnv)) return fromEnv;
4915
- return "unknown";
4916
- }
4917
- function isKnownTarget(value) {
4918
- return value === "unknown" || value === "node" || value === "distributed" || value === "cli" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "browser" || value === "sdk" || value === "mcpb";
4919
- }
4920
-
4921
- // libs/utils/src/env/provider.ts
4922
- var cached2;
4923
- function detectProvider() {
4924
- if (cached2) return cached2;
4925
- cached2 = detectProviderUncached();
4926
- return cached2;
4927
- }
4928
- function detectProviderUncached() {
4929
- const explicit = process.env["FRONTMCP_PROVIDER"];
4930
- if (explicit && isKnownProvider(explicit)) return explicit;
4931
- if (process.env["VERCEL"]) return "vercel";
4932
- if (process.env["AWS_LAMBDA_FUNCTION_NAME"]) return "lambda";
4933
- if (process.env["CF_PAGES"]) return "cloudflare";
4934
- if (process.env["NETLIFY"]) return "netlify";
4935
- if (process.env["AZURE_FUNCTIONS_ENVIRONMENT"]) return "azure";
4936
- if (process.env["K_SERVICE"]) return "gcp";
4937
- if (process.env["FLY_APP_NAME"]) return "fly";
4938
- if (process.env["RENDER"]) return "render";
4939
- if (process.env["RAILWAY_ENVIRONMENT"]) return "railway";
4940
- try {
4941
- const nodeFs = __require("node:fs");
4942
- if (nodeFs.existsSync("/.dockerenv")) return "docker";
4943
- } catch {
4944
- }
4945
- return "bare";
4946
- }
4947
- function isKnownProvider(value) {
4948
- return value === "bare" || value === "docker" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "netlify" || value === "azure" || value === "gcp" || value === "fly" || value === "render" || value === "railway";
4949
- }
4950
-
4951
- // libs/utils/src/env/runtime-context.ts
4952
- var entryAvailabilitySchema = z3.object({
4953
- os: z3.array(z3.string().min(1)).optional(),
4954
- platform: z3.array(z3.string().min(1)).optional(),
4955
- runtime: z3.array(z3.string().min(1)).optional(),
4956
- deployment: z3.array(z3.string().min(1)).optional(),
4957
- provider: z3.array(z3.string().min(1)).optional(),
4958
- target: z3.array(z3.string().min(1)).optional(),
4959
- surface: z3.array(z3.enum(["mcp", "cli", "http-trigger", "job", "agent"])).optional(),
4960
- env: z3.array(z3.string().min(1)).optional()
4961
- }).strict();
4962
- var PROCESS_AXES = [
4963
- // `os` and `platform` both compare against the same RuntimeContext value
4964
- // — keeping `platform` as a deprecated alias lets pre-#417 metadata
4965
- // continue to match without any code change.
4966
- { key: "os", ctxKey: "os" },
4967
- { key: "platform", ctxKey: "platform" },
4968
- { key: "runtime", ctxKey: "runtime" },
4969
- { key: "deployment", ctxKey: "deployment" },
4970
- { key: "provider", ctxKey: "provider" },
4971
- { key: "target", ctxKey: "target" },
4972
- { key: "env", ctxKey: "env" }
4973
- ];
4974
- function isEntryAvailable(availability, ctx, callCtx) {
4975
- if (!availability) return true;
4976
- for (const { key, ctxKey } of PROCESS_AXES) {
4977
- const allowed = availability[key];
4978
- if (allowed === void 0) continue;
4979
- if (allowed.length === 0) return false;
4980
- if (!allowed.includes(ctx[ctxKey])) return false;
4981
- }
4982
- if (availability.surface !== void 0) {
4983
- if (availability.surface.length === 0) return false;
4984
- if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
4985
- return false;
4986
- }
4987
- }
4988
- return true;
4989
- }
4990
- function checkEntryAvailability(availability, ctx, callCtx) {
4991
- if (!availability) return { available: true, missingAxes: [] };
4992
- const missing = [];
4993
- for (const { key, ctxKey } of PROCESS_AXES) {
4994
- const allowed = availability[key];
4995
- if (allowed === void 0) continue;
4996
- if (allowed.length === 0 || !allowed.includes(ctx[ctxKey])) {
4997
- missing.push(key);
4998
- }
4999
- }
5000
- if (availability.surface !== void 0) {
5001
- if (availability.surface.length === 0) {
5002
- missing.push("surface");
5003
- } else if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
5004
- missing.push("surface");
5005
- }
5006
- }
5007
- return { available: missing.length === 0, missingAxes: missing };
5008
- }
5009
- function detectRuntime() {
5010
- if (typeof globalThis !== "undefined" && "Bun" in globalThis) return "bun";
5011
- if (typeof globalThis !== "undefined" && "Deno" in globalThis) return "deno";
5012
- if (isEdgeRuntime()) return "edge";
5013
- return "node";
5014
- }
5015
- function detectDeployment(runtime) {
5016
- const explicit = process.env["FRONTMCP_DEPLOYMENT_MODE"];
5017
- if (explicit === "distributed") return "distributed";
5018
- if (explicit === "serverless") return "serverless";
5019
- if (runtime === "browser") return "browser";
5020
- if (isServerless()) return "serverless";
5021
- return "standalone";
5022
- }
5023
- function detectRuntimeContext() {
5024
- const runtime = detectRuntime();
5025
- const os = process.platform;
5026
- return {
5027
- os,
5028
- platform: os,
5029
- runtime,
5030
- deployment: detectDeployment(runtime),
5031
- provider: detectProvider(),
5032
- target: getBuildTarget(),
5033
- env: process.env["NODE_ENV"] || "development"
5034
- };
5035
- }
5036
- var cached3;
5037
- function getRuntimeContext() {
5038
- if (!cached3) {
5039
- const detected = detectRuntimeContext();
5040
- Object.defineProperty(detected, "env", {
5041
- get: () => process.env["NODE_ENV"] || "development",
5042
- enumerable: true,
5043
- configurable: true
5044
- });
5045
- cached3 = detected;
5046
- }
5047
- return cached3;
5048
- }
5049
- function resetRuntimeContext() {
5050
- cached3 = void 0;
5051
- }
4966
+ import {
4967
+ getRuntimeContext,
4968
+ resetRuntimeContext,
4969
+ detectRuntimeContext,
4970
+ isEntryAvailable,
4971
+ checkEntryAvailability,
4972
+ entryAvailabilitySchema
4973
+ } from "#runtime-context";
5052
4974
 
5053
4975
  // libs/utils/src/storage/factory.ts
5054
4976
  init_errors();
5055
4977
 
5056
4978
  // libs/utils/src/storage/namespace.ts
4979
+ init_errors();
5057
4980
  var NAMESPACE_SEPARATOR = ":";
5058
4981
  function buildPrefix(name, id) {
5059
4982
  if (id) {
@@ -5185,6 +5108,12 @@ var NamespacedStorageImpl = class _NamespacedStorageImpl {
5185
5108
  async incrBy(key, amount) {
5186
5109
  return this.adapter.incrBy(this.prefixKey(key), amount);
5187
5110
  }
5111
+ async deleteIfEquals(key, expectedValue) {
5112
+ if (!this.adapter.deleteIfEquals) {
5113
+ throw new StorageNotSupportedError("deleteIfEquals", "this storage adapter");
5114
+ }
5115
+ return this.adapter.deleteIfEquals(this.prefixKey(key), expectedValue);
5116
+ }
5188
5117
  // ============================================
5189
5118
  // Pub/Sub (with channel prefixing)
5190
5119
  // ============================================
@@ -6070,6 +5999,7 @@ export {
6070
5999
  getEnv2 as getEnv,
6071
6000
  getEnvFlag,
6072
6001
  getMachineId,
6002
+ getNodeEnv,
6073
6003
  getOrCreateSecret,
6074
6004
  getRuntimeContext,
6075
6005
  getSpawnFn,
@@ -6085,7 +6015,7 @@ export {
6085
6015
  isDebug,
6086
6016
  isDevelopment,
6087
6017
  isDirEmpty,
6088
- isEdgeRuntime2 as isEdgeRuntime,
6018
+ isEdgeRuntime,
6089
6019
  isEntryAvailable,
6090
6020
  isExpired,
6091
6021
  isInputLengthSafe,
@@ -6099,7 +6029,7 @@ export {
6099
6029
  isSecretKeyData,
6100
6030
  isSecretPersistenceEnabled,
6101
6031
  isSecureRequest,
6102
- isServerless2 as isServerless,
6032
+ isServerless,
6103
6033
  isSignedData,
6104
6034
  isUriTemplate,
6105
6035
  isValidCodeChallenge,
@@ -0,0 +1,50 @@
1
+ var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
2
+ const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
3
+ // __frontmcpCreateRequire
4
+ // libs/utils/src/path/browser-path.ts
5
+ function notAvailable(name) {
6
+ throw new Error(`path.${name}() is not available in browser environments`);
7
+ }
8
+ function resolve(..._segments) {
9
+ return notAvailable("resolve");
10
+ }
11
+ function join(..._segments) {
12
+ return notAvailable("join");
13
+ }
14
+ function basename(p, ext) {
15
+ const trimmed = p.replace(/[/\\]+$/, "");
16
+ const lastSep = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
17
+ let base = lastSep >= 0 ? trimmed.slice(lastSep + 1) : trimmed;
18
+ if (ext && base.endsWith(ext)) {
19
+ base = base.slice(0, -ext.length);
20
+ }
21
+ return base;
22
+ }
23
+ function dirname(_p) {
24
+ return notAvailable("dirname");
25
+ }
26
+ function extname(p) {
27
+ const base = basename(p);
28
+ const dotIndex = base.lastIndexOf(".");
29
+ return dotIndex > 0 ? base.slice(dotIndex) : "";
30
+ }
31
+ function isAbsolute(p) {
32
+ if (!p) return false;
33
+ if (p.startsWith("/") || p.startsWith("\\")) return true;
34
+ if (/^[A-Za-z]:[\\/]/.test(p)) return true;
35
+ return false;
36
+ }
37
+ function pathToFileURL(_p) {
38
+ return notAvailable("pathToFileURL");
39
+ }
40
+ var sep = "/";
41
+ export {
42
+ basename,
43
+ dirname,
44
+ extname,
45
+ isAbsolute,
46
+ join,
47
+ pathToFileURL,
48
+ resolve,
49
+ sep
50
+ };