@frontmcp/utils 1.10.9-rc.1 → 1.10.9-rc.3

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.
@@ -1,192 +1 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // libs/utils/src/env/runtime-context.ts
21
- var runtime_context_exports = {};
22
- __export(runtime_context_exports, {
23
- checkEntryAvailability: () => checkEntryAvailability,
24
- detectRuntimeContext: () => detectRuntimeContext,
25
- entryAvailabilitySchema: () => entryAvailabilitySchema,
26
- getRuntimeContext: () => getRuntimeContext,
27
- isEntryAvailable: () => isEntryAvailable,
28
- resetRuntimeContext: () => resetRuntimeContext
29
- });
30
- module.exports = __toCommonJS(runtime_context_exports);
31
- var import_lazy_zod = require("@frontmcp/lazy-zod");
32
- var import_env = require("#env");
33
-
34
- // libs/utils/src/env/build-target.ts
35
- var cached;
36
- function getBuildTarget() {
37
- if (cached) return cached;
38
- cached = resolveBuildTarget();
39
- return cached;
40
- }
41
- function resolveBuildTarget() {
42
- const globalAny = globalThis;
43
- const fromGlobal = globalAny.FRONTMCP_BUILD_TARGET;
44
- if (typeof fromGlobal === "string" && isKnownTarget(fromGlobal)) return fromGlobal;
45
- const fromEnv = typeof process !== "undefined" ? process.env?.["FRONTMCP_BUILD_TARGET"] : void 0;
46
- if (typeof fromEnv === "string" && isKnownTarget(fromEnv)) return fromEnv;
47
- return "unknown";
48
- }
49
- function isKnownTarget(value) {
50
- return value === "unknown" || value === "node" || value === "distributed" || value === "cli" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "browser" || value === "sdk" || value === "mcpb";
51
- }
52
-
53
- // libs/utils/src/env/provider.ts
54
- var cached2;
55
- function detectProvider() {
56
- if (cached2) return cached2;
57
- cached2 = detectProviderUncached();
58
- return cached2;
59
- }
60
- function detectProviderUncached() {
61
- const explicit = process.env["FRONTMCP_PROVIDER"];
62
- if (explicit && isKnownProvider(explicit)) return explicit;
63
- if (process.env["VERCEL"]) return "vercel";
64
- if (process.env["AWS_LAMBDA_FUNCTION_NAME"]) return "lambda";
65
- if (process.env["CF_PAGES"]) return "cloudflare";
66
- if (process.env["NETLIFY"]) return "netlify";
67
- if (process.env["AZURE_FUNCTIONS_ENVIRONMENT"]) return "azure";
68
- if (process.env["K_SERVICE"]) return "gcp";
69
- if (process.env["FLY_APP_NAME"]) return "fly";
70
- if (process.env["RENDER"]) return "render";
71
- if (process.env["RAILWAY_ENVIRONMENT"]) return "railway";
72
- try {
73
- const nodeFs = require("node:fs");
74
- if (nodeFs.existsSync("/.dockerenv")) return "docker";
75
- } catch {
76
- }
77
- return "bare";
78
- }
79
- function isKnownProvider(value) {
80
- return value === "bare" || value === "docker" || value === "vercel" || value === "lambda" || value === "cloudflare" || value === "netlify" || value === "azure" || value === "gcp" || value === "fly" || value === "render" || value === "railway";
81
- }
82
-
83
- // libs/utils/src/env/runtime-context.ts
84
- var entryAvailabilitySchema = import_lazy_zod.z.object({
85
- os: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),
86
- platform: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),
87
- runtime: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),
88
- deployment: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),
89
- provider: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),
90
- target: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),
91
- surface: import_lazy_zod.z.array(import_lazy_zod.z.enum(["mcp", "cli", "http-trigger", "job", "agent", "webmcp"])).optional(),
92
- env: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional()
93
- }).strict();
94
- var PROCESS_AXES = [
95
- // `os` and `platform` both compare against the same RuntimeContext value
96
- // — keeping `platform` as a deprecated alias lets pre-#417 metadata
97
- // continue to match without any code change.
98
- { key: "os", ctxKey: "os" },
99
- { key: "platform", ctxKey: "platform" },
100
- { key: "runtime", ctxKey: "runtime" },
101
- { key: "deployment", ctxKey: "deployment" },
102
- { key: "provider", ctxKey: "provider" },
103
- { key: "target", ctxKey: "target" },
104
- { key: "env", ctxKey: "env" }
105
- ];
106
- function isEntryAvailable(availability, ctx, callCtx) {
107
- if (!availability) return true;
108
- for (const { key, ctxKey } of PROCESS_AXES) {
109
- const allowed = availability[key];
110
- if (allowed === void 0) continue;
111
- if (allowed.length === 0) return false;
112
- if (!allowed.includes(ctx[ctxKey])) return false;
113
- }
114
- if (availability.surface !== void 0) {
115
- if (availability.surface.length === 0) return false;
116
- if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
117
- return false;
118
- }
119
- }
120
- return true;
121
- }
122
- function checkEntryAvailability(availability, ctx, callCtx) {
123
- if (!availability) return { available: true, missingAxes: [] };
124
- const missing = [];
125
- for (const { key, ctxKey } of PROCESS_AXES) {
126
- const allowed = availability[key];
127
- if (allowed === void 0) continue;
128
- if (allowed.length === 0 || !allowed.includes(ctx[ctxKey])) {
129
- missing.push(key);
130
- }
131
- }
132
- if (availability.surface !== void 0) {
133
- if (availability.surface.length === 0) {
134
- missing.push("surface");
135
- } else if (callCtx?.surface !== void 0 && !availability.surface.includes(callCtx.surface)) {
136
- missing.push("surface");
137
- }
138
- }
139
- return { available: missing.length === 0, missingAxes: missing };
140
- }
141
- function detectRuntime() {
142
- if (typeof globalThis !== "undefined" && "Bun" in globalThis) return "bun";
143
- if (typeof globalThis !== "undefined" && "Deno" in globalThis) return "deno";
144
- if ((0, import_env.isEdgeRuntime)()) return "edge";
145
- return "node";
146
- }
147
- function detectDeployment(runtime) {
148
- const explicit = process.env["FRONTMCP_DEPLOYMENT_MODE"];
149
- if (explicit === "distributed") return "distributed";
150
- if (explicit === "serverless") return "serverless";
151
- if (runtime === "browser") return "browser";
152
- if ((0, import_env.isServerless)()) return "serverless";
153
- return "standalone";
154
- }
155
- function detectRuntimeContext() {
156
- const runtime = detectRuntime();
157
- const os = process.platform;
158
- return {
159
- os,
160
- platform: os,
161
- runtime,
162
- deployment: detectDeployment(runtime),
163
- provider: detectProvider(),
164
- target: getBuildTarget(),
165
- env: (0, import_env.getNodeEnv)() || "development"
166
- };
167
- }
168
- var cached3;
169
- function getRuntimeContext() {
170
- if (!cached3) {
171
- const detected = detectRuntimeContext();
172
- Object.defineProperty(detected, "env", {
173
- get: () => (0, import_env.getNodeEnv)() || "development",
174
- enumerable: true,
175
- configurable: true
176
- });
177
- cached3 = detected;
178
- }
179
- return cached3;
180
- }
181
- function resetRuntimeContext() {
182
- cached3 = void 0;
183
- }
184
- // Annotate the CommonJS export names for ESM import in node:
185
- 0 && (module.exports = {
186
- checkEntryAvailability,
187
- detectRuntimeContext,
188
- entryAvailabilitySchema,
189
- getRuntimeContext,
190
- isEntryAvailable,
191
- resetRuntimeContext
192
- });
1
+ "use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var runtime_context_exports={};__export(runtime_context_exports,{checkEntryAvailability:()=>checkEntryAvailability,detectRuntimeContext:()=>detectRuntimeContext,entryAvailabilitySchema:()=>entryAvailabilitySchema,getRuntimeContext:()=>getRuntimeContext,isEntryAvailable:()=>isEntryAvailable,resetRuntimeContext:()=>resetRuntimeContext});module.exports=__toCommonJS(runtime_context_exports);var import_lazy_zod=require("@frontmcp/lazy-zod");var import_env=require("#env");var cached;function getBuildTarget(){if(cached)return cached;cached=resolveBuildTarget();return cached}function resolveBuildTarget(){const globalAny=globalThis;const fromGlobal=globalAny.FRONTMCP_BUILD_TARGET;if(typeof fromGlobal==="string"&&isKnownTarget(fromGlobal))return fromGlobal;const fromEnv=typeof process!=="undefined"?process.env?.["FRONTMCP_BUILD_TARGET"]:void 0;if(typeof fromEnv==="string"&&isKnownTarget(fromEnv))return fromEnv;return"unknown"}function isKnownTarget(value){return value==="unknown"||value==="node"||value==="distributed"||value==="cli"||value==="vercel"||value==="lambda"||value==="cloudflare"||value==="browser"||value==="sdk"||value==="mcpb"}var cached2;function detectProvider(){if(cached2)return cached2;cached2=detectProviderUncached();return cached2}function detectProviderUncached(){const explicit=process.env["FRONTMCP_PROVIDER"];if(explicit&&isKnownProvider(explicit))return explicit;if(process.env["VERCEL"])return"vercel";if(process.env["AWS_LAMBDA_FUNCTION_NAME"])return"lambda";if(process.env["CF_PAGES"])return"cloudflare";if(process.env["NETLIFY"])return"netlify";if(process.env["AZURE_FUNCTIONS_ENVIRONMENT"])return"azure";if(process.env["K_SERVICE"])return"gcp";if(process.env["FLY_APP_NAME"])return"fly";if(process.env["RENDER"])return"render";if(process.env["RAILWAY_ENVIRONMENT"])return"railway";try{const nodeFs=require("node:fs");if(nodeFs.existsSync("/.dockerenv"))return"docker"}catch{}return"bare"}function isKnownProvider(value){return value==="bare"||value==="docker"||value==="vercel"||value==="lambda"||value==="cloudflare"||value==="netlify"||value==="azure"||value==="gcp"||value==="fly"||value==="render"||value==="railway"}var entryAvailabilitySchema=import_lazy_zod.z.object({os:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),platform:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),runtime:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),deployment:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),provider:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),target:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional(),surface:import_lazy_zod.z.array(import_lazy_zod.z.enum(["mcp","cli","http-trigger","job","agent","webmcp"])).optional(),env:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).optional()}).strict();var PROCESS_AXES=[{key:"os",ctxKey:"os"},{key:"platform",ctxKey:"platform"},{key:"runtime",ctxKey:"runtime"},{key:"deployment",ctxKey:"deployment"},{key:"provider",ctxKey:"provider"},{key:"target",ctxKey:"target"},{key:"env",ctxKey:"env"}];function isEntryAvailable(availability,ctx,callCtx){if(!availability)return true;for(const{key,ctxKey}of PROCESS_AXES){const allowed=availability[key];if(allowed===void 0)continue;if(allowed.length===0)return false;if(!allowed.includes(ctx[ctxKey]))return false}if(availability.surface!==void 0){if(availability.surface.length===0)return false;if(callCtx?.surface!==void 0&&!availability.surface.includes(callCtx.surface)){return false}}return true}function checkEntryAvailability(availability,ctx,callCtx){if(!availability)return{available:true,missingAxes:[]};const missing=[];for(const{key,ctxKey}of PROCESS_AXES){const allowed=availability[key];if(allowed===void 0)continue;if(allowed.length===0||!allowed.includes(ctx[ctxKey])){missing.push(key)}}if(availability.surface!==void 0){if(availability.surface.length===0){missing.push("surface")}else if(callCtx?.surface!==void 0&&!availability.surface.includes(callCtx.surface)){missing.push("surface")}}return{available:missing.length===0,missingAxes:missing}}function detectRuntime(){if(typeof globalThis!=="undefined"&&"Bun"in globalThis)return"bun";if(typeof globalThis!=="undefined"&&"Deno"in globalThis)return"deno";if((0,import_env.isEdgeRuntime)())return"edge";return"node"}function detectDeployment(runtime){const explicit=process.env["FRONTMCP_DEPLOYMENT_MODE"];if(explicit==="distributed")return"distributed";if(explicit==="serverless")return"serverless";if(runtime==="browser")return"browser";if((0,import_env.isServerless)())return"serverless";return"standalone"}function detectRuntimeContext(){const runtime=detectRuntime();const os=process.platform;return{os,platform:os,runtime,deployment:detectDeployment(runtime),provider:detectProvider(),target:getBuildTarget(),env:(0,import_env.getNodeEnv)()||"development"}}var cached3;function getRuntimeContext(){if(!cached3){const detected=detectRuntimeContext();Object.defineProperty(detected,"env",{get:()=>(0,import_env.getNodeEnv)()||"development",enumerable:true,configurable:true});cached3=detected}return cached3}function resetRuntimeContext(){cached3=void 0}0&&(module.exports={checkEntryAvailability,detectRuntimeContext,entryAvailabilitySchema,getRuntimeContext,isEntryAvailable,resetRuntimeContext});
@@ -1,183 +1 @@
1
- // libs/utils/src/async-context/overlap-error.ts
2
- var AsyncContextOverlapError = class extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = "AsyncContextOverlapError";
6
- }
7
- };
8
-
9
- // libs/utils/src/async-context/browser-async-context.ts
10
- var nativeAsyncContext = (() => {
11
- const candidate = globalThis.AsyncContext;
12
- return typeof candidate?.Variable === "function" ? candidate : void 0;
13
- })();
14
- function getAsyncContextMode() {
15
- return nativeAsyncContext ? "native" : "serialized";
16
- }
17
- var SLOW_TURN_WARNING_MS = 1e4;
18
- var RequestSlot = class {
19
- /** Frames of every storage that are still running in this request. */
20
- live = 0;
21
- /** Storages whose runs overlapped in this request; they refuse to answer until they unwind. */
22
- tainted = /* @__PURE__ */ new Set();
23
- idleWaiters = [];
24
- enter() {
25
- this.live++;
26
- }
27
- leave() {
28
- this.live--;
29
- if (this.live === 0) {
30
- for (const resolve of this.idleWaiters.splice(0)) resolve();
31
- }
32
- }
33
- /** Resolves once no frame of this request is running any more. */
34
- idle() {
35
- return this.live === 0 ? Promise.resolve() : new Promise((resolve) => this.idleWaiters.push(resolve));
36
- }
37
- };
38
- var ROOT = new RequestSlot();
39
- var active = ROOT;
40
- var owner;
41
- var turnQueue = [];
42
- var slowTurnWarned = false;
43
- var overlapReported = false;
44
- function takeTurn(slot) {
45
- if (!owner) {
46
- owner = slot;
47
- active = slot;
48
- return Promise.resolve();
49
- }
50
- return new Promise((resolve) => {
51
- const timer = setTimeout(() => {
52
- if (slowTurnWarned) return;
53
- slowTurnWarned = true;
54
- console.warn(
55
- "[frontmcp] A request has waited more than 10s for another one to finish. This runtime has no AsyncContext, so FrontMCP runs requests one at a time to keep their contexts apart. A tool that calls its own server through a client (instead of this.scope flows) waits for itself."
56
- );
57
- }, SLOW_TURN_WARNING_MS);
58
- timer.unref?.();
59
- turnQueue.push({
60
- slot,
61
- start: () => {
62
- clearTimeout(timer);
63
- resolve();
64
- }
65
- });
66
- });
67
- }
68
- function passTurn(slot) {
69
- if (owner !== slot) return;
70
- const next = turnQueue.shift();
71
- if (next) {
72
- owner = next.slot;
73
- active = next.slot;
74
- next.start();
75
- } else {
76
- owner = void 0;
77
- active = ROOT;
78
- }
79
- }
80
- async function runRequestExclusive(fn) {
81
- if (nativeAsyncContext) return fn();
82
- const slot = new RequestSlot();
83
- await takeTurn(slot);
84
- try {
85
- return await fn();
86
- } finally {
87
- await slot.idle();
88
- passTurn(slot);
89
- }
90
- }
91
- async function awaitOutsideRequest(promise) {
92
- if (nativeAsyncContext) return promise;
93
- const slot = owner;
94
- if (!slot || active !== slot) return promise;
95
- passTurn(slot);
96
- try {
97
- return await promise;
98
- } finally {
99
- await takeTurn(slot);
100
- }
101
- }
102
- var AsyncLocalStorage = class {
103
- native;
104
- stacks = /* @__PURE__ */ new WeakMap();
105
- constructor() {
106
- if (nativeAsyncContext) this.native = new nativeAsyncContext.Variable();
107
- }
108
- run(store, callback, ...args) {
109
- if (this.native) return this.native.run(store, callback, ...args);
110
- const slot = active;
111
- let stack = this.stacks.get(slot);
112
- if (!stack) {
113
- stack = [];
114
- this.stacks.set(slot, stack);
115
- }
116
- const frame = { store };
117
- stack.push(frame);
118
- slot.enter();
119
- let result;
120
- try {
121
- result = callback(...args);
122
- } catch (error) {
123
- this.leave(slot, frame);
124
- throw error;
125
- }
126
- if (result instanceof Promise) {
127
- return result.then(
128
- (value) => {
129
- if (!this.leave(slot, frame)) throw this.overlapError();
130
- return value;
131
- },
132
- (error) => {
133
- this.leave(slot, frame);
134
- throw error;
135
- }
136
- );
137
- }
138
- this.leave(slot, frame);
139
- return result;
140
- }
141
- getStore() {
142
- if (this.native) return this.native.get();
143
- const slot = active;
144
- if (slot.tainted.has(this)) throw this.overlapError();
145
- const stack = this.stacks.get(slot);
146
- return stack && stack.length > 0 ? stack[stack.length - 1].store : void 0;
147
- }
148
- /**
149
- * Remove `frame` from its request's stack. Returns false when it was not the innermost frame: a
150
- * later run of this storage in the same request was still open, so the two overlapped and reads
151
- * in between may have seen the other run's store.
152
- */
153
- leave(slot, frame) {
154
- const stack = this.stacks.get(slot) ?? [];
155
- const index = stack.lastIndexOf(frame);
156
- const innermost = index === stack.length - 1;
157
- if (index !== -1) stack.splice(index, 1);
158
- if (!innermost) {
159
- slot.tainted.add(this);
160
- if (!overlapReported) {
161
- overlapReported = true;
162
- console.error(
163
- "[frontmcp] Two concurrent runs of one async context overlapped inside a request. This runtime has no AsyncContext, so the context of each cannot be told apart; reads fail for the rest of that request instead of returning the wrong value."
164
- );
165
- }
166
- }
167
- if (stack.length === 0) slot.tainted.delete(this);
168
- slot.leave();
169
- return innermost;
170
- }
171
- overlapError() {
172
- return new AsyncContextOverlapError(
173
- "Concurrent runs of an async context overlapped in one request, and this runtime has no AsyncContext to tell them apart. Run the calls one after another, or use a runtime with AsyncContext."
174
- );
175
- }
176
- };
177
- export {
178
- AsyncContextOverlapError,
179
- AsyncLocalStorage,
180
- awaitOutsideRequest,
181
- getAsyncContextMode,
182
- runRequestExclusive
183
- };
1
+ var AsyncContextOverlapError=class extends Error{constructor(message){super(message);this.name="AsyncContextOverlapError"}};var nativeAsyncContext=(()=>{const candidate=globalThis.AsyncContext;return typeof candidate?.Variable==="function"?candidate:void 0})();function getAsyncContextMode(){return nativeAsyncContext?"native":"serialized"}var SLOW_TURN_WARNING_MS=1e4;var RequestSlot=class{live=0;tainted=new Set;idleWaiters=[];enter(){this.live++}leave(){this.live--;if(this.live===0){for(const resolve of this.idleWaiters.splice(0))resolve()}}idle(){return this.live===0?Promise.resolve():new Promise(resolve=>this.idleWaiters.push(resolve))}};var ROOT=new RequestSlot;var active=ROOT;var owner;var turnQueue=[];var slowTurnWarned=false;var overlapReported=false;function takeTurn(slot){if(!owner){owner=slot;active=slot;return Promise.resolve()}return new Promise(resolve=>{const timer=setTimeout(()=>{if(slowTurnWarned)return;slowTurnWarned=true;console.warn("[frontmcp] A request has waited more than 10s for another one to finish. This runtime has no AsyncContext, so FrontMCP runs requests one at a time to keep their contexts apart. A tool that calls its own server through a client (instead of this.scope flows) waits for itself.")},SLOW_TURN_WARNING_MS);timer.unref?.();turnQueue.push({slot,start:()=>{clearTimeout(timer);resolve()}})})}function passTurn(slot){if(owner!==slot)return;const next=turnQueue.shift();if(next){owner=next.slot;active=next.slot;next.start()}else{owner=void 0;active=ROOT}}async function runRequestExclusive(fn){if(nativeAsyncContext)return fn();const slot=new RequestSlot;await takeTurn(slot);try{return await fn()}finally{await slot.idle();passTurn(slot)}}async function awaitOutsideRequest(promise){if(nativeAsyncContext)return promise;const slot=owner;if(!slot||active!==slot)return promise;passTurn(slot);try{return await promise}finally{await takeTurn(slot)}}var AsyncLocalStorage=class{native;stacks=new WeakMap;constructor(){if(nativeAsyncContext)this.native=new nativeAsyncContext.Variable}run(store,callback,...args){if(this.native)return this.native.run(store,callback,...args);const slot=active;let stack=this.stacks.get(slot);if(!stack){stack=[];this.stacks.set(slot,stack)}const frame={store};stack.push(frame);slot.enter();let result;try{result=callback(...args)}catch(error){this.leave(slot,frame);throw error}if(result instanceof Promise){return result.then(value=>{if(!this.leave(slot,frame))throw this.overlapError();return value},error=>{this.leave(slot,frame);throw error})}this.leave(slot,frame);return result}getStore(){if(this.native)return this.native.get();const slot=active;if(slot.tainted.has(this))throw this.overlapError();const stack=this.stacks.get(slot);return stack&&stack.length>0?stack[stack.length-1].store:void 0}leave(slot,frame){const stack=this.stacks.get(slot)??[];const index=stack.lastIndexOf(frame);const innermost=index===stack.length-1;if(index!==-1)stack.splice(index,1);if(!innermost){slot.tainted.add(this);if(!overlapReported){overlapReported=true;console.error("[frontmcp] Two concurrent runs of one async context overlapped inside a request. This runtime has no AsyncContext, so the context of each cannot be told apart; reads fail for the rest of that request instead of returning the wrong value.")}}if(stack.length===0)slot.tainted.delete(this);slot.leave();return innermost}overlapError(){return new AsyncContextOverlapError("Concurrent runs of an async context overlapped in one request, and this runtime has no AsyncContext to tell them apart. Run the calls one after another, or use a runtime with AsyncContext.")}};export{AsyncContextOverlapError,AsyncLocalStorage,awaitOutsideRequest,getAsyncContextMode,runRequestExclusive};
@@ -1,28 +1 @@
1
- // libs/utils/src/async-context/node-async-context.ts
2
- import { AsyncLocalStorage } from "node:async_hooks";
3
-
4
- // libs/utils/src/async-context/overlap-error.ts
5
- var AsyncContextOverlapError = class extends Error {
6
- constructor(message) {
7
- super(message);
8
- this.name = "AsyncContextOverlapError";
9
- }
10
- };
11
-
12
- // libs/utils/src/async-context/node-async-context.ts
13
- function getAsyncContextMode() {
14
- return "native";
15
- }
16
- async function runRequestExclusive(fn) {
17
- return fn();
18
- }
19
- async function awaitOutsideRequest(promise) {
20
- return promise;
21
- }
22
- export {
23
- AsyncContextOverlapError,
24
- AsyncLocalStorage,
25
- awaitOutsideRequest,
26
- getAsyncContextMode,
27
- runRequestExclusive
28
- };
1
+ import{AsyncLocalStorage}from"node:async_hooks";var AsyncContextOverlapError=class extends Error{constructor(message){super(message);this.name="AsyncContextOverlapError"}};function getAsyncContextMode(){return"native"}async function runRequestExclusive(fn){return fn()}async function awaitOutsideRequest(promise){return promise}export{AsyncContextOverlapError,AsyncLocalStorage,awaitOutsideRequest,getAsyncContextMode,runRequestExclusive};
@@ -1,154 +1 @@
1
- // libs/utils/src/crypto/browser.ts
2
- import { gcm } from "@noble/ciphers/aes.js";
3
- import { hkdf } from "@noble/hashes/hkdf.js";
4
- import { hmac } from "@noble/hashes/hmac.js";
5
- import { sha256 as sha256Hash } from "@noble/hashes/sha2.js";
6
- import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils.js";
7
-
8
- // libs/utils/src/crypto/jwt-alg.ts
9
- function isRsaPssAlg(jwtAlg) {
10
- return jwtAlg.startsWith("PS");
11
- }
12
- var JWT_ALG_TO_WEB_CRYPTO = {
13
- RS256: "SHA-256",
14
- RS384: "SHA-384",
15
- RS512: "SHA-512",
16
- PS256: "SHA-256",
17
- PS384: "SHA-384",
18
- PS512: "SHA-512"
19
- };
20
- function jwtAlgToWebCryptoAlg(jwtAlg) {
21
- const webAlg = JWT_ALG_TO_WEB_CRYPTO[jwtAlg];
22
- if (!webAlg) {
23
- throw new Error(`Unsupported JWT algorithm for WebCrypto: ${jwtAlg}`);
24
- }
25
- return webAlg;
26
- }
27
-
28
- // libs/utils/src/crypto/browser.ts
29
- function toBytes(data) {
30
- if (typeof data === "string") {
31
- return new TextEncoder().encode(data);
32
- }
33
- return data;
34
- }
35
- function toHex(bytes) {
36
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
37
- }
38
- function generateUUID() {
39
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
40
- return crypto.randomUUID();
41
- }
42
- const bytes = nobleRandomBytes(16);
43
- bytes[6] = bytes[6] & 15 | 64;
44
- bytes[8] = bytes[8] & 63 | 128;
45
- const hex = toHex(bytes);
46
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
47
- }
48
- function constantTimeEqual(a, b) {
49
- if (a.length !== b.length) return false;
50
- let result = 0;
51
- for (let i = 0; i < a.length; i++) {
52
- result |= a[i] ^ b[i];
53
- }
54
- return result === 0;
55
- }
56
- var browserCrypto = {
57
- randomUUID() {
58
- return generateUUID();
59
- },
60
- randomBytes(length) {
61
- return nobleRandomBytes(length);
62
- },
63
- sha256(data) {
64
- return sha256Hash(toBytes(data));
65
- },
66
- sha256Hex(data) {
67
- return toHex(sha256Hash(toBytes(data)));
68
- },
69
- hmacSha256(key, data) {
70
- return hmac(sha256Hash, key, data);
71
- },
72
- hkdfSha256(ikm, salt, info, length) {
73
- const effectiveSalt = salt.length > 0 ? salt : new Uint8Array(32);
74
- return hkdf(sha256Hash, ikm, effectiveSalt, info, length);
75
- },
76
- encryptAesGcm(key, plaintext, iv) {
77
- const cipher = gcm(key, iv);
78
- const sealed = cipher.encrypt(plaintext);
79
- const ciphertext = sealed.slice(0, -16);
80
- const tag = sealed.slice(-16);
81
- return { ciphertext, tag };
82
- },
83
- decryptAesGcm(key, ciphertext, iv, tag) {
84
- const cipher = gcm(key, iv);
85
- const sealed = new Uint8Array(ciphertext.length + tag.length);
86
- sealed.set(ciphertext);
87
- sealed.set(tag, ciphertext.length);
88
- return cipher.decrypt(sealed);
89
- },
90
- timingSafeEqual(a, b) {
91
- return constantTimeEqual(a, b);
92
- }
93
- };
94
- function nodeOnly(name) {
95
- throw new Error(`${name} is only available in Node.js runtimes`);
96
- }
97
- function rsaVerify() {
98
- return nodeOnly("rsaVerify");
99
- }
100
- function rsaSignBase64Url() {
101
- return nodeOnly("rsaSignBase64Url");
102
- }
103
- function rsaVerifySync() {
104
- return nodeOnly("rsaVerifySync");
105
- }
106
- function pemToPublicJwk() {
107
- return nodeOnly("pemToPublicJwk");
108
- }
109
- function generateRsaKeyPair() {
110
- return nodeOnly("generateRsaKeyPair");
111
- }
112
- async function rsaVerifyBrowser(jwtAlg, data, publicJwk, signature) {
113
- if (typeof globalThis.crypto?.subtle === "undefined") {
114
- throw new Error("WebCrypto API (crypto.subtle) is not available in this environment");
115
- }
116
- const webAlg = jwtAlgToWebCryptoAlg(jwtAlg);
117
- const isPss = isRsaPssAlg(jwtAlg);
118
- const algorithm = {
119
- name: isPss ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
120
- hash: { name: webAlg }
121
- };
122
- const key = await globalThis.crypto.subtle.importKey("jwk", publicJwk, algorithm, false, ["verify"]);
123
- const verifyAlgorithm = isPss ? { name: "RSA-PSS", saltLength: getSaltLength(jwtAlg) } : { name: "RSASSA-PKCS1-v1_5" };
124
- const sigBuf = new Uint8Array(signature).buffer;
125
- const dataBuf = new Uint8Array(data).buffer;
126
- return globalThis.crypto.subtle.verify(verifyAlgorithm, key, sigBuf, dataBuf);
127
- }
128
- function getSaltLength(jwtAlg) {
129
- switch (jwtAlg) {
130
- case "PS256":
131
- return 32;
132
- // SHA-256 digest length
133
- case "PS384":
134
- return 48;
135
- // SHA-384 digest length
136
- case "PS512":
137
- return 64;
138
- // SHA-512 digest length
139
- default:
140
- return 32;
141
- }
142
- }
143
- export {
144
- browserCrypto,
145
- browserCrypto as cryptoProvider,
146
- generateRsaKeyPair,
147
- isRsaPssAlg,
148
- jwtAlgToWebCryptoAlg,
149
- pemToPublicJwk,
150
- rsaSignBase64Url,
151
- rsaVerify,
152
- rsaVerifyBrowser,
153
- rsaVerifySync
154
- };
1
+ import{gcm}from"@noble/ciphers/aes.js";import{hkdf}from"@noble/hashes/hkdf.js";import{hmac}from"@noble/hashes/hmac.js";import{sha256 as sha256Hash}from"@noble/hashes/sha2.js";import{randomBytes as nobleRandomBytes}from"@noble/hashes/utils.js";function isRsaPssAlg(jwtAlg){return jwtAlg.startsWith("PS")}var JWT_ALG_TO_WEB_CRYPTO={RS256:"SHA-256",RS384:"SHA-384",RS512:"SHA-512",PS256:"SHA-256",PS384:"SHA-384",PS512:"SHA-512"};function jwtAlgToWebCryptoAlg(jwtAlg){const webAlg=JWT_ALG_TO_WEB_CRYPTO[jwtAlg];if(!webAlg){throw new Error(`Unsupported JWT algorithm for WebCrypto: ${jwtAlg}`)}return webAlg}function toBytes(data){if(typeof data==="string"){return new TextEncoder().encode(data)}return data}function toHex(bytes){return Array.from(bytes).map(b=>b.toString(16).padStart(2,"0")).join("")}function generateUUID(){if(typeof crypto!=="undefined"&&typeof crypto.randomUUID==="function"){return crypto.randomUUID()}const bytes=nobleRandomBytes(16);bytes[6]=bytes[6]&15|64;bytes[8]=bytes[8]&63|128;const hex=toHex(bytes);return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`}function constantTimeEqual(a,b){if(a.length!==b.length)return false;let result=0;for(let i=0;i<a.length;i++){result|=a[i]^b[i]}return result===0}var browserCrypto={randomUUID(){return generateUUID()},randomBytes(length){return nobleRandomBytes(length)},sha256(data){return sha256Hash(toBytes(data))},sha256Hex(data){return toHex(sha256Hash(toBytes(data)))},hmacSha256(key,data){return hmac(sha256Hash,key,data)},hkdfSha256(ikm,salt,info,length){const effectiveSalt=salt.length>0?salt:new Uint8Array(32);return hkdf(sha256Hash,ikm,effectiveSalt,info,length)},encryptAesGcm(key,plaintext,iv){const cipher=gcm(key,iv);const sealed=cipher.encrypt(plaintext);const ciphertext=sealed.slice(0,-16);const tag=sealed.slice(-16);return{ciphertext,tag}},decryptAesGcm(key,ciphertext,iv,tag){const cipher=gcm(key,iv);const sealed=new Uint8Array(ciphertext.length+tag.length);sealed.set(ciphertext);sealed.set(tag,ciphertext.length);return cipher.decrypt(sealed)},timingSafeEqual(a,b){return constantTimeEqual(a,b)}};function nodeOnly(name){throw new Error(`${name} is only available in Node.js runtimes`)}function rsaVerify(){return nodeOnly("rsaVerify")}function rsaSignBase64Url(){return nodeOnly("rsaSignBase64Url")}function rsaVerifySync(){return nodeOnly("rsaVerifySync")}function pemToPublicJwk(){return nodeOnly("pemToPublicJwk")}function generateRsaKeyPair(){return nodeOnly("generateRsaKeyPair")}async function rsaVerifyBrowser(jwtAlg,data,publicJwk,signature){if(typeof globalThis.crypto?.subtle==="undefined"){throw new Error("WebCrypto API (crypto.subtle) is not available in this environment")}const webAlg=jwtAlgToWebCryptoAlg(jwtAlg);const isPss=isRsaPssAlg(jwtAlg);const algorithm={name:isPss?"RSA-PSS":"RSASSA-PKCS1-v1_5",hash:{name:webAlg}};const key=await globalThis.crypto.subtle.importKey("jwk",publicJwk,algorithm,false,["verify"]);const verifyAlgorithm=isPss?{name:"RSA-PSS",saltLength:getSaltLength(jwtAlg)}:{name:"RSASSA-PKCS1-v1_5"};const sigBuf=new Uint8Array(signature).buffer;const dataBuf=new Uint8Array(data).buffer;return globalThis.crypto.subtle.verify(verifyAlgorithm,key,sigBuf,dataBuf)}function getSaltLength(jwtAlg){switch(jwtAlg){case"PS256":return 32;case"PS384":return 48;case"PS512":return 64;default:return 32}}export{browserCrypto,browserCrypto as cryptoProvider,generateRsaKeyPair,isRsaPssAlg,jwtAlgToWebCryptoAlg,pemToPublicJwk,rsaSignBase64Url,rsaVerify,rsaVerifyBrowser,rsaVerifySync};