Compare commits

...

49 Commits

Author SHA1 Message Date
Nick O'Leary
f7e9c109f6 Bump for 0.20.8 2019-09-06 10:28:52 +01:00
Nick O'Leary
30c3004f27 Sanitize tab name in edit dialog 2019-09-06 10:25:30 +01:00
Nick O'Leary
afaf077aca Pass httpServer to runtime even when httpAdmin disabled
Fixes #2272
2019-08-21 11:12:50 +01:00
Nick O'Leary
189bde7c9c Merge pull request #2259 from kazuhitoyokoi/master-fixtabsmenu
Remove tab menu from node property UI for subflow and configuration nodes
2019-08-09 10:26:08 +01:00
Nick O'Leary
6a4760e291 Mark workspace dirty when shift-click-drag detaches wires
Fixes #2260
2019-08-09 10:24:52 +01:00
Kazuhito Yokoi
c082bb97e0 Remove tab menu from node property UI for subflow and config nodes 2019-08-07 12:29:20 +09:00
Nick O'Leary
defa9a2270 Fix ssh-keygen error handling 2019-08-06 17:12:40 +01:00
Nick O'Leary
ffd10e656e Merge pull request #2251 from kazuhitoyokoi/master-fixsplitnode
Fix escape character handling for separator in split node
2019-08-06 16:00:58 +01:00
Nick O'Leary
59c1828078 Merge pull request #2253 from kazuhitoyokoi/master-removetooltip
Fix duplicated tooltips
2019-08-06 16:00:40 +01:00
Nick O'Leary
6164271fe8 Merge pull request #2250 from kazuhitoyokoi/master-updatetranslation4delaynode
Add Japanese translation into delay node
2019-08-06 16:00:01 +01:00
Nick O'Leary
87359937c9 Merge pull request #2256 from kazuhitoyokoi/master-fixerrorhandlingtostartserver
Use appropriate version of Node.js
2019-08-06 15:59:34 +01:00
Nick O'Leary
9b938f6515 Fix default value handling on context array access
Fixes #2252
2019-08-06 15:55:25 +01:00
Nick O'Leary
6c3913785d Add error event handler to ssh-keygen child_process
Fixes #2255
2019-08-06 15:21:57 +01:00
Nick O'Leary
542cf3147d Support displaying falsey node status values
Fixes #2246
2019-08-06 15:12:13 +01:00
Kazuhito Yokoi
fde8548166 Remove handling for unused error code 2019-08-06 19:30:05 +09:00
Kazuhito Yokoi
fe91295704 Replace node.js with Node.js 2019-08-06 19:27:46 +09:00
Kazuhito Yokoi
15b99c5749 Use appropriate the version of Node.js 2019-08-06 19:24:45 +09:00
Kazuhito Yokoi
9d66ca4a49 Fix duplicated tooltip 2019-08-05 19:03:30 +09:00
Nick O'Leary
083212cffe Merge pull request #2248 from kazuhitoyokoi/master-removeunusedvariables
Remove unused variable
2019-08-02 09:42:22 +01:00
Kazuhito Yokoi
3a6448f727 Fix splitters in split node 2019-08-02 13:56:37 +09:00
Kazuhito Yokoi
fe18df25ba Add Japanese translation to delay node 2019-08-01 20:50:35 +09:00
Kazuhito Yokoi
0ad3eceb82 Remove unused variables 2019-07-31 16:06:30 +09:00
Nick O'Leary
18c3223105 Merge pull request #2247 from kazuhitoyokoi/master-fixvariablename
Fix wrong variable name
2019-07-30 23:01:59 +01:00
Kazuhito Yokoi
b9e97792f3 Fix wrong variable name 2019-07-30 19:52:28 +09:00
Ben Hardill
5ab90b85da Limit the regex for the /nodes/ api end points
fixes #2240

It looks like the regex for the /nodes/... endpoints over matches.

I've added `^` to the start to anchor the matches to the start of the
URL.
2019-07-29 11:42:29 +01:00
Nick O'Leary
f3e1e8a2c7 Merge pull request #2244 from kazuhitoyokoi/master-fixwiring4subflownode
Fix inserting new subflow node to existing wire
2019-07-29 10:57:45 +01:00
Nick O'Leary
e41b292e54 Merge pull request #2238 from teastman/master
Handle undefined node._def in edit stack title.
2019-07-29 10:44:54 +01:00
Kazuhito Yokoi
2f5ec8b5bf Fix inserting new subflow node to existing wire between nodes 2019-07-26 17:51:49 +09:00
Tyler Eastman
14ac6446de Handle undefined node._def in edit stack title. 2019-07-22 14:25:52 -07:00
Nick O'Leary
8bb7b2e88b Ensure session expiry timeout doesn't exceed limit 2019-07-06 16:34:48 +01:00
Nick O'Leary
aab0b0b4bf Bump for 0.20.7 2019-07-05 11:12:26 +01:00
Nick O'Leary
083d6c5125 Merge pull request #2224 from natcl/patch-4
Update jsonata to 1.6.5 which should fix #2183
2019-07-05 09:29:13 +01:00
Nathanaël Lécaudé
c2167a2c5f Add jsonata bump in util 2019-07-04 18:08:44 -04:00
Nathanaël Lécaudé
1a695e0451 Update jsonata to 1.6.5 which should fix #2183 2019-07-04 17:50:55 -04:00
Nick O'Leary
f49d1ae860 Ensure the subflow stop promise is waiting for before restarting 2019-07-01 12:42:11 +01:00
Nick O'Leary
55645e3730 Properly escape node types in palette
We were only escaping the first instance of any invalid dom char
and not all of the
2019-06-28 22:39:27 +01:00
Nick O'Leary
b73f12cdba Bump for 0.20.6 2019-06-21 13:25:39 +01:00
Nick O'Leary
28fbb61e81 Bump dependencies 2019-06-21 13:25:09 +01:00
Nick O'Leary
c1104d1cd6 Revealing node position needs to account for zoom level
Fixes #2172
2019-06-21 12:53:09 +01:00
Dave Conway-Jones
e346702292 stop join tripping up if last message of buffer is blank. 2019-06-21 12:49:21 +01:00
Nick O'Leary
90887779ea Improve handling of file upload in request node
formData can only be Strings or Buffers - anything else will cause
errors. To help matters, we now look for invalid types and json-encode
them where needed.
2019-06-21 12:48:13 +01:00
Nick O'Leary
a941b1437c Handle subflow internal node wired to a non-existant node
Fixes #2202
2019-06-21 12:47:37 +01:00
Nick O'Leary
04bdcbd490 Do not save subflow env vars with blank names 2019-06-21 12:46:53 +01:00
Nick O'Leary
87a815fd6f Don't allow a link node virtual wire to connect to normal port 2019-06-21 12:45:50 +01:00
Nick O'Leary
46abd0cc42 Clear HTTP Request node authType when auth disabled
Fixes #2215
2019-06-20 22:33:38 +01:00
Nick O'Leary
e315325d91 Fix parsing of content-type header
Fixes #2216

This was broken when we switched from media-typer to content-type
modules for parsing the content-type header.

The content-type header can handle the field with parameters, but
does not do the type/sub-type parsing that media-typer does.

Our code relied on that extra bit of parsing to correctly
identify if the content should be parsed to String or kept as
a buffer.

The fix restores the use of media-typer, but using the result
of the content-type module to make sure it valid
2019-06-20 21:15:20 +01:00
Dave Conway-Jones
f3fc083330 Fix join node reset issue with merging objects
and add tests
to close #2188
2019-06-20 19:47:53 +01:00
Nick O'Leary
8486f4d43a Copy data-i18n attribute on TypedInput
Fixes #2211
2019-06-19 10:10:17 +01:00
Nick O'Leary
ccc3809daa Make 'anything else' template more explicit 2019-06-09 17:32:14 +01:00
40 changed files with 253 additions and 161 deletions

View File

@@ -28,7 +28,7 @@ To help us understand the issue, please fill-in as much of the following informa
### Please tell us about your environment: ### Please tell us about your environment:
- [ ] Node-RED version: - [ ] Node-RED version:
- [ ] node.js version: - [ ] Node.js version:
- [ ] npm version: - [ ] npm version:
- [ ] Platform/OS: - [ ] Platform/OS:
- [ ] Browser: - [ ] Browser:

View File

@@ -33,7 +33,7 @@ To help us understand the issue, please fill-in as much of the following informa
### Please tell us about your environment: ### Please tell us about your environment:
- [ ] Node-RED version: - [ ] Node-RED version:
- [ ] node.js version: - [ ] Node.js version:
- [ ] npm version: - [ ] npm version:
- [ ] Platform/OS: - [ ] Platform/OS:
- [ ] Browser: - [ ] Browser:

View File

@@ -7,8 +7,11 @@ assignees: ''
--- ---
Please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). Please DO NOT raise an issue.
You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`. We DO NOT use the issue tracker for general support or feature requests. Only bug reports should be raised here using the 'Bug report' template.
For general support, please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`.
That way the whole Node-RED user community can help, rather than rely on the core development team. That way the whole Node-RED user community can help, rather than rely on the core development team.
For feature requests, please use the Node-RED Forum](https://discourse.nodered.org). Many ideas have already been discussed there and you should search that for your request before starting a new discussion.

View File

@@ -1,3 +1,27 @@
#### 0.20.8: Maintenance Release
- Sanitize tab name in edit dialog
- Pass httpServer to runtime even when httpAdmin disabled Fixes #2272
#### 0.20.7: Maintenance Release
- Update jsonata to 1.6.5 which should fix #2183
- Ensure the subflow stop promise is waiting for before restarting
- Properly escape node types in palette
#### 0.20.6: Maintenance Release
- Revealing node position needs to account for zoom level Fixes #2172
- stop join tripping up if last message of buffer is blank.
- Improve handling of file upload in request node
- Handle subflow internal node wired to a non-existant node Fixes #2202
- Do not save subflow env vars with blank names
- Don't allow a link node virtual wire to connect to normal port
- Clear HTTP Request node authType when auth disabled Fixes #2215
- Fix parsing of content-type header Fixes #2216
- Fix join node reset issue with merging objects
- Copy data-i18n attribute on TypedInput Fixes #2211
#### 0.20.5: Maintenance Release #### 0.20.5: Maintenance Release
- Revert error handling in palette manager - Revert error handling in palette manager
@@ -658,7 +682,7 @@ Nodes
- Initial support of sequence rules for SWITCH node (#1545) - Initial support of sequence rules for SWITCH node (#1545)
- initial support of SORT node (#1500) - initial support of SORT node (#1500)
- Inject node - let once delay be editable (#1541) - Inject node - let once delay be editable (#1541)
- Introduce `nodeMaxMessageBufferLength` setting for msg sequence nodes - Introduce `nodeMessageBufferMaxLength` setting for msg sequence nodes
- Let CSV correct parts if we remove header row. - Let CSV correct parts if we remove header row.
- let default apply if msg.delay not set in override mode. (#1397) - let default apply if msg.delay not set in override mode. (#1397)
- let trigger node be reset by boolean message (#1554) - let trigger node be reset by boolean message (#1554)

View File

@@ -26,7 +26,7 @@ relevant nodes, press Ctrl-E and copy the flow data from the Export dialog.
At a minimum, please include: At a minimum, please include:
- Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly. - Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly.
- Version of node.js - what does `node -v` say? - Version of Node.js - what does `node -v` say?
## Feature requests ## Feature requests

View File

@@ -1,6 +1,6 @@
{ {
"name": "node-red", "name": "node-red",
"version": "0.20.5", "version": "0.20.8",
"description": "A visual tool for wiring the Internet of Things", "description": "A visual tool for wiring the Internet of Things",
"homepage": "http://nodered.org", "homepage": "http://nodered.org",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -31,53 +31,54 @@
"cheerio": "0.22.0", "cheerio": "0.22.0",
"clone": "2.1.2", "clone": "2.1.2",
"content-type": "1.0.4", "content-type": "1.0.4",
"cookie": "0.3.1", "cookie": "0.4.0",
"cookie-parser": "1.4.4", "cookie-parser": "1.4.4",
"cors": "2.8.5", "cors": "2.8.5",
"cron": "1.7.1", "cron": "1.7.1",
"denque": "1.4.1", "denque": "1.4.1",
"express": "4.16.4", "express": "4.17.1",
"express-session": "1.16.1", "express-session": "1.16.2",
"fs-extra": "7.0.1", "fs-extra": "8.1.0",
"fs.notify": "0.0.4", "fs.notify": "0.0.4",
"hash-sum": "1.0.2", "hash-sum": "2.0.0",
"https-proxy-agent": "2.2.1", "https-proxy-agent": "2.2.1",
"i18next": "15.1.0", "i18next": "15.1.0",
"iconv-lite": "0.4.24", "iconv-lite": "0.5.0",
"is-utf8": "0.2.1", "is-utf8": "0.2.1",
"js-yaml": "3.13.1", "js-yaml": "3.13.1",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"jsonata": "1.6.4", "jsonata": "1.6.5",
"media-typer": "1.1.0",
"memorystore": "1.6.1", "memorystore": "1.6.1",
"mime": "2.4.2", "mime": "2.4.4",
"mqtt": "2.18.8", "mqtt": "2.18.8",
"multer": "1.4.1", "multer": "1.4.1",
"mustache": "3.0.1", "mustache": "3.0.1",
"node-red-node-email": "^1.4.0", "node-red-node-email": "^1.6.2",
"node-red-node-feedparser": "^0.1.14", "node-red-node-feedparser": "^0.1.14",
"node-red-node-rbe": "^0.2.4", "node-red-node-rbe": "^0.2.4",
"node-red-node-sentiment": "^0.1.3", "node-red-node-sentiment": "^0.1.3",
"node-red-node-tail": "^0.0.2", "node-red-node-tail": "^0.0.2",
"node-red-node-twitter": "^1.1.4", "node-red-node-twitter": "^1.1.5",
"nopt": "4.0.1", "nopt": "4.0.1",
"oauth2orize": "1.11.0", "oauth2orize": "1.11.0",
"on-headers": "1.0.2", "on-headers": "1.0.2",
"passport": "0.4.0", "passport": "0.4.0",
"passport-http-bearer": "1.0.1", "passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2", "passport-oauth2-client-password": "0.1.2",
"raw-body": "2.4.0", "raw-body": "2.4.1",
"request": "2.88.0", "request": "2.88.0",
"semver": "6.0.0", "semver": "6.2.0",
"uglify-js": "3.5.9", "uglify-js": "3.6.0",
"when": "3.7.8", "when": "3.7.8",
"ws": "6.2.1", "ws": "6.2.1",
"xml2js": "0.4.19" "xml2js": "0.4.19"
}, },
"optionalDependencies": { "optionalDependencies": {
"bcrypt": "3.0.5" "bcrypt": "3.0.6"
}, },
"devDependencies": { "devDependencies": {
"grunt": "~1.0.3", "grunt": "~1.0.4",
"grunt-chmod": "~1.1.1", "grunt-chmod": "~1.1.1",
"grunt-cli": "~1.3.2", "grunt-cli": "~1.3.2",
"grunt-concurrent": "~2.3.1", "grunt-concurrent": "~2.3.1",

View File

@@ -48,13 +48,13 @@ module.exports = {
// Nodes // Nodes
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler); adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler);
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler); adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler);
adminApp.get(/\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler); adminApp.get(/^\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler);
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler); adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler);
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler); adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler);
adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler); adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler);
adminApp.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler); adminApp.delete(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler);
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler); adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler);
adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler); adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler);
// Context // Context
adminApp.get("/context/:scope(global)",needsPermission("context.read"),context.get,apiUtil.errorHandler); adminApp.get("/context/:scope(global)",needsPermission("context.read"),context.get,apiUtil.errorHandler);

View File

@@ -56,7 +56,7 @@ function expireSessions() {
} }
if (nextExpiry < Number.MAX_SAFE_INTEGER) { if (nextExpiry < Number.MAX_SAFE_INTEGER) {
// Allow 5 seconds grace // Allow 5 seconds grace
expiryTimeout = setTimeout(expireSessions,(nextExpiry - Date.now()) + 5000) expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(nextExpiry - Date.now()) + 5000))
} }
if (modified) { if (modified) {
return storage.saveSessions(sessions); return storage.saveSessions(sessions);
@@ -129,7 +129,7 @@ module.exports = {
sessions[accessToken] = session; sessions[accessToken] = session;
if (!expiryTimeout) { if (!expiryTimeout) {
expiryTimeout = setTimeout(expireSessions,(accessTokenExpiresAt - Date.now()) + 5000) expiryTimeout = setTimeout(expireSessions,Math.min(2147483647,(accessTokenExpiresAt - Date.now()) + 5000))
} }
return storage.saveSessions(sessions).then(function() { return storage.saveSessions(sessions).then(function() {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/editor-api", "name": "@node-red/editor-api",
"version": "0.20.5", "version": "0.20.8",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,16 +16,16 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/util": "0.20.5", "@node-red/util": "0.20.8",
"@node-red/editor-client": "0.20.5", "@node-red/editor-client": "0.20.8",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"body-parser": "1.19.0", "body-parser": "1.19.0",
"clone": "2.1.2", "clone": "2.1.2",
"cors": "2.8.5", "cors": "2.8.5",
"express-session": "1.16.1", "express-session": "1.16.2",
"express": "4.16.4", "express": "4.17.1",
"memorystore": "1.6.1", "memorystore": "1.6.1",
"mime": "2.4.2", "mime": "2.4.4",
"mustache": "3.0.1", "mustache": "3.0.1",
"oauth2orize": "1.11.0", "oauth2orize": "1.11.0",
"passport-http-bearer": "1.0.1", "passport-http-bearer": "1.0.1",
@@ -35,6 +35,6 @@
"ws": "6.2.1" "ws": "6.2.1"
}, },
"optionalDependencies": { "optionalDependencies": {
"bcrypt": "3.0.5" "bcrypt": "3.0.6"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/editor-client", "name": "@node-red/editor-client",
"version": "0.20.5", "version": "0.20.8",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -160,7 +160,7 @@
that.input.css("margin"+d,0); that.input.css("margin"+d,0);
}); });
["type","placeholder"].forEach(function(d) { ["type","placeholder","data-i18n"].forEach(function(d) {
var m = that.element.attr(d); var m = that.element.attr(d);
that.input.attr(d,m); that.input.attr(d,m);
}); });

View File

@@ -517,7 +517,7 @@ RED.editor = (function() {
} else if (node.type.indexOf("subflow:")===0) { } else if (node.type.indexOf("subflow:")===0) {
var subflow = RED.nodes.subflow(node.type.substring(8)); var subflow = RED.nodes.subflow(node.type.substring(8));
label = RED._("subflow.editSubflowInstance",{name:RED.utils.sanitize(subflow.name)}) label = RED._("subflow.editSubflowInstance",{name:RED.utils.sanitize(subflow.name)})
} else { } else if (node._def !== undefined) {
if (typeof node._def.paletteLabel !== "undefined") { if (typeof node._def.paletteLabel !== "undefined") {
try { try {
label = RED.utils.sanitize((typeof node._def.paletteLabel === "function" ? node._def.paletteLabel.call(node._def) : node._def.paletteLabel)||""); label = RED.utils.sanitize((typeof node._def.paletteLabel === "function" ? node._def.paletteLabel.call(node._def) : node._def.paletteLabel)||"");
@@ -658,17 +658,19 @@ RED.editor = (function() {
list.each(function(i) { list.each(function(i) {
var entry = $(this); var entry = $(this);
var item = entry.data('data'); var item = entry.data('data');
var name = item.parent?item.name:entry.find(".node-input-env-name").val(); var name = (item.parent?item.name:entry.find(".node-input-env-name").val()).trim();
var valueInput = entry.find(".node-input-env-value"); if (name !== "") {
var value = valueInput.typedInput("value"); var valueInput = entry.find(".node-input-env-value");
var type = valueInput.typedInput("type"); var value = valueInput.typedInput("value");
if (!item.parent || (item.parent.value !== value || item.parent.type !== type)) { var type = valueInput.typedInput("type");
var item = { if (!item.parent || (item.parent.value !== value || item.parent.type !== type)) {
name: name, var item = {
type: type, name: name,
value: value type: type,
}; value: value
env.push(item); };
env.push(item);
}
} }
}); });
return env; return env;
@@ -1684,7 +1686,8 @@ RED.editor = (function() {
RED.tray.resize(); RED.tray.resize();
} }
}, },
collapsible: true collapsible: true,
menu: false
}); });
var nodePropertiesTab = { var nodePropertiesTab = {
@@ -2224,7 +2227,8 @@ RED.editor = (function() {
RED.tray.resize(); RED.tray.resize();
} }
}, },
collapsible: true collapsible: true,
menu: false
}); });
var nodePropertiesTab = { var nodePropertiesTab = {

View File

@@ -150,7 +150,7 @@ RED.palette = (function() {
} }
function escapeNodeType(nt) { function escapeNodeType(nt) {
return nt.replace(" ","_").replace(".","_").replace(":","_"); return nt.replace(/[ .:]/g,"_");
} }
function addNodeType(nt,def) { function addNodeType(nt,def) {
@@ -243,7 +243,6 @@ RED.palette = (function() {
RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp")); RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp"));
}); });
var chart = $("#chart"); var chart = $("#chart");
var chartOffset = chart.offset();
var chartSVG = $("#chart>svg").get(0); var chartSVG = $("#chart>svg").get(0);
var activeSpliceLink; var activeSpliceLink;
var mouseX; var mouseX;
@@ -267,8 +266,8 @@ RED.palette = (function() {
ui.originalPosition.left = $('#' + e.target.id).offset().left; ui.originalPosition.left = $('#' + e.target.id).offset().left;
if (def.inputs > 0 && def.outputs > 0) { if (def.inputs > 0 && def.outputs > 0) {
mouseX = ui.position.left-paletteWidth+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft(); mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft();
mouseY = ui.position.top-paletteTop+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop(); mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop();
if (!spliceTimer) { if (!spliceTimer) {
spliceTimer = setTimeout(function() { spliceTimer = setTimeout(function() {
var nodes = []; var nodes = [];

View File

@@ -37,7 +37,7 @@ RED.sidebar.context = (function() {
// '</div>').appendTo(content); // '</div>').appendTo(content);
var footerToolbar = $('<div>'+ var footerToolbar = $('<div>'+
// '<span class="button-group"><a class="sidebar-footer-button" href="#" data-i18n="[title]node-red:debug.sidebar.openWindow"><i class="fa fa-desktop"></i></a></span> ' + // '<span class="button-group"><a class="sidebar-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
'</div>'); '</div>');

View File

@@ -1221,12 +1221,15 @@ RED.view = (function() {
removedLinks.push(drag_lines[i].link) removedLinks.push(drag_lines[i].link)
} }
} }
historyEvent = { if (removedLinks.length > 0) {
t:"delete", historyEvent = {
links: removedLinks, t:"delete",
dirty:RED.nodes.dirty() links: removedLinks,
}; dirty:RED.nodes.dirty()
RED.history.push(historyEvent); };
RED.history.push(historyEvent);
RED.nodes.dirty(true);
}
hideDragLines(); hideDragLines();
} }
if (lasso) { if (lasso) {
@@ -1331,24 +1334,31 @@ RED.view = (function() {
function zoomIn() { function zoomIn() {
if (scaleFactor < 2) { if (scaleFactor < 2) {
scaleFactor += 0.1; zoomView(scaleFactor+0.1);
RED.view.navigator.resize();
redraw();
} }
} }
function zoomOut() { function zoomOut() {
if (scaleFactor > 0.3) { if (scaleFactor > 0.3) {
scaleFactor -= 0.1; zoomView(scaleFactor-0.1);
RED.view.navigator.resize();
redraw();
} }
} }
function zoomZero() { function zoomZero() { zoomView(1); }
scaleFactor = 1;
function zoomView(factor) {
var screenSize = [chart.width(),chart.height()];
var scrollPos = [chart.scrollLeft(),chart.scrollTop()];
var center = [(scrollPos[0] + screenSize[0]/2)/scaleFactor,(scrollPos[1] + screenSize[1]/2)/scaleFactor];
scaleFactor = factor;
var newCenter = [(scrollPos[0] + screenSize[0]/2)/scaleFactor,(scrollPos[1] + screenSize[1]/2)/scaleFactor];
var delta = [(newCenter[0]-center[0])*scaleFactor,(newCenter[1]-center[1])*scaleFactor]
chart.scrollLeft(scrollPos[0]-delta[0]);
chart.scrollTop(scrollPos[1]-delta[1]);
RED.view.navigator.resize(); RED.view.navigator.resize();
redraw(); redraw();
} }
function selectAll() { function selectAll() {
RED.nodes.eachNode(function(n) { RED.nodes.eachNode(function(n) {
if (n.z == RED.workspaces.active()) { if (n.z == RED.workspaces.active()) {
@@ -1863,7 +1873,7 @@ RED.view = (function() {
} }
var link = {source: src, sourcePort:src_port, target: dst}; var link = {source: src, sourcePort:src_port, target: dst};
if (drag_line.virtualLink) { if (drag_line.virtualLink) {
if (/^link (in|out)$/.test(src.type) && /^link (in|out)$/.test(dst.type)) { if (/^link (in|out)$/.test(src.type) && /^link (in|out)$/.test(dst.type) && src.type !== dst.type) {
if (src.links.indexOf(dst.id) === -1 && dst.links.indexOf(src.id) === -1) { if (src.links.indexOf(dst.id) === -1 && dst.links.indexOf(src.id) === -1) {
var oldSrcLinks = $.extend(true,{},{v:src.links}).v var oldSrcLinks = $.extend(true,{},{v:src.links}).v
var oldDstLinks = $.extend(true,{},{v:dst.links}).v var oldDstLinks = $.extend(true,{},{v:dst.links}).v
@@ -3049,7 +3059,7 @@ RED.view = (function() {
} }
thisNode.selectAll(".node_status").style(style); thisNode.selectAll(".node_status").style(style);
} }
if (d.status.text) { if (d.status.hasOwnProperty('text')) {
thisNode.selectAll(".node_status_label").text(d.status.text); thisNode.selectAll(".node_status_label").text(d.status.text);
} else { } else {
thisNode.selectAll(".node_status_label").text(""); thisNode.selectAll(".node_status_label").text("");
@@ -3530,13 +3540,13 @@ RED.view = (function() {
node.dirty = true; node.dirty = true;
RED.workspaces.show(node.z); RED.workspaces.show(node.z);
var screenSize = [$("#chart").width(),$("#chart").height()]; var screenSize = [chart.width()/scaleFactor,chart.height()/scaleFactor];
var scrollPos = [$("#chart").scrollLeft(),$("#chart").scrollTop()]; var scrollPos = [chart.scrollLeft()/scaleFactor,chart.scrollTop()/scaleFactor];
if (node.x < scrollPos[0] || node.y < scrollPos[1] || node.x > screenSize[0]+scrollPos[0] || node.y > screenSize[1]+scrollPos[1]) { if (node.x < scrollPos[0] || node.y < scrollPos[1] || node.x > screenSize[0]+scrollPos[0] || node.y > screenSize[1]+scrollPos[1]) {
var deltaX = '-='+((scrollPos[0] - node.x) + screenSize[0]/2); var deltaX = '-='+(((scrollPos[0] - node.x) + screenSize[0]/2)*scaleFactor);
var deltaY = '-='+((scrollPos[1] - node.y) + screenSize[1]/2); var deltaY = '-='+(((scrollPos[1] - node.y) + screenSize[1]/2)*scaleFactor);
$("#chart").animate({ chart.animate({
scrollLeft: deltaX, scrollLeft: deltaX,
scrollTop: deltaY scrollTop: deltaY
},200); },200);

View File

@@ -63,7 +63,7 @@ RED.workspaces = (function() {
RED.view.state(RED.state.EDITING); RED.view.state(RED.state.EDITING);
var tabflowEditor; var tabflowEditor;
var trayOptions = { var trayOptions = {
title: RED._("workspace.editFlow",{name:workspace.label}), title: RED._("workspace.editFlow",{name:RED.utils.sanitize(workspace.label)}),
buttons: [ buttons: [
{ {
id: "node-dialog-delete", id: "node-dialog-delete",

View File

@@ -42,14 +42,14 @@ RED.debug = (function() {
var content = $("<div>").css({"position":"relative","height":"100%"}); var content = $("<div>").css({"position":"relative","height":"100%"});
var toolbar = $('<div class="sidebar-header">'+ var toolbar = $('<div class="sidebar-header">'+
'<span class="button-group"><a id="debug-tab-filter" class="sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+ '<span class="button-group"><a id="debug-tab-filter" class="sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+
'<span class="button-group"><a id="debug-tab-clear" class="sidebar-header-button" href="#" data-i18n="[title]node-red:debug.sidebar.clearLog"><i class="fa fa-trash"></i></a></span></div>').appendTo(content); '<span class="button-group"><a id="debug-tab-clear" class="sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content);
var footerToolbar = $('<div>'+ var footerToolbar = $('<div>'+
// '<span class="button-group">'+ // '<span class="button-group">'+
// '<a class="sidebar-footer-button-toggle text-button selected" id="debug-tab-view-list" href="#"><span data-i18n="">list</span></a>'+ // '<a class="sidebar-footer-button-toggle text-button selected" id="debug-tab-view-list" href="#"><span data-i18n="">list</span></a>'+
// '<a class="sidebar-footer-button-toggle text-button" id="debug-tab-view-table" href="#"><span data-i18n="">table</span></a> '+ // '<a class="sidebar-footer-button-toggle text-button" id="debug-tab-view-table" href="#"><span data-i18n="">table</span></a> '+
// '</span>'+ // '</span>'+
'<span class="button-group"><a id="debug-tab-open" class="sidebar-footer-button" href="#" data-i18n="[title]node-red:debug.sidebar.openWindow"><i class="fa fa-desktop"></i></a></span> ' + '<span class="button-group"><a id="debug-tab-open" class="sidebar-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
'</div>'); '</div>');
messageList = $('<div class="debug-content debug-content-list"/>').appendTo(content); messageList = $('<div class="debug-content debug-content-list"/>').appendTo(content);

View File

@@ -23,6 +23,7 @@ module.exports = function(RED) {
var cors = require('cors'); var cors = require('cors');
var onHeaders = require('on-headers'); var onHeaders = require('on-headers');
var typer = require('content-type'); var typer = require('content-type');
var mediaTyper = require('media-typer');
var isUtf8 = require('is-utf8'); var isUtf8 = require('is-utf8');
var hashSum = require("hash-sum"); var hashSum = require("hash-sum");
@@ -36,18 +37,22 @@ module.exports = function(RED) {
var checkUTF = false; var checkUTF = false;
if (req.headers['content-type']) { if (req.headers['content-type']) {
var parsedType = typer.parse(req.headers['content-type']) var contentType = typer.parse(req.headers['content-type'])
if (parsedType.type === "text") { if (contentType.type) {
isText = true; var parsedType = mediaTyper.parse(contentType.type);
} else if (parsedType.subtype === "xml" || parsedType.suffix === "xml") { if (parsedType.type === "text") {
isText = true; isText = true;
} else if (parsedType.type !== "application") { } else if (parsedType.subtype === "xml" || parsedType.suffix === "xml") {
isText = false; isText = true;
} else if (parsedType.subtype !== "octet-stream") { } else if (parsedType.type !== "application") {
checkUTF = true; isText = false;
} else { } else if (parsedType.subtype !== "octet-stream") {
// applicatino/octet-stream checkUTF = true;
isText = false; } else {
// applicatino/octet-stream
isText = false;
}
} }
} }

View File

@@ -49,12 +49,13 @@
<label for="node-input-useAuth" style="width: 70%;"><span data-i18n="httpin.basicauth"></span></label> <label for="node-input-useAuth" style="width: 70%;"><span data-i18n="httpin.basicauth"></span></label>
<div style="margin-left: 20px" class="node-input-useAuth-row hide"> <div style="margin-left: 20px" class="node-input-useAuth-row hide">
<div class="form-row"> <div class="form-row">
<label for="node-input-authType"><i class="fa fa-user-secret "></i> <span data-i18n="httpin.label.authType"></span></label> <label for="node-input-authType-select"><i class="fa fa-user-secret "></i> <span data-i18n="httpin.label.authType"></span></label>
<select type="text" id="node-input-authType" style="width:70%;"> <select type="text" id="node-input-authType-select" style="width:70%;">
<option value="basic" data-i18n="httpin.basic"></option> <option value="basic" data-i18n="httpin.basic"></option>
<option value="digest" data-i18n="httpin.digest"></option> <option value="digest" data-i18n="httpin.digest"></option>
<option value="bearer" data-i18n="httpin.bearer"></option> <option value="bearer" data-i18n="httpin.bearer"></option>
</select> </select>
<input type="hidden" id="node-input-authType">
</div> </div>
<div class="form-row node-input-basic-row"> <div class="form-row node-input-basic-row">
<label for="node-input-user"><i class="fa fa-user"></i> <span data-i18n="common.label.username"></span></label> <label for="node-input-user"><i class="fa fa-user"></i> <span data-i18n="common.label.username"></span></label>
@@ -102,7 +103,7 @@
url:{value:"",validate:function(v) { return (v.trim().length === 0) || (v.indexOf("://") === -1) || (v.trim().indexOf("http") === 0)} }, url:{value:"",validate:function(v) { return (v.trim().length === 0) || (v.indexOf("://") === -1) || (v.trim().indexOf("http") === 0)} },
tls: {type:"tls-config",required: false}, tls: {type:"tls-config",required: false},
proxy: {type:"http proxy",required: false}, proxy: {type:"http proxy",required: false},
authType: {value: "basic"} authType: {value: ""}
}, },
credentials: { credentials: {
user: {type:"text"}, user: {type:"text"},
@@ -130,7 +131,7 @@
$(".node-input-useAuth-row").show(); $(".node-input-useAuth-row").show();
// Nodes (< version 0.20.x) with credentials but without authentication type, need type 'basic' // Nodes (< version 0.20.x) with credentials but without authentication type, need type 'basic'
if (!$('#node-input-authType').val()) { if (!$('#node-input-authType').val()) {
$('#node-input-authType').val('basic'); $("#node-input-authType-select").val('basic').trigger("change");
} }
} else { } else {
$(".node-input-useAuth-row").hide(); $(".node-input-useAuth-row").hide();
@@ -139,12 +140,14 @@
$('#node-input-password').val(''); $('#node-input-password').val('');
} }
}); });
$("#node-input-authType").change(function() { $("#node-input-authType-select").change(function() {
if ($(this).val() == "basic" || $(this).val() == "digest") { var val = $(this).val();
$("#node-input-authType").val(val);
if (val === "basic" || val === "digest") {
$(".node-input-basic-row").show(); $(".node-input-basic-row").show();
$('#node-span-password').show(); $('#node-span-password').show();
$('#node-span-token').hide(); $('#node-span-token').hide();
} else if ($(this).val() == "bearer") { } else if (val === "bearer") {
$(".node-input-basic-row").hide(); $(".node-input-basic-row").hide();
$('#node-span-password').hide(); $('#node-span-password').hide();
$('#node-span-token').show(); $('#node-span-token').show();
@@ -158,8 +161,9 @@
$(".node-input-paytoqs-row").hide(); $(".node-input-paytoqs-row").hide();
} }
}); });
if (this.credentials.user || this.credentials.has_password) { if (this.authType) {
$('#node-input-useAuth').prop('checked', true); $('#node-input-useAuth').prop('checked', true);
$("#node-input-authType-select").val(this.authType);
} else { } else {
$('#node-input-useAuth').prop('checked', false); $('#node-input-useAuth').prop('checked', false);
} }

View File

@@ -203,8 +203,28 @@ module.exports = function(RED) {
var payload = null; var payload = null;
if (method !== 'GET' && method !== 'HEAD' && typeof msg.payload !== "undefined") { if (method !== 'GET' && method !== 'HEAD' && typeof msg.payload !== "undefined") {
if (opts.headers['content-type'] == 'multipart/form-data' && typeof payload === "object") { if (opts.headers['content-type'] == 'multipart/form-data' && typeof msg.payload === "object") {
opts.formData = msg.payload; opts.formData = {};
for (var opt in msg.payload) {
if (msg.payload.hasOwnProperty(opt)) {
var val = msg.payload[opt];
if (val !== undefined && val !== null) {
if (typeof val === 'string' || Buffer.isBuffer(val)) {
opts.formData[opt] = val;
} else if (typeof val === 'object' && val.hasOwnProperty('value')) {
// Treat as file to upload - ensure it has an options object
// as request complains if it doesn't
if (!val.hasOwnProperty('options')) {
val.options = {};
}
opts.formData[opt] = val;
} else {
opts.formData[opt] = JSON.stringify(val);
}
}
}
}
} else { } else {
if (typeof msg.payload === "string" || Buffer.isBuffer(msg.payload)) { if (typeof msg.payload === "string" || Buffer.isBuffer(msg.payload)) {
payload = msg.payload; payload = msg.payload;

View File

@@ -352,7 +352,6 @@
}, },
oneditsave: function() { oneditsave: function() {
var rules = $("#node-input-rule-container").editableList('items'); var rules = $("#node-input-rule-container").editableList('items');
var ruleset;
var node = this; var node = this;
node.rules = []; node.rules = [];
rules.each(function(i) { rules.each(function(i) {

View File

@@ -226,7 +226,6 @@
}, },
oneditsave: function() { oneditsave: function() {
var rules = $("#node-input-rule-container").editableList('items'); var rules = $("#node-input-rule-container").editableList('items');
var ruleset;
var node = this; var node = this;
node.rules= []; node.rules= [];
rules.each(function(i) { rules.each(function(i) {

View File

@@ -42,7 +42,7 @@ module.exports = function(RED) {
node.addname = n.addname || ""; node.addname = n.addname || "";
try { try {
if (node.spltType === "str") { if (node.spltType === "str") {
this.splt = (n.splt || "\\n").replace(/\\n/,"\n").replace(/\\r/,"\r").replace(/\\t/,"\t").replace(/\\e/,"\e").replace(/\\f/,"\f").replace(/\\0/,"\0"); this.splt = (n.splt || "\\n").replace(/\\n/g,"\n").replace(/\\r/g,"\r").replace(/\\t/g,"\t").replace(/\\e/g,"\e").replace(/\\f/g,"\f").replace(/\\0/g,"\0");
} else if (node.spltType === "bin") { } else if (node.spltType === "bin") {
var spltArray = JSON.parse(n.splt); var spltArray = JSON.parse(n.splt);
if (Array.isArray(spltArray)) { if (Array.isArray(spltArray)) {
@@ -572,6 +572,8 @@ module.exports = function(RED) {
} }
} }
if (msg.hasOwnProperty("reset")) { if (inflight[partId]) { delete inflight[partId] }; return; }
if ((payloadType === 'object') && (propertyKey === null || propertyKey === undefined || propertyKey === "")) { if ((payloadType === 'object') && (propertyKey === null || propertyKey === undefined || propertyKey === "")) {
if (node.mode === "auto") { if (node.mode === "auto") {
node.warn("Message missing 'msg.parts.key' property - cannot add to object"); node.warn("Message missing 'msg.parts.key' property - cannot add to object");
@@ -590,7 +592,6 @@ module.exports = function(RED) {
return; return;
} }
if (msg.hasOwnProperty("reset")) { if (inflight[partid]) { delete inflight[partId] } return; }
if (!inflight.hasOwnProperty(partId)) { if (!inflight.hasOwnProperty(partId)) {
if (payloadType === 'object' || payloadType === 'merged') { if (payloadType === 'object' || payloadType === 'merged') {
inflight[partId] = { inflight[partId] = {
@@ -627,11 +628,13 @@ module.exports = function(RED) {
var group = inflight[partId]; var group = inflight[partId];
if (payloadType === 'buffer') { if (payloadType === 'buffer') {
inflight[partId].bufferLen += property.length; if (property !== undefined) {
inflight[partId].bufferLen += property.length;
}
} }
if (payloadType === 'object') { if (payloadType === 'object') {
group.payload[propertyKey] = property; group.payload[propertyKey] = property;
group.currentCount = (group.currentCount || 0) + 1; group.currentCount = Object.keys(group.payload).length;
} else if (payloadType === 'merged') { } else if (payloadType === 'merged') {
if (Array.isArray(property) || typeof property !== 'object') { if (Array.isArray(property) || typeof property !== 'object') {
if (!msg.hasOwnProperty("complete")) { if (!msg.hasOwnProperty("complete")) {

View File

@@ -22,12 +22,12 @@
<dd>Sets the delay, in milliseconds, to be applied to the message. This <dd>Sets the delay, in milliseconds, to be applied to the message. This
option only applies if the node is configured to allow the message to option only applies if the node is configured to allow the message to
override the configured default delay interval.</dd> override the configured default delay interval.</dd>
<dt class="optional">reset</dt> <dt class="optional">reset</dt>
<dd>If the received message has this property set to any value, all <dd>If the received message has this property set to any value, all
outstanding messages held by the node are cleared without being sent.</dd> outstanding messages held by the node are cleared without being sent.</dd>
<dt class="optional">flush</dt> <dt class="optional">flush</dt>
<dd>If the received message has this property set to any value, all <dd>If the received message has this property set to any value, all
outstanding messages held by the node are sent immediately.</dd> outstanding messages held by the node are sent immediately.</dd>
</dl> </dl>
<h3>Details</h3> <h3>Details</h3>
<p>When configured to delay messages, the delay interval can be a fixed value, <p>When configured to delay messages, the delay interval can be a fixed value,

View File

@@ -22,6 +22,8 @@
<dd>メッセージの遅延時間をミリ秒単位で設定しますこれはノードの設定でデフォルトの遅延時間を上書きできるようノードを設定した場合にのみ適用します</dd> <dd>メッセージの遅延時間をミリ秒単位で設定しますこれはノードの設定でデフォルトの遅延時間を上書きできるようノードを設定した場合にのみ適用します</dd>
<dt class="optional">reset</dt> <dt class="optional">reset</dt>
<dd>受信メッセージでこのプロパティを任意の値に設定するとノードが保持する全ての未送信メッセージをクリアします</dd> <dd>受信メッセージでこのプロパティを任意の値に設定するとノードが保持する全ての未送信メッセージをクリアします</dd>
<dt class="optional">flush</dt>
<dd>受信メッセージでこのプロパティを任意の値に設定するとノードが保持する全ての未送信メッセージを直ちに送信します</dd>
</dl> </dl>
<h3>詳細</h3> <h3>詳細</h3>
<p>メッセージを遅延させるように設定する場合遅延時間は固定値範囲内の乱数値メッセージ毎の動的な指定値のいずれかを指定できます</p> <p>メッセージを遅延させるように設定する場合遅延時間は固定値範囲内の乱数値メッセージ毎の動的な指定値のいずれかを指定できます</p>

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/nodes", "name": "@node-red/nodes",
"version": "0.20.5", "version": "0.20.8",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -20,24 +20,25 @@
"cheerio": "0.22.0", "cheerio": "0.22.0",
"content-type": "1.0.4", "content-type": "1.0.4",
"cookie-parser": "1.4.4", "cookie-parser": "1.4.4",
"cookie": "0.3.1", "cookie": "0.4.0",
"cors": "2.8.5", "cors": "2.8.5",
"cron": "1.7.1", "cron": "1.7.1",
"denque": "1.4.1", "denque": "1.4.1",
"fs-extra": "7.0.1", "fs-extra": "8.1.0",
"fs.notify": "0.0.4", "fs.notify": "0.0.4",
"hash-sum": "1.0.2", "hash-sum": "2.0.0",
"https-proxy-agent": "2.2.1", "https-proxy-agent": "2.2.1",
"is-utf8": "0.2.1", "is-utf8": "0.2.1",
"js-yaml": "3.13.1", "js-yaml": "3.13.1",
"media-typer": "1.1.0",
"mqtt": "2.18.8", "mqtt": "2.18.8",
"multer": "1.4.1", "multer": "1.4.1",
"mustache": "3.0.1", "mustache": "3.0.1",
"on-headers": "1.0.2", "on-headers": "1.0.2",
"raw-body": "2.4.0", "raw-body": "2.4.1",
"request": "2.88.0", "request": "2.88.0",
"ws": "6.2.1", "ws": "6.2.1",
"xml2js": "0.4.19", "xml2js": "0.4.19",
"iconv-lite": "0.4.24" "iconv-lite": "0.5.0"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/registry", "name": "@node-red/registry",
"version": "0.20.5", "version": "0.20.8",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,9 +16,9 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/util": "0.20.5", "@node-red/util": "0.20.8",
"semver": "6.0.0", "semver": "6.2.0",
"uglify-js": "3.5.9", "uglify-js": "3.6.0",
"when": "3.7.8" "when": "3.7.8"
} }
} }

View File

@@ -129,7 +129,7 @@ function start() {
log.info(log._("runtime.version",{component:"Node.js ",version:process.version})); log.info(log._("runtime.version",{component:"Node.js ",version:process.version}));
if (settings.UNSUPPORTED_VERSION) { if (settings.UNSUPPORTED_VERSION) {
log.error("*****************************************************************"); log.error("*****************************************************************");
log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=4"})+" *"); log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=8.9.0"})+" *");
log.error("*****************************************************************"); log.error("*****************************************************************");
events.emit("runtime-event",{id:"runtime-unsupported-version",payload:{type:"error",text:"notification.errors.unsupportedVersion"},retain:true}); events.emit("runtime-event",{id:"runtime-unsupported-version",payload:{type:"error",text:"notification.errors.unsupportedVersion"},retain:true});
} }

View File

@@ -234,7 +234,7 @@ function createContext(id,seed,parent) {
if (err.code === "INVALID_EXPR") { if (err.code === "INVALID_EXPR") {
throw err; throw err;
} }
value[0] = undefined; values[0] = undefined;
} }
} }
} else { } else {
@@ -246,7 +246,7 @@ function createContext(id,seed,parent) {
if (err.code === "INVALID_EXPR") { if (err.code === "INVALID_EXPR") {
throw err; throw err;
} }
value[i] = undefined; values[i] = undefined;
} }
} }
} }

View File

@@ -277,7 +277,7 @@ class Flow {
if (this.subflowInstanceNodes[stopList[i]]) { if (this.subflowInstanceNodes[stopList[i]]) {
try { try {
(function(subflow) { (function(subflow) {
promises.push(stopNode(node,false).then(() => { subflow.stop() })); promises.push(stopNode(node,false).then(() => subflow.stop()));
})(this.subflowInstanceNodes[stopList[i]]); })(this.subflowInstanceNodes[stopList[i]]);
} catch(err) { } catch(err) {
node.error(err); node.error(err);

View File

@@ -409,7 +409,11 @@ function remapSubflowNodes(nodes,nodeMap) {
for (j=0;j<outputs.length;j++) { for (j=0;j<outputs.length;j++) {
wires = outputs[j]; wires = outputs[j];
for (k=0;k<wires.length;k++) { for (k=0;k<wires.length;k++) {
outputs[j][k] = nodeMap[outputs[j][k]].id if (nodeMap[outputs[j][k]]) {
outputs[j][k] = nodeMap[outputs[j][k]].id
} else {
outputs[j][k] = null;
}
} }
} }
} }
@@ -421,7 +425,6 @@ function remapSubflowNodes(nodes,nodeMap) {
for (var prop in node) { for (var prop in node) {
if (node.hasOwnProperty(prop) && prop !== '_alias') { if (node.hasOwnProperty(prop) && prop !== '_alias') {
if (nodeMap[node[prop]]) { if (nodeMap[node[prop]]) {
//console.log("Mapped",node.type,node.id,prop,nodeMap[node[prop]].id);
node[prop] = nodeMap[node[prop]].id; node[prop] = nodeMap[node[prop]].id;
} }
} }

View File

@@ -51,6 +51,12 @@ function runSshKeygenCommand(args,cwd,env) {
resolve(stdout); resolve(stdout);
} }
}); });
child.on('error', function(err) {
if (/ENOENT/.test(err.toString())) {
err.code = "command_not_found";
}
reject(err);
});
}); });
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/runtime", "name": "@node-red/runtime",
"version": "0.20.5", "version": "0.20.8",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,11 +16,11 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/registry": "0.20.5", "@node-red/registry": "0.20.8",
"@node-red/util": "0.20.5", "@node-red/util": "0.20.8",
"clone": "2.1.2", "clone": "2.1.2",
"express": "4.16.4", "express": "4.17.1",
"fs-extra": "7.0.1", "fs-extra": "8.1.0",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"when": "3.7.8" "when": "3.7.8"
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/util", "name": "@node-red/util",
"version": "0.20.5", "version": "0.20.8",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -18,7 +18,7 @@
"clone": "2.1.2", "clone": "2.1.2",
"i18next": "15.1.0", "i18next": "15.1.0",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"jsonata": "1.6.4", "jsonata": "1.6.5",
"when": "3.7.8" "when": "3.7.8"
} }
} }

View File

@@ -27,9 +27,9 @@ var apiEnabled = false;
function checkVersion(userSettings) { function checkVersion(userSettings) {
var semver = require('semver'); var semver = require('semver');
if (!semver.satisfies(process.version,">=4.8.0")) { if (!semver.satisfies(process.version,">=8.9.0")) {
// TODO: in the future, make this a hard error. // TODO: in the future, make this a hard error.
// var e = new Error("Unsupported version of node.js"); // var e = new Error("Unsupported version of Node.js");
// e.code = "unsupported_version"; // e.code = "unsupported_version";
// throw e; // throw e;
userSettings.UNSUPPORTED_VERSION = process.version; userSettings.UNSUPPORTED_VERSION = process.version;
@@ -39,7 +39,7 @@ function checkVersion(userSettings) {
* This module provides the full Node-RED application, with both the runtime * This module provides the full Node-RED application, with both the runtime
* and editor components built in. * and editor components built in.
* *
* The API this module exposes allows it to be embedded within another node.js * The API this module exposes allows it to be embedded within another Node.js
* application. * application.
* *
* @namespace node-red * @namespace node-red
@@ -76,7 +76,7 @@ module.exports = {
apiEnabled = true; apiEnabled = true;
server = httpServer; server = httpServer;
} else { } else {
runtime.init(userSettings); runtime.init(userSettings, httpServer);
apiEnabled = false; apiEnabled = false;
if (httpServer) { if (httpServer) {
server = httpServer; server = httpServer;

View File

@@ -1,6 +1,6 @@
{ {
"name": "node-red", "name": "node-red",
"version": "0.20.5", "version": "0.20.8",
"description": "A visual tool for wiring the Internet of Things", "description": "A visual tool for wiring the Internet of Things",
"homepage": "http://nodered.org", "homepage": "http://nodered.org",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -31,25 +31,25 @@
"flow" "flow"
], ],
"dependencies": { "dependencies": {
"@node-red/editor-api": "0.20.5", "@node-red/editor-api": "0.20.8",
"@node-red/runtime": "0.20.5", "@node-red/runtime": "0.20.8",
"@node-red/util": "0.20.5", "@node-red/util": "0.20.8",
"@node-red/nodes": "0.20.5", "@node-red/nodes": "0.20.8",
"basic-auth": "2.0.1", "basic-auth": "2.0.1",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"express": "4.16.4", "express": "4.17.1",
"fs-extra": "7.0.1", "fs-extra": "8.1.0",
"node-red-node-email": "^1.4.0", "node-red-node-email": "^1.6.2",
"node-red-node-feedparser": "^0.1.14", "node-red-node-feedparser": "^0.1.14",
"node-red-node-rbe": "^0.2.4", "node-red-node-rbe": "^0.2.4",
"node-red-node-sentiment": "^0.1.3", "node-red-node-sentiment": "^0.1.3",
"node-red-node-tail": "^0.0.2", "node-red-node-tail": "^0.0.2",
"node-red-node-twitter": "^1.1.4", "node-red-node-twitter": "^1.1.5",
"nopt": "4.0.1", "nopt": "4.0.1",
"semver": "6.0.0" "semver": "6.2.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"bcrypt": "3.0.5" "bcrypt": "3.0.6"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"

View File

@@ -197,10 +197,8 @@ try {
RED.init(server,settings); RED.init(server,settings);
} catch(err) { } catch(err) {
if (err.code == "unsupported_version") { if (err.code == "unsupported_version") {
console.log("Unsupported version of node.js:",process.version); console.log("Unsupported version of Node.js:",process.version);
console.log("Node-RED requires node.js v4 or later"); console.log("Node-RED requires Node.js v8.9.0 or later");
} else if (err.code == "not_built") {
console.log("Node-RED has not been built. See README.md for details");
} else { } else {
console.log("Failed to start server:"); console.log("Failed to start server:");
if (err.stack) { if (err.stack) {

View File

@@ -55,7 +55,7 @@ module.exports = {
// The maximum number of messages nodes will buffer internally as part of their // The maximum number of messages nodes will buffer internally as part of their
// operation. This applies across a range of nodes that operate on message sequences. // operation. This applies across a range of nodes that operate on message sequences.
// defaults to no limit. A value of 0 also means no limit is applied. // defaults to no limit. A value of 0 also means no limit is applied.
//nodeMaxMessageBufferLength: 0, //nodeMessageBufferMaxLength: 0,
// To disable the option for using local files for storing keys and certificates in the TLS configuration // To disable the option for using local files for storing keys and certificates in the TLS configuration
// node, set this to true // node, set this to true

View File

@@ -1291,6 +1291,7 @@ describe('HTTP Request Node', function() {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
console.log(msg.payload);
try { try {
msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); msg.payload.headers.should.have.property('content-type').which.startWith('application/json');
msg.payload.headers.should.not.have.property('x-node-red-request-node'); msg.payload.headers.should.not.have.property('x-node-red-request-node');
@@ -1301,7 +1302,11 @@ describe('HTTP Request Node', function() {
}); });
// Pass in a headers property with an unmodified x-node-red-request-node hash // Pass in a headers property with an unmodified x-node-red-request-node hash
// This should cause the node to ignore the headers // This should cause the node to ignore the headers
n1.receive({payload:{foo:"bar"}, headers: { 'content-type': 'text/plain', "x-node-red-request-node":"67690139"}});
var headers = { 'content-type': 'text/plain' };
headers['x-node-red-request-node'] = require("hash-sum")(headers);
n1.receive({payload:{foo:"bar"}, headers: headers});
}); });
}); });

View File

@@ -677,6 +677,9 @@ describe('JOIN node', function() {
n1.receive({payload:{f:1}, topic:"f", complete:true}); n1.receive({payload:{f:1}, topic:"f", complete:true});
n1.receive({payload:{g:2}, topic:"g"}); n1.receive({payload:{g:2}, topic:"g"});
n1.receive({payload:{h:1}, topic:"h"}); n1.receive({payload:{h:1}, topic:"h"});
n1.receive({reset:true});
n1.receive({payload:{g:2}, topic:"g"});
n1.receive({payload:{h:1}, topic:"h"});
n1.receive({payload:{i:3}, topic:"i"}); n1.receive({payload:{i:3}, topic:"i"});
}); });
}); });
@@ -700,6 +703,9 @@ describe('JOIN node', function() {
} }
catch(e) { done(e) } catch(e) { done(e) }
}); });
n1.receive({payload:2, foo:"b"});
n1.receive({payload:3, foo:"c"});
n1.receive({reset:true});
n1.receive({payload:1, foo:"a"}); n1.receive({payload:1, foo:"a"});
n1.receive({payload:2, foo:"b"}); n1.receive({payload:2, foo:"b"});
n1.receive({payload:3, foo:"c"}); n1.receive({payload:3, foo:"c"});