node-red-contrib-prib-functions 0.23.2 → 0.26.0
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/copilot-instructions.md +36 -0
- package/README.md +153 -140
- package/columnar/columnar.html +258 -0
- package/columnar/columnar.js +1055 -0
- package/columnar/icons/columnar.svg +38 -0
- package/fileSystem/filesystem.html +299 -0
- package/fileSystem/filesystem.js +170 -0
- package/gitlab/gitlab.html +191 -0
- package/gitlab/gitlab.js +248 -0
- package/gitlab/icons/gitlab.svg +17 -0
- package/lib/AlphaBeta.js +32 -0
- package/lib/GraphDB.js +40 -9
- package/lib/MinMax.js +17 -0
- package/lib/Tree.js +64 -0
- package/lib/objectExtensions.js +28 -5
- package/lib/timeDimension.js +36 -0
- package/lib/typedInput.js +18 -2
- package/logisticRegression/icons/logisticregression.svg +22 -0
- package/logisticRegression/logisticRegression.html +136 -0
- package/logisticRegression/logisticRegression.js +83 -0
- package/package.json +21 -9
- package/test/02-graphdb.js +46 -0
- package/test/columnar.js +509 -0
- package/test/data/.config.nodes.json +114 -70
- package/test/data/.config.nodes.json.backup +104 -71
- package/test/data/.config.runtime.json +2 -1
- package/test/data/.config.runtime.json.backup +2 -1
- package/test/data/.config.users.json +3 -2
- package/test/data/.config.users.json.backup +3 -2
- package/test/data/.flow.json.backup +1545 -369
- package/test/data/flow.json +1457 -270
- package/test/data/package-lock.json +11 -11
- package/test/data/shares/.config.nodes.json +611 -0
- package/test/data/shares/.config.nodes.json.backup +589 -0
- package/test/data/shares/.config.runtime.json +5 -0
- package/test/data/shares/.config.runtime.json.backup +4 -0
- package/test/data/shares/.config.users.json +33 -0
- package/test/data/shares/.config.users.json.backup +33 -0
- package/test/data/shares/.flow.json.backup +230 -0
- package/test/data/shares/.flow_cred.json.backup +3 -0
- package/test/data/shares/flow.json +267 -0
- package/test/data/shares/flow_cred.json +3 -0
- package/test/data/shares/package.json +6 -0
- package/test/data/shares/settings.js +544 -0
- package/test/dataAnalysisExtensions.js +93 -93
- package/test/logisticRegression.js +379 -0
- package/test/transform.js +11 -11
- package/test/transformConfluence.js +4 -2
- package/test/transformNumPy.js +3 -1
- package/test/transformXLSX.js +4 -2
- package/test/transformXML.js +4 -2
- package/test-runner.js +400 -0
- package/test.parq +0 -0
- package/test_select.js +37 -0
- package/testing/test.js +8 -7
- package/transform/transform.html +23 -2
- package/transform/transform.js +239 -283
- package/transform/xlsx2.js +74 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="columnarGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#8BC34A;stop-opacity:1" />
|
|
5
|
+
<stop offset="100%" style="stop-color:#4CAF50;stop-opacity:1" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<!-- Database/storage base -->
|
|
10
|
+
<rect x="2" y="20" width="28" height="8" rx="2" fill="url(#columnarGradient)" opacity="0.8"/>
|
|
11
|
+
|
|
12
|
+
<!-- Column bars representing columnar storage -->
|
|
13
|
+
<rect x="4" y="8" width="3" height="12" fill="url(#columnarGradient)"/>
|
|
14
|
+
<rect x="9" y="6" width="3" height="14" fill="url(#columnarGradient)"/>
|
|
15
|
+
<rect x="14" y="10" width="3" height="10" fill="url(#columnarGradient)"/>
|
|
16
|
+
<rect x="19" y="4" width="3" height="16" fill="url(#columnarGradient)"/>
|
|
17
|
+
<rect x="24" y="12" width="3" height="8" fill="url(#columnarGradient)"/>
|
|
18
|
+
|
|
19
|
+
<!-- Data points on columns -->
|
|
20
|
+
<circle cx="5.5" cy="10" r="1" fill="#FFFFFF"/>
|
|
21
|
+
<circle cx="5.5" cy="14" r="1" fill="#FFFFFF"/>
|
|
22
|
+
<circle cx="5.5" cy="18" r="1" fill="#FFFFFF"/>
|
|
23
|
+
|
|
24
|
+
<circle cx="10.5" cy="8" r="1" fill="#FFFFFF"/>
|
|
25
|
+
<circle cx="10.5" cy="12" r="1" fill="#FFFFFF"/>
|
|
26
|
+
<circle cx="10.5" cy="16" r="1" fill="#FFFFFF"/>
|
|
27
|
+
|
|
28
|
+
<circle cx="15.5" cy="12" r="1" fill="#FFFFFF"/>
|
|
29
|
+
<circle cx="15.5" cy="16" r="1" fill="#FFFFFF"/>
|
|
30
|
+
|
|
31
|
+
<circle cx="20.5" cy="6" r="1" fill="#FFFFFF"/>
|
|
32
|
+
<circle cx="20.5" cy="10" r="1" fill="#FFFFFF"/>
|
|
33
|
+
<circle cx="20.5" cy="14" r="1" fill="#FFFFFF"/>
|
|
34
|
+
<circle cx="20.5" cy="18" r="1" fill="#FFFFFF"/>
|
|
35
|
+
|
|
36
|
+
<circle cx="25.5" cy="14" r="1" fill="#FFFFFF"/>
|
|
37
|
+
<circle cx="25.5" cy="18" r="1" fill="#FFFFFF"/>
|
|
38
|
+
</svg>
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
/*globals RED */
|
|
3
|
+
RED.nodes.registerType('filesystem', {
|
|
4
|
+
category: 'storage',
|
|
5
|
+
color: '#fdeea2',
|
|
6
|
+
defaults: {
|
|
7
|
+
name: {value: ""},
|
|
8
|
+
action: {value:"read",required:true}
|
|
9
|
+
},
|
|
10
|
+
inputs: 1,
|
|
11
|
+
outputs: 2,
|
|
12
|
+
icon: "icons8-one-way-transition-80.png",
|
|
13
|
+
align: 'left',
|
|
14
|
+
paletteLabel: "filesystem",
|
|
15
|
+
inputLabels: "Message In",
|
|
16
|
+
outputLabels: ["Message Out","Error"],
|
|
17
|
+
label: function () {
|
|
18
|
+
return this.name ?? this.action
|
|
19
|
+
},
|
|
20
|
+
actionArgs:{
|
|
21
|
+
"access":["path","mode"],
|
|
22
|
+
"appendFile":["path","data","options"],
|
|
23
|
+
"chmod":["path","mode"],
|
|
24
|
+
"chown":["path","uid","gid"],
|
|
25
|
+
"close":["fd"],
|
|
26
|
+
"copyFile":["src","dest","mode"],
|
|
27
|
+
"cp":["src","dest","options"],
|
|
28
|
+
"createReadStream":["path","options"],
|
|
29
|
+
"createWriteStream":["path","options"],
|
|
30
|
+
"fchmod":["fd","mode"],
|
|
31
|
+
"fchown":["fd","uid","gid"],
|
|
32
|
+
"fdatasync":["fd"],
|
|
33
|
+
"fstat":["fd","options"],
|
|
34
|
+
"fsync":["fd"],
|
|
35
|
+
"ftruncate":["fd","len"],
|
|
36
|
+
"futimes":["fd","atime","mtime"],
|
|
37
|
+
"glob":["pattern","options"],
|
|
38
|
+
"lchmod":["path","mode"],
|
|
39
|
+
"lchown":["path","uid","gid"],
|
|
40
|
+
"lutimes":["path","atime","mtime"],
|
|
41
|
+
"link":["existingPath","newPath"],
|
|
42
|
+
"lstat":["path","options"],
|
|
43
|
+
"mkdir":["path","options"],
|
|
44
|
+
"mkdtemp":["prefix","options"],
|
|
45
|
+
"open":["path","flags","mode"],
|
|
46
|
+
"openAsBlob":["path","options"],
|
|
47
|
+
"opendir":["path","options"],
|
|
48
|
+
"read":["fd","buffer","offset","length","position"],
|
|
49
|
+
"read":["fd","options"],
|
|
50
|
+
"read":["fd","buffer","options"],
|
|
51
|
+
"readdir":["path","options"],
|
|
52
|
+
"readFile":["path","options"],
|
|
53
|
+
"readlink":["path","options"],
|
|
54
|
+
"readv":["fd","buffers","position"],
|
|
55
|
+
"realpath":["path","options"],
|
|
56
|
+
"realpath.native":["path","options"],
|
|
57
|
+
"rename":["oldPath","newPath"],
|
|
58
|
+
"rmdir":["path","options"],
|
|
59
|
+
"rm":["path","options"],
|
|
60
|
+
"stat":["path","options"],
|
|
61
|
+
"statfs":["path","options"],
|
|
62
|
+
"symlink":["target","path","type"],
|
|
63
|
+
"truncate":["path","length"],
|
|
64
|
+
"unlink":["path"],
|
|
65
|
+
"unwatchFile":["filename","listener"],
|
|
66
|
+
"utimes":["path","atime","mtime"],
|
|
67
|
+
"watch":["filename","options","listener"],
|
|
68
|
+
"watchFile":["filename","options","listener"],
|
|
69
|
+
"writeDirect":["fd","buffer","offset","length","position]"],
|
|
70
|
+
"write":["fd","buffer","options"],
|
|
71
|
+
"writeString":["fd","string","position","encoding"],
|
|
72
|
+
"writeFile":["file","data","options"],
|
|
73
|
+
"writev":["fd","buffers","position"]
|
|
74
|
+
},
|
|
75
|
+
argTypes:{
|
|
76
|
+
"atime":{_types:["num","msg"],label:null},
|
|
77
|
+
"buffer":{_types:["msg"],label:null,default:"payload.buffer"},
|
|
78
|
+
"buffers":{_types:['msg'],label:null},
|
|
79
|
+
"encoding":{_types:["str","msg"],label:null},
|
|
80
|
+
"fd":{_types:["msg"],label:null,default:"payload.fd"},
|
|
81
|
+
"flags":{
|
|
82
|
+
typedInput:{
|
|
83
|
+
type:"flags",
|
|
84
|
+
types:[{
|
|
85
|
+
value: "flags",
|
|
86
|
+
multiple: false,
|
|
87
|
+
options: [
|
|
88
|
+
{value: "a", label: "Open for appending, created if missing"},
|
|
89
|
+
{value: "ax", label: "Open for appending"},
|
|
90
|
+
{value: "a+", label: "Open for reading + appending, created if missing"},
|
|
91
|
+
{value: "ax+", label: "Open for reading + appending"},
|
|
92
|
+
{value: "as", label: "Open for synchronous appending, file created if missing"},
|
|
93
|
+
{value: "as+", label: "Open for synchronous reading and appending,created if missing"},
|
|
94
|
+
{value: "r", label: "Open for reading"},
|
|
95
|
+
{value: "rs", label: "Open for synchronous reading"},
|
|
96
|
+
{value: "r+", label: "Open for synchronous reading and writing"},
|
|
97
|
+
{value: "rs+", label: "Open for synchronous reading and writing, bypass system caching"},
|
|
98
|
+
{value: "w", label: "Open for synchronous writing, created if missing or truncated"},
|
|
99
|
+
{value: "wx", label: "Open for synchronous writing, truncated"},
|
|
100
|
+
{value: "w+", label: "Open reading and writing, created if missing or truncated"},
|
|
101
|
+
{value: "wx+", label: "Open reading and writing"}
|
|
102
|
+
]
|
|
103
|
+
}]
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"uid":{_types:["num","msg"],label:null},
|
|
107
|
+
"gid":{_types:["num","msg"],label:null},
|
|
108
|
+
"length":{_types:["msg","num"],label:null,default:"payload.length"},
|
|
109
|
+
"listener":{_types:["msg"],label:null},
|
|
110
|
+
"mode":{
|
|
111
|
+
label:null,
|
|
112
|
+
typedInput:{
|
|
113
|
+
type:"modes",
|
|
114
|
+
types:[{
|
|
115
|
+
value: "modes",
|
|
116
|
+
multiple: false,
|
|
117
|
+
options: [
|
|
118
|
+
{value: "F_OK", label: "Visible"},
|
|
119
|
+
{value: "R_OK", label: "Read"},
|
|
120
|
+
{value: "W_OK", label: "Write"},
|
|
121
|
+
{value: "X_OK", label: "Execute"},
|
|
122
|
+
]
|
|
123
|
+
}]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"mode-file":{
|
|
127
|
+
label:null,
|
|
128
|
+
typedInput:{
|
|
129
|
+
type:"modes",
|
|
130
|
+
types:[{
|
|
131
|
+
value: "modes",
|
|
132
|
+
multiple: false,
|
|
133
|
+
options: [
|
|
134
|
+
{value: "S_IRUSR", label: "read by owner"},
|
|
135
|
+
{value: "S_IWUSR", label: "write by owner"},
|
|
136
|
+
{value: "S_IXUSR", label: "execute/search by owner"},
|
|
137
|
+
{value: "S_IRGRP", label: "read by group"},
|
|
138
|
+
{value: "S_IWGRP", label: "write by group"},
|
|
139
|
+
{value: "S_IXGRP", label: "execute/search by group"},
|
|
140
|
+
{value: "S_IROTH", label: "read by others"},
|
|
141
|
+
{value: "S_IWOTH", label: "write by others"},
|
|
142
|
+
{value: "S_IXOTH", label: "execute/search by others"},
|
|
143
|
+
]
|
|
144
|
+
}]
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"mtime":{_types:["num","msg"],label:null},
|
|
148
|
+
"newPath":{_types:["str","msg"],label:null},
|
|
149
|
+
"options":{
|
|
150
|
+
appendFile:{
|
|
151
|
+
encoding: {types:['str'],label:null}, //<string> | <null> Default: 'utf8'
|
|
152
|
+
mode: {types:['str'],label:null}, // <integer> Default: 0o666
|
|
153
|
+
flag:"$flag", // <string> See support of file system flags. Default: 'a'.
|
|
154
|
+
flush:{types:['boolean']}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"path":{_types:['msg','str','flow','global','jsonata','env'],label:null,default:"payload.path"},
|
|
158
|
+
"pattern":{_types:["str","msg"],label:null},
|
|
159
|
+
"offset":{_types:["msg","num"],label:null,default:"payload.offset"},
|
|
160
|
+
"position":{_types:["msg","num"],label:null,default:"payload.position"},
|
|
161
|
+
"prefix":{_types:["str","msg"],label:null},
|
|
162
|
+
"string":{_types:["str","msg"],label:null},
|
|
163
|
+
"type":{_types:["str","msg"],label:null},
|
|
164
|
+
"dest":{_types:['str','msg','flow','global','jsonata','env'],label:"destination"},
|
|
165
|
+
"existingPath":{_types:['str','msg','flow','global','jsonata','env'],label:"existing path"},
|
|
166
|
+
"filename":{_types:['str','msg','flow','global','jsonata','env'],label:"file name"},
|
|
167
|
+
"oldPath":{_types:['str','msg','flow','global','jsonata','env'],label:"old path"},
|
|
168
|
+
"src":{_types:['str','msg','flow','global','jsonata','env'],label:"source"},
|
|
169
|
+
"target":{_types:['msg'],label:"Target",default:"payload.result"}
|
|
170
|
+
},
|
|
171
|
+
addInput: function (baseElement, property, label = property) {
|
|
172
|
+
// console.log("adding field "+property)
|
|
173
|
+
const div=$('<div>', {id:'form-row-http-in-'+property, class: "form-row" })
|
|
174
|
+
const input=$('<input>', { type: 'text', id: 'node-input-' + property, style: "width:70%" })
|
|
175
|
+
const inputType=$('<input>', { type: 'hidden', id: 'node-input-' + property + 'Type' })
|
|
176
|
+
div.append(
|
|
177
|
+
$('<label>', {for:"node-input-" + property}).append(
|
|
178
|
+
$('<i>', {class:"fa fa-bookmark"}),
|
|
179
|
+
$('<span>').attr("data-i18n", "common.label.string").text(" "+(label??property))
|
|
180
|
+
),
|
|
181
|
+
input,
|
|
182
|
+
inputType
|
|
183
|
+
)
|
|
184
|
+
baseElement.append(div)
|
|
185
|
+
const argType=this.argTypes[property]
|
|
186
|
+
argType.input=input
|
|
187
|
+
argType.inputType=inputType
|
|
188
|
+
if(argType.typedInput)
|
|
189
|
+
return input.typedInput(argType.typedInput)
|
|
190
|
+
const types=argType.types
|
|
191
|
+
input.typedInput({
|
|
192
|
+
default: types[0],
|
|
193
|
+
typeField: inputType,
|
|
194
|
+
types:types,
|
|
195
|
+
validate: ()=>{
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
},
|
|
199
|
+
setProperty:function(property,value){
|
|
200
|
+
try{
|
|
201
|
+
// console.log("set "+property)
|
|
202
|
+
if(property.hasOwnProperty("_types")){
|
|
203
|
+
$("#form-row-http-in-"+property).show()
|
|
204
|
+
const argType=this.argTypes[property]
|
|
205
|
+
argType.input.typedInput('value',value??argType.default??"")
|
|
206
|
+
// argType.inputType.val(_this[property+"type"])
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
Object.keys(value).forEach(p=>this.setProperty(p,value[p]))
|
|
210
|
+
} catch(ex){
|
|
211
|
+
console.error("setProperty error "+ex.message);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
oneditprepare: function() {
|
|
215
|
+
const _this=this
|
|
216
|
+
const nodeBase=this._def
|
|
217
|
+
const inputBase=$("#input-base")
|
|
218
|
+
for(const property in nodeBase.argTypes) nodeBase.addInput(inputBase,property,nodeBase.argTypes[property].label)
|
|
219
|
+
const action=this.action
|
|
220
|
+
const actions=Object.keys(nodeBase.actionArgs).map(property=>({value:property,label:property}))
|
|
221
|
+
$("#node-input-action").typedInput({type:"action", types:[{
|
|
222
|
+
value: "action",
|
|
223
|
+
options: actions
|
|
224
|
+
}]});
|
|
225
|
+
|
|
226
|
+
$("#node-input-action").change(function() {
|
|
227
|
+
const action=$(this).val();
|
|
228
|
+
Object.keys(nodeBase.argTypes).forEach(property=>{
|
|
229
|
+
try{
|
|
230
|
+
$("#form-row-http-in-"+property).hide()
|
|
231
|
+
} catch(ex){
|
|
232
|
+
console.error("hide in row error "+ex.message);
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
nodeBase.actionArgs[action].forEach(property=>nodeBase.setProperty(property,_this[property]))
|
|
236
|
+
if(["open","createWriteStream","exists","fstat","fsync","lstat","mkdir","mkdtemp","open",
|
|
237
|
+
"openAsBlob","opendir","read","readdir","readFile","readlink","readv","realpath","stat","statfs",
|
|
238
|
+
"watch","watchFile","write","writev","existsSync","globSync","lstatSync","mkdirSync","mkdtempSync",
|
|
239
|
+
"mkdtempDisposableSync","opendirSync","openSync","readdirSync","readFileSync","readlinkSync",
|
|
240
|
+
"readSync","readSync"
|
|
241
|
+
].includes(action)
|
|
242
|
+
)
|
|
243
|
+
nodeBase.setProperty("target",_this.target)
|
|
244
|
+
}).change();
|
|
245
|
+
},
|
|
246
|
+
oneditsave: function() {
|
|
247
|
+
const _this=this
|
|
248
|
+
const nodeBase=this._def
|
|
249
|
+
nodeBase.actionArgs[this.action].forEach(property=>{
|
|
250
|
+
const argType=nodeBase.argTypes[property]
|
|
251
|
+
if(argType.hasOwnProperty("_types")){
|
|
252
|
+
_this[property]=argType.input.typedInput('value');
|
|
253
|
+
_this[property+"type"]=argType.input.typedInput('type')
|
|
254
|
+
return
|
|
255
|
+
}
|
|
256
|
+
for (const p in argType) {
|
|
257
|
+
_this[p]=argType[p].input.typedInput('value')
|
|
258
|
+
_this[p+"type"]=argType[p].input.typedInput('type')
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
},
|
|
262
|
+
resizeRule : function(file,newWidth) {
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
</script>
|
|
266
|
+
|
|
267
|
+
<script type="text/x-red" data-template-name="filesystem">
|
|
268
|
+
<div class="form-row">
|
|
269
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name </label>
|
|
270
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
271
|
+
</div>
|
|
272
|
+
<div class="form-row">
|
|
273
|
+
<label for="node-input-action"><i class="fa fa-tag"></i> Action </label>
|
|
274
|
+
<input type="select" id="node-input-action" placeholder="Action">
|
|
275
|
+
</div>
|
|
276
|
+
<div id="input-base">
|
|
277
|
+
</div>
|
|
278
|
+
|
|
279
|
+
</script>
|
|
280
|
+
|
|
281
|
+
<script type="text/x-red" data-help-name="filesystem">
|
|
282
|
+
<p>filesystem</p>
|
|
283
|
+
<p>
|
|
284
|
+
</p>
|
|
285
|
+
<h3>Inputs</h3>
|
|
286
|
+
<dl class="message-properties">
|
|
287
|
+
<dt>msg <span class="property-type">topic</span></dt>
|
|
288
|
+
<dd>incoming message with topic</dd>
|
|
289
|
+
<dt>msg <span class="property-type">payload</span></dt>
|
|
290
|
+
<dd></dd>
|
|
291
|
+
</dl>
|
|
292
|
+
<h3>Ports</h3>
|
|
293
|
+
<dl class="message-properties">
|
|
294
|
+
<dt><span class="property-type">message out</span></dt>
|
|
295
|
+
<dd>Inbound message with </dd>
|
|
296
|
+
<dt><span class="property-type">error</span></dt>
|
|
297
|
+
<dd>a message where msg.error details error</dd>
|
|
298
|
+
</dl>
|
|
299
|
+
</script>
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
const logger = new (require("node-red-contrib-logger"))("filesystem");
|
|
2
|
+
logger.sendInfo("Copyright 2025 Jaroslav Peter Prib");
|
|
3
|
+
|
|
4
|
+
const fs=require('fs')
|
|
5
|
+
const typedInput=require('../lib/typedInput')
|
|
6
|
+
|
|
7
|
+
const actionReturnsValue=["createReadStream","exists","fstat","lstat","mkdir","mkdtemp","open","opendir"]
|
|
8
|
+
|
|
9
|
+
const mode={
|
|
10
|
+
access:{
|
|
11
|
+
"exists":fs.constants.F_OK,
|
|
12
|
+
"readable":fs.constants.R_OK,
|
|
13
|
+
"writable":fs.constants.W_OK,
|
|
14
|
+
"executable":fs.constants.X_OK
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const OpenErrors={
|
|
19
|
+
"EEXIST":"File already exists",
|
|
20
|
+
"ENOENT":"File does not exist"
|
|
21
|
+
}
|
|
22
|
+
const setAndSend=(msg,value)=>{
|
|
23
|
+
const node=msg._temp.node
|
|
24
|
+
node.setTarget(msg,value)
|
|
25
|
+
delete node._temp
|
|
26
|
+
node.send(msg)
|
|
27
|
+
}
|
|
28
|
+
const setAndSendError=(msg,value)=>{
|
|
29
|
+
const node=msg._temp.node
|
|
30
|
+
node.setTarget(msg,value)
|
|
31
|
+
delete node._temp
|
|
32
|
+
node.send([null,msg])
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const callbacks={
|
|
36
|
+
default:err=>setAndSendError(this, err==null),
|
|
37
|
+
open:(err,fd)=>{
|
|
38
|
+
if(err){
|
|
39
|
+
try{
|
|
40
|
+
setAndSendError(this,openErrors[err])
|
|
41
|
+
} catch(ex){
|
|
42
|
+
setAndSendError(this,err)
|
|
43
|
+
}
|
|
44
|
+
} else
|
|
45
|
+
setAndSend(this,fd)
|
|
46
|
+
},
|
|
47
|
+
read:(err,data)=>{
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
callbacks.stat=callbacks.read
|
|
51
|
+
callbacks.access=callbacks.default
|
|
52
|
+
callbacks.appendFile=callbacks.default
|
|
53
|
+
callbacks.chmod=callbacks.default
|
|
54
|
+
callbacks.chown=callbacks.default
|
|
55
|
+
callbacks.close=callbacks.default
|
|
56
|
+
callbacks.copyFile=callbacks.default
|
|
57
|
+
callbacks.cp=callbacks.default
|
|
58
|
+
|
|
59
|
+
const fsArgs={
|
|
60
|
+
"access":["path","mode","callback"],
|
|
61
|
+
"appendFile":["path","data","options","callback"],
|
|
62
|
+
"chmod":["path","mode","callback"],
|
|
63
|
+
"chown":["path","uid","gid","callback"],
|
|
64
|
+
"close":["fd","callback"],
|
|
65
|
+
"copyFile":["src","dest","mode","callback"],
|
|
66
|
+
"cp":["src","dest","options","callback"],
|
|
67
|
+
"createReadStream":["path","options"],
|
|
68
|
+
"createWriteStream":["path","options"],
|
|
69
|
+
"exists":["path","callback"],
|
|
70
|
+
"fchmod":["fd","mode","callback"],
|
|
71
|
+
"fchown":["fd","uid","gid","callback"],
|
|
72
|
+
"fdatasync":["fd","callback"],
|
|
73
|
+
"fstat":["fd","options","callback"],
|
|
74
|
+
"fsync":["fd","callback"],
|
|
75
|
+
"ftruncate":["fd","len","callback"],
|
|
76
|
+
"futimes":["fd","atime","mtime","callback"],
|
|
77
|
+
"glob":["pattern","options","callback"],
|
|
78
|
+
"lchmod":["path","mode","callback"],
|
|
79
|
+
"lchown":["path","uid","gid","callback"],
|
|
80
|
+
"lutimes":["path","atime","mtime","callback"],
|
|
81
|
+
"link":["existingPath","newPath","callback"],
|
|
82
|
+
"lstat":["path","options","callback"],
|
|
83
|
+
"mkdir":["path","options","callback"],
|
|
84
|
+
"mkdtemp":["prefix","options","callback"],
|
|
85
|
+
"open":["path","flags","mode]","callback"],
|
|
86
|
+
"openAsBlob":["path","options"],
|
|
87
|
+
"opendir":["path","options","callback"],
|
|
88
|
+
"read":["fd","buffer","offset","length","position","callback"],
|
|
89
|
+
"read":["fd","options","callback"],
|
|
90
|
+
"read":["fd","buffer","options","callback"],
|
|
91
|
+
"readdir":["path","options","callback"],
|
|
92
|
+
"readFile":["path","options","callback"],
|
|
93
|
+
"readlink":["path","options","callback"],
|
|
94
|
+
"readv":["fd","buffers","position","callback"],
|
|
95
|
+
"realpath":["path","options","callback"],
|
|
96
|
+
"realpath.native":["path","options","callback"],
|
|
97
|
+
"rename":["oldPath","newPath","callback"],
|
|
98
|
+
"rmdir":["path","options","callback"],
|
|
99
|
+
"rm":["path","options","callback"],
|
|
100
|
+
"stat":["path","options","callback"],
|
|
101
|
+
"statfs":["path","options","callback"],
|
|
102
|
+
"symlink":["target","path","type","callback"],
|
|
103
|
+
"truncate":["path","length","callback"],
|
|
104
|
+
"unlink":["path","callback"],
|
|
105
|
+
"unwatchFile":["filename","listener"],
|
|
106
|
+
"utimes":["path","atime","mtime","callback"],
|
|
107
|
+
"watch":["filename","options","listener"],
|
|
108
|
+
"watchFile":["filename","options","listener"],
|
|
109
|
+
"writeDirect":["fd","buffer","offset","length","position]","callback"],
|
|
110
|
+
"write":["fd","buffer","options","callback"],
|
|
111
|
+
"writeString":["fd","string","position","encoding","callback"],
|
|
112
|
+
"writeFile":["file","data","options","callback"],
|
|
113
|
+
"writev":["fd","buffers","position","callback"]
|
|
114
|
+
}
|
|
115
|
+
/*
|
|
116
|
+
const options={
|
|
117
|
+
append [encoding <string> | <null> Default: 'utf8'
|
|
118
|
+
mode <integer> Default: 0o666
|
|
119
|
+
flag <string> See support of file system flags. Default: 'a'.
|
|
120
|
+
flush <boolean> If true, the underlying file descriptor is flushed prior to closing it. Default: false.
|
|
121
|
+
}
|
|
122
|
+
*/
|
|
123
|
+
module.exports = function (RED) {
|
|
124
|
+
function filesystemNode(config) {
|
|
125
|
+
RED.nodes.createNode(this, config);
|
|
126
|
+
const node=Object.assign(this,config)
|
|
127
|
+
try{
|
|
128
|
+
node.actionFunction=fs[node.action]
|
|
129
|
+
node.argList=fsArgs[node.action]
|
|
130
|
+
const argFunctions=getArgFunctions(RED,node,node.argList)
|
|
131
|
+
if(node.argList.includes("callback")){
|
|
132
|
+
node.callback=callbacks[node.action]
|
|
133
|
+
} else {
|
|
134
|
+
node.processFunction=(RED,msg,node)=>{
|
|
135
|
+
node.actionFunction()
|
|
136
|
+
node.send(msg)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
setCallback(node)
|
|
140
|
+
node.status({fill:"green",shape:"ring"})
|
|
141
|
+
if(node.action=="open"){
|
|
142
|
+
this.openedFiles=[]
|
|
143
|
+
node.close = function (removed, done) {
|
|
144
|
+
logger.send({ label: 'close',node:{id:node.id,name:node.name}})
|
|
145
|
+
this.openedFiles.forEach(opened=>{
|
|
146
|
+
try {
|
|
147
|
+
close(open.fdfd,err=>{
|
|
148
|
+
logger({label:"closed",msg:opened_msgid})
|
|
149
|
+
})
|
|
150
|
+
} catch (ex) {
|
|
151
|
+
logger.sendErrorAndStackDump(ex.message, ex)
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
done()
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
node.on("input", function(msg) {
|
|
158
|
+
try{
|
|
159
|
+
msg._temp={node:node,RED:RED}
|
|
160
|
+
node.processFunction.call(typedInput.getArgsFromFunctions(RED,node,msg,argFunctions))
|
|
161
|
+
} catch(ex) {
|
|
162
|
+
logger.sendErrorAndStackDump(ex.message, ex)
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
} catch (ex){
|
|
166
|
+
node.status({fill:"red",shape:"ring"});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
RED.nodes.registerType(logger.label,filesystemNode);
|
|
170
|
+
}
|