Procházet zdrojové kódy

feat: parse dynamicOutputs and named inputs out of node files

fszontagh před 1 měsícem
rodič
revize
fdb1456a8b

+ 51 - 0
src/webserver/nodes/node_store.cpp

@@ -212,6 +212,10 @@ nlohmann::json StoredNode::toJson() const {
         j["outputs"].push_back(output.toJson());
     }
 
+    if (!dynamic_outputs.is_null()) {
+        j["dynamicOutputs"] = dynamic_outputs;
+    }
+
     return j;
 }
 
@@ -253,6 +257,10 @@ StoredNode StoredNode::fromJson(const nlohmann::json& j) {
         }
     }
 
+    if (j.contains("dynamicOutputs")) {
+        node.dynamic_outputs = j["dynamicOutputs"];
+    }
+
     return node;
 }
 
@@ -375,6 +383,49 @@ StoredNode StoredNode::parseFromCode(const std::string& code, const std::string&
         }
     }
 
+    // Parse dynamicOutputs object - ports a placed node derives from its config
+    std::regex dynamic_outputs_regex(R"(const\s+dynamicOutputs\s*=\s*)");
+    if (std::regex_search(code, match, dynamic_outputs_regex)) {
+        size_t start_pos = match.position() + match.length();
+        size_t brace_pos = code.find('{', start_pos);
+        if (brace_pos != std::string::npos) {
+            std::string jsonStr = jsLiteralToJson(code, brace_pos);
+            if (!jsonStr.empty()) {
+                try {
+                    node.dynamic_outputs = nlohmann::json::parse(jsonStr);
+                } catch (const nlohmann::json::exception& e) {
+                    LOG_WARN("Failed to parse dynamicOutputs for {}: {}", node.id, e.what());
+                }
+            }
+        }
+    }
+
+    // Parse inputs array - a node with more than one input handle
+    std::regex inputs_start_regex(R"(const\s+inputs\s*=\s*\[)");
+    if (std::regex_search(code, match, inputs_start_regex)) {
+        size_t start_pos = match.position() + match.length() - 1;
+        std::string jsonStr = jsLiteralToJson(code, start_pos);
+        if (!jsonStr.empty()) {
+            try {
+                auto inputs_json = nlohmann::json::parse(jsonStr);
+                if (inputs_json.is_array()) {
+                    for (const auto& in : inputs_json) {
+                        NodeIO input;
+                        input.name = in.value("name", "");
+                        input.display_name = in.value("displayName", in.value("name", ""));
+                        input.type = in.value("type", "any");
+                        input.required = in.value("required", false);
+                        if (!input.name.empty()) {
+                            node.inputs.push_back(input);
+                        }
+                    }
+                }
+            } catch (const nlohmann::json::exception& e) {
+                LOG_DEBUG("Failed to parse inputs array for {}: {}", node.id, e.what());
+            }
+        }
+    }
+
     // Default inputs (non-triggers get a data input)
     if (node.inputs.empty() && !node.is_trigger) {
         NodeIO default_input;

+ 1 - 0
src/webserver/nodes/node_store.hpp

@@ -35,6 +35,7 @@ struct StoredNode {
     nlohmann::json output_schema;
     std::vector<NodeIO> inputs;
     std::vector<NodeIO> outputs;
+    nlohmann::json dynamic_outputs;    // Ports derived from a placed node's config
     bool is_trigger = false;
     bool is_scheduled = false;  // For triggers that support scheduled/periodic execution
     std::string owner_id;