Compare commits

..

3 Commits

Author SHA1 Message Date
Steve-Mcl
20a63a3292 fix tests after adding 'set by msg.payloadHandling' 2022-11-29 13:50:39 +00:00
Steve-Mcl
3a5cdbc8ae improve UI around payloadHandling 2022-11-29 13:38:09 +00:00
Stephen McLaughlin
3ed5969e87 add msg.payloadHandling for get requests 2022-11-28 19:31:44 +00:00
107 changed files with 338 additions and 668 deletions

View File

@@ -19,9 +19,9 @@ jobs:
matrix:
node-version: [14, 16]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies

View File

View File

View File

View File

@@ -683,8 +683,6 @@
"empty": "empty",
"globalConfig": "Global Configuration Nodes",
"triggerAction": "Trigger action",
"showFlow": "Show",
"hideFlow": "Hide",
"find": "Find in workspace"
},
"help": {

View File

View File

View File

@@ -683,8 +683,6 @@
"empty": "空",
"globalConfig": "グローバル設定ノード",
"triggerAction": "アクションを実行",
"showFlow": "表示",
"hideFlow": "非表示",
"find": "ワークスペース内を検索"
},
"help": {

View File

View File

View File

View File

View File

View File

View File

@@ -1965,7 +1965,7 @@ RED.nodes = (function() {
}
}
} else {
const keepNodesCurrentZ = reimport && n.z && (RED.workspaces.contains(n.z) || RED.nodes.subflow(n.z))
const keepNodesCurrentZ = reimport && n.z && RED.workspaces.contains(n.z)
if (!keepNodesCurrentZ && n.z && !workspace_map[n.z] && !subflow_map[n.z]) {
n.z = activeWorkspace;
}
@@ -2067,7 +2067,7 @@ RED.nodes = (function() {
node.id = getID();
} else {
node.id = n.id;
const keepNodesCurrentZ = reimport && node.z && (RED.workspaces.contains(node.z) || RED.nodes.subflow(node.z))
const keepNodesCurrentZ = reimport && node.z && RED.workspaces.contains(node.z)
if (!keepNodesCurrentZ && (node.z == null || (!workspace_map[node.z] && !subflow_map[node.z]))) {
if (createMissingWorkspace) {
if (missingWorkspace === null) {
@@ -2740,7 +2740,6 @@ RED.nodes = (function() {
}
});
const nodeGroupMap = {}
var replaceNodeIds = Object.keys(replaceNodes);
if (replaceNodeIds.length > 0) {
var reimportList = [];
@@ -2751,12 +2750,6 @@ RED.nodes = (function() {
} else {
allNodes.removeNode(n);
}
if (n.g) {
// reimporting a node *without* including its group object
// will cause the g property to be cleared. Cache it
// here so we can restore it
nodeGroupMap[n.id] = n.g
}
reimportList.push(convertNode(n));
RED.events.emit('nodes:remove',n);
});
@@ -2778,18 +2771,6 @@ RED.nodes = (function() {
var newNodeMap = {};
result.nodes.forEach(function(n) {
newNodeMap[n.id] = n;
if (nodeGroupMap[n.id]) {
// This node is in a group - need to substitute the
// node reference inside the group
n.g = nodeGroupMap[n.id]
const group = RED.nodes.group(n.g)
if (group) {
var index = group.nodes.findIndex(gn => gn.id === n.id)
if (index > -1) {
group.nodes[index] = n
}
}
}
});
RED.nodes.eachLink(function(l) {
if (newNodeMap.hasOwnProperty(l.source.id)) {

View File

@@ -321,8 +321,6 @@ var RED = (function() {
loader.end()
RED.notify($("<p>").text(message));
RED.sidebar.info.refresh()
RED.menu.setDisabled('menu-item-projects-open',false);
RED.menu.setDisabled('menu-item-projects-settings',false);
});
});
return;

View File

@@ -238,7 +238,6 @@ RED.editor = (function() {
var valid = validateNodeProperty(node, defaults, property,value);
if (((typeof valid) === "string") || !valid) {
input.addClass("input-error");
input.next(".red-ui-typedInput-container").addClass("input-error");
if ((typeof valid) === "string") {
var tooltip = input.data("tooltip");
if (tooltip) {
@@ -251,7 +250,6 @@ RED.editor = (function() {
}
} else {
input.removeClass("input-error");
input.next(".red-ui-typedInput-container").removeClass("input-error");
var tooltip = input.data("tooltip");
if (tooltip) {
input.data("tooltip", null);

0
packages/node_modules/@node-red/editor-client/src/js/ui/library.js vendored Normal file → Executable file
View File

2
packages/node_modules/@node-red/editor-client/src/js/ui/palette.js vendored Normal file → Executable file
View File

@@ -432,7 +432,6 @@ RED.palette = (function() {
categoryNode.find(".red-ui-palette-content").slideToggle();
categoryNode.find("i").toggleClass("expanded");
}
categoryNode.hide();
}
}
@@ -511,7 +510,6 @@ RED.palette = (function() {
currentCategoryNode.find(".red-ui-palette-content").slideToggle();
currentCategoryNode.find("i").toggleClass("expanded");
}
currentCategoryNode.hide();
}
}

View File

View File

@@ -135,10 +135,6 @@ RED.sidebar.info.outliner = (function() {
RED.workspaces.show(n.id, null, true);
}
});
RED.popover.tooltip(toggleVisibleButton, function () {
var isHidden = !div.hasClass("red-ui-info-outline-item-hidden");
return RED._("sidebar.info." + (isHidden ? "hideFlow" : "showFlow"));
});
}
if (n.type !== 'subflow') {
var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
@@ -617,9 +613,6 @@ RED.sidebar.info.outliner = (function() {
objects[n.id].children = missingParents[n.id];
delete missingParents[n.id]
}
if (objects[n.id].children.length === 0) {
objects[n.id].children.push(getEmptyItem(n.id));
}
}
var parent = n.g||n.z||"__global__";

88
packages/node_modules/@node-red/editor-client/src/js/ui/view.js vendored Normal file → Executable file
View File

@@ -586,28 +586,11 @@ RED.view = (function() {
var group = $(ui.helper).data("group");
if (group) {
var oldX = group.x;
var oldY = group.y;
RED.group.addToGroup(group, nn);
var moveEvent = null;
if ((group.x !== oldX) ||
(group.y !== oldY)) {
moveEvent = {
t: "move",
nodes: [{n: group,
ox: oldX, oy: oldY,
dx: group.x -oldX,
dy: group.y -oldY}],
dirty: true
};
}
historyEvent = {
t: 'multi',
events: [historyEvent],
};
if (moveEvent) {
historyEvent.events.push(moveEvent)
}
historyEvent.events.push({
t: "addToGroup",
@@ -1367,35 +1350,19 @@ RED.view = (function() {
RED.editor.validateNode(nn);
if (targetGroup) {
var oldX = targetGroup.x;
var oldY = targetGroup.y;
RED.group.addToGroup(targetGroup, nn);
var moveEvent = null;
if ((targetGroup.x !== oldX) ||
(targetGroup.y !== oldY)) {
moveEvent = {
t: "move",
nodes: [{n: targetGroup,
ox: oldX, oy: oldY,
dx: targetGroup.x -oldX,
dy: targetGroup.y -oldY}],
dirty: true
};
}
if (historyEvent.t !== "multi") {
historyEvent = {
t:'multi',
events: [historyEvent]
};
}
}
historyEvent.events.push({
t: "addToGroup",
group: targetGroup,
nodes: nn
});
if (moveEvent) {
historyEvent.events.push(moveEvent);
}
})
}
if (spliceLink) {
@@ -1731,7 +1698,6 @@ RED.view = (function() {
// Check link splice or group-add
if (movingSet.length() === 1 && movingSet.get(0).n.type !== "group") {
//}{//NIS
node = movingSet.get(0);
if (spliceActive) {
if (!spliceTimer) {
@@ -2091,25 +2057,11 @@ RED.view = (function() {
if (mouse_mode == RED.state.MOVING_ACTIVE) {
if (movingSet.length() > 0) {
var addedToGroup = null;
var moveEvent = null;
if (activeHoverGroup) {
var oldX = activeHoverGroup.x;
var oldY = activeHoverGroup.y;
for (var j=0;j<movingSet.length();j++) {
var n = movingSet.get(j);
RED.group.addToGroup(activeHoverGroup,n.n);
}
if ((activeHoverGroup.x !== oldX) ||
(activeHoverGroup.y !== oldY)) {
moveEvent = {
t: "move",
nodes: [{n: activeHoverGroup,
ox: oldX, oy: oldY,
dx: activeHoverGroup.x -oldX,
dy: activeHoverGroup.y -oldY}],
dirty: true
};
}
addedToGroup = activeHoverGroup;
activeHoverGroup.hovered = false;
@@ -2155,12 +2107,6 @@ RED.view = (function() {
historyEvent.addToGroup = addedToGroup;
}
RED.nodes.dirty(true);
if (moveEvent) {
historyEvent = {
t: "multi",
events: [moveEvent, historyEvent]
};
}
RED.history.push(historyEvent);
}
}
@@ -3423,9 +3369,6 @@ RED.view = (function() {
}
if (dblClickPrimed && mousedown_node == d && clickElapsed > 0 && clickElapsed < dblClickInterval) {
mouse_mode = RED.state.DEFAULT;
// Avoid dbl click causing text selection.
d3.event.preventDefault()
document.getSelection().removeAllRanges()
if (d.type != "subflow") {
if (/^subflow:/.test(d.type) && (d3.event.ctrlKey || d3.event.metaKey)) {
RED.workspaces.show(d.type.substring(8));
@@ -3520,25 +3463,11 @@ RED.view = (function() {
updateActiveNodes();
}
var moveEvent = null;
if (activeHoverGroup) {
var oldX = activeHoverGroup.x;
var oldY = activeHoverGroup.y;
for (var j=0;j<movingSet.length();j++) {
var n = movingSet.get(j);
RED.group.addToGroup(activeHoverGroup,n.n);
}
if ((activeHoverGroup.x !== oldX) ||
(activeHoverGroup.y !== oldY)) {
moveEvent = {
t: "move",
nodes: [{n: activeHoverGroup,
ox: oldX, oy: oldY,
dx: activeHoverGroup.x -oldX,
dy: activeHoverGroup.y -oldY}],
dirty: true
};
}
historyEvent.addedToGroup = activeHoverGroup;
activeHoverGroup.hovered = false;
@@ -3547,6 +3476,7 @@ RED.view = (function() {
activeGroup.selected = true;
activeHoverGroup = null;
}
if (mouse_mode == RED.state.DETACHED_DRAGGING) {
var ns = [];
for (var j=0;j<movingSet.length();j++) {
@@ -3557,15 +3487,7 @@ RED.view = (function() {
n.n.moved = true;
}
}
var event = {t:"multi",events:[historyEvent,{t:"move",nodes:ns}],dirty: historyEvent.dirty};
if (moveEvent) {
event.events.push(moveEvent);
}
RED.history.replace(event)
}
else if(moveEvent) {
var event = {t:"multi", events:[historyEvent, moveEvent], dirty: true};
RED.history.replace(event);
RED.history.replace({t:"multi",events:[historyEvent,{t:"move",nodes:ns}],dirty: historyEvent.dirty})
}
updateSelection();

View File

@@ -32,8 +32,7 @@
color: var(--red-ui-primary-text-color);
border: 1px solid var(--red-ui-notification-border-default);
border-left-width: 16px;
overflow: auto;
max-height: 80vh;
overflow: hidden;
.ui-dialog-buttonset {
margin-top: 20px;
margin-bottom: 10px;

View File

@@ -41,7 +41,6 @@
height: 50px;
background: var(--red-ui-secondary-background);
border: 2px solid var(--red-ui-primary-border-color);
color: var(--red-ui-primary-text-color);
text-align: center;
line-height:50px;
@@ -52,7 +51,7 @@
.red-ui-editor-radial-menu-opt-disabled {
border-color: var(--red-ui-tertiary-border-color);
color: var(--red-ui-secondary-text-color-disabled);
color: var(--red-ui-tertiary-border-color);
}
.red-ui-editor-radial-menu-opt-active {
background: var(--red-ui-secondary-background-hover);

View File

@@ -95,64 +95,45 @@ module.exports = function(RED) {
}
this.on("input", function(msg, send, done) {
const errors = [];
let props = this.props;
var errors = [];
var props = this.props;
if (msg.__user_inject_props__ && Array.isArray(msg.__user_inject_props__)) {
props = msg.__user_inject_props__;
}
delete msg.__user_inject_props__;
props = [...props]
function evaluateProperty(doneEvaluating) {
if (props.length === 0) {
doneEvaluating()
return
}
const p = props.shift()
const property = p.p;
const value = p.v ? p.v : '';
const valueType = p.vt ? p.vt : 'str';
props.forEach(p => {
var property = p.p;
var value = p.v ? p.v : '';
var valueType = p.vt ? p.vt : 'str';
if (property) {
if (valueType === "jsonata") {
if (p.v) {
try {
var exp = RED.util.prepareJSONataExpression(p.v, node);
var val = RED.util.evaluateJSONataExpression(exp, msg);
RED.util.setMessageProperty(msg, property, val, true);
}
catch (err) {
errors.push(err.message);
}
}
evaluateProperty(doneEvaluating)
} else {
if (!property) return;
if (valueType === "jsonata") {
if (p.v) {
try {
RED.util.evaluateNodeProperty(value, valueType, node, msg, (err, newValue) => {
if (err) {
errors.push(err.toString())
} else {
RED.util.setMessageProperty(msg,property,newValue,true);
}
evaluateProperty(doneEvaluating)
})
} catch (err) {
errors.push(err.toString());
evaluateProperty(doneEvaluating)
var exp = RED.util.prepareJSONataExpression(p.v, node);
var val = RED.util.evaluateJSONataExpression(exp, msg);
RED.util.setMessageProperty(msg, property, val, true);
}
catch (err) {
errors.push(err.message);
}
}
} else {
evaluateProperty(doneEvaluating)
return;
}
try {
RED.util.setMessageProperty(msg,property,RED.util.evaluateNodeProperty(value, valueType, this, msg),true);
} catch (err) {
errors.push(err.toString());
}
});
if (errors.length) {
done(errors.join('; '));
} else {
send(msg);
done();
}
evaluateProperty(() => {
if (errors.length) {
done(errors.join('; '));
} else {
send(msg);
done();
}
})
});
}

View File

@@ -18,16 +18,7 @@
color:"#c0edc0",
defaults: {
name: {value:""},
scope: {
value: [],
type: "*[]",
validate: function (v, opt) {
if (v.length > 0) {
return true;
}
return RED._("node-red:complete.errors.scopeUndefined");
}
},
scope: {value:[], type:"*[]"},
uncaught: {value:false}
},
inputs:0,

View File

@@ -4,7 +4,7 @@
<label style="width: auto" for="node-input-scope" data-i18n="catch.label.source"></label>
<select id="node-input-scope-select">
<option value="all" data-i18n="catch.scope.all"></option>
<option value="target" data-i18n="catch.scope.selected"></option>
<option value="target" data-i18n="catch.scope.selected"></options>
</select>
</div>
<div class="form-row node-input-uncaught-row">

View File

@@ -4,7 +4,7 @@
<label style="width: auto" for="node-input-scope" data-i18n="status.label.source"></label>
<select id="node-input-scope-select">
<option value="all" data-i18n="status.scope.all"></option>
<option value="target" data-i18n="status.scope.selected"></option>
<option value="target" data-i18n="status.scope.selected"></options>
</select>
</div>
<div class="form-row node-input-target-row">

View File

@@ -1,3 +1,4 @@
<script type="text/html" data-template-name="link in">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
@@ -271,17 +272,7 @@
color:"#ddd",//"#87D8CF",
defaults: {
name: { value: "" },
links: {
value: [],
type: "link in[]",
validate: function (v, opt) {
if ((this.linkType === "static" && v.length > 0)
|| this.linkType === "dynamic") {
return true;
}
return RED._("node-red:link.errors.linkUndefined");
}
},
links: { value: [], type:"link in[]" },
linkType: { value:"static" },
timeout: {
value: "30",

View File

@@ -164,10 +164,10 @@ module.exports = function(RED) {
if (returnNode && returnNode.returnLinkMessage) {
returnNode.returnLinkMessage(messageEvent.id, msg);
} else {
node.warn(RED._("link.errors.missingReturn"));
node.warn(RED._("link.error.missingReturn"))
}
} else {
node.warn(RED._("link.errors.missingReturn"));
node.warn(RED._("link.error.missingReturn"))
}
done();
} else if (mode === "link") {

View File

@@ -17,8 +17,6 @@
display: flex;
background: var(--red-ui-tertiary-background);
padding-right: 75px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
#node-input-libs-container-row .red-ui-editableList-header > div {
flex-grow: 1;

View File

@@ -21,7 +21,6 @@
<option value="javascript">JavaScript</option>
<option value="css">CSS</option>
<option value="markdown">Markdown</option>
<option value="php">PHP</option>
<option value="python">Python</option>
<option value="sql">SQL</option>
<option value="yaml">YAML</option>

View File

@@ -295,7 +295,7 @@ module.exports = function(RED) {
/* mute error - it simply isnt JSON, just leave payload as a string */
}
}
} //else {
} //else {
//leave as buffer
//}
}
@@ -357,7 +357,7 @@ module.exports = function(RED) {
return;
}
done(err);
});
});
} else {
done();
}
@@ -366,16 +366,6 @@ module.exports = function(RED) {
}
}
function updateStatus(node, allNodes) {
let setStatus = setStatusDisconnected
if(node.connecting) {
setStatus = setStatusConnecting
} else if(node.connected) {
setStatus = setStatusConnected
}
setStatus(node, allNodes)
}
function setStatusDisconnected(node, allNodes) {
if(allNodes) {
for (var id in node.users) {
@@ -707,21 +697,16 @@ module.exports = function(RED) {
if (Object.keys(node.users).length === 1) {
if(node.autoConnect) {
node.connect();
//update nodes status
setTimeout(function() {
updateStatus(node, true)
}, 1)
}
}
};
node.deregister = function(mqttNode, done, autoDisconnect) {
node.deregister = function(mqttNode,done) {
delete node.users[mqttNode.id];
if (autoDisconnect && !node.closing && node.connected && Object.keys(node.users).length === 0) {
node.disconnect(done);
} else {
done();
if (!node.closing && node.connected && Object.keys(node.users).length === 0) {
node.disconnect();
}
done();
};
node.canConnect = function() {
return !node.connected && !node.connecting;
@@ -855,7 +840,7 @@ module.exports = function(RED) {
let waitEnd = (client, ms) => {
return new Promise( (resolve, reject) => {
node.closing = true;
if(!client) {
if(!client) {
resolve();
} else {
const t = setTimeout(() => {
@@ -1034,7 +1019,7 @@ module.exports = function(RED) {
/**
* Add event handlers to the MQTT.js client and track them so that
* we do not remove any handlers that the MQTT client uses internally.
* we do not remove any handlers that the MQTT client uses internally.
* Use {@link node._clientRemoveListeners `node._clientRemoveListeners`} to remove handlers
* @param {string} event The name of the event
* @param {function} handler The handler for this event
@@ -1042,11 +1027,11 @@ module.exports = function(RED) {
node._clientOn = function(event, handler) {
node.clientListeners.push({event, handler})
node.client.on(event, handler)
}
}
/**
* Remove event handlers from the MQTT.js client & only the events
* that we attached in {@link node._clientOn `node._clientOn`}.
* Remove event handlers from the MQTT.js client & only the events
* that we attached in {@link node._clientOn `node._clientOn`}.
* * If `event` is omitted, then all events matching `handler` are removed
* * If `handler` is omitted, then all events named `event` are removed
* * If both parameters are omitted, then all events are removed
@@ -1235,7 +1220,7 @@ module.exports = function(RED) {
} else {
node.brokerConn.unsubscribe(node.topic,node.id, removed);
}
node.brokerConn.deregister(node, done, removed);
node.brokerConn.deregister(node, done);
node.brokerConn = null;
} else {
done();
@@ -1298,9 +1283,9 @@ module.exports = function(RED) {
node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"});
}
node.brokerConn.register(node);
node.on('close', function(removed, done) {
node.on('close', function(done) {
if (node.brokerConn) {
node.brokerConn.deregister(node, done, removed)
node.brokerConn.deregister(node,done);
node.brokerConn = null;
} else {
done();

View File

@@ -46,7 +46,7 @@ module.exports = function(RED) {
isText = true;
} else if (parsedType.type !== "application") {
isText = false;
} else if ((parsedType.subtype !== "octet-stream")
} else if ((parsedType.subtype !== "octet-stream")
&& (parsedType.subtype !== "cbor")
&& (parsedType.subtype !== "x-protobuf")) {
checkUTF = true;
@@ -200,15 +200,6 @@ module.exports = function(RED) {
this.callback = function(req,res) {
var msgid = RED.util.generateId();
res._msgid = msgid;
// Since Node 15, req.headers are lazily computed and the property
// marked as non-enumerable.
// That means it doesn't show up in the Debug sidebar.
// This redefines the property causing it to be evaluated *and*
// marked as enumerable again.
Object.defineProperty(req, 'headers', {
value: req.headers,
enumerable: true
})
if (node.method.match(/^(post|delete|put|options|patch)$/)) {
node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res),payload:req.body});
} else if (node.method == "get") {

View File

@@ -33,11 +33,12 @@
</div>
<div class="form-row node-input-paytoqs-row">
<label for="node-input-paytoqs"><span data-i18n="common.label.payload"></span></label>
<label for="node-input-paytoqs"><span data-i18n="httpin.label.paytoqs.label"></span></label>
<select id="node-input-paytoqs" style="width: 70%;">
<option value="ignore" data-i18n="httpin.label.paytoqs.ignore"></option>
<option value="query" data-i18n="httpin.label.paytoqs.query"></option>
<option value="body" data-i18n="httpin.label.paytoqs.body"></option>
<option value="setby" data-i18n="httpin.label.paytoqs.setby"></option>
</select>
</div>
@@ -290,7 +291,7 @@
RED.tray.resize();
});
$("#node-input-method").on("change", function() {
if ($(this).val() == "GET") {
if ($(this).val() == "GET" || $(this).val() == "use") {
$(".node-input-paytoqs-row").show();
} else {
$(".node-input-paytoqs-row").hide();

View File

@@ -16,7 +16,7 @@
module.exports = function(RED) {
"use strict";
const got = require("got");
const got = require("got").default;
const {CookieJar} = require("tough-cookie");
const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent');
const FormData = require('form-data');
@@ -69,8 +69,6 @@ in your Node-RED user directory (${RED.settings.userDir}).
var nodeUrl = n.url;
var isTemplatedUrl = (nodeUrl||"").indexOf("{{") != -1;
var nodeMethod = n.method || "GET";
var paytoqs = false;
var paytobody = false;
var redirectList = [];
var sendErrorsToCatch = n.senderr;
node.headers = n.headers || [];
@@ -78,15 +76,12 @@ in your Node-RED user directory (${RED.settings.userDir}).
if (n.tls) {
var tlsNode = RED.nodes.getNode(n.tls);
}
this.ret = n.ret || "txt";
this.authType = n.authType || "basic";
if (RED.settings.httpRequestTimeout) { this.reqTimeout = parseInt(RED.settings.httpRequestTimeout) || 120000; }
else { this.reqTimeout = 120000; }
if (n.paytoqs === true || n.paytoqs === "query") { paytoqs = true; }
else if (n.paytoqs === "body") { paytobody = true; }
node.ret = n.ret || "txt";
node.authType = n.authType || "basic";
if (RED.settings.httpRequestTimeout) { node.reqTimeout = parseInt(RED.settings.httpRequestTimeout) || 120000; }
else { node.reqTimeout = 120000; }
node.insecureHTTPParser = n.insecureHTTPParser
node.paytoqs = n.paytoqs
var prox, noprox;
if (process.env.http_proxy) { prox = process.env.http_proxy; }
@@ -196,20 +191,26 @@ in your Node-RED user directory (${RED.settings.userDir}).
}
}
var method = nodeMethod.toUpperCase() || "GET";
let method = nodeMethod.toUpperCase() || "GET";
if (msg.method && n.method && (n.method !== "use")) { // warn if override option not set
node.warn(RED._("common.errors.nooverride"));
}
if (msg.method && n.method && (n.method === "use")) {
method = msg.method.toUpperCase(); // use the msg parameter
method = msg.method.toUpperCase(); // use the msg parameter
}
/** @type {boolean|'query'|'body'|'setby'} */
let payloadHandling = node.paytoqs
if (msg.payloadHandling && payloadHandling && (payloadHandling !== "setby")) { // warn if override option not set
node.warn(RED._("common.errors.nooverride"));
}
if (msg.payloadHandling && payloadHandling && (payloadHandling === "setby")) {
payloadHandling = msg.payloadHandling // use the msg parameter
}
if (payloadHandling === true) { payloadHandling = "query" }
// var isHttps = (/^https/i.test(url));
/** @type {import('got').Options} */
var opts = {};
// set defaultport, else when using HttpsProxyAgent, it's defaultPort of 443 will be used :(.
// Had to remove this to get http->https redirect to work
// opts.defaultPort = isHttps?443:80;
opts.timeout = node.reqTimeout;
opts.throwHttpErrors = false;
// TODO: add UI option to auto decompress. Setting to false for 1.x compatibility
@@ -435,10 +436,6 @@ in your Node-RED user directory (${RED.settings.userDir}).
formData.append(opt, val);
} else if (typeof val === 'object' && val.hasOwnProperty('value')) {
formData.append(opt,val.value,val.options || {});
} else if (Array.isArray(val)) {
for (var i=0; i<val.length; i++) {
formData.append(opt, val[i])
}
} else {
formData.append(opt,JSON.stringify(val));
}
@@ -476,7 +473,7 @@ in your Node-RED user directory (${RED.settings.userDir}).
}
if (method == 'GET' && typeof msg.payload !== "undefined" && paytoqs) {
if (method == "GET" && typeof msg.payload !== "undefined" && payloadHandling === "query") {
if (typeof msg.payload === "object") {
try {
if (url.indexOf("?") !== -1) {
@@ -485,18 +482,16 @@ in your Node-RED user directory (${RED.settings.userDir}).
url += "?" + querystring.stringify(msg.payload);
}
} catch(err) {
node.error(RED._("httpin.errors.invalid-payload"),msg);
nodeDone();
return;
}
} else {
node.error(RED._("httpin.errors.invalid-payload"),msg);
nodeDone();
return;
}
} else if ( method == "GET" && typeof msg.payload !== "undefined" && paytobody) {
} else if ( method == "GET" && typeof msg.payload !== "undefined" && payloadHandling === "body") {
opts.allowGetBody = true;
if (typeof msg.payload === "object") {
opts.body = JSON.stringify(msg.payload);

View File

@@ -135,10 +135,7 @@ module.exports = function(RED) {
ou += node.sep;
}
else {
var tt = template[t];
if (template[t].indexOf('"') >=0 ) { tt = "'"+tt+"'"; }
else { tt = '"'+tt+'"'; }
var p = RED.util.getMessageProperty(msg,'payload["'+s+'"]['+tt+']');
var p = RED.util.getMessageProperty(msg,"payload["+s+"]['"+template[t]+"']");
/* istanbul ignore else */
if (p === undefined) { p = ""; }
// fix to honour include null values flag

View File

@@ -251,9 +251,7 @@ module.exports = function(RED) {
}
else {
node.buffer = buff.slice(p,buff.length);
if (node.buffer.length > 0) {
node.pendingDones.push(done);
}
node.pendingDones.push(done);
}
if (node.buffer.length == 0) {
done();

0
packages/node_modules/@node-red/nodes/core/storage/10-file.html vendored Normal file → Executable file
View File

View File

@@ -117,9 +117,7 @@ module.exports = function(RED) {
}
if (typeof data === "boolean") { data = data.toString(); }
if (typeof data === "number") { data = data.toString(); }
var aflg = true;
if (msg.hasOwnProperty("parts") && msg.parts.type === "string" && (msg.parts.count === msg.parts.index + 1)) { aflg = false; }
if ((node.appendNewline) && (!Buffer.isBuffer(data)) && aflg) { data += os.EOL; }
if ((node.appendNewline) && (!Buffer.isBuffer(data))) { data += os.EOL; }
var buf;
if (node.encoding === "setbymsg") {
buf = encode(data, msg.encoding || "none");
@@ -316,6 +314,7 @@ module.exports = function(RED) {
});
filename = filename || "";
var fullFilename = filename;
var filePath = "";
if (filename && RED.settings.fileWorkingDirectory && !path.isAbsolute(filename)) {
fullFilename = path.resolve(path.join(RED.settings.fileWorkingDirectory,filename));
}

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

4
packages/node_modules/@node-red/nodes/locales/de/messages.json vendored Normal file → Executable file
View File

@@ -449,9 +449,11 @@
"headers": "Kopfzeilen",
"other": "andere",
"paytoqs": {
"label": "Payload (GET)",
"ignore": "Ignorieren",
"query": "Anfügen an query-string-Parameter",
"body": "Senden als request-body"
"body": "Senden als request-body",
"setby": "Durch msg.payloadHandling festgelegt"
},
"utf8String": "UTF-8-String",
"binaryBuffer": "Binärer Buffer",

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

@@ -18,5 +18,5 @@
<p>A node you can use to add comments to your flows.</p>
<h3>Details</h3>
<p>The edit panel will accept Markdown syntax. The text will be rendered into
the information side panel.</p>
this information side panel.</p>
</script>

View File

@@ -119,10 +119,7 @@
}
},
"complete": {
"completeNodes": "complete: __number__",
"errors": {
"scopeUndefined": "scope undefined"
}
"completeNodes": "complete: __number__"
},
"debug": {
"output": "Output",
@@ -184,9 +181,8 @@
"staticLinkCall": "Fixed target",
"dynamicLinkCall": "Dynamic target (msg.target)",
"dynamicLinkLabel": "Dynamic",
"errors": {
"missingReturn": "Missing return node information",
"linkUndefined": "link undefined"
"error": {
"missingReturn": "Missing return node information"
}
},
"tls": {
@@ -513,9 +509,11 @@
"headers": "Headers",
"other": "other",
"paytoqs": {
"label": "Payload (GET)",
"ignore": "Ignore",
"query": "Append to query-string parameters",
"body": "Send as request body"
"body": "Send as request body",
"setby": "- set by msg.payloadHandling -"
},
"utf8String": "UTF8 string",
"binaryBuffer": "binary buffer",

View File

@@ -30,6 +30,10 @@
<dd>If set, can be used to send cookies with the request.</dd>
<dt class="optional">payload</dt>
<dd>Sent as the body of the request.</dd>
<dt class="optional">payloadHandling <span class="property-type">string</span></dt>
<dd>Only valid with GET requests. If set to <b>"- use msg.payloadHandling -"</b> in the node configuration, this property
indicates how the <code>payload</code> will be sent. <code>msg.payloadHandling</code> should contain either
<code>"query"</code> or <code>"body"</code> otherwise the payload will not be sent with the GET request</dd>
<dt class="optional">rejectUnauthorized</dt>
<dd>If set to <code>false</code>, allows requests to be made to https sites that use
self signed certificates.</dd>

View File

@@ -119,10 +119,7 @@
}
},
"complete": {
"completeNodes": "complete: __number__",
"errors": {
"scopeUndefined": "スコープが未定義"
}
"completeNodes": "complete: __number__"
},
"debug": {
"output": "対象",
@@ -184,9 +181,8 @@
"staticLinkCall": "対象を固定で指定",
"dynamicLinkCall": "対象を動的に指定 (msg.target)",
"dynamicLinkLabel": "動的",
"errors": {
"missingReturn": "返却するノードの情報が存在しません",
"linkUndefined": "リンクが未定義"
"error": {
"missingReturn": "返却するノードの情報が存在しません"
}
},
"tls": {
@@ -513,9 +509,11 @@
"headers": "ヘッダ",
"other": "その他",
"paytoqs": {
"label": "ペイロード (GET)",
"ignore": "無視",
"query": "クエリパラメータに追加",
"body": "リクエストボディとして送信"
"body": "リクエストボディとして送信",
"setby": "- msg.payloadHandlingに定義 -"
},
"utf8String": "UTF8文字列",
"binaryBuffer": "バイナリバッファ",

8
packages/node_modules/@node-red/nodes/locales/ko/messages.json vendored Normal file → Executable file
View File

@@ -387,7 +387,13 @@
"status": "상태코드",
"headers": "헤더",
"other": "그 외",
"paytoqs" : "msg.payload를 쿼리 파라미터에 추가",
"paytoqs": {
"label": "페이로드(GET)",
"ignore": "무시",
"query": "msg.payload를 쿼리 파라미터에 추가",
"body": "본문에 msg.payload 추가",
"setby": "- msg.payloadHandling에 의해 설정됨 -"
},
"utf8String": "UTF8문자열",
"binaryBuffer": "바이너리 버퍼",
"jsonObject": "JSON오브젝트",

4
packages/node_modules/@node-red/nodes/locales/ru/messages.json vendored Normal file → Executable file
View File

@@ -411,9 +411,11 @@
"headers": "Заголовки",
"other": "другое",
"paytoqs": {
"label": "Данные (GET)",
"ignore": "Игнорировать",
"query": "Добавлять к параметрам строки запроса",
"body": "Отправлять как тело запроса"
"body": "Отправлять как тело запроса",
"setby": "- устанавливается через msg.payloadHandling -"
},
"utf8String": "Строка UTF8",
"binaryBuffer": "двоичный буфер",

View File

@@ -407,7 +407,13 @@
"status": "状态码",
"headers": "头",
"other": "其他",
"paytoqs": "将msg.payload附加为查询字符串参数",
"paytoqs": {
"label": "有效负载(仅限 GET",
"ignore": "漠视",
"query": "将msg.payload附加为查询字符串参数",
"body": "在请求正文中发送负载",
"setby": "- 用 msg.payloadHandling 设定 -"
},
"utf8String": "UTF8格式的字符串",
"binaryBuffer": "二进制buffer",
"jsonObject": "解析的JSON对象",

View File

@@ -411,7 +411,13 @@
"status": "狀態碼",
"headers": "Header",
"other": "其他",
"paytoqs": "將msg.payload附加為查詢字符串參數",
"paytoqs": {
"label": "有效負載(僅限 GET",
"ignore": "漠視",
"query": "將msg.payload附加為查詢字符串參數",
"body": "在請求正文中發送負載",
"setby": "- 用 msg.payloadHandling 設定 -"
},
"utf8String": "UTF8格式的字符串",
"binaryBuffer": "二進制buffer",
"jsonObject": "解析的JSON對象",

View File

@@ -43,40 +43,37 @@ function load(disableNodePathScan) {
return loadModuleFiles(modules);
}
function splitPath(p) {
return path.posix.normalize((p || '').replace(/\\/g, path.sep)).split(path.sep)
}
function loadModuleTypeFiles(module, type) {
const things = module[type];
let first = true;
const promises = [];
for (let thingName in things) {
var first = true;
var promises = [];
for (var thingName in things) {
/* istanbul ignore else */
if (things.hasOwnProperty(thingName)) {
if (module.name != "node-red" && first) {
// Check the module directory exists
first = false;
let moduleFn = module.path
const fn = things[thingName].file
const parts = splitPath(fn)
const nmi = parts.indexOf('node_modules')
if(nmi > -1) {
moduleFn = parts.slice(0,nmi+2).join(path.sep);
}
if (!moduleFn) {
// shortcut - skip calling statSync on empty string
break; // Module not found, don't attempt to load its nodes
var fn = things[thingName].file;
var parts = fn.split("/");
var i = parts.length-1;
for (;i>=0;i--) {
if (parts[i] == "node_modules") {
break;
}
}
var moduleFn = parts.slice(0,i+2).join("/");
try {
const stat = fs.statSync(moduleFn);
var stat = fs.statSync(moduleFn);
} catch(err) {
break; // Module not found, don't attempt to load its nodes
// Module not found, don't attempt to load its nodes
break;
}
}
try {
let promise;
var promise;
if (type === "nodes") {
promise = loadNodeConfig(things[thingName]);
} else if (type === "plugins") {
@@ -85,7 +82,8 @@ function loadModuleTypeFiles(module, type) {
promises.push(
promise.then(
(function() {
const n = thingName;
var m = module.name;
var n = thingName;
return function(nodeSet) {
things[n] = nodeSet;
return nodeSet;
@@ -95,6 +93,7 @@ function loadModuleTypeFiles(module, type) {
);
} catch(err) {
console.log(err)
//
}
}
}
@@ -126,24 +125,38 @@ function loadModuleFiles(modules) {
}
var pluginList;
var nodeList;
return Promise.all(pluginPromises).then(function(results) {
pluginList = results.filter(r => !!r);
return Promise.all(nodePromises)
// Initial plugin load has happened. Ensure modules that provide
// plugins are in the registry now.
for (var module in modules) {
if (modules.hasOwnProperty(module)) {
if (modules[module].plugins && Object.keys(modules[module].plugins).length > 0) {
// Add the modules for plugins
if (!modules[module].err) {
registry.addModule(modules[module]);
}
}
}
}
return loadNodeSetList(pluginList);
}).then(function() {
return Promise.all(nodePromises);
}).then(function(results) {
nodeList = results.filter(r => !!r);
// Initial node load has happened. Ensure remaining modules are in the registry
for (var module in modules) {
if (modules.hasOwnProperty(module)) {
if (!modules[module].err) {
registry.addModule(modules[module]);
if (!modules[module].plugins || Object.keys(modules[module].plugins).length === 0) {
if (!modules[module].err) {
registry.addModule(modules[module]);
}
}
}
}
}).then(function() {
return loadNodeSetList(pluginList);
}).then(function() {
return loadNodeSetList(nodeList);
})
});
}
async function loadPluginTemplate(plugin) {

View File

@@ -106,8 +106,8 @@ function getLocalNodeFiles(dir, skipValidNodeRedModules) {
// when loading local files, if the path is a valid node-red module
// dont include it (will be picked up in scanTreeForNodesModules)
if(skipValidNodeRedModules && files.indexOf("package.json") >= 0) {
const packageDetails = getPackageDetails(dir)
if(packageDetails.isNodeRedModule) {
const package = getPackageDetails(dir)
if(package.isNodeRedModule) {
return {files: [], icons: []};
}
}
@@ -135,17 +135,17 @@ function getLocalNodeFiles(dir, skipValidNodeRedModules) {
return {files: result, icons: icons}
}
function scanDirForNodesModules(dir,moduleName,packageDetails) {
function scanDirForNodesModules(dir,moduleName,package) {
let results = [];
let scopeName;
let files
try {
let isNodeRedModule = false
if(packageDetails) {
dir = path.join(packageDetails.moduleDir,'..')
files = [path.basename(packageDetails.moduleDir)]
moduleName = (packageDetails.package ? packageDetails.package.name : null) || moduleName
isNodeRedModule = packageDetails.isNodeRedModule
if(package) {
dir = path.join(package.moduleDir,'..')
files = [path.basename(package.moduleDir)]
moduleName = (package.package ? package.package.name : null) || moduleName
isNodeRedModule = package.isNodeRedModule
} else {
files = fs.readdirSync(dir);
if (moduleName) {
@@ -156,16 +156,6 @@ function scanDirForNodesModules(dir,moduleName,packageDetails) {
}
}
}
// if we have found a package.json, this IS a node_module, lets see if it is a node-red node
if (!isNodeRedModule && files.indexOf('package.json') > -1) {
packageDetails = getPackageDetails(dir) // get package details
if(packageDetails && packageDetails.isNodeRedModule) {
isNodeRedModule = true
files = ['package.json'] // shortcut the file scan
}
}
for (let i=0;i<files.length;i++) {
let fn = files[i];
if (!isNodeRedModule && /^@/.test(fn)) {
@@ -179,8 +169,8 @@ function scanDirForNodesModules(dir,moduleName,packageDetails) {
} else {
if ((isNodeRedModule || (!moduleName || fn == moduleName)) && (isIncluded(fn) && !isExcluded(fn))) {
try {
const moduleDir = isNodeRedModule ? packageDetails.moduleDir : path.join(dir,fn);
const pkg = packageDetails || getPackageDetails(moduleDir)
const moduleDir = isNodeRedModule ? package.moduleDir : path.join(dir,fn);
const pkg = package || getPackageDetails(moduleDir)
if(pkg.error) {
throw pkg.error
}

View File

@@ -185,17 +185,10 @@ function loadNodeConfigs() {
function addModule(module) {
moduleNodes[module.name] = [];
moduleConfigs[module.name] = module;
for (const setName in module.nodes) {
// console.log("registry.js.addModule",module.name,"user?",module.user,"usedBy",module.usedBy,"dependencies",module.dependencies)
for (var setName in module.nodes) {
if (module.nodes.hasOwnProperty(setName)) {
const set = module.nodes[setName];
if (!set.types) {
const err = new Error("Set has no types")
err.code = "set_has_no_types"
err.details = {
...set
}
set.err = err
}
var set = module.nodes[setName];
moduleNodes[module.name].push(set.name);
nodeList.push(set.id);
if (!set.err) {

View File

@@ -818,16 +818,6 @@ function handlePreRoute(flow, sendEvent, reportError) {
})
}
function deliverMessageToDestination(sendEvent) {
if (sendEvent?.destination?.node) {
try {
sendEvent.destination.node.receive(sendEvent.msg);
} catch(err) {
Log.error(`Error delivering message to node:${sendEvent.destination.node._path} [${sendEvent.destination.node.type}]`)
Log.error(err.stack)
}
}
}
function handlePreDeliver(flow,sendEvent, reportError) {
// preDeliver - the local router has identified the node it is going to send to. At this point, the message has been cloned if needed.
hooks.trigger("preDeliver",sendEvent,(err) => {
@@ -837,10 +827,15 @@ function handlePreDeliver(flow,sendEvent, reportError) {
} else if (err !== false) {
if (asyncMessageDelivery) {
setImmediate(function() {
deliverMessageToDestination(sendEvent)
if (sendEvent.destination.node) {
sendEvent.destination.node.receive(sendEvent.msg);
}
})
} else {
deliverMessageToDestination(sendEvent)
if (sendEvent.destination.node) {
sendEvent.destination.node.receive(sendEvent.msg);
}
}
// postDeliver - the message has been dispatched to be delivered asynchronously (unless the sync delivery flag is set, in which case it would be continue as synchronous delivery)
hooks.trigger("postDeliver", sendEvent, function(err) {

View File

@@ -641,7 +641,6 @@ function getFlow(id) {
if (node.type === 'link out') {
delete node.wires;
}
delete node.credentials;
return node;
})
}
@@ -649,10 +648,7 @@ function getFlow(id) {
if (flow.configs) {
var configIds = Object.keys(flow.configs);
result.configs = configIds.map(function(configId) {
const node = clone(flow.configs[configId]);
delete node.credentials;
return node
return clone(flow.configs[configId]);
})
if (result.configs.length === 0) {
delete result.configs;
@@ -664,16 +660,12 @@ function getFlow(id) {
var subflow = clone(flow.subflows[subflowId]);
var nodeIds = Object.keys(subflow.nodes);
subflow.nodes = nodeIds.map(function(id) {
const node = clone(subflow.nodes[id])
delete node.credentials
return node
return subflow.nodes[id];
});
if (subflow.configs) {
var configIds = Object.keys(subflow.configs);
subflow.configs = configIds.map(function(id) {
const node = clone(subflow.configs[id])
delete node.credentials
return node
return subflow.configs[id];
})
}
delete subflow.instances;

View File

@@ -161,8 +161,6 @@ function start() {
for (i=0;i<nodeErrors.length;i+=1) {
if (nodeErrors[i].err.code === "type_already_registered") {
log.warn("["+nodeErrors[i].id+"] "+log._("server.type-already-registered",{type:nodeErrors[i].err.details.type,module: nodeErrors[i].err.details.moduleA}));
} else if (nodeErrors[i].err.code === "set_has_no_types") {
log.warn("["+nodeErrors[i].id+"] "+log._("server.set-has-no-types", nodeErrors[i].err.details));
} else {
log.warn("["+nodeErrors[i].id+"] "+nodeErrors[i].err);
}

View File

@@ -373,11 +373,6 @@ Node.prototype.send = function(msg) {
if (msg === null || typeof msg === "undefined") {
return;
} else if (!util.isArray(msg)) {
// A single message has been passed in
if (typeof msg !== 'object') {
this.error(Log._("nodes.flow.non-message-returned", { type: typeof msg }));
return
}
if (this._wire) {
// A single message and a single wire on output 0
// TODO: pre-load flows.get calls - cannot do in constructor
@@ -430,31 +425,27 @@ Node.prototype.send = function(msg) {
for (k = 0; k < msgs.length; k++) {
var m = msgs[k];
if (m !== null && m !== undefined) {
if (typeof m !== 'object') {
this.error(Log._("nodes.flow.non-message-returned", { type: typeof m }));
} else {
if (!m._msgid) {
hasMissingIds = true;
}
/* istanbul ignore else */
if (!sentMessageId) {
sentMessageId = m._msgid;
}
sendEvents.push({
msg: m,
source: {
id: this.id,
node: this,
port: i
},
destination: {
id: wires[j],
node: undefined
},
cloneMessage: msgSent
});
msgSent = true;
if (!m._msgid) {
hasMissingIds = true;
}
/* istanbul ignore else */
if (!sentMessageId) {
sentMessageId = m._msgid;
}
sendEvents.push({
msg: m,
source: {
id: this.id,
node: this,
port: i
},
destination: {
id: wires[j],
node: undefined
},
cloneMessage: msgSent
});
msgSent = true;
}
}
}

View File

@@ -18,7 +18,7 @@ var i18n = require("@node-red/util").i18n;
module.exports = {
"package.json": function(project) {
var packageDetails = {
var package = {
"name": project.name,
"description": project.summary||i18n._("storage.localfilesystem.projects.summary"),
"version": "0.0.1",
@@ -30,11 +30,11 @@ module.exports = {
};
if (project.files) {
if (project.files.flow) {
packageDetails['node-red'].settings.flowFile = project.files.flow;
packageDetails['node-red'].settings.credentialsFile = project.files.credentials;
package['node-red'].settings.flowFile = project.files.flow;
package['node-red'].settings.credentialsFile = project.files.credentials;
}
}
return JSON.stringify(packageDetails,"",4);
return JSON.stringify(package,"",4);
},
"README.md": function(project) {
var content = project.name+"\n"+("=".repeat(project.name.length))+"\n\n";

View File

@@ -71,8 +71,6 @@ function runGitCommand(args,cwd,env,emit) {
err.code = "git_missing_user";
} else if (/name consists only of disallowed characters/i.test(stderr)) {
err.code = "git_missing_user";
} else if (/nothing (add )?to commit/i.test(stdout)) {
return stdout;
}
throw err;
})
@@ -108,7 +106,7 @@ function runGitCommandWithSSHCommand(args,cwd,auth,emit) {
commandEnv.GIT_SSH = path.join(__dirname,"node-red-ssh.sh");
commandEnv.NODE_RED_KEY_FILE=auth.key_path;
// GIT_SSH_COMMAND - added in git 2.3.0
commandEnv.GIT_SSH_COMMAND = "ssh -i \"" + auth.key_path + "\" -F /dev/null";
commandEnv.GIT_SSH_COMMAND = "ssh -i " + auth.key_path + " -F /dev/null";
// console.log('commandEnv:', commandEnv);
return runGitCommand(args,cwd,commandEnv,emit).then( result => {
rs.close();
@@ -421,10 +419,7 @@ module.exports = {
});
},
initRepo: function(cwd) {
var args = ["init", "--initial-branch", "main"];
return runGitCommand(args, cwd).catch(function () {
return runGitCommand(["init"], cwd);
});
return runGitCommand(["init"],cwd);
},
setUpstream: function(cwd,remoteBranch) {
var args = ["branch","--set-upstream-to",remoteBranch];

0
packages/node_modules/@node-red/runtime/locales/de/runtime.json vendored Normal file → Executable file
View File

View File

@@ -20,7 +20,6 @@
"errors-help": "Run with -v for details",
"missing-modules": "Missing node modules:",
"node-version-mismatch": "Node module cannot be loaded on this version. Requires: __version__ ",
"set-has-no-types": "Set does not have any types. name: '__name__', module: '__module__', file: '__file__'",
"type-already-registered": "'__type__' already registered by module __module__",
"removing-modules": "Removing modules from config",
"added-types": "Added node types:",
@@ -135,8 +134,7 @@
"flow": {
"unknown-type": "Unknown type: __type__",
"missing-types": "missing types",
"error-loop": "Message exceeded maximum number of catches",
"non-message-returned": "Node tried to send a message of type __type__"
"error-loop": "Message exceeded maximum number of catches"
},
"index": {
"unrecognised-id": "Unrecognised id: __id__",

View File

@@ -20,7 +20,6 @@
"errors-help": "詳細は -v を指定して実行してください",
"missing-modules": "不足しているノードモジュール:",
"node-version-mismatch": "ノードモジュールはこのバージョンではロードできません。必要なバージョン: __version__ ",
"set-has-no-types": "セットに型がありません。 名前: '__name__', モジュール: '__module__', ファイル: '__file__'",
"type-already-registered": "'__type__' はモジュール __module__ で登録済みです",
"removing-modules": "設定からモジュールを削除します",
"added-types": "追加したノード:",
@@ -135,8 +134,7 @@
"flow": {
"unknown-type": "不明なノード: __type__",
"missing-types": "欠落したノード",
"error-loop": "メッセージの例外補足回数が最大値を超えました",
"non-message-returned": "ノードが __type__ 型のメッセージの送信を試みました"
"error-loop": "メッセージの例外補足回数が最大値を超えました"
},
"index": {
"unrecognised-id": "不明なID: __id__",

0
packages/node_modules/@node-red/runtime/locales/ko/runtime.json vendored Normal file → Executable file
View File

View File

@@ -458,7 +458,7 @@ httpsPromise.then(function(startupHttps) {
RED.start().then(function() {
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
server.on('error', function(err) {
if (err.code === "EADDRINUSE") {
if (err.errno === "EADDRINUSE") {
RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()}));
RED.log.error(RED.log._("server.port-in-use"));
} else {

View File

@@ -181,7 +181,7 @@ module.exports = {
/** Some nodes, such as HTTP In, can be used to listen for incoming http requests.
* By default, these are served relative to '/'. The following property
* can be used to specify a different root path. If set to false, this is
* can be used to specifiy a different root path. If set to false, this is
* disabled.
*/
//httpNodeRoot: '/red-nodes',
@@ -219,17 +219,17 @@ module.exports = {
/** When httpAdminRoot is used to move the UI to a different root path, the
* following property can be used to identify a directory of static content
* that should be served at http://localhost:1880/.
* When httpStaticRoot is set differently to httpAdminRoot, there is no need
* When httpStaticRoot is set differently to httpAdminRoot, there is no need
* to move httpAdminRoot
*/
//httpStatic: '/home/nol/node-red-static/', //single static source
/* OR multiple static sources can be created using an array of objects... */
//httpStatic: [
// {path: '/home/nol/pics/', root: "/img/"},
// {path: '/home/nol/reports/', root: "/doc/"},
// {path: '/home/nol/pics/', root: "/img/"},
// {path: '/home/nol/reports/', root: "/doc/"},
//],
/**
/**
* All static routes will be appended to httpStaticRoot
* e.g. if httpStatic = "/home/nol/docs" and httpStaticRoot = "/static/"
* then "/home/nol/docs" will be served at "/static/"
@@ -256,11 +256,11 @@ module.exports = {
*/
// lang: "de",
/** Configure diagnostics options
/** Configure diagnostics options
* - enabled: When `enabled` is `true` (or unset), diagnostics data will
* be available at http://localhost:1880/diagnostics
* - ui: When `ui` is `true` (or unset), the action `show-system-info` will
* be available to logged in users of node-red editor
* be available at http://localhost:1880/diagnostics
* - ui: When `ui` is `true` (or unset), the action `show-system-info` will
* be available to logged in users of node-red editor
*/
diagnostics: {
/** enable or disable diagnostics endpoint. Must be set to `false` to disable */
@@ -268,10 +268,10 @@ module.exports = {
/** enable or disable diagnostics display in the node-red editor. Must be set to `false` to disable */
ui: true,
},
/** Configure runtimeState options
* - enabled: When `enabled` is `true` flows runtime can be Started/Stopped
* by POSTing to available at http://localhost:1880/flows/state
* - ui: When `ui` is `true`, the action `core:start-flows` and
/** Configure runtimeState options
* - enabled: When `enabled` is `true` flows runtime can be Started/Stoped
* by POSTing to available at http://localhost:1880/flows/state
* - ui: When `ui` is `true`, the action `core:start-flows` and
* `core:stop-flows` will be available to logged in users of node-red editor
* Also, the deploy menu (when set to default) will show a stop or start button
*/
@@ -416,7 +416,7 @@ module.exports = {
*/
// theme: "vs",
/** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc.
* for the full list, see https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneEditorConstructionOptions.html
* for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneEditorConstructionOptions.html
*/
//fontSize: 14,
//fontFamily: "Cascadia Code, Fira Code, Consolas, 'Courier New', monospace",
@@ -519,7 +519,7 @@ module.exports = {
*/
//tlsConfigDisableLocalFiles: true,
/** The following property can be used to verify WebSocket connection attempts.
/** The following property can be used to verify websocket connection attempts.
* This allows, for example, the HTTP request headers to be checked to ensure
* they include valid authentication information.
*/

View File

@@ -294,6 +294,19 @@ describe('HTTP Request Node', function() {
url: req.originalUrl
});
})
testApp.get('/getBodyParams', function(req,res) {
// Either body-parser or express is discarding the body OR
// GOT never sent a body. (there is nothing in params/query/body)
// Oddly, if we set options.json (instead of options.body) in the GOT
// request, then req.body will have the values!
//I suspect the GOT lib *is* sending body on a GET request since an
// error is thrown if we try to set options.body on a GET request without
// setting options.allowGetBody to true.
res.json({
// body:JSON.parse(req.body), //req.body is empty!
url: req.originalUrl
});
})
testApp.get('/returnError/:code', function(req,res) {
res.status(parseInt(req.params.code)).json({gotError:req.params.code});
})
@@ -1117,6 +1130,89 @@ describe('HTTP Request Node', function() {
});
});
it('should allow the payload to be sent in the body for a GET request', function(done) {
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",paytoqs:"body",ret:"obj",url:getTestURL('/getBodyParams')},
{id:"n2", type:"helper"}];
helper.load(httpRequestNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
const payload = {a:"one",b:true,c:3}
n2.on("input", function(msg) {
try {
// Either Express does not deliver the body of a GET request OR GOT doesn't send it!
// That means we cannot test this! Oddly, if the HTTP-Req node sets options.json instead
// of options.body, then the body is delivered.
// msg.should.have.property('payload',{
// body:payload,
// url: '/getBodyParams'
// });
msg.should.have.property('payload').and.be.an.Object()
msg.payload.should.have.property('url', '/getBodyParams')
msg.should.have.property('statusCode',200);
msg.should.have.property('headers');
done();
} catch(err) {
done(err);
}
});
n1.receive({payload:payload});
});
});
it('should allow the message to specify that the payload be append to querystring for a GET request', function(done) {
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",paytoqs:"setby",ret:"obj",url:getTestURL('/getQueryParams')},
{id:"n2", type:"helper"}];
helper.load(httpRequestNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
try {
msg.should.have.property('payload',{
query:{a:'1',b:'2',c:'3'},
url: '/getQueryParams?a=1&b=2&c=3'
});
msg.should.have.property('statusCode',200);
msg.should.have.property('headers');
done();
} catch(err) {
done(err);
}
});
n1.receive({payload:{a:1,b:2,c:3},method:"get",payloadHandling:'query'});
});
});
it('should allow the message to specify that the payload be sent in the body for a GET request', function(done) {
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",paytoqs:"setby",ret:"obj",url:getTestURL('/getBodyParams')},
{id:"n2", type:"helper"}];
helper.load(httpRequestNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
const payload = {a:"one",b:true,c:3}
n2.on("input", function(msg) {
try {
// Either Express does not deliver the body of a GET request OR GOT doesn't send it!
// That means we cannot test this! Oddly, if the HTTP-Req node sets options.json instead
// of options.body, then the body is delivered.
// msg.should.have.property('payload',{
// payload: payload,
// url: '/getBodyParams'
// });
msg.should.have.property('payload').and.be.an.Object()
msg.payload.should.have.property('url', '/getBodyParams')
msg.should.have.property('statusCode',200);
msg.should.have.property('headers');
done();
} catch(err) {
done(err);
}
});
n1.receive({payload:payload,method:"get",payloadHandling:'body'});
});
});
it('should send a msg for non-2xx response status - 400', function(done) {
var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/returnError/400')},
{id:"n2", type:"helper"}];
@@ -2334,38 +2430,4 @@ describe('HTTP Request Node', function() {
});
}
});
describe('multipart form posts', function() {
it('should send arrays as multiple entries', function (done) {
const flow = [
{
id: 'n1', type: 'http request', wires: [['n2']], method: 'POST', ret: 'obj', url: getTestURL('/file-upload'), headers: [
]
},
{ id: "n2", type: "helper" }
];
helper.load(httpRequestNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on('input', function(msg){
try {
msg.payload.body.should.have.property('foo')
msg.payload.body.list.should.deepEqual(['a','b','c'])
done()
} catch (e) {
done(e)
}
});
n1.receive({
headers: {
'content-type': 'multipart/form-data'
},
payload: {
foo: 'bar',
list: [ 'a', 'b', 'c' ]
}
});
})
});
})
});

View File

@@ -766,33 +766,6 @@ describe('CSV node', function() {
});
});
it('should handle a template with quotes in the property names', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"", hdrout:"all", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
try {
msg.should.have.property('payload', 'a"a,b\'b\nA1,B1\nA2,B2\n');
done();
}
catch(e) { done(e); }
});
var testJson = [
{
"a\"a": "A1",
"b'b": "B1"
},
{
"a\"a": "A2",
"b'b": "B2"
}
]
n1.emit("input", {payload:testJson});
});
});
it('should convert an array of objects to a multi-line csv', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,d,c,b", wires:[["n2"]] },
{id:"n2", type:"helper"} ];

View File

@@ -194,55 +194,6 @@ describe('file Nodes', function() {
});
});
it('should append to a file and add newline, except last line of multipart input', function(done) {
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":true, "overwriteFile":false, wires: [["helperNode1"]]},
{id:"helperNode1", type:"helper"}];
try {
fs.unlinkSync(fileToTest);
} catch(err) {
}
helper.load(fileNode, flow, function() {
var n1 = helper.getNode("fileNode1");
var n2 = helper.getNode("helperNode1");
var count = 0;
//var data = ["Line1", "Line2"];
n2.on("input", function (msg) {
try {
msg.should.have.property("payload");
//data.should.containDeep([msg.payload]);
if (count === 3) {
var f = fs.readFileSync(fileToTest).toString();
if (os.type() !== "Windows_NT") {
f.should.have.length(23);
f.should.equal("Line1\nLine2\nLine3\nLine4");
}
else {
f.should.have.length(23);
f.should.equal("Line1\r\nLine2\r\nLine3\r\nLine4");
}
done();
}
count++;
}
catch (e) {
done(e);
}
});
n1.receive({payload:"Line1",parts:{index:0,type:"string"}}); // string
setTimeout(function() {
n1.receive({payload:"Line2",parts:{index:1,type:"string"}}); // string
},30);
setTimeout(function() {
n1.receive({payload:"Line3",parts:{index:2,type:"string"}}); // string
},60);
setTimeout(function() {
n1.receive({payload:"Line4",parts:{index:3,type:"string",count:4}}); // string
},90);
});
});
it('should append to a file after it has been deleted ', function(done) {
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false, wires: [["helperNode1"]]},
{id:"helperNode1", type:"helper"}];

Some files were not shown because too many files have changed in this diff Show More