@frontmcp/utils
Advanced tools
| /** | ||
| * 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; |
| /** | ||
| * 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 @@ */ |
+16
-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
@@ -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'; |
+3
-3
@@ -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'; |
+2
-2
| { | ||
| "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; |
+1
-1
| 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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
615622
2.75%103
1.98%18201
2.12%85
34.92%