node-red-contrib-prib-functions 0.18.0 → 0.19.2
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/README.md +16 -17
- package/dataAnalysis/pca.js +399 -0
- package/documentation/loadInjector.png +0 -0
- package/matrix/matrix.js +48 -2
- package/matrix/matrixNode.html +144 -154
- package/matrix/matrixNode.js +26 -9
- package/package.json +16 -5
- package/test/01-base.js +88 -0
- package/test/data/.flow.json.backup +3192 -0
- package/test/data/flow.json +3212 -0
- package/test/data/settings.js +544 -0
- package/test/matrix/02base.js +36 -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/transform.html +61 -19
- package/transform/transform.js +110 -6
- package/documentation/LoadInjector.JPG +0 -0
package/transform/transform.html
CHANGED
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
schemaType: {value:"json"},
|
|
31
31
|
skipLeading: {value:0},
|
|
32
32
|
skipTrailing: {value:0},
|
|
33
|
-
delimiter: {value:",",required:true}
|
|
33
|
+
delimiter: {value:",",required:true},
|
|
34
|
+
compressionType: {value:"gzip"}
|
|
34
35
|
},
|
|
35
36
|
inputs: 1,
|
|
36
37
|
outputs: 2,
|
|
@@ -43,11 +44,49 @@
|
|
|
43
44
|
return this.name ||this.actionSource+"=>"+this.actionTarget|| "Transform";
|
|
44
45
|
},
|
|
45
46
|
oneditprepare: function() {
|
|
46
|
-
const actionTarget=this.actionTarget
|
|
47
|
+
const actionTarget=this.actionTarget;
|
|
48
|
+
$("#node-input-actionSource").typedInput({type:"actionSource", types:[{
|
|
49
|
+
value: "actionSource",
|
|
50
|
+
options: [
|
|
51
|
+
{ value: "Array", label: "Array"},
|
|
52
|
+
{ value: "AVRO", label: "AVRO"},
|
|
53
|
+
{ value: "Buffer", label: "Buffer"},
|
|
54
|
+
{ value: "Compressed", label: "Compressed"},
|
|
55
|
+
{ value: "Confluence", label: "Confluence"},
|
|
56
|
+
{ value: "CSVWithHeader", label: "CSV with header"},
|
|
57
|
+
{ value: "CSV", label: "CSV"},
|
|
58
|
+
{ value: "ISO8385", label: "ISO 8583"},
|
|
59
|
+
{ value: "JSON", label: "JSON"},
|
|
60
|
+
{ value: "String", label: "String"},
|
|
61
|
+
{ value: "snappy", label: "Snappy"},
|
|
62
|
+
{ value: "path", label: "Path"},
|
|
63
|
+
{ value: "XLSX", label: "XLSX (excel)"},
|
|
64
|
+
{ value: "XLSXObject", label: "XLSX object (excel)"},
|
|
65
|
+
{ value: "XML", label: "XML"}
|
|
66
|
+
]
|
|
67
|
+
}]});
|
|
68
|
+
$("#node-input-compressionType").typedInput({type:"compression", types:[{
|
|
69
|
+
value: "compression",
|
|
70
|
+
options: [
|
|
71
|
+
{ value: "setGzip", label: "gzip"},
|
|
72
|
+
{ value: "setGzipSpeed", label: "gzip speed"},
|
|
73
|
+
{ value: "setGzipCompression", label: "gzip compression"},
|
|
74
|
+
{ value: "setZlib", label: "zip"},
|
|
75
|
+
{ value: "setZlibSpeed", label: "zip speed"},
|
|
76
|
+
{ value: "setZlibCompression", label: "zip compression"},
|
|
77
|
+
{ value: "setLzma", label: "Lempel-Ziv-Markov speed"},
|
|
78
|
+
{ value: "setLzmaCompression", label: "Lempel-Ziv-Markov compression"},
|
|
79
|
+
{ value: "setBrotli", label: "Brotli"},
|
|
80
|
+
{ value: "setSnappy", label: "Snappy"},
|
|
81
|
+
{ value: "setFlate", label: "Deflate/Inflate"}
|
|
82
|
+
]
|
|
83
|
+
}]});
|
|
84
|
+
|
|
47
85
|
$("#node-input-actionSource").change(function() {
|
|
48
86
|
const actionSource=$(this).val();
|
|
49
87
|
$(".form-row-http-in-skip").hide();
|
|
50
88
|
$(".form-row-http-in-schema").hide();
|
|
89
|
+
$(".form-row-http-in-compressionType").hide();
|
|
51
90
|
if(!['CSV','CSVWithHeader'].includes(actionSource)) {
|
|
52
91
|
$(".form-row-http-in-csv").hide();
|
|
53
92
|
}
|
|
@@ -62,10 +101,19 @@
|
|
|
62
101
|
options["XLSXObject"]="XLSX object (excel)";
|
|
63
102
|
break;
|
|
64
103
|
case 'AVRO':
|
|
104
|
+
case 'Buffer':
|
|
105
|
+
options["Compressed"]="Compressed";
|
|
106
|
+
break;
|
|
65
107
|
case 'Confluence':
|
|
66
108
|
options["JSON"]="JSON";
|
|
67
109
|
$(".form-row-http-in-schema").show();
|
|
68
110
|
break;
|
|
111
|
+
case 'Compressed':
|
|
112
|
+
options["JSON"]="JSON";
|
|
113
|
+
options["String"]="String";
|
|
114
|
+
options["Buffer"]="Buffer";
|
|
115
|
+
$(".form-row-http-in-compressionType").show();
|
|
116
|
+
break;
|
|
69
117
|
case 'CSVWithHeader':
|
|
70
118
|
options["JSON"]="JSON";
|
|
71
119
|
case 'CSV':
|
|
@@ -82,8 +130,8 @@
|
|
|
82
130
|
case 'JSON':
|
|
83
131
|
options["Array"]="Array";
|
|
84
132
|
options["AVRO"]="AVRO";
|
|
133
|
+
options["Compressed"]="Compressed";
|
|
85
134
|
options["Confluence"]="Confluence";
|
|
86
|
-
options["CSVWithHeader"]="CSV with header";
|
|
87
135
|
options["CSV"]="CSV";
|
|
88
136
|
options["ISO8385"]="ISO 8583";
|
|
89
137
|
options["HTML"]="HTML";
|
|
@@ -108,6 +156,7 @@
|
|
|
108
156
|
options["Compress"]="Compress";
|
|
109
157
|
break;
|
|
110
158
|
case 'String':
|
|
159
|
+
options["Compressed"]="Compressed";
|
|
111
160
|
options["JSON"]="JSON";
|
|
112
161
|
break;
|
|
113
162
|
case 'XLSX':
|
|
@@ -145,11 +194,15 @@
|
|
|
145
194
|
if(!['CSV','CSVWithHeader'].includes(actionTarget)) {
|
|
146
195
|
$(".form-row-http-in-csv").hide();
|
|
147
196
|
}
|
|
197
|
+
$(".form-row-http-in-compressionType").hide();
|
|
148
198
|
switch (actionTarget) {
|
|
149
199
|
case 'AVRO':
|
|
150
200
|
case 'Confluence':
|
|
151
201
|
$(".form-row-http-in-schema").show();
|
|
152
202
|
break;
|
|
203
|
+
case 'Compressed':
|
|
204
|
+
$(".form-row-http-in-compressionType").show();
|
|
205
|
+
break;
|
|
153
206
|
case 'CSV':
|
|
154
207
|
$(".form-row-http-in-csv").show();
|
|
155
208
|
break;
|
|
@@ -187,21 +240,7 @@
|
|
|
187
240
|
</div>
|
|
188
241
|
<div class="form-row">
|
|
189
242
|
<label for="node-input-actionSource"><i class="fa fa-list-ul"></i> Source Type </label>
|
|
190
|
-
<
|
|
191
|
-
<option value="Array">Array</option>
|
|
192
|
-
<option value="AVRO">AVRO</option>
|
|
193
|
-
<option value="Confluence">Confluence</option>
|
|
194
|
-
<option value="CSVWithHeader">CSV with header</option>
|
|
195
|
-
<option value="CSV">CSV</option>
|
|
196
|
-
<option value="ISO8385">ISO 8583</option>
|
|
197
|
-
<option value="JSON">JSON</option>
|
|
198
|
-
<option value="String">String</option>
|
|
199
|
-
<option value="snappy">snappy</option>
|
|
200
|
-
<option value="path">Path</option>
|
|
201
|
-
<option value="XLSX">XLSX (excel)</option>
|
|
202
|
-
<option value="XLSXObject">XLSX object (excel)</option>
|
|
203
|
-
<option value="XML">XML</option>
|
|
204
|
-
</select>
|
|
243
|
+
<input type="text" id="node-input-actionSource">
|
|
205
244
|
</div>
|
|
206
245
|
<div class="form-row">
|
|
207
246
|
<label for="node-input-actionTarget"><i class="fa fa-list-ul"></i> Target Type </label>
|
|
@@ -227,7 +266,10 @@
|
|
|
227
266
|
<input type="text" id="node-input-schema" style="width:70%">
|
|
228
267
|
<input type="hidden" id="node-input-schemaType">
|
|
229
268
|
</div>
|
|
230
|
-
|
|
269
|
+
<div class="form-row form-row-http-in-compressionType hide">
|
|
270
|
+
<label for="node-input-compressionType"><i class="fa fa-envelope"></i> <span data-i18n="common.label.compressionType"> Type </span></label>
|
|
271
|
+
<input type="text" id="node-input-compressionType">
|
|
272
|
+
</div>
|
|
231
273
|
|
|
232
274
|
</script>
|
|
233
275
|
|
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
|
+
const CompressionTool = require('compressiontool');
|
|
3
4
|
|
|
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,8 +332,17 @@ const functions={
|
|
|
256
332
|
}
|
|
257
333
|
return data;
|
|
258
334
|
},
|
|
335
|
+
JSONToCompressed: (RED,node,msg,data)=>compressor.compress(JSON.stringify(data),
|
|
336
|
+
(compressed)=>{
|
|
337
|
+
node.setData(RED,node,msg,compressed);
|
|
338
|
+
node.send(msg);
|
|
339
|
+
},
|
|
340
|
+
(err)=>{
|
|
341
|
+
error(node,Error(err));
|
|
342
|
+
}
|
|
343
|
+
),
|
|
259
344
|
JSONToConfluence:JSONToConfluence,
|
|
260
|
-
JSONToCSV: (RED,node,msg,data)=>
|
|
345
|
+
JSONToCSV: (RED,node,msg,data)=>Array2csv(node,data),
|
|
261
346
|
JSONToAVRO: (RED,node,msg,data)=>node.avroTransformer.toBuffer(data), // Encoded buffer.
|
|
262
347
|
JSONToHTML: (RED,node,msg,data,level=0)=>{
|
|
263
348
|
if(Array.isArray(data)) {
|
|
@@ -294,6 +379,15 @@ const functions={
|
|
|
294
379
|
JSONToXLSX:JSONToXLSX,
|
|
295
380
|
JSONToXLSXObject:JSONToXLSXObject,
|
|
296
381
|
JSONToXML: (RED,node,msg,data)=>json2xmlParser.parse(data),
|
|
382
|
+
StringToCompressed: (RED,node,msg,data)=>compressor.compress(data,
|
|
383
|
+
(compressed)=>{
|
|
384
|
+
node.setData(RED,node,msg,compressed);
|
|
385
|
+
node.send(msg);
|
|
386
|
+
},
|
|
387
|
+
(err)=>{
|
|
388
|
+
error(node,Error(err));
|
|
389
|
+
}
|
|
390
|
+
),
|
|
297
391
|
StringToJSON: (RED,node,msg,data)=>JSON.parse(data),
|
|
298
392
|
pathToBasename: (RED,node,msg,data)=>path.basename(data),
|
|
299
393
|
pathToDirname: (RED,node,msg,data)=>path.dirname(data),
|
|
@@ -373,11 +467,11 @@ module.exports = function (RED) {
|
|
|
373
467
|
}
|
|
374
468
|
if(logger.active) logger.send({label:"load xml",xmlParserKeys:Object.keys(xmlParser),json2xmlParser:Object.keys(json2xmlParser)});
|
|
375
469
|
}
|
|
376
|
-
node.sendInFunction=["snappy"].includes(node.actionSource)||["Messages"].includes(node.actionTarget);
|
|
470
|
+
node.sendInFunction=["snappy","Compressed"].includes(node.actionSource)||["Messages","Compressed"].includes(node.actionTarget);
|
|
377
471
|
node.hasNewTopic=![null,""].includes(node.topicProperty);
|
|
378
472
|
const sourceMap="(RED,node,msg)=>"+(node.sourceProperty||"msg.payload"),
|
|
379
473
|
sourceDelete="(RED,node,msg)=>{delete "+(node.sourceProperty||"msg.payload")+";}",
|
|
380
|
-
|
|
474
|
+
targetMap="(RED,node,msg,data,index)=>{"+(node.targetProperty||"msg.payload")+"=data;"+
|
|
381
475
|
(node.sendInFunction && node.hasNewTopic? "msg.topic=node.topicFunction(RED,node,msg,data,index);":"")+
|
|
382
476
|
(node.sendInFunction ? "" : "node.send(msg);" )+
|
|
383
477
|
"}",
|
|
@@ -389,13 +483,21 @@ module.exports = function (RED) {
|
|
|
389
483
|
node.topicFunction=evalFunction("topic",topicMap);
|
|
390
484
|
if(is(node,"AVRO")) {
|
|
391
485
|
node.avroTransformer=avsc.Type.forSchema(node.schemaValid);
|
|
486
|
+
} else if(is(node,"Compressed")) {
|
|
487
|
+
compressor=new CompressionTool();
|
|
488
|
+
compressor[node.compressionType]();
|
|
392
489
|
} else if(is(node,"Confluence")) {
|
|
393
490
|
node.schemas={};
|
|
394
491
|
for(const schema in node.schemaValid )
|
|
395
492
|
node.schemas[schema]=avsc.Type.forSchema(node.schemaValid[schema]);
|
|
396
493
|
logger.info({label:"confluence",schemas:Object.keys(node.schemas)});
|
|
397
494
|
}
|
|
495
|
+
if(node.actionTarget=="Compressed"){
|
|
496
|
+
compressor=new CompressionTool();
|
|
497
|
+
compressor[node.compressionType]();
|
|
498
|
+
}
|
|
398
499
|
} catch(ex) {
|
|
500
|
+
logger.error(n);
|
|
399
501
|
error(node,ex,"Invalid setup "+ex.message);
|
|
400
502
|
return;
|
|
401
503
|
}
|
|
@@ -420,15 +522,17 @@ module.exports = function (RED) {
|
|
|
420
522
|
error(node,ex,node.actionSource+"\nto "+node.actionTarget + " not implemented")
|
|
421
523
|
return;
|
|
422
524
|
}
|
|
423
|
-
|
|
525
|
+
node.processMsg=node.sendInFunction?this.transform
|
|
526
|
+
:(RED,node,msg,data)=>node.setData(RED,node,msg,node.transform(RED,node,msg,data));
|
|
424
527
|
this.status({fill:"green",shape:"ring",text:"Ready"});
|
|
425
528
|
node.on("input", function(msg) {
|
|
426
529
|
if(logger.active) logger.send({label:"input",msgid:msg._msgid,topic:msg.topic});
|
|
427
530
|
try{
|
|
428
531
|
const data=node.getData(RED,node,msg);
|
|
429
532
|
if(node.invalidSourceType(data)) throw Error("expected source data type "+node.actionSource);
|
|
430
|
-
node.
|
|
533
|
+
node.processMsg(RED,node,msg,data);
|
|
431
534
|
} catch (ex) {
|
|
535
|
+
if(logger.active) logger.sendErrorAndDump("on input error",ex)
|
|
432
536
|
msg.error=node.actionSource+" to "+node.actionTarget + " " +ex.message;
|
|
433
537
|
error(node,Error(msg.error),"Error(s)");
|
|
434
538
|
node.send([null,msg]);
|
|
Binary file
|