@frontmcp/utils 1.2.1 → 1.3.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-runtime-context.d.ts +35 -3
- package/env/build-target.d.ts +27 -0
- package/env/index.d.ts +6 -2
- package/env/provider.d.ts +33 -0
- package/env/runtime-context.d.ts +69 -9
- package/esm/index.mjs +123 -20
- package/fs/fs.d.ts +16 -0
- package/fs/index.d.ts +1 -1
- package/index.d.ts +3 -3
- package/index.js +126 -20
- package/package.json +2 -2
- package/path/browser-path.d.ts +1 -0
- package/path/index.d.ts +1 -1
- package/path/node-path.d.ts +1 -0
|
@@ -1,28 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Runtime context detection and entry availability matching (Browser version).
|
|
3
3
|
*
|
|
4
|
-
* Returns safe defaults for browser environments.
|
|
5
|
-
*
|
|
4
|
+
* Returns safe defaults for browser environments. The matcher and
|
|
5
|
+
* `EntryAvailability` shape track the Node version (issue #417 added
|
|
6
|
+
* `os`/`provider`/`target`/`surface`).
|
|
6
7
|
*/
|
|
7
8
|
export interface RuntimeContext {
|
|
9
|
+
/** Issue #417: renamed from `platform`. */
|
|
10
|
+
os: string;
|
|
11
|
+
/** @deprecated Use `os`. */
|
|
8
12
|
platform: string;
|
|
9
13
|
runtime: string;
|
|
10
14
|
deployment: string;
|
|
15
|
+
/** Issue #417 — deploy provider. Always `'bare'` in browser. */
|
|
16
|
+
provider: string;
|
|
17
|
+
/** Issue #417 — build target. Always `'browser'` in browser. */
|
|
18
|
+
target: string;
|
|
11
19
|
env: string;
|
|
12
20
|
}
|
|
21
|
+
export type Surface = 'mcp' | 'cli' | 'http-trigger' | 'job' | 'agent';
|
|
22
|
+
export interface CallContext {
|
|
23
|
+
surface?: Surface;
|
|
24
|
+
}
|
|
13
25
|
export interface EntryAvailability {
|
|
26
|
+
/** Issue #417: renamed from `platform`. */
|
|
27
|
+
os?: string[];
|
|
28
|
+
/** @deprecated Use `os`. */
|
|
14
29
|
platform?: string[];
|
|
15
30
|
runtime?: string[];
|
|
16
31
|
deployment?: string[];
|
|
32
|
+
provider?: string[];
|
|
33
|
+
target?: string[];
|
|
34
|
+
surface?: Surface[];
|
|
17
35
|
env?: string[];
|
|
18
36
|
}
|
|
19
37
|
export declare const entryAvailabilitySchema: import("@frontmcp/lazy-zod").ZodObject<{
|
|
38
|
+
os: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
20
39
|
platform: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
21
40
|
runtime: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
22
41
|
deployment: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
42
|
+
provider: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
43
|
+
target: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
44
|
+
surface: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodEnum<{
|
|
45
|
+
cli: "cli";
|
|
46
|
+
mcp: "mcp";
|
|
47
|
+
"http-trigger": "http-trigger";
|
|
48
|
+
job: "job";
|
|
49
|
+
agent: "agent";
|
|
50
|
+
}>>>;
|
|
23
51
|
env: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
24
52
|
}, import("zod/v4/core").$strict>;
|
|
25
|
-
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext): boolean;
|
|
53
|
+
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): boolean;
|
|
54
|
+
export declare function checkEntryAvailability(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): {
|
|
55
|
+
available: boolean;
|
|
56
|
+
missingAxes: (keyof EntryAvailability)[];
|
|
57
|
+
};
|
|
26
58
|
export declare function detectRuntimeContext(): RuntimeContext;
|
|
27
59
|
export declare function getRuntimeContext(): RuntimeContext;
|
|
28
60
|
export declare function resetRuntimeContext(): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-target detection (issue #417).
|
|
3
|
+
*
|
|
4
|
+
* The CLI's `build` command knows the target name (`cli`, `node`,
|
|
5
|
+
* `vercel`, `lambda`, `cloudflare`, `browser`, `sdk`, `mcpb`,
|
|
6
|
+
* `distributed`) but doesn't tell the runtime today. This helper exposes
|
|
7
|
+
* it so `@Tool({ availableWhen: { target: ['cli'] } })` can express
|
|
8
|
+
* "this tool is only valid in the compiled CLI bundle."
|
|
9
|
+
*
|
|
10
|
+
* Resolution order:
|
|
11
|
+
*
|
|
12
|
+
* 1. `globalThis.FRONTMCP_BUILD_TARGET` — preferred. Build adapters
|
|
13
|
+
* inline `const FRONTMCP_BUILD_TARGET = '<target>';` into the
|
|
14
|
+
* emitted entry shim before any user code runs, so this constant
|
|
15
|
+
* is correct from the very first line of imports.
|
|
16
|
+
* 2. `process.env.FRONTMCP_BUILD_TARGET` — set by the build adapter
|
|
17
|
+
* via the runtime env when inlining isn't viable (e.g. SEA).
|
|
18
|
+
* 3. `'unknown'` — dev mode, tests, or any context the build command
|
|
19
|
+
* hasn't touched.
|
|
20
|
+
*
|
|
21
|
+
* The supported values match `frontmcp build --target <name>` plus
|
|
22
|
+
* `'unknown'` for the dev path.
|
|
23
|
+
*/
|
|
24
|
+
export type BuildTarget = 'unknown' | 'node' | 'distributed' | 'cli' | 'vercel' | 'lambda' | 'cloudflare' | 'browser' | 'sdk' | 'mcpb';
|
|
25
|
+
export declare function getBuildTarget(): BuildTarget;
|
|
26
|
+
/** Test helper — reset the cache between specs. */
|
|
27
|
+
export declare function resetBuildTargetCacheForTesting(): void;
|
package/env/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export { getEnv, getCwd, isProduction, isDevelopment, getEnvFlag, isDebug, setEnv, isEdgeRuntime, isServerless, supportsAnsi, } from '#env';
|
|
2
|
-
export { getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, entryAvailabilitySchema, } from '#runtime-context';
|
|
3
|
-
export type { RuntimeContext, EntryAvailability } from '#runtime-context';
|
|
2
|
+
export { getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, checkEntryAvailability, entryAvailabilitySchema, } from '#runtime-context';
|
|
3
|
+
export type { RuntimeContext, EntryAvailability, Surface, CallContext } from '#runtime-context';
|
|
4
|
+
export { detectProvider, resetProviderCacheForTesting } from './provider';
|
|
5
|
+
export type { DeployProvider } from './provider';
|
|
6
|
+
export { getBuildTarget, resetBuildTargetCacheForTesting } from './build-target';
|
|
7
|
+
export type { BuildTarget } from './build-target';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy-provider detection (issue #417).
|
|
3
|
+
*
|
|
4
|
+
* `isServerless()` collapses every serverless env to a single boolean;
|
|
5
|
+
* this returns the discriminated identity so `@Tool({ availableWhen: {
|
|
6
|
+
* provider: ['vercel'] } })` can express provider-specific rules.
|
|
7
|
+
*
|
|
8
|
+
* Order matters — first match wins. A user can override detection by
|
|
9
|
+
* setting `FRONTMCP_PROVIDER=<name>` explicitly (used by tests and by
|
|
10
|
+
* Docker images that don't expose a discriminating env var).
|
|
11
|
+
*/
|
|
12
|
+
export type DeployProvider = 'bare' | 'docker' | 'vercel' | 'lambda' | 'cloudflare' | 'netlify' | 'azure' | 'gcp' | 'fly' | 'render' | 'railway';
|
|
13
|
+
/**
|
|
14
|
+
* Detect the current deploy provider. Cached per process.
|
|
15
|
+
*
|
|
16
|
+
* Detection rules (first match wins):
|
|
17
|
+
*
|
|
18
|
+
* 1. `FRONTMCP_PROVIDER` env var (override; trust whatever the operator set).
|
|
19
|
+
* 2. `VERCEL` env var → `'vercel'`.
|
|
20
|
+
* 3. `AWS_LAMBDA_FUNCTION_NAME` → `'lambda'`.
|
|
21
|
+
* 4. `CF_PAGES` → `'cloudflare'`.
|
|
22
|
+
* 5. `NETLIFY` → `'netlify'`.
|
|
23
|
+
* 6. `AZURE_FUNCTIONS_ENVIRONMENT` → `'azure'`.
|
|
24
|
+
* 7. `K_SERVICE` (Cloud Run / Knative) → `'gcp'`.
|
|
25
|
+
* 8. `FLY_APP_NAME` → `'fly'`.
|
|
26
|
+
* 9. `RENDER` → `'render'`.
|
|
27
|
+
* 10. `RAILWAY_ENVIRONMENT` → `'railway'`.
|
|
28
|
+
* 11. `/.dockerenv` exists → `'docker'`.
|
|
29
|
+
* 12. Fallback: `'bare'`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function detectProvider(): DeployProvider;
|
|
32
|
+
/** Test helper — reset the cache between specs. */
|
|
33
|
+
export declare function resetProviderCacheForTesting(): void;
|
package/env/runtime-context.d.ts
CHANGED
|
@@ -2,25 +2,48 @@
|
|
|
2
2
|
* Runtime context detection and entry availability matching (Node.js version).
|
|
3
3
|
*
|
|
4
4
|
* Provides:
|
|
5
|
-
* - `RuntimeContext` — snapshot of the current platform, runtime, deployment,
|
|
5
|
+
* - `RuntimeContext` — snapshot of the current platform, runtime, deployment, env, provider, target
|
|
6
6
|
* - `EntryAvailability` — declarative constraint for when an entry is available
|
|
7
7
|
* - `getRuntimeContext()` — lazy singleton returning the detected context
|
|
8
8
|
* - `isEntryAvailable()` — pure matcher: does the constraint match the context?
|
|
9
|
+
* - `checkEntryAvailability()` — structured matcher returning `{available, missingAxes}`
|
|
10
|
+
*
|
|
11
|
+
* Issue #417 adds:
|
|
12
|
+
* - `os` as the new name for `platform` (alias preserved for back-compat)
|
|
13
|
+
* - `provider` (vercel / lambda / cloudflare / netlify / docker / bare / …)
|
|
14
|
+
* - `target` (the build output produced by `frontmcp build --target <x>`)
|
|
15
|
+
* - `surface` (per-call axis: mcp / cli / agent / job / http-trigger)
|
|
9
16
|
*/
|
|
10
17
|
/**
|
|
11
|
-
* Snapshot of the current runtime environment.
|
|
12
|
-
*
|
|
18
|
+
* Snapshot of the current runtime environment. Detected once and cached
|
|
19
|
+
* for the lifetime of the process.
|
|
13
20
|
*/
|
|
14
21
|
export interface RuntimeContext {
|
|
15
|
-
/** OS platform: 'darwin', 'linux', 'win32',
|
|
22
|
+
/** OS platform: 'darwin', 'linux', 'win32', etc. (issue #417: renamed from platform) */
|
|
23
|
+
os: string;
|
|
24
|
+
/** @deprecated Use `os` instead. Legacy alias preserved for back-compat. */
|
|
16
25
|
platform: string;
|
|
17
26
|
/** JavaScript runtime: 'node', 'bun', 'deno', 'edge', 'browser' */
|
|
18
27
|
runtime: string;
|
|
19
28
|
/** Deployment mode: 'distributed', 'serverless', 'standalone', or 'browser' */
|
|
20
29
|
deployment: string;
|
|
30
|
+
/** Deploy provider (issue #417): 'vercel', 'lambda', 'cloudflare', 'docker', 'bare', … */
|
|
31
|
+
provider: string;
|
|
32
|
+
/** Build target produced by `frontmcp build` (issue #417). `'unknown'` in dev. */
|
|
33
|
+
target: string;
|
|
21
34
|
/** NODE_ENV value: 'production', 'development', 'test', etc. */
|
|
22
35
|
env: string;
|
|
23
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Per-call surface — `surface` is the only axis that varies per request.
|
|
39
|
+
* Set by transport adapters / agent dispatchers / job runners on the
|
|
40
|
+
* outgoing `ctx` so registry filtering can fork on call origin.
|
|
41
|
+
*/
|
|
42
|
+
export type Surface = 'mcp' | 'cli' | 'http-trigger' | 'job' | 'agent';
|
|
43
|
+
/** Call-context wrapper threaded through `findTool` for per-call filtering. */
|
|
44
|
+
export interface CallContext {
|
|
45
|
+
surface?: Surface;
|
|
46
|
+
}
|
|
24
47
|
/**
|
|
25
48
|
* Declarative constraint for entry availability.
|
|
26
49
|
*
|
|
@@ -33,21 +56,34 @@ export interface RuntimeContext {
|
|
|
33
56
|
*
|
|
34
57
|
* @example macOS only
|
|
35
58
|
* ```typescript
|
|
36
|
-
* {
|
|
59
|
+
* { os: ['darwin'] }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example CLI binary on Linux only (issue #417)
|
|
63
|
+
* ```typescript
|
|
64
|
+
* { target: ['cli'], os: ['linux'] }
|
|
37
65
|
* ```
|
|
38
66
|
*
|
|
39
|
-
* @example
|
|
67
|
+
* @example MCP-only — block CLI / agent / job invocations (issue #417)
|
|
40
68
|
* ```typescript
|
|
41
|
-
* {
|
|
69
|
+
* { surface: ['mcp'] }
|
|
42
70
|
* ```
|
|
43
71
|
*/
|
|
44
72
|
export interface EntryAvailability {
|
|
45
|
-
/** OS
|
|
73
|
+
/** OS constraint (issue #417: renamed from `platform`). */
|
|
74
|
+
os?: string[];
|
|
75
|
+
/** @deprecated Use `os` instead. Legacy alias preserved for back-compat. */
|
|
46
76
|
platform?: string[];
|
|
47
77
|
/** Runtime constraint: 'node', 'browser', 'edge', 'bun', 'deno' */
|
|
48
78
|
runtime?: string[];
|
|
49
79
|
/** Deployment constraint: 'distributed', 'serverless', 'standalone', 'browser' */
|
|
50
80
|
deployment?: string[];
|
|
81
|
+
/** Deploy-provider constraint (issue #417). */
|
|
82
|
+
provider?: string[];
|
|
83
|
+
/** Build-target constraint (issue #417). */
|
|
84
|
+
target?: string[];
|
|
85
|
+
/** Surface constraint (issue #417): 'mcp', 'cli', 'agent', 'job', 'http-trigger'. */
|
|
86
|
+
surface?: Surface[];
|
|
51
87
|
/** Environment constraint: 'production', 'development', 'test', etc. */
|
|
52
88
|
env?: string[];
|
|
53
89
|
}
|
|
@@ -55,19 +91,43 @@ export interface EntryAvailability {
|
|
|
55
91
|
* Zod schema for validating EntryAvailability in metadata.
|
|
56
92
|
*/
|
|
57
93
|
export declare const entryAvailabilitySchema: import("@frontmcp/lazy-zod").ZodObject<{
|
|
94
|
+
os: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
58
95
|
platform: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
59
96
|
runtime: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
60
97
|
deployment: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
98
|
+
provider: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
99
|
+
target: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
100
|
+
surface: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodEnum<{
|
|
101
|
+
cli: "cli";
|
|
102
|
+
mcp: "mcp";
|
|
103
|
+
"http-trigger": "http-trigger";
|
|
104
|
+
job: "job";
|
|
105
|
+
agent: "agent";
|
|
106
|
+
}>>>;
|
|
61
107
|
env: import("@frontmcp/lazy-zod").ZodOptional<import("@frontmcp/lazy-zod").ZodArray<import("@frontmcp/lazy-zod").ZodString>>;
|
|
62
108
|
}, import("zod/v4/core").$strict>;
|
|
63
109
|
/**
|
|
64
110
|
* Check if an entry is available in the given runtime context.
|
|
65
111
|
*
|
|
112
|
+
* Surface is checked separately because it's a per-call axis, not a
|
|
113
|
+
* process-global one. Pass it via `callCtx.surface` to enforce
|
|
114
|
+
* `availableWhen.surface` at call time.
|
|
115
|
+
*
|
|
66
116
|
* @param availability - The constraint (undefined = always available)
|
|
67
117
|
* @param ctx - The current runtime context
|
|
118
|
+
* @param callCtx - Optional per-call context (surface, …)
|
|
68
119
|
* @returns true if the entry should be available
|
|
69
120
|
*/
|
|
70
|
-
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext): boolean;
|
|
121
|
+
export declare function isEntryAvailable(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Structured variant of `isEntryAvailable` — returns the list of axes
|
|
124
|
+
* that failed so flow-level call sites can build a `missingAxes`-shaped
|
|
125
|
+
* error response (issue #417).
|
|
126
|
+
*/
|
|
127
|
+
export declare function checkEntryAvailability(availability: EntryAvailability | undefined, ctx: RuntimeContext, callCtx?: CallContext): {
|
|
128
|
+
available: boolean;
|
|
129
|
+
missingAxes: (keyof EntryAvailability)[];
|
|
130
|
+
};
|
|
71
131
|
/**
|
|
72
132
|
* Detect the current runtime context from the environment.
|
|
73
133
|
*/
|
package/esm/index.mjs
CHANGED
|
@@ -70,8 +70,8 @@ async function readFile(p, encoding = "utf8") {
|
|
|
70
70
|
return fsp.readFile(p, encoding);
|
|
71
71
|
}
|
|
72
72
|
function readFileSync(p, encoding = "utf8") {
|
|
73
|
-
const
|
|
74
|
-
return
|
|
73
|
+
const fs2 = getFs();
|
|
74
|
+
return fs2.readFileSync(p, encoding);
|
|
75
75
|
}
|
|
76
76
|
async function readFileBuffer(p) {
|
|
77
77
|
const fsp = getFsp();
|
|
@@ -143,6 +143,10 @@ async function readdir(p) {
|
|
|
143
143
|
const fsp = getFsp();
|
|
144
144
|
return fsp.readdir(p);
|
|
145
145
|
}
|
|
146
|
+
function readdirSync(p) {
|
|
147
|
+
const fs2 = getFs();
|
|
148
|
+
return fs2.readdirSync(p);
|
|
149
|
+
}
|
|
146
150
|
async function rm(p, options) {
|
|
147
151
|
const fsp = getFsp();
|
|
148
152
|
await fsp.rm(p, options);
|
|
@@ -562,9 +566,9 @@ function createSecretData(options) {
|
|
|
562
566
|
}
|
|
563
567
|
async function getOrCreateSecret(options) {
|
|
564
568
|
const cacheKey = resolveSecretPath(options);
|
|
565
|
-
const
|
|
566
|
-
if (
|
|
567
|
-
return
|
|
569
|
+
const cached4 = secretCache.get(cacheKey);
|
|
570
|
+
if (cached4) {
|
|
571
|
+
return cached4;
|
|
568
572
|
}
|
|
569
573
|
const existing = generationPromises.get(cacheKey);
|
|
570
574
|
if (existing) {
|
|
@@ -801,8 +805,8 @@ var init_key_persistence = __esm({
|
|
|
801
805
|
*/
|
|
802
806
|
async get(kid) {
|
|
803
807
|
if (this.enableCache) {
|
|
804
|
-
const
|
|
805
|
-
if (
|
|
808
|
+
const cached4 = this.cache.get(kid);
|
|
809
|
+
if (cached4) return cached4;
|
|
806
810
|
}
|
|
807
811
|
const raw = await this.storage.get(kid);
|
|
808
812
|
if (!raw) return null;
|
|
@@ -4185,6 +4189,7 @@ function joinPath(...parts) {
|
|
|
4185
4189
|
|
|
4186
4190
|
// libs/utils/src/path/node-path.ts
|
|
4187
4191
|
import { resolve, join, basename, dirname, extname, isAbsolute } from "path";
|
|
4192
|
+
import { pathToFileURL } from "url";
|
|
4188
4193
|
|
|
4189
4194
|
// libs/utils/src/content/content.ts
|
|
4190
4195
|
function sanitizeToJson(value) {
|
|
@@ -4483,23 +4488,114 @@ import {
|
|
|
4483
4488
|
// libs/utils/src/env/runtime-context.ts
|
|
4484
4489
|
import { z as z3 } from "@frontmcp/lazy-zod";
|
|
4485
4490
|
import { isEdgeRuntime, isServerless } from "#env";
|
|
4491
|
+
|
|
4492
|
+
// libs/utils/src/env/build-target.ts
|
|
4493
|
+
var cached;
|
|
4494
|
+
function getBuildTarget() {
|
|
4495
|
+
if (cached) return cached;
|
|
4496
|
+
cached = resolveBuildTarget();
|
|
4497
|
+
return cached;
|
|
4498
|
+
}
|
|
4499
|
+
function resolveBuildTarget() {
|
|
4500
|
+
const globalAny = globalThis;
|
|
4501
|
+
const fromGlobal = globalAny.FRONTMCP_BUILD_TARGET;
|
|
4502
|
+
if (typeof fromGlobal === "string" && isKnownTarget(fromGlobal)) return fromGlobal;
|
|
4503
|
+
const fromEnv = typeof process !== "undefined" ? process.env?.["FRONTMCP_BUILD_TARGET"] : void 0;
|
|
4504
|
+
if (typeof fromEnv === "string" && isKnownTarget(fromEnv)) return fromEnv;
|
|
4505
|
+
return "unknown";
|
|
4506
|
+
}
|
|
4507
|
+
function isKnownTarget(value) {
|
|
4508
|
+
return value === "unknown" || value === "node" || value === "distributed" || value === "cli" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "browser" || value === "sdk" || value === "mcpb";
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
// libs/utils/src/env/provider.ts
|
|
4512
|
+
import * as fs from "node:fs";
|
|
4513
|
+
var cached2;
|
|
4514
|
+
function detectProvider() {
|
|
4515
|
+
if (cached2) return cached2;
|
|
4516
|
+
cached2 = detectProviderUncached();
|
|
4517
|
+
return cached2;
|
|
4518
|
+
}
|
|
4519
|
+
function detectProviderUncached() {
|
|
4520
|
+
const explicit = process.env["FRONTMCP_PROVIDER"];
|
|
4521
|
+
if (explicit && isKnownProvider(explicit)) return explicit;
|
|
4522
|
+
if (process.env["VERCEL"]) return "vercel";
|
|
4523
|
+
if (process.env["AWS_LAMBDA_FUNCTION_NAME"]) return "lambda";
|
|
4524
|
+
if (process.env["CF_PAGES"]) return "cloudflare";
|
|
4525
|
+
if (process.env["NETLIFY"]) return "netlify";
|
|
4526
|
+
if (process.env["AZURE_FUNCTIONS_ENVIRONMENT"]) return "azure";
|
|
4527
|
+
if (process.env["K_SERVICE"]) return "gcp";
|
|
4528
|
+
if (process.env["FLY_APP_NAME"]) return "fly";
|
|
4529
|
+
if (process.env["RENDER"]) return "render";
|
|
4530
|
+
if (process.env["RAILWAY_ENVIRONMENT"]) return "railway";
|
|
4531
|
+
try {
|
|
4532
|
+
if (fs.existsSync("/.dockerenv")) return "docker";
|
|
4533
|
+
} catch {
|
|
4534
|
+
}
|
|
4535
|
+
return "bare";
|
|
4536
|
+
}
|
|
4537
|
+
function isKnownProvider(value) {
|
|
4538
|
+
return value === "bare" || value === "docker" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "netlify" || value === "azure" || value === "gcp" || value === "fly" || value === "render" || value === "railway";
|
|
4539
|
+
}
|
|
4540
|
+
|
|
4541
|
+
// libs/utils/src/env/runtime-context.ts
|
|
4486
4542
|
var entryAvailabilitySchema = z3.object({
|
|
4543
|
+
os: z3.array(z3.string().min(1)).optional(),
|
|
4487
4544
|
platform: z3.array(z3.string().min(1)).optional(),
|
|
4488
4545
|
runtime: z3.array(z3.string().min(1)).optional(),
|
|
4489
4546
|
deployment: z3.array(z3.string().min(1)).optional(),
|
|
4547
|
+
provider: z3.array(z3.string().min(1)).optional(),
|
|
4548
|
+
target: z3.array(z3.string().min(1)).optional(),
|
|
4549
|
+
surface: z3.array(z3.enum(["mcp", "cli", "http-trigger", "job", "agent"])).optional(),
|
|
4490
4550
|
env: z3.array(z3.string().min(1)).optional()
|
|
4491
4551
|
}).strict();
|
|
4492
|
-
|
|
4552
|
+
var PROCESS_AXES = [
|
|
4553
|
+
// `os` and `platform` both compare against the same RuntimeContext value
|
|
4554
|
+
// — keeping `platform` as a deprecated alias lets pre-#417 metadata
|
|
4555
|
+
// continue to match without any code change.
|
|
4556
|
+
{ key: "os", ctxKey: "os" },
|
|
4557
|
+
{ key: "platform", ctxKey: "platform" },
|
|
4558
|
+
{ key: "runtime", ctxKey: "runtime" },
|
|
4559
|
+
{ key: "deployment", ctxKey: "deployment" },
|
|
4560
|
+
{ key: "provider", ctxKey: "provider" },
|
|
4561
|
+
{ key: "target", ctxKey: "target" },
|
|
4562
|
+
{ key: "env", ctxKey: "env" }
|
|
4563
|
+
];
|
|
4564
|
+
function isEntryAvailable(availability, ctx, callCtx) {
|
|
4493
4565
|
if (!availability) return true;
|
|
4494
|
-
const
|
|
4495
|
-
|
|
4496
|
-
const allowed = availability[field];
|
|
4566
|
+
for (const { key, ctxKey } of PROCESS_AXES) {
|
|
4567
|
+
const allowed = availability[key];
|
|
4497
4568
|
if (allowed === void 0) continue;
|
|
4498
4569
|
if (allowed.length === 0) return false;
|
|
4499
|
-
if (!allowed.includes(ctx[
|
|
4570
|
+
if (!allowed.includes(ctx[ctxKey])) return false;
|
|
4571
|
+
}
|
|
4572
|
+
if (availability.surface !== void 0) {
|
|
4573
|
+
if (availability.surface.length === 0) return false;
|
|
4574
|
+
if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
|
|
4575
|
+
return false;
|
|
4576
|
+
}
|
|
4500
4577
|
}
|
|
4501
4578
|
return true;
|
|
4502
4579
|
}
|
|
4580
|
+
function checkEntryAvailability(availability, ctx, callCtx) {
|
|
4581
|
+
if (!availability) return { available: true, missingAxes: [] };
|
|
4582
|
+
const missing = [];
|
|
4583
|
+
for (const { key, ctxKey } of PROCESS_AXES) {
|
|
4584
|
+
const allowed = availability[key];
|
|
4585
|
+
if (allowed === void 0) continue;
|
|
4586
|
+
if (allowed.length === 0 || !allowed.includes(ctx[ctxKey])) {
|
|
4587
|
+
missing.push(key);
|
|
4588
|
+
}
|
|
4589
|
+
}
|
|
4590
|
+
if (availability.surface !== void 0) {
|
|
4591
|
+
if (availability.surface.length === 0) {
|
|
4592
|
+
missing.push("surface");
|
|
4593
|
+
} else if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
|
|
4594
|
+
missing.push("surface");
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
return { available: missing.length === 0, missingAxes: missing };
|
|
4598
|
+
}
|
|
4503
4599
|
function detectRuntime() {
|
|
4504
4600
|
if (typeof globalThis !== "undefined" && "Bun" in globalThis) return "bun";
|
|
4505
4601
|
if (typeof globalThis !== "undefined" && "Deno" in globalThis) return "deno";
|
|
@@ -4516,22 +4612,26 @@ function detectDeployment(runtime) {
|
|
|
4516
4612
|
}
|
|
4517
4613
|
function detectRuntimeContext() {
|
|
4518
4614
|
const runtime = detectRuntime();
|
|
4615
|
+
const os = process.platform;
|
|
4519
4616
|
return {
|
|
4520
|
-
|
|
4617
|
+
os,
|
|
4618
|
+
platform: os,
|
|
4521
4619
|
runtime,
|
|
4522
4620
|
deployment: detectDeployment(runtime),
|
|
4621
|
+
provider: detectProvider(),
|
|
4622
|
+
target: getBuildTarget(),
|
|
4523
4623
|
env: process.env["NODE_ENV"] || "development"
|
|
4524
4624
|
};
|
|
4525
4625
|
}
|
|
4526
|
-
var
|
|
4626
|
+
var cached3;
|
|
4527
4627
|
function getRuntimeContext() {
|
|
4528
|
-
if (!
|
|
4529
|
-
|
|
4628
|
+
if (!cached3) {
|
|
4629
|
+
cached3 = detectRuntimeContext();
|
|
4530
4630
|
}
|
|
4531
|
-
return
|
|
4631
|
+
return cached3;
|
|
4532
4632
|
}
|
|
4533
4633
|
function resetRuntimeContext() {
|
|
4534
|
-
|
|
4634
|
+
cached3 = void 0;
|
|
4535
4635
|
}
|
|
4536
4636
|
|
|
4537
4637
|
// libs/utils/src/storage/factory.ts
|
|
@@ -5372,8 +5472,8 @@ function loadMachineIdSync() {
|
|
|
5372
5472
|
if (!isDevPersistenceEnabled()) return null;
|
|
5373
5473
|
const machineIdPath = resolveMachineIdPath();
|
|
5374
5474
|
try {
|
|
5375
|
-
const
|
|
5376
|
-
const content =
|
|
5475
|
+
const fs2 = __require("fs");
|
|
5476
|
+
const content = fs2.readFileSync(machineIdPath, "utf8").trim();
|
|
5377
5477
|
if (/^[0-9a-f-]{32,36}$/i.test(content)) return content;
|
|
5378
5478
|
console.warn(`[MachineId] Invalid format at ${machineIdPath}, will regenerate`);
|
|
5379
5479
|
return null;
|
|
@@ -5472,6 +5572,7 @@ export {
|
|
|
5472
5572
|
buildPrefix,
|
|
5473
5573
|
buildSetCookie,
|
|
5474
5574
|
bytesToHex,
|
|
5575
|
+
checkEntryAvailability,
|
|
5475
5576
|
clearCachedSecret,
|
|
5476
5577
|
collapseChar,
|
|
5477
5578
|
collapseWhitespace,
|
|
@@ -5573,6 +5674,7 @@ export {
|
|
|
5573
5674
|
parseUriTemplate,
|
|
5574
5675
|
join as pathJoin,
|
|
5575
5676
|
resolve as pathResolve,
|
|
5677
|
+
pathToFileURL,
|
|
5576
5678
|
pemToPublicJwk2 as pemToPublicJwk,
|
|
5577
5679
|
processPlatformToolCalls,
|
|
5578
5680
|
randomBytes,
|
|
@@ -5582,6 +5684,7 @@ export {
|
|
|
5582
5684
|
readFileSync,
|
|
5583
5685
|
readJSON,
|
|
5584
5686
|
readdir,
|
|
5687
|
+
readdirSync,
|
|
5585
5688
|
realpath,
|
|
5586
5689
|
rename,
|
|
5587
5690
|
resetRuntimeContext,
|
package/fs/fs.d.ts
CHANGED
|
@@ -228,6 +228,21 @@ export declare function cp(src: string, dest: string, options?: {
|
|
|
228
228
|
* const files = await readdir('/path/to/dir');
|
|
229
229
|
*/
|
|
230
230
|
export declare function readdir(p: string): Promise<string[]>;
|
|
231
|
+
/**
|
|
232
|
+
* List directory contents synchronously.
|
|
233
|
+
*
|
|
234
|
+
* **Node.js only** - throws an error if called in browser.
|
|
235
|
+
*
|
|
236
|
+
* Use this only when async operations are not possible (e.g., per-scrape
|
|
237
|
+
* synchronous metrics collectors). Prefer the async `readdir` in most cases.
|
|
238
|
+
*
|
|
239
|
+
* @param p - Path to directory
|
|
240
|
+
* @returns Array of file/directory names
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* const files = readdirSync('/proc/self/fd');
|
|
244
|
+
*/
|
|
245
|
+
export declare function readdirSync(p: string): string[];
|
|
231
246
|
/**
|
|
232
247
|
* Remove a file or directory recursively.
|
|
233
248
|
*
|
|
@@ -296,4 +311,5 @@ export declare function access(p: string, mode?: number): Promise<void>;
|
|
|
296
311
|
*/
|
|
297
312
|
export declare function runCmd(cmd: string, args: string[], opts?: {
|
|
298
313
|
cwd?: string;
|
|
314
|
+
env?: NodeJS.ProcessEnv;
|
|
299
315
|
}): Promise<void>;
|
package/fs/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
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';
|
|
1
|
+
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';
|
package/index.d.ts
CHANGED
|
@@ -9,18 +9,18 @@ export { splitWords, toCase, sepFor, shortHash, ensureMaxLen, idFromString } fro
|
|
|
9
9
|
export type { NameCase } from './naming';
|
|
10
10
|
export { isValidMcpUri, extractUriScheme, isValidMcpUriTemplate, parseUriTemplate, matchUriTemplate, expandUriTemplate, extractTemplateParams, isUriTemplate, } from './uri';
|
|
11
11
|
export type { ParsedUriTemplate } from './uri';
|
|
12
|
-
export { trimSlashes, joinPath, pathResolve, pathJoin, basename, dirname, extname, isAbsolute } from './path';
|
|
12
|
+
export { trimSlashes, joinPath, pathResolve, pathJoin, basename, dirname, extname, isAbsolute, pathToFileURL, } from './path';
|
|
13
13
|
export { sanitizeToJson, inferMimeType, findNonFiniteNumber } from './content';
|
|
14
14
|
export { validateBaseUrl, buildSetCookie, parseCookies, getCookie, isLocalhost, isSecureRequest } from './http';
|
|
15
15
|
export type { CookieOptions, SecureDetectionRequest } from './http';
|
|
16
|
-
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';
|
|
16
|
+
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';
|
|
17
17
|
export { escapeHtml, escapeHtmlAttr, escapeJsString, escapeScriptClose, safeJsonForScript } from './escape';
|
|
18
18
|
export { safeStringify } from './serialization';
|
|
19
19
|
export { getCrypto, rsaVerify, rsaVerifySync, pemToPublicJwk, generateRsaKeyPair, rsaSignBase64Url, type RsaJwk, type RsaKeyPair, jwtAlgToNodeAlg, isRsaPssAlg, randomUUID, randomBytes, sha256, sha256Hex, sha256Base64url, hmacSha256, hkdfSha256, encryptAesGcm, decryptAesGcm, timingSafeEqual, bytesToHex, base64urlEncode, base64urlDecode, base64Encode, base64Decode, isNode, isBrowser, assertNode, EncryptedBlobError, encryptValue, decryptValue, tryDecryptValue, serializeBlob, deserializeBlob, tryDeserializeBlob, isValidEncryptedBlob, encryptAndSerialize, deserializeAndDecrypt, tryDeserializeAndDecrypt, generateCodeVerifier, generateCodeChallenge, verifyCodeChallenge, generatePkcePair, isValidCodeVerifier, isValidCodeChallenge, MIN_CODE_VERIFIER_LENGTH, MAX_CODE_VERIFIER_LENGTH, DEFAULT_CODE_VERIFIER_LENGTH, PkceError, type PkcePair, type SecretData, type SecretPersistenceOptions, type SecretValidationResult, secretDataSchema, validateSecretData, parseSecretData, isSecretPersistenceEnabled, resolveSecretPath, loadSecret, saveSecret, deleteSecret, generateSecret, createSecretData, getOrCreateSecret, clearCachedSecret, isSecretCached, type SignedData, type HmacSigningConfig, signData, verifyData, isSignedData, verifyOrParseData, type BaseKeyData, type SecretKeyData, type AsymmetricKeyData, type AnyKeyData, type KeyPersistenceOptions, type CreateKeyPersistenceOptions, type CreateSecretOptions, type CreateAsymmetricOptions, type KeyValidationResult, asymmetricAlgSchema, secretKeyDataSchema, asymmetricKeyDataSchema, anyKeyDataSchema, validateKeyData, parseKeyData, isSecretKeyData, isAsymmetricKeyData, KeyPersistence, createKeyPersistence, createKeyPersistenceWithStorage, } from './crypto';
|
|
20
20
|
export type { CryptoProvider, EncBlob, EncryptedBlob } from './crypto';
|
|
21
21
|
export { AsyncLocalStorage } from './async-context';
|
|
22
22
|
export { EventEmitter } from './event-emitter';
|
|
23
|
-
export { getEnv, getCwd, isProduction, isDevelopment, getEnvFlag, isDebug, setEnv, isEdgeRuntime, isServerless, supportsAnsi, getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, entryAvailabilitySchema, } from './env';
|
|
23
|
+
export { getEnv, getCwd, isProduction, isDevelopment, getEnvFlag, isDebug, setEnv, isEdgeRuntime, isServerless, supportsAnsi, getRuntimeContext, resetRuntimeContext, detectRuntimeContext, isEntryAvailable, checkEntryAvailability, entryAvailabilitySchema, } from './env';
|
|
24
24
|
export type { RuntimeContext, EntryAvailability } from './env';
|
|
25
25
|
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';
|
|
26
26
|
export { createStorage, createMemoryStorage, getDetectedStorageType, NamespacedStorageImpl, createRootStorage, createNamespacedStorage, buildPrefix, NAMESPACE_SEPARATOR, StorageError, StorageConnectionError, StorageOperationError, StorageNotSupportedError, StorageConfigError, StorageTTLError, StoragePatternError, StorageNotConnectedError, EncryptedStorageError, BaseStorageAdapter, MemoryStorageAdapter, RedisStorageAdapter, VercelKvStorageAdapter, UpstashStorageAdapter, FileSystemStorageAdapter, type FileSystemAdapterOptions, TypedStorage, type TypedStorageOptions, type TypedSetOptions, type TypedSetEntry, EncryptedTypedStorage, type EncryptedTypedStorageOptions, type EncryptedSetOptions, type EncryptedSetEntry, type EncryptionKey, type StoredEncryptedBlob, type ClientKeyBinding, globToRegex, matchesPattern, validatePattern, escapeGlob, MAX_TTL_SECONDS, validateTTL, validateOptionalTTL, ttlToExpiresAt, expiresAtToTTL, isExpired, normalizeTTL, } from './storage';
|
package/index.js
CHANGED
|
@@ -75,8 +75,8 @@ async function readFile(p, encoding = "utf8") {
|
|
|
75
75
|
return fsp.readFile(p, encoding);
|
|
76
76
|
}
|
|
77
77
|
function readFileSync(p, encoding = "utf8") {
|
|
78
|
-
const
|
|
79
|
-
return
|
|
78
|
+
const fs2 = getFs();
|
|
79
|
+
return fs2.readFileSync(p, encoding);
|
|
80
80
|
}
|
|
81
81
|
async function readFileBuffer(p) {
|
|
82
82
|
const fsp = getFsp();
|
|
@@ -148,6 +148,10 @@ async function readdir(p) {
|
|
|
148
148
|
const fsp = getFsp();
|
|
149
149
|
return fsp.readdir(p);
|
|
150
150
|
}
|
|
151
|
+
function readdirSync(p) {
|
|
152
|
+
const fs2 = getFs();
|
|
153
|
+
return fs2.readdirSync(p);
|
|
154
|
+
}
|
|
151
155
|
async function rm(p, options) {
|
|
152
156
|
const fsp = getFsp();
|
|
153
157
|
await fsp.rm(p, options);
|
|
@@ -566,9 +570,9 @@ function createSecretData(options) {
|
|
|
566
570
|
}
|
|
567
571
|
async function getOrCreateSecret(options) {
|
|
568
572
|
const cacheKey = resolveSecretPath(options);
|
|
569
|
-
const
|
|
570
|
-
if (
|
|
571
|
-
return
|
|
573
|
+
const cached4 = secretCache.get(cacheKey);
|
|
574
|
+
if (cached4) {
|
|
575
|
+
return cached4;
|
|
572
576
|
}
|
|
573
577
|
const existing = generationPromises.get(cacheKey);
|
|
574
578
|
if (existing) {
|
|
@@ -806,8 +810,8 @@ var init_key_persistence = __esm({
|
|
|
806
810
|
*/
|
|
807
811
|
async get(kid) {
|
|
808
812
|
if (this.enableCache) {
|
|
809
|
-
const
|
|
810
|
-
if (
|
|
813
|
+
const cached4 = this.cache.get(kid);
|
|
814
|
+
if (cached4) return cached4;
|
|
811
815
|
}
|
|
812
816
|
const raw = await this.storage.get(kid);
|
|
813
817
|
if (!raw) return null;
|
|
@@ -3834,6 +3838,7 @@ __export(index_exports, {
|
|
|
3834
3838
|
buildPrefix: () => buildPrefix,
|
|
3835
3839
|
buildSetCookie: () => buildSetCookie,
|
|
3836
3840
|
bytesToHex: () => bytesToHex,
|
|
3841
|
+
checkEntryAvailability: () => checkEntryAvailability,
|
|
3837
3842
|
clearCachedSecret: () => clearCachedSecret,
|
|
3838
3843
|
collapseChar: () => collapseChar,
|
|
3839
3844
|
collapseWhitespace: () => collapseWhitespace,
|
|
@@ -3935,6 +3940,7 @@ __export(index_exports, {
|
|
|
3935
3940
|
parseUriTemplate: () => parseUriTemplate,
|
|
3936
3941
|
pathJoin: () => import_path.join,
|
|
3937
3942
|
pathResolve: () => import_path.resolve,
|
|
3943
|
+
pathToFileURL: () => import_url.pathToFileURL,
|
|
3938
3944
|
pemToPublicJwk: () => pemToPublicJwk2,
|
|
3939
3945
|
processPlatformToolCalls: () => processPlatformToolCalls,
|
|
3940
3946
|
randomBytes: () => randomBytes,
|
|
@@ -3944,6 +3950,7 @@ __export(index_exports, {
|
|
|
3944
3950
|
readFileSync: () => readFileSync,
|
|
3945
3951
|
readJSON: () => readJSON,
|
|
3946
3952
|
readdir: () => readdir,
|
|
3953
|
+
readdirSync: () => readdirSync,
|
|
3947
3954
|
realpath: () => realpath,
|
|
3948
3955
|
rename: () => rename,
|
|
3949
3956
|
resetRuntimeContext: () => resetRuntimeContext,
|
|
@@ -4405,6 +4412,7 @@ function joinPath(...parts) {
|
|
|
4405
4412
|
|
|
4406
4413
|
// libs/utils/src/path/node-path.ts
|
|
4407
4414
|
var import_path = require("path");
|
|
4415
|
+
var import_url = require("url");
|
|
4408
4416
|
|
|
4409
4417
|
// libs/utils/src/content/content.ts
|
|
4410
4418
|
function sanitizeToJson(value) {
|
|
@@ -4692,23 +4700,114 @@ var import_env3 = require("#env");
|
|
|
4692
4700
|
// libs/utils/src/env/runtime-context.ts
|
|
4693
4701
|
var import_lazy_zod3 = require("@frontmcp/lazy-zod");
|
|
4694
4702
|
var import_env2 = require("#env");
|
|
4703
|
+
|
|
4704
|
+
// libs/utils/src/env/build-target.ts
|
|
4705
|
+
var cached;
|
|
4706
|
+
function getBuildTarget() {
|
|
4707
|
+
if (cached) return cached;
|
|
4708
|
+
cached = resolveBuildTarget();
|
|
4709
|
+
return cached;
|
|
4710
|
+
}
|
|
4711
|
+
function resolveBuildTarget() {
|
|
4712
|
+
const globalAny = globalThis;
|
|
4713
|
+
const fromGlobal = globalAny.FRONTMCP_BUILD_TARGET;
|
|
4714
|
+
if (typeof fromGlobal === "string" && isKnownTarget(fromGlobal)) return fromGlobal;
|
|
4715
|
+
const fromEnv = typeof process !== "undefined" ? process.env?.["FRONTMCP_BUILD_TARGET"] : void 0;
|
|
4716
|
+
if (typeof fromEnv === "string" && isKnownTarget(fromEnv)) return fromEnv;
|
|
4717
|
+
return "unknown";
|
|
4718
|
+
}
|
|
4719
|
+
function isKnownTarget(value) {
|
|
4720
|
+
return value === "unknown" || value === "node" || value === "distributed" || value === "cli" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "browser" || value === "sdk" || value === "mcpb";
|
|
4721
|
+
}
|
|
4722
|
+
|
|
4723
|
+
// libs/utils/src/env/provider.ts
|
|
4724
|
+
var fs = __toESM(require("node:fs"));
|
|
4725
|
+
var cached2;
|
|
4726
|
+
function detectProvider() {
|
|
4727
|
+
if (cached2) return cached2;
|
|
4728
|
+
cached2 = detectProviderUncached();
|
|
4729
|
+
return cached2;
|
|
4730
|
+
}
|
|
4731
|
+
function detectProviderUncached() {
|
|
4732
|
+
const explicit = process.env["FRONTMCP_PROVIDER"];
|
|
4733
|
+
if (explicit && isKnownProvider(explicit)) return explicit;
|
|
4734
|
+
if (process.env["VERCEL"]) return "vercel";
|
|
4735
|
+
if (process.env["AWS_LAMBDA_FUNCTION_NAME"]) return "lambda";
|
|
4736
|
+
if (process.env["CF_PAGES"]) return "cloudflare";
|
|
4737
|
+
if (process.env["NETLIFY"]) return "netlify";
|
|
4738
|
+
if (process.env["AZURE_FUNCTIONS_ENVIRONMENT"]) return "azure";
|
|
4739
|
+
if (process.env["K_SERVICE"]) return "gcp";
|
|
4740
|
+
if (process.env["FLY_APP_NAME"]) return "fly";
|
|
4741
|
+
if (process.env["RENDER"]) return "render";
|
|
4742
|
+
if (process.env["RAILWAY_ENVIRONMENT"]) return "railway";
|
|
4743
|
+
try {
|
|
4744
|
+
if (fs.existsSync("/.dockerenv")) return "docker";
|
|
4745
|
+
} catch {
|
|
4746
|
+
}
|
|
4747
|
+
return "bare";
|
|
4748
|
+
}
|
|
4749
|
+
function isKnownProvider(value) {
|
|
4750
|
+
return value === "bare" || value === "docker" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "netlify" || value === "azure" || value === "gcp" || value === "fly" || value === "render" || value === "railway";
|
|
4751
|
+
}
|
|
4752
|
+
|
|
4753
|
+
// libs/utils/src/env/runtime-context.ts
|
|
4695
4754
|
var entryAvailabilitySchema = import_lazy_zod3.z.object({
|
|
4755
|
+
os: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
4696
4756
|
platform: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
4697
4757
|
runtime: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
4698
4758
|
deployment: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
4759
|
+
provider: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
4760
|
+
target: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional(),
|
|
4761
|
+
surface: import_lazy_zod3.z.array(import_lazy_zod3.z.enum(["mcp", "cli", "http-trigger", "job", "agent"])).optional(),
|
|
4699
4762
|
env: import_lazy_zod3.z.array(import_lazy_zod3.z.string().min(1)).optional()
|
|
4700
4763
|
}).strict();
|
|
4701
|
-
|
|
4764
|
+
var PROCESS_AXES = [
|
|
4765
|
+
// `os` and `platform` both compare against the same RuntimeContext value
|
|
4766
|
+
// — keeping `platform` as a deprecated alias lets pre-#417 metadata
|
|
4767
|
+
// continue to match without any code change.
|
|
4768
|
+
{ key: "os", ctxKey: "os" },
|
|
4769
|
+
{ key: "platform", ctxKey: "platform" },
|
|
4770
|
+
{ key: "runtime", ctxKey: "runtime" },
|
|
4771
|
+
{ key: "deployment", ctxKey: "deployment" },
|
|
4772
|
+
{ key: "provider", ctxKey: "provider" },
|
|
4773
|
+
{ key: "target", ctxKey: "target" },
|
|
4774
|
+
{ key: "env", ctxKey: "env" }
|
|
4775
|
+
];
|
|
4776
|
+
function isEntryAvailable(availability, ctx, callCtx) {
|
|
4702
4777
|
if (!availability) return true;
|
|
4703
|
-
const
|
|
4704
|
-
|
|
4705
|
-
const allowed = availability[field];
|
|
4778
|
+
for (const { key, ctxKey } of PROCESS_AXES) {
|
|
4779
|
+
const allowed = availability[key];
|
|
4706
4780
|
if (allowed === void 0) continue;
|
|
4707
4781
|
if (allowed.length === 0) return false;
|
|
4708
|
-
if (!allowed.includes(ctx[
|
|
4782
|
+
if (!allowed.includes(ctx[ctxKey])) return false;
|
|
4783
|
+
}
|
|
4784
|
+
if (availability.surface !== void 0) {
|
|
4785
|
+
if (availability.surface.length === 0) return false;
|
|
4786
|
+
if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
|
|
4787
|
+
return false;
|
|
4788
|
+
}
|
|
4709
4789
|
}
|
|
4710
4790
|
return true;
|
|
4711
4791
|
}
|
|
4792
|
+
function checkEntryAvailability(availability, ctx, callCtx) {
|
|
4793
|
+
if (!availability) return { available: true, missingAxes: [] };
|
|
4794
|
+
const missing = [];
|
|
4795
|
+
for (const { key, ctxKey } of PROCESS_AXES) {
|
|
4796
|
+
const allowed = availability[key];
|
|
4797
|
+
if (allowed === void 0) continue;
|
|
4798
|
+
if (allowed.length === 0 || !allowed.includes(ctx[ctxKey])) {
|
|
4799
|
+
missing.push(key);
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4802
|
+
if (availability.surface !== void 0) {
|
|
4803
|
+
if (availability.surface.length === 0) {
|
|
4804
|
+
missing.push("surface");
|
|
4805
|
+
} else if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
|
|
4806
|
+
missing.push("surface");
|
|
4807
|
+
}
|
|
4808
|
+
}
|
|
4809
|
+
return { available: missing.length === 0, missingAxes: missing };
|
|
4810
|
+
}
|
|
4712
4811
|
function detectRuntime() {
|
|
4713
4812
|
if (typeof globalThis !== "undefined" && "Bun" in globalThis) return "bun";
|
|
4714
4813
|
if (typeof globalThis !== "undefined" && "Deno" in globalThis) return "deno";
|
|
@@ -4725,22 +4824,26 @@ function detectDeployment(runtime) {
|
|
|
4725
4824
|
}
|
|
4726
4825
|
function detectRuntimeContext() {
|
|
4727
4826
|
const runtime = detectRuntime();
|
|
4827
|
+
const os = process.platform;
|
|
4728
4828
|
return {
|
|
4729
|
-
|
|
4829
|
+
os,
|
|
4830
|
+
platform: os,
|
|
4730
4831
|
runtime,
|
|
4731
4832
|
deployment: detectDeployment(runtime),
|
|
4833
|
+
provider: detectProvider(),
|
|
4834
|
+
target: getBuildTarget(),
|
|
4732
4835
|
env: process.env["NODE_ENV"] || "development"
|
|
4733
4836
|
};
|
|
4734
4837
|
}
|
|
4735
|
-
var
|
|
4838
|
+
var cached3;
|
|
4736
4839
|
function getRuntimeContext() {
|
|
4737
|
-
if (!
|
|
4738
|
-
|
|
4840
|
+
if (!cached3) {
|
|
4841
|
+
cached3 = detectRuntimeContext();
|
|
4739
4842
|
}
|
|
4740
|
-
return
|
|
4843
|
+
return cached3;
|
|
4741
4844
|
}
|
|
4742
4845
|
function resetRuntimeContext() {
|
|
4743
|
-
|
|
4846
|
+
cached3 = void 0;
|
|
4744
4847
|
}
|
|
4745
4848
|
|
|
4746
4849
|
// libs/utils/src/storage/factory.ts
|
|
@@ -5581,8 +5684,8 @@ function loadMachineIdSync() {
|
|
|
5581
5684
|
if (!isDevPersistenceEnabled()) return null;
|
|
5582
5685
|
const machineIdPath = resolveMachineIdPath();
|
|
5583
5686
|
try {
|
|
5584
|
-
const
|
|
5585
|
-
const content =
|
|
5687
|
+
const fs2 = require("fs");
|
|
5688
|
+
const content = fs2.readFileSync(machineIdPath, "utf8").trim();
|
|
5586
5689
|
if (/^[0-9a-f-]{32,36}$/i.test(content)) return content;
|
|
5587
5690
|
console.warn(`[MachineId] Invalid format at ${machineIdPath}, will regenerate`);
|
|
5588
5691
|
return null;
|
|
@@ -5682,6 +5785,7 @@ function setMachineIdOverride(id) {
|
|
|
5682
5785
|
buildPrefix,
|
|
5683
5786
|
buildSetCookie,
|
|
5684
5787
|
bytesToHex,
|
|
5788
|
+
checkEntryAvailability,
|
|
5685
5789
|
clearCachedSecret,
|
|
5686
5790
|
collapseChar,
|
|
5687
5791
|
collapseWhitespace,
|
|
@@ -5783,6 +5887,7 @@ function setMachineIdOverride(id) {
|
|
|
5783
5887
|
parseUriTemplate,
|
|
5784
5888
|
pathJoin,
|
|
5785
5889
|
pathResolve,
|
|
5890
|
+
pathToFileURL,
|
|
5786
5891
|
pemToPublicJwk,
|
|
5787
5892
|
processPlatformToolCalls,
|
|
5788
5893
|
randomBytes,
|
|
@@ -5792,6 +5897,7 @@ function setMachineIdOverride(id) {
|
|
|
5792
5897
|
readFileSync,
|
|
5793
5898
|
readJSON,
|
|
5794
5899
|
readdir,
|
|
5900
|
+
readdirSync,
|
|
5795
5901
|
realpath,
|
|
5796
5902
|
rename,
|
|
5797
5903
|
resetRuntimeContext,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Shared utility functions for FrontMCP - string manipulation, URI handling, path utilities, and more",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@vercel/kv": "^2.0.0 || ^3.0.0",
|
|
36
36
|
"ioredis": "^5.0.0",
|
|
37
|
-
"@frontmcp/lazy-zod": "1.
|
|
37
|
+
"@frontmcp/lazy-zod": "1.3.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@vercel/kv": {
|
package/path/browser-path.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export declare function basename(p: string, ext?: string): string;
|
|
|
4
4
|
export declare function dirname(_p: string): string;
|
|
5
5
|
export declare function extname(p: string): string;
|
|
6
6
|
export declare function isAbsolute(p: string): boolean;
|
|
7
|
+
export declare function pathToFileURL(_p: string): URL;
|
package/path/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { trimSlashes, joinPath } from './path';
|
|
2
|
-
export { resolve as pathResolve, join as pathJoin, basename, dirname, extname, isAbsolute } from '#path';
|
|
2
|
+
export { resolve as pathResolve, join as pathJoin, basename, dirname, extname, isAbsolute, pathToFileURL } from '#path';
|
package/path/node-path.d.ts
CHANGED