node-red-contrib-prib-functions
Advanced tools
Comparing version 0.9.5 to 0.10.0
@@ -8,36 +8,35 @@ const logger = new (require("node-red-contrib-logger"))("append"); | ||
module.exports = function (RED) { | ||
function appendNode(config) { | ||
var node=this, cnt=0, loadCnt=0, errCnt=0; | ||
RED.nodes.createNode(node, config); | ||
node.name = config.name; | ||
node.files = config.files; | ||
node.data=""; | ||
for (const file of node.files) { | ||
if (file.type=="text") { | ||
node.data+=file.value; | ||
continue; | ||
} | ||
if (file.type=="file") { | ||
node.log("loading: "+file.value); | ||
node.data+=fs.readFileSync(file.value); | ||
continue; | ||
} | ||
try{ | ||
var filename= require.resolve(file.value); | ||
node.log("loading: "+filename); | ||
node.data+=fs.readFileSync(filename); | ||
} catch(ex) { | ||
logger.send("not found require") | ||
node.error("require "+file.value+" "+ex); | ||
errCnt++; | ||
} | ||
} | ||
node.status({fill:errCnt<1?"green":"red",shape:"ring",text:"initially loaded: "+loadCnt+" errors: "+errCnt}); | ||
node.on("input", function(msg) { | ||
msg.payload+=node.data; | ||
node.status({fill:"green",shape:"ring",text:"processed "+(++cnt) + " errors: "+errCnt}); | ||
function appendNode(config) { | ||
var node=this, cnt=0, loadCnt=0, errCnt=0; | ||
RED.nodes.createNode(node, config); | ||
node.name = config.name; | ||
node.files = config.files; | ||
node.data=""; | ||
for (const file of node.files) { | ||
if (file.type=="text") { | ||
node.data+=file.value; | ||
continue; | ||
} else if (file.type=="file") { | ||
node.log("loading: "+file.value); | ||
node.data+=fs.readFileSync(file.value); | ||
continue; | ||
} | ||
try{ | ||
var filename= require.resolve(file.value); | ||
node.log("loading: "+filename); | ||
node.data+=fs.readFileSync(filename); | ||
} catch(ex) { | ||
logger.send("not found require") | ||
node.error("require "+file.value+" "+ex); | ||
errCnt++; | ||
} | ||
} | ||
node.status({fill:errCnt<1?"green":"red",shape:"ring",text:"initially loaded: "+loadCnt+" errors: "+errCnt}); | ||
node.on("input", function(msg) { | ||
msg.payload+=node.data; | ||
node.status({fill:"green",shape:"ring",text:"processed "+(++cnt) + " errors: "+errCnt}); | ||
node.send(msg); | ||
}); | ||
} | ||
RED.nodes.registerType(logger.label,appendNode); | ||
}); | ||
} | ||
RED.nodes.registerType(logger.label,appendNode); | ||
}; |
{ | ||
"name": "node-red-contrib-prib-functions", | ||
"version": "0.9.5", | ||
"version": "0.10.0", | ||
"description": "Node-RED added node functions.", | ||
@@ -5,0 +5,0 @@ "dependencies": { |
@@ -178,2 +178,8 @@ # [node-red-contrib-prib-functions][2] | ||
0.10.0 Many fixes to transform. Array and csv to various forms work. Added test to validate. | ||
Improved test to allow for escape to put special characters into a string. | ||
0.9.6 Enhance transform with csv ignore lead or trailing lines. | ||
Add Array and CSV to Messages. Add in topic override | ||
0.9.5 Enhance transform with path and setting source and target | ||
@@ -180,0 +186,0 @@ |
@@ -1,6 +0,25 @@ | ||
const nodeLabel="test"; | ||
const Logger = require("node-red-contrib-logger"); | ||
const logger = new Logger(nodeLabel); | ||
logger.sendInfo("Copyright 2020 Jaroslav Peter Prib"); | ||
const logger = new (require("node-red-contrib-logger"))("test").sendInfo("Copyright 2020 Jaroslav Peter Prib"); | ||
if(String.prototype.escapeSpecialChars) | ||
logger.warn("String.prototype.escapeSpecialChars already defined"); | ||
else | ||
String.prototype.escapeSpecialChars=function() { | ||
return this.replace(/\\n/g,"\n") | ||
.replace(/\\'/g,"\'") | ||
.replace(/\\"/g,'\"') | ||
.replace(/\\&/g,"\&") | ||
.replace(/\\r/g,"\r") | ||
.replace(/\\t/g,"\t") | ||
.replace(/\\b/g,"\b") | ||
.replace(/\\f/g,"\f"); | ||
}; | ||
function escapeSpecialChars(s){ | ||
try{ | ||
return s?s.escapeSpecialChars():s; | ||
} catch(e) { | ||
const error="escapeSpecialChars expecting string found "+(typeof s); | ||
logger.error(error); | ||
throw Error(error); | ||
} | ||
} | ||
function setError(msg,node,err) { | ||
@@ -25,81 +44,93 @@ msg._test.error=err; | ||
} | ||
return true; | ||
return true; | ||
} | ||
module.exports = function(RED) { | ||
"use strict"; | ||
function testNode(n) { | ||
RED.nodes.createNode(this,n); | ||
let node=Object.assign(this,n); | ||
try{ | ||
node.getData= eval("((msg,node)=>"+(node.resultProperty||"msg.payload")+")"); | ||
node.status({fill:"green",shape:"ring",text:"Ready"}); | ||
} catch(e) { | ||
node.error(e); | ||
node.status({fill:"red",shape:"ring",text:"Invalid setup "+e.toString()}); | ||
} | ||
this.on("input",function(msg) { | ||
if(msg._test) { | ||
if(msg._test.id!==node.id) { | ||
setError(msg,node,"Sent by another test "+msg._test.id); | ||
} else if(!equalObjects(node.getData(msg,node),msg._test.result)) { | ||
msg._test.testedValue=node.getData(msg,node); | ||
setError(msg,node,"Test failed"); | ||
} else { | ||
node.status({fill:"green",shape:"ring",text:"Success"}); | ||
} | ||
return; | ||
} | ||
node.status({fill:"yellow",shape:"ring",text:"waiting on response"}); | ||
msg._test={ | ||
id:node.id, | ||
result:RED.util.evaluateNodeProperty(this.result,this.resultType,this,msg) | ||
}; | ||
msg.topic = this.topic; | ||
if(["flow","global"].includes(this.payloadType)) { | ||
RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg, function(err,res) { | ||
if (err) { | ||
node.error(err,msg); | ||
} else { | ||
msg.payload = res; | ||
node.send(msg); | ||
} | ||
}); | ||
} else { | ||
try { | ||
if ( (this.payloadType == null && this.payload === "") || this.payloadType === "date") { | ||
msg.payload = Date.now(); | ||
} else if (this.payloadType == null) { | ||
msg.payload = this.payload; | ||
} else if (this.payloadType === 'none') { | ||
msg.payload = ""; | ||
} else { | ||
msg.payload = RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg); | ||
} | ||
this.send(msg); | ||
msg = null; | ||
} catch(err) { | ||
this.error(err,msg); | ||
} | ||
} | ||
}); | ||
} | ||
"use strict"; | ||
function testNode(n) { | ||
RED.nodes.createNode(this,n); | ||
let node=Object.assign(this,n); | ||
try{ | ||
node.getData=eval("((msg,node)=>"+(node.resultProperty||"msg.payload")+")"); | ||
if(node.escapeString && node.resultType=="str") { | ||
node.getData=eval("((msg,node)=>escapeSpecialChars("+(node.resultProperty||"msg.payload")+"))"); | ||
} | ||
node.status({fill:"green",shape:"ring",text:"Ready"}); | ||
} catch(e) { | ||
node.error(e); | ||
node.status({fill:"red",shape:"ring",text:"Invalid setup "+e.toString()}); | ||
} | ||
node.payloadEscape=(node.payloadType=="str"&&node.escapeString); | ||
node.equalObjects=node.resultType=="re"?(value,regex)=>RegExp(regex).test(value):equalObjects; | ||
node.on("input",function(msg) { | ||
if(msg._test) { | ||
try{ | ||
if(msg._test.id!==node.id) { | ||
setError(msg,node,"Sent by another test "+msg._test.id); | ||
} else if(!equalObjects(node.getData(msg,node),msg._test.result)) { | ||
msg._test.testedValue=node.getData(msg,node); | ||
setError(msg,node,"Test failed"); | ||
} else { | ||
node.status({fill:"green",shape:"ring",text:"Success"}); | ||
delete msg._test; | ||
node.send([null,null,msg]); | ||
} | ||
} catch(ex){ | ||
setError(msg,node,"Test failed on get data "+ex.message); | ||
} | ||
return; | ||
} | ||
node.status({fill:"yellow",shape:"ring",text:"waiting on response"}); | ||
const result=RED.util.evaluateNodeProperty(node.result,node.resultType,node,msg); | ||
msg._test={ | ||
id:node.id, | ||
result:node.escapeString&&node.resultType=="str"?escapeSpecialChars(result):result | ||
}; | ||
msg.topic=node.topic; | ||
if(["flow","global"].includes(node.payloadType)) { | ||
RED.util.evaluateNodeProperty(node.payload,node.payloadType,node,msg, function(err,res) { | ||
if (err) { | ||
node.error(err,msg); | ||
} else { | ||
msg.payload=res; | ||
node.send(msg); | ||
} | ||
}); | ||
} else { | ||
try { | ||
if ( (node.payloadType == null && node.payload === "") || node.payloadType === "date") { | ||
msg.payload = Date.now(); | ||
} else if (node.payloadType == null) { | ||
msg.payload = node.payload; | ||
} else if (node.payloadType === 'none') { | ||
msg.payload = ""; | ||
} else { | ||
msg.payload=RED.util.evaluateNodeProperty(this.payload,node.payloadType,node,msg); | ||
if(node.payloadEscape) msg.payload=msg.payload.escapeSpecialChars(); | ||
} | ||
node.send(msg); | ||
msg = null; | ||
} catch(err) { | ||
node.error(err,msg); | ||
} | ||
} | ||
}); | ||
} | ||
RED.nodes.registerType(nodeLabel,testNode); | ||
RED.httpAdmin.post("/test/:id", RED.auth.needsPermission("test.write"), function(req,res) { | ||
let node = RED.nodes.getNode(req.params.id); | ||
if (node) { | ||
try { | ||
node.receive(); | ||
res.sendStatus(200); | ||
} catch(err) { | ||
res.sendStatus(500); | ||
node.error(RED._("inject.failed",{error:err.toString()})); | ||
} | ||
} else { | ||
res.sendStatus(404); | ||
} | ||
}); | ||
RED.nodes.registerType(logger.label,testNode); | ||
RED.httpAdmin.post("/test/:id", RED.auth.needsPermission("test.write"), function(req,res) { | ||
let node = RED.nodes.getNode(req.params.id); | ||
if (node) { | ||
try { | ||
node.receive(); | ||
res.sendStatus(200); | ||
} catch(err) { | ||
res.sendStatus(500); | ||
node.error(RED._("inject.failed",{error:err.toString()})); | ||
} | ||
} else { | ||
res.sendStatus(404); | ||
} | ||
}); | ||
} |
@@ -1,18 +0,56 @@ | ||
const nodeLabel="transform"; | ||
const Logger = require("node-red-contrib-logger"); | ||
const logger = new Logger(nodeLabel); | ||
const logger = new (require("node-red-contrib-logger"))("transform"); | ||
logger.sendInfo("Copyright 2020 Jaroslav Peter Prib"); | ||
let ISO8583,ISO8583message; | ||
const regexLines=/(?!\B"[^"]*)\n(?![^"]*"\B)/g; | ||
//const regexLines=/(?!\B"[^"]*)\n(?![^"]*"\B)/g; | ||
const regexCSV=/,(?=(?:(?:[^"]*"){2})*[^"]*$)/; | ||
const path = require('path'); | ||
function removeQuotes(d){ | ||
return d.length>1 && d.startsWith('"') && d.endsWith('"') ? d.slice(1,-1) : d; | ||
function removeQuotes(data){ | ||
try{ | ||
const d=data.trim(); | ||
if(d.length>1 && d.startsWith('"') && d.endsWith('"')) return d.slice(1,-1); | ||
const r=Number(d); | ||
return r?r:d; | ||
} catch(ex) { | ||
return data; | ||
} | ||
} | ||
function csvLines(data,skipLeading=0,skipTrailing=0) { | ||
if(logger.active) logger.send({label:"csvLines",skipLeading:skipLeading,skipTrailing:skipTrailing}); | ||
let lines=data.split(/[\r\n]+/g),skip=skipLeading; | ||
while(skip--) lines.shift(); | ||
skip=skipTrailing; | ||
while(skip--) lines.pop(); | ||
return lines; | ||
} | ||
function array2tag(a,t,tf){ | ||
const ts="<"+t+">",te="</"+t+">" | ||
return a.reduce((a,c)=>a+=ts+tf(c)+te,""); | ||
} | ||
const functions={ | ||
ArrayToCSV: (data)=>data.map(x=>JSON.stringify(x)).join("\n"), | ||
ArrayToISO8385: (data)=>ISO8583message.packSync(data), | ||
CSVToArray: (data)=>{ | ||
let lines = data.split(regexLines); | ||
ArrayToCSV: (RED,node,msg,data)=>data.map(c=>JSON.stringify(c)).join("\n"), | ||
ArrayToHTML: (RED,node,msg,data)=> | ||
"<table>"+ array2tag(data,"tr",(c)=>( | ||
Array.isArray(c)? | ||
array2tag(c,"td",(cc)=> | ||
Array.isArray(cc)? | ||
functions.ArrayToHTML(RED,node,msg,cc): | ||
"<![CDATA["+cc+"]]>" | ||
): | ||
"<![CDATA["+c+"]]>" | ||
) | ||
)+"</table>", | ||
ArrayToISO8385: (RED,node,msg,data)=>ISO8583message.packSync(data), | ||
ArrayToMessages: (RED,node,msg,data)=>{ | ||
if(logger.active) logger.send({label:"ArrayToMessages",arraySize:data.length}); | ||
data.map((c,i)=>{ | ||
const newMsg=RED.util.cloneMessage(msg); | ||
newMsg.payload=c; | ||
newMsg._msgid=newMsg._msgid+":"+i; | ||
if(node.hasNewTopic) newMsg.topic=node.topicFunction(RED,node,newMsg); | ||
node.send(newMsg); | ||
}) | ||
}, | ||
CSVToArray: (RED,node,msg,data)=>{ | ||
let lines=csvLines(data,node.skipLeading,node.skipTrailing); | ||
lines.forEach((value, idx) => { | ||
@@ -23,8 +61,27 @@ lines[idx]=value.split(regexCSV).map((c)=>removeQuotes(c)); | ||
}, | ||
CSVWithHeaderToArray: (data)=>functions.CSV2Array(data).shift(), | ||
CSVWithHeaderToJSON: (data)=>{ | ||
let lines = data.split(regexLines); | ||
var headers=lines.pop().split(regexCSV); | ||
CSVToHTML: (RED,node,msg,data)=> | ||
"<table>"+ array2tag(csvLines(data,node.skipLeading,node.skipTrailing),"tr",(line)=> | ||
array2tag(line.split(regexCSV),"td",(c)=>"<![CDATA["+removeQuotes(c)+"]]>") | ||
)+"</table>", | ||
CSVToMessages: (RED,node,msg,data)=>{ | ||
functions.ArrayToMessages(RED,node,msg,csvLines(data,this.skipLeading,this.skipTrailing)); | ||
}, | ||
CSVWithHeaderToArray: (RED,node,msg,data)=>{ | ||
let r=functions.CSVToArray(RED,node,msg,data); | ||
r.shift(); | ||
return r; | ||
}, | ||
CSVWithHeaderToHTML: (RED,node,msg,data)=>{ | ||
let lines=csvLines(data,node.skipLeading,node.skipTrailing); | ||
const header=array2tag(lines.shift().split(regexCSV),"th",(c)=>"<![CDATA["+removeQuotes(c)+"]]>"); | ||
return "<table><tr>"+header+"</tr>"+array2tag(lines,"tr",(line)=> | ||
array2tag(line.split(regexCSV),'td',(c)=>"<![CDATA["+removeQuotes(c)+"]]>") | ||
)+"</table>" | ||
}, | ||
CSVWithHeaderToJSON: (RED,node,msg,data)=>{ | ||
let lines=csvLines(data,node.skipLeading,node.skipTrailing); | ||
let header=lines.shift().split(regexCSV); | ||
if(logger.active) logger.send({label:"CSVWithHeaderToJSON",header:header}); | ||
lines.forEach((value, idx) => { | ||
var o={}; | ||
let o={}; | ||
value.split(regexCSV).forEach((c,i)=>{ | ||
@@ -37,4 +94,4 @@ o[header[i]]=removeQuotes(c); | ||
}, | ||
ISO8385ToArray: (data)=>ISO8583message.unpackSync(data, data.length), | ||
ISO8385ToJSON: (data)=>{ | ||
ISO8385ToArray: (RED,node,msg,data)=>ISO8583message.unpackSync(data, data.length), | ||
ISO8385ToJSON: (RED,node,msg,data)=>{ | ||
let j={},d=ISO8583message.unpackSync(data, data.length); | ||
@@ -46,3 +103,3 @@ d.forEach((r)=>{ | ||
}, | ||
JSONToISO8385: (data)=>{ | ||
JSONToISO8385: (RED,node,msg,data)=>{ | ||
var d=[]; | ||
@@ -53,7 +110,7 @@ Object.getOwnPropertyNames(data).forEach((v)=>d.push([ISO8583BitMapName[v].id,data[v]])); | ||
}, | ||
JSONToArray: (data)=>{ | ||
JSONToArray: (RED,node,msg,data)=>{ | ||
if(data instanceof Object){ | ||
let a=[]; | ||
for(let p in data) { | ||
a.push([p,functions.JSONToArray(data[p])]); | ||
a.push([p,functions.JSONToArray(RED,node,msg,data[p])]); | ||
} | ||
@@ -64,8 +121,5 @@ return a; | ||
}, | ||
JSONToHTML: (data,level=0)=>{ | ||
JSONToHTML: (RED,node,msg,data,level=0)=>{ | ||
if(Array.isArray(data)) { | ||
if(data.length) { | ||
return "<table><tr>"+data.map((r)=>functions.JSONToHTML(r,++level)).join("</tr><tr>")+"</tr><table>" | ||
} | ||
return ""; | ||
return data.length?"<table><tr>"+data.map((r)=>functions.JSONToHTML(RED,node,msg,r,++level)).join("</tr><tr>")+"</tr><table>":""; | ||
} | ||
@@ -75,3 +129,3 @@ if(data instanceof Object){ | ||
for(let p in data) { | ||
a.push("<td style='vertical-align: top;'>"+escape(p)+":</td><td>"+functions.JSONToHTML(data[p],++level)+"</td>"); | ||
a.push("<td style='vertical-align: top;'>"+escape(p)+":</td><td>"+functions.JSONToHTML(RED,node,msg,data[p],++level)+"</td>"); | ||
} | ||
@@ -82,33 +136,48 @@ return "<table><tr>"+a.join("</tr><tr>")+"</tr><table>"; | ||
}, | ||
JSONToString: (data)=>JSON.stringify(data), | ||
StringToJSON: (data)=>JSON.parse(data), | ||
pathToBasename: (data)=>path.basename(data), | ||
pathToDirname: (data)=>path.dirname(data), | ||
pathToExtname: (data)=>path.extname(data), | ||
pathToFormat: (data)=>path.format(data), | ||
pathToIsAbsolute: (data)=>path.isAbsolute(data), | ||
pathToJoin: (...data)=>path.join(...data), | ||
pathToParse: (data)=>path.parse(data), | ||
pathToNormalize: (data)=>path.normalize(data), | ||
pathToResolve: (data)=>path.resolve(data) | ||
JSONToString: (RED,node,msg,data)=>JSON.stringify(data), | ||
StringToJSON: (RED,node,msg,data)=>JSON.parse(data), | ||
pathToBasename: (RED,node,msg,data)=>path.basename(data), | ||
pathToDirname: (RED,node,msg,data)=>path.dirname(data), | ||
pathToExtname: (RED,node,msg,data)=>path.extname(data), | ||
pathToFormat: (RED,node,msg,data)=>path.format(data), | ||
pathToIsAbsolute: (RED,node,msg,data)=>path.isAbsolute(data), | ||
pathToJoin: (RED,node,msg,...data)=>path.join(...data), | ||
pathToParse: (RED,node,msg,data)=>path.parse(data), | ||
pathToNormalize: (RED,node,msg,data)=>path.normalize(data), | ||
pathToResolve: (RED,node,msg,data)=>path.resolve(data) | ||
}; | ||
function evalFunction(id,mapping){ | ||
try{ | ||
return eval(mapping); | ||
} catch(ex) { | ||
throw Error(id+" "+ex.message); | ||
} | ||
} | ||
module.exports = function (RED) { | ||
function transformNode(n) { | ||
RED.nodes.createNode(this,n); | ||
var node=Object.assign(this,n); | ||
let node=Object.assign(this,n,{RED:RED}); | ||
node.sendInFunction=["Messages"].includes(node.actionTarget); | ||
node.hasNewTopic=![null,"","msg.topic"].includes(node.topicProperty); | ||
const sourceMap="(RED,node,msg)=>"+(node.sourceProperty||"msg.payload"), | ||
targetMap="(RED,node,msg,data)=>{"+(node.targetProperty||"msg.payload")+"=data;"+ | ||
(node.sendInFunction && node.hasNewTopic? "" : "msg.topic=node.topicFunction(RED,node,msg);")+ | ||
(node.sendInFunction ? "" : "node.send(msg);" )+ | ||
"}", | ||
topicMap="(RED,node,msg)=>"+(node.topicProperty||"msg.topic"); | ||
logger.sendInfo({label:"mappings",source:sourceMap,target:targetMap,topicMap:topicMap}); | ||
try{ | ||
node.getData=eval("((msg,node)=>"+(node.sourceProperty||"msg.payload")+")"); | ||
node.setData=eval("((msg,node,data)=>"+(node.targetProperty||"msg.payload")+"=data)"); | ||
} catch(e) { | ||
node.error(e); | ||
node.status({fill:"red",shape:"ring",text:"Invalid setup "+e.toString()}); | ||
node.getData=evalFunction("source",sourceMap); | ||
node.setData=evalFunction("target",targetMap); | ||
node.topicFunction=evalFunction("topic",topicMap); | ||
} catch(ex) { | ||
node.error(ex); | ||
node.status({fill:"red",shape:"ring",text:"Invalid setup "+ex.message}); | ||
return; | ||
} | ||
} | ||
if(node.actionSource=="ISO8583" || node.actionTarget=="ISO8583") { | ||
if(!ISO8583) { | ||
try{ | ||
ISO8583 = require('iso-8583'); | ||
ISO8583message = ISO8583.Message(); | ||
ISO8583=require('iso-8583'); | ||
ISO8583message=ISO8583.Message(); | ||
node.log("loaded iso-8583"); | ||
@@ -134,13 +203,13 @@ } catch (e) { | ||
try{ | ||
// msg.payload=node.transform.apply(node,[node.getData(msg,node)]); | ||
node.setData(msg,node,node.transform.apply(node,[node.getData(msg)])); | ||
} catch (e) { | ||
node.error(node.actionSource+" to "+node.actionTarget + " " +e); | ||
node.setData(RED,node,msg,node.transform(RED,node,msg,node.getData(RED,node,msg))); | ||
} catch (ex) { | ||
msg.error=node.actionSource+" to "+node.actionTarget + " " +ex.message; | ||
node.error(msg.error); | ||
this.status({fill:"red",shape:"ring",text:"Error(s)"}); | ||
node.send([null,msg]); | ||
return; | ||
} | ||
node.send(msg); | ||
}); | ||
} | ||
RED.nodes.registerType(nodeLabel,transformNode); | ||
RED.nodes.registerType(logger.label,transformNode); | ||
}; | ||
@@ -147,0 +216,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1100754
49
1387
226