From cb35604ef5ee9fda5a3d46e3068c815e33d83f01 Mon Sep 17 00:00:00 2001 From: Jeremy Barlow Date: Wed, 19 Sep 2018 08:44:26 -0700 Subject: [PATCH 1/6] Resolve path when sending example file for Windows support Previously, when trying to import an example into the flow editor on Windows, the load attempt would fail with an HTTP 404 error in the browser client, with a `TypeError: path must be absolute or specify root to res.sendFile` error being written to the Node-RED log. This was due to the path being passed to the `res.sendFile` function not being fully-qualified (for example, `\Users\myuser\...\example.json`). With the changes in this commit, the path to the example file is resolved to a fully-qualified path before being passed into the `res.sendFile` call. For example, a path on Windows of `\Users\myuser\...\example.json` would be transformed to `C:\\Users\\myuser\\...\\example.json` before being passed along to the `sendFile` function. This change allows the file to be loaded and sent properly to the browser client and for the embedded flows in the example to be loaded in the flow editor. --- red/api/editor/library.js | 5 +++-- test/red/api/editor/library_spec.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/red/api/editor/library.js b/red/api/editor/library.js index d5cbb020f..fd9c2d085 100644 --- a/red/api/editor/library.js +++ b/red/api/editor/library.js @@ -102,9 +102,10 @@ module.exports = { var fullPath = redNodes.getNodeExampleFlowPath(module,path); if (fullPath) { try { - fs.statSync(fullPath); + var resolvedPath = fspath.resolve(fullPath); + fs.statSync(resolvedPath); log.audit({event: "library.get",type:"flow",path:req.params[0]},req); - return res.sendFile(fullPath,{ + return res.sendFile(resolvedPath,{ headers:{ 'Content-Type': 'application/json' } diff --git a/test/red/api/editor/library_spec.js b/test/red/api/editor/library_spec.js index 65e53e459..f921596a3 100644 --- a/test/red/api/editor/library_spec.js +++ b/test/red/api/editor/library_spec.js @@ -225,7 +225,7 @@ describe("api/editor/library", function() { throw err; } res.body.should.have.property('sendFile', - 'node-module:example-one'); + fspath.resolve('node-module') + ':example-one'); done(); }); }); @@ -243,7 +243,8 @@ describe("api/editor/library", function() { throw err; } res.body.should.have.property('sendFile', - '@org_scope/node_package:example-one'); + fspath.resolve('@org_scope/node_package') + + ':example-one'); done(); }); }); From ce85c8d986f69c8fc2e5d8bbebbcbd8c9800ca6d Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 24 Sep 2018 21:15:39 +0100 Subject: [PATCH 2/6] Ensure all palette categories are opened properly Closes #1893 --- editor/js/ui/palette.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/editor/js/ui/palette.js b/editor/js/ui/palette.js index a345233ff..2f27def07 100644 --- a/editor/js/ui/palette.js +++ b/editor/js/ui/palette.js @@ -320,9 +320,9 @@ RED.palette = (function() { } setLabel(nt,$(d),label,nodeInfo); - var categoryNode = $("#palette-container-"+category); + var categoryNode = $("#palette-container-"+rootCategory); if (categoryNode.find(".palette_node").length === 1) { - categoryContainers[category].open(); + categoryContainers[rootCategory].open(); } } @@ -459,7 +459,6 @@ RED.palette = (function() { } }); RED.events.on('registry:node-set-disabled', function(nodeSet) { - console.log(nodeSet); for (var j=0;j Date: Wed, 26 Sep 2018 10:22:01 +0900 Subject: [PATCH 3/6] Add test cases for red/api/editor/settings.js --- test/red/api/editor/settings_spec.js | 84 +++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/test/red/api/editor/settings_spec.js b/test/red/api/editor/settings_spec.js index 631d0907a..e602d1f44 100644 --- a/test/red/api/editor/settings_spec.js +++ b/test/red/api/editor/settings_spec.js @@ -19,6 +19,7 @@ var request = require('supertest'); var express = require('express'); var sinon = require('sinon'); var when = require('when'); +var bodyParser = require('body-parser'); var app = express(); var info = require("../../../../red/api/editor/settings"); @@ -29,6 +30,7 @@ describe("api/editor/settings", function() { before(function() { sinon.stub(theme,"settings",function() { return { test: 456 };}); app = express(); + app.use(bodyParser.json()); app.get("/settings",info.runtimeSettings); app.get("/settingsWithUser",function(req,res,next) { req.user = { @@ -40,12 +42,13 @@ describe("api/editor/settings", function() { } next(); },info.runtimeSettings); + app.get("/settings/user", info.userSettings); + app.post("/settings/user", info.updateUserSettings); }); after(function() { theme.settings.restore(); }); - it('returns the filtered settings', function(done) { info.init({ settings: { @@ -120,6 +123,83 @@ describe("api/editor/settings", function() { done(); }); }); + it('returns user settings', function (done) { + info.init({ + settings: { + getUserSettings: function () { + return { + "editor": { + "view": { + "view-grid-size": "20", + "view-node-status": true, + "view-show-tips": true, + "view-snap-grid": true, + "view-show-grid": true + } + } + }; + } + } + }); + request(app) + .get("/settings/user") + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + res.body.should.have.property("editor"); + res.body.editor.should.have.property("view"); + res.body.editor.view.should.have.property("view-grid-size", "20"); + res.body.editor.view.should.have.property("view-node-status", true); + res.body.editor.view.should.have.property("view-show-tips", true); + res.body.editor.view.should.have.property("view-snap-grid", true); + res.body.editor.view.should.have.property("view-show-grid", true); + done(); + }); + }); + it('sets user settings', function (done) { + info.init({ + settings: { + getUserSettings: function () { + return {}; + }, + setUserSettings: function (username, currentSettings) { + currentSettings.should.have.property("editor"); + currentSettings.editor.should.have.property("view"); + currentSettings.editor.view.should.have.property("view-grid-size", "21"); + currentSettings.editor.view.should.have.property("view-node-status", false); + currentSettings.editor.view.should.have.property("view-show-tips", false); + currentSettings.editor.view.should.have.property("view-snap-grid", false); + currentSettings.editor.view.should.have.property("view-show-grid", false); + return when.resolve(); + } + }, + log: { + audit: function () {} + } + }); + request(app) + .post("/settings/user") + .send({ + "editor": { + "view": { + "view-grid-size": "21", + "view-node-status": false, + "view-show-tips": false, + "view-snap-grid": false, + "view-show-grid": false + } + } + }) + .expect(204) + .end(function (err, res) { + res.should.have.property("status"); + res.status.should.equal(204); + res.should.have.property("text", ""); + done(); + }); + }); it('includes project settings if projects available', function(done) { info.init({ settings: { @@ -277,7 +357,7 @@ describe("api/editor/settings", function() { res.body.editorTheme.should.have.property("palette",{editable:false}); done(); }); - }) + }); }); }); From 8e2c12f8d9d9fe344a420ef001bc0549e960016a Mon Sep 17 00:00:00 2001 From: Amila Welihinda Date: Mon, 1 Oct 2018 12:50:03 -0700 Subject: [PATCH 4/6] Change repo badge to point to master branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1306a796..a0afbdc70 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ http://nodered.org -[![Build Status](https://travis-ci.org/node-red/node-red.svg)](https://travis-ci.org/node-red/node-red) +[![Build Status](https://travis-ci.org/node-red/node-red.svg?branch=master)](https://travis-ci.org/node-red/node-red) [![Coverage Status](https://coveralls.io/repos/node-red/node-red/badge.svg?branch=master)](https://coveralls.io/r/node-red/node-red?branch=master) A visual tool for wiring the Internet of Things. From 629536b562f8cc48823d668f297bb59786962955 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sun, 7 Oct 2018 11:11:30 +0100 Subject: [PATCH 5/6] Handle manually added project deps that are unused Fixes #1908 --- editor/js/ui/projects/projectSettings.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/editor/js/ui/projects/projectSettings.js b/editor/js/ui/projects/projectSettings.js index 011c9fbe7..d43d67bfd 100644 --- a/editor/js/ui/projects/projectSettings.js +++ b/editor/js/ui/projects/projectSettings.js @@ -461,7 +461,11 @@ RED.projects.settings = (function() { setTimeout(function() { depsList.editableList('removeItem',entry); refreshModuleInUseCounts(); - entry.count = modulesInUse[entry.id].count; + if (modulesInUse.hasOwnProperty(entry.id)) { + entry.count = modulesInUse[entry.id].count; + } else { + entry.count = 0; + } depsList.editableList('addItem',entry); },500); } From 98c1bc276d6d93c1d8d873dd39b6ba99d2207e00 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sun, 7 Oct 2018 11:37:50 +0100 Subject: [PATCH 6/6] Merge project package changes to avoid overwritten changes --- .../storage/localfilesystem/projects/Project.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/red/runtime/storage/localfilesystem/projects/Project.js b/red/runtime/storage/localfilesystem/projects/Project.js index 989774d6c..f580c178e 100644 --- a/red/runtime/storage/localfilesystem/projects/Project.js +++ b/red/runtime/storage/localfilesystem/projects/Project.js @@ -358,7 +358,15 @@ Project.prototype.update = function (user, data) { promises.push(util.writeFile(this.paths['README.md'], this.description)); } if (savePackage) { - promises.push(util.writeFile(this.paths['package.json'], JSON.stringify(this.package,"",4))); + promises.push(fs.readFile(project.paths['package.json'],"utf8").then(content => { + var currentPackage = {}; + try { + currentPackage = util.parseJSON(content); + } catch(err) { + } + this.package = Object.assign(currentPackage,this.package); + return util.writeFile(this.paths['package.json'], JSON.stringify(this.package,"",4)); + })); } return when.settle(promises).then(function(res) { return {