From ca5cf0e3b0295849635b0aaed792136863c6a98f Mon Sep 17 00:00:00 2001 From: josedario87 Date: Thu, 12 Feb 2026 22:37:47 -0600 Subject: [PATCH] Fork de @jason.today/webmcp v0.1.13 con parches Nucleo: registro dinamico, clipboard y clear-cache --- LICENSE | 21 + README.md | 141 +++ build/index.js | 36 + build/index.js.map | 7 + build/webmcp.js | 2 + build/webmcp.js.map | 7 + package.json | 44 + src/config.js | 118 +++ src/server.js | 848 +++++++++++++++ src/tokens.js | 118 +++ src/webmcp.js | 2196 +++++++++++++++++++++++++++++++++++++++ src/websocket-server.js | 1830 ++++++++++++++++++++++++++++++++ 12 files changed, 5368 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100755 build/index.js create mode 100644 build/index.js.map create mode 100644 build/webmcp.js create mode 100644 build/webmcp.js.map create mode 100644 package.json create mode 100644 src/config.js create mode 100644 src/server.js create mode 100644 src/tokens.js create mode 100644 src/webmcp.js create mode 100644 src/websocket-server.js diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2e4b4c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Jason McGhee + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b21d2c9 --- /dev/null +++ b/README.md @@ -0,0 +1,141 @@ +# WebMCP + +A proposal and code for websites to support client side LLMs + +[![NPM Version](https://img.shields.io/npm/v/%40jason.today%2Fwebmcp)](https://www.npmjs.com/package/@jason.today/webmcp) [![MIT licensed](https://img.shields.io/npm/l/%40jason.today%2Fwebmcp)](./LICENSE) + +WebMCP allows websites to share tools, resources, prompts, etc. to LLMs. In other words, WebMCP allows a website to be an MCP server. No sharing API Keys. Use any model you want. + +[Here's a simple website I built that is WebMCP-enabled](https://webmcp.dev) + +It comes in the form of a widget that a website owner can put on their site and expose tools to give client-side LLMs what they need to provide a great UX for the user or agent. + +_The look, feel, how it's used, and security are all absolutely open for contribution / constructive criticism. MCP Clients directly building WebMCP functionality seems like an ideal outcome._ + +An end-user can connect to any number of websites at a time - and tools are "scoped" (by name) based on the domain to simplify organization. + +### Super Quick Demo (20 seconds, Sound on 🔊) + +https://github.com/user-attachments/assets/61229470-1242-401e-a7d9-c0d762d7b519 + +## Getting started (using your LLM with websites using WebMCP) + +#### Installation + +Just specify your MCP client (`claude`, `cursor`, `cline`, `windsurf`, or a path to json) + +```bash +npx -y @jason.today/webmcp@latest --config claude +``` + +_If you're interested in setting it up manually, use the command `npx -y @jason.today/webmcp@latest --mcp`._ + +_Auto-install was inspired by Smithery, but their code is AGPL so I wrote this myself. If it doesn't work for you or you don't see your mcp client, please file an issue._ + +#### Using WebMCP + +When you're ready to connect to a website, you can ask your model to generate you an mcp token. + +Copy the token and paste it to the website's input. As soon as the website registers with it, it's thrown away and cannot be used for subsequent registrations or anything else. The website will receive its own session token for making requests. + +If you'd rather your model / service never see the token, you can manually execute `npx @jason.today/webmcp --new` instead. + +Some MCP clients, including Claude Desktop, need to be restarted to get access to new tools. (at least at time of writing) + +To disconnect, you can close the browser tab, click "disconnect", or shut down the server with `npx @jason.today/webmcp -q`. + +All configuration files are stored in `~/.webmcp` directory. + +## Getting started (adding WebMCP to your website) + +To use WebMCP, simply include [`webmcp.js`](https://github.com/jasonjmcghee/WebMCP/releases) on your page (via src or directly): + +``` + +``` + +The WebMCP widget will automatically initialize and appear in the bottom right corner of your page. Clicking on it will ask for a webmcp token which the end-user will generate. + +### Full Demo (3 minutes) + +https://github.com/user-attachments/assets/43ad160a-846d-48ad-9af9-f6d537e78473 + +## More Info About How It Works + +The bridge between the MCP client and the website is a localhost-only (not accessible to requests outside your computer) websocket server. Because it is configured to allow requests from your local web browser, authentication / token exchange is required, in case you visit a website attempting to abuse this. + +_Ideally the web browser itself would have an explicit permission for this, like webcam or microphone use._ + +1. The MCP client connects to the `/mcp` path using the server token from `.env` (auto-generated) +2. The server generates a registration token (instigated via the built-in mcp tool by a model or the `--new` command) +3. Web clients connect to the `/register` endpoint with this token and its domain. +4. Web pages connect to their assigned channel based on their domain. +5. When an LLM wants to use a tool / resource / prompt, the request flows from: + - MCP Client → MCP Server → WebSocket Server → Web Page with the tool / resource / prompt + - (similar for requesting a list of tools / resources / prompts) +6. The web page performs the request (e.g. call tool) and sends the result back through the same path +7. Multiple web pages can be connected simultaneously, each with their own set of tools and tokens +8. The MCP client sees all tools as a unified list, with channel prefixes to avoid name collisions + +```mermaid +sequenceDiagram + participant User + participant MCP as MCP Client + participant Server as MCP Server + participant WS as WebSocket Server + participant Web as Website + + %% Initial connection + MCP->>Server: Connect to /mcp with internal server token + + %% Website registration token + User->>MCP: Request registration token + MCP->>Server: Request registration token + Server-->>MCP: Return registration token + MCP-->>User: Display registration token + + %% Website registration + User->>Web: Paste registration token + Web->>WS: Connect to /register with token & domain (registration token deleted) + WS-->>Web: Assign channel & session token + Web->>WS: Connect to assigned channel + + %% Tool interaction + MCP->>Server: Request tools list + Server->>WS: Forward request + WS->>Web: Request tools + Web-->>WS: Return tools list + WS-->>Server: Forward tools list + Server-->>MCP: Return tools list + + %% Tool execution + MCP->>Server: Tool request + Server->>WS: Forward request + WS->>Web: Execute tool + Web-->>WS: Return result + WS-->>Server: Forward result + Server-->>MCP: Return result + + %% Disconnection + User->>Web: Disconnect + Web->>WS: Close connection +``` + +## Security + +This is a super early project. I'm very interested in hardening security to prevent malicious extensions etc. from being +able to perform prompt injection attacks and similar. If you have constructive ideas, please reach out or open an issue. + +## Built in tools + +- Token generator (for connecting to WebMCP websites) +- MCP Tool Definer (to simplify building the schema of a tool for use with MCP) + - You can ask for the javascript (if relevant) in a follow-up message for use with WebMCP + +## Docker + +There is a `Dockerfile` specifically for Smithery deployment. + +If you'd like to use docker to run the websocket server, I've added a `docker-compose.yml` for demonstration purposes. + +If `--docker` is provided to the mcp client config alongside `--mcp`, it will assume the server is running. This will allow you to dockerize the main process (websocket server), and your mcp client will connect to your docker container via websocket. Similarly, websites will communicate with your docker container. diff --git a/build/index.js b/build/index.js new file mode 100755 index 0000000..6cb1e4c --- /dev/null +++ b/build/index.js @@ -0,0 +1,36 @@ +#!/usr/bin/env node +import { createRequire } from "module"; const require = createRequire(import.meta.url); +var Li=Object.create;var Ls=Object.defineProperty;var Mi=Object.getOwnPropertyDescriptor;var Di=Object.getOwnPropertyNames;var qi=Object.getPrototypeOf,Bi=Object.prototype.hasOwnProperty;var q=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Ui=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Di(e))!Bi.call(t,n)&&n!==r&&Ls(t,n,{get:()=>e[n],enumerable:!(s=Mi(e,n))||s.enumerable});return t};var M=(t,e,r)=>(r=t!=null?Li(qi(t)):{},Ui(e||!t||!t.__esModule?Ls(r,"default",{value:t,enumerable:!0}):r,t));var ae=q((Hl,qs)=>{"use strict";var Ms=["nodebuffer","arraybuffer","fragments"],Ds=typeof Blob<"u";Ds&&Ms.push("blob");qs.exports={BINARY_TYPES:Ms,EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",hasBlob:Ds,kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}});var St=q((Gl,Wt)=>{"use strict";var{EMPTY_BUFFER:Vi}=ae(),Pr=Buffer[Symbol.species];function Wi(t,e){if(t.length===0)return Vi;if(t.length===1)return t[0];let r=Buffer.allocUnsafe(e),s=0;for(let n=0;n{"use strict";var Vs=Symbol("kDone"),$r=Symbol("kRun"),Ar=class{constructor(e){this[Vs]=()=>{this.pending--,this[$r]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[$r]()}[$r](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[Vs])}}};Ws.exports=Ar});var kt=q((Yl,Gs)=>{"use strict";var wt=require("zlib"),Zs=St(),Zi=Fs(),{kStatusCode:zs}=ae(),zi=Buffer[Symbol.species],Hi=Buffer.from([0,0,255,255]),zt=Symbol("permessage-deflate"),ce=Symbol("total-length"),Et=Symbol("callback"),_e=Symbol("buffers"),Zt=Symbol("error"),Ft,Lr=class{constructor(e,r,s){if(this._maxPayload=s|0,this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!r,this._deflate=null,this._inflate=null,this.params=null,!Ft){let n=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;Ft=new Zi(n)}}static get extensionName(){return"permessage-deflate"}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let e=this._deflate[Et];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(e){let r=this._options,s=e.find(n=>!(r.serverNoContextTakeover===!1&&n.server_no_context_takeover||n.server_max_window_bits&&(r.serverMaxWindowBits===!1||typeof r.serverMaxWindowBits=="number"&&r.serverMaxWindowBits>n.server_max_window_bits)||typeof r.clientMaxWindowBits=="number"&&!n.client_max_window_bits));if(!s)throw new Error("None of the extension offers can be accepted");return r.serverNoContextTakeover&&(s.server_no_context_takeover=!0),r.clientNoContextTakeover&&(s.client_no_context_takeover=!0),typeof r.serverMaxWindowBits=="number"&&(s.server_max_window_bits=r.serverMaxWindowBits),typeof r.clientMaxWindowBits=="number"?s.client_max_window_bits=r.clientMaxWindowBits:(s.client_max_window_bits===!0||r.clientMaxWindowBits===!1)&&delete s.client_max_window_bits,s}acceptAsClient(e){let r=e[0];if(this._options.clientNoContextTakeover===!1&&r.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!r.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(r.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&r.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return r}normalizeParams(e){return e.forEach(r=>{Object.keys(r).forEach(s=>{let n=r[s];if(n.length>1)throw new Error(`Parameter "${s}" must have only a single value`);if(n=n[0],s==="client_max_window_bits"){if(n!==!0){let i=+n;if(!Number.isInteger(i)||i<8||i>15)throw new TypeError(`Invalid value for parameter "${s}": ${n}`);n=i}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${s}": ${n}`)}else if(s==="server_max_window_bits"){let i=+n;if(!Number.isInteger(i)||i<8||i>15)throw new TypeError(`Invalid value for parameter "${s}": ${n}`);n=i}else if(s==="client_no_context_takeover"||s==="server_no_context_takeover"){if(n!==!0)throw new TypeError(`Invalid value for parameter "${s}": ${n}`)}else throw new Error(`Unknown parameter "${s}"`);r[s]=n})}),e}decompress(e,r,s){Ft.add(n=>{this._decompress(e,r,(i,o)=>{n(),s(i,o)})})}compress(e,r,s){Ft.add(n=>{this._compress(e,r,(i,o)=>{n(),s(i,o)})})}_decompress(e,r,s){let n=this._isServer?"client":"server";if(!this._inflate){let i=`${n}_max_window_bits`,o=typeof this.params[i]!="number"?wt.Z_DEFAULT_WINDOWBITS:this.params[i];this._inflate=wt.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[zt]=this,this._inflate[ce]=0,this._inflate[_e]=[],this._inflate.on("error",Ji),this._inflate.on("data",Hs)}this._inflate[Et]=s,this._inflate.write(e),r&&this._inflate.write(Hi),this._inflate.flush(()=>{let i=this._inflate[Zt];if(i){this._inflate.close(),this._inflate=null,s(i);return}let o=Zs.concat(this._inflate[_e],this._inflate[ce]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[ce]=0,this._inflate[_e]=[],r&&this.params[`${n}_no_context_takeover`]&&this._inflate.reset()),s(null,o)})}_compress(e,r,s){let n=this._isServer?"server":"client";if(!this._deflate){let i=`${n}_max_window_bits`,o=typeof this.params[i]!="number"?wt.Z_DEFAULT_WINDOWBITS:this.params[i];this._deflate=wt.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[ce]=0,this._deflate[_e]=[],this._deflate.on("data",Gi)}this._deflate[Et]=s,this._deflate.write(e),this._deflate.flush(wt.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let i=Zs.concat(this._deflate[_e],this._deflate[ce]);r&&(i=new zi(i.buffer,i.byteOffset,i.length-4)),this._deflate[Et]=null,this._deflate[ce]=0,this._deflate[_e]=[],r&&this.params[`${n}_no_context_takeover`]&&this._deflate.reset(),s(null,i)})}};Gs.exports=Lr;function Gi(t){this[_e].push(t),this[ce]+=t.length}function Hs(t){if(this[ce]+=t.length,this[zt]._maxPayload<1||this[ce]<=this[zt]._maxPayload){this[_e].push(t);return}this[Zt]=new RangeError("Max payload size exceeded"),this[Zt].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[Zt][zs]=1009,this.removeListener("data",Hs),this.reset()}function Ji(t){this[zt]._inflate=null,t[zs]=1007,this[Et](t)}});var rt=q((Kl,Ht)=>{"use strict";var{isUtf8:Js}=require("buffer"),{hasBlob:Yi}=ae(),Ki=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function Xi(t){return t>=1e3&&t<=1014&&t!==1004&&t!==1005&&t!==1006||t>=3e3&&t<=4999}function Mr(t){let e=t.length,r=0;for(;r=e||(t[r+1]&192)!==128||(t[r+2]&192)!==128||t[r]===224&&(t[r+1]&224)===128||t[r]===237&&(t[r+1]&224)===160)return!1;r+=3}else if((t[r]&248)===240){if(r+3>=e||(t[r+1]&192)!==128||(t[r+2]&192)!==128||(t[r+3]&192)!==128||t[r]===240&&(t[r+1]&240)===128||t[r]===244&&t[r+1]>143||t[r]>244)return!1;r+=4}else return!1;return!0}function Qi(t){return Yi&&typeof t=="object"&&typeof t.arrayBuffer=="function"&&typeof t.type=="string"&&typeof t.stream=="function"&&(t[Symbol.toStringTag]==="Blob"||t[Symbol.toStringTag]==="File")}Ht.exports={isBlob:Qi,isValidStatusCode:Xi,isValidUTF8:Mr,tokenChars:Ki};if(Js)Ht.exports.isValidUTF8=function(t){return t.length<24?Mr(t):Js(t)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let t=require("utf-8-validate");Ht.exports.isValidUTF8=function(e){return e.length<32?Mr(e):t(e)}}catch{}});var Vr=q((Xl,rn)=>{"use strict";var{Writable:eo}=require("stream"),Ys=kt(),{BINARY_TYPES:to,EMPTY_BUFFER:Ks,kStatusCode:ro,kWebSocket:so}=ae(),{concat:Dr,toArrayBuffer:no,unmask:io}=St(),{isValidStatusCode:oo,isValidUTF8:Xs}=rt(),Gt=Buffer[Symbol.species],H=0,Qs=1,en=2,tn=3,qr=4,Br=5,Jt=6,Ur=class extends eo{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents!==void 0?e.allowSynchronousEvents:!0,this._binaryType=e.binaryType||to[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[so]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=H}_write(e,r,s){if(this._opcode===8&&this._state==H)return s();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(s)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e=s.length?r.set(this._buffers.shift(),n):(r.set(new Uint8Array(s.buffer,s.byteOffset,e),n),this._buffers[0]=new Gt(s.buffer,s.byteOffset+e,s.length-e)),e-=s.length}while(e>0);return r}startLoop(e){this._loop=!0;do switch(this._state){case H:this.getInfo(e);break;case Qs:this.getPayloadLength16(e);break;case en:this.getPayloadLength64(e);break;case tn:this.getMask();break;case qr:this.getData(e);break;case Br:case Jt:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let r=this.consume(2);if((r[0]&48)!==0){let n=this.createError(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");e(n);return}let s=(r[0]&64)===64;if(s&&!this._extensions[Ys.extensionName]){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._fin=(r[0]&128)===128,this._opcode=r[0]&15,this._payloadLength=r[1]&127,this._opcode===0){if(s){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(!this._fragmented){let n=this.createError(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._compressed=s}else if(this._opcode>7&&this._opcode<11){if(!this._fin){let n=this.createError(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");e(n);return}if(s){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){let n=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");e(n);return}}else{let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(r[1]&128)===128,this._isServer){if(!this._masked){let n=this.createError(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK");e(n);return}}else if(this._masked){let n=this.createError(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");e(n);return}this._payloadLength===126?this._state=Qs:this._payloadLength===127?this._state=en:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let r=this.consume(8),s=r.readUInt32BE(0);if(s>Math.pow(2,21)-1){let n=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");e(n);return}this._payloadLength=s*Math.pow(2,32)+r.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){let r=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");e(r);return}this._masked?this._state=tn:this._state=qr}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=qr}getData(e){let r=Ks;if(this._payloadLength){if(this._bufferedBytes7){this.controlMessage(r,e);return}if(this._compressed){this._state=Br,this.decompress(r,e);return}r.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(r)),this.dataMessage(e)}decompress(e,r){this._extensions[Ys.extensionName].decompress(e,this._fin,(n,i)=>{if(n)return r(n);if(i.length){if(this._messageLength+=i.length,this._messageLength>this._maxPayload&&this._maxPayload>0){let o=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");r(o);return}this._fragments.push(i)}this.dataMessage(r),this._state===H&&this.startLoop(r)})}dataMessage(e){if(!this._fin){this._state=H;return}let r=this._messageLength,s=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let n;this._binaryType==="nodebuffer"?n=Dr(s,r):this._binaryType==="arraybuffer"?n=no(Dr(s,r)):this._binaryType==="blob"?n=new Blob(s):n=s,this._allowSynchronousEvents?(this.emit("message",n,!0),this._state=H):(this._state=Jt,setImmediate(()=>{this.emit("message",n,!0),this._state=H,this.startLoop(e)}))}else{let n=Dr(s,r);if(!this._skipUTF8Validation&&!Xs(n)){let i=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");e(i);return}this._state===Br||this._allowSynchronousEvents?(this.emit("message",n,!1),this._state=H):(this._state=Jt,setImmediate(()=>{this.emit("message",n,!1),this._state=H,this.startLoop(e)}))}}controlMessage(e,r){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit("conclude",1005,Ks),this.end();else{let s=e.readUInt16BE(0);if(!oo(s)){let i=this.createError(RangeError,`invalid status code ${s}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");r(i);return}let n=new Gt(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!Xs(n)){let i=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");r(i);return}this._loop=!1,this.emit("conclude",s,n),this.end()}this._state=H;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?"ping":"pong",e),this._state=H):(this._state=Jt,setImmediate(()=>{this.emit(this._opcode===9?"ping":"pong",e),this._state=H,this.startLoop(r)}))}createError(e,r,s,n,i){this._loop=!1,this._errored=!0;let o=new e(s?`Invalid WebSocket frame: ${r}`:r);return Error.captureStackTrace(o,this.createError),o.code=i,o[ro]=n,o}};rn.exports=Ur});var Zr=q((ed,on)=>{"use strict";var{Duplex:Ql}=require("stream"),{randomFillSync:ao}=require("crypto"),sn=kt(),{EMPTY_BUFFER:co,kWebSocket:lo,NOOP:uo}=ae(),{isBlob:st,isValidStatusCode:fo}=rt(),{mask:nn,toBuffer:Oe}=St(),G=Symbol("kByteLength"),ho=Buffer.alloc(4),Yt=8*1024,Ce,nt=Yt,X=0,po=1,mo=2,Wr=class t{constructor(e,r,s){this._extensions=r||{},s&&(this._generateMask=s,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=X,this.onerror=uo,this[lo]=void 0}static frame(e,r){let s,n=!1,i=2,o=!1;r.mask&&(s=r.maskBuffer||ho,r.generateMask?r.generateMask(s):(nt===Yt&&(Ce===void 0&&(Ce=Buffer.alloc(Yt)),ao(Ce,0,Yt),nt=0),s[0]=Ce[nt++],s[1]=Ce[nt++],s[2]=Ce[nt++],s[3]=Ce[nt++]),o=(s[0]|s[1]|s[2]|s[3])===0,i=6);let a;typeof e=="string"?(!r.mask||o)&&r[G]!==void 0?a=r[G]:(e=Buffer.from(e),a=e.length):(a=e.length,n=r.mask&&r.readOnly&&!o);let l=a;a>=65536?(i+=8,l=127):a>125&&(i+=2,l=126);let d=Buffer.allocUnsafe(n?a+i:i);return d[0]=r.fin?r.opcode|128:r.opcode,r.rsv1&&(d[0]|=64),d[1]=l,l===126?d.writeUInt16BE(a,2):l===127&&(d[2]=d[3]=0,d.writeUIntBE(a,4,6)),r.mask?(d[1]|=128,d[i-4]=s[0],d[i-3]=s[1],d[i-2]=s[2],d[i-1]=s[3],o?[d,e]:n?(nn(e,s,d,i,a),[d]):(nn(e,s,e,0,a),[d,e])):[d,e]}close(e,r,s,n){let i;if(e===void 0)i=co;else{if(typeof e!="number"||!fo(e))throw new TypeError("First argument must be a valid error code number");if(r===void 0||!r.length)i=Buffer.allocUnsafe(2),i.writeUInt16BE(e,0);else{let a=Buffer.byteLength(r);if(a>123)throw new RangeError("The message must not be greater than 123 bytes");i=Buffer.allocUnsafe(2+a),i.writeUInt16BE(e,0),typeof r=="string"?i.write(r,2):i.set(r,2)}}let o={[G]:i.length,fin:!0,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state!==X?this.enqueue([this.dispatch,i,!1,o,n]):this.sendFrame(t.frame(i,o),n)}ping(e,r,s){let n,i;if(typeof e=="string"?(n=Buffer.byteLength(e),i=!1):st(e)?(n=e.size,i=!1):(e=Oe(e),n=e.length,i=Oe.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[G]:n,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:9,readOnly:i,rsv1:!1};st(e)?this._state!==X?this.enqueue([this.getBlobData,e,!1,o,s]):this.getBlobData(e,!1,o,s):this._state!==X?this.enqueue([this.dispatch,e,!1,o,s]):this.sendFrame(t.frame(e,o),s)}pong(e,r,s){let n,i;if(typeof e=="string"?(n=Buffer.byteLength(e),i=!1):st(e)?(n=e.size,i=!1):(e=Oe(e),n=e.length,i=Oe.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[G]:n,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:10,readOnly:i,rsv1:!1};st(e)?this._state!==X?this.enqueue([this.getBlobData,e,!1,o,s]):this.getBlobData(e,!1,o,s):this._state!==X?this.enqueue([this.dispatch,e,!1,o,s]):this.sendFrame(t.frame(e,o),s)}send(e,r,s){let n=this._extensions[sn.extensionName],i=r.binary?2:1,o=r.compress,a,l;typeof e=="string"?(a=Buffer.byteLength(e),l=!1):st(e)?(a=e.size,l=!1):(e=Oe(e),a=e.length,l=Oe.readOnly),this._firstFragment?(this._firstFragment=!1,o&&n&&n.params[n._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(o=a>=n._threshold),this._compress=o):(o=!1,i=0),r.fin&&(this._firstFragment=!0);let d={[G]:a,fin:r.fin,generateMask:this._generateMask,mask:r.mask,maskBuffer:this._maskBuffer,opcode:i,readOnly:l,rsv1:o};st(e)?this._state!==X?this.enqueue([this.getBlobData,e,this._compress,d,s]):this.getBlobData(e,this._compress,d,s):this._state!==X?this.enqueue([this.dispatch,e,this._compress,d,s]):this.dispatch(e,this._compress,d,s)}getBlobData(e,r,s,n){this._bufferedBytes+=s[G],this._state=mo,e.arrayBuffer().then(i=>{if(this._socket.destroyed){let a=new Error("The socket was closed while the blob was being read");process.nextTick(Fr,this,a,n);return}this._bufferedBytes-=s[G];let o=Oe(i);r?this.dispatch(o,r,s,n):(this._state=X,this.sendFrame(t.frame(o,s),n),this.dequeue())}).catch(i=>{process.nextTick(go,this,i,n)})}dispatch(e,r,s,n){if(!r){this.sendFrame(t.frame(e,s),n);return}let i=this._extensions[sn.extensionName];this._bufferedBytes+=s[G],this._state=po,i.compress(e,s.fin,(o,a)=>{if(this._socket.destroyed){let l=new Error("The socket was closed while data was being compressed");Fr(this,l,n);return}this._bufferedBytes-=s[G],this._state=X,s.readOnly=!1,this.sendFrame(t.frame(a,s),n),this.dequeue()})}dequeue(){for(;this._state===X&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][G],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][G],this._queue.push(e)}sendFrame(e,r){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],r),this._socket.uncork()):this._socket.write(e[0],r)}};on.exports=Wr;function Fr(t,e,r){typeof r=="function"&&r(e);for(let s=0;s{"use strict";var{kForOnEventAttribute:Tt,kListener:zr}=ae(),an=Symbol("kCode"),cn=Symbol("kData"),ln=Symbol("kError"),dn=Symbol("kMessage"),un=Symbol("kReason"),it=Symbol("kTarget"),fn=Symbol("kType"),hn=Symbol("kWasClean"),le=class{constructor(e){this[it]=null,this[fn]=e}get target(){return this[it]}get type(){return this[fn]}};Object.defineProperty(le.prototype,"target",{enumerable:!0});Object.defineProperty(le.prototype,"type",{enumerable:!0});var Ie=class extends le{constructor(e,r={}){super(e),this[an]=r.code===void 0?0:r.code,this[un]=r.reason===void 0?"":r.reason,this[hn]=r.wasClean===void 0?!1:r.wasClean}get code(){return this[an]}get reason(){return this[un]}get wasClean(){return this[hn]}};Object.defineProperty(Ie.prototype,"code",{enumerable:!0});Object.defineProperty(Ie.prototype,"reason",{enumerable:!0});Object.defineProperty(Ie.prototype,"wasClean",{enumerable:!0});var ot=class extends le{constructor(e,r={}){super(e),this[ln]=r.error===void 0?null:r.error,this[dn]=r.message===void 0?"":r.message}get error(){return this[ln]}get message(){return this[dn]}};Object.defineProperty(ot.prototype,"error",{enumerable:!0});Object.defineProperty(ot.prototype,"message",{enumerable:!0});var Rt=class extends le{constructor(e,r={}){super(e),this[cn]=r.data===void 0?null:r.data}get data(){return this[cn]}};Object.defineProperty(Rt.prototype,"data",{enumerable:!0});var _o={addEventListener(t,e,r={}){for(let n of this.listeners(t))if(!r[Tt]&&n[zr]===e&&!n[Tt])return;let s;if(t==="message")s=function(i,o){let a=new Rt("message",{data:o?i:i.toString()});a[it]=this,Kt(e,this,a)};else if(t==="close")s=function(i,o){let a=new Ie("close",{code:i,reason:o.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});a[it]=this,Kt(e,this,a)};else if(t==="error")s=function(i){let o=new ot("error",{error:i,message:i.message});o[it]=this,Kt(e,this,o)};else if(t==="open")s=function(){let i=new le("open");i[it]=this,Kt(e,this,i)};else return;s[Tt]=!!r[Tt],s[zr]=e,r.once?this.once(t,s):this.on(t,s)},removeEventListener(t,e){for(let r of this.listeners(t))if(r[zr]===e&&!r[Tt]){this.removeListener(t,r);break}}};pn.exports={CloseEvent:Ie,ErrorEvent:ot,Event:le,EventTarget:_o,MessageEvent:Rt};function Kt(t,e,r){typeof t=="object"&&t.handleEvent?t.handleEvent.call(t,r):t.call(e,r)}});var Hr=q((rd,gn)=>{"use strict";var{tokenChars:Nt}=rt();function se(t,e,r){t[e]===void 0?t[e]=[r]:t[e].push(r)}function yo(t){let e=Object.create(null),r=Object.create(null),s=!1,n=!1,i=!1,o,a,l=-1,d=-1,u=-1,f=0;for(;f{let r=t[e];return Array.isArray(r)||(r=[r]),r.map(s=>[e].concat(Object.keys(s).map(n=>{let i=s[n];return Array.isArray(i)||(i=[i]),i.map(o=>o===!0?n:`${n}=${o}`).join("; ")})).join("; ")).join(", ")}).join(", ")}gn.exports={format:vo,parse:yo}});var tr=q((id,Nn)=>{"use strict";var xo=require("events"),bo=require("https"),So=require("http"),vn=require("net"),wo=require("tls"),{randomBytes:Eo,createHash:ko}=require("crypto"),{Duplex:sd,Readable:nd}=require("stream"),{URL:Gr}=require("url"),ye=kt(),To=Vr(),Ro=Zr(),{isBlob:No}=rt(),{BINARY_TYPES:_n,EMPTY_BUFFER:Xt,GUID:Oo,kForOnEventAttribute:Jr,kListener:Co,kStatusCode:Io,kWebSocket:$,NOOP:xn}=ae(),{EventTarget:{addEventListener:Po,removeEventListener:jo}}=mn(),{format:$o,parse:Ao}=Hr(),{toBuffer:Lo}=St(),Mo=30*1e3,bn=Symbol("kAborted"),Yr=[8,13],de=["CONNECTING","OPEN","CLOSING","CLOSED"],Do=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,I=class t extends xo{constructor(e,r,s){super(),this._binaryType=_n[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=Xt,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol="",this._readyState=t.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,r===void 0?r=[]:Array.isArray(r)||(typeof r=="object"&&r!==null?(s=r,r=[]):r=[r]),Sn(this,e,r,s)):(this._autoPong=s.autoPong,this._isServer=!0)}get binaryType(){return this._binaryType}set binaryType(e){_n.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,r,s){let n=new To({allowSynchronousEvents:s.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:s.maxPayload,skipUTF8Validation:s.skipUTF8Validation}),i=new Ro(e,this._extensions,s.generateMask);this._receiver=n,this._sender=i,this._socket=e,n[$]=this,i[$]=this,e[$]=this,n.on("conclude",Uo),n.on("drain",Vo),n.on("error",Wo),n.on("message",Fo),n.on("ping",Zo),n.on("pong",zo),i.onerror=Ho,e.setTimeout&&e.setTimeout(0),e.setNoDelay&&e.setNoDelay(),r.length>0&&e.unshift(r),e.on("close",kn),e.on("data",er),e.on("end",Tn),e.on("error",Rn),this._readyState=t.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=t.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[ye.extensionName]&&this._extensions[ye.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=t.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(e,r){if(this.readyState!==t.CLOSED){if(this.readyState===t.CONNECTING){V(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===t.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=t.CLOSING,this._sender.close(e,r,!this._isServer,s=>{s||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),En(this)}}pause(){this.readyState===t.CONNECTING||this.readyState===t.CLOSED||(this._paused=!0,this._socket.pause())}ping(e,r,s){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(s=e,e=r=void 0):typeof r=="function"&&(s=r,r=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Kr(this,e,s);return}r===void 0&&(r=!this._isServer),this._sender.ping(e||Xt,r,s)}pong(e,r,s){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(s=e,e=r=void 0):typeof r=="function"&&(s=r,r=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Kr(this,e,s);return}r===void 0&&(r=!this._isServer),this._sender.pong(e||Xt,r,s)}resume(){this.readyState===t.CONNECTING||this.readyState===t.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(e,r,s){if(this.readyState===t.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof r=="function"&&(s=r,r={}),typeof e=="number"&&(e=e.toString()),this.readyState!==t.OPEN){Kr(this,e,s);return}let n={binary:typeof e!="string",mask:!this._isServer,compress:!0,fin:!0,...r};this._extensions[ye.extensionName]||(n.compress=!1),this._sender.send(e||Xt,n,s)}terminate(){if(this.readyState!==t.CLOSED){if(this.readyState===t.CONNECTING){V(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=t.CLOSING,this._socket.destroy())}}};Object.defineProperty(I,"CONNECTING",{enumerable:!0,value:de.indexOf("CONNECTING")});Object.defineProperty(I.prototype,"CONNECTING",{enumerable:!0,value:de.indexOf("CONNECTING")});Object.defineProperty(I,"OPEN",{enumerable:!0,value:de.indexOf("OPEN")});Object.defineProperty(I.prototype,"OPEN",{enumerable:!0,value:de.indexOf("OPEN")});Object.defineProperty(I,"CLOSING",{enumerable:!0,value:de.indexOf("CLOSING")});Object.defineProperty(I.prototype,"CLOSING",{enumerable:!0,value:de.indexOf("CLOSING")});Object.defineProperty(I,"CLOSED",{enumerable:!0,value:de.indexOf("CLOSED")});Object.defineProperty(I.prototype,"CLOSED",{enumerable:!0,value:de.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(t=>{Object.defineProperty(I.prototype,t,{enumerable:!0})});["open","error","close","message"].forEach(t=>{Object.defineProperty(I.prototype,`on${t}`,{enumerable:!0,get(){for(let e of this.listeners(t))if(e[Jr])return e[Co];return null},set(e){for(let r of this.listeners(t))if(r[Jr]){this.removeListener(t,r);break}typeof e=="function"&&this.addEventListener(t,e,{[Jr]:!0})}})});I.prototype.addEventListener=Po;I.prototype.removeEventListener=jo;Nn.exports=I;function Sn(t,e,r,s){let n={allowSynchronousEvents:!0,autoPong:!0,protocolVersion:Yr[1],maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...s,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(t._autoPong=n.autoPong,!Yr.includes(n.protocolVersion))throw new RangeError(`Unsupported protocol version: ${n.protocolVersion} (supported versions: ${Yr.join(", ")})`);let i;if(e instanceof Gr)i=e;else try{i=new Gr(e)}catch{throw new SyntaxError(`Invalid URL: ${e}`)}i.protocol==="http:"?i.protocol="ws:":i.protocol==="https:"&&(i.protocol="wss:"),t._url=i.href;let o=i.protocol==="wss:",a=i.protocol==="ws+unix:",l;if(i.protocol!=="ws:"&&!o&&!a?l=`The URL's protocol must be one of "ws:", "wss:", "http:", "https", or "ws+unix:"`:a&&!i.pathname?l="The URL's pathname is empty":i.hash&&(l="The URL contains a fragment identifier"),l){let _=new SyntaxError(l);if(t._redirects===0)throw _;Qt(t,_);return}let d=o?443:80,u=Eo(16).toString("base64"),f=o?bo.request:So.request,x=new Set,E;if(n.createConnection=n.createConnection||(o?Bo:qo),n.defaultPort=n.defaultPort||d,n.port=i.port||d,n.host=i.hostname.startsWith("[")?i.hostname.slice(1,-1):i.hostname,n.headers={...n.headers,"Sec-WebSocket-Version":n.protocolVersion,"Sec-WebSocket-Key":u,Connection:"Upgrade",Upgrade:"websocket"},n.path=i.pathname+i.search,n.timeout=n.handshakeTimeout,n.perMessageDeflate&&(E=new ye(n.perMessageDeflate!==!0?n.perMessageDeflate:{},!1,n.maxPayload),n.headers["Sec-WebSocket-Extensions"]=$o({[ye.extensionName]:E.offer()})),r.length){for(let _ of r){if(typeof _!="string"||!Do.test(_)||x.has(_))throw new SyntaxError("An invalid or duplicated subprotocol was specified");x.add(_)}n.headers["Sec-WebSocket-Protocol"]=r.join(",")}if(n.origin&&(n.protocolVersion<13?n.headers["Sec-WebSocket-Origin"]=n.origin:n.headers.Origin=n.origin),(i.username||i.password)&&(n.auth=`${i.username}:${i.password}`),a){let _=n.path.split(":");n.socketPath=_[0],n.path=_[1]}let T;if(n.followRedirects){if(t._redirects===0){t._originalIpc=a,t._originalSecure=o,t._originalHostOrSocketPath=a?n.socketPath:i.host;let _=s&&s.headers;if(s={...s,headers:{}},_)for(let[R,A]of Object.entries(_))s.headers[R.toLowerCase()]=A}else if(t.listenerCount("redirect")===0){let _=a?t._originalIpc?n.socketPath===t._originalHostOrSocketPath:!1:t._originalIpc?!1:i.host===t._originalHostOrSocketPath;(!_||t._originalSecure&&!o)&&(delete n.headers.authorization,delete n.headers.cookie,_||delete n.headers.host,n.auth=void 0)}n.auth&&!s.headers.authorization&&(s.headers.authorization="Basic "+Buffer.from(n.auth).toString("base64")),T=t._req=f(n),t._redirects&&t.emit("redirect",t.url,T)}else T=t._req=f(n);n.timeout&&T.on("timeout",()=>{V(t,T,"Opening handshake has timed out")}),T.on("error",_=>{T===null||T[bn]||(T=t._req=null,Qt(t,_))}),T.on("response",_=>{let R=_.headers.location,A=_.statusCode;if(R&&n.followRedirects&&A>=300&&A<400){if(++t._redirects>n.maxRedirects){V(t,T,"Maximum redirects exceeded");return}T.abort();let Ne;try{Ne=new Gr(R,e)}catch{let tt=new SyntaxError(`Invalid URL: ${R}`);Qt(t,tt);return}Sn(t,Ne,r,s)}else t.emit("unexpected-response",T,_)||V(t,T,`Unexpected server response: ${_.statusCode}`)}),T.on("upgrade",(_,R,A)=>{if(t.emit("upgrade",_),t.readyState!==I.CONNECTING)return;T=t._req=null;let Ne=_.headers.upgrade;if(Ne===void 0||Ne.toLowerCase()!=="websocket"){V(t,R,"Invalid Upgrade header");return}let js=ko("sha1").update(u+Oo).digest("base64");if(_.headers["sec-websocket-accept"]!==js){V(t,R,"Invalid Sec-WebSocket-Accept header");return}let tt=_.headers["sec-websocket-protocol"],bt;if(tt!==void 0?x.size?x.has(tt)||(bt="Server sent an invalid subprotocol"):bt="Server sent a subprotocol but none was requested":x.size&&(bt="Server sent no subprotocol"),bt){V(t,R,bt);return}tt&&(t._protocol=tt);let $s=_.headers["sec-websocket-extensions"];if($s!==void 0){if(!E){V(t,R,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let Cr;try{Cr=Ao($s)}catch{V(t,R,"Invalid Sec-WebSocket-Extensions header");return}let As=Object.keys(Cr);if(As.length!==1||As[0]!==ye.extensionName){V(t,R,"Server indicated an extension that was not requested");return}try{E.accept(Cr[ye.extensionName])}catch{V(t,R,"Invalid Sec-WebSocket-Extensions header");return}t._extensions[ye.extensionName]=E}t.setSocket(R,A,{allowSynchronousEvents:n.allowSynchronousEvents,generateMask:n.generateMask,maxPayload:n.maxPayload,skipUTF8Validation:n.skipUTF8Validation})}),n.finishRequest?n.finishRequest(T,t):T.end()}function Qt(t,e){t._readyState=I.CLOSING,t._errorEmitted=!0,t.emit("error",e),t.emitClose()}function qo(t){return t.path=t.socketPath,vn.connect(t)}function Bo(t){return t.path=void 0,!t.servername&&t.servername!==""&&(t.servername=vn.isIP(t.host)?"":t.host),wo.connect(t)}function V(t,e,r){t._readyState=I.CLOSING;let s=new Error(r);Error.captureStackTrace(s,V),e.setHeader?(e[bn]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(Qt,t,s)):(e.destroy(s),e.once("error",t.emit.bind(t,"error")),e.once("close",t.emitClose.bind(t)))}function Kr(t,e,r){if(e){let s=No(e)?e.size:Lo(e).length;t._socket?t._sender._bufferedBytes+=s:t._bufferedAmount+=s}if(r){let s=new Error(`WebSocket is not open: readyState ${t.readyState} (${de[t.readyState]})`);process.nextTick(r,s)}}function Uo(t,e){let r=this[$];r._closeFrameReceived=!0,r._closeMessage=e,r._closeCode=t,r._socket[$]!==void 0&&(r._socket.removeListener("data",er),process.nextTick(wn,r._socket),t===1005?r.close():r.close(t,e))}function Vo(){let t=this[$];t.isPaused||t._socket.resume()}function Wo(t){let e=this[$];e._socket[$]!==void 0&&(e._socket.removeListener("data",er),process.nextTick(wn,e._socket),e.close(t[Io])),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t))}function yn(){this[$].emitClose()}function Fo(t,e){this[$].emit("message",t,e)}function Zo(t){let e=this[$];e._autoPong&&e.pong(t,!this._isServer,xn),e.emit("ping",t)}function zo(t){this[$].emit("pong",t)}function wn(t){t.resume()}function Ho(t){let e=this[$];e.readyState!==I.CLOSED&&(e.readyState===I.OPEN&&(e._readyState=I.CLOSING,En(e)),this._socket.end(),e._errorEmitted||(e._errorEmitted=!0,e.emit("error",t)))}function En(t){t._closeTimer=setTimeout(t._socket.destroy.bind(t._socket),Mo)}function kn(){let t=this[$];this.removeListener("close",kn),this.removeListener("data",er),this.removeListener("end",Tn),t._readyState=I.CLOSING;let e;!this._readableState.endEmitted&&!t._closeFrameReceived&&!t._receiver._writableState.errorEmitted&&(e=t._socket.read())!==null&&t._receiver.write(e),t._receiver.end(),this[$]=void 0,clearTimeout(t._closeTimer),t._receiver._writableState.finished||t._receiver._writableState.errorEmitted?t.emitClose():(t._receiver.on("error",yn),t._receiver.on("finish",yn))}function er(t){this[$]._receiver.write(t)||this.pause()}function Tn(){let t=this[$];t._readyState=I.CLOSING,t._receiver.end(),this.end()}function Rn(){let t=this[$];this.removeListener("error",Rn),this.on("error",xn),t&&(t._readyState=I.CLOSING,this.destroy())}});var Pn=q((ad,In)=>{"use strict";var od=tr(),{Duplex:Go}=require("stream");function On(t){t.emit("close")}function Jo(){!this.destroyed&&this._writableState.finished&&this.destroy()}function Cn(t){this.removeListener("error",Cn),this.destroy(),this.listenerCount("error")===0&&this.emit("error",t)}function Yo(t,e){let r=!0,s=new Go({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return t.on("message",function(i,o){let a=!o&&s._readableState.objectMode?i.toString():i;s.push(a)||t.pause()}),t.once("error",function(i){s.destroyed||(r=!1,s.destroy(i))}),t.once("close",function(){s.destroyed||s.push(null)}),s._destroy=function(n,i){if(t.readyState===t.CLOSED){i(n),process.nextTick(On,s);return}let o=!1;t.once("error",function(l){o=!0,i(l)}),t.once("close",function(){o||i(n),process.nextTick(On,s)}),r&&t.terminate()},s._final=function(n){if(t.readyState===t.CONNECTING){t.once("open",function(){s._final(n)});return}t._socket!==null&&(t._socket._writableState.finished?(n(),s._readableState.endEmitted&&s.destroy()):(t._socket.once("finish",function(){n()}),t.close()))},s._read=function(){t.isPaused&&t.resume()},s._write=function(n,i,o){if(t.readyState===t.CONNECTING){t.once("open",function(){s._write(n,i,o)});return}t.send(n,o)},s.on("end",Jo),s.on("error",Cn),s}In.exports=Yo});var $n=q((cd,jn)=>{"use strict";var{tokenChars:Ko}=rt();function Xo(t){let e=new Set,r=-1,s=-1,n=0;for(n;n{"use strict";var Qo=require("events"),rr=require("http"),{Duplex:ld}=require("stream"),{createHash:ea}=require("crypto"),An=Hr(),Pe=kt(),ta=$n(),ra=tr(),{GUID:sa,kWebSocket:na}=ae(),ia=/^[+/0-9A-Za-z]{22}==$/,Ln=0,Mn=1,qn=2,Xr=class extends Qo{constructor(e,r){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:ra,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified');if(e.port!=null?(this._server=rr.createServer((s,n)=>{let i=rr.STATUS_CODES[426];n.writeHead(426,{"Content-Length":i.length,"Content-Type":"text/plain"}),n.end(i)}),this._server.listen(e.port,e.host,e.backlog,r)):e.server&&(this._server=e.server),this._server){let s=this.emit.bind(this,"connection");this._removeListeners=oa(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(n,i,o)=>{this.handleUpgrade(n,i,o,s)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=Ln}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(this._state===qn){e&&this.once("close",()=>{e(new Error("The server is not running"))}),process.nextTick(Ot,this);return}if(e&&this.once("close",e),this._state!==Mn)if(this._state=Mn,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(Ot,this):process.nextTick(Ot,this);else{let r=this._server;this._removeListeners(),this._removeListeners=this._server=null,r.close(()=>{Ot(this)})}}shouldHandle(e){if(this.options.path){let r=e.url.indexOf("?");if((r!==-1?e.url.slice(0,r):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,r,s,n){r.on("error",Dn);let i=e.headers["sec-websocket-key"],o=e.headers.upgrade,a=+e.headers["sec-websocket-version"];if(e.method!=="GET"){je(this,e,r,405,"Invalid HTTP method");return}if(o===void 0||o.toLowerCase()!=="websocket"){je(this,e,r,400,"Invalid Upgrade header");return}if(i===void 0||!ia.test(i)){je(this,e,r,400,"Missing or invalid Sec-WebSocket-Key header");return}if(a!==8&&a!==13){je(this,e,r,400,"Missing or invalid Sec-WebSocket-Version header");return}if(!this.shouldHandle(e)){Ct(r,400);return}let l=e.headers["sec-websocket-protocol"],d=new Set;if(l!==void 0)try{d=ta.parse(l)}catch{je(this,e,r,400,"Invalid Sec-WebSocket-Protocol header");return}let u=e.headers["sec-websocket-extensions"],f={};if(this.options.perMessageDeflate&&u!==void 0){let x=new Pe(this.options.perMessageDeflate,!0,this.options.maxPayload);try{let E=An.parse(u);E[Pe.extensionName]&&(x.accept(E[Pe.extensionName]),f[Pe.extensionName]=x)}catch{je(this,e,r,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){let x={origin:e.headers[`${a===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(x,(E,T,_,R)=>{if(!E)return Ct(r,T||401,_,R);this.completeUpgrade(f,i,d,e,r,s,n)});return}if(!this.options.verifyClient(x))return Ct(r,401)}this.completeUpgrade(f,i,d,e,r,s,n)}completeUpgrade(e,r,s,n,i,o,a){if(!i.readable||!i.writable)return i.destroy();if(i[na])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>Ln)return Ct(i,503);let d=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${ea("sha1").update(r+sa).digest("base64")}`],u=new this.options.WebSocket(null,void 0,this.options);if(s.size){let f=this.options.handleProtocols?this.options.handleProtocols(s,n):s.values().next().value;f&&(d.push(`Sec-WebSocket-Protocol: ${f}`),u._protocol=f)}if(e[Pe.extensionName]){let f=e[Pe.extensionName].params,x=An.format({[Pe.extensionName]:[f]});d.push(`Sec-WebSocket-Extensions: ${x}`),u._extensions=e}this.emit("headers",d,n),i.write(d.concat(`\r +`).join(`\r +`)),i.removeListener("error",Dn),u.setSocket(i,o,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(u),u.on("close",()=>{this.clients.delete(u),this._shouldEmitClose&&!this.clients.size&&process.nextTick(Ot,this)})),a(u,n)}};Bn.exports=Xr;function oa(t,e){for(let r of Object.keys(e))t.on(r,e[r]);return function(){for(let s of Object.keys(e))t.removeListener(s,e[s])}}function Ot(t){t._state=qn,t.emit("close")}function Dn(){this.destroy()}function Ct(t,e,r,s){r=r||rr.STATUS_CODES[e],s={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(r),...s},t.once("finish",t.destroy),t.end(`HTTP/1.1 ${e} ${rr.STATUS_CODES[e]}\r +`+Object.keys(s).map(n=>`${n}: ${s[n]}`).join(`\r +`)+`\r +\r +`+r)}function je(t,e,r,s,n){if(t.listenerCount("wsClientError")){let i=new Error(n);Error.captureStackTrace(i,je),t.emit("wsClientError",i,r,e)}else Ct(r,s,n)}});var pi=q((Id,nl)=>{nl.exports={name:"dotenv",version:"16.4.7",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard",pretest:"npm run lint && npm run dts-check",test:"tap run --allow-empty-coverage --disable-coverage --timeout=60000","test:coverage":"tap run --show-full-coverage --timeout=60000 --coverage-report=lcov",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},funding:"https://dotenvx.com",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@types/node":"^18.11.3",decache:"^4.6.2",sinon:"^14.0.1",standard:"^17.0.0","standard-version":"^9.5.0",tap:"^19.2.0",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var yi=q((Pd,me)=>{var vs=require("fs"),xs=require("path"),il=require("os"),ol=require("crypto"),al=pi(),bs=al.version,cl=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function ll(t){let e={},r=t.toString();r=r.replace(/\r\n?/mg,` +`);let s;for(;(s=cl.exec(r))!=null;){let n=s[1],i=s[2]||"";i=i.trim();let o=i[0];i=i.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),o==='"'&&(i=i.replace(/\\n/g,` +`),i=i.replace(/\\r/g,"\r")),e[n]=i}return e}function dl(t){let e=_i(t),r=j.configDotenv({path:e});if(!r.parsed){let o=new Error(`MISSING_DATA: Cannot parse ${e} for an unknown reason`);throw o.code="MISSING_DATA",o}let s=gi(t).split(","),n=s.length,i;for(let o=0;o=n)throw a}return j.parse(i)}function ul(t){console.log(`[dotenv@${bs}][INFO] ${t}`)}function fl(t){console.log(`[dotenv@${bs}][WARN] ${t}`)}function wr(t){console.log(`[dotenv@${bs}][DEBUG] ${t}`)}function gi(t){return t&&t.DOTENV_KEY&&t.DOTENV_KEY.length>0?t.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function hl(t,e){let r;try{r=new URL(e)}catch(a){if(a.code==="ERR_INVALID_URL"){let l=new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw l.code="INVALID_DOTENV_KEY",l}throw a}let s=r.password;if(!s){let a=new Error("INVALID_DOTENV_KEY: Missing key part");throw a.code="INVALID_DOTENV_KEY",a}let n=r.searchParams.get("environment");if(!n){let a=new Error("INVALID_DOTENV_KEY: Missing environment part");throw a.code="INVALID_DOTENV_KEY",a}let i=`DOTENV_VAULT_${n.toUpperCase()}`,o=t.parsed[i];if(!o){let a=new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${i} in your .env.vault file.`);throw a.code="NOT_FOUND_DOTENV_ENVIRONMENT",a}return{ciphertext:o,key:s}}function _i(t){let e=null;if(t&&t.path&&t.path.length>0)if(Array.isArray(t.path))for(let r of t.path)vs.existsSync(r)&&(e=r.endsWith(".vault")?r:`${r}.vault`);else e=t.path.endsWith(".vault")?t.path:`${t.path}.vault`;else e=xs.resolve(process.cwd(),".env.vault");return vs.existsSync(e)?e:null}function mi(t){return t[0]==="~"?xs.join(il.homedir(),t.slice(1)):t}function pl(t){ul("Loading env from encrypted .env.vault");let e=j._parseVault(t),r=process.env;return t&&t.processEnv!=null&&(r=t.processEnv),j.populate(r,e,t),{parsed:e}}function ml(t){let e=xs.resolve(process.cwd(),".env"),r="utf8",s=!!(t&&t.debug);t&&t.encoding?r=t.encoding:s&&wr("No encoding is specified. UTF-8 is used by default");let n=[e];if(t&&t.path)if(!Array.isArray(t.path))n=[mi(t.path)];else{n=[];for(let l of t.path)n.push(mi(l))}let i,o={};for(let l of n)try{let d=j.parse(vs.readFileSync(l,{encoding:r}));j.populate(o,d,t)}catch(d){s&&wr(`Failed to load ${l} ${d.message}`),i=d}let a=process.env;return t&&t.processEnv!=null&&(a=t.processEnv),j.populate(a,o,t),i?{parsed:o,error:i}:{parsed:o}}function gl(t){if(gi(t).length===0)return j.configDotenv(t);let e=_i(t);return e?j._configVault(t):(fl(`You set DOTENV_KEY but you are missing a .env.vault file at ${e}. Did you forget to build it?`),j.configDotenv(t))}function _l(t,e){let r=Buffer.from(e.slice(-64),"hex"),s=Buffer.from(t,"base64"),n=s.subarray(0,12),i=s.subarray(-16);s=s.subarray(12,-16);try{let o=ol.createDecipheriv("aes-256-gcm",r,n);return o.setAuthTag(i),`${o.update(s)}${o.final()}`}catch(o){let a=o instanceof RangeError,l=o.message==="Invalid key length",d=o.message==="Unsupported state or unable to authenticate data";if(a||l){let u=new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw u.code="INVALID_DOTENV_KEY",u}else if(d){let u=new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw u.code="DECRYPTION_FAILED",u}else throw o}}function yl(t,e,r={}){let s=!!(r&&r.debug),n=!!(r&&r.override);if(typeof e!="object"){let i=new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw i.code="OBJECT_REQUIRED",i}for(let i of Object.keys(e))Object.prototype.hasOwnProperty.call(t,i)?(n===!0&&(t[i]=e[i]),s&&wr(n===!0?`"${i}" is already defined and WAS overwritten`:`"${i}" is already defined and was NOT overwritten`)):t[i]=e[i]}var j={configDotenv:ml,_configVault:pl,_parseVault:dl,config:gl,decrypt:_l,parse:ll,populate:yl};me.exports.configDotenv=j.configDotenv;me.exports._configVault=j._configVault;me.exports._parseVault=j._parseVault;me.exports.config=j.config;me.exports.decrypt=j.decrypt;me.exports.parse=j.parse;me.exports.populate=j.populate;me.exports=j});var et=M(require("fs/promises"),1);var aa=M(Pn(),1),ca=M(Vr(),1),la=M(Zr(),1),It=M(tr(),1),Qr=M(Un(),1);var Q=It.default;var Ii=require("http"),Pi=require("url"),ji=require("child_process");var k;(function(t){t.assertEqual=n=>n;function e(n){}t.assertIs=e;function r(n){throw new Error}t.assertNever=r,t.arrayToEnum=n=>{let i={};for(let o of n)i[o]=o;return i},t.getValidEnumValues=n=>{let i=t.objectKeys(n).filter(a=>typeof n[n[a]]!="number"),o={};for(let a of i)o[a]=n[a];return t.objectValues(o)},t.objectValues=n=>t.objectKeys(n).map(function(i){return n[i]}),t.objectKeys=typeof Object.keys=="function"?n=>Object.keys(n):n=>{let i=[];for(let o in n)Object.prototype.hasOwnProperty.call(n,o)&&i.push(o);return i},t.find=(n,i)=>{for(let o of n)if(i(o))return o},t.isInteger=typeof Number.isInteger=="function"?n=>Number.isInteger(n):n=>typeof n=="number"&&isFinite(n)&&Math.floor(n)===n;function s(n,i=" | "){return n.map(o=>typeof o=="string"?`'${o}'`:o).join(i)}t.joinValues=s,t.jsonStringifyReplacer=(n,i)=>typeof i=="bigint"?i.toString():i})(k||(k={}));var ts;(function(t){t.mergeShapes=(e,r)=>({...e,...r})})(ts||(ts={}));var m=k.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),fe=t=>{switch(typeof t){case"undefined":return m.undefined;case"string":return m.string;case"number":return isNaN(t)?m.nan:m.number;case"boolean":return m.boolean;case"function":return m.function;case"bigint":return m.bigint;case"symbol":return m.symbol;case"object":return Array.isArray(t)?m.array:t===null?m.null:t.then&&typeof t.then=="function"&&t.catch&&typeof t.catch=="function"?m.promise:typeof Map<"u"&&t instanceof Map?m.map:typeof Set<"u"&&t instanceof Set?m.set:typeof Date<"u"&&t instanceof Date?m.date:m.object;default:return m.unknown}},h=k.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),da=t=>JSON.stringify(t,null,2).replace(/"([^"]+)":/g,"$1:"),W=class t extends Error{get errors(){return this.issues}constructor(e){super(),this.issues=[],this.addIssue=s=>{this.issues=[...this.issues,s]},this.addIssues=(s=[])=>{this.issues=[...this.issues,...s]};let r=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,r):this.__proto__=r,this.name="ZodError",this.issues=e}format(e){let r=e||function(i){return i.message},s={_errors:[]},n=i=>{for(let o of i.issues)if(o.code==="invalid_union")o.unionErrors.map(n);else if(o.code==="invalid_return_type")n(o.returnTypeError);else if(o.code==="invalid_arguments")n(o.argumentsError);else if(o.path.length===0)s._errors.push(r(o));else{let a=s,l=0;for(;lr.message){let r={},s=[];for(let n of this.issues)n.path.length>0?(r[n.path[0]]=r[n.path[0]]||[],r[n.path[0]].push(e(n))):s.push(e(n));return{formErrors:s,fieldErrors:r}}get formErrors(){return this.flatten()}};W.create=t=>new W(t);var lt=(t,e)=>{let r;switch(t.code){case h.invalid_type:t.received===m.undefined?r="Required":r=`Expected ${t.expected}, received ${t.received}`;break;case h.invalid_literal:r=`Invalid literal value, expected ${JSON.stringify(t.expected,k.jsonStringifyReplacer)}`;break;case h.unrecognized_keys:r=`Unrecognized key(s) in object: ${k.joinValues(t.keys,", ")}`;break;case h.invalid_union:r="Invalid input";break;case h.invalid_union_discriminator:r=`Invalid discriminator value. Expected ${k.joinValues(t.options)}`;break;case h.invalid_enum_value:r=`Invalid enum value. Expected ${k.joinValues(t.options)}, received '${t.received}'`;break;case h.invalid_arguments:r="Invalid function arguments";break;case h.invalid_return_type:r="Invalid function return type";break;case h.invalid_date:r="Invalid date";break;case h.invalid_string:typeof t.validation=="object"?"includes"in t.validation?(r=`Invalid input: must include "${t.validation.includes}"`,typeof t.validation.position=="number"&&(r=`${r} at one or more positions greater than or equal to ${t.validation.position}`)):"startsWith"in t.validation?r=`Invalid input: must start with "${t.validation.startsWith}"`:"endsWith"in t.validation?r=`Invalid input: must end with "${t.validation.endsWith}"`:k.assertNever(t.validation):t.validation!=="regex"?r=`Invalid ${t.validation}`:r="Invalid";break;case h.too_small:t.type==="array"?r=`Array must contain ${t.exact?"exactly":t.inclusive?"at least":"more than"} ${t.minimum} element(s)`:t.type==="string"?r=`String must contain ${t.exact?"exactly":t.inclusive?"at least":"over"} ${t.minimum} character(s)`:t.type==="number"?r=`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:t.type==="date"?r=`Date must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(t.minimum))}`:r="Invalid input";break;case h.too_big:t.type==="array"?r=`Array must contain ${t.exact?"exactly":t.inclusive?"at most":"less than"} ${t.maximum} element(s)`:t.type==="string"?r=`String must contain ${t.exact?"exactly":t.inclusive?"at most":"under"} ${t.maximum} character(s)`:t.type==="number"?r=`Number must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:t.type==="bigint"?r=`BigInt must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:t.type==="date"?r=`Date must be ${t.exact?"exactly":t.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(t.maximum))}`:r="Invalid input";break;case h.custom:r="Invalid input";break;case h.invalid_intersection_types:r="Intersection results could not be merged";break;case h.not_multiple_of:r=`Number must be a multiple of ${t.multipleOf}`;break;case h.not_finite:r="Number must be finite";break;default:r=e.defaultError,k.assertNever(t)}return{message:r}},Zn=lt;function ua(t){Zn=t}function sr(){return Zn}var nr=t=>{let{data:e,path:r,errorMaps:s,issueData:n}=t,i=[...r,...n.path||[]],o={...n,path:i};if(n.message!==void 0)return{...n,path:i,message:n.message};let a="",l=s.filter(d=>!!d).slice().reverse();for(let d of l)a=d(o,{data:e,defaultError:a}).message;return{...n,path:i,message:a}},fa=[];function p(t,e){let r=sr(),s=nr({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,r,r===lt?void 0:lt].filter(n=>!!n)});t.common.issues.push(s)}var D=class t{constructor(){this.value="valid"}dirty(){this.value==="valid"&&(this.value="dirty")}abort(){this.value!=="aborted"&&(this.value="aborted")}static mergeArray(e,r){let s=[];for(let n of r){if(n.status==="aborted")return v;n.status==="dirty"&&e.dirty(),s.push(n.value)}return{status:e.value,value:s}}static async mergeObjectAsync(e,r){let s=[];for(let n of r){let i=await n.key,o=await n.value;s.push({key:i,value:o})}return t.mergeObjectSync(e,s)}static mergeObjectSync(e,r){let s={};for(let n of r){let{key:i,value:o}=n;if(i.status==="aborted"||o.status==="aborted")return v;i.status==="dirty"&&e.dirty(),o.status==="dirty"&&e.dirty(),i.value!=="__proto__"&&(typeof o.value<"u"||n.alwaysSet)&&(s[i.value]=o.value)}return{status:e.value,value:s}}},v=Object.freeze({status:"aborted"}),ct=t=>({status:"dirty",value:t}),B=t=>({status:"valid",value:t}),rs=t=>t.status==="aborted",ss=t=>t.status==="dirty",$e=t=>t.status==="valid",$t=t=>typeof Promise<"u"&&t instanceof Promise;function ir(t,e,r,s){if(r==="a"&&!s)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return r==="m"?s:r==="a"?s.call(t):s?s.value:e.get(t)}function zn(t,e,r,s,n){if(s==="m")throw new TypeError("Private method is not writable");if(s==="a"&&!n)throw new TypeError("Private accessor was defined without a setter");if(typeof e=="function"?t!==e||!n:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return s==="a"?n.call(t,r):n?n.value=r:e.set(t,r),r}var g;(function(t){t.errToObj=e=>typeof e=="string"?{message:e}:e||{},t.toString=e=>typeof e=="string"?e:e?.message})(g||(g={}));var Pt,jt,Y=class{constructor(e,r,s,n){this._cachedPath=[],this.parent=e,this.data=r,this._path=s,this._key=n}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},Vn=(t,e)=>{if($e(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;let r=new W(t.common.issues);return this._error=r,this._error}}};function S(t){if(!t)return{};let{errorMap:e,invalid_type_error:r,required_error:s,description:n}=t;if(e&&(r||s))throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);return e?{errorMap:e,description:n}:{errorMap:(o,a)=>{var l,d;let{message:u}=t;return o.code==="invalid_enum_value"?{message:u??a.defaultError}:typeof a.data>"u"?{message:(l=u??s)!==null&&l!==void 0?l:a.defaultError}:o.code!=="invalid_type"?{message:a.defaultError}:{message:(d=u??r)!==null&&d!==void 0?d:a.defaultError}},description:n}}var w=class{get description(){return this._def.description}_getType(e){return fe(e.data)}_getOrReturnCtx(e,r){return r||{common:e.parent.common,data:e.data,parsedType:fe(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new D,ctx:{common:e.parent.common,data:e.data,parsedType:fe(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){let r=this._parse(e);if($t(r))throw new Error("Synchronous parse encountered promise.");return r}_parseAsync(e){let r=this._parse(e);return Promise.resolve(r)}parse(e,r){let s=this.safeParse(e,r);if(s.success)return s.data;throw s.error}safeParse(e,r){var s;let n={common:{issues:[],async:(s=r?.async)!==null&&s!==void 0?s:!1,contextualErrorMap:r?.errorMap},path:r?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:fe(e)},i=this._parseSync({data:e,path:n.path,parent:n});return Vn(n,i)}"~validate"(e){var r,s;let n={common:{issues:[],async:!!this["~standard"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:fe(e)};if(!this["~standard"].async)try{let i=this._parseSync({data:e,path:[],parent:n});return $e(i)?{value:i.value}:{issues:n.common.issues}}catch(i){!((s=(r=i?.message)===null||r===void 0?void 0:r.toLowerCase())===null||s===void 0)&&s.includes("encountered")&&(this["~standard"].async=!0),n.common={issues:[],async:!0}}return this._parseAsync({data:e,path:[],parent:n}).then(i=>$e(i)?{value:i.value}:{issues:n.common.issues})}async parseAsync(e,r){let s=await this.safeParseAsync(e,r);if(s.success)return s.data;throw s.error}async safeParseAsync(e,r){let s={common:{issues:[],contextualErrorMap:r?.errorMap,async:!0},path:r?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:fe(e)},n=this._parse({data:e,path:s.path,parent:s}),i=await($t(n)?n:Promise.resolve(n));return Vn(s,i)}refine(e,r){let s=n=>typeof r=="string"||typeof r>"u"?{message:r}:typeof r=="function"?r(n):r;return this._refinement((n,i)=>{let o=e(n),a=()=>i.addIssue({code:h.custom,...s(n)});return typeof Promise<"u"&&o instanceof Promise?o.then(l=>l?!0:(a(),!1)):o?!0:(a(),!1)})}refinement(e,r){return this._refinement((s,n)=>e(s)?!0:(n.addIssue(typeof r=="function"?r(s,n):r),!1))}_refinement(e){return new F({schema:this,typeName:y.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this["~standard"]={version:1,vendor:"zod",validate:r=>this["~validate"](r)}}optional(){return J.create(this,this._def)}nullable(){return ie.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return pe.create(this)}promise(){return be.create(this,this._def)}or(e){return Ue.create([this,e],this._def)}and(e){return Ve.create(this,e,this._def)}transform(e){return new F({...S(this._def),schema:this,typeName:y.ZodEffects,effect:{type:"transform",transform:e}})}default(e){let r=typeof e=="function"?e:()=>e;return new He({...S(this._def),innerType:this,defaultValue:r,typeName:y.ZodDefault})}brand(){return new At({typeName:y.ZodBranded,type:this,...S(this._def)})}catch(e){let r=typeof e=="function"?e:()=>e;return new Ge({...S(this._def),innerType:this,catchValue:r,typeName:y.ZodCatch})}describe(e){let r=this.constructor;return new r({...this._def,description:e})}pipe(e){return Lt.create(this,e)}readonly(){return Je.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},ha=/^c[^\s-]{8,}$/i,pa=/^[0-9a-z]+$/,ma=/^[0-9A-HJKMNP-TV-Z]{26}$/i,ga=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,_a=/^[a-z0-9_-]{21}$/i,ya=/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,va=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,xa=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,ba="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$",es,Sa=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,wa=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,Ea=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,ka=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,Ta=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,Ra=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Hn="((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))",Na=new RegExp(`^${Hn}$`);function Gn(t){let e="([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d";return t.precision?e=`${e}\\.\\d{${t.precision}}`:t.precision==null&&(e=`${e}(\\.\\d+)?`),e}function Oa(t){return new RegExp(`^${Gn(t)}$`)}function Jn(t){let e=`${Hn}T${Gn(t)}`,r=[];return r.push(t.local?"Z?":"Z"),t.offset&&r.push("([+-]\\d{2}:?\\d{2})"),e=`${e}(${r.join("|")})`,new RegExp(`^${e}$`)}function Ca(t,e){return!!((e==="v4"||!e)&&Sa.test(t)||(e==="v6"||!e)&&Ea.test(t))}function Ia(t,e){if(!ya.test(t))return!1;try{let[r]=t.split("."),s=r.replace(/-/g,"+").replace(/_/g,"/").padEnd(r.length+(4-r.length%4)%4,"="),n=JSON.parse(atob(s));return!(typeof n!="object"||n===null||!n.typ||!n.alg||e&&n.alg!==e)}catch{return!1}}function Pa(t,e){return!!((e==="v4"||!e)&&wa.test(t)||(e==="v6"||!e)&&ka.test(t))}var ve=class t extends w{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==m.string){let i=this._getOrReturnCtx(e);return p(i,{code:h.invalid_type,expected:m.string,received:i.parsedType}),v}let s=new D,n;for(let i of this._def.checks)if(i.kind==="min")e.data.lengthi.value&&(n=this._getOrReturnCtx(e,n),p(n,{code:h.too_big,maximum:i.value,type:"string",inclusive:!0,exact:!1,message:i.message}),s.dirty());else if(i.kind==="length"){let o=e.data.length>i.value,a=e.data.lengthe.test(n),{validation:r,code:h.invalid_string,...g.errToObj(s)})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...g.errToObj(e)})}url(e){return this._addCheck({kind:"url",...g.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...g.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...g.errToObj(e)})}nanoid(e){return this._addCheck({kind:"nanoid",...g.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...g.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...g.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...g.errToObj(e)})}base64(e){return this._addCheck({kind:"base64",...g.errToObj(e)})}base64url(e){return this._addCheck({kind:"base64url",...g.errToObj(e)})}jwt(e){return this._addCheck({kind:"jwt",...g.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...g.errToObj(e)})}cidr(e){return this._addCheck({kind:"cidr",...g.errToObj(e)})}datetime(e){var r,s;return typeof e=="string"?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:e}):this._addCheck({kind:"datetime",precision:typeof e?.precision>"u"?null:e?.precision,offset:(r=e?.offset)!==null&&r!==void 0?r:!1,local:(s=e?.local)!==null&&s!==void 0?s:!1,...g.errToObj(e?.message)})}date(e){return this._addCheck({kind:"date",message:e})}time(e){return typeof e=="string"?this._addCheck({kind:"time",precision:null,message:e}):this._addCheck({kind:"time",precision:typeof e?.precision>"u"?null:e?.precision,...g.errToObj(e?.message)})}duration(e){return this._addCheck({kind:"duration",...g.errToObj(e)})}regex(e,r){return this._addCheck({kind:"regex",regex:e,...g.errToObj(r)})}includes(e,r){return this._addCheck({kind:"includes",value:e,position:r?.position,...g.errToObj(r?.message)})}startsWith(e,r){return this._addCheck({kind:"startsWith",value:e,...g.errToObj(r)})}endsWith(e,r){return this._addCheck({kind:"endsWith",value:e,...g.errToObj(r)})}min(e,r){return this._addCheck({kind:"min",value:e,...g.errToObj(r)})}max(e,r){return this._addCheck({kind:"max",value:e,...g.errToObj(r)})}length(e,r){return this._addCheck({kind:"length",value:e,...g.errToObj(r)})}nonempty(e){return this.min(1,g.errToObj(e))}trim(){return new t({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(e=>e.kind==="datetime")}get isDate(){return!!this._def.checks.find(e=>e.kind==="date")}get isTime(){return!!this._def.checks.find(e=>e.kind==="time")}get isDuration(){return!!this._def.checks.find(e=>e.kind==="duration")}get isEmail(){return!!this._def.checks.find(e=>e.kind==="email")}get isURL(){return!!this._def.checks.find(e=>e.kind==="url")}get isEmoji(){return!!this._def.checks.find(e=>e.kind==="emoji")}get isUUID(){return!!this._def.checks.find(e=>e.kind==="uuid")}get isNANOID(){return!!this._def.checks.find(e=>e.kind==="nanoid")}get isCUID(){return!!this._def.checks.find(e=>e.kind==="cuid")}get isCUID2(){return!!this._def.checks.find(e=>e.kind==="cuid2")}get isULID(){return!!this._def.checks.find(e=>e.kind==="ulid")}get isIP(){return!!this._def.checks.find(e=>e.kind==="ip")}get isCIDR(){return!!this._def.checks.find(e=>e.kind==="cidr")}get isBase64(){return!!this._def.checks.find(e=>e.kind==="base64")}get isBase64url(){return!!this._def.checks.find(e=>e.kind==="base64url")}get minLength(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxLength(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.value{var e;return new ve({checks:[],typeName:y.ZodString,coerce:(e=t?.coerce)!==null&&e!==void 0?e:!1,...S(t)})};function ja(t,e){let r=(t.toString().split(".")[1]||"").length,s=(e.toString().split(".")[1]||"").length,n=r>s?r:s,i=parseInt(t.toFixed(n).replace(".","")),o=parseInt(e.toFixed(n).replace(".",""));return i%o/Math.pow(10,n)}var Ae=class t extends w{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==m.number){let i=this._getOrReturnCtx(e);return p(i,{code:h.invalid_type,expected:m.number,received:i.parsedType}),v}let s,n=new D;for(let i of this._def.checks)i.kind==="int"?k.isInteger(e.data)||(s=this._getOrReturnCtx(e,s),p(s,{code:h.invalid_type,expected:"integer",received:"float",message:i.message}),n.dirty()):i.kind==="min"?(i.inclusive?e.datai.value:e.data>=i.value)&&(s=this._getOrReturnCtx(e,s),p(s,{code:h.too_big,maximum:i.value,type:"number",inclusive:i.inclusive,exact:!1,message:i.message}),n.dirty()):i.kind==="multipleOf"?ja(e.data,i.value)!==0&&(s=this._getOrReturnCtx(e,s),p(s,{code:h.not_multiple_of,multipleOf:i.value,message:i.message}),n.dirty()):i.kind==="finite"?Number.isFinite(e.data)||(s=this._getOrReturnCtx(e,s),p(s,{code:h.not_finite,message:i.message}),n.dirty()):k.assertNever(i);return{status:n.value,value:e.data}}gte(e,r){return this.setLimit("min",e,!0,g.toString(r))}gt(e,r){return this.setLimit("min",e,!1,g.toString(r))}lte(e,r){return this.setLimit("max",e,!0,g.toString(r))}lt(e,r){return this.setLimit("max",e,!1,g.toString(r))}setLimit(e,r,s,n){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:s,message:g.toString(n)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:g.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:g.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:g.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:g.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:g.toString(e)})}multipleOf(e,r){return this._addCheck({kind:"multipleOf",value:e,message:g.toString(r)})}finite(e){return this._addCheck({kind:"finite",message:g.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:g.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:g.toString(e)})}get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.valuee.kind==="int"||e.kind==="multipleOf"&&k.isInteger(e.value))}get isFinite(){let e=null,r=null;for(let s of this._def.checks){if(s.kind==="finite"||s.kind==="int"||s.kind==="multipleOf")return!0;s.kind==="min"?(r===null||s.value>r)&&(r=s.value):s.kind==="max"&&(e===null||s.valuenew Ae({checks:[],typeName:y.ZodNumber,coerce:t?.coerce||!1,...S(t)});var Le=class t extends w{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce)try{e.data=BigInt(e.data)}catch{return this._getInvalidInput(e)}if(this._getType(e)!==m.bigint)return this._getInvalidInput(e);let s,n=new D;for(let i of this._def.checks)i.kind==="min"?(i.inclusive?e.datai.value:e.data>=i.value)&&(s=this._getOrReturnCtx(e,s),p(s,{code:h.too_big,type:"bigint",maximum:i.value,inclusive:i.inclusive,message:i.message}),n.dirty()):i.kind==="multipleOf"?e.data%i.value!==BigInt(0)&&(s=this._getOrReturnCtx(e,s),p(s,{code:h.not_multiple_of,multipleOf:i.value,message:i.message}),n.dirty()):k.assertNever(i);return{status:n.value,value:e.data}}_getInvalidInput(e){let r=this._getOrReturnCtx(e);return p(r,{code:h.invalid_type,expected:m.bigint,received:r.parsedType}),v}gte(e,r){return this.setLimit("min",e,!0,g.toString(r))}gt(e,r){return this.setLimit("min",e,!1,g.toString(r))}lte(e,r){return this.setLimit("max",e,!0,g.toString(r))}lt(e,r){return this.setLimit("max",e,!1,g.toString(r))}setLimit(e,r,s,n){return new t({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:s,message:g.toString(n)}]})}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:g.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:g.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:g.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:g.toString(e)})}multipleOf(e,r){return this._addCheck({kind:"multipleOf",value:e,message:g.toString(r)})}get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.value{var e;return new Le({checks:[],typeName:y.ZodBigInt,coerce:(e=t?.coerce)!==null&&e!==void 0?e:!1,...S(t)})};var Me=class extends w{_parse(e){if(this._def.coerce&&(e.data=!!e.data),this._getType(e)!==m.boolean){let s=this._getOrReturnCtx(e);return p(s,{code:h.invalid_type,expected:m.boolean,received:s.parsedType}),v}return B(e.data)}};Me.create=t=>new Me({typeName:y.ZodBoolean,coerce:t?.coerce||!1,...S(t)});var De=class t extends w{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==m.date){let i=this._getOrReturnCtx(e);return p(i,{code:h.invalid_type,expected:m.date,received:i.parsedType}),v}if(isNaN(e.data.getTime())){let i=this._getOrReturnCtx(e);return p(i,{code:h.invalid_date}),v}let s=new D,n;for(let i of this._def.checks)i.kind==="min"?e.data.getTime()i.value&&(n=this._getOrReturnCtx(e,n),p(n,{code:h.too_big,message:i.message,inclusive:!0,exact:!1,maximum:i.value,type:"date"}),s.dirty()):k.assertNever(i);return{status:s.value,value:new Date(e.data.getTime())}}_addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}min(e,r){return this._addCheck({kind:"min",value:e.getTime(),message:g.toString(r)})}max(e,r){return this._addCheck({kind:"max",value:e.getTime(),message:g.toString(r)})}get minDate(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e!=null?new Date(e):null}get maxDate(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.valuenew De({checks:[],coerce:t?.coerce||!1,typeName:y.ZodDate,...S(t)});var dt=class extends w{_parse(e){if(this._getType(e)!==m.symbol){let s=this._getOrReturnCtx(e);return p(s,{code:h.invalid_type,expected:m.symbol,received:s.parsedType}),v}return B(e.data)}};dt.create=t=>new dt({typeName:y.ZodSymbol,...S(t)});var qe=class extends w{_parse(e){if(this._getType(e)!==m.undefined){let s=this._getOrReturnCtx(e);return p(s,{code:h.invalid_type,expected:m.undefined,received:s.parsedType}),v}return B(e.data)}};qe.create=t=>new qe({typeName:y.ZodUndefined,...S(t)});var Be=class extends w{_parse(e){if(this._getType(e)!==m.null){let s=this._getOrReturnCtx(e);return p(s,{code:h.invalid_type,expected:m.null,received:s.parsedType}),v}return B(e.data)}};Be.create=t=>new Be({typeName:y.ZodNull,...S(t)});var xe=class extends w{constructor(){super(...arguments),this._any=!0}_parse(e){return B(e.data)}};xe.create=t=>new xe({typeName:y.ZodAny,...S(t)});var he=class extends w{constructor(){super(...arguments),this._unknown=!0}_parse(e){return B(e.data)}};he.create=t=>new he({typeName:y.ZodUnknown,...S(t)});var ee=class extends w{_parse(e){let r=this._getOrReturnCtx(e);return p(r,{code:h.invalid_type,expected:m.never,received:r.parsedType}),v}};ee.create=t=>new ee({typeName:y.ZodNever,...S(t)});var ut=class extends w{_parse(e){if(this._getType(e)!==m.undefined){let s=this._getOrReturnCtx(e);return p(s,{code:h.invalid_type,expected:m.void,received:s.parsedType}),v}return B(e.data)}};ut.create=t=>new ut({typeName:y.ZodVoid,...S(t)});var pe=class t extends w{_parse(e){let{ctx:r,status:s}=this._processInputParams(e),n=this._def;if(r.parsedType!==m.array)return p(r,{code:h.invalid_type,expected:m.array,received:r.parsedType}),v;if(n.exactLength!==null){let o=r.data.length>n.exactLength.value,a=r.data.lengthn.maxLength.value&&(p(r,{code:h.too_big,maximum:n.maxLength.value,type:"array",inclusive:!0,exact:!1,message:n.maxLength.message}),s.dirty()),r.common.async)return Promise.all([...r.data].map((o,a)=>n.type._parseAsync(new Y(r,o,r.path,a)))).then(o=>D.mergeArray(s,o));let i=[...r.data].map((o,a)=>n.type._parseSync(new Y(r,o,r.path,a)));return D.mergeArray(s,i)}get element(){return this._def.type}min(e,r){return new t({...this._def,minLength:{value:e,message:g.toString(r)}})}max(e,r){return new t({...this._def,maxLength:{value:e,message:g.toString(r)}})}length(e,r){return new t({...this._def,exactLength:{value:e,message:g.toString(r)}})}nonempty(e){return this.min(1,e)}};pe.create=(t,e)=>new pe({type:t,minLength:null,maxLength:null,exactLength:null,typeName:y.ZodArray,...S(e)});function at(t){if(t instanceof U){let e={};for(let r in t.shape){let s=t.shape[r];e[r]=J.create(at(s))}return new U({...t._def,shape:()=>e})}else return t instanceof pe?new pe({...t._def,type:at(t.element)}):t instanceof J?J.create(at(t.unwrap())):t instanceof ie?ie.create(at(t.unwrap())):t instanceof ne?ne.create(t.items.map(e=>at(e))):t}var U=class t extends w{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;let e=this._def.shape(),r=k.objectKeys(e);return this._cached={shape:e,keys:r}}_parse(e){if(this._getType(e)!==m.object){let d=this._getOrReturnCtx(e);return p(d,{code:h.invalid_type,expected:m.object,received:d.parsedType}),v}let{status:s,ctx:n}=this._processInputParams(e),{shape:i,keys:o}=this._getCached(),a=[];if(!(this._def.catchall instanceof ee&&this._def.unknownKeys==="strip"))for(let d in n.data)o.includes(d)||a.push(d);let l=[];for(let d of o){let u=i[d],f=n.data[d];l.push({key:{status:"valid",value:d},value:u._parse(new Y(n,f,n.path,d)),alwaysSet:d in n.data})}if(this._def.catchall instanceof ee){let d=this._def.unknownKeys;if(d==="passthrough")for(let u of a)l.push({key:{status:"valid",value:u},value:{status:"valid",value:n.data[u]}});else if(d==="strict")a.length>0&&(p(n,{code:h.unrecognized_keys,keys:a}),s.dirty());else if(d!=="strip")throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{let d=this._def.catchall;for(let u of a){let f=n.data[u];l.push({key:{status:"valid",value:u},value:d._parse(new Y(n,f,n.path,u)),alwaysSet:u in n.data})}}return n.common.async?Promise.resolve().then(async()=>{let d=[];for(let u of l){let f=await u.key,x=await u.value;d.push({key:f,value:x,alwaysSet:u.alwaysSet})}return d}).then(d=>D.mergeObjectSync(s,d)):D.mergeObjectSync(s,l)}get shape(){return this._def.shape()}strict(e){return g.errToObj,new t({...this._def,unknownKeys:"strict",...e!==void 0?{errorMap:(r,s)=>{var n,i,o,a;let l=(o=(i=(n=this._def).errorMap)===null||i===void 0?void 0:i.call(n,r,s).message)!==null&&o!==void 0?o:s.defaultError;return r.code==="unrecognized_keys"?{message:(a=g.errToObj(e).message)!==null&&a!==void 0?a:l}:{message:l}}}:{}})}strip(){return new t({...this._def,unknownKeys:"strip"})}passthrough(){return new t({...this._def,unknownKeys:"passthrough"})}extend(e){return new t({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:y.ZodObject})}setKey(e,r){return this.augment({[e]:r})}catchall(e){return new t({...this._def,catchall:e})}pick(e){let r={};return k.objectKeys(e).forEach(s=>{e[s]&&this.shape[s]&&(r[s]=this.shape[s])}),new t({...this._def,shape:()=>r})}omit(e){let r={};return k.objectKeys(this.shape).forEach(s=>{e[s]||(r[s]=this.shape[s])}),new t({...this._def,shape:()=>r})}deepPartial(){return at(this)}partial(e){let r={};return k.objectKeys(this.shape).forEach(s=>{let n=this.shape[s];e&&!e[s]?r[s]=n:r[s]=n.optional()}),new t({...this._def,shape:()=>r})}required(e){let r={};return k.objectKeys(this.shape).forEach(s=>{if(e&&!e[s])r[s]=this.shape[s];else{let i=this.shape[s];for(;i instanceof J;)i=i._def.innerType;r[s]=i}}),new t({...this._def,shape:()=>r})}keyof(){return Yn(k.objectKeys(this.shape))}};U.create=(t,e)=>new U({shape:()=>t,unknownKeys:"strip",catchall:ee.create(),typeName:y.ZodObject,...S(e)});U.strictCreate=(t,e)=>new U({shape:()=>t,unknownKeys:"strict",catchall:ee.create(),typeName:y.ZodObject,...S(e)});U.lazycreate=(t,e)=>new U({shape:t,unknownKeys:"strip",catchall:ee.create(),typeName:y.ZodObject,...S(e)});var Ue=class extends w{_parse(e){let{ctx:r}=this._processInputParams(e),s=this._def.options;function n(i){for(let a of i)if(a.result.status==="valid")return a.result;for(let a of i)if(a.result.status==="dirty")return r.common.issues.push(...a.ctx.common.issues),a.result;let o=i.map(a=>new W(a.ctx.common.issues));return p(r,{code:h.invalid_union,unionErrors:o}),v}if(r.common.async)return Promise.all(s.map(async i=>{let o={...r,common:{...r.common,issues:[]},parent:null};return{result:await i._parseAsync({data:r.data,path:r.path,parent:o}),ctx:o}})).then(n);{let i,o=[];for(let l of s){let d={...r,common:{...r.common,issues:[]},parent:null},u=l._parseSync({data:r.data,path:r.path,parent:d});if(u.status==="valid")return u;u.status==="dirty"&&!i&&(i={result:u,ctx:d}),d.common.issues.length&&o.push(d.common.issues)}if(i)return r.common.issues.push(...i.ctx.common.issues),i.result;let a=o.map(l=>new W(l));return p(r,{code:h.invalid_union,unionErrors:a}),v}}get options(){return this._def.options}};Ue.create=(t,e)=>new Ue({options:t,typeName:y.ZodUnion,...S(e)});var ue=t=>t instanceof We?ue(t.schema):t instanceof F?ue(t.innerType()):t instanceof Fe?[t.value]:t instanceof Ze?t.options:t instanceof ze?k.objectValues(t.enum):t instanceof He?ue(t._def.innerType):t instanceof qe?[void 0]:t instanceof Be?[null]:t instanceof J?[void 0,...ue(t.unwrap())]:t instanceof ie?[null,...ue(t.unwrap())]:t instanceof At||t instanceof Je?ue(t.unwrap()):t instanceof Ge?ue(t._def.innerType):[],or=class t extends w{_parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==m.object)return p(r,{code:h.invalid_type,expected:m.object,received:r.parsedType}),v;let s=this.discriminator,n=r.data[s],i=this.optionsMap.get(n);return i?r.common.async?i._parseAsync({data:r.data,path:r.path,parent:r}):i._parseSync({data:r.data,path:r.path,parent:r}):(p(r,{code:h.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]}),v)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,r,s){let n=new Map;for(let i of r){let o=ue(i.shape[e]);if(!o.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(let a of o){if(n.has(a))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(a)}`);n.set(a,i)}}return new t({typeName:y.ZodDiscriminatedUnion,discriminator:e,options:r,optionsMap:n,...S(s)})}};function ns(t,e){let r=fe(t),s=fe(e);if(t===e)return{valid:!0,data:t};if(r===m.object&&s===m.object){let n=k.objectKeys(e),i=k.objectKeys(t).filter(a=>n.indexOf(a)!==-1),o={...t,...e};for(let a of i){let l=ns(t[a],e[a]);if(!l.valid)return{valid:!1};o[a]=l.data}return{valid:!0,data:o}}else if(r===m.array&&s===m.array){if(t.length!==e.length)return{valid:!1};let n=[];for(let i=0;i{if(rs(i)||rs(o))return v;let a=ns(i.value,o.value);return a.valid?((ss(i)||ss(o))&&r.dirty(),{status:r.value,value:a.data}):(p(s,{code:h.invalid_intersection_types}),v)};return s.common.async?Promise.all([this._def.left._parseAsync({data:s.data,path:s.path,parent:s}),this._def.right._parseAsync({data:s.data,path:s.path,parent:s})]).then(([i,o])=>n(i,o)):n(this._def.left._parseSync({data:s.data,path:s.path,parent:s}),this._def.right._parseSync({data:s.data,path:s.path,parent:s}))}};Ve.create=(t,e,r)=>new Ve({left:t,right:e,typeName:y.ZodIntersection,...S(r)});var ne=class t extends w{_parse(e){let{status:r,ctx:s}=this._processInputParams(e);if(s.parsedType!==m.array)return p(s,{code:h.invalid_type,expected:m.array,received:s.parsedType}),v;if(s.data.lengththis._def.items.length&&(p(s,{code:h.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),r.dirty());let i=[...s.data].map((o,a)=>{let l=this._def.items[a]||this._def.rest;return l?l._parse(new Y(s,o,s.path,a)):null}).filter(o=>!!o);return s.common.async?Promise.all(i).then(o=>D.mergeArray(r,o)):D.mergeArray(r,i)}get items(){return this._def.items}rest(e){return new t({...this._def,rest:e})}};ne.create=(t,e)=>{if(!Array.isArray(t))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new ne({items:t,typeName:y.ZodTuple,rest:null,...S(e)})};var ar=class t extends w{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:r,ctx:s}=this._processInputParams(e);if(s.parsedType!==m.object)return p(s,{code:h.invalid_type,expected:m.object,received:s.parsedType}),v;let n=[],i=this._def.keyType,o=this._def.valueType;for(let a in s.data)n.push({key:i._parse(new Y(s,a,s.path,a)),value:o._parse(new Y(s,s.data[a],s.path,a)),alwaysSet:a in s.data});return s.common.async?D.mergeObjectAsync(r,n):D.mergeObjectSync(r,n)}get element(){return this._def.valueType}static create(e,r,s){return r instanceof w?new t({keyType:e,valueType:r,typeName:y.ZodRecord,...S(s)}):new t({keyType:ve.create(),valueType:e,typeName:y.ZodRecord,...S(r)})}},ft=class extends w{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:r,ctx:s}=this._processInputParams(e);if(s.parsedType!==m.map)return p(s,{code:h.invalid_type,expected:m.map,received:s.parsedType}),v;let n=this._def.keyType,i=this._def.valueType,o=[...s.data.entries()].map(([a,l],d)=>({key:n._parse(new Y(s,a,s.path,[d,"key"])),value:i._parse(new Y(s,l,s.path,[d,"value"]))}));if(s.common.async){let a=new Map;return Promise.resolve().then(async()=>{for(let l of o){let d=await l.key,u=await l.value;if(d.status==="aborted"||u.status==="aborted")return v;(d.status==="dirty"||u.status==="dirty")&&r.dirty(),a.set(d.value,u.value)}return{status:r.value,value:a}})}else{let a=new Map;for(let l of o){let d=l.key,u=l.value;if(d.status==="aborted"||u.status==="aborted")return v;(d.status==="dirty"||u.status==="dirty")&&r.dirty(),a.set(d.value,u.value)}return{status:r.value,value:a}}}};ft.create=(t,e,r)=>new ft({valueType:e,keyType:t,typeName:y.ZodMap,...S(r)});var ht=class t extends w{_parse(e){let{status:r,ctx:s}=this._processInputParams(e);if(s.parsedType!==m.set)return p(s,{code:h.invalid_type,expected:m.set,received:s.parsedType}),v;let n=this._def;n.minSize!==null&&s.data.sizen.maxSize.value&&(p(s,{code:h.too_big,maximum:n.maxSize.value,type:"set",inclusive:!0,exact:!1,message:n.maxSize.message}),r.dirty());let i=this._def.valueType;function o(l){let d=new Set;for(let u of l){if(u.status==="aborted")return v;u.status==="dirty"&&r.dirty(),d.add(u.value)}return{status:r.value,value:d}}let a=[...s.data.values()].map((l,d)=>i._parse(new Y(s,l,s.path,d)));return s.common.async?Promise.all(a).then(l=>o(l)):o(a)}min(e,r){return new t({...this._def,minSize:{value:e,message:g.toString(r)}})}max(e,r){return new t({...this._def,maxSize:{value:e,message:g.toString(r)}})}size(e,r){return this.min(e,r).max(e,r)}nonempty(e){return this.min(1,e)}};ht.create=(t,e)=>new ht({valueType:t,minSize:null,maxSize:null,typeName:y.ZodSet,...S(e)});var cr=class t extends w{constructor(){super(...arguments),this.validate=this.implement}_parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==m.function)return p(r,{code:h.invalid_type,expected:m.function,received:r.parsedType}),v;function s(a,l){return nr({data:a,path:r.path,errorMaps:[r.common.contextualErrorMap,r.schemaErrorMap,sr(),lt].filter(d=>!!d),issueData:{code:h.invalid_arguments,argumentsError:l}})}function n(a,l){return nr({data:a,path:r.path,errorMaps:[r.common.contextualErrorMap,r.schemaErrorMap,sr(),lt].filter(d=>!!d),issueData:{code:h.invalid_return_type,returnTypeError:l}})}let i={errorMap:r.common.contextualErrorMap},o=r.data;if(this._def.returns instanceof be){let a=this;return B(async function(...l){let d=new W([]),u=await a._def.args.parseAsync(l,i).catch(E=>{throw d.addIssue(s(l,E)),d}),f=await Reflect.apply(o,this,u);return await a._def.returns._def.type.parseAsync(f,i).catch(E=>{throw d.addIssue(n(f,E)),d})})}else{let a=this;return B(function(...l){let d=a._def.args.safeParse(l,i);if(!d.success)throw new W([s(l,d.error)]);let u=Reflect.apply(o,this,d.data),f=a._def.returns.safeParse(u,i);if(!f.success)throw new W([n(u,f.error)]);return f.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new t({...this._def,args:ne.create(e).rest(he.create())})}returns(e){return new t({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,r,s){return new t({args:e||ne.create([]).rest(he.create()),returns:r||he.create(),typeName:y.ZodFunction,...S(s)})}},We=class extends w{get schema(){return this._def.getter()}_parse(e){let{ctx:r}=this._processInputParams(e);return this._def.getter()._parse({data:r.data,path:r.path,parent:r})}};We.create=(t,e)=>new We({getter:t,typeName:y.ZodLazy,...S(e)});var Fe=class extends w{_parse(e){if(e.data!==this._def.value){let r=this._getOrReturnCtx(e);return p(r,{received:r.data,code:h.invalid_literal,expected:this._def.value}),v}return{status:"valid",value:e.data}}get value(){return this._def.value}};Fe.create=(t,e)=>new Fe({value:t,typeName:y.ZodLiteral,...S(e)});function Yn(t,e){return new Ze({values:t,typeName:y.ZodEnum,...S(e)})}var Ze=class t extends w{constructor(){super(...arguments),Pt.set(this,void 0)}_parse(e){if(typeof e.data!="string"){let r=this._getOrReturnCtx(e),s=this._def.values;return p(r,{expected:k.joinValues(s),received:r.parsedType,code:h.invalid_type}),v}if(ir(this,Pt,"f")||zn(this,Pt,new Set(this._def.values),"f"),!ir(this,Pt,"f").has(e.data)){let r=this._getOrReturnCtx(e),s=this._def.values;return p(r,{received:r.data,code:h.invalid_enum_value,options:s}),v}return B(e.data)}get options(){return this._def.values}get enum(){let e={};for(let r of this._def.values)e[r]=r;return e}get Values(){let e={};for(let r of this._def.values)e[r]=r;return e}get Enum(){let e={};for(let r of this._def.values)e[r]=r;return e}extract(e,r=this._def){return t.create(e,{...this._def,...r})}exclude(e,r=this._def){return t.create(this.options.filter(s=>!e.includes(s)),{...this._def,...r})}};Pt=new WeakMap;Ze.create=Yn;var ze=class extends w{constructor(){super(...arguments),jt.set(this,void 0)}_parse(e){let r=k.getValidEnumValues(this._def.values),s=this._getOrReturnCtx(e);if(s.parsedType!==m.string&&s.parsedType!==m.number){let n=k.objectValues(r);return p(s,{expected:k.joinValues(n),received:s.parsedType,code:h.invalid_type}),v}if(ir(this,jt,"f")||zn(this,jt,new Set(k.getValidEnumValues(this._def.values)),"f"),!ir(this,jt,"f").has(e.data)){let n=k.objectValues(r);return p(s,{received:s.data,code:h.invalid_enum_value,options:n}),v}return B(e.data)}get enum(){return this._def.values}};jt=new WeakMap;ze.create=(t,e)=>new ze({values:t,typeName:y.ZodNativeEnum,...S(e)});var be=class extends w{unwrap(){return this._def.type}_parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==m.promise&&r.common.async===!1)return p(r,{code:h.invalid_type,expected:m.promise,received:r.parsedType}),v;let s=r.parsedType===m.promise?r.data:Promise.resolve(r.data);return B(s.then(n=>this._def.type.parseAsync(n,{path:r.path,errorMap:r.common.contextualErrorMap})))}};be.create=(t,e)=>new be({type:t,typeName:y.ZodPromise,...S(e)});var F=class extends w{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===y.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){let{status:r,ctx:s}=this._processInputParams(e),n=this._def.effect||null,i={addIssue:o=>{p(s,o),o.fatal?r.abort():r.dirty()},get path(){return s.path}};if(i.addIssue=i.addIssue.bind(i),n.type==="preprocess"){let o=n.transform(s.data,i);if(s.common.async)return Promise.resolve(o).then(async a=>{if(r.value==="aborted")return v;let l=await this._def.schema._parseAsync({data:a,path:s.path,parent:s});return l.status==="aborted"?v:l.status==="dirty"||r.value==="dirty"?ct(l.value):l});{if(r.value==="aborted")return v;let a=this._def.schema._parseSync({data:o,path:s.path,parent:s});return a.status==="aborted"?v:a.status==="dirty"||r.value==="dirty"?ct(a.value):a}}if(n.type==="refinement"){let o=a=>{let l=n.refinement(a,i);if(s.common.async)return Promise.resolve(l);if(l instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return a};if(s.common.async===!1){let a=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});return a.status==="aborted"?v:(a.status==="dirty"&&r.dirty(),o(a.value),{status:r.value,value:a.value})}else return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then(a=>a.status==="aborted"?v:(a.status==="dirty"&&r.dirty(),o(a.value).then(()=>({status:r.value,value:a.value}))))}if(n.type==="transform")if(s.common.async===!1){let o=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!$e(o))return o;let a=n.transform(o.value,i);if(a instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:r.value,value:a}}else return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then(o=>$e(o)?Promise.resolve(n.transform(o.value,i)).then(a=>({status:r.value,value:a})):o);k.assertNever(n)}};F.create=(t,e,r)=>new F({schema:t,typeName:y.ZodEffects,effect:e,...S(r)});F.createWithPreprocess=(t,e,r)=>new F({schema:e,effect:{type:"preprocess",transform:t},typeName:y.ZodEffects,...S(r)});var J=class extends w{_parse(e){return this._getType(e)===m.undefined?B(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};J.create=(t,e)=>new J({innerType:t,typeName:y.ZodOptional,...S(e)});var ie=class extends w{_parse(e){return this._getType(e)===m.null?B(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};ie.create=(t,e)=>new ie({innerType:t,typeName:y.ZodNullable,...S(e)});var He=class extends w{_parse(e){let{ctx:r}=this._processInputParams(e),s=r.data;return r.parsedType===m.undefined&&(s=this._def.defaultValue()),this._def.innerType._parse({data:s,path:r.path,parent:r})}removeDefault(){return this._def.innerType}};He.create=(t,e)=>new He({innerType:t,typeName:y.ZodDefault,defaultValue:typeof e.default=="function"?e.default:()=>e.default,...S(e)});var Ge=class extends w{_parse(e){let{ctx:r}=this._processInputParams(e),s={...r,common:{...r.common,issues:[]}},n=this._def.innerType._parse({data:s.data,path:s.path,parent:{...s}});return $t(n)?n.then(i=>({status:"valid",value:i.status==="valid"?i.value:this._def.catchValue({get error(){return new W(s.common.issues)},input:s.data})})):{status:"valid",value:n.status==="valid"?n.value:this._def.catchValue({get error(){return new W(s.common.issues)},input:s.data})}}removeCatch(){return this._def.innerType}};Ge.create=(t,e)=>new Ge({innerType:t,typeName:y.ZodCatch,catchValue:typeof e.catch=="function"?e.catch:()=>e.catch,...S(e)});var pt=class extends w{_parse(e){if(this._getType(e)!==m.nan){let s=this._getOrReturnCtx(e);return p(s,{code:h.invalid_type,expected:m.nan,received:s.parsedType}),v}return{status:"valid",value:e.data}}};pt.create=t=>new pt({typeName:y.ZodNaN,...S(t)});var $a=Symbol("zod_brand"),At=class extends w{_parse(e){let{ctx:r}=this._processInputParams(e),s=r.data;return this._def.type._parse({data:s,path:r.path,parent:r})}unwrap(){return this._def.type}},Lt=class t extends w{_parse(e){let{status:r,ctx:s}=this._processInputParams(e);if(s.common.async)return(async()=>{let i=await this._def.in._parseAsync({data:s.data,path:s.path,parent:s});return i.status==="aborted"?v:i.status==="dirty"?(r.dirty(),ct(i.value)):this._def.out._parseAsync({data:i.value,path:s.path,parent:s})})();{let n=this._def.in._parseSync({data:s.data,path:s.path,parent:s});return n.status==="aborted"?v:n.status==="dirty"?(r.dirty(),{status:"dirty",value:n.value}):this._def.out._parseSync({data:n.value,path:s.path,parent:s})}}static create(e,r){return new t({in:e,out:r,typeName:y.ZodPipeline})}},Je=class extends w{_parse(e){let r=this._def.innerType._parse(e),s=n=>($e(n)&&(n.value=Object.freeze(n.value)),n);return $t(r)?r.then(n=>s(n)):s(r)}unwrap(){return this._def.innerType}};Je.create=(t,e)=>new Je({innerType:t,typeName:y.ZodReadonly,...S(e)});function Wn(t,e){let r=typeof t=="function"?t(e):typeof t=="string"?{message:t}:t;return typeof r=="string"?{message:r}:r}function Kn(t,e={},r){return t?xe.create().superRefine((s,n)=>{var i,o;let a=t(s);if(a instanceof Promise)return a.then(l=>{var d,u;if(!l){let f=Wn(e,s),x=(u=(d=f.fatal)!==null&&d!==void 0?d:r)!==null&&u!==void 0?u:!0;n.addIssue({code:"custom",...f,fatal:x})}});if(!a){let l=Wn(e,s),d=(o=(i=l.fatal)!==null&&i!==void 0?i:r)!==null&&o!==void 0?o:!0;n.addIssue({code:"custom",...l,fatal:d})}}):xe.create()}var Aa={object:U.lazycreate},y;(function(t){t.ZodString="ZodString",t.ZodNumber="ZodNumber",t.ZodNaN="ZodNaN",t.ZodBigInt="ZodBigInt",t.ZodBoolean="ZodBoolean",t.ZodDate="ZodDate",t.ZodSymbol="ZodSymbol",t.ZodUndefined="ZodUndefined",t.ZodNull="ZodNull",t.ZodAny="ZodAny",t.ZodUnknown="ZodUnknown",t.ZodNever="ZodNever",t.ZodVoid="ZodVoid",t.ZodArray="ZodArray",t.ZodObject="ZodObject",t.ZodUnion="ZodUnion",t.ZodDiscriminatedUnion="ZodDiscriminatedUnion",t.ZodIntersection="ZodIntersection",t.ZodTuple="ZodTuple",t.ZodRecord="ZodRecord",t.ZodMap="ZodMap",t.ZodSet="ZodSet",t.ZodFunction="ZodFunction",t.ZodLazy="ZodLazy",t.ZodLiteral="ZodLiteral",t.ZodEnum="ZodEnum",t.ZodEffects="ZodEffects",t.ZodNativeEnum="ZodNativeEnum",t.ZodOptional="ZodOptional",t.ZodNullable="ZodNullable",t.ZodDefault="ZodDefault",t.ZodCatch="ZodCatch",t.ZodPromise="ZodPromise",t.ZodBranded="ZodBranded",t.ZodPipeline="ZodPipeline",t.ZodReadonly="ZodReadonly"})(y||(y={}));var La=(t,e={message:`Input not instance of ${t.name}`})=>Kn(r=>r instanceof t,e),Xn=ve.create,Qn=Ae.create,Ma=pt.create,Da=Le.create,ei=Me.create,qa=De.create,Ba=dt.create,Ua=qe.create,Va=Be.create,Wa=xe.create,Fa=he.create,Za=ee.create,za=ut.create,Ha=pe.create,Ga=U.create,Ja=U.strictCreate,Ya=Ue.create,Ka=or.create,Xa=Ve.create,Qa=ne.create,ec=ar.create,tc=ft.create,rc=ht.create,sc=cr.create,nc=We.create,ic=Fe.create,oc=Ze.create,ac=ze.create,cc=be.create,Fn=F.create,lc=J.create,dc=ie.create,uc=F.createWithPreprocess,fc=Lt.create,hc=()=>Xn().optional(),pc=()=>Qn().optional(),mc=()=>ei().optional(),gc={string:t=>ve.create({...t,coerce:!0}),number:t=>Ae.create({...t,coerce:!0}),boolean:t=>Me.create({...t,coerce:!0}),bigint:t=>Le.create({...t,coerce:!0}),date:t=>De.create({...t,coerce:!0})},_c=v,c=Object.freeze({__proto__:null,defaultErrorMap:lt,setErrorMap:ua,getErrorMap:sr,makeIssue:nr,EMPTY_PATH:fa,addIssueToContext:p,ParseStatus:D,INVALID:v,DIRTY:ct,OK:B,isAborted:rs,isDirty:ss,isValid:$e,isAsync:$t,get util(){return k},get objectUtil(){return ts},ZodParsedType:m,getParsedType:fe,ZodType:w,datetimeRegex:Jn,ZodString:ve,ZodNumber:Ae,ZodBigInt:Le,ZodBoolean:Me,ZodDate:De,ZodSymbol:dt,ZodUndefined:qe,ZodNull:Be,ZodAny:xe,ZodUnknown:he,ZodNever:ee,ZodVoid:ut,ZodArray:pe,ZodObject:U,ZodUnion:Ue,ZodDiscriminatedUnion:or,ZodIntersection:Ve,ZodTuple:ne,ZodRecord:ar,ZodMap:ft,ZodSet:ht,ZodFunction:cr,ZodLazy:We,ZodLiteral:Fe,ZodEnum:Ze,ZodNativeEnum:ze,ZodPromise:be,ZodEffects:F,ZodTransformer:F,ZodOptional:J,ZodNullable:ie,ZodDefault:He,ZodCatch:Ge,ZodNaN:pt,BRAND:$a,ZodBranded:At,ZodPipeline:Lt,ZodReadonly:Je,custom:Kn,Schema:w,ZodSchema:w,late:Aa,get ZodFirstPartyTypeKind(){return y},coerce:gc,any:Wa,array:Ha,bigint:Da,boolean:ei,date:qa,discriminatedUnion:Ka,effect:Fn,enum:oc,function:sc,instanceof:La,intersection:Xa,lazy:nc,literal:ic,map:tc,nan:Ma,nativeEnum:ac,never:Za,null:Va,nullable:dc,number:Qn,object:Ga,oboolean:mc,onumber:pc,optional:lc,ostring:hc,pipeline:fc,preprocess:uc,promise:cc,record:ec,set:rc,strictObject:Ja,string:Xn,symbol:Ba,transformer:Fn,tuple:Qa,undefined:Ua,union:Ya,unknown:Fa,void:za,NEVER:_c,ZodIssueCode:h,quotelessJson:da,ZodError:W});var is="2024-11-05",ti=[is,"2024-10-07"],lr="2.0",ri=c.union([c.string(),c.number().int()]),si=c.string(),te=c.object({_meta:c.optional(c.object({progressToken:c.optional(ri)}).passthrough())}).passthrough(),Z=c.object({method:c.string(),params:c.optional(te)}),Mt=c.object({_meta:c.optional(c.object({}).passthrough())}).passthrough(),oe=c.object({method:c.string(),params:c.optional(Mt)}),re=c.object({_meta:c.optional(c.object({}).passthrough())}).passthrough(),dr=c.union([c.string(),c.number().int()]),yc=c.object({jsonrpc:c.literal(lr),id:dr}).merge(Z).strict(),vc=c.object({jsonrpc:c.literal(lr)}).merge(oe).strict(),xc=c.object({jsonrpc:c.literal(lr),id:dr,result:re}).strict(),Se;(function(t){t[t.ConnectionClosed=-32e3]="ConnectionClosed",t[t.RequestTimeout=-32001]="RequestTimeout",t[t.ParseError=-32700]="ParseError",t[t.InvalidRequest=-32600]="InvalidRequest",t[t.MethodNotFound=-32601]="MethodNotFound",t[t.InvalidParams=-32602]="InvalidParams",t[t.InternalError=-32603]="InternalError"})(Se||(Se={}));var bc=c.object({jsonrpc:c.literal(lr),id:dr,error:c.object({code:c.number().int(),message:c.string(),data:c.optional(c.unknown())})}).strict(),ni=c.union([yc,vc,xc,bc]),ur=re.strict(),fr=oe.extend({method:c.literal("notifications/cancelled"),params:Mt.extend({requestId:dr,reason:c.string().optional()})}),ii=c.object({name:c.string(),version:c.string()}).passthrough(),Sc=c.object({experimental:c.optional(c.object({}).passthrough()),sampling:c.optional(c.object({}).passthrough()),roots:c.optional(c.object({listChanged:c.optional(c.boolean())}).passthrough())}).passthrough(),os=Z.extend({method:c.literal("initialize"),params:te.extend({protocolVersion:c.string(),capabilities:Sc,clientInfo:ii})}),wc=c.object({experimental:c.optional(c.object({}).passthrough()),logging:c.optional(c.object({}).passthrough()),prompts:c.optional(c.object({listChanged:c.optional(c.boolean())}).passthrough()),resources:c.optional(c.object({subscribe:c.optional(c.boolean()),listChanged:c.optional(c.boolean())}).passthrough()),tools:c.optional(c.object({listChanged:c.optional(c.boolean())}).passthrough())}).passthrough(),Ec=re.extend({protocolVersion:c.string(),capabilities:wc,serverInfo:ii,instructions:c.optional(c.string())}),as=oe.extend({method:c.literal("notifications/initialized")}),hr=Z.extend({method:c.literal("ping")}),kc=c.object({progress:c.number(),total:c.optional(c.number())}).passthrough(),pr=oe.extend({method:c.literal("notifications/progress"),params:Mt.merge(kc).extend({progressToken:ri})}),mr=Z.extend({params:te.extend({cursor:c.optional(si)}).optional()}),gr=re.extend({nextCursor:c.optional(si)}),oi=c.object({uri:c.string(),mimeType:c.optional(c.string())}).passthrough(),ai=oi.extend({text:c.string()}),ci=oi.extend({blob:c.string().base64()}),Tc=c.object({uri:c.string(),name:c.string(),description:c.optional(c.string()),mimeType:c.optional(c.string())}).passthrough(),Rc=c.object({uriTemplate:c.string(),name:c.string(),description:c.optional(c.string()),mimeType:c.optional(c.string())}).passthrough(),cs=mr.extend({method:c.literal("resources/list")}),Nc=gr.extend({resources:c.array(Tc)}),ls=mr.extend({method:c.literal("resources/templates/list")}),Oc=gr.extend({resourceTemplates:c.array(Rc)}),ds=Z.extend({method:c.literal("resources/read"),params:te.extend({uri:c.string()})}),Cc=re.extend({contents:c.array(c.union([ai,ci]))}),Ic=oe.extend({method:c.literal("notifications/resources/list_changed")}),Pc=Z.extend({method:c.literal("resources/subscribe"),params:te.extend({uri:c.string()})}),jc=Z.extend({method:c.literal("resources/unsubscribe"),params:te.extend({uri:c.string()})}),$c=oe.extend({method:c.literal("notifications/resources/updated"),params:Mt.extend({uri:c.string()})}),Ac=c.object({name:c.string(),description:c.optional(c.string()),required:c.optional(c.boolean())}).passthrough(),Lc=c.object({name:c.string(),description:c.optional(c.string()),arguments:c.optional(c.array(Ac))}).passthrough(),us=mr.extend({method:c.literal("prompts/list")}),Mc=gr.extend({prompts:c.array(Lc)}),fs=Z.extend({method:c.literal("prompts/get"),params:te.extend({name:c.string(),arguments:c.optional(c.record(c.string()))})}),_r=c.object({type:c.literal("text"),text:c.string()}).passthrough(),yr=c.object({type:c.literal("image"),data:c.string().base64(),mimeType:c.string()}).passthrough(),li=c.object({type:c.literal("resource"),resource:c.union([ai,ci])}).passthrough(),Dc=c.object({role:c.enum(["user","assistant"]),content:c.union([_r,yr,li])}).passthrough(),qc=re.extend({description:c.optional(c.string()),messages:c.array(Dc)}),Bc=oe.extend({method:c.literal("notifications/prompts/list_changed")}),Uc=c.object({name:c.string(),description:c.optional(c.string()),inputSchema:c.object({type:c.literal("object"),properties:c.optional(c.object({}).passthrough())}).passthrough()}).passthrough(),hs=mr.extend({method:c.literal("tools/list")}),Vc=gr.extend({tools:c.array(Uc)}),di=re.extend({content:c.array(c.union([_r,yr,li])),isError:c.boolean().default(!1).optional()}),pd=di.or(re.extend({toolResult:c.unknown()})),ps=Z.extend({method:c.literal("tools/call"),params:te.extend({name:c.string(),arguments:c.optional(c.record(c.unknown()))})}),Wc=oe.extend({method:c.literal("notifications/tools/list_changed")}),ui=c.enum(["debug","info","notice","warning","error","critical","alert","emergency"]),Fc=Z.extend({method:c.literal("logging/setLevel"),params:te.extend({level:ui})}),Zc=oe.extend({method:c.literal("notifications/message"),params:Mt.extend({level:ui,logger:c.optional(c.string()),data:c.unknown()})}),zc=c.object({name:c.string().optional()}).passthrough(),Hc=c.object({hints:c.optional(c.array(zc)),costPriority:c.optional(c.number().min(0).max(1)),speedPriority:c.optional(c.number().min(0).max(1)),intelligencePriority:c.optional(c.number().min(0).max(1))}).passthrough(),Gc=c.object({role:c.enum(["user","assistant"]),content:c.union([_r,yr])}).passthrough(),ms=Z.extend({method:c.literal("sampling/createMessage"),params:te.extend({messages:c.array(Gc),systemPrompt:c.optional(c.string()),includeContext:c.optional(c.enum(["none","thisServer","allServers"])),temperature:c.optional(c.number()),maxTokens:c.number().int(),stopSequences:c.optional(c.array(c.string())),metadata:c.optional(c.object({}).passthrough()),modelPreferences:c.optional(Hc)})}),gs=re.extend({model:c.string(),stopReason:c.optional(c.enum(["endTurn","stopSequence","maxTokens"]).or(c.string())),role:c.enum(["user","assistant"]),content:c.discriminatedUnion("type",[_r,yr])}),Jc=c.object({type:c.literal("ref/resource"),uri:c.string()}).passthrough(),Yc=c.object({type:c.literal("ref/prompt"),name:c.string()}).passthrough(),Kc=Z.extend({method:c.literal("completion/complete"),params:te.extend({ref:c.union([Yc,Jc]),argument:c.object({name:c.string(),value:c.string()}).passthrough()})}),Xc=re.extend({completion:c.object({values:c.array(c.string()).max(100),total:c.optional(c.number().int()),hasMore:c.optional(c.boolean())}).passthrough()}),Qc=c.object({uri:c.string().startsWith("file://"),name:c.optional(c.string())}).passthrough(),el=Z.extend({method:c.literal("roots/list")}),_s=re.extend({roots:c.array(Qc)}),tl=oe.extend({method:c.literal("notifications/roots/list_changed")}),md=c.union([hr,os,Kc,Fc,fs,us,cs,ls,ds,Pc,jc,ps,hs]),gd=c.union([fr,pr,as,tl]),_d=c.union([ur,gs,_s]),yd=c.union([hr,ms,el]),vd=c.union([fr,pr,Zc,$c,Ic,Wc,Bc]),xd=c.union([ur,Ec,Xc,qc,Mc,Nc,Oc,Cc,di,Vc]),Ye=class extends Error{constructor(e,r,s){super(`MCP error ${e}: ${r}`),this.code=e,this.data=s,this.name="McpError"}};var rl=6e4,vr=class{constructor(e){this._options=e,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this.setNotificationHandler(fr,r=>{let s=this._requestHandlerAbortControllers.get(r.params.requestId);s?.abort(r.params.reason)}),this.setNotificationHandler(pr,r=>{this._onprogress(r)}),this.setRequestHandler(hr,r=>({}))}_setupTimeout(e,r,s,n){this._timeoutInfo.set(e,{timeoutId:setTimeout(n,r),startTime:Date.now(),timeout:r,maxTotalTimeout:s,onTimeout:n})}_resetTimeout(e){let r=this._timeoutInfo.get(e);if(!r)return!1;let s=Date.now()-r.startTime;if(r.maxTotalTimeout&&s>=r.maxTotalTimeout)throw this._timeoutInfo.delete(e),new Ye(Se.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:r.maxTotalTimeout,totalElapsed:s});return clearTimeout(r.timeoutId),r.timeoutId=setTimeout(r.onTimeout,r.timeout),!0}_cleanupTimeout(e){let r=this._timeoutInfo.get(e);r&&(clearTimeout(r.timeoutId),this._timeoutInfo.delete(e))}async connect(e){this._transport=e,this._transport.onclose=()=>{this._onclose()},this._transport.onerror=r=>{this._onerror(r)},this._transport.onmessage=r=>{"method"in r?"id"in r?this._onrequest(r):this._onnotification(r):this._onresponse(r)},await this._transport.start()}_onclose(){var e;let r=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._transport=void 0,(e=this.onclose)===null||e===void 0||e.call(this);let s=new Ye(Se.ConnectionClosed,"Connection closed");for(let n of r.values())n(s)}_onerror(e){var r;(r=this.onerror)===null||r===void 0||r.call(this,e)}_onnotification(e){var r;let s=(r=this._notificationHandlers.get(e.method))!==null&&r!==void 0?r:this.fallbackNotificationHandler;s!==void 0&&Promise.resolve().then(()=>s(e)).catch(n=>this._onerror(new Error(`Uncaught error in notification handler: ${n}`)))}_onrequest(e){var r,s;let n=(r=this._requestHandlers.get(e.method))!==null&&r!==void 0?r:this.fallbackRequestHandler;if(n===void 0){(s=this._transport)===null||s===void 0||s.send({jsonrpc:"2.0",id:e.id,error:{code:Se.MethodNotFound,message:"Method not found"}}).catch(o=>this._onerror(new Error(`Failed to send an error response: ${o}`)));return}let i=new AbortController;this._requestHandlerAbortControllers.set(e.id,i),Promise.resolve().then(()=>n(e,{signal:i.signal})).then(o=>{var a;if(!i.signal.aborted)return(a=this._transport)===null||a===void 0?void 0:a.send({result:o,jsonrpc:"2.0",id:e.id})},o=>{var a,l;if(!i.signal.aborted)return(a=this._transport)===null||a===void 0?void 0:a.send({jsonrpc:"2.0",id:e.id,error:{code:Number.isSafeInteger(o.code)?o.code:Se.InternalError,message:(l=o.message)!==null&&l!==void 0?l:"Internal error"}})}).catch(o=>this._onerror(new Error(`Failed to send response: ${o}`))).finally(()=>{this._requestHandlerAbortControllers.delete(e.id)})}_onprogress(e){let{progressToken:r,...s}=e.params,n=Number(r),i=this._progressHandlers.get(n);if(!i){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(e)}`));return}let o=this._responseHandlers.get(n);if(this._timeoutInfo.has(n)&&o)try{this._resetTimeout(n)}catch(a){o(a);return}i(s)}_onresponse(e){let r=Number(e.id),s=this._responseHandlers.get(r);if(s===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(e)}`));return}if(this._responseHandlers.delete(r),this._progressHandlers.delete(r),this._cleanupTimeout(r),"result"in e)s(e);else{let n=new Ye(e.error.code,e.error.message,e.error.data);s(n)}}get transport(){return this._transport}async close(){var e;await((e=this._transport)===null||e===void 0?void 0:e.close())}request(e,r,s){return new Promise((n,i)=>{var o,a,l,d;if(!this._transport){i(new Error("Not connected"));return}((o=this._options)===null||o===void 0?void 0:o.enforceStrictCapabilities)===!0&&this.assertCapabilityForMethod(e.method),(a=s?.signal)===null||a===void 0||a.throwIfAborted();let u=this._requestMessageId++,f={...e,jsonrpc:"2.0",id:u};s?.onprogress&&(this._progressHandlers.set(u,s.onprogress),f.params={...e.params,_meta:{progressToken:u}});let x=_=>{var R;this._responseHandlers.delete(u),this._progressHandlers.delete(u),this._cleanupTimeout(u),(R=this._transport)===null||R===void 0||R.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:u,reason:String(_)}}).catch(A=>this._onerror(new Error(`Failed to send cancellation: ${A}`))),i(_)};this._responseHandlers.set(u,_=>{var R;if(!(!((R=s?.signal)===null||R===void 0)&&R.aborted)){if(_ instanceof Error)return i(_);try{let A=r.parse(_.result);n(A)}catch(A){i(A)}}}),(l=s?.signal)===null||l===void 0||l.addEventListener("abort",()=>{var _;x((_=s?.signal)===null||_===void 0?void 0:_.reason)});let E=(d=s?.timeout)!==null&&d!==void 0?d:rl,T=()=>x(new Ye(Se.RequestTimeout,"Request timed out",{timeout:E}));this._setupTimeout(u,E,s?.maxTotalTimeout,T),this._transport.send(f).catch(_=>{this._cleanupTimeout(u),i(_)})})}async notification(e){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(e.method);let r={...e,jsonrpc:"2.0"};await this._transport.send(r)}setRequestHandler(e,r){let s=e.shape.method.value;this.assertRequestHandlerCapability(s),this._requestHandlers.set(s,(n,i)=>Promise.resolve(r(e.parse(n),i)))}removeRequestHandler(e){this._requestHandlers.delete(e)}assertCanSetRequestHandler(e){if(this._requestHandlers.has(e))throw new Error(`A request handler for ${e} already exists, which would be overridden`)}setNotificationHandler(e,r){this._notificationHandlers.set(e.shape.method.value,s=>Promise.resolve(r(e.parse(s))))}removeNotificationHandler(e){this._notificationHandlers.delete(e)}};function fi(t,e){return Object.entries(e).reduce((r,[s,n])=>(n&&typeof n=="object"?r[s]=r[s]?{...r[s],...n}:n:r[s]=n,r),{...t})}var xr=class extends vr{constructor(e,r){var s;super(r),this._serverInfo=e,this._capabilities=(s=r?.capabilities)!==null&&s!==void 0?s:{},this._instructions=r?.instructions,this.setRequestHandler(os,n=>this._oninitialize(n)),this.setNotificationHandler(as,()=>{var n;return(n=this.oninitialized)===null||n===void 0?void 0:n.call(this)})}registerCapabilities(e){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=fi(this._capabilities,e)}assertCapabilityForMethod(e){var r,s;switch(e){case"sampling/createMessage":if(!(!((r=this._clientCapabilities)===null||r===void 0)&&r.sampling))throw new Error(`Client does not support sampling (required for ${e})`);break;case"roots/list":if(!(!((s=this._clientCapabilities)===null||s===void 0)&&s.roots))throw new Error(`Client does not support listing roots (required for ${e})`);break;case"ping":break}}assertNotificationCapability(e){switch(e){case"notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${e})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${e})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${e})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${e})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(e){switch(e){case"sampling/createMessage":if(!this._capabilities.sampling)throw new Error(`Server does not support sampling (required for ${e})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${e})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${e})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${e})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${e})`);break;case"ping":case"initialize":break}}async _oninitialize(e){let r=e.params.protocolVersion;return this._clientCapabilities=e.params.capabilities,this._clientVersion=e.params.clientInfo,{protocolVersion:ti.includes(r)?r:is,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},ur)}async createMessage(e,r){return this.request({method:"sampling/createMessage",params:e},gs,r)}async listRoots(e,r){return this.request({method:"roots/list",params:e},_s,r)}async sendLoggingMessage(e){return this.notification({method:"notifications/message",params:e})}async sendResourceUpdated(e){return this.notification({method:"notifications/resources/updated",params:e})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}};var ys=M(require("node:process"),1);var br=class{append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}readMessage(){if(!this._buffer)return null;let e=this._buffer.indexOf(` +`);if(e===-1)return null;let r=this._buffer.toString("utf8",0,e);return this._buffer=this._buffer.subarray(e+1),sl(r)}clear(){this._buffer=void 0}};function sl(t){return ni.parse(JSON.parse(t))}function hi(t){return JSON.stringify(t)+` +`}var Sr=class{constructor(e=ys.default.stdin,r=ys.default.stdout){this._stdin=e,this._stdout=r,this._readBuffer=new br,this._started=!1,this._ondata=s=>{this._readBuffer.append(s),this.processReadBuffer()},this._onerror=s=>{var n;(n=this.onerror)===null||n===void 0||n.call(this,s)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(var e,r;;)try{let s=this._readBuffer.readMessage();if(s===null)break;(e=this.onmessage)===null||e===void 0||e.call(this,s)}catch(s){(r=this.onerror)===null||r===void 0||r.call(this,s)}}async close(){var e;this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),(e=this.onclose)===null||e===void 0||e.call(this)}send(e){return new Promise(r=>{let s=hi(e);this._stdout.write(s)?r():this._stdout.once("drain",r)})}};var gt=M(require("fs/promises"),1),Ti=M(require("crypto"),1);var Ee=M(require("path"),1),xi=M(yi(),1),bi=M(require("os"),1),ge=M(require("fs/promises"),1);var P=M(require("node:path"),1),Ss=M(require("node:os"),1),Er=M(require("node:process"),1),we=Ss.default.homedir(),ws=Ss.default.tmpdir(),{env:mt}=Er.default,vl=t=>{let e=P.default.join(we,"Library");return{data:P.default.join(e,"Application Support",t),config:P.default.join(e,"Preferences",t),cache:P.default.join(e,"Caches",t),log:P.default.join(e,"Logs",t),temp:P.default.join(ws,t)}},xl=t=>{let e=mt.APPDATA||P.default.join(we,"AppData","Roaming"),r=mt.LOCALAPPDATA||P.default.join(we,"AppData","Local");return{data:P.default.join(r,t,"Data"),config:P.default.join(e,t,"Config"),cache:P.default.join(r,t,"Cache"),log:P.default.join(r,t,"Log"),temp:P.default.join(ws,t)}},bl=t=>{let e=P.default.basename(we);return{data:P.default.join(mt.XDG_DATA_HOME||P.default.join(we,".local","share"),t),config:P.default.join(mt.XDG_CONFIG_HOME||P.default.join(we,".config"),t),cache:P.default.join(mt.XDG_CACHE_HOME||P.default.join(we,".cache"),t),log:P.default.join(mt.XDG_STATE_HOME||P.default.join(we,".local","state"),t),temp:P.default.join(ws,e,t)}};function kr(t,{suffix:e="nodejs"}={}){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);return e&&(t+=`-${e}`),Er.default.platform==="darwin"?vl(t):Er.default.platform==="win32"?xl(t):bl(t)}var Es=bi.homedir(),Dt=Ee.join(Es,".webmcp"),Si=async()=>{try{await ge.mkdir(Dt,{recursive:!0})}catch(t){console.error(`Error creating config directory at ${Dt}:`,t)}},qt=Ee.join(Dt,".webmcp-server.pid"),Bt=Ee.join(Dt,".env"),ks=Ee.join(Dt,".webmcp-tokens.json");xi.config({path:Bt});var wi=process.env.WEBMCP_SERVER_TOKEN||"",ke="localhost",L={};function Ei(t){Object.entries(t).forEach(([e,r])=>{L[e]=r})}function Ut(t){return`/${t.replace(/[.:]/g,"_")}`}async function vi(t){try{return await ge.access(t),!0}catch{return!1}}async function Ts(t){let e=Ee.dirname(t);await vi(e)||await ge.mkdir(e,{recursive:!0});let r={webmcp:{command:"npx",args:["-y","@jason.today/webmcp@latest","--mcp"]}},s={mcpServers:{}};if(await vi(t)){let n=await ge.readFile(t);try{s=JSON.parse(n)}catch(i){throw new Error(`Failed to update MCP client configuration: ${i}`)}}s.mcpServers={...s.mcpServers,...r},await ge.writeFile(t,JSON.stringify(s,null,2))}var Rs={claude:[kr("Claude",{suffix:""}).data,"claude_desktop_config.json"],cline:[kr("Code",{suffix:""}).data,"User","globalStorage","saoudrizwan.claude-dev","settings","cline_mcp_settings.json"],cursor:[Es,".cursor","mcp.json"],windsurf:[Es,".codeium","windsurf","mcp_config.json"]};async function ki(t){let e=Rs[t];e||(console.error("Unsupported client - treating it like a path..."),e=t),await Ts(Ee.join(...e))}function Tr(){return Ti.randomBytes(16).toString("hex")}var Ke={};function Ns(t){return Ke[t]}function Os(t,e){Ke[t]=e}function Cs(t){delete Ke[t]}function Ri(t){Ke={}}async function Rr(){try{let t=await gt.readFile(ks,"utf8");return Ke=JSON.parse(t||"{}"),!0}catch(t){return t.code==="ENOENT"?(Ke={},!0):(console.error("Error loading authorized tokens:",t),!1)}}async function _t(){try{let t=JSON.stringify(Ke,null,2);return await gt.writeFile(ks,t,"utf8"),!0}catch(t){return console.error("Error saving authorized tokens:",t),!1}}async function Ni(t){try{let e="";try{e=await gt.readFile(Bt,"utf8"),e.includes("WEBMCP_SERVER_TOKEN=")?e=e.replace(/WEBMCP_SERVER_TOKEN=.*(\r?\n|$)/g,`WEBMCP_SERVER_TOKEN=${t}$1`):e+=` +WEBMCP_SERVER_TOKEN=${t} +`}catch{e=`WEBMCP_SERVER_TOKEN=${t} +`}return await gt.writeFile(Bt,e,"utf8"),console.error(`Server token saved to ${Bt}`),!0}catch(e){return console.error("Error saving server token to .env file:",e),!1}}async function Nr(){let t=Tr(),e=`${ke}:${L.port}`,s={server:`ws://${e}`,token:t},n=JSON.stringify(s),i=Buffer.from(n).toString("base64");return Os(Ut(e),t),await _t(),i}var K=new xr({name:"WebMCP",version:"0.1.12"},{capabilities:{tools:{listChanged:!0},prompts:{listChanged:!0},resources:{listChanged:!0,subscribe:!0},sampling:{}}}),O=null,Is="/mcp",b=new Map,Te=1;async function Sl(t){try{let e=JSON.parse(t);if(console.error(`Received message: ${e.type}`),e.type==="toolResponse"){let{id:r,result:s,error:n}=e;if(b.has(r)){let{resolve:i,reject:o}=b.get(r);b.delete(r),n?o(new Error(n)):i(s)}else console.error(`No pending request found for ID: ${r}`)}else if(e.type==="promptResponse"){let{id:r,result:s,error:n}=e;if(b.has(r)){let{resolve:i,reject:o}=b.get(r);b.delete(r),n?o(new Error(n)):i(s)}else console.error(`No pending request found for ID: ${r}`)}else if(e.type==="resourceResponse"){let{id:r,result:s,error:n}=e;if(b.has(r)){let{resolve:i,reject:o}=b.get(r);b.delete(r),n?o(new Error(n)):i(s)}else console.error(`No pending request found for ID: ${r}`)}else if(e.type==="samplingResponse"){let{id:r,result:s,error:n}=e;if(b.has(r)){let{resolve:i,reject:o}=b.get(r);b.delete(r),n?o(new Error(n)):i(s)}else console.error(`No pending request found for ID: ${r}`)}else if(e.type==="listToolsResponse"){let{id:r,tools:s,error:n}=e;if(b.has(r)){let{resolve:i,reject:o}=b.get(r);b.delete(r),n?o(new Error(n)):i(s)}else console.error(`No pending request found for ID: ${r}`)}else if(e.type==="listPromptsResponse"){let{id:r,prompts:s,error:n}=e;if(b.has(r)){let{resolve:i,reject:o}=b.get(r);b.delete(r),n?o(new Error(n)):i(s)}else console.error(`No pending request found for ID: ${r}`)}else if(e.type==="listResourcesResponse"){let{id:r,resources:s,resourceTemplates:n,error:i}=e;if(b.has(r)){let{resolve:o,reject:a}=b.get(r);b.delete(r),i?a(new Error(i)):o({resources:s,resourceTemplates:n})}else console.error(`No pending request found for ID: ${r}`)}else e.type==="toolRegistered"?await K.sendToolListChanged():e.type==="resourceRegistered"?await K.sendResourceListChanged():e.type==="promptRegistered"?await K.sendPromptListChanged():e.type==="welcome"?console.error(`Connected to path: ${e.channel}`):e.type==="pong"?console.error(`Received pong with timestamp: ${e.timestamp}`):e.type==="error"&&console.error(`Received error: ${e.message}`)}catch(e){console.error("Error processing WebSocket message:",e)}}function Oi(t){let e=`ws://localhost:${L.port}${Is}?token=${t}`;console.error(`Connecting to WebSocket server at ${Is} with authentication...`),O=new Q(e),O.on("open",()=>{console.error(`Connected to WebSocket server on path: ${Is}`)}),O.on("message",r=>{Sl(r)}),O.on("close",(r,s)=>{console.error(`WebSocket connection closed: ${r} ${s}`),O=null,setTimeout(Oi,5e3)}),O.on("error",r=>{console.error("WebSocket connection error:",r)})}function Re(t){if(!O||O.readyState!==Q.OPEN)return console.error("Cannot send message: WebSocket not connected"),Promise.reject(new Error("WebSocket not connected"));try{return O.send(JSON.stringify(t)),Promise.resolve()}catch(e){return console.error("Error sending message:",e),Promise.reject(e)}}K.setRequestHandler(ps,async t=>{if(t.params.name==="_webmcp_get-token")return{content:[{type:"text",text:`Paste this into the token input on the WebMCP website +${await Nr()}`}]};if(t.params.name==="_webmcp_define-mcp-tool")return{content:[{type:"text",text:"Instruct the user to view the result from the tool call. Do not say anything else."}]};if(!O||O.readyState!==Q.OPEN)return{content:[{type:"text",text:"Not connected to WebSocket server"}],isError:!0};let e=(Te++).toString(),r=new Promise((s,n)=>{b.set(e,{resolve:s,reject:n}),setTimeout(()=>{b.has(e)&&(b.delete(e),n(new Error(`Tool call timed out: ${t.params.name}`)))},3e4)});try{return await Re({id:e,type:"callTool",tool:t.params.name,arguments:t.params.arguments}),await r}catch(s){return{content:[{type:"text",text:`Error: ${s.message}`}],isError:!0}}});K.setRequestHandler(hs,async()=>{let t=[{name:"_webmcp_get-token",description:"Retrieve a token to connect to a website for WebMCP. A user might say 'register a token' or 'add a webmcp'",inputSchema:{type:"object",properties:{}}},{name:"_webmcp_define-mcp-tool",description:"Used to define an 'mcp tool'. Only use this if the user specifically asks for an mcp tool. A webmcp token is not required for this.",inputSchema:{type:"object",description:"The schema which describes the tool.",properties:{name:{type:"string",description:"The name of the tool"},description:{type:"string",description:"Provides a clear and concise description of the tool and what it is used for."},inputSchema:{type:"object",description:"The inputSchema required or optional for the tool.",properties:{type:{type:"string",enum:["object","array","string","number","boolean","enum"],description:"The type of the parameter being defined."},properties:{type:"object",description:"The properties of the parameter if it's an object type.",additionalProperties:{type:"object",properties:{type:{type:"string",description:"The data type of the property.",enum:["object","array","string","number","boolean","enum"]},description:{type:"string",description:"A brief description of the property."},enum:{type:"array",description:"A list of allowed values for the property.",items:{type:"string"}}},required:["type","description"]}},required:{type:"array",items:{type:"string"}}},required:["type","description","properties"]}},required:["name","description","inputSchema"]}}];if(!O||O.readyState!==Q.OPEN)return{tools:t};let e=(Te++).toString(),r=new Promise((s,n)=>{b.set(e,{resolve:s,reject:n}),setTimeout(()=>{b.has(e)&&(b.delete(e),n(new Error("List tools request timed out")))},1e4)});try{return await Re({id:e,type:"listTools"}),{tools:[...await r,...t]}}catch(s){return console.error("Error listing tools:",s),{tools:[]}}});K.setRequestHandler(us,async()=>{let t=[];if(!O||O.readyState!==Q.OPEN)return{prompts:t};let e=(Te++).toString(),r=new Promise((s,n)=>{b.set(e,{resolve:s,reject:n}),setTimeout(()=>{b.has(e)&&(b.delete(e),n(new Error("List prompts request timed out")))},1e4)});try{return await Re({id:e,type:"listPrompts"}),{prompts:[...await r,...t]}}catch(s){return console.error("Error listing prompts:",s),{prompts:[]}}});K.setRequestHandler(fs,async t=>{if(!O||O.readyState!==Q.OPEN)throw new Error("Not connected to WebSocket server");let e=(Te++).toString(),r=new Promise((s,n)=>{b.set(e,{resolve:s,reject:n}),setTimeout(()=>{b.has(e)&&(b.delete(e),n(new Error(`Get prompt request timed out: ${t.params.name}`)))},3e4)});try{return await Re({id:e,type:"getPrompt",name:t.params.name,arguments:t.params.arguments}),await r}catch(s){throw console.error("Error getting prompt:",s),s}});K.setRequestHandler(cs,async()=>{if(!O||O.readyState!==Q.OPEN)return{resources:[]};let t=(Te++).toString(),e=new Promise((r,s)=>{b.set(t,{resolve:r,reject:s}),setTimeout(()=>{b.has(t)&&(b.delete(t),s(new Error("List resources request timed out")))},1e4)});try{await Re({id:t,type:"listResources"});let{resources:r}=await e;return{resources:r}}catch(r){return console.error("Error listing resources:",r),{resources:[]}}});K.setRequestHandler(ls,async()=>{if(!O||O.readyState!==Q.OPEN)return{resourceTemplates:[]};let t=(Te++).toString(),e=new Promise((r,s)=>{b.set(t,{resolve:r,reject:s}),setTimeout(()=>{b.has(t)&&(b.delete(t),s(new Error("List resource templates request timed out")))},1e4)});try{await Re({id:t,type:"listResources"});let{resourceTemplates:r}=await e;return{resourceTemplates:r}}catch(r){return console.error("Error listing resource templates:",r),{resourceTemplates:[]}}});K.setRequestHandler(ds,async t=>{if(!O||O.readyState!==Q.OPEN)throw new Error("Not connected to WebSocket server");let e=(Te++).toString(),r=new Promise((s,n)=>{b.set(e,{resolve:s,reject:n}),setTimeout(()=>{b.has(e)&&(b.delete(e),n(new Error(`Read resource request timed out: ${t.params.uri}`)))},3e4)});try{return await Re({id:e,type:"readResource",uri:t.params.uri}),await r}catch(s){throw console.error("Error reading resource:",s),s}});K.setRequestHandler(ms,async t=>{if(!O||O.readyState!==Q.OPEN)throw new Error("Not connected to WebSocket server");let e=(Te++).toString(),r=new Promise((s,n)=>{b.set(e,{resolve:s,reject:n}),setTimeout(()=>{b.has(e)&&(b.delete(e),n(new Error("Sampling request timed out")))},12e4)});try{return await Re({id:e,type:"createSamplingMessage",messages:t.params.messages,systemPrompt:t.params.systemPrompt,includeContext:t.params.includeContext,temperature:t.params.temperature,maxTokens:t.params.maxTokens,stopSequences:t.params.stopSequences,metadata:t.params.metadata,modelPreferences:t.params.modelPreferences}),await r}catch(s){throw console.error("Error creating sampling message:",s),s}});async function Ci(t){Oi(t);let e=new Sr;await K.connect(e),console.error("MCP server running with stdio transport")}var yt=wi,Ps=(0,Ii.createServer)((t,e)=>{if(e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type"),t.method==="OPTIONS"){e.writeHead(204),e.end();return}e.writeHead(200,{"Content-Type":"text/plain"}),e.end("MCP WebSocket server is running")}),wl=new Qr.default({server:Ps,clientTracking:!0,verifyClient:El}),C={},z="/mcp",$i="/register";function vt(t,e,r,s,n=!1){t&&t.readyState===It.default.OPEN&&(n||t.send(JSON.stringify({type:r,...s}))),C[z]&&C[z].size>0&&C[z].values().forEach(i=>{if(i&&i.readyState===It.default.OPEN){let o={...s};o.name&&e&&(o.name=`${e.slice(1)}-${o.name}`),i.send(JSON.stringify({type:r,...o}))}})}var Xe={},xt={},Qe={},Or=1,N={};async function El(t,e){let r=new URL(`https://${ke}${t.req.url}`),s=r.searchParams.get("token"),n=r.pathname||"/";return n===z?s===process.env.WEBMCP_SERVER_TOKEN?e(!0):(console.error("Invalid MCP token provided"),e(!1,401,"Unauthorized - Invalid MCP token")):n===$i?e(!0):s?(await Rr(),Ns(n)===s?e(!0):(console.error(`Unauthorized connection attempt to ${n}`),e(!1,401,"Unauthorized - Invalid channel-token pair"))):(console.error("No token provided for path:",n),e(!1,401,"Unauthorized - No token provided"))}function kl(t){return C[t]?C[t].closeTimeout&&(clearTimeout(C[t].closeTimeout),delete C[t].closeTimeout,console.error(`Cancelled channel closure for ${t} as a new client connected`)):(C[t]=new Set,console.error(`Created new channel for path: ${t}`)),C[t]}wl.on("connection",(t,e)=>{let n=(0,Pi.parse)(e.url).pathname||"/";if(console.error(`Client connected from ${e.socket.remoteAddress} to path: ${n}`),n===$i){console.error(`Registration request received from ${e.socket.remoteAddress}`);let o=setTimeout(()=>{console.error("Registration timeout - closing connection"),t.close(1008,"Registration timeout")},3e4);t.once("message",async a=>{clearTimeout(o);try{let l=a.toString(),d=Buffer.from(l,"base64").toString("utf8"),u=JSON.parse(d),{host:f,token:x}=u;if(!x){console.error("Invalid registration data format - missing token"),t.send(JSON.stringify({type:"error",message:"Invalid registration data format - missing token"})),t.close(1008,"Invalid registration data");return}let E=Ut(f);if(!x||x.length<16){console.error("Invalid token provided"),t.send(JSON.stringify({type:"error",message:"Invalid token provided"})),t.close(1008,"Invalid token");return}let T=Ut(`${ke}:${L.port}`);if(await Rr(),x!==Ns(T)){console.error("Invalid token provided"),t.send(JSON.stringify({type:"error",message:"Invalid token provided"})),t.close(1008,"Invalid token");return}Cs(T);let _=Tr();Os(E,_),await _t(),t.send(JSON.stringify({type:"registerSuccess",channel:E,message:`Registration successful for ${E}`,token:_})),console.error(`Registered channel: ${E} with token: ${x}`),t.close(1e3,"Registration complete")}catch(l){console.error("Registration error:",l),t.send(JSON.stringify({type:"error",message:"Registration error"})),t.close(1011,"Registration error")}});return}kl(n).add(t),t.send(JSON.stringify({type:"welcome",channel:n,message:`Connected to path: ${n}`})),t.on("message",o=>{try{let a=JSON.parse(o);switch(console.error(`Received message: ${a.type} on ${n}`),a.type){case"ping":Tl(t,a);break;case"registerTool":Rl(t,n,a);break;case"registerPrompt":Nl(t,n,a);break;case"registerResource":Ol(t,n,a);break;case"listTools":Cl(t,n,a);break;case"listPrompts":Il(t,n,a);break;case"listResources":Pl(t,n,a);break;case"callTool":jl(t,n,a);break;case"getPrompt":$l(t,n,a);break;case"readResource":Al(t,n,a);break;case"createSamplingMessage":Bl(t,n,a);break;case"toolResponse":Ll(a);break;case"promptResponse":Ml(a);break;case"resourceResponse":Dl(a);break;case"samplingResponse":ql(a);break;default:t.send(JSON.stringify({type:"error",message:`Unknown message type: ${a.type}`}))}}catch(a){console.error("Error processing WebSocket message:",a);try{t.send(JSON.stringify({type:"error",message:"Invalid message format"}))}catch(l){console.error("Error sending error response:",l)}}}),t.on("close",async()=>{console.error(`Client disconnected from path: ${n}`);let o=C[n];o&&(o.delete(t),o.size===0&&(console.error(`Channel ${n} is empty, will close in 1 minute if no one joins`),o.closeTimeout=setTimeout(async()=>{if(C[n]&&C[n].size===0){delete C[n],console.error(`Removed empty channel for path: ${n} after 1 minute inactivity`);let a={tools:[],prompts:[],resources:[]};for(let[l,d]of Object.entries(Xe))d.channel===n&&a.tools.push(l);for(let[l,d]of Object.entries(xt))d.channel===n&&a.prompts.push(l);for(let[l,d]of Object.entries(Qe))d.channel===n&&a.resources.push(l);a.tools.forEach(l=>{delete Xe[l],console.error(`Removed tool: ${l} from path: ${n}`)}),a.prompts.forEach(l=>{delete xt[l],console.error(`Removed prompt: ${l} from path: ${n}`)}),a.resources.forEach(l=>{delete Qe[l],console.error(`Removed resource: ${l} from path: ${n}`)}),n!==z&&(Cs(n),await _t(),console.error(`Removed authorized token for channel: ${n}`)),vt(t,void 0,"toolRegistered",{},!0),vt(t,void 0,"promptRegistered",{},!0),vt(t,void 0,"resourceRegistered",{},!0)}},6e4)))}),t.on("error",o=>{console.error("WebSocket error:",o);let a=C[n];a&&a.delete(t)})});function Tl(t,e){t.send(JSON.stringify({id:e.id,type:"pong",timestamp:Date.now()}))}function Rl(t,e,r){let{name:s,description:n,inputSchema:i}=r;if(!s){t.send(JSON.stringify({type:"error",message:"Tool name is required"}));return}let o=`${e.slice(1)}-${s}`;Xe[o]={channel:e,name:s,description:n||`Tool: ${s}`,inputSchema:i,originalName:s},vt(t,e,"toolRegistered",{name:s,toolId:o}),console.error(`Tool registered: ${o}`)}function Nl(t,e,r){let{name:s,description:n,arguments:i}=r;if(!s){t.send(JSON.stringify({type:"error",message:"Prompt name is required"}));return}let o=`${e.slice(1)}-${s}`;xt[o]={channel:e,name:s,description:n||`Prompt: ${s}`,arguments:i||[],originalName:s},vt(t,e,"promptRegistered",{name:s,promptId:o}),console.error(`Prompt registered: ${o}`)}function Ol(t,e,r){let{uri:s,name:n,description:i,mimeType:o,isTemplate:a,uriTemplate:l}=r;if(!s&&!l||!n){t.send(JSON.stringify({type:"error",message:"Resource URI/template and name are required"}));return}let d=`${e.slice(1)}-${n}`;Qe[d]={channel:e,name:n,description:i||`Resource: ${n}`,uri:s,uriTemplate:l,isTemplate:!!a,mimeType:o,originalName:n},vt(t,e,"resourceRegistered",{name:n,resourceId:d}),console.error(`Resource registered: ${d}`)}function Cl(t,e,r){let{id:s}=r,n=e===z,i;n?(i=Object.entries(Xe).map(([o,a])=>({name:`${a.channel.slice(1)}-${a.originalName}`,description:a.description,inputSchema:a.inputSchema})),console.error(`Sending all ${i.length} tools to MCP client on path ${e}`)):(i=Object.entries(Xe).filter(([o,a])=>a.channel===e).map(([o,a])=>({name:a.originalName,description:a.description,inputSchema:a.inputSchema})),console.error(`Sending ${i.length} tools from path ${e}`)),t.send(JSON.stringify({id:s,type:"listToolsResponse",tools:i}))}function Il(t,e,r){let{id:s}=r,n=e===z,i;n?(i=Object.entries(xt).map(([o,a])=>({name:`${a.channel.slice(1)}-${a.originalName}`,description:a.description,arguments:a.arguments})),console.error(`Sending all ${i.length} prompts to MCP client on path ${e}`)):(i=Object.entries(xt).filter(([o,a])=>a.channel===e).map(([o,a])=>({name:a.originalName,description:a.description,arguments:a.arguments})),console.error(`Sending ${i.length} prompts from path ${e}`)),t.send(JSON.stringify({id:s,type:"listPromptsResponse",prompts:i}))}function Pl(t,e,r){let{id:s}=r,n=e===z,i=[],o=[];n?(Object.entries(Qe).forEach(([a,l])=>{let d=`${l.channel.slice(1)}-${l.originalName}`;l.isTemplate?o.push({name:d,description:l.description,uriTemplate:l.uriTemplate,mimeType:l.mimeType}):i.push({name:d,description:l.description,uri:l.uri,mimeType:l.mimeType})}),console.error(`Sending all ${i.length} resources and ${o.length} templates to MCP client on path ${e}`)):(Object.entries(Qe).filter(([a,l])=>l.channel===e).forEach(([a,l])=>{l.isTemplate?o.push({name:l.originalName,description:l.description,uriTemplate:l.uriTemplate,mimeType:l.mimeType}):i.push({name:l.originalName,description:l.description,uri:l.uri,mimeType:l.mimeType})}),console.error(`Sending ${i.length} resources and ${o.length} templates from path ${e}`)),t.send(JSON.stringify({id:s,type:"listResourcesResponse",resources:i,resourceTemplates:o}))}function jl(t,e,r){let{id:s,tool:n,arguments:i}=r,o=e===z,a,l;if(o&&n.startsWith("/"))[a,l]=n.slice(1).split("-").slice(1),a=`/${a}`;else{if(!Xe[n]){t.send(JSON.stringify({id:s,type:"toolResponse",error:`Tool not found: ${n}`}));return}let f=Xe[n];a=f.channel,l=f.originalName}if(!C[a]||C[a].size===0){t.send(JSON.stringify({id:s,type:"toolResponse",error:`No clients available in channel ${a} to handle tool: ${l}`}));return}let d=C[a].values().next().value,u=(Or++).toString();N[u]={originalId:s,requesterWs:t,timestamp:Date.now()},setTimeout(()=>{if(N[u]){let{requesterWs:f,originalId:x}=N[u];delete N[u];try{f.send(JSON.stringify({id:x,type:"toolResponse",error:`Tool call timed out: ${l}`}))}catch(E){console.error("Error sending timeout response:",E)}}},3e4),d.send(JSON.stringify({id:u,type:"callTool",tool:l,arguments:i})),console.error(`Tool call forwarded: ${l} to channel: ${a}`)}function $l(t,e,r){let{id:s,name:n,arguments:i}=r,o=e===z,a,l;if(o&&n.startsWith("/"))[a,l]=n.slice(1).split("-").slice(1),a=`/${a}`;else{let f=Object.values(xt).find(x=>x.channel===e&&x.originalName===n);if(!f){t.send(JSON.stringify({id:s,type:"promptResponse",error:`Prompt not found: ${n}`}));return}a=f.channel,l=f.originalName}if(!C[a]||C[a].size===0){t.send(JSON.stringify({id:s,type:"promptResponse",error:`No clients available in channel ${a} to handle prompt: ${l}`}));return}let d=C[a].values().next().value,u=(Or++).toString();N[u]={originalId:s,requesterWs:t,timestamp:Date.now()},setTimeout(()=>{if(N[u]){let{requesterWs:f,originalId:x}=N[u];delete N[u];try{f.send(JSON.stringify({id:x,type:"promptResponse",error:`Prompt request timed out: ${l}`}))}catch(E){console.error("Error sending timeout response:",E)}}},3e4),d.send(JSON.stringify({id:u,type:"getPrompt",name:l,arguments:i})),console.error(`Prompt request forwarded: ${l} to channel: ${a}`)}function Al(t,e,r){let{id:s,uri:n}=r,i,o,a;for(let[u,f]of Object.entries(Qe))if(!f.isTemplate&&f.uri===n){a=f,i=f.channel,o=f.originalName;break}if(!a){for(let[u,f]of Object.entries(Qe))if(f.isTemplate&&n.startsWith(f.uriTemplate.split("{")[0])){a=f,i=f.channel,o=f.originalName;break}}if(!a){t.send(JSON.stringify({id:s,type:"resourceResponse",error:`Resource not found for URI: ${n}`}));return}if(!C[i]||C[i].size===0){t.send(JSON.stringify({id:s,type:"resourceResponse",error:`No clients available in channel ${i} to handle resource: ${o}`}));return}let l=C[i].values().next().value,d=(Or++).toString();N[d]={originalId:s,requesterWs:t,timestamp:Date.now()},setTimeout(()=>{if(N[d]){let{requesterWs:u,originalId:f}=N[d];delete N[d];try{u.send(JSON.stringify({id:f,type:"resourceResponse",error:`Resource request timed out: ${n}`}))}catch(x){console.error("Error sending timeout response:",x)}}},3e4),l.send(JSON.stringify({id:d,type:"readResource",uri:n})),console.error(`Resource request forwarded: ${n} to channel: ${i}`)}function Ll(t){let{id:e,result:r,error:s}=t;if(!N[e]){console.error(`No pending request found for ID: ${e}`);return}let{requesterWs:n,originalId:i}=N[e];delete N[e];try{n.send(JSON.stringify({id:i,type:"toolResponse",result:r,error:s}))}catch(o){console.error("Error forwarding tool response:",o)}}function Ml(t){let{id:e,result:r,error:s}=t;if(!N[e]){console.error(`No pending request found for ID: ${e}`);return}let{requesterWs:n,originalId:i}=N[e];delete N[e];try{n.send(JSON.stringify({id:i,type:"promptResponse",result:r,error:s}))}catch(o){console.error("Error forwarding prompt response:",o)}}function Dl(t){let{id:e,result:r,error:s}=t;if(!N[e]){console.error(`No pending request found for ID: ${e}`);return}let{requesterWs:n,originalId:i}=N[e];delete N[e];try{n.send(JSON.stringify({id:i,type:"resourceResponse",result:r,error:s}))}catch(o){console.error("Error forwarding resource response:",o)}}function ql(t){let{id:e,result:r,error:s}=t;if(!N[e]){console.error(`No pending request found for ID: ${e}`);return}let{requesterWs:n,originalId:i}=N[e];delete N[e];try{n.send(JSON.stringify({id:i,type:"samplingResponse",result:r,error:s}))}catch(o){console.error("Error forwarding sampling response:",o)}}function Bl(t,e,r){let{id:s,messages:n,systemPrompt:i,includeContext:o,temperature:a,maxTokens:l,stopSequences:d,metadata:u,modelPreferences:f}=r;if(!(e===z)){t.send(JSON.stringify({id:s,type:"samplingResponse",error:"Sampling is only available through MCP path"}));return}let E=null,T=null;for(let[R,A]of Object.entries(C))if(R!==z&&A.size>0){E=A.values().next().value,T=R;break}if(!E){t.send(JSON.stringify({id:s,type:"samplingResponse",error:"No clients available to handle sampling request"}));return}let _=(Or++).toString();N[_]={originalId:s,requesterWs:t,timestamp:Date.now()},setTimeout(()=>{if(N[_]){let{requesterWs:R,originalId:A}=N[_];delete N[_];try{R.send(JSON.stringify({id:A,type:"samplingResponse",error:"Sampling request timed out"}))}catch(Ne){console.error("Error sending timeout response:",Ne)}}},12e4),E.send(JSON.stringify({id:_,type:"createSamplingMessage",messages:n,systemPrompt:i,includeContext:o,temperature:a,maxTokens:l,stopSequences:d,metadata:u,modelPreferences:f})),console.error(`Sampling request forwarded to channel: ${T}`)}async function Ul(){if(L.startMCP&&L.docker)return!0;try{let t=await et.readFile(qt,"utf8"),e=parseInt(t.trim(),10);try{return process.kill(e,0),{running:!0,pid:e}}catch{return await et.unlink(qt),{running:!1}}}catch{return{running:!1}}}async function Vl(){try{return await et.writeFile(qt,process.pid.toString(),"utf8"),!0}catch(t){return console.error("Error saving PID file:",t),!1}}async function Wl(){let t=process.argv.slice(2);t.includes("--forked")||t.push("--forked");let e=(0,ji.fork)(process.argv[1],t,{detached:!0,stdio:"ignore"});e.unref(),console.error(`Server started as daemon with PID: ${e.pid}`),console.error("Use 'node websocket-server.js --quit' to stop the server"),console.error("Use 'node websocket-server.js --new ' to authorize a channel-token pair"),console.error("Put 'npx @jason.today/webmcp --mcp' in your mcp client config"),L.startMCP||process.exit(0)}var Fl=async()=>{let t=process.argv.slice(2),e=4797,r=!1,s=!1,n=!1,i=!1,o=!1,a=null,l=!0;for(let d=0;d65535)&&(console.error("Error: Port must be a number between 1 and 65535"),Vt(),process.exit(1)),e=f,d++}else console.error("Error: Port option requires a value"),Vt(),process.exit(1);else if(u==="--config")if(d+1{console.log(` +Usage: node websocket-server.js [options] + +Options: + -p, --port Specify the port number (default: 4797) + -h, --help Display this help message + -q, --quit Stop the running server + -n, --new Generate a new token for client registration + -c, --clean Remove all authorized tokens + -f, --foreground Run in foreground (don't daemonize) + -m, --mcp Internal WebMCP Server codepath, likely only used in MCP client config + -d, --docker Tell the MCP client that WebMCP is running in docker + +Use --new to generate a token which clients can use to register on the /register endpoint. +Use --clean to remove all authorized tokens when you want to start fresh. + `)},Zl=async()=>{await Si(),await Rr(),Ei(await Fl());let t=await Ul();if(L.cleanTokens&&(console.log("Removing all authorized tokens..."),Ri(),await _t(),console.log("All tokens have been removed. Tokens file cleared."),t.running&&console.log(`Server is running with PID: ${t.pid}. Please restart it to apply changes.`),process.exit(0)),L.quit){if(t.running){console.log(`Stopping server with PID: ${t.pid}`);try{process.kill(t.pid,"SIGTERM"),console.log("Server stopped successfully")}catch(s){console.error("Error stopping server:",s)}}else console.log("No running server found");process.exit(0)}if(L.newToken){let s=await Nr();console.log(` +CONNECTION TOKEN (paste this in your web client):`),console.log(`${s} +`),t.running&&process.exit(0)}if(yt||(yt=Tr(),await Ni(yt)),t.running){if(console.error(`Server is already running with PID: ${t.pid}`),console.error("Use 'node websocket-server.js --quit' to stop the server"),console.error("Use 'node websocket-server.js --new ' to authorize a channel-token pair"),console.error("Put 'npx @jason.today/webmcp --mcp' in your mcp client config"),L.startMCP)return;process.exit(0)}if(L.daemon&&!process.argv.includes("--forked"))return process.argv.push("--forked"),Wl();await Vl();let e=L.port;Ps.listen(e,()=>{console.error(`WebSocket server running at http://${ke}:${e}`),console.error(`WebSocket server running at http://${ke}:${e}`),console.error(`WebMCP client token (for MCP path): ${yt}`),console.error(`WebMCP client URL: ws://${ke}:${e}${z}?token=${yt}`),console.error("Use 'node websocket-server.js --new ' to authorize a channel-token pair")});let r=async s=>{console.error(` +Received ${s}. Shutting down gracefully...`),await _t();for(let n of Object.values(C))for(let i of n)try{i.close()}catch(o){console.error("Error closing WebSocket connection:",o)}Ps.close(()=>{console.error("HTTP server closed"),et.unlink(qt).catch(n=>{console.error("Error removing PID file:",n)}),process.exit(0)})};process.on("SIGINT",()=>r("SIGINT")),process.on("SIGTERM",()=>r("SIGTERM")),process.platform==="win32"&&(process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("data",s=>{s.length===1&&s[0]===3&&r("CTRL+C")}))};Zl().catch(t=>{console.error("Error in main:",t),process.exit(1)}).then(()=>{L.startMCP&&setTimeout(()=>{console.error("Starting up MCP Server"),Ci(yt).catch(t=>{console.error("Fatal error in main():",t),process.exit(1)})},100)}); +//# sourceMappingURL=index.js.map diff --git a/build/index.js.map b/build/index.js.map new file mode 100644 index 0000000..f15c253 --- /dev/null +++ b/build/index.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../node_modules/ws/lib/constants.js", "../node_modules/ws/lib/buffer-util.js", "../node_modules/ws/lib/limiter.js", "../node_modules/ws/lib/permessage-deflate.js", "../node_modules/ws/lib/validation.js", "../node_modules/ws/lib/receiver.js", "../node_modules/ws/lib/sender.js", "../node_modules/ws/lib/event-target.js", "../node_modules/ws/lib/extension.js", "../node_modules/ws/lib/websocket.js", "../node_modules/ws/lib/stream.js", "../node_modules/ws/lib/subprotocol.js", "../node_modules/ws/lib/websocket-server.js", "../node_modules/dotenv/package.json", "../node_modules/dotenv/lib/main.js", "../src/websocket-server.js", "../node_modules/ws/wrapper.mjs", "../node_modules/zod/lib/index.mjs", "../node_modules/@modelcontextprotocol/sdk/src/types.ts", "../node_modules/@modelcontextprotocol/sdk/src/shared/protocol.ts", "../node_modules/@modelcontextprotocol/sdk/src/server/index.ts", "../node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts", "../node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts", "../src/tokens.js", "../src/config.js", "../node_modules/env-paths/index.js", "../src/server.js"], + "sourcesContent": ["'use strict';\n\nconst BINARY_TYPES = ['nodebuffer', 'arraybuffer', 'fragments'];\nconst hasBlob = typeof Blob !== 'undefined';\n\nif (hasBlob) BINARY_TYPES.push('blob');\n\nmodule.exports = {\n BINARY_TYPES,\n EMPTY_BUFFER: Buffer.alloc(0),\n GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',\n hasBlob,\n kForOnEventAttribute: Symbol('kIsForOnEventAttribute'),\n kListener: Symbol('kListener'),\n kStatusCode: Symbol('status-code'),\n kWebSocket: Symbol('websocket'),\n NOOP: () => {}\n};\n", "'use strict';\n\nconst { EMPTY_BUFFER } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\n\n/**\n * Merges an array of buffers into a new buffer.\n *\n * @param {Buffer[]} list The array of buffers to concat\n * @param {Number} totalLength The total length of buffers in the list\n * @return {Buffer} The resulting buffer\n * @public\n */\nfunction concat(list, totalLength) {\n if (list.length === 0) return EMPTY_BUFFER;\n if (list.length === 1) return list[0];\n\n const target = Buffer.allocUnsafe(totalLength);\n let offset = 0;\n\n for (let i = 0; i < list.length; i++) {\n const buf = list[i];\n target.set(buf, offset);\n offset += buf.length;\n }\n\n if (offset < totalLength) {\n return new FastBuffer(target.buffer, target.byteOffset, offset);\n }\n\n return target;\n}\n\n/**\n * Masks a buffer using the given mask.\n *\n * @param {Buffer} source The buffer to mask\n * @param {Buffer} mask The mask to use\n * @param {Buffer} output The buffer where to store the result\n * @param {Number} offset The offset at which to start writing\n * @param {Number} length The number of bytes to mask.\n * @public\n */\nfunction _mask(source, mask, output, offset, length) {\n for (let i = 0; i < length; i++) {\n output[offset + i] = source[i] ^ mask[i & 3];\n }\n}\n\n/**\n * Unmasks a buffer using the given mask.\n *\n * @param {Buffer} buffer The buffer to unmask\n * @param {Buffer} mask The mask to use\n * @public\n */\nfunction _unmask(buffer, mask) {\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] ^= mask[i & 3];\n }\n}\n\n/**\n * Converts a buffer to an `ArrayBuffer`.\n *\n * @param {Buffer} buf The buffer to convert\n * @return {ArrayBuffer} Converted buffer\n * @public\n */\nfunction toArrayBuffer(buf) {\n if (buf.length === buf.buffer.byteLength) {\n return buf.buffer;\n }\n\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);\n}\n\n/**\n * Converts `data` to a `Buffer`.\n *\n * @param {*} data The data to convert\n * @return {Buffer} The buffer\n * @throws {TypeError}\n * @public\n */\nfunction toBuffer(data) {\n toBuffer.readOnly = true;\n\n if (Buffer.isBuffer(data)) return data;\n\n let buf;\n\n if (data instanceof ArrayBuffer) {\n buf = new FastBuffer(data);\n } else if (ArrayBuffer.isView(data)) {\n buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);\n } else {\n buf = Buffer.from(data);\n toBuffer.readOnly = false;\n }\n\n return buf;\n}\n\nmodule.exports = {\n concat,\n mask: _mask,\n toArrayBuffer,\n toBuffer,\n unmask: _unmask\n};\n\n/* istanbul ignore else */\nif (!process.env.WS_NO_BUFFER_UTIL) {\n try {\n const bufferUtil = require('bufferutil');\n\n module.exports.mask = function (source, mask, output, offset, length) {\n if (length < 48) _mask(source, mask, output, offset, length);\n else bufferUtil.mask(source, mask, output, offset, length);\n };\n\n module.exports.unmask = function (buffer, mask) {\n if (buffer.length < 32) _unmask(buffer, mask);\n else bufferUtil.unmask(buffer, mask);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst kDone = Symbol('kDone');\nconst kRun = Symbol('kRun');\n\n/**\n * A very simple job queue with adjustable concurrency. Adapted from\n * https://github.com/STRML/async-limiter\n */\nclass Limiter {\n /**\n * Creates a new `Limiter`.\n *\n * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed\n * to run concurrently\n */\n constructor(concurrency) {\n this[kDone] = () => {\n this.pending--;\n this[kRun]();\n };\n this.concurrency = concurrency || Infinity;\n this.jobs = [];\n this.pending = 0;\n }\n\n /**\n * Adds a job to the queue.\n *\n * @param {Function} job The job to run\n * @public\n */\n add(job) {\n this.jobs.push(job);\n this[kRun]();\n }\n\n /**\n * Removes a job from the queue and runs it if possible.\n *\n * @private\n */\n [kRun]() {\n if (this.pending === this.concurrency) return;\n\n if (this.jobs.length) {\n const job = this.jobs.shift();\n\n this.pending++;\n job(this[kDone]);\n }\n }\n}\n\nmodule.exports = Limiter;\n", "'use strict';\n\nconst zlib = require('zlib');\n\nconst bufferUtil = require('./buffer-util');\nconst Limiter = require('./limiter');\nconst { kStatusCode } = require('./constants');\n\nconst FastBuffer = Buffer[Symbol.species];\nconst TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);\nconst kPerMessageDeflate = Symbol('permessage-deflate');\nconst kTotalLength = Symbol('total-length');\nconst kCallback = Symbol('callback');\nconst kBuffers = Symbol('buffers');\nconst kError = Symbol('error');\n\n//\n// We limit zlib concurrency, which prevents severe memory fragmentation\n// as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913\n// and https://github.com/websockets/ws/issues/1202\n//\n// Intentionally global; it's the global thread pool that's an issue.\n//\nlet zlibLimiter;\n\n/**\n * permessage-deflate implementation.\n */\nclass PerMessageDeflate {\n /**\n * Creates a PerMessageDeflate instance.\n *\n * @param {Object} [options] Configuration options\n * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support\n * for, or request, a custom client window size\n * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/\n * acknowledge disabling of client context takeover\n * @param {Number} [options.concurrencyLimit=10] The number of concurrent\n * calls to zlib\n * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the\n * use of a custom server window size\n * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept\n * disabling of server context takeover\n * @param {Number} [options.threshold=1024] Size (in bytes) below which\n * messages should not be compressed if context takeover is disabled\n * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on\n * deflate\n * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on\n * inflate\n * @param {Boolean} [isServer=false] Create the instance in either server or\n * client mode\n * @param {Number} [maxPayload=0] The maximum allowed message length\n */\n constructor(options, isServer, maxPayload) {\n this._maxPayload = maxPayload | 0;\n this._options = options || {};\n this._threshold =\n this._options.threshold !== undefined ? this._options.threshold : 1024;\n this._isServer = !!isServer;\n this._deflate = null;\n this._inflate = null;\n\n this.params = null;\n\n if (!zlibLimiter) {\n const concurrency =\n this._options.concurrencyLimit !== undefined\n ? this._options.concurrencyLimit\n : 10;\n zlibLimiter = new Limiter(concurrency);\n }\n }\n\n /**\n * @type {String}\n */\n static get extensionName() {\n return 'permessage-deflate';\n }\n\n /**\n * Create an extension negotiation offer.\n *\n * @return {Object} Extension parameters\n * @public\n */\n offer() {\n const params = {};\n\n if (this._options.serverNoContextTakeover) {\n params.server_no_context_takeover = true;\n }\n if (this._options.clientNoContextTakeover) {\n params.client_no_context_takeover = true;\n }\n if (this._options.serverMaxWindowBits) {\n params.server_max_window_bits = this._options.serverMaxWindowBits;\n }\n if (this._options.clientMaxWindowBits) {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n } else if (this._options.clientMaxWindowBits == null) {\n params.client_max_window_bits = true;\n }\n\n return params;\n }\n\n /**\n * Accept an extension negotiation offer/response.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Object} Accepted configuration\n * @public\n */\n accept(configurations) {\n configurations = this.normalizeParams(configurations);\n\n this.params = this._isServer\n ? this.acceptAsServer(configurations)\n : this.acceptAsClient(configurations);\n\n return this.params;\n }\n\n /**\n * Releases all resources used by the extension.\n *\n * @public\n */\n cleanup() {\n if (this._inflate) {\n this._inflate.close();\n this._inflate = null;\n }\n\n if (this._deflate) {\n const callback = this._deflate[kCallback];\n\n this._deflate.close();\n this._deflate = null;\n\n if (callback) {\n callback(\n new Error(\n 'The deflate stream was closed while data was being processed'\n )\n );\n }\n }\n }\n\n /**\n * Accept an extension negotiation offer.\n *\n * @param {Array} offers The extension negotiation offers\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsServer(offers) {\n const opts = this._options;\n const accepted = offers.find((params) => {\n if (\n (opts.serverNoContextTakeover === false &&\n params.server_no_context_takeover) ||\n (params.server_max_window_bits &&\n (opts.serverMaxWindowBits === false ||\n (typeof opts.serverMaxWindowBits === 'number' &&\n opts.serverMaxWindowBits > params.server_max_window_bits))) ||\n (typeof opts.clientMaxWindowBits === 'number' &&\n !params.client_max_window_bits)\n ) {\n return false;\n }\n\n return true;\n });\n\n if (!accepted) {\n throw new Error('None of the extension offers can be accepted');\n }\n\n if (opts.serverNoContextTakeover) {\n accepted.server_no_context_takeover = true;\n }\n if (opts.clientNoContextTakeover) {\n accepted.client_no_context_takeover = true;\n }\n if (typeof opts.serverMaxWindowBits === 'number') {\n accepted.server_max_window_bits = opts.serverMaxWindowBits;\n }\n if (typeof opts.clientMaxWindowBits === 'number') {\n accepted.client_max_window_bits = opts.clientMaxWindowBits;\n } else if (\n accepted.client_max_window_bits === true ||\n opts.clientMaxWindowBits === false\n ) {\n delete accepted.client_max_window_bits;\n }\n\n return accepted;\n }\n\n /**\n * Accept the extension negotiation response.\n *\n * @param {Array} response The extension negotiation response\n * @return {Object} Accepted configuration\n * @private\n */\n acceptAsClient(response) {\n const params = response[0];\n\n if (\n this._options.clientNoContextTakeover === false &&\n params.client_no_context_takeover\n ) {\n throw new Error('Unexpected parameter \"client_no_context_takeover\"');\n }\n\n if (!params.client_max_window_bits) {\n if (typeof this._options.clientMaxWindowBits === 'number') {\n params.client_max_window_bits = this._options.clientMaxWindowBits;\n }\n } else if (\n this._options.clientMaxWindowBits === false ||\n (typeof this._options.clientMaxWindowBits === 'number' &&\n params.client_max_window_bits > this._options.clientMaxWindowBits)\n ) {\n throw new Error(\n 'Unexpected or invalid parameter \"client_max_window_bits\"'\n );\n }\n\n return params;\n }\n\n /**\n * Normalize parameters.\n *\n * @param {Array} configurations The extension negotiation offers/reponse\n * @return {Array} The offers/response with normalized parameters\n * @private\n */\n normalizeParams(configurations) {\n configurations.forEach((params) => {\n Object.keys(params).forEach((key) => {\n let value = params[key];\n\n if (value.length > 1) {\n throw new Error(`Parameter \"${key}\" must have only a single value`);\n }\n\n value = value[0];\n\n if (key === 'client_max_window_bits') {\n if (value !== true) {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (!this._isServer) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else if (key === 'server_max_window_bits') {\n const num = +value;\n if (!Number.isInteger(num) || num < 8 || num > 15) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n value = num;\n } else if (\n key === 'client_no_context_takeover' ||\n key === 'server_no_context_takeover'\n ) {\n if (value !== true) {\n throw new TypeError(\n `Invalid value for parameter \"${key}\": ${value}`\n );\n }\n } else {\n throw new Error(`Unknown parameter \"${key}\"`);\n }\n\n params[key] = value;\n });\n });\n\n return configurations;\n }\n\n /**\n * Decompress data. Concurrency limited.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n decompress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._decompress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Compress data. Concurrency limited.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @public\n */\n compress(data, fin, callback) {\n zlibLimiter.add((done) => {\n this._compress(data, fin, (err, result) => {\n done();\n callback(err, result);\n });\n });\n }\n\n /**\n * Decompress data.\n *\n * @param {Buffer} data Compressed data\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _decompress(data, fin, callback) {\n const endpoint = this._isServer ? 'client' : 'server';\n\n if (!this._inflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._inflate = zlib.createInflateRaw({\n ...this._options.zlibInflateOptions,\n windowBits\n });\n this._inflate[kPerMessageDeflate] = this;\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n this._inflate.on('error', inflateOnError);\n this._inflate.on('data', inflateOnData);\n }\n\n this._inflate[kCallback] = callback;\n\n this._inflate.write(data);\n if (fin) this._inflate.write(TRAILER);\n\n this._inflate.flush(() => {\n const err = this._inflate[kError];\n\n if (err) {\n this._inflate.close();\n this._inflate = null;\n callback(err);\n return;\n }\n\n const data = bufferUtil.concat(\n this._inflate[kBuffers],\n this._inflate[kTotalLength]\n );\n\n if (this._inflate._readableState.endEmitted) {\n this._inflate.close();\n this._inflate = null;\n } else {\n this._inflate[kTotalLength] = 0;\n this._inflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._inflate.reset();\n }\n }\n\n callback(null, data);\n });\n }\n\n /**\n * Compress data.\n *\n * @param {(Buffer|String)} data Data to compress\n * @param {Boolean} fin Specifies whether or not this is the last fragment\n * @param {Function} callback Callback\n * @private\n */\n _compress(data, fin, callback) {\n const endpoint = this._isServer ? 'server' : 'client';\n\n if (!this._deflate) {\n const key = `${endpoint}_max_window_bits`;\n const windowBits =\n typeof this.params[key] !== 'number'\n ? zlib.Z_DEFAULT_WINDOWBITS\n : this.params[key];\n\n this._deflate = zlib.createDeflateRaw({\n ...this._options.zlibDeflateOptions,\n windowBits\n });\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n this._deflate.on('data', deflateOnData);\n }\n\n this._deflate[kCallback] = callback;\n\n this._deflate.write(data);\n this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {\n if (!this._deflate) {\n //\n // The deflate stream was closed while data was being processed.\n //\n return;\n }\n\n let data = bufferUtil.concat(\n this._deflate[kBuffers],\n this._deflate[kTotalLength]\n );\n\n if (fin) {\n data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);\n }\n\n //\n // Ensure that the callback will not be called again in\n // `PerMessageDeflate#cleanup()`.\n //\n this._deflate[kCallback] = null;\n\n this._deflate[kTotalLength] = 0;\n this._deflate[kBuffers] = [];\n\n if (fin && this.params[`${endpoint}_no_context_takeover`]) {\n this._deflate.reset();\n }\n\n callback(null, data);\n });\n }\n}\n\nmodule.exports = PerMessageDeflate;\n\n/**\n * The listener of the `zlib.DeflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction deflateOnData(chunk) {\n this[kBuffers].push(chunk);\n this[kTotalLength] += chunk.length;\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction inflateOnData(chunk) {\n this[kTotalLength] += chunk.length;\n\n if (\n this[kPerMessageDeflate]._maxPayload < 1 ||\n this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload\n ) {\n this[kBuffers].push(chunk);\n return;\n }\n\n this[kError] = new RangeError('Max payload size exceeded');\n this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';\n this[kError][kStatusCode] = 1009;\n this.removeListener('data', inflateOnData);\n this.reset();\n}\n\n/**\n * The listener of the `zlib.InflateRaw` stream `'error'` event.\n *\n * @param {Error} err The emitted error\n * @private\n */\nfunction inflateOnError(err) {\n //\n // There is no need to call `Zlib#close()` as the handle is automatically\n // closed when an error is emitted.\n //\n this[kPerMessageDeflate]._inflate = null;\n err[kStatusCode] = 1007;\n this[kCallback](err);\n}\n", "'use strict';\n\nconst { isUtf8 } = require('buffer');\n\nconst { hasBlob } = require('./constants');\n\n//\n// Allowed token characters:\n//\n// '!', '#', '$', '%', '&', ''', '*', '+', '-',\n// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'\n//\n// tokenChars[32] === 0 // ' '\n// tokenChars[33] === 1 // '!'\n// tokenChars[34] === 0 // '\"'\n// ...\n//\n// prettier-ignore\nconst tokenChars = [\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31\n 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63\n 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111\n 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127\n];\n\n/**\n * Checks if a status code is allowed in a close frame.\n *\n * @param {Number} code The status code\n * @return {Boolean} `true` if the status code is valid, else `false`\n * @public\n */\nfunction isValidStatusCode(code) {\n return (\n (code >= 1000 &&\n code <= 1014 &&\n code !== 1004 &&\n code !== 1005 &&\n code !== 1006) ||\n (code >= 3000 && code <= 4999)\n );\n}\n\n/**\n * Checks if a given buffer contains only correct UTF-8.\n * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by\n * Markus Kuhn.\n *\n * @param {Buffer} buf The buffer to check\n * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`\n * @public\n */\nfunction _isValidUTF8(buf) {\n const len = buf.length;\n let i = 0;\n\n while (i < len) {\n if ((buf[i] & 0x80) === 0) {\n // 0xxxxxxx\n i++;\n } else if ((buf[i] & 0xe0) === 0xc0) {\n // 110xxxxx 10xxxxxx\n if (\n i + 1 === len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i] & 0xfe) === 0xc0 // Overlong\n ) {\n return false;\n }\n\n i += 2;\n } else if ((buf[i] & 0xf0) === 0xe0) {\n // 1110xxxx 10xxxxxx 10xxxxxx\n if (\n i + 2 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong\n (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)\n ) {\n return false;\n }\n\n i += 3;\n } else if ((buf[i] & 0xf8) === 0xf0) {\n // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n if (\n i + 3 >= len ||\n (buf[i + 1] & 0xc0) !== 0x80 ||\n (buf[i + 2] & 0xc0) !== 0x80 ||\n (buf[i + 3] & 0xc0) !== 0x80 ||\n (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong\n (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||\n buf[i] > 0xf4 // > U+10FFFF\n ) {\n return false;\n }\n\n i += 4;\n } else {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Determines whether a value is a `Blob`.\n *\n * @param {*} value The value to be tested\n * @return {Boolean} `true` if `value` is a `Blob`, else `false`\n * @private\n */\nfunction isBlob(value) {\n return (\n hasBlob &&\n typeof value === 'object' &&\n typeof value.arrayBuffer === 'function' &&\n typeof value.type === 'string' &&\n typeof value.stream === 'function' &&\n (value[Symbol.toStringTag] === 'Blob' ||\n value[Symbol.toStringTag] === 'File')\n );\n}\n\nmodule.exports = {\n isBlob,\n isValidStatusCode,\n isValidUTF8: _isValidUTF8,\n tokenChars\n};\n\nif (isUtf8) {\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);\n };\n} /* istanbul ignore else */ else if (!process.env.WS_NO_UTF_8_VALIDATE) {\n try {\n const isValidUTF8 = require('utf-8-validate');\n\n module.exports.isValidUTF8 = function (buf) {\n return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);\n };\n } catch (e) {\n // Continue regardless of the error.\n }\n}\n", "'use strict';\n\nconst { Writable } = require('stream');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n kStatusCode,\n kWebSocket\n} = require('./constants');\nconst { concat, toArrayBuffer, unmask } = require('./buffer-util');\nconst { isValidStatusCode, isValidUTF8 } = require('./validation');\n\nconst FastBuffer = Buffer[Symbol.species];\n\nconst GET_INFO = 0;\nconst GET_PAYLOAD_LENGTH_16 = 1;\nconst GET_PAYLOAD_LENGTH_64 = 2;\nconst GET_MASK = 3;\nconst GET_DATA = 4;\nconst INFLATING = 5;\nconst DEFER_EVENT = 6;\n\n/**\n * HyBi Receiver implementation.\n *\n * @extends Writable\n */\nclass Receiver extends Writable {\n /**\n * Creates a Receiver instance.\n *\n * @param {Object} [options] Options object\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {String} [options.binaryType=nodebuffer] The type for binary data\n * @param {Object} [options.extensions] An object containing the negotiated\n * extensions\n * @param {Boolean} [options.isServer=false] Specifies whether to operate in\n * client or server mode\n * @param {Number} [options.maxPayload=0] The maximum allowed message length\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n */\n constructor(options = {}) {\n super();\n\n this._allowSynchronousEvents =\n options.allowSynchronousEvents !== undefined\n ? options.allowSynchronousEvents\n : true;\n this._binaryType = options.binaryType || BINARY_TYPES[0];\n this._extensions = options.extensions || {};\n this._isServer = !!options.isServer;\n this._maxPayload = options.maxPayload | 0;\n this._skipUTF8Validation = !!options.skipUTF8Validation;\n this[kWebSocket] = undefined;\n\n this._bufferedBytes = 0;\n this._buffers = [];\n\n this._compressed = false;\n this._payloadLength = 0;\n this._mask = undefined;\n this._fragmented = 0;\n this._masked = false;\n this._fin = false;\n this._opcode = 0;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragments = [];\n\n this._errored = false;\n this._loop = false;\n this._state = GET_INFO;\n }\n\n /**\n * Implements `Writable.prototype._write()`.\n *\n * @param {Buffer} chunk The chunk of data to write\n * @param {String} encoding The character encoding of `chunk`\n * @param {Function} cb Callback\n * @private\n */\n _write(chunk, encoding, cb) {\n if (this._opcode === 0x08 && this._state == GET_INFO) return cb();\n\n this._bufferedBytes += chunk.length;\n this._buffers.push(chunk);\n this.startLoop(cb);\n }\n\n /**\n * Consumes `n` bytes from the buffered data.\n *\n * @param {Number} n The number of bytes to consume\n * @return {Buffer} The consumed bytes\n * @private\n */\n consume(n) {\n this._bufferedBytes -= n;\n\n if (n === this._buffers[0].length) return this._buffers.shift();\n\n if (n < this._buffers[0].length) {\n const buf = this._buffers[0];\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n\n return new FastBuffer(buf.buffer, buf.byteOffset, n);\n }\n\n const dst = Buffer.allocUnsafe(n);\n\n do {\n const buf = this._buffers[0];\n const offset = dst.length - n;\n\n if (n >= buf.length) {\n dst.set(this._buffers.shift(), offset);\n } else {\n dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);\n this._buffers[0] = new FastBuffer(\n buf.buffer,\n buf.byteOffset + n,\n buf.length - n\n );\n }\n\n n -= buf.length;\n } while (n > 0);\n\n return dst;\n }\n\n /**\n * Starts the parsing loop.\n *\n * @param {Function} cb Callback\n * @private\n */\n startLoop(cb) {\n this._loop = true;\n\n do {\n switch (this._state) {\n case GET_INFO:\n this.getInfo(cb);\n break;\n case GET_PAYLOAD_LENGTH_16:\n this.getPayloadLength16(cb);\n break;\n case GET_PAYLOAD_LENGTH_64:\n this.getPayloadLength64(cb);\n break;\n case GET_MASK:\n this.getMask();\n break;\n case GET_DATA:\n this.getData(cb);\n break;\n case INFLATING:\n case DEFER_EVENT:\n this._loop = false;\n return;\n }\n } while (this._loop);\n\n if (!this._errored) cb();\n }\n\n /**\n * Reads the first two bytes of a frame.\n *\n * @param {Function} cb Callback\n * @private\n */\n getInfo(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(2);\n\n if ((buf[0] & 0x30) !== 0x00) {\n const error = this.createError(\n RangeError,\n 'RSV2 and RSV3 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_2_3'\n );\n\n cb(error);\n return;\n }\n\n const compressed = (buf[0] & 0x40) === 0x40;\n\n if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n this._fin = (buf[0] & 0x80) === 0x80;\n this._opcode = buf[0] & 0x0f;\n this._payloadLength = buf[1] & 0x7f;\n\n if (this._opcode === 0x00) {\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fragmented) {\n const error = this.createError(\n RangeError,\n 'invalid opcode 0',\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._opcode = this._fragmented;\n } else if (this._opcode === 0x01 || this._opcode === 0x02) {\n if (this._fragmented) {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n this._compressed = compressed;\n } else if (this._opcode > 0x07 && this._opcode < 0x0b) {\n if (!this._fin) {\n const error = this.createError(\n RangeError,\n 'FIN must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_FIN'\n );\n\n cb(error);\n return;\n }\n\n if (compressed) {\n const error = this.createError(\n RangeError,\n 'RSV1 must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_RSV_1'\n );\n\n cb(error);\n return;\n }\n\n if (\n this._payloadLength > 0x7d ||\n (this._opcode === 0x08 && this._payloadLength === 1)\n ) {\n const error = this.createError(\n RangeError,\n `invalid payload length ${this._payloadLength}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n } else {\n const error = this.createError(\n RangeError,\n `invalid opcode ${this._opcode}`,\n true,\n 1002,\n 'WS_ERR_INVALID_OPCODE'\n );\n\n cb(error);\n return;\n }\n\n if (!this._fin && !this._fragmented) this._fragmented = this._opcode;\n this._masked = (buf[1] & 0x80) === 0x80;\n\n if (this._isServer) {\n if (!this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be set',\n true,\n 1002,\n 'WS_ERR_EXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n } else if (this._masked) {\n const error = this.createError(\n RangeError,\n 'MASK must be clear',\n true,\n 1002,\n 'WS_ERR_UNEXPECTED_MASK'\n );\n\n cb(error);\n return;\n }\n\n if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;\n else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;\n else this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+16).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength16(cb) {\n if (this._bufferedBytes < 2) {\n this._loop = false;\n return;\n }\n\n this._payloadLength = this.consume(2).readUInt16BE(0);\n this.haveLength(cb);\n }\n\n /**\n * Gets extended payload length (7+64).\n *\n * @param {Function} cb Callback\n * @private\n */\n getPayloadLength64(cb) {\n if (this._bufferedBytes < 8) {\n this._loop = false;\n return;\n }\n\n const buf = this.consume(8);\n const num = buf.readUInt32BE(0);\n\n //\n // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned\n // if payload length is greater than this number.\n //\n if (num > Math.pow(2, 53 - 32) - 1) {\n const error = this.createError(\n RangeError,\n 'Unsupported WebSocket frame: payload length > 2^53 - 1',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);\n this.haveLength(cb);\n }\n\n /**\n * Payload length has been read.\n *\n * @param {Function} cb Callback\n * @private\n */\n haveLength(cb) {\n if (this._payloadLength && this._opcode < 0x08) {\n this._totalPayloadLength += this._payloadLength;\n if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n }\n\n if (this._masked) this._state = GET_MASK;\n else this._state = GET_DATA;\n }\n\n /**\n * Reads mask bytes.\n *\n * @private\n */\n getMask() {\n if (this._bufferedBytes < 4) {\n this._loop = false;\n return;\n }\n\n this._mask = this.consume(4);\n this._state = GET_DATA;\n }\n\n /**\n * Reads data bytes.\n *\n * @param {Function} cb Callback\n * @private\n */\n getData(cb) {\n let data = EMPTY_BUFFER;\n\n if (this._payloadLength) {\n if (this._bufferedBytes < this._payloadLength) {\n this._loop = false;\n return;\n }\n\n data = this.consume(this._payloadLength);\n\n if (\n this._masked &&\n (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0\n ) {\n unmask(data, this._mask);\n }\n }\n\n if (this._opcode > 0x07) {\n this.controlMessage(data, cb);\n return;\n }\n\n if (this._compressed) {\n this._state = INFLATING;\n this.decompress(data, cb);\n return;\n }\n\n if (data.length) {\n //\n // This message is not compressed so its length is the sum of the payload\n // length of all fragments.\n //\n this._messageLength = this._totalPayloadLength;\n this._fragments.push(data);\n }\n\n this.dataMessage(cb);\n }\n\n /**\n * Decompresses data.\n *\n * @param {Buffer} data Compressed data\n * @param {Function} cb Callback\n * @private\n */\n decompress(data, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n perMessageDeflate.decompress(data, this._fin, (err, buf) => {\n if (err) return cb(err);\n\n if (buf.length) {\n this._messageLength += buf.length;\n if (this._messageLength > this._maxPayload && this._maxPayload > 0) {\n const error = this.createError(\n RangeError,\n 'Max payload size exceeded',\n false,\n 1009,\n 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'\n );\n\n cb(error);\n return;\n }\n\n this._fragments.push(buf);\n }\n\n this.dataMessage(cb);\n if (this._state === GET_INFO) this.startLoop(cb);\n });\n }\n\n /**\n * Handles a data message.\n *\n * @param {Function} cb Callback\n * @private\n */\n dataMessage(cb) {\n if (!this._fin) {\n this._state = GET_INFO;\n return;\n }\n\n const messageLength = this._messageLength;\n const fragments = this._fragments;\n\n this._totalPayloadLength = 0;\n this._messageLength = 0;\n this._fragmented = 0;\n this._fragments = [];\n\n if (this._opcode === 2) {\n let data;\n\n if (this._binaryType === 'nodebuffer') {\n data = concat(fragments, messageLength);\n } else if (this._binaryType === 'arraybuffer') {\n data = toArrayBuffer(concat(fragments, messageLength));\n } else if (this._binaryType === 'blob') {\n data = new Blob(fragments);\n } else {\n data = fragments;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit('message', data, true);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', data, true);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n } else {\n const buf = concat(fragments, messageLength);\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n if (this._state === INFLATING || this._allowSynchronousEvents) {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit('message', buf, false);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n }\n\n /**\n * Handles a control message.\n *\n * @param {Buffer} data Data to handle\n * @return {(Error|RangeError|undefined)} A possible error\n * @private\n */\n controlMessage(data, cb) {\n if (this._opcode === 0x08) {\n if (data.length === 0) {\n this._loop = false;\n this.emit('conclude', 1005, EMPTY_BUFFER);\n this.end();\n } else {\n const code = data.readUInt16BE(0);\n\n if (!isValidStatusCode(code)) {\n const error = this.createError(\n RangeError,\n `invalid status code ${code}`,\n true,\n 1002,\n 'WS_ERR_INVALID_CLOSE_CODE'\n );\n\n cb(error);\n return;\n }\n\n const buf = new FastBuffer(\n data.buffer,\n data.byteOffset + 2,\n data.length - 2\n );\n\n if (!this._skipUTF8Validation && !isValidUTF8(buf)) {\n const error = this.createError(\n Error,\n 'invalid UTF-8 sequence',\n true,\n 1007,\n 'WS_ERR_INVALID_UTF8'\n );\n\n cb(error);\n return;\n }\n\n this._loop = false;\n this.emit('conclude', code, buf);\n this.end();\n }\n\n this._state = GET_INFO;\n return;\n }\n\n if (this._allowSynchronousEvents) {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n } else {\n this._state = DEFER_EVENT;\n setImmediate(() => {\n this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);\n this._state = GET_INFO;\n this.startLoop(cb);\n });\n }\n }\n\n /**\n * Builds an error object.\n *\n * @param {function(new:Error|RangeError)} ErrorCtor The error constructor\n * @param {String} message The error message\n * @param {Boolean} prefix Specifies whether or not to add a default prefix to\n * `message`\n * @param {Number} statusCode The status code\n * @param {String} errorCode The exposed error code\n * @return {(Error|RangeError)} The error\n * @private\n */\n createError(ErrorCtor, message, prefix, statusCode, errorCode) {\n this._loop = false;\n this._errored = true;\n\n const err = new ErrorCtor(\n prefix ? `Invalid WebSocket frame: ${message}` : message\n );\n\n Error.captureStackTrace(err, this.createError);\n err.code = errorCode;\n err[kStatusCode] = statusCode;\n return err;\n }\n}\n\nmodule.exports = Receiver;\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex\" }] */\n\n'use strict';\n\nconst { Duplex } = require('stream');\nconst { randomFillSync } = require('crypto');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst { EMPTY_BUFFER, kWebSocket, NOOP } = require('./constants');\nconst { isBlob, isValidStatusCode } = require('./validation');\nconst { mask: applyMask, toBuffer } = require('./buffer-util');\n\nconst kByteLength = Symbol('kByteLength');\nconst maskBuffer = Buffer.alloc(4);\nconst RANDOM_POOL_SIZE = 8 * 1024;\nlet randomPool;\nlet randomPoolPointer = RANDOM_POOL_SIZE;\n\nconst DEFAULT = 0;\nconst DEFLATING = 1;\nconst GET_BLOB_DATA = 2;\n\n/**\n * HyBi Sender implementation.\n */\nclass Sender {\n /**\n * Creates a Sender instance.\n *\n * @param {Duplex} socket The connection socket\n * @param {Object} [extensions] An object containing the negotiated extensions\n * @param {Function} [generateMask] The function used to generate the masking\n * key\n */\n constructor(socket, extensions, generateMask) {\n this._extensions = extensions || {};\n\n if (generateMask) {\n this._generateMask = generateMask;\n this._maskBuffer = Buffer.alloc(4);\n }\n\n this._socket = socket;\n\n this._firstFragment = true;\n this._compress = false;\n\n this._bufferedBytes = 0;\n this._queue = [];\n this._state = DEFAULT;\n this.onerror = NOOP;\n this[kWebSocket] = undefined;\n }\n\n /**\n * Frames a piece of data according to the HyBi WebSocket protocol.\n *\n * @param {(Buffer|String)} data The data to frame\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @return {(Buffer|String)[]} The framed data\n * @public\n */\n static frame(data, options) {\n let mask;\n let merge = false;\n let offset = 2;\n let skipMasking = false;\n\n if (options.mask) {\n mask = options.maskBuffer || maskBuffer;\n\n if (options.generateMask) {\n options.generateMask(mask);\n } else {\n if (randomPoolPointer === RANDOM_POOL_SIZE) {\n /* istanbul ignore else */\n if (randomPool === undefined) {\n //\n // This is lazily initialized because server-sent frames must not\n // be masked so it may never be used.\n //\n randomPool = Buffer.alloc(RANDOM_POOL_SIZE);\n }\n\n randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);\n randomPoolPointer = 0;\n }\n\n mask[0] = randomPool[randomPoolPointer++];\n mask[1] = randomPool[randomPoolPointer++];\n mask[2] = randomPool[randomPoolPointer++];\n mask[3] = randomPool[randomPoolPointer++];\n }\n\n skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;\n offset = 6;\n }\n\n let dataLength;\n\n if (typeof data === 'string') {\n if (\n (!options.mask || skipMasking) &&\n options[kByteLength] !== undefined\n ) {\n dataLength = options[kByteLength];\n } else {\n data = Buffer.from(data);\n dataLength = data.length;\n }\n } else {\n dataLength = data.length;\n merge = options.mask && options.readOnly && !skipMasking;\n }\n\n let payloadLength = dataLength;\n\n if (dataLength >= 65536) {\n offset += 8;\n payloadLength = 127;\n } else if (dataLength > 125) {\n offset += 2;\n payloadLength = 126;\n }\n\n const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);\n\n target[0] = options.fin ? options.opcode | 0x80 : options.opcode;\n if (options.rsv1) target[0] |= 0x40;\n\n target[1] = payloadLength;\n\n if (payloadLength === 126) {\n target.writeUInt16BE(dataLength, 2);\n } else if (payloadLength === 127) {\n target[2] = target[3] = 0;\n target.writeUIntBE(dataLength, 4, 6);\n }\n\n if (!options.mask) return [target, data];\n\n target[1] |= 0x80;\n target[offset - 4] = mask[0];\n target[offset - 3] = mask[1];\n target[offset - 2] = mask[2];\n target[offset - 1] = mask[3];\n\n if (skipMasking) return [target, data];\n\n if (merge) {\n applyMask(data, mask, target, offset, dataLength);\n return [target];\n }\n\n applyMask(data, mask, data, 0, dataLength);\n return [target, data];\n }\n\n /**\n * Sends a close message to the other peer.\n *\n * @param {Number} [code] The status code component of the body\n * @param {(String|Buffer)} [data] The message component of the body\n * @param {Boolean} [mask=false] Specifies whether or not to mask the message\n * @param {Function} [cb] Callback\n * @public\n */\n close(code, data, mask, cb) {\n let buf;\n\n if (code === undefined) {\n buf = EMPTY_BUFFER;\n } else if (typeof code !== 'number' || !isValidStatusCode(code)) {\n throw new TypeError('First argument must be a valid error code number');\n } else if (data === undefined || !data.length) {\n buf = Buffer.allocUnsafe(2);\n buf.writeUInt16BE(code, 0);\n } else {\n const length = Buffer.byteLength(data);\n\n if (length > 123) {\n throw new RangeError('The message must not be greater than 123 bytes');\n }\n\n buf = Buffer.allocUnsafe(2 + length);\n buf.writeUInt16BE(code, 0);\n\n if (typeof data === 'string') {\n buf.write(data, 2);\n } else {\n buf.set(data, 2);\n }\n }\n\n const options = {\n [kByteLength]: buf.length,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x08,\n readOnly: false,\n rsv1: false\n };\n\n if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, buf, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(buf, options), cb);\n }\n }\n\n /**\n * Sends a ping message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n ping(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x09,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a pong message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Boolean} [mask=false] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback\n * @public\n */\n pong(data, mask, cb) {\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (byteLength > 125) {\n throw new RangeError('The data size must not be greater than 125 bytes');\n }\n\n const options = {\n [kByteLength]: byteLength,\n fin: true,\n generateMask: this._generateMask,\n mask,\n maskBuffer: this._maskBuffer,\n opcode: 0x0a,\n readOnly,\n rsv1: false\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, false, options, cb]);\n } else {\n this.getBlobData(data, false, options, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, false, options, cb]);\n } else {\n this.sendFrame(Sender.frame(data, options), cb);\n }\n }\n\n /**\n * Sends a data message to the other peer.\n *\n * @param {*} data The message to send\n * @param {Object} options Options object\n * @param {Boolean} [options.binary=false] Specifies whether `data` is binary\n * or text\n * @param {Boolean} [options.compress=false] Specifies whether or not to\n * compress `data`\n * @param {Boolean} [options.fin=false] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Function} [cb] Callback\n * @public\n */\n send(data, options, cb) {\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n let opcode = options.binary ? 2 : 1;\n let rsv1 = options.compress;\n\n let byteLength;\n let readOnly;\n\n if (typeof data === 'string') {\n byteLength = Buffer.byteLength(data);\n readOnly = false;\n } else if (isBlob(data)) {\n byteLength = data.size;\n readOnly = false;\n } else {\n data = toBuffer(data);\n byteLength = data.length;\n readOnly = toBuffer.readOnly;\n }\n\n if (this._firstFragment) {\n this._firstFragment = false;\n if (\n rsv1 &&\n perMessageDeflate &&\n perMessageDeflate.params[\n perMessageDeflate._isServer\n ? 'server_no_context_takeover'\n : 'client_no_context_takeover'\n ]\n ) {\n rsv1 = byteLength >= perMessageDeflate._threshold;\n }\n this._compress = rsv1;\n } else {\n rsv1 = false;\n opcode = 0;\n }\n\n if (options.fin) this._firstFragment = true;\n\n const opts = {\n [kByteLength]: byteLength,\n fin: options.fin,\n generateMask: this._generateMask,\n mask: options.mask,\n maskBuffer: this._maskBuffer,\n opcode,\n readOnly,\n rsv1\n };\n\n if (isBlob(data)) {\n if (this._state !== DEFAULT) {\n this.enqueue([this.getBlobData, data, this._compress, opts, cb]);\n } else {\n this.getBlobData(data, this._compress, opts, cb);\n }\n } else if (this._state !== DEFAULT) {\n this.enqueue([this.dispatch, data, this._compress, opts, cb]);\n } else {\n this.dispatch(data, this._compress, opts, cb);\n }\n }\n\n /**\n * Gets the contents of a blob as binary data.\n *\n * @param {Blob} blob The blob\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * the data\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n getBlobData(blob, compress, options, cb) {\n this._bufferedBytes += options[kByteLength];\n this._state = GET_BLOB_DATA;\n\n blob\n .arrayBuffer()\n .then((arrayBuffer) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while the blob was being read'\n );\n\n //\n // `callCallbacks` is called in the next tick to ensure that errors\n // that might be thrown in the callbacks behave like errors thrown\n // outside the promise chain.\n //\n process.nextTick(callCallbacks, this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n const data = toBuffer(arrayBuffer);\n\n if (!compress) {\n this._state = DEFAULT;\n this.sendFrame(Sender.frame(data, options), cb);\n this.dequeue();\n } else {\n this.dispatch(data, compress, options, cb);\n }\n })\n .catch((err) => {\n //\n // `onError` is called in the next tick for the same reason that\n // `callCallbacks` above is.\n //\n process.nextTick(onError, this, err, cb);\n });\n }\n\n /**\n * Dispatches a message.\n *\n * @param {(Buffer|String)} data The message to send\n * @param {Boolean} [compress=false] Specifies whether or not to compress\n * `data`\n * @param {Object} options Options object\n * @param {Boolean} [options.fin=false] Specifies whether or not to set the\n * FIN bit\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Boolean} [options.mask=false] Specifies whether or not to mask\n * `data`\n * @param {Buffer} [options.maskBuffer] The buffer used to store the masking\n * key\n * @param {Number} options.opcode The opcode\n * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be\n * modified\n * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the\n * RSV1 bit\n * @param {Function} [cb] Callback\n * @private\n */\n dispatch(data, compress, options, cb) {\n if (!compress) {\n this.sendFrame(Sender.frame(data, options), cb);\n return;\n }\n\n const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];\n\n this._bufferedBytes += options[kByteLength];\n this._state = DEFLATING;\n perMessageDeflate.compress(data, options.fin, (_, buf) => {\n if (this._socket.destroyed) {\n const err = new Error(\n 'The socket was closed while data was being compressed'\n );\n\n callCallbacks(this, err, cb);\n return;\n }\n\n this._bufferedBytes -= options[kByteLength];\n this._state = DEFAULT;\n options.readOnly = false;\n this.sendFrame(Sender.frame(buf, options), cb);\n this.dequeue();\n });\n }\n\n /**\n * Executes queued send operations.\n *\n * @private\n */\n dequeue() {\n while (this._state === DEFAULT && this._queue.length) {\n const params = this._queue.shift();\n\n this._bufferedBytes -= params[3][kByteLength];\n Reflect.apply(params[0], this, params.slice(1));\n }\n }\n\n /**\n * Enqueues a send operation.\n *\n * @param {Array} params Send operation parameters.\n * @private\n */\n enqueue(params) {\n this._bufferedBytes += params[3][kByteLength];\n this._queue.push(params);\n }\n\n /**\n * Sends a frame.\n *\n * @param {(Buffer | String)[]} list The frame to send\n * @param {Function} [cb] Callback\n * @private\n */\n sendFrame(list, cb) {\n if (list.length === 2) {\n this._socket.cork();\n this._socket.write(list[0]);\n this._socket.write(list[1], cb);\n this._socket.uncork();\n } else {\n this._socket.write(list[0], cb);\n }\n }\n}\n\nmodule.exports = Sender;\n\n/**\n * Calls queued callbacks with an error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error to call the callbacks with\n * @param {Function} [cb] The first callback\n * @private\n */\nfunction callCallbacks(sender, err, cb) {\n if (typeof cb === 'function') cb(err);\n\n for (let i = 0; i < sender._queue.length; i++) {\n const params = sender._queue[i];\n const callback = params[params.length - 1];\n\n if (typeof callback === 'function') callback(err);\n }\n}\n\n/**\n * Handles a `Sender` error.\n *\n * @param {Sender} sender The `Sender` instance\n * @param {Error} err The error\n * @param {Function} [cb] The first pending callback\n * @private\n */\nfunction onError(sender, err, cb) {\n callCallbacks(sender, err, cb);\n sender.onerror(err);\n}\n", "'use strict';\n\nconst { kForOnEventAttribute, kListener } = require('./constants');\n\nconst kCode = Symbol('kCode');\nconst kData = Symbol('kData');\nconst kError = Symbol('kError');\nconst kMessage = Symbol('kMessage');\nconst kReason = Symbol('kReason');\nconst kTarget = Symbol('kTarget');\nconst kType = Symbol('kType');\nconst kWasClean = Symbol('kWasClean');\n\n/**\n * Class representing an event.\n */\nclass Event {\n /**\n * Create a new `Event`.\n *\n * @param {String} type The name of the event\n * @throws {TypeError} If the `type` argument is not specified\n */\n constructor(type) {\n this[kTarget] = null;\n this[kType] = type;\n }\n\n /**\n * @type {*}\n */\n get target() {\n return this[kTarget];\n }\n\n /**\n * @type {String}\n */\n get type() {\n return this[kType];\n }\n}\n\nObject.defineProperty(Event.prototype, 'target', { enumerable: true });\nObject.defineProperty(Event.prototype, 'type', { enumerable: true });\n\n/**\n * Class representing a close event.\n *\n * @extends Event\n */\nclass CloseEvent extends Event {\n /**\n * Create a new `CloseEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {Number} [options.code=0] The status code explaining why the\n * connection was closed\n * @param {String} [options.reason=''] A human-readable string explaining why\n * the connection was closed\n * @param {Boolean} [options.wasClean=false] Indicates whether or not the\n * connection was cleanly closed\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kCode] = options.code === undefined ? 0 : options.code;\n this[kReason] = options.reason === undefined ? '' : options.reason;\n this[kWasClean] = options.wasClean === undefined ? false : options.wasClean;\n }\n\n /**\n * @type {Number}\n */\n get code() {\n return this[kCode];\n }\n\n /**\n * @type {String}\n */\n get reason() {\n return this[kReason];\n }\n\n /**\n * @type {Boolean}\n */\n get wasClean() {\n return this[kWasClean];\n }\n}\n\nObject.defineProperty(CloseEvent.prototype, 'code', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'reason', { enumerable: true });\nObject.defineProperty(CloseEvent.prototype, 'wasClean', { enumerable: true });\n\n/**\n * Class representing an error event.\n *\n * @extends Event\n */\nclass ErrorEvent extends Event {\n /**\n * Create a new `ErrorEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.error=null] The error that generated this event\n * @param {String} [options.message=''] The error message\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kError] = options.error === undefined ? null : options.error;\n this[kMessage] = options.message === undefined ? '' : options.message;\n }\n\n /**\n * @type {*}\n */\n get error() {\n return this[kError];\n }\n\n /**\n * @type {String}\n */\n get message() {\n return this[kMessage];\n }\n}\n\nObject.defineProperty(ErrorEvent.prototype, 'error', { enumerable: true });\nObject.defineProperty(ErrorEvent.prototype, 'message', { enumerable: true });\n\n/**\n * Class representing a message event.\n *\n * @extends Event\n */\nclass MessageEvent extends Event {\n /**\n * Create a new `MessageEvent`.\n *\n * @param {String} type The name of the event\n * @param {Object} [options] A dictionary object that allows for setting\n * attributes via object members of the same name\n * @param {*} [options.data=null] The message content\n */\n constructor(type, options = {}) {\n super(type);\n\n this[kData] = options.data === undefined ? null : options.data;\n }\n\n /**\n * @type {*}\n */\n get data() {\n return this[kData];\n }\n}\n\nObject.defineProperty(MessageEvent.prototype, 'data', { enumerable: true });\n\n/**\n * This provides methods for emulating the `EventTarget` interface. It's not\n * meant to be used directly.\n *\n * @mixin\n */\nconst EventTarget = {\n /**\n * Register an event listener.\n *\n * @param {String} type A string representing the event type to listen for\n * @param {(Function|Object)} handler The listener to add\n * @param {Object} [options] An options object specifies characteristics about\n * the event listener\n * @param {Boolean} [options.once=false] A `Boolean` indicating that the\n * listener should be invoked at most once after being added. If `true`,\n * the listener would be automatically removed when invoked.\n * @public\n */\n addEventListener(type, handler, options = {}) {\n for (const listener of this.listeners(type)) {\n if (\n !options[kForOnEventAttribute] &&\n listener[kListener] === handler &&\n !listener[kForOnEventAttribute]\n ) {\n return;\n }\n }\n\n let wrapper;\n\n if (type === 'message') {\n wrapper = function onMessage(data, isBinary) {\n const event = new MessageEvent('message', {\n data: isBinary ? data : data.toString()\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'close') {\n wrapper = function onClose(code, message) {\n const event = new CloseEvent('close', {\n code,\n reason: message.toString(),\n wasClean: this._closeFrameReceived && this._closeFrameSent\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'error') {\n wrapper = function onError(error) {\n const event = new ErrorEvent('error', {\n error,\n message: error.message\n });\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else if (type === 'open') {\n wrapper = function onOpen() {\n const event = new Event('open');\n\n event[kTarget] = this;\n callListener(handler, this, event);\n };\n } else {\n return;\n }\n\n wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];\n wrapper[kListener] = handler;\n\n if (options.once) {\n this.once(type, wrapper);\n } else {\n this.on(type, wrapper);\n }\n },\n\n /**\n * Remove an event listener.\n *\n * @param {String} type A string representing the event type to remove\n * @param {(Function|Object)} handler The listener to remove\n * @public\n */\n removeEventListener(type, handler) {\n for (const listener of this.listeners(type)) {\n if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {\n this.removeListener(type, listener);\n break;\n }\n }\n }\n};\n\nmodule.exports = {\n CloseEvent,\n ErrorEvent,\n Event,\n EventTarget,\n MessageEvent\n};\n\n/**\n * Call an event listener\n *\n * @param {(Function|Object)} listener The listener to call\n * @param {*} thisArg The value to use as `this`` when calling the listener\n * @param {Event} event The event to pass to the listener\n * @private\n */\nfunction callListener(listener, thisArg, event) {\n if (typeof listener === 'object' && listener.handleEvent) {\n listener.handleEvent.call(listener, event);\n } else {\n listener.call(thisArg, event);\n }\n}\n", "'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Adds an offer to the map of extension offers or a parameter to the map of\n * parameters.\n *\n * @param {Object} dest The map of extension offers or parameters\n * @param {String} name The extension or parameter name\n * @param {(Object|Boolean|String)} elem The extension parameters or the\n * parameter value\n * @private\n */\nfunction push(dest, name, elem) {\n if (dest[name] === undefined) dest[name] = [elem];\n else dest[name].push(elem);\n}\n\n/**\n * Parses the `Sec-WebSocket-Extensions` header into an object.\n *\n * @param {String} header The field value of the header\n * @return {Object} The parsed object\n * @public\n */\nfunction parse(header) {\n const offers = Object.create(null);\n let params = Object.create(null);\n let mustUnescape = false;\n let isEscaping = false;\n let inQuotes = false;\n let extensionName;\n let paramName;\n let start = -1;\n let code = -1;\n let end = -1;\n let i = 0;\n\n for (; i < header.length; i++) {\n code = header.charCodeAt(i);\n\n if (extensionName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n const name = header.slice(start, end);\n if (code === 0x2c) {\n push(offers, name, params);\n params = Object.create(null);\n } else {\n extensionName = name;\n }\n\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (paramName === undefined) {\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x20 || code === 0x09) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n push(params, header.slice(start, end), true);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n start = end = -1;\n } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {\n paramName = header.slice(start, i);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else {\n //\n // The value of a quoted-string after unescaping must conform to the\n // token ABNF, so only token characters are valid.\n // Ref: https://tools.ietf.org/html/rfc6455#section-9.1\n //\n if (isEscaping) {\n if (tokenChars[code] !== 1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n if (start === -1) start = i;\n else if (!mustUnescape) mustUnescape = true;\n isEscaping = false;\n } else if (inQuotes) {\n if (tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (code === 0x22 /* '\"' */ && start !== -1) {\n inQuotes = false;\n end = i;\n } else if (code === 0x5c /* '\\' */) {\n isEscaping = true;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {\n inQuotes = true;\n } else if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (start !== -1 && (code === 0x20 || code === 0x09)) {\n if (end === -1) end = i;\n } else if (code === 0x3b || code === 0x2c) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n let value = header.slice(start, end);\n if (mustUnescape) {\n value = value.replace(/\\\\/g, '');\n mustUnescape = false;\n }\n push(params, paramName, value);\n if (code === 0x2c) {\n push(offers, extensionName, params);\n params = Object.create(null);\n extensionName = undefined;\n }\n\n paramName = undefined;\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n }\n\n if (start === -1 || inQuotes || code === 0x20 || code === 0x09) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n if (end === -1) end = i;\n const token = header.slice(start, end);\n if (extensionName === undefined) {\n push(offers, token, params);\n } else {\n if (paramName === undefined) {\n push(params, token, true);\n } else if (mustUnescape) {\n push(params, paramName, token.replace(/\\\\/g, ''));\n } else {\n push(params, paramName, token);\n }\n push(offers, extensionName, params);\n }\n\n return offers;\n}\n\n/**\n * Builds the `Sec-WebSocket-Extensions` header field value.\n *\n * @param {Object} extensions The map of extensions and parameters to format\n * @return {String} A string representing the given object\n * @public\n */\nfunction format(extensions) {\n return Object.keys(extensions)\n .map((extension) => {\n let configurations = extensions[extension];\n if (!Array.isArray(configurations)) configurations = [configurations];\n return configurations\n .map((params) => {\n return [extension]\n .concat(\n Object.keys(params).map((k) => {\n let values = params[k];\n if (!Array.isArray(values)) values = [values];\n return values\n .map((v) => (v === true ? k : `${k}=${v}`))\n .join('; ');\n })\n )\n .join('; ');\n })\n .join(', ');\n })\n .join(', ');\n}\n\nmodule.exports = { format, parse };\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex|Readable$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst https = require('https');\nconst http = require('http');\nconst net = require('net');\nconst tls = require('tls');\nconst { randomBytes, createHash } = require('crypto');\nconst { Duplex, Readable } = require('stream');\nconst { URL } = require('url');\n\nconst PerMessageDeflate = require('./permessage-deflate');\nconst Receiver = require('./receiver');\nconst Sender = require('./sender');\nconst { isBlob } = require('./validation');\n\nconst {\n BINARY_TYPES,\n EMPTY_BUFFER,\n GUID,\n kForOnEventAttribute,\n kListener,\n kStatusCode,\n kWebSocket,\n NOOP\n} = require('./constants');\nconst {\n EventTarget: { addEventListener, removeEventListener }\n} = require('./event-target');\nconst { format, parse } = require('./extension');\nconst { toBuffer } = require('./buffer-util');\n\nconst closeTimeout = 30 * 1000;\nconst kAborted = Symbol('kAborted');\nconst protocolVersions = [8, 13];\nconst readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];\nconst subprotocolRegex = /^[!#$%&'*+\\-.0-9A-Z^_`|a-z~]+$/;\n\n/**\n * Class representing a WebSocket.\n *\n * @extends EventEmitter\n */\nclass WebSocket extends EventEmitter {\n /**\n * Create a new `WebSocket`.\n *\n * @param {(String|URL)} address The URL to which to connect\n * @param {(String|String[])} [protocols] The subprotocols\n * @param {Object} [options] Connection options\n */\n constructor(address, protocols, options) {\n super();\n\n this._binaryType = BINARY_TYPES[0];\n this._closeCode = 1006;\n this._closeFrameReceived = false;\n this._closeFrameSent = false;\n this._closeMessage = EMPTY_BUFFER;\n this._closeTimer = null;\n this._errorEmitted = false;\n this._extensions = {};\n this._paused = false;\n this._protocol = '';\n this._readyState = WebSocket.CONNECTING;\n this._receiver = null;\n this._sender = null;\n this._socket = null;\n\n if (address !== null) {\n this._bufferedAmount = 0;\n this._isServer = false;\n this._redirects = 0;\n\n if (protocols === undefined) {\n protocols = [];\n } else if (!Array.isArray(protocols)) {\n if (typeof protocols === 'object' && protocols !== null) {\n options = protocols;\n protocols = [];\n } else {\n protocols = [protocols];\n }\n }\n\n initAsClient(this, address, protocols, options);\n } else {\n this._autoPong = options.autoPong;\n this._isServer = true;\n }\n }\n\n /**\n * For historical reasons, the custom \"nodebuffer\" type is used by the default\n * instead of \"blob\".\n *\n * @type {String}\n */\n get binaryType() {\n return this._binaryType;\n }\n\n set binaryType(type) {\n if (!BINARY_TYPES.includes(type)) return;\n\n this._binaryType = type;\n\n //\n // Allow to change `binaryType` on the fly.\n //\n if (this._receiver) this._receiver._binaryType = type;\n }\n\n /**\n * @type {Number}\n */\n get bufferedAmount() {\n if (!this._socket) return this._bufferedAmount;\n\n return this._socket._writableState.length + this._sender._bufferedBytes;\n }\n\n /**\n * @type {String}\n */\n get extensions() {\n return Object.keys(this._extensions).join();\n }\n\n /**\n * @type {Boolean}\n */\n get isPaused() {\n return this._paused;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onclose() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onerror() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onopen() {\n return null;\n }\n\n /**\n * @type {Function}\n */\n /* istanbul ignore next */\n get onmessage() {\n return null;\n }\n\n /**\n * @type {String}\n */\n get protocol() {\n return this._protocol;\n }\n\n /**\n * @type {Number}\n */\n get readyState() {\n return this._readyState;\n }\n\n /**\n * @type {String}\n */\n get url() {\n return this._url;\n }\n\n /**\n * Set up the socket and the internal resources.\n *\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Object} options Options object\n * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.maxPayload=0] The maximum allowed message size\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\n setSocket(socket, head, options) {\n const receiver = new Receiver({\n allowSynchronousEvents: options.allowSynchronousEvents,\n binaryType: this.binaryType,\n extensions: this._extensions,\n isServer: this._isServer,\n maxPayload: options.maxPayload,\n skipUTF8Validation: options.skipUTF8Validation\n });\n\n const sender = new Sender(socket, this._extensions, options.generateMask);\n\n this._receiver = receiver;\n this._sender = sender;\n this._socket = socket;\n\n receiver[kWebSocket] = this;\n sender[kWebSocket] = this;\n socket[kWebSocket] = this;\n\n receiver.on('conclude', receiverOnConclude);\n receiver.on('drain', receiverOnDrain);\n receiver.on('error', receiverOnError);\n receiver.on('message', receiverOnMessage);\n receiver.on('ping', receiverOnPing);\n receiver.on('pong', receiverOnPong);\n\n sender.onerror = senderOnError;\n\n //\n // These methods may not be available if `socket` is just a `Duplex`.\n //\n if (socket.setTimeout) socket.setTimeout(0);\n if (socket.setNoDelay) socket.setNoDelay();\n\n if (head.length > 0) socket.unshift(head);\n\n socket.on('close', socketOnClose);\n socket.on('data', socketOnData);\n socket.on('end', socketOnEnd);\n socket.on('error', socketOnError);\n\n this._readyState = WebSocket.OPEN;\n this.emit('open');\n }\n\n /**\n * Emit the `'close'` event.\n *\n * @private\n */\n emitClose() {\n if (!this._socket) {\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n return;\n }\n\n if (this._extensions[PerMessageDeflate.extensionName]) {\n this._extensions[PerMessageDeflate.extensionName].cleanup();\n }\n\n this._receiver.removeAllListeners();\n this._readyState = WebSocket.CLOSED;\n this.emit('close', this._closeCode, this._closeMessage);\n }\n\n /**\n * Start a closing handshake.\n *\n * +----------+ +-----------+ +----------+\n * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -\n * | +----------+ +-----------+ +----------+ |\n * +----------+ +-----------+ |\n * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING\n * +----------+ +-----------+ |\n * | | | +---+ |\n * +------------------------+-->|fin| - - - -\n * | +---+ | +---+\n * - - - - -|fin|<---------------------+\n * +---+\n *\n * @param {Number} [code] Status code explaining why the connection is closing\n * @param {(String|Buffer)} [data] The reason why the connection is\n * closing\n * @public\n */\n close(code, data) {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this.readyState === WebSocket.CLOSING) {\n if (\n this._closeFrameSent &&\n (this._closeFrameReceived || this._receiver._writableState.errorEmitted)\n ) {\n this._socket.end();\n }\n\n return;\n }\n\n this._readyState = WebSocket.CLOSING;\n this._sender.close(code, data, !this._isServer, (err) => {\n //\n // This error is handled by the `'error'` listener on the socket. We only\n // want to know if the close frame has been sent here.\n //\n if (err) return;\n\n this._closeFrameSent = true;\n\n if (\n this._closeFrameReceived ||\n this._receiver._writableState.errorEmitted\n ) {\n this._socket.end();\n }\n });\n\n setCloseTimer(this);\n }\n\n /**\n * Pause the socket.\n *\n * @public\n */\n pause() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = true;\n this._socket.pause();\n }\n\n /**\n * Send a ping.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the ping is sent\n * @public\n */\n ping(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.ping(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Send a pong.\n *\n * @param {*} [data] The data to send\n * @param {Boolean} [mask] Indicates whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when the pong is sent\n * @public\n */\n pong(data, mask, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof data === 'function') {\n cb = data;\n data = mask = undefined;\n } else if (typeof mask === 'function') {\n cb = mask;\n mask = undefined;\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n if (mask === undefined) mask = !this._isServer;\n this._sender.pong(data || EMPTY_BUFFER, mask, cb);\n }\n\n /**\n * Resume the socket.\n *\n * @public\n */\n resume() {\n if (\n this.readyState === WebSocket.CONNECTING ||\n this.readyState === WebSocket.CLOSED\n ) {\n return;\n }\n\n this._paused = false;\n if (!this._receiver._writableState.needDrain) this._socket.resume();\n }\n\n /**\n * Send a data message.\n *\n * @param {*} data The message to send\n * @param {Object} [options] Options object\n * @param {Boolean} [options.binary] Specifies whether `data` is binary or\n * text\n * @param {Boolean} [options.compress] Specifies whether or not to compress\n * `data`\n * @param {Boolean} [options.fin=true] Specifies whether the fragment is the\n * last one\n * @param {Boolean} [options.mask] Specifies whether or not to mask `data`\n * @param {Function} [cb] Callback which is executed when data is written out\n * @public\n */\n send(data, options, cb) {\n if (this.readyState === WebSocket.CONNECTING) {\n throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');\n }\n\n if (typeof options === 'function') {\n cb = options;\n options = {};\n }\n\n if (typeof data === 'number') data = data.toString();\n\n if (this.readyState !== WebSocket.OPEN) {\n sendAfterClose(this, data, cb);\n return;\n }\n\n const opts = {\n binary: typeof data !== 'string',\n mask: !this._isServer,\n compress: true,\n fin: true,\n ...options\n };\n\n if (!this._extensions[PerMessageDeflate.extensionName]) {\n opts.compress = false;\n }\n\n this._sender.send(data || EMPTY_BUFFER, opts, cb);\n }\n\n /**\n * Forcibly close the connection.\n *\n * @public\n */\n terminate() {\n if (this.readyState === WebSocket.CLOSED) return;\n if (this.readyState === WebSocket.CONNECTING) {\n const msg = 'WebSocket was closed before the connection was established';\n abortHandshake(this, this._req, msg);\n return;\n }\n\n if (this._socket) {\n this._readyState = WebSocket.CLOSING;\n this._socket.destroy();\n }\n }\n}\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} CONNECTING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CONNECTING', {\n enumerable: true,\n value: readyStates.indexOf('CONNECTING')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} OPEN\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'OPEN', {\n enumerable: true,\n value: readyStates.indexOf('OPEN')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSING\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSING', {\n enumerable: true,\n value: readyStates.indexOf('CLOSING')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket\n */\nObject.defineProperty(WebSocket, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n/**\n * @constant {Number} CLOSED\n * @memberof WebSocket.prototype\n */\nObject.defineProperty(WebSocket.prototype, 'CLOSED', {\n enumerable: true,\n value: readyStates.indexOf('CLOSED')\n});\n\n[\n 'binaryType',\n 'bufferedAmount',\n 'extensions',\n 'isPaused',\n 'protocol',\n 'readyState',\n 'url'\n].forEach((property) => {\n Object.defineProperty(WebSocket.prototype, property, { enumerable: true });\n});\n\n//\n// Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.\n// See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface\n//\n['open', 'error', 'close', 'message'].forEach((method) => {\n Object.defineProperty(WebSocket.prototype, `on${method}`, {\n enumerable: true,\n get() {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) return listener[kListener];\n }\n\n return null;\n },\n set(handler) {\n for (const listener of this.listeners(method)) {\n if (listener[kForOnEventAttribute]) {\n this.removeListener(method, listener);\n break;\n }\n }\n\n if (typeof handler !== 'function') return;\n\n this.addEventListener(method, handler, {\n [kForOnEventAttribute]: true\n });\n }\n });\n});\n\nWebSocket.prototype.addEventListener = addEventListener;\nWebSocket.prototype.removeEventListener = removeEventListener;\n\nmodule.exports = WebSocket;\n\n/**\n * Initialize a WebSocket client.\n *\n * @param {WebSocket} websocket The client to initialize\n * @param {(String|URL)} address The URL to which to connect\n * @param {Array} protocols The subprotocols\n * @param {Object} [options] Connection options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any\n * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple\n * times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Function} [options.finishRequest] A function which can be used to\n * customize the headers of each http request before it is sent\n * @param {Boolean} [options.followRedirects=false] Whether or not to follow\n * redirects\n * @param {Function} [options.generateMask] The function used to generate the\n * masking key\n * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the\n * handshake request\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Number} [options.maxRedirects=10] The maximum number of redirects\n * allowed\n * @param {String} [options.origin] Value of the `Origin` or\n * `Sec-WebSocket-Origin` header\n * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable\n * permessage-deflate\n * @param {Number} [options.protocolVersion=13] Value of the\n * `Sec-WebSocket-Version` header\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @private\n */\nfunction initAsClient(websocket, address, protocols, options) {\n const opts = {\n allowSynchronousEvents: true,\n autoPong: true,\n protocolVersion: protocolVersions[1],\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: true,\n followRedirects: false,\n maxRedirects: 10,\n ...options,\n socketPath: undefined,\n hostname: undefined,\n protocol: undefined,\n timeout: undefined,\n method: 'GET',\n host: undefined,\n path: undefined,\n port: undefined\n };\n\n websocket._autoPong = opts.autoPong;\n\n if (!protocolVersions.includes(opts.protocolVersion)) {\n throw new RangeError(\n `Unsupported protocol version: ${opts.protocolVersion} ` +\n `(supported versions: ${protocolVersions.join(', ')})`\n );\n }\n\n let parsedUrl;\n\n if (address instanceof URL) {\n parsedUrl = address;\n } else {\n try {\n parsedUrl = new URL(address);\n } catch (e) {\n throw new SyntaxError(`Invalid URL: ${address}`);\n }\n }\n\n if (parsedUrl.protocol === 'http:') {\n parsedUrl.protocol = 'ws:';\n } else if (parsedUrl.protocol === 'https:') {\n parsedUrl.protocol = 'wss:';\n }\n\n websocket._url = parsedUrl.href;\n\n const isSecure = parsedUrl.protocol === 'wss:';\n const isIpcUrl = parsedUrl.protocol === 'ws+unix:';\n let invalidUrlMessage;\n\n if (parsedUrl.protocol !== 'ws:' && !isSecure && !isIpcUrl) {\n invalidUrlMessage =\n 'The URL\\'s protocol must be one of \"ws:\", \"wss:\", ' +\n '\"http:\", \"https\", or \"ws+unix:\"';\n } else if (isIpcUrl && !parsedUrl.pathname) {\n invalidUrlMessage = \"The URL's pathname is empty\";\n } else if (parsedUrl.hash) {\n invalidUrlMessage = 'The URL contains a fragment identifier';\n }\n\n if (invalidUrlMessage) {\n const err = new SyntaxError(invalidUrlMessage);\n\n if (websocket._redirects === 0) {\n throw err;\n } else {\n emitErrorAndClose(websocket, err);\n return;\n }\n }\n\n const defaultPort = isSecure ? 443 : 80;\n const key = randomBytes(16).toString('base64');\n const request = isSecure ? https.request : http.request;\n const protocolSet = new Set();\n let perMessageDeflate;\n\n opts.createConnection =\n opts.createConnection || (isSecure ? tlsConnect : netConnect);\n opts.defaultPort = opts.defaultPort || defaultPort;\n opts.port = parsedUrl.port || defaultPort;\n opts.host = parsedUrl.hostname.startsWith('[')\n ? parsedUrl.hostname.slice(1, -1)\n : parsedUrl.hostname;\n opts.headers = {\n ...opts.headers,\n 'Sec-WebSocket-Version': opts.protocolVersion,\n 'Sec-WebSocket-Key': key,\n Connection: 'Upgrade',\n Upgrade: 'websocket'\n };\n opts.path = parsedUrl.pathname + parsedUrl.search;\n opts.timeout = opts.handshakeTimeout;\n\n if (opts.perMessageDeflate) {\n perMessageDeflate = new PerMessageDeflate(\n opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},\n false,\n opts.maxPayload\n );\n opts.headers['Sec-WebSocket-Extensions'] = format({\n [PerMessageDeflate.extensionName]: perMessageDeflate.offer()\n });\n }\n if (protocols.length) {\n for (const protocol of protocols) {\n if (\n typeof protocol !== 'string' ||\n !subprotocolRegex.test(protocol) ||\n protocolSet.has(protocol)\n ) {\n throw new SyntaxError(\n 'An invalid or duplicated subprotocol was specified'\n );\n }\n\n protocolSet.add(protocol);\n }\n\n opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');\n }\n if (opts.origin) {\n if (opts.protocolVersion < 13) {\n opts.headers['Sec-WebSocket-Origin'] = opts.origin;\n } else {\n opts.headers.Origin = opts.origin;\n }\n }\n if (parsedUrl.username || parsedUrl.password) {\n opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;\n }\n\n if (isIpcUrl) {\n const parts = opts.path.split(':');\n\n opts.socketPath = parts[0];\n opts.path = parts[1];\n }\n\n let req;\n\n if (opts.followRedirects) {\n if (websocket._redirects === 0) {\n websocket._originalIpc = isIpcUrl;\n websocket._originalSecure = isSecure;\n websocket._originalHostOrSocketPath = isIpcUrl\n ? opts.socketPath\n : parsedUrl.host;\n\n const headers = options && options.headers;\n\n //\n // Shallow copy the user provided options so that headers can be changed\n // without mutating the original object.\n //\n options = { ...options, headers: {} };\n\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n options.headers[key.toLowerCase()] = value;\n }\n }\n } else if (websocket.listenerCount('redirect') === 0) {\n const isSameHost = isIpcUrl\n ? websocket._originalIpc\n ? opts.socketPath === websocket._originalHostOrSocketPath\n : false\n : websocket._originalIpc\n ? false\n : parsedUrl.host === websocket._originalHostOrSocketPath;\n\n if (!isSameHost || (websocket._originalSecure && !isSecure)) {\n //\n // Match curl 7.77.0 behavior and drop the following headers. These\n // headers are also dropped when following a redirect to a subdomain.\n //\n delete opts.headers.authorization;\n delete opts.headers.cookie;\n\n if (!isSameHost) delete opts.headers.host;\n\n opts.auth = undefined;\n }\n }\n\n //\n // Match curl 7.77.0 behavior and make the first `Authorization` header win.\n // If the `Authorization` header is set, then there is nothing to do as it\n // will take precedence.\n //\n if (opts.auth && !options.headers.authorization) {\n options.headers.authorization =\n 'Basic ' + Buffer.from(opts.auth).toString('base64');\n }\n\n req = websocket._req = request(opts);\n\n if (websocket._redirects) {\n //\n // Unlike what is done for the `'upgrade'` event, no early exit is\n // triggered here if the user calls `websocket.close()` or\n // `websocket.terminate()` from a listener of the `'redirect'` event. This\n // is because the user can also call `request.destroy()` with an error\n // before calling `websocket.close()` or `websocket.terminate()` and this\n // would result in an error being emitted on the `request` object with no\n // `'error'` event listeners attached.\n //\n websocket.emit('redirect', websocket.url, req);\n }\n } else {\n req = websocket._req = request(opts);\n }\n\n if (opts.timeout) {\n req.on('timeout', () => {\n abortHandshake(websocket, req, 'Opening handshake has timed out');\n });\n }\n\n req.on('error', (err) => {\n if (req === null || req[kAborted]) return;\n\n req = websocket._req = null;\n emitErrorAndClose(websocket, err);\n });\n\n req.on('response', (res) => {\n const location = res.headers.location;\n const statusCode = res.statusCode;\n\n if (\n location &&\n opts.followRedirects &&\n statusCode >= 300 &&\n statusCode < 400\n ) {\n if (++websocket._redirects > opts.maxRedirects) {\n abortHandshake(websocket, req, 'Maximum redirects exceeded');\n return;\n }\n\n req.abort();\n\n let addr;\n\n try {\n addr = new URL(location, address);\n } catch (e) {\n const err = new SyntaxError(`Invalid URL: ${location}`);\n emitErrorAndClose(websocket, err);\n return;\n }\n\n initAsClient(websocket, addr, protocols, options);\n } else if (!websocket.emit('unexpected-response', req, res)) {\n abortHandshake(\n websocket,\n req,\n `Unexpected server response: ${res.statusCode}`\n );\n }\n });\n\n req.on('upgrade', (res, socket, head) => {\n websocket.emit('upgrade', res);\n\n //\n // The user may have closed the connection from a listener of the\n // `'upgrade'` event.\n //\n if (websocket.readyState !== WebSocket.CONNECTING) return;\n\n req = websocket._req = null;\n\n const upgrade = res.headers.upgrade;\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n abortHandshake(websocket, socket, 'Invalid Upgrade header');\n return;\n }\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n if (res.headers['sec-websocket-accept'] !== digest) {\n abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');\n return;\n }\n\n const serverProt = res.headers['sec-websocket-protocol'];\n let protError;\n\n if (serverProt !== undefined) {\n if (!protocolSet.size) {\n protError = 'Server sent a subprotocol but none was requested';\n } else if (!protocolSet.has(serverProt)) {\n protError = 'Server sent an invalid subprotocol';\n }\n } else if (protocolSet.size) {\n protError = 'Server sent no subprotocol';\n }\n\n if (protError) {\n abortHandshake(websocket, socket, protError);\n return;\n }\n\n if (serverProt) websocket._protocol = serverProt;\n\n const secWebSocketExtensions = res.headers['sec-websocket-extensions'];\n\n if (secWebSocketExtensions !== undefined) {\n if (!perMessageDeflate) {\n const message =\n 'Server sent a Sec-WebSocket-Extensions header but no extension ' +\n 'was requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n let extensions;\n\n try {\n extensions = parse(secWebSocketExtensions);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n const extensionNames = Object.keys(extensions);\n\n if (\n extensionNames.length !== 1 ||\n extensionNames[0] !== PerMessageDeflate.extensionName\n ) {\n const message = 'Server indicated an extension that was not requested';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n try {\n perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Extensions header';\n abortHandshake(websocket, socket, message);\n return;\n }\n\n websocket._extensions[PerMessageDeflate.extensionName] =\n perMessageDeflate;\n }\n\n websocket.setSocket(socket, head, {\n allowSynchronousEvents: opts.allowSynchronousEvents,\n generateMask: opts.generateMask,\n maxPayload: opts.maxPayload,\n skipUTF8Validation: opts.skipUTF8Validation\n });\n });\n\n if (opts.finishRequest) {\n opts.finishRequest(req, websocket);\n } else {\n req.end();\n }\n}\n\n/**\n * Emit the `'error'` and `'close'` events.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {Error} The error to emit\n * @private\n */\nfunction emitErrorAndClose(websocket, err) {\n websocket._readyState = WebSocket.CLOSING;\n //\n // The following assignment is practically useless and is done only for\n // consistency.\n //\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n websocket.emitClose();\n}\n\n/**\n * Create a `net.Socket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {net.Socket} The newly created socket used to start the connection\n * @private\n */\nfunction netConnect(options) {\n options.path = options.socketPath;\n return net.connect(options);\n}\n\n/**\n * Create a `tls.TLSSocket` and initiate a connection.\n *\n * @param {Object} options Connection options\n * @return {tls.TLSSocket} The newly created socket used to start the connection\n * @private\n */\nfunction tlsConnect(options) {\n options.path = undefined;\n\n if (!options.servername && options.servername !== '') {\n options.servername = net.isIP(options.host) ? '' : options.host;\n }\n\n return tls.connect(options);\n}\n\n/**\n * Abort the handshake and emit an error.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to\n * abort or the socket to destroy\n * @param {String} message The error message\n * @private\n */\nfunction abortHandshake(websocket, stream, message) {\n websocket._readyState = WebSocket.CLOSING;\n\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshake);\n\n if (stream.setHeader) {\n stream[kAborted] = true;\n stream.abort();\n\n if (stream.socket && !stream.socket.destroyed) {\n //\n // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if\n // called after the request completed. See\n // https://github.com/websockets/ws/issues/1869.\n //\n stream.socket.destroy();\n }\n\n process.nextTick(emitErrorAndClose, websocket, err);\n } else {\n stream.destroy(err);\n stream.once('error', websocket.emit.bind(websocket, 'error'));\n stream.once('close', websocket.emitClose.bind(websocket));\n }\n}\n\n/**\n * Handle cases where the `ping()`, `pong()`, or `send()` methods are called\n * when the `readyState` attribute is `CLOSING` or `CLOSED`.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @param {*} [data] The data to send\n * @param {Function} [cb] Callback\n * @private\n */\nfunction sendAfterClose(websocket, data, cb) {\n if (data) {\n const length = isBlob(data) ? data.size : toBuffer(data).length;\n\n //\n // The `_bufferedAmount` property is used only when the peer is a client and\n // the opening handshake fails. Under these circumstances, in fact, the\n // `setSocket()` method is not called, so the `_socket` and `_sender`\n // properties are set to `null`.\n //\n if (websocket._socket) websocket._sender._bufferedBytes += length;\n else websocket._bufferedAmount += length;\n }\n\n if (cb) {\n const err = new Error(\n `WebSocket is not open: readyState ${websocket.readyState} ` +\n `(${readyStates[websocket.readyState]})`\n );\n process.nextTick(cb, err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'conclude'` event.\n *\n * @param {Number} code The status code\n * @param {Buffer} reason The reason for closing\n * @private\n */\nfunction receiverOnConclude(code, reason) {\n const websocket = this[kWebSocket];\n\n websocket._closeFrameReceived = true;\n websocket._closeMessage = reason;\n websocket._closeCode = code;\n\n if (websocket._socket[kWebSocket] === undefined) return;\n\n websocket._socket.removeListener('data', socketOnData);\n process.nextTick(resume, websocket._socket);\n\n if (code === 1005) websocket.close();\n else websocket.close(code, reason);\n}\n\n/**\n * The listener of the `Receiver` `'drain'` event.\n *\n * @private\n */\nfunction receiverOnDrain() {\n const websocket = this[kWebSocket];\n\n if (!websocket.isPaused) websocket._socket.resume();\n}\n\n/**\n * The listener of the `Receiver` `'error'` event.\n *\n * @param {(RangeError|Error)} err The emitted error\n * @private\n */\nfunction receiverOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket._socket[kWebSocket] !== undefined) {\n websocket._socket.removeListener('data', socketOnData);\n\n //\n // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See\n // https://github.com/websockets/ws/issues/1940.\n //\n process.nextTick(resume, websocket._socket);\n\n websocket.close(err[kStatusCode]);\n }\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * The listener of the `Receiver` `'finish'` event.\n *\n * @private\n */\nfunction receiverOnFinish() {\n this[kWebSocket].emitClose();\n}\n\n/**\n * The listener of the `Receiver` `'message'` event.\n *\n * @param {Buffer|ArrayBuffer|Buffer[])} data The message\n * @param {Boolean} isBinary Specifies whether the message is binary or not\n * @private\n */\nfunction receiverOnMessage(data, isBinary) {\n this[kWebSocket].emit('message', data, isBinary);\n}\n\n/**\n * The listener of the `Receiver` `'ping'` event.\n *\n * @param {Buffer} data The data included in the ping frame\n * @private\n */\nfunction receiverOnPing(data) {\n const websocket = this[kWebSocket];\n\n if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);\n websocket.emit('ping', data);\n}\n\n/**\n * The listener of the `Receiver` `'pong'` event.\n *\n * @param {Buffer} data The data included in the pong frame\n * @private\n */\nfunction receiverOnPong(data) {\n this[kWebSocket].emit('pong', data);\n}\n\n/**\n * Resume a readable stream\n *\n * @param {Readable} stream The readable stream\n * @private\n */\nfunction resume(stream) {\n stream.resume();\n}\n\n/**\n * The `Sender` error event handler.\n *\n * @param {Error} The error\n * @private\n */\nfunction senderOnError(err) {\n const websocket = this[kWebSocket];\n\n if (websocket.readyState === WebSocket.CLOSED) return;\n if (websocket.readyState === WebSocket.OPEN) {\n websocket._readyState = WebSocket.CLOSING;\n setCloseTimer(websocket);\n }\n\n //\n // `socket.end()` is used instead of `socket.destroy()` to allow the other\n // peer to finish sending queued data. There is no need to set a timer here\n // because `CLOSING` means that it is already set or not needed.\n //\n this._socket.end();\n\n if (!websocket._errorEmitted) {\n websocket._errorEmitted = true;\n websocket.emit('error', err);\n }\n}\n\n/**\n * Set a timer to destroy the underlying raw socket of a WebSocket.\n *\n * @param {WebSocket} websocket The WebSocket instance\n * @private\n */\nfunction setCloseTimer(websocket) {\n websocket._closeTimer = setTimeout(\n websocket._socket.destroy.bind(websocket._socket),\n closeTimeout\n );\n}\n\n/**\n * The listener of the socket `'close'` event.\n *\n * @private\n */\nfunction socketOnClose() {\n const websocket = this[kWebSocket];\n\n this.removeListener('close', socketOnClose);\n this.removeListener('data', socketOnData);\n this.removeListener('end', socketOnEnd);\n\n websocket._readyState = WebSocket.CLOSING;\n\n let chunk;\n\n //\n // The close frame might not have been received or the `'end'` event emitted,\n // for example, if the socket was destroyed due to an error. Ensure that the\n // `receiver` stream is closed after writing any remaining buffered data to\n // it. If the readable side of the socket is in flowing mode then there is no\n // buffered data as everything has been already written and `readable.read()`\n // will return `null`. If instead, the socket is paused, any possible buffered\n // data will be read as a single chunk.\n //\n if (\n !this._readableState.endEmitted &&\n !websocket._closeFrameReceived &&\n !websocket._receiver._writableState.errorEmitted &&\n (chunk = websocket._socket.read()) !== null\n ) {\n websocket._receiver.write(chunk);\n }\n\n websocket._receiver.end();\n\n this[kWebSocket] = undefined;\n\n clearTimeout(websocket._closeTimer);\n\n if (\n websocket._receiver._writableState.finished ||\n websocket._receiver._writableState.errorEmitted\n ) {\n websocket.emitClose();\n } else {\n websocket._receiver.on('error', receiverOnFinish);\n websocket._receiver.on('finish', receiverOnFinish);\n }\n}\n\n/**\n * The listener of the socket `'data'` event.\n *\n * @param {Buffer} chunk A chunk of data\n * @private\n */\nfunction socketOnData(chunk) {\n if (!this[kWebSocket]._receiver.write(chunk)) {\n this.pause();\n }\n}\n\n/**\n * The listener of the socket `'end'` event.\n *\n * @private\n */\nfunction socketOnEnd() {\n const websocket = this[kWebSocket];\n\n websocket._readyState = WebSocket.CLOSING;\n websocket._receiver.end();\n this.end();\n}\n\n/**\n * The listener of the socket `'error'` event.\n *\n * @private\n */\nfunction socketOnError() {\n const websocket = this[kWebSocket];\n\n this.removeListener('error', socketOnError);\n this.on('error', NOOP);\n\n if (websocket) {\n websocket._readyState = WebSocket.CLOSING;\n this.destroy();\n }\n}\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^WebSocket$\" }] */\n'use strict';\n\nconst WebSocket = require('./websocket');\nconst { Duplex } = require('stream');\n\n/**\n * Emits the `'close'` event on a stream.\n *\n * @param {Duplex} stream The stream.\n * @private\n */\nfunction emitClose(stream) {\n stream.emit('close');\n}\n\n/**\n * The listener of the `'end'` event.\n *\n * @private\n */\nfunction duplexOnEnd() {\n if (!this.destroyed && this._writableState.finished) {\n this.destroy();\n }\n}\n\n/**\n * The listener of the `'error'` event.\n *\n * @param {Error} err The error\n * @private\n */\nfunction duplexOnError(err) {\n this.removeListener('error', duplexOnError);\n this.destroy();\n if (this.listenerCount('error') === 0) {\n // Do not suppress the throwing behavior.\n this.emit('error', err);\n }\n}\n\n/**\n * Wraps a `WebSocket` in a duplex stream.\n *\n * @param {WebSocket} ws The `WebSocket` to wrap\n * @param {Object} [options] The options for the `Duplex` constructor\n * @return {Duplex} The duplex stream\n * @public\n */\nfunction createWebSocketStream(ws, options) {\n let terminateOnDestroy = true;\n\n const duplex = new Duplex({\n ...options,\n autoDestroy: false,\n emitClose: false,\n objectMode: false,\n writableObjectMode: false\n });\n\n ws.on('message', function message(msg, isBinary) {\n const data =\n !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;\n\n if (!duplex.push(data)) ws.pause();\n });\n\n ws.once('error', function error(err) {\n if (duplex.destroyed) return;\n\n // Prevent `ws.terminate()` from being called by `duplex._destroy()`.\n //\n // - If the `'error'` event is emitted before the `'open'` event, then\n // `ws.terminate()` is a noop as no socket is assigned.\n // - Otherwise, the error is re-emitted by the listener of the `'error'`\n // event of the `Receiver` object. The listener already closes the\n // connection by calling `ws.close()`. This allows a close frame to be\n // sent to the other peer. If `ws.terminate()` is called right after this,\n // then the close frame might not be sent.\n terminateOnDestroy = false;\n duplex.destroy(err);\n });\n\n ws.once('close', function close() {\n if (duplex.destroyed) return;\n\n duplex.push(null);\n });\n\n duplex._destroy = function (err, callback) {\n if (ws.readyState === ws.CLOSED) {\n callback(err);\n process.nextTick(emitClose, duplex);\n return;\n }\n\n let called = false;\n\n ws.once('error', function error(err) {\n called = true;\n callback(err);\n });\n\n ws.once('close', function close() {\n if (!called) callback(err);\n process.nextTick(emitClose, duplex);\n });\n\n if (terminateOnDestroy) ws.terminate();\n };\n\n duplex._final = function (callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._final(callback);\n });\n return;\n }\n\n // If the value of the `_socket` property is `null` it means that `ws` is a\n // client websocket and the handshake failed. In fact, when this happens, a\n // socket is never assigned to the websocket. Wait for the `'error'` event\n // that will be emitted by the websocket.\n if (ws._socket === null) return;\n\n if (ws._socket._writableState.finished) {\n callback();\n if (duplex._readableState.endEmitted) duplex.destroy();\n } else {\n ws._socket.once('finish', function finish() {\n // `duplex` is not destroyed here because the `'end'` event will be\n // emitted on `duplex` after this `'finish'` event. The EOF signaling\n // `null` chunk is, in fact, pushed when the websocket emits `'close'`.\n callback();\n });\n ws.close();\n }\n };\n\n duplex._read = function () {\n if (ws.isPaused) ws.resume();\n };\n\n duplex._write = function (chunk, encoding, callback) {\n if (ws.readyState === ws.CONNECTING) {\n ws.once('open', function open() {\n duplex._write(chunk, encoding, callback);\n });\n return;\n }\n\n ws.send(chunk, callback);\n };\n\n duplex.on('end', duplexOnEnd);\n duplex.on('error', duplexOnError);\n return duplex;\n}\n\nmodule.exports = createWebSocketStream;\n", "'use strict';\n\nconst { tokenChars } = require('./validation');\n\n/**\n * Parses the `Sec-WebSocket-Protocol` header into a set of subprotocol names.\n *\n * @param {String} header The field value of the header\n * @return {Set} The subprotocol names\n * @public\n */\nfunction parse(header) {\n const protocols = new Set();\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (i; i < header.length; i++) {\n const code = header.charCodeAt(i);\n\n if (end === -1 && tokenChars[code] === 1) {\n if (start === -1) start = i;\n } else if (\n i !== 0 &&\n (code === 0x20 /* ' ' */ || code === 0x09) /* '\\t' */\n ) {\n if (end === -1 && start !== -1) end = i;\n } else if (code === 0x2c /* ',' */) {\n if (start === -1) {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n\n if (end === -1) end = i;\n\n const protocol = header.slice(start, end);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n start = end = -1;\n } else {\n throw new SyntaxError(`Unexpected character at index ${i}`);\n }\n }\n\n if (start === -1 || end !== -1) {\n throw new SyntaxError('Unexpected end of input');\n }\n\n const protocol = header.slice(start, i);\n\n if (protocols.has(protocol)) {\n throw new SyntaxError(`The \"${protocol}\" subprotocol is duplicated`);\n }\n\n protocols.add(protocol);\n return protocols;\n}\n\nmodule.exports = { parse };\n", "/* eslint no-unused-vars: [\"error\", { \"varsIgnorePattern\": \"^Duplex$\", \"caughtErrors\": \"none\" }] */\n\n'use strict';\n\nconst EventEmitter = require('events');\nconst http = require('http');\nconst { Duplex } = require('stream');\nconst { createHash } = require('crypto');\n\nconst extension = require('./extension');\nconst PerMessageDeflate = require('./permessage-deflate');\nconst subprotocol = require('./subprotocol');\nconst WebSocket = require('./websocket');\nconst { GUID, kWebSocket } = require('./constants');\n\nconst keyRegex = /^[+/0-9A-Za-z]{22}==$/;\n\nconst RUNNING = 0;\nconst CLOSING = 1;\nconst CLOSED = 2;\n\n/**\n * Class representing a WebSocket server.\n *\n * @extends EventEmitter\n */\nclass WebSocketServer extends EventEmitter {\n /**\n * Create a `WebSocketServer` instance.\n *\n * @param {Object} options Configuration options\n * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether\n * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted\n * multiple times in the same tick\n * @param {Boolean} [options.autoPong=true] Specifies whether or not to\n * automatically send a pong in response to a ping\n * @param {Number} [options.backlog=511] The maximum length of the queue of\n * pending connections\n * @param {Boolean} [options.clientTracking=true] Specifies whether or not to\n * track clients\n * @param {Function} [options.handleProtocols] A hook to handle protocols\n * @param {String} [options.host] The hostname where to bind the server\n * @param {Number} [options.maxPayload=104857600] The maximum allowed message\n * size\n * @param {Boolean} [options.noServer=false] Enable no server mode\n * @param {String} [options.path] Accept only connections matching this path\n * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable\n * permessage-deflate\n * @param {Number} [options.port] The port where to bind the server\n * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S\n * server to use\n * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or\n * not to skip UTF-8 validation for text and close messages\n * @param {Function} [options.verifyClient] A hook to reject connections\n * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`\n * class to use. It must be the `WebSocket` class or class that extends it\n * @param {Function} [callback] A listener for the `listening` event\n */\n constructor(options, callback) {\n super();\n\n options = {\n allowSynchronousEvents: true,\n autoPong: true,\n maxPayload: 100 * 1024 * 1024,\n skipUTF8Validation: false,\n perMessageDeflate: false,\n handleProtocols: null,\n clientTracking: true,\n verifyClient: null,\n noServer: false,\n backlog: null, // use default (511 as implemented in net.js)\n server: null,\n host: null,\n path: null,\n port: null,\n WebSocket,\n ...options\n };\n\n if (\n (options.port == null && !options.server && !options.noServer) ||\n (options.port != null && (options.server || options.noServer)) ||\n (options.server && options.noServer)\n ) {\n throw new TypeError(\n 'One and only one of the \"port\", \"server\", or \"noServer\" options ' +\n 'must be specified'\n );\n }\n\n if (options.port != null) {\n this._server = http.createServer((req, res) => {\n const body = http.STATUS_CODES[426];\n\n res.writeHead(426, {\n 'Content-Length': body.length,\n 'Content-Type': 'text/plain'\n });\n res.end(body);\n });\n this._server.listen(\n options.port,\n options.host,\n options.backlog,\n callback\n );\n } else if (options.server) {\n this._server = options.server;\n }\n\n if (this._server) {\n const emitConnection = this.emit.bind(this, 'connection');\n\n this._removeListeners = addListeners(this._server, {\n listening: this.emit.bind(this, 'listening'),\n error: this.emit.bind(this, 'error'),\n upgrade: (req, socket, head) => {\n this.handleUpgrade(req, socket, head, emitConnection);\n }\n });\n }\n\n if (options.perMessageDeflate === true) options.perMessageDeflate = {};\n if (options.clientTracking) {\n this.clients = new Set();\n this._shouldEmitClose = false;\n }\n\n this.options = options;\n this._state = RUNNING;\n }\n\n /**\n * Returns the bound address, the address family name, and port of the server\n * as reported by the operating system if listening on an IP socket.\n * If the server is listening on a pipe or UNIX domain socket, the name is\n * returned as a string.\n *\n * @return {(Object|String|null)} The address of the server\n * @public\n */\n address() {\n if (this.options.noServer) {\n throw new Error('The server is operating in \"noServer\" mode');\n }\n\n if (!this._server) return null;\n return this._server.address();\n }\n\n /**\n * Stop the server from accepting new connections and emit the `'close'` event\n * when all existing connections are closed.\n *\n * @param {Function} [cb] A one-time listener for the `'close'` event\n * @public\n */\n close(cb) {\n if (this._state === CLOSED) {\n if (cb) {\n this.once('close', () => {\n cb(new Error('The server is not running'));\n });\n }\n\n process.nextTick(emitClose, this);\n return;\n }\n\n if (cb) this.once('close', cb);\n\n if (this._state === CLOSING) return;\n this._state = CLOSING;\n\n if (this.options.noServer || this.options.server) {\n if (this._server) {\n this._removeListeners();\n this._removeListeners = this._server = null;\n }\n\n if (this.clients) {\n if (!this.clients.size) {\n process.nextTick(emitClose, this);\n } else {\n this._shouldEmitClose = true;\n }\n } else {\n process.nextTick(emitClose, this);\n }\n } else {\n const server = this._server;\n\n this._removeListeners();\n this._removeListeners = this._server = null;\n\n //\n // The HTTP/S server was created internally. Close it, and rely on its\n // `'close'` event.\n //\n server.close(() => {\n emitClose(this);\n });\n }\n }\n\n /**\n * See if a given request should be handled by this server instance.\n *\n * @param {http.IncomingMessage} req Request object to inspect\n * @return {Boolean} `true` if the request is valid, else `false`\n * @public\n */\n shouldHandle(req) {\n if (this.options.path) {\n const index = req.url.indexOf('?');\n const pathname = index !== -1 ? req.url.slice(0, index) : req.url;\n\n if (pathname !== this.options.path) return false;\n }\n\n return true;\n }\n\n /**\n * Handle a HTTP Upgrade request.\n *\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @public\n */\n handleUpgrade(req, socket, head, cb) {\n socket.on('error', socketOnError);\n\n const key = req.headers['sec-websocket-key'];\n const upgrade = req.headers.upgrade;\n const version = +req.headers['sec-websocket-version'];\n\n if (req.method !== 'GET') {\n const message = 'Invalid HTTP method';\n abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);\n return;\n }\n\n if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {\n const message = 'Invalid Upgrade header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (key === undefined || !keyRegex.test(key)) {\n const message = 'Missing or invalid Sec-WebSocket-Key header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (version !== 8 && version !== 13) {\n const message = 'Missing or invalid Sec-WebSocket-Version header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n\n if (!this.shouldHandle(req)) {\n abortHandshake(socket, 400);\n return;\n }\n\n const secWebSocketProtocol = req.headers['sec-websocket-protocol'];\n let protocols = new Set();\n\n if (secWebSocketProtocol !== undefined) {\n try {\n protocols = subprotocol.parse(secWebSocketProtocol);\n } catch (err) {\n const message = 'Invalid Sec-WebSocket-Protocol header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n const secWebSocketExtensions = req.headers['sec-websocket-extensions'];\n const extensions = {};\n\n if (\n this.options.perMessageDeflate &&\n secWebSocketExtensions !== undefined\n ) {\n const perMessageDeflate = new PerMessageDeflate(\n this.options.perMessageDeflate,\n true,\n this.options.maxPayload\n );\n\n try {\n const offers = extension.parse(secWebSocketExtensions);\n\n if (offers[PerMessageDeflate.extensionName]) {\n perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);\n extensions[PerMessageDeflate.extensionName] = perMessageDeflate;\n }\n } catch (err) {\n const message =\n 'Invalid or unacceptable Sec-WebSocket-Extensions header';\n abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);\n return;\n }\n }\n\n //\n // Optionally call external client verification handler.\n //\n if (this.options.verifyClient) {\n const info = {\n origin:\n req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],\n secure: !!(req.socket.authorized || req.socket.encrypted),\n req\n };\n\n if (this.options.verifyClient.length === 2) {\n this.options.verifyClient(info, (verified, code, message, headers) => {\n if (!verified) {\n return abortHandshake(socket, code || 401, message, headers);\n }\n\n this.completeUpgrade(\n extensions,\n key,\n protocols,\n req,\n socket,\n head,\n cb\n );\n });\n return;\n }\n\n if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);\n }\n\n this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);\n }\n\n /**\n * Upgrade the connection to WebSocket.\n *\n * @param {Object} extensions The accepted extensions\n * @param {String} key The value of the `Sec-WebSocket-Key` header\n * @param {Set} protocols The subprotocols\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The network socket between the server and client\n * @param {Buffer} head The first packet of the upgraded stream\n * @param {Function} cb Callback\n * @throws {Error} If called more than once with the same socket\n * @private\n */\n completeUpgrade(extensions, key, protocols, req, socket, head, cb) {\n //\n // Destroy the socket if the client has already sent a FIN packet.\n //\n if (!socket.readable || !socket.writable) return socket.destroy();\n\n if (socket[kWebSocket]) {\n throw new Error(\n 'server.handleUpgrade() was called more than once with the same ' +\n 'socket, possibly due to a misconfiguration'\n );\n }\n\n if (this._state > RUNNING) return abortHandshake(socket, 503);\n\n const digest = createHash('sha1')\n .update(key + GUID)\n .digest('base64');\n\n const headers = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${digest}`\n ];\n\n const ws = new this.options.WebSocket(null, undefined, this.options);\n\n if (protocols.size) {\n //\n // Optionally call external protocol selection handler.\n //\n const protocol = this.options.handleProtocols\n ? this.options.handleProtocols(protocols, req)\n : protocols.values().next().value;\n\n if (protocol) {\n headers.push(`Sec-WebSocket-Protocol: ${protocol}`);\n ws._protocol = protocol;\n }\n }\n\n if (extensions[PerMessageDeflate.extensionName]) {\n const params = extensions[PerMessageDeflate.extensionName].params;\n const value = extension.format({\n [PerMessageDeflate.extensionName]: [params]\n });\n headers.push(`Sec-WebSocket-Extensions: ${value}`);\n ws._extensions = extensions;\n }\n\n //\n // Allow external modification/inspection of handshake headers.\n //\n this.emit('headers', headers, req);\n\n socket.write(headers.concat('\\r\\n').join('\\r\\n'));\n socket.removeListener('error', socketOnError);\n\n ws.setSocket(socket, head, {\n allowSynchronousEvents: this.options.allowSynchronousEvents,\n maxPayload: this.options.maxPayload,\n skipUTF8Validation: this.options.skipUTF8Validation\n });\n\n if (this.clients) {\n this.clients.add(ws);\n ws.on('close', () => {\n this.clients.delete(ws);\n\n if (this._shouldEmitClose && !this.clients.size) {\n process.nextTick(emitClose, this);\n }\n });\n }\n\n cb(ws, req);\n }\n}\n\nmodule.exports = WebSocketServer;\n\n/**\n * Add event listeners on an `EventEmitter` using a map of \n * pairs.\n *\n * @param {EventEmitter} server The event emitter\n * @param {Object.} map The listeners to add\n * @return {Function} A function that will remove the added listeners when\n * called\n * @private\n */\nfunction addListeners(server, map) {\n for (const event of Object.keys(map)) server.on(event, map[event]);\n\n return function removeListeners() {\n for (const event of Object.keys(map)) {\n server.removeListener(event, map[event]);\n }\n };\n}\n\n/**\n * Emit a `'close'` event on an `EventEmitter`.\n *\n * @param {EventEmitter} server The event emitter\n * @private\n */\nfunction emitClose(server) {\n server._state = CLOSED;\n server.emit('close');\n}\n\n/**\n * Handle socket errors.\n *\n * @private\n */\nfunction socketOnError() {\n this.destroy();\n}\n\n/**\n * Close the connection when preconditions are not fulfilled.\n *\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} [message] The HTTP response body\n * @param {Object} [headers] Additional HTTP response headers\n * @private\n */\nfunction abortHandshake(socket, code, message, headers) {\n //\n // The socket is writable unless the user destroyed or ended it before calling\n // `server.handleUpgrade()` or in the `verifyClient` function, which is a user\n // error. Handling this does not make much sense as the worst that can happen\n // is that some of the data written by the user might be discarded due to the\n // call to `socket.end()` below, which triggers an `'error'` event that in\n // turn causes the socket to be destroyed.\n //\n message = message || http.STATUS_CODES[code];\n headers = {\n Connection: 'close',\n 'Content-Type': 'text/html',\n 'Content-Length': Buffer.byteLength(message),\n ...headers\n };\n\n socket.once('finish', socket.destroy);\n\n socket.end(\n `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\\r\\n` +\n Object.keys(headers)\n .map((h) => `${h}: ${headers[h]}`)\n .join('\\r\\n') +\n '\\r\\n\\r\\n' +\n message\n );\n}\n\n/**\n * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least\n * one listener for it, otherwise call `abortHandshake()`.\n *\n * @param {WebSocketServer} server The WebSocket server\n * @param {http.IncomingMessage} req The request object\n * @param {Duplex} socket The socket of the upgrade request\n * @param {Number} code The HTTP response status code\n * @param {String} message The HTTP response body\n * @private\n */\nfunction abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {\n if (server.listenerCount('wsClientError')) {\n const err = new Error(message);\n Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);\n\n server.emit('wsClientError', err, socket, req);\n } else {\n abortHandshake(socket, code, message);\n }\n}\n", "{\n \"name\": \"dotenv\",\n \"version\": \"16.4.7\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run --show-full-coverage --timeout=60000 --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n", "const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n const vaultPath = _vaultPath(options)\n\n // Parse .env.vault\n const result = DotenvModule.configDotenv({ path: vaultPath })\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}][INFO] ${message}`)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n _log('Loading env from encrypted .env.vault')\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n", "import * as fs from 'fs/promises';\nimport {WebSocketServer, WebSocket} from 'ws';\nimport {createServer} from 'http';\nimport {parse} from 'url';\nimport {fork} from 'child_process';\nimport {runMcpServer} from './server.js';\nimport {\n clearTokens,\n deleteToken, generateNewRegistrationToken,\n generateToken,\n getToken,\n loadAuthorizedTokens,\n saveAuthorizedTokens, saveServerTokenToEnv,\n setToken\n} from \"./tokens.js\";\nimport {\n CONFIG,\n HOST,\n PID_FILE,\n SERVER_TOKEN,\n ensureConfigDir,\n formatChannel,\n setConfig, configureMcpClient, configureMcpClientWithPath, availableClientConfigs,\n} from './config.js';\n\nlet serverToken = SERVER_TOKEN;\n\n// Create HTTP server with CORS headers\nconst httpServer = createServer((req, res) => {\n // Set CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n // Handle preflight requests\n res.writeHead(204);\n res.end();\n return;\n }\n\n res.writeHead(200, {'Content-Type': 'text/plain'});\n res.end('MCP WebSocket server is running');\n});\n\n// Create WebSocket server instance\nconst wss = new WebSocketServer({\n server: httpServer,\n clientTracking: true,\n verifyClient: verifyClientToken\n});\n\n// Store active WebSocket connections by channel\nconst channels = {};\n\n// Special channel paths\nconst MCP_PATH = '/mcp';\nconst REGISTER_PATH = '/register';\n\n// Function to send notifications to a client and MCP (if connected)\nfunction sendNotification(clientWs, channelPath, notificationType, data, mcpOnly = false) {\n // Send to the client that initiated the action\n if (clientWs && clientWs.readyState === WebSocket.OPEN) {\n if (!mcpOnly) {\n clientWs.send(JSON.stringify({\n type: notificationType,\n ...data\n }));\n }\n }\n\n // Also send to MCP if connected\n if (channels[MCP_PATH] && channels[MCP_PATH].size > 0) {\n channels[MCP_PATH].values().forEach((mcpClient) => {\n if (mcpClient && mcpClient.readyState === WebSocket.OPEN) {\n // For MCP, prefix names with the channel path\n const mcpData = {...data};\n if (mcpData.name && channelPath) {\n mcpData.name = `${channelPath.slice(1)}-${mcpData.name}`;\n }\n\n mcpClient.send(JSON.stringify({\n type: notificationType,\n ...mcpData\n }));\n }\n });\n }\n}\n\n// Track all available tools, prompts, and resources across all channels\nconst toolsRegistry = {};\nconst promptsRegistry = {};\nconst resourcesRegistry = {};\n\n// Request counter for unique IDs\nlet requestIdCounter = 1;\n\n// Map to store pending requests\nconst pendingRequests = {};\n\n\n// Function to verify client token during WebSocket handshake\nasync function verifyClientToken(info, callback) {\n const url = new URL(`https://${HOST}${info.req.url}`);\n const clientToken = url.searchParams.get('token');\n const path = url.pathname || '/';\n\n // Special case for MCP path - use server token from .env\n if (path === MCP_PATH) {\n // For MCP connections, we use the token from the .env file\n if (clientToken === process.env.WEBMCP_SERVER_TOKEN) {\n return callback(true);\n }\n console.error('Invalid MCP token provided');\n return callback(false, 401, 'Unauthorized - Invalid MCP token');\n }\n\n // Special case for registration path - allow all connections for now\n // The actual authorization will happen in the connection handler\n if (path === REGISTER_PATH) {\n return callback(true);\n }\n\n // For other paths, check if the channel-token pair is authorized\n if (!clientToken) {\n console.error('No token provided for path:', path);\n return callback(false, 401, 'Unauthorized - No token provided');\n }\n\n await loadAuthorizedTokens();\n\n // Check if this channel has a valid token and it matches\n if (getToken(path) === clientToken) {\n return callback(true);\n }\n\n console.error(`Unauthorized connection attempt to ${path}`);\n return callback(false, 401, 'Unauthorized - Invalid channel-token pair');\n}\n\n// Helper function to get or create a channel\nfunction getOrCreateChannel(channelPath) {\n if (!channels[channelPath]) {\n channels[channelPath] = new Set();\n console.error(`Created new channel for path: ${channelPath}`);\n } else if (channels[channelPath].closeTimeout) {\n // Clear the timeout if it exists (someone is joining an empty channel)\n clearTimeout(channels[channelPath].closeTimeout);\n delete channels[channelPath].closeTimeout;\n console.error(`Cancelled channel closure for ${channelPath} as a new client connected`);\n }\n return channels[channelPath];\n}\n\n// Handle WebSocket connections\nwss.on('connection', (ws, req) => {\n // Extract the path from the URL\n const parsedUrl = parse(req.url);\n const path = parsedUrl.pathname;\n\n // Set channel based on connection path\n const clientChannel = path || '/';\n\n console.error(`Client connected from ${req.socket.remoteAddress} to path: ${clientChannel}`);\n\n // Special handling for registration endpoint\n if (clientChannel === REGISTER_PATH) {\n console.error(`Registration request received from ${req.socket.remoteAddress}`);\n\n // Wait for the first message which should contain the registration data\n let registrationTimeout = setTimeout(() => {\n console.error('Registration timeout - closing connection');\n ws.close(1008, 'Registration timeout');\n }, 30000); // 30 second timeout\n\n // Register message handler specifically for registration\n ws.once('message', async (message) => {\n clearTimeout(registrationTimeout);\n\n try {\n // The message should be base64 encoded JSON with server and token\n const encodedData = message.toString();\n const decodedJson = Buffer.from(encodedData, 'base64').toString('utf8');\n const connectionData = JSON.parse(decodedJson);\n\n const {host, token} = connectionData;\n\n if (!token) {\n console.error('Invalid registration data format - missing token');\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Invalid registration data format - missing token'\n }));\n ws.close(1008, 'Invalid registration data');\n return;\n }\n\n // Format the channel path (replace : with _)\n const channelPath = formatChannel(host);\n\n // Check if this is a valid token from a \"--new\" command\n if (!token || token.length < 16) {\n console.error('Invalid token provided');\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Invalid token provided'\n }));\n ws.close(1008, 'Invalid token');\n return;\n }\n\n const serverChannel = formatChannel(`${HOST}:${CONFIG.port}`);\n\n await loadAuthorizedTokens();\n if (token !== getToken(serverChannel)) {\n console.error('Invalid token provided');\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Invalid token provided'\n }));\n ws.close(1008, 'Invalid token');\n return;\n }\n\n // Throw away registration token and make a session token.\n deleteToken(serverChannel);\n const sessionToken = generateToken();\n\n // Authorize the channel-token pair\n setToken(channelPath, sessionToken);\n await saveAuthorizedTokens();\n\n // Send success response\n ws.send(JSON.stringify({\n type: 'registerSuccess',\n channel: channelPath,\n message: `Registration successful for ${channelPath}`,\n token: sessionToken\n }));\n\n console.error(`Registered channel: ${channelPath} with token: ${token}`);\n\n // Close the registration connection - they'll reconnect to their channel\n ws.close(1000, 'Registration complete');\n } catch (error) {\n console.error('Registration error:', error);\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Registration error'\n }));\n ws.close(1011, 'Registration error');\n }\n });\n\n return; // Don't proceed with the normal connection handling\n }\n\n // Add client to the channel based on path (for non-registration paths)\n const channel = getOrCreateChannel(clientChannel);\n channel.add(ws);\n\n // Send welcome message with channel info\n ws.send(JSON.stringify({\n type: 'welcome',\n channel: clientChannel,\n message: `Connected to path: ${clientChannel}`\n }));\n\n // Handle incoming messages\n ws.on('message', (message) => {\n try {\n const data = JSON.parse(message);\n console.error(`Received message: ${data.type} on ${clientChannel}`);\n\n // Process message based on type\n switch (data.type) {\n case 'ping':\n handlePing(ws, data);\n break;\n\n case 'registerTool':\n handleRegisterTool(ws, clientChannel, data);\n break;\n\n case 'registerPrompt':\n handleRegisterPrompt(ws, clientChannel, data);\n break;\n\n case 'registerResource':\n handleRegisterResource(ws, clientChannel, data);\n break;\n\n case 'listTools':\n handleListTools(ws, clientChannel, data);\n break;\n\n case 'listPrompts':\n handleListPrompts(ws, clientChannel, data);\n break;\n\n case 'listResources':\n handleListResources(ws, clientChannel, data);\n break;\n\n case 'callTool':\n handleCallTool(ws, clientChannel, data);\n break;\n\n case 'getPrompt':\n handleGetPrompt(ws, clientChannel, data);\n break;\n\n case 'readResource':\n handleReadResource(ws, clientChannel, data);\n break;\n\n case 'createSamplingMessage':\n handleCreateSamplingMessage(ws, clientChannel, data);\n break;\n\n case 'toolResponse':\n handleToolResponse(data);\n break;\n\n case 'promptResponse':\n handlePromptResponse(data);\n break;\n\n case 'resourceResponse':\n handleResourceResponse(data);\n break;\n\n case 'samplingResponse':\n handleSamplingResponse(data);\n break;\n\n default:\n ws.send(JSON.stringify({\n type: 'error',\n message: `Unknown message type: ${data.type}`\n }));\n }\n } catch (error) {\n console.error('Error processing WebSocket message:', error);\n try {\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Invalid message format'\n }));\n } catch (sendError) {\n console.error('Error sending error response:', sendError);\n }\n }\n });\n\n // Handle disconnection\n ws.on('close', async () => {\n console.error(`Client disconnected from path: ${clientChannel}`);\n\n // Remove from channel\n const channel = channels[clientChannel];\n if (channel) {\n channel.delete(ws);\n\n // Set a timer to clean up empty channels after 1 minute\n if (channel.size === 0) {\n console.error(`Channel ${clientChannel} is empty, will close in 1 minute if no one joins`);\n\n // Store the timeout in the channel object so we can clear it if needed\n channel.closeTimeout = setTimeout(async () => {\n // Check if the channel is still empty after 1 minute\n if (channels[clientChannel] && channels[clientChannel].size === 0) {\n delete channels[clientChannel];\n console.error(`Removed empty channel for path: ${clientChannel} after 1 minute inactivity`);\n\n // Clean up tools, prompts, and resources for this channel\n const itemsToRemove = {\n tools: [],\n prompts: [],\n resources: []\n };\n\n for (const [toolId, toolInfo] of Object.entries(toolsRegistry)) {\n if (toolInfo.channel === clientChannel) {\n itemsToRemove.tools.push(toolId);\n }\n }\n\n for (const [promptId, promptInfo] of Object.entries(promptsRegistry)) {\n if (promptInfo.channel === clientChannel) {\n itemsToRemove.prompts.push(promptId);\n }\n }\n\n for (const [resourceId, resourceInfo] of Object.entries(resourcesRegistry)) {\n if (resourceInfo.channel === clientChannel) {\n itemsToRemove.resources.push(resourceId);\n }\n }\n\n itemsToRemove.tools.forEach(toolId => {\n delete toolsRegistry[toolId];\n console.error(`Removed tool: ${toolId} from path: ${clientChannel}`);\n });\n\n itemsToRemove.prompts.forEach(promptId => {\n delete promptsRegistry[promptId];\n console.error(`Removed prompt: ${promptId} from path: ${clientChannel}`);\n });\n\n itemsToRemove.resources.forEach(resourceId => {\n delete resourcesRegistry[resourceId];\n console.error(`Removed resource: ${resourceId} from path: ${clientChannel}`);\n });\n\n // Remove the authorized token for this channel if not MCP\n if (clientChannel !== MCP_PATH) {\n deleteToken(clientChannel);\n await saveAuthorizedTokens();\n console.error(`Removed authorized token for channel: ${clientChannel}`);\n }\n\n // Update them all\n sendNotification(ws, undefined, 'toolRegistered', {}, true);\n sendNotification(ws, undefined, 'promptRegistered', {}, true);\n sendNotification(ws, undefined, 'resourceRegistered', {}, true);\n }\n }, 60000); // 1 minute timeout\n }\n }\n });\n\n // Handle errors\n ws.on('error', (error) => {\n console.error('WebSocket error:', error);\n\n // Remove from channel\n const channel = channels[clientChannel];\n if (channel) {\n channel.delete(ws);\n }\n });\n});\n\n// Handle ping messages\nfunction handlePing(ws, data) {\n ws.send(JSON.stringify({\n id: data.id,\n type: 'pong',\n timestamp: Date.now()\n }));\n}\n\n// Handle tool registration\nfunction handleRegisterTool(ws, channelPath, data) {\n const {name, description, inputSchema} = data;\n\n if (!name) {\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Tool name is required'\n }));\n return;\n }\n\n // Create a unique tool ID for internal tracking\n const toolId = `${channelPath.slice(1)}-${name}`;\n\n // Register the tool\n toolsRegistry[toolId] = {\n channel: channelPath,\n name,\n description: description || `Tool: ${name}`,\n inputSchema,\n originalName: name\n };\n\n // Send registration notification to both client and MCP\n sendNotification(ws, channelPath, 'toolRegistered', {\n name,\n toolId\n });\n\n console.error(`Tool registered: ${toolId}`);\n}\n\n// Handle prompt registration\nfunction handleRegisterPrompt(ws, channelPath, data) {\n const {name, description, arguments: promptArgs} = data;\n\n if (!name) {\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Prompt name is required'\n }));\n return;\n }\n\n // Create a unique prompt ID for internal tracking\n const promptId = `${channelPath.slice(1)}-${name}`;\n\n // Register the prompt\n promptsRegistry[promptId] = {\n channel: channelPath,\n name,\n description: description || `Prompt: ${name}`,\n arguments: promptArgs || [],\n originalName: name\n };\n\n // Send registration notification to both client and MCP\n sendNotification(ws, channelPath, 'promptRegistered', {\n name,\n promptId\n });\n\n console.error(`Prompt registered: ${promptId}`);\n}\n\n// Handle resource registration\nfunction handleRegisterResource(ws, channelPath, data) {\n const {uri, name, description, mimeType, isTemplate, uriTemplate} = data;\n\n if ((!uri && !uriTemplate) || !name) {\n ws.send(JSON.stringify({\n type: 'error',\n message: 'Resource URI/template and name are required'\n }));\n return;\n }\n\n // Create a unique resource ID for internal tracking\n const resourceId = `${channelPath.slice(1)}-${name}`;\n\n // Register the resource\n resourcesRegistry[resourceId] = {\n channel: channelPath,\n name,\n description: description || `Resource: ${name}`,\n uri: uri,\n uriTemplate: uriTemplate,\n isTemplate: !!isTemplate,\n mimeType,\n originalName: name\n };\n\n // Send registration notification to both client and MCP\n sendNotification(ws, channelPath, 'resourceRegistered', {\n name,\n resourceId\n });\n\n console.error(`Resource registered: ${resourceId}`);\n}\n\n// Handle list tools requests\nfunction handleListTools(ws, clientChannel, data) {\n const {id} = data;\n\n // Special handling if the request is from the MCP client\n const isMcpClient = (clientChannel === MCP_PATH);\n\n let tools;\n\n if (isMcpClient) {\n // For MCP clients, return all tools across all paths with path prefixes\n tools = Object.entries(toolsRegistry).map(([toolId, toolInfo]) => {\n // Create a path-based fully qualified name - combine path and tool name\n const pathBasedName = `${toolInfo.channel.slice(1)}-${toolInfo.originalName}`;\n return {\n name: pathBasedName,\n description: toolInfo.description,\n inputSchema: toolInfo.inputSchema,\n };\n });\n console.error(`Sending all ${tools.length} tools to MCP client on path ${clientChannel}`);\n } else {\n // For regular clients, return only their own tools without path prefixes\n tools = Object.entries(toolsRegistry)\n .filter(([_, toolInfo]) => toolInfo.channel === clientChannel)\n .map(([_, toolInfo]) => ({\n name: toolInfo.originalName,\n description: toolInfo.description,\n inputSchema: toolInfo.inputSchema,\n }));\n console.error(`Sending ${tools.length} tools from path ${clientChannel}`);\n }\n\n ws.send(JSON.stringify({\n id,\n type: 'listToolsResponse',\n tools\n }));\n}\n\n// Handle list prompts requests\nfunction handleListPrompts(ws, clientChannel, data) {\n const {id} = data;\n\n // Special handling if the request is from the MCP client\n const isMcpClient = (clientChannel === MCP_PATH);\n\n let prompts;\n\n if (isMcpClient) {\n // For MCP clients, return all prompts across all paths with path prefixes\n prompts = Object.entries(promptsRegistry).map(([promptId, promptInfo]) => {\n // Create a path-based fully qualified name - combine path and prompt name\n const pathBasedName = `${promptInfo.channel.slice(1)}-${promptInfo.originalName}`;\n return {\n name: pathBasedName,\n description: promptInfo.description,\n arguments: promptInfo.arguments,\n };\n });\n console.error(`Sending all ${prompts.length} prompts to MCP client on path ${clientChannel}`);\n } else {\n // For regular clients, return only their own prompts without path prefixes\n prompts = Object.entries(promptsRegistry)\n .filter(([_, promptInfo]) => promptInfo.channel === clientChannel)\n .map(([_, promptInfo]) => ({\n name: promptInfo.originalName,\n description: promptInfo.description,\n arguments: promptInfo.arguments,\n }));\n console.error(`Sending ${prompts.length} prompts from path ${clientChannel}`);\n }\n\n ws.send(JSON.stringify({\n id,\n type: 'listPromptsResponse',\n prompts\n }));\n}\n\n// Handle list resources requests\nfunction handleListResources(ws, clientChannel, data) {\n const {id} = data;\n\n // Special handling if the request is from the MCP client\n const isMcpClient = (clientChannel === MCP_PATH);\n\n let resources = [];\n let resourceTemplates = [];\n\n if (isMcpClient) {\n // For MCP clients, return all resources across all paths with path prefixes\n Object.entries(resourcesRegistry).forEach(([resourceId, resourceInfo]) => {\n // Create a path-based fully qualified name - combine path and resource name\n const pathBasedName = `${resourceInfo.channel.slice(1)}-${resourceInfo.originalName}`;\n\n if (resourceInfo.isTemplate) {\n resourceTemplates.push({\n name: pathBasedName,\n description: resourceInfo.description,\n uriTemplate: resourceInfo.uriTemplate,\n mimeType: resourceInfo.mimeType,\n });\n } else {\n resources.push({\n name: pathBasedName,\n description: resourceInfo.description,\n uri: resourceInfo.uri,\n mimeType: resourceInfo.mimeType,\n });\n }\n });\n console.error(`Sending all ${resources.length} resources and ${resourceTemplates.length} templates to MCP client on path ${clientChannel}`);\n } else {\n // For regular clients, return only their own resources without path prefixes\n Object.entries(resourcesRegistry)\n .filter(([_, resourceInfo]) => resourceInfo.channel === clientChannel)\n .forEach(([_, resourceInfo]) => {\n if (resourceInfo.isTemplate) {\n resourceTemplates.push({\n name: resourceInfo.originalName,\n description: resourceInfo.description,\n uriTemplate: resourceInfo.uriTemplate,\n mimeType: resourceInfo.mimeType,\n });\n } else {\n resources.push({\n name: resourceInfo.originalName,\n description: resourceInfo.description,\n uri: resourceInfo.uri,\n mimeType: resourceInfo.mimeType,\n });\n }\n });\n console.error(`Sending ${resources.length} resources and ${resourceTemplates.length} templates from path ${clientChannel}`);\n }\n\n ws.send(JSON.stringify({\n id,\n type: 'listResourcesResponse',\n resources,\n resourceTemplates\n }));\n}\n\n// Handle tool call requests\nfunction handleCallTool(ws, callerChannel, data) {\n const {id, tool, arguments: args} = data;\n\n // Special handling if the caller is on the MCP path\n const isMcpClient = (callerChannel === MCP_PATH);\n\n // If the caller is MCP, the tool name might include a path prefix\n let targetChannel;\n let toolName;\n\n if (isMcpClient && tool.startsWith('/')) {\n // Extract the path and tool name from the fully qualified name\n [targetChannel, toolName] = tool.slice(1).split(\"-\").slice(1);\n targetChannel = `/${targetChannel}`;\n } else {\n // Check if the tool exists in the registry\n if (!toolsRegistry[tool]) {\n ws.send(JSON.stringify({\n id,\n type: 'toolResponse',\n error: `Tool not found: ${tool}`\n }));\n return;\n }\n\n const toolInfo = toolsRegistry[tool];\n targetChannel = toolInfo.channel;\n toolName = toolInfo.originalName;\n }\n\n // Get the target channel\n if (!channels[targetChannel] || channels[targetChannel].size === 0) {\n ws.send(JSON.stringify({\n id,\n type: 'toolResponse',\n error: `No clients available in channel ${targetChannel} to handle tool: ${toolName}`\n }));\n return;\n }\n\n // Pick the first client in the target channel (you could implement more sophisticated routing)\n const targetClient = channels[targetChannel].values().next().value;\n\n // Create a unique request ID for tracking\n const requestId = (requestIdCounter++).toString();\n\n // Store the pending request\n pendingRequests[requestId] = {\n originalId: id,\n requesterWs: ws,\n timestamp: Date.now()\n };\n\n // Set up timeout for the request\n setTimeout(() => {\n if (pendingRequests[requestId]) {\n const {requesterWs, originalId} = pendingRequests[requestId];\n delete pendingRequests[requestId];\n\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'toolResponse',\n error: `Tool call timed out: ${toolName}`\n }));\n } catch (error) {\n console.error('Error sending timeout response:', error);\n }\n }\n }, 30000); // 30 second timeout\n\n // Send the request to the target client\n targetClient.send(JSON.stringify({\n id: requestId,\n type: 'callTool',\n tool: toolName, // Send just the tool name without channel prefix\n arguments: args\n }));\n\n console.error(`Tool call forwarded: ${toolName} to channel: ${targetChannel}`);\n}\n\n// Handle get prompt requests\nfunction handleGetPrompt(ws, callerChannel, data) {\n const {id, name, arguments: args} = data;\n\n // Special handling if the caller is on the MCP path\n const isMcpClient = (callerChannel === MCP_PATH);\n\n // If the caller is MCP, the prompt name might include a path prefix\n let targetChannel;\n let promptName;\n\n if (isMcpClient && name.startsWith('/')) {\n // Extract the path and prompt name from the fully qualified name\n [targetChannel, promptName] = name.slice(1).split(\"-\").slice(1);\n targetChannel = `/${targetChannel}`;\n } else {\n // Check if the prompt exists in the registry\n const promptInfo = Object.values(promptsRegistry).find(p =>\n p.channel === callerChannel && p.originalName === name);\n\n if (!promptInfo) {\n ws.send(JSON.stringify({\n id,\n type: 'promptResponse',\n error: `Prompt not found: ${name}`\n }));\n return;\n }\n\n targetChannel = promptInfo.channel;\n promptName = promptInfo.originalName;\n }\n\n // Get the target channel\n if (!channels[targetChannel] || channels[targetChannel].size === 0) {\n ws.send(JSON.stringify({\n id,\n type: 'promptResponse',\n error: `No clients available in channel ${targetChannel} to handle prompt: ${promptName}`\n }));\n return;\n }\n\n // Pick the first client in the target channel\n const targetClient = channels[targetChannel].values().next().value;\n\n // Create a unique request ID for tracking\n const requestId = (requestIdCounter++).toString();\n\n // Store the pending request\n pendingRequests[requestId] = {\n originalId: id,\n requesterWs: ws,\n timestamp: Date.now()\n };\n\n // Set up timeout for the request\n setTimeout(() => {\n if (pendingRequests[requestId]) {\n const {requesterWs, originalId} = pendingRequests[requestId];\n delete pendingRequests[requestId];\n\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'promptResponse',\n error: `Prompt request timed out: ${promptName}`\n }));\n } catch (error) {\n console.error('Error sending timeout response:', error);\n }\n }\n }, 30000); // 30 second timeout\n\n // Send the request to the target client\n targetClient.send(JSON.stringify({\n id: requestId,\n type: 'getPrompt',\n name: promptName,\n arguments: args\n }));\n\n console.error(`Prompt request forwarded: ${promptName} to channel: ${targetChannel}`);\n}\n\n// Handle read resource requests\nfunction handleReadResource(ws, callerChannel, data) {\n const {id, uri} = data;\n\n // Find the resource that matches this URI\n let targetChannel;\n let resourceName;\n let resourceInfo;\n\n // First, try to find an exact match for the URI\n for (const [resId, info] of Object.entries(resourcesRegistry)) {\n if (!info.isTemplate && info.uri === uri) {\n resourceInfo = info;\n targetChannel = info.channel;\n resourceName = info.originalName;\n break;\n }\n }\n\n // If no exact match, check for templates\n if (!resourceInfo) {\n // This is a simplistic approach; a real implementation would properly parse the URI template\n for (const [resId, info] of Object.entries(resourcesRegistry)) {\n if (info.isTemplate && uri.startsWith(info.uriTemplate.split('{')[0])) {\n resourceInfo = info;\n targetChannel = info.channel;\n resourceName = info.originalName;\n break;\n }\n }\n }\n\n if (!resourceInfo) {\n ws.send(JSON.stringify({\n id,\n type: 'resourceResponse',\n error: `Resource not found for URI: ${uri}`\n }));\n return;\n }\n\n // Get the target channel\n if (!channels[targetChannel] || channels[targetChannel].size === 0) {\n ws.send(JSON.stringify({\n id,\n type: 'resourceResponse',\n error: `No clients available in channel ${targetChannel} to handle resource: ${resourceName}`\n }));\n return;\n }\n\n // Pick the first client in the target channel\n const targetClient = channels[targetChannel].values().next().value;\n\n // Create a unique request ID for tracking\n const requestId = (requestIdCounter++).toString();\n\n // Store the pending request\n pendingRequests[requestId] = {\n originalId: id,\n requesterWs: ws,\n timestamp: Date.now()\n };\n\n // Set up timeout for the request\n setTimeout(() => {\n if (pendingRequests[requestId]) {\n const {requesterWs, originalId} = pendingRequests[requestId];\n delete pendingRequests[requestId];\n\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'resourceResponse',\n error: `Resource request timed out: ${uri}`\n }));\n } catch (error) {\n console.error('Error sending timeout response:', error);\n }\n }\n }, 30000); // 30 second timeout\n\n // Send the request to the target client\n targetClient.send(JSON.stringify({\n id: requestId,\n type: 'readResource',\n uri: uri\n }));\n\n console.error(`Resource request forwarded: ${uri} to channel: ${targetChannel}`);\n}\n\n// Handle tool response\nfunction handleToolResponse(data) {\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (!pendingRequests[id]) {\n console.error(`No pending request found for ID: ${id}`);\n return;\n }\n\n // Get the original requester information\n const {requesterWs, originalId} = pendingRequests[id];\n delete pendingRequests[id];\n\n // Forward the response to the original requester\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'toolResponse',\n result: result,\n error: error\n }));\n } catch (error) {\n console.error('Error forwarding tool response:', error);\n }\n}\n\n// Handle prompt response\nfunction handlePromptResponse(data) {\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (!pendingRequests[id]) {\n console.error(`No pending request found for ID: ${id}`);\n return;\n }\n\n // Get the original requester information\n const {requesterWs, originalId} = pendingRequests[id];\n delete pendingRequests[id];\n\n // Forward the response to the original requester\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'promptResponse',\n result: result,\n error: error\n }));\n } catch (error) {\n console.error('Error forwarding prompt response:', error);\n }\n}\n\n// Handle resource response\nfunction handleResourceResponse(data) {\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (!pendingRequests[id]) {\n console.error(`No pending request found for ID: ${id}`);\n return;\n }\n\n // Get the original requester information\n const {requesterWs, originalId} = pendingRequests[id];\n delete pendingRequests[id];\n\n // Forward the response to the original requester\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'resourceResponse',\n result: result,\n error: error\n }));\n } catch (error) {\n console.error('Error forwarding resource response:', error);\n }\n}\n\n// Handle sampling response\nfunction handleSamplingResponse(data) {\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (!pendingRequests[id]) {\n console.error(`No pending request found for ID: ${id}`);\n return;\n }\n\n // Get the original requester information\n const {requesterWs, originalId} = pendingRequests[id];\n delete pendingRequests[id];\n\n // Forward the response to the original requester\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'samplingResponse',\n result: result,\n error: error\n }));\n } catch (error) {\n console.error('Error forwarding sampling response:', error);\n }\n}\n\n// Handle create sampling message\nfunction handleCreateSamplingMessage(ws, callerChannel, data) {\n const {\n id,\n messages,\n systemPrompt,\n includeContext,\n temperature,\n maxTokens,\n stopSequences,\n metadata,\n modelPreferences\n } = data;\n\n // Special handling if the caller is on the MCP path\n const isMcpClient = (callerChannel === MCP_PATH);\n\n // For non-MCP clients or if no client is available in any channel\n if (!isMcpClient) {\n ws.send(JSON.stringify({\n id,\n type: 'samplingResponse',\n error: `Sampling is only available through MCP path`\n }));\n return;\n }\n\n // Find a client that can handle sampling - target the first available client\n let targetClient = null;\n let targetChannel = null;\n\n // Iterate through all channels to find one with clients\n for (const [channel, clients] of Object.entries(channels)) {\n if (channel !== MCP_PATH && clients.size > 0) {\n targetClient = clients.values().next().value;\n targetChannel = channel;\n break;\n }\n }\n\n if (!targetClient) {\n ws.send(JSON.stringify({\n id,\n type: 'samplingResponse',\n error: 'No clients available to handle sampling request'\n }));\n return;\n }\n\n // Create a unique request ID for tracking\n const requestId = (requestIdCounter++).toString();\n\n // Store the pending request\n pendingRequests[requestId] = {\n originalId: id,\n requesterWs: ws,\n timestamp: Date.now()\n };\n\n // Set up timeout for the request (longer timeout for sampling)\n setTimeout(() => {\n if (pendingRequests[requestId]) {\n const {requesterWs, originalId} = pendingRequests[requestId];\n delete pendingRequests[requestId];\n\n try {\n requesterWs.send(JSON.stringify({\n id: originalId,\n type: 'samplingResponse',\n error: 'Sampling request timed out'\n }));\n } catch (error) {\n console.error('Error sending timeout response:', error);\n }\n }\n }, 120000); // 120 second timeout for sampling\n\n // Forward the request to the target client\n targetClient.send(JSON.stringify({\n id: requestId,\n type: 'createSamplingMessage',\n messages,\n systemPrompt,\n includeContext,\n temperature,\n maxTokens,\n stopSequences,\n metadata,\n modelPreferences\n }));\n\n console.error(`Sampling request forwarded to channel: ${targetChannel}`);\n}\n\n\n// Function to decode a base64 encoded channel-token pair\nfunction decodeChannelTokenPair(encodedPair) {\n try {\n const decodedString = Buffer.from(encodedPair, 'base64').toString('utf8');\n const [channel, token] = decodedString.split(':');\n\n if (!channel || !token) {\n throw new Error('Invalid format');\n }\n\n // Ensure channel has leading slash\n const formattedChannel = channel.startsWith('/') ? channel : `/${channel}`;\n\n return {channel: formattedChannel, token};\n } catch (error) {\n console.error('Error decoding channel-token pair:', error);\n return null;\n }\n}\n\n// Function to authorize a new channel-token pair\nasync function authorizeChannelToken(encodedPair) {\n const decoded = decodeChannelTokenPair(encodedPair);\n if (!decoded) {\n return {success: false, message: 'Invalid encoded channel-token pair'};\n }\n\n const {channel, token} = decoded;\n\n // Check if this channel already has an active connection\n if (channels[channel] && channels[channel].size > 0) {\n return {success: false, message: `Channel ${channel} already has an active connection`};\n }\n\n // Add to authorized tokens\n setToken(channel, token);\n await saveAuthorizedTokens();\n\n return {\n success: true,\n message: `Authorized channel: ${channel}`,\n channel,\n token\n };\n}\n\n// Function to check if server is already running\nasync function isServerRunning() {\n // If using \"docker\" and \"startMCP\" just assume the server is running\n if (CONFIG.startMCP && CONFIG.docker) {\n return true;\n }\n\n try {\n // Check if PID file exists\n const pidData = await fs.readFile(PID_FILE, 'utf8');\n const pid = parseInt(pidData.trim(), 10);\n\n // Check if process with this PID is running\n // This is platform-specific, using a simple approach\n try {\n process.kill(pid, 0); // This doesn't actually kill the process, just checks if it exists\n return {running: true, pid};\n } catch (e) {\n // Process not running, remove stale PID file\n await fs.unlink(PID_FILE);\n return {running: false};\n }\n } catch (error) {\n // PID file doesn't exist or other error\n return {running: false};\n }\n}\n\n// Function to save current PID to file\nasync function savePid() {\n try {\n await fs.writeFile(PID_FILE, process.pid.toString(), 'utf8');\n return true;\n } catch (error) {\n console.error('Error saving PID file:', error);\n return false;\n }\n}\n\n// Function to run the server in the background\nasync function daemonize() {\n // Fork a new process that will become the daemon\n const args = process.argv.slice(2);\n\n // Make sure the --forked flag is included\n if (!args.includes('--forked')) {\n args.push('--forked');\n }\n\n // Create a detached child process\n const child = fork(process.argv[1], args, {\n detached: true,\n stdio: 'ignore'\n });\n\n // Detach the child process so it can run independently\n child.unref();\n\n console.error(`Server started as daemon with PID: ${child.pid}`);\n console.error(`Use 'node websocket-server.js --quit' to stop the server`);\n console.error(`Use 'node websocket-server.js --new ' to authorize a channel-token pair`);\n console.error(`Put 'npx @jason.today/webmcp --mcp' in your mcp client config`);\n if (!CONFIG.startMCP) {\n process.exit(0);\n }\n}\n\nconst parseArgs = async () => {\n const args = process.argv.slice(2);\n let port = 4797; // Default port\n let quit = false;\n let newToken = false;\n let startMCP = false;\n let docker = false;\n let cleanTokens = false;\n let encodedPair = null;\n let daemon = true; // Default to daemonize\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === '-h' || arg === '--help') {\n showHelp();\n process.exit(0);\n } else if (arg === '-p' || arg === '--port') {\n if (i + 1 < args.length) {\n const portArg = parseInt(args[i + 1], 10);\n if (isNaN(portArg) || portArg < 1 || portArg > 65535) {\n console.error('Error: Port must be a number between 1 and 65535');\n showHelp();\n process.exit(1);\n }\n port = portArg;\n i++; // Skip the next argument as we've already processed it\n } else {\n console.error('Error: Port option requires a value');\n showHelp();\n process.exit(1);\n }\n } else if (arg === '--config') {\n if (i + 1 < args.length) {\n const config = args[i + 1];\n if (availableClientConfigs[config]) {\n await configureMcpClient(config)\n } else {\n await configureMcpClientWithPath(config)\n }\n i++; // Skip the next argument as we've already processed it\n } else {\n console.error('Error: Config option requires a mcp client type or path to json');\n showHelp();\n process.exit(1);\n }\n } else if (arg === '-q' || arg === '--quit') {\n quit = true;\n } else if (arg === '-n' || arg === '--new') {\n newToken = true;\n } else if (arg === '-m' || arg === '--mcp') {\n startMCP = true;\n } else if (arg === '-d' || arg === '--docker') {\n docker = true;\n } else if (arg === '-c' || arg === '--clean') {\n cleanTokens = true;\n } else if (arg === '-f' || arg === '--foreground') {\n daemon = false;\n } else if (arg === '--forked') {\n // This is an internal flag to indicate we're the forked child \u2502 \u2502\n // No need to do anything with it here, just don't error on it\n } else {\n console.error(`Error: Unknown option: ${arg}`);\n showHelp();\n process.exit(1);\n }\n }\n\n return {port, quit, newToken, cleanTokens, encodedPair, daemon, startMCP};\n};\n\nconst showHelp = () => {\n console.log(`\nUsage: node websocket-server.js [options]\n\nOptions:\n -p, --port Specify the port number (default: 4797)\n -h, --help Display this help message\n -q, --quit Stop the running server\n -n, --new Generate a new token for client registration\n -c, --clean Remove all authorized tokens\n -f, --foreground Run in foreground (don't daemonize)\n -m, --mcp Internal WebMCP Server codepath, likely only used in MCP client config\n -d, --docker Tell the MCP client that WebMCP is running in docker\n \nUse --new to generate a token which clients can use to register on the /register endpoint.\nUse --clean to remove all authorized tokens when you want to start fresh.\n `);\n};\n\nconst main = async () => {\n // Ensure the config directory exists\n await ensureConfigDir();\n\n // Load authorized tokens from disk\n await loadAuthorizedTokens();\n\n setConfig(await parseArgs());\n\n // Check if server is already running\n const serverStatus = await isServerRunning();\n\n // Handle clean tokens command\n if (CONFIG.cleanTokens) {\n console.log(`Removing all authorized tokens...`);\n clearTokens();\n await saveAuthorizedTokens();\n console.log(`All tokens have been removed. Tokens file cleared.`);\n\n // If server is running, we need to notify it to reload tokens\n if (serverStatus.running) {\n console.log(`Server is running with PID: ${serverStatus.pid}. Please restart it to apply changes.`);\n }\n\n process.exit(0);\n }\n\n // Handle quit command\n if (CONFIG.quit) {\n if (serverStatus.running) {\n console.log(`Stopping server with PID: ${serverStatus.pid}`);\n try {\n process.kill(serverStatus.pid, 'SIGTERM');\n console.log('Server stopped successfully');\n } catch (error) {\n console.error('Error stopping server:', error);\n }\n } else {\n console.log('No running server found');\n }\n process.exit(0);\n }\n\n // Handle new token generation\n if (CONFIG.newToken) {\n const encodedData = await generateNewRegistrationToken();\n console.log(`\\nCONNECTION TOKEN (paste this in your web client):`);\n console.log(`${encodedData}\\n`);\n\n // If server is running, exit\n if (serverStatus.running) {\n process.exit(0);\n }\n }\n\n // Check if we have a server token, generate one if not\n if (!serverToken) {\n // console.log('No server token found, generating a new one...');\n serverToken = generateToken();\n await saveServerTokenToEnv(serverToken);\n // console.log(`New server token: \"${serverToken}\". Saved to .env`);\n }\n\n // If server is already running and we're not authorizing a token, just show status and exit\n if (serverStatus.running) {\n console.error(`Server is already running with PID: ${serverStatus.pid}`);\n console.error(`Use 'node websocket-server.js --quit' to stop the server`);\n console.error(`Use 'node websocket-server.js --new ' to authorize a channel-token pair`);\n console.error(`Put 'npx @jason.today/webmcp --mcp' in your mcp client config`);\n if (CONFIG.startMCP) {\n return;\n } else {\n process.exit(0);\n }\n }\n\n // Daemonize if requested\n if (CONFIG.daemon) {\n // We need to add a marker to args to prevent fork bombs\n // If we already have the --forked flag, we're in the child process and should continue\n if (!process.argv.includes('--forked')) {\n // Add the --forked flag to the arguments before daemonizing\n process.argv.push('--forked');\n return daemonize();\n }\n }\n\n // If we have the --forked flag, we're already the daemon, continue execution\n // Save PID file\n await savePid();\n\n // Start the server\n const PORT = CONFIG.port;\n httpServer.listen(PORT, () => {\n console.error(`WebSocket server running at http://${HOST}:${PORT}`);\n console.error(`WebSocket server running at http://${HOST}:${PORT}`);\n console.error(`WebMCP client token (for MCP path): ${serverToken}`);\n console.error(`WebMCP client URL: ws://${HOST}:${PORT}${MCP_PATH}?token=${serverToken}`);\n console.error(`Use 'node websocket-server.js --new ' to authorize a channel-token pair`);\n });\n\n // Handle graceful shutdown\n const shutdownGracefully = async (signal) => {\n console.error(`\\nReceived ${signal}. Shutting down gracefully...`);\n\n // Save authorized tokens before shutting down\n await saveAuthorizedTokens();\n\n // Close all WebSocket connections in all channels\n for (const channel of Object.values(channels)) {\n for (const ws of channel) {\n try {\n ws.close();\n } catch (error) {\n console.error('Error closing WebSocket connection:', error);\n }\n }\n }\n\n // Close the HTTP server\n httpServer.close(() => {\n console.error('HTTP server closed');\n\n // Remove PID file\n fs.unlink(PID_FILE).catch(err => {\n console.error('Error removing PID file:', err);\n });\n\n process.exit(0);\n });\n };\n\n // Handle CTRL+C (SIGINT)\n process.on('SIGINT', () => shutdownGracefully('SIGINT'));\n\n // Handle SIGTERM\n process.on('SIGTERM', () => shutdownGracefully('SIGTERM'));\n\n // Enable keyboard input handling for CTRL+C on Windows\n if (process.platform === 'win32') {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', (data) => {\n // Check for CTRL+C (03 in hex)\n if (data.length === 1 && data[0] === 0x03) {\n shutdownGracefully('CTRL+C');\n }\n });\n }\n};\n\nmain().catch(error => {\n console.error('Error in main:', error);\n process.exit(1);\n}).then(() => {\n // Handle starting MCP\n if (CONFIG.startMCP) {\n setTimeout(() => {\n console.error(\"Starting up MCP Server\")\n runMcpServer(serverToken).catch((error) => {\n console.error(\"Fatal error in main():\", error);\n process.exit(1);\n });\n }, 100);\n }\n});\n", "import createWebSocketStream from './lib/stream.js';\nimport Receiver from './lib/receiver.js';\nimport Sender from './lib/sender.js';\nimport WebSocket from './lib/websocket.js';\nimport WebSocketServer from './lib/websocket-server.js';\n\nexport { createWebSocketStream, Receiver, Sender, WebSocket, WebSocketServer };\nexport default WebSocket;\n", "var util;\n(function (util) {\n util.assertEqual = (val) => val;\n function assertIs(_arg) { }\n util.assertIs = assertIs;\n function assertNever(_x) {\n throw new Error();\n }\n util.assertNever = assertNever;\n util.arrayToEnum = (items) => {\n const obj = {};\n for (const item of items) {\n obj[item] = item;\n }\n return obj;\n };\n util.getValidEnumValues = (obj) => {\n const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== \"number\");\n const filtered = {};\n for (const k of validKeys) {\n filtered[k] = obj[k];\n }\n return util.objectValues(filtered);\n };\n util.objectValues = (obj) => {\n return util.objectKeys(obj).map(function (e) {\n return obj[e];\n });\n };\n util.objectKeys = typeof Object.keys === \"function\" // eslint-disable-line ban/ban\n ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban\n : (object) => {\n const keys = [];\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n keys.push(key);\n }\n }\n return keys;\n };\n util.find = (arr, checker) => {\n for (const item of arr) {\n if (checker(item))\n return item;\n }\n return undefined;\n };\n util.isInteger = typeof Number.isInteger === \"function\"\n ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban\n : (val) => typeof val === \"number\" && isFinite(val) && Math.floor(val) === val;\n function joinValues(array, separator = \" | \") {\n return array\n .map((val) => (typeof val === \"string\" ? `'${val}'` : val))\n .join(separator);\n }\n util.joinValues = joinValues;\n util.jsonStringifyReplacer = (_, value) => {\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n return value;\n };\n})(util || (util = {}));\nvar objectUtil;\n(function (objectUtil) {\n objectUtil.mergeShapes = (first, second) => {\n return {\n ...first,\n ...second, // second overwrites first\n };\n };\n})(objectUtil || (objectUtil = {}));\nconst ZodParsedType = util.arrayToEnum([\n \"string\",\n \"nan\",\n \"number\",\n \"integer\",\n \"float\",\n \"boolean\",\n \"date\",\n \"bigint\",\n \"symbol\",\n \"function\",\n \"undefined\",\n \"null\",\n \"array\",\n \"object\",\n \"unknown\",\n \"promise\",\n \"void\",\n \"never\",\n \"map\",\n \"set\",\n]);\nconst getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return ZodParsedType.undefined;\n case \"string\":\n return ZodParsedType.string;\n case \"number\":\n return isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;\n case \"boolean\":\n return ZodParsedType.boolean;\n case \"function\":\n return ZodParsedType.function;\n case \"bigint\":\n return ZodParsedType.bigint;\n case \"symbol\":\n return ZodParsedType.symbol;\n case \"object\":\n if (Array.isArray(data)) {\n return ZodParsedType.array;\n }\n if (data === null) {\n return ZodParsedType.null;\n }\n if (data.then &&\n typeof data.then === \"function\" &&\n data.catch &&\n typeof data.catch === \"function\") {\n return ZodParsedType.promise;\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return ZodParsedType.map;\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return ZodParsedType.set;\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return ZodParsedType.date;\n }\n return ZodParsedType.object;\n default:\n return ZodParsedType.unknown;\n }\n};\n\nconst ZodIssueCode = util.arrayToEnum([\n \"invalid_type\",\n \"invalid_literal\",\n \"custom\",\n \"invalid_union\",\n \"invalid_union_discriminator\",\n \"invalid_enum_value\",\n \"unrecognized_keys\",\n \"invalid_arguments\",\n \"invalid_return_type\",\n \"invalid_date\",\n \"invalid_string\",\n \"too_small\",\n \"too_big\",\n \"invalid_intersection_types\",\n \"not_multiple_of\",\n \"not_finite\",\n]);\nconst quotelessJson = (obj) => {\n const json = JSON.stringify(obj, null, 2);\n return json.replace(/\"([^\"]+)\":/g, \"$1:\");\n};\nclass ZodError extends Error {\n get errors() {\n return this.issues;\n }\n constructor(issues) {\n super();\n this.issues = [];\n this.addIssue = (sub) => {\n this.issues = [...this.issues, sub];\n };\n this.addIssues = (subs = []) => {\n this.issues = [...this.issues, ...subs];\n };\n const actualProto = new.target.prototype;\n if (Object.setPrototypeOf) {\n // eslint-disable-next-line ban/ban\n Object.setPrototypeOf(this, actualProto);\n }\n else {\n this.__proto__ = actualProto;\n }\n this.name = \"ZodError\";\n this.issues = issues;\n }\n format(_mapper) {\n const mapper = _mapper ||\n function (issue) {\n return issue.message;\n };\n const fieldErrors = { _errors: [] };\n const processError = (error) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\") {\n issue.unionErrors.map(processError);\n }\n else if (issue.code === \"invalid_return_type\") {\n processError(issue.returnTypeError);\n }\n else if (issue.code === \"invalid_arguments\") {\n processError(issue.argumentsError);\n }\n else if (issue.path.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < issue.path.length) {\n const el = issue.path[i];\n const terminal = i === issue.path.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n // if (typeof el === \"string\") {\n // curr[el] = curr[el] || { _errors: [] };\n // } else if (typeof el === \"number\") {\n // const errorArray: any = [];\n // errorArray._errors = [];\n // curr[el] = curr[el] || errorArray;\n // }\n }\n else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i++;\n }\n }\n }\n };\n processError(this);\n return fieldErrors;\n }\n static assert(value) {\n if (!(value instanceof ZodError)) {\n throw new Error(`Not a ZodError: ${value}`);\n }\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return this.issues.length === 0;\n }\n flatten(mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of this.issues) {\n if (sub.path.length > 0) {\n fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];\n fieldErrors[sub.path[0]].push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n }\n get formErrors() {\n return this.flatten();\n }\n}\nZodError.create = (issues) => {\n const error = new ZodError(issues);\n return error;\n};\n\nconst errorMap = (issue, _ctx) => {\n let message;\n switch (issue.code) {\n case ZodIssueCode.invalid_type:\n if (issue.received === ZodParsedType.undefined) {\n message = \"Required\";\n }\n else {\n message = `Expected ${issue.expected}, received ${issue.received}`;\n }\n break;\n case ZodIssueCode.invalid_literal:\n message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;\n break;\n case ZodIssueCode.unrecognized_keys:\n message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, \", \")}`;\n break;\n case ZodIssueCode.invalid_union:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_union_discriminator:\n message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;\n break;\n case ZodIssueCode.invalid_enum_value:\n message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;\n break;\n case ZodIssueCode.invalid_arguments:\n message = `Invalid function arguments`;\n break;\n case ZodIssueCode.invalid_return_type:\n message = `Invalid function return type`;\n break;\n case ZodIssueCode.invalid_date:\n message = `Invalid date`;\n break;\n case ZodIssueCode.invalid_string:\n if (typeof issue.validation === \"object\") {\n if (\"includes\" in issue.validation) {\n message = `Invalid input: must include \"${issue.validation.includes}\"`;\n if (typeof issue.validation.position === \"number\") {\n message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;\n }\n }\n else if (\"startsWith\" in issue.validation) {\n message = `Invalid input: must start with \"${issue.validation.startsWith}\"`;\n }\n else if (\"endsWith\" in issue.validation) {\n message = `Invalid input: must end with \"${issue.validation.endsWith}\"`;\n }\n else {\n util.assertNever(issue.validation);\n }\n }\n else if (issue.validation !== \"regex\") {\n message = `Invalid ${issue.validation}`;\n }\n else {\n message = \"Invalid\";\n }\n break;\n case ZodIssueCode.too_small:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? \"exactly\" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact\n ? `exactly equal to `\n : issue.inclusive\n ? `greater than or equal to `\n : `greater than `}${issue.minimum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact\n ? `exactly equal to `\n : issue.inclusive\n ? `greater than or equal to `\n : `greater than `}${new Date(Number(issue.minimum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodIssueCode.too_big:\n if (issue.type === \"array\")\n message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;\n else if (issue.type === \"string\")\n message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;\n else if (issue.type === \"number\")\n message = `Number must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `less than or equal to`\n : `less than`} ${issue.maximum}`;\n else if (issue.type === \"bigint\")\n message = `BigInt must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `less than or equal to`\n : `less than`} ${issue.maximum}`;\n else if (issue.type === \"date\")\n message = `Date must be ${issue.exact\n ? `exactly`\n : issue.inclusive\n ? `smaller than or equal to`\n : `smaller than`} ${new Date(Number(issue.maximum))}`;\n else\n message = \"Invalid input\";\n break;\n case ZodIssueCode.custom:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_intersection_types:\n message = `Intersection results could not be merged`;\n break;\n case ZodIssueCode.not_multiple_of:\n message = `Number must be a multiple of ${issue.multipleOf}`;\n break;\n case ZodIssueCode.not_finite:\n message = \"Number must be finite\";\n break;\n default:\n message = _ctx.defaultError;\n util.assertNever(issue);\n }\n return { message };\n};\n\nlet overrideErrorMap = errorMap;\nfunction setErrorMap(map) {\n overrideErrorMap = map;\n}\nfunction getErrorMap() {\n return overrideErrorMap;\n}\n\nconst makeIssue = (params) => {\n const { data, path, errorMaps, issueData } = params;\n const fullPath = [...path, ...(issueData.path || [])];\n const fullIssue = {\n ...issueData,\n path: fullPath,\n };\n if (issueData.message !== undefined) {\n return {\n ...issueData,\n path: fullPath,\n message: issueData.message,\n };\n }\n let errorMessage = \"\";\n const maps = errorMaps\n .filter((m) => !!m)\n .slice()\n .reverse();\n for (const map of maps) {\n errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;\n }\n return {\n ...issueData,\n path: fullPath,\n message: errorMessage,\n };\n};\nconst EMPTY_PATH = [];\nfunction addIssueToContext(ctx, issueData) {\n const overrideMap = getErrorMap();\n const issue = makeIssue({\n issueData: issueData,\n data: ctx.data,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap, // contextual error map is first priority\n ctx.schemaErrorMap, // then schema-bound map if available\n overrideMap, // then global override map\n overrideMap === errorMap ? undefined : errorMap, // then global default map\n ].filter((x) => !!x),\n });\n ctx.common.issues.push(issue);\n}\nclass ParseStatus {\n constructor() {\n this.value = \"valid\";\n }\n dirty() {\n if (this.value === \"valid\")\n this.value = \"dirty\";\n }\n abort() {\n if (this.value !== \"aborted\")\n this.value = \"aborted\";\n }\n static mergeArray(status, results) {\n const arrayValue = [];\n for (const s of results) {\n if (s.status === \"aborted\")\n return INVALID;\n if (s.status === \"dirty\")\n status.dirty();\n arrayValue.push(s.value);\n }\n return { status: status.value, value: arrayValue };\n }\n static async mergeObjectAsync(status, pairs) {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value,\n });\n }\n return ParseStatus.mergeObjectSync(status, syncPairs);\n }\n static mergeObjectSync(status, pairs) {\n const finalObject = {};\n for (const pair of pairs) {\n const { key, value } = pair;\n if (key.status === \"aborted\")\n return INVALID;\n if (value.status === \"aborted\")\n return INVALID;\n if (key.status === \"dirty\")\n status.dirty();\n if (value.status === \"dirty\")\n status.dirty();\n if (key.value !== \"__proto__\" &&\n (typeof value.value !== \"undefined\" || pair.alwaysSet)) {\n finalObject[key.value] = value.value;\n }\n }\n return { status: status.value, value: finalObject };\n }\n}\nconst INVALID = Object.freeze({\n status: \"aborted\",\n});\nconst DIRTY = (value) => ({ status: \"dirty\", value });\nconst OK = (value) => ({ status: \"valid\", value });\nconst isAborted = (x) => x.status === \"aborted\";\nconst isDirty = (x) => x.status === \"dirty\";\nconst isValid = (x) => x.status === \"valid\";\nconst isAsync = (x) => typeof Promise !== \"undefined\" && x instanceof Promise;\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nvar errorUtil;\n(function (errorUtil) {\n errorUtil.errToObj = (message) => typeof message === \"string\" ? { message } : message || {};\n errorUtil.toString = (message) => typeof message === \"string\" ? message : message === null || message === void 0 ? void 0 : message.message;\n})(errorUtil || (errorUtil = {}));\n\nvar _ZodEnum_cache, _ZodNativeEnum_cache;\nclass ParseInputLazyPath {\n constructor(parent, value, path, key) {\n this._cachedPath = [];\n this.parent = parent;\n this.data = value;\n this._path = path;\n this._key = key;\n }\n get path() {\n if (!this._cachedPath.length) {\n if (this._key instanceof Array) {\n this._cachedPath.push(...this._path, ...this._key);\n }\n else {\n this._cachedPath.push(...this._path, this._key);\n }\n }\n return this._cachedPath;\n }\n}\nconst handleResult = (ctx, result) => {\n if (isValid(result)) {\n return { success: true, data: result.value };\n }\n else {\n if (!ctx.common.issues.length) {\n throw new Error(\"Validation failed but no issues detected.\");\n }\n return {\n success: false,\n get error() {\n if (this._error)\n return this._error;\n const error = new ZodError(ctx.common.issues);\n this._error = error;\n return this._error;\n },\n };\n }\n};\nfunction processCreateParams(params) {\n if (!params)\n return {};\n const { errorMap, invalid_type_error, required_error, description } = params;\n if (errorMap && (invalid_type_error || required_error)) {\n throw new Error(`Can't use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.`);\n }\n if (errorMap)\n return { errorMap: errorMap, description };\n const customMap = (iss, ctx) => {\n var _a, _b;\n const { message } = params;\n if (iss.code === \"invalid_enum_value\") {\n return { message: message !== null && message !== void 0 ? message : ctx.defaultError };\n }\n if (typeof ctx.data === \"undefined\") {\n return { message: (_a = message !== null && message !== void 0 ? message : required_error) !== null && _a !== void 0 ? _a : ctx.defaultError };\n }\n if (iss.code !== \"invalid_type\")\n return { message: ctx.defaultError };\n return { message: (_b = message !== null && message !== void 0 ? message : invalid_type_error) !== null && _b !== void 0 ? _b : ctx.defaultError };\n };\n return { errorMap: customMap, description };\n}\nclass ZodType {\n get description() {\n return this._def.description;\n }\n _getType(input) {\n return getParsedType(input.data);\n }\n _getOrReturnCtx(input, ctx) {\n return (ctx || {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n });\n }\n _processInputParams(input) {\n return {\n status: new ParseStatus(),\n ctx: {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent,\n },\n };\n }\n _parseSync(input) {\n const result = this._parse(input);\n if (isAsync(result)) {\n throw new Error(\"Synchronous parse encountered promise.\");\n }\n return result;\n }\n _parseAsync(input) {\n const result = this._parse(input);\n return Promise.resolve(result);\n }\n parse(data, params) {\n const result = this.safeParse(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n safeParse(data, params) {\n var _a;\n const ctx = {\n common: {\n issues: [],\n async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false,\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n const result = this._parseSync({ data, path: ctx.path, parent: ctx });\n return handleResult(ctx, result);\n }\n \"~validate\"(data) {\n var _a, _b;\n const ctx = {\n common: {\n issues: [],\n async: !!this[\"~standard\"].async,\n },\n path: [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n if (!this[\"~standard\"].async) {\n try {\n const result = this._parseSync({ data, path: [], parent: ctx });\n return isValid(result)\n ? {\n value: result.value,\n }\n : {\n issues: ctx.common.issues,\n };\n }\n catch (err) {\n if ((_b = (_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === null || _b === void 0 ? void 0 : _b.includes(\"encountered\")) {\n this[\"~standard\"].async = true;\n }\n ctx.common = {\n issues: [],\n async: true,\n };\n }\n }\n return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result)\n ? {\n value: result.value,\n }\n : {\n issues: ctx.common.issues,\n });\n }\n async parseAsync(data, params) {\n const result = await this.safeParseAsync(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n async safeParseAsync(data, params) {\n const ctx = {\n common: {\n issues: [],\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n async: true,\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data),\n };\n const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });\n const result = await (isAsync(maybeAsyncResult)\n ? maybeAsyncResult\n : Promise.resolve(maybeAsyncResult));\n return handleResult(ctx, result);\n }\n refine(check, message) {\n const getIssueProperties = (val) => {\n if (typeof message === \"string\" || typeof message === \"undefined\") {\n return { message };\n }\n else if (typeof message === \"function\") {\n return message(val);\n }\n else {\n return message;\n }\n };\n return this._refinement((val, ctx) => {\n const result = check(val);\n const setError = () => ctx.addIssue({\n code: ZodIssueCode.custom,\n ...getIssueProperties(val),\n });\n if (typeof Promise !== \"undefined\" && result instanceof Promise) {\n return result.then((data) => {\n if (!data) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n if (!result) {\n setError();\n return false;\n }\n else {\n return true;\n }\n });\n }\n refinement(check, refinementData) {\n return this._refinement((val, ctx) => {\n if (!check(val)) {\n ctx.addIssue(typeof refinementData === \"function\"\n ? refinementData(val, ctx)\n : refinementData);\n return false;\n }\n else {\n return true;\n }\n });\n }\n _refinement(refinement) {\n return new ZodEffects({\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"refinement\", refinement },\n });\n }\n superRefine(refinement) {\n return this._refinement(refinement);\n }\n constructor(def) {\n /** Alias of safeParseAsync */\n this.spa = this.safeParseAsync;\n this._def = def;\n this.parse = this.parse.bind(this);\n this.safeParse = this.safeParse.bind(this);\n this.parseAsync = this.parseAsync.bind(this);\n this.safeParseAsync = this.safeParseAsync.bind(this);\n this.spa = this.spa.bind(this);\n this.refine = this.refine.bind(this);\n this.refinement = this.refinement.bind(this);\n this.superRefine = this.superRefine.bind(this);\n this.optional = this.optional.bind(this);\n this.nullable = this.nullable.bind(this);\n this.nullish = this.nullish.bind(this);\n this.array = this.array.bind(this);\n this.promise = this.promise.bind(this);\n this.or = this.or.bind(this);\n this.and = this.and.bind(this);\n this.transform = this.transform.bind(this);\n this.brand = this.brand.bind(this);\n this.default = this.default.bind(this);\n this.catch = this.catch.bind(this);\n this.describe = this.describe.bind(this);\n this.pipe = this.pipe.bind(this);\n this.readonly = this.readonly.bind(this);\n this.isNullable = this.isNullable.bind(this);\n this.isOptional = this.isOptional.bind(this);\n this[\"~standard\"] = {\n version: 1,\n vendor: \"zod\",\n validate: (data) => this[\"~validate\"](data),\n };\n }\n optional() {\n return ZodOptional.create(this, this._def);\n }\n nullable() {\n return ZodNullable.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return ZodArray.create(this);\n }\n promise() {\n return ZodPromise.create(this, this._def);\n }\n or(option) {\n return ZodUnion.create([this, option], this._def);\n }\n and(incoming) {\n return ZodIntersection.create(this, incoming, this._def);\n }\n transform(transform) {\n return new ZodEffects({\n ...processCreateParams(this._def),\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: \"transform\", transform },\n });\n }\n default(def) {\n const defaultValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodDefault({\n ...processCreateParams(this._def),\n innerType: this,\n defaultValue: defaultValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n });\n }\n brand() {\n return new ZodBranded({\n typeName: ZodFirstPartyTypeKind.ZodBranded,\n type: this,\n ...processCreateParams(this._def),\n });\n }\n catch(def) {\n const catchValueFunc = typeof def === \"function\" ? def : () => def;\n return new ZodCatch({\n ...processCreateParams(this._def),\n innerType: this,\n catchValue: catchValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n });\n }\n describe(description) {\n const This = this.constructor;\n return new This({\n ...this._def,\n description,\n });\n }\n pipe(target) {\n return ZodPipeline.create(this, target);\n }\n readonly() {\n return ZodReadonly.create(this);\n }\n isOptional() {\n return this.safeParse(undefined).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n}\nconst cuidRegex = /^c[^\\s-]{8,}$/i;\nconst cuid2Regex = /^[0-9a-z]+$/;\nconst ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;\n// const uuidRegex =\n// /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;\nconst uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i;\nconst nanoidRegex = /^[a-z0-9_-]{21}$/i;\nconst jwtRegex = /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/;\nconst durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/;\n// from https://stackoverflow.com/a/46181/1550155\n// old version: too slow, didn't support unicode\n// const emailRegex = /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i;\n//old email regex\n// const emailRegex = /^(([^<>()[\\].,;:\\s@\"]+(\\.[^<>()[\\].,;:\\s@\"]+)*)|(\".+\"))@((?!-)([^<>()[\\].,;:\\s@\"]+\\.)+[^<>()[\\].,;:\\s@\"]{1,})[^-<>()[\\].,;:\\s@\"]$/i;\n// eslint-disable-next-line\n// const emailRegex =\n// /^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\])|(\\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\\.[A-Za-z]{2,})+))$/;\n// const emailRegex =\n// /^[a-zA-Z0-9\\.\\!\\#\\$\\%\\&\\'\\*\\+\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~\\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n// const emailRegex =\n// /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])$/i;\nconst emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n// const emailRegex =\n// /^[a-z0-9.!#$%&\u2019*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\\.[a-z0-9\\-]+)*$/i;\n// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression\nconst _emojiRegex = `^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$`;\nlet emojiRegex;\n// faster, simpler, safer\nconst ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;\nconst ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/;\n// const ipv6Regex =\n// /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;\nconst ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\nconst ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;\n// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript\nconst base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;\n// https://base64.guru/standards/base64url\nconst base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;\n// simple\n// const dateRegexSource = `\\\\d{4}-\\\\d{2}-\\\\d{2}`;\n// no leap year validation\n// const dateRegexSource = `\\\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\\\d|2\\\\d))`;\n// with leap year validation\nconst dateRegexSource = `((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))`;\nconst dateRegex = new RegExp(`^${dateRegexSource}$`);\nfunction timeRegexSource(args) {\n // let regex = `\\\\d{2}:\\\\d{2}:\\\\d{2}`;\n let regex = `([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d`;\n if (args.precision) {\n regex = `${regex}\\\\.\\\\d{${args.precision}}`;\n }\n else if (args.precision == null) {\n regex = `${regex}(\\\\.\\\\d+)?`;\n }\n return regex;\n}\nfunction timeRegex(args) {\n return new RegExp(`^${timeRegexSource(args)}$`);\n}\n// Adapted from https://stackoverflow.com/a/3143231\nfunction datetimeRegex(args) {\n let regex = `${dateRegexSource}T${timeRegexSource(args)}`;\n const opts = [];\n opts.push(args.local ? `Z?` : `Z`);\n if (args.offset)\n opts.push(`([+-]\\\\d{2}:?\\\\d{2})`);\n regex = `${regex}(${opts.join(\"|\")})`;\n return new RegExp(`^${regex}$`);\n}\nfunction isValidIP(ip, version) {\n if ((version === \"v4\" || !version) && ipv4Regex.test(ip)) {\n return true;\n }\n if ((version === \"v6\" || !version) && ipv6Regex.test(ip)) {\n return true;\n }\n return false;\n}\nfunction isValidJWT(jwt, alg) {\n if (!jwtRegex.test(jwt))\n return false;\n try {\n const [header] = jwt.split(\".\");\n // Convert base64url to base64\n const base64 = header\n .replace(/-/g, \"+\")\n .replace(/_/g, \"/\")\n .padEnd(header.length + ((4 - (header.length % 4)) % 4), \"=\");\n const decoded = JSON.parse(atob(base64));\n if (typeof decoded !== \"object\" || decoded === null)\n return false;\n if (!decoded.typ || !decoded.alg)\n return false;\n if (alg && decoded.alg !== alg)\n return false;\n return true;\n }\n catch (_a) {\n return false;\n }\n}\nfunction isValidCidr(ip, version) {\n if ((version === \"v4\" || !version) && ipv4CidrRegex.test(ip)) {\n return true;\n }\n if ((version === \"v6\" || !version) && ipv6CidrRegex.test(ip)) {\n return true;\n }\n return false;\n}\nclass ZodString extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = String(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.string) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.string,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const status = new ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.length < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.length > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"length\") {\n const tooBig = input.data.length > check.value;\n const tooSmall = input.data.length < check.value;\n if (tooBig || tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n if (tooBig) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n else if (tooSmall) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: \"string\",\n inclusive: true,\n exact: true,\n message: check.message,\n });\n }\n status.dirty();\n }\n }\n else if (check.kind === \"email\") {\n if (!emailRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"email\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"emoji\") {\n if (!emojiRegex) {\n emojiRegex = new RegExp(_emojiRegex, \"u\");\n }\n if (!emojiRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"emoji\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"uuid\") {\n if (!uuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"uuid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"nanoid\") {\n if (!nanoidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"nanoid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid\") {\n if (!cuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"cuid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cuid2\") {\n if (!cuid2Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"cuid2\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ulid\") {\n if (!ulidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"ulid\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"url\") {\n try {\n new URL(input.data);\n }\n catch (_a) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"url\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"regex\") {\n check.regex.lastIndex = 0;\n const testResult = check.regex.test(input.data);\n if (!testResult) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"regex\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"trim\") {\n input.data = input.data.trim();\n }\n else if (check.kind === \"includes\") {\n if (!input.data.includes(check.value, check.position)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { includes: check.value, position: check.position },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"toLowerCase\") {\n input.data = input.data.toLowerCase();\n }\n else if (check.kind === \"toUpperCase\") {\n input.data = input.data.toUpperCase();\n }\n else if (check.kind === \"startsWith\") {\n if (!input.data.startsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { startsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"endsWith\") {\n if (!input.data.endsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { endsWith: check.value },\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"datetime\") {\n const regex = datetimeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: \"datetime\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"date\") {\n const regex = dateRegex;\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: \"date\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"time\") {\n const regex = timeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: \"time\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"duration\") {\n if (!durationRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"duration\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"ip\") {\n if (!isValidIP(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"ip\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"jwt\") {\n if (!isValidJWT(input.data, check.alg)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"jwt\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"cidr\") {\n if (!isValidCidr(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"cidr\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"base64\") {\n if (!base64Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"base64\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"base64url\") {\n if (!base64urlRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: \"base64url\",\n code: ZodIssueCode.invalid_string,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _regex(regex, validation, message) {\n return this.refinement((data) => regex.test(data), {\n validation,\n code: ZodIssueCode.invalid_string,\n ...errorUtil.errToObj(message),\n });\n }\n _addCheck(check) {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n email(message) {\n return this._addCheck({ kind: \"email\", ...errorUtil.errToObj(message) });\n }\n url(message) {\n return this._addCheck({ kind: \"url\", ...errorUtil.errToObj(message) });\n }\n emoji(message) {\n return this._addCheck({ kind: \"emoji\", ...errorUtil.errToObj(message) });\n }\n uuid(message) {\n return this._addCheck({ kind: \"uuid\", ...errorUtil.errToObj(message) });\n }\n nanoid(message) {\n return this._addCheck({ kind: \"nanoid\", ...errorUtil.errToObj(message) });\n }\n cuid(message) {\n return this._addCheck({ kind: \"cuid\", ...errorUtil.errToObj(message) });\n }\n cuid2(message) {\n return this._addCheck({ kind: \"cuid2\", ...errorUtil.errToObj(message) });\n }\n ulid(message) {\n return this._addCheck({ kind: \"ulid\", ...errorUtil.errToObj(message) });\n }\n base64(message) {\n return this._addCheck({ kind: \"base64\", ...errorUtil.errToObj(message) });\n }\n base64url(message) {\n // base64url encoding is a modification of base64 that can safely be used in URLs and filenames\n return this._addCheck({\n kind: \"base64url\",\n ...errorUtil.errToObj(message),\n });\n }\n jwt(options) {\n return this._addCheck({ kind: \"jwt\", ...errorUtil.errToObj(options) });\n }\n ip(options) {\n return this._addCheck({ kind: \"ip\", ...errorUtil.errToObj(options) });\n }\n cidr(options) {\n return this._addCheck({ kind: \"cidr\", ...errorUtil.errToObj(options) });\n }\n datetime(options) {\n var _a, _b;\n if (typeof options === \"string\") {\n return this._addCheck({\n kind: \"datetime\",\n precision: null,\n offset: false,\n local: false,\n message: options,\n });\n }\n return this._addCheck({\n kind: \"datetime\",\n precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === \"undefined\" ? null : options === null || options === void 0 ? void 0 : options.precision,\n offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false,\n local: (_b = options === null || options === void 0 ? void 0 : options.local) !== null && _b !== void 0 ? _b : false,\n ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n date(message) {\n return this._addCheck({ kind: \"date\", message });\n }\n time(options) {\n if (typeof options === \"string\") {\n return this._addCheck({\n kind: \"time\",\n precision: null,\n message: options,\n });\n }\n return this._addCheck({\n kind: \"time\",\n precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === \"undefined\" ? null : options === null || options === void 0 ? void 0 : options.precision,\n ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n duration(message) {\n return this._addCheck({ kind: \"duration\", ...errorUtil.errToObj(message) });\n }\n regex(regex, message) {\n return this._addCheck({\n kind: \"regex\",\n regex: regex,\n ...errorUtil.errToObj(message),\n });\n }\n includes(value, options) {\n return this._addCheck({\n kind: \"includes\",\n value: value,\n position: options === null || options === void 0 ? void 0 : options.position,\n ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),\n });\n }\n startsWith(value, message) {\n return this._addCheck({\n kind: \"startsWith\",\n value: value,\n ...errorUtil.errToObj(message),\n });\n }\n endsWith(value, message) {\n return this._addCheck({\n kind: \"endsWith\",\n value: value,\n ...errorUtil.errToObj(message),\n });\n }\n min(minLength, message) {\n return this._addCheck({\n kind: \"min\",\n value: minLength,\n ...errorUtil.errToObj(message),\n });\n }\n max(maxLength, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxLength,\n ...errorUtil.errToObj(message),\n });\n }\n length(len, message) {\n return this._addCheck({\n kind: \"length\",\n value: len,\n ...errorUtil.errToObj(message),\n });\n }\n /**\n * Equivalent to `.min(1)`\n */\n nonempty(message) {\n return this.min(1, errorUtil.errToObj(message));\n }\n trim() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"trim\" }],\n });\n }\n toLowerCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toLowerCase\" }],\n });\n }\n toUpperCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: \"toUpperCase\" }],\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((ch) => ch.kind === \"datetime\");\n }\n get isDate() {\n return !!this._def.checks.find((ch) => ch.kind === \"date\");\n }\n get isTime() {\n return !!this._def.checks.find((ch) => ch.kind === \"time\");\n }\n get isDuration() {\n return !!this._def.checks.find((ch) => ch.kind === \"duration\");\n }\n get isEmail() {\n return !!this._def.checks.find((ch) => ch.kind === \"email\");\n }\n get isURL() {\n return !!this._def.checks.find((ch) => ch.kind === \"url\");\n }\n get isEmoji() {\n return !!this._def.checks.find((ch) => ch.kind === \"emoji\");\n }\n get isUUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"uuid\");\n }\n get isNANOID() {\n return !!this._def.checks.find((ch) => ch.kind === \"nanoid\");\n }\n get isCUID() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid\");\n }\n get isCUID2() {\n return !!this._def.checks.find((ch) => ch.kind === \"cuid2\");\n }\n get isULID() {\n return !!this._def.checks.find((ch) => ch.kind === \"ulid\");\n }\n get isIP() {\n return !!this._def.checks.find((ch) => ch.kind === \"ip\");\n }\n get isCIDR() {\n return !!this._def.checks.find((ch) => ch.kind === \"cidr\");\n }\n get isBase64() {\n return !!this._def.checks.find((ch) => ch.kind === \"base64\");\n }\n get isBase64url() {\n // base64url encoding is a modification of base64 that can safely be used in URLs and filenames\n return !!this._def.checks.find((ch) => ch.kind === \"base64url\");\n }\n get minLength() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxLength() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nZodString.create = (params) => {\n var _a;\n return new ZodString({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodString,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params),\n });\n};\n// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034\nfunction floatSafeRemainder(val, step) {\n const valDecCount = (val.toString().split(\".\")[1] || \"\").length;\n const stepDecCount = (step.toString().split(\".\")[1] || \"\").length;\n const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;\n const valInt = parseInt(val.toFixed(decCount).replace(\".\", \"\"));\n const stepInt = parseInt(step.toFixed(decCount).replace(\".\", \"\"));\n return (valInt % stepInt) / Math.pow(10, decCount);\n}\nclass ZodNumber extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n this.step = this.multipleOf;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.number) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.number,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n let ctx = undefined;\n const status = new ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"int\") {\n if (!util.isInteger(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: \"integer\",\n received: \"float\",\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"min\") {\n const tooSmall = check.inclusive\n ? input.data < check.value\n : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive\n ? input.data > check.value\n : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: \"number\",\n inclusive: check.inclusive,\n exact: false,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (floatSafeRemainder(input.data, check.value) !== 0) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"finite\") {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_finite,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodNumber({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodNumber({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n int(message) {\n return this._addCheck({\n kind: \"int\",\n message: errorUtil.toString(message),\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: 0,\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: 0,\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value: value,\n message: errorUtil.toString(message),\n });\n }\n finite(message) {\n return this._addCheck({\n kind: \"finite\",\n message: errorUtil.toString(message),\n });\n }\n safe(message) {\n return this._addCheck({\n kind: \"min\",\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message: errorUtil.toString(message),\n })._addCheck({\n kind: \"max\",\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message: errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n get isInt() {\n return !!this._def.checks.find((ch) => ch.kind === \"int\" ||\n (ch.kind === \"multipleOf\" && util.isInteger(ch.value)));\n }\n get isFinite() {\n let max = null, min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"finite\" ||\n ch.kind === \"int\" ||\n ch.kind === \"multipleOf\") {\n return true;\n }\n else if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n else if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n}\nZodNumber.create = (params) => {\n return new ZodNumber({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodNumber,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params),\n });\n};\nclass ZodBigInt extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n }\n _parse(input) {\n if (this._def.coerce) {\n try {\n input.data = BigInt(input.data);\n }\n catch (_a) {\n return this._getInvalidInput(input);\n }\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.bigint) {\n return this._getInvalidInput(input);\n }\n let ctx = undefined;\n const status = new ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n const tooSmall = check.inclusive\n ? input.data < check.value\n : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n type: \"bigint\",\n minimum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n const tooBig = check.inclusive\n ? input.data > check.value\n : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n type: \"bigint\",\n maximum: check.value,\n inclusive: check.inclusive,\n message: check.message,\n });\n status.dirty();\n }\n }\n else if (check.kind === \"multipleOf\") {\n if (input.data % check.value !== BigInt(0)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message,\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _getInvalidInput(input) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.bigint,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n gte(value, message) {\n return this.setLimit(\"min\", value, true, errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit(\"min\", value, false, errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit(\"max\", value, true, errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit(\"max\", value, false, errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodBigInt({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil.toString(message),\n },\n ],\n });\n }\n _addCheck(check) {\n return new ZodBigInt({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n positive(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n negative(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil.toString(message),\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: \"max\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: \"min\",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil.toString(message),\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: \"multipleOf\",\n value,\n message: errorUtil.toString(message),\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n}\nZodBigInt.create = (params) => {\n var _a;\n return new ZodBigInt({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodBigInt,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params),\n });\n};\nclass ZodBoolean extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = Boolean(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.boolean) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.boolean,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodBoolean.create = (params) => {\n return new ZodBoolean({\n typeName: ZodFirstPartyTypeKind.ZodBoolean,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params),\n });\n};\nclass ZodDate extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = new Date(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.date) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.date,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n if (isNaN(input.data.getTime())) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_date,\n });\n return INVALID;\n }\n const status = new ParseStatus();\n let ctx = undefined;\n for (const check of this._def.checks) {\n if (check.kind === \"min\") {\n if (input.data.getTime() < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n message: check.message,\n inclusive: true,\n exact: false,\n minimum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else if (check.kind === \"max\") {\n if (input.data.getTime() > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n message: check.message,\n inclusive: true,\n exact: false,\n maximum: check.value,\n type: \"date\",\n });\n status.dirty();\n }\n }\n else {\n util.assertNever(check);\n }\n }\n return {\n status: status.value,\n value: new Date(input.data.getTime()),\n };\n }\n _addCheck(check) {\n return new ZodDate({\n ...this._def,\n checks: [...this._def.checks, check],\n });\n }\n min(minDate, message) {\n return this._addCheck({\n kind: \"min\",\n value: minDate.getTime(),\n message: errorUtil.toString(message),\n });\n }\n max(maxDate, message) {\n return this._addCheck({\n kind: \"max\",\n value: maxDate.getTime(),\n message: errorUtil.toString(message),\n });\n }\n get minDate() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"min\") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min != null ? new Date(min) : null;\n }\n get maxDate() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === \"max\") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max != null ? new Date(max) : null;\n }\n}\nZodDate.create = (params) => {\n return new ZodDate({\n checks: [],\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n typeName: ZodFirstPartyTypeKind.ZodDate,\n ...processCreateParams(params),\n });\n};\nclass ZodSymbol extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.symbol) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.symbol,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodSymbol.create = (params) => {\n return new ZodSymbol({\n typeName: ZodFirstPartyTypeKind.ZodSymbol,\n ...processCreateParams(params),\n });\n};\nclass ZodUndefined extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.undefined,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodUndefined.create = (params) => {\n return new ZodUndefined({\n typeName: ZodFirstPartyTypeKind.ZodUndefined,\n ...processCreateParams(params),\n });\n};\nclass ZodNull extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.null) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.null,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodNull.create = (params) => {\n return new ZodNull({\n typeName: ZodFirstPartyTypeKind.ZodNull,\n ...processCreateParams(params),\n });\n};\nclass ZodAny extends ZodType {\n constructor() {\n super(...arguments);\n // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject.\n this._any = true;\n }\n _parse(input) {\n return OK(input.data);\n }\n}\nZodAny.create = (params) => {\n return new ZodAny({\n typeName: ZodFirstPartyTypeKind.ZodAny,\n ...processCreateParams(params),\n });\n};\nclass ZodUnknown extends ZodType {\n constructor() {\n super(...arguments);\n // required\n this._unknown = true;\n }\n _parse(input) {\n return OK(input.data);\n }\n}\nZodUnknown.create = (params) => {\n return new ZodUnknown({\n typeName: ZodFirstPartyTypeKind.ZodUnknown,\n ...processCreateParams(params),\n });\n};\nclass ZodNever extends ZodType {\n _parse(input) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.never,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n}\nZodNever.create = (params) => {\n return new ZodNever({\n typeName: ZodFirstPartyTypeKind.ZodNever,\n ...processCreateParams(params),\n });\n};\nclass ZodVoid extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.void,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n}\nZodVoid.create = (params) => {\n return new ZodVoid({\n typeName: ZodFirstPartyTypeKind.ZodVoid,\n ...processCreateParams(params),\n });\n};\nclass ZodArray extends ZodType {\n _parse(input) {\n const { ctx, status } = this._processInputParams(input);\n const def = this._def;\n if (ctx.parsedType !== ZodParsedType.array) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.array,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n if (def.exactLength !== null) {\n const tooBig = ctx.data.length > def.exactLength.value;\n const tooSmall = ctx.data.length < def.exactLength.value;\n if (tooBig || tooSmall) {\n addIssueToContext(ctx, {\n code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,\n minimum: (tooSmall ? def.exactLength.value : undefined),\n maximum: (tooBig ? def.exactLength.value : undefined),\n type: \"array\",\n inclusive: true,\n exact: true,\n message: def.exactLength.message,\n });\n status.dirty();\n }\n }\n if (def.minLength !== null) {\n if (ctx.data.length < def.minLength.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: def.minLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.minLength.message,\n });\n status.dirty();\n }\n }\n if (def.maxLength !== null) {\n if (ctx.data.length > def.maxLength.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: def.maxLength.value,\n type: \"array\",\n inclusive: true,\n exact: false,\n message: def.maxLength.message,\n });\n status.dirty();\n }\n }\n if (ctx.common.async) {\n return Promise.all([...ctx.data].map((item, i) => {\n return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n })).then((result) => {\n return ParseStatus.mergeArray(status, result);\n });\n }\n const result = [...ctx.data].map((item, i) => {\n return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));\n });\n return ParseStatus.mergeArray(status, result);\n }\n get element() {\n return this._def.type;\n }\n min(minLength, message) {\n return new ZodArray({\n ...this._def,\n minLength: { value: minLength, message: errorUtil.toString(message) },\n });\n }\n max(maxLength, message) {\n return new ZodArray({\n ...this._def,\n maxLength: { value: maxLength, message: errorUtil.toString(message) },\n });\n }\n length(len, message) {\n return new ZodArray({\n ...this._def,\n exactLength: { value: len, message: errorUtil.toString(message) },\n });\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nZodArray.create = (schema, params) => {\n return new ZodArray({\n type: schema,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: ZodFirstPartyTypeKind.ZodArray,\n ...processCreateParams(params),\n });\n};\nfunction deepPartialify(schema) {\n if (schema instanceof ZodObject) {\n const newShape = {};\n for (const key in schema.shape) {\n const fieldSchema = schema.shape[key];\n newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));\n }\n return new ZodObject({\n ...schema._def,\n shape: () => newShape,\n });\n }\n else if (schema instanceof ZodArray) {\n return new ZodArray({\n ...schema._def,\n type: deepPartialify(schema.element),\n });\n }\n else if (schema instanceof ZodOptional) {\n return ZodOptional.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodNullable) {\n return ZodNullable.create(deepPartialify(schema.unwrap()));\n }\n else if (schema instanceof ZodTuple) {\n return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));\n }\n else {\n return schema;\n }\n}\nclass ZodObject extends ZodType {\n constructor() {\n super(...arguments);\n this._cached = null;\n /**\n * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped.\n * If you want to pass through unknown properties, use `.passthrough()` instead.\n */\n this.nonstrict = this.passthrough;\n // extend<\n // Augmentation extends ZodRawShape,\n // NewOutput extends util.flatten<{\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // }>,\n // NewInput extends util.flatten<{\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }>\n // >(\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape,\n // UnknownKeys,\n // Catchall,\n // NewOutput,\n // NewInput\n // > {\n // return new ZodObject({\n // ...this._def,\n // shape: () => ({\n // ...this._def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // }\n /**\n * @deprecated Use `.extend` instead\n * */\n this.augment = this.extend;\n }\n _getCached() {\n if (this._cached !== null)\n return this._cached;\n const shape = this._def.shape();\n const keys = util.objectKeys(shape);\n return (this._cached = { shape, keys });\n }\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.object) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const { status, ctx } = this._processInputParams(input);\n const { shape, keys: shapeKeys } = this._getCached();\n const extraKeys = [];\n if (!(this._def.catchall instanceof ZodNever &&\n this._def.unknownKeys === \"strip\")) {\n for (const key in ctx.data) {\n if (!shapeKeys.includes(key)) {\n extraKeys.push(key);\n }\n }\n }\n const pairs = [];\n for (const key of shapeKeys) {\n const keyValidator = shape[key];\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),\n alwaysSet: key in ctx.data,\n });\n }\n if (this._def.catchall instanceof ZodNever) {\n const unknownKeys = this._def.unknownKeys;\n if (unknownKeys === \"passthrough\") {\n for (const key of extraKeys) {\n pairs.push({\n key: { status: \"valid\", value: key },\n value: { status: \"valid\", value: ctx.data[key] },\n });\n }\n }\n else if (unknownKeys === \"strict\") {\n if (extraKeys.length > 0) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.unrecognized_keys,\n keys: extraKeys,\n });\n status.dirty();\n }\n }\n else if (unknownKeys === \"strip\") ;\n else {\n throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);\n }\n }\n else {\n // run catchall validation\n const catchall = this._def.catchall;\n for (const key of extraKeys) {\n const value = ctx.data[key];\n pairs.push({\n key: { status: \"valid\", value: key },\n value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value)\n ),\n alwaysSet: key in ctx.data,\n });\n }\n }\n if (ctx.common.async) {\n return Promise.resolve()\n .then(async () => {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value,\n alwaysSet: pair.alwaysSet,\n });\n }\n return syncPairs;\n })\n .then((syncPairs) => {\n return ParseStatus.mergeObjectSync(status, syncPairs);\n });\n }\n else {\n return ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get shape() {\n return this._def.shape();\n }\n strict(message) {\n errorUtil.errToObj;\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strict\",\n ...(message !== undefined\n ? {\n errorMap: (issue, ctx) => {\n var _a, _b, _c, _d;\n const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;\n if (issue.code === \"unrecognized_keys\")\n return {\n message: (_d = errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError,\n };\n return {\n message: defaultError,\n };\n },\n }\n : {}),\n });\n }\n strip() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"strip\",\n });\n }\n passthrough() {\n return new ZodObject({\n ...this._def,\n unknownKeys: \"passthrough\",\n });\n }\n // const AugmentFactory =\n // (def: Def) =>\n // (\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape, Augmentation>,\n // Def[\"unknownKeys\"],\n // Def[\"catchall\"]\n // > => {\n // return new ZodObject({\n // ...def,\n // shape: () => ({\n // ...def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // };\n extend(augmentation) {\n return new ZodObject({\n ...this._def,\n shape: () => ({\n ...this._def.shape(),\n ...augmentation,\n }),\n });\n }\n /**\n * Prior to zod@1.0.12 there was a bug in the\n * inferred type of merged objects. Please\n * upgrade if you are experiencing issues.\n */\n merge(merging) {\n const merged = new ZodObject({\n unknownKeys: merging._def.unknownKeys,\n catchall: merging._def.catchall,\n shape: () => ({\n ...this._def.shape(),\n ...merging._def.shape(),\n }),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n });\n return merged;\n }\n // merge<\n // Incoming extends AnyZodObject,\n // Augmentation extends Incoming[\"shape\"],\n // NewOutput extends {\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k][\"_output\"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // },\n // NewInput extends {\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k][\"_input\"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }\n // >(\n // merging: Incoming\n // ): ZodObject<\n // extendShape>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"],\n // NewOutput,\n // NewInput\n // > {\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n setKey(key, schema) {\n return this.augment({ [key]: schema });\n }\n // merge(\n // merging: Incoming\n // ): //ZodObject = (merging) => {\n // ZodObject<\n // extendShape>,\n // Incoming[\"_def\"][\"unknownKeys\"],\n // Incoming[\"_def\"][\"catchall\"]\n // > {\n // // const mergedShape = objectUtil.mergeShapes(\n // // this._def.shape(),\n // // merging._def.shape()\n // // );\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n catchall(index) {\n return new ZodObject({\n ...this._def,\n catchall: index,\n });\n }\n pick(mask) {\n const shape = {};\n util.objectKeys(mask).forEach((key) => {\n if (mask[key] && this.shape[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n omit(mask) {\n const shape = {};\n util.objectKeys(this.shape).forEach((key) => {\n if (!mask[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape,\n });\n }\n /**\n * @deprecated\n */\n deepPartial() {\n return deepPartialify(this);\n }\n partial(mask) {\n const newShape = {};\n util.objectKeys(this.shape).forEach((key) => {\n const fieldSchema = this.shape[key];\n if (mask && !mask[key]) {\n newShape[key] = fieldSchema;\n }\n else {\n newShape[key] = fieldSchema.optional();\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n required(mask) {\n const newShape = {};\n util.objectKeys(this.shape).forEach((key) => {\n if (mask && !mask[key]) {\n newShape[key] = this.shape[key];\n }\n else {\n const fieldSchema = this.shape[key];\n let newField = fieldSchema;\n while (newField instanceof ZodOptional) {\n newField = newField._def.innerType;\n }\n newShape[key] = newField;\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape,\n });\n }\n keyof() {\n return createZodEnum(util.objectKeys(this.shape));\n }\n}\nZodObject.create = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.strictCreate = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: \"strict\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nZodObject.lazycreate = (shape, params) => {\n return new ZodObject({\n shape,\n unknownKeys: \"strip\",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params),\n });\n};\nclass ZodUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const options = this._def.options;\n function handleResults(results) {\n // return first issue-free validation if it exists\n for (const result of results) {\n if (result.result.status === \"valid\") {\n return result.result;\n }\n }\n for (const result of results) {\n if (result.result.status === \"dirty\") {\n // add issues from dirty option\n ctx.common.issues.push(...result.ctx.common.issues);\n return result.result;\n }\n }\n // return invalid\n const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union,\n unionErrors,\n });\n return INVALID;\n }\n if (ctx.common.async) {\n return Promise.all(options.map(async (option) => {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n return {\n result: await option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n }),\n ctx: childCtx,\n };\n })).then(handleResults);\n }\n else {\n let dirty = undefined;\n const issues = [];\n for (const option of options) {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n parent: null,\n };\n const result = option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx,\n });\n if (result.status === \"valid\") {\n return result;\n }\n else if (result.status === \"dirty\" && !dirty) {\n dirty = { result, ctx: childCtx };\n }\n if (childCtx.common.issues.length) {\n issues.push(childCtx.common.issues);\n }\n }\n if (dirty) {\n ctx.common.issues.push(...dirty.ctx.common.issues);\n return dirty.result;\n }\n const unionErrors = issues.map((issues) => new ZodError(issues));\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union,\n unionErrors,\n });\n return INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n}\nZodUnion.create = (types, params) => {\n return new ZodUnion({\n options: types,\n typeName: ZodFirstPartyTypeKind.ZodUnion,\n ...processCreateParams(params),\n });\n};\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\n////////// //////////\n////////// ZodDiscriminatedUnion //////////\n////////// //////////\n/////////////////////////////////////////////////////\n/////////////////////////////////////////////////////\nconst getDiscriminator = (type) => {\n if (type instanceof ZodLazy) {\n return getDiscriminator(type.schema);\n }\n else if (type instanceof ZodEffects) {\n return getDiscriminator(type.innerType());\n }\n else if (type instanceof ZodLiteral) {\n return [type.value];\n }\n else if (type instanceof ZodEnum) {\n return type.options;\n }\n else if (type instanceof ZodNativeEnum) {\n // eslint-disable-next-line ban/ban\n return util.objectValues(type.enum);\n }\n else if (type instanceof ZodDefault) {\n return getDiscriminator(type._def.innerType);\n }\n else if (type instanceof ZodUndefined) {\n return [undefined];\n }\n else if (type instanceof ZodNull) {\n return [null];\n }\n else if (type instanceof ZodOptional) {\n return [undefined, ...getDiscriminator(type.unwrap())];\n }\n else if (type instanceof ZodNullable) {\n return [null, ...getDiscriminator(type.unwrap())];\n }\n else if (type instanceof ZodBranded) {\n return getDiscriminator(type.unwrap());\n }\n else if (type instanceof ZodReadonly) {\n return getDiscriminator(type.unwrap());\n }\n else if (type instanceof ZodCatch) {\n return getDiscriminator(type._def.innerType);\n }\n else {\n return [];\n }\n};\nclass ZodDiscriminatedUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.object) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const discriminator = this.discriminator;\n const discriminatorValue = ctx.data[discriminator];\n const option = this.optionsMap.get(discriminatorValue);\n if (!option) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [discriminator],\n });\n return INVALID;\n }\n if (ctx.common.async) {\n return option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n else {\n return option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n /**\n * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.\n * However, it only allows a union of objects, all of which need to share a discriminator property. This property must\n * have a different value for each object in the union.\n * @param discriminator the name of the discriminator property\n * @param types an array of object schemas\n * @param params\n */\n static create(discriminator, options, params) {\n // Get all the valid discriminator values\n const optionsMap = new Map();\n // try {\n for (const type of options) {\n const discriminatorValues = getDiscriminator(type.shape[discriminator]);\n if (!discriminatorValues.length) {\n throw new Error(`A discriminator value for key \\`${discriminator}\\` could not be extracted from all schema options`);\n }\n for (const value of discriminatorValues) {\n if (optionsMap.has(value)) {\n throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);\n }\n optionsMap.set(value, type);\n }\n }\n return new ZodDiscriminatedUnion({\n typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,\n discriminator,\n options,\n optionsMap,\n ...processCreateParams(params),\n });\n }\n}\nfunction mergeValues(a, b) {\n const aType = getParsedType(a);\n const bType = getParsedType(b);\n if (a === b) {\n return { valid: true, data: a };\n }\n else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {\n const bKeys = util.objectKeys(b);\n const sharedKeys = util\n .objectKeys(a)\n .filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a, ...b };\n for (const key of sharedKeys) {\n const sharedValue = mergeValues(a[key], b[key]);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n }\n else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {\n if (a.length !== b.length) {\n return { valid: false };\n }\n const newArray = [];\n for (let index = 0; index < a.length; index++) {\n const itemA = a[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n }\n else if (aType === ZodParsedType.date &&\n bType === ZodParsedType.date &&\n +a === +b) {\n return { valid: true, data: a };\n }\n else {\n return { valid: false };\n }\n}\nclass ZodIntersection extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const handleParsed = (parsedLeft, parsedRight) => {\n if (isAborted(parsedLeft) || isAborted(parsedRight)) {\n return INVALID;\n }\n const merged = mergeValues(parsedLeft.value, parsedRight.value);\n if (!merged.valid) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_intersection_types,\n });\n return INVALID;\n }\n if (isDirty(parsedLeft) || isDirty(parsedRight)) {\n status.dirty();\n }\n return { status: status.value, value: merged.data };\n };\n if (ctx.common.async) {\n return Promise.all([\n this._def.left._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n this._def.right._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }),\n ]).then(([left, right]) => handleParsed(left, right));\n }\n else {\n return handleParsed(this._def.left._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }), this._def.right._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n }));\n }\n }\n}\nZodIntersection.create = (left, right, params) => {\n return new ZodIntersection({\n left: left,\n right: right,\n typeName: ZodFirstPartyTypeKind.ZodIntersection,\n ...processCreateParams(params),\n });\n};\nclass ZodTuple extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.array) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.array,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n if (ctx.data.length < this._def.items.length) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n return INVALID;\n }\n const rest = this._def.rest;\n if (!rest && ctx.data.length > this._def.items.length) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: \"array\",\n });\n status.dirty();\n }\n const items = [...ctx.data]\n .map((item, itemIndex) => {\n const schema = this._def.items[itemIndex] || this._def.rest;\n if (!schema)\n return null;\n return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));\n })\n .filter((x) => !!x); // filter nulls\n if (ctx.common.async) {\n return Promise.all(items).then((results) => {\n return ParseStatus.mergeArray(status, results);\n });\n }\n else {\n return ParseStatus.mergeArray(status, items);\n }\n }\n get items() {\n return this._def.items;\n }\n rest(rest) {\n return new ZodTuple({\n ...this._def,\n rest,\n });\n }\n}\nZodTuple.create = (schemas, params) => {\n if (!Array.isArray(schemas)) {\n throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");\n }\n return new ZodTuple({\n items: schemas,\n typeName: ZodFirstPartyTypeKind.ZodTuple,\n rest: null,\n ...processCreateParams(params),\n });\n};\nclass ZodRecord extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.object) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const pairs = [];\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n for (const key in ctx.data) {\n pairs.push({\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),\n value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),\n alwaysSet: key in ctx.data,\n });\n }\n if (ctx.common.async) {\n return ParseStatus.mergeObjectAsync(status, pairs);\n }\n else {\n return ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get element() {\n return this._def.valueType;\n }\n static create(first, second, third) {\n if (second instanceof ZodType) {\n return new ZodRecord({\n keyType: first,\n valueType: second,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(third),\n });\n }\n return new ZodRecord({\n keyType: ZodString.create(),\n valueType: first,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(second),\n });\n }\n}\nclass ZodMap extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.map) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.map,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n const pairs = [...ctx.data.entries()].map(([key, value], index) => {\n return {\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, \"key\"])),\n value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, \"value\"])),\n };\n });\n if (ctx.common.async) {\n const finalMap = new Map();\n return Promise.resolve().then(async () => {\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n });\n }\n else {\n const finalMap = new Map();\n for (const pair of pairs) {\n const key = pair.key;\n const value = pair.value;\n if (key.status === \"aborted\" || value.status === \"aborted\") {\n return INVALID;\n }\n if (key.status === \"dirty\" || value.status === \"dirty\") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n }\n }\n}\nZodMap.create = (keyType, valueType, params) => {\n return new ZodMap({\n valueType,\n keyType,\n typeName: ZodFirstPartyTypeKind.ZodMap,\n ...processCreateParams(params),\n });\n};\nclass ZodSet extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.set) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.set,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const def = this._def;\n if (def.minSize !== null) {\n if (ctx.data.size < def.minSize.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: def.minSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.minSize.message,\n });\n status.dirty();\n }\n }\n if (def.maxSize !== null) {\n if (ctx.data.size > def.maxSize.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: def.maxSize.value,\n type: \"set\",\n inclusive: true,\n exact: false,\n message: def.maxSize.message,\n });\n status.dirty();\n }\n }\n const valueType = this._def.valueType;\n function finalizeSet(elements) {\n const parsedSet = new Set();\n for (const element of elements) {\n if (element.status === \"aborted\")\n return INVALID;\n if (element.status === \"dirty\")\n status.dirty();\n parsedSet.add(element.value);\n }\n return { status: status.value, value: parsedSet };\n }\n const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));\n if (ctx.common.async) {\n return Promise.all(elements).then((elements) => finalizeSet(elements));\n }\n else {\n return finalizeSet(elements);\n }\n }\n min(minSize, message) {\n return new ZodSet({\n ...this._def,\n minSize: { value: minSize, message: errorUtil.toString(message) },\n });\n }\n max(maxSize, message) {\n return new ZodSet({\n ...this._def,\n maxSize: { value: maxSize, message: errorUtil.toString(message) },\n });\n }\n size(size, message) {\n return this.min(size, message).max(size, message);\n }\n nonempty(message) {\n return this.min(1, message);\n }\n}\nZodSet.create = (valueType, params) => {\n return new ZodSet({\n valueType,\n minSize: null,\n maxSize: null,\n typeName: ZodFirstPartyTypeKind.ZodSet,\n ...processCreateParams(params),\n });\n};\nclass ZodFunction extends ZodType {\n constructor() {\n super(...arguments);\n this.validate = this.implement;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.function) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.function,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n function makeArgsIssue(args, error) {\n return makeIssue({\n data: args,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n getErrorMap(),\n errorMap,\n ].filter((x) => !!x),\n issueData: {\n code: ZodIssueCode.invalid_arguments,\n argumentsError: error,\n },\n });\n }\n function makeReturnsIssue(returns, error) {\n return makeIssue({\n data: returns,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n getErrorMap(),\n errorMap,\n ].filter((x) => !!x),\n issueData: {\n code: ZodIssueCode.invalid_return_type,\n returnTypeError: error,\n },\n });\n }\n const params = { errorMap: ctx.common.contextualErrorMap };\n const fn = ctx.data;\n if (this._def.returns instanceof ZodPromise) {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return OK(async function (...args) {\n const error = new ZodError([]);\n const parsedArgs = await me._def.args\n .parseAsync(args, params)\n .catch((e) => {\n error.addIssue(makeArgsIssue(args, e));\n throw error;\n });\n const result = await Reflect.apply(fn, this, parsedArgs);\n const parsedReturns = await me._def.returns._def.type\n .parseAsync(result, params)\n .catch((e) => {\n error.addIssue(makeReturnsIssue(result, e));\n throw error;\n });\n return parsedReturns;\n });\n }\n else {\n // Would love a way to avoid disabling this rule, but we need\n // an alias (using an arrow function was what caused 2651).\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const me = this;\n return OK(function (...args) {\n const parsedArgs = me._def.args.safeParse(args, params);\n if (!parsedArgs.success) {\n throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);\n }\n const result = Reflect.apply(fn, this, parsedArgs.data);\n const parsedReturns = me._def.returns.safeParse(result, params);\n if (!parsedReturns.success) {\n throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);\n }\n return parsedReturns.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...items) {\n return new ZodFunction({\n ...this._def,\n args: ZodTuple.create(items).rest(ZodUnknown.create()),\n });\n }\n returns(returnType) {\n return new ZodFunction({\n ...this._def,\n returns: returnType,\n });\n }\n implement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n strictImplement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n static create(args, returns, params) {\n return new ZodFunction({\n args: (args\n ? args\n : ZodTuple.create([]).rest(ZodUnknown.create())),\n returns: returns || ZodUnknown.create(),\n typeName: ZodFirstPartyTypeKind.ZodFunction,\n ...processCreateParams(params),\n });\n }\n}\nclass ZodLazy extends ZodType {\n get schema() {\n return this._def.getter();\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const lazySchema = this._def.getter();\n return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });\n }\n}\nZodLazy.create = (getter, params) => {\n return new ZodLazy({\n getter: getter,\n typeName: ZodFirstPartyTypeKind.ZodLazy,\n ...processCreateParams(params),\n });\n};\nclass ZodLiteral extends ZodType {\n _parse(input) {\n if (input.data !== this._def.value) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_literal,\n expected: this._def.value,\n });\n return INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n get value() {\n return this._def.value;\n }\n}\nZodLiteral.create = (value, params) => {\n return new ZodLiteral({\n value: value,\n typeName: ZodFirstPartyTypeKind.ZodLiteral,\n ...processCreateParams(params),\n });\n};\nfunction createZodEnum(values, params) {\n return new ZodEnum({\n values,\n typeName: ZodFirstPartyTypeKind.ZodEnum,\n ...processCreateParams(params),\n });\n}\nclass ZodEnum extends ZodType {\n constructor() {\n super(...arguments);\n _ZodEnum_cache.set(this, void 0);\n }\n _parse(input) {\n if (typeof input.data !== \"string\") {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n addIssueToContext(ctx, {\n expected: util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodIssueCode.invalid_type,\n });\n return INVALID;\n }\n if (!__classPrivateFieldGet(this, _ZodEnum_cache, \"f\")) {\n __classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values), \"f\");\n }\n if (!__classPrivateFieldGet(this, _ZodEnum_cache, \"f\").has(input.data)) {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Values() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n extract(values, newDef = this._def) {\n return ZodEnum.create(values, {\n ...this._def,\n ...newDef,\n });\n }\n exclude(values, newDef = this._def) {\n return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {\n ...this._def,\n ...newDef,\n });\n }\n}\n_ZodEnum_cache = new WeakMap();\nZodEnum.create = createZodEnum;\nclass ZodNativeEnum extends ZodType {\n constructor() {\n super(...arguments);\n _ZodNativeEnum_cache.set(this, void 0);\n }\n _parse(input) {\n const nativeEnumValues = util.getValidEnumValues(this._def.values);\n const ctx = this._getOrReturnCtx(input);\n if (ctx.parsedType !== ZodParsedType.string &&\n ctx.parsedType !== ZodParsedType.number) {\n const expectedValues = util.objectValues(nativeEnumValues);\n addIssueToContext(ctx, {\n expected: util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodIssueCode.invalid_type,\n });\n return INVALID;\n }\n if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, \"f\")) {\n __classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util.getValidEnumValues(this._def.values)), \"f\");\n }\n if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, \"f\").has(input.data)) {\n const expectedValues = util.objectValues(nativeEnumValues);\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_enum_value,\n options: expectedValues,\n });\n return INVALID;\n }\n return OK(input.data);\n }\n get enum() {\n return this._def.values;\n }\n}\n_ZodNativeEnum_cache = new WeakMap();\nZodNativeEnum.create = (values, params) => {\n return new ZodNativeEnum({\n values: values,\n typeName: ZodFirstPartyTypeKind.ZodNativeEnum,\n ...processCreateParams(params),\n });\n};\nclass ZodPromise extends ZodType {\n unwrap() {\n return this._def.type;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.promise &&\n ctx.common.async === false) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.promise,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n const promisified = ctx.parsedType === ZodParsedType.promise\n ? ctx.data\n : Promise.resolve(ctx.data);\n return OK(promisified.then((data) => {\n return this._def.type.parseAsync(data, {\n path: ctx.path,\n errorMap: ctx.common.contextualErrorMap,\n });\n }));\n }\n}\nZodPromise.create = (schema, params) => {\n return new ZodPromise({\n type: schema,\n typeName: ZodFirstPartyTypeKind.ZodPromise,\n ...processCreateParams(params),\n });\n};\nclass ZodEffects extends ZodType {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects\n ? this._def.schema.sourceType()\n : this._def.schema;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const effect = this._def.effect || null;\n const checkCtx = {\n addIssue: (arg) => {\n addIssueToContext(ctx, arg);\n if (arg.fatal) {\n status.abort();\n }\n else {\n status.dirty();\n }\n },\n get path() {\n return ctx.path;\n },\n };\n checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);\n if (effect.type === \"preprocess\") {\n const processed = effect.transform(ctx.data, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(processed).then(async (processed) => {\n if (status.value === \"aborted\")\n return INVALID;\n const result = await this._def.schema._parseAsync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n if (result.status === \"aborted\")\n return INVALID;\n if (result.status === \"dirty\")\n return DIRTY(result.value);\n if (status.value === \"dirty\")\n return DIRTY(result.value);\n return result;\n });\n }\n else {\n if (status.value === \"aborted\")\n return INVALID;\n const result = this._def.schema._parseSync({\n data: processed,\n path: ctx.path,\n parent: ctx,\n });\n if (result.status === \"aborted\")\n return INVALID;\n if (result.status === \"dirty\")\n return DIRTY(result.value);\n if (status.value === \"dirty\")\n return DIRTY(result.value);\n return result;\n }\n }\n if (effect.type === \"refinement\") {\n const executeRefinement = (acc) => {\n const result = effect.refinement(acc, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(result);\n }\n if (result instanceof Promise) {\n throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n }\n return acc;\n };\n if (ctx.common.async === false) {\n const inner = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inner.status === \"aborted\")\n return INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n // return value is ignored\n executeRefinement(inner.value);\n return { status: status.value, value: inner.value };\n }\n else {\n return this._def.schema\n ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })\n .then((inner) => {\n if (inner.status === \"aborted\")\n return INVALID;\n if (inner.status === \"dirty\")\n status.dirty();\n return executeRefinement(inner.value).then(() => {\n return { status: status.value, value: inner.value };\n });\n });\n }\n }\n if (effect.type === \"transform\") {\n if (ctx.common.async === false) {\n const base = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (!isValid(base))\n return base;\n const result = effect.transform(base.value, checkCtx);\n if (result instanceof Promise) {\n throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);\n }\n return { status: status.value, value: result };\n }\n else {\n return this._def.schema\n ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })\n .then((base) => {\n if (!isValid(base))\n return base;\n return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));\n });\n }\n }\n util.assertNever(effect);\n }\n}\nZodEffects.create = (schema, effect, params) => {\n return new ZodEffects({\n schema,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect,\n ...processCreateParams(params),\n });\n};\nZodEffects.createWithPreprocess = (preprocess, schema, params) => {\n return new ZodEffects({\n schema,\n effect: { type: \"preprocess\", transform: preprocess },\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n ...processCreateParams(params),\n });\n};\nclass ZodOptional extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === ZodParsedType.undefined) {\n return OK(undefined);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nZodOptional.create = (type, params) => {\n return new ZodOptional({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodOptional,\n ...processCreateParams(params),\n });\n};\nclass ZodNullable extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === ZodParsedType.null) {\n return OK(null);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nZodNullable.create = (type, params) => {\n return new ZodNullable({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodNullable,\n ...processCreateParams(params),\n });\n};\nclass ZodDefault extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n let data = ctx.data;\n if (ctx.parsedType === ZodParsedType.undefined) {\n data = this._def.defaultValue();\n }\n return this._def.innerType._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n}\nZodDefault.create = (type, params) => {\n return new ZodDefault({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n defaultValue: typeof params.default === \"function\"\n ? params.default\n : () => params.default,\n ...processCreateParams(params),\n });\n};\nclass ZodCatch extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n // newCtx is used to not collect issues from inner types in ctx\n const newCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: [],\n },\n };\n const result = this._def.innerType._parse({\n data: newCtx.data,\n path: newCtx.path,\n parent: {\n ...newCtx,\n },\n });\n if (isAsync(result)) {\n return result.then((result) => {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n });\n }\n else {\n return {\n status: \"valid\",\n value: result.status === \"valid\"\n ? result.value\n : this._def.catchValue({\n get error() {\n return new ZodError(newCtx.common.issues);\n },\n input: newCtx.data,\n }),\n };\n }\n }\n removeCatch() {\n return this._def.innerType;\n }\n}\nZodCatch.create = (type, params) => {\n return new ZodCatch({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n catchValue: typeof params.catch === \"function\" ? params.catch : () => params.catch,\n ...processCreateParams(params),\n });\n};\nclass ZodNaN extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.nan) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.nan,\n received: ctx.parsedType,\n });\n return INVALID;\n }\n return { status: \"valid\", value: input.data };\n }\n}\nZodNaN.create = (params) => {\n return new ZodNaN({\n typeName: ZodFirstPartyTypeKind.ZodNaN,\n ...processCreateParams(params),\n });\n};\nconst BRAND = Symbol(\"zod_brand\");\nclass ZodBranded extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const data = ctx.data;\n return this._def.type._parse({\n data,\n path: ctx.path,\n parent: ctx,\n });\n }\n unwrap() {\n return this._def.type;\n }\n}\nclass ZodPipeline extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.common.async) {\n const handleAsync = async () => {\n const inResult = await this._def.in._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return DIRTY(inResult.value);\n }\n else {\n return this._def.out._parseAsync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n };\n return handleAsync();\n }\n else {\n const inResult = this._def.in._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx,\n });\n if (inResult.status === \"aborted\")\n return INVALID;\n if (inResult.status === \"dirty\") {\n status.dirty();\n return {\n status: \"dirty\",\n value: inResult.value,\n };\n }\n else {\n return this._def.out._parseSync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx,\n });\n }\n }\n }\n static create(a, b) {\n return new ZodPipeline({\n in: a,\n out: b,\n typeName: ZodFirstPartyTypeKind.ZodPipeline,\n });\n }\n}\nclass ZodReadonly extends ZodType {\n _parse(input) {\n const result = this._def.innerType._parse(input);\n const freeze = (data) => {\n if (isValid(data)) {\n data.value = Object.freeze(data.value);\n }\n return data;\n };\n return isAsync(result)\n ? result.then((data) => freeze(data))\n : freeze(result);\n }\n unwrap() {\n return this._def.innerType;\n }\n}\nZodReadonly.create = (type, params) => {\n return new ZodReadonly({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodReadonly,\n ...processCreateParams(params),\n });\n};\n////////////////////////////////////////\n////////////////////////////////////////\n////////// //////////\n////////// z.custom //////////\n////////// //////////\n////////////////////////////////////////\n////////////////////////////////////////\nfunction cleanParams(params, data) {\n const p = typeof params === \"function\"\n ? params(data)\n : typeof params === \"string\"\n ? { message: params }\n : params;\n const p2 = typeof p === \"string\" ? { message: p } : p;\n return p2;\n}\nfunction custom(check, _params = {}, \n/**\n * @deprecated\n *\n * Pass `fatal` into the params object instead:\n *\n * ```ts\n * z.string().custom((val) => val.length > 5, { fatal: false })\n * ```\n *\n */\nfatal) {\n if (check)\n return ZodAny.create().superRefine((data, ctx) => {\n var _a, _b;\n const r = check(data);\n if (r instanceof Promise) {\n return r.then((r) => {\n var _a, _b;\n if (!r) {\n const params = cleanParams(_params, data);\n const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;\n ctx.addIssue({ code: \"custom\", ...params, fatal: _fatal });\n }\n });\n }\n if (!r) {\n const params = cleanParams(_params, data);\n const _fatal = (_b = (_a = params.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;\n ctx.addIssue({ code: \"custom\", ...params, fatal: _fatal });\n }\n return;\n });\n return ZodAny.create();\n}\nconst late = {\n object: ZodObject.lazycreate,\n};\nvar ZodFirstPartyTypeKind;\n(function (ZodFirstPartyTypeKind) {\n ZodFirstPartyTypeKind[\"ZodString\"] = \"ZodString\";\n ZodFirstPartyTypeKind[\"ZodNumber\"] = \"ZodNumber\";\n ZodFirstPartyTypeKind[\"ZodNaN\"] = \"ZodNaN\";\n ZodFirstPartyTypeKind[\"ZodBigInt\"] = \"ZodBigInt\";\n ZodFirstPartyTypeKind[\"ZodBoolean\"] = \"ZodBoolean\";\n ZodFirstPartyTypeKind[\"ZodDate\"] = \"ZodDate\";\n ZodFirstPartyTypeKind[\"ZodSymbol\"] = \"ZodSymbol\";\n ZodFirstPartyTypeKind[\"ZodUndefined\"] = \"ZodUndefined\";\n ZodFirstPartyTypeKind[\"ZodNull\"] = \"ZodNull\";\n ZodFirstPartyTypeKind[\"ZodAny\"] = \"ZodAny\";\n ZodFirstPartyTypeKind[\"ZodUnknown\"] = \"ZodUnknown\";\n ZodFirstPartyTypeKind[\"ZodNever\"] = \"ZodNever\";\n ZodFirstPartyTypeKind[\"ZodVoid\"] = \"ZodVoid\";\n ZodFirstPartyTypeKind[\"ZodArray\"] = \"ZodArray\";\n ZodFirstPartyTypeKind[\"ZodObject\"] = \"ZodObject\";\n ZodFirstPartyTypeKind[\"ZodUnion\"] = \"ZodUnion\";\n ZodFirstPartyTypeKind[\"ZodDiscriminatedUnion\"] = \"ZodDiscriminatedUnion\";\n ZodFirstPartyTypeKind[\"ZodIntersection\"] = \"ZodIntersection\";\n ZodFirstPartyTypeKind[\"ZodTuple\"] = \"ZodTuple\";\n ZodFirstPartyTypeKind[\"ZodRecord\"] = \"ZodRecord\";\n ZodFirstPartyTypeKind[\"ZodMap\"] = \"ZodMap\";\n ZodFirstPartyTypeKind[\"ZodSet\"] = \"ZodSet\";\n ZodFirstPartyTypeKind[\"ZodFunction\"] = \"ZodFunction\";\n ZodFirstPartyTypeKind[\"ZodLazy\"] = \"ZodLazy\";\n ZodFirstPartyTypeKind[\"ZodLiteral\"] = \"ZodLiteral\";\n ZodFirstPartyTypeKind[\"ZodEnum\"] = \"ZodEnum\";\n ZodFirstPartyTypeKind[\"ZodEffects\"] = \"ZodEffects\";\n ZodFirstPartyTypeKind[\"ZodNativeEnum\"] = \"ZodNativeEnum\";\n ZodFirstPartyTypeKind[\"ZodOptional\"] = \"ZodOptional\";\n ZodFirstPartyTypeKind[\"ZodNullable\"] = \"ZodNullable\";\n ZodFirstPartyTypeKind[\"ZodDefault\"] = \"ZodDefault\";\n ZodFirstPartyTypeKind[\"ZodCatch\"] = \"ZodCatch\";\n ZodFirstPartyTypeKind[\"ZodPromise\"] = \"ZodPromise\";\n ZodFirstPartyTypeKind[\"ZodBranded\"] = \"ZodBranded\";\n ZodFirstPartyTypeKind[\"ZodPipeline\"] = \"ZodPipeline\";\n ZodFirstPartyTypeKind[\"ZodReadonly\"] = \"ZodReadonly\";\n})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));\nconst instanceOfType = (\n// const instanceOfType = any>(\ncls, params = {\n message: `Input not instance of ${cls.name}`,\n}) => custom((data) => data instanceof cls, params);\nconst stringType = ZodString.create;\nconst numberType = ZodNumber.create;\nconst nanType = ZodNaN.create;\nconst bigIntType = ZodBigInt.create;\nconst booleanType = ZodBoolean.create;\nconst dateType = ZodDate.create;\nconst symbolType = ZodSymbol.create;\nconst undefinedType = ZodUndefined.create;\nconst nullType = ZodNull.create;\nconst anyType = ZodAny.create;\nconst unknownType = ZodUnknown.create;\nconst neverType = ZodNever.create;\nconst voidType = ZodVoid.create;\nconst arrayType = ZodArray.create;\nconst objectType = ZodObject.create;\nconst strictObjectType = ZodObject.strictCreate;\nconst unionType = ZodUnion.create;\nconst discriminatedUnionType = ZodDiscriminatedUnion.create;\nconst intersectionType = ZodIntersection.create;\nconst tupleType = ZodTuple.create;\nconst recordType = ZodRecord.create;\nconst mapType = ZodMap.create;\nconst setType = ZodSet.create;\nconst functionType = ZodFunction.create;\nconst lazyType = ZodLazy.create;\nconst literalType = ZodLiteral.create;\nconst enumType = ZodEnum.create;\nconst nativeEnumType = ZodNativeEnum.create;\nconst promiseType = ZodPromise.create;\nconst effectsType = ZodEffects.create;\nconst optionalType = ZodOptional.create;\nconst nullableType = ZodNullable.create;\nconst preprocessType = ZodEffects.createWithPreprocess;\nconst pipelineType = ZodPipeline.create;\nconst ostring = () => stringType().optional();\nconst onumber = () => numberType().optional();\nconst oboolean = () => booleanType().optional();\nconst coerce = {\n string: ((arg) => ZodString.create({ ...arg, coerce: true })),\n number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),\n boolean: ((arg) => ZodBoolean.create({\n ...arg,\n coerce: true,\n })),\n bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),\n date: ((arg) => ZodDate.create({ ...arg, coerce: true })),\n};\nconst NEVER = INVALID;\n\nvar z = /*#__PURE__*/Object.freeze({\n __proto__: null,\n defaultErrorMap: errorMap,\n setErrorMap: setErrorMap,\n getErrorMap: getErrorMap,\n makeIssue: makeIssue,\n EMPTY_PATH: EMPTY_PATH,\n addIssueToContext: addIssueToContext,\n ParseStatus: ParseStatus,\n INVALID: INVALID,\n DIRTY: DIRTY,\n OK: OK,\n isAborted: isAborted,\n isDirty: isDirty,\n isValid: isValid,\n isAsync: isAsync,\n get util () { return util; },\n get objectUtil () { return objectUtil; },\n ZodParsedType: ZodParsedType,\n getParsedType: getParsedType,\n ZodType: ZodType,\n datetimeRegex: datetimeRegex,\n ZodString: ZodString,\n ZodNumber: ZodNumber,\n ZodBigInt: ZodBigInt,\n ZodBoolean: ZodBoolean,\n ZodDate: ZodDate,\n ZodSymbol: ZodSymbol,\n ZodUndefined: ZodUndefined,\n ZodNull: ZodNull,\n ZodAny: ZodAny,\n ZodUnknown: ZodUnknown,\n ZodNever: ZodNever,\n ZodVoid: ZodVoid,\n ZodArray: ZodArray,\n ZodObject: ZodObject,\n ZodUnion: ZodUnion,\n ZodDiscriminatedUnion: ZodDiscriminatedUnion,\n ZodIntersection: ZodIntersection,\n ZodTuple: ZodTuple,\n ZodRecord: ZodRecord,\n ZodMap: ZodMap,\n ZodSet: ZodSet,\n ZodFunction: ZodFunction,\n ZodLazy: ZodLazy,\n ZodLiteral: ZodLiteral,\n ZodEnum: ZodEnum,\n ZodNativeEnum: ZodNativeEnum,\n ZodPromise: ZodPromise,\n ZodEffects: ZodEffects,\n ZodTransformer: ZodEffects,\n ZodOptional: ZodOptional,\n ZodNullable: ZodNullable,\n ZodDefault: ZodDefault,\n ZodCatch: ZodCatch,\n ZodNaN: ZodNaN,\n BRAND: BRAND,\n ZodBranded: ZodBranded,\n ZodPipeline: ZodPipeline,\n ZodReadonly: ZodReadonly,\n custom: custom,\n Schema: ZodType,\n ZodSchema: ZodType,\n late: late,\n get ZodFirstPartyTypeKind () { return ZodFirstPartyTypeKind; },\n coerce: coerce,\n any: anyType,\n array: arrayType,\n bigint: bigIntType,\n boolean: booleanType,\n date: dateType,\n discriminatedUnion: discriminatedUnionType,\n effect: effectsType,\n 'enum': enumType,\n 'function': functionType,\n 'instanceof': instanceOfType,\n intersection: intersectionType,\n lazy: lazyType,\n literal: literalType,\n map: mapType,\n nan: nanType,\n nativeEnum: nativeEnumType,\n never: neverType,\n 'null': nullType,\n nullable: nullableType,\n number: numberType,\n object: objectType,\n oboolean: oboolean,\n onumber: onumber,\n optional: optionalType,\n ostring: ostring,\n pipeline: pipelineType,\n preprocess: preprocessType,\n promise: promiseType,\n record: recordType,\n set: setType,\n strictObject: strictObjectType,\n string: stringType,\n symbol: symbolType,\n transformer: effectsType,\n tuple: tupleType,\n 'undefined': undefinedType,\n union: unionType,\n unknown: unknownType,\n 'void': voidType,\n NEVER: NEVER,\n ZodIssueCode: ZodIssueCode,\n quotelessJson: quotelessJson,\n ZodError: ZodError\n});\n\nexport { BRAND, DIRTY, EMPTY_PATH, INVALID, NEVER, OK, ParseStatus, ZodType as Schema, ZodAny, ZodArray, ZodBigInt, ZodBoolean, ZodBranded, ZodCatch, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodEffects, ZodEnum, ZodError, ZodFirstPartyTypeKind, ZodFunction, ZodIntersection, ZodIssueCode, ZodLazy, ZodLiteral, ZodMap, ZodNaN, ZodNativeEnum, ZodNever, ZodNull, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodParsedType, ZodPipeline, ZodPromise, ZodReadonly, ZodRecord, ZodType as ZodSchema, ZodSet, ZodString, ZodSymbol, ZodEffects as ZodTransformer, ZodTuple, ZodType, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, addIssueToContext, anyType as any, arrayType as array, bigIntType as bigint, booleanType as boolean, coerce, custom, dateType as date, datetimeRegex, z as default, errorMap as defaultErrorMap, discriminatedUnionType as discriminatedUnion, effectsType as effect, enumType as enum, functionType as function, getErrorMap, getParsedType, instanceOfType as instanceof, intersectionType as intersection, isAborted, isAsync, isDirty, isValid, late, lazyType as lazy, literalType as literal, makeIssue, mapType as map, nanType as nan, nativeEnumType as nativeEnum, neverType as never, nullType as null, nullableType as nullable, numberType as number, objectType as object, objectUtil, oboolean, onumber, optionalType as optional, ostring, pipelineType as pipeline, preprocessType as preprocess, promiseType as promise, quotelessJson, recordType as record, setType as set, setErrorMap, strictObjectType as strictObject, stringType as string, symbolType as symbol, effectsType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, unknownType as unknown, util, voidType as void, z };\n", null, null, null, null, null, "import * as fs from 'fs/promises';\nimport * as crypto from 'crypto';\nimport {ENV_FILE, formatChannel, HOST, TOKENS_FILE,CONFIG} from \"./config.js\";\n\n// Function to generate a secure random token\nfunction generateToken() {\n return crypto.randomBytes(16).toString('hex');\n}\n\n\n// Authorized channel-token pairs - Only channels with valid tokens can connect\n// Format: { \"/channel1\": \"token123\" }\nlet authorizedTokens = {};\n\nfunction getToken(channel) {\n return authorizedTokens[channel];\n}\n\nfunction setToken(channel, value) {\n authorizedTokens[channel] = value;\n}\n\nfunction deleteToken(channel) {\n delete authorizedTokens[channel];\n}\n\nfunction clearTokens(channel) {\n authorizedTokens = {};\n}\n\n// Load authorized tokens from disk\nasync function loadAuthorizedTokens() {\n try {\n const data = await fs.readFile(TOKENS_FILE, 'utf8');\n authorizedTokens = JSON.parse(data || \"{}\");\n\n // console.error(`Loaded ${Object.keys(authorizedTokens).length} authorized channel-token pairs from ${TOKENS_FILE}`);\n return true;\n } catch (error) {\n // If file doesn't exist, start with empty tokens\n if (error.code === 'ENOENT') {\n authorizedTokens = {};\n return true;\n }\n console.error('Error loading authorized tokens:', error);\n return false;\n }\n}\n\n// Save authorized tokens to disk\nasync function saveAuthorizedTokens() {\n try {\n // Convert Map to object for JSON serialization\n const stringified = JSON.stringify(authorizedTokens, null, 2);\n await fs.writeFile(TOKENS_FILE, stringified, 'utf8');\n // console.error(`Saved ${stringified} authorized channel-token pairs to ${TOKENS_FILE}`);\n return true;\n } catch (error) {\n console.error('Error saving authorized tokens:', error);\n return false;\n }\n}\n\n// Function to save server token to .env file\nasync function saveServerTokenToEnv(token) {\n try {\n let envContent = '';\n\n try {\n // Try to read existing .env file\n envContent = await fs.readFile(ENV_FILE, 'utf8');\n\n // Check if WEBMCP_SERVER_TOKEN is already defined\n if (envContent.includes('WEBMCP_SERVER_TOKEN=')) {\n // Replace the existing token\n envContent = envContent.replace(/WEBMCP_SERVER_TOKEN=.*(\\r?\\n|$)/g, `WEBMCP_SERVER_TOKEN=${token}$1`);\n } else {\n // Add the token to the end\n envContent += `\\nWEBMCP_SERVER_TOKEN=${token}\\n`;\n }\n } catch (err) {\n // File doesn't exist, create new content\n envContent = `WEBMCP_SERVER_TOKEN=${token}\\n`;\n }\n\n // Write the content to the .env file\n await fs.writeFile(ENV_FILE, envContent, 'utf8');\n console.error(`Server token saved to ${ENV_FILE}`);\n return true;\n } catch (error) {\n console.error('Error saving server token to .env file:', error);\n return false;\n }\n}\n\nasync function generateNewRegistrationToken() {\n // Generate a random token for registration\n const token = generateToken();\n\n // Create a connection object with server address and token\n const address = `${HOST}:${CONFIG.port}`;\n const serverAddress = `ws://${address}`;\n const connectionData = {\n server: serverAddress,\n token: token\n };\n\n // Convert to JSON and base64 encode\n const jsonStr = JSON.stringify(connectionData);\n const encodedData = Buffer.from(jsonStr).toString('base64');\n\n setToken(formatChannel(address), token);\n await saveAuthorizedTokens();\n\n return encodedData;\n}\n\nexport {generateToken, getToken, setToken, loadAuthorizedTokens, saveAuthorizedTokens, clearTokens, deleteToken, saveServerTokenToEnv, generateNewRegistrationToken};\n", "import * as path from 'path';\nimport * as dotenv from 'dotenv';\nimport * as os from 'os';\nimport * as fs from 'fs/promises';\nimport envPaths from 'env-paths';\n\n// Create config directory in user's home folder\nconst HOME_DIR = os.homedir();\nconst CONFIG_DIR = path.join(HOME_DIR, '.webmcp');\n\n// Ensure config directory exists\nconst ensureConfigDir = async () => {\n try {\n await fs.mkdir(CONFIG_DIR, {recursive: true});\n } catch (error) {\n console.error(`Error creating config directory at ${CONFIG_DIR}:`, error);\n }\n};\n\n// Process ID file path\nconst PID_FILE = path.join(CONFIG_DIR, '.webmcp-server.pid');\n// Environment file path\nconst ENV_FILE = path.join(CONFIG_DIR, '.env');\n// Tokens file path\nconst TOKENS_FILE = path.join(CONFIG_DIR, '.webmcp-tokens.json');\n\n// Load environment variables\ndotenv.config({path: ENV_FILE});\n\n// Server token for MCP authentication\nconst SERVER_TOKEN = process.env.WEBMCP_SERVER_TOKEN || '';\n\nconst HOST = \"localhost\";\n\nconst CONFIG = {};\n\nfunction setConfig(args) {\n Object.entries(args).forEach(([key, value]) => {\n CONFIG[key] = value;\n });\n}\n\nfunction formatChannel(channel) {\n return `/${channel.replace(/[.:]/g, '_')}`\n}\n\nasync function exists(somePath) {\n try {\n await fs.access(somePath);\n return true;\n } catch (e) {\n return false;\n }\n}\n\nasync function configureMcpClientWithPath(clientConfigPath) {\n const directory = path.dirname(clientConfigPath);\n if (!await exists(directory)) {\n await fs.mkdir(directory, { recursive: true });\n }\n\n const webmcpConfig = {\n \"webmcp\": {\n \"command\": \"npx\",\n \"args\": [\n \"-y\",\n \"@jason.today/webmcp@latest\",\n \"--mcp\"\n ]\n }\n };\n\n let json = { mcpServers: {} };\n\n // If one already exists, we'll want to update it\n if (await exists(clientConfigPath)) {\n const rawJSON = await fs.readFile(clientConfigPath);\n try {\n json = JSON.parse(rawJSON);\n } catch (e) {\n throw new Error(`Failed to update MCP client configuration: ${e}`);\n }\n }\n\n json.mcpServers = { ...json.mcpServers, ...webmcpConfig};\n await fs.writeFile(clientConfigPath, JSON.stringify(json, null, 2));\n}\n\nconst availableClientConfigs = {\n \"claude\": [envPaths(\"Claude\", { suffix: \"\" }).data, \"claude_desktop_config.json\"],\n \"cline\": [envPaths(\"Code\", { suffix: \"\" }).data, \"User\", \"globalStorage\", \"saoudrizwan.claude-dev\", \"settings\", \"cline_mcp_settings.json\"],\n \"cursor\": [HOME_DIR, \".cursor\", \"mcp.json\"],\n \"windsurf\": [HOME_DIR, \".codeium\", \"windsurf\", \"mcp_config.json\"]\n};\n\nasync function configureMcpClient(clientType) {\n let clientConfigPath = availableClientConfigs[clientType];\n if (!clientConfigPath) {\n console.error(\"Unsupported client - treating it like a path...\")\n clientConfigPath = clientType;\n }\n await configureMcpClientWithPath(path.join(...clientConfigPath));\n}\n\nexport {\n CONFIG,\n HOST,\n PID_FILE,\n ENV_FILE,\n TOKENS_FILE,\n SERVER_TOKEN,\n ensureConfigDir,\n formatChannel,\n setConfig,\n configureMcpClientWithPath,\n configureMcpClient,\n availableClientConfigs,\n};\n", "import path from 'node:path';\nimport os from 'node:os';\nimport process from 'node:process';\n\nconst homedir = os.homedir();\nconst tmpdir = os.tmpdir();\nconst {env} = process;\n\nconst macos = name => {\n\tconst library = path.join(homedir, 'Library');\n\n\treturn {\n\t\tdata: path.join(library, 'Application Support', name),\n\t\tconfig: path.join(library, 'Preferences', name),\n\t\tcache: path.join(library, 'Caches', name),\n\t\tlog: path.join(library, 'Logs', name),\n\t\ttemp: path.join(tmpdir, name),\n\t};\n};\n\nconst windows = name => {\n\tconst appData = env.APPDATA || path.join(homedir, 'AppData', 'Roaming');\n\tconst localAppData = env.LOCALAPPDATA || path.join(homedir, 'AppData', 'Local');\n\n\treturn {\n\t\t// Data/config/cache/log are invented by me as Windows isn't opinionated about this\n\t\tdata: path.join(localAppData, name, 'Data'),\n\t\tconfig: path.join(appData, name, 'Config'),\n\t\tcache: path.join(localAppData, name, 'Cache'),\n\t\tlog: path.join(localAppData, name, 'Log'),\n\t\ttemp: path.join(tmpdir, name),\n\t};\n};\n\n// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\nconst linux = name => {\n\tconst username = path.basename(homedir);\n\n\treturn {\n\t\tdata: path.join(env.XDG_DATA_HOME || path.join(homedir, '.local', 'share'), name),\n\t\tconfig: path.join(env.XDG_CONFIG_HOME || path.join(homedir, '.config'), name),\n\t\tcache: path.join(env.XDG_CACHE_HOME || path.join(homedir, '.cache'), name),\n\t\t// https://wiki.debian.org/XDGBaseDirectorySpecification#state\n\t\tlog: path.join(env.XDG_STATE_HOME || path.join(homedir, '.local', 'state'), name),\n\t\ttemp: path.join(tmpdir, username, name),\n\t};\n};\n\nexport default function envPaths(name, {suffix = 'nodejs'} = {}) {\n\tif (typeof name !== 'string') {\n\t\tthrow new TypeError(`Expected a string, got ${typeof name}`);\n\t}\n\n\tif (suffix) {\n\t\t// Add suffix to prevent possible conflict with native apps\n\t\tname += `-${suffix}`;\n\t}\n\n\tif (process.platform === 'darwin') {\n\t\treturn macos(name);\n\t}\n\n\tif (process.platform === 'win32') {\n\t\treturn windows(name);\n\t}\n\n\treturn linux(name);\n}\n", "import {Server} from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {StdioServerTransport} from '@modelcontextprotocol/sdk/server/stdio.js';\nimport WebSocket from 'ws';\nimport {\n CallToolRequestSchema,\n CreateMessageRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema\n} from '@modelcontextprotocol/sdk/types.js';\nimport {generateNewRegistrationToken} from \"./tokens.js\";\nimport {CONFIG} from \"./config.js\";\n\n// Create a central MCP server that communicates over stdio\nconst mcpServer = new Server(\n {\n name: \"WebMCP\",\n version: \"0.1.12\",\n },\n {\n capabilities: {\n tools: {\n listChanged: true\n },\n prompts: {\n listChanged: true\n },\n resources: {\n listChanged: true,\n subscribe: true\n },\n sampling: {}\n }\n }\n);\n\n// WebSocket client connection\nlet wsClient = null;\n\n// MCP specific channel path\nconst MCP_PATH = '/mcp';\n\n// Map to store pending requests from WebSocket to MCP\nconst pendingRequests = new Map();\nlet requestIdCounter = 1;\n\n// Function to handle WebSocket messages\nasync function handleWebSocketMessage(message) {\n try {\n const data = JSON.parse(message);\n console.error(`Received message: ${data.type}`);\n\n if (data.type === 'toolResponse') {\n // Handle tool response from WebSocket server\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve(result);\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'promptResponse') {\n // Handle prompt response from WebSocket server\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve(result);\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'resourceResponse') {\n // Handle resource response from WebSocket server\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve(result);\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'samplingResponse') {\n // Handle sampling response from WebSocket server\n const {id, result, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve(result);\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'listToolsResponse') {\n // Handle list tools response from WebSocket server\n const {id, tools, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve(tools);\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'listPromptsResponse') {\n // Handle list prompts response from WebSocket server\n const {id, prompts, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve(prompts);\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'listResourcesResponse') {\n // Handle list resources response from WebSocket server\n const {id, resources, resourceTemplates, error} = data;\n\n // Check if this is a response to a pending request\n if (pendingRequests.has(id)) {\n const {resolve, reject} = pendingRequests.get(id);\n pendingRequests.delete(id);\n\n if (error) {\n reject(new Error(error));\n } else {\n resolve({resources, resourceTemplates});\n }\n } else {\n console.error(`No pending request found for ID: ${id}`);\n }\n } else if (data.type === 'toolRegistered') {\n await mcpServer.sendToolListChanged();\n } else if (data.type === 'resourceRegistered') {\n await mcpServer.sendResourceListChanged();\n } else if (data.type === 'promptRegistered') {\n await mcpServer.sendPromptListChanged();\n } else if (data.type === 'welcome') {\n // Welcome message from the server, we're already connected to the MCP path\n console.error(`Connected to path: ${data.channel}`);\n } else if (data.type === 'pong') {\n // Pong response\n console.error(`Received pong with timestamp: ${data.timestamp}`);\n } else if (data.type === 'error') {\n // Error message\n console.error(`Received error: ${data.message}`);\n }\n } catch (error) {\n console.error('Error processing WebSocket message:', error);\n }\n}\n\n// Function to connect to the WebSocket server\nfunction connectToWebSocketServer(serverToken) {\n // Connect to the MCP path directly with server token\n const serverUrl = `ws://localhost:${CONFIG.port}${MCP_PATH}?token=${serverToken}`;\n\n console.error(`Connecting to WebSocket server at ${MCP_PATH} with authentication...`);\n\n wsClient = new WebSocket(serverUrl);\n\n // Handle connection opening\n wsClient.on('open', () => {\n console.error(`Connected to WebSocket server on path: ${MCP_PATH}`);\n });\n\n // Handle incoming messages\n wsClient.on('message', (message) => {\n handleWebSocketMessage(message);\n });\n\n // Handle connection closing\n wsClient.on('close', (code, reason) => {\n console.error(`WebSocket connection closed: ${code} ${reason}`);\n wsClient = null;\n\n // Try to reconnect after a delay\n setTimeout(connectToWebSocketServer, 5000);\n });\n\n // Handle connection errors\n wsClient.on('error', (error) => {\n console.error('WebSocket connection error:', error);\n });\n}\n\n// Function to send a message to the WebSocket server\nfunction sendMessage(message) {\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket not connected');\n return Promise.reject(new Error('WebSocket not connected'));\n }\n\n try {\n wsClient.send(JSON.stringify(message));\n return Promise.resolve();\n } catch (error) {\n console.error('Error sending message:', error);\n return Promise.reject(error);\n }\n}\n\n// Set up the MCP server to handle tool calls by sending them to the WebSocket server\nmcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (request.params.name === \"_webmcp_get-token\") {\n return {\n content: [{\n type: \"text\",\n text: `Paste this into the token input on the WebMCP website\n${await generateNewRegistrationToken()}`,\n }]\n };\n }\n\n if (request.params.name === \"_webmcp_define-mcp-tool\") {\n return {\n content: [{\n type: \"text\",\n text: \"Instruct the user to view the result from the tool call. Do not say anything else.\",\n }]\n }\n }\n\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n return {\n content: [{\n type: \"text\",\n text: \"Not connected to WebSocket server\"\n }],\n isError: true\n };\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error(`Tool call timed out: ${request.params.name}`));\n }\n }, 30000); // 30 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'callTool',\n tool: request.params.name,\n arguments: request.params.arguments\n });\n\n // Wait for the response\n return await responsePromise;\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Error: ${error.message}`\n }],\n isError: true\n };\n }\n});\n\n// Set up the MCP server to handle list tools by querying the WebSocket server\nmcpServer.setRequestHandler(ListToolsRequestSchema, async () => {\n const builtInTools = [\n {\n name: \"_webmcp_get-token\",\n description: \"Retrieve a token to connect to a website for WebMCP. A user might say 'register a token' or 'add a webmcp'\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n {\n name: \"_webmcp_define-mcp-tool\",\n description: \"Used to define an 'mcp tool'. Only use this if the user specifically asks for an mcp tool. \" +\n \"A webmcp token is not required for this.\",\n inputSchema: {\n type: \"object\",\n description: \"The schema which describes the tool.\",\n properties: {\n name: {\n type: \"string\",\n description: \"The name of the tool\"\n },\n description: {\n type: \"string\",\n description: \"Provides a clear and concise description of the tool and what it is used for.\"\n },\n inputSchema: {\n type: \"object\",\n description: \"The inputSchema required or optional for the tool.\",\n properties: {\n type: {\n type: \"string\",\n enum: [\"object\", \"array\", \"string\", \"number\", \"boolean\", \"enum\"],\n description: \"The type of the parameter being defined.\"\n },\n properties: {\n type: \"object\",\n description: \"The properties of the parameter if it's an object type.\",\n additionalProperties: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The data type of the property.\",\n enum: [\"object\", \"array\", \"string\", \"number\", \"boolean\", \"enum\"]\n },\n description: {\n type: \"string\",\n description: \"A brief description of the property.\"\n },\n enum: {\n type: \"array\",\n description: \"A list of allowed values for the property.\",\n items: {\n type: \"string\"\n }\n }\n },\n required: [\"type\", \"description\"]\n }\n },\n required: {\n type: \"array\",\n items: {\n type: \"string\"\n }\n }\n },\n required: [\"type\", \"description\", \"properties\"]\n }\n },\n required: [\"name\", \"description\", \"inputSchema\"]\n },\n }\n ];\n\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n return {tools: builtInTools};\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error('List tools request timed out'));\n }\n }, 10000); // 10 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'listTools'\n });\n\n const tools = await responsePromise;\n\n // Wait for the response\n return { tools: [...tools, ...builtInTools] };\n } catch (error) {\n console.error('Error listing tools:', error);\n return {tools: []}; // Return empty list on error\n }\n});\n\n// Set up the MCP server to handle list prompts by querying the WebSocket server\nmcpServer.setRequestHandler(ListPromptsRequestSchema, async () => {\n const builtInPrompts = [];\n\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n return {\n prompts: builtInPrompts\n };\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error('List prompts request timed out'));\n }\n }, 10000); // 10 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'listPrompts'\n });\n\n const prompts = await responsePromise;\n\n // Wait for the response\n return {\n prompts: [\n ...prompts,\n ...builtInPrompts\n ],\n };\n } catch (error) {\n console.error('Error listing prompts:', error);\n return {prompts: []}; // Return empty list on error\n }\n});\n\n// Set up the MCP server to handle get prompt by querying the WebSocket server\nmcpServer.setRequestHandler(GetPromptRequestSchema, async (request) => {\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n throw new Error(\"Not connected to WebSocket server\");\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error(`Get prompt request timed out: ${request.params.name}`));\n }\n }, 30000); // 30 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'getPrompt',\n name: request.params.name,\n arguments: request.params.arguments\n });\n\n // Wait for the response\n return await responsePromise;\n } catch (error) {\n console.error('Error getting prompt:', error);\n throw error;\n }\n});\n\n// Set up the MCP server to handle list resources by querying the WebSocket server\nmcpServer.setRequestHandler(ListResourcesRequestSchema, async () => {\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n return {resources: []};\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error('List resources request timed out'));\n }\n }, 10000); // 10 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'listResources'\n });\n\n const {resources} = await responsePromise;\n\n // Wait for the response\n return {resources};\n } catch (error) {\n console.error('Error listing resources:', error);\n return {resources: []}; // Return empty list on error\n }\n});\n\n// Set up the MCP server to handle list resource templates by querying the WebSocket server\nmcpServer.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n return {resourceTemplates: []};\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error('List resource templates request timed out'));\n }\n }, 10000); // 10 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'listResources'\n });\n\n const {resourceTemplates} = await responsePromise;\n\n // Wait for the response\n return {resourceTemplates};\n } catch (error) {\n console.error('Error listing resource templates:', error);\n return {resourceTemplates: []}; // Return empty list on error\n }\n});\n\n// Set up the MCP server to handle read resource by querying the WebSocket server\nmcpServer.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n throw new Error(\"Not connected to WebSocket server\");\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error(`Read resource request timed out: ${request.params.uri}`));\n }\n }, 30000); // 30 second timeout\n });\n\n // Send the request to the WebSocket server\n try {\n await sendMessage({\n id: requestId,\n type: 'readResource',\n uri: request.params.uri\n });\n\n // Wait for the response\n return await responsePromise;\n } catch (error) {\n console.error('Error reading resource:', error);\n throw error;\n }\n});\n\n// Set up the MCP server to handle sampling by querying the WebSocket server\nmcpServer.setRequestHandler(CreateMessageRequestSchema, async (request) => {\n if (!wsClient || wsClient.readyState !== WebSocket.OPEN) {\n throw new Error(\"Not connected to WebSocket server\");\n }\n\n // Create a unique request ID\n const requestId = (requestIdCounter++).toString();\n\n // Create a promise that will be resolved when we get a response\n const responsePromise = new Promise((resolve, reject) => {\n // Store the resolver functions\n pendingRequests.set(requestId, {resolve, reject});\n\n // Set a timeout to prevent hanging requests\n setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n pendingRequests.delete(requestId);\n reject(new Error(`Sampling request timed out`));\n }\n }, 120000); // 120 second timeout (sampling can take longer)\n });\n\n // Send the request to the WebSocket server with all parameters from the request\n try {\n await sendMessage({\n id: requestId,\n type: 'createSamplingMessage',\n messages: request.params.messages,\n systemPrompt: request.params.systemPrompt,\n includeContext: request.params.includeContext,\n temperature: request.params.temperature,\n maxTokens: request.params.maxTokens,\n stopSequences: request.params.stopSequences,\n metadata: request.params.metadata,\n modelPreferences: request.params.modelPreferences\n });\n\n // Wait for the response\n return await responsePromise;\n } catch (error) {\n console.error('Error creating sampling message:', error);\n throw error;\n }\n});\n\nasync function runMcpServer(serverToken) {\n // Connect to the WebSocket server\n connectToWebSocketServer(serverToken);\n const transport = new StdioServerTransport();\n await mcpServer.connect(transport);\n console.error(\"MCP server running with stdio transport\");\n}\n\nexport { runMcpServer };\n"], + "mappings": "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", + "names": ["require_constants", "__commonJSMin", "exports", "module", "BINARY_TYPES", "hasBlob", "require_buffer_util", "__commonJSMin", "exports", "module", "EMPTY_BUFFER", "FastBuffer", "concat", "list", "totalLength", "target", "offset", "i", "buf", "_mask", "source", "mask", "output", "length", "_unmask", "buffer", "toArrayBuffer", "toBuffer", "data", "bufferUtil", "require_limiter", "__commonJSMin", "exports", "module", "kDone", "kRun", "Limiter", "concurrency", "job", "require_permessage_deflate", "__commonJSMin", "exports", "module", "zlib", "bufferUtil", "Limiter", "kStatusCode", "FastBuffer", "TRAILER", "kPerMessageDeflate", "kTotalLength", "kCallback", "kBuffers", "kError", "zlibLimiter", "PerMessageDeflate", "options", "isServer", "maxPayload", "concurrency", "params", "configurations", "callback", "offers", "opts", "accepted", "response", "key", "value", "num", "data", "fin", "done", "err", "result", "endpoint", "windowBits", "inflateOnError", "inflateOnData", "deflateOnData", "chunk", "require_validation", "__commonJSMin", "exports", "module", "isUtf8", "hasBlob", "tokenChars", "isValidStatusCode", "code", "_isValidUTF8", "buf", "len", "i", "isBlob", "value", "isValidUTF8", "require_receiver", "__commonJSMin", "exports", "module", "Writable", "PerMessageDeflate", "BINARY_TYPES", "EMPTY_BUFFER", "kStatusCode", "kWebSocket", "concat", "toArrayBuffer", "unmask", "isValidStatusCode", "isValidUTF8", "FastBuffer", "GET_INFO", "GET_PAYLOAD_LENGTH_16", "GET_PAYLOAD_LENGTH_64", "GET_MASK", "GET_DATA", "INFLATING", "DEFER_EVENT", "Receiver", "options", "chunk", "encoding", "cb", "n", "buf", "dst", "offset", "error", "compressed", "num", "data", "err", "messageLength", "fragments", "code", "ErrorCtor", "message", "prefix", "statusCode", "errorCode", "require_sender", "__commonJSMin", "exports", "module", "Duplex", "randomFillSync", "PerMessageDeflate", "EMPTY_BUFFER", "kWebSocket", "NOOP", "isBlob", "isValidStatusCode", "applyMask", "toBuffer", "kByteLength", "maskBuffer", "RANDOM_POOL_SIZE", "randomPool", "randomPoolPointer", "DEFAULT", "DEFLATING", "GET_BLOB_DATA", "Sender", "_Sender", "socket", "extensions", "generateMask", "data", "options", "mask", "merge", "offset", "skipMasking", "dataLength", "payloadLength", "target", "code", "cb", "buf", "length", "byteLength", "readOnly", "perMessageDeflate", "opcode", "rsv1", "opts", "blob", "compress", "arrayBuffer", "err", "callCallbacks", "onError", "_", "params", "list", "sender", "i", "callback", "require_event_target", "__commonJSMin", "exports", "module", "kForOnEventAttribute", "kListener", "kCode", "kData", "kError", "kMessage", "kReason", "kTarget", "kType", "kWasClean", "Event", "type", "CloseEvent", "options", "ErrorEvent", "MessageEvent", "EventTarget", "handler", "listener", "wrapper", "data", "isBinary", "event", "callListener", "code", "message", "error", "thisArg", "require_extension", "__commonJSMin", "exports", "module", "tokenChars", "push", "dest", "name", "elem", "parse", "header", "offers", "params", "mustUnescape", "isEscaping", "inQuotes", "extensionName", "paramName", "start", "code", "end", "i", "value", "token", "format", "extensions", "extension", "configurations", "k", "values", "v", "require_websocket", "__commonJSMin", "exports", "module", "EventEmitter", "https", "http", "net", "tls", "randomBytes", "createHash", "Duplex", "Readable", "URL", "PerMessageDeflate", "Receiver", "Sender", "isBlob", "BINARY_TYPES", "EMPTY_BUFFER", "GUID", "kForOnEventAttribute", "kListener", "kStatusCode", "kWebSocket", "NOOP", "addEventListener", "removeEventListener", "format", "parse", "toBuffer", "closeTimeout", "kAborted", "protocolVersions", "readyStates", "subprotocolRegex", "WebSocket", "_WebSocket", "address", "protocols", "options", "initAsClient", "type", "socket", "head", "receiver", "sender", "receiverOnConclude", "receiverOnDrain", "receiverOnError", "receiverOnMessage", "receiverOnPing", "receiverOnPong", "senderOnError", "socketOnClose", "socketOnData", "socketOnEnd", "socketOnError", "code", "data", "abortHandshake", "err", "setCloseTimer", "mask", "cb", "sendAfterClose", "opts", "property", "method", "listener", "handler", "websocket", "parsedUrl", "isSecure", "isIpcUrl", "invalidUrlMessage", "emitErrorAndClose", "defaultPort", "key", "request", "protocolSet", "perMessageDeflate", "tlsConnect", "netConnect", "protocol", "parts", "req", "headers", "value", "isSameHost", "res", "location", "statusCode", "addr", "upgrade", "digest", "serverProt", "protError", "secWebSocketExtensions", "extensions", "extensionNames", "stream", "message", "length", "reason", "resume", "receiverOnFinish", "isBinary", "chunk", "require_stream", "__commonJSMin", "exports", "module", "WebSocket", "Duplex", "emitClose", "stream", "duplexOnEnd", "duplexOnError", "err", "createWebSocketStream", "ws", "options", "terminateOnDestroy", "duplex", "msg", "isBinary", "data", "callback", "called", "chunk", "encoding", "require_subprotocol", "__commonJSMin", "exports", "module", "tokenChars", "parse", "header", "protocols", "start", "end", "i", "code", "protocol", "require_websocket_server", "__commonJSMin", "exports", "module", "EventEmitter", "http", "Duplex", "createHash", "extension", "PerMessageDeflate", "subprotocol", "WebSocket", "GUID", "kWebSocket", "keyRegex", "RUNNING", "CLOSING", "CLOSED", "WebSocketServer", "options", "callback", "req", "res", "body", "emitConnection", "addListeners", "socket", "head", "cb", "emitClose", "server", "index", "socketOnError", "key", "upgrade", "version", "abortHandshakeOrEmitwsClientError", "abortHandshake", "secWebSocketProtocol", "protocols", "secWebSocketExtensions", "extensions", "perMessageDeflate", "offers", "info", "verified", "code", "message", "headers", "ws", "protocol", "params", "value", "map", "event", "h", "err", "require_package", "__commonJSMin", "exports", "module", "require_main", "__commonJSMin", "exports", "module", "fs", "path", "os", "crypto", "packageJson", "version", "LINE", "parse", "src", "obj", "lines", "match", "key", "value", "maybeQuote", "_parseVault", "options", "vaultPath", "_vaultPath", "result", "DotenvModule", "err", "keys", "_dotenvKey", "length", "decrypted", "i", "attrs", "_instructions", "error", "_log", "message", "_warn", "_debug", "dotenvKey", "uri", "environment", "environmentKey", "ciphertext", "possibleVaultPath", "filepath", "_resolveHome", "envPath", "_configVault", "parsed", "processEnv", "configDotenv", "dotenvPath", "encoding", "debug", "optionPaths", "lastError", "parsedAll", "e", "config", "decrypt", "encrypted", "keyStr", "nonce", "authTag", "aesgcm", "isRange", "invalidKeyLength", "decryptionFailed", "populate", "override", "fs", "import_stream", "import_receiver", "import_sender", "import_websocket", "import_websocket_server", "wrapper_default", "WebSocket", "import_http", "import_url", "import_child_process", "util", "val", "assertIs", "_arg", "assertNever", "_x", "items", "obj", "item", "validKeys", "k", "filtered", "e", "object", "keys", "key", "arr", "checker", "joinValues", "array", "separator", "_", "value", "objectUtil", "first", "second", "ZodParsedType", "getParsedType", "data", "ZodIssueCode", "quotelessJson", "ZodError", "_ZodError", "issues", "sub", "subs", "actualProto", "_mapper", "mapper", "issue", "fieldErrors", "processError", "error", "curr", "i", "el", "formErrors", "errorMap", "_ctx", "message", "overrideErrorMap", "setErrorMap", "map", "getErrorMap", "makeIssue", "params", "path", "errorMaps", "issueData", "fullPath", "fullIssue", "errorMessage", "maps", "m", "EMPTY_PATH", "addIssueToContext", "ctx", "overrideMap", "x", "ParseStatus", "_ParseStatus", "status", "results", "arrayValue", "s", "INVALID", "pairs", "syncPairs", "pair", "finalObject", "DIRTY", "OK", "isAborted", "isDirty", "isValid", "isAsync", "__classPrivateFieldGet", "receiver", "state", "kind", "f", "__classPrivateFieldSet", "errorUtil", "message", "_ZodEnum_cache", "_ZodNativeEnum_cache", "ParseInputLazyPath", "parent", "value", "path", "key", "handleResult", "ctx", "result", "isValid", "error", "ZodError", "processCreateParams", "params", "errorMap", "invalid_type_error", "required_error", "description", "iss", "_a", "_b", "ZodType", "input", "getParsedType", "ParseStatus", "isAsync", "data", "err", "maybeAsyncResult", "check", "getIssueProperties", "val", "setError", "ZodIssueCode", "refinementData", "refinement", "ZodEffects", "ZodFirstPartyTypeKind", "def", "ZodOptional", "ZodNullable", "ZodArray", "ZodPromise", "option", "ZodUnion", "incoming", "ZodIntersection", "transform", "defaultValueFunc", "ZodDefault", "ZodBranded", "catchValueFunc", "ZodCatch", "This", "target", "ZodPipeline", "ZodReadonly", "cuidRegex", "cuid2Regex", "ulidRegex", "uuidRegex", "nanoidRegex", "jwtRegex", "durationRegex", "emailRegex", "_emojiRegex", "emojiRegex", "ipv4Regex", "ipv4CidrRegex", "ipv6Regex", "ipv6CidrRegex", "base64Regex", "base64urlRegex", "dateRegexSource", "dateRegex", "timeRegexSource", "args", "regex", "timeRegex", "datetimeRegex", "opts", "isValidIP", "ip", "version", "isValidJWT", "jwt", "alg", "header", "base64", "decoded", "isValidCidr", "ZodString", "_ZodString", "ZodParsedType", "addIssueToContext", "INVALID", "status", "tooBig", "tooSmall", "util", "validation", "options", "minLength", "maxLength", "len", "ch", "min", "max", "floatSafeRemainder", "step", "valDecCount", "stepDecCount", "decCount", "valInt", "stepInt", "ZodNumber", "_ZodNumber", "kind", "inclusive", "ZodBigInt", "_ZodBigInt", "ZodBoolean", "OK", "ZodDate", "_ZodDate", "minDate", "maxDate", "ZodSymbol", "ZodUndefined", "ZodNull", "ZodAny", "ZodUnknown", "ZodNever", "ZodVoid", "_ZodArray", "item", "i", "schema", "deepPartialify", "ZodObject", "newShape", "fieldSchema", "ZodTuple", "_ZodObject", "shape", "keys", "shapeKeys", "extraKeys", "pairs", "keyValidator", "unknownKeys", "catchall", "syncPairs", "pair", "issue", "_c", "_d", "defaultError", "augmentation", "merging", "index", "mask", "newField", "createZodEnum", "handleResults", "results", "unionErrors", "childCtx", "dirty", "issues", "types", "getDiscriminator", "type", "ZodLazy", "ZodLiteral", "ZodEnum", "ZodNativeEnum", "ZodDiscriminatedUnion", "_ZodDiscriminatedUnion", "discriminator", "discriminatorValue", "optionsMap", "discriminatorValues", "mergeValues", "a", "b", "aType", "bType", "bKeys", "sharedKeys", "newObj", "sharedValue", "newArray", "itemA", "itemB", "handleParsed", "parsedLeft", "parsedRight", "isAborted", "merged", "isDirty", "left", "right", "_ZodTuple", "items", "itemIndex", "x", "rest", "schemas", "ZodRecord", "_ZodRecord", "keyType", "valueType", "first", "second", "third", "ZodMap", "finalMap", "ZodSet", "_ZodSet", "finalizeSet", "elements", "parsedSet", "element", "minSize", "maxSize", "size", "ZodFunction", "_ZodFunction", "makeArgsIssue", "makeIssue", "getErrorMap", "makeReturnsIssue", "returns", "fn", "me", "parsedArgs", "e", "parsedReturns", "returnType", "func", "getter", "values", "_ZodEnum", "expectedValues", "__classPrivateFieldGet", "__classPrivateFieldSet", "enumValues", "newDef", "opt", "nativeEnumValues", "promisified", "effect", "checkCtx", "arg", "processed", "DIRTY", "executeRefinement", "acc", "inner", "base", "preprocess", "newCtx", "ZodNaN", "BRAND", "_ZodPipeline", "inResult", "freeze", "cleanParams", "p", "custom", "_params", "fatal", "r", "_fatal", "late", "instanceOfType", "cls", "stringType", "numberType", "nanType", "bigIntType", "booleanType", "dateType", "symbolType", "undefinedType", "nullType", "anyType", "unknownType", "neverType", "voidType", "arrayType", "objectType", "strictObjectType", "unionType", "discriminatedUnionType", "intersectionType", "tupleType", "recordType", "mapType", "setType", "functionType", "lazyType", "literalType", "enumType", "nativeEnumType", "promiseType", "effectsType", "optionalType", "nullableType", "preprocessType", "pipelineType", "ostring", "onumber", "oboolean", "coerce", "NEVER", "z", "setErrorMap", "EMPTY_PATH", "objectUtil", "quotelessJson", "LATEST_PROTOCOL_VERSION", "SUPPORTED_PROTOCOL_VERSIONS", "JSONRPC_VERSION", "ProgressTokenSchema", "z", "CursorSchema", "BaseRequestParamsSchema", "RequestSchema", "BaseNotificationParamsSchema", "NotificationSchema", "ResultSchema", "RequestIdSchema", "JSONRPCRequestSchema", "JSONRPCNotificationSchema", "JSONRPCResponseSchema", "ErrorCode", "JSONRPCErrorSchema", "JSONRPCMessageSchema", "EmptyResultSchema", "CancelledNotificationSchema", "ImplementationSchema", "ClientCapabilitiesSchema", "InitializeRequestSchema", "ServerCapabilitiesSchema", "InitializeResultSchema", "InitializedNotificationSchema", "PingRequestSchema", "ProgressSchema", "ProgressNotificationSchema", "PaginatedRequestSchema", "PaginatedResultSchema", "ResourceContentsSchema", "TextResourceContentsSchema", "BlobResourceContentsSchema", "ResourceSchema", "ResourceTemplateSchema", "ListResourcesRequestSchema", "ListResourcesResultSchema", "ListResourceTemplatesRequestSchema", "ListResourceTemplatesResultSchema", "ReadResourceRequestSchema", "ReadResourceResultSchema", "ResourceListChangedNotificationSchema", "SubscribeRequestSchema", "UnsubscribeRequestSchema", "ResourceUpdatedNotificationSchema", "PromptArgumentSchema", "PromptSchema", "ListPromptsRequestSchema", "ListPromptsResultSchema", "GetPromptRequestSchema", "TextContentSchema", "ImageContentSchema", "EmbeddedResourceSchema", "PromptMessageSchema", "GetPromptResultSchema", "PromptListChangedNotificationSchema", "ToolSchema", "ListToolsRequestSchema", "ListToolsResultSchema", "CallToolResultSchema", "CompatibilityCallToolResultSchema", "CallToolRequestSchema", "ToolListChangedNotificationSchema", "LoggingLevelSchema", "SetLevelRequestSchema", "LoggingMessageNotificationSchema", "ModelHintSchema", "ModelPreferencesSchema", "SamplingMessageSchema", "CreateMessageRequestSchema", "CreateMessageResultSchema", "ResourceReferenceSchema", "PromptReferenceSchema", "CompleteRequestSchema", "CompleteResultSchema", "RootSchema", "ListRootsRequestSchema", "ListRootsResultSchema", "RootsListChangedNotificationSchema", "ClientRequestSchema", "ClientNotificationSchema", "ClientResultSchema", "ServerRequestSchema", "ServerNotificationSchema", "ServerResultSchema", "McpError", "code", "message", "data", "DEFAULT_REQUEST_TIMEOUT_MSEC", "Protocol", "_options", "CancelledNotificationSchema", "notification", "controller", "ProgressNotificationSchema", "PingRequestSchema", "_request", "messageId", "timeout", "maxTotalTimeout", "onTimeout", "info", "totalElapsed", "McpError", "ErrorCode", "transport", "error", "message", "responseHandlers", "_a", "handler", "request", "_b", "abortController", "result", "progressToken", "params", "responseHandler", "response", "resultSchema", "options", "resolve", "reject", "jsonrpcRequest", "cancel", "reason", "_c", "_d", "timeoutHandler", "jsonrpcNotification", "requestSchema", "method", "extra", "notificationSchema", "mergeCapabilities", "base", "additional", "acc", "key", "value", "Server", "Protocol", "_serverInfo", "options", "_a", "InitializeRequestSchema", "request", "InitializedNotificationSchema", "capabilities", "mergeCapabilities", "method", "_b", "requestedVersion", "SUPPORTED_PROTOCOL_VERSIONS", "LATEST_PROTOCOL_VERSION", "EmptyResultSchema", "params", "CreateMessageResultSchema", "ListRootsResultSchema", "import_node_process", "ReadBuffer", "chunk", "index", "line", "deserializeMessage", "JSONRPCMessageSchema", "serializeMessage", "message", "StdioServerTransport", "_stdin", "process", "_stdout", "ReadBuffer", "chunk", "error", "_a", "message", "_b", "resolve", "json", "serializeMessage", "fs", "crypto", "path", "dotenv", "os", "fs", "import_node_path", "import_node_os", "import_node_process", "homedir", "os", "tmpdir", "env", "process", "macos", "name", "library", "path", "windows", "appData", "localAppData", "linux", "username", "envPaths", "suffix", "HOME_DIR", "CONFIG_DIR", "ensureConfigDir", "error", "PID_FILE", "ENV_FILE", "TOKENS_FILE", "SERVER_TOKEN", "HOST", "CONFIG", "setConfig", "args", "key", "value", "formatChannel", "channel", "exists", "somePath", "configureMcpClientWithPath", "clientConfigPath", "directory", "webmcpConfig", "json", "rawJSON", "e", "availableClientConfigs", "envPaths", "configureMcpClient", "clientType", "generateToken", "authorizedTokens", "getToken", "channel", "setToken", "value", "deleteToken", "clearTokens", "loadAuthorizedTokens", "data", "TOKENS_FILE", "error", "saveAuthorizedTokens", "stringified", "saveServerTokenToEnv", "token", "envContent", "ENV_FILE", "generateNewRegistrationToken", "address", "HOST", "CONFIG", "connectionData", "jsonStr", "encodedData", "formatChannel", "mcpServer", "Server", "wsClient", "MCP_PATH", "pendingRequests", "requestIdCounter", "handleWebSocketMessage", "message", "data", "id", "result", "error", "resolve", "reject", "tools", "prompts", "resources", "resourceTemplates", "connectToWebSocketServer", "serverToken", "serverUrl", "CONFIG", "wrapper_default", "code", "reason", "sendMessage", "CallToolRequestSchema", "request", "generateNewRegistrationToken", "requestId", "responsePromise", "ListToolsRequestSchema", "builtInTools", "ListPromptsRequestSchema", "builtInPrompts", "GetPromptRequestSchema", "ListResourcesRequestSchema", "ListResourceTemplatesRequestSchema", "ReadResourceRequestSchema", "CreateMessageRequestSchema", "runMcpServer", "transport", "StdioServerTransport", "serverToken", "SERVER_TOKEN", "httpServer", "req", "res", "wss", "WebSocketServer", "verifyClientToken", "channels", "MCP_PATH", "REGISTER_PATH", "sendNotification", "clientWs", "channelPath", "notificationType", "data", "mcpOnly", "WebSocket", "mcpClient", "mcpData", "toolsRegistry", "promptsRegistry", "resourcesRegistry", "requestIdCounter", "pendingRequests", "info", "callback", "url", "HOST", "clientToken", "path", "loadAuthorizedTokens", "getToken", "getOrCreateChannel", "ws", "clientChannel", "registrationTimeout", "message", "encodedData", "decodedJson", "connectionData", "host", "token", "formatChannel", "serverChannel", "CONFIG", "deleteToken", "sessionToken", "generateToken", "setToken", "saveAuthorizedTokens", "error", "handlePing", "handleRegisterTool", "handleRegisterPrompt", "handleRegisterResource", "handleListTools", "handleListPrompts", "handleListResources", "handleCallTool", "handleGetPrompt", "handleReadResource", "handleCreateSamplingMessage", "handleToolResponse", "handlePromptResponse", "handleResourceResponse", "handleSamplingResponse", "sendError", "channel", "itemsToRemove", "toolId", "toolInfo", "promptId", "promptInfo", "resourceId", "resourceInfo", "name", "description", "inputSchema", "promptArgs", "uri", "mimeType", "isTemplate", "uriTemplate", "id", "isMcpClient", "tools", "_", "prompts", "resources", "resourceTemplates", "pathBasedName", "callerChannel", "tool", "args", "targetChannel", "toolName", "targetClient", "requestId", "requesterWs", "originalId", "promptName", "p", "resourceName", "resId", "result", "messages", "systemPrompt", "includeContext", "temperature", "maxTokens", "stopSequences", "metadata", "modelPreferences", "clients", "isServerRunning", "CONFIG", "pidData", "PID_FILE", "pid", "savePid", "error", "daemonize", "args", "child", "parseArgs", "port", "quit", "newToken", "startMCP", "docker", "cleanTokens", "encodedPair", "daemon", "i", "arg", "showHelp", "portArg", "config", "availableClientConfigs", "configureMcpClient", "configureMcpClientWithPath", "main", "ensureConfigDir", "loadAuthorizedTokens", "setConfig", "serverStatus", "clearTokens", "saveAuthorizedTokens", "encodedData", "generateNewRegistrationToken", "serverToken", "generateToken", "saveServerTokenToEnv", "PORT", "httpServer", "HOST", "MCP_PATH", "shutdownGracefully", "signal", "channel", "channels", "ws", "err", "data", "runMcpServer"] +} diff --git a/build/webmcp.js b/build/webmcp.js new file mode 100644 index 0000000..8ea7cde --- /dev/null +++ b/build/webmcp.js @@ -0,0 +1,2 @@ +(()=>{var I=Object.defineProperty,P=Object.defineProperties;var j=Object.getOwnPropertyDescriptors;var O=Object.getOwnPropertySymbols;var $=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var k=(a,e,t)=>e in a?I(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t,_=(a,e)=>{for(var t in e||(e={}))$.call(e,t)&&k(a,t,e[t]);if(O)for(var t of O(e))L.call(e,t)&&k(a,t,e[t]);return a},v=(a,e)=>P(a,j(e));var w=(a,e,t)=>new Promise((s,o)=>{var n=l=>{try{i(t.next(l))}catch(d){o(d)}},r=l=>{try{i(t.throw(l))}catch(d){o(d)}},i=l=>l.done?s(l.value):Promise.resolve(l.value).then(n,r);i((t=t.apply(a,e)).next())});var R=class{constructor(e={}){this.options=_({color:"#007bff",position:"bottom-right",size:"30px",padding:"20px",inactivityTimeout:5*60*1e3},e),this.isConnected=!1,this.isExpanded=!1,this.socket=null,this.inactivityTimer=null,this.availableTools=new Map,this.availablePrompts=new Map,this.availableResources=new Map,this.samplingCallbacks=new Map,this.currentToken="",this.currentServer="",this.currentChannel="",this.elementId="webmcp-widget-"+Math.random().toString(36).substr(2,9),this.registeredTools=new Set,this.registeredPrompts=new Set,this.registeredResources=new Set,this.SESSION_STORAGE_KEY="webmcp_token",this.TOOLS_STORAGE_KEY="webmcp_tools",this.PROMPTS_STORAGE_KEY="webmcp_prompts",this.RESOURCES_STORAGE_KEY="webmcp_resources",this.REGISTER_PATH="/register",this._init()}_format(e){return e.replace(/[.:]/g,"_")}_init(){if(document.querySelector("[data-webmcp-widget]")){console.warn("WebMCP widget already initialized on this page");return}this._createWidget(),this._setupEventListeners(),this._resetInactivityTimer(),this._checkStoredToken()}_checkStoredToken(){let e=sessionStorage.getItem(this.SESSION_STORAGE_KEY);if(e)try{let t=JSON.parse(e);if(t.token){if(console.log("Found stored connection info, attempting to connect"),this.currentServer=t.server,this.currentChannel=`/${t.channelHost||this._format(window.location.host)}`,t.token.includes("{")){let s=JSON.parse(t.token);this.currentToken=s.token}else try{let s=atob(t.token),o=JSON.parse(s);this.currentToken=o.token}catch(s){this.currentToken=t.token}this._loadStoredItems(),this.connect(t.token)}}catch(t){console.error("Error parsing stored connection info:",t),sessionStorage.removeItem(this.SESSION_STORAGE_KEY),this._clearStoredItems()}}_saveItemsToStorage(){try{let e={};this.availableTools.forEach((o,n)=>{e[n]={name:o.name,description:o.description,inputSchema:o.inputSchema}}),sessionStorage.setItem(this.TOOLS_STORAGE_KEY,JSON.stringify(e));let t={};this.availablePrompts.forEach((o,n)=>{t[n]={name:o.name,description:o.description,arguments:o.arguments}}),sessionStorage.setItem(this.PROMPTS_STORAGE_KEY,JSON.stringify(t));let s={};this.availableResources.forEach((o,n)=>{s[n]={name:o.name,description:o.description,uri:o.uri,uriTemplate:o.uriTemplate,isTemplate:o.isTemplate,mimeType:o.mimeType}}),sessionStorage.setItem(this.RESOURCES_STORAGE_KEY,JSON.stringify(s)),console.log("Saved items to session storage:",{tools:Object.keys(e).length,prompts:Object.keys(t).length,resources:Object.keys(s).length})}catch(e){console.error("Error saving items to session storage:",e)}}_loadStoredItems(){try{let e=sessionStorage.getItem(this.TOOLS_STORAGE_KEY);if(e){let o=JSON.parse(e);Object.entries(o).forEach(([n,r])=>{this.availableTools.set(n,v(_({},r),{execute:function(i){return console.warn(`Tool ${n} was loaded from storage but has not been re-registered with an execution function`),`Tool ${n} needs to be re-registered`}}))})}let t=sessionStorage.getItem(this.PROMPTS_STORAGE_KEY);if(t){let o=JSON.parse(t);Object.entries(o).forEach(([n,r])=>{this.availablePrompts.set(n,v(_({},r),{execute:function(i){return console.warn(`Prompt ${n} was loaded from storage but has not been re-registered with an execution function`),{messages:[{role:"user",content:{type:"text",text:`Prompt ${n} needs to be re-registered`}}]}}}))})}let s=sessionStorage.getItem(this.RESOURCES_STORAGE_KEY);if(s){let o=JSON.parse(s);Object.entries(o).forEach(([n,r])=>{this.availableResources.set(n,v(_({},r),{provide:function(i){return console.warn(`Resource ${n} was loaded from storage but has not been re-registered with a provider function`),{contents:[{uri:i,text:`Resource ${n} needs to be re-registered`,mimeType:r.mimeType||"text/plain"}]}}}))})}console.log("Loaded items from session storage:",{tools:this.availableTools.size,prompts:this.availablePrompts.size,resources:this.availableResources.size}),this._updateToolsList(),this._updatePromptsList(),this._updateResourcesList()}catch(e){console.error("Error loading items from session storage:",e),this._clearStoredItems()}}_clearStoredItems(){sessionStorage.removeItem(this.TOOLS_STORAGE_KEY),sessionStorage.removeItem(this.PROMPTS_STORAGE_KEY),sessionStorage.removeItem(this.RESOURCES_STORAGE_KEY),console.log("Cleared stored items from session storage")}_createWidget(){let e=document.createElement("div");e.id=this.elementId,e.dataset.webmcpWidget=!0,Object.assign(e.style,{position:"fixed",zIndex:"9999",display:"flex",flexDirection:"column",fontFamily:"Arial, sans-serif",fontSize:"14px",transition:"all 0.3s ease"}),this._setWidgetPosition(e);let t=document.createElement("div");t.className="webmcp-trigger",Object.assign(t.style,{width:this.options.size,height:this.options.size,backgroundColor:this.options.color,borderRadius:"4px",cursor:"pointer",boxShadow:"0 2px 10px rgba(0,0,0,0.2)",display:"flex",justifyContent:"center",alignItems:"center",alignSelf:"flex-end"});let s=document.createElement("div");s.className="webmcp-content",Object.assign(s.style,{backgroundColor:"#ffffff",border:"1px solid #e1e1e1",borderRadius:"5px",padding:"15px",marginBottom:"10px",boxShadow:"0 5px 15px rgba(0,0,0,0.1)",width:"250px",display:"none",overflow:"hidden",position:"absolute",bottom:"40px"});let o=document.createElement("div");Object.assign(o.style,{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"15px"});let n=document.createElement("div");n.textContent="WebMCP",Object.assign(n.style,{fontWeight:"bold",fontSize:"16px"});let r=document.createElement("button");r.innerHTML="×",r.className="webmcp-close",Object.assign(r.style,{background:"none",border:"none",cursor:"pointer",fontSize:"20px",padding:"0",lineHeight:"1",color:"#999"}),o.appendChild(n),o.appendChild(r),s.appendChild(o),this._createConnectionForm(s);let i=document.createElement("div");i.className="webmcp-status",i.textContent="Disconnected",Object.assign(i.style,{padding:"8px",borderRadius:"3px",backgroundColor:"#f8d7da",color:"#721c24",textAlign:"center",marginBottom:"10px",fontSize:"12px"}),s.appendChild(i);let l=document.createElement("div");l.className="webmcp-connection-panel",s.appendChild(l);let d=document.createElement("div");d.className="webmcp-registered-items",Object.assign(d.style,{marginTop:"15px",fontSize:"12px",display:"none",maxHeight:"200px",overflow:"auto",border:"1px solid #eee",borderRadius:"4px"}),s.appendChild(d);let E=document.createElement("div");E.className="webmcp-tools-list",Object.assign(E.style,{padding:"10px",borderBottom:"1px solid #eee"});let u=document.createElement("div");u.textContent="Registered Tools:",Object.assign(u.style,{fontWeight:"bold",marginBottom:"5px"});let p=document.createElement("ul");p.className="webmcp-tools-container",Object.assign(p.style,{listStyle:"none",padding:"0",margin:"0"}),E.appendChild(u),E.appendChild(p),d.appendChild(E);let h=document.createElement("div");h.className="webmcp-prompts-list",Object.assign(h.style,{padding:"10px",borderBottom:"1px solid #eee"});let g=document.createElement("div");g.textContent="Registered Prompts:",Object.assign(g.style,{fontWeight:"bold",marginBottom:"5px"});let y=document.createElement("ul");y.className="webmcp-prompts-container",Object.assign(y.style,{listStyle:"none",padding:"0",margin:"0"}),h.appendChild(g),h.appendChild(y),d.appendChild(h);let m=document.createElement("div");m.className="webmcp-resources-list",Object.assign(m.style,{padding:"10px"});let b=document.createElement("div");b.textContent="Registered Resources:",Object.assign(b.style,{fontWeight:"bold",marginBottom:"5px"});let f=document.createElement("ul");f.className="webmcp-resources-container",Object.assign(f.style,{listStyle:"none",padding:"0",margin:"0"}),m.appendChild(b),m.appendChild(f),d.appendChild(m),e.appendChild(s),e.appendChild(t),document.body.appendChild(e)}_setWidgetPosition(e){let{position:t,padding:s}=this.options;switch(t){case"bottom-right":Object.assign(e.style,{bottom:s,right:s,alignItems:"flex-end"});break;case"bottom-left":Object.assign(e.style,{bottom:s,left:s,alignItems:"flex-start"});break;case"top-right":Object.assign(e.style,{top:s,right:s,alignItems:"flex-end"});break;case"top-left":Object.assign(e.style,{top:s,left:s,alignItems:"flex-start"});break;default:Object.assign(e.style,{bottom:s,right:s,alignItems:"flex-end"})}}_createConnectionForm(e){let t=document.createElement("div");Object.assign(t.style,{marginBottom:"8px"});let s=document.createElement("div");Object.assign(s.style,{display:"flex",marginBottom:"8px"});let o=document.createElement("input");o.type="text",o.className="webmcp-token-input",o.placeholder="Paste connection token",Object.assign(o.style,{flex:"1",padding:"8px",border:"1px solid #ccc",borderRadius:"4px 0 0 4px",fontSize:"12px"});let n=document.createElement("button");n.className="webmcp-connect-btn",n.textContent="Connect",Object.assign(n.style,{padding:"8px 12px",backgroundColor:this.options.color,color:"white",border:"none",borderRadius:"0 4px 4px 0",cursor:"pointer",fontSize:"12px"}),s.appendChild(o),s.appendChild(n);let r=document.createElement("button");r.className="webmcp-disconnect-btn",r.textContent="Disconnect",Object.assign(r.style,{padding:"8px 12px",backgroundColor:"#dc3545",color:"white",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"12px",width:"100%",display:"none"}),t.appendChild(s),t.appendChild(r),e.appendChild(t)}_setupEventListeners(){let e=document.getElementById(this.elementId);if(!e)return;e.querySelector(".webmcp-trigger").addEventListener("click",()=>{this._toggleExpanded()}),e.querySelector(".webmcp-close").addEventListener("click",()=>{this._toggleExpanded(!1)}),e.querySelector(".webmcp-connect-btn").addEventListener("click",()=>{let r=e.querySelector(".webmcp-token-input");this.connect(r.value)}),e.querySelector(".webmcp-disconnect-btn").addEventListener("click",()=>{this.disconnect()}),document.addEventListener("mousemove",()=>this._resetInactivityTimer()),document.addEventListener("keypress",()=>this._resetInactivityTimer()),document.addEventListener("click",()=>this._resetInactivityTimer()),document.addEventListener("scroll",()=>this._resetInactivityTimer())}_toggleExpanded(e=null){let t=document.getElementById(this.elementId);if(!t)return;let s=t.querySelector(".webmcp-content");this.isExpanded=e!==null?e:!this.isExpanded,this.isExpanded?s.style.display="block":s.style.display="none",this._resetInactivityTimer()}_updateStatus(e,t){let s=document.getElementById(this.elementId);if(!s)return;let o=s.querySelector(".webmcp-status");if(o)switch(o.classList.remove("connected","disconnected","connecting","pending-auth"),o.textContent=t||e,e){case"connected":Object.assign(o.style,{backgroundColor:"#d4edda",color:"#155724"});break;case"disconnected":Object.assign(o.style,{backgroundColor:"#f8d7da",color:"#721c24"});break;case"connecting":Object.assign(o.style,{backgroundColor:"#fff3cd",color:"#856404"});break;case"pending-auth":Object.assign(o.style,{backgroundColor:"#d1ecf1",color:"#0c5460"});break}}_updateConnectionUI(e){let t=document.getElementById(this.elementId);if(!t)return;let s=t.querySelector(".webmcp-token-input"),o=t.querySelector(".webmcp-connect-btn"),n=t.querySelector(".webmcp-disconnect-btn"),r=t.querySelector(".webmcp-registered-items");if(e){s.style.display="none",o.style.display="none",n.style.display="block",r.style.display="block";let i=t.querySelector(".webmcp-trigger");i.innerHTML="\u2713",i.style.color="white",i.style.fontWeight="bold"}else{s.style.display="block",o.style.display="block",n.style.display="none",r.style.display="none";let i=t.querySelector(".webmcp-trigger");i.innerHTML=""}}_updateToolsList(){let e=document.getElementById(this.elementId);if(!e)return;let t=e.querySelector(".webmcp-tools-container");if(t){if(t.innerHTML="",this.availableTools.size===0){let s=document.createElement("li");s.textContent="No tools registered",s.style.fontStyle="italic",s.style.color="#666",t.appendChild(s);return}this.availableTools.forEach((s,o)=>{let n=document.createElement("li");Object.assign(n.style,{padding:"5px 0",borderBottom:"1px solid #eee"});let r=document.createElement("strong");r.textContent=o;let i=document.createElement("div");i.textContent=s.description,i.style.fontSize="10px",i.style.color="#666",n.appendChild(r),n.appendChild(i),t.appendChild(n)})}}_updatePromptsList(){let e=document.getElementById(this.elementId);if(!e)return;let t=e.querySelector(".webmcp-prompts-container");if(t){if(t.innerHTML="",this.availablePrompts.size===0){let s=document.createElement("li");s.textContent="No prompts registered",s.style.fontStyle="italic",s.style.color="#666",t.appendChild(s);return}this.availablePrompts.forEach((s,o)=>{let n=document.createElement("li");Object.assign(n.style,{padding:"5px 0",borderBottom:"1px solid #eee"});let r=document.createElement("strong");r.textContent=o;let i=document.createElement("div");i.textContent=s.description,i.style.fontSize="10px",i.style.color="#666",n.appendChild(r),n.appendChild(i),t.appendChild(n)})}}_updateResourcesList(){let e=document.getElementById(this.elementId);if(!e)return;let t=e.querySelector(".webmcp-resources-container");if(t){if(t.innerHTML="",this.availableResources.size===0){let s=document.createElement("li");s.textContent="No resources registered",s.style.fontStyle="italic",s.style.color="#666",t.appendChild(s);return}this.availableResources.forEach((s,o)=>{let n=document.createElement("li");Object.assign(n.style,{padding:"5px 0",borderBottom:"1px solid #eee"});let r=document.createElement("strong");r.textContent=o;let i=document.createElement("div");i.textContent=s.description+(s.isTemplate?" (Template)":""),i.style.fontSize="10px",i.style.color="#666",n.appendChild(r),n.appendChild(i),t.appendChild(n)})}}_resetInactivityTimer(){this.inactivityTimer&&clearTimeout(this.inactivityTimer),this.inactivityTimer=setTimeout(()=>{this._handleInactivity()},this.options.inactivityTimeout)}_handleInactivity(){console.log("Inactivity timeout reached, disconnecting"),this.isConnected&&this.disconnect(),this._toggleExpanded(!1),sessionStorage.removeItem(this.SESSION_STORAGE_KEY)}connect(e){return w(this,null,function*(){if(!e){this._updateStatus("disconnected","Error: No token provided");return}this._updateStatus("connecting","Connecting...");try{if(!this._processConnectionToken(e))return;let t={token:e,server:this.currentServer,host:this._format(window.location.host)},s=sessionStorage.getItem(this.SESSION_STORAGE_KEY),o=!1;if(s)try{let r=JSON.parse(s);r.server===this.currentServer&&r.host===this._format(window.location.host)&&(o=!0)}catch(r){console.error("Error parsing stored connection info:",r)}if(!o){let r=yield this._registerWithServer(e);if(!r.token){this._updateStatus("disconnected","Registration failed");return}t.token=r.token,this.currentToken=r.token,sessionStorage.setItem(this.SESSION_STORAGE_KEY,JSON.stringify(t))}let n=`${this.currentServer}${this.currentChannel}?token=${this.currentToken}`;this._updateStatus("connecting","Connecting to channel..."),this.socket=new WebSocket(n),this._setupSocketListeners(),this._resetInactivityTimer()}catch(t){console.error("Connection error:",t),this._updateStatus("disconnected",`Error: ${t.message}`)}})}disconnect(){this.socket&&(this.socket.close(),this.socket=null),this.isConnected=!1,this._updateStatus("disconnected","Disconnected"),this._updateConnectionUI(!1),this.currentToken="",this.currentServer="",this.currentChannel="",sessionStorage.removeItem(this.SESSION_STORAGE_KEY),this._clearStoredItems()}_processConnectionToken(e){try{let t=atob(e),s=JSON.parse(t),{server:o,token:n}=s;return!o||!n?(this._updateStatus("disconnected","Invalid token"),!1):(this.currentServer=o,this.currentToken=n,this.currentChannel=`/${this._format(window.location.host)}`,!0)}catch(t){return this._updateStatus("disconnected","Unable to parse token"),!1}}_registerWithServer(e){this._updateStatus("pending-auth","Registering...");let t=new WebSocket(`${this.currentServer}${this.REGISTER_PATH}`);return new Promise((s,o)=>{t.addEventListener("open",n=>{console.log("Registration connection established");let r=atob(e),i=JSON.parse(r);i.host=this._format(window.location.host),t.send(btoa(JSON.stringify(i)))}),t.addEventListener("message",n=>{try{let r=JSON.parse(n.data);r.type==="registerSuccess"&&r.token?(console.log(`Registration successful: ${r.message}`),s({token:r.token})):r.type==="error"&&(console.error(`Registration failed: ${r.message}`),this._updateStatus("disconnected",`Registration failed: ${r.message}`),o(new Error(r.message)))}catch(r){console.error(`Error parsing registration response: ${r.message}`),this._updateStatus("disconnected","Error parsing server response"),o(r)}}),t.addEventListener("error",n=>{console.error("Registration connection error"),this._updateStatus("disconnected","Registration connection error"),sessionStorage.removeItem(this.SESSION_STORAGE_KEY),o(new Error("Connection error"))}),t.addEventListener("close",n=>{console.log(`Registration connection closed: ${n.code} ${n.reason}`),n.code!==1e3&&(this._updateStatus("disconnected","Registration failed"),sessionStorage.removeItem(this.SESSION_STORAGE_KEY),o(new Error("Connection closed")))})})}_setupSocketListeners(){if(!this.socket){console.error("Cannot set up socket listeners: WebSocket not available");return}this.socket.addEventListener("open",()=>{this.isConnected=!0,this._updateStatus("connected",`Connected to ${this.currentChannel}`),this._updateConnectionUI(!0),console.log("WebMCP connection established"),this._registerItemsWithServer()}),this.socket.addEventListener("close",e=>{this.isConnected=!1,this._updateStatus("disconnected","Disconnected"),this._updateConnectionUI(!1),console.log(`Connection closed: ${e.code} ${e.reason}`),(e.code===1001||e.code===401)&&(this._updateStatus("disconnected","Authorization failed"),this.currentToken="",this.currentServer="",this.currentChannel="",sessionStorage.removeItem(this.SESSION_STORAGE_KEY))}),this.socket.addEventListener("error",()=>{console.error("WebSocket error"),this.isConnected?this._updateStatus("disconnected","Connection error occurred"):this._updateStatus("disconnected","Connection failed"),sessionStorage.removeItem(this.SESSION_STORAGE_KEY)}),this.socket.addEventListener("message",e=>{try{let t=JSON.parse(e.data);this._handleServerMessage(t)}catch(t){console.error(`Error parsing message: ${t.message}`)}})}_handleServerMessage(e){switch(e.type){case"welcome":console.log(`Server says: ${e.message}`);break;case"toolRegistered":console.log(`Tool registered with server: ${e.name}`);break;case"promptRegistered":console.log(`Prompt registered with server: ${e.name}`);break;case"resourceRegistered":console.log(`Resource registered with server: ${e.name}`);break;case"callTool":this._handleToolCall(e);break;case"getPrompt":this._handleGetPrompt(e);break;case"readResource":this._handleReadResource(e);break;case"createSamplingMessage":this._handleCreateSamplingMessage(e);break;case"listTools":this._sendToolsList(e.id);break;case"listPrompts":this._sendPromptsList(e.id);break;case"listResources":this._sendResourcesList(e.id);break;case"ping":this._sendMessage({type:"pong",id:e.id,timestamp:Date.now()});break;case"error":console.error(`Server error: ${e.message}`);break;default:console.warn(`Unknown message type: ${e.type}`)}}_handleToolCall(e){let{id:t,tool:s,arguments:o}=e;if(console.log(`Tool call: ${s} with args:`,o),!this.availableTools.has(s)){this._sendMessage({id:t,type:"toolResponse",error:`Tool not found: ${s}`});return}try{let r=this.availableTools.get(s).execute(o);r instanceof Promise?r.then(i=>{this._sendMessage({id:t,type:"toolResponse",result:i})}).catch(i=>{this._sendMessage({id:t,type:"toolResponse",error:i.message||"Tool execution error"})}):this._sendMessage({id:t,type:"toolResponse",result:r}),console.log(`Tool response sent for ${s}`)}catch(n){this._sendMessage({id:t,type:"toolResponse",error:n.message||"Tool execution error"}),console.error("Tool execution error:",n)}}_handleGetPrompt(e){let{id:t,name:s,arguments:o}=e;if(console.log(`Prompt request: ${s} with args:`,o),!this.availablePrompts.has(s)){this._sendMessage({id:t,type:"promptResponse",error:`Prompt not found: ${s}`});return}try{let r=this.availablePrompts.get(s).execute(o);r instanceof Promise?r.then(i=>{this._sendMessage({id:t,type:"promptResponse",result:i})}).catch(i=>{this._sendMessage({id:t,type:"promptResponse",error:i.message||"Prompt execution error"})}):this._sendMessage({id:t,type:"promptResponse",result:r}),console.log(`Prompt response sent for ${s}`)}catch(n){this._sendMessage({id:t,type:"promptResponse",error:n.message||"Prompt execution error"}),console.error("Prompt execution error:",n)}}_handleReadResource(e){let{id:t,uri:s}=e;console.log(`Resource request: ${s}`);let o=null;for(let n of this.availableResources.values())if(!n.isTemplate&&n.uri===s){o=n;break}if(!o){for(let n of this.availableResources.values())if(n.isTemplate){let r=n.uriTemplate.split("{")[0];if(s.startsWith(r)){o=n;break}}}if(!o){this._sendMessage({id:t,type:"resourceResponse",error:`No resource handler found for URI: ${s}`});return}try{let n=o.provide(s);n instanceof Promise?n.then(r=>{this._sendMessage({id:t,type:"resourceResponse",result:r})}).catch(r=>{this._sendMessage({id:t,type:"resourceResponse",error:r.message||"Resource read error"})}):this._sendMessage({id:t,type:"resourceResponse",result:n}),console.log(`Resource response sent for ${s}`)}catch(n){this._sendMessage({id:t,type:"resourceResponse",error:n.message||"Resource read error"}),console.error("Resource read error:",n)}}_sendToolsList(e){let t=Array.from(this.availableTools.values()).map(s=>({name:s.name,description:s.description,inputSchema:s.inputSchema}));this._sendMessage({id:e,type:"listToolsResponse",tools:t}),console.log(`Sent tools list: ${t.length} tools`)}_sendPromptsList(e){let t=Array.from(this.availablePrompts.values()).map(s=>({name:s.name,description:s.description,arguments:s.arguments}));this._sendMessage({id:e,type:"listPromptsResponse",prompts:t}),console.log(`Sent prompts list: ${t.length} prompts`)}_sendResourcesList(e){let t=[],s=[];this.availableResources.forEach(o=>{o.isTemplate?s.push({name:o.name,description:o.description,uriTemplate:o.uriTemplate,mimeType:o.mimeType}):t.push({name:o.name,description:o.description,uri:o.uri,mimeType:o.mimeType})}),this._sendMessage({id:e,type:"listResourcesResponse",resources:t,resourceTemplates:s}),console.log(`Sent resources list: ${t.length} resources, ${s.length} templates`)}_sendMessage(e){if(!this.isConnected||!this.socket){console.error("Cannot send message: not connected");return}try{return this.socket.send(JSON.stringify(e)),Promise.resolve()}catch(t){return console.error(`Error sending message: ${t.message}`),Promise.reject(t)}}_registerItemsWithServer(){this.isConnected&&(this.registeredTools=new Set,this.registeredPrompts=new Set,this.registeredResources=new Set,this.availableTools.forEach((e,t)=>{this._sendMessage({type:"registerTool",name:t,description:e.description,inputSchema:e.inputSchema}),this.registeredTools.add(t),console.log(`Registering tool with server: ${t}`)}),this.availablePrompts.forEach((e,t)=>{this._sendMessage({type:"registerPrompt",name:t,description:e.description,arguments:e.arguments}),this.registeredPrompts.add(t),console.log(`Registering prompt with server: ${t}`)}),this.availableResources.forEach((e,t)=>{this._sendMessage({type:"registerResource",name:t,description:e.description,uri:e.uri,uriTemplate:e.uriTemplate,isTemplate:e.isTemplate,mimeType:e.mimeType}),this.registeredResources.add(t),console.log(`Registering resource with server: ${t}`)}))}registerTool(e,t,s,o){if(!e){console.error("Tool name is required");return}this.availableTools.set(e,{name:e,description:t||`Tool: ${e}`,execute:o||function(n){return`Default implementation of ${e} with args: ${JSON.stringify(n)}`},inputSchema:s||{type:"object",properties:{}}}),this.isConnected&&(this._sendMessage({type:"registerTool",name:e,description:t||`Tool: ${e}`,inputSchema:s||{type:"object",properties:{}}}),this.registeredTools.add(e)),this._saveItemsToStorage(),this._updateToolsList(),console.log(`Tool registered: ${e}`)}registerPrompt(e,t,s,o){if(!e){console.error("Prompt name is required");return}this.availablePrompts.set(e,{name:e,description:t||`Prompt: ${e}`,execute:o||function(n){return{messages:[{role:"user",content:{type:"text",text:`Default implementation of prompt ${e} with args: ${JSON.stringify(n)}`}}]}},arguments:s||[]}),this.isConnected&&(this._sendMessage({type:"registerPrompt",name:e,description:t||`Prompt: ${e}`,arguments:s||[]}),this.registeredPrompts.add(e)),this._saveItemsToStorage(),this._updatePromptsList(),console.log(`Prompt registered: ${e}`)}registerResource(e,t,s,o){if(!e){console.error("Resource name is required");return}if(!s.uri&&!s.uriTemplate){console.error("Either uri or uriTemplate is required for a resource");return}let n=!!s.uriTemplate;this.availableResources.set(e,{name:e,description:t||`Resource: ${e}`,uri:s.uri,uriTemplate:s.uriTemplate,isTemplate:n,mimeType:s.mimeType,provide:o||function(r){return{contents:[{uri:r,text:`Default implementation of resource ${e} for URI: ${r}`,mimeType:s.mimeType||"text/plain"}]}}}),this.isConnected&&(this._sendMessage({type:"registerResource",name:e,description:t||`Resource: ${e}`,uri:s.uri,uriTemplate:s.uriTemplate,isTemplate:n,mimeType:s.mimeType}),this.registeredResources.add(e)),this._saveItemsToStorage(),this._updateResourcesList(),console.log(`Resource registered: ${e}`)}_handleCreateSamplingMessage(e){let{id:t,messages:s,systemPrompt:o,includeContext:n,temperature:r,maxTokens:i,stopSequences:l,metadata:d,modelPreferences:E}=e;console.log(`Sampling request received with ${(s==null?void 0:s.length)||0} messages`);let u=document.createElement("div");Object.assign(u.style,{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",backgroundColor:"rgba(0, 0, 0, 0.5)",display:"flex",justifyContent:"center",alignItems:"center",zIndex:"10000"});let p=document.createElement("div");Object.assign(p.style,{backgroundColor:"white",padding:"20px",borderRadius:"5px",maxWidth:"500px",width:"90%",maxHeight:"80%",overflow:"auto"});let h=document.createElement("h3");h.textContent="Sampling Request",Object.assign(h.style,{margin:"0 0 15px 0",padding:"0 0 10px 0",borderBottom:"1px solid #ddd"});let g=document.createElement("div");if(Object.assign(g.style,{marginBottom:"15px",maxHeight:"300px",overflow:"auto",border:"1px solid #ddd",padding:"10px",backgroundColor:"#f9f9f9"}),s&&s.length>0?s.forEach(c=>{let S=document.createElement("div");Object.assign(S.style,{marginBottom:"10px",padding:"5px",borderRadius:"3px",backgroundColor:c.role==="user"?"#e1f5fe":"#f1f8e9"});let x=document.createElement("strong");x.textContent=c.role==="user"?"User: ":"Assistant: ";let T=document.createElement("span");c.content.type==="text"?T.textContent=c.content.text:c.content.type==="image"&&(T.textContent="[Image data]"),S.appendChild(x),S.appendChild(T),g.appendChild(S)}):g.textContent="No messages provided in sampling request",o){let c=document.createElement("div");Object.assign(c.style,{marginBottom:"10px",padding:"5px",backgroundColor:"#fff8e1"});let S=document.createElement("strong");S.textContent="System Prompt: ";let x=document.createElement("span");x.textContent=o,c.appendChild(S),c.appendChild(x),g.appendChild(c)}let y=document.createElement("label");y.textContent="Assistant Response:",Object.assign(y.style,{display:"block",marginBottom:"5px",fontWeight:"bold"});let m=document.createElement("textarea");Object.assign(m.style,{width:"100%",minHeight:"100px",padding:"10px",marginBottom:"15px",boxSizing:"border-box"});let b=document.createElement("div");Object.assign(b.style,{display:"flex",justifyContent:"space-between"});let f=document.createElement("button");f.textContent="Submit Response",Object.assign(f.style,{padding:"8px 15px",backgroundColor:"#4CAF50",color:"white",border:"none",borderRadius:"4px",cursor:"pointer"});let C=document.createElement("button");C.textContent="Cancel",Object.assign(C.style,{padding:"8px 15px",backgroundColor:"#f44336",color:"white",border:"none",borderRadius:"4px",cursor:"pointer"}),b.appendChild(C),b.appendChild(f),p.appendChild(h),p.appendChild(g),p.appendChild(y),p.appendChild(m),p.appendChild(b),u.appendChild(p),document.body.appendChild(u),m.focus(),f.addEventListener("click",()=>{let c=m.value.trim();c?(this._sendMessage({id:t,type:"samplingResponse",result:{model:"web-user-input",role:"assistant",content:{type:"text",text:c}}}),document.body.removeChild(u)):alert("Please enter a response")}),C.addEventListener("click",()=>{this._sendMessage({id:t,type:"samplingResponse",error:"User cancelled sampling request"}),document.body.removeChild(u)})}};typeof module!="undefined"&&typeof module.exports!="undefined"&&(module.exports=R);})(); +//# sourceMappingURL=webmcp.js.map diff --git a/build/webmcp.js.map b/build/webmcp.js.map new file mode 100644 index 0000000..668e280 --- /dev/null +++ b/build/webmcp.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../src/webmcp.js"], + "sourcesContent": ["/**\n * WebMCP - Snippet to add MCP functionality to any website\n *\n * Shows as a small blue square in bottom right corner\n * On click, expands to allow connection with token\n * Auto-disconnects after 5 minutes of inactivity\n */\n\nclass WebMCP {\n constructor(options = {}) {\n // Options with defaults\n this.options = {\n color: '#007bff',\n position: 'bottom-right',\n size: '30px',\n padding: '20px',\n inactivityTimeout: 5 * 60 * 1000, // 5 minutes in milliseconds\n ...options\n };\n\n // State variables\n this.isConnected = false;\n this.isExpanded = false;\n this.socket = null;\n this.inactivityTimer = null;\n this.availableTools = new Map();\n this.availablePrompts = new Map();\n this.availableResources = new Map();\n this.samplingCallbacks = new Map(); // For storing sampling callbacks\n this.currentToken = '';\n this.currentServer = '';\n this.currentChannel = '';\n this.elementId = 'webmcp-widget-' + Math.random().toString(36).substr(2, 9);\n this.registeredTools = new Set();\n this.registeredPrompts = new Set();\n this.registeredResources = new Set();\n\n // Storage keys for sessionStorage\n this.SESSION_STORAGE_KEY = 'webmcp_token';\n this.TOOLS_STORAGE_KEY = 'webmcp_tools';\n this.PROMPTS_STORAGE_KEY = 'webmcp_prompts';\n this.RESOURCES_STORAGE_KEY = 'webmcp_resources';\n\n // Constants\n this.REGISTER_PATH = '/register';\n\n // Initialize\n this._init();\n }\n\n _format(s) {\n return s.replace(/[.:]/g, '_');\n }\n\n /**\n * Initialize the WebMCP widget\n * @private\n */\n _init() {\n // Check if already initialized on this page\n if (document.querySelector('[data-webmcp-widget]')) {\n console.warn('WebMCP widget already initialized on this page');\n return;\n }\n\n // Create and inject the widget\n this._createWidget();\n\n // Set up event listeners\n this._setupEventListeners();\n\n // Start inactivity timer\n this._resetInactivityTimer();\n\n // Check for stored token and connect if available\n this._checkStoredToken();\n }\n\n /**\n * Check for stored connection info in sessionStorage and connect if found\n * @private\n */\n _checkStoredToken() {\n const storedConnectionInfo = sessionStorage.getItem(this.SESSION_STORAGE_KEY);\n\n if (storedConnectionInfo) {\n try {\n const connectionInfo = JSON.parse(storedConnectionInfo);\n if (connectionInfo.token) {\n console.log('Found stored connection info, attempting to connect');\n\n // Set the connection properties directly\n this.currentServer = connectionInfo.server;\n this.currentChannel = `/${connectionInfo.channelHost || this._format(window.location.host)}`;\n\n // Set the current token from connection info\n if (connectionInfo.token.includes('{')) {\n // It's already parsed JSON\n const tokenData = JSON.parse(connectionInfo.token);\n this.currentToken = tokenData.token;\n } else {\n // It's a base64 encoded string\n try {\n const jsonStr = atob(connectionInfo.token);\n const tokenData = JSON.parse(jsonStr);\n this.currentToken = tokenData.token;\n } catch (e) {\n this.currentToken = connectionInfo.token;\n }\n }\n\n // Load stored items before connecting\n this._loadStoredItems();\n\n // Connect using the stored token\n this.connect(connectionInfo.token);\n }\n } catch (error) {\n console.error('Error parsing stored connection info:', error);\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n this._clearStoredItems();\n }\n }\n }\n\n /**\n * Save tools, prompts, and resources to session storage\n * @private\n */\n _saveItemsToStorage() {\n try {\n // Save tools\n const toolsData = {};\n this.availableTools.forEach((tool, name) => {\n toolsData[name] = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n // We don't store the execution function as it can't be serialized\n };\n });\n sessionStorage.setItem(this.TOOLS_STORAGE_KEY, JSON.stringify(toolsData));\n\n // Save prompts\n const promptsData = {};\n this.availablePrompts.forEach((prompt, name) => {\n promptsData[name] = {\n name: prompt.name,\n description: prompt.description,\n arguments: prompt.arguments,\n // We don't store the execution function as it can't be serialized\n };\n });\n sessionStorage.setItem(this.PROMPTS_STORAGE_KEY, JSON.stringify(promptsData));\n\n // Save resources\n const resourcesData = {};\n this.availableResources.forEach((resource, name) => {\n resourcesData[name] = {\n name: resource.name,\n description: resource.description,\n uri: resource.uri,\n uriTemplate: resource.uriTemplate,\n isTemplate: resource.isTemplate,\n mimeType: resource.mimeType,\n // We don't store the provide function as it can't be serialized\n };\n });\n sessionStorage.setItem(this.RESOURCES_STORAGE_KEY, JSON.stringify(resourcesData));\n\n console.log('Saved items to session storage:', {\n tools: Object.keys(toolsData).length,\n prompts: Object.keys(promptsData).length,\n resources: Object.keys(resourcesData).length\n });\n } catch (error) {\n console.error('Error saving items to session storage:', error);\n }\n }\n\n /**\n * Load tools, prompts, and resources from session storage\n * @private\n */\n _loadStoredItems() {\n try {\n // Load tools\n const storedTools = sessionStorage.getItem(this.TOOLS_STORAGE_KEY);\n if (storedTools) {\n const toolsData = JSON.parse(storedTools);\n Object.entries(toolsData).forEach(([name, tool]) => {\n // Add to the available tools with placeholder execute function\n this.availableTools.set(name, {\n ...tool,\n execute: function (args) {\n console.warn(`Tool ${name} was loaded from storage but has not been re-registered with an execution function`);\n return `Tool ${name} needs to be re-registered`;\n }\n });\n });\n }\n\n // Load prompts\n const storedPrompts = sessionStorage.getItem(this.PROMPTS_STORAGE_KEY);\n if (storedPrompts) {\n const promptsData = JSON.parse(storedPrompts);\n Object.entries(promptsData).forEach(([name, prompt]) => {\n // Add to the available prompts with placeholder execute function\n this.availablePrompts.set(name, {\n ...prompt,\n execute: function (args) {\n console.warn(`Prompt ${name} was loaded from storage but has not been re-registered with an execution function`);\n return {\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Prompt ${name} needs to be re-registered`\n }\n }]\n };\n }\n });\n });\n }\n\n // Load resources\n const storedResources = sessionStorage.getItem(this.RESOURCES_STORAGE_KEY);\n if (storedResources) {\n const resourcesData = JSON.parse(storedResources);\n Object.entries(resourcesData).forEach(([name, resource]) => {\n // Add to the available resources with placeholder provide function\n this.availableResources.set(name, {\n ...resource,\n provide: function (uri) {\n console.warn(`Resource ${name} was loaded from storage but has not been re-registered with a provider function`);\n return {\n contents: [{\n uri: uri,\n text: `Resource ${name} needs to be re-registered`,\n mimeType: resource.mimeType || \"text/plain\"\n }]\n };\n }\n });\n });\n }\n\n console.log('Loaded items from session storage:', {\n tools: this.availableTools.size,\n prompts: this.availablePrompts.size,\n resources: this.availableResources.size\n });\n\n // Update the UI\n this._updateToolsList();\n this._updatePromptsList();\n this._updateResourcesList();\n\n } catch (error) {\n console.error('Error loading items from session storage:', error);\n this._clearStoredItems();\n }\n }\n\n /**\n * Clear all stored items from session storage\n * @private\n */\n _clearStoredItems() {\n sessionStorage.removeItem(this.TOOLS_STORAGE_KEY);\n sessionStorage.removeItem(this.PROMPTS_STORAGE_KEY);\n sessionStorage.removeItem(this.RESOURCES_STORAGE_KEY);\n console.log('Cleared stored items from session storage');\n }\n\n /**\n * Create and inject the WebMCP widget into the DOM\n * @private\n */\n _createWidget() {\n // Create main container\n const container = document.createElement('div');\n container.id = this.elementId;\n container.dataset.webmcpWidget = true;\n\n // Apply styles\n Object.assign(container.style, {\n position: 'fixed',\n zIndex: '9999',\n display: 'flex',\n flexDirection: 'column',\n fontFamily: 'Arial, sans-serif',\n fontSize: '14px',\n transition: 'all 0.3s ease'\n });\n\n // Set position based on option\n this._setWidgetPosition(container);\n\n // Create trigger button (blue square)\n const triggerButton = document.createElement('div');\n triggerButton.className = 'webmcp-trigger';\n Object.assign(triggerButton.style, {\n width: this.options.size,\n height: this.options.size,\n backgroundColor: this.options.color,\n borderRadius: '4px',\n cursor: 'pointer',\n boxShadow: '0 2px 10px rgba(0,0,0,0.2)',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n alignSelf: 'flex-end'\n });\n\n // Create content panel (initially hidden) - positioned above the trigger\n const contentPanel = document.createElement('div');\n contentPanel.className = 'webmcp-content';\n Object.assign(contentPanel.style, {\n backgroundColor: '#ffffff',\n border: '1px solid #e1e1e1',\n borderRadius: '5px',\n padding: '15px',\n marginBottom: '10px',\n boxShadow: '0 5px 15px rgba(0,0,0,0.1)',\n width: '250px',\n display: 'none',\n overflow: 'hidden',\n position: 'absolute',\n bottom: '40px'\n });\n\n // Add header with title and close button\n const header = document.createElement('div');\n Object.assign(header.style, {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: '15px'\n });\n\n const title = document.createElement('div');\n title.textContent = 'WebMCP';\n Object.assign(title.style, {\n fontWeight: 'bold',\n fontSize: '16px'\n });\n\n const closeButton = document.createElement('button');\n closeButton.innerHTML = '×'; // \u00D7 symbol\n closeButton.className = 'webmcp-close';\n Object.assign(closeButton.style, {\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '20px',\n padding: '0',\n lineHeight: '1',\n color: '#999'\n });\n\n header.appendChild(title);\n header.appendChild(closeButton);\n contentPanel.appendChild(header);\n\n // Add connection form\n this._createConnectionForm(contentPanel);\n\n // Add status indicator\n const statusIndicator = document.createElement('div');\n statusIndicator.className = 'webmcp-status';\n statusIndicator.textContent = 'Disconnected';\n Object.assign(statusIndicator.style, {\n padding: '8px',\n borderRadius: '3px',\n backgroundColor: '#f8d7da',\n color: '#721c24',\n textAlign: 'center',\n marginBottom: '10px',\n fontSize: '12px'\n });\n contentPanel.appendChild(statusIndicator);\n\n // Add connection panel\n const connectionPanel = document.createElement('div');\n connectionPanel.className = 'webmcp-connection-panel';\n contentPanel.appendChild(connectionPanel);\n\n // Create a single container for all registered items\n const registeredItemsContainer = document.createElement('div');\n registeredItemsContainer.className = 'webmcp-registered-items';\n Object.assign(registeredItemsContainer.style, {\n marginTop: '15px',\n fontSize: '12px',\n display: 'none',\n maxHeight: '200px',\n overflow: 'auto',\n border: '1px solid #eee',\n borderRadius: '4px'\n });\n contentPanel.appendChild(registeredItemsContainer);\n\n // Add features lists (initially empty)\n // Tools list\n const toolsList = document.createElement('div');\n toolsList.className = 'webmcp-tools-list';\n Object.assign(toolsList.style, {\n padding: '10px',\n borderBottom: '1px solid #eee'\n });\n\n const toolsHeader = document.createElement('div');\n toolsHeader.textContent = 'Registered Tools:';\n Object.assign(toolsHeader.style, {\n fontWeight: 'bold',\n marginBottom: '5px'\n });\n\n const toolsContainer = document.createElement('ul');\n toolsContainer.className = 'webmcp-tools-container';\n Object.assign(toolsContainer.style, {\n listStyle: 'none',\n padding: '0',\n margin: '0'\n });\n\n toolsList.appendChild(toolsHeader);\n toolsList.appendChild(toolsContainer);\n registeredItemsContainer.appendChild(toolsList);\n\n // Prompts list\n const promptsList = document.createElement('div');\n promptsList.className = 'webmcp-prompts-list';\n Object.assign(promptsList.style, {\n padding: '10px',\n borderBottom: '1px solid #eee'\n });\n\n const promptsHeader = document.createElement('div');\n promptsHeader.textContent = 'Registered Prompts:';\n Object.assign(promptsHeader.style, {\n fontWeight: 'bold',\n marginBottom: '5px'\n });\n\n const promptsContainer = document.createElement('ul');\n promptsContainer.className = 'webmcp-prompts-container';\n Object.assign(promptsContainer.style, {\n listStyle: 'none',\n padding: '0',\n margin: '0'\n });\n\n promptsList.appendChild(promptsHeader);\n promptsList.appendChild(promptsContainer);\n registeredItemsContainer.appendChild(promptsList);\n\n // Resources list\n const resourcesList = document.createElement('div');\n resourcesList.className = 'webmcp-resources-list';\n Object.assign(resourcesList.style, {\n padding: '10px'\n });\n\n const resourcesHeader = document.createElement('div');\n resourcesHeader.textContent = 'Registered Resources:';\n Object.assign(resourcesHeader.style, {\n fontWeight: 'bold',\n marginBottom: '5px'\n });\n\n const resourcesContainer = document.createElement('ul');\n resourcesContainer.className = 'webmcp-resources-container';\n Object.assign(resourcesContainer.style, {\n listStyle: 'none',\n padding: '0',\n margin: '0'\n });\n\n resourcesList.appendChild(resourcesHeader);\n resourcesList.appendChild(resourcesContainer);\n registeredItemsContainer.appendChild(resourcesList);\n\n // Add to main container and then to document - content panel first so it appears above trigger\n container.appendChild(contentPanel);\n container.appendChild(triggerButton);\n document.body.appendChild(container);\n }\n\n /**\n * Set widget position based on option\n * @private\n */\n _setWidgetPosition(container) {\n const {position, padding} = this.options;\n\n switch (position) {\n case 'bottom-right':\n Object.assign(container.style, {\n bottom: padding,\n right: padding,\n alignItems: 'flex-end'\n });\n break;\n case 'bottom-left':\n Object.assign(container.style, {\n bottom: padding,\n left: padding,\n alignItems: 'flex-start'\n });\n break;\n case 'top-right':\n Object.assign(container.style, {\n top: padding,\n right: padding,\n alignItems: 'flex-end'\n });\n break;\n case 'top-left':\n Object.assign(container.style, {\n top: padding,\n left: padding,\n alignItems: 'flex-start'\n });\n break;\n default:\n // Default to bottom-right\n Object.assign(container.style, {\n bottom: padding,\n right: padding,\n alignItems: 'flex-end'\n });\n }\n }\n\n /**\n * Create the connection form\n * @private\n */\n _createConnectionForm(container) {\n const form = document.createElement('div');\n Object.assign(form.style, {\n marginBottom: '8px',\n });\n\n // Token input field\n const inputGroup = document.createElement('div');\n Object.assign(inputGroup.style, {\n display: 'flex',\n marginBottom: '8px',\n });\n\n const tokenInput = document.createElement('input');\n tokenInput.type = 'text';\n tokenInput.className = 'webmcp-token-input';\n tokenInput.placeholder = 'Paste connection token';\n Object.assign(tokenInput.style, {\n flex: '1',\n padding: '8px',\n border: '1px solid #ccc',\n borderRadius: '4px 0 0 4px',\n fontSize: '12px'\n });\n\n const connectButton = document.createElement('button');\n connectButton.className = 'webmcp-connect-btn';\n connectButton.textContent = 'Connect';\n Object.assign(connectButton.style, {\n padding: '8px 12px',\n backgroundColor: this.options.color,\n color: 'white',\n border: 'none',\n borderRadius: '0 4px 4px 0',\n cursor: 'pointer',\n fontSize: '12px'\n });\n\n inputGroup.appendChild(tokenInput);\n inputGroup.appendChild(connectButton);\n\n const disconnectButton = document.createElement('button');\n disconnectButton.className = 'webmcp-disconnect-btn';\n disconnectButton.textContent = 'Disconnect';\n Object.assign(disconnectButton.style, {\n padding: '8px 12px',\n backgroundColor: '#dc3545',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontSize: '12px',\n width: '100%',\n display: 'none'\n });\n\n form.appendChild(inputGroup);\n form.appendChild(disconnectButton);\n container.appendChild(form);\n }\n\n /**\n * Set up event listeners for the widget\n * @private\n */\n _setupEventListeners() {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n // Trigger button click - expand/collapse\n const trigger = container.querySelector('.webmcp-trigger');\n trigger.addEventListener('click', () => {\n this._toggleExpanded();\n });\n\n // Close button click - collapse\n const closeBtn = container.querySelector('.webmcp-close');\n closeBtn.addEventListener('click', () => {\n this._toggleExpanded(false);\n });\n\n // Connect button click\n const connectBtn = container.querySelector('.webmcp-connect-btn');\n connectBtn.addEventListener('click', () => {\n const tokenInput = container.querySelector('.webmcp-token-input');\n this.connect(tokenInput.value);\n });\n\n // Disconnect button click\n const disconnectBtn = container.querySelector('.webmcp-disconnect-btn');\n disconnectBtn.addEventListener('click', () => {\n this.disconnect();\n });\n\n // User activity detection to reset inactivity timer\n document.addEventListener('mousemove', () => this._resetInactivityTimer());\n document.addEventListener('keypress', () => this._resetInactivityTimer());\n document.addEventListener('click', () => this._resetInactivityTimer());\n document.addEventListener('scroll', () => this._resetInactivityTimer());\n }\n\n /**\n * Toggle the expanded state of the widget\n * @private\n */\n _toggleExpanded(force = null) {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n const contentPanel = container.querySelector('.webmcp-content');\n this.isExpanded = force !== null ? force : !this.isExpanded;\n\n if (this.isExpanded) {\n contentPanel.style.display = 'block';\n } else {\n contentPanel.style.display = 'none';\n }\n\n this._resetInactivityTimer();\n }\n\n /**\n * Update the status indicator\n * @private\n */\n _updateStatus(status, message) {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n const statusIndicator = container.querySelector('.webmcp-status');\n if (!statusIndicator) return;\n\n // Clear existing classes\n statusIndicator.classList.remove('connected', 'disconnected', 'connecting', 'pending-auth');\n\n // Set new status\n statusIndicator.textContent = message || status;\n\n // Apply styling based on status\n switch (status) {\n case 'connected':\n Object.assign(statusIndicator.style, {\n backgroundColor: '#d4edda',\n color: '#155724'\n });\n break;\n case 'disconnected':\n Object.assign(statusIndicator.style, {\n backgroundColor: '#f8d7da',\n color: '#721c24'\n });\n break;\n case 'connecting':\n Object.assign(statusIndicator.style, {\n backgroundColor: '#fff3cd',\n color: '#856404'\n });\n break;\n case 'pending-auth':\n Object.assign(statusIndicator.style, {\n backgroundColor: '#d1ecf1',\n color: '#0c5460'\n });\n break;\n }\n }\n\n /**\n * Update UI based on connection state\n * @private\n */\n _updateConnectionUI(isConnected) {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n const tokenInput = container.querySelector('.webmcp-token-input');\n const connectBtn = container.querySelector('.webmcp-connect-btn');\n const disconnectBtn = container.querySelector('.webmcp-disconnect-btn');\n const registeredItemsContainer = container.querySelector('.webmcp-registered-items');\n\n if (isConnected) {\n tokenInput.style.display = 'none';\n connectBtn.style.display = 'none';\n disconnectBtn.style.display = 'block';\n registeredItemsContainer.style.display = 'block';\n\n // Update the trigger button to show connected state\n const trigger = container.querySelector('.webmcp-trigger');\n trigger.innerHTML = '\u2713';\n trigger.style.color = 'white';\n trigger.style.fontWeight = 'bold';\n } else {\n tokenInput.style.display = 'block';\n connectBtn.style.display = 'block';\n disconnectBtn.style.display = 'none';\n registeredItemsContainer.style.display = 'none';\n\n // Reset the trigger button\n const trigger = container.querySelector('.webmcp-trigger');\n trigger.innerHTML = '';\n }\n }\n\n /**\n * Update tools list in UI\n * @private\n */\n _updateToolsList() {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n const toolsContainer = container.querySelector('.webmcp-tools-container');\n if (!toolsContainer) return;\n\n // Clear current list\n toolsContainer.innerHTML = '';\n\n if (this.availableTools.size === 0) {\n const emptyMessage = document.createElement('li');\n emptyMessage.textContent = 'No tools registered';\n emptyMessage.style.fontStyle = 'italic';\n emptyMessage.style.color = '#666';\n toolsContainer.appendChild(emptyMessage);\n return;\n }\n\n // Add each tool to the list\n this.availableTools.forEach((tool, name) => {\n const toolItem = document.createElement('li');\n Object.assign(toolItem.style, {\n padding: '5px 0',\n borderBottom: '1px solid #eee'\n });\n\n const toolName = document.createElement('strong');\n toolName.textContent = name;\n\n const toolDesc = document.createElement('div');\n toolDesc.textContent = tool.description;\n toolDesc.style.fontSize = '10px';\n toolDesc.style.color = '#666';\n\n toolItem.appendChild(toolName);\n toolItem.appendChild(toolDesc);\n toolsContainer.appendChild(toolItem);\n });\n }\n\n /**\n * Update prompts list in UI\n * @private\n */\n _updatePromptsList() {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n const promptsContainer = container.querySelector('.webmcp-prompts-container');\n if (!promptsContainer) return;\n\n // Clear current list\n promptsContainer.innerHTML = '';\n\n if (this.availablePrompts.size === 0) {\n const emptyMessage = document.createElement('li');\n emptyMessage.textContent = 'No prompts registered';\n emptyMessage.style.fontStyle = 'italic';\n emptyMessage.style.color = '#666';\n promptsContainer.appendChild(emptyMessage);\n return;\n }\n\n // Add each prompt to the list\n this.availablePrompts.forEach((prompt, name) => {\n const promptItem = document.createElement('li');\n Object.assign(promptItem.style, {\n padding: '5px 0',\n borderBottom: '1px solid #eee'\n });\n\n const promptName = document.createElement('strong');\n promptName.textContent = name;\n\n const promptDesc = document.createElement('div');\n promptDesc.textContent = prompt.description;\n promptDesc.style.fontSize = '10px';\n promptDesc.style.color = '#666';\n\n promptItem.appendChild(promptName);\n promptItem.appendChild(promptDesc);\n promptsContainer.appendChild(promptItem);\n });\n }\n\n /**\n * Update resources list in UI\n * @private\n */\n _updateResourcesList() {\n const container = document.getElementById(this.elementId);\n if (!container) return;\n\n const resourcesContainer = container.querySelector('.webmcp-resources-container');\n if (!resourcesContainer) return;\n\n // Clear current list\n resourcesContainer.innerHTML = '';\n\n if (this.availableResources.size === 0) {\n const emptyMessage = document.createElement('li');\n emptyMessage.textContent = 'No resources registered';\n emptyMessage.style.fontStyle = 'italic';\n emptyMessage.style.color = '#666';\n resourcesContainer.appendChild(emptyMessage);\n return;\n }\n\n // Add each resource to the list\n this.availableResources.forEach((resource, name) => {\n const resourceItem = document.createElement('li');\n Object.assign(resourceItem.style, {\n padding: '5px 0',\n borderBottom: '1px solid #eee'\n });\n\n const resourceName = document.createElement('strong');\n resourceName.textContent = name;\n\n const resourceDesc = document.createElement('div');\n resourceDesc.textContent = resource.description +\n (resource.isTemplate ? ' (Template)' : '');\n resourceDesc.style.fontSize = '10px';\n resourceDesc.style.color = '#666';\n\n resourceItem.appendChild(resourceName);\n resourceItem.appendChild(resourceDesc);\n resourcesContainer.appendChild(resourceItem);\n });\n }\n\n /**\n * Reset the inactivity timer\n * @private\n */\n _resetInactivityTimer() {\n // Clear existing timer\n if (this.inactivityTimer) {\n clearTimeout(this.inactivityTimer);\n }\n\n // Set new timer\n this.inactivityTimer = setTimeout(() => {\n this._handleInactivity();\n }, this.options.inactivityTimeout);\n }\n\n /**\n * Handle user inactivity\n * @private\n */\n _handleInactivity() {\n console.log('Inactivity timeout reached, disconnecting');\n\n // Disconnect if connected\n if (this.isConnected) {\n this.disconnect();\n }\n\n // Minimize UI\n this._toggleExpanded(false);\n\n // Clear the stored token\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n }\n\n\n /**\n * Connect to the WebSocket server\n * @public\n * @param {string} connectionToken - The encoded connection token\n */\n async connect(connectionToken) {\n if (!connectionToken) {\n this._updateStatus('disconnected', 'Error: No token provided');\n return;\n }\n\n // Update UI to show connecting state\n this._updateStatus('connecting', 'Connecting...');\n\n try {\n // Process the connection token\n if (!this._processConnectionToken(connectionToken)) {\n return;\n }\n\n // Store the connection info in sessionStorage for page navigations\n const connectionInfo = {\n token: connectionToken,\n server: this.currentServer,\n host: this._format(window.location.host)\n };\n\n // Check if we have connection data already in sessionStorage\n const storedConnectionInfo = sessionStorage.getItem(this.SESSION_STORAGE_KEY);\n let skipRegistration = false;\n\n if (storedConnectionInfo) {\n try {\n const connectionInfo = JSON.parse(storedConnectionInfo);\n // If we already have a valid token and server, we can skip registration\n if (connectionInfo.server === this.currentServer &&\n connectionInfo.host === this._format(window.location.host)) {\n skipRegistration = true;\n }\n } catch (error) {\n console.error('Error parsing stored connection info:', error);\n }\n }\n\n if (!skipRegistration) {\n // First register with server\n const response = await this._registerWithServer(connectionToken);\n\n if (!response.token) {\n this._updateStatus('disconnected', 'Registration failed');\n return;\n }\n\n // Save the new token\n connectionInfo.token = response.token;\n this.currentToken = response.token;\n\n sessionStorage.setItem(this.SESSION_STORAGE_KEY, JSON.stringify(connectionInfo));\n }\n\n // Now connect to the actual channel\n const serverUrl = `${this.currentServer}${this.currentChannel}?token=${this.currentToken}`;\n\n // Update UI\n this._updateStatus('connecting', 'Connecting to channel...');\n\n // Create WebSocket connection with the path and token\n this.socket = new WebSocket(serverUrl);\n\n // Set up socket event listeners\n this._setupSocketListeners();\n\n // Reset inactivity timer\n this._resetInactivityTimer();\n\n } catch (error) {\n console.error('Connection error:', error);\n this._updateStatus('disconnected', `Error: ${error.message}`);\n }\n }\n\n /**\n * Disconnect from WebSocket server\n * @public\n */\n disconnect() {\n // Close the WebSocket connection if it exists\n if (this.socket) {\n this.socket.close();\n this.socket = null;\n }\n\n this.isConnected = false;\n this._updateStatus('disconnected', 'Disconnected');\n this._updateConnectionUI(false);\n\n // Reset state\n this.currentToken = '';\n this.currentServer = '';\n this.currentChannel = '';\n\n // Remove the token from sessionStorage\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n\n // Clear items from sessionStorage\n this._clearStoredItems();\n }\n\n /**\n * Process connection token\n * @private\n * @param {string} encodedToken - The encoded connection token\n * @returns {boolean} - True if processing was successful\n */\n _processConnectionToken(encodedToken) {\n try {\n // Decode the base64 token\n const jsonStr = atob(encodedToken);\n const connectionData = JSON.parse(jsonStr);\n\n // Extract server and token\n const {server, token} = connectionData;\n\n if (!server || !token) {\n this._updateStatus('disconnected', 'Invalid token');\n return false;\n }\n\n // Store connection info\n this.currentServer = server;\n this.currentToken = token;\n\n // Format channel based on hostname\n this.currentChannel = `/${this._format(window.location.host)}`;\n\n return true;\n } catch (error) {\n this._updateStatus('disconnected', `Unable to parse token`);\n return false;\n }\n }\n\n /**\n * Register with server using connection token\n * @private\n * @param {string} encodedToken - The encoded connection token\n * @returns {Promise<{ token: string }>} - Resolves to true if registration was successful\n */\n _registerWithServer(encodedToken) {\n // Update UI\n this._updateStatus('pending-auth', 'Registering...');\n\n // Connect to the registration endpoint\n const regSocket = new WebSocket(`${this.currentServer}${this.REGISTER_PATH}`);\n\n return new Promise((resolve, reject) => {\n // Connection opened - send the token\n regSocket.addEventListener('open', (event) => {\n console.log('Registration connection established');\n\n // Send the original encoded token back to the server\n const jsonStr = atob(encodedToken);\n const connectionData = JSON.parse(jsonStr);\n connectionData.host = this._format(window.location.host);\n regSocket.send(btoa(JSON.stringify(connectionData)));\n });\n\n // Listen for registration response\n regSocket.addEventListener('message', (event) => {\n try {\n const message = JSON.parse(event.data);\n\n if (message.type === 'registerSuccess' && message.token) {\n console.log(`Registration successful: ${message.message}`);\n\n // Registration complete, can now connect to channel\n resolve({ token: message.token });\n } else if (message.type === 'error') {\n console.error(`Registration failed: ${message.message}`);\n this._updateStatus('disconnected', `Registration failed: ${message.message}`);\n reject(new Error(message.message));\n }\n } catch (error) {\n console.error(`Error parsing registration response: ${error.message}`);\n this._updateStatus('disconnected', 'Error parsing server response');\n reject(error);\n }\n });\n\n // Handle registration errors\n regSocket.addEventListener('error', (event) => {\n console.error('Registration connection error');\n this._updateStatus('disconnected', 'Registration connection error');\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n reject(new Error('Connection error'));\n });\n\n // Handle registration connection close\n regSocket.addEventListener('close', (event) => {\n console.log(`Registration connection closed: ${event.code} ${event.reason}`);\n\n if (event.code !== 1000) {\n // If it wasn't a normal closure, show an error\n this._updateStatus('disconnected', 'Registration failed');\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n reject(new Error('Connection closed'));\n }\n });\n });\n }\n\n /**\n * Set up WebSocket event listeners for direct connection\n * @private\n */\n _setupSocketListeners() {\n if (!this.socket) {\n console.error('Cannot set up socket listeners: WebSocket not available');\n return;\n }\n\n // Set up socket open handler\n this.socket.addEventListener('open', () => {\n this.isConnected = true;\n this._updateStatus('connected', `Connected to ${this.currentChannel}`);\n this._updateConnectionUI(true);\n console.log('WebMCP connection established');\n this._registerItemsWithServer();\n });\n\n // Set up socket close handler\n this.socket.addEventListener('close', (event) => {\n this.isConnected = false;\n this._updateStatus('disconnected', 'Disconnected');\n this._updateConnectionUI(false);\n console.log(`Connection closed: ${event.code} ${event.reason}`);\n\n // Check if it was an authorization error\n if (event.code === 1001 || event.code === 401) {\n this._updateStatus('disconnected', 'Authorization failed');\n this.currentToken = '';\n this.currentServer = '';\n this.currentChannel = '';\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n }\n });\n\n // Set up socket error handler\n this.socket.addEventListener('error', () => {\n console.error('WebSocket error');\n\n if (this.isConnected) {\n this._updateStatus('disconnected', 'Connection error occurred');\n } else {\n this._updateStatus('disconnected', 'Connection failed');\n }\n\n sessionStorage.removeItem(this.SESSION_STORAGE_KEY);\n });\n\n // Set up socket message handler\n this.socket.addEventListener('message', (event) => {\n try {\n const message = JSON.parse(event.data);\n this._handleServerMessage(message);\n } catch (error) {\n console.error(`Error parsing message: ${error.message}`);\n }\n });\n }\n\n /**\n * Handle messages from the server\n * @private\n * @param {Object} message - The parsed message object\n */\n _handleServerMessage(message) {\n switch (message.type) {\n case 'welcome':\n console.log(`Server says: ${message.message}`);\n break;\n\n case 'toolRegistered':\n console.log(`Tool registered with server: ${message.name}`);\n break;\n\n case 'promptRegistered':\n console.log(`Prompt registered with server: ${message.name}`);\n break;\n\n case 'resourceRegistered':\n console.log(`Resource registered with server: ${message.name}`);\n break;\n\n case 'callTool':\n // Server is asking us to execute a tool\n this._handleToolCall(message);\n break;\n\n case 'getPrompt':\n // Server is asking us to provide a prompt\n this._handleGetPrompt(message);\n break;\n\n case 'readResource':\n // Server is asking us to provide a resource\n this._handleReadResource(message);\n break;\n\n case 'createSamplingMessage':\n // Server is asking us to create a sampling message\n this._handleCreateSamplingMessage(message);\n break;\n\n case 'listTools':\n // Server is asking for available tools\n this._sendToolsList(message.id);\n break;\n\n case 'listPrompts':\n // Server is asking for available prompts\n this._sendPromptsList(message.id);\n break;\n\n case 'listResources':\n // Server is asking for available resources\n this._sendResourcesList(message.id);\n break;\n\n case 'ping':\n // Respond to ping\n this._sendMessage({\n type: 'pong',\n id: message.id,\n timestamp: Date.now()\n });\n break;\n\n case 'error':\n console.error(`Server error: ${message.message}`);\n break;\n\n default:\n console.warn(`Unknown message type: ${message.type}`);\n }\n }\n\n /**\n * Handle tool call from server\n * @private\n * @param {Object} message - The parsed message object\n */\n _handleToolCall(message) {\n const {id, tool, arguments: args} = message;\n\n console.log(`Tool call: ${tool} with args:`, args);\n\n if (!this.availableTools.has(tool)) {\n this._sendMessage({\n id,\n type: 'toolResponse',\n error: `Tool not found: ${tool}`\n });\n return;\n }\n\n // Execute the tool\n try {\n const toolObj = this.availableTools.get(tool);\n\n // Call the tool's execute function\n const result = toolObj.execute(args);\n\n // Handle promises\n if (result instanceof Promise) {\n result\n .then(resolvedResult => {\n this._sendMessage({\n id,\n type: 'toolResponse',\n result: resolvedResult\n });\n })\n .catch(error => {\n this._sendMessage({\n id,\n type: 'toolResponse',\n error: error.message || 'Tool execution error'\n });\n });\n } else {\n // Send immediate result\n this._sendMessage({\n id,\n type: 'toolResponse',\n result\n });\n }\n\n console.log(`Tool response sent for ${tool}`);\n } catch (error) {\n this._sendMessage({\n id,\n type: 'toolResponse',\n error: error.message || 'Tool execution error'\n });\n console.error(`Tool execution error:`, error);\n }\n }\n\n /**\n * Handle prompt request from server\n * @private\n * @param {Object} message - The parsed message object\n */\n _handleGetPrompt(message) {\n const {id, name, arguments: args} = message;\n\n console.log(`Prompt request: ${name} with args:`, args);\n\n if (!this.availablePrompts.has(name)) {\n this._sendMessage({\n id,\n type: 'promptResponse',\n error: `Prompt not found: ${name}`\n });\n return;\n }\n\n // Execute the prompt\n try {\n const promptObj = this.availablePrompts.get(name);\n\n // Call the prompt's execute function\n const result = promptObj.execute(args);\n\n // Handle promises\n if (result instanceof Promise) {\n result\n .then(resolvedResult => {\n this._sendMessage({\n id,\n type: 'promptResponse',\n result: resolvedResult\n });\n })\n .catch(error => {\n this._sendMessage({\n id,\n type: 'promptResponse',\n error: error.message || 'Prompt execution error'\n });\n });\n } else {\n // Send immediate result\n this._sendMessage({\n id,\n type: 'promptResponse',\n result\n });\n }\n\n console.log(`Prompt response sent for ${name}`);\n } catch (error) {\n this._sendMessage({\n id,\n type: 'promptResponse',\n error: error.message || 'Prompt execution error'\n });\n console.error(`Prompt execution error:`, error);\n }\n }\n\n /**\n * Handle resource request from server\n * @private\n * @param {Object} message - The parsed message object\n */\n _handleReadResource(message) {\n const {id, uri} = message;\n\n console.log(`Resource request: ${uri}`);\n\n // Find resource that handles this URI\n let resourceObj = null;\n\n // First check for direct URI match\n for (const resource of this.availableResources.values()) {\n if (!resource.isTemplate && resource.uri === uri) {\n resourceObj = resource;\n break;\n }\n }\n\n // If no direct match, check for template match\n if (!resourceObj) {\n for (const resource of this.availableResources.values()) {\n if (resource.isTemplate) {\n // Simple check - if URI starts with template prefix (before any parameters)\n const templatePrefix = resource.uriTemplate.split('{')[0];\n if (uri.startsWith(templatePrefix)) {\n resourceObj = resource;\n break;\n }\n }\n }\n }\n\n if (!resourceObj) {\n this._sendMessage({\n id,\n type: 'resourceResponse',\n error: `No resource handler found for URI: ${uri}`\n });\n return;\n }\n\n // Execute the resource provider\n try {\n // Call the resource's provide function\n const result = resourceObj.provide(uri);\n\n // Handle promises\n if (result instanceof Promise) {\n result\n .then(resolvedResult => {\n this._sendMessage({\n id,\n type: 'resourceResponse',\n result: resolvedResult\n });\n })\n .catch(error => {\n this._sendMessage({\n id,\n type: 'resourceResponse',\n error: error.message || 'Resource read error'\n });\n });\n } else {\n // Send immediate result\n this._sendMessage({\n id,\n type: 'resourceResponse',\n result\n });\n }\n\n console.log(`Resource response sent for ${uri}`);\n } catch (error) {\n this._sendMessage({\n id,\n type: 'resourceResponse',\n error: error.message || 'Resource read error'\n });\n console.error(`Resource read error:`, error);\n }\n }\n\n /**\n * Send available tools list\n * @private\n * @param {string} requestId - The request ID to respond to\n */\n _sendToolsList(requestId) {\n const toolsList = Array.from(this.availableTools.values()).map(tool => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }));\n\n this._sendMessage({\n id: requestId,\n type: 'listToolsResponse',\n tools: toolsList\n });\n\n console.log(`Sent tools list: ${toolsList.length} tools`);\n }\n\n /**\n * Send available prompts list\n * @private\n * @param {string} requestId - The request ID to respond to\n */\n _sendPromptsList(requestId) {\n const promptsList = Array.from(this.availablePrompts.values()).map(prompt => ({\n name: prompt.name,\n description: prompt.description,\n arguments: prompt.arguments,\n }));\n\n this._sendMessage({\n id: requestId,\n type: 'listPromptsResponse',\n prompts: promptsList\n });\n\n console.log(`Sent prompts list: ${promptsList.length} prompts`);\n }\n\n /**\n * Send available resources list\n * @private\n * @param {string} requestId - The request ID to respond to\n */\n _sendResourcesList(requestId) {\n const resources = [];\n const resourceTemplates = [];\n\n // Split resources and templates\n this.availableResources.forEach((resource) => {\n if (resource.isTemplate) {\n resourceTemplates.push({\n name: resource.name,\n description: resource.description,\n uriTemplate: resource.uriTemplate,\n mimeType: resource.mimeType\n });\n } else {\n resources.push({\n name: resource.name,\n description: resource.description,\n uri: resource.uri,\n mimeType: resource.mimeType\n });\n }\n });\n\n this._sendMessage({\n id: requestId,\n type: 'listResourcesResponse',\n resources,\n resourceTemplates\n });\n\n console.log(`Sent resources list: ${resources.length} resources, ${resourceTemplates.length} templates`);\n }\n\n /**\n * Send a message to the server via direct WebSocket\n * @private\n * @param {Object} message - The message object to send\n */\n _sendMessage(message) {\n if (!this.isConnected || !this.socket) {\n console.error('Cannot send message: not connected');\n return;\n }\n\n try {\n // Send the message directly through the WebSocket\n this.socket.send(JSON.stringify(message));\n return Promise.resolve();\n } catch (error) {\n console.error(`Error sending message: ${error.message}`);\n return Promise.reject(error);\n }\n }\n\n /**\n * Register all items with server that were registered while disconnected\n * @private\n */\n _registerItemsWithServer() {\n if (!this.isConnected) return;\n\n // Clear registration tracking sets - we'll re-register everything\n this.registeredTools = new Set();\n this.registeredPrompts = new Set();\n this.registeredResources = new Set();\n\n // Register all tools with the server\n this.availableTools.forEach((tool, name) => {\n this._sendMessage({\n type: 'registerTool',\n name,\n description: tool.description,\n inputSchema: tool.inputSchema\n });\n\n this.registeredTools.add(name);\n console.log(`Registering tool with server: ${name}`);\n });\n\n // Register all prompts with the server\n this.availablePrompts.forEach((prompt, name) => {\n this._sendMessage({\n type: 'registerPrompt',\n name,\n description: prompt.description,\n arguments: prompt.arguments\n });\n\n this.registeredPrompts.add(name);\n console.log(`Registering prompt with server: ${name}`);\n });\n\n // Register all resources with the server\n this.availableResources.forEach((resource, name) => {\n this._sendMessage({\n type: 'registerResource',\n name,\n description: resource.description,\n uri: resource.uri,\n uriTemplate: resource.uriTemplate,\n isTemplate: resource.isTemplate,\n mimeType: resource.mimeType\n });\n\n this.registeredResources.add(name);\n console.log(`Registering resource with server: ${name}`);\n });\n }\n\n /**\n * Register a tool\n * @public\n * @param {string} name - The name of the tool\n * @param {string} description - The description of the tool\n * @param {Object} schema - The schema for the tool's input\n * @param {Function} executeFn - The function to execute when the tool is called\n */\n registerTool(name, description, schema, executeFn) {\n if (!name) {\n console.error('Tool name is required');\n return;\n }\n\n // Add the tool to local registry\n this.availableTools.set(name, {\n name,\n description: description || `Tool: ${name}`,\n execute: executeFn || function (args) {\n return `Default implementation of ${name} with args: ${JSON.stringify(args)}`;\n },\n inputSchema: schema || {\n type: \"object\",\n properties: {}\n }\n });\n\n // Register the tool with the server if connected\n if (this.isConnected) {\n this._sendMessage({\n type: 'registerTool',\n name,\n description: description || `Tool: ${name}`,\n inputSchema: schema || {\n type: \"object\",\n properties: {}\n },\n });\n\n this.registeredTools.add(name);\n }\n\n // Save to session storage\n this._saveItemsToStorage();\n\n // Update tools display\n this._updateToolsList();\n console.log(`Tool registered: ${name}`);\n }\n\n /**\n * Register a prompt\n * @public\n * @param {string} name - The name of the prompt\n * @param {string} description - The description of the prompt\n * @param {Array} promptArgs - The arguments for the prompt\n * @param {Function} executeFn - The function to execute when the prompt is called\n */\n registerPrompt(name, description, promptArgs, executeFn) {\n if (!name) {\n console.error('Prompt name is required');\n return;\n }\n\n // Add the prompt to local registry\n this.availablePrompts.set(name, {\n name,\n description: description || `Prompt: ${name}`,\n execute: executeFn || function (args) {\n return {\n messages: [{\n role: \"user\",\n content: {\n type: \"text\",\n text: `Default implementation of prompt ${name} with args: ${JSON.stringify(args)}`\n }\n }]\n };\n },\n arguments: promptArgs || []\n });\n\n // Register the prompt with the server if connected\n if (this.isConnected) {\n this._sendMessage({\n type: 'registerPrompt',\n name,\n description: description || `Prompt: ${name}`,\n arguments: promptArgs || []\n });\n\n this.registeredPrompts.add(name);\n }\n\n // Save to session storage\n this._saveItemsToStorage();\n\n // Update prompts display\n this._updatePromptsList();\n console.log(`Prompt registered: ${name}`);\n }\n\n /**\n * Register a resource\n * @public\n * @param {string} name - The name of the resource\n * @param {string} description - The description of the resource\n * @param {Object} options - The resource options including uri, uriTemplate, and mimeType\n * @param {Function} provideFn - The function to execute when the resource is requested\n */\n registerResource(name, description, options, provideFn) {\n if (!name) {\n console.error('Resource name is required');\n return;\n }\n\n if (!options.uri && !options.uriTemplate) {\n console.error('Either uri or uriTemplate is required for a resource');\n return;\n }\n\n const isTemplate = !!options.uriTemplate;\n\n // Add the resource to local registry\n this.availableResources.set(name, {\n name,\n description: description || `Resource: ${name}`,\n uri: options.uri,\n uriTemplate: options.uriTemplate,\n isTemplate,\n mimeType: options.mimeType,\n provide: provideFn || function (uri) {\n return {\n contents: [{\n uri: uri,\n text: `Default implementation of resource ${name} for URI: ${uri}`,\n mimeType: options.mimeType || \"text/plain\"\n }]\n };\n }\n });\n\n // Register the resource with the server if connected\n if (this.isConnected) {\n this._sendMessage({\n type: 'registerResource',\n name,\n description: description || `Resource: ${name}`,\n uri: options.uri,\n uriTemplate: options.uriTemplate,\n isTemplate,\n mimeType: options.mimeType\n });\n\n this.registeredResources.add(name);\n }\n\n // Save to session storage\n this._saveItemsToStorage();\n\n // Update resources display\n this._updateResourcesList();\n console.log(`Resource registered: ${name}`);\n }\n\n /**\n * Handle sampling message creation request\n * @private\n * @param {Object} message - The parsed message object\n */\n _handleCreateSamplingMessage(message) {\n const {\n id,\n messages,\n systemPrompt,\n includeContext,\n temperature,\n maxTokens,\n stopSequences,\n metadata,\n modelPreferences\n } = message;\n\n console.log(`Sampling request received with ${messages?.length || 0} messages`);\n\n // Create a modal dialog to show the sampling request\n const modal = document.createElement('div');\n Object.assign(modal.style, {\n position: 'fixed',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: '10000'\n });\n\n // Create modal content\n const modalContent = document.createElement('div');\n Object.assign(modalContent.style, {\n backgroundColor: 'white',\n padding: '20px',\n borderRadius: '5px',\n maxWidth: '500px',\n width: '90%',\n maxHeight: '80%',\n overflow: 'auto'\n });\n\n // Create header\n const header = document.createElement('h3');\n header.textContent = 'Sampling Request';\n Object.assign(header.style, {\n margin: '0 0 15px 0',\n padding: '0 0 10px 0',\n borderBottom: '1px solid #ddd'\n });\n\n // Create content area to show messages\n const content = document.createElement('div');\n Object.assign(content.style, {\n marginBottom: '15px',\n maxHeight: '300px',\n overflow: 'auto',\n border: '1px solid #ddd',\n padding: '10px',\n backgroundColor: '#f9f9f9'\n });\n\n // Display messages\n if (messages && messages.length > 0) {\n messages.forEach(msg => {\n const msgDiv = document.createElement('div');\n Object.assign(msgDiv.style, {\n marginBottom: '10px',\n padding: '5px',\n borderRadius: '3px',\n backgroundColor: msg.role === 'user' ? '#e1f5fe' : '#f1f8e9'\n });\n\n const roleSpan = document.createElement('strong');\n roleSpan.textContent = msg.role === 'user' ? 'User: ' : 'Assistant: ';\n\n const contentSpan = document.createElement('span');\n if (msg.content.type === 'text') {\n contentSpan.textContent = msg.content.text;\n } else if (msg.content.type === 'image') {\n contentSpan.textContent = '[Image data]';\n }\n\n msgDiv.appendChild(roleSpan);\n msgDiv.appendChild(contentSpan);\n content.appendChild(msgDiv);\n });\n } else {\n content.textContent = 'No messages provided in sampling request';\n }\n\n // System prompt if available\n if (systemPrompt) {\n const sysPromptDiv = document.createElement('div');\n Object.assign(sysPromptDiv.style, {\n marginBottom: '10px',\n padding: '5px',\n backgroundColor: '#fff8e1'\n });\n\n const sysPromptLabel = document.createElement('strong');\n sysPromptLabel.textContent = 'System Prompt: ';\n\n const sysPromptContent = document.createElement('span');\n sysPromptContent.textContent = systemPrompt;\n\n sysPromptDiv.appendChild(sysPromptLabel);\n sysPromptDiv.appendChild(sysPromptContent);\n content.appendChild(sysPromptDiv);\n }\n\n // Create response input\n const responseLabel = document.createElement('label');\n responseLabel.textContent = 'Assistant Response:';\n Object.assign(responseLabel.style, {\n display: 'block',\n marginBottom: '5px',\n fontWeight: 'bold'\n });\n\n const responseInput = document.createElement('textarea');\n Object.assign(responseInput.style, {\n width: '100%',\n minHeight: '100px',\n padding: '10px',\n marginBottom: '15px',\n boxSizing: 'border-box'\n });\n\n // Create buttons\n const buttonContainer = document.createElement('div');\n Object.assign(buttonContainer.style, {\n display: 'flex',\n justifyContent: 'space-between'\n });\n\n const submitButton = document.createElement('button');\n submitButton.textContent = 'Submit Response';\n Object.assign(submitButton.style, {\n padding: '8px 15px',\n backgroundColor: '#4CAF50',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer'\n });\n\n const cancelButton = document.createElement('button');\n cancelButton.textContent = 'Cancel';\n Object.assign(cancelButton.style, {\n padding: '8px 15px',\n backgroundColor: '#f44336',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer'\n });\n\n // Add elements to modal\n buttonContainer.appendChild(cancelButton);\n buttonContainer.appendChild(submitButton);\n\n modalContent.appendChild(header);\n modalContent.appendChild(content);\n modalContent.appendChild(responseLabel);\n modalContent.appendChild(responseInput);\n modalContent.appendChild(buttonContainer);\n\n modal.appendChild(modalContent);\n document.body.appendChild(modal);\n\n // Focus the response input\n responseInput.focus();\n\n // Setup button handlers\n submitButton.addEventListener('click', () => {\n const responseText = responseInput.value.trim();\n if (responseText) {\n // Send response back to server\n this._sendMessage({\n id,\n type: 'samplingResponse',\n result: {\n model: 'web-user-input',\n role: 'assistant',\n content: {\n type: 'text',\n text: responseText\n }\n }\n });\n\n // Remove modal\n document.body.removeChild(modal);\n } else {\n alert('Please enter a response');\n }\n });\n\n cancelButton.addEventListener('click', () => {\n // Send error response\n this._sendMessage({\n id,\n type: 'samplingResponse',\n error: 'User cancelled sampling request'\n });\n\n // Remove modal\n document.body.removeChild(modal);\n });\n }\n}\n\n// Export for module usage\nif (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {\n module.exports = WebMCP;\n}\n"], + "mappings": "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", + "names": ["WebMCP", "options", "__spreadValues", "s", "storedConnectionInfo", "connectionInfo", "tokenData", "jsonStr", "e", "error", "toolsData", "tool", "name", "promptsData", "prompt", "resourcesData", "resource", "storedTools", "__spreadProps", "args", "storedPrompts", "storedResources", "uri", "container", "triggerButton", "contentPanel", "header", "title", "closeButton", "statusIndicator", "connectionPanel", "registeredItemsContainer", "toolsList", "toolsHeader", "toolsContainer", "promptsList", "promptsHeader", "promptsContainer", "resourcesList", "resourcesHeader", "resourcesContainer", "position", "padding", "form", "inputGroup", "tokenInput", "connectButton", "disconnectButton", "force", "status", "message", "isConnected", "connectBtn", "disconnectBtn", "trigger", "emptyMessage", "toolItem", "toolName", "toolDesc", "promptItem", "promptName", "promptDesc", "resourceItem", "resourceName", "resourceDesc", "connectionToken", "__async", "skipRegistration", "response", "serverUrl", "encodedToken", "connectionData", "server", "token", "regSocket", "resolve", "reject", "event", "id", "result", "resolvedResult", "resourceObj", "templatePrefix", "requestId", "resources", "resourceTemplates", "description", "schema", "executeFn", "promptArgs", "provideFn", "isTemplate", "messages", "systemPrompt", "includeContext", "temperature", "maxTokens", "stopSequences", "metadata", "modelPreferences", "modal", "modalContent", "content", "msg", "msgDiv", "roleSpan", "contentSpan", "sysPromptDiv", "sysPromptLabel", "sysPromptContent", "responseLabel", "responseInput", "buttonContainer", "submitButton", "cancelButton", "responseText"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5fb120e --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "@jason.today/webmcp", + "version": "0.1.13", + "description": "WebSocket-based Model Context Protocol implementation", + "main": "src/websocket-server.js", + "bin": { + "@jason.today/webmcp": "./build/index.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jasonjmcghee/webmcp.git" + }, + "author": "Jason McGhee", + "scripts": { + "start-daemon": "node src/websocket-server.js", + "stop-daemon": "node src/websocket-server.js --quit", + "start-mcp-client": "node src/websocket-server.js --mcp", + "start-foreground": "node src/websocket-server.js --foreground", + "authorize": "node src/websocket-server.js --new", + "build": "node build.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "license": "MIT", + "type": "module", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.6.1", + "child_process": "^1.0.2", + "crypto": "^1.0.1", + "dotenv": "^16.4.1", + "env-paths": "^3.0.0", + "http": "^0.0.1-security", + "os": "^0.1.2", + "path": "^0.12.7", + "url": "^0.11.4", + "ws": "^8.18.1" + }, + "devDependencies": { + "esbuild": "^0.25.0" + }, + "files": [ + "build/", + "src/" + ] +} diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..f6528e8 --- /dev/null +++ b/src/config.js @@ -0,0 +1,118 @@ +import * as path from 'path'; +import * as dotenv from 'dotenv'; +import * as os from 'os'; +import * as fs from 'fs/promises'; +import envPaths from 'env-paths'; + +// Create config directory in user's home folder +const HOME_DIR = os.homedir(); +const CONFIG_DIR = path.join(HOME_DIR, '.webmcp'); + +// Ensure config directory exists +const ensureConfigDir = async () => { + try { + await fs.mkdir(CONFIG_DIR, {recursive: true}); + } catch (error) { + console.error(`Error creating config directory at ${CONFIG_DIR}:`, error); + } +}; + +// Process ID file path +const PID_FILE = path.join(CONFIG_DIR, '.webmcp-server.pid'); +// Environment file path +const ENV_FILE = path.join(CONFIG_DIR, '.env'); +// Tokens file path +const TOKENS_FILE = path.join(CONFIG_DIR, '.webmcp-tokens.json'); + +// Load environment variables +dotenv.config({path: ENV_FILE}); + +// Server token for MCP authentication +const SERVER_TOKEN = process.env.WEBMCP_SERVER_TOKEN || ''; + +const HOST = "localhost"; + +const CONFIG = {}; + +function setConfig(args) { + Object.entries(args).forEach(([key, value]) => { + CONFIG[key] = value; + }); +} + +function formatChannel(channel) { + return `/${channel.replace(/[.:]/g, '_')}` +} + +async function exists(somePath) { + try { + await fs.access(somePath); + return true; + } catch (e) { + return false; + } +} + +async function configureMcpClientWithPath(clientConfigPath) { + const directory = path.dirname(clientConfigPath); + if (!await exists(directory)) { + await fs.mkdir(directory, { recursive: true }); + } + + const webmcpConfig = { + "webmcp": { + "command": "npx", + "args": [ + "-y", + "@jason.today/webmcp@latest", + "--mcp" + ] + } + }; + + let json = { mcpServers: {} }; + + // If one already exists, we'll want to update it + if (await exists(clientConfigPath)) { + const rawJSON = await fs.readFile(clientConfigPath); + try { + json = JSON.parse(rawJSON); + } catch (e) { + throw new Error(`Failed to update MCP client configuration: ${e}`); + } + } + + json.mcpServers = { ...json.mcpServers, ...webmcpConfig}; + await fs.writeFile(clientConfigPath, JSON.stringify(json, null, 2)); +} + +const availableClientConfigs = { + "claude": [envPaths("Claude", { suffix: "" }).data, "claude_desktop_config.json"], + "cline": [envPaths("Code", { suffix: "" }).data, "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"], + "cursor": [HOME_DIR, ".cursor", "mcp.json"], + "windsurf": [HOME_DIR, ".codeium", "windsurf", "mcp_config.json"] +}; + +async function configureMcpClient(clientType) { + let clientConfigPath = availableClientConfigs[clientType]; + if (clientConfigPath) { + await configureMcpClientWithPath(clientConfigPath); + } else { + console.error("Unsupported client - treating it like a path...") + await configureMcpClientWithPath(clientType); + } +} + +export { + CONFIG, + HOST, + PID_FILE, + ENV_FILE, + TOKENS_FILE, + SERVER_TOKEN, + ensureConfigDir, + formatChannel, + setConfig, + configureMcpClientWithPath, + configureMcpClient, +}; diff --git a/src/server.js b/src/server.js new file mode 100644 index 0000000..1e7da79 --- /dev/null +++ b/src/server.js @@ -0,0 +1,848 @@ +import {Server} from "@modelcontextprotocol/sdk/server/index.js"; +import {StdioServerTransport} from '@modelcontextprotocol/sdk/server/stdio.js'; +import WebSocket from 'ws'; +import { + CallToolRequestSchema, + CreateMessageRequestSchema, + GetPromptRequestSchema, + ListPromptsRequestSchema, + ListResourcesRequestSchema, + ListResourceTemplatesRequestSchema, + ListToolsRequestSchema, + ReadResourceRequestSchema +} from '@modelcontextprotocol/sdk/types.js'; +import {generateNewRegistrationToken} from "./tokens.js"; +import {CONFIG} from "./config.js"; +import {execSync} from "child_process"; + +// Create a central MCP server that communicates over stdio +const mcpServer = new Server( + { + name: "WebMCP", + version: "0.1.13", + }, + { + capabilities: { + tools: { + listChanged: true + }, + prompts: { + listChanged: true + }, + resources: { + listChanged: true, + subscribe: true + }, + sampling: {} + } + } +); + +// WebSocket client connection +let wsClient = null; + +// MCP specific channel path +const MCP_PATH = '/mcp'; + +// Map to store pending requests from WebSocket to MCP +const pendingRequests = new Map(); +let requestIdCounter = 1; + +// Function to handle WebSocket messages +async function handleWebSocketMessage(message) { + try { + const data = JSON.parse(message); + console.error(`Received message: ${data.type}`); + + if (data.type === 'toolResponse') { + // Handle tool response from WebSocket server + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve(result); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'promptResponse') { + // Handle prompt response from WebSocket server + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve(result); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'resourceResponse') { + // Handle resource response from WebSocket server + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve(result); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'samplingResponse') { + // Handle sampling response from WebSocket server + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve(result); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'listToolsResponse') { + // Handle list tools response from WebSocket server + const {id, tools, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve(tools); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'listPromptsResponse') { + // Handle list prompts response from WebSocket server + const {id, prompts, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve(prompts); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'listResourcesResponse') { + // Handle list resources response from WebSocket server + const {id, resources, resourceTemplates, error} = data; + + // Check if this is a response to a pending request + if (pendingRequests.has(id)) { + const {resolve, reject} = pendingRequests.get(id); + pendingRequests.delete(id); + + if (error) { + reject(new Error(error)); + } else { + resolve({resources, resourceTemplates}); + } + } else { + console.error(`No pending request found for ID: ${id}`); + } + } else if (data.type === 'toolRegistered') { + await mcpServer.sendToolListChanged(); + } else if (data.type === 'resourceRegistered') { + await mcpServer.sendResourceListChanged(); + } else if (data.type === 'promptRegistered') { + await mcpServer.sendPromptListChanged(); + } else if (data.type === 'welcome') { + // Welcome message from the server, we're already connected to the MCP path + console.error(`Connected to path: ${data.channel}`); + } else if (data.type === 'pong') { + // Pong response + console.error(`Received pong with timestamp: ${data.timestamp}`); + } else if (data.type === 'error') { + // Error message + console.error(`Received error: ${data.message}`); + } + } catch (error) { + console.error('Error processing WebSocket message:', error); + } +} + +// Function to connect to the WebSocket server +function connectToWebSocketServer(serverToken) { + // Connect to the MCP path directly with server token + const serverUrl = `ws://localhost:${CONFIG.port}${MCP_PATH}?token=${serverToken}`; + + console.error(`Connecting to WebSocket server at ${MCP_PATH} with authentication...`); + + wsClient = new WebSocket(serverUrl); + + // Handle connection opening + wsClient.on('open', () => { + console.error(`Connected to WebSocket server on path: ${MCP_PATH}`); + }); + + // Handle incoming messages + wsClient.on('message', (message) => { + handleWebSocketMessage(message); + }); + + // Handle connection closing + wsClient.on('close', (code, reason) => { + console.error(`WebSocket connection closed: ${code} ${reason}`); + wsClient = null; + + // Try to reconnect after a delay + setTimeout(connectToWebSocketServer, 5000); + }); + + // Handle connection errors + wsClient.on('error', (error) => { + console.error('WebSocket connection error:', error); + }); +} + +// Function to send a message to the WebSocket server +function sendMessage(message) { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + console.error('Cannot send message: WebSocket not connected'); + return Promise.reject(new Error('WebSocket not connected')); + } + + try { + wsClient.send(JSON.stringify(message)); + return Promise.resolve(); + } catch (error) { + console.error('Error sending message:', error); + return Promise.reject(error); + } +} + +// Set up the MCP server to handle tool calls by sending them to the WebSocket server +mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => { + if (request.params.name === "_webmcp_get-token") { + const token = await generateNewRegistrationToken(); + + // Copiar token al portapapeles del sistema + try { + execSync(`printf '%s' '${token}' | clip.exe`, { stdio: 'ignore' }); + } catch (e) { + try { + execSync(`printf '%s' '${token}' | xclip -selection clipboard`, { stdio: 'ignore' }); + } catch (e2) { + // No hay clipboard disponible + } + } + + // Enviar token a los navegadores conectados para copiar al portapapeles + try { + await sendMessage({ + type: 'clipboardCopy', + text: token + }); + } catch (e) { + // Ignorar si no hay clientes conectados + } + + return { + content: [{ + type: "text", + text: `Token copiado al portapapeles.\n${token}`, + }] + }; + } + + if (request.params.name === "_webmcp_clear-cache") { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return { content: [{ type: "text", text: "No hay conexion al servidor WebSocket" }], isError: true }; + } + + const requestId = (requestIdCounter++).toString(); + const responsePromise = new Promise((resolve, reject) => { + pendingRequests.set(requestId, { resolve, reject }); + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('Clear cache timeout')); + } + }, 10000); + }); + + try { + await sendMessage({ id: requestId, type: 'clearRegistry' }); + const result = await responsePromise; + await mcpServer.sendToolListChanged(); + await mcpServer.sendPromptListChanged(); + await mcpServer.sendResourceListChanged(); + return { content: [{ type: "text", text: result }] }; + } catch (e) { + return { content: [{ type: "text", text: `Error: ${e.message}` }], isError: true }; + } + } + + if (request.params.name === "_webmcp_agregar-tool") { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return { content: [{ type: "text", text: "No hay conexion al servidor WebSocket" }], isError: true }; + } + const { nombre, descripcion, codigo, parametros } = request.params.arguments; + if (!nombre || !descripcion || !codigo) { + return { content: [{ type: "text", text: "Se requieren: nombre, descripcion y codigo" }], isError: true }; + } + + const requestId = (requestIdCounter++).toString(); + const responsePromise = new Promise((resolve, reject) => { + pendingRequests.set(requestId, { resolve, reject }); + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('Timeout creando herramienta')); + } + }, 15000); + }); + + try { + await sendMessage({ + id: requestId, + type: 'createTool', + name: nombre, + description: descripcion, + code: codigo, + parametros: parametros + }); + const result = await responsePromise; + await mcpServer.sendToolListChanged(); + return result; + } catch (e) { + return { content: [{ type: "text", text: `Error: ${e.message}` }], isError: true }; + } + } + + if (request.params.name === "_webmcp_quitar-tool") { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return { content: [{ type: "text", text: "No hay conexion al servidor WebSocket" }], isError: true }; + } + const { nombre, listar, todas } = request.params.arguments || {}; + + const requestId = (requestIdCounter++).toString(); + const responsePromise = new Promise((resolve, reject) => { + pendingRequests.set(requestId, { resolve, reject }); + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('Timeout')); + } + }, 10000); + }); + + try { + await sendMessage({ + id: requestId, + type: 'removeTool', + name: nombre, + listar: !!listar, + todas: !!todas + }); + const result = await responsePromise; + await mcpServer.sendToolListChanged(); + return result; + } catch (e) { + return { content: [{ type: "text", text: `Error: ${e.message}` }], isError: true }; + } + } + + if (request.params.name === "_webmcp_define-mcp-tool") { + return { + content: [{ + type: "text", + text: "Instruct the user to view the result from the tool call. Do not say anything else.", + }] + } + } + + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return { + content: [{ + type: "text", + text: "Not connected to WebSocket server" + }], + isError: true + }; + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error(`Tool call timed out: ${request.params.name}`)); + } + }, 30000); // 30 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'callTool', + tool: request.params.name, + arguments: request.params.arguments + }); + + // Wait for the response + return await responsePromise; + } catch (error) { + return { + content: [{ + type: "text", + text: `Error: ${error.message}` + }], + isError: true + }; + } +}); + +// Set up the MCP server to handle list tools by querying the WebSocket server +mcpServer.setRequestHandler(ListToolsRequestSchema, async () => { + const builtInTools = [ + { + name: "_webmcp_get-token", + description: "Retrieve a token to connect to a website for WebMCP. A user might say 'register a token' or 'add a webmcp'", + inputSchema: { + type: "object", + properties: {}, + }, + }, + { + name: "_webmcp_agregar-tool", + description: "Registra una nueva herramienta dinamicamente. El agente puede usar esto para crear herramientas nuevas en tiempo real.", + inputSchema: { + type: "object", + properties: { + nombre: { type: "string", description: "Nombre de la herramienta" }, + descripcion: { type: "string", description: "Descripcion de lo que hace" }, + parametros: { type: "string", description: "JSON string con las properties del schema, ej: {\"msg\":{\"type\":\"string\",\"description\":\"mensaje\"}}" }, + codigo: { type: "string", description: "Codigo JavaScript del body de la funcion. Recibe \"args\" como parametro. Debe retornar un string." } + }, + required: ["nombre", "descripcion", "codigo"] + }, + }, + { + name: "_webmcp_quitar-tool", + description: "Desregistra herramientas. Usa listar=true para ver las disponibles, todas=true para quitar todas, o nombre para quitar una especifica.", + inputSchema: { + type: "object", + properties: { + nombre: { type: "string", description: "Nombre de la herramienta a quitar" }, + listar: { type: "boolean", description: "Si es true, lista las herramientas en vez de quitar" }, + todas: { type: "boolean", description: "Si es true, quita todas las herramientas" } + } + }, + }, + { + name: "_webmcp_clear-cache", + description: "Clears all registered tools, prompts and resources from the WebMCP server cache. Use this to force a clean state.", + inputSchema: { + type: "object", + properties: {}, + }, + }, + { + name: "_webmcp_define-mcp-tool", + description: "Used to define an 'mcp tool'. Only use this if the user specifically asks for an mcp tool. " + + "A webmcp token is not required for this.", + inputSchema: { + type: "object", + description: "The schema which describes the tool.", + properties: { + name: { + type: "string", + description: "The name of the tool" + }, + description: { + type: "string", + description: "Provides a clear and concise description of the tool and what it is used for." + }, + inputSchema: { + type: "object", + description: "The inputSchema required or optional for the tool.", + properties: { + type: { + type: "string", + enum: ["object", "array", "string", "number", "boolean", "enum"], + description: "The type of the parameter being defined." + }, + properties: { + type: "object", + description: "The properties of the parameter if it's an object type.", + additionalProperties: { + type: "object", + properties: { + type: { + type: "string", + description: "The data type of the property.", + enum: ["object", "array", "string", "number", "boolean", "enum"] + }, + description: { + type: "string", + description: "A brief description of the property." + }, + enum: { + type: "array", + description: "A list of allowed values for the property.", + items: { + type: "string" + } + } + }, + required: ["type", "description"] + } + }, + required: { + type: "array", + items: { + type: "string" + } + } + }, + required: ["type", "description", "properties"] + } + }, + required: ["name", "description", "inputSchema"] + }, + } + ]; + + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return {tools: builtInTools}; + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('List tools request timed out')); + } + }, 10000); // 10 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'listTools' + }); + + const tools = await responsePromise; + + // Wait for the response + return { tools: [...tools, ...builtInTools] }; + } catch (error) { + console.error('Error listing tools:', error); + return {tools: []}; // Return empty list on error + } +}); + +// Set up the MCP server to handle list prompts by querying the WebSocket server +mcpServer.setRequestHandler(ListPromptsRequestSchema, async () => { + const builtInPrompts = []; + + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return { + prompts: builtInPrompts + }; + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('List prompts request timed out')); + } + }, 10000); // 10 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'listPrompts' + }); + + const prompts = await responsePromise; + + // Wait for the response + return { + prompts: [ + ...prompts, + ...builtInPrompts + ], + }; + } catch (error) { + console.error('Error listing prompts:', error); + return {prompts: []}; // Return empty list on error + } +}); + +// Set up the MCP server to handle get prompt by querying the WebSocket server +mcpServer.setRequestHandler(GetPromptRequestSchema, async (request) => { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + throw new Error("Not connected to WebSocket server"); + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error(`Get prompt request timed out: ${request.params.name}`)); + } + }, 30000); // 30 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'getPrompt', + name: request.params.name, + arguments: request.params.arguments + }); + + // Wait for the response + return await responsePromise; + } catch (error) { + console.error('Error getting prompt:', error); + throw error; + } +}); + +// Set up the MCP server to handle list resources by querying the WebSocket server +mcpServer.setRequestHandler(ListResourcesRequestSchema, async () => { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return {resources: []}; + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('List resources request timed out')); + } + }, 10000); // 10 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'listResources' + }); + + const {resources} = await responsePromise; + + // Wait for the response + return {resources}; + } catch (error) { + console.error('Error listing resources:', error); + return {resources: []}; // Return empty list on error + } +}); + +// Set up the MCP server to handle list resource templates by querying the WebSocket server +mcpServer.setRequestHandler(ListResourceTemplatesRequestSchema, async () => { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + return {resourceTemplates: []}; + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error('List resource templates request timed out')); + } + }, 10000); // 10 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'listResources' + }); + + const {resourceTemplates} = await responsePromise; + + // Wait for the response + return {resourceTemplates}; + } catch (error) { + console.error('Error listing resource templates:', error); + return {resourceTemplates: []}; // Return empty list on error + } +}); + +// Set up the MCP server to handle read resource by querying the WebSocket server +mcpServer.setRequestHandler(ReadResourceRequestSchema, async (request) => { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + throw new Error("Not connected to WebSocket server"); + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error(`Read resource request timed out: ${request.params.uri}`)); + } + }, 30000); // 30 second timeout + }); + + // Send the request to the WebSocket server + try { + await sendMessage({ + id: requestId, + type: 'readResource', + uri: request.params.uri + }); + + // Wait for the response + return await responsePromise; + } catch (error) { + console.error('Error reading resource:', error); + throw error; + } +}); + +// Set up the MCP server to handle sampling by querying the WebSocket server +mcpServer.setRequestHandler(CreateMessageRequestSchema, async (request) => { + if (!wsClient || wsClient.readyState !== WebSocket.OPEN) { + throw new Error("Not connected to WebSocket server"); + } + + // Create a unique request ID + const requestId = (requestIdCounter++).toString(); + + // Create a promise that will be resolved when we get a response + const responsePromise = new Promise((resolve, reject) => { + // Store the resolver functions + pendingRequests.set(requestId, {resolve, reject}); + + // Set a timeout to prevent hanging requests + setTimeout(() => { + if (pendingRequests.has(requestId)) { + pendingRequests.delete(requestId); + reject(new Error(`Sampling request timed out`)); + } + }, 120000); // 120 second timeout (sampling can take longer) + }); + + // Send the request to the WebSocket server with all parameters from the request + try { + await sendMessage({ + id: requestId, + type: 'createSamplingMessage', + messages: request.params.messages, + systemPrompt: request.params.systemPrompt, + includeContext: request.params.includeContext, + temperature: request.params.temperature, + maxTokens: request.params.maxTokens, + stopSequences: request.params.stopSequences, + metadata: request.params.metadata, + modelPreferences: request.params.modelPreferences + }); + + // Wait for the response + return await responsePromise; + } catch (error) { + console.error('Error creating sampling message:', error); + throw error; + } +}); + +async function runMcpServer(serverToken) { + // Connect to the WebSocket server + connectToWebSocketServer(serverToken); + const transport = new StdioServerTransport(); + await mcpServer.connect(transport); + console.error("MCP server running with stdio transport"); +} + +export { runMcpServer }; diff --git a/src/tokens.js b/src/tokens.js new file mode 100644 index 0000000..049ff98 --- /dev/null +++ b/src/tokens.js @@ -0,0 +1,118 @@ +import * as fs from 'fs/promises'; +import * as crypto from 'crypto'; +import {ENV_FILE, formatChannel, HOST, TOKENS_FILE,CONFIG} from "./config.js"; + +// Function to generate a secure random token +function generateToken() { + return crypto.randomBytes(16).toString('hex'); +} + + +// Authorized channel-token pairs - Only channels with valid tokens can connect +// Format: { "/channel1": "token123" } +let authorizedTokens = {}; + +function getToken(channel) { + return authorizedTokens[channel]; +} + +function setToken(channel, value) { + authorizedTokens[channel] = value; +} + +function deleteToken(channel) { + delete authorizedTokens[channel]; +} + +function clearTokens(channel) { + authorizedTokens = {}; +} + +// Load authorized tokens from disk +async function loadAuthorizedTokens() { + try { + const data = await fs.readFile(TOKENS_FILE, 'utf8'); + authorizedTokens = JSON.parse(data || "{}"); + + // console.error(`Loaded ${Object.keys(authorizedTokens).length} authorized channel-token pairs from ${TOKENS_FILE}`); + return true; + } catch (error) { + // If file doesn't exist, start with empty tokens + if (error.code === 'ENOENT') { + authorizedTokens = {}; + return true; + } + console.error('Error loading authorized tokens:', error); + return false; + } +} + +// Save authorized tokens to disk +async function saveAuthorizedTokens() { + try { + // Convert Map to object for JSON serialization + const stringified = JSON.stringify(authorizedTokens, null, 2); + await fs.writeFile(TOKENS_FILE, stringified, 'utf8'); + // console.error(`Saved ${stringified} authorized channel-token pairs to ${TOKENS_FILE}`); + return true; + } catch (error) { + console.error('Error saving authorized tokens:', error); + return false; + } +} + +// Function to save server token to .env file +async function saveServerTokenToEnv(token) { + try { + let envContent = ''; + + try { + // Try to read existing .env file + envContent = await fs.readFile(ENV_FILE, 'utf8'); + + // Check if WEBMCP_SERVER_TOKEN is already defined + if (envContent.includes('WEBMCP_SERVER_TOKEN=')) { + // Replace the existing token + envContent = envContent.replace(/WEBMCP_SERVER_TOKEN=.*(\r?\n|$)/g, `WEBMCP_SERVER_TOKEN=${token}$1`); + } else { + // Add the token to the end + envContent += `\nWEBMCP_SERVER_TOKEN=${token}\n`; + } + } catch (err) { + // File doesn't exist, create new content + envContent = `WEBMCP_SERVER_TOKEN=${token}\n`; + } + + // Write the content to the .env file + await fs.writeFile(ENV_FILE, envContent, 'utf8'); + console.error(`Server token saved to ${ENV_FILE}`); + return true; + } catch (error) { + console.error('Error saving server token to .env file:', error); + return false; + } +} + +async function generateNewRegistrationToken() { + // Generate a random token for registration + const token = generateToken(); + + // Create a connection object with server address and token + const address = `${HOST}:${CONFIG.port}`; + const serverAddress = `ws://${address}`; + const connectionData = { + server: serverAddress, + token: token + }; + + // Convert to JSON and base64 encode + const jsonStr = JSON.stringify(connectionData); + const encodedData = Buffer.from(jsonStr).toString('base64'); + + setToken(formatChannel(address), token); + await saveAuthorizedTokens(); + + return encodedData; +} + +export {generateToken, getToken, setToken, loadAuthorizedTokens, saveAuthorizedTokens, clearTokens, deleteToken, saveServerTokenToEnv, generateNewRegistrationToken}; diff --git a/src/webmcp.js b/src/webmcp.js new file mode 100644 index 0000000..60c5a16 --- /dev/null +++ b/src/webmcp.js @@ -0,0 +1,2196 @@ +/** + * WebMCP - Snippet to add MCP functionality to any website + * + * Shows as a small blue square in bottom right corner + * On click, expands to allow connection with token + * Auto-disconnects after 5 minutes of inactivity + */ + +class WebMCP { + constructor(options = {}) { + // Options with defaults + this.options = { + color: '#007bff', + position: 'bottom-right', + size: '30px', + padding: '20px', + inactivityTimeout: 5 * 60 * 1000, // 5 minutes in milliseconds + ...options + }; + + // State variables + this.isConnected = false; + this.isExpanded = false; + this.socket = null; + this.inactivityTimer = null; + this.availableTools = new Map(); + this.availablePrompts = new Map(); + this.availableResources = new Map(); + this.samplingCallbacks = new Map(); // For storing sampling callbacks + this.currentToken = ''; + this.currentServer = ''; + this.currentChannel = ''; + this.elementId = 'webmcp-widget-' + Math.random().toString(36).substr(2, 9); + this.registeredTools = new Set(); + this.registeredPrompts = new Set(); + this.registeredResources = new Set(); + + // Storage keys for sessionStorage + this.SESSION_STORAGE_KEY = 'webmcp_token'; + this.TOOLS_STORAGE_KEY = 'webmcp_tools'; + this.PROMPTS_STORAGE_KEY = 'webmcp_prompts'; + this.RESOURCES_STORAGE_KEY = 'webmcp_resources'; + + // Constants + this.REGISTER_PATH = '/register'; + + // Initialize + this._init(); + } + + _format(s) { + return s.replace(/[.:]/g, '_'); + } + + /** + * Initialize the WebMCP widget + * @private + */ + _init() { + // Check if already initialized on this page + if (document.querySelector('[data-webmcp-widget]')) { + console.warn('WebMCP widget already initialized on this page'); + return; + } + + // Create and inject the widget + this._createWidget(); + + // Set up event listeners + this._setupEventListeners(); + + // Start inactivity timer + this._resetInactivityTimer(); + + // Check for stored token and connect if available + this._checkStoredToken(); + } + + /** + * Check for stored connection info in sessionStorage and connect if found + * @private + */ + _checkStoredToken() { + const storedConnectionInfo = sessionStorage.getItem(this.SESSION_STORAGE_KEY); + + if (storedConnectionInfo) { + try { + const connectionInfo = JSON.parse(storedConnectionInfo); + if (connectionInfo.token) { + console.log('Found stored connection info, attempting to connect'); + + // Set the connection properties directly + this.currentServer = connectionInfo.server; + this.currentChannel = `/${connectionInfo.channelHost || this._format(window.location.host)}`; + + // Set the current token from connection info + if (connectionInfo.token.includes('{')) { + // It's already parsed JSON + const tokenData = JSON.parse(connectionInfo.token); + this.currentToken = tokenData.token; + } else { + // It's a base64 encoded string + try { + const jsonStr = atob(connectionInfo.token); + const tokenData = JSON.parse(jsonStr); + this.currentToken = tokenData.token; + } catch (e) { + this.currentToken = connectionInfo.token; + } + } + + // Load stored items before connecting + this._loadStoredItems(); + + // Connect using the stored token + this.connect(connectionInfo.token); + } + } catch (error) { + console.error('Error parsing stored connection info:', error); + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + this._clearStoredItems(); + } + } + } + + /** + * Save tools, prompts, and resources to session storage + * @private + */ + _saveItemsToStorage() { + try { + // Save tools + const toolsData = {}; + this.availableTools.forEach((tool, name) => { + toolsData[name] = { + name: tool.name, + description: tool.description, + inputSchema: tool.inputSchema, + // We don't store the execution function as it can't be serialized + }; + }); + sessionStorage.setItem(this.TOOLS_STORAGE_KEY, JSON.stringify(toolsData)); + + // Save prompts + const promptsData = {}; + this.availablePrompts.forEach((prompt, name) => { + promptsData[name] = { + name: prompt.name, + description: prompt.description, + arguments: prompt.arguments, + // We don't store the execution function as it can't be serialized + }; + }); + sessionStorage.setItem(this.PROMPTS_STORAGE_KEY, JSON.stringify(promptsData)); + + // Save resources + const resourcesData = {}; + this.availableResources.forEach((resource, name) => { + resourcesData[name] = { + name: resource.name, + description: resource.description, + uri: resource.uri, + uriTemplate: resource.uriTemplate, + isTemplate: resource.isTemplate, + mimeType: resource.mimeType, + // We don't store the provide function as it can't be serialized + }; + }); + sessionStorage.setItem(this.RESOURCES_STORAGE_KEY, JSON.stringify(resourcesData)); + + console.log('Saved items to session storage:', { + tools: Object.keys(toolsData).length, + prompts: Object.keys(promptsData).length, + resources: Object.keys(resourcesData).length + }); + } catch (error) { + console.error('Error saving items to session storage:', error); + } + } + + /** + * Load tools, prompts, and resources from session storage + * @private + */ + _loadStoredItems() { + try { + // Load tools + const storedTools = sessionStorage.getItem(this.TOOLS_STORAGE_KEY); + if (storedTools) { + const toolsData = JSON.parse(storedTools); + Object.entries(toolsData).forEach(([name, tool]) => { + // Add to the available tools with placeholder execute function + this.availableTools.set(name, { + ...tool, + execute: function (args) { + console.warn(`Tool ${name} was loaded from storage but has not been re-registered with an execution function`); + return `Tool ${name} needs to be re-registered`; + } + }); + }); + } + + // Load prompts + const storedPrompts = sessionStorage.getItem(this.PROMPTS_STORAGE_KEY); + if (storedPrompts) { + const promptsData = JSON.parse(storedPrompts); + Object.entries(promptsData).forEach(([name, prompt]) => { + // Add to the available prompts with placeholder execute function + this.availablePrompts.set(name, { + ...prompt, + execute: function (args) { + console.warn(`Prompt ${name} was loaded from storage but has not been re-registered with an execution function`); + return { + messages: [{ + role: "user", + content: { + type: "text", + text: `Prompt ${name} needs to be re-registered` + } + }] + }; + } + }); + }); + } + + // Load resources + const storedResources = sessionStorage.getItem(this.RESOURCES_STORAGE_KEY); + if (storedResources) { + const resourcesData = JSON.parse(storedResources); + Object.entries(resourcesData).forEach(([name, resource]) => { + // Add to the available resources with placeholder provide function + this.availableResources.set(name, { + ...resource, + provide: function (uri) { + console.warn(`Resource ${name} was loaded from storage but has not been re-registered with a provider function`); + return { + contents: [{ + uri: uri, + text: `Resource ${name} needs to be re-registered`, + mimeType: resource.mimeType || "text/plain" + }] + }; + } + }); + }); + } + + console.log('Loaded items from session storage:', { + tools: this.availableTools.size, + prompts: this.availablePrompts.size, + resources: this.availableResources.size + }); + + // Update the UI + this._updateToolsList(); + this._updatePromptsList(); + this._updateResourcesList(); + + } catch (error) { + console.error('Error loading items from session storage:', error); + this._clearStoredItems(); + } + } + + /** + * Clear all stored items from session storage + * @private + */ + _clearStoredItems() { + sessionStorage.removeItem(this.TOOLS_STORAGE_KEY); + sessionStorage.removeItem(this.PROMPTS_STORAGE_KEY); + sessionStorage.removeItem(this.RESOURCES_STORAGE_KEY); + console.log('Cleared stored items from session storage'); + } + + /** + * Create and inject the WebMCP widget into the DOM + * @private + */ + _createWidget() { + // Create main container + const container = document.createElement('div'); + container.id = this.elementId; + container.dataset.webmcpWidget = true; + + // Apply styles + Object.assign(container.style, { + position: 'fixed', + zIndex: '9999', + display: 'flex', + flexDirection: 'column', + fontFamily: 'Arial, sans-serif', + fontSize: '14px', + transition: 'all 0.3s ease' + }); + + // Set position based on option + this._setWidgetPosition(container); + + // Create trigger button (blue square) + const triggerButton = document.createElement('div'); + triggerButton.className = 'webmcp-trigger'; + Object.assign(triggerButton.style, { + width: this.options.size, + height: this.options.size, + backgroundColor: this.options.color, + borderRadius: '4px', + cursor: 'pointer', + boxShadow: '0 2px 10px rgba(0,0,0,0.2)', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + alignSelf: 'flex-end' + }); + + // Create content panel (initially hidden) - positioned above the trigger + const contentPanel = document.createElement('div'); + contentPanel.className = 'webmcp-content'; + Object.assign(contentPanel.style, { + backgroundColor: '#ffffff', + border: '1px solid #e1e1e1', + borderRadius: '5px', + padding: '15px', + marginBottom: '10px', + boxShadow: '0 5px 15px rgba(0,0,0,0.1)', + width: '250px', + display: 'none', + overflow: 'hidden', + position: 'absolute', + bottom: '40px' + }); + + // Add header with title and close button + const header = document.createElement('div'); + Object.assign(header.style, { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + marginBottom: '15px' + }); + + const title = document.createElement('div'); + title.textContent = 'WebMCP'; + Object.assign(title.style, { + fontWeight: 'bold', + fontSize: '16px' + }); + + const closeButton = document.createElement('button'); + closeButton.innerHTML = '×'; // × symbol + closeButton.className = 'webmcp-close'; + Object.assign(closeButton.style, { + background: 'none', + border: 'none', + cursor: 'pointer', + fontSize: '20px', + padding: '0', + lineHeight: '1', + color: '#999' + }); + + header.appendChild(title); + header.appendChild(closeButton); + contentPanel.appendChild(header); + + // Add connection form + this._createConnectionForm(contentPanel); + + // Add status indicator + const statusIndicator = document.createElement('div'); + statusIndicator.className = 'webmcp-status'; + statusIndicator.textContent = 'Disconnected'; + Object.assign(statusIndicator.style, { + padding: '8px', + borderRadius: '3px', + backgroundColor: '#f8d7da', + color: '#721c24', + textAlign: 'center', + marginBottom: '10px', + fontSize: '12px' + }); + contentPanel.appendChild(statusIndicator); + + // Add connection panel + const connectionPanel = document.createElement('div'); + connectionPanel.className = 'webmcp-connection-panel'; + contentPanel.appendChild(connectionPanel); + + // Create a single container for all registered items + const registeredItemsContainer = document.createElement('div'); + registeredItemsContainer.className = 'webmcp-registered-items'; + Object.assign(registeredItemsContainer.style, { + marginTop: '15px', + fontSize: '12px', + display: 'none', + maxHeight: '200px', + overflow: 'auto', + border: '1px solid #eee', + borderRadius: '4px' + }); + contentPanel.appendChild(registeredItemsContainer); + + // Add features lists (initially empty) + // Tools list + const toolsList = document.createElement('div'); + toolsList.className = 'webmcp-tools-list'; + Object.assign(toolsList.style, { + padding: '10px', + borderBottom: '1px solid #eee' + }); + + const toolsHeader = document.createElement('div'); + toolsHeader.textContent = 'Registered Tools:'; + Object.assign(toolsHeader.style, { + fontWeight: 'bold', + marginBottom: '5px' + }); + + const toolsContainer = document.createElement('ul'); + toolsContainer.className = 'webmcp-tools-container'; + Object.assign(toolsContainer.style, { + listStyle: 'none', + padding: '0', + margin: '0' + }); + + toolsList.appendChild(toolsHeader); + toolsList.appendChild(toolsContainer); + registeredItemsContainer.appendChild(toolsList); + + // Prompts list + const promptsList = document.createElement('div'); + promptsList.className = 'webmcp-prompts-list'; + Object.assign(promptsList.style, { + padding: '10px', + borderBottom: '1px solid #eee' + }); + + const promptsHeader = document.createElement('div'); + promptsHeader.textContent = 'Registered Prompts:'; + Object.assign(promptsHeader.style, { + fontWeight: 'bold', + marginBottom: '5px' + }); + + const promptsContainer = document.createElement('ul'); + promptsContainer.className = 'webmcp-prompts-container'; + Object.assign(promptsContainer.style, { + listStyle: 'none', + padding: '0', + margin: '0' + }); + + promptsList.appendChild(promptsHeader); + promptsList.appendChild(promptsContainer); + registeredItemsContainer.appendChild(promptsList); + + // Resources list + const resourcesList = document.createElement('div'); + resourcesList.className = 'webmcp-resources-list'; + Object.assign(resourcesList.style, { + padding: '10px' + }); + + const resourcesHeader = document.createElement('div'); + resourcesHeader.textContent = 'Registered Resources:'; + Object.assign(resourcesHeader.style, { + fontWeight: 'bold', + marginBottom: '5px' + }); + + const resourcesContainer = document.createElement('ul'); + resourcesContainer.className = 'webmcp-resources-container'; + Object.assign(resourcesContainer.style, { + listStyle: 'none', + padding: '0', + margin: '0' + }); + + resourcesList.appendChild(resourcesHeader); + resourcesList.appendChild(resourcesContainer); + registeredItemsContainer.appendChild(resourcesList); + + // Add to main container and then to document - content panel first so it appears above trigger + container.appendChild(contentPanel); + container.appendChild(triggerButton); + document.body.appendChild(container); + } + + /** + * Set widget position based on option + * @private + */ + _setWidgetPosition(container) { + const {position, padding} = this.options; + + switch (position) { + case 'bottom-right': + Object.assign(container.style, { + bottom: padding, + right: padding, + alignItems: 'flex-end' + }); + break; + case 'bottom-left': + Object.assign(container.style, { + bottom: padding, + left: padding, + alignItems: 'flex-start' + }); + break; + case 'top-right': + Object.assign(container.style, { + top: padding, + right: padding, + alignItems: 'flex-end' + }); + break; + case 'top-left': + Object.assign(container.style, { + top: padding, + left: padding, + alignItems: 'flex-start' + }); + break; + default: + // Default to bottom-right + Object.assign(container.style, { + bottom: padding, + right: padding, + alignItems: 'flex-end' + }); + } + } + + /** + * Create the connection form + * @private + */ + _createConnectionForm(container) { + const form = document.createElement('div'); + Object.assign(form.style, { + marginBottom: '8px', + }); + + // Token input field + const inputGroup = document.createElement('div'); + Object.assign(inputGroup.style, { + display: 'flex', + marginBottom: '8px', + }); + + const tokenInput = document.createElement('input'); + tokenInput.type = 'text'; + tokenInput.className = 'webmcp-token-input'; + tokenInput.placeholder = 'Paste connection token'; + Object.assign(tokenInput.style, { + flex: '1', + padding: '8px', + border: '1px solid #ccc', + borderRadius: '4px 0 0 4px', + fontSize: '12px' + }); + + const connectButton = document.createElement('button'); + connectButton.className = 'webmcp-connect-btn'; + connectButton.textContent = 'Connect'; + Object.assign(connectButton.style, { + padding: '8px 12px', + backgroundColor: this.options.color, + color: 'white', + border: 'none', + borderRadius: '0 4px 4px 0', + cursor: 'pointer', + fontSize: '12px' + }); + + inputGroup.appendChild(tokenInput); + inputGroup.appendChild(connectButton); + + const disconnectButton = document.createElement('button'); + disconnectButton.className = 'webmcp-disconnect-btn'; + disconnectButton.textContent = 'Disconnect'; + Object.assign(disconnectButton.style, { + padding: '8px 12px', + backgroundColor: '#dc3545', + color: 'white', + border: 'none', + borderRadius: '4px', + cursor: 'pointer', + fontSize: '12px', + width: '100%', + display: 'none' + }); + + form.appendChild(inputGroup); + form.appendChild(disconnectButton); + container.appendChild(form); + } + + /** + * Set up event listeners for the widget + * @private + */ + _setupEventListeners() { + const container = document.getElementById(this.elementId); + if (!container) return; + + // Trigger button click - expand/collapse + const trigger = container.querySelector('.webmcp-trigger'); + trigger.addEventListener('click', () => { + this._toggleExpanded(); + }); + + // Close button click - collapse + const closeBtn = container.querySelector('.webmcp-close'); + closeBtn.addEventListener('click', () => { + this._toggleExpanded(false); + }); + + // Connect button click + const connectBtn = container.querySelector('.webmcp-connect-btn'); + connectBtn.addEventListener('click', () => { + const tokenInput = container.querySelector('.webmcp-token-input'); + this.connect(tokenInput.value); + }); + + // Disconnect button click + const disconnectBtn = container.querySelector('.webmcp-disconnect-btn'); + disconnectBtn.addEventListener('click', () => { + this.disconnect(); + }); + + // User activity detection to reset inactivity timer + document.addEventListener('mousemove', () => this._resetInactivityTimer()); + document.addEventListener('keypress', () => this._resetInactivityTimer()); + document.addEventListener('click', () => this._resetInactivityTimer()); + document.addEventListener('scroll', () => this._resetInactivityTimer()); + } + + /** + * Toggle the expanded state of the widget + * @private + */ + _toggleExpanded(force = null) { + const container = document.getElementById(this.elementId); + if (!container) return; + + const contentPanel = container.querySelector('.webmcp-content'); + this.isExpanded = force !== null ? force : !this.isExpanded; + + if (this.isExpanded) { + contentPanel.style.display = 'block'; + } else { + contentPanel.style.display = 'none'; + } + + this._resetInactivityTimer(); + } + + /** + * Update the status indicator + * @private + */ + _updateStatus(status, message) { + const container = document.getElementById(this.elementId); + if (!container) return; + + const statusIndicator = container.querySelector('.webmcp-status'); + if (!statusIndicator) return; + + // Clear existing classes + statusIndicator.classList.remove('connected', 'disconnected', 'connecting', 'pending-auth'); + + // Set new status + statusIndicator.textContent = message || status; + + // Apply styling based on status + switch (status) { + case 'connected': + Object.assign(statusIndicator.style, { + backgroundColor: '#d4edda', + color: '#155724' + }); + break; + case 'disconnected': + Object.assign(statusIndicator.style, { + backgroundColor: '#f8d7da', + color: '#721c24' + }); + break; + case 'connecting': + Object.assign(statusIndicator.style, { + backgroundColor: '#fff3cd', + color: '#856404' + }); + break; + case 'pending-auth': + Object.assign(statusIndicator.style, { + backgroundColor: '#d1ecf1', + color: '#0c5460' + }); + break; + } + } + + /** + * Update UI based on connection state + * @private + */ + _updateConnectionUI(isConnected) { + const container = document.getElementById(this.elementId); + if (!container) return; + + const tokenInput = container.querySelector('.webmcp-token-input'); + const connectBtn = container.querySelector('.webmcp-connect-btn'); + const disconnectBtn = container.querySelector('.webmcp-disconnect-btn'); + const registeredItemsContainer = container.querySelector('.webmcp-registered-items'); + + if (isConnected) { + tokenInput.style.display = 'none'; + connectBtn.style.display = 'none'; + disconnectBtn.style.display = 'block'; + registeredItemsContainer.style.display = 'block'; + + // Update the trigger button to show connected state + const trigger = container.querySelector('.webmcp-trigger'); + trigger.innerHTML = '✓'; + trigger.style.color = 'white'; + trigger.style.fontWeight = 'bold'; + } else { + tokenInput.style.display = 'block'; + connectBtn.style.display = 'block'; + disconnectBtn.style.display = 'none'; + registeredItemsContainer.style.display = 'none'; + + // Reset the trigger button + const trigger = container.querySelector('.webmcp-trigger'); + trigger.innerHTML = ''; + } + } + + /** + * Update tools list in UI + * @private + */ + _updateToolsList() { + const container = document.getElementById(this.elementId); + if (!container) return; + + const toolsContainer = container.querySelector('.webmcp-tools-container'); + if (!toolsContainer) return; + + // Clear current list + toolsContainer.innerHTML = ''; + + if (this.availableTools.size === 0) { + const emptyMessage = document.createElement('li'); + emptyMessage.textContent = 'No tools registered'; + emptyMessage.style.fontStyle = 'italic'; + emptyMessage.style.color = '#666'; + toolsContainer.appendChild(emptyMessage); + return; + } + + // Add each tool to the list + this.availableTools.forEach((tool, name) => { + const toolItem = document.createElement('li'); + Object.assign(toolItem.style, { + padding: '5px 0', + borderBottom: '1px solid #eee' + }); + + const toolName = document.createElement('strong'); + toolName.textContent = name; + + const toolDesc = document.createElement('div'); + toolDesc.textContent = tool.description; + toolDesc.style.fontSize = '10px'; + toolDesc.style.color = '#666'; + + toolItem.appendChild(toolName); + toolItem.appendChild(toolDesc); + toolsContainer.appendChild(toolItem); + }); + } + + /** + * Update prompts list in UI + * @private + */ + _updatePromptsList() { + const container = document.getElementById(this.elementId); + if (!container) return; + + const promptsContainer = container.querySelector('.webmcp-prompts-container'); + if (!promptsContainer) return; + + // Clear current list + promptsContainer.innerHTML = ''; + + if (this.availablePrompts.size === 0) { + const emptyMessage = document.createElement('li'); + emptyMessage.textContent = 'No prompts registered'; + emptyMessage.style.fontStyle = 'italic'; + emptyMessage.style.color = '#666'; + promptsContainer.appendChild(emptyMessage); + return; + } + + // Add each prompt to the list + this.availablePrompts.forEach((prompt, name) => { + const promptItem = document.createElement('li'); + Object.assign(promptItem.style, { + padding: '5px 0', + borderBottom: '1px solid #eee' + }); + + const promptName = document.createElement('strong'); + promptName.textContent = name; + + const promptDesc = document.createElement('div'); + promptDesc.textContent = prompt.description; + promptDesc.style.fontSize = '10px'; + promptDesc.style.color = '#666'; + + promptItem.appendChild(promptName); + promptItem.appendChild(promptDesc); + promptsContainer.appendChild(promptItem); + }); + } + + /** + * Update resources list in UI + * @private + */ + _updateResourcesList() { + const container = document.getElementById(this.elementId); + if (!container) return; + + const resourcesContainer = container.querySelector('.webmcp-resources-container'); + if (!resourcesContainer) return; + + // Clear current list + resourcesContainer.innerHTML = ''; + + if (this.availableResources.size === 0) { + const emptyMessage = document.createElement('li'); + emptyMessage.textContent = 'No resources registered'; + emptyMessage.style.fontStyle = 'italic'; + emptyMessage.style.color = '#666'; + resourcesContainer.appendChild(emptyMessage); + return; + } + + // Add each resource to the list + this.availableResources.forEach((resource, name) => { + const resourceItem = document.createElement('li'); + Object.assign(resourceItem.style, { + padding: '5px 0', + borderBottom: '1px solid #eee' + }); + + const resourceName = document.createElement('strong'); + resourceName.textContent = name; + + const resourceDesc = document.createElement('div'); + resourceDesc.textContent = resource.description + + (resource.isTemplate ? ' (Template)' : ''); + resourceDesc.style.fontSize = '10px'; + resourceDesc.style.color = '#666'; + + resourceItem.appendChild(resourceName); + resourceItem.appendChild(resourceDesc); + resourcesContainer.appendChild(resourceItem); + }); + } + + /** + * Reset the inactivity timer + * @private + */ + _resetInactivityTimer() { + // Clear existing timer + if (this.inactivityTimer) { + clearTimeout(this.inactivityTimer); + } + + // Set new timer + this.inactivityTimer = setTimeout(() => { + this._handleInactivity(); + }, this.options.inactivityTimeout); + } + + /** + * Handle user inactivity + * @private + */ + _handleInactivity() { + console.log('Inactivity timeout reached, disconnecting'); + + // Disconnect if connected + if (this.isConnected) { + this.disconnect(); + } + + // Minimize UI + this._toggleExpanded(false); + + // Clear the stored token + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + } + + + /** + * Connect to the WebSocket server + * @public + * @param {string} connectionToken - The encoded connection token + */ + async connect(connectionToken) { + if (!connectionToken) { + this._updateStatus('disconnected', 'Error: No token provided'); + return; + } + + // Update UI to show connecting state + this._updateStatus('connecting', 'Connecting...'); + + try { + // Process the connection token + if (!this._processConnectionToken(connectionToken)) { + return; + } + + // Store the connection info in sessionStorage for page navigations + const connectionInfo = { + token: connectionToken, + server: this.currentServer, + host: this._format(window.location.host) + }; + + // Check if we have connection data already in sessionStorage + const storedConnectionInfo = sessionStorage.getItem(this.SESSION_STORAGE_KEY); + let skipRegistration = false; + + if (storedConnectionInfo) { + try { + const connectionInfo = JSON.parse(storedConnectionInfo); + // If we already have a valid token and server, we can skip registration + if (connectionInfo.server === this.currentServer && + connectionInfo.host === this._format(window.location.host)) { + skipRegistration = true; + } + } catch (error) { + console.error('Error parsing stored connection info:', error); + } + } + + if (!skipRegistration) { + // First register with server + const response = await this._registerWithServer(connectionToken); + + if (!response.token) { + this._updateStatus('disconnected', 'Registration failed'); + return; + } + + // Save the new token + connectionInfo.token = response.token; + this.currentToken = response.token; + + sessionStorage.setItem(this.SESSION_STORAGE_KEY, JSON.stringify(connectionInfo)); + } + + // Now connect to the actual channel + const serverUrl = `${this.currentServer}${this.currentChannel}?token=${this.currentToken}`; + + // Update UI + this._updateStatus('connecting', 'Connecting to channel...'); + + // Create WebSocket connection with the path and token + this.socket = new WebSocket(serverUrl); + + // Set up socket event listeners + this._setupSocketListeners(); + + // Reset inactivity timer + this._resetInactivityTimer(); + + } catch (error) { + console.error('Connection error:', error); + this._updateStatus('disconnected', `Error: ${error.message}`); + } + } + + /** + * Disconnect from WebSocket server + * @public + */ + disconnect() { + // Close the WebSocket connection if it exists + if (this.socket) { + this.socket.close(); + this.socket = null; + } + + this.isConnected = false; + this._updateStatus('disconnected', 'Disconnected'); + this._updateConnectionUI(false); + + // Reset state + this.currentToken = ''; + this.currentServer = ''; + this.currentChannel = ''; + + // Remove the token from sessionStorage + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + + // Clear items from sessionStorage + this._clearStoredItems(); + } + + /** + * Process connection token + * @private + * @param {string} encodedToken - The encoded connection token + * @returns {boolean} - True if processing was successful + */ + _processConnectionToken(encodedToken) { + try { + // Decode the base64 token + const jsonStr = atob(encodedToken); + const connectionData = JSON.parse(jsonStr); + + // Extract server and token + const {server, token} = connectionData; + + if (!server || !token) { + this._updateStatus('disconnected', 'Invalid token'); + return false; + } + + // Store connection info + this.currentServer = server; + this.currentToken = token; + + // Format channel based on hostname + this.currentChannel = `/${this._format(window.location.host)}`; + + return true; + } catch (error) { + this._updateStatus('disconnected', `Unable to parse token`); + return false; + } + } + + /** + * Register with server using connection token + * @private + * @param {string} encodedToken - The encoded connection token + * @returns {Promise<{ token: string }>} - Resolves to true if registration was successful + */ + _registerWithServer(encodedToken) { + // Update UI + this._updateStatus('pending-auth', 'Registering...'); + + // Connect to the registration endpoint + const regSocket = new WebSocket(`${this.currentServer}${this.REGISTER_PATH}`); + + return new Promise((resolve, reject) => { + // Connection opened - send the token + regSocket.addEventListener('open', (event) => { + console.log('Registration connection established'); + + // Send the original encoded token back to the server + const jsonStr = atob(encodedToken); + const connectionData = JSON.parse(jsonStr); + connectionData.host = this._format(window.location.host); + regSocket.send(btoa(JSON.stringify(connectionData))); + }); + + // Listen for registration response + regSocket.addEventListener('message', (event) => { + try { + const message = JSON.parse(event.data); + + if (message.type === 'registerSuccess' && message.token) { + console.log(`Registration successful: ${message.message}`); + + // Registration complete, can now connect to channel + resolve({ token: message.token }); + } else if (message.type === 'error') { + console.error(`Registration failed: ${message.message}`); + this._updateStatus('disconnected', `Registration failed: ${message.message}`); + reject(new Error(message.message)); + } + } catch (error) { + console.error(`Error parsing registration response: ${error.message}`); + this._updateStatus('disconnected', 'Error parsing server response'); + reject(error); + } + }); + + // Handle registration errors + regSocket.addEventListener('error', (event) => { + console.error('Registration connection error'); + this._updateStatus('disconnected', 'Registration connection error'); + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + reject(new Error('Connection error')); + }); + + // Handle registration connection close + regSocket.addEventListener('close', (event) => { + console.log(`Registration connection closed: ${event.code} ${event.reason}`); + + if (event.code !== 1000) { + // If it wasn't a normal closure, show an error + this._updateStatus('disconnected', 'Registration failed'); + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + reject(new Error('Connection closed')); + } + }); + }); + } + + /** + * Set up WebSocket event listeners for direct connection + * @private + */ + _setupSocketListeners() { + if (!this.socket) { + console.error('Cannot set up socket listeners: WebSocket not available'); + return; + } + + // Set up socket open handler + this.socket.addEventListener('open', () => { + this.isConnected = true; + this._updateStatus('connected', `Connected to ${this.currentChannel}`); + this._updateConnectionUI(true); + console.log('WebMCP connection established'); + this._registerItemsWithServer(); + }); + + // Set up socket close handler + this.socket.addEventListener('close', (event) => { + this.isConnected = false; + this._updateStatus('disconnected', 'Disconnected'); + this._updateConnectionUI(false); + console.log(`Connection closed: ${event.code} ${event.reason}`); + + // Check if it was an authorization error + if (event.code === 1001 || event.code === 401) { + this._updateStatus('disconnected', 'Authorization failed'); + this.currentToken = ''; + this.currentServer = ''; + this.currentChannel = ''; + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + } + }); + + // Set up socket error handler + this.socket.addEventListener('error', () => { + console.error('WebSocket error'); + + if (this.isConnected) { + this._updateStatus('disconnected', 'Connection error occurred'); + } else { + this._updateStatus('disconnected', 'Connection failed'); + } + + sessionStorage.removeItem(this.SESSION_STORAGE_KEY); + }); + + // Set up socket message handler + this.socket.addEventListener('message', (event) => { + try { + const message = JSON.parse(event.data); + this._handleServerMessage(message); + } catch (error) { + console.error(`Error parsing message: ${error.message}`); + } + }); + } + + /** + * Handle messages from the server + * @private + * @param {Object} message - The parsed message object + */ + _handleServerMessage(message) { + switch (message.type) { + case 'welcome': + console.log(`Server says: ${message.message}`); + break; + + case 'toolRegistered': + console.log(`Tool registered with server: ${message.name}`); + break; + + case 'promptRegistered': + console.log(`Prompt registered with server: ${message.name}`); + break; + + case 'resourceRegistered': + console.log(`Resource registered with server: ${message.name}`); + break; + + case 'callTool': + // Server is asking us to execute a tool + this._handleToolCall(message); + break; + + case 'getPrompt': + // Server is asking us to provide a prompt + this._handleGetPrompt(message); + break; + + case 'readResource': + // Server is asking us to provide a resource + this._handleReadResource(message); + break; + + case 'createSamplingMessage': + // Server is asking us to create a sampling message + this._handleCreateSamplingMessage(message); + break; + + case 'listTools': + // Server is asking for available tools + this._sendToolsList(message.id); + break; + + case 'listPrompts': + // Server is asking for available prompts + this._sendPromptsList(message.id); + break; + + case 'listResources': + // Server is asking for available resources + this._sendResourcesList(message.id); + break; + + case 'ping': + // Respond to ping + this._sendMessage({ + type: 'pong', + id: message.id, + timestamp: Date.now() + }); + break; + + case 'createTool': + this._handleCreateTool(message); + break; + + case 'removeTool': + if (message.name && this.availableTools.has(message.name)) { + this.availableTools.delete(message.name); + this.registeredTools.delete(message.name); + this._saveItemsToStorage(); + this._updateToolsList(); + console.log(`Tool removed by server: ${message.name}`); + } + break; + + case 'removeAllTools': + this.availableTools.clear(); + this.registeredTools.clear(); + this._saveItemsToStorage(); + this._updateToolsList(); + console.log('All tools removed by server'); + break; + + case 'clipboardCopy': + if (message.text && navigator.clipboard) { + navigator.clipboard.writeText(message.text).then(() => { + console.log('Token copiado al portapapeles'); + }).catch(err => { + console.error('Error copiando al portapapeles:', err); + }); + } + break; + + case 'error': + console.error(`Server error: ${message.message}`); + break; + + default: + console.warn(`Unknown message type: ${message.type}`); + } + } + + /** + * Handle createTool request from server (via built-in agregar-tool) + * @private + * @param {Object} message - The parsed message object + */ + _handleCreateTool(message) { + const {id, name, description, code, parametros} = message; + try { + let props = {}; + if (parametros) props = JSON.parse(parametros); + const schema = { type: 'object', properties: props }; + const fn = new Function('args', code); + this.registerTool(name, description, schema, fn); + this._sendMessage({ + id, + type: 'toolResponse', + result: { content: [{ type: 'text', text: `Herramienta "${name}" registrada exitosamente` }] } + }); + console.log(`Tool created by agent: ${name}`); + } catch (e) { + this._sendMessage({ + id, + type: 'toolResponse', + error: `Error creando herramienta: ${e.message}` + }); + } + } + + /** + * Handle tool call from server + * @private + * @param {Object} message - The parsed message object + */ + _handleToolCall(message) { + const {id, tool, arguments: args} = message; + + console.log(`Tool call: ${tool} with args:`, args); + + if (!this.availableTools.has(tool)) { + this._sendMessage({ + id, + type: 'toolResponse', + error: `Tool not found: ${tool}` + }); + return; + } + + // Execute the tool + try { + const toolObj = this.availableTools.get(tool); + + // Normalize result to MCP content format + const wrapResult = (raw) => { + if (raw && raw.content && Array.isArray(raw.content)) return raw; + const text = typeof raw === 'string' ? raw : JSON.stringify(raw); + return { content: [{ type: "text", text }] }; + }; + + // Call the tool's execute function + const result = toolObj.execute(args); + + // Handle promises + if (result instanceof Promise) { + result + .then(resolvedResult => { + this._sendMessage({ + id, + type: 'toolResponse', + result: wrapResult(resolvedResult) + }); + }) + .catch(error => { + this._sendMessage({ + id, + type: 'toolResponse', + error: error.message || 'Tool execution error' + }); + }); + } else { + // Send immediate result + this._sendMessage({ + id, + type: 'toolResponse', + result: wrapResult(result) + }); + } + + console.log(`Tool response sent for ${tool}`); + } catch (error) { + this._sendMessage({ + id, + type: 'toolResponse', + error: error.message || 'Tool execution error' + }); + console.error(`Tool execution error:`, error); + } + } + + /** + * Handle prompt request from server + * @private + * @param {Object} message - The parsed message object + */ + _handleGetPrompt(message) { + const {id, name, arguments: args} = message; + + console.log(`Prompt request: ${name} with args:`, args); + + if (!this.availablePrompts.has(name)) { + this._sendMessage({ + id, + type: 'promptResponse', + error: `Prompt not found: ${name}` + }); + return; + } + + // Execute the prompt + try { + const promptObj = this.availablePrompts.get(name); + + // Call the prompt's execute function + const result = promptObj.execute(args); + + // Handle promises + if (result instanceof Promise) { + result + .then(resolvedResult => { + this._sendMessage({ + id, + type: 'promptResponse', + result: resolvedResult + }); + }) + .catch(error => { + this._sendMessage({ + id, + type: 'promptResponse', + error: error.message || 'Prompt execution error' + }); + }); + } else { + // Send immediate result + this._sendMessage({ + id, + type: 'promptResponse', + result + }); + } + + console.log(`Prompt response sent for ${name}`); + } catch (error) { + this._sendMessage({ + id, + type: 'promptResponse', + error: error.message || 'Prompt execution error' + }); + console.error(`Prompt execution error:`, error); + } + } + + /** + * Handle resource request from server + * @private + * @param {Object} message - The parsed message object + */ + _handleReadResource(message) { + const {id, uri} = message; + + console.log(`Resource request: ${uri}`); + + // Find resource that handles this URI + let resourceObj = null; + + // First check for direct URI match + for (const resource of this.availableResources.values()) { + if (!resource.isTemplate && resource.uri === uri) { + resourceObj = resource; + break; + } + } + + // If no direct match, check for template match + if (!resourceObj) { + for (const resource of this.availableResources.values()) { + if (resource.isTemplate) { + // Simple check - if URI starts with template prefix (before any parameters) + const templatePrefix = resource.uriTemplate.split('{')[0]; + if (uri.startsWith(templatePrefix)) { + resourceObj = resource; + break; + } + } + } + } + + if (!resourceObj) { + this._sendMessage({ + id, + type: 'resourceResponse', + error: `No resource handler found for URI: ${uri}` + }); + return; + } + + // Execute the resource provider + try { + // Call the resource's provide function + const result = resourceObj.provide(uri); + + // Handle promises + if (result instanceof Promise) { + result + .then(resolvedResult => { + this._sendMessage({ + id, + type: 'resourceResponse', + result: resolvedResult + }); + }) + .catch(error => { + this._sendMessage({ + id, + type: 'resourceResponse', + error: error.message || 'Resource read error' + }); + }); + } else { + // Send immediate result + this._sendMessage({ + id, + type: 'resourceResponse', + result + }); + } + + console.log(`Resource response sent for ${uri}`); + } catch (error) { + this._sendMessage({ + id, + type: 'resourceResponse', + error: error.message || 'Resource read error' + }); + console.error(`Resource read error:`, error); + } + } + + /** + * Send available tools list + * @private + * @param {string} requestId - The request ID to respond to + */ + _sendToolsList(requestId) { + const toolsList = Array.from(this.availableTools.values()).map(tool => ({ + name: tool.name, + description: tool.description, + inputSchema: tool.inputSchema, + })); + + this._sendMessage({ + id: requestId, + type: 'listToolsResponse', + tools: toolsList + }); + + console.log(`Sent tools list: ${toolsList.length} tools`); + } + + /** + * Send available prompts list + * @private + * @param {string} requestId - The request ID to respond to + */ + _sendPromptsList(requestId) { + const promptsList = Array.from(this.availablePrompts.values()).map(prompt => ({ + name: prompt.name, + description: prompt.description, + arguments: prompt.arguments, + })); + + this._sendMessage({ + id: requestId, + type: 'listPromptsResponse', + prompts: promptsList + }); + + console.log(`Sent prompts list: ${promptsList.length} prompts`); + } + + /** + * Send available resources list + * @private + * @param {string} requestId - The request ID to respond to + */ + _sendResourcesList(requestId) { + const resources = []; + const resourceTemplates = []; + + // Split resources and templates + this.availableResources.forEach((resource) => { + if (resource.isTemplate) { + resourceTemplates.push({ + name: resource.name, + description: resource.description, + uriTemplate: resource.uriTemplate, + mimeType: resource.mimeType + }); + } else { + resources.push({ + name: resource.name, + description: resource.description, + uri: resource.uri, + mimeType: resource.mimeType + }); + } + }); + + this._sendMessage({ + id: requestId, + type: 'listResourcesResponse', + resources, + resourceTemplates + }); + + console.log(`Sent resources list: ${resources.length} resources, ${resourceTemplates.length} templates`); + } + + /** + * Send a message to the server via direct WebSocket + * @private + * @param {Object} message - The message object to send + */ + _sendMessage(message) { + if (!this.isConnected || !this.socket) { + console.error('Cannot send message: not connected'); + return; + } + + try { + // Send the message directly through the WebSocket + this.socket.send(JSON.stringify(message)); + return Promise.resolve(); + } catch (error) { + console.error(`Error sending message: ${error.message}`); + return Promise.reject(error); + } + } + + /** + * Register all items with server that were registered while disconnected + * @private + */ + _registerItemsWithServer() { + if (!this.isConnected) return; + + // Clear registration tracking sets - we'll re-register everything + this.registeredTools = new Set(); + this.registeredPrompts = new Set(); + this.registeredResources = new Set(); + + // Register all tools with the server + this.availableTools.forEach((tool, name) => { + this._sendMessage({ + type: 'registerTool', + name, + description: tool.description, + inputSchema: tool.inputSchema + }); + + this.registeredTools.add(name); + console.log(`Registering tool with server: ${name}`); + }); + + // Register all prompts with the server + this.availablePrompts.forEach((prompt, name) => { + this._sendMessage({ + type: 'registerPrompt', + name, + description: prompt.description, + arguments: prompt.arguments + }); + + this.registeredPrompts.add(name); + console.log(`Registering prompt with server: ${name}`); + }); + + // Register all resources with the server + this.availableResources.forEach((resource, name) => { + this._sendMessage({ + type: 'registerResource', + name, + description: resource.description, + uri: resource.uri, + uriTemplate: resource.uriTemplate, + isTemplate: resource.isTemplate, + mimeType: resource.mimeType + }); + + this.registeredResources.add(name); + console.log(`Registering resource with server: ${name}`); + }); + } + + /** + * Register a tool + * @public + * @param {string} name - The name of the tool + * @param {string} description - The description of the tool + * @param {Object} schema - The schema for the tool's input + * @param {Function} executeFn - The function to execute when the tool is called + */ + registerTool(name, description, schema, executeFn) { + if (!name) { + console.error('Tool name is required'); + return; + } + + // Add the tool to local registry + this.availableTools.set(name, { + name, + description: description || `Tool: ${name}`, + execute: executeFn || function (args) { + return `Default implementation of ${name} with args: ${JSON.stringify(args)}`; + }, + inputSchema: schema || { + type: "object", + properties: {} + } + }); + + // Register the tool with the server if connected + if (this.isConnected) { + this._sendMessage({ + type: 'registerTool', + name, + description: description || `Tool: ${name}`, + inputSchema: schema || { + type: "object", + properties: {} + }, + }); + + this.registeredTools.add(name); + } + + // Save to session storage + this._saveItemsToStorage(); + + // Update tools display + this._updateToolsList(); + console.log(`Tool registered: ${name}`); + } + + /** + * Unregister a tool + * @public + * @param {string} name - The name of the tool to unregister + */ + unregisterTool(name) { + if (!name) { + console.error('Tool name is required'); + return; + } + + if (!this.availableTools.has(name)) { + console.warn(`Tool not found: ${name}`); + return; + } + + this.availableTools.delete(name); + + if (this.isConnected) { + this._sendMessage({ + type: 'unregisterTool', + name + }); + } + + this.registeredTools.delete(name); + this._saveItemsToStorage(); + this._updateToolsList(); + console.log(`Tool unregistered: ${name}`); + } + + /** + * Unregister all tools at once (single notification) + * @public + */ + unregisterAllTools() { + if (this.availableTools.size === 0) return; + + this.availableTools.clear(); + this.registeredTools.clear(); + + if (this.isConnected) { + this._sendMessage({ type: 'unregisterAllTools' }); + } + + this._saveItemsToStorage(); + this._updateToolsList(); + console.log('All tools unregistered'); + } + + /** + * Register a prompt + * @public + * @param {string} name - The name of the prompt + * @param {string} description - The description of the prompt + * @param {Array} promptArgs - The arguments for the prompt + * @param {Function} executeFn - The function to execute when the prompt is called + */ + registerPrompt(name, description, promptArgs, executeFn) { + if (!name) { + console.error('Prompt name is required'); + return; + } + + // Add the prompt to local registry + this.availablePrompts.set(name, { + name, + description: description || `Prompt: ${name}`, + execute: executeFn || function (args) { + return { + messages: [{ + role: "user", + content: { + type: "text", + text: `Default implementation of prompt ${name} with args: ${JSON.stringify(args)}` + } + }] + }; + }, + arguments: promptArgs || [] + }); + + // Register the prompt with the server if connected + if (this.isConnected) { + this._sendMessage({ + type: 'registerPrompt', + name, + description: description || `Prompt: ${name}`, + arguments: promptArgs || [] + }); + + this.registeredPrompts.add(name); + } + + // Save to session storage + this._saveItemsToStorage(); + + // Update prompts display + this._updatePromptsList(); + console.log(`Prompt registered: ${name}`); + } + + /** + * Unregister a prompt + * @public + * @param {string} name - The name of the prompt to unregister + */ + unregisterPrompt(name) { + if (!name) { + console.error('Prompt name is required'); + return; + } + + if (!this.availablePrompts.has(name)) { + console.warn(`Prompt not found: ${name}`); + return; + } + + this.availablePrompts.delete(name); + + if (this.isConnected) { + this._sendMessage({ + type: 'unregisterPrompt', + name + }); + } + + this.registeredPrompts.delete(name); + this._saveItemsToStorage(); + this._updatePromptsList(); + console.log(`Prompt unregistered: ${name}`); + } + + /** + * Register a resource + * @public + * @param {string} name - The name of the resource + * @param {string} description - The description of the resource + * @param {Object} options - The resource options including uri, uriTemplate, and mimeType + * @param {Function} provideFn - The function to execute when the resource is requested + */ + registerResource(name, description, options, provideFn) { + if (!name) { + console.error('Resource name is required'); + return; + } + + if (!options.uri && !options.uriTemplate) { + console.error('Either uri or uriTemplate is required for a resource'); + return; + } + + const isTemplate = !!options.uriTemplate; + + // Add the resource to local registry + this.availableResources.set(name, { + name, + description: description || `Resource: ${name}`, + uri: options.uri, + uriTemplate: options.uriTemplate, + isTemplate, + mimeType: options.mimeType, + provide: provideFn || function (uri) { + return { + contents: [{ + uri: uri, + text: `Default implementation of resource ${name} for URI: ${uri}`, + mimeType: options.mimeType || "text/plain" + }] + }; + } + }); + + // Register the resource with the server if connected + if (this.isConnected) { + this._sendMessage({ + type: 'registerResource', + name, + description: description || `Resource: ${name}`, + uri: options.uri, + uriTemplate: options.uriTemplate, + isTemplate, + mimeType: options.mimeType + }); + + this.registeredResources.add(name); + } + + // Save to session storage + this._saveItemsToStorage(); + + // Update resources display + this._updateResourcesList(); + console.log(`Resource registered: ${name}`); + } + + /** + * Unregister a resource + * @public + * @param {string} name - The name of the resource to unregister + */ + unregisterResource(name) { + if (!name) { + console.error('Resource name is required'); + return; + } + + if (!this.availableResources.has(name)) { + console.warn(`Resource not found: ${name}`); + return; + } + + this.availableResources.delete(name); + + if (this.isConnected) { + this._sendMessage({ + type: 'unregisterResource', + name + }); + } + + this.registeredResources.delete(name); + this._saveItemsToStorage(); + this._updateResourcesList(); + console.log(`Resource unregistered: ${name}`); + } + + /** + * Handle sampling message creation request + * @private + * @param {Object} message - The parsed message object + */ + _handleCreateSamplingMessage(message) { + const { + id, + messages, + systemPrompt, + includeContext, + temperature, + maxTokens, + stopSequences, + metadata, + modelPreferences + } = message; + + console.log(`Sampling request received with ${messages?.length || 0} messages`); + + // Create a modal dialog to show the sampling request + const modal = document.createElement('div'); + Object.assign(modal.style, { + position: 'fixed', + top: '0', + left: '0', + width: '100%', + height: '100%', + backgroundColor: 'rgba(0, 0, 0, 0.5)', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + zIndex: '10000' + }); + + // Create modal content + const modalContent = document.createElement('div'); + Object.assign(modalContent.style, { + backgroundColor: 'white', + padding: '20px', + borderRadius: '5px', + maxWidth: '500px', + width: '90%', + maxHeight: '80%', + overflow: 'auto' + }); + + // Create header + const header = document.createElement('h3'); + header.textContent = 'Sampling Request'; + Object.assign(header.style, { + margin: '0 0 15px 0', + padding: '0 0 10px 0', + borderBottom: '1px solid #ddd' + }); + + // Create content area to show messages + const content = document.createElement('div'); + Object.assign(content.style, { + marginBottom: '15px', + maxHeight: '300px', + overflow: 'auto', + border: '1px solid #ddd', + padding: '10px', + backgroundColor: '#f9f9f9' + }); + + // Display messages + if (messages && messages.length > 0) { + messages.forEach(msg => { + const msgDiv = document.createElement('div'); + Object.assign(msgDiv.style, { + marginBottom: '10px', + padding: '5px', + borderRadius: '3px', + backgroundColor: msg.role === 'user' ? '#e1f5fe' : '#f1f8e9' + }); + + const roleSpan = document.createElement('strong'); + roleSpan.textContent = msg.role === 'user' ? 'User: ' : 'Assistant: '; + + const contentSpan = document.createElement('span'); + if (msg.content.type === 'text') { + contentSpan.textContent = msg.content.text; + } else if (msg.content.type === 'image') { + contentSpan.textContent = '[Image data]'; + } + + msgDiv.appendChild(roleSpan); + msgDiv.appendChild(contentSpan); + content.appendChild(msgDiv); + }); + } else { + content.textContent = 'No messages provided in sampling request'; + } + + // System prompt if available + if (systemPrompt) { + const sysPromptDiv = document.createElement('div'); + Object.assign(sysPromptDiv.style, { + marginBottom: '10px', + padding: '5px', + backgroundColor: '#fff8e1' + }); + + const sysPromptLabel = document.createElement('strong'); + sysPromptLabel.textContent = 'System Prompt: '; + + const sysPromptContent = document.createElement('span'); + sysPromptContent.textContent = systemPrompt; + + sysPromptDiv.appendChild(sysPromptLabel); + sysPromptDiv.appendChild(sysPromptContent); + content.appendChild(sysPromptDiv); + } + + // Create response input + const responseLabel = document.createElement('label'); + responseLabel.textContent = 'Assistant Response:'; + Object.assign(responseLabel.style, { + display: 'block', + marginBottom: '5px', + fontWeight: 'bold' + }); + + const responseInput = document.createElement('textarea'); + Object.assign(responseInput.style, { + width: '100%', + minHeight: '100px', + padding: '10px', + marginBottom: '15px', + boxSizing: 'border-box' + }); + + // Create buttons + const buttonContainer = document.createElement('div'); + Object.assign(buttonContainer.style, { + display: 'flex', + justifyContent: 'space-between' + }); + + const submitButton = document.createElement('button'); + submitButton.textContent = 'Submit Response'; + Object.assign(submitButton.style, { + padding: '8px 15px', + backgroundColor: '#4CAF50', + color: 'white', + border: 'none', + borderRadius: '4px', + cursor: 'pointer' + }); + + const cancelButton = document.createElement('button'); + cancelButton.textContent = 'Cancel'; + Object.assign(cancelButton.style, { + padding: '8px 15px', + backgroundColor: '#f44336', + color: 'white', + border: 'none', + borderRadius: '4px', + cursor: 'pointer' + }); + + // Add elements to modal + buttonContainer.appendChild(cancelButton); + buttonContainer.appendChild(submitButton); + + modalContent.appendChild(header); + modalContent.appendChild(content); + modalContent.appendChild(responseLabel); + modalContent.appendChild(responseInput); + modalContent.appendChild(buttonContainer); + + modal.appendChild(modalContent); + document.body.appendChild(modal); + + // Focus the response input + responseInput.focus(); + + // Setup button handlers + submitButton.addEventListener('click', () => { + const responseText = responseInput.value.trim(); + if (responseText) { + // Send response back to server + this._sendMessage({ + id, + type: 'samplingResponse', + result: { + model: 'web-user-input', + role: 'assistant', + content: { + type: 'text', + text: responseText + } + } + }); + + // Remove modal + document.body.removeChild(modal); + } else { + alert('Please enter a response'); + } + }); + + cancelButton.addEventListener('click', () => { + // Send error response + this._sendMessage({ + id, + type: 'samplingResponse', + error: 'User cancelled sampling request' + }); + + // Remove modal + document.body.removeChild(modal); + }); + } +} + +// Export for module usage +if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = WebMCP; +} diff --git a/src/websocket-server.js b/src/websocket-server.js new file mode 100644 index 0000000..5da7be4 --- /dev/null +++ b/src/websocket-server.js @@ -0,0 +1,1830 @@ +import * as fs from 'fs/promises'; +import {WebSocketServer, WebSocket} from 'ws'; +import {createServer} from 'http'; +import {parse} from 'url'; +import {fork} from 'child_process'; +import {runMcpServer} from './server.js'; +import { + clearTokens, + deleteToken, generateNewRegistrationToken, + generateToken, + getToken, + loadAuthorizedTokens, + saveAuthorizedTokens, saveServerTokenToEnv, + setToken +} from "./tokens.js"; +import { + CONFIG, + HOST, + PID_FILE, + SERVER_TOKEN, + ensureConfigDir, + formatChannel, + setConfig, + configureMcpClient, +} from './config.js'; + +let serverToken = SERVER_TOKEN; + +// Create HTTP server with CORS headers +const httpServer = createServer((req, res) => { + // Set CORS headers + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + // Handle preflight requests + res.writeHead(204); + res.end(); + return; + } + + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('MCP WebSocket server is running'); +}); + +// Create WebSocket server instance +const wss = new WebSocketServer({ + server: httpServer, + clientTracking: true, + verifyClient: verifyClientToken +}); + +// Store active WebSocket connections by channel +const channels = {}; + +// Special channel paths +const MCP_PATH = '/mcp'; +const REGISTER_PATH = '/register'; + +// Function to send notifications to a client and MCP (if connected) +function sendNotification(clientWs, channelPath, notificationType, data, mcpOnly = false) { + // Send to the client that initiated the action + if (clientWs && clientWs.readyState === WebSocket.OPEN) { + if (!mcpOnly) { + clientWs.send(JSON.stringify({ + type: notificationType, + ...data + })); + } + } + + // Also send to MCP if connected + if (channels[MCP_PATH] && channels[MCP_PATH].size > 0) { + channels[MCP_PATH].values().forEach((mcpClient) => { + if (mcpClient && mcpClient.readyState === WebSocket.OPEN) { + // For MCP, prefix names with the channel path + const mcpData = {...data}; + if (mcpData.name && channelPath) { + mcpData.name = `${channelPath.slice(1)}-${mcpData.name}`; + } + + mcpClient.send(JSON.stringify({ + type: notificationType, + ...mcpData + })); + } + }); + } +} + +// Track all available tools, prompts, and resources across all channels +const toolsRegistry = {}; +const promptsRegistry = {}; +const resourcesRegistry = {}; + +// Request counter for unique IDs +let requestIdCounter = 1; + +// Map to store pending requests +const pendingRequests = {}; + + +// Function to verify client token during WebSocket handshake +async function verifyClientToken(info, callback) { + const url = new URL(`https://${HOST}${info.req.url}`); + const clientToken = url.searchParams.get('token'); + const path = url.pathname || '/'; + + // Special case for MCP path - use server token from .env + if (path === MCP_PATH) { + // For MCP connections, we use the token from the .env file + if (clientToken === process.env.WEBMCP_SERVER_TOKEN) { + return callback(true); + } + console.error('Invalid MCP token provided'); + return callback(false, 401, 'Unauthorized - Invalid MCP token'); + } + + // Special case for registration path - allow all connections for now + // The actual authorization will happen in the connection handler + if (path === REGISTER_PATH) { + return callback(true); + } + + // For other paths, check if the channel-token pair is authorized + if (!clientToken) { + console.error('No token provided for path:', path); + return callback(false, 401, 'Unauthorized - No token provided'); + } + + await loadAuthorizedTokens(); + + // Check if this channel has a valid token and it matches + if (getToken(path) === clientToken) { + return callback(true); + } + + console.error(`Unauthorized connection attempt to ${path}`); + return callback(false, 401, 'Unauthorized - Invalid channel-token pair'); +} + +// Helper function to get or create a channel +function getOrCreateChannel(channelPath) { + if (!channels[channelPath]) { + channels[channelPath] = new Set(); + console.error(`Created new channel for path: ${channelPath}`); + } else if (channels[channelPath].closeTimeout) { + // Clear the timeout if it exists (someone is joining an empty channel) + clearTimeout(channels[channelPath].closeTimeout); + delete channels[channelPath].closeTimeout; + console.error(`Cancelled channel closure for ${channelPath} as a new client connected`); + } + return channels[channelPath]; +} + +// Handle WebSocket connections +wss.on('connection', (ws, req) => { + // Extract the path from the URL + const parsedUrl = parse(req.url); + const path = parsedUrl.pathname; + + // Set channel based on connection path + const clientChannel = path || '/'; + + console.error(`Client connected from ${req.socket.remoteAddress} to path: ${clientChannel}`); + + // Special handling for registration endpoint + if (clientChannel === REGISTER_PATH) { + console.error(`Registration request received from ${req.socket.remoteAddress}`); + + // Wait for the first message which should contain the registration data + let registrationTimeout = setTimeout(() => { + console.error('Registration timeout - closing connection'); + ws.close(1008, 'Registration timeout'); + }, 30000); // 30 second timeout + + // Register message handler specifically for registration + ws.once('message', async (message) => { + clearTimeout(registrationTimeout); + + try { + // The message should be base64 encoded JSON with server and token + const encodedData = message.toString(); + const decodedJson = Buffer.from(encodedData, 'base64').toString('utf8'); + const connectionData = JSON.parse(decodedJson); + + const {host, token} = connectionData; + + if (!token) { + console.error('Invalid registration data format - missing token'); + ws.send(JSON.stringify({ + type: 'error', + message: 'Invalid registration data format - missing token' + })); + ws.close(1008, 'Invalid registration data'); + return; + } + + // Format the channel path (replace : with _) + const channelPath = formatChannel(host); + + // Check if this is a valid token from a "--new" command + if (!token || token.length < 16) { + console.error('Invalid token provided'); + ws.send(JSON.stringify({ + type: 'error', + message: 'Invalid token provided' + })); + ws.close(1008, 'Invalid token'); + return; + } + + const serverChannel = formatChannel(`${HOST}:${CONFIG.port}`); + + await loadAuthorizedTokens(); + if (token !== getToken(serverChannel)) { + console.error('Invalid token provided'); + ws.send(JSON.stringify({ + type: 'error', + message: 'Invalid token provided' + })); + ws.close(1008, 'Invalid token'); + return; + } + + // Throw away registration token and make a session token. + deleteToken(serverChannel); + const sessionToken = generateToken(); + + // Authorize the channel-token pair + setToken(channelPath, sessionToken); + await saveAuthorizedTokens(); + + // Send success response + ws.send(JSON.stringify({ + type: 'registerSuccess', + channel: channelPath, + message: `Registration successful for ${channelPath}`, + token: sessionToken + })); + + console.error(`Registered channel: ${channelPath} with token: ${token}`); + + // Close the registration connection - they'll reconnect to their channel + ws.close(1000, 'Registration complete'); + } catch (error) { + console.error('Registration error:', error); + ws.send(JSON.stringify({ + type: 'error', + message: 'Registration error' + })); + ws.close(1011, 'Registration error'); + } + }); + + return; // Don't proceed with the normal connection handling + } + + // Add client to the channel based on path (for non-registration paths) + const channel = getOrCreateChannel(clientChannel); + channel.add(ws); + + // Send welcome message with channel info + ws.send(JSON.stringify({ + type: 'welcome', + channel: clientChannel, + message: `Connected to path: ${clientChannel}` + })); + + // Handle incoming messages + ws.on('message', (message) => { + try { + const data = JSON.parse(message); + console.error(`Received message: ${data.type} on ${clientChannel}`); + + // Process message based on type + switch (data.type) { + case 'ping': + handlePing(ws, data); + break; + + case 'registerTool': + handleRegisterTool(ws, clientChannel, data); + break; + + case 'registerPrompt': + handleRegisterPrompt(ws, clientChannel, data); + break; + + case 'registerResource': + handleRegisterResource(ws, clientChannel, data); + break; + + case 'unregisterTool': + handleUnregisterTool(ws, clientChannel, data); + break; + + case 'unregisterPrompt': + handleUnregisterPrompt(ws, clientChannel, data); + break; + + case 'unregisterResource': + handleUnregisterResource(ws, clientChannel, data); + break; + + case 'unregisterAllTools': + handleUnregisterAllTools(ws, clientChannel); + break; + + case 'listTools': + handleListTools(ws, clientChannel, data); + break; + + case 'listPrompts': + handleListPrompts(ws, clientChannel, data); + break; + + case 'listResources': + handleListResources(ws, clientChannel, data); + break; + + case 'callTool': + handleCallTool(ws, clientChannel, data); + break; + + case 'getPrompt': + handleGetPrompt(ws, clientChannel, data); + break; + + case 'readResource': + handleReadResource(ws, clientChannel, data); + break; + + case 'createSamplingMessage': + handleCreateSamplingMessage(ws, clientChannel, data); + break; + + case 'toolResponse': + handleToolResponse(data); + break; + + case 'promptResponse': + handlePromptResponse(data); + break; + + case 'resourceResponse': + handleResourceResponse(data); + break; + + case 'samplingResponse': + handleSamplingResponse(data); + break; + + case 'clipboardCopy': + handleClipboardCopy(data); + break; + + case 'clearRegistry': + handleClearRegistry(ws, data); + break; + + case 'createTool': + handleCreateTool(ws, data); + break; + + case 'removeTool': + handleRemoveTool(ws, data); + break; + + default: + ws.send(JSON.stringify({ + type: 'error', + message: `Unknown message type: ${data.type}` + })); + } + } catch (error) { + console.error('Error processing WebSocket message:', error); + try { + ws.send(JSON.stringify({ + type: 'error', + message: 'Invalid message format' + })); + } catch (sendError) { + console.error('Error sending error response:', sendError); + } + } + }); + + // Handle disconnection + ws.on('close', async () => { + console.error(`Client disconnected from path: ${clientChannel}`); + + // Remove from channel + const channel = channels[clientChannel]; + if (channel) { + channel.delete(ws); + + // Set a timer to clean up empty channels after 1 minute + if (channel.size === 0) { + console.error(`Channel ${clientChannel} is empty, will close in 1 minute if no one joins`); + + // Store the timeout in the channel object so we can clear it if needed + channel.closeTimeout = setTimeout(async () => { + // Check if the channel is still empty after 1 minute + if (channels[clientChannel] && channels[clientChannel].size === 0) { + delete channels[clientChannel]; + console.error(`Removed empty channel for path: ${clientChannel} after 1 minute inactivity`); + + // Clean up tools, prompts, and resources for this channel + const itemsToRemove = { + tools: [], + prompts: [], + resources: [] + }; + + for (const [toolId, toolInfo] of Object.entries(toolsRegistry)) { + if (toolInfo.channel === clientChannel) { + itemsToRemove.tools.push(toolId); + } + } + + for (const [promptId, promptInfo] of Object.entries(promptsRegistry)) { + if (promptInfo.channel === clientChannel) { + itemsToRemove.prompts.push(promptId); + } + } + + for (const [resourceId, resourceInfo] of Object.entries(resourcesRegistry)) { + if (resourceInfo.channel === clientChannel) { + itemsToRemove.resources.push(resourceId); + } + } + + itemsToRemove.tools.forEach(toolId => { + delete toolsRegistry[toolId]; + console.error(`Removed tool: ${toolId} from path: ${clientChannel}`); + }); + + itemsToRemove.prompts.forEach(promptId => { + delete promptsRegistry[promptId]; + console.error(`Removed prompt: ${promptId} from path: ${clientChannel}`); + }); + + itemsToRemove.resources.forEach(resourceId => { + delete resourcesRegistry[resourceId]; + console.error(`Removed resource: ${resourceId} from path: ${clientChannel}`); + }); + + // Remove the authorized token for this channel if not MCP + if (clientChannel !== MCP_PATH) { + deleteToken(clientChannel); + await saveAuthorizedTokens(); + console.error(`Removed authorized token for channel: ${clientChannel}`); + } + + // Update them all + sendNotification(ws, undefined, 'toolRegistered', {}, true); + sendNotification(ws, undefined, 'promptRegistered', {}, true); + sendNotification(ws, undefined, 'resourceRegistered', {}, true); + } + }, 60000); // 1 minute timeout + } + } + }); + + // Handle errors + ws.on('error', (error) => { + console.error('WebSocket error:', error); + + // Remove from channel + const channel = channels[clientChannel]; + if (channel) { + channel.delete(ws); + } + }); +}); + +// Handle ping messages +function handlePing(ws, data) { + ws.send(JSON.stringify({ + id: data.id, + type: 'pong', + timestamp: Date.now() + })); +} + +// Handle tool registration +function handleRegisterTool(ws, channelPath, data) { + const {name, description, inputSchema} = data; + + if (!name) { + ws.send(JSON.stringify({ + type: 'error', + message: 'Tool name is required' + })); + return; + } + + // Create a unique tool ID for internal tracking + const toolId = `${channelPath.slice(1)}-${name}`; + + // Register the tool + toolsRegistry[toolId] = { + channel: channelPath, + name, + description: description || `Tool: ${name}`, + inputSchema, + originalName: name + }; + + // Send registration notification to both client and MCP + sendNotification(ws, channelPath, 'toolRegistered', { + name, + toolId + }); + + console.error(`Tool registered: ${toolId}`); +} + +// Handle prompt registration +function handleRegisterPrompt(ws, channelPath, data) { + const {name, description, arguments: promptArgs} = data; + + if (!name) { + ws.send(JSON.stringify({ + type: 'error', + message: 'Prompt name is required' + })); + return; + } + + // Create a unique prompt ID for internal tracking + const promptId = `${channelPath.slice(1)}-${name}`; + + // Register the prompt + promptsRegistry[promptId] = { + channel: channelPath, + name, + description: description || `Prompt: ${name}`, + arguments: promptArgs || [], + originalName: name + }; + + // Send registration notification to both client and MCP + sendNotification(ws, channelPath, 'promptRegistered', { + name, + promptId + }); + + console.error(`Prompt registered: ${promptId}`); +} + +// Handle resource registration +function handleRegisterResource(ws, channelPath, data) { + const {uri, name, description, mimeType, isTemplate, uriTemplate} = data; + + if ((!uri && !uriTemplate) || !name) { + ws.send(JSON.stringify({ + type: 'error', + message: 'Resource URI/template and name are required' + })); + return; + } + + // Create a unique resource ID for internal tracking + const resourceId = `${channelPath.slice(1)}-${name}`; + + // Register the resource + resourcesRegistry[resourceId] = { + channel: channelPath, + name, + description: description || `Resource: ${name}`, + uri: uri, + uriTemplate: uriTemplate, + isTemplate: !!isTemplate, + mimeType, + originalName: name + }; + + // Send registration notification to both client and MCP + sendNotification(ws, channelPath, 'resourceRegistered', { + name, + resourceId + }); + + console.error(`Resource registered: ${resourceId}`); +} + +// Handle tool unregistration +function handleUnregisterTool(ws, channelPath, data) { + const {name} = data; + + if (!name) { + ws.send(JSON.stringify({ + type: 'error', + message: 'Tool name is required' + })); + return; + } + + const toolId = `${channelPath.slice(1)}-${name}`; + + if (!toolsRegistry[toolId]) { + ws.send(JSON.stringify({ + type: 'error', + message: `Tool not found: ${name}` + })); + return; + } + + delete toolsRegistry[toolId]; + + sendNotification(ws, channelPath, 'toolRegistered', { + name, + toolId + }); + + console.error(`Tool unregistered: ${toolId}`); +} + +// Handle prompt unregistration +function handleUnregisterPrompt(ws, channelPath, data) { + const {name} = data; + + if (!name) { + ws.send(JSON.stringify({ + type: 'error', + message: 'Prompt name is required' + })); + return; + } + + const promptId = `${channelPath.slice(1)}-${name}`; + + if (!promptsRegistry[promptId]) { + ws.send(JSON.stringify({ + type: 'error', + message: `Prompt not found: ${name}` + })); + return; + } + + delete promptsRegistry[promptId]; + + sendNotification(ws, channelPath, 'promptRegistered', { + name, + promptId + }); + + console.error(`Prompt unregistered: ${promptId}`); +} + +// Handle resource unregistration +function handleUnregisterResource(ws, channelPath, data) { + const {name} = data; + + if (!name) { + ws.send(JSON.stringify({ + type: 'error', + message: 'Resource name is required' + })); + return; + } + + const resourceId = `${channelPath.slice(1)}-${name}`; + + if (!resourcesRegistry[resourceId]) { + ws.send(JSON.stringify({ + type: 'error', + message: `Resource not found: ${name}` + })); + return; + } + + delete resourcesRegistry[resourceId]; + + sendNotification(ws, channelPath, 'resourceRegistered', { + name, + resourceId + }); + + console.error(`Resource unregistered: ${resourceId}`); +} + +// Handle batch unregistration of all tools for a channel +function handleUnregisterAllTools(ws, channelPath) { + const removed = []; + for (const [toolId, toolInfo] of Object.entries(toolsRegistry)) { + if (toolInfo.channel === channelPath) { + removed.push(toolId); + } + } + + removed.forEach(toolId => { + delete toolsRegistry[toolId]; + }); + + if (removed.length > 0) { + sendNotification(ws, channelPath, 'toolRegistered', {}, true); + console.error(`Batch unregistered ${removed.length} tools from ${channelPath}`); + } +} + +// Handle createTool - forward to web clients to create and register +function handleCreateTool(ws, data) { + const {id, name, description, code, parametros} = data; + + // Find a web client to forward to + let targetClient = null; + let targetChannel = null; + for (const [channelPath, clients] of Object.entries(channels)) { + if (channelPath === MCP_PATH) continue; + if (clients.size > 0) { + targetClient = clients.values().next().value; + targetChannel = channelPath; + break; + } + } + + if (!targetClient) { + ws.send(JSON.stringify({ + id, + type: 'toolResponse', + error: 'No hay navegadores conectados para crear la herramienta' + })); + return; + } + + const requestId = (requestIdCounter++).toString(); + pendingRequests[requestId] = { originalId: id, requesterWs: ws, timestamp: Date.now() }; + + setTimeout(() => { + if (pendingRequests[requestId]) { + const {requesterWs, originalId} = pendingRequests[requestId]; + delete pendingRequests[requestId]; + try { + requesterWs.send(JSON.stringify({ id: originalId, type: 'toolResponse', error: 'Timeout creando herramienta' })); + } catch (e) {} + } + }, 15000); + + targetClient.send(JSON.stringify({ + id: requestId, + type: 'createTool', + name, description, code, parametros + })); + + console.error(`createTool forwarded to ${targetChannel}: ${name}`); +} + +// Handle removeTool - list or remove tools from registry +function handleRemoveTool(ws, data) { + const {id, name, listar, todas} = data; + + if (listar) { + const tools = Object.entries(toolsRegistry) + .filter(([_, info]) => info.channel !== MCP_PATH) + .map(([toolId, info]) => info.originalName); + const msg = tools.length > 0 ? `Herramientas activas: ${tools.join(', ')}` : 'No hay herramientas registradas'; + ws.send(JSON.stringify({ id, type: 'toolResponse', result: { content: [{ type: 'text', text: msg }] } })); + return; + } + + if (todas) { + let count = 0; + for (const [toolId, info] of Object.entries(toolsRegistry)) { + if (info.channel !== MCP_PATH) { + delete toolsRegistry[toolId]; + count++; + } + } + // Notify web clients + for (const [channelPath, clients] of Object.entries(channels)) { + if (channelPath === MCP_PATH) continue; + clients.forEach(c => { + if (c.readyState === WebSocket.OPEN) { + c.send(JSON.stringify({ type: 'removeAllTools' })); + } + }); + } + ws.send(JSON.stringify({ id, type: 'toolResponse', result: { content: [{ type: 'text', text: `${count} herramientas desregistradas` }] } })); + return; + } + + if (!name) { + ws.send(JSON.stringify({ id, type: 'toolResponse', error: 'Especifica nombre, listar=true, o todas=true' })); + return; + } + + // Find and remove by originalName + let found = false; + for (const [toolId, info] of Object.entries(toolsRegistry)) { + if (info.originalName === name) { + const channel = info.channel; + delete toolsRegistry[toolId]; + found = true; + // Notify web client + if (channels[channel]) { + channels[channel].forEach(c => { + if (c.readyState === WebSocket.OPEN) { + c.send(JSON.stringify({ type: 'removeTool', name })); + } + }); + } + break; + } + } + + if (found) { + ws.send(JSON.stringify({ id, type: 'toolResponse', result: { content: [{ type: 'text', text: `Herramienta "${name}" desregistrada` }] } })); + } else { + ws.send(JSON.stringify({ id, type: 'toolResponse', error: `Herramienta "${name}" no encontrada` })); + } +} + +// Handle clearing all registries +function handleClearRegistry(ws, data) { + const {id} = data; + let toolCount = Object.keys(toolsRegistry).length; + let promptCount = Object.keys(promptsRegistry).length; + let resourceCount = Object.keys(resourcesRegistry).length; + + for (const key of Object.keys(toolsRegistry)) delete toolsRegistry[key]; + for (const key of Object.keys(promptsRegistry)) delete promptsRegistry[key]; + for (const key of Object.keys(resourcesRegistry)) delete resourcesRegistry[key]; + + const msg = `Cache limpiado: ${toolCount} tools, ${promptCount} prompts, ${resourceCount} resources eliminados`; + console.error(msg); + + ws.send(JSON.stringify({ + id, + type: 'toolResponse', + result: msg + })); +} + +// Handle clipboard copy - broadcast to all non-MCP channels +function handleClipboardCopy(data) { + const {text} = data; + if (!text) return; + + for (const [channelPath, channelClients] of Object.entries(channels)) { + if (channelPath === MCP_PATH) continue; + channelClients.forEach(client => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify({ + type: 'clipboardCopy', + text + })); + } + }); + } + console.error(`Clipboard copy broadcasted to web clients`); +} + +// Handle list tools requests +function handleListTools(ws, clientChannel, data) { + const {id} = data; + + // Special handling if the request is from the MCP client + const isMcpClient = (clientChannel === MCP_PATH); + + let tools; + + if (isMcpClient) { + // For MCP clients, return all tools across all paths with path prefixes + tools = Object.entries(toolsRegistry).map(([toolId, toolInfo]) => { + // Create a path-based fully qualified name - combine path and tool name + const pathBasedName = `${toolInfo.channel.slice(1)}-${toolInfo.originalName}`; + return { + name: pathBasedName, + description: toolInfo.description, + inputSchema: toolInfo.inputSchema, + }; + }); + console.error(`Sending all ${tools.length} tools to MCP client on path ${clientChannel}`); + } else { + // For regular clients, return only their own tools without path prefixes + tools = Object.entries(toolsRegistry) + .filter(([_, toolInfo]) => toolInfo.channel === clientChannel) + .map(([_, toolInfo]) => ({ + name: toolInfo.originalName, + description: toolInfo.description, + inputSchema: toolInfo.inputSchema, + })); + console.error(`Sending ${tools.length} tools from path ${clientChannel}`); + } + + ws.send(JSON.stringify({ + id, + type: 'listToolsResponse', + tools + })); +} + +// Handle list prompts requests +function handleListPrompts(ws, clientChannel, data) { + const {id} = data; + + // Special handling if the request is from the MCP client + const isMcpClient = (clientChannel === MCP_PATH); + + let prompts; + + if (isMcpClient) { + // For MCP clients, return all prompts across all paths with path prefixes + prompts = Object.entries(promptsRegistry).map(([promptId, promptInfo]) => { + // Create a path-based fully qualified name - combine path and prompt name + const pathBasedName = `${promptInfo.channel.slice(1)}-${promptInfo.originalName}`; + return { + name: pathBasedName, + description: promptInfo.description, + arguments: promptInfo.arguments, + }; + }); + console.error(`Sending all ${prompts.length} prompts to MCP client on path ${clientChannel}`); + } else { + // For regular clients, return only their own prompts without path prefixes + prompts = Object.entries(promptsRegistry) + .filter(([_, promptInfo]) => promptInfo.channel === clientChannel) + .map(([_, promptInfo]) => ({ + name: promptInfo.originalName, + description: promptInfo.description, + arguments: promptInfo.arguments, + })); + console.error(`Sending ${prompts.length} prompts from path ${clientChannel}`); + } + + ws.send(JSON.stringify({ + id, + type: 'listPromptsResponse', + prompts + })); +} + +// Handle list resources requests +function handleListResources(ws, clientChannel, data) { + const {id} = data; + + // Special handling if the request is from the MCP client + const isMcpClient = (clientChannel === MCP_PATH); + + let resources = []; + let resourceTemplates = []; + + if (isMcpClient) { + // For MCP clients, return all resources across all paths with path prefixes + Object.entries(resourcesRegistry).forEach(([resourceId, resourceInfo]) => { + // Create a path-based fully qualified name - combine path and resource name + const pathBasedName = `${resourceInfo.channel.slice(1)}-${resourceInfo.originalName}`; + + if (resourceInfo.isTemplate) { + resourceTemplates.push({ + name: pathBasedName, + description: resourceInfo.description, + uriTemplate: resourceInfo.uriTemplate, + mimeType: resourceInfo.mimeType, + }); + } else { + resources.push({ + name: pathBasedName, + description: resourceInfo.description, + uri: resourceInfo.uri, + mimeType: resourceInfo.mimeType, + }); + } + }); + console.error(`Sending all ${resources.length} resources and ${resourceTemplates.length} templates to MCP client on path ${clientChannel}`); + } else { + // For regular clients, return only their own resources without path prefixes + Object.entries(resourcesRegistry) + .filter(([_, resourceInfo]) => resourceInfo.channel === clientChannel) + .forEach(([_, resourceInfo]) => { + if (resourceInfo.isTemplate) { + resourceTemplates.push({ + name: resourceInfo.originalName, + description: resourceInfo.description, + uriTemplate: resourceInfo.uriTemplate, + mimeType: resourceInfo.mimeType, + }); + } else { + resources.push({ + name: resourceInfo.originalName, + description: resourceInfo.description, + uri: resourceInfo.uri, + mimeType: resourceInfo.mimeType, + }); + } + }); + console.error(`Sending ${resources.length} resources and ${resourceTemplates.length} templates from path ${clientChannel}`); + } + + ws.send(JSON.stringify({ + id, + type: 'listResourcesResponse', + resources, + resourceTemplates + })); +} + +// Handle tool call requests +function handleCallTool(ws, callerChannel, data) { + const {id, tool, arguments: args} = data; + + // Special handling if the caller is on the MCP path + const isMcpClient = (callerChannel === MCP_PATH); + + // If the caller is MCP, the tool name might include a path prefix + let targetChannel; + let toolName; + + if (isMcpClient && tool.startsWith('/')) { + // Extract the path and tool name from the fully qualified name + [targetChannel, toolName] = tool.slice(1).split("-").slice(1); + targetChannel = `/${targetChannel}`; + } else { + // Check if the tool exists in the registry + if (!toolsRegistry[tool]) { + ws.send(JSON.stringify({ + id, + type: 'toolResponse', + error: `Tool not found: ${tool}` + })); + return; + } + + const toolInfo = toolsRegistry[tool]; + targetChannel = toolInfo.channel; + toolName = toolInfo.originalName; + } + + // Get the target channel + if (!channels[targetChannel] || channels[targetChannel].size === 0) { + ws.send(JSON.stringify({ + id, + type: 'toolResponse', + error: `No clients available in channel ${targetChannel} to handle tool: ${toolName}` + })); + return; + } + + // Pick the first client in the target channel (you could implement more sophisticated routing) + const targetClient = channels[targetChannel].values().next().value; + + // Create a unique request ID for tracking + const requestId = (requestIdCounter++).toString(); + + // Store the pending request + pendingRequests[requestId] = { + originalId: id, + requesterWs: ws, + timestamp: Date.now() + }; + + // Set up timeout for the request + setTimeout(() => { + if (pendingRequests[requestId]) { + const {requesterWs, originalId} = pendingRequests[requestId]; + delete pendingRequests[requestId]; + + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'toolResponse', + error: `Tool call timed out: ${toolName}` + })); + } catch (error) { + console.error('Error sending timeout response:', error); + } + } + }, 30000); // 30 second timeout + + // Send the request to the target client + targetClient.send(JSON.stringify({ + id: requestId, + type: 'callTool', + tool: toolName, // Send just the tool name without channel prefix + arguments: args + })); + + console.error(`Tool call forwarded: ${toolName} to channel: ${targetChannel}`); +} + +// Handle get prompt requests +function handleGetPrompt(ws, callerChannel, data) { + const {id, name, arguments: args} = data; + + // Special handling if the caller is on the MCP path + const isMcpClient = (callerChannel === MCP_PATH); + + // If the caller is MCP, the prompt name might include a path prefix + let targetChannel; + let promptName; + + if (isMcpClient && name.startsWith('/')) { + // Extract the path and prompt name from the fully qualified name + [targetChannel, promptName] = name.slice(1).split("-").slice(1); + targetChannel = `/${targetChannel}`; + } else { + // Check if the prompt exists in the registry + const promptInfo = Object.values(promptsRegistry).find(p => + p.channel === callerChannel && p.originalName === name); + + if (!promptInfo) { + ws.send(JSON.stringify({ + id, + type: 'promptResponse', + error: `Prompt not found: ${name}` + })); + return; + } + + targetChannel = promptInfo.channel; + promptName = promptInfo.originalName; + } + + // Get the target channel + if (!channels[targetChannel] || channels[targetChannel].size === 0) { + ws.send(JSON.stringify({ + id, + type: 'promptResponse', + error: `No clients available in channel ${targetChannel} to handle prompt: ${promptName}` + })); + return; + } + + // Pick the first client in the target channel + const targetClient = channels[targetChannel].values().next().value; + + // Create a unique request ID for tracking + const requestId = (requestIdCounter++).toString(); + + // Store the pending request + pendingRequests[requestId] = { + originalId: id, + requesterWs: ws, + timestamp: Date.now() + }; + + // Set up timeout for the request + setTimeout(() => { + if (pendingRequests[requestId]) { + const {requesterWs, originalId} = pendingRequests[requestId]; + delete pendingRequests[requestId]; + + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'promptResponse', + error: `Prompt request timed out: ${promptName}` + })); + } catch (error) { + console.error('Error sending timeout response:', error); + } + } + }, 30000); // 30 second timeout + + // Send the request to the target client + targetClient.send(JSON.stringify({ + id: requestId, + type: 'getPrompt', + name: promptName, + arguments: args + })); + + console.error(`Prompt request forwarded: ${promptName} to channel: ${targetChannel}`); +} + +// Handle read resource requests +function handleReadResource(ws, callerChannel, data) { + const {id, uri} = data; + + // Find the resource that matches this URI + let targetChannel; + let resourceName; + let resourceInfo; + + // First, try to find an exact match for the URI + for (const [resId, info] of Object.entries(resourcesRegistry)) { + if (!info.isTemplate && info.uri === uri) { + resourceInfo = info; + targetChannel = info.channel; + resourceName = info.originalName; + break; + } + } + + // If no exact match, check for templates + if (!resourceInfo) { + // This is a simplistic approach; a real implementation would properly parse the URI template + for (const [resId, info] of Object.entries(resourcesRegistry)) { + if (info.isTemplate && uri.startsWith(info.uriTemplate.split('{')[0])) { + resourceInfo = info; + targetChannel = info.channel; + resourceName = info.originalName; + break; + } + } + } + + if (!resourceInfo) { + ws.send(JSON.stringify({ + id, + type: 'resourceResponse', + error: `Resource not found for URI: ${uri}` + })); + return; + } + + // Get the target channel + if (!channels[targetChannel] || channels[targetChannel].size === 0) { + ws.send(JSON.stringify({ + id, + type: 'resourceResponse', + error: `No clients available in channel ${targetChannel} to handle resource: ${resourceName}` + })); + return; + } + + // Pick the first client in the target channel + const targetClient = channels[targetChannel].values().next().value; + + // Create a unique request ID for tracking + const requestId = (requestIdCounter++).toString(); + + // Store the pending request + pendingRequests[requestId] = { + originalId: id, + requesterWs: ws, + timestamp: Date.now() + }; + + // Set up timeout for the request + setTimeout(() => { + if (pendingRequests[requestId]) { + const {requesterWs, originalId} = pendingRequests[requestId]; + delete pendingRequests[requestId]; + + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'resourceResponse', + error: `Resource request timed out: ${uri}` + })); + } catch (error) { + console.error('Error sending timeout response:', error); + } + } + }, 30000); // 30 second timeout + + // Send the request to the target client + targetClient.send(JSON.stringify({ + id: requestId, + type: 'readResource', + uri: uri + })); + + console.error(`Resource request forwarded: ${uri} to channel: ${targetChannel}`); +} + +// Handle tool response +function handleToolResponse(data) { + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (!pendingRequests[id]) { + console.error(`No pending request found for ID: ${id}`); + return; + } + + // Get the original requester information + const {requesterWs, originalId} = pendingRequests[id]; + delete pendingRequests[id]; + + // Forward the response to the original requester + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'toolResponse', + result: result, + error: error + })); + } catch (error) { + console.error('Error forwarding tool response:', error); + } +} + +// Handle prompt response +function handlePromptResponse(data) { + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (!pendingRequests[id]) { + console.error(`No pending request found for ID: ${id}`); + return; + } + + // Get the original requester information + const {requesterWs, originalId} = pendingRequests[id]; + delete pendingRequests[id]; + + // Forward the response to the original requester + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'promptResponse', + result: result, + error: error + })); + } catch (error) { + console.error('Error forwarding prompt response:', error); + } +} + +// Handle resource response +function handleResourceResponse(data) { + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (!pendingRequests[id]) { + console.error(`No pending request found for ID: ${id}`); + return; + } + + // Get the original requester information + const {requesterWs, originalId} = pendingRequests[id]; + delete pendingRequests[id]; + + // Forward the response to the original requester + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'resourceResponse', + result: result, + error: error + })); + } catch (error) { + console.error('Error forwarding resource response:', error); + } +} + +// Handle sampling response +function handleSamplingResponse(data) { + const {id, result, error} = data; + + // Check if this is a response to a pending request + if (!pendingRequests[id]) { + console.error(`No pending request found for ID: ${id}`); + return; + } + + // Get the original requester information + const {requesterWs, originalId} = pendingRequests[id]; + delete pendingRequests[id]; + + // Forward the response to the original requester + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'samplingResponse', + result: result, + error: error + })); + } catch (error) { + console.error('Error forwarding sampling response:', error); + } +} + +// Handle create sampling message +function handleCreateSamplingMessage(ws, callerChannel, data) { + const { + id, + messages, + systemPrompt, + includeContext, + temperature, + maxTokens, + stopSequences, + metadata, + modelPreferences + } = data; + + // Special handling if the caller is on the MCP path + const isMcpClient = (callerChannel === MCP_PATH); + + // For non-MCP clients or if no client is available in any channel + if (!isMcpClient) { + ws.send(JSON.stringify({ + id, + type: 'samplingResponse', + error: `Sampling is only available through MCP path` + })); + return; + } + + // Find a client that can handle sampling - target the first available client + let targetClient = null; + let targetChannel = null; + + // Iterate through all channels to find one with clients + for (const [channel, clients] of Object.entries(channels)) { + if (channel !== MCP_PATH && clients.size > 0) { + targetClient = clients.values().next().value; + targetChannel = channel; + break; + } + } + + if (!targetClient) { + ws.send(JSON.stringify({ + id, + type: 'samplingResponse', + error: 'No clients available to handle sampling request' + })); + return; + } + + // Create a unique request ID for tracking + const requestId = (requestIdCounter++).toString(); + + // Store the pending request + pendingRequests[requestId] = { + originalId: id, + requesterWs: ws, + timestamp: Date.now() + }; + + // Set up timeout for the request (longer timeout for sampling) + setTimeout(() => { + if (pendingRequests[requestId]) { + const {requesterWs, originalId} = pendingRequests[requestId]; + delete pendingRequests[requestId]; + + try { + requesterWs.send(JSON.stringify({ + id: originalId, + type: 'samplingResponse', + error: 'Sampling request timed out' + })); + } catch (error) { + console.error('Error sending timeout response:', error); + } + } + }, 120000); // 120 second timeout for sampling + + // Forward the request to the target client + targetClient.send(JSON.stringify({ + id: requestId, + type: 'createSamplingMessage', + messages, + systemPrompt, + includeContext, + temperature, + maxTokens, + stopSequences, + metadata, + modelPreferences + })); + + console.error(`Sampling request forwarded to channel: ${targetChannel}`); +} + + +// Function to decode a base64 encoded channel-token pair +function decodeChannelTokenPair(encodedPair) { + try { + const decodedString = Buffer.from(encodedPair, 'base64').toString('utf8'); + const [channel, token] = decodedString.split(':'); + + if (!channel || !token) { + throw new Error('Invalid format'); + } + + // Ensure channel has leading slash + const formattedChannel = channel.startsWith('/') ? channel : `/${channel}`; + + return {channel: formattedChannel, token}; + } catch (error) { + console.error('Error decoding channel-token pair:', error); + return null; + } +} + +// Function to authorize a new channel-token pair +async function authorizeChannelToken(encodedPair) { + const decoded = decodeChannelTokenPair(encodedPair); + if (!decoded) { + return {success: false, message: 'Invalid encoded channel-token pair'}; + } + + const {channel, token} = decoded; + + // Check if this channel already has an active connection + if (channels[channel] && channels[channel].size > 0) { + return {success: false, message: `Channel ${channel} already has an active connection`}; + } + + // Add to authorized tokens + setToken(channel, token); + await saveAuthorizedTokens(); + + return { + success: true, + message: `Authorized channel: ${channel}`, + channel, + token + }; +} + +// Function to check if server is already running +async function isServerRunning() { + // If using "docker" and "startMCP" just assume the server is running + if (CONFIG.startMCP && CONFIG.docker) { + return true; + } + + try { + // Check if PID file exists + const pidData = await fs.readFile(PID_FILE, 'utf8'); + const pid = parseInt(pidData.trim(), 10); + + // Check if process with this PID is running + // This is platform-specific, using a simple approach + try { + process.kill(pid, 0); // This doesn't actually kill the process, just checks if it exists + return {running: true, pid}; + } catch (e) { + // Process not running, remove stale PID file + await fs.unlink(PID_FILE); + return {running: false}; + } + } catch (error) { + // PID file doesn't exist or other error + return {running: false}; + } +} + +// Function to save current PID to file +async function savePid() { + try { + await fs.writeFile(PID_FILE, process.pid.toString(), 'utf8'); + return true; + } catch (error) { + console.error('Error saving PID file:', error); + return false; + } +} + +// Function to run the server in the background +async function daemonize() { + // Fork a new process that will become the daemon + const args = process.argv.slice(2); + + // Make sure the --forked flag is included + if (!args.includes('--forked')) { + args.push('--forked'); + } + + // Create a detached child process + const child = fork(process.argv[1], args, { + detached: true, + stdio: 'ignore' + }); + + // Detach the child process so it can run independently + child.unref(); + + console.error(`Server started as daemon with PID: ${child.pid}`); + console.error(`Use 'node websocket-server.js --quit' to stop the server`); + console.error(`Use 'node websocket-server.js --new ' to authorize a channel-token pair`); + console.error(`Put 'npx @jason.today/webmcp --mcp' in your mcp client config`); + if (!CONFIG.startMCP) { + process.exit(0); + } +} + +const parseArgs = async () => { + const args = process.argv.slice(2); + let port = 4797; // Default port + let quit = false; + let newToken = false; + let startMCP = false; + let docker = false; + let cleanTokens = false; + let encodedPair = null; + let daemon = true; // Default to daemonize + + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + + if (arg === '-h' || arg === '--help') { + showHelp(); + process.exit(0); + } else if (arg === '-p' || arg === '--port') { + if (i + 1 < args.length) { + const portArg = parseInt(args[i + 1], 10); + if (isNaN(portArg) || portArg < 1 || portArg > 65535) { + console.error('Error: Port must be a number between 1 and 65535'); + showHelp(); + process.exit(1); + } + port = portArg; + i++; // Skip the next argument as we've already processed it + } else { + console.error('Error: Port option requires a value'); + showHelp(); + process.exit(1); + } + } else if (arg === '--config') { + if (i + 1 < args.length) { + const config = args[i + 1]; + await configureMcpClient(config) + i++; // Skip the next argument as we've already processed it + } else { + console.error('Error: Config option requires a mcp client type or path to json'); + showHelp(); + process.exit(1); + } + } else if (arg === '-q' || arg === '--quit') { + quit = true; + } else if (arg === '-n' || arg === '--new') { + newToken = true; + } else if (arg === '-m' || arg === '--mcp') { + startMCP = true; + } else if (arg === '-d' || arg === '--docker') { + docker = true; + } else if (arg === '-c' || arg === '--clean') { + cleanTokens = true; + } else if (arg === '-f' || arg === '--foreground') { + daemon = false; + } else if (arg === '--forked') { + // This is an internal flag to indicate we're the forked child │ │ + // No need to do anything with it here, just don't error on it + } else { + console.error(`Error: Unknown option: ${arg}`); + showHelp(); + process.exit(1); + } + } + + return {port, quit, newToken, cleanTokens, encodedPair, daemon, startMCP}; +}; + +const showHelp = () => { + console.log(` +Usage: node websocket-server.js [options] + +Options: + --config Automatically update MCP client configuration to add WebMCP + -p, --port Specify the port number (default: 4797) + -h, --help Display this help message + -q, --quit Stop the running server + -n, --new Generate a new token for client registration + -c, --clean Remove all authorized tokens + -f, --foreground Run in foreground (don't daemonize) + -m, --mcp Internal WebMCP Server codepath, likely only used in MCP client config + -d, --docker Tell the MCP client that WebMCP is running in docker + +Use --new to generate a token which clients can use to register on the /register endpoint. +Use --clean to remove all authorized tokens when you want to start fresh. + `); +}; + +const main = async () => { + // Ensure the config directory exists + await ensureConfigDir(); + + // Load authorized tokens from disk + await loadAuthorizedTokens(); + + setConfig(await parseArgs()); + + // Check if server is already running + const serverStatus = await isServerRunning(); + + // Handle clean tokens command + if (CONFIG.cleanTokens) { + console.log(`Removing all authorized tokens...`); + clearTokens(); + await saveAuthorizedTokens(); + console.log(`All tokens have been removed. Tokens file cleared.`); + + // If server is running, we need to notify it to reload tokens + if (serverStatus.running) { + console.log(`Server is running with PID: ${serverStatus.pid}. Please restart it to apply changes.`); + } + + process.exit(0); + } + + // Handle quit command + if (CONFIG.quit) { + if (serverStatus.running) { + console.log(`Stopping server with PID: ${serverStatus.pid}`); + try { + process.kill(serverStatus.pid, 'SIGTERM'); + console.log('Server stopped successfully'); + } catch (error) { + console.error('Error stopping server:', error); + } + } else { + console.log('No running server found'); + } + process.exit(0); + } + + // Handle new token generation + if (CONFIG.newToken) { + const encodedData = await generateNewRegistrationToken(); + console.log(`\nCONNECTION TOKEN (paste this in your web client):`); + console.log(`${encodedData}\n`); + + // If server is running, exit + if (serverStatus.running) { + process.exit(0); + } + } + + // Check if we have a server token, generate one if not + if (!serverToken) { + // console.log('No server token found, generating a new one...'); + serverToken = generateToken(); + await saveServerTokenToEnv(serverToken); + // console.log(`New server token: "${serverToken}". Saved to .env`); + } + + // If server is already running and we're not authorizing a token, just show status and exit + if (serverStatus.running) { + console.error(`Server is already running with PID: ${serverStatus.pid}`); + console.error(`Use 'node websocket-server.js --quit' to stop the server`); + console.error(`Use 'node websocket-server.js --new ' to authorize a channel-token pair`); + console.error(`Put 'npx @jason.today/webmcp --mcp' in your mcp client config`); + if (CONFIG.startMCP) { + return; + } else { + process.exit(0); + } + } + + // Daemonize if requested + if (CONFIG.daemon) { + // We need to add a marker to args to prevent fork bombs + // If we already have the --forked flag, we're in the child process and should continue + if (!process.argv.includes('--forked')) { + // Add the --forked flag to the arguments before daemonizing + process.argv.push('--forked'); + return daemonize(); + } + } + + // If we have the --forked flag, we're already the daemon, continue execution + // Save PID file + await savePid(); + + // Start the server + const PORT = CONFIG.port; + httpServer.listen(PORT, () => { + console.error(`WebSocket server running at http://${HOST}:${PORT}`); + console.error(`WebSocket server running at http://${HOST}:${PORT}`); + console.error(`WebMCP client token (for MCP path): ${serverToken}`); + console.error(`WebMCP client URL: ws://${HOST}:${PORT}${MCP_PATH}?token=${serverToken}`); + console.error(`Use 'node websocket-server.js --new ' to authorize a channel-token pair`); + }); + + // Handle graceful shutdown + const shutdownGracefully = async (signal) => { + console.error(`\nReceived ${signal}. Shutting down gracefully...`); + + // Save authorized tokens before shutting down + await saveAuthorizedTokens(); + + // Close all WebSocket connections in all channels + for (const channel of Object.values(channels)) { + for (const ws of channel) { + try { + ws.close(); + } catch (error) { + console.error('Error closing WebSocket connection:', error); + } + } + } + + // Close the HTTP server + httpServer.close(() => { + console.error('HTTP server closed'); + + // Remove PID file + fs.unlink(PID_FILE).catch(err => { + console.error('Error removing PID file:', err); + }); + + process.exit(0); + }); + }; + + // Handle CTRL+C (SIGINT) + process.on('SIGINT', () => shutdownGracefully('SIGINT')); + + // Handle SIGTERM + process.on('SIGTERM', () => shutdownGracefully('SIGTERM')); + + // Enable keyboard input handling for CTRL+C on Windows + if (process.platform === 'win32') { + process.stdin.setRawMode(true); + process.stdin.resume(); + process.stdin.on('data', (data) => { + // Check for CTRL+C (03 in hex) + if (data.length === 1 && data[0] === 0x03) { + shutdownGracefully('CTRL+C'); + } + }); + } +}; + +main().catch(error => { + console.error('Error in main:', error); + process.exit(1); +}).then(() => { + // Handle starting MCP + if (CONFIG.startMCP) { + setTimeout(() => { + console.error("Starting up MCP Server") + runMcpServer(serverToken).catch((error) => { + console.error("Fatal error in main():", error); + process.exit(1); + }); + }, 100); + } +});