mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
25 Commits
increase-w
...
editor-cre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
347410f744 | ||
|
|
586006de4d | ||
|
|
af8ec9f02b | ||
|
|
dc6abb691e | ||
|
|
d273c38194 | ||
|
|
940a246160 | ||
|
|
6179d1eef2 | ||
|
|
9f121f4c72 | ||
|
|
4deca552fa | ||
|
|
2d066307f4 | ||
|
|
e47698bfd4 | ||
|
|
e91981207f | ||
|
|
f1fa1bbe4e | ||
|
|
5eb46c570d | ||
|
|
24178beafc | ||
|
|
e30df544db | ||
|
|
6044871438 | ||
|
|
e612bb6a38 | ||
|
|
81ea67d6da | ||
|
|
892d21fb77 | ||
|
|
95a7980ada | ||
|
|
281e9d1357 | ||
|
|
742f05f59d | ||
|
|
79db4f8aa1 | ||
|
|
f4d7b71984 |
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@@ -19,9 +19,9 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
node-version: [16, 18]
|
node-version: [16, 18]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
|
|||||||
51
CHANGELOG.md
51
CHANGELOG.md
@@ -1,5 +1,54 @@
|
|||||||
#### 3.1.0-beta.1: Beta Release
|
#### 3.1.0-beta.2: Beta Release
|
||||||
|
|
||||||
|
Editor
|
||||||
|
|
||||||
|
- NEW: Add change icon to tabs (#4068) @knolleary
|
||||||
|
- NEW: Complete overhaul of Group UX (#4079) @knolleary
|
||||||
|
- NEW: Add link to node help in node edit dialog footer (#4065) @knolleary
|
||||||
|
- NEW: Added editor feature for connecting multiple nodes to single node (#4051) @sonntam
|
||||||
|
- NEW: Increase workspace size to 8000x8000 (#4094) @knolleary
|
||||||
|
- Ensure node buttons are redrawn when flow lock state is changed (#4091) @knolleary
|
||||||
|
- Prevent loops being created with junction nodes (#4087) @knolleary
|
||||||
|
- Prevent opening locked node's edit dialog (#4069) @knolleary
|
||||||
|
- Reverse direction of tab scroll to expected direction (#4064) @knolleary
|
||||||
|
- Add cancel operation to editableList (#4077) @HiroyasuNishiyama
|
||||||
|
- Apply Mermaid diagram for project settings UI (#4054) @kazuhitoyokoi
|
||||||
|
- Add tooltip for show/hide button on info sidebar (#4050) @kazuhitoyokoi
|
||||||
|
- Fix align nodes on locked tab (#4072) @HiroyasuNishiyama
|
||||||
|
- Fix importing connected link nodes into a subflow (#4082) @knolleary
|
||||||
|
- Fix to add empty marker to empty group (#4060) @HiroyasuNishiyama
|
||||||
|
- Fix image URLs for v3.0 tour (#4053) @kazuhitoyokoi
|
||||||
|
- Show scrollbar in notification dialog only when needed (#4048) @kazuhitoyokoi
|
||||||
|
- Update-monaco-and-typings (#4089) @Steve-Mcl
|
||||||
|
- Update jquery UI (#4088) @knolleary
|
||||||
|
- Support i18n of lock/unlock buttons in flow property UI (#4049) @kazuhitoyokoi
|
||||||
|
- Translation kr (#3895) @hae-iotplatform
|
||||||
|
- Translation zhcn (!!请懂中文的帮忙review) (#3952) @cliyr
|
||||||
|
- Add French translation of nodes (#3964) @GogoVega
|
||||||
|
- Add French translation (#3962) @GogoVega
|
||||||
|
- Portuguese Brazilian (pt-BR) translation (#3804) @FabsMuller
|
||||||
|
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
|
||||||
|
- NEW: Generate stable ids for subflow instance internal nodes (#4093) @knolleary
|
||||||
|
- NEW: Change default file name to flows.json in project feature (#4073) @kazuhitoyokoi
|
||||||
|
- NEW: Deprecate synchronous access to jsonata (#4090) @knolleary
|
||||||
|
- Add Node 18 to test matrix (#4084) @knolleary
|
||||||
|
- Bump minimum nodejs version supported to match documented value (#4086) @knolleary
|
||||||
|
- Update monaco docs link in settings.js (#4075) @Steve-Mcl
|
||||||
|
- Remove duplicated messages in the message catalog (#4066) @kazuhitoyokoi
|
||||||
|
- Ensure errors in preDeliver callback are handled (#3911) @knolleary
|
||||||
|
- Fix "EADDRINUSE" error (#4046) @bggbr
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
|
||||||
|
- Link Call: Clear link-call timeouts when node is closed (#4085) @knolleary
|
||||||
|
- Join: ensure inflight status is cleared when in auto mode (#4083) @knolleary
|
||||||
|
- File Out: Fix extra newline append for multipart file write (#3915) @dceejay
|
||||||
|
- Add validators for complete and link call nodes (#4056) @kazuhitoyokoi
|
||||||
|
|
||||||
|
#### 3.1.0-beta.1: Beta Release
|
||||||
|
|
||||||
Editor
|
Editor
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "http://nodered.org",
|
"homepage": "http://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-api",
|
"name": "@node-red/editor-api",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "3.1.0-beta.1",
|
"@node-red/util": "3.1.0-beta.2",
|
||||||
"@node-red/editor-client": "3.1.0-beta.1",
|
"@node-red/editor-client": "3.1.0-beta.2",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.20.2",
|
"body-parser": "1.20.2",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-client",
|
"name": "@node-red/editor-client",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -1468,7 +1468,7 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.type !== "subflow") {
|
if (node.type !== "subflow") {
|
||||||
var convertedNode = RED.nodes.convertNode(node);
|
var convertedNode = RED.nodes.convertNode(node, { credentials: false });
|
||||||
for (var d in node._def.defaults) {
|
for (var d in node._def.defaults) {
|
||||||
if (node._def.defaults[d].type) {
|
if (node._def.defaults[d].type) {
|
||||||
var nodeList = node[d];
|
var nodeList = node[d];
|
||||||
@@ -1501,7 +1501,7 @@ RED.nodes = (function() {
|
|||||||
nns = nns.concat(createExportableNodeSet(node.nodes, exportedIds, exportedSubflows, exportedConfigNodes));
|
nns = nns.concat(createExportableNodeSet(node.nodes, exportedIds, exportedSubflows, exportedConfigNodes));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var convertedSubflow = convertSubflow(node);
|
var convertedSubflow = convertSubflow(node, { credentials: false });
|
||||||
nns.push(convertedSubflow);
|
nns.push(convertedSubflow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -731,7 +731,7 @@ RED.clipboard = (function() {
|
|||||||
nodes.unshift(parentNode);
|
nodes.unshift(parentNode);
|
||||||
nodes = RED.nodes.createExportableNodeSet(nodes);
|
nodes = RED.nodes.createExportableNodeSet(nodes);
|
||||||
} else if (type === 'full') {
|
} else if (type === 'full') {
|
||||||
nodes = RED.nodes.createCompleteNodeSet(false);
|
nodes = RED.nodes.createCompleteNodeSet({ credentials: false });
|
||||||
}
|
}
|
||||||
if (nodes !== null) {
|
if (nodes !== null) {
|
||||||
if (format === "red-ui-clipboard-dialog-export-fmt-full") {
|
if (format === "red-ui-clipboard-dialog-export-fmt-full") {
|
||||||
|
|||||||
@@ -294,7 +294,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expr.evaluate(legacyMode?{msg:parsedData}:parsedData, (err, result) => {
|
expr.evaluate(legacyMode?{msg:parsedData}:parsedData, null, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1);
|
testResultEditor.setValue(RED._("expressionEditor.errors.eval",{message:err.message}),-1);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -171,23 +171,15 @@ RED.palette = (function() {
|
|||||||
}
|
}
|
||||||
metaData += type;
|
metaData += type;
|
||||||
|
|
||||||
|
const safeType = type.replace(/'/g,"\\'");
|
||||||
|
const searchType = type.indexOf(' ') > -1 ? '"' + type + '"' : type
|
||||||
|
|
||||||
if (/^subflow:/.test(type)) {
|
if (/^subflow:/.test(type)) {
|
||||||
$('<button type="button" onclick="RED.workspaces.show(\''+type.substring(8).replace(/'/g,"\\'")+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-pencil"></i></button>').appendTo(popOverContent)
|
$('<button type="button" onclick="RED.workspaces.show(\''+type.substring(8).replace(/'/g,"\\'")+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-pencil"></i></button>').appendTo(popOverContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
const safeType = type.replace(/'/g,"\\'");
|
$('<button type="button" onclick="RED.search.show(\'type:'+searchType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-search"></i></button>').appendTo(popOverContent)
|
||||||
const wrapStr = function (str) {
|
|
||||||
if(str.indexOf(' ') >= 0) {
|
|
||||||
return '"' + str + '"'
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
$('<button type="button"; return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-search"></i></button>')
|
|
||||||
.appendTo(popOverContent)
|
|
||||||
.on('click', function() {
|
|
||||||
RED.search.show('type:' + wrapStr(safeType))
|
|
||||||
})
|
|
||||||
$('<button type="button" onclick="RED.sidebar.help.show(\''+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
$('<button type="button" onclick="RED.sidebar.help.show(\''+safeType+'\'); return false;" class="red-ui-button red-ui-button-small" style="float: right; margin-left: 5px;"><i class="fa fa-book"></i></button>').appendTo(popOverContent)
|
||||||
|
|
||||||
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
$('<p>',{style:"font-size: 0.8em"}).text(metaData).appendTo(popOverContent);
|
||||||
|
|||||||
@@ -747,14 +747,14 @@ RED.projects = (function() {
|
|||||||
var row = $('<div class="form-row"></div>').appendTo(body);
|
var row = $('<div class="form-row"></div>').appendTo(body);
|
||||||
$('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.default-files.flow-file")+'</label>').appendTo(row);
|
$('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.default-files.flow-file")+'</label>').appendTo(row);
|
||||||
var subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
var subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
||||||
var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow)||"flow.json";
|
var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow) || "flows.json";
|
||||||
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val(defaultFlowFile)
|
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val(defaultFlowFile)
|
||||||
.on("change keyup paste",validateForm)
|
.on("change keyup paste",validateForm)
|
||||||
.appendTo(subrow);
|
.appendTo(subrow);
|
||||||
$('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow);
|
$('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow);
|
||||||
$('<label class="red-ui-projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row);
|
$('<label class="red-ui-projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row);
|
||||||
|
|
||||||
var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials)||"flow_cred.json";
|
var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials) || "flows_cred.json";
|
||||||
row = $('<div class="form-row"></div>').appendTo(body);
|
row = $('<div class="form-row"></div>').appendTo(body);
|
||||||
$('<label for="red-ui-projects-dialog-screen-create-project-credfile">'+RED._("projects.default-files.credentials-file")+'</label>').appendTo(row);
|
$('<label for="red-ui-projects-dialog-screen-create-project-credfile">'+RED._("projects.default-files.credentials-file")+'</label>').appendTo(row);
|
||||||
subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
||||||
@@ -1257,7 +1257,7 @@ RED.projects = (function() {
|
|||||||
row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(container);
|
row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty"></div>').appendTo(container);
|
||||||
$('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.create.flow-file")+'</label>').appendTo(row);
|
$('<label for="red-ui-projects-dialog-screen-create-project-file">'+RED._("projects.create.flow-file")+'</label>').appendTo(row);
|
||||||
subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
subrow = $('<div style="position:relative;"></div>').appendTo(row);
|
||||||
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val("flow.json")
|
projectFlowFileInput = $('<input id="red-ui-projects-dialog-screen-create-project-file" type="text">').val("flows.json")
|
||||||
.on("change keyup paste",validateForm)
|
.on("change keyup paste",validateForm)
|
||||||
.appendTo(subrow);
|
.appendTo(subrow);
|
||||||
$('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow);
|
$('<div class="red-ui-projects-dialog-screen-input-status"></div>').appendTo(subrow);
|
||||||
|
|||||||
BIN
packages/node_modules/@node-red/editor-client/src/tours/images/node-help.png
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/tours/images/node-help.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
packages/node_modules/@node-red/editor-client/src/tours/images/tab-changes.png
vendored
Normal file
BIN
packages/node_modules/@node-red/editor-client/src/tours/images/tab-changes.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -1,15 +1,71 @@
|
|||||||
export default {
|
export default {
|
||||||
version: "3.1.0-beta.1",
|
version: "3.1.0-beta.2",
|
||||||
steps: [
|
steps: [
|
||||||
{
|
{
|
||||||
titleIcon: "fa fa-map-o",
|
titleIcon: "fa fa-map-o",
|
||||||
title: {
|
title: {
|
||||||
"en-US": "Welcome to Node-RED 3.1 Beta 1!",
|
"en-US": "Welcome to Node-RED 3.1 Beta 2!",
|
||||||
"ja": "Node-RED 3.1 ベータ1へようこそ!"
|
"ja": "Node-RED 3.1 ベータ1へようこそ!"
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
"en-US": "<p>This is the first beta release for 3.1.0 and we have a few new features to tell you about.</p>",
|
"en-US": "<p>This is the second beta release for 3.1.0 and we have a few new features to tell you about.</p>",
|
||||||
"ja": "<p>これは3.1.0の最初のベータリリースです。いくつかの新機能について説明します。</p>"
|
// "ja": "<p>これは3.1.0の最初のベータリリースです。いくつかの新機能について説明します。</p>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
"en-US": "New ways to work with groups",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
"en-US": `<p>We have changed how you interact with groups in the editor.</p>
|
||||||
|
<ul>
|
||||||
|
<li>They don't get in the way when clicking on a node</li>
|
||||||
|
<li>They can be reordered using the Moving Forwards and Move Backwards actions</li>
|
||||||
|
<li>Multiple nodes can be dragged into a group in one go</li>
|
||||||
|
<li>Holding <code>Alt</code> when dragging a node will *remove* it from its group</li>
|
||||||
|
</ul>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
"en-US": "Change notification on tabs",
|
||||||
|
},
|
||||||
|
image: 'images/tab-changes.png',
|
||||||
|
description: {
|
||||||
|
"en-US": `<p>When a tab contains undeployed changes it now shows the
|
||||||
|
same style of change icon used by nodes.</p>
|
||||||
|
<p>This will make it much easier to track down changes when you're
|
||||||
|
working across multiple flows.</p>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
"en-US": "A bigger canvas to work with",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
"en-US": `<p>The default canvas size has been increased so you can fit more
|
||||||
|
into one flow.</p>
|
||||||
|
<p>We still recommend using tools such as subflows and Link Nodes to help
|
||||||
|
keep things organised, but now you have more room to work in.</p>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
"en-US": "Finding help",
|
||||||
|
},
|
||||||
|
image: 'images/node-help.png',
|
||||||
|
description: {
|
||||||
|
"en-US": `<p>All node edit dialogs now include a link to that node's help
|
||||||
|
in the footer.</p>
|
||||||
|
<p>Clicking it will open up the Help sidebar showing the help for that node.</p>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: {
|
||||||
|
"en-US": "And lots more...",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
"en-US": `<p>Of course we have everything from 3.1.0-beta.1 as well....</p>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -117,7 +117,9 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
if (typeof data === "boolean") { data = data.toString(); }
|
if (typeof data === "boolean") { data = data.toString(); }
|
||||||
if (typeof data === "number") { data = data.toString(); }
|
if (typeof data === "number") { data = data.toString(); }
|
||||||
if ((node.appendNewline) && (!Buffer.isBuffer(data))) { data += os.EOL; }
|
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; }
|
||||||
var buf;
|
var buf;
|
||||||
if (node.encoding === "setbymsg") {
|
if (node.encoding === "setbymsg") {
|
||||||
buf = encode(data, msg.encoding || "none");
|
buf = encode(data, msg.encoding || "none");
|
||||||
@@ -314,7 +316,6 @@ module.exports = function(RED) {
|
|||||||
});
|
});
|
||||||
filename = filename || "";
|
filename = filename || "";
|
||||||
var fullFilename = filename;
|
var fullFilename = filename;
|
||||||
var filePath = "";
|
|
||||||
if (filename && RED.settings.fileWorkingDirectory && !path.isAbsolute(filename)) {
|
if (filename && RED.settings.fileWorkingDirectory && !path.isAbsolute(filename)) {
|
||||||
fullFilename = path.resolve(path.join(RED.settings.fileWorkingDirectory,filename));
|
fullFilename = path.resolve(path.join(RED.settings.fileWorkingDirectory,filename));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/nodes",
|
"name": "@node-red/nodes",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/registry",
|
"name": "@node-red/registry",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "3.1.0-beta.1",
|
"@node-red/util": "3.1.0-beta.2",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"fs-extra": "10.1.0",
|
"fs-extra": "10.1.0",
|
||||||
"semver": "7.3.8",
|
"semver": "7.3.8",
|
||||||
|
|||||||
@@ -818,6 +818,16 @@ 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) {
|
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.
|
// 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) => {
|
hooks.trigger("preDeliver",sendEvent,(err) => {
|
||||||
@@ -827,15 +837,10 @@ function handlePreDeliver(flow,sendEvent, reportError) {
|
|||||||
} else if (err !== false) {
|
} else if (err !== false) {
|
||||||
if (asyncMessageDelivery) {
|
if (asyncMessageDelivery) {
|
||||||
setImmediate(function() {
|
setImmediate(function() {
|
||||||
if (sendEvent.destination.node) {
|
deliverMessageToDestination(sendEvent)
|
||||||
sendEvent.destination.node.receive(sendEvent.msg);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (sendEvent.destination.node) {
|
deliverMessageToDestination(sendEvent)
|
||||||
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)
|
// 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) {
|
hooks.trigger("postDeliver", sendEvent, function(err) {
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ class Subflow extends Flow {
|
|||||||
*/
|
*/
|
||||||
function createNodeInSubflow(subflowInstanceId, def) {
|
function createNodeInSubflow(subflowInstanceId, def) {
|
||||||
let node = clone(def);
|
let node = clone(def);
|
||||||
let nid = redUtil.generateId();
|
let nid = `${subflowInstanceId}-${node.id}` //redUtil.generateId();
|
||||||
// console.log("Create Node In subflow",node._alias, "--->",nid, "(",node.type,")")
|
// console.log("Create Node In subflow",node._alias, "--->",nid, "(",node.type,")")
|
||||||
// node_map[node.id] = node;
|
// node_map[node.id] = node;
|
||||||
node._alias = node.id;
|
node._alias = node.id;
|
||||||
|
|||||||
@@ -589,17 +589,28 @@ function deleteContext(id,flowId) {
|
|||||||
* If flowConfig is undefined, all flow/node contexts will be removed
|
* If flowConfig is undefined, all flow/node contexts will be removed
|
||||||
**/
|
**/
|
||||||
function clean(flowConfig) {
|
function clean(flowConfig) {
|
||||||
flowConfig = flowConfig || { allNodes: {} };
|
flowConfig = flowConfig || { allNodes: {}, subflows: {} };
|
||||||
var promises = [];
|
const knownNodes = new Set(Object.keys(flowConfig.allNodes))
|
||||||
for(var plugin in stores){
|
|
||||||
if(stores.hasOwnProperty(plugin)){
|
// We need to alias all of the subflow instance contents
|
||||||
promises.push(stores[plugin].clean(Object.keys(flowConfig.allNodes)));
|
for (const subflow of Object.values(flowConfig.subflows || {})) {
|
||||||
}
|
subflow.instances.forEach(instance => {
|
||||||
|
for (const nodeId of Object.keys(subflow.nodes || {})) {
|
||||||
|
knownNodes.add(`${instance.id}-${nodeId}`)
|
||||||
|
}
|
||||||
|
for (const nodeId of Object.keys(subflow.configs || {})) {
|
||||||
|
knownNodes.add(`${instance.id}-${nodeId}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
for (var id in contexts) {
|
var promises = [];
|
||||||
if (contexts.hasOwnProperty(id) && id !== "global") {
|
for (const store of Object.values(stores)){
|
||||||
|
promises.push(store.clean(Array.from(knownNodes)));
|
||||||
|
}
|
||||||
|
for (const id of Object.keys(contexts)) {
|
||||||
|
if (id !== "global") {
|
||||||
var idParts = id.split(":");
|
var idParts = id.split(":");
|
||||||
if (!flowConfig.allNodes.hasOwnProperty(idParts[0])) {
|
if (!knownNodes.has(idParts[0])) {
|
||||||
delete contexts[id];
|
delete contexts[id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/runtime",
|
"name": "@node-red/runtime",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/registry": "3.1.0-beta.1",
|
"@node-red/registry": "3.1.0-beta.2",
|
||||||
"@node-red/util": "3.1.0-beta.1",
|
"@node-red/util": "3.1.0-beta.2",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"express": "4.18.2",
|
"express": "4.18.2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/util",
|
"name": "@node-red/util",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
10
packages/node_modules/node-red/package.json
vendored
10
packages/node_modules/node-red/package.json
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "3.1.0-beta.1",
|
"version": "3.1.0-beta.2",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "http://nodered.org",
|
"homepage": "http://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -31,10 +31,10 @@
|
|||||||
"flow"
|
"flow"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/editor-api": "3.1.0-beta.1",
|
"@node-red/editor-api": "3.1.0-beta.2",
|
||||||
"@node-red/runtime": "3.1.0-beta.1",
|
"@node-red/runtime": "3.1.0-beta.2",
|
||||||
"@node-red/util": "3.1.0-beta.1",
|
"@node-red/util": "3.1.0-beta.2",
|
||||||
"@node-red/nodes": "3.1.0-beta.1",
|
"@node-red/nodes": "3.1.0-beta.2",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"express": "4.18.2",
|
"express": "4.18.2",
|
||||||
|
|||||||
2
packages/node_modules/node-red/red.js
vendored
2
packages/node_modules/node-red/red.js
vendored
@@ -458,7 +458,7 @@ httpsPromise.then(function(startupHttps) {
|
|||||||
RED.start().then(function() {
|
RED.start().then(function() {
|
||||||
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
|
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
|
||||||
server.on('error', function(err) {
|
server.on('error', function(err) {
|
||||||
if (err.errno === "EADDRINUSE") {
|
if (err.code === "EADDRINUSE") {
|
||||||
RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()}));
|
RED.log.error(RED.log._("server.unable-to-listen", {listenpath:getListenPath()}));
|
||||||
RED.log.error(RED.log._("server.port-in-use"));
|
RED.log.error(RED.log._("server.port-in-use"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
2
packages/node_modules/node-red/settings.js
vendored
2
packages/node_modules/node-red/settings.js
vendored
@@ -416,7 +416,7 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
// theme: "vs",
|
// theme: "vs",
|
||||||
/** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc.
|
/** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc.
|
||||||
* for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneEditorConstructionOptions.html
|
* for the full list, see https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneEditorConstructionOptions.html
|
||||||
*/
|
*/
|
||||||
//fontSize: 14,
|
//fontSize: 14,
|
||||||
//fontFamily: "Cascadia Code, Fira Code, Consolas, 'Courier New', monospace",
|
//fontFamily: "Cascadia Code, Fira Code, Consolas, 'Courier New', monospace",
|
||||||
|
|||||||
@@ -194,6 +194,55 @@ 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) {
|
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"]]},
|
var flow = [{id:"fileNode1", type:"file", name: "fileNode", "filename":fileToTest, "appendNewline":false, "overwriteFile":false, wires: [["helperNode1"]]},
|
||||||
{id:"helperNode1", type:"helper"}];
|
{id:"helperNode1", type:"helper"}];
|
||||||
|
|||||||
Reference in New Issue
Block a user