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.
package/README.md CHANGED
@@ -111,53 +111,104 @@ Messages generates a message for each row or record.
111
111
 
112
112
  Transformations:
113
113
 
114
- * Array to CSV
115
- * Array to HTML
116
- * Array to ISO8385
117
- * Array to Messages
118
- * Array to xlsx / xlsx object (excel uses [xlsx][7])
114
+ * Array to
115
+ * CSV
116
+ * HTML
117
+ * ISO8385
118
+ * Messages
119
+ * xlsx / xlsx object (excel uses [xlsx][7])
119
120
  * AVRO to JSON (uses [avsc][6])
120
- * Buffer to comprossed
121
+ * Buffer to compressed
121
122
  * Confluence to JSON
122
- * Compressed to Buffer
123
- * Compressed to String
124
- * COmpressed to JSON
125
- * CSV to Array
126
- * CSV to HTML
127
- * CSV to Messages
128
- * CSVWithHeader to Array
129
- * CSVWithHeader to HTML
130
- * CSVWithHeader to JSON
123
+ * Compressed to
124
+ * Buffer
125
+ * String
126
+ * JSON
127
+ * CSV to
128
+ * Array
129
+ * HTML
130
+ * Messages
131
+ * CSVWithHeader to
132
+ * Array
133
+ * HTML
134
+ * JSON
135
+ * Date to
136
+ * is between
137
+ * ISO string
138
+ * locale string
139
+ * range limit
131
140
  * ISO8385 to Array
132
141
  * ISO8385 to JSON
133
- * JSON to Array
134
- * JSON to Confluence
135
- * JSON to CSV
136
- * JSON to AVRO (uses [avsc][6])
137
- * JSON to ISO8385
138
- * JSON to Messages
139
- * JSON to String
140
- * JSON to xlsx / xlsx object (excel uses [xlsx][7])
141
- * JSON to XML (uses [fast-xml-parser][4])
142
- * String to JSON
143
- * path to Basename
144
- * path to Dirname
145
- * path to Extname
146
- * path to Format
147
- * path to Is Absolute
148
- * path to Join
149
- * path to Parse
150
- * path to Normalize
151
- * path to Resolve
142
+ * JSON to
143
+ * Array
144
+ * Confluence
145
+ * CSV
146
+ * AVRO (uses [avsc][6])
147
+ * ISO8385
148
+ * Messages
149
+ * String
150
+ * xlsx / xlsx object (excel uses [xlsx][7])
151
+ * XML (uses [fast-xml-parser][4])
152
+ * Number
153
+ * is between
154
+ * range limit
155
+ * path
156
+ * Basename
157
+ * Dirname
158
+ * Extname
159
+ * Format
160
+ * Is Absolute
161
+ * Join
162
+ * Parse
163
+ * Normalize
164
+ * Resolve
152
165
  * snappy compress (uses [snappy][5], must install separately)
153
166
  * snappy uncompress (uses [snappy][5], must install separately)
167
+ * String to
168
+ * Append
169
+ * Array By Delimiter
170
+ * At
171
+ * Camelize
172
+ * Capitalize
173
+ * Compressed
174
+ * Char At
175
+ * Char Code At"
176
+ * Code Point At
177
+ * Concat
178
+ * Date
179
+ * Delimiter On Case
180
+ * _ to space
181
+ * _ to space Capitilize
182
+ * Drop square bracket prefix
183
+ * Ends With
184
+ * Float
185
+ * Get Word
186
+ * Integer
187
+ * is Between
188
+ * Lower Case
189
+ * Number
190
+ * Prepend
191
+ * JSON
192
+ * Range Limit
193
+ * Split
194
+ * Starts With
195
+ * Timestamp
196
+ * Title
197
+ * Title Grammatical
198
+ * Trim
199
+ * Trim End
200
+ * Trim Start
201
+ * Upper Case
202
+ * Xml String Encode
203
+
204
+
154
205
  * xlsx / xlsx object to array/JSON (excel uses [xlsx][7])
155
206
  * XML to JSON (uses [fast-xml-parser][4])
156
207
 
157
208
  Note, snappy needs to be installed separately as can have issues with auto install as build binaries.
158
209
 
159
210
  With xlsx object one can use the function in [xlsx][7] against the object in functions node.
160
-
211
+ "
161
212
  Example AVRO with schema
162
213
 
163
214
  ![Transform AVRO](documentation/transformArvo.jpg "Transform AVRO example")
@@ -302,6 +353,7 @@ Test/example flow in test/generalTest.json
302
353
  ------------------------------------------------------------
303
354
 
304
355
  # Version
356
+ 0.23.0 Removes bug in test, more translation
305
357
 
306
358
  0.22.0 Add autocovariance + autocorealationship to real time data analystics, improves test
307
359
 
package/lib/common.js ADDED
@@ -0,0 +1,128 @@
1
+ const error=(node,message,shortMessage,logger)=>{
2
+ if(logger && logger.active) logger.send({label:"error",node:node.id,error:error,shortMessage});
3
+ node.error(message);
4
+ node.status({fill:"red",shape:"ring",text:shortMessage});
5
+ }
6
+ const evalFunction(id,mapping,logger)=>{
7
+ logger&&logger.sendInfo({label:"evalFunction",id:id,mapping:mapping})
8
+ try{
9
+ return eval(mapping);
10
+ } catch(ex) {
11
+ logger.sendError({label:"evalFunction error",id:id,mapping:mapping,error:ex.message})
12
+ throw Error(id+" "+ex.message);
13
+ }
14
+ }
15
+ const evalInFunction=(node,propertyName)=>{
16
+ try{
17
+ const nodeContext = node.context();
18
+ const flow = nodeContext.flow;
19
+ const global = nodeContext.global;
20
+ const property=node[propertyName];
21
+ if(property==null) throw Error("no value for "+propertyName);
22
+ const propertyType=propertyName+"-type";
23
+ if(! (propertyType in node)) return evalFunction(propertyName,"()=>node."+property)
24
+ switch (node[propertyType]){
25
+ case "num":
26
+ case "json":
27
+ return evalFunction(propertyName,"()=>"+property);
28
+ case "node":
29
+ return evalFunction(propertyName,"()=>nodeContext.get("+property+")");
30
+ case "flow":
31
+ if(flow) throw Error("context store may be memoryonly so flow doesn't work")
32
+ return evalFunction(propertyName,"()=>flow.get("+property+")");
33
+ case "global":
34
+ return evalFunction(propertyName,"()=>global.get("+property+")");
35
+ case "env":
36
+ return evalFunction(propertyName,"()=>env.get("+property+")");
37
+ case "msg":
38
+ return evalFunction(propertyName,"(msg)=>msg."+property);
39
+ default:
40
+ logger.sendInfo({label:"setData unknown type",action:node.action,propertyType:propertyType,type:node[propertyType]});
41
+ throw Error("unknown type "+node[propertyType])
42
+ }
43
+ } catch(ex) {
44
+ logger.sendError({label:"setup",error:ex.message,stack:ex.stack});
45
+ throw Error(property+" "+ex.message);
46
+ }
47
+ }
48
+
49
+ const argsArray=(node,msg)=>{
50
+ const args=[];
51
+ node.argFunction.forEach(callFunction=> {
52
+ const result=callFunction(msg);
53
+ args.push(result);
54
+ });
55
+ return args;
56
+ }
57
+ const setArgsFunction=(node)=>{
58
+ node.argFunction=[];
59
+ node.args.forEach(property=>{
60
+ try{
61
+ node.argFunction.push(evalInFunction(node,property).bind(this));
62
+ } catch(ex) {
63
+ throw Error("args "+property+" "+ex.message)
64
+ }
65
+ })
66
+ }
67
+
68
+
69
+ const setTargetFunction=(node)=>{
70
+ if(node.target) throw Error("target is null")
71
+ if(node.hasOwnProperty("target-type")) {
72
+ node.setData=evalFunction("target","data=>data)")
73
+ return
74
+ }
75
+ const nodeContext = node.context()
76
+ const type=node["target-type"]
77
+ switch(type){
78
+ case "node":
79
+ node.setData=evalFunction("target","data=>nodeContext.set("+node.target+",data)")
80
+ break
81
+ case "flow":
82
+ if(nodeContext.flow) throw Error("context store may be memory only so flow doesn't work")
83
+ node.setData=evalFunction("target","data=>nodeContext.flow.set("+node.target+",data)")
84
+ break
85
+ case "global":
86
+ node.setData=evalFunction("target","data=>nodeContext.global.set("+node.target+",data)")
87
+ break
88
+ case "msg":
89
+ node.setData=evalFunction("target","(data,msg)=>{msg."+node.target+"=data;}")
90
+ break
91
+ default:
92
+ throw Error("setData unknown type "+type)
93
+ }
94
+ }
95
+
96
+ const baseProcess=(msg,call=sourceMatrix[node.action])=>{
97
+ const value=node.getSource(msg);
98
+ if(value==null) throw Error("source data not found");
99
+ const valueObject=(value instanceof Matrix?value:new Matrix(value));
100
+ return call.apply(valueObject,argsArray(node,msg));
101
+ }
102
+ const baseProcessAndSet=(msg)=>{
103
+ const result=baseProcess(msg);
104
+ node.setData.apply(node,[result,msg]);
105
+ }
106
+ function createProcess(msg){
107
+ const sourceMatrix=new Matrix({rowsMax:node.rows,columns:node.columns,dataType:node.dataType});
108
+ if(!(node.initialState in sourceMatrix)) throw Error("Invalid initial state "+node.initialState);
109
+ sourceMatrix[node.initialState]()
110
+ node.setData.apply(node,[sourceMatrix,msg]);
111
+ }
112
+ function defineProcess(msg){
113
+ const sourceMatrix=new Matrix({rows:node.rows,columns:node.columns,dataType:node.dataType});
114
+ node.setData.apply(node,[sourceMatrix,msg]);
115
+ }
116
+ function defineEmptyProcess(msg){
117
+ if(logger.active) logger.sendInfo({label:"define",arg:{rowsMax:node.row,columns:node.column}});
118
+ const sourceMatrix=new Matrix({rowsMax:node.rows,columns:node.columns});
119
+ node.setData.apply(node,[sourceMatrix,msg]);
120
+ }
121
+ function createSize(msg){
122
+ const sourceMatrix=new Matrix({rows:node.size,columns:node.size});
123
+ node.setData.apply(node,[sourceMatrix[node.action](),msg]);
124
+ }
125
+ function createDummy(msg){
126
+ const sourceMatrix=new Matrix(1,1);
127
+ node.setData.apply(node,[sourceMatrix[node.action].apply(sourceMatrix,argsArray(node,msg)),msg]);
128
+ }
@@ -1,71 +1,54 @@
1
- if(!Array.prototype.move)
2
- Array.prototype.move = function(from, to) {
3
- if(from<to) to--;
4
- this.splice(to, 0, this.splice(from, 1)[0]);
5
- };
6
- if(!Number.prototype.between)
7
- Number.prototype.between = function (min, max) {
8
- return !(this < min || this > max);
9
- };
10
- if(!String.prototype.in)
11
- String.prototype.in = function (str) {
12
- for (var i = 0; i < arguments.length; i++)
13
- if(this==arguments[i]) return true;
14
- return false;
15
- };
16
- if(!String.prototype.startsWith)
17
- String.prototype.startsWith = function (str) {
18
- return this.slice(0, str.length) == str;
19
- };
20
- if(!String.prototype.toTitle)
21
- String.prototype.toTitle = function () {
22
- var title=this.substr(0,1).toUpperCase()
23
- ,lastLowerCase=false;
24
- for(var i=1 ; i<this.length; i++ ) {
25
- char=this.substr(i,1);
26
- if(char==char.toUpperCase()) {
27
- if(lastLowerCase) title+=' ';
28
- lastLowerCase=false;
29
- if(char=='_') continue;
30
- if(char==' ') continue;
31
- } else lastLowerCase=true;
32
- title+=char;
33
- }
34
- return title;
35
- };
36
- if(!String.prototype.to)
37
- String.prototype.to = function (type) {
38
- if (this==null) return null;
39
- if (type==null) return value;
40
- return this['to'+type.capitalize()];
1
+ const defineMethod=(object,name,call)=>{
2
+ if(name in object.prototype) return
3
+ try{
4
+ Object.defineProperty(object.prototype, name, {
5
+ enumerable: false,
6
+ value: call
7
+ })
8
+ } catch(ex){
9
+ console.error("defining "+name,ex.message)
41
10
  }
42
- if(!String.prototype.toReal)
43
- String.prototype.toReal = function () {
44
- return parseFloat(this);
45
- };
46
- if(!String.prototype.toInt)
47
- String.prototype.toInt = function () {
48
- return parseInt(this);
49
- };
50
- if(!String.prototype.toTimestamp)
51
- String.prototype.toTimestamp = function () {
52
- return Date.parse(this.substr(0,4)+'/'+this.substr(5,2)+'/'+this.substr(8,11))
53
- + parseInt(this.substr(21,3));
54
- };
55
- if(!String.prototype.toTime)
56
- String.prototype.toTime = function () {
57
- return Date.parse(this);
58
- };
59
- if(!String.prototype.toDatetime)
60
- String.prototype.toDatetime = String.prototype.toTime;
61
- if(!String.prototype.toDate)
62
- String.prototype.toDate = String.prototype.toTime;
63
- if(!String.prototype.CRLF2BR)
64
- String.prototype.CRLF2BR = function () {
65
- return this.replace("\n\r","<br/>").replace("\n","<br/>");
66
- };
11
+ }
12
+ const toDateType=aDate=>aDate instanceof Date? aDate : new Date(Date.parse(aDate))
13
+ const toDateTypeZulu=aDate=>aDate instanceof Date? aDate : new Date(aDate)
14
+ defineMethod(Array,'move',function(from, to) {
15
+ if(from<to) to--
16
+ this.splice(to, 0, this.splice(from, 1)[0])
17
+ })
18
+ defineMethod(String,"in",function (...str) {
19
+ for (var i = 0; i < arguments.length; i++)
20
+ if(this==arguments[i]) return true
21
+ return false
22
+ })
23
+ defineMethod(String,"capitalize",function() {return this.charAt(0).toUpperCase() + this.slice(1)})
24
+ defineMethod(String,"toCapitalized",function() {return this.charAt(0).toUpperCase() + this.slice(1)})
25
+ defineMethod(String,"to",function (type) {
26
+ if(type==null) return value
27
+ return this['to'+type.capitalize()]
28
+ })
29
+ defineMethod(String,"toReal",function (){return parseFloat(this)})
30
+ defineMethod(String,"toTitle", function (){return this.replace(/\w\S*/g, text => text.capitalize())})
31
+
32
+ defineMethod(String,"toTitleGrammatical", function (){
33
+ const lowerCaseList = ['a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'as', 'at',
34
+ 'by', 'from', 'in', 'into', 'of', 'on', 'onto', 'to', 'with', 'yet', 'so','upon', 'like', 'over', 'plus', 'up', 'down', 'off', 'near'];
35
+ const title=this.replace(/\p{L}+/gu, (word)=>{
36
+ const wordLowerCase=word.toLowerCase()
37
+ return lowerCaseList.includes(wordLowerCase) ? wordLowerCase : word.capitalize()
38
+ })
39
+ return title.capitalize()
40
+ })
67
41
 
68
- Array.prototype.findSorted = function(searchElement,minIndex = 0,maxIndex = this.length - 1) {
42
+ defineMethod(String,"toInt",function() {return parseInt(this)})
43
+ if(!String.prototype.toInt) String.prototype.toInteger=String.prototype.toInt
44
+ defineMethod(String,"toTimestamp",function () {
45
+ return Date.parse(this.substring(0,4)+'/'+this.substring(5,2)+'/'+this.substring(8,11))
46
+ + parseInt(this.substring(21,3));
47
+ })
48
+ defineMethod(String,"toTime",function () {return Date.parse(this)})
49
+ defineMethod(String,"CRLF2BR", function(){return this.replace("\n\r","<br/>").replace("\n","<br/>")})
50
+
51
+ defineMethod(Array,"findSorted",function(searchElement,minIndex = 0,maxIndex = this.length - 1) {
69
52
  let currentIndex, currentElement
70
53
  while(minIndex <= maxIndex) {
71
54
  currentIndex = (minIndex + maxIndex) / 2 | 0
@@ -77,8 +60,8 @@ Array.prototype.findSorted = function(searchElement,minIndex = 0,maxIndex = this
77
60
  } else return currentIndex
78
61
  }
79
62
  return -minIndex
80
- }
81
- Array.prototype.addSorted = function(element) {
63
+ })
64
+ defineMethod(Array,"addSorted",function(element) {
82
65
  if(this.length){
83
66
  const position = -this.findSorted(element)
84
67
  if(position<0 ) return -position
@@ -87,15 +70,16 @@ Array.prototype.findSorted = function(searchElement,minIndex = 0,maxIndex = this
87
70
  }
88
71
  this.push(element)
89
72
  return 0
90
- }
91
- Object.prototype.addList = function(property,object) {
73
+ })
74
+
75
+ defineMethod(Object,"addList",function(property,object) {
92
76
  try{
93
77
  this[property].push(object)
94
78
  } catch(ex) {
95
79
  this[property]=[object]
96
80
  }
97
- }
98
- Object.prototype.addErrorFunctions = function(){
81
+ })
82
+ defineMethod(Object,"addErrorFunctions",function(){
99
83
  this.onError=function(call){
100
84
  if(this.errorStack) this.errorStack.push(call)
101
85
  else this.errorStack=[this.call]
@@ -113,8 +97,9 @@ Object.prototype.addErrorFunctions = function(){
113
97
  if(typeof ex == "string") throw Error(ex)
114
98
  throw ex
115
99
  }
116
- }
117
- if(!colourSmallList) var colourSmallList={
100
+ })
101
+
102
+ const colourSmallList={
118
103
  "Red":'#FF0000',
119
104
  "Turquoise":'#00FFFF',
120
105
  "Grass Green":'#408080',
@@ -132,7 +117,7 @@ if(!colourSmallList) var colourSmallList={
132
117
  "Light Purple":'#FF0080',
133
118
  "Dark Grey":'#808080'
134
119
  }
135
- if(!colours) var colours ={
120
+ const colours ={
136
121
  AliceBlue: '#F0F8FF',
137
122
  AntiqueWhite: '#FAEBD7',
138
123
  Aqua: '#00FFFF',
@@ -282,8 +267,7 @@ if(!colours) var colours ={
282
267
  Yellow: '#FFFF00',
283
268
  YellowGreen: '#9ACD32'
284
269
  }
285
-
286
- String.prototype.csvLine=function(delimiter=",",quote='"'){
270
+ defineMethod(String,"csvLine",function(delimiter=",",quote='"'){
287
271
  let i=this.length,j=i,charInQuote,result=[]
288
272
  if(i==0) return result
289
273
  delimiter:while(i--){
@@ -317,9 +301,8 @@ String.prototype.csvLine=function(delimiter=",",quote='"'){
317
301
  const v=this.substring(i+1,j)
318
302
  result.unshift(v.length?isNaN(v)? v : Number(v):null)
319
303
  return result
320
- }
321
-
322
- String.prototype.csvFile=function(delimiter=",",quote='"'){
304
+ })
305
+ defineMethod(String,"csvFile",function(delimiter=",",quote='"'){
323
306
  let i=this.length,j=i,charInQuote,result=[],line=[]
324
307
  if(i==0) return result
325
308
  line:while(i--){
@@ -358,4 +341,131 @@ String.prototype.csvFile=function(delimiter=",",quote='"'){
358
341
  result.unshift(line)
359
342
  }
360
343
  return result
344
+ })
345
+
346
+ defineMethod(Date,"isBetween",function(min, max) {return !(this < toDateType(min) || this > toDateType(max))})
347
+ defineMethod(Number,"isBetween",function(min, max) {return !(this < min || this > max)})
348
+ defineMethod(String,"isBetween",function(min, max) {return !(this < min || this > max)})
349
+ defineMethod(Object,"toSimpleArray",function(prefix) {
350
+ const returnValue=[]
351
+ for (let property in this) {
352
+ if(this[property]==null || this[property].enumerable==null || this[property].enumerable)
353
+ returnValue.push([(prefix?prefix:"")+property,this[property],typeof this[property]])
354
+ }
355
+ return returnValue
356
+ })
357
+ defineMethod(Object,"toSimpleArrayIgnoreNulls",function(prefix) {
358
+ const returnValue=[]
359
+ for (let property in this) {
360
+ if(this[property]==null ) continue
361
+ if(this[property].enumerable==null || this[property].enumerable)
362
+ returnValue.push([(prefix?prefix:"")+property,this[property],typeof this[property]])
363
+ }
364
+ return returnValue
365
+ })
366
+
367
+ defineMethod(String,"in",function () {
368
+ for (let i = 0; i < arguments.length; i++)
369
+ if(this.toString()===arguments[i]) return true;
370
+ return false
371
+ })
372
+ defineMethod(String,"startsWithList",function () {
373
+ for (var i = 0; i < arguments.length; i++)
374
+ if(this.slice(0, arguments[i].length)===arguments[i]) return true
375
+ return false
376
+ })
377
+ defineMethod(String,"startsWithListAnyCase",function (...list) {
378
+ for (var i = 0; i < list.length; i++){
379
+ const testString=list[i].toLowerCase()
380
+ if(this.slice(0, testString.length).toLowerCase()==testString) return true
381
+ }
382
+ return false
383
+ })
384
+ defineMethod(String,"xmlStringEncode",function() {
385
+ return this.toString().replace(/([\&"<>])/g, function(str, item) {
386
+ return {
387
+ '&': '&amp;',
388
+ '"': '&quot;',
389
+ '<': '&lt;',
390
+ '>': '&gt;'
391
+ }[item]
392
+ });
393
+ })
394
+
395
+ defineMethod(Number,"toAbbreviated",function() {
396
+ const digits=(v,e)=>{
397
+ const nv=v/Math.pow(10,e)
398
+ const anv=Math.abs(nv)
399
+ if(anv<10) return nv.toFixed(2).toString()
400
+ if(anv<100) return nv.toFixed(1).toString()
401
+ return nv.toFixed(0).toString()
402
+ }
403
+ const a=Math.abs(this)
404
+ if(a>Math.pow(10,15)) return digits(this,15)+'P'
405
+ if(a>Math.pow(10,12)) return digits(this,12)+'T'
406
+ if(a>Math.pow(10,9)) return digits(this,9)+'G'
407
+ if(a>Math.pow(10,6)) return digits(this,6)+'M'
408
+ if(a>Math.pow(10,3)) return digits(this,3)+'K'
409
+ return digits(this,0)
410
+ })
411
+
412
+ defineMethod(BigInt,"toAbbreviated",function() {
413
+ const digits=(v,e)=>{
414
+ const nv=v/Math.pow(10,e)
415
+ const anv=Math.abs(nv)
416
+ if(anv<10) return nv.toFixed(2).toString()
417
+ if(anv<100) return nv.toFixed(1).toString()
418
+ return nv.toFixed(0).toString()
419
+ }
420
+ const a=Math.abs(this)
421
+ if(a>Math.pow(10,15)) return digits(this,15)+'P'
422
+ if(a>Math.pow(10,12)) return digits(this,12)+'T'
423
+ if(a>Math.pow(10,9)) return digits(this,9)+'G'
424
+ if(a>Math.pow(10,6)) return digits(this,6)+'M'
425
+ if(a>Math.pow(10,3)) return digits(this,3)+'K'
426
+ return digits(this,0)
427
+ })
428
+
429
+
430
+ defineMethod(String,"getWord",function(wordPosition) {return this.split(/\s+/g,wordPosition+1)[wordPosition-1]??""})
431
+
432
+ const coalesce=(...args)=>{
433
+ for (var i=0; i<args.length; ++i)
434
+ if (args[i] != null) return args[i]
435
+ return null;
361
436
  }
437
+ const nullif=(a,b)=>{return a==b?null:a}
438
+ //missing Float16Array,
439
+ [ArrayBuffer,Number,Boolean,BigInt,Date,String,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,BigInt64Array,BigUint64Array,Float32Array,Float64Array].forEach(type=>{
440
+ defineMethod(type,"deepClone",function(){ return new type(this)})
441
+ })
442
+
443
+
444
+ //defineMethod(TypedArray,"deepClone",function(){ return new type(this)})
445
+ defineMethod(Array,"deepClone",function(){
446
+ const clone=[]
447
+ for (let i in this)
448
+ clone[i]=this[i].deepClone()
449
+ return clone
450
+ })
451
+ defineMethod(Object,"deepClone",function(){
452
+ const clone={}
453
+ for (let i in this)
454
+ clone[i]=this[i].deepClone()
455
+ return clone
456
+ })
457
+ defineMethod(Number, "rangeLimit",function(min,max) {return (min!=null && this<min) ? min : ((max!=null && this>max) ? max : this)})
458
+ defineMethod(BigInt, "rangeLimit",function(min,max) {return (min!=null && this<min) ? min : ((max!=null && this>max) ? max : this)})
459
+ defineMethod(Date, "rangeLimit",function(min,max) {return (min!=null && this<min) ? min : ((max!=null && this>max) ? max : this)})
460
+ defineMethod(String, "rangeLimit",function(min,max) {return (min!=null && this<min) ? min : ((max!=null && this>max) ? max : this)})
461
+ defineMethod(String,"deunderscore",function(){return this.replace(/_/g," ")})
462
+ defineMethod(String,"deunderscoreCapitilize",function(){return this.replace(/_/g," ").toTitle()})
463
+ defineMethod(String,"dropSquareBracketPrefix",function(bracket="[",endBracket="]"){return (this.substr(0,1)==bracket)? this.split(endBracket+" ")[1] : this})
464
+ module.exports={
465
+ coalesce:coalesce,
466
+ colours:colours,
467
+ colourSmallList:colourSmallList,
468
+ nullif:nullif,
469
+ toDateType,
470
+ toDateTypeZulu,
471
+ }
@@ -0,0 +1,77 @@
1
+
2
+ const setGetFunction=(RED,node,propertyName)=>node["get"+propertyName[0].toUpperCase() + propertyName.slice(1)]=getFunction(RED,node,propertyName)
3
+
4
+ const getFunction=(RED,node,propertyName)=>{
5
+ try{
6
+ const property=node[propertyName];
7
+ if(property==null) throw Error("no value for "+propertyName);
8
+ const propertyType=propertyName+"Type";
9
+ if(! (propertyType in node)) return eval("()=>node."+property)
10
+ const type=node[propertyType]
11
+ switch (type){
12
+ case "bin": // a Node.js Buffer
13
+ case "re": // a Regular Expression
14
+ case "jsonata": // a Jsonata Expression
15
+ case "cred": // a secure credential
16
+ case "bool":
17
+ case "json":
18
+ case "num":
19
+ case "str":
20
+ case "date": // the current timestamp
21
+ case "env":
22
+ case "global":
23
+ const value=RED.util.evaluateNodeProperty(property, type, node)
24
+ return eval("()=>value")
25
+ case "flow":
26
+ const flow = node.context().flow;
27
+ if(flow) throw Error("context store may be memoryonly so flow doesn't work")
28
+ return eval("()=>flow.get("+property+")");
29
+ case "msg":
30
+ return eval("(msg)=>msg."+property);
31
+ case "node":
32
+ const nodeContext = node.context();
33
+ return eval("()=>nodeContext.get("+property+")");
34
+ default:
35
+ throw Error("unknown type "+node[propertyType])
36
+ }
37
+ } catch(ex) {
38
+ throw Error(propertyName+" "+ex.message);
39
+ }
40
+
41
+ }
42
+ const setFunction=(RED,node,name)=>{
43
+ if(!name)
44
+ if(!node.hasOwnProperty(name)) throw Error("name is null")
45
+ if(!node.hasOwnProperty(name+"-type")) {
46
+ node.set[name]=eval("data=>msg.payload['"+name+"']=data)")
47
+ return
48
+ }
49
+ const type=node[name+"t-type"]
50
+ switch(type){
51
+ case "node":
52
+ node.set[name]=eval("data=>node.context().set("+node[name]+",data)")
53
+ break
54
+ case "flow":
55
+ const flow=node.context().flow
56
+ if(flow) throw Error("context store may be memory only so flow doesn't work")
57
+ node.set[name]=eval("data=>flow.set("+node[name]+",data)")
58
+ break
59
+ case "global":
60
+ node.set[name]=eval("data=>nodeContext.global.set("+node[name]+",data)")
61
+ break
62
+ case "msg":
63
+ node.set[name]=eval("(data,msg)=>{msg."+node[name]+"=data;}")
64
+ break
65
+ default:
66
+ throw Error("setData unknown type "+type)
67
+ }
68
+ }
69
+
70
+ const getValue=(RED,node,propertyName,defaultValue)=>propertyName in node?getFunction(RED,node,propertyName)():defaultValue
71
+
72
+ module.exports={
73
+ getFunction:getFunction,
74
+ setFunction:setFunction,
75
+ setGetFunction:setGetFunction,
76
+ getValue:getValue
77
+ }