"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UtcpServerManager = void 0; const express_1 = __importDefault(require("express")); const cors_1 = __importDefault(require("cors")); const decorators_1 = require("./decorators"); require("./tools/typescript-defenition"); require("./tools/get-properties-tool"); require("./tools/set-property-tool"); require("./tools/asset-tools"); require("./tools/component-tools"); require("./tools/scene-tools"); require("./tools/editor-tools"); const asset_importers_1 = require("./utils/asset-importers"); const qs_1 = require("qs"); class UtcpServerManager { constructor() { this.app = (0, express_1.default)(); (0, asset_importers_1.registerAllImporters)(); } async start(port = 3000) { this.app.use((0, cors_1.default)()); this.app.use(express_1.default.json()); this.app.set("query parser", (queryString) => (0, qs_1.parse)(queryString, { decoder(value, defaultDecoder, charset, type) { const decoded = defaultDecoder(value); if (decoded === "true") return true; if (decoded === "false") return false; if (typeof decoded === "string" && decoded !== "" && !Number.isNaN(Number(decoded))) { return Number(decoded); } if (decoded === "__null__") return null; return decoded; } })); const tools = decorators_1.ToolRegistry.getTools(); const toolInstances = new Map(); const utcpTools = []; let currentPort = port; // Let's listen first to get the port if it's 0 return new Promise((resolve, reject) => { this.server = this.app.listen(port, "127.0.0.1", () => { const addr = this.server.address(); if (addr && typeof addr === 'object') { currentPort = addr.port; } // Now register tools with the correct port this.registerTools(currentPort, tools, toolInstances, utcpTools); resolve(currentPort); }); this.server.on('error', (err) => { reject(err); }); }); } registerTools(port, tools, toolInstances, utcpTools) { const baseUrl = `http://localhost:${port}`; // Initialize tool instances and build UTCP definitions for (const toolMeta of tools) { const ToolClass = toolMeta.target.constructor; let instance = toolInstances.get(ToolClass); if (!instance) { instance = new ToolClass(); toolInstances.set(ToolClass, instance); } const toolDef = JSON.parse(JSON.stringify(toolMeta.tool)); const toolUrlPath = toolDef.tool_call_template.url; toolDef.tool_call_template.url = `${baseUrl}${toolUrlPath}`; utcpTools.push(toolDef); // Register specific endpoint const handler = async (req, res) => { try { const args = req.query; let result = await toolMeta.method.apply(instance, [args]); if (result === undefined || result === null) { res.json(null); return; } res.json(result); } catch (err) { console.error(`Error in tool ${toolDef.name}:`, err); res.status(500).json({ error: err.message }); } }; switch (toolDef.tool_call_template.http_method) { case 'POST': this.app.post(toolUrlPath, handler); break; case 'GET': this.app.get(toolUrlPath, handler); break; case 'DELETE': this.app.delete(toolUrlPath, handler); break; case 'PUT': this.app.put(toolUrlPath, handler); break; default: // throw new Error(`Unsupported HTTP method: ${toolDef.tool_call_template.http_method}`); } } // Serve UTCP Manual this.app.get('/utcp', (req, res) => { const manual = { utcp_version: "1.0.1", manual_version: "1.0.0", tools: utcpTools }; res.json(manual); }); } stop() { if (this.server) { this.server.close(); console.log("UTCP Server stopped"); } } } exports.UtcpServerManager = UtcpServerManager; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRjcC1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvdXRjcC91dGNwLXNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxzREFBcUQ7QUFDckQsZ0RBQXdCO0FBQ3hCLDZDQUE0QztBQUM1Qyx5Q0FBdUM7QUFDdkMsdUNBQXFDO0FBQ3JDLHFDQUFtQztBQUNuQywrQkFBNkI7QUFDN0IsbUNBQWlDO0FBQ2pDLCtCQUE2QjtBQUM3QixnQ0FBOEI7QUFDOUIsNkRBQStEO0FBRS9ELDJCQUEyQjtBQUUzQixNQUFhLGlCQUFpQjtJQUkxQjtRQUNJLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBQSxpQkFBTyxHQUFFLENBQUM7UUFDckIsSUFBQSxzQ0FBb0IsR0FBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQWUsSUFBSTtRQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFBLGNBQUksR0FBRSxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsaUJBQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDLFdBQW1CLEVBQUUsRUFBRSxDQUNqRCxJQUFBLFVBQUssRUFBQyxXQUFXLEVBQUU7WUFDZixPQUFPLENBQUMsS0FBSyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsSUFBSTtnQkFDeEMsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUV0QyxJQUFJLE9BQU8sS0FBSyxNQUFNO29CQUFFLE9BQU8sSUFBSSxDQUFDO2dCQUNwQyxJQUFJLE9BQU8sS0FBSyxPQUFPO29CQUFFLE9BQU8sS0FBSyxDQUFDO2dCQUV0QyxJQUNJLE9BQU8sT0FBTyxLQUFLLFFBQVE7b0JBQzNCLE9BQU8sS0FBSyxFQUFF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RyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDL0IsTUFBTSxNQUFNLEdBQWU7Z0JBQ3ZCLFlBQVksRUFBRSxPQUFPO2dCQUNyQixjQUFjLEVBQUUsT0FBTztnQkFDdkIsS0FBSyxFQUFFLFNBQVM7YUFDbkIsQ0FBQztZQUNGLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsSUFBSTtRQUNBLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwQixPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNMLENBQUM7Q0FDSjtBQXRJRCw4Q0FzSUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZXhwcmVzcywgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5pbXBvcnQgeyBUb29sUmVnaXN0cnkgfSBmcm9tICcuL2RlY29yYXRvcnMnO1xuaW1wb3J0ICcuL3Rvb2xzL3R5cGVzY3JpcHQtZGVmZW5pdGlvbic7XG5pbXBvcnQgJy4vdG9vbHMvZ2V0LXByb3BlcnRpZXMtdG9vbCc7XG5pbXBvcnQgJy4vdG9vbHMvc2V0LXByb3BlcnR5LXRvb2wnO1xuaW1wb3J0ICcuL3Rvb2xzL2Fzc2V0LXRvb2xzJztcbmltcG9ydCAnLi90b29scy9jb21wb25lbnQtdG9vbHMnO1xuaW1wb3J0ICcuL3Rvb2xzL3NjZW5lLXRvb2xzJztcbmltcG9ydCAnLi90b29scy9lZGl0b3ItdG9vbHMnO1xuaW1wb3J0IHsgcmVnaXN0ZXJBbGxJbXBvcnRlcnMgfSBmcm9tICcuL3V0aWxzL2Fzc2V0LWltcG9ydGVycyc7XG5pbXBvcnQgeyBUb29sLCBVdGNwTWFudWFsIH0gZnJvbSAnQHV0Y3Avc2RrJztcbmltcG9ydCB7IHBhcnNlIH0gZnJvbSAncXMnO1xuXG5leHBvcnQgY2xhc3MgVXRjcFNlcnZlck1hbmFnZXIge1xuICAgIHByaXZhdGUgYXBwOiBleHByZXNzLkFwcGxpY2F0aW9uO1xuICAgIHByaXZhdGUgc2VydmVyOiBhbnk7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5hcHAgPSBleHByZXNzKCk7XG4gICAgICAgIHJlZ2lzdGVyQWxsSW1wb3J0ZXJzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgc3RhcnQocG9ydDogbnVtYmVyID0gMzAwMCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICAgIHRoaXMuYXBwLnVzZShjb3JzKCkpO1xuICAgICAgICB0aGlzLmFwcC51c2UoZXhwcmVzcy5qc29uKCkpO1xuICAgICAgICB0aGlzLmFwcC5zZXQoXCJxdWVyeSBwYXJzZXJcIiwgKHF1ZXJ5U3RyaW5nOiBzdHJpbmcpID0+XG4gICAgICAgICAgICBwYXJzZShxdWVyeVN0cmluZywge1xuICAgICAgICAgICAgICAgIGRlY29kZXIodmFsdWUsIGRlZmF1bHREZWNvZGVyLCBjaGFyc2V0LCB0eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlY29kZWQgPSBkZWZhdWx0RGVjb2Rlcih2YWx1ZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlY29kZWQgPT09IFwidHJ1ZVwiKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlY29kZWQgPT09IFwiZmFsc2VcIikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBkZWNvZGVkID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVkICE9PSBcIlwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAhTnVtYmVyLmlzTmFOKE51bWJlcihkZWNvZGVkKSlcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyKGRlY29kZWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlY29kZWQgPT09IFwiX19udWxsX19cIikgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCB0b29scyA9IFRvb2xSZWdpc3RyeS5nZXRUb29scygpO1xuICAgICAgICBjb25zdCB0b29sSW5zdGFuY2VzID0gbmV3IE1hcDxGdW5jdGlvbiwgYW55PigpO1xuICAgICAgICBjb25zdCB1dGNwVG9vbHM6IFRvb2xbXSA9IFtdO1xuXG4gICAgICAgIGxldCBjdXJyZW50UG9ydCA9IHBvcnQ7XG5cbiAgICAgICAgLy8gTGV0J3MgbGlzdGVuIGZpcnN0IHRvIGdldCB0aGUgcG9ydCBpZiBpdCdzIDBcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyID0gdGhpcy5hcHAubGlzdGVuKHBvcnQsIFwiMTI3LjAuMC4xXCIsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhZGRyID0gdGhpcy5zZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgICAgICAgICAgIGlmIChhZGRyICYmIHR5cGVvZiBhZGRyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UG9ydCA9IGFkZHIucG9ydDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBOb3cgcmVnaXN0ZXIgdG9vbHMgd2l0aCB0aGUgY29ycmVjdCBwb3J0XG4gICAgICAgICAgICAgICAgdGhpcy5yZWdpc3RlclRvb2xzKGN1cnJlbnRQb3J0LCB0b29scywgdG9vbEluc3RhbmNlcywgdXRjcFRvb2xzKTtcblxuICAgICAgICAgICAgICAgIHJlc29sdmUoY3VycmVudFBvcnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNlcnZlci5vbignZXJyb3InLCAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlZ2lzdGVyVG9vbHMocG9ydDogbnVtYmVyLCB0b29sczogYW55W10sIHRvb2xJbnN0YW5jZXM6IE1hcDxGdW5jdGlvbiwgYW55PiwgdXRjcFRvb2xzOiBUb29sW10pIHtcbiAgICAgICAgY29uc3QgYmFzZVVybCA9IGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgdG9vbCBpbnN0YW5jZXMgYW5kIGJ1aWxkIFVUQ1AgZGVmaW5pdGlvbnNcbiAgICAgICAgZm9yIChjb25zdCB0b29sTWV0YSBvZiB0b29scykge1xuICAgICAgICAgICAgY29uc3QgVG9vbENsYXNzID0gdG9vbE1ldGEudGFyZ2V0LmNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgbGV0IGluc3RhbmNlID0gdG9vbEluc3RhbmNlcy5nZXQoVG9vbENsYXNzKTtcbiAgICAgICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBUb29sQ2xhc3MoKTtcbiAgICAgICAgICAgICAgICB0b29sSW5zdGFuY2VzLnNldChUb29sQ2xhc3MsIGluc3RhbmNlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdG9vbERlZiA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodG9vbE1ldGEudG9vbCkpO1xuICAgICAgICAgICAgY29uc3QgdG9vbFVybFBhdGggPSB0b29sRGVmLnRvb2xfY2FsbF90ZW1wbGF0ZS51cmw7XG5cbiAgICAgICAgICAgIHRvb2xEZWYudG9vbF9jYWxsX3RlbXBsYXRlLnVybCA9IGAke2Jhc2VVcmx9JHt0b29sVXJsUGF0aH1gO1xuXG4gICAgICAgICAgICB1dGNwVG9vbHMucHVzaCh0b29sRGVmKTtcblxuICAgICAgICAgICAgLy8gUmVnaXN0ZXIgc3BlY2lmaWMgZW5kcG9pbnRcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IHJlcS5xdWVyeTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdG9vbE1ldGEubWV0aG9kLmFwcGx5KGluc3RhbmNlLCBbYXJnc10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCB8fCByZXN1bHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5qc29uKG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzLmpzb24ocmVzdWx0KTtcblxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGluIHRvb2wgJHt0b29sRGVmLm5hbWV9OmAsIGVycik7XG4gICAgICAgICAgICAgICAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHsgZXJyb3I6IGVyci5tZXNzYWdlIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHN3aXRjaCAodG9vbERlZi50b29sX2NhbGxfdGVtcGxhdGUuaHR0cF9tZXRob2QpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdQT1NUJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAucG9zdCh0b29sVXJsUGF0aCwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ0dFVCc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwLmdldCh0b29sVXJsUGF0aCwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ0RFTEVURSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwLmRlbGV0ZSh0b29sVXJsUGF0aCwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1BVVCc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwLnB1dCh0b29sVXJsUGF0aCwgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBIVFRQIG1ldGhvZDogJHt0b29sRGVmLnRvb2xfY2FsbF90ZW1wbGF0ZS5odHRwX21ldGhvZH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNlcnZlIFVUQ1AgTWFudWFsXG4gICAgICAgIHRoaXMuYXBwLmdldCgnL3V0Y3AnLCAocmVxLCByZXMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1hbnVhbDogVXRjcE1hbnVhbCA9IHtcbiAgICAgICAgICAgICAgICB1dGNwX3ZlcnNpb246IFwiMS4wLjFcIixcbiAgICAgICAgICAgICAgICBtYW51YWxfdmVyc2lvbjogXCIxLjAuMFwiLFxuICAgICAgICAgICAgICAgIHRvb2xzOiB1dGNwVG9vbHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXMuanNvbihtYW51YWwpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdG9wKCkge1xuICAgICAgICBpZiAodGhpcy5zZXJ2ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmNsb3NlKCk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIlVUQ1AgU2VydmVyIHN0b3BwZWRcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=