mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
commit
da114fa3a5
@ -448,12 +448,18 @@ RED.nodes = (function() {
|
||||
doZFilter = true;
|
||||
}
|
||||
}
|
||||
var objectLookup = false;
|
||||
if (searchSet === null) {
|
||||
searchSet = nodes;
|
||||
searchSet = Object.keys(nodes);
|
||||
objectLookup = true;
|
||||
}
|
||||
|
||||
|
||||
for (var n=0;n<searchSet.length;n++) {
|
||||
var node = searchSet[n];
|
||||
if (objectLookup) {
|
||||
node = nodes[node];
|
||||
}
|
||||
if (filter.hasOwnProperty("type") && node.type !== filter.type) {
|
||||
continue;
|
||||
}
|
||||
@ -1118,8 +1124,8 @@ RED.nodes = (function() {
|
||||
}
|
||||
}
|
||||
if ((!n._def.defaults || !n._def.defaults.hasOwnProperty("l")) && n.hasOwnProperty('l')) {
|
||||
var isLink = /^link (in|out)$/.test(node.type);
|
||||
if (isLink == n.l) {
|
||||
var showLabel = n._def.hasOwnProperty("showLabel")?n._def.showLabel:true;
|
||||
if (showLabel != n.l) {
|
||||
node.l = n.l;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
* sublabel: 'Local', // a sub-label for the item
|
||||
* icon: 'fa fa-rocket', // (optional) icon for the item
|
||||
* checkbox: true/false, // (optional) if present, display checkbox accordingly
|
||||
* radio: 'group-name', // (optional) if present, display radio box - using group-name to set radio group
|
||||
* selected: true/false, // (optional) whether the item is selected or not
|
||||
* children: [] | function(done,item) // (optional) an array of child items, or a function
|
||||
* // that will call the `done` callback with an array
|
||||
@ -640,6 +641,41 @@
|
||||
}
|
||||
}
|
||||
selectWrapper.appendTo(label)
|
||||
} else if (item.radio) {
|
||||
var selectWrapper = $('<span class="red-ui-treeList-icon"></span>');
|
||||
var cb = $('<input class="red-ui-treeList-radio" type="radio">').prop('name', item.radio).prop('checked',item.selected).appendTo(selectWrapper);
|
||||
cb.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
cb.on('change', function(e) {
|
||||
item.selected = this.checked;
|
||||
that._selected.forEach(function(selectedItem) {
|
||||
if (selectedItem.radio === item.radio) {
|
||||
selectedItem.treeList.label.removeClass("selected");
|
||||
selectedItem.selected = false;
|
||||
that._selected.delete(selectedItem);
|
||||
}
|
||||
})
|
||||
if (item.selected) {
|
||||
that._selected.add(item);
|
||||
} else {
|
||||
that._selected.delete(item);
|
||||
}
|
||||
label.toggleClass("selected",this.checked);
|
||||
that._trigger("select",e,item);
|
||||
})
|
||||
if (!item.children) {
|
||||
label.on("click", function(e) {
|
||||
e.stopPropagation();
|
||||
cb.trigger("click");
|
||||
})
|
||||
}
|
||||
item.treeList.select = function(v) {
|
||||
if (v !== item.selected) {
|
||||
cb.trigger("click");
|
||||
}
|
||||
}
|
||||
selectWrapper.appendTo(label)
|
||||
} else {
|
||||
label.on("click", function(e) {
|
||||
if (!that.options.multi) {
|
||||
|
@ -151,7 +151,7 @@ RED.editor = (function() {
|
||||
valid = definition[property].hasOwnProperty("required") && !definition[property].required;
|
||||
} else {
|
||||
var configNode = RED.nodes.node(value);
|
||||
valid = (configNode !== null && (configNode.valid == null || configNode.valid));
|
||||
valid = (configNode && (configNode.valid == null || configNode.valid));
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
|
@ -93,17 +93,20 @@
|
||||
|
||||
|
||||
}
|
||||
var showLabel = node._def.hasOwnProperty("showLabel")?node._def.showLabel:true;
|
||||
|
||||
if (!$("#node-input-show-label").prop('checked')) {
|
||||
// Not checked - hide label
|
||||
if (!/^link (in|out)$/.test(node.type)) {
|
||||
// Not a link node - default state is true
|
||||
|
||||
if (showLabel) {
|
||||
// Default to show label
|
||||
if (node.l !== false) {
|
||||
editState.changes.l = node.l
|
||||
editState.changed = true;
|
||||
}
|
||||
node.l = false;
|
||||
} else {
|
||||
// A link node - default state is false
|
||||
// Node has showLabel:false (eg link nodes)
|
||||
if (node.hasOwnProperty('l') && node.l) {
|
||||
editState.changes.l = node.l
|
||||
editState.changed = true;
|
||||
@ -112,8 +115,8 @@
|
||||
}
|
||||
} else {
|
||||
// Checked - show label
|
||||
if (!/^link (in|out)$/.test(node.type)) {
|
||||
// Not a link node - default state is true
|
||||
if (showLabel) {
|
||||
// Default to show label
|
||||
if (node.hasOwnProperty('l') && !node.l) {
|
||||
editState.changes.l = node.l
|
||||
editState.changed = true;
|
||||
@ -204,8 +207,8 @@
|
||||
})
|
||||
|
||||
if (!node.hasOwnProperty("l")) {
|
||||
// Show label if type not link
|
||||
node.l = !/^link (in|out)$/.test(node._def.type);
|
||||
// Show label unless def.showLabel set to false
|
||||
node.l = node._def.hasOwnProperty("showLabel")?node._def.showLabel:true;
|
||||
}
|
||||
$("#node-input-show-label").prop("checked",node.l).trigger("change");
|
||||
|
||||
|
@ -159,15 +159,15 @@ RED.view.tools = (function() {
|
||||
nodes.forEach(function(n) {
|
||||
var modified = false;
|
||||
var oldValue = n.l === undefined?true:n.l;
|
||||
var isLink = /^link (in|out)$/.test(n._def.type);
|
||||
var showLabel = n._def.hasOwnProperty("showLabel")?n._def.showLabel:true;
|
||||
|
||||
if (labelShown) {
|
||||
if (n.l === false || (isLink && !n.hasOwnProperty('l'))) {
|
||||
if (n.l === false || (!showLabel && !n.hasOwnProperty('l'))) {
|
||||
n.l = true;
|
||||
modified = true;
|
||||
}
|
||||
} else {
|
||||
if ((!isLink && (!n.hasOwnProperty('l') || n.l === true)) || (isLink && n.l === true) ) {
|
||||
if ((showLabel && (!n.hasOwnProperty('l') || n.l === true)) || (!showLabel && n.l === true) ) {
|
||||
n.l = false;
|
||||
modified = true;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ RED.view = (function() {
|
||||
var nn = result.node;
|
||||
|
||||
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
||||
if (showLabel !== undefined && !/^link (in|out)$/.test(nn._def.type) && !nn._def.defaults.hasOwnProperty("l")) {
|
||||
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
|
||||
nn.l = showLabel;
|
||||
}
|
||||
|
||||
@ -1088,7 +1088,7 @@ RED.view = (function() {
|
||||
nn.x = point[0];
|
||||
nn.y = point[1];
|
||||
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
||||
if (showLabel !== undefined && !/^link (in|out)$/.test(nn._def.type) && !nn._def.defaults.hasOwnProperty("l")) {
|
||||
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
|
||||
nn.l = showLabel;
|
||||
}
|
||||
if (quickAddLink) {
|
||||
@ -1991,7 +1991,7 @@ RED.view = (function() {
|
||||
activeLinkNodes = {};
|
||||
for (var i=0;i<movingSet.length();i++) {
|
||||
var msn = movingSet.get(i);
|
||||
if ((msn.n.type === "link out" || msn.n.type === "link in") &&
|
||||
if (((msn.n.type === "link out" && msn.n.mode !== 'return') || msn.n.type === "link in") &&
|
||||
(msn.n.z === activeWorkspace)) {
|
||||
var linkNode = msn.n;
|
||||
activeLinkNodes[linkNode.id] = linkNode;
|
||||
@ -4140,7 +4140,7 @@ RED.view = (function() {
|
||||
}
|
||||
var numOutputs = d.outputs;
|
||||
if (isLink && d.type === "link out") {
|
||||
if (showAllLinkPorts===PORT_TYPE_OUTPUT || activeLinkNodes[d.id]) {
|
||||
if (d.mode !== "return" && (showAllLinkPorts===PORT_TYPE_OUTPUT || activeLinkNodes[d.id])) {
|
||||
numOutputs = 1;
|
||||
} else {
|
||||
numOutputs = 0;
|
||||
|
@ -95,7 +95,8 @@
|
||||
color: $list-item-color;
|
||||
}
|
||||
|
||||
input.red-ui-treeList-checkbox {
|
||||
input.red-ui-treeList-checkbox,
|
||||
input.red-ui-treeList-radio {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,26 @@
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-mode"><span data-i18n="link.outMode"></span></label>
|
||||
<select id="node-input-mode" style="width: 70%">
|
||||
<option value="link" selected data-i18n="link.sendToAll"></option>
|
||||
<option value="return" data-i18n="link.returnToCaller"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="node-input-link-rows" style="position:relative; height: 30px; text-align: right;"><div style="display:inline-block"><input type="text" id="node-input-link-target-filter"></div></div>
|
||||
<div class="form-row node-input-link-row node-input-link-rows"></div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-template-name="link call">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-timeout"><span data-i18n="exec.label.timeout"></span></label>
|
||||
<input type="text" id="node-input-timeout" placeholder="30" style="width: 70px; margin-right: 5px;"><span data-i18n="inject.seconds"></span>
|
||||
</div>
|
||||
<div style="position:relative; height: 30px; text-align: right;"><div style="display:inline-block"><input type="text" id="node-input-link-target-filter"></div></div>
|
||||
<div class="form-row node-input-link-row"></div>
|
||||
</script>
|
||||
@ -48,7 +68,6 @@
|
||||
}
|
||||
});
|
||||
var candidateNodes = RED.nodes.filterNodes({type:targetType});
|
||||
|
||||
var search = $("#node-input-link-target-filter").searchBox({
|
||||
style: "compact",
|
||||
delay: 300,
|
||||
@ -104,7 +123,8 @@
|
||||
node: n,
|
||||
label: n.name||n.id,
|
||||
selected: isChecked,
|
||||
checkbox: true
|
||||
checkbox: node.type !== "link call",
|
||||
radio: node.type === "link call"
|
||||
})
|
||||
}
|
||||
});
|
||||
@ -129,6 +149,7 @@
|
||||
function onEditSave(node) {
|
||||
var flows = treeList.treeList('data');
|
||||
node.links = [];
|
||||
if (node.type !== "link out" || $("node-input-mode").val() === 'link') {
|
||||
flows.forEach(function(f) {
|
||||
f.children.forEach(function(n) {
|
||||
if (n.selected) {
|
||||
@ -136,8 +157,14 @@
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
node.oldLinks.sort();
|
||||
node.links.sort();
|
||||
|
||||
if (node.type === "link call") {
|
||||
return
|
||||
}
|
||||
|
||||
var nodeMap = {};
|
||||
var length = Math.max(node.oldLinks.length,node.links.length);
|
||||
for (var i=0;i<length;i++) {
|
||||
@ -195,6 +222,7 @@
|
||||
outputLabels: function(i) {
|
||||
return this.name||this._("link.linkIn");
|
||||
},
|
||||
showLabel: false,
|
||||
label: function() {
|
||||
return this.name||this._("link.linkIn");
|
||||
},
|
||||
@ -211,25 +239,32 @@
|
||||
oneditresize: resizeNodeList
|
||||
});
|
||||
|
||||
RED.nodes.registerType('link out',{
|
||||
RED.nodes.registerType('link call',{
|
||||
category: 'common',
|
||||
color:"#ddd",//"#87D8CF",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
links: { value: [], type:"link in[]"}
|
||||
links: { value: [], type:"link in[]"},
|
||||
timeout: { value: "30", validate:RED.validators.number(true) }
|
||||
},
|
||||
align:"right",
|
||||
inputs: 1,
|
||||
outputs:0,
|
||||
icon: "link-out.svg",
|
||||
outputs: 1,
|
||||
icon: "link-call.svg",
|
||||
inputLabels: function(i) {
|
||||
return this.name||this._("link.linkOut");
|
||||
return this.name||this._("link.linkCall");
|
||||
},
|
||||
label: function() {
|
||||
return this.name||this._("link.linkOut");
|
||||
if (this.name) {
|
||||
return this.name;
|
||||
}
|
||||
if (this.links.length > 0) {
|
||||
var targetNode = RED.nodes.node(this.links[0]);
|
||||
return targetNode && (targetNode.name || targetNode.id);
|
||||
}
|
||||
return this._("link.linkCall");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
return (this.name || this.links.length > 0)?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
onEditPrepare(this,"link in");
|
||||
@ -237,8 +272,56 @@
|
||||
oneditsave: function() {
|
||||
onEditSave(this);
|
||||
},
|
||||
oneditresize: resizeNodeList
|
||||
});
|
||||
|
||||
|
||||
RED.nodes.registerType('link out',{
|
||||
category: 'common',
|
||||
color:"#ddd",//"#87D8CF",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
mode: { value: "link" },// link || return
|
||||
links: { value: [], type:"link in[]"}
|
||||
},
|
||||
align:"right",
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: function() {
|
||||
if (this.mode === "return") {
|
||||
return "link-return.svg";
|
||||
} else {
|
||||
return "link-out.svg";
|
||||
}
|
||||
},
|
||||
inputLabels: function(i) {
|
||||
return this.name||(this.mode === "return" ?this._("link.linkOutReturn"):this._("link.linkOut"));
|
||||
},
|
||||
showLabel: false,
|
||||
label: function() {
|
||||
return this.name||(this.mode === "return" ?this._("link.linkOutReturn"):this._("link.linkOut"));
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
onEditPrepare(this,"link in");
|
||||
$("#node-input-mode").on("change", function() {
|
||||
$(".node-input-link-rows").toggle(this.value === "link")
|
||||
})
|
||||
if (!this.mode) {
|
||||
$("#node-input-mode").val('link').trigger("change");
|
||||
}
|
||||
|
||||
},
|
||||
oneditsave: function() {
|
||||
onEditSave(this);
|
||||
},
|
||||
onadd: onAdd,
|
||||
oneditresize: resizeNodeList
|
||||
});
|
||||
|
||||
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
@ -17,6 +17,8 @@
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
|
||||
const crypto = require("crypto");
|
||||
|
||||
function LinkInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
@ -40,13 +42,91 @@ module.exports = function(RED) {
|
||||
function LinkOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
var mode = n.mode || "link";
|
||||
|
||||
var event = "node:"+n.id;
|
||||
this.on("input", function(msg, send, done) {
|
||||
msg._event = event;
|
||||
RED.events.emit(event,msg)
|
||||
|
||||
if (mode === "return") {
|
||||
if (Array.isArray(msg._linkSource) && msg._linkSource.length > 0) {
|
||||
var messageEvent = msg._linkSource.pop();
|
||||
var returnNode = RED.nodes.getNode(messageEvent.node);
|
||||
if (returnNode && returnNode.returnLinkMessage) {
|
||||
returnNode.returnLinkMessage(messageEvent.id, msg);
|
||||
} else {
|
||||
node.warn(RED._("link.error.missingReturn"))
|
||||
}
|
||||
} else {
|
||||
node.warn(RED._("link.error.missingReturn"))
|
||||
}
|
||||
done();
|
||||
} else if (mode === "link") {
|
||||
send(msg);
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("link out",LinkOutNode);
|
||||
|
||||
|
||||
function LinkCallNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
const node = this;
|
||||
const target = n.links[0];
|
||||
const messageEvents = {};
|
||||
let timeout = parseFloat(n.timeout || "30")*1000;
|
||||
if (isNaN(timeout)) {
|
||||
timeout = 30000;
|
||||
}
|
||||
|
||||
this.on("input", function(msg, send, done) {
|
||||
msg._linkSource = msg._linkSource || [];
|
||||
const messageEvent = {
|
||||
id: crypto.randomBytes(14).toString('hex'),
|
||||
node: node.id,
|
||||
}
|
||||
messageEvents[messageEvent.id] = {
|
||||
msg: RED.util.cloneMessage(msg),
|
||||
send,
|
||||
done,
|
||||
ts: setTimeout(function() {
|
||||
timeoutMessage(messageEvent.id)
|
||||
}, timeout )
|
||||
};
|
||||
msg._linkSource.push(messageEvent);
|
||||
var targetNode = RED.nodes.getNode(target);
|
||||
if (targetNode) {
|
||||
targetNode.receive(msg);
|
||||
}
|
||||
});
|
||||
|
||||
this.returnLinkMessage = function(eventId, msg) {
|
||||
if (Array.isArray(msg._linkSource) && msg._linkSource.length === 0) {
|
||||
delete msg._linkSource;
|
||||
}
|
||||
const messageEvent = messageEvents[eventId];
|
||||
if (messageEvent) {
|
||||
clearTimeout(messageEvent.ts);
|
||||
delete messageEvents[eventId];
|
||||
messageEvent.send(msg);
|
||||
messageEvent.done();
|
||||
} else {
|
||||
node.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function timeoutMessage(eventId) {
|
||||
const messageEvent = messageEvents[eventId];
|
||||
if (messageEvent) {
|
||||
delete messageEvents[eventId];
|
||||
node.error("timeout",messageEvent.msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
RED.nodes.registerType("link call",LinkCallNode);
|
||||
|
||||
|
||||
}
|
||||
|
5
packages/node_modules/@node-red/nodes/icons/link-call.svg
vendored
Normal file
5
packages/node_modules/@node-red/nodes/icons/link-call.svg
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="10.583mm" height="15.875mm" version="1.1" viewBox="0 0 10.583 15.875" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m8.2021 2.3812-4.8922 0.53612 1.604 0.92604-1.0395 1.8004c0.73719-0.37402 1.6437-0.38227 2.4095 0.059892 0.76511 0.44174 1.2118 1.2301 1.2577 2.055l1.0384-1.7986 1.604 0.92604zm-2.3813 4.1244c-0.77016-0.44465-1.7402-0.18474-2.1848 0.58542-0.44465 0.77016-0.185 1.7406 0.58516 2.1853 0.77016 0.44465 1.7422 0.18533 2.1869-0.58483 0.44465-0.77016 0.18295-1.7412-0.58721-2.1858zm-3.3193 1.5159-1.8211 3.1542 3.6662 2.1167 1.82-3.1524c-0.73731 0.37266-1.6431 0.37961-2.4082-0.062129-0.76585-0.44216-1.2122-1.2309-1.2569-2.0563z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 771 B |
5
packages/node_modules/@node-red/nodes/icons/link-return.svg
vendored
Normal file
5
packages/node_modules/@node-red/nodes/icons/link-return.svg
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="10.583mm" height="15.875mm" version="1.1" viewBox="0 0 10.583 15.875" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m2.6623 13.292 4.8922-0.53612-1.604-0.92604 1.0395-1.8004c-0.73719 0.37402-1.6437 0.38227-2.4095-0.059892-0.76511-0.44174-1.2118-1.2301-1.2577-2.055l-1.0384 1.7986-1.604-0.92604zm2.3813-4.1244c0.77016 0.44465 1.7402 0.18474 2.1848-0.58542 0.44465-0.77016 0.185-1.7406-0.58516-2.1853-0.77016-0.44465-1.7422-0.18533-2.1869 0.58483-0.44465 0.77016-0.18295 1.7412 0.58721 2.1858zm3.3193-1.5159 1.8211-3.1542-3.6662-2.1167-1.82 3.1524c0.73731-0.37266 1.6431-0.37961 2.4082 0.062129 0.76585 0.44216 1.2122 1.2309 1.2569 2.0563z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 769 B |
@ -28,10 +28,23 @@
|
||||
<script type="text/html" data-help-name="link out">
|
||||
<p>Create virtual wires between flows.</p>
|
||||
<h3>Details</h3>
|
||||
<p>The node can be connected to any <code>link in</code> node that exists on any tab.
|
||||
Once connected, they behave as if they were wired together.</p>
|
||||
<p>The wires between link nodes are only displayed when a link node is selected.
|
||||
If there are any wires to other tabs, a virtual node is show that can be clicked
|
||||
on to jump to the appropriate tab.</p>
|
||||
<p>This node can be configured to either send messages to all <code>link in</code>
|
||||
nodes it is connected to, or to send a response back to the <code>link call</code>
|
||||
node that triggered the flow.</p>
|
||||
<p>When in 'send to all' mode, the wires between link nodes are only displayed when
|
||||
the node is selected. If there are any wires to other tabs, a virtual node
|
||||
is shown that can be clicked on to jump to the appropriate tab.</p>
|
||||
<p><b>Note: </b>Links cannot be created going into, or out of, a subflow.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="link call">
|
||||
<p>Calls a flow that starts with a <code>link in</code> node and passes on the response.</p>
|
||||
<h3>Details</h3>
|
||||
<p>This node can be connected to a <code>link in</code> node that exists on any tab.
|
||||
The flow connected to that node must end with a <code>link out</code> node configured
|
||||
in 'return' mode.</p>
|
||||
<p>When this node receives a message, it is passed to the connected <code>link in</code> node.
|
||||
It then waits for a response which it then sends on.</o>
|
||||
<p>If no response is received within the configured timeout, default 30 seconds, the node
|
||||
will log an error that can be caught using the <code>catch</code> node.</p>
|
||||
</script>
|
||||
|
@ -159,7 +159,15 @@
|
||||
},
|
||||
"link": {
|
||||
"linkIn": "link in",
|
||||
"linkOut": "link out"
|
||||
"linkOut": "link out",
|
||||
"linkCall": "link call",
|
||||
"linkOutReturn": "link return",
|
||||
"outMode": "Mode",
|
||||
"sendToAll": "Send to all connected link nodes",
|
||||
"returnToCaller": "Return to calling link node",
|
||||
"error": {
|
||||
"missingReturn": "Missing return node information"
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"tls": "TLS configuration",
|
||||
|
@ -119,4 +119,69 @@ describe('link Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("link-call node", function() {
|
||||
it('should call link-in node and get response', function(done) {
|
||||
var flow = [{id:"link-in-1", type:"link in", wires: [[ "func"]]},
|
||||
{id:"func", type:"helper", wires: [["link-out-1"]]},
|
||||
{id:"link-out-1", type:"link out", mode: "return"},
|
||||
{id:"link-call", type:"link call", links:["link-in-1"], wires:[["n4"]]},
|
||||
{id:"n4", type:"helper"} ];
|
||||
helper.load(linkNode, flow, function() {
|
||||
var func = helper.getNode("func");
|
||||
func.on("input", function(msg, send, done) {
|
||||
msg.payload = "123";
|
||||
send(msg);
|
||||
done();
|
||||
})
|
||||
var n1 = helper.getNode("link-call");
|
||||
var n4 = helper.getNode("n4");
|
||||
n4.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('payload', '123');
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:"hello"});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
it('should allow nested link-call flows', function(done) {
|
||||
var flow = [/** Multiply by 2 link flow **/
|
||||
{id:"li1", type:"link in", wires: [[ "m2"]]},
|
||||
{id:"m2", type:"helper", wires: [["lo1"]]},
|
||||
{id:"lo1", type:"link out", mode: "return"},
|
||||
/** Multiply by 3 link flow **/
|
||||
{id:"li2", type:"link in", wires: [[ "m3"]]},
|
||||
{id:"m3", type:"helper", wires: [["lo2"]]},
|
||||
{id:"lo2", type:"link out", mode: "return"},
|
||||
/** Multiply by 6 link flow **/
|
||||
{id:"li3", type:"link in", wires: [[ "link-call-1"]]},
|
||||
{id:"link-call-1", type:"link call", links:["m2"], wires:[["link-call-2"]]},
|
||||
{id:"link-call-2", type:"link call", links:["m3"], wires:[["lo3"]]},
|
||||
{id:"lo3", type:"link out", mode: "return"},
|
||||
/** Test Flow Entry **/
|
||||
{id:"link-call", type:"link call", links:["li3"], wires:[["n4"]]},
|
||||
{id:"n4", type:"helper"} ];
|
||||
helper.load(linkNode, flow, function() {
|
||||
var m2 = helper.getNode("m2");
|
||||
m2.on("input", function(msg, send, done) { msg.payload *= 2 ; send(msg); done(); })
|
||||
var m3 = helper.getNode("m3");
|
||||
m3.on("input", function(msg, send, done) { msg.payload *= 3 ; send(msg); done(); })
|
||||
|
||||
var n1 = helper.getNode("link-call");
|
||||
var n4 = helper.getNode("n4");
|
||||
n4.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('payload', 24);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
n1.receive({payload:4});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user