imcp 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/installers/clients/BaseClientInstaller.d.ts +7 -1
- package/dist/core/installers/clients/BaseClientInstaller.js +1 -1
- package/dist/core/installers/clients/BaseClientInstaller.js.map +1 -1
- package/dist/core/installers/clients/GithubCopilotInstaller.d.ts +0 -5
- package/dist/core/installers/clients/GithubCopilotInstaller.js +1 -1
- package/dist/core/installers/clients/GithubCopilotInstaller.js.map +1 -1
- package/dist/core/installers/clients/MSRooCodeInstaller.js +1 -1
- package/dist/core/installers/clients/MSRooCodeInstaller.js.map +1 -1
- package/dist/core/installers/clients/VisualStudioInstaller.d.ts +0 -5
- package/dist/core/installers/clients/VisualStudioInstaller.js +1 -1
- package/dist/core/installers/clients/VisualStudioInstaller.js.map +1 -1
- package/dist/core/metadatas/types.d.ts +1 -0
- package/dist/core/metadatas/types.js.map +1 -1
- package/dist/web/public/css/modal.css +22 -0
- package/dist/web/public/js/modal/modalSetup.js +1 -1
- package/dist/web/public/js/onboard/formProcessor.js +1 -1
- package/dist/web/public/js/onboard/uiHandlers.js +1 -1
- package/package.json +1 -1
|
@@ -35,11 +35,17 @@ export declare abstract class BaseClientInstaller {
|
|
|
35
35
|
* Override in child classes to provide custom stdio configuration
|
|
36
36
|
*/
|
|
37
37
|
protected handleStdioMode(settings: any, serverName: string, finalConfig: any): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a server is reachable at the given URL.
|
|
40
|
+
* @param urlString The URL to check.
|
|
41
|
+
* @returns A promise that resolves to true if the server is reachable, false otherwise.
|
|
42
|
+
*/
|
|
43
|
+
private isServerReachable;
|
|
38
44
|
/**
|
|
39
45
|
* Handle SSE mode configuration
|
|
40
46
|
* Override in child classes to provide custom SSE configuration
|
|
41
47
|
*/
|
|
42
|
-
protected handleSseMode(settings: any, serverName: string, installConfig: any): void
|
|
48
|
+
protected handleSseMode(settings: any, serverName: string, installConfig: any): Promise<void>;
|
|
43
49
|
/**
|
|
44
50
|
* Checks if VS Code or VS Code Insiders is installed and installs the client extension.
|
|
45
51
|
* @param operationId The operation ID for tracking.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Logger}from"../../../utils/logger.js";import{exec}from"child_process";import{promisify}from"util";import{isCommandAvailable,getNpmExecutablePath}from"../../../utils/osUtils.js";import{ExtensionInstaller}from"./ExtensionInstaller.js";import{SUPPORTED_CLIENTS}from"../../metadatas/constants.js";import{MACRO_EXPRESSIONS,MacroResolverFunctions}from"../../../utils/macroExpressionUtils.js";import{InstallOperationManager}from"../../loaders/InstallOperationManager.js";import*as RecordingConstants from"../../metadatas/recordingConstants.js";const execAsync=promisify(exec);export class BaseClientInstaller{generateOperationId(){return`install-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}async setupInstallConfig(e,
|
|
1
|
+
import{Logger}from"../../../utils/logger.js";import{exec,spawn}from"child_process";import{promisify}from"util";import*as http from"http";import*as https from"https";import{isCommandAvailable,getNpmExecutablePath}from"../../../utils/osUtils.js";import{ExtensionInstaller}from"./ExtensionInstaller.js";import{SUPPORTED_CLIENTS}from"../../metadatas/constants.js";import{MACRO_EXPRESSIONS,MacroResolverFunctions}from"../../../utils/macroExpressionUtils.js";import{InstallOperationManager}from"../../loaders/InstallOperationManager.js";import*as RecordingConstants from"../../metadatas/recordingConstants.js";const execAsync=promisify(exec);export class BaseClientInstaller{generateOperationId(){return`install-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}async setupInstallConfig(e,t){const s={...e.installation};s.mode=e.mode,t.args&&t.args.length>0&&(Logger.debug(`Using args from ServerInstallOptions: ${t.args.join(" ")}`),s.args=t.args);const n=s.env||{},r={};for(const[e,t]of Object.entries(n)){const s=t;s.Default&&(r[e]=s.Default)}return s.env={...r,...t.env||{}},await this._resolveConfigMacros(s,t),Logger.debug(`Final installation config: ${JSON.stringify(s)}`),s}async _resolveConfigMacros(e,t){for(const s of Object.values(MACRO_EXPRESSIONS)){const n=e.args?.some((e=>"string"==typeof e&&e.includes(s))),r=Object.values(e.env||{}).some((e=>"string"==typeof e&&e.includes(s)));if(!n&&!r&&s!==MACRO_EXPRESSIONS.PYTHON_PACKAGE){Logger.debug(`Macro ${s} not found in args or env, skipping resolution.`);continue}const a=MacroResolverFunctions[s];if(a){const n=await a(e,t);if(void 0!==n){if(e.args){const t=e.args.join(" ");e.args=e.args.map((e=>"string"==typeof e&&e.includes(s)?e.replace(new RegExp(s.replace(/[${}]/g,"\\$&"),"g"),n):e)),e.args.join(" ")!==t&&Logger.debug(`Args after ${s} ('${n}') replacement: ${e.args.join(" ")}`)}if(e.env){const t=JSON.stringify(e.env);for(const t in e.env)"string"==typeof e.env[t]&&e.env[t].includes(s)&&(e.env[t]=e.env[t].replace(new RegExp(s.replace(/[${}]/g,"\\$&"),"g"),n));JSON.stringify(e.env)!==t&&Logger.debug(`Env after ${s} ('${n}') replacement: ${JSON.stringify(e.env)}`)}}else Logger.debug(`Could not resolve value for macro: ${s}. It will not be replaced.`)}}}async handleWindowsNpx(e){if("win32"===process.platform&&"npx"===e.command){const t=await getNpmExecutablePath();return{...e,command:"cmd",args:["/c","npx",...e.args],env:{...e.env,APPDATA:t}}}return e}initializeSettings(e){e.mcpServers||(e.mcpServers={})}async handleStdioMode(e,t,s){s.args&&(s.args=s.args.map((e=>"string"==typeof e?e.replace(/\\/g,"/"):e))),e.mcpServers[t]={command:s.command,args:s.args,env:s.env,autoApprove:[],disabled:!1,alwaysAllow:[]}}async isServerReachable(e){return new Promise((t=>{try{const s=new URL(e),n=("https:"===s.protocol?https:http).request(s,{method:"HEAD",timeout:2e3},(e=>{t(!0),e.resume()}));n.on("error",(s=>{Logger.debug(`Server at ${e} is not reachable: ${s.message}`),t(!1)})),n.on("timeout",(()=>{Logger.debug(`Timeout checking server reachability at ${e}`),n.destroy(),t(!1)})),n.end()}catch(s){Logger.error(`Error parsing URL or making request to ${e}: ${s.message}`),t(!1)}}))}async handleSseMode(e,t,s){if(s.url){if(await this.isServerReachable(s.url))Logger.info(`Server at ${s.url} is already running or reachable. Skipping start command.`);else if(s.startingCommand&&"string"==typeof s.startingCommand){Logger.info(`Server at ${s.url} not reachable. Attempting to start server with command: ${s.startingCommand}`);const e=s.startingCommand.split(" "),t=e[0],n=e.slice(1);try{const e=spawn(t,n,{detached:!0,stdio:"ignore",shell:"win32"===process.platform});e.on("error",(e=>{Logger.error(`Failed to start server process with command "${s.startingCommand}": ${e.message}`)})),e.unref(),Logger.info(`Detached server process (PID: ${e.pid}) started with command: "${s.startingCommand}". It will continue running if this main process exits.`)}catch(e){Logger.error(`Exception when trying to spawn server process with command "${s.startingCommand}": ${e.message}`)}}else s.startingCommand?Logger.warn(`startingCommand is present but not a string: ${JSON.stringify(s.startingCommand)}`):Logger.info(`Server at ${s.url} not reachable and no startingCommand provided.`)}else Logger.warn("No URL provided in installConfig for SSE mode. Cannot check reachability or configure server.");e.mcpServers[t]={type:"sse",url:s.url}}async checkVSCodeAndInstallExtension(e){const t=await isCommandAvailable("code"),s=await isCommandAvailable("code-insiders");if(!t&&!s)return{status:"failed",type:"install",target:"server",message:"Failed to install as neither VS Code nor VS Code Insiders are installed on this system. Please run `code` or `code-insiders` to make sure they are installed. Relaunch imcp after installation.",operationId:e};return await ExtensionInstaller.installExtension(this.clientName)?void 0:(Logger.debug(`Failed to install ${this.clientName} extension`),{status:"failed",type:"install",target:"server",message:`Failed to install ${this.clientName} extension`,operationId:e})}async updateVSCodeSettings(e,t){const s=[],n=await isCommandAvailable("code"),r=await isCommandAvailable("code-insiders");if(n)try{const n=SUPPORTED_CLIENTS[this.clientName].codeSettingPath;await this.setupClientSettings(n,e,t),s.push({success:!0,path:n})}catch(e){s.push({success:!1,path:SUPPORTED_CLIENTS[this.clientName].codeSettingPath,error:e instanceof Error?e.message:String(e)})}if(r)try{const n=SUPPORTED_CLIENTS[this.clientName].codeInsiderSettingPath;await this.setupClientSettings(n,e,t),s.push({success:!0,path:n})}catch(e){s.push({success:!1,path:SUPPORTED_CLIENTS[this.clientName].codeInsiderSettingPath,error:e instanceof Error?e.message:String(e)})}return s}async install(e,t,s){const n=this.generateOperationId(),r=InstallOperationManager.getInstance(s||e.name,e.name);return await r.recording((async()=>{await r.recording((()=>this.checkVSCodeAndInstallExtension(n)),{stepName:RecordingConstants.STEP_CHECK_VSCODE_AND_INSTALL_EXTENSION,endMessage:e=>e?.message,onResult:e=>"failed"!==e?.status});const s=await r.recording((()=>this.setupInstallConfig(e,t)),{stepName:RecordingConstants.STEP_SETUP_INSTALLATION_CONFIG});e.mode&&(s.mode=e.mode);const a=await r.recording((()=>this.updateVSCodeSettings(e.name,s)),{stepName:RecordingConstants.STEP_UPDATE_VSCODE_SETTINGS,endMessage:e=>e?.some((e=>e.success))?`Updated settings in: ${e.map((e=>e.path)).join(", ")}`:`Failed to update settings: ${e.map((e=>e.error)).join("; ")}`,onResult:e=>e?.some((e=>e.success))}),o=a.some((e=>e.success)),i=a.filter((e=>e.success)).map((e=>e.path)),l=a.filter((e=>!e.success)).map((e=>e.error));return{status:o?"completed":"failed",type:"install",target:"server",message:o?`Successfully installed ${this.clientName} client. Updated settings in: ${i.join(", ")}`:`Failed to install ${this.clientName} client. Errors: ${l.join("; ")}`,operationId:n,error:o?void 0:l.join("; ")}}),{stepName:RecordingConstants.STEP_INSTALLATION,onResult:e=>"failed"!==e?.status,endMessage:e=>e?.message,onError:e=>{const t=`Unexpected error installing ${this.clientName} client: ${e instanceof Error?e.message:String(e)}`;return{result:{status:"failed",type:"install",target:"server",message:t,operationId:n,error:e instanceof Error?e.message:String(e)},message:t}}})}}
|
|
2
2
|
//# sourceMappingURL=BaseClientInstaller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Logger","exec","promisify","isCommandAvailable","getNpmExecutablePath","ExtensionInstaller","SUPPORTED_CLIENTS","MACRO_EXPRESSIONS","MacroResolverFunctions","InstallOperationManager","RecordingConstants","execAsync","BaseClientInstaller","generateOperationId","Date","now","Math","random","toString","substr","setupInstallConfig","serverConfig","options","finalConfig","installation","mode","args","length","debug","join","baseEnv","env","defaultEnv","key","config","Object","entries","envConfig","Default","this","_resolveConfigMacros","JSON","stringify","macro","values","isMacroInArgs","some","arg","includes","isMacroInEnv","value","resolver","resolvedValue","undefined","originalArgsString","map","replace","RegExp","originalEnvJson","handleWindowsNpx","process","platform","command","npmPath","APPDATA","initializeSettings","settings","mcpServers","handleStdioMode","serverName","autoApprove","disabled","alwaysAllow","handleSseMode","installConfig","
|
|
1
|
+
{"version":3,"names":["Logger","exec","spawn","promisify","http","https","isCommandAvailable","getNpmExecutablePath","ExtensionInstaller","SUPPORTED_CLIENTS","MACRO_EXPRESSIONS","MacroResolverFunctions","InstallOperationManager","RecordingConstants","execAsync","BaseClientInstaller","generateOperationId","Date","now","Math","random","toString","substr","setupInstallConfig","serverConfig","options","finalConfig","installation","mode","args","length","debug","join","baseEnv","env","defaultEnv","key","config","Object","entries","envConfig","Default","this","_resolveConfigMacros","JSON","stringify","macro","values","isMacroInArgs","some","arg","includes","isMacroInEnv","value","PYTHON_PACKAGE","resolver","resolvedValue","undefined","originalArgsString","map","replace","RegExp","originalEnvJson","handleWindowsNpx","process","platform","command","npmPath","APPDATA","initializeSettings","settings","mcpServers","handleStdioMode","serverName","autoApprove","disabled","alwaysAllow","isServerReachable","urlString","Promise","resolve","url","URL","request","protocol","method","timeout","res","resume","on","err","message","destroy","end","error","handleSseMode","installConfig","info","startingCommand","commandParts","split","slice","child","detached","stdio","shell","unref","pid","warn","type","checkVSCodeAndInstallExtension","operationId","isVSCodeInstalled","isVSCodeInsidersInstalled","status","target","installExtension","clientName","updateVSCodeSettings","results","settingPath","codeSettingPath","setupClientSettings","push","success","path","Error","String","codeInsiderSettingPath","install","categoryName","recorder","getInstance","name","recording","async","stepName","STEP_CHECK_VSCODE_AND_INSTALL_EXTENSION","endMessage","result","onResult","STEP_SETUP_INSTALLATION_CONFIG","STEP_UPDATE_VSCODE_SETTINGS","r","anySuccess","successPaths","filter","errors","STEP_INSTALLATION","onError","errorMsg"],"sources":["../../../../src/core/installers/clients/BaseClientInstaller.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -15,11 +15,6 @@ export declare class GithubCopilotInstaller extends BaseClientInstaller {
|
|
|
15
15
|
* Overrides base method to provide custom stdio configuration
|
|
16
16
|
*/
|
|
17
17
|
protected handleStdioMode(settings: any, serverName: string, finalConfig: any): Promise<void>;
|
|
18
|
-
/**
|
|
19
|
-
* Handle SSE mode configuration for GithubCopilot
|
|
20
|
-
* Overrides base method to provide custom SSE configuration
|
|
21
|
-
*/
|
|
22
|
-
protected handleSseMode(settings: any, serverName: string, installConfig: any): void;
|
|
23
18
|
/**
|
|
24
19
|
* Set up Github Copilot client settings
|
|
25
20
|
* Updates VS Code settings with MCP server configuration
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseClientInstaller}from"./BaseClientInstaller.js";import{readJsonFile,writeJsonFile}from"../../../utils/clientUtils.js";export class GithubCopilotInstaller extends BaseClientInstaller{clientName="GithubCopilot";initializeSettings(e){e.mcp||(e.mcp={servers:{},inputs:[]}),e.mcp.servers||(e.mcp.servers={})}async handleStdioMode(e,s,t){t.args&&(t.args=t.args.map((e=>"string"==typeof e?e.replace(/\\/g,"/"):e))),e.mcp.servers[s]={command:t.command,args:t.args,env:t.env}}
|
|
1
|
+
import{BaseClientInstaller}from"./BaseClientInstaller.js";import{readJsonFile,writeJsonFile}from"../../../utils/clientUtils.js";export class GithubCopilotInstaller extends BaseClientInstaller{clientName="GithubCopilot";initializeSettings(e){e.mcp||(e.mcp={servers:{},inputs:[]}),e.mcp.servers||(e.mcp.servers={})}async handleStdioMode(e,s,t){t.args&&(t.args=t.args.map((e=>"string"==typeof e?e.replace(/\\/g,"/"):e))),e.mcp.servers[s]={command:t.command,args:t.args,env:t.env}}async setupClientSettings(e,s,t){const i=await readJsonFile(e,!0);this.initializeSettings(i),"stdio"===t.mode?await this.handleStdioMode(i,s,t):"sse"===t.mode&&this.handleSseMode(i,s,t),await writeJsonFile(e,i)}}
|
|
2
2
|
//# sourceMappingURL=GithubCopilotInstaller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BaseClientInstaller","readJsonFile","writeJsonFile","GithubCopilotInstaller","clientName","initializeSettings","settings","mcp","servers","inputs","handleStdioMode","serverName","finalConfig","args","map","arg","replace","command","env","
|
|
1
|
+
{"version":3,"names":["BaseClientInstaller","readJsonFile","writeJsonFile","GithubCopilotInstaller","clientName","initializeSettings","settings","mcp","servers","inputs","handleStdioMode","serverName","finalConfig","args","map","arg","replace","command","env","setupClientSettings","settingPath","installConfig","this","mode","handleSseMode"],"sources":["../../../../src/core/installers/clients/GithubCopilotInstaller.ts"],"mappings":"OAASA,wBAA2B,kCAC3BC,aAAcC,kBAAqB,uCAMtC,MAAOC,+BAA+BH,oBACrBI,WAAqB,gBAO9B,kBAAAC,CAAmBC,GACpBA,EAASC,MACVD,EAASC,IAAM,CACXC,QAAS,GACTC,OAAQ,KAIXH,EAASC,IAAIC,UACdF,EAASC,IAAIC,QAAU,GAE/B,CAMU,qBAAME,CAAgBJ,EAAeK,EAAoBC,GAC3DA,EAAYC,OACZD,EAAYC,KAAOD,EAAYC,KAAKC,KAAKC,GACtB,iBAARA,EAAmBA,EAAIC,QAAQ,MAAO,KAAOD,KAG5DT,EAASC,IAAIC,QAAQG,GAAc,CAC/BM,QAASL,EAAYK,QACrBJ,KAAMD,EAAYC,KAClBK,IAAKN,EAAYM,IAEzB,CAOA,yBAAMC,CAAoBC,EAAqBT,EAAoBU,GAE/D,MAAMf,QAAiBL,aAAamB,GAAa,GAGjDE,KAAKjB,mBAAmBC,GAGG,UAAvBe,EAAcE,WACRD,KAAKZ,gBAAgBJ,EAAUK,EAAYU,GACnB,QAAvBA,EAAcE,MACrBD,KAAKE,cAAclB,EAAUK,EAAYU,SAIvCnB,cAAckB,EAAad,EACrC","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseClientInstaller}from"./BaseClientInstaller.js";import{readJsonFile,writeJsonFile}from"../../../utils/clientUtils.js";export class MSRooCodeInstaller extends BaseClientInstaller{clientName="MSRooCode";async setupClientSettings(e,t,i){const s=await readJsonFile(e,!0);if(this.initializeSettings(s),"stdio"===i.mode){const e=await this.handleWindowsNpx(i);await this.handleStdioMode(s,t,e)}else"sse"===i.mode&&this.handleSseMode(s,t,i);await writeJsonFile(e,s)}}
|
|
1
|
+
import{BaseClientInstaller}from"./BaseClientInstaller.js";import{readJsonFile,writeJsonFile}from"../../../utils/clientUtils.js";export class MSRooCodeInstaller extends BaseClientInstaller{clientName="MSRooCode";async setupClientSettings(e,t,i){const s=await readJsonFile(e,!0);if(this.initializeSettings(s),"stdio"===i.mode){const e=await this.handleWindowsNpx(i);await this.handleStdioMode(s,t,e)}else"sse"===i.mode&&await this.handleSseMode(s,t,i);await writeJsonFile(e,s)}}
|
|
2
2
|
//# sourceMappingURL=MSRooCodeInstaller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BaseClientInstaller","readJsonFile","writeJsonFile","MSRooCodeInstaller","clientName","setupClientSettings","settingPath","serverName","installConfig","settings","this","initializeSettings","mode","finalConfig","handleWindowsNpx","handleStdioMode","handleSseMode"],"sources":["../../../../src/core/installers/clients/MSRooCodeInstaller.ts"],"mappings":"OAASA,wBAA2B,kCAC3BC,aAAcC,kBAAqB,uCAKtC,MAAOC,2BAA2BH,oBACjBI,WAAqB,YAIxC,yBAAMC,CAAoBC,EAAqBC,EAAoBC,GAE/D,MAAMC,QAAiBR,aAAaK,GAAa,GAMjD,GAHAI,KAAKC,mBAAmBF,GAGG,UAAvBD,EAAcI,KAAkB,CAEhC,MAAMC,QAAoBH,KAAKI,iBAAiBN,SAE1CE,KAAKK,gBAAgBN,EAAUF,EAAYM,EACrD,KAAkC,QAAvBL,EAAcI,
|
|
1
|
+
{"version":3,"names":["BaseClientInstaller","readJsonFile","writeJsonFile","MSRooCodeInstaller","clientName","setupClientSettings","settingPath","serverName","installConfig","settings","this","initializeSettings","mode","finalConfig","handleWindowsNpx","handleStdioMode","handleSseMode"],"sources":["../../../../src/core/installers/clients/MSRooCodeInstaller.ts"],"mappings":"OAASA,wBAA2B,kCAC3BC,aAAcC,kBAAqB,uCAKtC,MAAOC,2BAA2BH,oBACjBI,WAAqB,YAIxC,yBAAMC,CAAoBC,EAAqBC,EAAoBC,GAE/D,MAAMC,QAAiBR,aAAaK,GAAa,GAMjD,GAHAI,KAAKC,mBAAmBF,GAGG,UAAvBD,EAAcI,KAAkB,CAEhC,MAAMC,QAAoBH,KAAKI,iBAAiBN,SAE1CE,KAAKK,gBAAgBN,EAAUF,EAAYM,EACrD,KAAkC,QAAvBL,EAAcI,YACfF,KAAKM,cAAcP,EAAUF,EAAYC,SAI7CN,cAAcI,EAAaG,EACrC","ignoreList":[]}
|
|
@@ -35,11 +35,6 @@ export declare class VisualStudioInstaller extends BaseClientInstaller {
|
|
|
35
35
|
* Overrides base method to provide custom stdio configuration
|
|
36
36
|
*/
|
|
37
37
|
protected handleStdioMode(settings: any, serverName: string, finalConfig: any): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Handle SSE mode configuration for GithubCopilot
|
|
40
|
-
* Overrides base method to provide custom SSE configuration
|
|
41
|
-
*/
|
|
42
|
-
protected handleSseMode(settings: any, serverName: string, installConfig: any): void;
|
|
43
38
|
/**
|
|
44
39
|
* Install MCP server configuration for Visual Studio
|
|
45
40
|
* Custom implementation that skips VSCode-specific steps
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{BaseClientInstaller}from"./BaseClientInstaller.js";import{Logger}from"../../../utils/logger.js";import fs from"fs/promises";import path from"path";import{SUPPORTED_CLIENTS}from"../../metadatas/constants.js";import{InstallOperationManager}from"../../loaders/InstallOperationManager.js";import*as RecordingConstants from"../../metadatas/recordingConstants.js";export class VisualStudioInstaller extends BaseClientInstaller{clientName="VisualStudio";async updateVSSettings(e,t){Logger.debug("Updating Visual Studio settings");const s=[];try{const a=SUPPORTED_CLIENTS[this.clientName].codeSettingPath;Logger.debug(`Attempting to update settings at: ${a}`),await this.setupClientSettings(a,e,t),s.push({success:!0,path:a}),Logger.debug("Successfully updated Visual Studio settings")}catch(e){const t=e instanceof Error?e.message:String(e);Logger.error("Failed to update Visual Studio settings:",e),s.push({success:!1,path:SUPPORTED_CLIENTS[this.clientName].codeSettingPath,error:t})}return s}async setupClientSettings(e,t,s){Logger.debug(`Setting up Visual Studio client settings at ${e}`);try{const a=path.dirname(e);await fs.mkdir(a,{recursive:!0});let i={};try{const t=await fs.readFile(e,"utf8");i=JSON.parse(t)}catch(e){Logger.debug("No existing settings file found, creating new one")}this.initializeSettings(i),t=t.replace(/-/g,"_"),"stdio"===s.mode?await this.handleStdioMode(i,t,s):"sse"===s.mode&&this.handleSseMode(i,t,s),await fs.writeFile(e,JSON.stringify(i,null,2),"utf8"),Logger.debug(`Successfully updated Visual Studio settings at ${e}`)}catch(e){throw Logger.error("Failed to setup Visual Studio client settings:",e),e}}initializeSettings(e){e||(e={servers:{},inputs:[]}),e.inputs||(e.inputs=[]),e.servers||(e.servers={})}async handleStdioMode(e,t,s){s.args&&(s.args=s.args.map((e=>"string"==typeof e?e.replace(/\\/g,"/"):e))),e.servers[t]={command:s.command,args:s.args,env:s.env}}
|
|
1
|
+
import{BaseClientInstaller}from"./BaseClientInstaller.js";import{Logger}from"../../../utils/logger.js";import fs from"fs/promises";import path from"path";import{SUPPORTED_CLIENTS}from"../../metadatas/constants.js";import{InstallOperationManager}from"../../loaders/InstallOperationManager.js";import*as RecordingConstants from"../../metadatas/recordingConstants.js";export class VisualStudioInstaller extends BaseClientInstaller{clientName="VisualStudio";async updateVSSettings(e,t){Logger.debug("Updating Visual Studio settings");const s=[];try{const a=SUPPORTED_CLIENTS[this.clientName].codeSettingPath;Logger.debug(`Attempting to update settings at: ${a}`),await this.setupClientSettings(a,e,t),s.push({success:!0,path:a}),Logger.debug("Successfully updated Visual Studio settings")}catch(e){const t=e instanceof Error?e.message:String(e);Logger.error("Failed to update Visual Studio settings:",e),s.push({success:!1,path:SUPPORTED_CLIENTS[this.clientName].codeSettingPath,error:t})}return s}async setupClientSettings(e,t,s){Logger.debug(`Setting up Visual Studio client settings at ${e}`);try{const a=path.dirname(e);await fs.mkdir(a,{recursive:!0});let i={};try{const t=await fs.readFile(e,"utf8");i=JSON.parse(t)}catch(e){Logger.debug("No existing settings file found, creating new one")}this.initializeSettings(i),t=t.replace(/-/g,"_"),"stdio"===s.mode?await this.handleStdioMode(i,t,s):"sse"===s.mode&&this.handleSseMode(i,t,s),await fs.writeFile(e,JSON.stringify(i,null,2),"utf8"),Logger.debug(`Successfully updated Visual Studio settings at ${e}`)}catch(e){throw Logger.error("Failed to setup Visual Studio client settings:",e),e}}initializeSettings(e){e||(e={servers:{},inputs:[]}),e.inputs||(e.inputs=[]),e.servers||(e.servers={})}async handleStdioMode(e,t,s){s.args&&(s.args=s.args.map((e=>"string"==typeof e?e.replace(/\\/g,"/"):e))),e.servers[t]={command:s.command,args:s.args,env:s.env}}async install(e,t,s){const a=this.generateOperationId(),i=InstallOperationManager.getInstance(s||e.name,e.name);return await i.recording((async()=>{const s=await i.recording((()=>this.setupInstallConfig(e,t)),{stepName:RecordingConstants.STEP_SETUP_INSTALLATION_CONFIG});e.mode&&(s.mode=e.mode);const n=await i.recording((()=>this.updateVSSettings(e.name,s)),{stepName:RecordingConstants.STEP_UPDATE_VS_SETTINGS,onResult:e=>e?.some((e=>e.success))}),r=n.some((e=>e.success)),o=n.filter((e=>e.success)).map((e=>e.path)),l=n.filter((e=>!e.success)).map((e=>e.error));return{status:r?"completed":"failed",type:"install",target:"server",message:r?`Successfully installed ${this.clientName} client. Updated settings in: ${o.join(", ")}`:`Failed to install ${this.clientName} client. Errors: ${l.join("; ")}`,operationId:a,error:r?void 0:l.join("; ")}}),{stepName:RecordingConstants.STEP_INSTALLATION,onResult:e=>"failed"!==e?.status,endMessage:e=>e?.message,onError:e=>{const t=`Unexpected error installing ${this.clientName} client: ${e instanceof Error?e.message:String(e)}`;return{result:{status:"failed",type:"install",target:"server",message:t,operationId:a,error:e instanceof Error?e.message:String(e)},message:t}}})}}
|
|
2
2
|
//# sourceMappingURL=VisualStudioInstaller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BaseClientInstaller","Logger","fs","path","SUPPORTED_CLIENTS","InstallOperationManager","RecordingConstants","VisualStudioInstaller","clientName","updateVSSettings","serverName","installConfig","debug","results","settingPath","this","codeSettingPath","setupClientSettings","push","success","error","errorMessage","Error","message","String","settingsDir","dirname","mkdir","recursive","settings","existingContent","readFile","JSON","parse","initializeSettings","replace","mode","handleStdioMode","handleSseMode","writeFile","stringify","servers","inputs","finalConfig","args","map","arg","command","env","
|
|
1
|
+
{"version":3,"names":["BaseClientInstaller","Logger","fs","path","SUPPORTED_CLIENTS","InstallOperationManager","RecordingConstants","VisualStudioInstaller","clientName","updateVSSettings","serverName","installConfig","debug","results","settingPath","this","codeSettingPath","setupClientSettings","push","success","error","errorMessage","Error","message","String","settingsDir","dirname","mkdir","recursive","settings","existingContent","readFile","JSON","parse","initializeSettings","replace","mode","handleStdioMode","handleSseMode","writeFile","stringify","servers","inputs","finalConfig","args","map","arg","command","env","install","serverConfig","options","categoryName","operationId","generateOperationId","recorder","getInstance","name","recording","async","setupInstallConfig","stepName","STEP_SETUP_INSTALLATION_CONFIG","STEP_UPDATE_VS_SETTINGS","onResult","result","some","r","anySuccess","successPaths","filter","errors","status","type","target","join","undefined","STEP_INSTALLATION","endMessage","onError","errorMsg"],"sources":["../../../../src/core/installers/clients/VisualStudioInstaller.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["OSType","MCPEvent"],"sources":["../../../src/core/metadatas/types.ts"],"mappings":"OAAA,IAAYA,QAAZ,SAAYA,GACVA,EAAA,kBACAA,EAAA,cACAA,EAAA,aACD,CAJD,CAAYA,gBAAM,
|
|
1
|
+
{"version":3,"names":["OSType","MCPEvent"],"sources":["../../../src/core/metadatas/types.ts"],"mappings":"OAAA,IAAYA,QAAZ,SAAYA,GACVA,EAAA,kBACAA,EAAA,cACAA,EAAA,aACD,CAJD,CAAYA,gBAAM,YAuKlB,IAAYC,UAAZ,SAAYA,GACVA,EAAA,oCACAA,EAAA,wCACAA,EAAA,gCACAA,EAAA,gCACAA,EAAA,+BACD,CAND,CAAYA,oBAAQ","ignoreList":[]}
|
|
@@ -754,4 +754,26 @@ body {
|
|
|
754
754
|
|
|
755
755
|
#installLoadingModal .modal-content .modal-close-btn:hover {
|
|
756
756
|
color: #333;
|
|
757
|
+
}
|
|
758
|
+
/* Styles for SSE Info Read-only Text Boxes */
|
|
759
|
+
.sse-info-field {
|
|
760
|
+
margin-bottom: 0.75rem; /* Consistent with other fields */
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
.sse-input-readonly {
|
|
764
|
+
background-color: #f9fafb; /* bg-gray-50 */
|
|
765
|
+
color: #4b5563; /* text-gray-600 */
|
|
766
|
+
border: 1px solid #d1d5db; /* border-gray-300 */
|
|
767
|
+
cursor: text; /* Indicate it's selectable text */
|
|
768
|
+
padding: 0.5rem 0.75rem;
|
|
769
|
+
border-radius: 0.5rem;
|
|
770
|
+
width: 100%;
|
|
771
|
+
box-sizing: border-box; /* Ensure padding and border are included in the element's total width and height */
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.sse-info-field label {
|
|
775
|
+
display: block;
|
|
776
|
+
margin-bottom: 0.25rem; /* Space between label and input */
|
|
777
|
+
font-weight: 500; /* medium */
|
|
778
|
+
color: #374151; /* gray-700 */
|
|
757
779
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{showToast,showConfirm}from"../notifications.js";import{showInstallLoadingModal,updateOverallInstallStatus}from"./loadingModal.js";import{uninstallTools}from"./installation.js";import{handleBulkClientInstall}from"./installation.js";import{compareVersions}from"./versionUtils.js";export function setupClientItems(e,t,n,s,a){e.forEach((e=>{const l=t.installedStatus[e]||{status:"not-installed",type:"check",target:"server"};let o="",i="";"completed"===l.status&&"install"===l.type?(o="Installed",i="installed"):"pending"===l.status?(o="Pending Requirements",i="pending"):"in-progress"===l.status?(o="In Progress",i="pending"):"failed"===l.status&&(o="Failed",i="not-installed");const r="completed"===l.status&&"install"===l.type,d="in-progress"===l.status,c=!r&&!d,m=createClientItem(e,o,i,c,r,d);setupClientItemListeners(m,e,c),setupUninstallButton(m,o,l,e,n,s,i),a.appendChild(m)})),addSectionTitle(a)}export function setupEnvironmentVariables(e,t,n){if("sse"===e.mode)return void(t.style.display="none");const s=e.installation?.env||e.installation?.env||{};addEnvironmentTitle(t),fetch("/api/settings").then((e=>e.json())).then((a=>{const l=a&&a.data&&a.data.userConfigurations?a.data.userConfigurations:{};0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,l)})).catch((()=>{0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,{})}))}export function setupInstallationArguments(e,t,n,s){if("sse"===s?.mode)return void(t.style.display="none");if(!e)return;addArgumentsTitle(t);const a=createArgumentsContainer();t.appendChild(a),e.args&&Array.isArray(e.args)?e.args.forEach((e=>{a.appendChild(createArgumentInput(e))})):a.appendChild(createArgumentInput()),("python"===e.command||e.command.includes("python"))&&addPythonEnvironmentInput(n,s.name,t)}export function setupServerRequirements(e,t,n,s,a){if("sse"===e.mode)return void(a.style.display="none");const l=e.dependencies?.requirements||[],o=t.data.installationStatus?.requirementsStatus||{};if(l.length>0){const e=renderRequirements(l,o,n,s);a.innerHTML=`\n <h3 class="text-lg font-semibold text-gray-700 mb-3">Dependencies</h3>\n <p class="text-sm text-gray-600 mb-4">These dependencies will be automatically installed when installing the server</p>\n ${e}\n `,setupUpdateToggles(a)}else a.innerHTML='<p class="text-gray-600">No additional dependencies required.</p>'}export function setupFormSubmitHandler(e,t,n,s,a,l,o,i,r){e.onsubmit=e=>{e.preventDefault();const d={},c=[],m=[];let u;if("sse"!==r?.mode){t.querySelectorAll("input").forEach((e=>{e.name&&e.value&&(d[e.name]=e.value)}));const e=n.querySelectorAll(".arg-input");c.push(...Array.from(e).map((e=>e.value.trim())).filter((e=>""!==e)));const a=document.getElementById("python_env");u=a?.value?.trim();s.querySelectorAll(".toggle-update:checked").forEach((e=>{m.push({name:e.dataset.name,version:e.dataset.version})}))}function proceedInstall(){const e=m.length>0,t=document.querySelector(".uninstall-btn");if(!t||!t.matches(":active")){const t=window.selectedClients;if(0===t.length&&!e)return void showToast("Please select at least one client to configure.","error");let n="Starting installation...";const s=o[l]||{installedStatus:{}};if(t.length>0){const e=t[0],a=s.installedStatus?.[e]?.message;a&&(n=a)}const r={targetClients:t,env:d,args:c,settings:u?{pythonEnv:u}:{}};m.length>0&&(r.requirements=m),handleBulkClientInstall(a,l,t,d,n,i,r)}}fetch("/api/settings").then((e=>e.json())).then((e=>{const t=e&&e.data&&e.data.userConfigurations?e.data.userConfigurations:{},n=e&&e.data&&e.data.pythonEnvs?e.data.pythonEnvs:{},s={...t},o={...n};Object.keys(d).forEach((e=>{s[e]=d[e]}));let i=!1;const r=new Set([...Object.keys(t),...Object.keys(d)]);for(const e of r)if(t[e]!==s[e]){i=!0;break}let c=!1;if(void 0!==u&&u!==n[`${a}:${l}`]&&(o[`${a}:${l}`]=u,c=!0),i||c){const e={};i&&(e.userConfigurations=s),c&&(e.pythonEnvs=o),fetch("/api/settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then((()=>{proceedInstall()})).catch((()=>{proceedInstall()}))}else proceedInstall()})).catch((()=>{proceedInstall()}))}}function createClientItem(e,t,n,s,a,l){const o=document.createElement("div");o.className="client-item",o.dataset.target=e,o.dataset.selected="false";const i=document.createElement("div");i.className="client-info";const r=document.createElement("span");return r.className="text-sm font-medium text-gray-900",r.textContent=e,i.appendChild(r),o.appendChild(i),s||(o.classList.add("non-selectable"),a?(o.classList.add("installed-item"),o.title="Already installed"):l&&(o.classList.add("in-progress-item"),o.title="Installation in progress")),o}function setupClientItemListeners(e,t,n){n&&e.addEventListener("click",(()=>{const n="true"===e.dataset.selected;e.dataset.selected=n?"false":"true",n?(e.classList.remove("selected"),window.selectedClients=window.selectedClients.filter((e=>e!==t))):(e.classList.add("selected"),window.selectedClients.includes(t)||window.selectedClients.push(t))}))}function setupUninstallButton(e,t,n,s,a,l,o){if(t){const i=document.createElement("div");i.className="status-container";const r=document.createElement("span");if(r.className=`status-badge ${o}`,r.textContent=t,i.appendChild(r),"completed"===n.status&&"install"===n.type){const e=createUninstallButton(s,a,l);i.appendChild(e)}e.appendChild(i)}}function createUninstallButton(e,t,n){const s=document.createElement("button");return s.className="uninstall-btn text-red-600 hover:text-red-800 ml-2",s.innerHTML='<i class="bx bx-trash"></i>',s.title="Uninstall from this client",s.onclick=async s=>{s.stopPropagation(),s.preventDefault();if(await showConfirm("Uninstall Confirmation",`Are you sure you want to uninstall ${n} from ${e}?`)){window.selectedClients=[e],showInstallLoadingModal("Uninstalling");const s={[n]:{removeData:!0}};try{updateOverallInstallStatus("in-progress",`Uninstalling ${n} from ${e}...`),await uninstallTools(t,s,[e])}catch(e){updateOverallInstallStatus("failed",`Error during uninstall: ${e.message}`)}}return!1},s}function addSectionTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Client Status",e.insertBefore(t,e.firstChild)}}function addEnvironmentTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Environment Variables",e.insertBefore(t,e.firstChild)}}function addNoEnvMessage(e){const t=document.createElement("p");t.className="text-gray-600",t.textContent="No environment variables required for this MCP server.",e.appendChild(t)}function createEnvironmentInputs(e,t,n,s,a={}){Object.keys(e).forEach((l=>{const o=e[l],i=`env_${l}`,r=document.createElement("div");r.className="mb-3";const d=document.createElement("label");d.htmlFor=i,d.className="block text-sm font-medium text-gray-700 mb-1",d.innerHTML=`${l} ${o.Required?'<span class="text-red-500">*</span>':""}`;const c=document.createElement("input");c.type=o.isSecret?"password":"text",c.id=i,c.name=l,c.placeholder=o.Description||l,c.required=o.Required,c.className="input-field";let m=o.Default||"";if(a&&a[l]?m=a[l]:n&&n.MSRooCode&&n.MSRooCode.mcpServers&&n.MSRooCode.mcpServers[s]&&n.MSRooCode.mcpServers[s].env&&n.MSRooCode.mcpServers[s].env[l]&&(m=n.MSRooCode.mcpServers[s].env[l]),c.value=m,r.appendChild(d),r.appendChild(c),o.Description){const e=document.createElement("p");e.className="text-xs text-gray-500 mt-1",e.textContent=o.Description,r.appendChild(e)}t.appendChild(r)}))}function addArgumentsTitle(e){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Arguments",e.appendChild(t)}function createArgumentsContainer(){const e=document.createElement("div");e.className="args-container mb-3";const t=document.createElement("button");return t.type="button",t.className="add-arg-button px-3 py-1 text-sm text-blue-600 hover:text-blue-800 border border-blue-600 hover:border-blue-800 rounded-md mb-2",t.innerHTML='<i class="bx bx-plus"></i> Add Argument',t.onclick=()=>e.appendChild(createArgumentInput()),e.appendChild(t),e}function createArgumentInput(e=""){const t=document.createElement("div");t.className="arg-wrapper flex items-center gap-2 mb-2";const n=document.createElement("input");n.type="text",n.className="arg-input flex-grow",n.value=e,n.placeholder="Enter argument value";const s=document.createElement("button");return s.type="button",s.className="remove-arg-button text-red-600 hover:text-red-800",s.innerHTML='<i class="bx bx-trash"></i>',s.onclick=()=>t.remove(),t.appendChild(n),t.appendChild(s),t}function addPythonEnvironmentInput(e,t,n){const s=document.createElement("div");s.className="mt-4";const a=document.createElement("label");a.htmlFor="python_env",a.className="block text-sm font-medium text-gray-700 mb-1",a.textContent="Python Environment";const l=document.createElement("input");l.type="text",l.id="python_env",l.className="input-field",l.placeholder="Enter Python environment path (optional)";const o=document.createElement("p");o.className="text-xs text-gray-500 mt-1",o.textContent="Specify the Python exectable file(e.g. C:/python312/python) to use for installation. Leave empty to use system default. You can specify value in Settings page",s.appendChild(a),s.appendChild(l),s.appendChild(o),n.appendChild(s),fetch("/api/settings").then((e=>e.json())).then((n=>{n&&n.data&&n.data.pythonEnvs&&(l.value=n.data.pythonEnvs[`${e}:${t}`]||n.data.pythonEnvs.system||"")})).catch((()=>{}))}function renderRequirements(e,t,n,s){return e.map((e=>{const a=t[e.name]||{};let l=a.installed?"text-green-600 bg-green-50":"text-yellow-600 bg-yellow-50",o=a.installed?"Installed":"Required",i=a.version?` • <span class="font-medium">${a.version}</span>`:"",r="";return a.installed&&a.availableUpdate&&a.availableUpdate.version&&a.version&&compareVersions(a.availableUpdate.version,a.version)>0&&(l="text-yellow-600 bg-yellow-50",o=`<span style="color: #f59e0b; font-weight: bold; margin-right: 5px;">↑</span>${a.availableUpdate.version}`,r=`\n <label class="inline-flex items-center cursor-pointer ml-2">\n <input type="checkbox" class="toggle-update sr-only"\n data-name="${e.name}"\n data-version="${a.availableUpdate.version}"\n data-category="${n}"\n data-server="${s}">\n <div class="relative w-10 h-5 bg-gray-200 rounded-full toggle-bg">\n <div class="absolute inset-y-0 left-0 w-5 h-5 bg-white rounded-full transition-transform duration-300 transform"></div>\n </div>\n <span class="ml-2 text-sm text-gray-700">Update</span>\n </label>\n `),`\n <div class="border border-gray-200 p-3 rounded-lg mb-2 hover:bg-gray-50">\n <div class="flex justify-between items-center">\n <div>\n <div class="font-semibold text-gray-800">${e.name}</div>\n <div class="text-sm text-gray-600 shadow-sm p-1 rounded bg-gray-50">\n <span class="font-medium">${a.type||"package"}</span>${i}\n </div>\n </div>\n <div class="flex items-center">\n <span class="${l} inline-flex items-center px-3 py-1 rounded-full text-sm">\n ${o}\n </span>\n ${r}\n </div>\n </div>\n </div>\n `})).join("")}function setupUpdateToggles(e){e.querySelectorAll(".toggle-update").forEach((e=>{e.addEventListener("change",(function(){const e=this.parentElement.querySelector(".toggle-bg");this.checked?(e.classList.add("bg-blue-500"),e.querySelector("div").classList.add("translate-x-5")):(e.classList.remove("bg-blue-500"),e.querySelector("div").classList.remove("translate-x-5"))}))}))}
|
|
1
|
+
import{showToast,showConfirm}from"../notifications.js";import{showInstallLoadingModal,updateOverallInstallStatus}from"./loadingModal.js";import{uninstallTools}from"./installation.js";import{handleBulkClientInstall}from"./installation.js";import{compareVersions}from"./versionUtils.js";export function setupClientItems(e,t,n,s,a){e.forEach((e=>{const l=t.installedStatus[e]||{status:"not-installed",type:"check",target:"server"};let o="",i="";"completed"===l.status&&"install"===l.type?(o="Installed",i="installed"):"pending"===l.status?(o="Pending Requirements",i="pending"):"in-progress"===l.status?(o="In Progress",i="pending"):"failed"===l.status&&(o="Failed",i="not-installed");const r="completed"===l.status&&"install"===l.type,d="in-progress"===l.status,c=!r&&!d,m=createClientItem(e,o,i,c,r,d);setupClientItemListeners(m,e,c),setupUninstallButton(m,o,l,e,n,s,i),a.appendChild(m)})),addSectionTitle(a)}export function setupEnvironmentVariables(e,t,n){if("sse"===e.mode)return void(t.style.display="none");const s=e.installation?.env||e.installation?.env||{};addEnvironmentTitle(t),fetch("/api/settings").then((e=>e.json())).then((a=>{const l=a&&a.data&&a.data.userConfigurations?a.data.userConfigurations:{};0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,l)})).catch((()=>{0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,{})}))}export function setupInstallationArguments(e,t,n,s){if(!e)return void(t.style.display="none");if("sse"===s?.mode){t.innerHTML="";let n=!1;return e.url&&(addArgumentsTitle(t),createReadOnlyTextBox(t,"Server URL",e.url,"sse_url"),n=!0),e.startingCommand&&(n||addArgumentsTitle(t),createReadOnlyTextBox(t,"Starting Command",e.startingCommand,"sse_starting_command"),n=!0),void(n||(t.style.display="none"))}addArgumentsTitle(t);const a=createArgumentsContainer();t.appendChild(a),e.args&&Array.isArray(e.args)?e.args.forEach((e=>{a.appendChild(createArgumentInput(e))})):a.appendChild(createArgumentInput()),("python"===e.command||e.command.includes("python"))&&addPythonEnvironmentInput(n,s.name,t)}export function setupServerRequirements(e,t,n,s,a){if("sse"===e.mode)return void(a.style.display="none");const l=e.dependencies?.requirements||[],o=t.data.installationStatus?.requirementsStatus||{};if(l.length>0){const e=renderRequirements(l,o,n,s);a.innerHTML=`\n <h3 class="text-lg font-semibold text-gray-700 mb-3">Dependencies</h3>\n <p class="text-sm text-gray-600 mb-4">These dependencies will be automatically installed when installing the server</p>\n ${e}\n `,setupUpdateToggles(a)}else a.innerHTML='<p class="text-gray-600">No additional dependencies required.</p>'}export function setupFormSubmitHandler(e,t,n,s,a,l,o,i,r){e.onsubmit=e=>{e.preventDefault();const d={},c=[],m=[];let u;if("sse"!==r?.mode){t.querySelectorAll("input").forEach((e=>{e.name&&e.value&&(d[e.name]=e.value)}));const e=n.querySelectorAll(".arg-input");c.push(...Array.from(e).map((e=>e.value.trim())).filter((e=>""!==e)));const a=document.getElementById("python_env");u=a?.value?.trim();s.querySelectorAll(".toggle-update:checked").forEach((e=>{m.push({name:e.dataset.name,version:e.dataset.version})}))}function proceedInstall(){const e=m.length>0,t=document.querySelector(".uninstall-btn");if(!t||!t.matches(":active")){const t=window.selectedClients;if(0===t.length&&!e)return void showToast("Please select at least one client to configure.","error");let n="Starting installation...";const s=o[l]||{installedStatus:{}};if(t.length>0){const e=t[0],a=s.installedStatus?.[e]?.message;a&&(n=a)}const r={targetClients:t,env:d,args:c,settings:u?{pythonEnv:u}:{}};m.length>0&&(r.requirements=m),handleBulkClientInstall(a,l,t,d,n,i,r)}}fetch("/api/settings").then((e=>e.json())).then((e=>{const t=e&&e.data&&e.data.userConfigurations?e.data.userConfigurations:{},n=e&&e.data&&e.data.pythonEnvs?e.data.pythonEnvs:{},s={...t},o={...n};Object.keys(d).forEach((e=>{s[e]=d[e]}));let i=!1;const r=new Set([...Object.keys(t),...Object.keys(d)]);for(const e of r)if(t[e]!==s[e]){i=!0;break}let c=!1;if(void 0!==u&&u!==n[`${a}:${l}`]&&(o[`${a}:${l}`]=u,c=!0),i||c){const e={};i&&(e.userConfigurations=s),c&&(e.pythonEnvs=o),fetch("/api/settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then((()=>{proceedInstall()})).catch((()=>{proceedInstall()}))}else proceedInstall()})).catch((()=>{proceedInstall()}))}}function createClientItem(e,t,n,s,a,l){const o=document.createElement("div");o.className="client-item",o.dataset.target=e,o.dataset.selected="false";const i=document.createElement("div");i.className="client-info";const r=document.createElement("span");return r.className="text-sm font-medium text-gray-900",r.textContent=e,i.appendChild(r),o.appendChild(i),s||(o.classList.add("non-selectable"),a?(o.classList.add("installed-item"),o.title="Already installed"):l&&(o.classList.add("in-progress-item"),o.title="Installation in progress")),o}function setupClientItemListeners(e,t,n){n&&e.addEventListener("click",(()=>{const n="true"===e.dataset.selected;e.dataset.selected=n?"false":"true",n?(e.classList.remove("selected"),window.selectedClients=window.selectedClients.filter((e=>e!==t))):(e.classList.add("selected"),window.selectedClients.includes(t)||window.selectedClients.push(t))}))}function setupUninstallButton(e,t,n,s,a,l,o){if(t){const i=document.createElement("div");i.className="status-container";const r=document.createElement("span");if(r.className=`status-badge ${o}`,r.textContent=t,i.appendChild(r),"completed"===n.status&&"install"===n.type){const e=createUninstallButton(s,a,l);i.appendChild(e)}e.appendChild(i)}}function createUninstallButton(e,t,n){const s=document.createElement("button");return s.className="uninstall-btn text-red-600 hover:text-red-800 ml-2",s.innerHTML='<i class="bx bx-trash"></i>',s.title="Uninstall from this client",s.onclick=async s=>{s.stopPropagation(),s.preventDefault();if(await showConfirm("Uninstall Confirmation",`Are you sure you want to uninstall ${n} from ${e}?`)){window.selectedClients=[e],showInstallLoadingModal("Uninstalling");const s={[n]:{removeData:!0}};try{updateOverallInstallStatus("in-progress",`Uninstalling ${n} from ${e}...`),await uninstallTools(t,s,[e])}catch(e){updateOverallInstallStatus("failed",`Error during uninstall: ${e.message}`)}}return!1},s}function addSectionTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Client Status",e.insertBefore(t,e.firstChild)}}function addEnvironmentTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Environment Variables",e.insertBefore(t,e.firstChild)}}function addNoEnvMessage(e){const t=document.createElement("p");t.className="text-gray-600",t.textContent="No environment variables required for this MCP server.",e.appendChild(t)}function createEnvironmentInputs(e,t,n,s,a={}){Object.keys(e).forEach((l=>{const o=e[l],i=`env_${l}`,r=document.createElement("div");r.className="mb-3";const d=document.createElement("label");d.htmlFor=i,d.className="block text-sm font-medium text-gray-700 mb-1",d.innerHTML=`${l} ${o.Required?'<span class="text-red-500">*</span>':""}`;const c=document.createElement("input");c.type=o.isSecret?"password":"text",c.id=i,c.name=l,c.placeholder=o.Description||l,c.required=o.Required,c.className="input-field";let m=o.Default||"";if(a&&a[l]?m=a[l]:n&&n.MSRooCode&&n.MSRooCode.mcpServers&&n.MSRooCode.mcpServers[s]&&n.MSRooCode.mcpServers[s].env&&n.MSRooCode.mcpServers[s].env[l]&&(m=n.MSRooCode.mcpServers[s].env[l]),c.value=m,r.appendChild(d),r.appendChild(c),o.Description){const e=document.createElement("p");e.className="text-xs text-gray-500 mt-1",e.textContent=o.Description,r.appendChild(e)}t.appendChild(r)}))}function addArgumentsTitle(e){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Arguments",e.appendChild(t)}function createArgumentsContainer(){const e=document.createElement("div");e.className="args-container mb-3";const t=document.createElement("button");return t.type="button",t.className="add-arg-button px-3 py-1 text-sm text-blue-600 hover:text-blue-800 border border-blue-600 hover:border-blue-800 rounded-md mb-2",t.innerHTML='<i class="bx bx-plus"></i> Add Argument',t.onclick=()=>e.appendChild(createArgumentInput()),e.appendChild(t),e}function createArgumentInput(e=""){const t=document.createElement("div");t.className="arg-wrapper flex items-center gap-2 mb-2";const n=document.createElement("input");n.type="text",n.className="arg-input flex-grow",n.value=e,n.placeholder="Enter argument value";const s=document.createElement("button");return s.type="button",s.className="remove-arg-button text-red-600 hover:text-red-800",s.innerHTML='<i class="bx bx-trash"></i>',s.onclick=()=>t.remove(),t.appendChild(n),t.appendChild(s),t}function createReadOnlyTextBox(e,t,n,s){const a=document.createElement("div");a.className="mb-3 sse-info-field";const l=document.createElement("label");l.htmlFor=s,l.className="block text-sm font-medium text-gray-700 mb-1",l.textContent=t;const o=document.createElement("input");o.type="text",o.id=s,o.value=n,o.readOnly=!0,o.className="input-field sse-input-readonly w-full",a.appendChild(l),a.appendChild(o),e.appendChild(a)}function addPythonEnvironmentInput(e,t,n){const s=document.createElement("div");s.className="mt-4";const a=document.createElement("label");a.htmlFor="python_env",a.className="block text-sm font-medium text-gray-700 mb-1",a.textContent="Python Environment";const l=document.createElement("input");l.type="text",l.id="python_env",l.className="input-field",l.placeholder="Enter Python environment path (optional)";const o=document.createElement("p");o.className="text-xs text-gray-500 mt-1",o.textContent="Specify the Python exectable file(e.g. C:/python312/python) to use for installation. Leave empty to use system default. You can specify value in Settings page",s.appendChild(a),s.appendChild(l),s.appendChild(o),n.appendChild(s),fetch("/api/settings").then((e=>e.json())).then((n=>{n&&n.data&&n.data.pythonEnvs&&(l.value=n.data.pythonEnvs[`${e}:${t}`]||n.data.pythonEnvs.system||"")})).catch((()=>{}))}function renderRequirements(e,t,n,s){return e.map((e=>{const a=t[e.name]||{};let l=a.installed?"text-green-600 bg-green-50":"text-yellow-600 bg-yellow-50",o=a.installed?"Installed":"Required",i=a.version?` • <span class="font-medium">${a.version}</span>`:"",r="";return a.installed&&a.availableUpdate&&a.availableUpdate.version&&a.version&&compareVersions(a.availableUpdate.version,a.version)>0&&(l="text-yellow-600 bg-yellow-50",o=`<span style="color: #f59e0b; font-weight: bold; margin-right: 5px;">↑</span>${a.availableUpdate.version}`,r=`\n <label class="inline-flex items-center cursor-pointer ml-2">\n <input type="checkbox" class="toggle-update sr-only"\n data-name="${e.name}"\n data-version="${a.availableUpdate.version}"\n data-category="${n}"\n data-server="${s}">\n <div class="relative w-10 h-5 bg-gray-200 rounded-full toggle-bg">\n <div class="absolute inset-y-0 left-0 w-5 h-5 bg-white rounded-full transition-transform duration-300 transform"></div>\n </div>\n <span class="ml-2 text-sm text-gray-700">Update</span>\n </label>\n `),`\n <div class="border border-gray-200 p-3 rounded-lg mb-2 hover:bg-gray-50">\n <div class="flex justify-between items-center">\n <div>\n <div class="font-semibold text-gray-800">${e.name}</div>\n <div class="text-sm text-gray-600 shadow-sm p-1 rounded bg-gray-50">\n <span class="font-medium">${a.type||"package"}</span>${i}\n </div>\n </div>\n <div class="flex items-center">\n <span class="${l} inline-flex items-center px-3 py-1 rounded-full text-sm">\n ${o}\n </span>\n ${r}\n </div>\n </div>\n </div>\n `})).join("")}function setupUpdateToggles(e){e.querySelectorAll(".toggle-update").forEach((e=>{e.addEventListener("change",(function(){const e=this.parentElement.querySelector(".toggle-bg");this.checked?(e.classList.add("bg-blue-500"),e.querySelector("div").classList.add("translate-x-5")):(e.classList.remove("bg-blue-500"),e.querySelector("div").classList.remove("translate-x-5"))}))}))}
|
|
2
2
|
//# sourceMappingURL=modalSetup.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{showToast}from"../notifications.js";import{state,setServerCounter,getServerCounter,clearEnvCountersForTab,clearServerRequirementCountersForTab}from"./state.js";function setupRealTimeValidation(e){const t=document.getElementById(e);if(!t)return;if(!t)return;const r=t.querySelector('input[name="name"]');r&&r.addEventListener("input",(e=>{const t=e.target.value.trim();t?/^[a-zA-Z0-9-_]+$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Only alphanumeric characters, hyphens, and underscores allowed"):showValidationMessage(e.target,"Name is required")}));const s=t.querySelector('input[name="displayName"]');s&&s.addEventListener("input",(e=>{const t=e.target.value.trim();t?t.length>100?showValidationMessage(e.target,"Must not exceed 100 characters"):showValidationMessage(e.target,"Valid display name",!1):showValidationMessage(e.target,"Display name is required")}));const a=t.querySelector('textarea[name="description"]');a&&a.addEventListener("input",(e=>{const t=e.target.value.trim();t.length>500?showValidationMessage(e.target,"Must not exceed 500 characters"):0===t.length?showValidationMessage(e.target,"Description is required"):showValidationMessage(e.target,"Valid description",!1)}));const n=t.querySelector('input[name="repository"]');n&&n.addEventListener("input",(e=>{const t=e.target.value.trim();if(t)try{new URL(t),showValidationMessage(e.target,"Valid URL",!1)}catch(t){showValidationMessage(e.target,"Invalid URL format")}else e.target.nextElementSibling?.remove()})),t.addEventListener("change",(e=>{if(e.target.name?.match(/servers\[\d+\]\.mode/)){const r=e.target.name.match(/servers\[(\d+)\]/)[1],s=t.querySelector(`[name="servers[${r}].installation.command"]`),a=t.querySelector(`[name="servers[${r}].installation.url"]`),n=t.querySelector(`[name="servers[${r}].installation.args"]`);"stdio"===e.target.value?(s&&(s.required=!0,showValidationMessage(s,"Command is required for stdio mode")),a&&(a.required=!1,a.value="",a.nextElementSibling?.remove())):"sse"===e.target.value&&(a&&(a.required=!0,showValidationMessage(a,"URL is required for sse mode")),s&&(s.required=!1,s.value="",s.nextElementSibling?.remove()),n&&(n.value="",n.nextElementSibling?.remove()))}})),t.addEventListener("input",(e=>{if(e.target.name?.includes(".installation.env[")){const t=e.target.name.match(/servers\[(\d+)\]\.installation\.env\[(\d+)\]\.(name|default)/);if(t){const[,r,s,a]=t;if("name"===a){const t=e.target.value.trim();t?/^[A-Z_][A-Z0-9_]*$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Must be uppercase with only letters, numbers, and underscores"):showValidationMessage(e.target,"Environment variable name is required")}}}}))}export async function submitForm(e,t,r=null){e.preventDefault();const s=e.target;let a,n=!1;if("create-category"===t)try{a=formDataToFeedConfiguration(s);const e=new URLSearchParams(window.location.search);n="edit"===e.get("action")&&e.get("category")===a.name}catch(e){return void console.error("Validation error:",e)}else{if("create-server"!==t)return void showToast("Invalid tab context for submission.","error");{if(!r||!r.name)return void showToast("No existing category selected or category data is missing.","error");const e=formDataToFeedConfiguration(s,!0,r);a=JSON.parse(JSON.stringify(r)),a.mcpServers=e.mcpServers||[];const t=new Set((a.requirements||[]).map((e=>`${e.type}|${e.name}|${e.version}`)));(e.requirements||[]).forEach((e=>{const r=`${e.type}|${e.name}|${e.version}`;t.has(r)||(a.requirements.push(e),t.add(r))})),n=!0}}try{const e=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categoryData:a,isUpdate:n})});if(!e.ok){const t=await e.json().catch((()=>({error:"Failed to parse error response"})));throw new Error(`HTTP error! status: ${e.status}, message: ${t.error||e.statusText}`)}await e.json();showToast("Form submitted successfully! See console for operation details.","success")}catch(e){console.error("Error submitting form:",e),showToast(`Error submitting form: ${e.message}. Please try again.`,"error")}}export function getFormData(e,t=!1,r=null){return formDataToFeedConfiguration(e,t,r)}function validateServerConfig(e){const t=[];if(e.name?/^[a-zA-Z0-9-_]+$/.test(e.name)?e.name.length>50&&t.push("Server name must not exceed 50 characters"):t.push("Server name must only contain alphanumeric characters, hyphens, and underscores"):t.push("Server name is required"),e.description&&""!==e.description.trim()?e.description.length>200&&t.push("Server description must not exceed 200 characters"):t.push("Server description is required"),e.mode?["stdio","sse"].includes(e.mode)||t.push('Server mode must be either "stdio" or "sse"'):t.push("Server mode is required"),"stdio"===e.mode)e.installation?.command?/^[a-zA-Z0-9-_.\\/]+$/.test(e.installation.command)||t.push("Command must only contain alphanumeric characters, hyphens, underscores, dots, and slashes"):t.push("Command is required for stdio server"),e.installation?.args?.length>0&&e.installation.args.forEach(((e,r)=>{/^[a-zA-Z0-9-_./\\]+$/.test(e)||t.push(`Argument ${r+1} must only contain alphanumeric characters, hyphens, underscores, dots, and slashes`)}));else if("sse"===e.mode)if(e.installation?.url)try{new URL(e.installation.url)}catch(e){t.push("Invalid URL format")}else t.push("URL is required for sse server");if(e.installation?.env&&Object.entries(e.installation.env).forEach((([e,r])=>{e?/^[A-Z_][A-Z0-9_]*$/.test(e)?e.length>50&&t.push(`Environment variable name "${e}" must not exceed 50 characters`):t.push(`Environment variable name "${e}" must be uppercase with only letters, numbers, and underscores`):t.push("Environment variable name is required"),r.Required&&!r.Default&&t.push(`Required environment variable "${e}" should have a default value`),r.Description&&r.Description.length>200&&t.push(`Description for environment variable "${e}" must not exceed 200 characters`)})),e.schemas)try{JSON.parse(e.schemas)}catch(e){t.push("Invalid JSON format in schemas")}return t}export function formDataToFeedConfiguration(e,t=!1,r=null){const s=new FormData(e),a={requirements:[],mcpServers:[]};let n;"onboardForm"===e.id?n="serversList":"onboardServerForm"===e.id?n="existingCategoryServersList":console.warn("[formDataToFeedConfiguration] Could not determine serversListId from formElement.id:",e.id),t?r&&(a.name=r.name):(a.name=s.get("name")||"",a.displayName=s.get("displayName")||"",a.description=s.get("description")||"",a.repository=s.get("repository")||void 0);const i=new Map,o=new Map;for(const[e,r]of s.entries()){if(t&&!e.startsWith("servers["))continue;const a=e.match(/^servers\[(\d+)\]\.(.+)$/);if(a){let t=parseInt(a[1],10);const n=a[2];let o=t;i.has(o)||i.set(o,{installation:{env:new Map},dependencies:{requirements:new Map},isNew:!0});const l=i.get(o);if("name"===n)l.name=r;else if("description"===n)l.description=r;else if("mode"===n)l.mode=r;else if("repository"===n)l.repository=r||void 0;else if("schemas"===n)l.schemas=r||void 0;else if("installation.command"===n)l.installation.command=r;else if("installation.args"===n)l.installation.args=r?r.split(",").map((e=>e.trim())).filter((e=>e)):[];else if("installation.url"===n)l.installation.url=r;else if(n.startsWith("installation.env[")){const t=n.match(/^installation\.env\[(\d+)\]\.(name|default|required|description)$/);if(t){const a=parseInt(t[1],10),n=t[2];l.installation.env.has(a)||l.installation.env.set(a,{});const i=l.installation.env.get(a);i[n]="required"===n?"on"===s.get(e):r||void 0}}else if(n.startsWith("requirements[")){const e=n.match(/^requirements\[(\d+)\]\.(.+)$/);if(e){const t=parseInt(e[1],10),s=e[2];l.dependencies.requirements.has(t)||l.dependencies.requirements.set(t,{registry:{}});const a=l.dependencies.requirements.get(t);"name"===s?a.name=r:"type"===s?a.type=r:"version"===s?a.version=r:"order"===s?a.order=r?parseInt(r,10):void 0:"alias"===s?a.alias=r||void 0:"registryType"===s?a.registryType=r:s.startsWith("registry.githubRelease.")?(a.registry.githubRelease=a.registry.githubRelease||{},a.registry.githubRelease[s.substring(23)]=r||void 0):s.startsWith("registry.artifacts.")?(a.registry.artifacts=a.registry.artifacts||{},a.registry.artifacts[s.substring(19)]=r||void 0):s.startsWith("registry.local.")&&(a.registry.local=a.registry.local||{},a.registry.local[s.substring(15)]=r||void 0)}}}}i.forEach(((t,r)=>{let s;if("sse"===t.mode)s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{url:t.installation.url||""},dependencies:{requirements:[]}};else{s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{command:t.installation.command,args:t.installation.args||[],env:{}},dependencies:{requirements:[]}};const e={};t.installation.env.forEach((t=>{t.name&&(e[t.name]={Required:t.required||!1,Description:t.description||"",Default:t.default||void 0})})),Object.keys(e).length>0?s.installation.env=e:delete s.installation.env}if(t.dependencies.requirements.forEach((e=>{if(!e.name||!e.type||!e.version)return;const t={name:e.name,type:e.type,version:e.version,alias:e.alias,order:e.order};e.registryType&&"public"!==e.registryType&&(t.registry={},"github"===e.registryType&&e.registry.githubRelease?t.registry.githubRelease={repository:e.registry.githubRelease.repository,assetsName:e.registry.githubRelease.assetsName,assetName:e.registry.githubRelease.assetName}:"artifacts"===e.registryType&&e.registry.artifacts?t.registry.artifacts={registryUrl:e.registry.artifacts.registryUrl,registryName:e.registry.artifacts.registryName}:"local"===e.registryType&&e.registry.local&&(t.registry.local={localPath:e.registry.local.localPath,assetName:e.registry.local.assetName}),t.registry.githubRelease&&!t.registry.githubRelease.repository&&delete t.registry.githubRelease,t.registry.artifacts&&!t.registry.artifacts.registryUrl&&delete t.registry.artifacts,t.registry.local&&!t.registry.local.localPath&&delete t.registry.local,0===Object.keys(t.registry).length&&delete t.registry),s.dependencies.requirements.push({name:e.name,version:e.version,order:e.order});const r=`${e.type}|${e.name}|${e.version}`;if(!o.has(r)){const{order:e,...s}=t;o.set(r,s)}})),0===s.dependencies.requirements.length&&delete s.dependencies,"onboardServerForm"===e.id&&n){const t=`#${n} .server-item[data-index="${r}"]`,a=document.querySelector(t);if(a&&a.dataset.systemTags)try{s.systemTags=JSON.parse(a.dataset.systemTags)}catch(t){console.error(`[formDataToFeedConfiguration] Error parsing systemTags for server index ${r} ('${s.name}') on ${e.id}:`,t,a.dataset.systemTags),s.systemTags={parseError:!0}}}else delete s.systemTags;a.mcpServers.push(s)})),t&&r&&Array.isArray(r.mcpServers)&&r.mcpServers.forEach((e=>{a.mcpServers.some((t=>t.name===e.name))||e.systemTags&&"true"===e.systemTags.adhoc||(a.mcpServers.push(JSON.parse(JSON.stringify(e))),e.dependencies&&Array.isArray(e.dependencies.requirements)&&e.dependencies.requirements.forEach((t=>{const s=r.requirements?.find((e=>e.name===t.name&&e.type&&e.version===t.version));if(s){const e=`${s.type}|${s.name}|${s.version}`;o.has(e)||o.set(e,JSON.parse(JSON.stringify(s)))}else{const s=r.requirements?.find((e=>e.name===t.name&&e.version===t.version));if(s&&s.type){const e=`${s.type}|${t.name}|${t.version}`;o.has(e)||o.set(e,{name:t.name,version:t.version,type:s.type})}else console.warn(`Could not find full global requirement definition (or type) for ${t.name} v${t.version} from original server ${e.name}`)}})))})),a.requirements=Array.from(o.values());const l=[];if(t||(a.name?/^[a-zA-Z0-9-_]+$/.test(a.name)||l.push("Category name must only contain alphanumeric characters, hyphens, and underscores"):l.push("Category name is required"),a.displayName||l.push("Display name is required")),a.mcpServers.forEach(((e,t)=>{const r=validateServerConfig(e);r.length>0&&l.push(`Server ${t+1} (${e.name||"unnamed"}): ${r.join(", ")}`)})),a.requirements.forEach(((e,t)=>{if(e.name&&e.type&&e.version||l.push(`Requirement ${t+1}: name, type, and version are required`),e.registry){const r=Object.keys(e.registry)[0];["githubRelease","artifacts","local"].includes(r)||l.push(`Requirement ${t+1}: Invalid registry type ${r}`)}})),l.length>0){e.querySelectorAll(".validation-error-message").forEach((e=>e.remove()));l.forEach((t=>{let r=null;if(t.includes("Category name")?r='input[name="name"]':t.includes("Display name")&&(r='input[name="displayName"]'),r){const s=e.querySelector(r);if(s){const e=document.createElement("div");e.className="validation-error-message text-red-500 text-xs mt-1",e.textContent=t,s.insertAdjacentElement("afterend",e)}}}))}return a}export function populateForm(e,t="onboardForm",r=!1,s=null){const a=document.getElementById(t);if(!a)return void console.error(`populateForm: Form with ID "${t}" not found.`);const n=s||("onboardForm"===t?"serversList":"existingCategoryServersList");if(resetOnboardFormDynamicContent(t,n),setupRealTimeValidation(t),e){if("onboardForm"===t){a.querySelector('[name="name"]').value=e.name||"",a.querySelector('[name="displayName"]').value=e.displayName||"",a.querySelector('[name="description"]').value=e.description||"",e.repository&&(a.querySelector('[name="repository"]').value=e.repository);const t=new URLSearchParams(window.location.search);if("edit"===t.get("action")&&t.get("category")===e.name){const e=a.querySelector('[name="name"]');e&&(e.readOnly=!0,e.classList.add("bg-gray-100","cursor-not-allowed"))}}else if("onboardServerForm"===t&&e){a.querySelector('input[name="name"]').value=e.name||"",a.querySelector('input[name="displayName"]').value=e.displayName||"",a.querySelector('textarea[name="description"]').value=e.description||"",a.querySelector('input[name="repository"]').value=e.repository||"";const t=document.getElementById("existingCategoryBasicInfoContainer");t&&t.classList.remove("hidden");const r=document.getElementById("existingCategoryMcpServersContainer");r&&r.classList.remove("hidden")}setServerCounter(n,0),clearEnvCountersForTab(n),clearServerRequirementCountersForTab(n),(e.mcpServers||[]).forEach((s=>{const i=getServerCounter(n);window.addServer(n,r,s);const o=a.querySelector(`#${n} .server-item[data-index="${i}"]`);if(o)if("onboardServerForm"===t)if("true"===s.systemTags?.adhoc)o.dataset.systemTags=JSON.stringify(s.systemTags);else if(state.originalServerNamesForFormPopulation&&s.name&&state.originalServerNamesForFormPopulation.has(s.name))o.dataset.systemTags=JSON.stringify({adhoc:"true"});else if(s.systemTags&&Object.keys(s.systemTags).length>0){const e={...s.systemTags};delete e.adhoc,Object.keys(e).length>0?o.dataset.systemTags=JSON.stringify(e):delete o.dataset.systemTags}else delete o.dataset.systemTags;else s.systemTags?o.dataset.systemTags=JSON.stringify(s.systemTags):delete o.dataset.systemTags;const l=a.querySelector(`[name="servers[${i}].name"]`);l&&(l.value=s.name||"");const m=a.querySelector(`[name="servers[${i}].mode"]`);m&&(m.value=s.mode||"stdio","function"==typeof window.renderInstallationConfig&&window.renderInstallationConfig(i,n,s.mode||"stdio",r,s.installation));const c=a.querySelector(`[name="servers[${i}].description"]`);if(c&&(c.value=s.description||""),s.schemas){const e=document.getElementById(`schema-path-${i}`);e&&(e.value=s.schemas)}if(s.repository){const e=a.querySelector(`[name="servers[${i}].repository"]`);e&&(e.value=s.repository)}if(s.installation)if("sse"===s.mode){const e=a.querySelector(`[name="servers[${i}].installation.url"]`);e&&(e.value=s.installation.url||"")}else{const e=a.querySelector(`[name="servers[${i}].installation.command"]`);if(e&&(e.value=s.installation.command||""),s.installation.args&&Array.isArray(s.installation.args)){const e=a.querySelector(`[name="servers[${i}].installation.args"]`);e&&(e.value=s.installation.args.join(", "))}s.installation.env&&Object.entries(s.installation.env).forEach((([e,t])=>{const s=window.addEnvVariable(i,n,r),o=a.querySelector(`[name="servers[${i}].installation.env[${s}].name"]`);if(o&&(o.value=e),t.Default){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].default"]`);e&&(e.value=t.Default)}if(t.Required){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].required"]`);e&&(e.checked=!0)}if(t.Description){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].description"]`);e&&(e.value=t.Description)}}))}if(s.dependencies&&s.dependencies.requirements){const t=r&&!("true"===s.systemTags?.adhoc);s.dependencies.requirements.forEach((r=>{const s=(e.requirements||[]).find((e=>e.name===r.name));if(!s)return void console.warn(`Could not find full requirement config for dependency name: ${r.name} (version ${r.version} specified by server, but lookup is by name only). Skipping.`);const o=window.addServerRequirement(i,n,t);a.querySelector(`[name="servers[${i}].requirements[${o}].name"]`).value=s.name||"",a.querySelector(`[name="servers[${i}].requirements[${o}].type"]`).value=s.type||"",a.querySelector(`[name="servers[${i}].requirements[${o}].version"]`).value=s.version||"",void 0!==r.order&&(a.querySelector(`[name="servers[${i}].requirements[${o}].order"]`).value=r.order),"command"===s.type&&s.alias&&(a.querySelector(`[name="servers[${i}].requirements[${o}].alias"]`).value=s.alias,window.toggleServerAliasField(i,o,n));let l="public";s.registry&&(s.registry.githubRelease?l="github":s.registry.artifacts?l="artifacts":s.registry.local&&(l="local"));const m=a.querySelector(`[name="servers[${i}].requirements[${o}].registryType"]`);if(m&&(m.value=l,window.toggleServerRegistryConfig(i,o,n)),"github"===l&&s.registry.githubRelease){const e=s.registry.githubRelease;e.repository&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.repository"]`).value=e.repository),e.assetsName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetsName"]`).value=e.assetsName),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetName"]`).value=e.assetName)}else if("artifacts"===l&&s.registry.artifacts){const e=s.registry.artifacts;e.registryUrl&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryUrl"]`).value=e.registryUrl),e.registryName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryName"]`).value=e.registryName)}else if("local"===l&&s.registry.local){const e=s.registry.local;e.localPath&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.localPath"]`).value=e.localPath),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.assetName"]`).value=e.assetName)}}))}}))}}export function resetOnboardFormDynamicContent(e="onboardForm",t="serversList"){const r=document.getElementById(e);r&&"onboardServerForm"!==e&&r.reset();const s=document.getElementById(t);let a,n;if(s&&(s.innerHTML=""),setServerCounter(0),state&&state.envCounters&&"function"==typeof state.envCounters.clear&&state.envCounters.clear(),state&&state.serverRequirementCounters&&"function"==typeof state.serverRequirementCounters.clear&&state.serverRequirementCounters.clear(),"onboardForm"===e?(a="validationStatusPanelNewCategory",n="validationStatusContentNewCategory"):"onboardServerForm"===e&&(a="validationStatusPanelExistingCategory",n="validationStatusContentExistingCategoryTab"),a){const e=document.getElementById(a);e&&e.classList.add("hidden")}if(n){const e=document.getElementById(n);e&&(e.innerHTML="")}if("onboardServerForm"===e){const e=document.getElementById("existingCategoryBasicInfoContainer");e&&e.classList.add("hidden");const t=document.getElementById("existingCategoryMcpServersContainer");t&&t.classList.add("hidden")}setupRealTimeValidation(e)}export function showValidationMessage(e,t,r=!0){let s=e.nextElementSibling;s&&s.classList.contains("validation-message")||(s=document.createElement("div"),s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500"),e.insertAdjacentElement("afterend",s)),s.textContent=t,s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500")}export{setupRealTimeValidation};
|
|
1
|
+
import{showToast}from"../notifications.js";import{state,setServerCounter,getServerCounter,clearEnvCountersForTab,clearServerRequirementCountersForTab}from"./state.js";function setupRealTimeValidation(e){const t=document.getElementById(e);if(!t)return;if(!t)return;const r=t.querySelector('input[name="name"]');r&&r.addEventListener("input",(e=>{const t=e.target.value.trim();t?/^[a-zA-Z0-9-_]+$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Only alphanumeric characters, hyphens, and underscores allowed"):showValidationMessage(e.target,"Name is required")}));const s=t.querySelector('input[name="displayName"]');s&&s.addEventListener("input",(e=>{const t=e.target.value.trim();t?t.length>100?showValidationMessage(e.target,"Must not exceed 100 characters"):showValidationMessage(e.target,"Valid display name",!1):showValidationMessage(e.target,"Display name is required")}));const a=t.querySelector('textarea[name="description"]');a&&a.addEventListener("input",(e=>{const t=e.target.value.trim();t.length>500?showValidationMessage(e.target,"Must not exceed 500 characters"):0===t.length?showValidationMessage(e.target,"Description is required"):showValidationMessage(e.target,"Valid description",!1)}));const n=t.querySelector('input[name="repository"]');n&&n.addEventListener("input",(e=>{const t=e.target.value.trim();if(t)try{new URL(t),showValidationMessage(e.target,"Valid URL",!1)}catch(t){showValidationMessage(e.target,"Invalid URL format")}else e.target.nextElementSibling?.remove()})),t.addEventListener("change",(e=>{if(e.target.name?.match(/servers\[\d+\]\.mode/)){const r=e.target.name.match(/servers\[(\d+)\]/)[1],s=t.querySelector(`[name="servers[${r}].installation.command"]`),a=t.querySelector(`[name="servers[${r}].installation.url"]`),n=t.querySelector(`[name="servers[${r}].installation.args"]`);"stdio"===e.target.value?(s&&(s.required=!0,showValidationMessage(s,"Command is required for stdio mode")),a&&(a.required=!1,a.value="",a.nextElementSibling?.remove())):"sse"===e.target.value&&(a&&(a.required=!0,showValidationMessage(a,"URL is required for sse mode")),s&&(s.required=!1,s.value="",s.nextElementSibling?.remove()),n&&(n.value="",n.nextElementSibling?.remove()))}})),t.addEventListener("input",(e=>{if(e.target.name?.includes(".installation.env[")){const t=e.target.name.match(/servers\[(\d+)\]\.installation\.env\[(\d+)\]\.(name|default)/);if(t){const[,r,s,a]=t;if("name"===a){const t=e.target.value.trim();t?/^[A-Z_][A-Z0-9_]*$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Must be uppercase with only letters, numbers, and underscores"):showValidationMessage(e.target,"Environment variable name is required")}}}}))}export async function submitForm(e,t,r=null){e.preventDefault();const s=e.target;let a,n=!1;if("create-category"===t)try{a=formDataToFeedConfiguration(s);const e=new URLSearchParams(window.location.search);n="edit"===e.get("action")&&e.get("category")===a.name}catch(e){return void console.error("Validation error:",e)}else{if("create-server"!==t)return void showToast("Invalid tab context for submission.","error");{if(!r||!r.name)return void showToast("No existing category selected or category data is missing.","error");const e=formDataToFeedConfiguration(s,!0,r);a=JSON.parse(JSON.stringify(r)),a.mcpServers=e.mcpServers||[];const t=new Set((a.requirements||[]).map((e=>`${e.type}|${e.name}|${e.version}`)));(e.requirements||[]).forEach((e=>{const r=`${e.type}|${e.name}|${e.version}`;t.has(r)||(a.requirements.push(e),t.add(r))})),n=!0}}try{const e=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categoryData:a,isUpdate:n})});if(!e.ok){const t=await e.json().catch((()=>({error:"Failed to parse error response"})));throw new Error(`HTTP error! status: ${e.status}, message: ${t.error||e.statusText}`)}await e.json();showToast("Form submitted successfully! See console for operation details.","success")}catch(e){console.error("Error submitting form:",e),showToast(`Error submitting form: ${e.message}. Please try again.`,"error")}}export function getFormData(e,t=!1,r=null){return formDataToFeedConfiguration(e,t,r)}function validateServerConfig(e){const t=[];if(e.name?/^[a-zA-Z0-9-_]+$/.test(e.name)?e.name.length>50&&t.push("Server name must not exceed 50 characters"):t.push("Server name must only contain alphanumeric characters, hyphens, and underscores"):t.push("Server name is required"),e.description&&""!==e.description.trim()?e.description.length>200&&t.push("Server description must not exceed 200 characters"):t.push("Server description is required"),e.mode?["stdio","sse"].includes(e.mode)||t.push('Server mode must be either "stdio" or "sse"'):t.push("Server mode is required"),"stdio"===e.mode)e.installation?.command?/^[a-zA-Z0-9-_.\\/]+$/.test(e.installation.command)||t.push("Command must only contain alphanumeric characters, hyphens, underscores, dots, and slashes"):t.push("Command is required for stdio server"),e.installation?.args?.length>0&&e.installation.args.forEach(((e,r)=>{/^[a-zA-Z0-9-_./\\]+$/.test(e)||t.push(`Argument ${r+1} must only contain alphanumeric characters, hyphens, underscores, dots, and slashes`)}));else if("sse"===e.mode)if(e.installation?.url)try{new URL(e.installation.url)}catch(e){t.push("Invalid URL format")}else t.push("URL is required for sse server");if(e.installation?.env&&Object.entries(e.installation.env).forEach((([e,r])=>{e?/^[A-Z_][A-Z0-9_]*$/.test(e)?e.length>50&&t.push(`Environment variable name "${e}" must not exceed 50 characters`):t.push(`Environment variable name "${e}" must be uppercase with only letters, numbers, and underscores`):t.push("Environment variable name is required"),r.Required&&!r.Default&&t.push(`Required environment variable "${e}" should have a default value`),r.Description&&r.Description.length>200&&t.push(`Description for environment variable "${e}" must not exceed 200 characters`)})),e.schemas)try{JSON.parse(e.schemas)}catch(e){t.push("Invalid JSON format in schemas")}return t}export function formDataToFeedConfiguration(e,t=!1,r=null){const s=new FormData(e),a={requirements:[],mcpServers:[]};let n;"onboardForm"===e.id?n="serversList":"onboardServerForm"===e.id?n="existingCategoryServersList":console.warn("[formDataToFeedConfiguration] Could not determine serversListId from formElement.id:",e.id),t?r&&(a.name=r.name):(a.name=s.get("name")||"",a.displayName=s.get("displayName")||"",a.description=s.get("description")||"",a.repository=s.get("repository")||void 0);const i=new Map,o=new Map;for(const[e,r]of s.entries()){if(t&&!e.startsWith("servers["))continue;const a=e.match(/^servers\[(\d+)\]\.(.+)$/);if(a){let t=parseInt(a[1],10);const n=a[2];let o=t;i.has(o)||i.set(o,{installation:{env:new Map},dependencies:{requirements:new Map},isNew:!0});const l=i.get(o);if("name"===n)l.name=r;else if("description"===n)l.description=r;else if("mode"===n)l.mode=r;else if("repository"===n)l.repository=r||void 0;else if("schemas"===n)l.schemas=r||void 0;else if("installation.command"===n)l.installation.command=r;else if("installation.args"===n)l.installation.args=r?r.split(",").map((e=>e.trim())).filter((e=>e)):[];else if("installation.url"===n)l.installation.url=r;else if("installation.isLocal"===n)l.installation.isLocal="on"===r;else if("installation.startingCommand"===n)l.installation.startingCommand=r.trim()||void 0;else if(n.startsWith("installation.env[")){const t=n.match(/^installation\.env\[(\d+)\]\.(name|default|required|description)$/);if(t){const a=parseInt(t[1],10),n=t[2];l.installation.env.has(a)||l.installation.env.set(a,{});const i=l.installation.env.get(a);i[n]="required"===n?"on"===s.get(e):r||void 0}}else if(n.startsWith("requirements[")){const e=n.match(/^requirements\[(\d+)\]\.(.+)$/);if(e){const t=parseInt(e[1],10),s=e[2];l.dependencies.requirements.has(t)||l.dependencies.requirements.set(t,{registry:{}});const a=l.dependencies.requirements.get(t);"name"===s?a.name=r:"type"===s?a.type=r:"version"===s?a.version=r:"order"===s?a.order=r?parseInt(r,10):void 0:"alias"===s?a.alias=r||void 0:"registryType"===s?a.registryType=r:s.startsWith("registry.githubRelease.")?(a.registry.githubRelease=a.registry.githubRelease||{},a.registry.githubRelease[s.substring(23)]=r||void 0):s.startsWith("registry.artifacts.")?(a.registry.artifacts=a.registry.artifacts||{},a.registry.artifacts[s.substring(19)]=r||void 0):s.startsWith("registry.local.")&&(a.registry.local=a.registry.local||{},a.registry.local[s.substring(15)]=r||void 0)}}}}i.forEach(((t,r)=>{let s;if("sse"===t.mode)s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{url:t.installation.url||""},dependencies:{requirements:[]}},t.installation.isLocal&&t.installation.startingCommand&&(s.installation.startingCommand=t.installation.startingCommand);else{s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{command:t.installation.command,args:t.installation.args||[],env:{}},dependencies:{requirements:[]}};const e={};t.installation.env.forEach((t=>{t.name&&(e[t.name]={Required:t.required||!1,Description:t.description||"",Default:t.default||void 0})})),Object.keys(e).length>0?s.installation.env=e:delete s.installation.env}if(t.dependencies.requirements.forEach((e=>{if(!e.name||!e.type||!e.version)return;const t={name:e.name,type:e.type,version:e.version,alias:e.alias,order:e.order};e.registryType&&"public"!==e.registryType&&(t.registry={},"github"===e.registryType&&e.registry.githubRelease?t.registry.githubRelease={repository:e.registry.githubRelease.repository,assetsName:e.registry.githubRelease.assetsName,assetName:e.registry.githubRelease.assetName}:"artifacts"===e.registryType&&e.registry.artifacts?t.registry.artifacts={registryUrl:e.registry.artifacts.registryUrl,registryName:e.registry.artifacts.registryName}:"local"===e.registryType&&e.registry.local&&(t.registry.local={localPath:e.registry.local.localPath,assetName:e.registry.local.assetName}),t.registry.githubRelease&&!t.registry.githubRelease.repository&&delete t.registry.githubRelease,t.registry.artifacts&&!t.registry.artifacts.registryUrl&&delete t.registry.artifacts,t.registry.local&&!t.registry.local.localPath&&delete t.registry.local,0===Object.keys(t.registry).length&&delete t.registry),s.dependencies.requirements.push({name:e.name,version:e.version,order:e.order});const r=`${e.type}|${e.name}|${e.version}`;if(!o.has(r)){const{order:e,...s}=t;o.set(r,s)}})),0===s.dependencies.requirements.length&&delete s.dependencies,"onboardServerForm"===e.id&&n){const t=`#${n} .server-item[data-index="${serverIndex}"]`,r=document.querySelector(t);if(r&&r.dataset.systemTags)try{s.systemTags=JSON.parse(r.dataset.systemTags)}catch(t){console.error(`[formDataToFeedConfiguration] Error parsing systemTags for server index ${serverIndex} ('${s.name}') on ${e.id}:`,t,r.dataset.systemTags),s.systemTags={parseError:!0}}}else delete s.systemTags;a.mcpServers.push(s)})),t&&r&&Array.isArray(r.mcpServers)&&r.mcpServers.forEach((e=>{a.mcpServers.some((t=>t.name===e.name))||e.systemTags&&"true"===e.systemTags.adhoc||(a.mcpServers.push(JSON.parse(JSON.stringify(e))),e.dependencies&&Array.isArray(e.dependencies.requirements)&&e.dependencies.requirements.forEach((t=>{const s=r.requirements?.find((e=>e.name===t.name&&e.type&&e.version===t.version));if(s){const e=`${s.type}|${s.name}|${s.version}`;o.has(e)||o.set(e,JSON.parse(JSON.stringify(s)))}else{const s=r.requirements?.find((e=>e.name===t.name&&e.version===t.version));if(s&&s.type){const e=`${s.type}|${t.name}|${t.version}`;o.has(e)||o.set(e,{name:t.name,version:t.version,type:s.type})}else console.warn(`Could not find full global requirement definition (or type) for ${t.name} v${t.version} from original server ${e.name}`)}})))})),a.requirements=Array.from(o.values());const l=[];if(t||(a.name?/^[a-zA-Z0-9-_]+$/.test(a.name)||l.push("Category name must only contain alphanumeric characters, hyphens, and underscores"):l.push("Category name is required"),a.displayName||l.push("Display name is required")),a.mcpServers.forEach(((e,t)=>{const r=validateServerConfig(e);r.length>0&&l.push(`Server ${t+1} (${e.name||"unnamed"}): ${r.join(", ")}`)})),a.requirements.forEach(((e,t)=>{if(e.name&&e.type&&e.version||l.push(`Requirement ${t+1}: name, type, and version are required`),e.registry){const r=Object.keys(e.registry)[0];["githubRelease","artifacts","local"].includes(r)||l.push(`Requirement ${t+1}: Invalid registry type ${r}`)}})),l.length>0){e.querySelectorAll(".validation-error-message").forEach((e=>e.remove()));l.forEach((t=>{let r=null;if(t.includes("Category name")?r='input[name="name"]':t.includes("Display name")&&(r='input[name="displayName"]'),r){const s=e.querySelector(r);if(s){const e=document.createElement("div");e.className="validation-error-message text-red-500 text-xs mt-1",e.textContent=t,s.insertAdjacentElement("afterend",e)}}}))}return a}export function populateForm(e,t="onboardForm",r=!1,s=null){const a=document.getElementById(t);if(!a)return void console.error(`populateForm: Form with ID "${t}" not found.`);const n=s||("onboardForm"===t?"serversList":"existingCategoryServersList");if(resetOnboardFormDynamicContent(t,n),setupRealTimeValidation(t),e){if("onboardForm"===t){a.querySelector('[name="name"]').value=e.name||"",a.querySelector('[name="displayName"]').value=e.displayName||"",a.querySelector('[name="description"]').value=e.description||"",e.repository&&(a.querySelector('[name="repository"]').value=e.repository);const t=new URLSearchParams(window.location.search);if("edit"===t.get("action")&&t.get("category")===e.name){const e=a.querySelector('[name="name"]');e&&(e.readOnly=!0,e.classList.add("bg-gray-100","cursor-not-allowed"))}}else if("onboardServerForm"===t&&e){a.querySelector('input[name="name"]').value=e.name||"",a.querySelector('input[name="displayName"]').value=e.displayName||"",a.querySelector('textarea[name="description"]').value=e.description||"",a.querySelector('input[name="repository"]').value=e.repository||"";const t=document.getElementById("existingCategoryBasicInfoContainer");t&&t.classList.remove("hidden");const r=document.getElementById("existingCategoryMcpServersContainer");r&&r.classList.remove("hidden")}setServerCounter(n,0),clearEnvCountersForTab(n),clearServerRequirementCountersForTab(n),(e.mcpServers||[]).forEach((s=>{const i=getServerCounter(n);window.addServer(n,r,s);const o=a.querySelector(`#${n} .server-item[data-index="${i}"]`);if(o)if("onboardServerForm"===t)if("true"===s.systemTags?.adhoc)o.dataset.systemTags=JSON.stringify(s.systemTags);else if(state.originalServerNamesForFormPopulation&&s.name&&state.originalServerNamesForFormPopulation.has(s.name))o.dataset.systemTags=JSON.stringify({adhoc:"true"});else if(s.systemTags&&Object.keys(s.systemTags).length>0){const e={...s.systemTags};delete e.adhoc,Object.keys(e).length>0?o.dataset.systemTags=JSON.stringify(e):delete o.dataset.systemTags}else delete o.dataset.systemTags;else s.systemTags?o.dataset.systemTags=JSON.stringify(s.systemTags):delete o.dataset.systemTags;const l=a.querySelector(`[name="servers[${i}].name"]`);l&&(l.value=s.name||"");const m=a.querySelector(`[name="servers[${i}].mode"]`);m&&(m.value=s.mode||"stdio","function"==typeof window.renderInstallationConfig&&window.renderInstallationConfig(i,n,s.mode||"stdio",r,s.installation));const c=a.querySelector(`[name="servers[${i}].description"]`);if(c&&(c.value=s.description||""),s.schemas){const e=document.getElementById(`schema-path-${i}`);e&&(e.value=s.schemas)}if(s.repository){const e=a.querySelector(`[name="servers[${i}].repository"]`);e&&(e.value=s.repository)}if(s.installation)if("sse"===s.mode){const e=a.querySelector(`[name="servers[${i}].installation.url"]`);e&&(e.value=s.installation.url||"")}else{const e=a.querySelector(`[name="servers[${i}].installation.command"]`);if(e&&(e.value=s.installation.command||""),s.installation.args&&Array.isArray(s.installation.args)){const e=a.querySelector(`[name="servers[${i}].installation.args"]`);e&&(e.value=s.installation.args.join(", "))}s.installation.env&&Object.entries(s.installation.env).forEach((([e,t])=>{const s=window.addEnvVariable(i,n,r),o=a.querySelector(`[name="servers[${i}].installation.env[${s}].name"]`);if(o&&(o.value=e),t.Default){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].default"]`);e&&(e.value=t.Default)}if(t.Required){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].required"]`);e&&(e.checked=!0)}if(t.Description){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].description"]`);e&&(e.value=t.Description)}}))}if(s.dependencies&&s.dependencies.requirements){const t=r&&!("true"===s.systemTags?.adhoc);s.dependencies.requirements.forEach((r=>{const s=(e.requirements||[]).find((e=>e.name===r.name));if(!s)return void console.warn(`Could not find full requirement config for dependency name: ${r.name} (version ${r.version} specified by server, but lookup is by name only). Skipping.`);const o=window.addServerRequirement(i,n,t);a.querySelector(`[name="servers[${i}].requirements[${o}].name"]`).value=s.name||"",a.querySelector(`[name="servers[${i}].requirements[${o}].type"]`).value=s.type||"",a.querySelector(`[name="servers[${i}].requirements[${o}].version"]`).value=s.version||"",void 0!==r.order&&(a.querySelector(`[name="servers[${i}].requirements[${o}].order"]`).value=r.order),"command"===s.type&&s.alias&&(a.querySelector(`[name="servers[${i}].requirements[${o}].alias"]`).value=s.alias,window.toggleServerAliasField(i,o,n));let l="public";s.registry&&(s.registry.githubRelease?l="github":s.registry.artifacts?l="artifacts":s.registry.local&&(l="local"));const m=a.querySelector(`[name="servers[${i}].requirements[${o}].registryType"]`);if(m&&(m.value=l,window.toggleServerRegistryConfig(i,o,n)),"github"===l&&s.registry.githubRelease){const e=s.registry.githubRelease;e.repository&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.repository"]`).value=e.repository),e.assetsName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetsName"]`).value=e.assetsName),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetName"]`).value=e.assetName)}else if("artifacts"===l&&s.registry.artifacts){const e=s.registry.artifacts;e.registryUrl&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryUrl"]`).value=e.registryUrl),e.registryName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryName"]`).value=e.registryName)}else if("local"===l&&s.registry.local){const e=s.registry.local;e.localPath&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.localPath"]`).value=e.localPath),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.assetName"]`).value=e.assetName)}}))}}))}}export function resetOnboardFormDynamicContent(e="onboardForm",t="serversList"){const r=document.getElementById(e);r&&"onboardServerForm"!==e&&r.reset();const s=document.getElementById(t);let a,n;if(s&&(s.innerHTML=""),setServerCounter(0),state&&state.envCounters&&"function"==typeof state.envCounters.clear&&state.envCounters.clear(),state&&state.serverRequirementCounters&&"function"==typeof state.serverRequirementCounters.clear&&state.serverRequirementCounters.clear(),"onboardForm"===e?(a="validationStatusPanelNewCategory",n="validationStatusContentNewCategory"):"onboardServerForm"===e&&(a="validationStatusPanelExistingCategory",n="validationStatusContentExistingCategoryTab"),a){const e=document.getElementById(a);e&&e.classList.add("hidden")}if(n){const e=document.getElementById(n);e&&(e.innerHTML="")}if("onboardServerForm"===e){const e=document.getElementById("existingCategoryBasicInfoContainer");e&&e.classList.add("hidden");const t=document.getElementById("existingCategoryMcpServersContainer");t&&t.classList.add("hidden")}setupRealTimeValidation(e)}export function showValidationMessage(e,t,r=!0){let s=e.nextElementSibling;s&&s.classList.contains("validation-message")||(s=document.createElement("div"),s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500"),e.insertAdjacentElement("afterend",s)),s.textContent=t,s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500")}export{setupRealTimeValidation};
|
|
2
2
|
//# sourceMappingURL=formProcessor.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{serverTemplate,envVariableTemplate,serverRequirementTemplate}from"./templates.js";import{state,setServerCounter,getServerCounter,setEnvCounter,getEnvCounter,deleteEnvCounter,clearEnvCountersForTab,setServerRequirementCounter,getServerRequirementCounter,deleteServerRequirementCounter,clearServerRequirementCountersForTab}from"./state.js";import{getFormData,populateForm,resetOnboardFormDynamicContent}from"./formProcessor.js";import{showToast}from"../notifications.js";function reindexElements(e,t,r,n){n.forEach((({selector:n,idBase:s,namePattern:o})=>{const a=e.querySelector(n);if(a&&(s&&(a.id=`${s}${r}`),o&&a.getAttribute("name"))){const e=a.getAttribute("name").replace(new RegExp(o.replace("INDEX",t)),`$1${r}$2`);a.setAttribute("name",e)}}))}function reindexServers(e="serversList"){const t=document.getElementById(e);if(!t)return;const r=t.querySelectorAll(".server-item"),n=new Map,s=new Map;r.forEach(((t,r)=>{const o=parseInt(t.dataset.index,10);t.dataset.index=r;const a=t.querySelector("h3");if(a){const e=a.textContent||"",t=`MCP Server #${r+1}`;let n="";e.includes("(Adhoc - Editable)")?n=' <span class="text-sm text-blue-600 ml-1">(Adhoc - Editable)</span>':e.includes("(Read-only)")&&(n=" (Read-only)"),a.innerHTML=`${t}${n}`}const i=t.querySelector(`#${e}-server-header-${o}`);if(i){i.id=`${e}-server-header-${r}`;const t=`${e}-server-content-${o}`,n=`${e}-server-content-${r}`;let s=i.getAttribute("onclick");s&&(s=s.replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),n),i.setAttribute("onclick",s));let a=i.getAttribute("onkeydown");a&&(a=a.replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),n),i.setAttribute("onkeydown",a)),i.setAttribute("aria-controls",n)}const l=t.querySelector(`#${e}-server-title-${o}`);l&&(l.id=`${e}-server-title-${r}`);const c=t.querySelector(`#${e}-server-content-${o}`);c&&c.setAttribute("aria-labelledby",`${e}-server-title-${r}`),t.querySelectorAll("[onclick]").forEach((t=>{const n=t.getAttribute("onclick");if(!n)return;if(t.id===`${e}-server-header-${r}`)return;const s=n.replace(new RegExp(`\\((\\s*)${o}(\\s*[,\\)])`,"g"),`($1${r}$2`).replace(new RegExp(`${e}-server-deps-content-${o}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),`${e}-server-deps-content-${r}`).replace(new RegExp(`${e}-installation-content-${o}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),`${e}-installation-content-${r}`).replace(new RegExp(`${e}-env-vars-content-${o}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),`${e}-env-vars-content-${r}`);t.setAttribute("onclick",s)})),reindexElements(t,o,r,[{selector:`#${e}-server-content-${o}`,idBase:`${e}-server-content-`},{selector:`#${e}-server-deps-content-${o}`,idBase:`${e}-server-deps-content-`},{selector:`#${e}-installation-content-${o}`,idBase:`${e}-installation-content-`},{selector:`#${e}-env-vars-content-${o}`,idBase:`${e}-env-vars-content-`},{selector:`#schema-path-${o}`,idBase:"schema-path-"},{selector:`#envVarsContainer_${o}`,idBase:"envVarsContainer_"}]);const d=t.querySelector(`#envVarsContainer_${r}`);let u=0;d&&d.querySelectorAll(".env-var-item").forEach(((e,t)=>{const n=parseInt(e.dataset.envIndex,10);e.dataset.envIndex=t,reindexElements(e,n,t,[{selector:"[name]",namePattern:`(servers\\[${r}\\]\\.installation\\.env\\[)\\d+(\\]\\..+)`}]),u++})),n.set(r,u);const m=t.querySelector(`#server-requirements-list-${r}`);let v=0;m&&m.querySelectorAll(".server-requirement-item").forEach(((e,t)=>{const n=parseInt(e.dataset.reqIndex,10);e.dataset.reqIndex=t,reindexElements(e,n,t,[{selector:"[name]",namePattern:`(servers\\[${r}\\]\\.requirements\\[)\\d+(\\]\\..+)`}]),v++})),s.set(r,v)})),clearEnvCountersForTab(e),n.forEach(((t,r)=>setEnvCounter(e,r,t))),clearServerRequirementCountersForTab(e),s.forEach(((t,r)=>setServerRequirementCounter(e,r,t))),setServerCounter(e,r.length)}export function addServer(e="serversList",t=!1,r=null){const n=document.getElementById(e);if(!n)return-1;0===n.children.length&&(setServerCounter(e,0),clearEnvCountersForTab(e),clearServerRequirementCountersForTab(e));const s=getServerCounter(e);let o;o=!("true"===r?.systemTags?.adhoc)&&(!!t&&(state.originalServerNamesForFormPopulation?!!(r&&r.name&&state.originalServerNamesForFormPopulation.has(r.name)):!!r)),n.insertAdjacentHTML("beforeend",serverTemplate(s,t,r,e)),setEnvCounter(e,s,0),setServerRequirementCounter(e,s,0),setServerCounter(e,s+1);const a=n.querySelector(`.server-item[data-index="${s}"]`);if(a){r&&r.systemTags?a.dataset.systemTags=JSON.stringify(r.systemTags):r&&!r.systemTags?delete a.dataset.systemTags:r||delete a.dataset.systemTags,r&&r.name?a.dataset.originalName=r.name:delete a.dataset.originalName,setupServerMode(a,s,e,o,r),setupReadOnlyState(a,o,r,e,s);if([{contentId:`${e}-server-deps-content-${s}`,iconSelector:`#${e}-deps-header-${s} i`},{contentId:`${e}-installation-content-${s}`,iconSelector:`#${e}-startup-header-${s} i`},{contentId:`${e}-env-vars-content-${s}`,iconSelector:`#${e}-envars-header-${s} i`}].forEach((({contentId:e,iconSelector:t})=>{const r=document.getElementById(e),n=a.querySelector(t);r&&n&&(r.classList.remove("hidden"),n.classList.remove("bxs-chevron-down"),n.classList.add("bxs-chevron-up"))})),!o){n.querySelectorAll(".server-item").forEach((t=>{const r=parseInt(t.dataset.index,10);if(t.parentElement!==n)return;const o=`${e}-server-content-${r}`,a=t.querySelector(".server-header-toggle i.toggle-icon"),i=document.getElementById(o);i&&a&&(r===s?(i.classList.contains("hidden")&&toggleSectionContent(o,a),setTimeout((()=>{t.scrollIntoView({behavior:"smooth",block:"nearest"})}),0)):i.classList.contains("hidden")||toggleSectionContent(o,a))}))}}return s}function setupServerMode(e,t,r,n,s){const o=e.querySelector(`select[name="servers[${t}].mode"]`);o&&(n&&s&&(o.value=s.mode||"stdio"),o.addEventListener("change",(()=>renderInstallationConfig(t,r))),renderInstallationConfig(t,r,o.value,n,s?.installation))}function setupReadOnlyState(e,t,r,n,s){const o=e.querySelector(`#${n}-server-title-${s}`),a=`MCP Server #${s+1}`;let i="true"===r?.systemTags?.adhoc;if(!i&&e.dataset.systemTags)try{"true"===JSON.parse(e.dataset.systemTags).adhoc&&(i=!0)}catch(e){}if(t){if(o)if(i)if(o.querySelector("span.text-blue-600")){const e=o.querySelector("span.text-blue-600").outerHTML;o.innerHTML=`${a} ${e}`}else o.innerHTML=`${a} <span class="text-sm text-blue-600 ml-1">(Adhoc - Editable)</span>`;else o.innerHTML=`${a} (Read-only)`;e.querySelectorAll("input, select, textarea").forEach((e=>{e.closest(".env-var-item")||e.closest(".server-requirement-item")||(e.disabled=!0,e.classList.add("bg-gray-100","cursor-not-allowed","opacity-70"))})),e.querySelectorAll(".action-button-in-server").forEach((e=>{e.classList.contains("duplicate-mcp-server-button")?(e.style.display="flex",e.classList.remove("hidden"),e.disabled=!1):(e.style.display="none",e.classList.add("hidden"))}));[{contentId:`${n}-server-content-${s}`,iconSelector:".server-header-toggle i.toggle-icon"},{contentId:`${n}-server-deps-content-${s}`,iconSelector:`#${n}-deps-header-${s} i`},{contentId:`${n}-installation-content-${s}`,iconSelector:`#${n}-startup-header-${s} i`},{contentId:`${n}-env-vars-content-${s}`,iconSelector:`#${n}-envars-header-${s} i`}].forEach((({contentId:t,iconSelector:r})=>{const n=document.getElementById(t),s=e.querySelector(r);n&&s&&(n.classList.remove("hidden"),s.classList.remove("bxs-chevron-down"),s.classList.add("bxs-chevron-up"))}))}else{if(o)if(i)if(o.querySelector("span.text-blue-600")){const e=o.querySelector("span.text-blue-600").outerHTML;o.innerHTML=`${a} ${e}`}else o.innerHTML=`${a} <span class="text-sm text-blue-600 ml-1">(Adhoc - Editable)</span>`;else o.innerHTML=a;setTimeout((()=>{e.querySelectorAll("input, select, textarea").forEach((e=>{e.closest(".env-var-item")||e.closest(".server-requirement-item")||(e.disabled=!1,e.removeAttribute("readonly"),e.classList.remove("bg-gray-100","cursor-not-allowed","opacity-70"))})),e.querySelectorAll(".action-button-in-server").forEach((e=>{e.style.display="flex",e.disabled=!1,e.classList.remove("hidden","opacity-50","cursor-not-allowed")}))}),0)}}export function renderInstallationConfig(e,t="serversList",r=null,n=!1,s=null){const o=document.querySelector(`#${t} .server-item[data-index="${e}"]`);if(!o)return;const a=o.querySelector(`select[name="servers[${e}].mode"]`),i=r||(a?a.value:"stdio"),l=o.querySelector(`#installation-config-${e}`),c=o.querySelector(`#env-vars-block-${e}`);if(!l)return;const d=n?"disabled":"",u=n?"bg-gray-100 cursor-not-allowed opacity-70":"";l.innerHTML="sse"===i?generateSSETemplate(e,d,u,s):generateStdioTemplate(e,d,u,s),c&&(c.style.display="sse"===i?"none":"")}function generateSSETemplate(e,t,r,n){return`\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Server URL*</label>\n <input type="text" name="servers[${e}].installation.url" required ${t}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${r}"\n placeholder="e.g., https://your-server.com/api/mcp"\n value="${n?.url||""}">\n </div>\n `}function generateStdioTemplate(e,t,r,n){return`\n <div class="grid grid-cols-1 md:grid-cols-2 gap-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Command*</label>\n <input type="text" name="servers[${e}].installation.command" required ${t}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${r}"\n placeholder="e.g., node, python3"\n value="${n?.command||""}">\n </div>\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Arguments (comma-separated)</label>\n <input type="text" name="servers[${e}].installation.args" ${t}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${r}"\n placeholder="arg1, path/to/script.js, --flag"\n value="${n?.args?n.args.join(", "):""}">\n </div>\n </div>\n `}export function removeServer(e,t="serversList"){const r=document.getElementById(t);if(!r)return;const n=r.querySelector(`.server-item[data-index="${e}"]`);n&&(n.remove(),deleteEnvCounter(t,e),deleteServerRequirementCounter(t,e),reindexServers(t))}export function addEnvVariable(e,t="serversList",r=!1){const n=document.querySelector(`#${t} .server-item[data-index="${e}"] #envVarsContainer_${e}`);if(!n)return-1;const s=getEnvCounter(t,e);return n.insertAdjacentHTML("beforeend",envVariableTemplate(e,s,r,t)),setEnvCounter(t,e,s+1),s}export function removeEnvVariable(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .env-var-item[data-env-index="${t}"]`);n&&n.remove()}export function addServerRequirement(e,t="serversList",r=!1){console.log(`[addServerRequirement] ServerIndex: ${e}, isServerEffectivelyReadOnly received: ${r}`);const n=document.querySelector(`#${t} .server-item[data-index="${e}"] #server-requirements-list-${e}`);if(!n)return-1;const s=getServerRequirementCounter(t,e);return n.insertAdjacentHTML("beforeend",serverRequirementTemplate(e,s,r,t)),setServerRequirementCounter(t,e,s+1),toggleServerAliasField(e,s,t),toggleServerRegistryConfig(e,s,t),s}export function removeServerRequirement(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .server-requirement-item[data-req-index="${t}"]`);n&&n.remove()}export function toggleServerAliasField(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .server-requirement-item[data-req-index="${t}"]`);if(!n)return;const s=n.querySelector(`select[name="servers[${e}].requirements[${t}].type"]`),o=n.querySelector(`#server-alias-field-${e}-${t}`);s&&o&&o.classList.toggle("hidden","command"!==s.value)}export function toggleServerRegistryConfig(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .server-requirement-item[data-req-index="${t}"]`);if(!n)return;const s=n.querySelector(`select[name="servers[${e}].requirements[${t}].registryType"]`);s&&["github","artifacts"].forEach((r=>{const o=n.querySelector(`#server-${r}-config-${e}-${t}`);o&&o.classList.toggle("hidden",s.value!==r)}))}export function toggleSectionContent(e,t,r=null){const n=document.getElementById(e);if(!n)return;r=r||t?.parentElement||null;const s=n.classList.toggle("hidden");t&&(t.classList.toggle("bxs-chevron-up",!s),t.classList.toggle("bxs-chevron-down",s)),r&&r.setAttribute("aria-expanded",(!s).toString())}export function toggleViewMode(e,t,r,n=null,s=!1){const o={createCategory:document.getElementById("panel-create-category"),createServer:document.getElementById("panel-create-server"),jsonEditor:document.getElementById("panel-json-editor"),textarea:document.getElementById("jsonEditorTextarea"),activeForm:document.getElementById(t),viewModeToggle:document.getElementById("viewModeToggle"),actionButtons:{json:document.getElementById("jsonEditorActionsContainer"),main:document.querySelector(`#${t} ~ .flex.justify-end.space-x-4.pt-6.border-t`)}};if(!isViewAlreadyActive(e,o,t)){state.originalServerNamesForFormPopulation&&(state.originalServerNamesForFormPopulation=null);try{e?handleJsonView(o,t,r,n,s):(s&&n&&n.mcpServers&&"onboardServerForm"===t&&(state.originalServerNamesForFormPopulation=new Set(n.mcpServers.map((e=>e.name)).filter((e=>e)))),handleFormView(o,t,r,n,s),state.originalServerNamesForFormPopulation&&(state.originalServerNamesForFormPopulation=null))}catch(t){console.error("Error in view mode toggle:",t),showToast(`Error: ${t.message}`,"error"),o.viewModeToggle&&(o.viewModeToggle.checked=e),state.originalServerNamesForFormPopulation&&(state.originalServerNamesForFormPopulation=null)}}}function isViewAlreadyActive(e,t,r){if(e&&t.jsonEditor&&!t.jsonEditor.classList.contains("hidden"))return!0;if(!e&&t.jsonEditor?.classList.contains("hidden")){if("onboardForm"===r&&t.createCategory&&!t.createCategory.classList.contains("hidden"))return!0;if("onboardServerForm"===r&&t.createServer&&!t.createServer.classList.contains("hidden"))return!0}return!1}function handleJsonView(e,t,r,n,s){const o=getFeedConfiguration(e.activeForm,n,s);e.textarea.value=JSON.stringify(o,null,2),e.textarea.readOnly=s&&n?.mcpServers?.length>0,e.textarea.readOnly?(e.textarea.classList.add("bg-gray-100","cursor-not-allowed"),showToast("JSON view is read-only for existing servers in this category.","info")):e.textarea.classList.remove("bg-gray-100","cursor-not-allowed"),togglePanels(e,!0),toggleButtons(e.actionButtons,!0)}function handleFormView(e,t,r,n,s){const o=JSON.parse(e.textarea.value),a=document.getElementById(r);a&&(a.innerHTML=""),resetOnboardFormDynamicContent(t,r),populateForm(o,t,s&&n?.mcpServers?.length>0,r),togglePanels(e,!1,t),toggleButtons(e.actionButtons,!1)}function getFeedConfiguration(e,t,r){if(!r||!t)return e?getFormData(e):{};const n=getFormData(e,!0,t),s=JSON.parse(JSON.stringify(t));return s.mcpServers=n.mcpServers||[],s.requirements=n.requirements||[],s}function togglePanels(e,t,r=null){e.createCategory?.classList.add("hidden"),e.createServer?.classList.add("hidden"),e.jsonEditor?.classList.add("hidden"),t?e.jsonEditor?.classList.remove("hidden"):r&&("onboardForm"===r?e.createCategory?.classList.remove("hidden"):"onboardServerForm"===r&&e.createServer?.classList.remove("hidden"))}function toggleButtons(e,t){e.main?.classList.toggle("hidden",t),e.json?.classList.toggle("hidden",t)}export async function saveJsonData(e,t=null){const r=document.getElementById("jsonEditorTextarea");if(r.readOnly)showToast("Cannot save, JSON editor is in read-only mode for existing servers.","warning");else try{const n=prepareConfiguration(e,JSON.parse(r.value),t);if(!n)return;await saveConfiguration(n)}catch(e){console.error("Error saving JSON data:",e),showToast(`Error saving JSON data: ${e.message}`,"error")}}function prepareConfiguration(e,t,r){return"create-category"===e?t.name?{data:t,isUpdate:isUpdateOperation(t.name)}:(showToast("Category Name is required in JSON.","error"),null):"create-server"===e?r?.name?{data:mergeConfigurations(r,t),isUpdate:!0}:(showToast("No existing category context for saving JSON.","error"),null):(showToast("Invalid tab context for saving JSON.","error"),null)}function isUpdateOperation(e){const t=new URLSearchParams(window.location.search);return"edit"===t.get("action")&&t.get("category")===e}function mergeConfigurations(e,t){const r=JSON.parse(JSON.stringify(e)),n=new Set(r.mcpServers?.map((e=>e.name))||[]),s=(t.mcpServers||[]).filter((e=>!n.has(e.name)));r.mcpServers=(r.mcpServers||[]).concat(s);const o=new Set(r.requirements?.map((e=>`${e.type}|${e.name}|${e.version}`))||[]);return(t.requirements||[]).forEach((e=>{const t=`${e.type}|${e.name}|${e.version}`,n=s.some((t=>t.dependencies?.requirements?.some((t=>t.name===e.name&&t.version===e.version))));!o.has(t)&&n&&(r.requirements=r.requirements||[],r.requirements.push(e))})),r}async function saveConfiguration({data:e,isUpdate:t}){const r=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categoryData:e,isUpdate:t})});if(!r.ok){const e=await r.json();throw new Error(e.error||`HTTP error! status: ${r.status}`)}showToast("JSON data submitted successfully!","success")}export async function copyJsonToClipboard(){const e=document.getElementById("jsonEditorTextarea");if(e)try{await navigator.clipboard.writeText(e.value),showToast("JSON copied to clipboard!","success")}catch(e){console.error("Failed to copy JSON:",e),showToast("Failed to copy JSON. See console for details.","error")}else showToast("JSON content not found.","error")}export function duplicateServer(e,t){const r="serversList"===t?"onboardForm":"onboardServerForm",n=document.getElementById(r);if(!n)return void showToast(`Form with ID ${r} not found. Cannot duplicate server.`,"error");const s="existingCategoryServersList"===t;let o=null;s&&(o=window.currentSelectedCategoryData||null);if(!n.querySelector(`.server-item[data-index="${e}"]`))return void showToast("Could not find the server item to duplicate in the DOM.","error");const a=[];n.querySelectorAll("input, select, textarea").forEach((e=>{e.disabled&&(a.push({element:e,wasDisabled:!0}),e.disabled=!1)}));const i=getFormData(n,s,o);if(a.forEach((({element:e,wasDisabled:t})=>{e.disabled=t})),!i||!i.mcpServers||i.mcpServers.length<=e)return void showToast("Could not retrieve data for the server to duplicate after attempting to enable fields.","error");let l=JSON.parse(JSON.stringify(i.mcpServers[e]));l.systemTags&&delete l.systemTags;let c=!1;s&&(c=window.isExistingCategoryReadOnly||!1);const d=addServer(t,c,null);if(-1===d)return void showToast("Failed to add a new server item for duplication.","error");const u=document.getElementById(t).querySelector(`.server-item[data-index="${d}"]`);u?(populateServerManually(u,d,l,t),showToast(`Server #${e+1} duplicated to Server #${d+1}.`,"success")):showToast("Failed to find the new server item after duplication.","error")}function populateServerManually(e,t,r,n){e.querySelector(`input[name="servers[${t}].name"]`).value=r.name||"",e.querySelector(`textarea[name="servers[${t}].description"]`).value=r.description||"",e.querySelector(`select[name="servers[${t}].mode"]`).value=r.mode||"stdio",e.querySelector(`input[name="servers[${t}].schemas"]`).value=r.schemas||"",e.querySelector(`input[name="servers[${t}].repository"]`).value=r.repository||"";const s=e.querySelector(`select[name="servers[${t}].mode"]`);if(s&&s.dispatchEvent(new Event("change")),"stdio"===r.mode&&r.installation){const n=e.querySelector(`input[name="servers[${t}].installation.command"]`);n&&(n.value=r.installation.command||"");const s=e.querySelector(`input[name="servers[${t}].installation.args"]`);s&&(s.value=r.installation.args?r.installation.args.join(", "):"")}else if("sse"===r.mode&&r.installation){const n=e.querySelector(`input[name="servers[${t}].installation.url"]`);n&&(n.value=r.installation.url||"")}const o=e.querySelector(`#envVarsContainer_${t}`);o&&r.installation&&r.installation.env&&Object.entries(r.installation.env).forEach((([e,r])=>{const s=addEnvVariable(t,n,!1),a=o.querySelector(`.env-var-item[data-env-index="${s}"]`);a&&(a.querySelector(`input[name="servers[${t}].installation.env[${s}].name"]`).value=e,a.querySelector(`input[name="servers[${t}].installation.env[${s}].default"]`).value=r.Default||"",a.querySelector(`input[name="servers[${t}].installation.env[${s}].required"]`).checked=r.Required||!1,a.querySelector(`textarea[name="servers[${t}].installation.env[${s}].description"]`).value=r.Description||"")}));const a=e.querySelector(`#server-requirements-list-${t}`);a&&r.dependencies&&r.dependencies.requirements&&r.dependencies.requirements.forEach((e=>{const r=addServerRequirement(t,n,!1),s=a.querySelector(`.server-requirement-item[data-req-index="${r}"]`);if(s){s.querySelector(`input[name="servers[${t}].requirements[${r}].name"]`).value=e.name||"",s.querySelector(`select[name="servers[${t}].requirements[${r}].type"]`).value=e.type||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].version"]`).value=e.version||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].order"]`).value=e.order||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].alias"]`).value=e.alias||"";const n=s.querySelector(`select[name="servers[${t}].requirements[${r}].type"]`);n&&n.dispatchEvent(new Event("change"));const o=s.querySelector(`select[name="servers[${t}].requirements[${r}].registryType"]`);o&&(o.value=e.registryType||"public",o.dispatchEvent(new Event("change")),e.registry&&("github"===e.registryType&&e.registry.githubRelease?(s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.githubRelease.repository"]`).value=e.registry.githubRelease.repository||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.githubRelease.assetsName"]`).value=e.registry.githubRelease.assetsName||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.githubRelease.assetName"]`).value=e.registry.githubRelease.assetName||""):"artifacts"===e.registryType&&e.registry.artifacts?(s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.artifacts.registryName"]`).value=e.registry.artifacts.registryName||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.artifacts.registryUrl"]`).value=e.registry.artifacts.registryUrl||""):"local"===e.registryType&&e.registry.local&&(s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.local.localPath"]`).value=e.registry.local.localPath||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.local.assetName"]`).value=e.registry.local.assetName||"")))}})),setupReadOnlyState(e,!1,null,n,t)}window.duplicateServer=duplicateServer,Object.entries({addServer:addServer,removeServer:removeServer,addEnvVariable:addEnvVariable,removeEnvVariable:removeEnvVariable,addServerRequirement:addServerRequirement,removeServerRequirement:removeServerRequirement,toggleServerAliasField:toggleServerAliasField,toggleServerRegistryConfig:toggleServerRegistryConfig,renderInstallationConfig:renderInstallationConfig,toggleSectionContent:toggleSectionContent,copyJsonToClipboard:copyJsonToClipboard}).forEach((([e,t])=>{window[e]=t}));
|
|
1
|
+
import{serverTemplate,envVariableTemplate,serverRequirementTemplate}from"./templates.js";import{state,setServerCounter,getServerCounter,setEnvCounter,getEnvCounter,deleteEnvCounter,clearEnvCountersForTab,setServerRequirementCounter,getServerRequirementCounter,deleteServerRequirementCounter,clearServerRequirementCountersForTab}from"./state.js";import{getFormData,populateForm,resetOnboardFormDynamicContent}from"./formProcessor.js";import{showToast}from"../notifications.js";function reindexElements(e,t,r,n){n.forEach((({selector:n,idBase:s,namePattern:o})=>{const a=e.querySelector(n);if(a&&(s&&(a.id=`${s}${r}`),o&&a.getAttribute("name"))){const e=a.getAttribute("name").replace(new RegExp(o.replace("INDEX",t)),`$1${r}$2`);a.setAttribute("name",e)}}))}function reindexServers(e="serversList"){const t=document.getElementById(e);if(!t)return;const r=t.querySelectorAll(".server-item"),n=new Map,s=new Map;r.forEach(((t,r)=>{const o=parseInt(t.dataset.index,10);t.dataset.index=r;const a=t.querySelector("h3");if(a){const e=a.textContent||"",t=`MCP Server #${r+1}`;let n="";e.includes("(Adhoc - Editable)")?n=' <span class="text-sm text-blue-600 ml-1">(Adhoc - Editable)</span>':e.includes("(Read-only)")&&(n=" (Read-only)"),a.innerHTML=`${t}${n}`}const i=t.querySelector(`#${e}-server-header-${o}`);if(i){i.id=`${e}-server-header-${r}`;const t=`${e}-server-content-${o}`,n=`${e}-server-content-${r}`;let s=i.getAttribute("onclick");s&&(s=s.replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),n),i.setAttribute("onclick",s));let a=i.getAttribute("onkeydown");a&&(a=a.replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),n),i.setAttribute("onkeydown",a)),i.setAttribute("aria-controls",n)}const l=t.querySelector(`#${e}-server-title-${o}`);l&&(l.id=`${e}-server-title-${r}`);const c=t.querySelector(`#${e}-server-content-${o}`);c&&c.setAttribute("aria-labelledby",`${e}-server-title-${r}`),t.querySelectorAll("[onclick]").forEach((t=>{const n=t.getAttribute("onclick");if(!n)return;if(t.id===`${e}-server-header-${r}`)return;const s=n.replace(new RegExp(`\\((\\s*)${o}(\\s*[,\\)])`,"g"),`($1${r}$2`).replace(new RegExp(`${e}-server-deps-content-${o}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),`${e}-server-deps-content-${r}`).replace(new RegExp(`${e}-installation-content-${o}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),`${e}-installation-content-${r}`).replace(new RegExp(`${e}-env-vars-content-${o}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),`${e}-env-vars-content-${r}`);t.setAttribute("onclick",s)})),reindexElements(t,o,r,[{selector:`#${e}-server-content-${o}`,idBase:`${e}-server-content-`},{selector:`#${e}-server-deps-content-${o}`,idBase:`${e}-server-deps-content-`},{selector:`#${e}-installation-content-${o}`,idBase:`${e}-installation-content-`},{selector:`#${e}-env-vars-content-${o}`,idBase:`${e}-env-vars-content-`},{selector:`#schema-path-${o}`,idBase:"schema-path-"},{selector:`#envVarsContainer_${o}`,idBase:"envVarsContainer_"}]);const d=t.querySelector(`#envVarsContainer_${r}`);let u=0;d&&d.querySelectorAll(".env-var-item").forEach(((e,t)=>{const n=parseInt(e.dataset.envIndex,10);e.dataset.envIndex=t,reindexElements(e,n,t,[{selector:"[name]",namePattern:`(servers\\[${r}\\]\\.installation\\.env\\[)\\d+(\\]\\..+)`}]),u++})),n.set(r,u);const m=t.querySelector(`#server-requirements-list-${r}`);let v=0;m&&m.querySelectorAll(".server-requirement-item").forEach(((e,t)=>{const n=parseInt(e.dataset.reqIndex,10);e.dataset.reqIndex=t,reindexElements(e,n,t,[{selector:"[name]",namePattern:`(servers\\[${r}\\]\\.requirements\\[)\\d+(\\]\\..+)`}]),v++})),s.set(r,v)})),clearEnvCountersForTab(e),n.forEach(((t,r)=>setEnvCounter(e,r,t))),clearServerRequirementCountersForTab(e),s.forEach(((t,r)=>setServerRequirementCounter(e,r,t))),setServerCounter(e,r.length)}export function addServer(e="serversList",t=!1,r=null){const n=document.getElementById(e);if(!n)return-1;0===n.children.length&&(setServerCounter(e,0),clearEnvCountersForTab(e),clearServerRequirementCountersForTab(e));const s=getServerCounter(e);let o;o=!("true"===r?.systemTags?.adhoc)&&(!!t&&(state.originalServerNamesForFormPopulation?!!(r&&r.name&&state.originalServerNamesForFormPopulation.has(r.name)):!!r)),n.insertAdjacentHTML("beforeend",serverTemplate(s,t,r,e)),setEnvCounter(e,s,0),setServerRequirementCounter(e,s,0),setServerCounter(e,s+1);const a=n.querySelector(`.server-item[data-index="${s}"]`);if(a){r&&r.systemTags?a.dataset.systemTags=JSON.stringify(r.systemTags):r&&!r.systemTags?delete a.dataset.systemTags:r||delete a.dataset.systemTags,r&&r.name?a.dataset.originalName=r.name:delete a.dataset.originalName,setupServerMode(a,s,e,o,r),setupReadOnlyState(a,o,r,e,s);if([{contentId:`${e}-server-deps-content-${s}`,iconSelector:`#${e}-deps-header-${s} i`},{contentId:`${e}-installation-content-${s}`,iconSelector:`#${e}-startup-header-${s} i`},{contentId:`${e}-env-vars-content-${s}`,iconSelector:`#${e}-envars-header-${s} i`}].forEach((({contentId:e,iconSelector:t})=>{const r=document.getElementById(e),n=a.querySelector(t);r&&n&&(r.classList.remove("hidden"),n.classList.remove("bxs-chevron-down"),n.classList.add("bxs-chevron-up"))})),!o){n.querySelectorAll(".server-item").forEach((t=>{const r=parseInt(t.dataset.index,10);if(t.parentElement!==n)return;const o=`${e}-server-content-${r}`,a=t.querySelector(".server-header-toggle i.toggle-icon"),i=document.getElementById(o);i&&a&&(r===s?(i.classList.contains("hidden")&&toggleSectionContent(o,a),setTimeout((()=>{t.scrollIntoView({behavior:"smooth",block:"nearest"})}),0)):i.classList.contains("hidden")||toggleSectionContent(o,a))}))}}return s}function setupServerMode(e,t,r,n,s){const o=e.querySelector(`select[name="servers[${t}].mode"]`);o&&(n&&s&&(o.value=s.mode||"stdio"),o.addEventListener("change",(()=>renderInstallationConfig(t,r))),renderInstallationConfig(t,r,o.value,n,s?.installation))}function setupReadOnlyState(e,t,r,n,s){const o=e.querySelector(`#${n}-server-title-${s}`),a=`MCP Server #${s+1}`;let i="true"===r?.systemTags?.adhoc;if(!i&&e.dataset.systemTags)try{"true"===JSON.parse(e.dataset.systemTags).adhoc&&(i=!0)}catch(e){}if(t){if(o)if(i)if(o.querySelector("span.text-blue-600")){const e=o.querySelector("span.text-blue-600").outerHTML;o.innerHTML=`${a} ${e}`}else o.innerHTML=`${a} <span class="text-sm text-blue-600 ml-1">(Adhoc - Editable)</span>`;else o.innerHTML=`${a} (Read-only)`;e.querySelectorAll("input, select, textarea").forEach((e=>{e.closest(".env-var-item")||e.closest(".server-requirement-item")||(e.disabled=!0,e.classList.add("bg-gray-100","cursor-not-allowed","opacity-70"))})),e.querySelectorAll(".action-button-in-server").forEach((e=>{e.classList.contains("duplicate-mcp-server-button")?(e.style.display="flex",e.classList.remove("hidden"),e.disabled=!1):(e.style.display="none",e.classList.add("hidden"))}));[{contentId:`${n}-server-content-${s}`,iconSelector:".server-header-toggle i.toggle-icon"},{contentId:`${n}-server-deps-content-${s}`,iconSelector:`#${n}-deps-header-${s} i`},{contentId:`${n}-installation-content-${s}`,iconSelector:`#${n}-startup-header-${s} i`},{contentId:`${n}-env-vars-content-${s}`,iconSelector:`#${n}-envars-header-${s} i`}].forEach((({contentId:t,iconSelector:r})=>{const n=document.getElementById(t),s=e.querySelector(r);n&&s&&(n.classList.remove("hidden"),s.classList.remove("bxs-chevron-down"),s.classList.add("bxs-chevron-up"))}))}else{if(o)if(i)if(o.querySelector("span.text-blue-600")){const e=o.querySelector("span.text-blue-600").outerHTML;o.innerHTML=`${a} ${e}`}else o.innerHTML=`${a} <span class="text-sm text-blue-600 ml-1">(Adhoc - Editable)</span>`;else o.innerHTML=a;setTimeout((()=>{e.querySelectorAll("input, select, textarea").forEach((e=>{e.closest(".env-var-item")||e.closest(".server-requirement-item")||(e.disabled=!1,e.removeAttribute("readonly"),e.classList.remove("bg-gray-100","cursor-not-allowed","opacity-70"))})),e.querySelectorAll(".action-button-in-server").forEach((e=>{e.style.display="flex",e.disabled=!1,e.classList.remove("hidden","opacity-50","cursor-not-allowed")}))}),0)}}export function renderInstallationConfig(e,t="serversList",r=null,n=!1,s=null){const o=document.querySelector(`#${t} .server-item[data-index="${e}"]`);if(!o)return;const a=o.querySelector(`select[name="servers[${e}].mode"]`),i=r||(a?a.value:"stdio"),l=o.querySelector(`#installation-config-${e}`),c=o.querySelector(`#env-vars-block-${e}`);if(!l)return;const d=n?"disabled":"",u=n?"bg-gray-100 cursor-not-allowed opacity-70":"";if(l.innerHTML="sse"===i?generateSSETemplate(e,d,u,s):generateStdioTemplate(e,d,u,s),"sse"===i){const t=o.querySelector(`#isLocalCheckbox-${e}`),r=o.querySelector(`#startingCommandContainer-${e}`),s=o.querySelector(`#startingCommandInput-${e}`);t&&r&&s&&t.addEventListener("change",(e=>{e.target.checked?(r.style.display="",n||(s.disabled=!1,s.classList.remove("bg-gray-100","cursor-not-allowed","opacity-70"))):(r.style.display="none",s.disabled=!0,s.classList.add("bg-gray-100","cursor-not-allowed","opacity-70"))}))}c&&(c.style.display="sse"===i?"none":"")}function generateSSETemplate(e,t,r,n){const s=t.includes("disabled"),o=!!n?.startingCommand,a=n?.startingCommand||"",i=s?"disabled":"",l=o?"checked":"",c=s||!o?"disabled":"",d=o?"":"display: none;",u=s||!o||s?r:"";return`\n <div class="space-y-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1" for="server-url-${e}">Server URL*</label>\n <input type="text" id="server-url-${e}" name="servers[${e}].installation.url" required ${t}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${r}"\n placeholder="e.g., http://localhost:8000 or https://remote-server.com/api"\n value="${n?.url||""}">\n </div>\n\n <div class="flex items-center">\n <input type="checkbox" id="isLocalCheckbox-${e}" name="servers[${e}].installation.isLocal" ${i} ${l}\n class="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 ${s?"cursor-not-allowed opacity-70":""}">\n <label for="isLocalCheckbox-${e}" class="ml-2 block text-sm text-gray-900 ${s?"cursor-not-allowed opacity-70":""}">\n Is Local Server (requires starting command)\n </label>\n </div>\n\n <div id="startingCommandContainer-${e}" style="${d}">\n <label class="block text-sm font-medium text-gray-700 mb-1" for="startingCommandInput-${e}">Starting Command</label>\n <input type="text" id="startingCommandInput-${e}" name="servers[${e}].installation.startingCommand"\n ${c}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${u}"\n placeholder="e.g., python -m my_server --port 8000"\n value="${a}">\n <p class="mt-1 text-xs text-gray-500">Command to run if the local server is not already running. Will be ignored if 'Is Local Server' is unchecked.</p>\n </div>\n </div>\n `}function generateStdioTemplate(e,t,r,n){return`\n <div class="grid grid-cols-1 md:grid-cols-2 gap-4">\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Command*</label>\n <input type="text" name="servers[${e}].installation.command" required ${t}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${r}"\n placeholder="e.g., node, python3"\n value="${n?.command||""}">\n </div>\n <div>\n <label class="block text-sm font-medium text-gray-700 mb-1">Arguments (comma-separated)</label>\n <input type="text" name="servers[${e}].installation.args" ${t}\n class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${r}"\n placeholder="arg1, path/to/script.js, --flag"\n value="${n?.args?n.args.join(", "):""}">\n </div>\n </div>\n `}export function removeServer(e,t="serversList"){const r=document.getElementById(t);if(!r)return;const n=r.querySelector(`.server-item[data-index="${e}"]`);n&&(n.remove(),deleteEnvCounter(t,e),deleteServerRequirementCounter(t,e),reindexServers(t))}export function addEnvVariable(e,t="serversList",r=!1){const n=document.querySelector(`#${t} .server-item[data-index="${e}"] #envVarsContainer_${e}`);if(!n)return-1;const s=getEnvCounter(t,e);return n.insertAdjacentHTML("beforeend",envVariableTemplate(e,s,r,t)),setEnvCounter(t,e,s+1),s}export function removeEnvVariable(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .env-var-item[data-env-index="${t}"]`);n&&n.remove()}export function addServerRequirement(e,t="serversList",r=!1){console.log(`[addServerRequirement] ServerIndex: ${e}, isServerEffectivelyReadOnly received: ${r}`);const n=document.querySelector(`#${t} .server-item[data-index="${e}"] #server-requirements-list-${e}`);if(!n)return-1;const s=getServerRequirementCounter(t,e);return n.insertAdjacentHTML("beforeend",serverRequirementTemplate(e,s,r,t)),setServerRequirementCounter(t,e,s+1),toggleServerAliasField(e,s,t),toggleServerRegistryConfig(e,s,t),s}export function removeServerRequirement(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .server-requirement-item[data-req-index="${t}"]`);n&&n.remove()}export function toggleServerAliasField(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .server-requirement-item[data-req-index="${t}"]`);if(!n)return;const s=n.querySelector(`select[name="servers[${e}].requirements[${t}].type"]`),o=n.querySelector(`#server-alias-field-${e}-${t}`);s&&o&&o.classList.toggle("hidden","command"!==s.value)}export function toggleServerRegistryConfig(e,t,r="serversList"){const n=document.querySelector(`#${r} .server-item[data-index="${e}"] .server-requirement-item[data-req-index="${t}"]`);if(!n)return;const s=n.querySelector(`select[name="servers[${e}].requirements[${t}].registryType"]`);s&&["github","artifacts"].forEach((r=>{const o=n.querySelector(`#server-${r}-config-${e}-${t}`);o&&o.classList.toggle("hidden",s.value!==r)}))}export function toggleSectionContent(e,t,r=null){const n=document.getElementById(e);if(!n)return;r=r||t?.parentElement||null;const s=n.classList.toggle("hidden");t&&(t.classList.toggle("bxs-chevron-up",!s),t.classList.toggle("bxs-chevron-down",s)),r&&r.setAttribute("aria-expanded",(!s).toString())}export function toggleViewMode(e,t,r,n=null,s=!1){const o={createCategory:document.getElementById("panel-create-category"),createServer:document.getElementById("panel-create-server"),jsonEditor:document.getElementById("panel-json-editor"),textarea:document.getElementById("jsonEditorTextarea"),activeForm:document.getElementById(t),viewModeToggle:document.getElementById("viewModeToggle"),actionButtons:{json:document.getElementById("jsonEditorActionsContainer"),main:document.querySelector(`#${t} ~ .flex.justify-end.space-x-4.pt-6.border-t`)}};if(!isViewAlreadyActive(e,o,t)){state.originalServerNamesForFormPopulation&&(state.originalServerNamesForFormPopulation=null);try{e?handleJsonView(o,t,r,n,s):(s&&n&&n.mcpServers&&"onboardServerForm"===t&&(state.originalServerNamesForFormPopulation=new Set(n.mcpServers.map((e=>e.name)).filter((e=>e)))),handleFormView(o,t,r,n,s),state.originalServerNamesForFormPopulation&&(state.originalServerNamesForFormPopulation=null))}catch(t){console.error("Error in view mode toggle:",t),showToast(`Error: ${t.message}`,"error"),o.viewModeToggle&&(o.viewModeToggle.checked=e),state.originalServerNamesForFormPopulation&&(state.originalServerNamesForFormPopulation=null)}}}function isViewAlreadyActive(e,t,r){if(e&&t.jsonEditor&&!t.jsonEditor.classList.contains("hidden"))return!0;if(!e&&t.jsonEditor?.classList.contains("hidden")){if("onboardForm"===r&&t.createCategory&&!t.createCategory.classList.contains("hidden"))return!0;if("onboardServerForm"===r&&t.createServer&&!t.createServer.classList.contains("hidden"))return!0}return!1}function handleJsonView(e,t,r,n,s){const o=getFeedConfiguration(e.activeForm,n,s);e.textarea.value=JSON.stringify(o,null,2),e.textarea.readOnly=s&&n?.mcpServers?.length>0,e.textarea.readOnly?(e.textarea.classList.add("bg-gray-100","cursor-not-allowed"),showToast("JSON view is read-only for existing servers in this category.","info")):e.textarea.classList.remove("bg-gray-100","cursor-not-allowed"),togglePanels(e,!0),toggleButtons(e.actionButtons,!0)}function handleFormView(e,t,r,n,s){const o=JSON.parse(e.textarea.value),a=document.getElementById(r);a&&(a.innerHTML=""),resetOnboardFormDynamicContent(t,r),populateForm(o,t,s&&n?.mcpServers?.length>0,r),togglePanels(e,!1,t),toggleButtons(e.actionButtons,!1)}function getFeedConfiguration(e,t,r){if(!r||!t)return e?getFormData(e):{};const n=getFormData(e,!0,t),s=JSON.parse(JSON.stringify(t));return s.mcpServers=n.mcpServers||[],s.requirements=n.requirements||[],s}function togglePanels(e,t,r=null){e.createCategory?.classList.add("hidden"),e.createServer?.classList.add("hidden"),e.jsonEditor?.classList.add("hidden"),t?e.jsonEditor?.classList.remove("hidden"):r&&("onboardForm"===r?e.createCategory?.classList.remove("hidden"):"onboardServerForm"===r&&e.createServer?.classList.remove("hidden"))}function toggleButtons(e,t){e.main?.classList.toggle("hidden",t),e.json?.classList.toggle("hidden",t)}export async function saveJsonData(e,t=null){const r=document.getElementById("jsonEditorTextarea");if(r.readOnly)showToast("Cannot save, JSON editor is in read-only mode for existing servers.","warning");else try{const n=prepareConfiguration(e,JSON.parse(r.value),t);if(!n)return;await saveConfiguration(n)}catch(e){console.error("Error saving JSON data:",e),showToast(`Error saving JSON data: ${e.message}`,"error")}}function prepareConfiguration(e,t,r){return"create-category"===e?t.name?{data:t,isUpdate:isUpdateOperation(t.name)}:(showToast("Category Name is required in JSON.","error"),null):"create-server"===e?r?.name?{data:mergeConfigurations(r,t),isUpdate:!0}:(showToast("No existing category context for saving JSON.","error"),null):(showToast("Invalid tab context for saving JSON.","error"),null)}function isUpdateOperation(e){const t=new URLSearchParams(window.location.search);return"edit"===t.get("action")&&t.get("category")===e}function mergeConfigurations(e,t){const r=JSON.parse(JSON.stringify(e)),n=new Set(r.mcpServers?.map((e=>e.name))||[]),s=(t.mcpServers||[]).filter((e=>!n.has(e.name)));r.mcpServers=(r.mcpServers||[]).concat(s);const o=new Set(r.requirements?.map((e=>`${e.type}|${e.name}|${e.version}`))||[]);return(t.requirements||[]).forEach((e=>{const t=`${e.type}|${e.name}|${e.version}`,n=s.some((t=>t.dependencies?.requirements?.some((t=>t.name===e.name&&t.version===e.version))));!o.has(t)&&n&&(r.requirements=r.requirements||[],r.requirements.push(e))})),r}async function saveConfiguration({data:e,isUpdate:t}){const r=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categoryData:e,isUpdate:t})});if(!r.ok){const e=await r.json();throw new Error(e.error||`HTTP error! status: ${r.status}`)}showToast("JSON data submitted successfully!","success")}export async function copyJsonToClipboard(){const e=document.getElementById("jsonEditorTextarea");if(e)try{await navigator.clipboard.writeText(e.value),showToast("JSON copied to clipboard!","success")}catch(e){console.error("Failed to copy JSON:",e),showToast("Failed to copy JSON. See console for details.","error")}else showToast("JSON content not found.","error")}export function duplicateServer(e,t){const r="serversList"===t?"onboardForm":"onboardServerForm",n=document.getElementById(r);if(!n)return void showToast(`Form with ID ${r} not found. Cannot duplicate server.`,"error");const s="existingCategoryServersList"===t;let o=null;s&&(o=window.currentSelectedCategoryData||null);if(!n.querySelector(`.server-item[data-index="${e}"]`))return void showToast("Could not find the server item to duplicate in the DOM.","error");const a=[];n.querySelectorAll("input, select, textarea").forEach((e=>{e.disabled&&(a.push({element:e,wasDisabled:!0}),e.disabled=!1)}));const i=getFormData(n,s,o);if(a.forEach((({element:e,wasDisabled:t})=>{e.disabled=t})),!i||!i.mcpServers||i.mcpServers.length<=e)return void showToast("Could not retrieve data for the server to duplicate after attempting to enable fields.","error");let l=JSON.parse(JSON.stringify(i.mcpServers[e]));l.systemTags&&delete l.systemTags;let c=!1;s&&(c=window.isExistingCategoryReadOnly||!1);const d=addServer(t,c,null);if(-1===d)return void showToast("Failed to add a new server item for duplication.","error");const u=document.getElementById(t).querySelector(`.server-item[data-index="${d}"]`);u?(populateServerManually(u,d,l,t),showToast(`Server #${e+1} duplicated to Server #${d+1}.`,"success")):showToast("Failed to find the new server item after duplication.","error")}function populateServerManually(e,t,r,n){e.querySelector(`input[name="servers[${t}].name"]`).value=r.name||"",e.querySelector(`textarea[name="servers[${t}].description"]`).value=r.description||"",e.querySelector(`select[name="servers[${t}].mode"]`).value=r.mode||"stdio",e.querySelector(`input[name="servers[${t}].schemas"]`).value=r.schemas||"",e.querySelector(`input[name="servers[${t}].repository"]`).value=r.repository||"";const s=e.querySelector(`select[name="servers[${t}].mode"]`);if(s&&s.dispatchEvent(new Event("change")),"stdio"===r.mode&&r.installation){const n=e.querySelector(`input[name="servers[${t}].installation.command"]`);n&&(n.value=r.installation.command||"");const s=e.querySelector(`input[name="servers[${t}].installation.args"]`);s&&(s.value=r.installation.args?r.installation.args.join(", "):"")}else if("sse"===r.mode&&r.installation){const n=e.querySelector(`input[name="servers[${t}].installation.url"]`);n&&(n.value=r.installation.url||"")}const o=e.querySelector(`#envVarsContainer_${t}`);o&&r.installation&&r.installation.env&&Object.entries(r.installation.env).forEach((([e,r])=>{const s=addEnvVariable(t,n,!1),a=o.querySelector(`.env-var-item[data-env-index="${s}"]`);a&&(a.querySelector(`input[name="servers[${t}].installation.env[${s}].name"]`).value=e,a.querySelector(`input[name="servers[${t}].installation.env[${s}].default"]`).value=r.Default||"",a.querySelector(`input[name="servers[${t}].installation.env[${s}].required"]`).checked=r.Required||!1,a.querySelector(`textarea[name="servers[${t}].installation.env[${s}].description"]`).value=r.Description||"")}));const a=e.querySelector(`#server-requirements-list-${t}`);a&&r.dependencies&&r.dependencies.requirements&&r.dependencies.requirements.forEach((e=>{const r=addServerRequirement(t,n,!1),s=a.querySelector(`.server-requirement-item[data-req-index="${r}"]`);if(s){s.querySelector(`input[name="servers[${t}].requirements[${r}].name"]`).value=e.name||"",s.querySelector(`select[name="servers[${t}].requirements[${r}].type"]`).value=e.type||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].version"]`).value=e.version||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].order"]`).value=e.order||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].alias"]`).value=e.alias||"";const n=s.querySelector(`select[name="servers[${t}].requirements[${r}].type"]`);n&&n.dispatchEvent(new Event("change"));const o=s.querySelector(`select[name="servers[${t}].requirements[${r}].registryType"]`);o&&(o.value=e.registryType||"public",o.dispatchEvent(new Event("change")),e.registry&&("github"===e.registryType&&e.registry.githubRelease?(s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.githubRelease.repository"]`).value=e.registry.githubRelease.repository||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.githubRelease.assetsName"]`).value=e.registry.githubRelease.assetsName||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.githubRelease.assetName"]`).value=e.registry.githubRelease.assetName||""):"artifacts"===e.registryType&&e.registry.artifacts?(s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.artifacts.registryName"]`).value=e.registry.artifacts.registryName||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.artifacts.registryUrl"]`).value=e.registry.artifacts.registryUrl||""):"local"===e.registryType&&e.registry.local&&(s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.local.localPath"]`).value=e.registry.local.localPath||"",s.querySelector(`input[name="servers[${t}].requirements[${r}].registry.local.assetName"]`).value=e.registry.local.assetName||"")))}})),setupReadOnlyState(e,!1,null,n,t)}window.duplicateServer=duplicateServer,Object.entries({addServer:addServer,removeServer:removeServer,addEnvVariable:addEnvVariable,removeEnvVariable:removeEnvVariable,addServerRequirement:addServerRequirement,removeServerRequirement:removeServerRequirement,toggleServerAliasField:toggleServerAliasField,toggleServerRegistryConfig:toggleServerRegistryConfig,renderInstallationConfig:renderInstallationConfig,toggleSectionContent:toggleSectionContent,copyJsonToClipboard:copyJsonToClipboard}).forEach((([e,t])=>{window[e]=t}));
|
|
2
2
|
//# sourceMappingURL=uiHandlers.js.map
|