hfs 0.46.1 → 0.47.0-alpha5
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 +4 -4
- package/admin/assets/{index-35f6e3dc.css → index-20dd43f3.css} +1 -1
- package/admin/assets/index-fb9e0c09.js +518 -0
- package/{frontend/assets/sha512-d9635c9d.js → admin/assets/sha512-da763b08.js} +1 -1
- package/admin/index.html +2 -2
- package/frontend/assets/index-0e105986.js +94 -0
- package/{admin/assets/sha512-3412b98f.js → frontend/assets/sha512-5c008206.js} +1 -1
- package/frontend/index.html +1 -2
- package/package.json +2 -2
- package/plugins/list-uploader/plugin.js +1 -1
- package/plugins/list-uploader/public/main.js +9 -10
- package/src/adminApis.js +20 -5
- package/src/api.file_list.js +3 -2
- package/src/api.monitor.js +34 -31
- package/src/api.vfs.js +37 -34
- package/src/apiMiddleware.js +42 -14
- package/src/commands.js +2 -2
- package/src/config.js +15 -12
- package/src/connections.js +3 -4
- package/src/consoleLog.js +17 -0
- package/src/const.js +4 -3
- package/src/frontEndApis.js +17 -10
- package/src/index.js +3 -1
- package/src/langs/hfs-lang-it.json +2 -2
- package/src/langs/hfs-lang-ru.json +3 -3
- package/src/log.js +2 -2
- package/src/middlewares.js +2 -2
- package/src/misc.js +5 -1
- package/src/serveFile.js +2 -1
- package/src/throttler.js +1 -1
- package/src/update.js +44 -7
- package/src/util-http.js +8 -3
- package/src/vfs.js +36 -12
- package/admin/assets/index-7f1741ba.js +0 -517
- package/frontend/assets/index-b49b8a16.js +0 -94
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as OF,c as UF}from"./index-
|
|
1
|
+
import{g as OF,c as UF}from"./index-0e105986.js";function gF(sF,hF){for(var eF=0;eF<hF.length;eF++){const tF=hF[eF];if(typeof tF!="string"&&!Array.isArray(tF)){for(const w in tF)if(w!=="default"&&!(w in sF)){const lF=Object.getOwnPropertyDescriptor(tF,w);lF&&Object.defineProperty(sF,w,lF.get?lF:{enumerable:!0,get:()=>tF[w]})}}}return Object.freeze(Object.defineProperty(sF,Symbol.toStringTag,{value:"Module"}))}var dF={exports:{}};/*
|
|
2
2
|
* [js-sha512]{@link https://github.com/emn178/js-sha512}
|
|
3
3
|
*
|
|
4
4
|
* @version 0.8.0
|
package/frontend/index.html
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0" />
|
|
6
6
|
<link href="/fontello.css" rel="stylesheet" />
|
|
7
|
-
<script>HFS={}</script>
|
|
8
7
|
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-0e105986.js"></script>
|
|
10
9
|
<link rel="stylesheet" href="/assets/index-f2f8fd6b.css">
|
|
11
10
|
</head>
|
|
12
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hfs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0-alpha5",
|
|
4
4
|
"description": "HTTP File Server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"file server",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"fast-glob": "^3.2.7",
|
|
69
69
|
"find-process": "^1.4.7",
|
|
70
70
|
"formidable": "^2.1.1",
|
|
71
|
-
"fs-x-attributes": "^1.0.
|
|
71
|
+
"fs-x-attributes": "^1.0.2",
|
|
72
72
|
"koa": "^2.13.4",
|
|
73
73
|
"koa-compress": "^5.1.0",
|
|
74
74
|
"koa-mount": "^4.0.0",
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
"use strict";{
|
|
2
|
+
const { React } = HFS
|
|
2
3
|
const { display } = HFS.getPluginConfig()
|
|
3
4
|
|
|
4
5
|
HFS.onEvent('additionalEntryDetails', ({ entry }) =>
|
|
5
6
|
HFS.h(Uploader, entry))
|
|
6
7
|
|
|
7
|
-
const cache = {}
|
|
8
|
-
|
|
9
8
|
function Uploader({ uri }) {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const [freshData, error] = HFS.useApi(!cachedData && 'get_file_details', { uri: fullUri })
|
|
13
|
-
if (!cachedData)
|
|
14
|
-
cache[fullUri] = freshData || Boolean(error)
|
|
15
|
-
const data = freshData || cachedData
|
|
16
|
-
const text = HFS.React.useMemo(() => {
|
|
9
|
+
const { data } = HFS.useBatch(getDetails, uri)
|
|
10
|
+
const text = React.useMemo(() => {
|
|
17
11
|
if (!data || data === true) return ''
|
|
18
12
|
const { upload: x } = data
|
|
19
13
|
return !x ? ''
|
|
20
14
|
: display === 'user' ? x.username
|
|
21
15
|
: display === 'ip' || !x.username ? x.ip
|
|
22
16
|
: x.ip + ' (' + x.username + ')'
|
|
23
|
-
})
|
|
17
|
+
}, [data])
|
|
24
18
|
return text && HFS.h('span', { className: 'uploader', title: HFS.t`Uploader` },
|
|
25
19
|
HFS.hIcon('upload'), ' ', text, ' – ')
|
|
26
20
|
}
|
|
21
|
+
|
|
22
|
+
function getDetails(batched) {
|
|
23
|
+
return batched.length && HFS.apiCall('get_file_details', { uris: batched }).then(x => x.details)
|
|
24
|
+
}
|
|
25
|
+
|
|
27
26
|
}
|
package/src/adminApis.js
CHANGED
|
@@ -51,6 +51,7 @@ const util_1 = require("util");
|
|
|
51
51
|
const customHtml_1 = require("./customHtml");
|
|
52
52
|
const lodash_1 = __importDefault(require("lodash"));
|
|
53
53
|
const update_1 = require("./update");
|
|
54
|
+
const consoleLog_1 = require("./consoleLog");
|
|
54
55
|
exports.adminApis = {
|
|
55
56
|
...api_vfs_1.default,
|
|
56
57
|
...api_accounts_1.default,
|
|
@@ -73,8 +74,12 @@ exports.adminApis = {
|
|
|
73
74
|
return {};
|
|
74
75
|
},
|
|
75
76
|
get_config: config_1.getWholeConfig,
|
|
76
|
-
update
|
|
77
|
-
|
|
77
|
+
update({ tag }) {
|
|
78
|
+
return (0, update_1.update)(tag);
|
|
79
|
+
},
|
|
80
|
+
async check_update() {
|
|
81
|
+
return { options: await (0, update_1.getUpdates)() };
|
|
82
|
+
},
|
|
78
83
|
get_custom_html() {
|
|
79
84
|
return {
|
|
80
85
|
sections: Object.fromEntries([
|
|
@@ -101,7 +106,7 @@ exports.adminApis = {
|
|
|
101
106
|
...await (0, listen_1.getServerStatus)(),
|
|
102
107
|
urls: (0, listen_1.getUrls)(),
|
|
103
108
|
baseUrl: middlewares_1.baseUrl.get(),
|
|
104
|
-
|
|
109
|
+
updatePossible: !(0, update_1.updateSupported)() ? false : await (0, update_1.localUpdateAvailable)() ? 'local' : true,
|
|
105
110
|
proxyDetected: (0, middlewares_1.getProxyDetected)(),
|
|
106
111
|
frpDetected: exports.localhostAdmin.get() && !(0, middlewares_1.getProxyDetected)()
|
|
107
112
|
&& (0, connections_1.getConnections)().every(misc_1.isLocalHost)
|
|
@@ -116,10 +121,20 @@ exports.adminApis = {
|
|
|
116
121
|
await (0, promises_1.writeFile)(files.cert, cert);
|
|
117
122
|
return files;
|
|
118
123
|
},
|
|
119
|
-
|
|
124
|
+
get_log({ file = 'log' }, ctx) {
|
|
120
125
|
return new apiMiddleware_1.SendListReadable({
|
|
121
126
|
bufferTime: 10,
|
|
122
|
-
doAtStart(list) {
|
|
127
|
+
async doAtStart(list) {
|
|
128
|
+
if (file === 'console') {
|
|
129
|
+
for (const chunk of lodash_1.default.chunk(consoleLog_1.consoleLog, 1000)) { // avoid occupying the thread too long
|
|
130
|
+
for (const x of chunk)
|
|
131
|
+
list.add(x);
|
|
132
|
+
await (0, misc_1.wait)(0);
|
|
133
|
+
}
|
|
134
|
+
list.ready();
|
|
135
|
+
events_1.default.on('console', x => list.add(x));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
123
138
|
const logger = log_1.loggers.find(l => l.name === file);
|
|
124
139
|
if (!logger)
|
|
125
140
|
return list.error(const_1.HTTP_NOT_FOUND, true);
|
package/src/api.file_list.js
CHANGED
|
@@ -39,7 +39,7 @@ const file_list = async ({ uri, offset, limit, search, c, sse }, ctx) => {
|
|
|
39
39
|
return { ...props, list: await (0, misc_1.asyncGeneratorToArray)(produceEntries()) };
|
|
40
40
|
setTimeout(async () => {
|
|
41
41
|
if (can_upload || can_delete)
|
|
42
|
-
list.
|
|
42
|
+
list.props(props);
|
|
43
43
|
for await (const entry of produceEntries())
|
|
44
44
|
list.add(entry);
|
|
45
45
|
list.close();
|
|
@@ -103,12 +103,13 @@ async function nodeToDirEntry(ctx, node) {
|
|
|
103
103
|
const pr = node.can_read === vfs_1.WHO_NO_ONE && !(folder && filesInsideCould()) ? 'r'
|
|
104
104
|
: !(0, vfs_1.hasPermission)(node, 'can_read', ctx) ? 'R'
|
|
105
105
|
: '';
|
|
106
|
+
const pd = (0, vfs_1.hasPermission)(node, 'can_delete', ctx) ? 'd' : '';
|
|
106
107
|
return {
|
|
107
108
|
n: name + (folder ? '/' : ''),
|
|
108
109
|
c: ctime,
|
|
109
110
|
m: Math.abs(+mtime - +ctime) < 1000 ? undefined : mtime,
|
|
110
111
|
s: folder ? undefined : st.size,
|
|
111
|
-
p: (pr + pl) || undefined
|
|
112
|
+
p: (pr + pl + pd) || undefined
|
|
112
113
|
};
|
|
113
114
|
}
|
|
114
115
|
catch (_a) {
|
package/src/api.monitor.js
CHANGED
|
@@ -26,47 +26,47 @@ const apis = {
|
|
|
26
26
|
return { result: Boolean(c) };
|
|
27
27
|
},
|
|
28
28
|
get_connections({}, ctx) {
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
29
|
+
const sent = Symbol('sent');
|
|
30
|
+
const list = new apiMiddleware_1.SendListReadable({
|
|
31
|
+
addAtStart: (0, connections_1.getConnections)().map(c => !ignore(c) && (c[sent] = serializeConnection(c))).filter(Boolean),
|
|
32
|
+
onEnd() {
|
|
33
|
+
for (const c of (0, connections_1.getConnections)())
|
|
34
|
+
delete c[sent];
|
|
35
|
+
}
|
|
36
|
+
});
|
|
32
37
|
list.props({ you: ctx.ip });
|
|
33
38
|
return list.events(ctx, {
|
|
34
39
|
connection(conn) {
|
|
35
|
-
|
|
40
|
+
if (ignore(conn))
|
|
41
|
+
return;
|
|
42
|
+
list.add(conn[sent] = serializeConnection(conn));
|
|
36
43
|
},
|
|
37
44
|
connectionClosed(conn) {
|
|
38
|
-
if (
|
|
45
|
+
if (ignore(conn))
|
|
39
46
|
return;
|
|
40
47
|
list.remove(getConnAddress(conn));
|
|
41
|
-
conn[
|
|
48
|
+
delete conn[sent];
|
|
42
49
|
},
|
|
43
50
|
connectionUpdated(conn, change) {
|
|
44
|
-
if (
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
if (ignore(conn) || ignore(change) || !conn[sent])
|
|
52
|
+
return;
|
|
53
|
+
if (change.ctx) {
|
|
54
|
+
Object.assign(change, fromCtx(change.ctx));
|
|
55
|
+
change.ctx = undefined;
|
|
56
|
+
}
|
|
57
|
+
if (change.opProgress)
|
|
58
|
+
change.opProgress = lodash_1.default.round(change.opProgress, 3);
|
|
59
|
+
// avoid sending non-changes
|
|
60
|
+
const last = conn[sent];
|
|
61
|
+
for (const [k, v] of (0, misc_1.typedEntries)(change))
|
|
62
|
+
if (v === last[k])
|
|
63
|
+
delete change[k];
|
|
64
|
+
if (lodash_1.default.isEmpty(change))
|
|
65
|
+
return;
|
|
66
|
+
Object.assign(last, change);
|
|
67
|
+
list.update(getConnAddress(conn), change);
|
|
50
68
|
},
|
|
51
69
|
});
|
|
52
|
-
function add(conn) {
|
|
53
|
-
if (!cancel(conn))
|
|
54
|
-
return;
|
|
55
|
-
list.add(serializeConnection(conn));
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
function cancel(conn) {
|
|
59
|
-
if (!conn[state])
|
|
60
|
-
return;
|
|
61
|
-
clearTimeout(conn[state]);
|
|
62
|
-
conn[state] = undefined;
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
function update(conn, change) {
|
|
66
|
-
if (conn[state] === false)
|
|
67
|
-
return;
|
|
68
|
-
list.update(getConnAddress(conn), change);
|
|
69
|
-
}
|
|
70
70
|
function serializeConnection(conn) {
|
|
71
71
|
var _a;
|
|
72
72
|
const { socket, started, secure } = conn;
|
|
@@ -99,13 +99,16 @@ const apis = {
|
|
|
99
99
|
inSpeed: throttler_1.totalInSpeed,
|
|
100
100
|
got: throttler_1.totalGot,
|
|
101
101
|
sent: throttler_1.totalSent,
|
|
102
|
-
connections: (0, connections_1.getConnections)()
|
|
102
|
+
connections: lodash_1.default.sumBy((0, connections_1.getConnections)(), x => ignore(x) ? 0 : 1),
|
|
103
103
|
};
|
|
104
104
|
await (0, misc_1.wait)(1000);
|
|
105
105
|
}
|
|
106
106
|
},
|
|
107
107
|
};
|
|
108
108
|
exports.default = apis;
|
|
109
|
+
function ignore(conn) {
|
|
110
|
+
return false; //conn.socket && isLocalHost(conn)
|
|
111
|
+
}
|
|
109
112
|
function getConnAddress(conn) {
|
|
110
113
|
return {
|
|
111
114
|
ip: conn.ip,
|
package/src/api.vfs.js
CHANGED
|
@@ -78,7 +78,7 @@ const apis = {
|
|
|
78
78
|
const n = await urlToNodeOriginal(uri);
|
|
79
79
|
if (!n)
|
|
80
80
|
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND, 'path not found');
|
|
81
|
-
props = pickProps(props, ['name', 'source', 'masks', 'default', 'accept',
|
|
81
|
+
props = pickProps(props, ['name', 'source', 'masks', 'default', 'accept', ...vfs_1.PERM_KEYS]); // sanitize
|
|
82
82
|
if (props.name && props.name !== (0, vfs_1.getNodeName)(n)) {
|
|
83
83
|
const parent = await urlToNodeOriginal((0, path_1.dirname)(uri));
|
|
84
84
|
if ((_a = parent === null || parent === void 0 ? void 0 : parent.children) === null || _a === void 0 ? void 0 : _a.find(x => (0, vfs_1.getNodeName)(x) === props.name))
|
|
@@ -151,44 +151,47 @@ const apis = {
|
|
|
151
151
|
path = (0, path_1.dirname)(path);
|
|
152
152
|
return { path };
|
|
153
153
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
const matching = (0, misc_1.makeMatcher)(fileMask);
|
|
167
|
-
path = (0, misc_1.isWindowsDrive)(path) ? path + '\\' : (0, path_1.resolve)(path || '/');
|
|
168
|
-
for await (const [name, isDir] of (0, misc_1.dirStream)(path)) {
|
|
169
|
-
if (ctx.req.aborted)
|
|
154
|
+
ls({ path, files = true, fileMask }, ctx) {
|
|
155
|
+
return new apiMiddleware_1.SendListReadable({
|
|
156
|
+
async doAtStart(list) {
|
|
157
|
+
if (!path && const_1.IS_WINDOWS) {
|
|
158
|
+
try {
|
|
159
|
+
for (const n of await (0, util_os_1.getDrives)())
|
|
160
|
+
list.add({ n, k: 'd' });
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.debug(error);
|
|
164
|
+
}
|
|
170
165
|
return;
|
|
166
|
+
}
|
|
171
167
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
168
|
+
const matching = (0, misc_1.makeMatcher)(fileMask);
|
|
169
|
+
path = (0, misc_1.isWindowsDrive)(path) ? path + '\\' : (0, path_1.resolve)(path || '/');
|
|
170
|
+
for await (const [name, isDir] of (0, misc_1.dirStream)(path)) {
|
|
171
|
+
if (ctx.req.aborted)
|
|
172
|
+
return;
|
|
173
|
+
if (!isDir)
|
|
174
|
+
if (!files || fileMask && !matching(name))
|
|
175
|
+
continue;
|
|
176
|
+
try {
|
|
177
|
+
const stats = await (0, promises_1.stat)((0, path_1.join)(path, name));
|
|
178
|
+
list.add({
|
|
179
|
+
n: name,
|
|
180
|
+
s: stats.size,
|
|
181
|
+
c: stats.ctime,
|
|
182
|
+
m: stats.mtime,
|
|
183
|
+
k: isDir ? 'd' : undefined,
|
|
184
|
+
});
|
|
183
185
|
}
|
|
184
|
-
|
|
186
|
+
catch (_a) { } // just ignore entries we can't stat
|
|
187
|
+
}
|
|
188
|
+
list.close();
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
list.error(e.code || e.message || String(e), true);
|
|
185
192
|
}
|
|
186
|
-
catch (_a) { } // just ignore entries we can't stat
|
|
187
193
|
}
|
|
188
|
-
}
|
|
189
|
-
catch (e) {
|
|
190
|
-
yield { error: e.code || e.message || String(e) };
|
|
191
|
-
}
|
|
194
|
+
});
|
|
192
195
|
}
|
|
193
196
|
};
|
|
194
197
|
exports.default = apis;
|
package/src/apiMiddleware.js
CHANGED
|
@@ -36,10 +36,16 @@ function apiMiddleware(apis) {
|
|
|
36
36
|
let res;
|
|
37
37
|
try {
|
|
38
38
|
for (const [k, v] of Object.entries(params))
|
|
39
|
-
if (k.startsWith('uri')
|
|
40
|
-
|
|
39
|
+
if (k.startsWith('uri'))
|
|
40
|
+
if (typeof v === 'string')
|
|
41
|
+
fixUri(params, k);
|
|
42
|
+
else if (typeof (v === null || v === void 0 ? void 0 : v[0]) === 'string')
|
|
43
|
+
v.forEach((x, i) => fixUri(v, i));
|
|
41
44
|
res = csrf && csrf !== params.csrf ? new ApiError(const_1.HTTP_UNAUTHORIZED, 'csrf')
|
|
42
45
|
: await apiFun(params || {}, ctx);
|
|
46
|
+
function fixUri(o, k) {
|
|
47
|
+
o[k] = (0, misc_1.removeStarting)(ctx.state.revProxyPath, o[k]);
|
|
48
|
+
}
|
|
43
49
|
}
|
|
44
50
|
catch (e) {
|
|
45
51
|
res = e;
|
|
@@ -69,18 +75,20 @@ function isAsyncGenerator(x) {
|
|
|
69
75
|
return typeof (x === null || x === void 0 ? void 0 : x.next) === 'function';
|
|
70
76
|
}
|
|
71
77
|
class SendListReadable extends stream_1.Readable {
|
|
72
|
-
constructor({ addAtStart, doAtStart, bufferTime } = {}) {
|
|
78
|
+
constructor({ addAtStart, doAtStart, bufferTime, onEnd } = {}) {
|
|
73
79
|
super({ objectMode: true, read() { } });
|
|
74
80
|
this.buffer = [];
|
|
75
81
|
if (!bufferTime)
|
|
76
|
-
bufferTime =
|
|
82
|
+
bufferTime = 200;
|
|
77
83
|
this.processBuffer = lodash_1.default.debounce(() => {
|
|
78
84
|
this.push(this.buffer);
|
|
79
85
|
this.buffer = [];
|
|
80
86
|
}, bufferTime, { maxWait: bufferTime });
|
|
81
|
-
this.on('end', () =>
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
this.on('end', () => {
|
|
88
|
+
onEnd === null || onEnd === void 0 ? void 0 : onEnd(this);
|
|
89
|
+
this.destroy();
|
|
90
|
+
});
|
|
91
|
+
setTimeout(() => doAtStart === null || doAtStart === void 0 ? void 0 : doAtStart(this)); // work later, when list object has been received by Koa
|
|
84
92
|
if (addAtStart) {
|
|
85
93
|
for (const x of addAtStart)
|
|
86
94
|
this.add(x);
|
|
@@ -95,25 +103,45 @@ class SendListReadable extends stream_1.Readable {
|
|
|
95
103
|
this.processBuffer();
|
|
96
104
|
}
|
|
97
105
|
add(rec) {
|
|
98
|
-
this._push(
|
|
106
|
+
this._push(['add', rec]);
|
|
99
107
|
}
|
|
100
|
-
remove(
|
|
101
|
-
|
|
108
|
+
remove(search) {
|
|
109
|
+
const match = lodash_1.default.matches(search);
|
|
110
|
+
const idx = lodash_1.default.findIndex(this.buffer, x => match(x[1]));
|
|
111
|
+
const found = this.buffer[idx];
|
|
112
|
+
const op = found === null || found === void 0 ? void 0 : found[0];
|
|
113
|
+
if (op === 'remove')
|
|
114
|
+
return;
|
|
115
|
+
if (found) {
|
|
116
|
+
this.buffer.splice(idx, 1);
|
|
117
|
+
if (op === 'add')
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this._push(['remove', search]);
|
|
102
121
|
}
|
|
103
122
|
update(search, change) {
|
|
104
|
-
|
|
123
|
+
if (lodash_1.default.isEmpty(change))
|
|
124
|
+
return;
|
|
125
|
+
const match = lodash_1.default.matches(search);
|
|
126
|
+
const found = lodash_1.default.find(this.buffer, x => match(x[1]));
|
|
127
|
+
const op = found === null || found === void 0 ? void 0 : found[0];
|
|
128
|
+
if (op === 'remove')
|
|
129
|
+
return;
|
|
130
|
+
if (op === 'add' || op === 'update')
|
|
131
|
+
return Object.assign(found[op === 'add' ? 1 : 2], change);
|
|
132
|
+
return this._push(['update', search, change]);
|
|
105
133
|
}
|
|
106
134
|
ready() {
|
|
107
|
-
this._push('ready');
|
|
135
|
+
this._push(['ready']);
|
|
108
136
|
}
|
|
109
137
|
custom(data) {
|
|
110
138
|
this._push(data);
|
|
111
139
|
}
|
|
112
140
|
props(props) {
|
|
113
|
-
this._push(
|
|
141
|
+
this._push(['props', props]);
|
|
114
142
|
}
|
|
115
143
|
error(msg, close = false, props) {
|
|
116
|
-
this._push(
|
|
144
|
+
this._push(['error', msg, props]);
|
|
117
145
|
this.lastError = msg;
|
|
118
146
|
if (close)
|
|
119
147
|
this.close();
|
package/src/commands.js
CHANGED
|
@@ -111,8 +111,8 @@ const commands = {
|
|
|
111
111
|
'check-update': {
|
|
112
112
|
params: '',
|
|
113
113
|
async cb() {
|
|
114
|
-
const update = await (0, update_1.
|
|
115
|
-
if (update
|
|
114
|
+
const [update] = await (0, update_1.getUpdates)();
|
|
115
|
+
if (!update)
|
|
116
116
|
throw "you already have the latest version: " + const_1.VERSION;
|
|
117
117
|
console.log("new version available", update.name);
|
|
118
118
|
}
|
package/src/config.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.saveConfigAsap = exports.setConfig = exports.getWholeConfig = exports.getConfig = exports.configKeyExists = exports.defineConfig = void 0;
|
|
7
|
+
exports.saveConfigAsap = exports.setConfig = exports.getWholeConfig = exports.getConfig = exports.configKeyExists = exports.defineConfig = exports.currentVersion = exports.versionToScalar = void 0;
|
|
8
8
|
const events_1 = __importDefault(require("events"));
|
|
9
9
|
const const_1 = require("./const");
|
|
10
10
|
const watchLoad_1 = require("./watchLoad");
|
|
@@ -48,27 +48,30 @@ if (!(0, fs_1.existsSync)(filePath) && (0, fs_1.existsSync)(legacyPosition))
|
|
|
48
48
|
catch (_b) { }
|
|
49
49
|
}
|
|
50
50
|
// takes a semver like 1.2.3-alpha1, but alpha and beta numbers must share the number progression
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
if (numbers.length !== 3)
|
|
51
|
+
exports.versionToScalar = lodash_1.default.memoize((ver) => {
|
|
52
|
+
// this regexp is supposed to be resistant to optional leading "v" and an optional custom name after a space
|
|
53
|
+
const res = /^v?(\d+)\.(\d+)\.(\d+)(?:-\w+(\d+))?/.exec(ver);
|
|
54
|
+
if (!res)
|
|
56
55
|
return NaN;
|
|
57
|
-
const
|
|
58
|
-
const
|
|
56
|
+
const [, a, b, c, beta] = res.map(Number);
|
|
57
|
+
const officialScalar = c + b * 1E3 + a * 1E6; // gives 3 digits for each number
|
|
58
|
+
const betaScalar = 1 / (1 + beta || Infinity); // beta tends to 0, while non-beta is 0. +1 to make it work even in case of alpha0
|
|
59
59
|
return officialScalar - betaScalar;
|
|
60
60
|
});
|
|
61
61
|
class Version extends String {
|
|
62
62
|
olderThan(otherVersion) {
|
|
63
|
-
return versionToScalar(this.valueOf()) < versionToScalar(otherVersion);
|
|
63
|
+
return (0, exports.versionToScalar)(this.valueOf()) < (0, exports.versionToScalar)(otherVersion);
|
|
64
|
+
}
|
|
65
|
+
getScalar() {
|
|
66
|
+
return (0, exports.versionToScalar)(this.valueOf());
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
69
|
const CONFIG_CHANGE_EVENT_PREFIX = 'new.';
|
|
67
|
-
|
|
70
|
+
exports.currentVersion = new Version(const_1.VERSION);
|
|
68
71
|
const configVersion = defineConfig('version', const_1.VERSION, v => new Version(v));
|
|
69
72
|
function defineConfig(k, defaultValue, compiler) {
|
|
70
73
|
configProps[k] = { defaultValue };
|
|
71
|
-
let compiled = compiler === null || compiler === void 0 ? void 0 : compiler(defaultValue, { version: currentVersion, defaultValue });
|
|
74
|
+
let compiled = compiler === null || compiler === void 0 ? void 0 : compiler(defaultValue, { version: exports.currentVersion, defaultValue });
|
|
72
75
|
const ret = {
|
|
73
76
|
key() {
|
|
74
77
|
return k;
|
|
@@ -162,7 +165,7 @@ function setConfig(newCfg, save) {
|
|
|
162
165
|
if (version !== const_1.VERSION) // be sure to save version
|
|
163
166
|
(0, exports.saveConfigAsap)();
|
|
164
167
|
function apply(k, newV, isDefault = false) {
|
|
165
|
-
return setConfig1(k, newV, save === undefined, argCfg && k in argCfg || isDefault ? currentVersion : version);
|
|
168
|
+
return setConfig1(k, newV, save === undefined, argCfg && k in argCfg || isDefault ? exports.currentVersion : version);
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
171
|
exports.setConfig = setConfig;
|
package/src/connections.js
CHANGED
|
@@ -6,7 +6,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.updateConnection = exports.socket2connection = exports.getConnections = exports.newConnection = exports.normalizeIp = exports.Connection = void 0;
|
|
8
8
|
const events_1 = __importDefault(require("./events"));
|
|
9
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
10
9
|
class Connection {
|
|
11
10
|
constructor(socket) {
|
|
12
11
|
this.socket = socket;
|
|
@@ -49,9 +48,9 @@ function socket2connection(socket) {
|
|
|
49
48
|
}
|
|
50
49
|
exports.socket2connection = socket2connection;
|
|
51
50
|
function updateConnection(conn, change) {
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
|
|
51
|
+
var _a;
|
|
52
|
+
if (change.op)
|
|
53
|
+
(_a = change.opProgress) !== null && _a !== void 0 ? _a : (change.opProgress = change.opOffset || 0);
|
|
55
54
|
Object.assign(conn, change);
|
|
56
55
|
events_1.default.emit('connectionUpdated', conn, change);
|
|
57
56
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.consoleLog = void 0;
|
|
7
|
+
const events_1 = __importDefault(require("./events"));
|
|
8
|
+
exports.consoleLog = [];
|
|
9
|
+
for (const k of ['log', 'warn', 'error']) {
|
|
10
|
+
const original = console[k];
|
|
11
|
+
console[k] = (...args) => {
|
|
12
|
+
const rec = { ts: new Date(), k, msg: args.join(' ') };
|
|
13
|
+
exports.consoleLog.push(rec);
|
|
14
|
+
events_1.default.emit('console', rec);
|
|
15
|
+
return original(...args);
|
|
16
|
+
};
|
|
17
|
+
}
|
package/src/const.js
CHANGED
|
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
28
|
};
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.APP_PATH = exports.IS_BINARY = exports.IS_WINDOWS = exports.HTTP_SERVER_ERROR = exports.HTTP_FAILED_DEPENDENCY = exports.HTTP_FOOL = exports.HTTP_RANGE_NOT_SATISFIABLE = exports.HTTP_PAYLOAD_TOO_LARGE = exports.HTTP_CONFLICT = exports.HTTP_NOT_ACCEPTABLE = exports.HTTP_METHOD_NOT_ALLOWED = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_UNAUTHORIZED = exports.HTTP_BAD_REQUEST = exports.HTTP_NOT_MODIFIED = exports.HTTP_TEMPORARY_REDIRECT = exports.HTTP_PARTIAL_CONTENT = exports.HTTP_NO_CONTENT = exports.HTTP_OK = exports.PLUGINS_PUB_URI = exports.API_URI = exports.ADMIN_URI = exports.FRONTEND_URI = exports.SPECIAL_URI = exports.HFS_REPO = exports.COMPATIBLE_API_VERSION = exports.API_VERSION = exports.DAY = exports.VERSION = exports.BUILD_TIMESTAMP = exports.HFS_STARTED = exports.ORIGINAL_CWD = exports.DEV = exports.argv = void 0;
|
|
30
|
+
exports.APP_PATH = exports.IS_BINARY = exports.IS_WINDOWS = exports.HTTP_SERVER_ERROR = exports.HTTP_FAILED_DEPENDENCY = exports.HTTP_FOOL = exports.HTTP_RANGE_NOT_SATISFIABLE = exports.HTTP_PAYLOAD_TOO_LARGE = exports.HTTP_CONFLICT = exports.HTTP_NOT_ACCEPTABLE = exports.HTTP_METHOD_NOT_ALLOWED = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_UNAUTHORIZED = exports.HTTP_BAD_REQUEST = exports.HTTP_NOT_MODIFIED = exports.HTTP_TEMPORARY_REDIRECT = exports.HTTP_PARTIAL_CONTENT = exports.HTTP_NO_CONTENT = exports.HTTP_OK = exports.PLUGINS_PUB_URI = exports.API_URI = exports.ADMIN_URI = exports.FRONTEND_URI = exports.SPECIAL_URI = exports.HFS_REPO = exports.COMPATIBLE_API_VERSION = exports.API_VERSION = exports.DAY = exports.RUNNING_BETA = exports.VERSION = exports.BUILD_TIMESTAMP = exports.HFS_STARTED = exports.ORIGINAL_CWD = exports.DEV = exports.argv = void 0;
|
|
31
31
|
const minimist_1 = __importDefault(require("minimist"));
|
|
32
32
|
const fs = __importStar(require("fs"));
|
|
33
33
|
const os_1 = require("os");
|
|
@@ -38,11 +38,12 @@ exports.DEV = process.env.DEV || exports.argv.dev ? 'DEV' : '';
|
|
|
38
38
|
exports.ORIGINAL_CWD = process.cwd();
|
|
39
39
|
exports.HFS_STARTED = new Date();
|
|
40
40
|
const PKG_PATH = (0, path_1.join)(__dirname, '..', 'package.json');
|
|
41
|
-
exports.BUILD_TIMESTAMP = "2023-07-
|
|
41
|
+
exports.BUILD_TIMESTAMP = "2023-07-23T12:24:58.087Z";
|
|
42
42
|
const pkg = JSON.parse(fs.readFileSync(PKG_PATH, 'utf8'));
|
|
43
43
|
exports.VERSION = pkg.version;
|
|
44
|
+
exports.RUNNING_BETA = exports.VERSION.includes('-');
|
|
44
45
|
exports.DAY = 86400000;
|
|
45
|
-
exports.API_VERSION = 8.
|
|
46
|
+
exports.API_VERSION = 8.3;
|
|
46
47
|
exports.COMPATIBLE_API_VERSION = 1; // while changes in the api are not breaking, this number stays the same, otherwise it is made equal to API_VERSION
|
|
47
48
|
exports.HFS_REPO = 'rejetto/hfs';
|
|
48
49
|
exports.SPECIAL_URI = '/~/';
|
package/src/frontEndApis.js
CHANGED
|
@@ -53,13 +53,19 @@ exports.frontEndApis = {
|
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
55
|
},
|
|
56
|
-
async get_file_details({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (!node)
|
|
60
|
-
return new apiMiddleware_1.ApiError(const_1.HTTP_NOT_FOUND);
|
|
56
|
+
async get_file_details({ uris }, ctx) {
|
|
57
|
+
if (typeof (uris === null || uris === void 0 ? void 0 : uris[0]) !== 'string')
|
|
58
|
+
return new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad uris');
|
|
61
59
|
return {
|
|
62
|
-
|
|
60
|
+
details: Promise.all(uris.map(async (uri) => {
|
|
61
|
+
if (typeof uri !== 'string')
|
|
62
|
+
return false; // false means error
|
|
63
|
+
const node = await (0, vfs_1.urlToNode)(uri, ctx);
|
|
64
|
+
if (!node)
|
|
65
|
+
return false;
|
|
66
|
+
const upload = node.source && await (0, upload_1.getUploadMeta)(node.source).catch(() => undefined);
|
|
67
|
+
return upload && { upload };
|
|
68
|
+
}))
|
|
63
69
|
};
|
|
64
70
|
},
|
|
65
71
|
async create_folder({ uri, name }, ctx) {
|
|
@@ -127,8 +133,9 @@ function notifyClient(ctx, name, data) {
|
|
|
127
133
|
exports.notifyClient = notifyClient;
|
|
128
134
|
const NOTIFICATION_PREFIX = 'notificationChannel:';
|
|
129
135
|
function apiAssertTypes(paramsByType) {
|
|
130
|
-
for (const [
|
|
131
|
-
for (const
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
for (const [types, params] of Object.entries(paramsByType))
|
|
137
|
+
for (const type of types.split('_'))
|
|
138
|
+
for (const [name, val] of Object.entries(params))
|
|
139
|
+
if (typeof val !== type)
|
|
140
|
+
throw new apiMiddleware_1.ApiError(const_1.HTTP_BAD_REQUEST, 'bad ' + name);
|
|
134
141
|
}
|