@vbarbarosh/node-helpers 3.29.0 → 3.30.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/package.json
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const const_type = require('./const_type');
|
|
2
|
+
const gettype = require('./gettype');
|
|
3
|
+
const json_stringify_stable = require('./json_stringify_stable');
|
|
4
|
+
|
|
5
|
+
function object_schema(obj)
|
|
6
|
+
{
|
|
7
|
+
const type = gettype(obj);
|
|
8
|
+
switch (type) {
|
|
9
|
+
case const_type.array:
|
|
10
|
+
return obj.map(object_schema).map(v => json_stringify_stable(v)).sort().filter((v,i,a) => a[i-1] !== v).map(v => JSON.parse(v));
|
|
11
|
+
case const_type.object:
|
|
12
|
+
const out = {};
|
|
13
|
+
Object.keys(obj).forEach(function (key) {
|
|
14
|
+
out[key] = object_schema(obj[key]);
|
|
15
|
+
});
|
|
16
|
+
return out;
|
|
17
|
+
default:
|
|
18
|
+
return type;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = object_schema;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const object_schema = require('./object_schema');
|
|
3
|
+
|
|
4
|
+
describe('object_schema', function () {
|
|
5
|
+
it('basic 1', function () {
|
|
6
|
+
const actual = object_schema({aaa: 1, bbb: 2});
|
|
7
|
+
const expected = {aaa: 'number', bbb: 'number'};
|
|
8
|
+
assert.deepStrictEqual(actual, expected);
|
|
9
|
+
});
|
|
10
|
+
it('basic 2', function () {
|
|
11
|
+
const actual = object_schema({aaa: 1, bbb: [1, 2, 3, 4, 'str']});
|
|
12
|
+
const expected = {aaa: 'number', bbb: ['number', 'string']};
|
|
13
|
+
assert.deepStrictEqual(actual, expected);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -3,7 +3,7 @@ const ignore = require('./ignore');
|
|
|
3
3
|
const ssh2 = require('ssh2');
|
|
4
4
|
const waitcb = require('./waitcb');
|
|
5
5
|
|
|
6
|
-
async function sftp_get_file_info(url, {
|
|
6
|
+
async function sftp_get_file_info(url, {user_friendly_status = ignore})
|
|
7
7
|
{
|
|
8
8
|
const u = new URL(url);
|
|
9
9
|
const host = u.host;
|
|
@@ -12,7 +12,7 @@ async function sftp_get_file_info(url, {log = ignore})
|
|
|
12
12
|
const password = decodeURIComponent(u.password);
|
|
13
13
|
const pathname = u.pathname;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
user_friendly_status('Establishing connection...');
|
|
16
16
|
const conn = new ssh2.Client();
|
|
17
17
|
try {
|
|
18
18
|
await new Promise(function (resolve, reject) {
|
|
@@ -21,10 +21,10 @@ async function sftp_get_file_info(url, {log = ignore})
|
|
|
21
21
|
conn.connect({host, port, username, password});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
user_friendly_status('Asking for an sftp service...');
|
|
25
25
|
const sftp = await waitcb(cb => conn.sftp(cb));
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
user_friendly_status('Requesting file info...');
|
|
28
28
|
const [stat, lstat, readdir] = await Promise.all([
|
|
29
29
|
waitcb(cb => sftp.stat(pathname, cb)),
|
|
30
30
|
waitcb(cb => sftp.lstat(pathname, cb)),
|
|
@@ -2,7 +2,7 @@ const ignore = require('./ignore');
|
|
|
2
2
|
const ssh2 = require('ssh2');
|
|
3
3
|
const waitcb = require('./waitcb');
|
|
4
4
|
|
|
5
|
-
async function sftp_get_stream_range(url, first, last, {
|
|
5
|
+
async function sftp_get_stream_range(url, first, last, {user_friendly_status = ignore} = {})
|
|
6
6
|
{
|
|
7
7
|
const u = new URL(url);
|
|
8
8
|
const host = u.host;
|
|
@@ -11,7 +11,7 @@ async function sftp_get_stream_range(url, first, last, {log = ignore} = {})
|
|
|
11
11
|
const password = decodeURIComponent(u.password);
|
|
12
12
|
const pathname = u.pathname;
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
user_friendly_status('Establishing connection...');
|
|
15
15
|
const conn = new ssh2.Client();
|
|
16
16
|
await new Promise(function (resolve, reject) {
|
|
17
17
|
conn.on('ready', resolve);
|
|
@@ -19,10 +19,10 @@ async function sftp_get_stream_range(url, first, last, {log = ignore} = {})
|
|
|
19
19
|
conn.connect({host, port, username, password});
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
user_friendly_status('Asking for an sftp service...');
|
|
23
23
|
const sftp = await waitcb(cb => conn.sftp(cb));
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
user_friendly_status('Requesting file info...');
|
|
26
26
|
const stat = await waitcb(cb => sftp.stat(pathname, cb));
|
|
27
27
|
|
|
28
28
|
if (first < 0 || last >= stat.size) {
|
|
@@ -36,6 +36,7 @@ async function sftp_get_stream_range(url, first, last, {log = ignore} = {})
|
|
|
36
36
|
last,
|
|
37
37
|
total: stat.size,
|
|
38
38
|
};
|
|
39
|
+
out.total = out.content_range.total;
|
|
39
40
|
out.once('error', function () {
|
|
40
41
|
conn.destroy();
|
|
41
42
|
});
|
package/src/stream_parse_xml.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
const
|
|
1
|
+
const const_stream = require('./const_stream');
|
|
2
2
|
const htmlparser2 = require('htmlparser2');
|
|
3
|
+
const stream = require('stream');
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
+
* Consume XML, produce objects.
|
|
6
7
|
*/
|
|
7
|
-
function stream_parse_xml(selector, mapper = stream_parse_xml.
|
|
8
|
+
function stream_parse_xml(selector, mapper = stream_parse_xml.guess)
|
|
8
9
|
{
|
|
9
10
|
let out;
|
|
10
11
|
let elem = {name: '#doc', parent: null, attrs: {}, text: [], children: [], raw: []};
|
|
@@ -17,16 +18,15 @@ function stream_parse_xml(selector, mapper = stream_parse_xml.makeobj)
|
|
|
17
18
|
const events = {
|
|
18
19
|
onopentag: function (name, attrs) {
|
|
19
20
|
elem = {name, parent: elem, attrs, text: [], children: [], raw: []};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
elem.parent.children.push(elem);
|
|
23
|
-
}
|
|
21
|
+
elem.parent.raw.push(elem);
|
|
22
|
+
elem.parent.children.push(elem);
|
|
24
23
|
path.push(elem.name);
|
|
25
24
|
path_str = path.join('>');
|
|
26
25
|
},
|
|
27
26
|
onclosetag: function (name) {
|
|
28
27
|
if (path_str === selector_str) {
|
|
29
|
-
|
|
28
|
+
const tmp = mapper(elem);
|
|
29
|
+
out.push((tmp === null ? const_stream.null : tmp));
|
|
30
30
|
}
|
|
31
31
|
elem = elem.parent;
|
|
32
32
|
path.pop();
|
|
@@ -38,7 +38,8 @@ function stream_parse_xml(selector, mapper = stream_parse_xml.makeobj)
|
|
|
38
38
|
},
|
|
39
39
|
onend: function () {
|
|
40
40
|
if (selector_str === '') {
|
|
41
|
-
|
|
41
|
+
const tmp = mapper(elem);
|
|
42
|
+
out.push((tmp === null ? const_stream.null : tmp));
|
|
42
43
|
}
|
|
43
44
|
},
|
|
44
45
|
};
|
|
@@ -50,18 +51,71 @@ function stream_parse_xml(selector, mapper = stream_parse_xml.makeobj)
|
|
|
50
51
|
parser.write(buf.toString());
|
|
51
52
|
next();
|
|
52
53
|
},
|
|
54
|
+
flush: function (next) {
|
|
55
|
+
parser.end();
|
|
56
|
+
next();
|
|
57
|
+
},
|
|
53
58
|
});
|
|
54
59
|
}
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
function guess(node)
|
|
62
|
+
{
|
|
63
|
+
const attrs = Object.keys(node.attrs);
|
|
64
|
+
|
|
65
|
+
if (attrs.length === 0) {
|
|
66
|
+
if (node.raw.length === 0) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (node.children.length === 0) {
|
|
70
|
+
return node.text.join('').trim();
|
|
71
|
+
}
|
|
72
|
+
if (node.children.length > 1) {
|
|
73
|
+
const tmp = node.children[0].name;
|
|
74
|
+
if (node.children.every(v => v.name === tmp)) {
|
|
75
|
+
return node.children.map(v => stream_parse_xml.guess);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const out = {...node.attrs};
|
|
81
|
+
|
|
82
|
+
if (node.text.length) {
|
|
83
|
+
const tmp = node.text.join('').trim();
|
|
84
|
+
if (tmp) {
|
|
85
|
+
out.value = tmp;
|
|
86
|
+
}
|
|
59
87
|
}
|
|
60
|
-
|
|
88
|
+
|
|
61
89
|
node.children.forEach(function (child) {
|
|
62
|
-
|
|
90
|
+
const tmp = stream_parse_xml.guess(child);
|
|
91
|
+
if (child.name in out) {
|
|
92
|
+
if (Array.isArray(out[child.name])) {
|
|
93
|
+
out[child.name].push(tmp);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
out[child.name] = [out[child.name], tmp];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
out[child.name] = tmp;
|
|
101
|
+
}
|
|
63
102
|
});
|
|
103
|
+
|
|
64
104
|
return out;
|
|
65
105
|
}
|
|
66
106
|
|
|
107
|
+
function ashtml(node)
|
|
108
|
+
{
|
|
109
|
+
return node.raw.map(fn).filter(v => v).join('').trim();
|
|
110
|
+
function fn(item) {
|
|
111
|
+
if (typeof item === 'string') {
|
|
112
|
+
return item.replace(/\s+/g, ' ');
|
|
113
|
+
}
|
|
114
|
+
return `<${item.name}>${ashtml(item)}</${item.name}>` ;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
stream_parse_xml.guess = guess;
|
|
119
|
+
stream_parse_xml.ashtml = ashtml;
|
|
120
|
+
|
|
67
121
|
module.exports = stream_parse_xml;
|
package/src/stream_progress.js
CHANGED
|
@@ -7,7 +7,7 @@ const stream = require('stream');
|
|
|
7
7
|
*
|
|
8
8
|
* @similar https://www.npmjs.com/package/progress-stream
|
|
9
9
|
*/
|
|
10
|
-
function stream_progress({total, user_friendly_status = s => console.log(s)})
|
|
10
|
+
function stream_progress({total, user_friendly_status = s => console.log(s)} = {})
|
|
11
11
|
{
|
|
12
12
|
let done = 0;
|
|
13
13
|
const timer = setInterval(tick, 1000);
|