node-red-contrib-context-editor
Version:
Context Editor
90 lines (73 loc) • 3.21 kB
JavaScript
const serveStatic = require('serve-static');
const path = require('path');
const jsondiffpatch = require('jsondiffpatch');
const nodeName = path.basename(__filename).split('.')[0];
// NOTE(alonam) a little trick to require the same "node-red" API to give private access to our own modulesContext.
const PRIVATERED = (function requireExistingNoderedInstance() {
for(const child of require.main.children) {
if(child.filename.endsWith('red.js')) {
return require(child.filename);
}
}
// In case node-red was not required before, just require it
return require('node-red');
})();
module.exports = function(RED) {
RED.httpAdmin.use(`/${nodeName}/static`, serveStatic(path.join(__dirname, "static")));
RED.httpAdmin.use(`/${nodeName}/static/jsoneditor`, serveStatic(path.join(__dirname, "node_modules", "jsoneditor", "dist")));
RED.httpAdmin.use(`/${nodeName}/static/jsondiffpatch`, serveStatic(path.join(__dirname, "node_modules", "jsondiffpatch", "dist")));
RED.httpAdmin.get(`/${nodeName}/flows`, function (req, res) {
const workspaces = [];
RED.nodes.eachNode(function (n) {
if (n.type === 'tab') {
workspaces.push({id: n.id, label: n.label});
}
});
res.send(workspaces);
});
function getFlowContextFullObject(flowId) {
const flowContext = PRIVATERED.nodes.getContext(null, flowId).flow;
const flowContextFullObject = {};
flowContext.keys(undefined, (__, keys)=>{
for(const key of keys) {
flowContextFullObject[key] = flowContext.get(key);
}
});
return flowContextFullObject;
}
RED.httpAdmin.patch(`/${nodeName}/flowContext/:id`, async function (req, res) {
try {
const flowContextObject = getFlowContextFullObject(req.params.id);
const originalFlowObjectKeys = Object.keys(flowContextObject);
const delta = req.body;
jsondiffpatch.patch(
flowContextObject,
delta
);
const flowContext = PRIVATERED.nodes.getContext(null, req.params.id).flow;
const promises = [];
// Inserting & Updating keys
for(const key of Object.keys(flowContextObject)) {
promises.push(new Promise(function (resolve) {
flowContext.set(key, flowContextObject[key], 'flow', resolve);
}));
}
// Deleting keys
for(const key of originalFlowObjectKeys) {
if(!flowContextObject.hasOwnProperty(key)) {
promises.push(new Promise(function (resolve) {
flowContext.set(key, undefined, 'flow', resolve);
}));
}
}
await Promise.all(promises);
res.send({ok:true});
} catch(e) {
res.status(404).send(e);
}
})
RED.httpAdmin.get(`/${nodeName}/flowContext/:id`, function (req, res) {
const flowContextFullObject = getFlowContextFullObject(req.params.id);
res.send(flowContextFullObject);
});
};