node-red-contrib-prib-functions 0.18.0 → 0.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/codeql-analysis.yml +3 -3
- package/.github/workflows/npmpublish.yml +6 -6
- package/.vs/VSWorkspaceState.json +7 -0
- package/.vs/node-red-contrib-prib-functions/v17/.wsuo +0 -0
- package/README.md +22 -19
- package/arima/index.js +18 -0
- package/dataAnalysis/arrayAllRowsSwap.js +15 -0
- package/dataAnalysis/arrayCompareToPrecision.js +34 -0
- package/dataAnalysis/arrayDifference.js +14 -0
- package/dataAnalysis/arrayDifferenceSeasonal.js +15 -0
- package/dataAnalysis/arrayDifferenceSeasonalSecondOrder.js +20 -0
- package/dataAnalysis/arrayDifferenceSecondOrder.js +14 -0
- package/dataAnalysis/arrayForEachRange.js +38 -0
- package/dataAnalysis/arrayOverlay.js +13 -0
- package/dataAnalysis/arrayProduct.js +11 -0
- package/dataAnalysis/arrayRandom.js +14 -0
- package/dataAnalysis/arrayReduceRange.js +11 -0
- package/dataAnalysis/arrayScale.js +11 -0
- package/dataAnalysis/arraySum.js +11 -0
- package/dataAnalysis/arraySumSquared.js +11 -0
- package/dataAnalysis/arraySwap.js +11 -0
- package/dataAnalysis/dataAnalysis.html +31 -14
- package/dataAnalysis/dataAnalysis.js +10 -1
- package/dataAnalysis/generateMatrixFunction.js +89 -0
- package/dataAnalysis/generateVectorFunction.js +25 -0
- package/dataAnalysis/pca.js +546 -0
- package/dataAnalysis/svd.js +239 -0
- package/documentation/loadInjector.png +0 -0
- package/echart/echart.html +68 -0
- package/echart/echart.js +85 -0
- package/echart/icons/chart-671.png +0 -0
- package/echart/lib/echarts.js +95886 -0
- package/lib/Chart.js +177 -0
- package/lib/Column.js +99 -0
- package/lib/GraphDB.js +14 -0
- package/lib/Table.js +185 -0
- package/lib/objectExtensions.js +361 -0
- package/matrix/matrix.js +50 -50
- package/matrix/matrixNode.html +144 -154
- package/matrix/matrixNode.js +26 -9
- package/monitor/BarGauge.js +8 -0
- package/monitor/Dataset.js +29 -0
- package/monitor/DialGauge.js +109 -0
- package/monitor/DialNeedle.js +36 -0
- package/monitor/Format.js +74 -0
- package/monitor/centerElement.js +14 -0
- package/monitor/compareElements.js +95 -0
- package/monitor/defs.js +23 -0
- package/monitor/extensions.js +906 -0
- package/monitor/functions.js +36 -0
- package/monitor/json2xml.js +103 -0
- package/monitor/monitorSystem.html +198 -0
- package/monitor/monitorSystem.js +322 -0
- package/monitor/svgHTML.js +179 -0
- package/monitor/svgObjects.js +64 -0
- package/package.json +31 -8
- package/test/00-objectExtensions.js +94 -0
- package/test/01-base.js +88 -0
- package/test/04-tables.js +33 -0
- package/test/data/.config.nodes.json +608 -0
- package/test/data/.config.nodes.json.backup +608 -0
- package/test/data/.config.runtime.json +4 -0
- package/test/data/.config.runtime.json.backup +3 -0
- package/test/data/.config.users.json +21 -0
- package/test/data/.config.users.json.backup +21 -0
- package/test/data/.flow.json.backup +3433 -0
- package/test/data/float32vector10.npy +0 -0
- package/test/data/flow.json +3433 -0
- package/test/data/int2matrix2x3.npy +0 -0
- package/test/data/package-lock.json +158 -0
- package/test/data/package.json +11 -0
- package/test/data/settings.js +544 -0
- package/test/dataAnalysisExtensions.js +472 -0
- package/test/dataAnalysisPCA.js +54 -0
- package/test/dataAnalysisSVD.js +31 -0
- package/test/euclideanDistance.js +2 -2
- package/test/matrix/02base.js +36 -0
- package/test/transformNumPy.js +132 -0
- package/testing/data/countries.csv +250 -0
- package/testing/hostAvailable.html +0 -2
- package/testing/load-injector.html +76 -21
- package/testing/load-injector.js +35 -54
- package/testing/test.js +1 -0
- package/transform/NumPy.js +303 -0
- package/transform/transform.html +73 -19
- package/transform/transform.js +144 -8
- package/documentation/LoadInjector.JPG +0 -0
package/transform/transform.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const logger = new (require("node-red-contrib-logger"))("transform");
|
|
2
2
|
logger.sendInfo("Copyright 2020 Jaroslav Peter Prib");
|
|
3
|
-
|
|
3
|
+
const CompressionTool = require('compressiontool');
|
|
4
|
+
const NumPy = require("./NumPy.js")
|
|
4
5
|
const regexCSV=/,(?=(?:(?:[^"]*"){2})*[^"]*$)/,
|
|
5
6
|
Buffer=require('buffer').Buffer,
|
|
6
7
|
os=require('os'),
|
|
7
8
|
path=require('path'),
|
|
8
9
|
process=require('process');
|
|
9
|
-
let avsc,snappy,xmlParser,json2xmlParser,XLSX;
|
|
10
|
+
let avsc,snappy,xmlParser,json2xmlParser,XLSX,compressor;
|
|
10
11
|
const {ISO8583BitMapId,ISO8583BitMapName}=require("./ISO8583BitMap");
|
|
11
12
|
let ISO8583,ISO8583message;
|
|
12
13
|
const XMLoptions = {
|
|
@@ -170,6 +171,35 @@ function array2tag(a,t,tf){
|
|
|
170
171
|
const ts="<"+t+">",te="</"+t+">"
|
|
171
172
|
return a.reduce((a,c)=>a+=ts+tf(c)+te,"");
|
|
172
173
|
}
|
|
174
|
+
function Array2csv(node,data){
|
|
175
|
+
if(!(data instanceof Array)) return JSON.stringify(data);
|
|
176
|
+
if(data.length==0) return;
|
|
177
|
+
if(data[0] instanceof Array) {
|
|
178
|
+
return data.map(r=>
|
|
179
|
+
r instanceof Array?r.map(c=>JSON.stringify(c)).join(node.delimiter):JSON.stringify(r)
|
|
180
|
+
).join("\n");
|
|
181
|
+
} else if(data[0] instanceof Object) {
|
|
182
|
+
const properties=[];
|
|
183
|
+
data.forEach(r=>{
|
|
184
|
+
if(typeof r == "object" && ! (r instanceof Array)){
|
|
185
|
+
Object.keys(r).forEach(p=>{
|
|
186
|
+
if(properties.includes(p)) return
|
|
187
|
+
properties.push(p)
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
properties.sort();
|
|
192
|
+
const rows=data.map(r=>{
|
|
193
|
+
if(typeof r == "object" && ! (r instanceof Array)) {
|
|
194
|
+
return properties.map(c=>r[c]||"").join(node.delimiter)
|
|
195
|
+
} else {
|
|
196
|
+
return node.delimiter.repeat(properties.length)+JSON.stringify(r)
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
return properties.join(node.delimiter)+"\n"+rows.join("\n");
|
|
200
|
+
}
|
|
201
|
+
return data .map(r=>JSON.stringify(r)).join("/n");
|
|
202
|
+
}
|
|
173
203
|
const functions={
|
|
174
204
|
ArrayToCSV: (RED,node,msg,data)=>data.map(c=>JSON.stringify(c)).join("\n"),
|
|
175
205
|
ArrayToHTML: (RED,node,msg,data)=>
|
|
@@ -198,6 +228,52 @@ const functions={
|
|
|
198
228
|
ArrayToXLSX:ArrayToXLSX,
|
|
199
229
|
ArrayToXLSXObject:ArrayToXLSXObject,
|
|
200
230
|
AVROToJSON: (RED,node,msg,data)=>node.avroTransformer.fromBuffer(data), // = {kind: 'CAT', name: 'Albert'}
|
|
231
|
+
BufferToCompressed: (RED,node,msg,data)=>compressor.compress(data,
|
|
232
|
+
(compressed)=>{
|
|
233
|
+
node.setData(RED,node,msg,compressed);
|
|
234
|
+
node.send(msg);
|
|
235
|
+
},
|
|
236
|
+
(err)=>{
|
|
237
|
+
error(node,Error(err));
|
|
238
|
+
}
|
|
239
|
+
),
|
|
240
|
+
CompressedToBuffer:(RED,node,msg,data)=>compressor.decompress(data,
|
|
241
|
+
(uncompressed)=>{
|
|
242
|
+
node.setData(RED,node,msg,uncompressed);
|
|
243
|
+
node.send(msg);
|
|
244
|
+
},
|
|
245
|
+
(err)=>{
|
|
246
|
+
error(node,Error(err));
|
|
247
|
+
}
|
|
248
|
+
),
|
|
249
|
+
CompressedToJSON:(RED,node,msg,data)=>compressor.decompress(data,
|
|
250
|
+
(uncompressed)=>{
|
|
251
|
+
try{
|
|
252
|
+
node.setData(RED,node,msg,JSON.parse(uncompressed));
|
|
253
|
+
node.send(msg);
|
|
254
|
+
} catch(ex){
|
|
255
|
+
msg.error=ex.message
|
|
256
|
+
node.setData(RED,node,msg,uncompressed);
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
(err)=>{
|
|
260
|
+
error(node,Error(err));
|
|
261
|
+
}
|
|
262
|
+
),
|
|
263
|
+
CompressedToString:(RED,node,msg,data)=>compressor.decompress(data,
|
|
264
|
+
(uncompressed)=>{
|
|
265
|
+
try{
|
|
266
|
+
node.setData(RED,node,msg,uncompressed.toString());
|
|
267
|
+
node.send(msg);
|
|
268
|
+
} catch(ex){
|
|
269
|
+
msg.error=ex.message;
|
|
270
|
+
node.setData(RED,node,msg,uncompressed);
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
(err)=>{
|
|
274
|
+
error(node,Error(err));
|
|
275
|
+
}
|
|
276
|
+
),
|
|
201
277
|
ConfluenceToJSON: ConfluenceToJSON,
|
|
202
278
|
CSVToArray: (RED,node,msg,data)=>{
|
|
203
279
|
let lines=csvLines(data,node.skipLeading,node.skipTrailing);
|
|
@@ -256,9 +332,18 @@ const functions={
|
|
|
256
332
|
}
|
|
257
333
|
return data;
|
|
258
334
|
},
|
|
259
|
-
JSONToConfluence:JSONToConfluence,
|
|
260
|
-
JSONToCSV: (RED,node,msg,data)=>functions.ArrayToCSV(RED,node,msg,functions.JSONToArray(RED,node,msg,data)),
|
|
261
335
|
JSONToAVRO: (RED,node,msg,data)=>node.avroTransformer.toBuffer(data), // Encoded buffer.
|
|
336
|
+
JSONToCompressed: (RED,node,msg,data)=>compressor.compress(JSON.stringify(data),
|
|
337
|
+
(compressed)=>{
|
|
338
|
+
node.setData(RED,node,msg,compressed);
|
|
339
|
+
node.send(msg);
|
|
340
|
+
},
|
|
341
|
+
(err)=>{
|
|
342
|
+
error(node,Error(err));
|
|
343
|
+
}
|
|
344
|
+
),
|
|
345
|
+
JSONToConfluence:JSONToConfluence,
|
|
346
|
+
JSONToCSV: (RED,node,msg,data)=>Array2csv(node,data),
|
|
262
347
|
JSONToHTML: (RED,node,msg,data,level=0)=>{
|
|
263
348
|
if(Array.isArray(data)) {
|
|
264
349
|
return data.length?"<table><tr>"+data.map((r)=>functions.JSONToHTML(RED,node,msg,r,++level)).join("</tr><tr>")+"</tr><table>":"";
|
|
@@ -290,10 +375,24 @@ const functions={
|
|
|
290
375
|
node.send(newMsg);
|
|
291
376
|
}
|
|
292
377
|
},
|
|
378
|
+
JSONTonpy: (RED,node,msg,data)=>new NumPy(data).toNpyBuffer(),
|
|
379
|
+
JSONToNumPyObject: (RED,node,msg,data)=>new NumPy(data),
|
|
293
380
|
JSONToString: (RED,node,msg,data)=>JSON.stringify(data),
|
|
294
381
|
JSONToXLSX:JSONToXLSX,
|
|
295
382
|
JSONToXLSXObject:JSONToXLSXObject,
|
|
296
383
|
JSONToXML: (RED,node,msg,data)=>json2xmlParser.parse(data),
|
|
384
|
+
npyToJSON: (RED,node,msg,data)=>new NumPy(data).toSerializable(),
|
|
385
|
+
npyToNumPyObject: (RED,node,msg,data)=>new NumPy(data),
|
|
386
|
+
NumPyObjectToJSON: (RED,node,msg,data)=> data.toSerializable(),
|
|
387
|
+
StringToCompressed: (RED,node,msg,data)=>compressor.compress(data,
|
|
388
|
+
(compressed)=>{
|
|
389
|
+
node.setData(RED,node,msg,compressed);
|
|
390
|
+
node.send(msg);
|
|
391
|
+
},
|
|
392
|
+
(err)=>{
|
|
393
|
+
error(node,Error(err));
|
|
394
|
+
}
|
|
395
|
+
),
|
|
297
396
|
StringToJSON: (RED,node,msg,data)=>JSON.parse(data),
|
|
298
397
|
pathToBasename: (RED,node,msg,data)=>path.basename(data),
|
|
299
398
|
pathToDirname: (RED,node,msg,data)=>path.dirname(data),
|
|
@@ -347,6 +446,23 @@ function evalFunction(id,mapping){
|
|
|
347
446
|
function is(node,value){
|
|
348
447
|
return node.actionSource==value||node.actionTarget==value;
|
|
349
448
|
}
|
|
449
|
+
let jsonata;
|
|
450
|
+
function JSONataTransform(data,ok,error){
|
|
451
|
+
/*
|
|
452
|
+
(async () => {
|
|
453
|
+
return result = await expression.evaluate(data);
|
|
454
|
+
})()
|
|
455
|
+
*/
|
|
456
|
+
|
|
457
|
+
this.transformFuncionCompiled.evalFunction(data,{},(error, result) => {
|
|
458
|
+
if(error) {
|
|
459
|
+
console.error(error);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
console.log("Finished with", result);
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
350
466
|
module.exports = function (RED) {
|
|
351
467
|
function transformNode(n) {
|
|
352
468
|
RED.nodes.createNode(this,n);
|
|
@@ -373,11 +489,11 @@ module.exports = function (RED) {
|
|
|
373
489
|
}
|
|
374
490
|
if(logger.active) logger.send({label:"load xml",xmlParserKeys:Object.keys(xmlParser),json2xmlParser:Object.keys(json2xmlParser)});
|
|
375
491
|
}
|
|
376
|
-
node.sendInFunction=["snappy"].includes(node.actionSource)||["Messages"].includes(node.actionTarget);
|
|
492
|
+
node.sendInFunction=["snappy","Compressed"].includes(node.actionSource)||["Messages","Compressed"].includes(node.actionTarget);
|
|
377
493
|
node.hasNewTopic=![null,""].includes(node.topicProperty);
|
|
378
494
|
const sourceMap="(RED,node,msg)=>"+(node.sourceProperty||"msg.payload"),
|
|
379
495
|
sourceDelete="(RED,node,msg)=>{delete "+(node.sourceProperty||"msg.payload")+";}",
|
|
380
|
-
|
|
496
|
+
targetMap="(RED,node,msg,data,index)=>{"+(node.targetProperty||"msg.payload")+"=data;"+
|
|
381
497
|
(node.sendInFunction && node.hasNewTopic? "msg.topic=node.topicFunction(RED,node,msg,data,index);":"")+
|
|
382
498
|
(node.sendInFunction ? "" : "node.send(msg);" )+
|
|
383
499
|
"}",
|
|
@@ -389,13 +505,21 @@ module.exports = function (RED) {
|
|
|
389
505
|
node.topicFunction=evalFunction("topic",topicMap);
|
|
390
506
|
if(is(node,"AVRO")) {
|
|
391
507
|
node.avroTransformer=avsc.Type.forSchema(node.schemaValid);
|
|
508
|
+
} else if(is(node,"Compressed")) {
|
|
509
|
+
compressor=new CompressionTool();
|
|
510
|
+
compressor[node.compressionType]();
|
|
392
511
|
} else if(is(node,"Confluence")) {
|
|
393
512
|
node.schemas={};
|
|
394
513
|
for(const schema in node.schemaValid )
|
|
395
514
|
node.schemas[schema]=avsc.Type.forSchema(node.schemaValid[schema]);
|
|
396
515
|
logger.info({label:"confluence",schemas:Object.keys(node.schemas)});
|
|
397
516
|
}
|
|
517
|
+
if(node.actionTarget=="Compressed"){
|
|
518
|
+
compressor=new CompressionTool();
|
|
519
|
+
compressor[node.compressionType]();
|
|
520
|
+
}
|
|
398
521
|
} catch(ex) {
|
|
522
|
+
logger.error(n);
|
|
399
523
|
error(node,ex,"Invalid setup "+ex.message);
|
|
400
524
|
return;
|
|
401
525
|
}
|
|
@@ -411,6 +535,16 @@ module.exports = function (RED) {
|
|
|
411
535
|
}
|
|
412
536
|
}
|
|
413
537
|
}
|
|
538
|
+
if(node.transformFuncion && ( node.actionSource=="JSON" || node.actionTarget=="JSON" )) {
|
|
539
|
+
try{
|
|
540
|
+
if(!jsonata) jsonata=require('jsonata')
|
|
541
|
+
node.transformFuncionCompiled = jsonata(node.transformFuncion);
|
|
542
|
+
} catch (ex) {
|
|
543
|
+
error(node,ex,"Transform function error");
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
414
548
|
const typeValidate="invalid"+node.actionSource;
|
|
415
549
|
node.invalidSourceType=typeValidate in functions &! ["XLSX","XLSXObject"].includes(node.actionTarget)?functions[typeValidate]:(()=>false);
|
|
416
550
|
try {
|
|
@@ -420,15 +554,17 @@ module.exports = function (RED) {
|
|
|
420
554
|
error(node,ex,node.actionSource+"\nto "+node.actionTarget + " not implemented")
|
|
421
555
|
return;
|
|
422
556
|
}
|
|
423
|
-
|
|
557
|
+
node.processMsg=node.sendInFunction?this.transform
|
|
558
|
+
:(RED,node,msg,data)=>node.setData(RED,node,msg,node.transform(RED,node,msg,data));
|
|
424
559
|
this.status({fill:"green",shape:"ring",text:"Ready"});
|
|
425
560
|
node.on("input", function(msg) {
|
|
426
561
|
if(logger.active) logger.send({label:"input",msgid:msg._msgid,topic:msg.topic});
|
|
427
562
|
try{
|
|
428
563
|
const data=node.getData(RED,node,msg);
|
|
429
564
|
if(node.invalidSourceType(data)) throw Error("expected source data type "+node.actionSource);
|
|
430
|
-
node.
|
|
565
|
+
node.processMsg(RED,node,msg,data);
|
|
431
566
|
} catch (ex) {
|
|
567
|
+
if(logger.active) logger.sendErrorAndDump("on input error",ex)
|
|
432
568
|
msg.error=node.actionSource+" to "+node.actionTarget + " " +ex.message;
|
|
433
569
|
error(node,Error(msg.error),"Error(s)");
|
|
434
570
|
node.send([null,msg]);
|
|
Binary file
|