[New Release] node-red-contrib-uibuilder - v3.3.0

Hi all, I'm pleased to announce that uibuilder v3.3.0 has just been published and is available.

A couple of nice new features in this release along with a load more bugs squashed and a lot of code refactoring which paves the way for yet more future improvements.


New

  • Add new pre-defined msg from Node-RED that will cause the front-end client (browser) to reload.
  • Add auto-reload flag to file editor - if set, any connected clients will automatically reload when a file is saved. (Only from the file editor in Node-RED for now, later I'll extend this to work if you are editing files using external editors).
  • Add new function to uibuilderfe.js - uibuilder.clearEventListeners() - Will forcably clear any onChange event listeners that have been created. Partial update for Issue #134.
  • Added initial documentation for front-end build tooling to technical documentation (general info and Snowpack).

Fixed

  • Issue #126 - Security not turning on even if TLS is used.
  • Update security.js template to remove simple false return if authentication fails - this is no longer valid.

Please note that the security features in uibuilder are still not complete and are not well tested. They also have some debug output. Other items on the backlog are currently taking preference.

Updated

  • Bump dependencies to latest

  • Add collapsible summaries to README.md

  • Various updates to technical documentation

  • Update chkAuth validation function to make it more robust

  • Improve auth process logging and msg._auth.info checks

  • Remove simple true/false return from auth processing as this is no longer valid

  • uibuilderfe

    • Added check for uibuilder.start() having already been called and prevent it being run more than once. Partial update for Issue #134.
    • Add new function uibuilder.clearEventListeners() - see details in New above.
    • Added initial code for a simple alert - not yet ready for use.
  • Internal code refactoring

    • Prep for adding the ability for uibuilder to use its own independent ExpressJS server

    • Rename uibuilder.js's nodeGo() function to nodeInstance() for clarity

    • Add dumpReq() to tilib.js - returns the important bits of an ExpressJS REQ object

    • Begin to add Node-RED type definitions

    • Add ExpressJS type definitions

    • Other linting improvements

    • The refactoring has removed several hundred lines of code from the main js file and
      simplified quite a few function calls.

    • Moved Socket.IO processing to its own Singleton class module.

      This means that any Node-RED related module can potentially require the socket.js module and get access to the list of Socket.IO namespace's for all uibuilder node instances. All you need is the uibuilder URL name.

      It also means that any module can send messages to connected front-end clients simply by referencing the module and knowing the url.

      Note that this currently only works once the class has been instantiated and a setup method called. That requires a number of objects to be passed to it. This happens when you have added and deployed a uibuilder node to your flows.

      But it does mean that, in theory at least, you could now write another custom node that could make use of the uibuilder communications channel. Of course, it also opens the way for new nodes to be added to uibuilder. However, a slight caveat to that would be that loading order would be important and you really must deploy uibuilder before any other node that might want to use the module.

    • Started moving ExpressJS web server handling to its own Singleton class module

      Again, this will mean that any module running in Node-RED could potentially tie into the module and be able to access/influence uibuilders web server capability.

      Works similarly to the Socket.IO class above. So it has to be initialised using a number of properties from the core uibuilder node.

      Currently, only the core ExpressJS app and server references are handled by the class. More work is required to move other processing into it.

  • Include PR #131 - add Socket.IO CORS support

8 Likes

I would just like to say 'thank you' for all the work put into this node.

As a result :grin: I thought that I should mention that when selecting 'Instance Details' I got this error message;

    at /home/pi/.node-red/node_modules/node-red-contrib-uibuilder/nodes/uiblib.js:874:40
    at Array.forEach (<anonymous>)
    at Object.showInstanceDetails (/home/pi/.node-red/node_modules/node-red-contrib-uibuilder/nodes/uiblib.js:872:25)
    at /home/pi/.node-red/node_modules/node-red-contrib-uibuilder/nodes/uibuilder.js:451:31
    at Layer.handle [as handle_request] (/usr/lib/node_modules/node-red/node_modules/express/lib/router/layer.js:95:5)
    at next (/usr/lib/node_modules/node-red/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/usr/lib/node_modules/node-red/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/usr/lib/node_modules/node-red/node_modules/express/lib/router/layer.js:95:5)
    at /usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/usr/lib/node_modules/node-red/node_modules/express/lib/middleware/init.js:40:5)
    at Layer.handle [as handle_request] (/usr/lib/node_modules/node-red/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:317:13)
    at /usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:275:10)
    at query (/usr/lib/node_modules/node-red/node_modules/express/lib/middleware/query.js:45:5)
    at Layer.handle [as handle_request] (/usr/lib/node_modules/node-red/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:317:13)
    at /usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/usr/lib/node_modules/node-red/node_modules/express/lib/router/index.js:335:12)

I have probably messed something up, either in operation or in understanding of what it is supposed to do but either way if you would point out what I have done wrong I would be grateful.

Again thanks for the node, great fun.

Hmm, that's odd, that part of the code hasn't been changed.

You are actually missing the error message though, do you have that? Without it, it is hard to see what the actual issue is.

However the code at uibuilib.js:874 does break one of my own inviolate rules which is that when using the JSON class, it MUST always be surrounded with a try/catch as it is very fragile.

I will add that now and get a bug fix out so that at least it doesn't crash there. Thanks for reporting.

v3.2.1 will have the bugfix to stop it crashing at least and adds a warning output to the Node-RED log that will tell us what property it is failing on.

Sorry, missed the first line;

TypeError: Cannot read property 'constructor' of undefined

'rules, what rules' :grinning:, or something like that. Appreciate the quick reply

Ah, what version of Node.js are you running?

No problem, caught me at just the right time

And v3.3.1 published. Fix untrapped JSON.stringify.

node.js v 14.16.1.

Updated to 3.3.1 and I now get the instance details OK but I also get these error messages in the debug pane;

msg : string[169]

"[uibuilder:uiblib:showInstanceDetails] b2ec14b3.c98ff8, http://192.168.1.20:1880/: Item 'ioChannels' failed to stringify. Cannot read property 'constructor' of undefined"

15/05/2021, 14:23:05msg : string[173]

"[uibuilder:uiblib:showInstanceDetails] b2ec14b3.c98ff8, http://192.168.1.20:1880/: Item 'ioClientsCount' failed to stringify. Cannot read property 'constructor' of undefined"

15/05/2021, 14:23:06msg : string[170]

"[uibuilder:uiblib:showInstanceDetails] b2ec14b3.c98ff8, http://192.168.1.20:1880/: Item 'ioNamespace' failed to stringify. Cannot read property 'constructor' of undefined"

15/05/2021, 14:23:07msg : string[170]

"[uibuilder:uiblib:showInstanceDetails] b2ec14b3.c98ff8, http://192.168.1.20:1880/: Item 'rcvMsgCount' failed to stringify. Cannot read property 'constructor' of undefined"

Expect you were already aware but thought I should mention it as it shows where the problem is.

Ah, got it!

You have left the url blank? or maybe just set to /? No, in fact, I think that you have set the url to http://192.168.1.20:1880/ am I right?

The "url" value in uibuilder should only be the path not the full URL. For example, if you want uibuilder to be served as http://192.168.1.20:1880/fred, you would set the url to "fred".

Does it actually work that way?

url is set to 'database' and the browser page is (http://192.168.1.20:1880/database/)

This is the info from the Debug Page if it helps

uibuilder Instance Debug Page
Note that this page is only accessible to users with Node-RED admin authority.

Instance Information for 'database'
The node id for this instance	fc20799e.c25e98
This can be used to search for the node in the Editor.
Filing system path to front-end resources	/home/pi/.node-red/uibuilder/database
Contains all of your UI code and other resources. Folders and files can be viewed, edited, created and deleted using the "Edit Files" button. You MUST keep at least the src and dist folders otherwise things may not work.
URL for the front-end resources	./database/
Index.html page will be shown if you click.
Node-RED userDir folder	/home/pi/.node-red
Also the location for any installed vendor resources (installed library packages) and your other nodes.
URL for vendor resources	../uibuilder/vendor/
See the Detailed Information Page for more details.
Filing system path to common (shared) front-end resources	/home/pi/.node-red/uibuilder/common
Resource files in this folder are accessible from the main URL.
Filing system path to common uibuilder configuration resource files	/home/pi/.node-red/uibuilder/.config
Contains the package list, master package list, authentication and authorisation middleware.
Filing system path to uibuilder master template files	/home/pi/.node-red/node_modules/node-red-contrib-uibuilder/templates
These are copied to any new instance of the uibuilder node. If you keep the copy flag turned on they are re-copied if deleted.
uibuilder version	3.3.1
Node-RED version	1.3.4
Minimum version required by uibuilder is >=1.0.0
Node.js version	14.16.1
Minimum version required by uibuilder is >=10.0
Node Instance Configuration Items
Shows the internal configuration.

_wireCount	2
allowScripts	false
allowStyles	false
copyIndex	true
credentials	{}
customFolder	/home/pi/.node-red/uibuilder/database
fwdInMessages	false
id	fc20799e.c25e98
ioChannels	undefined
ioClientsCount	undefined
ioNamespace	undefined
name	
rcvMsgCount	undefined
sessionLength	432000
showfolder	false
tokenAutoExtend	false
topic	
type	uibuilder
url	database
useSecurity	false
wires	63402278.37068c,e2fe07fc.1957f8,

Well, I'm very confused now:

ioChannels	undefined
ioClientsCount	undefined
ioNamespace	undefined
name	
rcvMsgCount	undefined

Should look like (taken from one of my nodes):

ioChannels	{"control":"uiBuilderControl","client":"uiBuilderClient","server":"uiBuilder"}
ioClientsCount	0
ioNamespace	heating
name	
rcvMsgCount	3570
sessionLength	120

In particular, ioChannels is a fixed entry and so there is no way it should ever be undefined - that should be impossible.

Next thing to try is to add another uibuilder node, change the url to test and then deploy. See if you get the same errors.


If you do get the same errors, stop node-red, go to a command prompt on the server and:

cd ~/.node-red
npm remove node-red-contrib-uibuilder
npm install node-red-contrib-uibuilder

Then restart node-red and reload the Editor page. Then try again.

Ooh, definitely going to play with it, and the clear event handlers might be a nifty addition to an obscure piece of code I’m working on. I actually got back into a fresh uibuilder based project about a week ago. Got really bored a month into this bedrest thing, so programming from bed it is. Something to do beyond staring at the ceiling.
Reloading of the frontend sounds like a great case for hot reloading the UI when needed, or if you don’t use a reactive framework, force a reload that way! :+1:

4 Likes

Good to hear from you again. :smile:

1 Like

Relevant for this topic I guess but I missed a lot in the last 7 or so months. Anyone having messed around with using vuex in a complex enough frontend to keep things shown centralised with different clients connected, as well as a central state kept in cache in node-red? I put together a vuex plugin that handles the logic for communicating with uibuilder, so that the application can just do what it should and not worry about the uibuilder aspect elsewhere in it, but it definitely feels like someone has had to come up with this already.

I'm in the process of building a configurable component-based dashboard using vue, vuetify and uibuilder. See towards the end of the long Uibuilder: to subscribe or not to subscribe? thread. I'm reflecting a big state tree from node-red into the front-end as described in that thread and from there into configurable widgets. I looked at using vuex but decided not to 'cause I didn't see the benefits in this use-case, and I'm already having enough issues with the reactivity that I didn't want to introduce another layer. (I looked at Vue3, which would be great, but neither Vuetify nor bootstrap-vue support it yet). I should have a demo in a couple of days, right now I'm still in refactoring #3... The code is up on github, so if anyone is eager I can point to it (or you can find it).

2 Likes

Tried new uibuilder node on a different system and got the same result (same result on 2 Pi's & a Ubuntu VM on Windows all set up using standard script.)

Installed uibuilder on a Ubuntu VM in Windows set up with your Alternate Installer (completely new install of uibuilder) and got the same result;

Note that this page is only accessible to users with Node-RED admin authority.

Instance Information for 'test'
The node id for this instance	518e64e1.50572c
This can be used to search for the node in the Editor.
Filing system path to front-end resources	/home/pi/Documents/nrdevelopment/data/uibuilder/test
Contains all of your UI code and other resources. Folders and files can be viewed, edited, created and deleted using the "Edit Files" button. You MUST keep at least the src and dist folders otherwise things may not work.
URL for the front-end resources	./test/
Index.html page will be shown if you click.
Node-RED userDir folder	/home/pi/Documents/nrdevelopment/data
Also the location for any installed vendor resources (installed library packages) and your other nodes.
URL for vendor resources	../uibuilder/vendor/
See the Detailed Information Page for more details.
Filing system path to common (shared) front-end resources	/home/pi/Documents/nrdevelopment/data/uibuilder/common
Resource files in this folder are accessible from the main URL.
Filing system path to common uibuilder configuration resource files	/home/pi/Documents/nrdevelopment/data/uibuilder/.config
Contains the package list, master package list, authentication and authorisation middleware.
Filing system path to uibuilder master template files	/home/pi/Documents/nrdevelopment/data/node_modules/node-red-contrib-uibuilder/templates
These are copied to any new instance of the uibuilder node. If you keep the copy flag turned on they are re-copied if deleted.
uibuilder version	3.3.1
Node-RED version	1.3.4
Minimum version required by uibuilder is >=1.0.0
Node.js version	12.22.1
Minimum version required by uibuilder is >=10.0
Node Instance Configuration Items
Shows the internal configuration.

_wireCount	0
allowScripts	false
allowStyles	false
copyIndex	true
credentials	{}
customFolder	/home/pi/Documents/nrdevelopment/data/uibuilder/test
fwdInMessages	false
id	518e64e1.50572c
ioChannels	undefined
ioClientsCount	undefined
ioNamespace	undefined
name	
rcvMsgCount	undefined
sessionLength	432000
showfolder	false
tokenAutoExtend	false
topic	
type	uibuilder
url	test
useSecurity	false
wires	,

I'm at a loss. Nobody else has reported this. Do the installations work as expected?

Yes, all of the many examples I have work as expected. Trust me to be different.

A copy of the Detailed Information page for one of the installations is below. Not sure that it helps though (- Express stuff)

uibuilder Detailed Information Page
Note that this page is only accessible to users with Node-RED admin authority.

Index of uibuilder pages
'Folders' refer to locations on your Node-RED's server. 'Paths' refer to URL's in the browser.

URL	Source Node Instance (2)	Server Filing System Folder
database	fc20799e.c25e98	/home/pi/.node-red/uibuilder/database
ui_knobs	b2ec14b3.c98ff8	/home/pi/.node-red/uibuilder/ui_knobs
kanban	5de49930.c869f8	/home/pi/.node-red/uibuilder/kanban
Notes:

Each instance of uibuilder uses its own socket.io namespace that matches httpNodeRoot/url. You can use this to manually send messages to your user interface.
Paste the Source Node Instance into the search feature in the Node-RED admin ui to find the instance. The "Filing System Folder" shows you where the front-end (client browser) code lives.
Vendor Client Libraries
You can include these libraries in any uibuilder served web page. Note though that you need to find out the correct file and relative folder either by looking on your Node-RED server in the location shown or by looking at the packages source online.

Package	Version	uibuilder URL (1)	Browser Entry Point (est.) (2)	Server Filing System Folder
socket.io	2.4.1	../uibuilder/vendor/socket.io	../uibuilder/vendor/socket.io/socket.io.js	/home/pi/.node-red/node_modules/socket.io
jquery	3.6.0	../uibuilder/vendor/jquery	../uibuilder/vendor/jquery/dist/jquery.js	/home/pi/.node-red/node_modules/jquery
vue	2.6.12	../uibuilder/vendor/vue	../uibuilder/vendor/vue/dist/vue.js	/home/pi/.node-red/node_modules/vue
bootstrap	4.5.3	../uibuilder/vendor/bootstrap	../uibuilder/vendor/bootstrap/dist/js/bootstrap.js	/home/pi/.node-red/node_modules/bootstrap
bootstrap-vue	2.21.2	../uibuilder/vendor/bootstrap-vue	../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.common.js	/home/pi/.node-red/node_modules/bootstrap-vue
Notes:

Always use relative URL's. All vendor URL's start ../uibuilder/vendor/, all uibuilder and custom file URL's start ./.
Using relative URL's saves you from needing to worry about http(s), ip names/addresses and port numbers.
The 'Main Entry Point' shown is usually a JavaScript file that you will want in your index.html. However, because this is reported by the authors of the package, it may refer to something completely different, uibuilder has no way of knowing. Treat it as a hint rather than absolute truth. Check the packages documentation for the correct library files to load.
Configuration
uibuilder
uibuilder Version	3.3.1	
uib.rootFolder	/home/pi/.node-red/uibuilder	All uibuilder data lives here
uib.configFolder	/home/pi/.node-red/uibuilder/.config	uibuilder Global Configuration Folder
uib.commonFolder	/home/pi/.node-red/uibuilder/common	Used for loading common resources between multiple uibuilder instances
Common URL	../uibuilder/common	The common folder maps to this URL
uib_socketPath	/uibuilder/vendor/socket.io	Unique path given to Socket.IO to ensure isolation from other Nodes that might also use it
uib.masterPackageListFilename	masterPackageList.json	Holds a list of npm packages automatically recognised, uibuilder will add URL's for these
uib.packageListFilename	packageList.json	The list of npm packages actually being served
uib.masterTemplateFolder	/home/pi/.node-red/node_modules/node-red-contrib-uibuilder/templates	The source templates, copied to any new instance
uib.masterTemplate	vue	Which master template is in use
Configuration Files
All are kept in the master configuration folder: /home/pi/.node-red/uibuilder/.config

masterPackageList.json
Holds a list of npm packages automatically recognised, uibuilder will add URL's for these.
packageList.json
The list of npm packages actually installed and being served.
sioUse.js
Custom Socket.IO Middleware file, also uibMiddleware.js.
uibMiddleware.js
Custom ExpressJS Middleware file.
Node-RED
See the <userDir>/settings.js file and the Node-RED documentation for details.

userDir	/home/pi/.node-red
httpNodeRoot	/
Node-RED Version	1.3.4
Min. Version Required by uibuilder	>=1.0.0
Node.js
Version	14.16.1
Min. version required by uibuilder	>=10.0

Brilliant work @TotallyInformation!

Can't believe you find the time to keep evolving this from what was such a great base to start with.

2 Likes