Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@frontmcp/utils

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@frontmcp/utils - npm Package Compare versions

Comparing version
1.2.1
to
1.3.0
+27
env/build-target.d.ts
/**
* Build-target detection (issue #417).
*
* The CLI's `build` command knows the target name (`cli`, `node`,
* `vercel`, `lambda`, `cloudflare`, `browser`, `sdk`, `mcpb`,
* `distributed`) but doesn't tell the runtime today. This helper exposes
* it so `@Tool({ availableWhen: { target: ['cli'] } })` can express
* "this tool is only valid in the compiled CLI bundle."
*
* Resolution order:
*
* 1. `globalThis.FRONTMCP_BUILD_TARGET` — preferred. Build adapters
* inline `const FRONTMCP_BUILD_TARGET = '<target>';` into the
* emitted entry shim before any user code runs, so this constant
* is correct from the very first line of imports.
* 2. `process.env.FRONTMCP_BUILD_TARGET` — set by the build adapter
* via the runtime env when inlining isn't viable (e.g. SEA).
* 3. `'unknown'` — dev mode, tests, or any context the build command
* hasn't touched.
*
* The supported values match `frontmcp build --target <name>` plus
* `'unknown'` for the dev path.
*/
export type BuildTarget = 'unknown' | 'node' | 'distributed' | 'cli' | 'vercel' | 'lambda' | 'cloudflare' | 'browser' | 'sdk' | 'mcpb';
export declare function getBuildTarget(): BuildTarget;
/** Test helper — reset the cache between specs. */
export declare function resetBuildTargetCacheForTesting(): void;
/**
* Deploy-provider detection (issue #417).
*
* `isServerless()` collapses every serverless env to a single boolean;
* this returns the discriminated identity so `@Tool({ availableWhen: {
* provider: ['vercel'] } })` can express provider-specific rules.
*
* Order matters — first match wins. A user can override detection by
* setting `FRONTMCP_PROVIDER=<name>` explicitly (used by tests and by
* Docker images that don't expose a discriminating env var).
*/
export type DeployProvider = 'bare' | 'docker' | 'vercel' | 'lambda' | 'cloudflare' | 'netlify' | 'azure' | 'gcp' | 'fly' | 'render' | 'railway';
/**
* Detect the current deploy provider. Cached per process.
*
* Detection rules (first match wins):
*
* 1. `FRONTMCP_PROVIDER` env var (override; trust whatever the operator set).
* 2. `VERCEL` env var → `'vercel'`.
* 3. `AWS_LAMBDA_FUNCTION_NAME` → `'lambda'`.
* 4. `CF_PAGES` → `'cloudflare'`.
* 5. `NETLIFY` → `'netlify'`.
* 6. `AZURE_FUNCTIONS_ENVIRONMENT` → `'azure'`.
* 7. `K_SERVICE` (Cloud Run / Knative) → `'gcp'`.
* 8. `FLY_APP_NAME` → `'fly'`.
* 9. `RENDER` → `'render'`.
* 10. `RAILWAY_ENVIRONMENT` → `'railway'`.
* 11. `/.dockerenv` exists → `'docker'`.
* 12. Fallback: `'bare'`.
*/
export declare function detectProvider(): DeployProvider;
/** Test helper — reset the cache between specs. */
export declare function resetProviderCacheForTesting(): void;
+35
-3
/**
* Runtime context detection and entry availability matching (Browser version).
*
* Returns safe defaults for browser environments.
* The isEntryAvailable matcher works identically to the Node version.
* Returns safe defaults for browser environments. The matcher and
* `EntryAvailability` shape track the Node version (issue #417 added
* `os`/`provider`/`target`/`surface`).
*/
export interface RuntimeContext {
/** Issue #417: renamed from `platform`. */
os: string;
/** @deprecated Use `os`. */
platform: string;
runtime: string;
deployment: string;
/** Issue #417 — deploy provider. Always `'bare'` in browser. */
provider: string;
/** Issue #417 — build target. Always `'browser'` in browser. */
target: string;
env: string;
}
export type Surface = 'mcp' | 'cli' | 'http-trigger' | 'job' | 'agent';
export interface CallContext {
surface?: Surface;
}
export interface EntryAvailability {
/** Issue #417: renamed from `platform`. */
os?: string[];
/** @deprecated Use `os`. */
platform?: string[];
runtime?: string[];
deployment?: string[];
provider?: string[];
target?: string[];
surface?: Surface[];
env?: string[];
}
export declare const entryAvailabilitySchema: import("@frontmcp/lazy-zod").ZodObject<{
os: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
platform: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
runtime: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
deployment: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
provider: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
target: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
surface: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodEnum<{
cli: "cli";
mcp: "mcp";
"http-trigger": "http-trigger";
job: "job";
agent: "agent";
}>>>;
env: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
}, import("zod/v4/core").$strict>;
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext): boolean;
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): boolean;
export declare function checkEntryAvailability(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): {
available: boolean;
missingAxes: (keyof EntryAvailability)[];
};
export declare function detectRuntimeContext(): RuntimeContext;
export declare function getRuntimeContext(): RuntimeContext;
export declare function resetRuntimeContext(): void;
+6
-2
export { getEnv, getCwd, isProduction, isDevelopment, getEnvFlag, isDebug, setEnv, isEdgeRuntime, isServerless, supportsAnsi, } from '#env';
export { getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, entryAvailabilitySchema, } from '#runtime-context';
export type { RuntimeContext, EntryAvailability } from '#runtime-context';
export { getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, checkEntryAvailability, entryAvailabilitySchema, } from '#runtime-context';
export type { RuntimeContext, EntryAvailability, Surface, CallContext } from '#runtime-context';
export { detectProvider, resetProviderCacheForTesting } from './provider';
export type { DeployProvider } from './provider';
export { getBuildTarget, resetBuildTargetCacheForTesting } from './build-target';
export type { BuildTarget } from './build-target';

@@ -5,13 +5,22 @@ /**

* Provides:
* - `RuntimeContext` — snapshot of the current platform, runtime, deployment, and env
* - `RuntimeContext` — snapshot of the current platform, runtime, deployment, env, provider, target
* - `EntryAvailability` — declarative constraint for when an entry is available
* - `getRuntimeContext()` — lazy singleton returning the detected context
* - `isEntryAvailable()` — pure matcher: does the constraint match the context?
* - `checkEntryAvailability()` — structured matcher returning `{available, missingAxes}`
*
* Issue #417 adds:
* - `os` as the new name for `platform` (alias preserved for back-compat)
* - `provider` (vercel / lambda / cloudflare / netlify / docker / bare / …)
* - `target` (the build output produced by `frontmcp build --target <x>`)
* - `surface` (per-call axis: mcp / cli / agent / job / http-trigger)
*/
/**
* Snapshot of the current runtime environment.
* Detected once and cached for the lifetime of the process.
* Snapshot of the current runtime environment. Detected once and cached
* for the lifetime of the process.
*/
export interface RuntimeContext {
/** OS platform: 'darwin', 'linux', 'win32', 'freebsd', etc. */
/** OS platform: 'darwin', 'linux', 'win32', etc. (issue #417: renamed from platform) */
os: string;
/** @deprecated Use `os` instead. Legacy alias preserved for back-compat. */
platform: string;

@@ -22,2 +31,6 @@ /** JavaScript runtime: 'node', 'bun', 'deno', 'edge', 'browser' */

deployment: string;
/** Deploy provider (issue #417): 'vercel', 'lambda', 'cloudflare', 'docker', 'bare', … */
provider: string;
/** Build target produced by `frontmcp build` (issue #417). `'unknown'` in dev. */
target: string;
/** NODE_ENV value: 'production', 'development', 'test', etc. */

@@ -27,2 +40,12 @@ env: string;

/**
* Per-call surface — `surface` is the only axis that varies per request.
* Set by transport adapters / agent dispatchers / job runners on the
* outgoing `ctx` so registry filtering can fork on call origin.
*/
export type Surface = 'mcp' | 'cli' | 'http-trigger' | 'job' | 'agent';
/** Call-context wrapper threaded through `findTool` for per-call filtering. */
export interface CallContext {
surface?: Surface;
}
/**
* Declarative constraint for entry availability.

@@ -39,12 +62,19 @@ *

* ```typescript
* { platform: ['darwin'] }
* { os: ['darwin'] }
* ```
*
* @example Node.js or Bun, production only
* @example CLI binary on Linux only (issue #417)
* ```typescript
* { runtime: ['node', 'bun'], env: ['production'] }
* { target: ['cli'], os: ['linux'] }
* ```
*
* @example MCP-only — block CLI / agent / job invocations (issue #417)
* ```typescript
* { surface: ['mcp'] }
* ```
*/
export interface EntryAvailability {
/** OS platform constraint: 'darwin', 'linux', 'win32', etc. */
/** OS constraint (issue #417: renamed from `platform`). */
os?: string[];
/** @deprecated Use `os` instead. Legacy alias preserved for back-compat. */
platform?: string[];

@@ -55,2 +85,8 @@ /** Runtime constraint: 'node', 'browser', 'edge', 'bun', 'deno' */

deployment?: string[];
/** Deploy-provider constraint (issue #417). */
provider?: string[];
/** Build-target constraint (issue #417). */
target?: string[];
/** Surface constraint (issue #417): 'mcp', 'cli', 'agent', 'job', 'http-trigger'. */
surface?: Surface[];
/** Environment constraint: 'production', 'development', 'test', etc. */

@@ -63,5 +99,15 @@ env?: string[];

export declare const entryAvailabilitySchema: import("@frontmcp/lazy-zod").ZodObject<{
os: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
platform: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
runtime: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
deployment: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
provider: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
target: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
surface: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodEnum<{
cli: "cli";
mcp: "mcp";
"http-trigger": "http-trigger";
job: "job";
agent: "agent";
}>>>;
env: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;

@@ -72,8 +118,22 @@ }, import("zod/v4/core").$strict>;

*
* Surface is checked separately because it's a per-call axis, not a
* process-global one. Pass it via `callCtx.surface` to enforce
* `availableWhen.surface` at call time.
*
* @param availability - The constraint (undefined = always available)
* @param ctx - The current runtime context
* @param callCtx - Optional per-call context (surface, …)
* @returns true if the entry should be available
*/
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext): boolean;
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): boolean;
/**
* Structured variant of `isEntryAvailable` — returns the list of axes
* that failed so flow-level call sites can build a `missingAxes`-shaped
* error response (issue #417).
*/
export declare function checkEntryAvailability(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): {
available: boolean;
missingAxes: (keyof EntryAvailability)[];
};
/**
* Detect the current runtime context from the environment.

@@ -80,0 +140,0 @@ */

@@ -232,2 +232,17 @@ /**

/**
* List directory contents synchronously.
*
* **Node.js only** - throws an error if called in browser.
*
* Use this only when async operations are not possible (e.g., per-scrape
* synchronous metrics collectors). Prefer the async `readdir` in most cases.
*
* @param p - Path to directory
* @returns Array of file/directory names
*
* @example
* const files = readdirSync('/proc/self/fd');
*/
export declare function readdirSync(p: string): string[];
/**
* Remove a file or directory recursively.

@@ -300,2 +315,3 @@ *

cwd?: string;
env?: NodeJS.ProcessEnv;
}): Promise<void>;

@@ -1,1 +0,1 @@

export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, realpath, rm, mkdtemp, symlink, access, fileExists, readJSON, writeJSON, ensureDir, isDirEmpty, runCmd, } from './fs';
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, readdirSync, realpath, rm, mkdtemp, symlink, access, fileExists, readJSON, writeJSON, ensureDir, isDirEmpty, runCmd, } from './fs';

@@ -12,7 +12,7 @@ /**

export type { ParsedUriTemplate } from './uri';
export { trimSlashes, joinPath, pathResolve, pathJoin, basename, dirname, extname, isAbsolute } from './path';
export { trimSlashes, joinPath, pathResolve, pathJoin, basename, dirname, extname, isAbsolute, pathToFileURL, } from './path';
export { sanitizeToJson, inferMimeType, findNonFiniteNumber } from './content';
export { validateBaseUrl, buildSetCookie, parseCookies, getCookie, isLocalhost, isSecureRequest } from './http';
export type { CookieOptions, SecureDetectionRequest } from './http';
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, realpath, rm, mkdtemp, symlink, access, fileExists, readJSON, writeJSON, ensureDir, isDirEmpty, runCmd, } from './fs';
export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, readdirSync, realpath, rm, mkdtemp, symlink, access, fileExists, readJSON, writeJSON, ensureDir, isDirEmpty, runCmd, } from './fs';
export { escapeHtml, escapeHtmlAttr, escapeJsString, escapeScriptClose, safeJsonForScript } from './escape';

@@ -24,3 +24,3 @@ export { safeStringify } from './serialization';

export { EventEmitter } from './event-emitter';
export { getEnv, getCwd, isProduction, isDevelopment, getEnvFlag, isDebug, setEnv, isEdgeRuntime, isServerless, supportsAnsi, getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, entryAvailabilitySchema, } from './env';
export { getEnv, getCwd, isProduction, isDevelopment, getEnvFlag, isDebug, setEnv, isEdgeRuntime, isServerless, supportsAnsi, getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, checkEntryAvailability, entryAvailabilitySchema, } from './env';
export type { RuntimeContext, EntryAvailability } from './env';

@@ -27,0 +27,0 @@ 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';

{
"name": "@frontmcp/utils",
"version": "1.2.1",
"version": "1.3.0",
"description": "Shared utility functions for FrontMCP - string manipulation, URI handling, path utilities, and more",

@@ -37,3 +37,3 @@ "author": "AgentFront <info@agentfront.dev>",

"ioredis": "^5.0.0",
"@frontmcp/lazy-zod": "1.2.1"
"@frontmcp/lazy-zod": "1.3.0"
},

@@ -40,0 +40,0 @@ "peerDependenciesMeta": {

@@ -7,1 +7,2 @@ export declare function resolve(..._segments: string[]): string;

export declare function isAbsolute(p: string): boolean;
export declare function pathToFileURL(_p: string): URL;
export { trimSlashes, joinPath } from './path';
export { resolve as pathResolve, join as pathJoin, basename, dirname, extname, isAbsolute } from '#path';
export { resolve as pathResolve, join as pathJoin, basename, dirname, extname, isAbsolute, pathToFileURL } from '#path';
export { resolve, join, basename, dirname, extname, isAbsolute } from 'path';
export { pathToFileURL } from 'url';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display