import * as vscode from "vscode"; export class LaunchUriHandler implements vscode.UriHandler { async handleUri(uri: vscode.Uri) { try { const params = new URLSearchParams(uri.query); if (uri.path == "/start") { // Some properties have default values let debugConfig: vscode.DebugConfiguration = { type: "lldb-dap", request: "launch", name: "", }; // The `config` parameter allows providing a complete JSON-encoded configuration const configJson = params.get("config"); if (configJson !== null) { Object.assign(debugConfig, JSON.parse(configJson)); } // Furthermore, some frequently used parameters can also be provided as separate parameters const stringKeys = [ "name", "request", "program", "cwd", "debuggerRoot", ]; const numberKeys = ["pid"]; const arrayKeys = [ "args", "initCommands", "preRunCommands", "stopCommands", "exitCommands", "terminateCommands", "launchCommands", "attachCommands", ]; for (const key of stringKeys) { const value = params.get(key); if (value) { debugConfig[key] = value; } } for (const key of numberKeys) { const value = params.get(key); if (value) { debugConfig[key] = Number(value); } } for (const key of arrayKeys) { // `getAll()` returns an array of strings. const value = params.getAll(key); if (value) { debugConfig[key] = value; } } // Report an error if we received any unknown parameters const supportedKeys = new Set( ["config"].concat(stringKeys).concat(numberKeys).concat(arrayKeys), ); const presentKeys = new Set(params.keys()); // FIXME: Use `Set.difference` as soon as ES2024 is widely available const unknownKeys = new Set(); for (const k of presentKeys.keys()) { if (!supportedKeys.has(k)) { unknownKeys.add(k); } } if (unknownKeys.size > 0) { throw new Error( `Unsupported URL parameters: ${Array.from(unknownKeys.keys()).join(", ")}`, ); } // Prodide a default for the config name const defaultName = debugConfig.request == "launch" ? "URL-based Launch" : "URL-based Attach"; debugConfig.name = debugConfig.name || debugConfig.program || defaultName; // Force the type to `lldb-dap`. We don't want to allow launching any other // Debug Adapters using this URI scheme. if (debugConfig.type != "lldb-dap") { throw new Error(`Unsupported debugger type: ${debugConfig.type}`); } await vscode.debug.startDebugging(undefined, debugConfig); } else { throw new Error(`Unsupported Uri path: ${uri.path}`); } } catch (err) { if (err instanceof Error) { await vscode.window.showErrorMessage( `Failed to handle lldb-dap URI request: ${err.message}`, ); } else { await vscode.window.showErrorMessage( `Failed to handle lldb-dap URI request: ${JSON.stringify(err)}`, ); } } } }