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.
Files changed (87) hide show
  1. package/.github/workflows/codeql-analysis.yml +3 -3
  2. package/.github/workflows/npmpublish.yml +6 -6
  3. package/.vs/VSWorkspaceState.json +7 -0
  4. package/.vs/node-red-contrib-prib-functions/v17/.wsuo +0 -0
  5. package/README.md +22 -19
  6. package/arima/index.js +18 -0
  7. package/dataAnalysis/arrayAllRowsSwap.js +15 -0
  8. package/dataAnalysis/arrayCompareToPrecision.js +34 -0
  9. package/dataAnalysis/arrayDifference.js +14 -0
  10. package/dataAnalysis/arrayDifferenceSeasonal.js +15 -0
  11. package/dataAnalysis/arrayDifferenceSeasonalSecondOrder.js +20 -0
  12. package/dataAnalysis/arrayDifferenceSecondOrder.js +14 -0
  13. package/dataAnalysis/arrayForEachRange.js +38 -0
  14. package/dataAnalysis/arrayOverlay.js +13 -0
  15. package/dataAnalysis/arrayProduct.js +11 -0
  16. package/dataAnalysis/arrayRandom.js +14 -0
  17. package/dataAnalysis/arrayReduceRange.js +11 -0
  18. package/dataAnalysis/arrayScale.js +11 -0
  19. package/dataAnalysis/arraySum.js +11 -0
  20. package/dataAnalysis/arraySumSquared.js +11 -0
  21. package/dataAnalysis/arraySwap.js +11 -0
  22. package/dataAnalysis/dataAnalysis.html +31 -14
  23. package/dataAnalysis/dataAnalysis.js +10 -1
  24. package/dataAnalysis/generateMatrixFunction.js +89 -0
  25. package/dataAnalysis/generateVectorFunction.js +25 -0
  26. package/dataAnalysis/pca.js +546 -0
  27. package/dataAnalysis/svd.js +239 -0
  28. package/documentation/loadInjector.png +0 -0
  29. package/echart/echart.html +68 -0
  30. package/echart/echart.js +85 -0
  31. package/echart/icons/chart-671.png +0 -0
  32. package/echart/lib/echarts.js +95886 -0
  33. package/lib/Chart.js +177 -0
  34. package/lib/Column.js +99 -0
  35. package/lib/GraphDB.js +14 -0
  36. package/lib/Table.js +185 -0
  37. package/lib/objectExtensions.js +361 -0
  38. package/matrix/matrix.js +50 -50
  39. package/matrix/matrixNode.html +144 -154
  40. package/matrix/matrixNode.js +26 -9
  41. package/monitor/BarGauge.js +8 -0
  42. package/monitor/Dataset.js +29 -0
  43. package/monitor/DialGauge.js +109 -0
  44. package/monitor/DialNeedle.js +36 -0
  45. package/monitor/Format.js +74 -0
  46. package/monitor/centerElement.js +14 -0
  47. package/monitor/compareElements.js +95 -0
  48. package/monitor/defs.js +23 -0
  49. package/monitor/extensions.js +906 -0
  50. package/monitor/functions.js +36 -0
  51. package/monitor/json2xml.js +103 -0
  52. package/monitor/monitorSystem.html +198 -0
  53. package/monitor/monitorSystem.js +322 -0
  54. package/monitor/svgHTML.js +179 -0
  55. package/monitor/svgObjects.js +64 -0
  56. package/package.json +31 -8
  57. package/test/00-objectExtensions.js +94 -0
  58. package/test/01-base.js +88 -0
  59. package/test/04-tables.js +33 -0
  60. package/test/data/.config.nodes.json +608 -0
  61. package/test/data/.config.nodes.json.backup +608 -0
  62. package/test/data/.config.runtime.json +4 -0
  63. package/test/data/.config.runtime.json.backup +3 -0
  64. package/test/data/.config.users.json +21 -0
  65. package/test/data/.config.users.json.backup +21 -0
  66. package/test/data/.flow.json.backup +3433 -0
  67. package/test/data/float32vector10.npy +0 -0
  68. package/test/data/flow.json +3433 -0
  69. package/test/data/int2matrix2x3.npy +0 -0
  70. package/test/data/package-lock.json +158 -0
  71. package/test/data/package.json +11 -0
  72. package/test/data/settings.js +544 -0
  73. package/test/dataAnalysisExtensions.js +472 -0
  74. package/test/dataAnalysisPCA.js +54 -0
  75. package/test/dataAnalysisSVD.js +31 -0
  76. package/test/euclideanDistance.js +2 -2
  77. package/test/matrix/02base.js +36 -0
  78. package/test/transformNumPy.js +132 -0
  79. package/testing/data/countries.csv +250 -0
  80. package/testing/hostAvailable.html +0 -2
  81. package/testing/load-injector.html +76 -21
  82. package/testing/load-injector.js +35 -54
  83. package/testing/test.js +1 -0
  84. package/transform/NumPy.js +303 -0
  85. package/transform/transform.html +73 -19
  86. package/transform/transform.js +144 -8
  87. package/documentation/LoadInjector.JPG +0 -0
@@ -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
- targetMap="(RED,node,msg,data,index)=>{"+(node.targetProperty||"msg.payload")+"=data;"+
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.setData(RED,node,msg,node.transform(RED,node,msg,data));
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