node-red-contrib-prib-functions 0.22.0 → 0.23.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.
@@ -14,7 +14,7 @@
14
14
  }
15
15
  },
16
16
  "../..": {
17
- "version": "0.21.0",
17
+ "version": "0.23.1",
18
18
  "license": "GPL-3.0",
19
19
  "dependencies": {
20
20
  "avsc": ">=5.7.7",
@@ -32,9 +32,9 @@
32
32
  "axios": ">=0.21.1",
33
33
  "bcrypt": "^5.0.1",
34
34
  "bl": "^5.0.0",
35
- "mocha": "^9.2.2",
36
- "node-red": "^3.0.2",
37
- "node-red-node-test-helper": "^0.3.0"
35
+ "mocha": "^10.8.2",
36
+ "node-red": ">=4.0.0",
37
+ "node-red-node-test-helper": ">=0.3.0"
38
38
  }
39
39
  },
40
40
  "node_modules/bignumber.js": {
package/testing/test.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const logger = new (require("node-red-contrib-logger"))("test").sendInfo("Copyright 2020 Jaroslav Peter Prib");
2
+ const assert = require('node:assert')
2
3
 
3
4
  if(String.prototype.escapeSpecialChars)
4
5
  logger.warn("String.prototype.escapeSpecialChars already defined");
@@ -23,31 +24,62 @@ function escapeSpecialChars(s){
23
24
  }
24
25
  }
25
26
  function setError(msg,node,err) {
26
- msg._test.error=err;
27
- node.error(err);
28
- node.status({fill:"red",shape:"ring",text:"error"});
29
- node.send([null,msg]);
27
+ msg._test.error=err
28
+ node.error(err)
29
+ node.status({fill:"red",shape:"ring",text:"error"})
30
+ node.send([null,msg])
31
+ }
32
+ function assertObjects(obj1,obj2,errorFactor,callEquals=()=>true,callNotEquals=()=>false) {
33
+ try{
34
+ node.assert(obj1,obj2).then(callEquals)
35
+ } catch(ex) {
36
+ logger.error(ex.message);
37
+ callNotEquals(ex.message)
38
+ }
39
+ /*
40
+ assert.deepStrictEqual(actual, expected[, message])
41
+ assert.deepEqual(actual, expected[, message])
42
+ assert.notDeepEqual(actual, expected[, message])
43
+ assert.partialDeepStrictEqual(actual, expected[, message])
44
+ assert.equal(actual, expected[, message])
45
+ assert.notEqual(actual, expected[, message])
46
+ assert.strictEqual(actual, expected[, message])
47
+ assert.notStrictEqual(actual, expected[, message])
48
+
49
+ assert.doesNotMatch(string, regexp[, message])
50
+ assert.match(string, regexp[, message])
51
+
52
+ assert.doesNotReject(asyncFn[, error][, message])
53
+ assert.doesNotThrow(fn[, error][, message])
54
+ assert.throws(fn[, error][, message])
55
+ assert.ifError(value)
56
+ assert.ok(value[, message])
57
+ assert.rejects(asyncFn[, error][, message])
58
+ */
30
59
  }
31
60
 
32
61
  function equalObjects(obj1,obj2,errorFactor,callEquals=()=>true,callNotEquals=()=>false) {
33
- if( obj1 === obj2 ) return callEquals();
34
- if(obj1 instanceof Buffer ) return Buffer.compare(obj1, obj2) === 0
35
- if( obj1 === Number.POSITIVE_INFINITY && obj2==="Infinity") return callEquals();
36
- if( obj1 === Number.NEGATIVE_INFINITY && obj2==="-Infinity") return callEquals();
37
- if( Number.isNaN(obj1) && obj2==="NaN") return callEquals();
38
- const obj1type=typeof obj1;
39
- if( obj1type != typeof obj2 ) return callNotEquals();
40
- if(errorFactor && obj1type=="number") return (Math.abs(obj2-obj1)/obj2)<errorFactor?callEquals():callNotEquals();
41
- if( !(obj1 instanceof Object) ) return callNotEquals();
42
- if( Object.keys(obj1).length !== Object.keys(obj2).length ) return callNotEquals();
43
- try{
44
- for(let key in obj1) {
45
- if( !equalObjects(obj1[key],obj2[key],errorFactor) ) return callNotEquals();
62
+ if(obj1 == obj2) return callEquals()
63
+ if(obj1 instanceof Buffer) return Buffer.compare(obj1, obj2) === 0?callEquals():callNotEquals("buffers not equal")
64
+ if(obj1 === Number.POSITIVE_INFINITY && obj2==="Infinity") return callEquals()
65
+ if(obj1 === Number.NEGATIVE_INFINITY && obj2==="-Infinity") return callEquals()
66
+ if(Number.isNaN(obj1) && obj2==="NaN") return callEquals()
67
+ const obj1type=typeof obj1
68
+ if(obj1type != typeof obj2) return callNotEquals("different data types, "+obj1type+" vs "+typeof obj2)
69
+ if(obj1type=="boolean") callNotEquals("boolean not equal")
70
+ if(errorFactor && obj1type=="number") return (Math.abs(obj2-obj1)/obj2)<errorFactor?callEquals():callNotEquals("number outside bounds")
71
+ if( !(obj1 instanceof Object) ) return callNotEquals("different object types")
72
+ const keys1=Object.keys(obj1).sort()
73
+ const keys2=Object.keys(obj2).sort()
74
+ if( keys1.length !== keys2.length ) return callNotEquals("different number of properties")
75
+ for(const key1 of keys1){
76
+ try{
77
+ if( !equalObjects(obj1[key1],obj2[key1],errorFactor) ) return callNotEquals()
78
+ } catch(ex){
79
+ return callNotEquals(ex.message)
46
80
  }
47
- } catch(e) {
48
- return callNotEquals();
49
81
  }
50
- return callEquals();
82
+ return callEquals();
51
83
  }
52
84
 
53
85
  const testedOK=(node,msg)=>{
@@ -55,9 +87,10 @@ const testedOK=(node,msg)=>{
55
87
  delete msg._test;
56
88
  node.send([null,null,msg]);
57
89
  }
58
- const testedFailed=(node,msg)=>{
59
- msg._test.testedValue=node.getData(msg,node);
60
- setError(msg,node,"Test failed");
90
+ const testedFailed=(node,msg,err)=>{
91
+ msg._test.testedValue=node.getData(msg,node)
92
+ msg._test.errorDetails=err
93
+ setError(msg,node,"Test failed")
61
94
  }
62
95
 
63
96
  module.exports = function(RED) {
@@ -94,13 +127,13 @@ module.exports = function(RED) {
94
127
 
95
128
  if(node.isJSONata)
96
129
  return RED.util.evaluateJSONataExpression(node.resultExpression,msg,(err,data)=>{
97
- if(err) testedFailed(node,msg)
98
- else return data?testedOK(node,msg):testedFailed(node,msg)
130
+ if(err) testedFailed(node,msg,err)
131
+ else return data?testedOK(node,msg):testedFailed(node,msg,"no data")
99
132
  })
100
133
 
101
134
  node.equalObjects(node.getData(msg,node),msg._test.result,node.errorFactor,
102
135
  ()=>testedOK(node,msg),
103
- ()=>testedFailed(node,msg)
136
+ (err)=>testedFailed(node,msg,err)
104
137
  );
105
138
 
106
139
  } catch(ex){
@@ -1,11 +1,11 @@
1
1
 
2
2
  <script type="text/javascript">
3
- function setInput(t) {
3
+ const setInput=(t,types=['str','json','env'])=>{
4
4
  $("#node-input-"+t+"Type").val(this[t+"Type"]);
5
5
  $("#node-input-"+t).typedInput({
6
- default: 'json',
6
+ default: types[0],
7
7
  typeField: $("#node-input-"+t+"Type"),
8
- types:['str','json','env'],
8
+ types:types,
9
9
  validate: ()=>{
10
10
  }
11
11
  });
@@ -21,15 +21,28 @@
21
21
  defaults: {
22
22
  name: {value: ""},
23
23
  actionSource: {value:"csv",required:true},
24
+ deleteSource: {value:true,validate: RED.validators.typedInput("deleteSourceType")},
25
+ deleteSourceType:{value:"bool"},
24
26
  actionTarget: {value:"JSON",required:true},
25
27
  sourceProperty:{value:"msg.payload"},
26
28
  targetProperty:{value:"msg.payload"},
27
29
  topicProperty:{value:"msg.topic"},
30
+ index: {value:0},
28
31
  maxMessages: {value:1000},
32
+ maxDate: {value:null},
33
+ minDate: {value:null},
34
+ maxNumber: {value:0},
35
+ minNumber: {value:0},
36
+ maxString: {value:""},
37
+ minString: {value:""},
38
+ radix: {value:10},
29
39
  schema: {value:schemaExample, validate: RED.validators.typedInput("schemaType")},
30
40
  schemaType: {value:"json"},
31
41
  skipLeading: {value:0},
32
42
  skipTrailing: {value:0},
43
+ radix: {value:10},
44
+ string: {value:"", validate: RED.validators.typedInput("stringType")},
45
+ stringType: {value:"str"},
33
46
  delimiter: {value:",",required:true},
34
47
  compressionType: {value:"gzip"}
35
48
  },
@@ -55,9 +68,11 @@
55
68
  { value: "Confluence", label: "Confluence"},
56
69
  { value: "CSVWithHeader", label: "CSV with header"},
57
70
  { value: "CSV", label: "CSV"},
71
+ { value: "Date", label: "Date"},
58
72
  { value: "ISO8385", label: "ISO 8583"},
59
73
  { value: "JSON", label: "JSON"},
60
74
  { value: "npy", label: "npy"},
75
+ { value: "Number", label: "Number"},
61
76
  { value: "NumPyObject", label: "NumPy Obect"},
62
77
  { value: "String", label: "String"},
63
78
  { value: "snappy", label: "Snappy"},
@@ -125,6 +140,12 @@
125
140
  options["HTML"]="HTML";
126
141
  options["Messages"]="Messages";
127
142
  break;
143
+ case 'Date':
144
+ options["isBetween"]="is between";
145
+ options["RangeLimit"]="Range Limit";
146
+ options["ISODate"]="YYYY-MM-DD";
147
+ options["LocalDate"]="Local String";
148
+ break;
128
149
  case 'ISO8385':
129
150
  options["JSON"]="JSON";
130
151
  options["Array"]="Array";
@@ -150,10 +171,18 @@
150
171
  options["JSON"]="JSON";
151
172
  options["NumPyObject"]="NumPy Object";
152
173
  break;
174
+ case 'Number':
175
+ options["Abbreviated"]="Abbreviated";
176
+ options["RangeLimit"]="Range Limit";
177
+ options["isBetween"]="is Between";
178
+ break;
153
179
  case 'NumPyObject':
154
180
  options["JSON"]="JSON";
155
181
  break;
156
-
182
+ case 'Object':
183
+ options["Coalesce"]="Coalesce";
184
+ options["Nullif"]="Nullif";
185
+ break;
157
186
  case 'path':
158
187
  options["Basename"]="basename";
159
188
  options["Dirname"]="dirname";
@@ -168,8 +197,42 @@
168
197
  options["Compress"]="Compress";
169
198
  break;
170
199
  case 'String':
171
- options["Compressed"]="Compressed";
200
+ options["Append"]="Append";
201
+ options["ArrayusingDelimiter"]="Array By Delimiter";
202
+ options["At"]="At";
203
+ options["Camelize"]="Camelize";
204
+ options["Capitalize"]="Capitalize";
205
+ options["Compressed"]="Compressed";
206
+ options["CharAt"]="Char At";
207
+ options["CharCodeAt"]="Char Code At";
208
+ options["CodePointAt"]="Code Point At";
209
+ options["Concat"]="Concat";
210
+ options["Date"]="Date";
211
+ options["DateLocal"]="Date Local";
212
+ options["DelimiterOnCase"]="Delimiter On Case";
213
+ options["Deunderscore"]="_ to space";
214
+ options["DeunderscoreCapitilize"]="_ to space Capitilize";
215
+ options["DropSquareBracketPrefix"]="Drop square bracket prefix";
216
+ options["EndsWith"]="Ends With";
217
+ options["Float"]="Float";
218
+ options["GetWord"]="Get Word";
219
+ options["Integer"]="Integer";
220
+ options["isBetween"]="is Between";
221
+ options["LowerCase"]="Lower Case";
222
+ options["Number"]="Number";
223
+ options["Prepend"]="Prepend";
172
224
  options["JSON"]="JSON";
225
+ options["RangeLimit"]="Range Limit";
226
+ options["Split"]="Split";
227
+ options["StartsWith"]="Starts With";
228
+ options["Timestamp"]="Timestamp";
229
+ options["Title"]="Title";
230
+ options["TitleGrammatical"]="Title Grammatical";
231
+ options["Trim"]="Trim";
232
+ options["TrimEnd"]="Trim End";
233
+ options["TrimStart"]="Trim Start";
234
+ options["UpperCase"]="Upper Case";
235
+ options["XmlStringEncode"]="Xml String Encode";
173
236
  break;
174
237
  case 'XLSX':
175
238
  options["XLSXObject"]="XLSX Object";
@@ -199,14 +262,22 @@
199
262
  $("#node-input-actionTarget").change(function() {
200
263
  const actionTarget=$(this).val();
201
264
  const actionSource=$("#node-input-actionSource").val();
202
- if(!["Confluence","AVRO"].includes(actionSource)){
203
- $(".form-row-http-in-schema").hide();
204
- }
205
- $(".form-row-http-in-maxMessages").hide();
206
- if(!['CSV','CSVWithHeader'].includes(actionTarget)) {
207
- $(".form-row-http-in-csv").hide();
208
- }
209
265
  $(".form-row-http-in-compressionType").hide();
266
+ $(".form-row-http-in-csv").hide();
267
+ $(".form-row-http-in-delimiter").hide();
268
+ $(".form-row-http-in-index").hide();
269
+ $(".form-row-http-in-length").hide();
270
+ $(".form-row-http-in-maxMessages").hide();
271
+ $(".form-row-http-in-maxDate").hide();
272
+ $(".form-row-http-in-maxNumber").hide();
273
+ $(".form-row-http-in-maxString").hide();
274
+ $(".form-row-http-in-minDate").hide();
275
+ $(".form-row-http-in-minNumber").hide();
276
+ $(".form-row-http-in-minString").hide();
277
+ $(".form-row-http-in-radix").hide();
278
+ $(".form-row-http-in-schema").hide();
279
+ $(".form-row-http-in-string").hide();
280
+
210
281
  switch (actionTarget) {
211
282
  case 'AVRO':
212
283
  case 'Confluence':
@@ -215,15 +286,42 @@
215
286
  case 'Compressed':
216
287
  $(".form-row-http-in-compressionType").show();
217
288
  break;
218
- case 'CSV':
219
- $(".form-row-http-in-csv").show();
220
- break;
221
289
  case 'Messages':
222
290
  $(".form-row-http-in-maxMessages").show();
223
291
  break;
292
+ case 'Integer':
293
+ $(".form-row-http-in-radix").show();
294
+ break;
295
+ case 'At':
296
+ case 'CharAt':
297
+ case 'CharCodeAt':
298
+ case 'CodePointAt':
299
+ case 'GetWord':
300
+ $(".form-row-http-in-index").show();
301
+ break;
302
+ case 'EndsWith':
303
+ case 'StartsWith':
304
+ case 'Append':
305
+ case 'Prepend':
306
+ case 'Concat':
307
+ case 'Split':
308
+ $(".form-row-http-in-string").show();
309
+ break;
310
+ case 'CSV':
311
+ case 'DelimiterOnCase':
312
+ case 'ArrayByDelimiter':
313
+ $(".form-row-http-in-delimiter").show();
314
+ break;
315
+ case 'RangeLimit':
316
+ case 'isBetween':
317
+ $(".form-row-http-in-max"+actionSource).show();
318
+ $(".form-row-http-in-min"+actionSource).show();
319
+ break;
224
320
  }
225
321
  }).change();
322
+ setInput.apply(this,["deleteSource",["bool"]]);
226
323
  setInput.apply(this,["schema"]);
324
+ setInput.apply(this,["string",["str","msg","flow","global","env","node"]]);
227
325
  },
228
326
  oneditsave: function() {
229
327
  },
@@ -239,11 +337,16 @@
239
337
  <input type="text" id="node-input-name" placeholder="Name">
240
338
  </div>
241
339
  <div class="form-row form-row-http-in-sourceProperty show">
242
- <label for="node-input-sourceProperty" style="white-space: nowrap"><i class="icon-bookmark"></i> Source Property </label>
340
+ <label for="node-input-sourceProperty" style="white-space: nowrap"> Source Property </label>
243
341
  <input type="text" id="node-input-sourceProperty" placeholder="msg.payload">
244
342
  </div>
343
+ <div class="form-row form-row-http-in-deleteSource show">
344
+ <label for="node-input-deleteSource"><span data-i18n="common.label.string"> Delete?</span></label>
345
+ <input type="text" id="node-input-deleteSource" style="width:70%">
346
+ <input type="hidden" id="node-input-deleteSourceType">
347
+ </div>
245
348
  <div class="form-row form-row-http-in-targetProperty show">
246
- <label for="node-input-targetProperty" style="white-space: nowrap"><i class="icon-bookmark"></i> Target Property </label>
349
+ <label for="node-input-targetProperty" style="white-space: nowrap"> Target Property </label>
247
350
  <input type="text" id="node-input-targetProperty" placeholder="msg.payload">
248
351
  </div>
249
352
  <div class="form-row form-row-http-in-topicProperty show">
@@ -259,10 +362,14 @@
259
362
  <select id="node-input-actionTarget" placeholder="actionTarget">
260
363
  </select>
261
364
  </div>
262
- <div class="form-row form-row-http-in-csv hide">
365
+ <div class="form-row form-row-http-in-delimiter hide">
263
366
  <label for="node-input-delimiter"><i class="icon-bookmark"></i> Delimiter</label>
264
367
  <input type="text" id="node-input-delimiter" placeholder="delimiter" size="1" minlength="1">
265
368
  </div>
369
+ <div class="form-row form-row-http-in-index hide">
370
+ <label for="node-input-index"><i class="icon-bookmark"></i> Index</label>
371
+ <input type="number" id="node-input-index" placeholder="index" min="-10000" max="10000" step="1">
372
+ </div>
266
373
  <div class="form-row form-row-http-in-skip hide">
267
374
  <label for="node-input-skipLeading"><i class="icon-bookmark"></i> Skip Leading</label>
268
375
  <input type="number" id="node-input-skipLeading" placeholder="skipLeading" min="0" max="10000" step="1">
@@ -271,7 +378,39 @@
271
378
  </div>
272
379
  <div class="form-row form-row-http-in-maxMessages hide">
273
380
  <label for="node-input-maxMessages"><i class="icon-bookmark"></i> Max Messages</label>
274
- <input type="number" id="node-input-maxMessages" placeholder="maxMessages" min="1" max="10000" step="100">
381
+ <input type="number" id="node-input-maxMessages" placeholder="maxMessages" min="1" max="36" step="1">
382
+ </div>
383
+ <div class="form-row form-row-http-in-minNumber hide">
384
+ <label for="node-input-minNumber"><i class="icon-bookmark"></i> Min</label>
385
+ <input type="number" id="node-input-minNumber" placeholder="min">
386
+ </div>
387
+ <div class="form-row form-row-http-in-maxNumber hide">
388
+ <label for="node-input-maxNumber"><i class="icon-bookmark"></i> Max</label>
389
+ <input type="number" id="node-input-maxNumber" placeholder="max">
390
+ </div>
391
+ <div class="form-row form-row-http-in-minString hide">
392
+ <label for="node-input-minString"><i class="icon-bookmark"></i> Min</label>
393
+ <input type="text" id="node-input-minString" placeholder="min">
394
+ </div>
395
+ <div class="form-row form-row-http-in-maxString hide">
396
+ <label for="node-input-maxString"><i class="icon-bookmark"></i> Max</label>
397
+ <input type="text" id="node-input-maxString" placeholder="max">
398
+ </div>
399
+ <div class="form-row form-row-http-in-minDate hide">
400
+ <label for="node-input-minDate"><i class="icon-bookmark"></i> Min</label>
401
+ <input type="date" id="node-input-minDate" placeholder="min">
402
+ </div>
403
+ <div class="form-row form-row-http-in-maxDate hide">
404
+ <label for="node-input-maxDate"><i class="icon-bookmark"></i> Max</label>
405
+ <input type="date" id="node-input-maxDate" placeholder="max">
406
+ </div>
407
+ <div class="form-row form-row-http-in-length hide">
408
+ <label for="node-input-length"><i class="icon-bookmark"></i> Length</label>
409
+ <input type="number" id="node-input-length" placeholder="length" min="1" max="1000" step="1">
410
+ </div>
411
+ <div class="form-row form-row-http-in-radix hide">
412
+ <label for="node-input-radix"><i class="icon-bookmark"></i> Radix</label>
413
+ <input type="number" id="node-input-radix" placeholder="radix" min="2" max="10000" step="100">
275
414
  </div>
276
415
  <div class="form-row form-row-http-in-schema hide">
277
416
  <label for="node-input-schema"><i class="fa fa-envelope"></i> <span data-i18n="common.label.schema"> Schema </span></label>
@@ -282,6 +421,11 @@
282
421
  <label for="node-input-compressionType"><i class="fa fa-envelope"></i> <span data-i18n="common.label.compressionType"> Type </span></label>
283
422
  <input type="text" id="node-input-compressionType">
284
423
  </div>
424
+ <div class="form-row form-row-http-in-string hide">
425
+ <label for="node-input-string"><i class="fa fa-bookmark"></i> <span data-i18n="common.label.string"> String</span></label>
426
+ <input type="text" id="node-input-string" style="width:70%">
427
+ <input type="hidden" id="node-input-stringType">
428
+ </div>
285
429
 
286
430
  </script>
287
431